2021-03-09 23:24:35 +01:00
|
|
|
#include "router_contact.hpp"
|
|
|
|
|
|
|
|
#include "constants/version.hpp"
|
|
|
|
#include "crypto/crypto.hpp"
|
|
|
|
#include "net/net.hpp"
|
|
|
|
#include "util/bencode.hpp"
|
|
|
|
#include "util/buffer.hpp"
|
2022-10-05 20:05:25 +02:00
|
|
|
#include "util/file.hpp"
|
2023-10-24 15:18:03 +02:00
|
|
|
|
|
|
|
#include <oxenc/bt_serialize.h>
|
2018-08-31 14:46:54 +02:00
|
|
|
|
2018-08-30 20:48:43 +02:00
|
|
|
namespace llarp
|
2018-07-08 15:26:24 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
void
|
|
|
|
RouterContact::bt_load(oxenc::bt_dict_consumer& data)
|
2018-12-19 17:17:41 +01:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
if (int rc_ver = data.require<uint8_t>(""); rc_ver != RC_VERSION)
|
|
|
|
throw std::runtime_error{"Invalid RC: do not know how to parse v{} RCs"_format(rc_ver)};
|
2018-12-19 17:17:41 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
auto ipv4_port = data.require<std::string_view>("4");
|
2018-12-19 17:17:41 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
if (ipv4_port.size() != 6)
|
|
|
|
throw std::runtime_error{
|
|
|
|
"Invalid RC address: expected 6-byte IPv4 IP/port, got {}"_format(ipv4_port.size())};
|
2019-08-27 01:29:17 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
sockaddr_in s4;
|
|
|
|
s4.sin_family = AF_INET;
|
2019-01-02 02:03:53 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
std::memcpy(&s4.sin_addr.s_addr, ipv4_port.data(), 4);
|
|
|
|
std::memcpy(&s4.sin_port, ipv4_port.data() + 4, 2);
|
2018-12-19 17:17:41 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
_addr = oxen::quic::Address{&s4};
|
2018-12-19 17:17:41 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
if (!_addr.is_public())
|
|
|
|
throw std::runtime_error{"Invalid RC: IPv4 address is not a publicly routable IP"};
|
|
|
|
|
|
|
|
if (auto ipv6_port = data.maybe<std::string_view>("6"))
|
2023-10-03 22:00:23 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
if (ipv6_port->size() != 18)
|
|
|
|
throw std::runtime_error{
|
|
|
|
"Invalid RC address: expected 18-byte IPv6 IP/port, got {}"_format(ipv6_port->size())};
|
|
|
|
|
|
|
|
sockaddr_in6 s6{};
|
|
|
|
s6.sin6_family = AF_INET6;
|
2023-10-03 22:00:23 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
std::memcpy(&s6.sin6_addr.s6_addr, ipv6_port->data(), 16);
|
|
|
|
std::memcpy(&s6.sin6_port, ipv6_port->data() + 16, 2);
|
2023-10-19 13:49:46 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
_addr6.emplace(&s6);
|
|
|
|
if (!_addr6->is_public())
|
|
|
|
throw std::runtime_error{"Invalid RC: IPv6 address is not a publicly routable IP"};
|
2023-10-03 22:00:23 +02:00
|
|
|
}
|
2023-10-31 21:49:01 +01:00
|
|
|
else
|
2023-10-03 22:00:23 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
_addr6.reset();
|
2023-10-03 22:00:23 +02:00
|
|
|
}
|
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
auto netid = data.maybe<std::string_view>("i").value_or(llarp::LOKINET_DEFAULT_NETID);
|
|
|
|
if (netid != ACTIVE_NETID)
|
|
|
|
throw std::runtime_error{
|
|
|
|
"Invalid RC netid: expected {}, got {}; this is an RC for a different network!"_format(
|
|
|
|
ACTIVE_NETID, netid)};
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
auto pk = data.require<std::string_view>("p");
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
if (pk.size() != RouterID::SIZE)
|
|
|
|
throw std::runtime_error{"Invalid RC: router id has invalid size {}"_format(pk.size())};
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
std::memcpy(_router_id.data(), pk.data(), RouterID::SIZE);
|
2023-08-29 16:26:59 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
_timestamp = rc_time{std::chrono::seconds{data.require<int64_t>("t")}};
|
2020-10-12 18:18:46 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
auto ver = data.require<ustring_view>("v");
|
2022-07-26 17:05:18 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
if (ver.size() != 3)
|
|
|
|
throw std::runtime_error{
|
|
|
|
"Invalid RC router version: received {} bytes (!= 3)"_format(ver.size())};
|
2018-05-13 20:07:36 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
_router_version[i] = ver[i];
|
|
|
|
}
|
2021-04-06 14:25:46 +02:00
|
|
|
|
2023-11-02 13:30:38 +01:00
|
|
|
bool
|
|
|
|
RouterContact::write(const fs::path& fname) const
|
|
|
|
{
|
2023-11-02 13:39:20 +01:00
|
|
|
auto bte = view();
|
2023-11-02 13:30:38 +01:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
util::buffer_to_file(fname, bte.data(), bte.size());
|
|
|
|
}
|
|
|
|
catch (const std::exception& e)
|
|
|
|
{
|
|
|
|
log::error(logcat, "Failed to write RC to {}: {}", fname, e.what());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-02-11 18:14:43 +01:00
|
|
|
util::StatusObject
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::extract_status() const
|
2019-02-08 20:43:25 +01:00
|
|
|
{
|
2021-03-05 18:31:52 +01:00
|
|
|
util::StatusObject obj{
|
2023-10-31 21:49:01 +01:00
|
|
|
{"lastUpdated", _timestamp.time_since_epoch().count()},
|
|
|
|
{"publicRouter", is_public_router()},
|
|
|
|
{"identity", _router_id.ToString()},
|
|
|
|
{"address", _addr.to_string()}};
|
|
|
|
|
|
|
|
// if (routerVersion)
|
|
|
|
// {
|
|
|
|
// obj["routerVersion"] = routerVersion->ToString();
|
|
|
|
// }
|
|
|
|
// std::vector<util::StatusObject> srv;
|
|
|
|
// for (const auto& record : srvRecords)
|
|
|
|
// {
|
|
|
|
// srv.emplace_back(record.ExtractStatus());
|
|
|
|
// }
|
|
|
|
// obj["srvRecords"] = srv;
|
2019-08-20 00:25:40 +02:00
|
|
|
|
2019-02-11 18:14:43 +01:00
|
|
|
return obj;
|
2019-02-08 20:43:25 +01:00
|
|
|
}
|
|
|
|
|
2020-09-25 20:05:28 +02:00
|
|
|
bool
|
|
|
|
RouterContact::BDecode(llarp_buffer_t* buf)
|
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
// TODO: unfuck all of this
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
(void)buf;
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// clear();
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (*buf->cur == 'd') // old format
|
|
|
|
// {
|
|
|
|
// return DecodeVersion_0(buf);
|
|
|
|
// }
|
|
|
|
// else if (*buf->cur != 'l') // if not dict, should be new format and start with list
|
|
|
|
// {
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// try
|
|
|
|
// {
|
|
|
|
// std::string_view buf_view(reinterpret_cast<char*>(buf->cur), buf->size_left());
|
|
|
|
// oxenc::bt_list_consumer btlist(buf_view);
|
|
|
|
|
|
|
|
// uint64_t outer_version = btlist.consume_integer<uint64_t>();
|
|
|
|
|
|
|
|
// if (outer_version == 1)
|
|
|
|
// {
|
|
|
|
// bool decode_result = DecodeVersion_1(btlist);
|
|
|
|
|
|
|
|
// // advance the llarp_buffer_t since lokimq serialization is unaware of it.
|
|
|
|
// // FIXME: this is broken (current_buffer got dropped), but the whole thing is getting
|
|
|
|
// // replaced.
|
|
|
|
// // buf->cur += btlist.
|
|
|
|
// // current_buffer().data() - buf_view.data() + 1;
|
|
|
|
|
|
|
|
// return decode_result;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// log::warning(logcat, "Received RouterContact with unkown version ({})", outer_version);
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// catch (const std::exception& e)
|
|
|
|
// {
|
|
|
|
// log::debug(logcat, "RouterContact::BDecode failed: {}", e.what());
|
|
|
|
// }
|
2020-09-25 20:05:28 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
return false;
|
2020-09-25 20:05:28 +02:00
|
|
|
}
|
|
|
|
|
2018-08-30 20:48:43 +02:00
|
|
|
bool
|
2023-08-31 18:28:02 +02:00
|
|
|
RouterContact::decode_key(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
2018-08-09 17:36:58 +02:00
|
|
|
{
|
2018-08-30 20:48:43 +02:00
|
|
|
bool read = false;
|
2023-10-31 21:49:01 +01:00
|
|
|
(void)key;
|
2023-10-19 13:49:46 +02:00
|
|
|
|
|
|
|
// TOFIX: fuck everything about llarp_buffer_t
|
2023-11-02 13:30:38 +01:00
|
|
|
|
2023-10-19 13:49:46 +02:00
|
|
|
// if (!BEncodeMaybeReadDictEntry("a", addr, read, key, buf))
|
|
|
|
// return false;
|
2018-08-30 20:48:43 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (!BEncodeMaybeReadDictEntry("i", netID, read, key, buf))
|
|
|
|
// return false;
|
2018-12-19 17:17:41 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (!BEncodeMaybeReadDictEntry("k", _router_id, read, key, buf))
|
|
|
|
// return false;
|
2018-08-02 02:48:43 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (key.startswith("r"))
|
|
|
|
// {
|
|
|
|
// RouterVersion r;
|
|
|
|
// if (not r.BDecode(buf))
|
|
|
|
// return false;
|
|
|
|
// routerVersion = r;
|
|
|
|
// return true;
|
|
|
|
// }
|
2020-01-25 17:28:07 +01:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (not BEncodeMaybeReadDictList("s", srvRecords, read, key, buf))
|
|
|
|
// return false;
|
2021-04-06 14:25:46 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (!BEncodeMaybeReadDictEntry("p", enckey, read, key, buf))
|
|
|
|
// return false;
|
2018-05-21 14:44:50 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (!BEncodeMaybeReadDictInt("u", _timestamp, read, key, buf))
|
|
|
|
// return false;
|
2018-08-31 15:51:24 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (!BEncodeMaybeReadDictInt("v", version, read, key, buf))
|
|
|
|
// return false;
|
2018-05-11 01:32:46 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (key.startswith("x") and serializeExit)
|
|
|
|
// {
|
|
|
|
// return bencode_discard(buf);
|
|
|
|
// }
|
2018-08-30 20:48:43 +02:00
|
|
|
|
2023-10-31 21:49:01 +01:00
|
|
|
// if (!BEncodeMaybeReadDictEntry("z", signature, read, key, buf))
|
|
|
|
// return false;
|
2018-08-30 20:48:43 +02:00
|
|
|
|
2021-04-06 14:25:46 +02:00
|
|
|
return read or bencode_discard(buf);
|
2018-05-11 01:32:46 +02:00
|
|
|
}
|
|
|
|
|
2018-08-31 14:46:54 +02:00
|
|
|
bool
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::is_public_router() const
|
2018-08-31 14:46:54 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
if (_router_version.empty())
|
2020-02-19 21:23:46 +01:00
|
|
|
return false;
|
2023-10-31 21:49:01 +01:00
|
|
|
return _addr.is_addressable();
|
2018-08-31 14:46:54 +02:00
|
|
|
}
|
|
|
|
|
2018-12-19 17:17:41 +01:00
|
|
|
bool
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::is_expired(llarp_time_t now) const
|
2019-07-15 18:56:09 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
return age(now) >= _timestamp.time_since_epoch() + LIFETIME;
|
2019-07-15 18:56:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
llarp_time_t
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::time_to_expiry(llarp_time_t now) const
|
2018-12-19 17:17:41 +01:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
const auto expiry = _timestamp.time_since_epoch() + LIFETIME;
|
|
|
|
return now < expiry ? expiry - now : 0s;
|
2019-07-15 18:56:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
llarp_time_t
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::age(llarp_time_t now) const
|
2018-08-31 14:46:54 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
auto delta = now - _timestamp.time_since_epoch();
|
|
|
|
return delta > 0s ? delta : 0s;
|
2018-10-15 14:02:32 +02:00
|
|
|
}
|
|
|
|
|
2023-11-29 02:47:20 +01:00
|
|
|
bool
|
|
|
|
RouterContact::is_stale(llarp_time_t now) const
|
|
|
|
{
|
|
|
|
return age(now) >= _timestamp.time_since_epoch() + STALE_AGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RouterContact::is_outdated(llarp_time_t now) const
|
|
|
|
{
|
|
|
|
return age(now) >= _timestamp.time_since_epoch() + OUTDATED_AGE;
|
|
|
|
}
|
|
|
|
|
2018-08-31 14:46:54 +02:00
|
|
|
bool
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::expires_within_delta(llarp_time_t now, llarp_time_t dlt) const
|
2018-08-31 14:46:54 +02:00
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
return time_to_expiry(now) <= dlt;
|
2018-08-31 14:46:54 +02:00
|
|
|
}
|
|
|
|
|
2022-09-27 19:00:27 +02:00
|
|
|
static constexpr std::array obsolete_bootstraps = {
|
2022-11-18 21:00:12 +01:00
|
|
|
"7a16ac0b85290bcf69b2f3b52456d7e989ac8913b4afbb980614e249a3723218"sv,
|
|
|
|
"e6b3a6fe5e32c379b64212c72232d65b0b88ddf9bbaed4997409d329f8519e0b"sv,
|
|
|
|
};
|
2022-09-27 19:00:27 +02:00
|
|
|
|
|
|
|
bool
|
2023-10-31 21:49:01 +01:00
|
|
|
RouterContact::is_obsolete_bootstrap() const
|
2022-09-27 19:00:27 +02:00
|
|
|
{
|
|
|
|
for (const auto& k : obsolete_bootstraps)
|
|
|
|
{
|
2023-10-31 21:49:01 +01:00
|
|
|
if (_router_id.ToHex() == k)
|
2022-09-27 19:00:27 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-30 20:48:43 +02:00
|
|
|
} // namespace llarp
|