lokinet/llarp/dht/message.cpp

135 lines
3.4 KiB
C++
Raw Normal View History

2019-01-19 13:49:15 +00:00
#include <dht/context.hpp>
2019-07-30 23:42:13 +00:00
#include <memory>
#include <util/bencode.hpp>
2019-01-19 13:49:15 +00:00
#include <dht/messages/findintro.hpp>
#include <dht/messages/findrouter.hpp>
#include <dht/messages/gotintro.hpp>
#include <dht/messages/gotrouter.hpp>
#include <dht/messages/pubintro.hpp>
namespace llarp
{
namespace dht
{
struct MessageDecoder
{
const Key_t &From;
2019-05-03 13:15:03 +00:00
IMessage::Ptr_t msg;
2020-02-14 17:43:44 +00:00
bool firstKey = true;
bool relayed = false;
2019-01-19 13:49:15 +00:00
2020-02-14 16:54:33 +00:00
MessageDecoder(const Key_t &from, bool wasRelayed)
: From(from), relayed(wasRelayed)
2019-01-19 13:49:15 +00:00
{
}
bool
operator()(llarp_buffer_t *buffer, llarp_buffer_t *key)
2019-01-19 13:49:15 +00:00
{
llarp_buffer_t strbuf;
// check for empty dict
if(!key)
return !firstKey;
2019-01-19 13:49:15 +00:00
// first key
if(firstKey)
2019-01-19 13:49:15 +00:00
{
if(!(*key == "A"))
2019-01-19 13:49:15 +00:00
return false;
if(!bencode_read_string(buffer, &strbuf))
2019-01-19 13:49:15 +00:00
return false;
// bad msg size?
if(strbuf.sz != 1)
return false;
2019-07-17 12:25:51 +00:00
llarp::LogDebug("Handle DHT message ", *strbuf.base,
" relayed=", relayed);
2019-01-19 13:49:15 +00:00
switch(*strbuf.base)
{
case 'F':
2020-02-14 16:54:33 +00:00
msg = std::make_unique< FindIntroMessage >(From, relayed, 0);
2019-01-19 13:49:15 +00:00
break;
case 'R':
if(relayed)
2019-07-30 23:42:13 +00:00
msg = std::make_unique< RelayedFindRouterMessage >(From);
2019-01-19 13:49:15 +00:00
else
2019-07-30 23:42:13 +00:00
msg = std::make_unique< FindRouterMessage >(From);
2019-01-19 13:49:15 +00:00
break;
case 'S':
2019-07-30 23:42:13 +00:00
msg = std::make_unique< GotRouterMessage >(From, relayed);
2019-01-19 13:49:15 +00:00
break;
case 'I':
2019-07-30 23:42:13 +00:00
msg = std::make_unique< PublishIntroMessage >();
2019-01-19 13:49:15 +00:00
break;
case 'G':
if(relayed)
2019-01-19 13:49:15 +00:00
{
2019-07-30 23:42:13 +00:00
msg = std::make_unique< RelayedGotIntroMessage >();
2019-01-19 13:49:15 +00:00
break;
}
else
{
2019-07-30 23:42:13 +00:00
msg = std::make_unique< GotIntroMessage >(From);
2019-01-19 13:49:15 +00:00
break;
}
default:
llarp::LogWarn("unknown dht message type: ", (char)*strbuf.base);
// bad msg type
return false;
}
firstKey = false;
return msg != nullptr;
2019-01-19 13:49:15 +00:00
}
2019-07-06 17:03:40 +00:00
return msg->DecodeKey(*key, buffer);
2019-01-19 13:49:15 +00:00
}
};
2019-05-03 13:15:03 +00:00
IMessage::Ptr_t
2020-02-14 16:54:33 +00:00
DecodeMesssage(const Key_t &from, llarp_buffer_t *buf, bool relayed)
2019-01-19 13:49:15 +00:00
{
2020-02-14 16:54:33 +00:00
MessageDecoder dec(from, relayed);
if(!bencode_read_dict(dec, buf))
2019-01-19 13:49:15 +00:00
return nullptr;
2019-05-03 13:15:03 +00:00
return std::move(dec.msg);
2019-01-19 13:49:15 +00:00
}
struct ListDecoder
{
2020-02-14 16:54:33 +00:00
ListDecoder(bool hasRelayed, const Key_t &from,
std::vector< IMessage::Ptr_t > &list)
2020-02-14 16:54:33 +00:00
: relayed(hasRelayed), From(from), l(list)
{
}
2019-01-19 13:49:15 +00:00
bool relayed;
2019-01-19 13:49:15 +00:00
const Key_t &From;
2019-05-03 13:15:03 +00:00
std::vector< IMessage::Ptr_t > &l;
2019-01-19 13:49:15 +00:00
bool
operator()(llarp_buffer_t *buffer, bool has)
2019-01-19 13:49:15 +00:00
{
if(!has)
return true;
2020-02-14 16:54:33 +00:00
auto msg = DecodeMesssage(From, buffer, relayed);
2019-01-19 13:49:15 +00:00
if(msg)
{
l.emplace_back(std::move(msg));
2019-01-19 13:49:15 +00:00
return true;
}
2019-07-06 17:03:40 +00:00
return false;
2019-01-19 13:49:15 +00:00
}
};
bool
DecodeMesssageList(Key_t from, llarp_buffer_t *buf,
2020-02-14 16:54:33 +00:00
std::vector< IMessage::Ptr_t > &list, bool relayed)
2019-01-19 13:49:15 +00:00
{
2020-02-14 16:54:33 +00:00
ListDecoder dec(relayed, from, list);
return bencode_read_list(dec, buf);
2019-01-19 13:49:15 +00:00
}
} // namespace dht
} // namespace llarp