lokinet/llarp/dht/messages/findrouter.cpp

198 lines
5.1 KiB
C++
Raw Normal View History

2018-12-15 16:21:52 +00:00
#include <dht/messages/findrouter.hpp>
2019-01-16 00:24:16 +00:00
#include <dht/context.hpp>
#include <dht/messages/gotrouter.hpp>
#include <messages/dht.hpp>
#include <path/path.hpp>
#include <nodedb.hpp>
#include <router/abstractrouter.hpp>
2019-01-16 00:24:16 +00:00
namespace llarp
{
namespace dht
{
bool
RelayedFindRouterMessage::HandleMessage(
llarp_dht_context *ctx,
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = *ctx->impl;
2019-01-16 00:24:16 +00:00
/// lookup for us, send an immeidate reply
Key_t us = dht.OurKey();
Key_t k{K};
if(K == us)
{
auto path = dht.GetRouter()->pathContext().GetByUpstream(K, pathID);
2019-01-16 00:24:16 +00:00
if(path)
{
replies.emplace_back(
new GotRouterMessage(k, txid, {dht.GetRouter()->rc()}, false));
2019-01-16 00:24:16 +00:00
return true;
}
return false;
}
Key_t peer;
// check if we know this in our nodedb first
RouterContact found;
if(!dht.GetRouter()->ConnectionToRouterAllowed(K))
{
// explicitly disallowed by network
replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
return true;
}
if(dht.GetRouter()->nodedb()->Get(K, found))
2019-01-16 00:24:16 +00:00
{
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
2019-04-16 18:55:47 +00:00
if((!dht.Nodes()->FindClosest(k, peer)) || peer == us)
{
// can't find any peers closer
replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
return true;
}
// lookup if we don't have it in our nodedb
2019-04-16 18:55:47 +00:00
dht.LookupRouterForPath(K, txid, pathID, peer);
2019-01-16 00:24:16 +00:00
return true;
}
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;
// exploritory or not?
if(!bencode_write_bytestring(buf, "E", 1))
return false;
if(!bencode_write_uint64(buf, exploritory ? 1 : 0))
return false;
// iterative or not?
if(!bencode_write_bytestring(buf, "I", 1))
return false;
if(!bencode_write_uint64(buf, iterative ? 1 : 0))
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(const llarp_buffer_t &key, llarp_buffer_t *val)
2019-01-16 00:24:16 +00:00
{
llarp_buffer_t strbuf;
if(key == "E")
2019-01-16 00:24:16 +00:00
{
uint64_t result;
if(!bencode_read_integer(val, &result))
return false;
exploritory = result != 0;
return true;
}
if(key == "I")
2019-01-16 00:24:16 +00:00
{
uint64_t result;
if(!bencode_read_integer(val, &result))
return false;
iterative = result != 0;
return true;
}
if(key == "K")
2019-01-16 00:24:16 +00:00
{
if(!bencode_read_string(val, &strbuf))
return false;
if(strbuf.sz != K.size())
return false;
std::copy(strbuf.base, strbuf.base + K.SIZE, K.begin());
return true;
}
if(key == "T")
2019-01-16 00:24:16 +00:00
{
return bencode_read_integer(val, &txid);
}
if(key == "V")
2019-01-16 00:24:16 +00:00
{
return bencode_read_integer(val, &version);
}
return false;
}
bool
FindRouterMessage::HandleMessage(
llarp_dht_context *ctx,
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = *ctx->impl;
if(!dht.AllowTransit())
2019-01-16 00:24:16 +00:00
{
llarp::LogWarn("Got DHT lookup from ", From,
" when we are not allowing dht transit");
return false;
}
if(dht.pendingRouterLookups().HasPendingLookupFrom({From, txid}))
2019-01-16 00:24:16 +00:00
{
llarp::LogWarn("Duplicate FRM from ", From, " txid=", txid);
return false;
}
RouterContact found;
Key_t k{K};
if(exploritory)
return dht.HandleExploritoryRouterLookup(From, txid, K, replies);
else if(!dht.GetRouter()->ConnectionToRouterAllowed(K))
{
// explicitly disallowed by network
replies.emplace_back(new GotRouterMessage(k, txid, {}, false));
return true;
}
2019-02-23 16:46:29 +00:00
else if(dht.Nodes()->HasNode(k))
2019-01-16 00:24:16 +00:00
{
2019-02-23 16:46:29 +00:00
found = dht.Nodes()->nodes[k].rc;
2019-01-16 00:24:16 +00:00
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
2019-03-27 12:36:27 +00:00
else if(dht.GetRCFromNodeDB(k, found))
2019-03-27 04:07:57 +00:00
{
replies.emplace_back(new GotRouterMessage(k, txid, {found}, false));
return true;
}
2019-01-16 00:24:16 +00:00
else
dht.LookupRouterRelayed(From, txid, k, !iterative, replies);
return true;
}
} // namespace dht
} // namespace llarp