diff --git a/include/llarp/bencode.hpp b/include/llarp/bencode.hpp index 286421c97..f07d1483e 100644 --- a/include/llarp/bencode.hpp +++ b/include/llarp/bencode.hpp @@ -2,6 +2,7 @@ #define LLARP_BENCODE_HPP #include +#include namespace llarp { @@ -35,15 +36,14 @@ namespace llarp BEncodeMaybeReadDictEntry(const char* k, Item_t& item, bool& read, llarp_buffer_t key, llarp_buffer_t* buf) { - llarp_buffer_t strbuf; if(llarp_buffer_eq(key, k)) { - if(!bencode_read_string(buf, &strbuf)) - return false; if(!item.BDecode(buf)) + { + llarp::Warn("failed to decode key ", k); return false; + } read = true; - return true; } return true; } @@ -58,7 +58,6 @@ namespace llarp if(!bencode_read_integer(buf, &item)) return false; read = item == expect; - return true; } return true; } @@ -103,6 +102,6 @@ namespace llarp return bencode_write_bytestring(buf, k, 1) && BEncodeWriteList(list.begin(), list.end(), buf); } -} +} // namespace llarp #endif \ No newline at end of file diff --git a/include/llarp/dht.hpp b/include/llarp/dht.hpp index d3b4d13ef..49c2c4a7e 100644 --- a/include/llarp/dht.hpp +++ b/include/llarp/dht.hpp @@ -201,8 +201,8 @@ namespace llarp struct TXOwner { - Key_t requester = {0}; - uint64_t txid = 0; + Key_t requester; + uint64_t txid = 0; bool operator==(const TXOwner& other) const @@ -291,8 +291,8 @@ namespace llarp uint64_t txid = 0; uint64_t version = 0; }; - } -} + } // namespace dht +} // namespace llarp struct llarp_dht_context { diff --git a/include/llarp/encrypted.hpp b/include/llarp/encrypted.hpp index c58d2d467..05e46e514 100644 --- a/include/llarp/encrypted.hpp +++ b/include/llarp/encrypted.hpp @@ -11,27 +11,31 @@ namespace llarp /// encrypted buffer base type struct Encrypted { - Encrypted() = default; + Encrypted(Encrypted&&) = delete; + Encrypted(const byte_t* buf, size_t sz); Encrypted(size_t sz); + ~Encrypted(); bool BEncode(llarp_buffer_t* buf) const { - return bencode_write_bytestring(buf, _data.data(), _data.size()); + return bencode_write_bytestring(buf, _data, _sz); } void Fill(byte_t fill) { - std::fill(_data.begin(), _data.end(), fill); + size_t idx = 0; + while(idx < _sz) + _data[idx++] = fill; } void Randomize() { - if(_data.size()) - randombytes(_data.data(), _data.size()); + if(_data && _sz) + randombytes(_data, _sz); } bool @@ -42,8 +46,12 @@ namespace llarp return false; if(strbuf.sz == 0) return false; - _data.resize(strbuf.sz); - memcpy(_data.data(), strbuf.base, _data.size()); + if(_data) + delete[] _data; + _sz = strbuf.sz; + _data = new byte_t[_sz]; + memcpy(_data, strbuf.base, _sz); + UpdateBuffer(); return true; } @@ -56,24 +64,31 @@ namespace llarp size_t size() { - return _data.size(); + return _sz; } size_t size() const { - return _data.size(); + return _sz; } byte_t* data() { - return _data.data(); + return _data; } - std::vector< byte_t > _data; - - private: + protected: + void + UpdateBuffer() + { + m_Buffer.base = data(); + m_Buffer.cur = data(); + m_Buffer.sz = size(); + } + byte_t* _data = nullptr; + size_t _sz = 0; llarp_buffer_t m_Buffer; }; } // namespace llarp diff --git a/include/llarp/encrypted_frame.hpp b/include/llarp/encrypted_frame.hpp index 81252d215..3d3b66317 100644 --- a/include/llarp/encrypted_frame.hpp +++ b/include/llarp/encrypted_frame.hpp @@ -12,7 +12,16 @@ namespace llarp { static constexpr size_t OverheadSize = PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE; - EncryptedFrame() = default; + + EncryptedFrame() : EncryptedFrame(256) + { + } + + EncryptedFrame(const EncryptedFrame& other) + : EncryptedFrame(other._data, other._sz) + { + } + EncryptedFrame(byte_t* buf, size_t sz) : Encrypted(buf, sz) { } @@ -21,6 +30,17 @@ namespace llarp { } + EncryptedFrame& + operator=(const EncryptedFrame& other) + { + if(_data) + delete[] _data; + _sz = other._sz; + _data = new byte_t[_sz]; + memcpy(_data, other._data, _sz); + return *this; + } + bool DecryptInPlace(byte_t* seckey, llarp_crypto* crypto); @@ -87,7 +107,11 @@ namespace llarp static_cast< AsyncFrameDecrypter< User >* >(user); if(ctx->target->DecryptInPlace(ctx->seckey, ctx->crypto)) - ctx->result(ctx->target->Buffer(), ctx->context); + { + auto buf = ctx->target->Buffer(); + buf->cur = buf->base + EncryptedFrame::OverheadSize; + ctx->result(buf, ctx->context); + } else ctx->result(nullptr, ctx->context); } diff --git a/include/llarp/messages/relay_commit.hpp b/include/llarp/messages/relay_commit.hpp index 90d4438a5..a7648b83f 100644 --- a/include/llarp/messages/relay_commit.hpp +++ b/include/llarp/messages/relay_commit.hpp @@ -19,8 +19,8 @@ namespace llarp RouterID nextHop; TunnelNonce tunnelNonce; PathID_t pathid; - PoW *work = nullptr; - uint64_t version; + PoW *work = nullptr; + uint64_t version = 0; bool BDecode(llarp_buffer_t *buf); @@ -30,25 +30,14 @@ namespace llarp ~LR_CommitRecord(); + bool + operator==(const LR_CommitRecord &other) const; + private: static bool OnKey(dict_reader *r, llarp_buffer_t *buf); }; - struct LR_AcceptRecord - { - RouterID upstream; - RouterID downstream; - PathID_t pathid; - uint64_t version = LLARP_PROTO_VERSION; - - bool - DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf); - - bool - BEncode(llarp_buffer_t *buf) const; - }; - struct LR_CommitMessage : public ILinkMessage { std::vector< EncryptedFrame > frames; diff --git a/include/llarp/path.hpp b/include/llarp/path.hpp index 65734ac11..753f4f40a 100644 --- a/include/llarp/path.hpp +++ b/include/llarp/path.hpp @@ -155,117 +155,6 @@ namespace llarp Upstream(); }; - template < typename User > - struct AsyncPathKeyExchangeContext - { - Path* path = nullptr; - typedef void (*Handler)(AsyncPathKeyExchangeContext< User >*); - User* user = nullptr; - Handler result = nullptr; - size_t idx = 0; - llarp_threadpool* worker = nullptr; - llarp_logic* logic = nullptr; - llarp_crypto* crypto = nullptr; - LR_CommitMessage* LRCM = nullptr; - - static void - HandleDone(void* u) - { - AsyncPathKeyExchangeContext< User >* ctx = - static_cast< AsyncPathKeyExchangeContext< User >* >(u); - ctx->result(ctx); - } - - static void - GenerateNextKey(void* u) - { - AsyncPathKeyExchangeContext< User >* ctx = - static_cast< AsyncPathKeyExchangeContext< User >* >(u); - - auto& hop = ctx->path->hops[ctx->idx]; - // generate key - ctx->crypto->encryption_keygen(hop.commkey); - hop.nonce.Randomize(); - // do key exchange - if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey, - hop.nonce)) - { - llarp::Error("Failed to generate shared key for path build"); - abort(); - return; - } - // randomize hop's path id - hop.pathID.Randomize(); - - LR_CommitRecord record; - - auto& frame = ctx->LRCM->frames[ctx->idx]; - ++ctx->idx; - if(ctx->idx < ctx->path->hops.size()) - { - hop.upstream = ctx->path->hops[ctx->idx].router.pubkey; - } - else - { - hop.upstream = hop.router.pubkey; - } - auto buf = frame.Buffer(); - buf->cur = buf->base + EncryptedFrame::OverheadSize; - // generate record - if(!record.BEncode(buf)) - { - // failed to encode? - llarp::Error("Failed to generate Commit Record"); - abort(); - return; - } - // rewind - buf->cur = buf->base; - - if(!frame.EncryptInPlace(hop.commkey, hop.router.enckey, ctx->crypto)) - { - llarp::Error("Failed to encrypt LRCR"); - abort(); - return; - } - - if(ctx->idx < ctx->path->hops.size()) - { - // next hop - llarp_threadpool_queue_job(ctx->worker, {ctx, &GenerateNextKey}); - } - else - { - // farthest hop - llarp_logic_queue_job(ctx->logic, {ctx, &HandleDone}); - } - } - - AsyncPathKeyExchangeContext(llarp_crypto* c) : crypto(c) - { - } - - /// Generate all keys asynchronously and call hadler when done - void - AsyncGenerateKeys(Path* p, llarp_logic* l, llarp_threadpool* pool, User* u, - Handler func) - { - path = p; - logic = l; - user = u; - result = func; - worker = pool; - LRCM = new LR_CommitMessage; - - for(size_t idx = 0; idx < MAXHOPS; ++idx) - { - LRCM->frames.emplace_back(256); - LRCM->frames.back().Randomize(); - } - llarp_threadpool_queue_job(pool, {this, &GenerateNextKey}); - } - }; - enum PathBuildStatus { ePathBuildSuccess, diff --git a/include/llarp/pow.hpp b/include/llarp/pow.hpp index 92f7cf6fb..d03fd2326 100644 --- a/include/llarp/pow.hpp +++ b/include/llarp/pow.hpp @@ -14,7 +14,7 @@ namespace llarp RouterID router; uint64_t version = 0; uint32_t extendedLifetime = 0; - byte_t nonce[32]; + AlignedBuffer< 32 > nonce; bool BEncode(llarp_buffer_t* buf) const; @@ -24,6 +24,19 @@ namespace llarp bool IsValid(llarp_shorthash_func hashfunc, const RouterID& us) const; + + bool + operator==(const PoW& other) const + { + return router == other.router && version == other.version + && extendedLifetime == other.extendedLifetime && nonce == other.nonce; + } + + bool + operator!=(const PoW& other) const + { + return !(*this == other); + } }; } // namespace llarp diff --git a/llarp/encrypted_frame.cpp b/llarp/encrypted_frame.cpp index 205b5fbc5..070ce68be 100644 --- a/llarp/encrypted_frame.cpp +++ b/llarp/encrypted_frame.cpp @@ -5,15 +5,19 @@ namespace llarp { - Encrypted::Encrypted(const byte_t* buf, size_t sz) : _data(sz) + Encrypted::Encrypted(const byte_t* buf, size_t sz) : _sz(sz) { + _data = new byte_t[sz]; if(buf) memcpy(data(), buf, sz); else llarp::Zero(data(), sz); - m_Buffer.base = data(); - m_Buffer.cur = data(); - m_Buffer.sz = size(); + UpdateBuffer(); + } + Encrypted::~Encrypted() + { + if(_data) + delete[] _data; } Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz) diff --git a/llarp/path.cpp b/llarp/path.cpp index 0ee2381e6..767a372eb 100644 --- a/llarp/path.cpp +++ b/llarp/path.cpp @@ -64,10 +64,10 @@ namespace llarp LR_CommitMessage* msg = new LR_CommitMessage; while(frames.size()) { - msg->frames.push_back(frames.back()); - frames.pop_back(); + msg->frames.push_back(frames.front()); + frames.pop_front(); } - return m_Router->SendToOrQueue(nextHop, {msg}); + return m_Router->SendToOrQueue(nextHop, msg); } template < typename Map_t, typename Key_t, typename CheckValue_t > diff --git a/llarp/pathbuilder.cpp b/llarp/pathbuilder.cpp index f8c7f5633..a83b797ee 100644 --- a/llarp/pathbuilder.cpp +++ b/llarp/pathbuilder.cpp @@ -6,6 +6,115 @@ namespace llarp { + template < typename User > + struct AsyncPathKeyExchangeContext + { + Path* path = nullptr; + typedef void (*Handler)(AsyncPathKeyExchangeContext< User >*); + User* user = nullptr; + Handler result = nullptr; + size_t idx = 0; + llarp_threadpool* worker = nullptr; + llarp_logic* logic = nullptr; + llarp_crypto* crypto = nullptr; + LR_CommitMessage* LRCM = nullptr; + + static void + HandleDone(void* u) + { + AsyncPathKeyExchangeContext< User >* ctx = + static_cast< AsyncPathKeyExchangeContext< User >* >(u); + ctx->result(ctx); + } + + static void + GenerateNextKey(void* u) + { + AsyncPathKeyExchangeContext< User >* ctx = + static_cast< AsyncPathKeyExchangeContext< User >* >(u); + + auto& hop = ctx->path->hops[ctx->idx]; + auto& frame = ctx->LRCM->frames[ctx->idx]; + // generate key + ctx->crypto->encryption_keygen(hop.commkey); + hop.nonce.Randomize(); + // do key exchange + if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey, + hop.nonce)) + { + llarp::Error("Failed to generate shared key for path build"); + abort(); + return; + } + // randomize hop's path id + hop.pathID.Randomize(); + + LR_CommitRecord record; + + ++ctx->idx; + if(ctx->idx < ctx->path->hops.size()) + { + hop.upstream = ctx->path->hops[ctx->idx].router.pubkey; + } + else + { + hop.upstream = hop.router.pubkey; + } + auto buf = frame.Buffer(); + buf->cur = buf->base + EncryptedFrame::OverheadSize; + // generate record + if(!record.BEncode(buf)) + { + // failed to encode? + llarp::Error("Failed to generate Commit Record"); + return; + } + // use ephameral keypair for frame + SecretKey framekey; + ctx->crypto->encryption_keygen(framekey); + if(!frame.EncryptInPlace(framekey, hop.router.enckey, ctx->crypto)) + { + llarp::Error("Failed to encrypt LRCR"); + return; + } + + if(ctx->idx < ctx->path->hops.size()) + { + // next hop + llarp_threadpool_queue_job(ctx->worker, {ctx, &GenerateNextKey}); + } + else + { + // farthest hop + llarp_logic_queue_job(ctx->logic, {ctx, &HandleDone}); + } + } + + AsyncPathKeyExchangeContext(llarp_crypto* c) : crypto(c) + { + } + + /// Generate all keys asynchronously and call hadler when done + void + AsyncGenerateKeys(Path* p, llarp_logic* l, llarp_threadpool* pool, User* u, + Handler func) + { + path = p; + logic = l; + user = u; + result = func; + worker = pool; + LRCM = new LR_CommitMessage; + + for(size_t idx = 0; idx < MAXHOPS; ++idx) + { + LRCM->frames.emplace_back(); + LRCM->frames.back().Randomize(); + } + llarp_threadpool_queue_job(pool, {this, &GenerateNextKey}); + } + }; + PathHopConfig::PathHopConfig() { llarp_rc_clear(&router); @@ -21,7 +130,7 @@ namespace llarp AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx) { auto remote = ctx->path->Upstream(); - llarp::Debug("Generated LRCM to", remote); + llarp::Info("Generated LRCM to ", remote); auto router = ctx->user->router; if(!router->SendToOrQueue(remote, ctx->LRCM)) { @@ -65,27 +174,28 @@ llarp_pathbuilder_context::llarp_pathbuilder_context( { } -extern "C" { -struct llarp_pathbuilder_context* -llarp_pathbuilder_context_new(struct llarp_router* router, - struct llarp_dht_context* dht) +extern "C" { - return new llarp_pathbuilder_context(router, dht); -} + struct llarp_pathbuilder_context* + llarp_pathbuilder_context_new(struct llarp_router* router, + struct llarp_dht_context* dht) + { + return new llarp_pathbuilder_context(router, dht); + } -void -llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx) -{ - delete ctx; -} + void + llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx) + { + delete ctx; + } -void -llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job) -{ - job->router = job->context->router; - if(job->selectHop == nullptr) - job->selectHop = &llarp_nodedb_select_random_hop; - llarp_logic_queue_job(job->router->logic, - {job, &llarp::pathbuilder_start_build}); -} + void + llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job) + { + job->router = job->context->router; + if(job->selectHop == nullptr) + job->selectHop = &llarp_nodedb_select_random_hop; + llarp_logic_queue_job(job->router->logic, + {job, &llarp::pathbuilder_start_build}); + } } \ No newline at end of file diff --git a/llarp/relay_commit.cpp b/llarp/relay_commit.cpp index 40dbe4f4e..68ae6fb02 100644 --- a/llarp/relay_commit.cpp +++ b/llarp/relay_commit.cpp @@ -5,24 +5,6 @@ namespace llarp { - bool - LR_AcceptRecord::BEncode(llarp_buffer_t* buf) const - { - if(!bencode_start_dict(buf)) - return false; - if(!BEncodeWriteDictMsgType(buf, "c", "a")) - return false; - if(!BEncodeWriteDictEntry("p", pathid, buf)) - return false; - if(!BEncodeWriteDictEntry("r", downstream, buf)) - return false; - if(!BEncodeWriteDictEntry("t", upstream, buf)) - return false; - if(!BEncodeWriteDictInt(buf, "v", LLARP_PROTO_VERSION)) - return false; - return bencode_end(buf); - } - LR_CommitMessage::~LR_CommitMessage() { } @@ -121,7 +103,8 @@ namespace llarp return false; if(!BEncodeMaybeReadDictEntry("i", self->nextHop, read, *key, r->buffer)) return false; - if(BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key, r->buffer)) + if(!BEncodeMaybeReadDictEntry("n", self->tunnelNonce, read, *key, + r->buffer)) return false; if(!BEncodeMaybeReadDictEntry("p", self->pathid, read, *key, r->buffer)) return false; @@ -132,7 +115,10 @@ namespace llarp { // check for duplicate if(self->work) + { + llarp::Warn("duplicate POW in LRCR"); return false; + } self->work = new PoW; return self->work->BDecode(r->buffer); @@ -149,6 +135,18 @@ namespace llarp return bencode_read_dict(buf, &r); } + bool + LR_CommitRecord::operator==(const LR_CommitRecord& other) const + { + if(work && other.work) + { + if(*work != *other.work) + return false; + } + return nextHop == other.nextHop && commkey == other.commkey + && pathid == other.pathid; + } + struct LRCMFrameDecrypt { typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter; @@ -165,7 +163,7 @@ namespace llarp : decrypter(dec), context(ctx) { for(const auto& f : commit->frames) - frames.push_front(f); + frames.push_back(f); hop.info.downstream = commit->remote; } @@ -198,6 +196,7 @@ namespace llarp delete self; return; } + buf->cur = buf->base + EncryptedFrame::OverheadSize; llarp::Debug("decrypted LRCM from ", info.downstream); // successful decrypt if(!self->record.BDecode(buf)) @@ -243,32 +242,9 @@ namespace llarp self->frames.pop_front(); // put our response on the end self->frames.emplace_back(sz); - auto& reply = self->frames.back(); - auto replybuf = reply.Buffer(); - LR_AcceptRecord replyrecord; - replyrecord.upstream = info.upstream; - replyrecord.downstream = info.downstream; - replyrecord.pathid = info.pathID; - if(!replyrecord.BEncode(replybuf)) - { - llarp::Error("failed to encode reply to LRCM, buffer too small?"); - delete self; - return; - } - // randomize leftover data inside reply - auto left = llarp_buffer_size_left(*replybuf); - if(left) - self->context->Crypto()->randbytes(replybuf->cur, left); + // random junk for now + self->frames.back().Randomize(); - // encrypt in place since we are in the worker thread - if(!reply.EncryptInPlace(self->context->EncryptionSecretKey(), - self->record.commkey, self->context->Crypto())) - { - // failed to encrypt wtf? - llarp::Error("Failed to encrypt reply to LRCM"); - delete self; - return; - } if(self->context->HopIsUs(info.upstream)) { // we are the farthest hop diff --git a/llarp/router.cpp b/llarp/router.cpp index 010de39fa..06778dd7b 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -220,6 +220,8 @@ llarp_router::EnsureEncryptionKey() return false; } f.read((char *)encryption.data(), encryption.size()); + llarp::PubKey onionenckey = llarp::seckey_topublic(encryption); + llarp::Info("encryption key loaded ", onionenckey); return true; } @@ -652,7 +654,8 @@ llarp_router::Run() llarp_logic_call_later(logic, {delay, this, &ConnectAll}); } else - { // delayed connect all for clients + { + // delayed connect all for clients auto delay = ((rand() % 10) * 500) + 1000; llarp_logic_call_later(logic, {delay, this, &ConnectAll}); } @@ -725,209 +728,210 @@ llarp_router::HasPendingConnectJob(const llarp::RouterID &remote) return pendingEstablishJobs.find(remote) != pendingEstablishJobs.end(); } -extern "C" { -struct llarp_router * -llarp_init_router(struct llarp_threadpool *tp, struct llarp_ev_loop *netloop, - struct llarp_logic *logic) +extern "C" { - llarp_router *router = new llarp_router(); - if(router) + struct llarp_router * + llarp_init_router(struct llarp_threadpool *tp, struct llarp_ev_loop *netloop, + struct llarp_logic *logic) { - router->netloop = netloop; - router->tp = tp; - router->logic = logic; - // TODO: make disk io threadpool count configurable + llarp_router *router = new llarp_router(); + if(router) + { + router->netloop = netloop; + router->tp = tp; + router->logic = logic; + // TODO: make disk io threadpool count configurable #ifdef TESTNET - router->disk = tp; + router->disk = tp; #else - router->disk = llarp_init_threadpool(1, "llarp-diskio"); + router->disk = llarp_init_threadpool(1, "llarp-diskio"); #endif - llarp_crypto_libsodium_init(&router->crypto); + llarp_crypto_libsodium_init(&router->crypto); + } + return router; } - return router; -} -bool -llarp_configure_router(struct llarp_router *router, struct llarp_config *conf) -{ - llarp_config_iterator iter; - iter.user = router; - iter.visit = llarp::router_iter_config; - llarp_config_iter(conf, &iter); - if(!router->InitOutboundLink()) - return false; - if(!router->Ready()) + bool + llarp_configure_router(struct llarp_router *router, struct llarp_config *conf) { - return false; + llarp_config_iterator iter; + iter.user = router; + iter.visit = llarp::router_iter_config; + llarp_config_iter(conf, &iter); + if(!router->InitOutboundLink()) + return false; + if(!router->Ready()) + { + return false; + } + return router->EnsureIdentity(); } - return router->EnsureIdentity(); -} -void -llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb) -{ - router->nodedb = nodedb; - router->Run(); -} + void + llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb) + { + router->nodedb = nodedb; + router->Run(); + } -bool -llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote, - uint16_t numretries) -{ - // do we already have a pending job for this remote? - if(router->HasPendingConnectJob(remote->pubkey)) - return false; - // try first address only - llarp_ai addr; - if(llarp_ai_list_index(remote->addrs, 0, &addr)) + bool + llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote, + uint16_t numretries) { - auto link = router->outboundLink; - auto itr = router->pendingEstablishJobs.emplace( - std::make_pair(remote->pubkey, llarp_link_establish_job{})); - auto job = &itr.first->second; - llarp_ai_copy(&job->ai, &addr); - memcpy(job->pubkey, remote->pubkey, PUBKEYSIZE); - job->retries = numretries; - job->timeout = 10000; - job->result = &llarp_router::on_try_connect_result; - // give router as user pointer - job->user = router; - // try establishing - link->try_establish(link, job); - return true; + // do we already have a pending job for this remote? + if(router->HasPendingConnectJob(remote->pubkey)) + return false; + // try first address only + llarp_ai addr; + if(llarp_ai_list_index(remote->addrs, 0, &addr)) + { + auto link = router->outboundLink; + auto itr = router->pendingEstablishJobs.emplace( + std::make_pair(remote->pubkey, llarp_link_establish_job{})); + auto job = &itr.first->second; + llarp_ai_copy(&job->ai, &addr); + memcpy(job->pubkey, remote->pubkey, PUBKEYSIZE); + job->retries = numretries; + job->timeout = 10000; + job->result = &llarp_router::on_try_connect_result; + // give router as user pointer + job->user = router; + // try establishing + link->try_establish(link, job); + return true; + } + return false; } - return false; -} -void -llarp_rc_clear(struct llarp_rc *rc) -{ - // zero out router contact - llarp::Zero(rc, sizeof(llarp_rc)); -} + void + llarp_rc_clear(struct llarp_rc *rc) + { + // zero out router contact + llarp::Zero(rc, sizeof(llarp_rc)); + } -bool -llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai) -{ - struct llarp_rc *rc = (llarp_rc *)iter->user; - llarp_ai_list_pushback(rc->addrs, ai); - return true; -} + bool + llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai) + { + struct llarp_rc *rc = (llarp_rc *)iter->user; + llarp_ai_list_pushback(rc->addrs, ai); + return true; + } -void -llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem, - struct llarp_ai_list *addr) -{ - rc->addrs = llarp_ai_list_new(); - struct llarp_ai_list_iter ai_itr; - ai_itr.user = rc; - ai_itr.visit = &llarp_rc_addr_list_iter; - llarp_ai_list_iterate(addr, &ai_itr); -} + void + llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem, + struct llarp_ai_list *addr) + { + rc->addrs = llarp_ai_list_new(); + struct llarp_ai_list_iter ai_itr; + ai_itr.user = rc; + ai_itr.visit = &llarp_rc_addr_list_iter; + llarp_ai_list_iterate(addr, &ai_itr); + } -void -llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey) -{ - // set public key - memcpy(rc->pubkey, pubkey, 32); -} + void + llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubkey) + { + // set public key + memcpy(rc->pubkey, pubkey, 32); + } -bool -llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath, - byte_t *secretkey) -{ - llarp::Debug("find or create ", fpath); - fs::path path(fpath); - std::error_code ec; - if(!fs::exists(path, ec)) + bool + llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath, + byte_t *secretkey) { - llarp::Info("regenerated identity key"); - crypto->identity_keygen(secretkey); - std::ofstream f(path, std::ios::binary); + llarp::Debug("find or create ", fpath); + fs::path path(fpath); + std::error_code ec; + if(!fs::exists(path, ec)) + { + llarp::Info("regenerated identity key"); + crypto->identity_keygen(secretkey); + std::ofstream f(path, std::ios::binary); + if(f.is_open()) + { + f.write((char *)secretkey, SECKEYSIZE); + } + } + std::ifstream f(path, std::ios::binary); if(f.is_open()) { - f.write((char *)secretkey, SECKEYSIZE); + f.read((char *)secretkey, SECKEYSIZE); + return true; } + llarp::Info("failed to get identity key"); + return false; } - std::ifstream f(path, std::ios::binary); - if(f.is_open()) + + bool + llarp_rc_write(struct llarp_rc *rc, const char *fpath) { - f.read((char *)secretkey, SECKEYSIZE); - return true; - } - llarp::Info("failed to get identity key"); - return false; -} + fs::path our_rc_file(fpath); + byte_t tmp[MAX_RC_SIZE]; + auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); -bool -llarp_rc_write(struct llarp_rc *rc, const char *fpath) -{ - fs::path our_rc_file(fpath); - byte_t tmp[MAX_RC_SIZE]; - auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); + if(llarp_rc_bencode(rc, &buf)) + { + std::ofstream f(our_rc_file, std::ios::binary); + if(f.is_open()) + { + f.write((char *)buf.base, buf.cur - buf.base); + return true; + } + } + return false; + } - if(llarp_rc_bencode(rc, &buf)) + void + llarp_rc_sign(llarp_crypto *crypto, const byte_t *seckey, struct llarp_rc *rc) { - std::ofstream f(our_rc_file, std::ios::binary); - if(f.is_open()) + byte_t buf[MAX_RC_SIZE]; + auto signbuf = llarp::StackBuffer< decltype(buf) >(buf); + // zero out previous signature + llarp::Zero(rc->signature, sizeof(rc->signature)); + // encode + if(llarp_rc_bencode(rc, &signbuf)) { - f.write((char *)buf.base, buf.cur - buf.base); - return true; + // sign + signbuf.sz = signbuf.cur - signbuf.base; + crypto->sign(rc->signature, seckey, signbuf); } } - return false; -} -void -llarp_rc_sign(llarp_crypto *crypto, const byte_t *seckey, struct llarp_rc *rc) -{ - byte_t buf[MAX_RC_SIZE]; - auto signbuf = llarp::StackBuffer< decltype(buf) >(buf); - // zero out previous signature - llarp::Zero(rc->signature, sizeof(rc->signature)); - // encode - if(llarp_rc_bencode(rc, &signbuf)) + void + llarp_stop_router(struct llarp_router *router) { - // sign - signbuf.sz = signbuf.cur - signbuf.base; - crypto->sign(rc->signature, seckey, signbuf); + if(router) + router->Close(); } -} - -void -llarp_stop_router(struct llarp_router *router) -{ - if(router) - router->Close(); -} -void -llarp_router_iterate_links(struct llarp_router *router, - struct llarp_router_link_iter i) -{ - for(auto link : router->inboundLinks) - if(!i.visit(&i, router, link)) - return; - i.visit(&i, router, router->outboundLink); -} + void + llarp_router_iterate_links(struct llarp_router *router, + struct llarp_router_link_iter i) + { + for(auto link : router->inboundLinks) + if(!i.visit(&i, router, link)) + return; + i.visit(&i, router, router->outboundLink); + } -void -llarp_free_router(struct llarp_router **router) -{ - if(*router) + void + llarp_free_router(struct llarp_router **router) { - delete *router; + if(*router) + { + delete *router; + } + *router = nullptr; } - *router = nullptr; -} -void -llarp_router_override_path_selection(struct llarp_router *router, - llarp_pathbuilder_select_hop_func func) -{ - if(func) - router->selectHopFunc = func; -} + void + llarp_router_override_path_selection(struct llarp_router *router, + llarp_pathbuilder_select_hop_func func) + { + if(func) + router->selectHopFunc = func; + } } namespace llarp diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index aca906860..cf83b3bfb 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -6,7 +6,6 @@ #include "logger.hpp" extern "C" { - void llarp_rc_free(struct llarp_rc *rc) { @@ -157,7 +156,7 @@ llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc) result = crypto->verify(rc->pubkey, buf, sig); } else - llarp::Warn(__FILE__, "RC encode failed"); + llarp::Warn("RC encode failed"); // restore sig memcpy(rc->signature, sig, SIGSIZE); return result; diff --git a/test/encrypted_frame_unittest.cpp b/test/encrypted_frame_unittest.cpp index bddb5e834..9d737f87d 100644 --- a/test/encrypted_frame_unittest.cpp +++ b/test/encrypted_frame_unittest.cpp @@ -6,7 +6,7 @@ using EncryptedFrame = llarp::EncryptedFrame; using SecretKey = llarp::SecretKey; using PubKey = llarp::PubKey; -using LRAR = llarp::LR_AcceptRecord; +using LRCR = llarp::LR_CommitRecord; class FrameTest : public ::testing::Test { @@ -40,9 +40,9 @@ TEST_F(FrameTest, TestFrameCrypto) { EncryptedFrame f(256); f.Fill(0); - LRAR record; - record.upstream.Fill(1); - record.downstream.Fill(2); + LRCR record; + record.nextHop.Fill(1); + record.tunnelNonce.Fill(2); record.pathid.Fill(3); auto buf = f.Buffer(); @@ -50,8 +50,14 @@ TEST_F(FrameTest, TestFrameCrypto) ASSERT_TRUE(record.BEncode(buf)); - buf->cur = buf->base; - // encrypt alice to bob + // rewind buffer + buf->cur = buf->base + EncryptedFrame::OverheadSize; + // encrypt to alice ASSERT_TRUE(f.EncryptInPlace(alice, llarp::seckey_topublic(bob), &crypto)); + // decrypt from alice ASSERT_TRUE(f.DecryptInPlace(bob, &crypto)); + + LRCR otherRecord; + ASSERT_TRUE(otherRecord.BDecode(buf)); + ASSERT_TRUE(otherRecord == record); }; \ No newline at end of file