2018-07-11 13:20:14 +00:00
|
|
|
|
|
|
|
#include <llarp/dht/context.hpp>
|
|
|
|
#include <llarp/dht/messages/findrouter.hpp>
|
|
|
|
#include <llarp/dht/messages/gotrouter.hpp>
|
|
|
|
#include <llarp/messages/dht.hpp>
|
|
|
|
#include "router.hpp"
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace dht
|
|
|
|
{
|
|
|
|
bool
|
|
|
|
RelayedFindRouterMessage::HandleMessage(
|
2018-09-02 18:25:42 +00:00
|
|
|
llarp_dht_context *ctx,
|
|
|
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
2018-07-11 13:20:14 +00:00
|
|
|
{
|
|
|
|
auto &dht = ctx->impl;
|
|
|
|
/// lookup for us, send an immeidate reply
|
|
|
|
if(K == dht.OurKey())
|
|
|
|
{
|
|
|
|
auto path = dht.router->paths.GetByUpstream(K, pathID);
|
|
|
|
if(path)
|
|
|
|
{
|
2018-09-02 18:25:42 +00:00
|
|
|
replies.emplace_back(
|
2018-09-09 11:23:21 +00:00
|
|
|
new GotRouterMessage(K.data(), txid, {dht.router->rc()}, false));
|
2018-07-11 13:20:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-30 18:48:43 +00:00
|
|
|
|
2018-07-11 13:20:14 +00:00
|
|
|
Key_t peer;
|
2018-08-29 20:40:26 +00:00
|
|
|
Key_t k = K.data();
|
2018-09-13 11:16:56 +00:00
|
|
|
// check if we know this in our nodedb first
|
|
|
|
RouterContact found;
|
|
|
|
if(llarp_nodedb_get_rc(dht.router->nodedb, K, found))
|
|
|
|
{
|
|
|
|
replies.emplace_back(
|
|
|
|
new GotRouterMessage(K.data(), txid, {found}, false));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// lookup if we don't have it in our nodedb
|
2018-08-29 20:40:26 +00:00
|
|
|
if(dht.nodes->FindClosest(k, peer))
|
2018-08-30 18:48:43 +00:00
|
|
|
dht.LookupRouterForPath(K, txid, pathID, peer);
|
2018-08-14 22:07:58 +00:00
|
|
|
return true;
|
2018-07-11 13:20:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FindRouterMessage::~FindRouterMessage()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
FindRouterMessage::BEncode(llarp_buffer_t *buf) const
|
|
|
|
{
|
|
|
|
if(!bencode_start_dict(buf))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// message type
|
|
|
|
if(!bencode_write_bytestring(buf, "A", 1))
|
|
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, "R", 1))
|
|
|
|
return false;
|
|
|
|
|
2018-08-27 13:44:16 +00:00
|
|
|
// exploritory or not?
|
|
|
|
if(!bencode_write_bytestring(buf, "E", 1))
|
|
|
|
return false;
|
|
|
|
if(!bencode_write_uint64(buf, exploritory ? 1 : 0))
|
|
|
|
return false;
|
|
|
|
|
2018-07-11 13:20:14 +00:00
|
|
|
// iterative or not?
|
|
|
|
if(!bencode_write_bytestring(buf, "I", 1))
|
|
|
|
return false;
|
2018-07-30 01:39:35 +00:00
|
|
|
if(!bencode_write_uint64(buf, iterative ? 1 : 0))
|
2018-07-11 13:20:14 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// key
|
|
|
|
if(!bencode_write_bytestring(buf, "K", 1))
|
|
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, K.data(), K.size()))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// txid
|
|
|
|
if(!bencode_write_bytestring(buf, "T", 1))
|
|
|
|
return false;
|
|
|
|
if(!bencode_write_uint64(buf, txid))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// version
|
|
|
|
if(!bencode_write_bytestring(buf, "V", 1))
|
|
|
|
return false;
|
|
|
|
if(!bencode_write_uint64(buf, version))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return bencode_end(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
FindRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
|
|
|
{
|
|
|
|
llarp_buffer_t strbuf;
|
|
|
|
|
2018-08-27 13:44:16 +00:00
|
|
|
if(llarp_buffer_eq(key, "E"))
|
|
|
|
{
|
|
|
|
uint64_t result;
|
|
|
|
if(!bencode_read_integer(val, &result))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
exploritory = result != 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-07-11 13:20:14 +00:00
|
|
|
if(llarp_buffer_eq(key, "I"))
|
|
|
|
{
|
|
|
|
uint64_t result;
|
|
|
|
if(!bencode_read_integer(val, &result))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
iterative = result != 0;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(llarp_buffer_eq(key, "K"))
|
|
|
|
{
|
|
|
|
if(!bencode_read_string(val, &strbuf))
|
|
|
|
return false;
|
|
|
|
if(strbuf.sz != K.size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
memcpy(K.data(), strbuf.base, K.size());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(llarp_buffer_eq(key, "T"))
|
|
|
|
{
|
|
|
|
return bencode_read_integer(val, &txid);
|
|
|
|
}
|
|
|
|
if(llarp_buffer_eq(key, "V"))
|
|
|
|
{
|
|
|
|
return bencode_read_integer(val, &version);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2018-09-02 18:25:42 +00:00
|
|
|
FindRouterMessage::HandleMessage(
|
|
|
|
llarp_dht_context *ctx,
|
|
|
|
std::vector< std::unique_ptr< IMessage > > &replies) const
|
2018-07-11 13:20:14 +00:00
|
|
|
{
|
|
|
|
auto &dht = ctx->impl;
|
|
|
|
if(!dht.allowTransit)
|
|
|
|
{
|
|
|
|
llarp::LogWarn("Got DHT lookup from ", From,
|
|
|
|
" when we are not allowing dht transit");
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-29 20:40:26 +00:00
|
|
|
if(dht.pendingRouterLookups.HasPendingLookupFrom({From, txid}))
|
2018-07-11 13:20:14 +00:00
|
|
|
{
|
2018-08-29 20:40:26 +00:00
|
|
|
llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid);
|
2018-07-11 13:20:14 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-09-13 11:16:56 +00:00
|
|
|
RouterContact found;
|
2018-08-27 13:44:16 +00:00
|
|
|
if(exploritory)
|
2018-08-29 20:40:26 +00:00
|
|
|
return dht.HandleExploritoryRouterLookup(From, txid, K, replies);
|
2018-09-13 11:16:56 +00:00
|
|
|
else if(llarp_nodedb_get_rc(dht.router->nodedb, K, found))
|
|
|
|
{
|
|
|
|
replies.emplace_back(
|
|
|
|
new GotRouterMessage(K.data(), txid, {found}, false));
|
|
|
|
return true;
|
|
|
|
}
|
2018-08-27 13:44:16 +00:00
|
|
|
else
|
2018-08-29 20:40:26 +00:00
|
|
|
dht.LookupRouterRelayed(From, txid, K.data(), !iterative, replies);
|
2018-07-11 13:20:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
2018-07-16 03:32:13 +00:00
|
|
|
} // namespace dht
|
2018-08-27 13:44:16 +00:00
|
|
|
} // namespace llarp
|