mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
testnet prep
- redoing link_manager functions again to implement previously ignored review comments on several PRs - conceptually merging "whitelist_routers" and new "known_{rids,rcs}", s.t. we can completely eliminate white/red/gray/green/etc lists in favor of something that isn't dumb
This commit is contained in:
parent
c9268dceba
commit
ed6bd28a35
17 changed files with 144 additions and 173 deletions
|
@ -61,8 +61,8 @@ namespace llarp
|
||||||
"netid",
|
"netid",
|
||||||
Default{llarp::LOKINET_DEFAULT_NETID},
|
Default{llarp::LOKINET_DEFAULT_NETID},
|
||||||
Comment{
|
Comment{
|
||||||
"Network ID; this is '"s + llarp::LOKINET_DEFAULT_NETID + "' for mainnet, "s
|
"Network ID; this is '"s + llarp::LOKINET_DEFAULT_NETID + "' for mainnet, '"s
|
||||||
+ llarp::LOKINET_TESTNET_NETID + "for testnet."s,
|
+ llarp::LOKINET_TESTNET_NETID + "' for testnet."s,
|
||||||
},
|
},
|
||||||
[this](std::string arg) {
|
[this](std::string arg) {
|
||||||
if (arg.size() > NETID_SIZE)
|
if (arg.size() > NETID_SIZE)
|
||||||
|
@ -290,7 +290,7 @@ namespace llarp
|
||||||
MultiValue,
|
MultiValue,
|
||||||
[this](std::string value) {
|
[this](std::string value) {
|
||||||
RouterID router;
|
RouterID router;
|
||||||
if (not router.FromString(value))
|
if (not router.from_string(value))
|
||||||
throw std::invalid_argument{"bad snode value: " + value};
|
throw std::invalid_argument{"bad snode value: " + value};
|
||||||
if (not strict_connect.insert(router).second)
|
if (not strict_connect.insert(router).second)
|
||||||
throw std::invalid_argument{"duplicate strict connect snode: " + value};
|
throw std::invalid_argument{"duplicate strict connect snode: " + value};
|
||||||
|
@ -710,7 +710,7 @@ namespace llarp
|
||||||
},
|
},
|
||||||
[this](std::string arg) {
|
[this](std::string arg) {
|
||||||
RouterID id;
|
RouterID id;
|
||||||
if (not id.FromString(arg))
|
if (not id.from_string(arg))
|
||||||
throw std::invalid_argument{fmt::format("Invalid RouterID: {}", arg)};
|
throw std::invalid_argument{fmt::format("Invalid RouterID: {}", arg)};
|
||||||
|
|
||||||
auto itr = snode_blacklist.emplace(std::move(id));
|
auto itr = snode_blacklist.emplace(std::move(id));
|
||||||
|
@ -923,6 +923,7 @@ namespace llarp
|
||||||
SockAddr pubaddr{arg};
|
SockAddr pubaddr{arg};
|
||||||
public_addr = pubaddr.getIP();
|
public_addr = pubaddr.getIP();
|
||||||
});
|
});
|
||||||
|
|
||||||
conf.define_option<uint16_t>(
|
conf.define_option<uint16_t>(
|
||||||
"bind",
|
"bind",
|
||||||
"public-port",
|
"public-port",
|
||||||
|
@ -980,10 +981,7 @@ namespace llarp
|
||||||
conf.define_option<std::string>(
|
conf.define_option<std::string>(
|
||||||
"bind",
|
"bind",
|
||||||
"listen",
|
"listen",
|
||||||
Required,
|
|
||||||
Comment{
|
Comment{
|
||||||
"********** NEW API OPTION (see note) **********",
|
|
||||||
"",
|
|
||||||
"IP and/or port for lokinet to bind to for inbound/outbound connections.",
|
"IP and/or port for lokinet to bind to for inbound/outbound connections.",
|
||||||
"",
|
"",
|
||||||
"If IP is omitted then lokinet will search for a local network interface with a",
|
"If IP is omitted then lokinet will search for a local network interface with a",
|
||||||
|
@ -1009,7 +1007,7 @@ namespace llarp
|
||||||
if (auto a = parse_addr_for_link(arg); a and a->is_addressable())
|
if (auto a = parse_addr_for_link(arg); a and a->is_addressable())
|
||||||
addr = *a;
|
addr = *a;
|
||||||
else
|
else
|
||||||
addr = oxen::quic::Address{""s, DEFAULT_LISTEN_PORT};
|
throw std::invalid_argument{"Could not parse listen address!"};
|
||||||
|
|
||||||
using_new_api = true;
|
using_new_api = true;
|
||||||
});
|
});
|
||||||
|
@ -1020,86 +1018,25 @@ namespace llarp
|
||||||
RelayOnly,
|
RelayOnly,
|
||||||
MultiValue,
|
MultiValue,
|
||||||
Hidden,
|
Hidden,
|
||||||
Comment{
|
|
||||||
"********** THIS PARAMETER IS DEPRECATED -- USE 'LISTEN' INSTEAD **********",
|
|
||||||
"",
|
|
||||||
"Note: the new API dictates the lokinet bind address through the 'listen' config",
|
|
||||||
"parameter. Only ONE address will be read (no more lists of inbounds). Any address",
|
|
||||||
"passed to `listen` will supersede the",
|
|
||||||
"",
|
|
||||||
"IP and/or port to listen on for incoming connections.",
|
|
||||||
"",
|
|
||||||
"If IP is omitted then lokinet will search for a local network interface with a",
|
|
||||||
"public IP address and use that IP (and will exit with an error if no such IP is found",
|
|
||||||
"on the system). If port is omitted then lokinet defaults to 1090.",
|
|
||||||
"",
|
|
||||||
"Examples:",
|
|
||||||
" inbound=15.5.29.5:443",
|
|
||||||
" inbound=10.0.2.2",
|
|
||||||
" inbound=:1234",
|
|
||||||
"",
|
|
||||||
"Using a private range IP address (like the second example entry) will require using",
|
|
||||||
"the public-ip= and public-port= to specify the public IP address at which this",
|
|
||||||
"router can be reached.",
|
|
||||||
},
|
|
||||||
[this, parse_addr_for_link](const std::string& arg) {
|
[this, parse_addr_for_link](const std::string& arg) {
|
||||||
if (using_new_api)
|
if (using_new_api)
|
||||||
throw std::runtime_error{"USE THE NEW API -- SPECIFY LOCAL ADDRESS UNDER [LISTEN]"};
|
throw std::runtime_error{"USE THE NEW API -- SPECIFY LOCAL ADDRESS UNDER [LISTEN]"};
|
||||||
|
|
||||||
if (auto a = parse_addr_for_link(arg); a and a->is_addressable())
|
if (auto a = parse_addr_for_link(arg); a and a->is_addressable())
|
||||||
addr = *a;
|
addr = *a;
|
||||||
else
|
|
||||||
addr = oxen::quic::Address{""s, DEFAULT_LISTEN_PORT};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
conf.define_option<std::string>(
|
conf.define_option<std::string>(
|
||||||
"bind",
|
"bind",
|
||||||
"outbound",
|
"outbound",
|
||||||
MultiValue,
|
MultiValue,
|
||||||
params.is_relay ? Comment{
|
Hidden,
|
||||||
"********** THIS PARAMETER IS DEPRECATED -- USE 'LISTEN' INSTEAD **********",
|
|
||||||
"",
|
|
||||||
"IP and/or port to use for outbound socket connections to other lokinet routers.",
|
|
||||||
"",
|
|
||||||
"If no outbound bind IP is configured, or the 0.0.0.0 wildcard IP is given, then",
|
|
||||||
"lokinet will bind to the same IP being used for inbound connections (either an",
|
|
||||||
"explicit inbound= provided IP, or the default). If no port is given, or port is",
|
|
||||||
"given as 0, then a random high port will be used.",
|
|
||||||
"",
|
|
||||||
"If using multiple inbound= addresses then you *must* provide an explicit oubound= IP.",
|
|
||||||
"",
|
|
||||||
"Examples:",
|
|
||||||
" outbound=1.2.3.4:5678",
|
|
||||||
" outbound=:9000",
|
|
||||||
" outbound=8.9.10.11",
|
|
||||||
"",
|
|
||||||
"The second example binds on the default incoming IP using port 9000; the third",
|
|
||||||
"example binds on the given IP address using a random high port.",
|
|
||||||
} : Comment{
|
|
||||||
"********** DEPRECATED **********",
|
|
||||||
"",
|
|
||||||
"IP and/or port to use for outbound socket connections to lokinet routers.",
|
|
||||||
"",
|
|
||||||
"If no outbound bind IP is configured then lokinet will use a wildcard IP address",
|
|
||||||
"(equivalent to specifying 0.0.0.0). If no port is given then a random high port",
|
|
||||||
"will be used.",
|
|
||||||
"",
|
|
||||||
"Examples:",
|
|
||||||
" outbound=1.2.3.4:5678",
|
|
||||||
" outbound=:9000",
|
|
||||||
" outbound=8.9.10.11",
|
|
||||||
"",
|
|
||||||
"The second example binds on the wildcard address using port 9000; the third example",
|
|
||||||
"binds on the given IP address using a random high port.",
|
|
||||||
},
|
|
||||||
[this, parse_addr_for_link](const std::string& arg) {
|
[this, parse_addr_for_link](const std::string& arg) {
|
||||||
if (using_new_api)
|
if (using_new_api)
|
||||||
throw std::runtime_error{"USE THE NEW API -- SPECIFY LOCAL ADDRESS UNDER [LISTEN]"};
|
throw std::runtime_error{"USE THE NEW API -- SPECIFY LOCAL ADDRESS UNDER [LISTEN]"};
|
||||||
|
|
||||||
if (auto a = parse_addr_for_link(arg); a and a->is_addressable())
|
if (auto a = parse_addr_for_link(arg); a and a->is_addressable())
|
||||||
addr = *a;
|
addr = *a;
|
||||||
else
|
|
||||||
addr = oxen::quic::Address{""s, DEFAULT_LISTEN_PORT};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
conf.add_undeclared_handler(
|
conf.add_undeclared_handler(
|
||||||
|
@ -1250,7 +1187,7 @@ namespace llarp
|
||||||
[this](std::string arg) { rpc_addr = oxenmq::address(arg); });
|
[this](std::string arg) { rpc_addr = oxenmq::address(arg); });
|
||||||
|
|
||||||
// Deprecated options:
|
// Deprecated options:
|
||||||
conf.define_option<std::string>("lokid", "jsonrpc", RelayOnly, Deprecated, [](std::string arg) {
|
conf.define_option<std::string>("lokid", "jsonrpc", RelayOnly, Hidden, [](std::string arg) {
|
||||||
if (arg.empty())
|
if (arg.empty())
|
||||||
return;
|
return;
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace llarp
|
||||||
std::optional<net::ipaddr_t> public_addr;
|
std::optional<net::ipaddr_t> public_addr;
|
||||||
std::optional<net::port_t> public_port;
|
std::optional<net::port_t> public_port;
|
||||||
|
|
||||||
oxen::quic::Address addr;
|
oxen::quic::Address addr{""s, DEFAULT_LISTEN_PORT};
|
||||||
bool using_new_api = false;
|
bool using_new_api = false;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -82,29 +82,34 @@ namespace llarp::consensus
|
||||||
|
|
||||||
// Pull the next element off the queue, but skip ourself, any that are no longer registered, and
|
// Pull the next element off the queue, but skip ourself, any that are no longer registered, and
|
||||||
// any that are currently known to be failing (those are queued for testing separately).
|
// any that are currently known to be failing (those are queued for testing separately).
|
||||||
RouterID my_pk{router->pubkey()};
|
auto local_pk = router->local_rid();
|
||||||
|
|
||||||
while (!testing_queue.empty())
|
while (!testing_queue.empty())
|
||||||
{
|
{
|
||||||
auto& pk = testing_queue.back();
|
auto& pk = testing_queue.back();
|
||||||
std::optional<RouterID> sn;
|
std::optional<RouterID> sn;
|
||||||
if (pk != my_pk && !failing.count(pk))
|
|
||||||
|
if (pk != local_pk && !failing.count(pk))
|
||||||
sn = pk;
|
sn = pk;
|
||||||
|
|
||||||
testing_queue.pop_back();
|
testing_queue.pop_back();
|
||||||
|
|
||||||
if (sn)
|
if (sn)
|
||||||
return sn;
|
return sn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!requeue)
|
if (!requeue)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
// FIXME: when a *new* node comes online we need to inject it into a random position in the SN
|
// FIXME: when a *new* node comes online we need to inject it into a random position in the SN
|
||||||
// list with probability (L/N) [L = current list size, N = potential list size]
|
// list with probability (L/N) [L = current list size, N = potential list size]
|
||||||
//
|
//
|
||||||
// (FIXME: put this FIXME in a better place ;-) )
|
|
||||||
|
|
||||||
// We exhausted the queue so repopulate it and try again
|
// We exhausted the queue so repopulate it and try again
|
||||||
|
|
||||||
testing_queue.clear();
|
testing_queue.clear();
|
||||||
const auto all = router->get_whitelist();
|
const auto& all = router->get_whitelist();
|
||||||
|
|
||||||
testing_queue.insert(testing_queue.begin(), all.begin(), all.end());
|
testing_queue.insert(testing_queue.begin(), all.begin(), all.end());
|
||||||
|
|
||||||
std::shuffle(testing_queue.begin(), testing_queue.end(), llarp::csrng);
|
std::shuffle(testing_queue.begin(), testing_queue.end(), llarp::csrng);
|
||||||
|
|
|
@ -281,7 +281,7 @@ namespace llarp::handlers
|
||||||
}
|
}
|
||||||
// forward dns for snode
|
// forward dns for snode
|
||||||
RouterID r;
|
RouterID r;
|
||||||
if (r.FromString(msg.questions[0].Name()))
|
if (r.from_string(msg.questions[0].Name()))
|
||||||
{
|
{
|
||||||
huint128_t ip;
|
huint128_t ip;
|
||||||
PubKey pubKey(r);
|
PubKey pubKey(r);
|
||||||
|
|
|
@ -535,7 +535,7 @@ namespace llarp::handlers
|
||||||
if (auto saddr = service::Address(); saddr.FromString(name))
|
if (auto saddr = service::Address(); saddr.FromString(name))
|
||||||
ReplyToLokiDNSWhenReady(saddr, msg, isV6);
|
ReplyToLokiDNSWhenReady(saddr, msg, isV6);
|
||||||
|
|
||||||
if (auto rid = RouterID(); rid.FromString(name))
|
if (auto rid = RouterID(); rid.from_string(name))
|
||||||
ReplyToSNodeDNSWhenReady(rid, msg, isV6);
|
ReplyToSNodeDNSWhenReady(rid, msg, isV6);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ namespace llarp::handlers
|
||||||
if (not qname)
|
if (not qname)
|
||||||
return false;
|
return false;
|
||||||
RouterID addr;
|
RouterID addr;
|
||||||
if (not addr.FromString(*qname))
|
if (not addr.from_string(*qname))
|
||||||
return false;
|
return false;
|
||||||
auto replyMsg = std::make_shared<dns::Message>(clear_dns_message(msg));
|
auto replyMsg = std::make_shared<dns::Message>(clear_dns_message(msg));
|
||||||
return ReplyToSNodeDNSWhenReady(addr, std::move(replyMsg), false);
|
return ReplyToSNodeDNSWhenReady(addr, std::move(replyMsg), false);
|
||||||
|
@ -604,7 +604,7 @@ namespace llarp::handlers
|
||||||
if (msg.questions[0].qtype == dns::qTypeTXT)
|
if (msg.questions[0].qtype == dns::qTypeTXT)
|
||||||
{
|
{
|
||||||
RouterID snode;
|
RouterID snode;
|
||||||
if (snode.FromString(qname))
|
if (snode.from_string(qname))
|
||||||
{
|
{
|
||||||
if (auto rc = router()->node_db()->get_rc(snode))
|
if (auto rc = router()->node_db()->get_rc(snode))
|
||||||
msg.AddTXTReply(std::string{rc->view()});
|
msg.AddTXTReply(std::string{rc->view()});
|
||||||
|
|
|
@ -622,18 +622,17 @@ namespace llarp
|
||||||
// this handler should not be registered for clients
|
// this handler should not be registered for clients
|
||||||
assert(_router.is_service_node());
|
assert(_router.is_service_node());
|
||||||
|
|
||||||
const auto& rcs = node_db->get_rcs();
|
std::set<RouterID> explicit_ids;
|
||||||
const auto now = time_point_now();
|
|
||||||
|
|
||||||
std::vector<std::string> explicit_ids;
|
|
||||||
rc_time since_time;
|
rc_time since_time;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
oxenc::bt_dict_consumer btdc{m.body()};
|
oxenc::bt_dict_consumer btdc{m.body()};
|
||||||
|
|
||||||
btdc.required("explicit_ids");
|
auto btlc = btdc.require<oxenc::bt_list_consumer>("explicit_ids");
|
||||||
explicit_ids = btdc.consume_list<std::vector<std::string>>();
|
|
||||||
|
while (not btlc.is_finished())
|
||||||
|
explicit_ids.emplace(btlc.consume<ustring_view>().data());
|
||||||
|
|
||||||
since_time = rc_time{std::chrono::seconds{btdc.require<int64_t>("since")}};
|
since_time = rc_time{std::chrono::seconds{btdc.require<int64_t>("since")}};
|
||||||
}
|
}
|
||||||
|
@ -644,24 +643,8 @@ namespace llarp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial fetch: give me all the RC's
|
const auto& rcs = node_db->get_rcs();
|
||||||
if (explicit_ids.empty())
|
const auto now = time_point_now();
|
||||||
{
|
|
||||||
// TODO: this
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_set<RouterID> explicit_relays;
|
|
||||||
|
|
||||||
for (auto& sv : explicit_ids)
|
|
||||||
{
|
|
||||||
if (sv.size() != RouterID::SIZE)
|
|
||||||
{
|
|
||||||
m.respond(RCFetchMessage::INVALID_REQUEST, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit_relays.emplace(reinterpret_cast<const byte_t*>(sv.data()));
|
|
||||||
}
|
|
||||||
|
|
||||||
oxenc::bt_dict_producer btdp;
|
oxenc::bt_dict_producer btdp;
|
||||||
const auto& last_time = node_db->get_last_rc_update_times();
|
const auto& last_time = node_db->get_last_rc_update_times();
|
||||||
|
@ -673,10 +656,22 @@ namespace llarp
|
||||||
if (since_time != decltype(since_time)::min())
|
if (since_time != decltype(since_time)::min())
|
||||||
since_time -= 5s;
|
since_time -= 5s;
|
||||||
|
|
||||||
for (const auto& rc : rcs)
|
// Initial fetch: give me all the RC's
|
||||||
|
if (explicit_ids.empty())
|
||||||
{
|
{
|
||||||
if (last_time.at(rc.router_id()) > since_time or explicit_relays.count(rc.router_id()))
|
for (const auto& rc : rcs)
|
||||||
sublist.append_encoded(rc.view());
|
{
|
||||||
|
if (last_time.at(rc.router_id()) > since_time)
|
||||||
|
sublist.append_encoded(rc.view());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& rid : explicit_ids)
|
||||||
|
{
|
||||||
|
if (auto maybe_rc = node_db->get_rc_by_rid(rid))
|
||||||
|
sublist.append_encoded(maybe_rc->view());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,56 +690,57 @@ namespace llarp
|
||||||
void
|
void
|
||||||
LinkManager::handle_fetch_router_ids(oxen::quic::message m)
|
LinkManager::handle_fetch_router_ids(oxen::quic::message m)
|
||||||
{
|
{
|
||||||
|
RouterID source;
|
||||||
|
RouterID local = router().local_rid();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
oxenc::bt_dict_consumer btdc{m.body()};
|
oxenc::bt_dict_consumer btdc{m.body()};
|
||||||
|
|
||||||
auto source = btdc.require<std::string_view>("source");
|
source.from_string(btdc.require<std::string_view>("source"));
|
||||||
|
|
||||||
// if bad request, silently fail
|
|
||||||
if (source.size() != RouterID::SIZE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto source_rid = RouterID{reinterpret_cast<const byte_t*>(source.data())};
|
|
||||||
const auto our_rid = RouterID{router().pubkey()};
|
|
||||||
|
|
||||||
if (source_rid == our_rid)
|
|
||||||
{
|
|
||||||
oxenc::bt_dict_producer btdp;
|
|
||||||
{
|
|
||||||
auto btlp = btdp.append_list("routers");
|
|
||||||
for (const auto& relay : node_db->whitelist())
|
|
||||||
{
|
|
||||||
btlp.append(relay.ToView());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
btdp.append_signature("signature", [this](ustring_view to_sign) {
|
|
||||||
std::array<unsigned char, 64> sig;
|
|
||||||
|
|
||||||
if (!crypto::sign(const_cast<unsigned char*>(sig.data()), _router.identity(), to_sign))
|
|
||||||
throw std::runtime_error{"Failed to sign fetch RouterIDs response"};
|
|
||||||
|
|
||||||
return sig;
|
|
||||||
});
|
|
||||||
m.respond(std::move(btdp).str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_control_message(
|
|
||||||
source_rid,
|
|
||||||
"fetch_router_ids"s,
|
|
||||||
m.body_str(),
|
|
||||||
[source_rid = std::move(source_rid),
|
|
||||||
orig_mess = std::move(m)](oxen::quic::message m) mutable {
|
|
||||||
if (not m.timed_out)
|
|
||||||
orig_mess.respond(m.body_str(), not m);
|
|
||||||
// on timeout, just silently drop (as original requester will just time out anyway)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
log::info(link_cat, "Error fulfilling fetch RouterIDs request: {}", e.what());
|
log::info(link_cat, "Error fulfilling fetch RouterIDs request: {}", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if bad request, silently fail
|
||||||
|
if (source.size() != RouterID::SIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (source != local)
|
||||||
|
{
|
||||||
|
send_control_message(
|
||||||
|
source,
|
||||||
|
"fetch_router_ids"s,
|
||||||
|
m.body_str(),
|
||||||
|
[source_rid = std::move(source), original = std::move(m)](oxen::quic::message m) mutable {
|
||||||
|
original.respond(m.body_str(), not m);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
oxenc::bt_dict_producer btdp;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto btlp = btdp.append_list("routers");
|
||||||
|
|
||||||
|
const auto& known_rcs = node_db->get_known_rcs();
|
||||||
|
|
||||||
|
for (const auto& rc : known_rcs)
|
||||||
|
btlp.append_encoded(rc.view());
|
||||||
|
}
|
||||||
|
|
||||||
|
btdp.append_signature("signature", [this](ustring_view to_sign) {
|
||||||
|
std::array<unsigned char, 64> sig;
|
||||||
|
|
||||||
|
if (!crypto::sign(const_cast<unsigned char*>(sig.data()), _router.identity(), to_sign))
|
||||||
|
throw std::runtime_error{"Failed to sign fetch RouterIDs response"};
|
||||||
|
|
||||||
|
return sig;
|
||||||
|
});
|
||||||
|
|
||||||
|
m.respond(std::move(btdp).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
namespace llarp
|
namespace llarp
|
||||||
{
|
{
|
||||||
namespace RCFetchMessage
|
namespace FetchRCMessage
|
||||||
{
|
{
|
||||||
inline const auto INVALID_REQUEST =
|
inline const auto INVALID_REQUEST =
|
||||||
messages::serialize_response({{messages::STATUS_KEY, "Invalid relay ID requested"}});
|
messages::serialize_response({{messages::STATUS_KEY, "Invalid relay ID requested"}});
|
||||||
|
@ -33,7 +33,7 @@ namespace llarp
|
||||||
|
|
||||||
return std::move(btdp).str();
|
return std::move(btdp).str();
|
||||||
}
|
}
|
||||||
} // namespace RCFetchMessage
|
} // namespace FetchRCMessage
|
||||||
|
|
||||||
namespace BootstrapFetchMessage
|
namespace BootstrapFetchMessage
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,6 +56,15 @@ namespace llarp
|
||||||
fetch_counters.clear();
|
fetch_counters.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<RemoteRC>
|
||||||
|
NodeDB::get_rc_by_rid(const RouterID& rid)
|
||||||
|
{
|
||||||
|
if (auto itr = rc_lookup.find(rid); itr != rc_lookup.end())
|
||||||
|
return itr->second;
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<RemoteRC>
|
std::optional<RemoteRC>
|
||||||
NodeDB::get_random_rc() const
|
NodeDB::get_random_rc() const
|
||||||
{
|
{
|
||||||
|
@ -178,7 +187,8 @@ namespace llarp
|
||||||
{
|
{
|
||||||
if (not _router.is_service_node())
|
if (not _router.is_service_node())
|
||||||
return true;
|
return true;
|
||||||
return registered_routers.count(rid);
|
|
||||||
|
return known_rids.count(rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -358,6 +368,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RouterID> needed;
|
std::vector<RouterID> needed;
|
||||||
|
|
||||||
const auto now = time_point_now();
|
const auto now = time_point_now();
|
||||||
|
|
||||||
for (const auto& [rid, rc] : rc_lookup)
|
for (const auto& [rid, rc] : rc_lookup)
|
||||||
|
@ -370,7 +381,7 @@ namespace llarp
|
||||||
|
|
||||||
_router.link_manager().fetch_rcs(
|
_router.link_manager().fetch_rcs(
|
||||||
src,
|
src,
|
||||||
RCFetchMessage::serialize(_router.last_rc_fetch, needed),
|
FetchRCMessage::serialize(_router.last_rc_fetch, needed),
|
||||||
[this, src, initial](oxen::quic::message m) mutable {
|
[this, src, initial](oxen::quic::message m) mutable {
|
||||||
if (m.timed_out)
|
if (m.timed_out)
|
||||||
{
|
{
|
||||||
|
@ -730,6 +741,7 @@ namespace llarp
|
||||||
replace_subset(rid_sources, specific, known_rids, RID_SOURCE_COUNT, csrng);
|
replace_subset(rid_sources, specific, known_rids, RID_SOURCE_COUNT, csrng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: nuke all this shit
|
||||||
void
|
void
|
||||||
NodeDB::set_router_whitelist(
|
NodeDB::set_router_whitelist(
|
||||||
const std::vector<RouterID>& whitelist,
|
const std::vector<RouterID>& whitelist,
|
||||||
|
@ -744,6 +756,9 @@ namespace llarp
|
||||||
registered_routers.insert(greylist.begin(), greylist.end());
|
registered_routers.insert(greylist.begin(), greylist.end());
|
||||||
registered_routers.insert(greenlist.begin(), greenlist.end());
|
registered_routers.insert(greenlist.begin(), greenlist.end());
|
||||||
|
|
||||||
|
for (const auto& rid : whitelist)
|
||||||
|
known_rids.insert(rid);
|
||||||
|
|
||||||
router_whitelist.clear();
|
router_whitelist.clear();
|
||||||
router_whitelist.insert(whitelist.begin(), whitelist.end());
|
router_whitelist.insert(whitelist.begin(), whitelist.end());
|
||||||
router_greylist.clear();
|
router_greylist.clear();
|
||||||
|
@ -752,19 +767,16 @@ namespace llarp
|
||||||
router_greenlist.insert(greenlist.begin(), greenlist.end());
|
router_greenlist.insert(greenlist.begin(), greenlist.end());
|
||||||
|
|
||||||
log::info(
|
log::info(
|
||||||
logcat, "lokinet service node list now has ", router_whitelist.size(), " active routers");
|
logcat, "lokinet service node list now has ", known_rids.size(), " active router RIDs");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<RouterID>
|
std::optional<RouterID>
|
||||||
NodeDB::get_random_whitelist_router() const
|
NodeDB::get_random_whitelist_router() const
|
||||||
{
|
{
|
||||||
const auto sz = router_whitelist.size();
|
if (auto rc = get_random_rc())
|
||||||
if (sz == 0)
|
return rc->router_id();
|
||||||
return std::nullopt;
|
|
||||||
auto itr = router_whitelist.begin();
|
return std::nullopt;
|
||||||
if (sz > 1)
|
|
||||||
std::advance(itr, randint() % sz);
|
|
||||||
return *itr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -777,7 +789,7 @@ namespace llarp
|
||||||
if (not _router.is_service_node())
|
if (not _router.is_service_node())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return router_whitelist.count(remote) or router_greylist.count(remote);
|
return known_rids.count(remote) or router_greylist.count(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace llarp
|
||||||
|
|
||||||
std::map<RouterID, const RemoteRC&> rc_lookup;
|
std::map<RouterID, const RemoteRC&> rc_lookup;
|
||||||
|
|
||||||
/** RouterID lists
|
/** RouterID lists // TODO: get rid of all these, replace with better decom/not staked sets
|
||||||
- white: active routers
|
- white: active routers
|
||||||
- gray: fully funded, but decommissioned routers
|
- gray: fully funded, but decommissioned routers
|
||||||
- green: registered, but not fully-staked routers
|
- green: registered, but not fully-staked routers
|
||||||
|
@ -187,6 +187,21 @@ namespace llarp
|
||||||
/// in memory nodedb
|
/// in memory nodedb
|
||||||
NodeDB();
|
NodeDB();
|
||||||
|
|
||||||
|
const std::set<RouterID>&
|
||||||
|
get_known_rids() const
|
||||||
|
{
|
||||||
|
return known_rids;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<RemoteRC>&
|
||||||
|
get_known_rcs() const
|
||||||
|
{
|
||||||
|
return known_rcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<RemoteRC>
|
||||||
|
get_rc_by_rid(const RouterID& rid);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
needs_initial_fetch() const
|
needs_initial_fetch() const
|
||||||
{
|
{
|
||||||
|
@ -270,7 +285,7 @@ namespace llarp
|
||||||
bool
|
bool
|
||||||
is_path_allowed(const RouterID& remote) const
|
is_path_allowed(const RouterID& remote) const
|
||||||
{
|
{
|
||||||
return router_whitelist.count(remote);
|
return known_rids.count(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if pinned edges were specified, the remote must be in that set, else any remote
|
// if pinned edges were specified, the remote must be in that set, else any remote
|
||||||
|
@ -293,10 +308,10 @@ namespace llarp
|
||||||
void
|
void
|
||||||
set_bootstrap_routers(std::unique_ptr<BootstrapList> from_router);
|
set_bootstrap_routers(std::unique_ptr<BootstrapList> from_router);
|
||||||
|
|
||||||
const std::unordered_set<RouterID>&
|
const std::set<RouterID>&
|
||||||
whitelist() const
|
whitelist() const
|
||||||
{
|
{
|
||||||
return router_whitelist;
|
return known_rids;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_set<RouterID>&
|
const std::unordered_set<RouterID>&
|
||||||
|
|
|
@ -1026,7 +1026,7 @@ namespace llarp
|
||||||
return _link_manager.get_random_connected(result);
|
return _link_manager.get_random_connected(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_set<RouterID>&
|
const std::set<RouterID>&
|
||||||
Router::get_whitelist() const
|
Router::get_whitelist() const
|
||||||
{
|
{
|
||||||
return _node_db->whitelist();
|
return _node_db->whitelist();
|
||||||
|
|
|
@ -155,6 +155,12 @@ namespace llarp
|
||||||
std::chrono::system_clock::time_point next_bootstrap_attempt{last_rc_gossip};
|
std::chrono::system_clock::time_point next_bootstrap_attempt{last_rc_gossip};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
RouterID
|
||||||
|
local_rid() const
|
||||||
|
{
|
||||||
|
return RouterID{pubkey()};
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
needs_initial_fetch() const;
|
needs_initial_fetch() const;
|
||||||
|
|
||||||
|
@ -284,7 +290,7 @@ namespace llarp
|
||||||
util::StatusObject
|
util::StatusObject
|
||||||
ExtractSummaryStatus() const;
|
ExtractSummaryStatus() const;
|
||||||
|
|
||||||
const std::unordered_set<RouterID>&
|
const std::set<RouterID>&
|
||||||
get_whitelist() const;
|
get_whitelist() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace llarp
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RouterID::FromString(std::string_view str)
|
RouterID::from_string(std::string_view str)
|
||||||
{
|
{
|
||||||
auto pos = str.find(SNODE_TLD);
|
auto pos = str.find(SNODE_TLD);
|
||||||
if (pos != str.size() - SNODE_TLD.size())
|
if (pos != str.size() - SNODE_TLD.size())
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace llarp
|
||||||
ShortString() const;
|
ShortString() const;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FromString(std::string_view str);
|
from_string(std::string_view str);
|
||||||
|
|
||||||
RouterID&
|
RouterID&
|
||||||
operator=(const byte_t* ptr)
|
operator=(const byte_t* ptr)
|
||||||
|
@ -49,7 +49,6 @@ namespace llarp
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
constexpr inline bool IsToStringFormattable<RouterID> = true;
|
constexpr inline bool IsToStringFormattable<RouterID> = true;
|
||||||
|
|
||||||
} // namespace llarp
|
} // namespace llarp
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
|
|
|
@ -269,6 +269,7 @@ namespace llarp::rpc
|
||||||
keymap = std::move(keymap),
|
keymap = std::move(keymap),
|
||||||
router = std::move(router)]() mutable {
|
router = std::move(router)]() mutable {
|
||||||
m_KeyMap = std::move(keymap);
|
m_KeyMap = std::move(keymap);
|
||||||
|
|
||||||
router->set_router_whitelist(active, decomm, unfunded);
|
router->set_router_whitelist(active, decomm, unfunded);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,7 +322,7 @@ namespace llarp::rpc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not routerID.FromString(lookupsnode.request.routerID))
|
if (not routerID.from_string(lookupsnode.request.routerID))
|
||||||
{
|
{
|
||||||
SetJSONError("Invalid remote: " + lookupsnode.request.routerID, lookupsnode.response);
|
SetJSONError("Invalid remote: " + lookupsnode.request.routerID, lookupsnode.response);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace llarp::service
|
||||||
{
|
{
|
||||||
RouterID router{};
|
RouterID router{};
|
||||||
service::Address addr{};
|
service::Address addr{};
|
||||||
if (router.FromString(lokinet_addr))
|
if (router.from_string(lokinet_addr))
|
||||||
return router;
|
return router;
|
||||||
if (addr.FromString(lokinet_addr))
|
if (addr.FromString(lokinet_addr))
|
||||||
return addr;
|
return addr;
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace llarp::service
|
||||||
{
|
{
|
||||||
oxenc::bt_dict_consumer btdc{std::move(buf)};
|
oxenc::bt_dict_consumer btdc{std::move(buf)};
|
||||||
|
|
||||||
router.FromString(btdc.require<std::string>("k"));
|
router.from_string(btdc.require<std::string>("k"));
|
||||||
latency = std::chrono::milliseconds{btdc.require<uint64_t>("l")};
|
latency = std::chrono::milliseconds{btdc.require<uint64_t>("l")};
|
||||||
path_id.from_string(btdc.require<std::string>("p"));
|
path_id.from_string(btdc.require<std::string>("p"));
|
||||||
expiry = std::chrono::milliseconds{btdc.require<uint64_t>("x")};
|
expiry = std::chrono::milliseconds{btdc.require<uint64_t>("x")};
|
||||||
|
|
Loading…
Reference in a new issue