mirror of
https://github.com/oxen-io/lokinet
synced 2023-12-14 06:53:00 +01:00
Merge branch 'master' of https://github.com/neuroscr/loki-network
This commit is contained in:
commit
cfb69224b5
7 changed files with 803 additions and 83 deletions
|
@ -1,5 +1,8 @@
|
|||
#include <llarp.h>
|
||||
#include <signal.h>
|
||||
#include <llarp/logger.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/param.h> // for MIN
|
||||
|
||||
struct llarp_main *ctx = 0;
|
||||
|
||||
|
@ -18,15 +21,57 @@ int
|
|||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *conffname = "daemon.ini";
|
||||
if(argc > 1)
|
||||
conffname = argv[1];
|
||||
int c;
|
||||
while(1)
|
||||
{
|
||||
static struct option long_options[] = {
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"logLevel", required_argument, 0, 'o'},
|
||||
{0, 0, 0, 0}};
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "c:o:", long_options, &option_index);
|
||||
if(c == -1)
|
||||
break;
|
||||
switch(c)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'c':
|
||||
conffname = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
if (strncmp(optarg, "debug", MIN(strlen(optarg), (unsigned long)5))==0)
|
||||
{
|
||||
cSetLogLevel(eLogDebug);
|
||||
}
|
||||
else
|
||||
if (strncmp(optarg, "info", MIN(strlen(optarg), (unsigned long)4))==0)
|
||||
{
|
||||
cSetLogLevel(eLogInfo);
|
||||
}
|
||||
else
|
||||
if (strncmp(optarg, "warn", MIN(strlen(optarg), (unsigned long)4))==0)
|
||||
{
|
||||
cSetLogLevel(eLogWarn);
|
||||
}
|
||||
else
|
||||
if (strncmp(optarg, "error", MIN(strlen(optarg), (unsigned long)5))==0)
|
||||
{
|
||||
cSetLogLevel(eLogError);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
ctx = llarp_main_init(conffname, !TESTNET);
|
||||
int code = 1;
|
||||
if(ctx)
|
||||
{
|
||||
signal(SIGINT, handle_signal);
|
||||
code = llarp_main_run(ctx);
|
||||
llarp_main_free(ctx);
|
||||
//llarp_main_free(ctx);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,16 @@
|
|||
#include <signal.h>
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/time.h>
|
||||
#include <fstream>
|
||||
#include "buffer.hpp"
|
||||
#include "crypto.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "net.hpp"
|
||||
#include "router.hpp"
|
||||
|
||||
struct llarp_main *ctx = 0;
|
||||
|
||||
llarp_main *sllarp = nullptr;
|
||||
|
@ -17,16 +27,6 @@ handle_signal(int sig)
|
|||
#define TESTNET 0
|
||||
#endif
|
||||
|
||||
#include <getopt.h>
|
||||
#include <llarp/router_contact.h>
|
||||
#include <llarp/time.h>
|
||||
#include <fstream>
|
||||
#include "buffer.hpp"
|
||||
#include "crypto.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "net.hpp"
|
||||
#include "router.hpp"
|
||||
|
||||
bool
|
||||
printNode(struct llarp_nodedb_iter *iter)
|
||||
{
|
||||
|
@ -38,6 +38,29 @@ printNode(struct llarp_nodedb_iter *iter)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aiLister(struct llarp_ai_list_iter *request, struct llarp_ai *addr)
|
||||
{
|
||||
static size_t count = 0;
|
||||
count++;
|
||||
llarp::Addr a(*addr);
|
||||
std::cout << "AddressInfo " << count << ": " << a << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void displayRC(llarp_rc *rc)
|
||||
{
|
||||
char ftmp[68] = {0};
|
||||
const char *hexPubSigKey =
|
||||
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(rc->pubkey, ftmp);
|
||||
printf("PubSigKey [%s]\n", hexPubSigKey);
|
||||
|
||||
struct llarp_ai_list_iter iter;
|
||||
// iter.user
|
||||
iter.visit = &aiLister;
|
||||
llarp_ai_list_iterate(rc->addrs, &iter);
|
||||
}
|
||||
|
||||
// fwd declr
|
||||
struct check_online_request;
|
||||
|
||||
|
@ -48,6 +71,7 @@ HandleDHTLocate(llarp_router_lookup_job *job)
|
|||
if (job->found)
|
||||
{
|
||||
// save to nodedb?
|
||||
displayRC(&job->result);
|
||||
}
|
||||
// shutdown router
|
||||
|
||||
|
@ -62,20 +86,11 @@ HandleDHTLocate(llarp_router_lookup_job *job)
|
|||
llarp_main_abort(ctx);
|
||||
}
|
||||
|
||||
bool
|
||||
aiLister(struct llarp_ai_list_iter *request, struct llarp_ai *addr)
|
||||
{
|
||||
static size_t count = 0;
|
||||
count++;
|
||||
llarp::Addr a(*addr);
|
||||
std::cout << "AddressInfo " << count << ": " << a << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
// take -c to set location of daemon.ini
|
||||
// take -o to set log level
|
||||
// --generate-blank /path/to/file.signed
|
||||
// --update-ifs /path/to/file.signed
|
||||
// --key /path/to/long_term_identity.key
|
||||
|
@ -89,12 +104,14 @@ main(int argc, char *argv[])
|
|||
{
|
||||
printf(
|
||||
"please specify: \n"
|
||||
"--generate with a path to a router contact file\n"
|
||||
"--update with a path to a router contact file\n"
|
||||
"--list \n"
|
||||
"--import with a path to a router contact file\n"
|
||||
"--export a hex formatted public key\n"
|
||||
"--locate a hex formatted public key"
|
||||
"--generate with a path to a router contact file\n"
|
||||
"--update with a path to a router contact file\n"
|
||||
"--list \n"
|
||||
"--import with a path to a router contact file\n"
|
||||
"--export a hex formatted public key\n"
|
||||
"--locate a hex formatted public key"
|
||||
"--localInfo \n"
|
||||
"--read with a path to a router contact file\n"
|
||||
"\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,6 +122,7 @@ main(int argc, char *argv[])
|
|||
bool exportMode = false;
|
||||
bool locateMode = false;
|
||||
bool localMode = false;
|
||||
bool readMode = false;
|
||||
int c;
|
||||
char *conffname;
|
||||
char defaultConfName[] = "daemon.ini";
|
||||
|
@ -117,6 +135,7 @@ main(int argc, char *argv[])
|
|||
{
|
||||
static struct option long_options[] = {
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"logLevel", required_argument, 0, 'o'},
|
||||
{"generate", required_argument, 0, 'g'},
|
||||
{"update", required_argument, 0, 'u'},
|
||||
{"list", no_argument, 0, 'l'},
|
||||
|
@ -124,9 +143,10 @@ main(int argc, char *argv[])
|
|||
{"export", required_argument, 0, 'e'},
|
||||
{"locate", required_argument, 0, 'q'},
|
||||
{"localInfo", no_argument, 0, 'n'},
|
||||
{"read", required_argument, 0, 'r'},
|
||||
{0, 0, 0, 0}};
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "cgluieqn", long_options, &option_index);
|
||||
c = getopt_long(argc, argv, "c:o:g:lu:i:e:q:nr:", long_options, &option_index);
|
||||
if(c == -1)
|
||||
break;
|
||||
switch(c)
|
||||
|
@ -136,6 +156,27 @@ main(int argc, char *argv[])
|
|||
case 'c':
|
||||
conffname = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
if (strncmp(optarg, "debug", std::min(strlen(optarg), static_cast<unsigned long>(5)))==0)
|
||||
{
|
||||
llarp::SetLogLevel(llarp::eLogDebug);
|
||||
}
|
||||
else
|
||||
if (strncmp(optarg, "info", std::min(strlen(optarg), static_cast<unsigned long>(4)))==0)
|
||||
{
|
||||
llarp::SetLogLevel(llarp::eLogInfo);
|
||||
}
|
||||
else
|
||||
if (strncmp(optarg, "warn", std::min(strlen(optarg), static_cast<unsigned long>(4)))==0)
|
||||
{
|
||||
llarp::SetLogLevel(llarp::eLogWarn);
|
||||
}
|
||||
else
|
||||
if (strncmp(optarg, "error", std::min(strlen(optarg), static_cast<unsigned long>(5)))==0)
|
||||
{
|
||||
llarp::SetLogLevel(llarp::eLogError);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
haveRequiredOptions = true;
|
||||
listMode = true;
|
||||
|
@ -174,6 +215,11 @@ main(int argc, char *argv[])
|
|||
haveRequiredOptions = true;
|
||||
localMode = true;
|
||||
break;
|
||||
case 'r':
|
||||
rcfname = optarg;
|
||||
haveRequiredOptions = true;
|
||||
readMode = true;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
@ -185,7 +231,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
printf("parsed options\n");
|
||||
if(!genMode && !updMode && !listMode && !importMode && !exportMode
|
||||
&& !locateMode && !localMode)
|
||||
&& !locateMode && !localMode && !readMode)
|
||||
{
|
||||
llarp::LogError(
|
||||
"I don't know what to do, no generate or update parameter\n");
|
||||
|
@ -309,12 +355,12 @@ main(int argc, char *argv[])
|
|||
llarp::PubKey binaryPK;
|
||||
llarp::HexDecode(rcfname, binaryPK.data());
|
||||
|
||||
//llarp::SetLogLevel(llarp::eLogDebug);
|
||||
|
||||
llarp::LogInfo("Queueing job");
|
||||
llarp_router_lookup_job *job = new llarp_router_lookup_job;
|
||||
job->iterative = true;
|
||||
job->found = false;
|
||||
job->hook = &HandleDHTLocate;
|
||||
llarp_rc_new(&job->result);
|
||||
memcpy(job->target, binaryPK, PUBKEYSIZE); // set job's target
|
||||
|
||||
// create query DHT request
|
||||
|
@ -332,19 +378,13 @@ main(int argc, char *argv[])
|
|||
}
|
||||
if(localMode)
|
||||
{
|
||||
// llarp::LogInfo("find our local rc file");
|
||||
|
||||
// llarp_rc *rc = llarp_rc_read("router.signed");
|
||||
llarp_rc *rc = llarp_main_getLocalRC(ctx);
|
||||
char ftmp[68] = {0};
|
||||
const char *hexPubSigKey =
|
||||
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(rc->pubkey, ftmp);
|
||||
printf("PubSigKey [%s]\n", hexPubSigKey);
|
||||
|
||||
struct llarp_ai_list_iter iter;
|
||||
// iter.user
|
||||
iter.visit = &aiLister;
|
||||
llarp_ai_list_iterate(rc->addrs, &iter);
|
||||
displayRC(rc);
|
||||
}
|
||||
if(readMode)
|
||||
{
|
||||
llarp_rc *rc = llarp_rc_read(rcfname);
|
||||
displayRC(rc);
|
||||
}
|
||||
// it's a unique_ptr, should clean up itself
|
||||
//llarp_main_free(ctx);
|
||||
|
|
|
@ -36,7 +36,9 @@ struct llarp_router_lookup_job
|
|||
struct llarp_dht_context* dht;
|
||||
byte_t target[PUBKEYSIZE];
|
||||
bool found;
|
||||
// make sure you initialize addr and exits
|
||||
struct llarp_rc result;
|
||||
bool iterative;
|
||||
};
|
||||
|
||||
/// start allowing dht participation on a context
|
||||
|
|
|
@ -42,6 +42,10 @@ struct llarp_rc
|
|||
void
|
||||
llarp_rc_free(struct llarp_rc *rc);
|
||||
|
||||
bool
|
||||
llarp_rc_new(struct llarp_rc *rc);
|
||||
|
||||
|
||||
bool
|
||||
llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc);
|
||||
|
||||
|
|
641
llarp/dht.cpp
641
llarp/dht.cpp
|
@ -2,6 +2,645 @@
|
|||
#include "router.hpp"
|
||||
#include "router_contact.hpp"
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#include <sodium.h>
|
||||
|
||||
#include <algorithm> // std::find
|
||||
#include <set>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
DHTImmeidateMessage::~DHTImmeidateMessage()
|
||||
{
|
||||
for(auto &msg : msgs)
|
||||
delete msg;
|
||||
msgs.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
DHTImmeidateMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "m"))
|
||||
return llarp::dht::DecodeMesssageList(remote.data(), buf, msgs);
|
||||
if(llarp_buffer_eq(key, "v"))
|
||||
{
|
||||
if(!bencode_read_integer(buf, &version))
|
||||
return false;
|
||||
return version == LLARP_PROTO_VERSION;
|
||||
}
|
||||
// bad key
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DHTImmeidateMessage::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, "m", 1))
|
||||
return false;
|
||||
|
||||
// dht messages
|
||||
if(!bencode_write_bytestring(buf, "m", 1))
|
||||
return false;
|
||||
// begin list
|
||||
if(!bencode_start_list(buf))
|
||||
return false;
|
||||
for(const auto &msg : msgs)
|
||||
{
|
||||
if(!msg->BEncode(buf))
|
||||
return false;
|
||||
}
|
||||
// end list
|
||||
if(!bencode_end(buf))
|
||||
return false;
|
||||
|
||||
// protocol version
|
||||
if(!bencode_write_version_entry(buf))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
DHTImmeidateMessage::HandleMessage(llarp_router *router) const
|
||||
{
|
||||
DHTImmeidateMessage *reply = new DHTImmeidateMessage(remote);
|
||||
bool result = true;
|
||||
for(auto &msg : msgs)
|
||||
{
|
||||
result &= msg->HandleMessage(router, reply->msgs);
|
||||
}
|
||||
return result && router->SendToOrQueue(remote.data(), reply);
|
||||
}
|
||||
|
||||
namespace dht
|
||||
{
|
||||
GotRouterMessage::~GotRouterMessage()
|
||||
{
|
||||
for(auto &rc : R)
|
||||
llarp_rc_free(&rc);
|
||||
R.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
GotRouterMessage::BEncode(llarp_buffer_t *buf) const
|
||||
{
|
||||
if(!bencode_start_dict(buf))
|
||||
return false;
|
||||
|
||||
// message type
|
||||
if(!BEncodeWriteDictMsgType(buf, "A", "S"))
|
||||
return false;
|
||||
|
||||
if(!BEncodeWriteDictList("R", R, buf))
|
||||
return false;
|
||||
|
||||
// txid
|
||||
if(!BEncodeWriteDictInt(buf, "T", txid))
|
||||
return false;
|
||||
|
||||
// version
|
||||
if(!BEncodeWriteDictInt(buf, "V", version))
|
||||
return false;
|
||||
|
||||
return bencode_end(buf);
|
||||
}
|
||||
|
||||
bool
|
||||
GotRouterMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t *val)
|
||||
{
|
||||
if(llarp_buffer_eq(key, "R"))
|
||||
{
|
||||
return BEncodeReadList(R, val);
|
||||
}
|
||||
if(llarp_buffer_eq(key, "T"))
|
||||
{
|
||||
return bencode_read_integer(val, &txid);
|
||||
}
|
||||
bool read = false;
|
||||
if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key,
|
||||
val))
|
||||
return false;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
bool
|
||||
GotRouterMessage::HandleMessage(llarp_router *router,
|
||||
std::vector< IMessage * > &replies) const
|
||||
{
|
||||
auto &dht = router->dht->impl;
|
||||
SearchJob *pending = dht.FindPendingTX(From, txid);
|
||||
if(pending)
|
||||
{
|
||||
if(R.size())
|
||||
{
|
||||
pending->Completed(&R[0]);
|
||||
if(pending->requester != dht.OurKey())
|
||||
{
|
||||
replies.push_back(new GotRouterMessage(
|
||||
pending->target, pending->requesterTX, &R[0]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// iterate to next closest peer
|
||||
Key_t nextPeer;
|
||||
pending->exclude.insert(From);
|
||||
if(pending->exclude.size() < 3
|
||||
&& dht.nodes->FindCloseExcluding(pending->target, nextPeer,
|
||||
pending->exclude))
|
||||
{
|
||||
llarp::Info(pending->target, " was not found via ", From,
|
||||
" iterating to next peer ", nextPeer, " already asked ",
|
||||
pending->exclude.size(), " other peers");
|
||||
// REVIEW: is this ok to relay the pending->job as the current job (seems to make things work)
|
||||
dht.LookupRouter(pending->target, pending->requester,
|
||||
pending->requesterTX, nextPeer, pending->job, true,
|
||||
pending->exclude);
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::Info(pending->target, " was not found via ", From,
|
||||
" and we won't look it up");
|
||||
pending->Completed(nullptr);
|
||||
if(pending->requester != dht.OurKey())
|
||||
{
|
||||
replies.push_back(new GotRouterMessage(
|
||||
pending->target, pending->requesterTX, nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
dht.RemovePendingLookup(From, txid);
|
||||
return true;
|
||||
}
|
||||
llarp::Warn("Got response for DHT transaction we are not tracking, txid=",
|
||||
txid);
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// iterative or not?
|
||||
if(!bencode_write_bytestring(buf, "I", 1))
|
||||
return false;
|
||||
if(!bencode_write_int(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(llarp_buffer_t key, llarp_buffer_t *val)
|
||||
{
|
||||
llarp_buffer_t strbuf;
|
||||
|
||||
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
|
||||
FindRouterMessage::HandleMessage(llarp_router *router,
|
||||
std::vector< IMessage * > &replies) const
|
||||
{
|
||||
auto &dht = router->dht->impl;
|
||||
if(!dht.allowTransit)
|
||||
{
|
||||
llarp::Warn("Got DHT lookup from ", From,
|
||||
" when we are not allowing dht transit");
|
||||
return false;
|
||||
}
|
||||
auto pending = dht.FindPendingTX(From, txid);
|
||||
if(pending)
|
||||
{
|
||||
llarp::Warn("Got duplicate DHT lookup from ", From, " txid=", txid);
|
||||
return false;
|
||||
}
|
||||
dht.LookupRouterRelayed(From, txid, K, !iterative, replies);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct MessageDecoder
|
||||
{
|
||||
const Key_t &From;
|
||||
bool firstKey = true;
|
||||
IMessage *msg = nullptr;
|
||||
|
||||
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;
|
||||
switch(*strbuf.base)
|
||||
{
|
||||
case 'R':
|
||||
dec->msg = new FindRouterMessage(dec->From);
|
||||
break;
|
||||
case 'S':
|
||||
dec->msg = new GotRouterMessage(dec->From);
|
||||
break;
|
||||
default:
|
||||
llarp::Warn("unknown dht message type: ", (char)*strbuf.base);
|
||||
// bad msg type
|
||||
return false;
|
||||
}
|
||||
dec->firstKey = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return dec->msg->DecodeKey(*key, r->buffer);
|
||||
}
|
||||
};
|
||||
|
||||
IMessage *
|
||||
DecodeMesssage(const Key_t &from, llarp_buffer_t *buf)
|
||||
{
|
||||
MessageDecoder dec(from);
|
||||
dict_reader r;
|
||||
r.user = &dec;
|
||||
r.on_key = &MessageDecoder::on_key;
|
||||
if(bencode_read_dict(buf, &r))
|
||||
return dec.msg;
|
||||
else
|
||||
{
|
||||
if(dec.msg)
|
||||
delete dec.msg;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
struct ListDecoder
|
||||
{
|
||||
ListDecoder(const Key_t &from, std::vector< IMessage * > &list)
|
||||
: From(from), l(list){};
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
ListDecoder dec(from, list);
|
||||
|
||||
list_reader r;
|
||||
r.user = &dec;
|
||||
r.on_item = &ListDecoder::on_item;
|
||||
return bencode_read_list(buf, &r);
|
||||
}
|
||||
|
||||
SearchJob::SearchJob()
|
||||
{
|
||||
started = 0;
|
||||
requester.Zero();
|
||||
target.Zero();
|
||||
}
|
||||
|
||||
SearchJob::SearchJob(const Key_t &asker, uint64_t tx, const Key_t &key,
|
||||
llarp_router_lookup_job *j,
|
||||
const std::set< Key_t > &excludes)
|
||||
: job(j)
|
||||
, started(llarp_time_now_ms())
|
||||
, requester(asker)
|
||||
, requesterTX(tx)
|
||||
, target(key)
|
||||
, exclude(excludes)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SearchJob::Completed(const llarp_rc *router, bool timeout) const
|
||||
{
|
||||
if(job && job->hook)
|
||||
{
|
||||
if(router)
|
||||
{
|
||||
job->found = true;
|
||||
llarp_rc_copy(&job->result, router);
|
||||
}
|
||||
job->hook(job);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SearchJob::IsExpired(llarp_time_t now) const
|
||||
{
|
||||
return now - started >= JobTimeout;
|
||||
}
|
||||
|
||||
Context::Context()
|
||||
{
|
||||
randombytes((byte_t *)&ids, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
Context::~Context()
|
||||
{
|
||||
if(nodes)
|
||||
delete nodes;
|
||||
if(services)
|
||||
delete services;
|
||||
}
|
||||
|
||||
void
|
||||
Context::handle_cleaner_timer(void *u, uint64_t orig, uint64_t left)
|
||||
{
|
||||
if(left)
|
||||
return;
|
||||
Context *ctx = static_cast< Context * >(u);
|
||||
|
||||
ctx->CleanupTX();
|
||||
ctx->ScheduleCleanupTimer();
|
||||
}
|
||||
|
||||
void
|
||||
Context::LookupRouterRelayed(const Key_t &requester, uint64_t txid,
|
||||
const Key_t &target, bool recursive,
|
||||
std::vector< IMessage * > &replies)
|
||||
{
|
||||
if(target == ourKey)
|
||||
{
|
||||
// we are the target, give them our RC
|
||||
replies.push_back(new GotRouterMessage(requester, txid, &router->rc));
|
||||
return;
|
||||
}
|
||||
Key_t next;
|
||||
std::set< Key_t > excluding = {requester, ourKey};
|
||||
if(nodes->FindCloseExcluding(target, next, excluding))
|
||||
{
|
||||
//llarp::Info("LookupRouterRelayed tick");
|
||||
if(next == target)
|
||||
{
|
||||
// we know it
|
||||
replies.push_back(
|
||||
new GotRouterMessage(requester, txid, nodes->nodes[target].rc));
|
||||
}
|
||||
else if(recursive) // are we doing a recursive lookup?
|
||||
{
|
||||
if((requester ^ target) < (ourKey ^ target))
|
||||
{
|
||||
// we aren't closer to the target than next hop
|
||||
// so we won't ask neighboor recursively, tell them we don't have it
|
||||
llarp::Info("we aren't closer to ", target, " than ", next,
|
||||
" so we end it here");
|
||||
replies.push_back(new GotRouterMessage(requester, txid, nullptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
// yeah, ask neighboor recursively
|
||||
llarp::Info("asking neighbor recursively");
|
||||
// FIXME: we may need to pass a job here...
|
||||
//auto sj = FindPendingTX(requester, txid);
|
||||
//LookupRouter(target, requester, txid, next, sj->job);
|
||||
LookupRouter(target, requester, txid, next);
|
||||
}
|
||||
}
|
||||
else // otherwise tell them we don't have it
|
||||
{
|
||||
llarp::Info("we don't have ", target,
|
||||
" and this was an iterative request so telling ",
|
||||
requester, " that we don't have it");
|
||||
replies.push_back(new GotRouterMessage(requester, txid, nullptr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't know it and have no closer peers
|
||||
llarp::Info("we don't have ", target,
|
||||
" and have no closer peers so telling ", requester,
|
||||
" that we don't have it");
|
||||
replies.push_back(new GotRouterMessage(requester, txid, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Context::RemovePendingLookup(const Key_t &owner, uint64_t id)
|
||||
{
|
||||
TXOwner search;
|
||||
search.node = owner;
|
||||
search.txid = id;
|
||||
auto itr = pendingTX.find(search);
|
||||
if(itr == pendingTX.end())
|
||||
return;
|
||||
pendingTX.erase(itr);
|
||||
}
|
||||
|
||||
SearchJob *
|
||||
Context::FindPendingTX(const Key_t &owner, uint64_t id)
|
||||
{
|
||||
TXOwner search;
|
||||
search.node = owner;
|
||||
search.txid = id;
|
||||
auto itr = pendingTX.find(search);
|
||||
if(itr == pendingTX.end())
|
||||
return nullptr;
|
||||
else
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
void
|
||||
Context::CleanupTX()
|
||||
{
|
||||
auto now = llarp_time_now_ms();
|
||||
llarp::Debug("DHT tick");
|
||||
|
||||
auto itr = pendingTX.begin();
|
||||
while(itr != pendingTX.end())
|
||||
{
|
||||
if(itr->second.IsExpired(now))
|
||||
{
|
||||
itr->second.Completed(nullptr, true);
|
||||
itr = pendingTX.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Context::Init(const Key_t &us, llarp_router *r)
|
||||
{
|
||||
router = r;
|
||||
ourKey = us;
|
||||
nodes = new Bucket< RCNode >(ourKey);
|
||||
services = new Bucket< ISNode >(ourKey);
|
||||
llarp::Debug("intialize dht with key ", ourKey);
|
||||
}
|
||||
|
||||
void
|
||||
Context::ScheduleCleanupTimer()
|
||||
{
|
||||
llarp_logic_call_later(router->logic,
|
||||
{1000, this, &handle_cleaner_timer});
|
||||
}
|
||||
|
||||
bool
|
||||
Context::RelayRequestForPath(const llarp::PathID_t &id, const IMessage *msg)
|
||||
{
|
||||
// TODO: implement me
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Context::LookupRouter(const Key_t &target, const Key_t &whoasked,
|
||||
uint64_t txid, const Key_t &askpeer,
|
||||
llarp_router_lookup_job *job, bool iterative,
|
||||
std::set< Key_t > excludes)
|
||||
{
|
||||
if(target.IsZero() || whoasked.IsZero() || askpeer.IsZero())
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto id = ++ids;
|
||||
TXOwner ownerKey;
|
||||
ownerKey.node = askpeer;
|
||||
ownerKey.txid = id;
|
||||
if(txid == 0)
|
||||
txid = id;
|
||||
|
||||
pendingTX[ownerKey] = SearchJob(whoasked, txid, target, job, excludes);
|
||||
|
||||
llarp::Info("Asking ", askpeer, " for router ", target, " for ",
|
||||
whoasked);
|
||||
auto msg = new llarp::DHTImmeidateMessage(askpeer);
|
||||
auto dhtmsg = new FindRouterMessage(askpeer, target, id);
|
||||
dhtmsg->iterative = iterative;
|
||||
msg->msgs.push_back(dhtmsg);
|
||||
router->SendToOrQueue(askpeer, msg);
|
||||
}
|
||||
|
||||
void
|
||||
Context::LookupRouterViaJob(llarp_router_lookup_job *job)
|
||||
{
|
||||
Key_t peer;
|
||||
/*
|
||||
llarp::Info("LookupRouterViaJob dumping nodes");
|
||||
for(const auto &item : nodes->nodes)
|
||||
{
|
||||
llarp::Info("LookupRouterViaJob dumping node: ", item.first);
|
||||
}
|
||||
*/
|
||||
llarp::Info("LookupRouterViaJob node count: ", nodes->nodes.size());
|
||||
llarp::Info("LookupRouterViaJob recursive: ", job->iterative?"yes":"no");
|
||||
if(nodes->FindClosest(job->target, peer))
|
||||
LookupRouter(job->target, ourKey, 0, peer, job, job->iterative);
|
||||
else if(job->hook)
|
||||
{
|
||||
job->found = false;
|
||||
job->hook(job);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Context::queue_router_lookup(void *user)
|
||||
{
|
||||
llarp_router_lookup_job *job =
|
||||
static_cast< llarp_router_lookup_job * >(user);
|
||||
job->dht->impl.LookupRouterViaJob(job);
|
||||
}
|
||||
|
||||
} // namespace dht
|
||||
} // namespace llarp
|
||||
|
||||
>>>>>>> ccc6300849a5375132dad112ff894eccba7be231
|
||||
llarp_dht_context::llarp_dht_context(llarp_router *router)
|
||||
{
|
||||
parent = router;
|
||||
|
@ -24,6 +663,7 @@ llarp_dht_put_peer(struct llarp_dht_context *ctx, struct llarp_rc *rc)
|
|||
|
||||
{
|
||||
llarp::dht::RCNode n(rc);
|
||||
llarp::Debug("Adding ", n.ID, " to DHT");
|
||||
ctx->impl.nodes->PutNode(n);
|
||||
}
|
||||
|
||||
|
@ -31,6 +671,7 @@ void
|
|||
llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id)
|
||||
{
|
||||
llarp::dht::Key_t k = id;
|
||||
llarp::Debug("Removing ", k, " to DHT");
|
||||
ctx->impl.nodes->DelNode(k);
|
||||
}
|
||||
|
||||
|
|
|
@ -164,49 +164,26 @@ llarp_router::HandleDHTLookupForSendTo(llarp_router_lookup_job *job)
|
|||
void
|
||||
llarp_router::try_connect(fs::path rcfile)
|
||||
{
|
||||
// FIXME: update API
|
||||
byte_t tmp[MAX_RC_SIZE];
|
||||
llarp_rc remote = {0};
|
||||
llarp_buffer_t buf;
|
||||
llarp::StackBuffer< decltype(tmp) >(buf, tmp);
|
||||
// open file
|
||||
llarp_rc *remote = new llarp_rc;
|
||||
llarp_rc_new(remote);
|
||||
remote = llarp_rc_read(rcfile.c_str());
|
||||
if (!remote)
|
||||
{
|
||||
std::ifstream f(rcfile, std::ios::binary);
|
||||
if(f.is_open())
|
||||
{
|
||||
f.seekg(0, std::ios::end);
|
||||
size_t sz = f.tellg();
|
||||
f.seekg(0, std::ios::beg);
|
||||
if(sz <= buf.sz)
|
||||
{
|
||||
f.read((char *)buf.base, sz);
|
||||
}
|
||||
else
|
||||
llarp::LogError(rcfile, " too large");
|
||||
}
|
||||
else
|
||||
{
|
||||
llarp::LogError("failed to open ", rcfile);
|
||||
return;
|
||||
}
|
||||
llarp::LogError("failure to decode or verify of remote RC");
|
||||
return;
|
||||
}
|
||||
if(llarp_rc_bdecode(&remote, &buf))
|
||||
if(llarp_rc_verify_sig(&crypto, remote))
|
||||
{
|
||||
if(llarp_rc_verify_sig(&crypto, &remote))
|
||||
llarp::Debug("verified signature");
|
||||
if(!llarp_router_try_connect(this, remote, 10))
|
||||
{
|
||||
llarp::LogDebug("verified signature");
|
||||
if(!llarp_router_try_connect(this, &remote, 10))
|
||||
{
|
||||
llarp::LogWarn("session already made");
|
||||
}
|
||||
// or error?
|
||||
llarp::LogWarn("session already made");
|
||||
}
|
||||
else
|
||||
llarp::LogError("failed to verify signature of RC", rcfile);
|
||||
}
|
||||
else
|
||||
llarp::LogError("failed to decode RC");
|
||||
|
||||
llarp_rc_free(&remote);
|
||||
llarp::LogError("failed to verify signature of RC", rcfile);
|
||||
llarp_rc_free(remote);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -266,6 +243,7 @@ llarp_router::SaveRC()
|
|||
void
|
||||
llarp_router::Close()
|
||||
{
|
||||
llarp::Info("Closing ", inboundLinks.size(), " server bindings");
|
||||
for(auto link : inboundLinks)
|
||||
{
|
||||
link->stop_link();
|
||||
|
@ -273,6 +251,7 @@ llarp_router::Close()
|
|||
}
|
||||
inboundLinks.clear();
|
||||
|
||||
llarp::Info("Closing LokiNetwork client");
|
||||
outboundLink->stop_link();
|
||||
delete outboundLink;
|
||||
outboundLink = nullptr;
|
||||
|
@ -637,8 +616,8 @@ llarp_router::Run()
|
|||
}
|
||||
if(a.isPrivate())
|
||||
{
|
||||
llarp::LogWarn("Skipping private network link: ", a);
|
||||
continue;
|
||||
//llarp::LogWarn("Skipping private network link: ", a);
|
||||
//continue;
|
||||
}
|
||||
llarp::LogInfo("Loading Addr: ", a, " into our RC");
|
||||
|
||||
|
|
|
@ -5,6 +5,15 @@
|
|||
#include "buffer.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
bool
|
||||
llarp_rc_new(struct llarp_rc *rc)
|
||||
{
|
||||
rc->addrs = llarp_ai_list_new();
|
||||
rc->exits = llarp_xi_list_new();
|
||||
rc->last_updated = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llarp_rc_free(struct llarp_rc *rc)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue