2018-07-11 13:20:14 +00:00
|
|
|
#include <llarp/dht/context.hpp>
|
|
|
|
#include <llarp/dht/messages/all.hpp>
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace dht
|
|
|
|
{
|
|
|
|
struct MessageDecoder
|
|
|
|
{
|
|
|
|
const Key_t &From;
|
|
|
|
bool firstKey = true;
|
|
|
|
IMessage *msg = nullptr;
|
|
|
|
bool relayed = false;
|
|
|
|
|
|
|
|
MessageDecoder(const Key_t &from) : From(from)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
on_key(dict_reader *r, llarp_buffer_t *key)
|
|
|
|
{
|
|
|
|
llarp_buffer_t strbuf;
|
|
|
|
MessageDecoder *dec = static_cast< MessageDecoder * >(r->user);
|
|
|
|
// check for empty dict
|
|
|
|
if(!key)
|
|
|
|
return !dec->firstKey;
|
|
|
|
|
|
|
|
// first key
|
|
|
|
if(dec->firstKey)
|
|
|
|
{
|
|
|
|
if(!llarp_buffer_eq(*key, "A"))
|
|
|
|
return false;
|
|
|
|
if(!bencode_read_string(r->buffer, &strbuf))
|
|
|
|
return false;
|
|
|
|
// bad msg size?
|
|
|
|
if(strbuf.sz != 1)
|
|
|
|
return false;
|
2018-08-10 03:51:38 +00:00
|
|
|
llarp::LogInfo("Handle DHT message ", *strbuf.base,
|
|
|
|
" relayed=", dec->relayed);
|
2018-07-11 13:20:14 +00:00
|
|
|
switch(*strbuf.base)
|
|
|
|
{
|
2018-07-16 21:22:25 +00:00
|
|
|
case 'F':
|
2018-07-18 20:58:16 +00:00
|
|
|
dec->msg = new FindIntroMessage(dec->From, dec->relayed);
|
|
|
|
break;
|
2018-07-11 13:20:14 +00:00
|
|
|
case 'R':
|
|
|
|
if(dec->relayed)
|
|
|
|
dec->msg = new RelayedFindRouterMessage(dec->From);
|
|
|
|
else
|
|
|
|
dec->msg = new FindRouterMessage(dec->From);
|
|
|
|
break;
|
|
|
|
case 'S':
|
2018-08-10 21:34:11 +00:00
|
|
|
dec->msg = new GotRouterMessage(dec->From, dec->relayed);
|
2018-07-11 13:20:14 +00:00
|
|
|
break;
|
|
|
|
case 'I':
|
|
|
|
dec->msg = new PublishIntroMessage();
|
|
|
|
break;
|
2018-07-11 16:11:19 +00:00
|
|
|
case 'G':
|
|
|
|
if(dec->relayed)
|
|
|
|
{
|
2018-07-12 13:43:37 +00:00
|
|
|
dec->msg = new RelayedGotIntroMessage();
|
2018-07-11 16:11:19 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-12 13:43:37 +00:00
|
|
|
dec->msg = new GotIntroMessage(dec->From);
|
|
|
|
break;
|
2018-07-11 16:11:19 +00:00
|
|
|
}
|
2018-07-11 13:20:14 +00:00
|
|
|
default:
|
|
|
|
llarp::LogWarn("unknown dht message type: ", (char)*strbuf.base);
|
|
|
|
// bad msg type
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
dec->firstKey = false;
|
|
|
|
return dec->msg != nullptr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return dec->msg->DecodeKey(*key, r->buffer);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
IMessage *
|
|
|
|
DecodeMesssage(const Key_t &from, llarp_buffer_t *buf, bool relayed)
|
|
|
|
{
|
|
|
|
MessageDecoder dec(from);
|
|
|
|
dec.relayed = relayed;
|
|
|
|
dict_reader r;
|
|
|
|
r.user = &dec;
|
|
|
|
r.on_key = &MessageDecoder::on_key;
|
|
|
|
if(bencode_read_dict(buf, &r))
|
2018-07-12 13:43:37 +00:00
|
|
|
{
|
2018-07-11 13:20:14 +00:00
|
|
|
return dec.msg;
|
2018-07-12 13:43:37 +00:00
|
|
|
}
|
2018-07-11 13:20:14 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if(dec.msg)
|
|
|
|
delete dec.msg;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ListDecoder
|
|
|
|
{
|
|
|
|
ListDecoder(const Key_t &from, std::vector< IMessage * > &list)
|
|
|
|
: From(from), l(list){};
|
|
|
|
|
|
|
|
bool relayed = false;
|
|
|
|
const Key_t &From;
|
|
|
|
std::vector< IMessage * > &l;
|
|
|
|
|
|
|
|
static bool
|
|
|
|
on_item(list_reader *r, bool has)
|
|
|
|
{
|
|
|
|
ListDecoder *dec = static_cast< ListDecoder * >(r->user);
|
|
|
|
if(!has)
|
|
|
|
return true;
|
|
|
|
auto msg = DecodeMesssage(dec->From, r->buffer, dec->relayed);
|
|
|
|
if(msg)
|
|
|
|
{
|
|
|
|
dec->l.push_back(msg);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool
|
|
|
|
DecodeMesssageList(const Key_t &from, llarp_buffer_t *buf,
|
|
|
|
std::vector< IMessage * > &list, bool relayed)
|
|
|
|
{
|
|
|
|
ListDecoder dec(from, list);
|
|
|
|
dec.relayed = relayed;
|
|
|
|
list_reader r;
|
|
|
|
r.user = &dec;
|
|
|
|
r.on_item = &ListDecoder::on_item;
|
|
|
|
return bencode_read_list(buf, &r);
|
|
|
|
}
|
2018-07-12 13:43:37 +00:00
|
|
|
} // namespace dht
|
|
|
|
} // namespace llarp
|