strict types for pubkey, secretkey and routerid

pull/120/head
Jeff Becker 6 years ago
parent eed62b2d7f
commit fad734a5ce
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -443,6 +443,7 @@ set(LIB_SRC
llarp/buffer.cpp
llarp/config.cpp
llarp/context.cpp
llarp/crypto.cpp
llarp/crypto_libsodium.cpp
llarp/dht.cpp
llarp/dns_rectypes.cpp
@ -467,6 +468,7 @@ set(LIB_SRC
llarp/relay_commit.cpp
llarp/relay_up_down.cpp
llarp/router_contact.cpp
llarp/router_id.cpp
llarp/router.cpp
llarp/rpc.cpp
llarp/service.cpp

@ -1,4 +1,3 @@
all: test
SIGN = gpg --sign --detach

@ -12,7 +12,26 @@ def jsonrpc(method, **args):
{'method': method, 'params': args, 'id': 0}), headers={'content-type': 'application/json'}).json()
def main():
def exit_sessions_main():
if len(sys.argv) == 2 and sys.argv[1] == 'config':
print("graph_title lokinet exit sessions")
print("graph_vlabel sessions")
print("graph_category network")
print("graph_info This graph shows the number of exit sessions on a lokinet exit")
print("lokinet.exit.sessions.info Number of exit sessions")
print("lokinet.exit.sessions.label sessions"))
else:
count = 0
try:
j = jsonrpc("llarp.admin.exit.list")
count = len(j['result'])
except:
pass
print("lokinet.exit.sessions {}".format(outbound))
def peers_main():
if len(sys.argv) == 2 and sys.argv[1] == 'config':
print("graph_title lokinet peers")
print("graph_vlabel peers")
@ -40,4 +59,9 @@ def main():
if __name__ == '__main__':
main()
if sys.argv[0] == 'lokinet-peers':
peers_main()
elif sys.argv[0] == 'lokinet-exit':
exit_sessions_main()
else:
print('please symlink this as `lokinet-peers` or `lokinet-exit` in munin plugins dir')

@ -5,6 +5,7 @@
#include <llarp/mem.h>
#include <llarp/threadpool.h>
#include <llarp/aligned.hpp>
#include <llarp/router_id.hpp>
namespace llarp
{
@ -19,13 +20,59 @@ namespace llarp
using SharedSecret = AlignedBuffer< SHAREDKEYSIZE >;
using KeyExchangeNonce = AlignedBuffer< 32 >;
using PubKey = AlignedBuffer< PUBKEYSIZE >;
using SecretKey = AlignedBuffer< SECKEYSIZE >;
using ShortHash = AlignedBuffer< SHORTHASHSIZE >;
using Signature = AlignedBuffer< SIGSIZE >;
using TunnelNonce = AlignedBuffer< TUNNONCESIZE >;
using SymmNonce = AlignedBuffer< NONCESIZE >;
using SymmKey = AlignedBuffer< 32 >;
struct PubKey final : public AlignedBuffer< PUBKEYSIZE >
{
PubKey() : AlignedBuffer< PUBKEYSIZE >(){};
PubKey(const byte_t* ptr) : AlignedBuffer< PUBKEYSIZE >(ptr){};
std::string
ToString() const;
bool
FromString(const std::string& str);
friend std::ostream&
operator<<(std::ostream& out, const PubKey& k)
{
return out << k.ToString();
}
operator RouterID() const
{
return RouterID(data());
}
PubKey&
operator=(const byte_t* ptr)
{
memcpy(data(), ptr, size());
return *this;
}
};
struct SecretKey final : public AlignedBuffer< SECKEYSIZE >
{
friend std::ostream&
operator<<(std::ostream& out, const SecretKey&)
{
// make sure we never print out secret keys
return out << "[secretkey]";
}
SecretKey&
operator=(const byte_t* ptr)
{
memcpy(data(), ptr, size());
return *this;
}
};
using ShortHash = AlignedBuffer< SHORTHASHSIZE >;
using Signature = AlignedBuffer< SIGSIZE >;
using TunnelNonce = AlignedBuffer< TUNNONCESIZE >;
using SymmNonce = AlignedBuffer< NONCESIZE >;
using SymmKey = AlignedBuffer< 32 >;
using PQCipherBlock = AlignedBuffer< PQ_CIPHERTEXTSIZE + 1 >;
using PQPubKey = AlignedBuffer< PQ_PUBKEYSIZE >;

@ -202,7 +202,7 @@ namespace llarp
/// send a dht message to peer, if keepalive is true then keep the session
/// with that peer alive for 10 seconds
void
DHTSendTo(const Key_t& peer, IMessage* msg, bool keepalive = true);
DHTSendTo(const byte_t* peer, IMessage* msg, bool keepalive = true);
/// get routers closest to target excluding requester
bool
@ -258,7 +258,7 @@ namespace llarp
Bucket< ISNode >* services = nullptr;
bool allowTransit = false;
const Key_t&
const byte_t*
OurKey() const
{
return ourKey;

@ -8,18 +8,19 @@ namespace llarp
{
struct FindRouterMessage : public IMessage
{
// inbound parsing
FindRouterMessage(const Key_t& from) : IMessage(from)
{
}
FindRouterMessage(const Key_t& from, const RouterID& target, uint64_t id)
: IMessage(from), K(target), txid(id)
// find by routerid
FindRouterMessage(uint64_t id, const RouterID& target)
: IMessage({}), K(target), txid(id)
{
}
// exploritory
FindRouterMessage(const Key_t& from, uint64_t id)
: IMessage(from), exploritory(true), txid(id)
FindRouterMessage(uint64_t id) : IMessage({}), exploritory(true), txid(id)
{
K.Randomize();
}

@ -24,7 +24,7 @@ namespace llarp
return llarp_ev_loop_time_now_ms(m_Loop);
}
bool
HasSessionTo(const PubKey& pk);
HasSessionTo(const byte_t* pk);
bool
HasSessionVia(const Addr& addr);
@ -80,13 +80,13 @@ namespace llarp
Name() const = 0;
void
CloseSessionTo(const PubKey& remote);
CloseSessionTo(const byte_t* remote);
void
KeepAliveSessionTo(const PubKey& remote);
KeepAliveSessionTo(const byte_t* remote);
bool
SendTo(const PubKey& remote, llarp_buffer_t buf);
SendTo(const byte_t* remote, llarp_buffer_t buf);
bool
GetOurAddressInfo(AddressInfo& addr) const;
@ -107,7 +107,7 @@ namespace llarp
EnsureKeys(const char* fpath);
void
MapAddr(const PubKey& pk, ILinkSession* s);
MapAddr(const byte_t* pk, ILinkSession* s);
virtual void
Tick(__attribute__((unused)) llarp_time_t now)
@ -146,8 +146,8 @@ namespace llarp
SecretKey m_SecretKey;
Mutex m_AuthedLinksMutex;
std::unordered_multimap< PubKey, std::unique_ptr< ILinkSession >,
PubKey::Hash >
std::unordered_multimap< RouterID, std::unique_ptr< ILinkSession >,
RouterID::Hash >
m_AuthedLinks;
Mutex m_PendingMutex;
std::list< std::unique_ptr< ILinkSession > > m_Pending;

@ -41,7 +41,7 @@ namespace llarp
std::function< bool(llarp_time_t) > TimedOut;
/// get remote public identity key
std::function< const PubKey &(void) > GetPubKey;
std::function< const byte_t *(void) > GetPubKey;
/// get remote address
std::function< const Addr &(void) > GetRemoteEndpoint;

@ -480,6 +480,9 @@ namespace llarp
RouterID
Endpoint() const;
PubKey
EndpointPubKey() const;
bool
IsEndpoint(const RouterID& router, const PathID_t& path) const;
@ -595,7 +598,7 @@ namespace llarp
const std::array< EncryptedFrame, 8 >& frames);
bool
HopIsUs(const PubKey& k) const;
HopIsUs(const RouterID& k) const;
bool
HandleLRUM(const RelayUpstreamMessage* msg);

@ -5,7 +5,37 @@
namespace llarp
{
using RouterID = AlignedBuffer< 32 >;
}
struct RouterID : public AlignedBuffer< 32 >
{
RouterID() : AlignedBuffer< 32 >()
{
}
RouterID(const byte_t* buf) : AlignedBuffer< 32 >(buf)
{
}
std::string
ToString() const;
bool
FromString(const std::string& str);
RouterID&
operator=(const byte_t* ptr)
{
memcpy(data(), ptr, 32);
return *this;
}
friend std::ostream&
operator<<(std::ostream& out, const RouterID& id)
{
return out << id.ToString();
}
using Hash = AlignedBuffer< 32 >::Hash;
};
} // namespace llarp
#endif

@ -0,0 +1,17 @@
#include <llarp/crypto.hpp>
namespace llarp
{
bool
PubKey::FromString(const std::string& str)
{
return HexDecode(str.c_str(), data(), size());
}
std::string
PubKey::ToString() const
{
char buf[(PUBKEYSIZE + 1) * 2] = {0};
return HexEncode(*this, buf);
}
} // namespace llarp

@ -56,8 +56,7 @@ namespace llarp
void
Start(const TXOwner &peer) override
{
parent->DHTSendTo(peer.node,
new FindRouterMessage(parent->OurKey(), peer.txid));
parent->DHTSendTo(peer.node, new FindRouterMessage(peer.txid));
}
bool
@ -92,8 +91,8 @@ namespace llarp
uint64_t txid = ++ids;
TXOwner peer(askpeer, txid);
TXOwner whoasked(OurKey(), txid);
pendingExploreLookups.NewTX(peer, whoasked, askpeer,
new ExploreNetworkJob(askpeer, this));
pendingExploreLookups.NewTX(peer, whoasked, askpeer.data(),
new ExploreNetworkJob(askpeer.data(), this));
}
void
@ -212,7 +211,7 @@ namespace llarp
if((next ^ target) < (ourKey ^ target))
{
// yes it is closer, ask neighboor recursively
LookupRouterRecursive(target, requester, txid, next);
LookupRouterRecursive(target.data(), requester, txid, next);
}
else
{
@ -282,7 +281,7 @@ namespace llarp
}
void
Context::DHTSendTo(const Key_t &peer, IMessage *msg, bool keepalive)
Context::DHTSendTo(const byte_t *peer, IMessage *msg, bool keepalive)
{
llarp::DHTImmeidateMessage m;
m.msgs.emplace_back(msg);
@ -722,9 +721,7 @@ namespace llarp
void
Start(const TXOwner &peer) override
{
parent->DHTSendTo(
peer.node,
new FindRouterMessage(parent->OurKey(), target, peer.txid));
parent->DHTSendTo(peer.node, new FindRouterMessage(peer.txid, target));
}
virtual void

@ -11,8 +11,7 @@ namespace llarp
DHTImmeidateMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
{
if(llarp_buffer_eq(key, "m"))
return llarp::dht::DecodeMesssageList(session->GetPubKey().data(), buf,
msgs);
return llarp::dht::DecodeMesssageList(session->GetPubKey(), buf, msgs);
if(llarp_buffer_eq(key, "v"))
{
if(!bencode_read_integer(buf, &version))

@ -130,8 +130,8 @@ namespace llarp
}
else
{
const auto& us = dht.OurKey();
auto target = S.ToKey();
Key_t us = dht.OurKey();
Key_t target = S.data();
// we are recursive
if(dht.nodes->FindCloseExcluding(target, peer, exclude))
{

@ -16,7 +16,8 @@ namespace llarp
{
auto &dht = ctx->impl;
/// lookup for us, send an immeidate reply
if(K == dht.OurKey())
Key_t us = dht.OurKey();
if(K == us)
{
auto path = dht.router->paths.GetByUpstream(K, pathID);
if(path)

@ -99,7 +99,7 @@ namespace llarp
dht.pendingExploreLookups.NotFound(owner, K);
else
{
dht.pendingExploreLookups.Found(owner, From, N);
dht.pendingExploreLookups.Found(owner, From.data(), N);
}
return true;
}

@ -52,7 +52,8 @@ namespace llarp
if(k == "exit-node")
{
llarp::RouterID exitRouter;
if(!HexDecode(v.c_str(), exitRouter, exitRouter.size()))
if(!(exitRouter.FromString(v)
|| HexDecode(v.c_str(), exitRouter, exitRouter.size())))
{
llarp::LogError(Name(), " bad exit router key: ", v);
return false;

@ -8,7 +8,7 @@ namespace llarp
}
bool
ILinkLayer::HasSessionTo(const PubKey& pk)
ILinkLayer::HasSessionTo(const byte_t* pk)
{
Lock l(m_AuthedLinksMutex);
return m_AuthedLinks.find(pk) != m_AuthedLinks.end();
@ -84,7 +84,7 @@ namespace llarp
}
void
ILinkLayer::MapAddr(const PubKey& pk, ILinkSession* s)
ILinkLayer::MapAddr(const byte_t* pk, ILinkSession* s)
{
static constexpr size_t MaxSessionsPerKey = 16;
Lock l_authed(m_AuthedLinksMutex);
@ -128,7 +128,7 @@ namespace llarp
llarp::AddressInfo to;
if(!PickAddress(rc, to))
return false;
llarp::LogInfo("Try establish to ", rc.pubkey);
llarp::LogInfo("Try establish to ", RouterID(rc.pubkey.data()));
llarp::Addr addr(to);
auto s = NewOutboundSession(rc, to);
s->Start();
@ -170,11 +170,12 @@ namespace llarp
}
void
ILinkLayer::CloseSessionTo(const PubKey& remote)
ILinkLayer::CloseSessionTo(const byte_t* remote)
{
Lock l(m_AuthedLinksMutex);
llarp::LogInfo("Closing all to ", remote);
auto range = m_AuthedLinks.equal_range(remote);
RouterID r = remote;
llarp::LogInfo("Closing all to ", r);
auto range = m_AuthedLinks.equal_range(r);
auto itr = range.first;
while(itr != range.second)
{
@ -184,7 +185,7 @@ namespace llarp
}
void
ILinkLayer::KeepAliveSessionTo(const PubKey& remote)
ILinkLayer::KeepAliveSessionTo(const byte_t* remote)
{
Lock l(m_AuthedLinksMutex);
auto range = m_AuthedLinks.equal_range(remote);
@ -197,7 +198,7 @@ namespace llarp
}
bool
ILinkLayer::SendTo(const PubKey& remote, llarp_buffer_t buf)
ILinkLayer::SendTo(const byte_t* remote, llarp_buffer_t buf)
{
ILinkSession* s = nullptr;
{

@ -207,7 +207,7 @@ namespace llarp
// mix keys
bool
DoKeyExchange(llarp_transport_dh_func dh, const KeyExchangeNonce& n,
const PubKey& other, const SecretKey& secret)
const PubKey& other, const byte_t* secret)
{
ShortHash t_h;
AlignedBuffer< 64 > tmp;
@ -555,7 +555,7 @@ namespace llarp
#ifdef __linux__
ProcessICMP();
#endif
std::set< PubKey > sessions;
std::set< RouterID > sessions;
{
Lock l(m_AuthedLinksMutex);
auto itr = m_AuthedLinks.begin();

@ -23,12 +23,13 @@ struct llarp_nodedb
llarp_crypto *crypto;
// std::map< llarp::pubkey, llarp_rc > entries;
llarp::util::Mutex access;
std::unordered_map< llarp::PubKey, llarp::RouterContact, llarp::PubKey::Hash >
std::unordered_map< llarp::RouterID, llarp::RouterContact,
llarp::RouterID::Hash >
entries;
fs::path nodePath;
bool
Remove(const llarp::PubKey &pk)
Remove(const byte_t *pk)
{
llarp::util::Lock lock(access);
auto itr = entries.find(pk);
@ -47,7 +48,7 @@ struct llarp_nodedb
}
bool
Get(const llarp::PubKey &pk, llarp::RouterContact &result)
Get(const byte_t *pk, llarp::RouterContact &result)
{
llarp::util::Lock lock(access);
auto itr = entries.find(pk);
@ -58,7 +59,7 @@ struct llarp_nodedb
}
bool
Has(const llarp::PubKey &pk)
Has(const byte_t *pk)
{
llarp::util::Lock lock(access);
return entries.find(pk) != entries.end();
@ -69,7 +70,8 @@ struct llarp_nodedb
{
char ftmp[68] = {0};
const char *hexname =
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(pubkey, ftmp);
llarp::HexEncode< llarp::AlignedBuffer< 32 >, decltype(ftmp) >(pubkey,
ftmp);
std::string hexString(hexname);
std::string skiplistDir;
skiplistDir += hexString[hexString.length() - 1];
@ -86,7 +88,7 @@ struct llarp_nodedb
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
{
llarp::util::Lock lock(access);
entries.insert(std::make_pair(rc.pubkey, rc));
entries.insert(std::make_pair(rc.pubkey.data(), rc));
}
if(!rc.BEncode(&buf))
return false;
@ -163,7 +165,7 @@ struct llarp_nodedb
}
{
llarp::util::Lock lock(access);
entries.insert(std::make_pair(rc.pubkey, rc));
entries.insert(std::make_pair(rc.pubkey.data(), rc));
}
return true;
}

@ -58,9 +58,9 @@ namespace llarp
}
bool
PathContext::HopIsUs(const PubKey& k) const
PathContext::HopIsUs(const RouterID& k) const
{
return memcmp(k, m_Router->pubkey(), PUBKEYSIZE) == 0;
return memcmp(k.data(), m_Router->pubkey(), PUBKEYSIZE) == 0;
}
bool
@ -372,6 +372,12 @@ namespace llarp
return hops[hops.size() - 1].rc.pubkey;
}
PubKey
Path::EndpointPubKey() const
{
return hops[hops.size() - 1].rc.pubkey;
}
const PathID_t&
Path::TXID() const
{
@ -692,7 +698,7 @@ namespace llarp
/// allows exits to close from their end
if(SupportsAnyRoles(ePathRoleExit | ePathRoleSVC))
{
if(msg->Verify(&r->crypto, Endpoint()))
if(msg->Verify(&r->crypto, EndpointPubKey()))
{
llarp::LogInfo(Name(), " had its exit closed");
_role &= ~ePathRoleExit;
@ -741,7 +747,7 @@ namespace llarp
{
if(m_ExitObtainTX && msg->T == m_ExitObtainTX)
{
if(!msg->Verify(&r->crypto, Endpoint()))
if(!msg->Verify(&r->crypto, EndpointPubKey()))
{
llarp::LogError(Name(), "RXM invalid signature");
return false;
@ -760,7 +766,7 @@ namespace llarp
{
if(m_ExitObtainTX && msg->T == m_ExitObtainTX)
{
if(!msg->Verify(&r->crypto, Endpoint()))
if(!msg->Verify(&r->crypto, EndpointPubKey()))
{
llarp::LogError(Name(), " GXM signature failed");
return false;

@ -63,11 +63,11 @@ namespace llarp
if(isFarthestHop)
{
hop.upstream = hop.rc.pubkey;
hop.upstream = hop.rc.pubkey.data();
}
else
{
hop.upstream = ctx->path->hops[ctx->idx].rc.pubkey;
hop.upstream = ctx->path->hops[ctx->idx].rc.pubkey.data();
}
// build record

@ -86,12 +86,13 @@ namespace llarp
}
Path*
PathSet::GetEstablishedPathClosestTo(const AlignedBuffer< 32 >& id,
PathSet::GetEstablishedPathClosestTo(const RouterID& id,
PathRole roles) const
{
Lock_t l(m_PathsMutex);
Path* path = nullptr;
AlignedBuffer< 32 > dist;
AlignedBuffer< 32 > to = id.data();
dist.Fill(0xff);
for(const auto& item : m_Paths)
{
@ -99,7 +100,7 @@ namespace llarp
continue;
if(!item.second->SupportsAnyRoles(roles))
continue;
AlignedBuffer< 32 > localDist = item.second->Endpoint() ^ id;
AlignedBuffer< 32 > localDist = item.second->Endpoint() ^ to;
if(localDist < dist)
{
dist = localDist;

@ -46,14 +46,13 @@ struct TryConnectJob
void
Failed()
{
llarp::LogInfo("session to ", rc.pubkey, " closed");
llarp::LogInfo("session to ", llarp::RouterID(rc.pubkey.data()), " closed");
link->CloseSessionTo(rc.pubkey);
}
void
Success()
{
llarp::LogInfo("established session with ", rc.pubkey);
router->FlushOutboundFor(rc.pubkey, link);
}
@ -112,7 +111,7 @@ llarp_router_try_connect(struct llarp_router *router,
auto link = router->outboundLink.get();
auto itr = router->pendingEstablishJobs.insert(std::make_pair(
remote.pubkey,
remote.pubkey.data(),
std::make_unique< TryConnectJob >(remote, link, numretries, router)));
TryConnectJob *job = itr.first->second.get();
// try establishing async
@ -174,13 +173,13 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote,
{
for(const auto &link : inboundLinks)
{
if(link->HasSessionTo(remote))
if(link->HasSessionTo(remote.data()))
{
SendTo(remote, msg, link.get());
return true;
}
}
if(outboundLink && outboundLink->HasSessionTo(remote))
if(outboundLink && outboundLink->HasSessionTo(remote.data()))
{
SendTo(remote, msg, outboundLink.get());
return true;
@ -397,7 +396,7 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job)
llarp::RouterContact rc = job->rc;
router->validRouters.insert(std::make_pair(pk, rc));
router->validRouters.insert(std::make_pair(pk.data(), rc));
// track valid router in dht
router->dht->impl.nodes->PutNode(rc);
@ -834,10 +833,8 @@ llarp_router::Run()
// set public encryption key
_rc.enckey = llarp::seckey_topublic(encryption);
llarp::LogInfo("Your Encryption pubkey ", rc().enckey);
// set public signing key
_rc.pubkey = llarp::seckey_topublic(identity);
llarp::LogInfo("Your Identity pubkey ", rc().pubkey);
if(ExitEnabled())
{
llarp::nuint32_t a = publicAddr.xtonl();
@ -892,6 +889,8 @@ llarp_router::Run()
llarp::LogError("Failed to initialize service node");
return false;
}
llarp::RouterID us = pubkey();
llarp::LogInfo("initalized service node: ", us);
}
else
{
@ -921,9 +920,7 @@ llarp_router::Run()
llarp::LogError("Failed to start hidden service context");
return false;
}
llarp::PubKey ourPubkey = pubkey();
llarp::LogInfo("starting dht context as ", ourPubkey);
llarp_dht_context_start(dht, ourPubkey);
llarp_dht_context_start(dht, pubkey());
ScheduleTicker(1000);
return true;
}
@ -1245,14 +1242,22 @@ namespace llarp
llarp::LogError("cannot use strict-connect option as service node");
return;
}
llarp::RouterID snode;
llarp::PubKey pk;
if(llarp::HexDecode(val, pk.data(), pk.size()))
if(pk.FromString(val))
{
if(self->strictConnectPubkeys.insert(pk).second)
if(self->strictConnectPubkeys.insert(pk.data()).second)
llarp::LogInfo("added ", pk, " to strict connect list");
else
llarp::LogWarn("duplicate key for strict connect: ", pk);
}
else if(snode.FromString(val))
{
if(self->strictConnectPubkeys.insert(snode).second)
llarp::LogInfo("added ", snode, " to strict connect list");
else
llarp::LogWarn("duplicate key for strict connect: ", snode);
}
else
llarp::LogError("invalid key for strict-connect: ", val);
}
@ -1318,7 +1323,7 @@ namespace llarp
auto &rc = self->bootstrapRCList.back();
if(rc.Read(val) && rc.Verify(&self->crypto))
{
llarp::LogInfo("Added bootstrap node ", rc.pubkey);
llarp::LogInfo("Added bootstrap node ", RouterID(rc.pubkey.data()));
}
else
{

@ -108,7 +108,7 @@ struct llarp_router
/// identity keys whitelist of routers we will connect to directly (not for
/// service nodes)
std::set< llarp::PubKey > strictConnectPubkeys;
std::set< llarp::RouterID > strictConnectPubkeys;
/// bootstrap RCs
std::list< llarp::RouterContact > bootstrapRCList;
@ -169,7 +169,7 @@ struct llarp_router
// lokinet routers from lokid, maps pubkey to when we think it will expire,
// set to max value right now
std::unordered_map< llarp::PubKey, llarp_time_t, llarp::PubKey::Hash >
std::unordered_map< llarp::RouterID, llarp_time_t, llarp::RouterID::Hash >
lokinetRouters;
llarp_router();

@ -0,0 +1,20 @@
#include <llarp/router_id.hpp>
namespace llarp
{
std::string
RouterID::ToString() const
{
char stack[64] = {0};
return std::string(llarp::Base32Encode(*this, stack)) + ".snode";
}
bool
RouterID::FromString(const std::string& str)
{
auto pos = str.find(".snode");
if(pos == std::string::npos || pos == 0)
return false;
return Base32Decode(str.substr(0, pos), *this);
}
} // namespace llarp

@ -715,8 +715,7 @@ namespace llarp
auto path = GetEstablishedPathClosestTo(router);
routing::DHTMessage msg;
auto txid = GenTXID();
msg.M.emplace_back(
new dht::FindRouterMessage({}, dht::Key_t(router), txid));
msg.M.emplace_back(new dht::FindRouterMessage(txid, router));
if(path && path->SendRoutingMessage(&msg, m_Router))
{

Loading…
Cancel
Save