From 5228a81bae914a2a28ea2ec80bab73f6c0720a54 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 30 Aug 2018 14:48:43 -0400 Subject: [PATCH] more refactor get rid of C api --- daemon/rcutil.cpp | 2 +- include/llarp.h | 2 - include/llarp.hpp | 1 + include/llarp/address_info.hpp | 36 +++ include/llarp/bencode.hpp | 53 ++- include/llarp/dht.h | 26 -- include/llarp/dht/context.hpp | 32 +- include/llarp/dht/messages/gotrouter.hpp | 14 +- include/llarp/dht/node.hpp | 13 +- include/llarp/encrypted.hpp | 26 +- include/llarp/encrypted_frame.hpp | 7 +- include/llarp/exit_info.hpp | 45 +++ include/llarp/iwp/establish_job.hpp | 8 +- include/llarp/iwp/frame_state.hpp | 2 +- include/llarp/iwp/inbound_message.hpp | 22 +- include/llarp/iwp/sendbuf.hpp | 31 +- include/llarp/iwp/server.hpp | 2 +- include/llarp/iwp/session.hpp | 11 +- include/llarp/messages/link_intro.hpp | 8 +- include/llarp/messages/relay_commit.hpp | 2 +- include/llarp/net.hpp | 4 +- include/llarp/{nodedb.h => nodedb.hpp} | 39 ++- include/llarp/path.h | 28 -- include/llarp/path.hpp | 19 +- include/llarp/pathbuilder.h | 62 ---- include/llarp/pathbuilder.hpp | 66 ++-- include/llarp/pathset.hpp | 11 +- include/llarp/router.h | 15 +- include/llarp/router_contact.h | 115 ------- include/llarp/router_contact.hpp | 67 ++++ include/llarp/service/endpoint.hpp | 8 +- llarp/context.cpp | 38 --- llarp/crypto_async.cpp | 2 +- llarp/dht.cpp | 20 -- llarp/dht/context.cpp | 77 ++--- llarp/dht/find_router.cpp | 68 +--- llarp/dht/got_router.cpp | 3 - llarp/encrypted_frame.cpp | 6 +- llarp/iwp/frame_state.cpp | 52 +-- llarp/iwp/server.cpp | 17 +- llarp/iwp/session.cpp | 34 +- llarp/link/encoder.cpp | 4 +- llarp/link/encoder.hpp | 4 +- llarp/link_intro.cpp | 17 +- llarp/link_message.cpp | 5 +- llarp/nodedb.cpp | 199 ++++-------- llarp/path.cpp | 31 +- llarp/pathbuilder.cpp | 221 ++++++------- llarp/relay_commit.cpp | 31 +- llarp/router.cpp | 392 ++++++----------------- llarp/router.hpp | 49 +-- llarp/router_contact.cpp | 282 ++++------------ llarp/router_contact.hpp | 5 - llarp/service/endpoint.cpp | 22 +- llarp/threadpool.cpp | 34 +- llarp/threadpool.hpp | 15 +- llarp/timer.cpp | 43 ++- 57 files changed, 910 insertions(+), 1538 deletions(-) create mode 100644 include/llarp/address_info.hpp create mode 100644 include/llarp/exit_info.hpp rename include/llarp/{nodedb.h => nodedb.hpp} (80%) delete mode 100644 include/llarp/path.h delete mode 100644 include/llarp/pathbuilder.h delete mode 100644 include/llarp/router_contact.h create mode 100644 include/llarp/router_contact.hpp diff --git a/daemon/rcutil.cpp b/daemon/rcutil.cpp index fcc5dc0e8..ed107bd67 100644 --- a/daemon/rcutil.cpp +++ b/daemon/rcutil.cpp @@ -3,7 +3,7 @@ #include #include "logger.hpp" -#include +#include #include #include diff --git a/include/llarp.h b/include/llarp.h index 4ae0819cc..260aa440e 100644 --- a/include/llarp.h +++ b/include/llarp.h @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include #ifdef __cplusplus diff --git a/include/llarp.hpp b/include/llarp.hpp index e5ef4b314..fc7f579c7 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace llarp { diff --git a/include/llarp/address_info.hpp b/include/llarp/address_info.hpp new file mode 100644 index 000000000..3c8937688 --- /dev/null +++ b/include/llarp/address_info.hpp @@ -0,0 +1,36 @@ +#ifndef LLARP_AI_HPP +#define LLARP_AI_HPP +#include +#include +#include +#include + +#include + +/** + * address_info.hpp + * + * utilities for handling addresses on the llarp network + */ + +/// address information model +namespace llarp +{ + struct AddressInfo + { + uint16_t rank; + std::string dialect; + llarp::PubKey pubkey; + struct in6_addr ip; + uint16_t port; + + bool + BEncode(llarp_buffer_t *buf) const; + + bool + BDecode(llarp_buffer_t *buf); + }; + +} // namespace llarp + +#endif diff --git a/include/llarp/bencode.hpp b/include/llarp/bencode.hpp index a60e149f4..0a68909fe 100644 --- a/include/llarp/bencode.hpp +++ b/include/llarp/bencode.hpp @@ -38,6 +38,20 @@ namespace llarp return bencode_write_bytestring(buf, k, 1) && bencode_write_uint64(buf, i); } + template < typename List_t > + bool + BEncodeMaybeReadDictList(const char* k, List_t& item, bool& read, + llarp_buffer_t key, llarp_buffer_t* buf) + { + if(llarp_buffer_eq(key, k)) + { + if(!BEncodeReadList(item, buf)) + return false; + read = true; + } + return true; + } + template < typename Item_t > bool BEncodeMaybeReadDictEntry(const char* k, Item_t& item, bool& read, @@ -105,6 +119,43 @@ namespace llarp return bencode_end(buf); } + template < typename Array > + bool + BEncodeWriteDictArray(const char* k, const Array& array, llarp_buffer_t* buf) + { + if(!bencode_write_bytestring(buf, k, 1)) + return false; + if(!bencode_start_list(buf)) + return false; + + for(size_t idx = 0; idx < array.size(); ++idx) + if(!array[idx].BEncode(buf)) + return false; + return bencode_end(buf); + } + + template < typename Array > + bool + BEncodeReadArray(Array& array, llarp_buffer_t* buf) + { + if(*buf->cur != 'l') // ensure is a list + return false; + + buf->cur++; + size_t idx = 0; + while(llarp_buffer_size_left(*buf) && *buf->cur != 'e') + { + if(idx >= array.size()) + return false; + if(!array[idx++].BDecode(buf)) + return false; + } + if(*buf->cur != 'e') // make sure we're at a list end + return false; + buf->cur++; + return true; + } + template < typename Iter > bool BEncodeWriteList(Iter itr, Iter end, llarp_buffer_t* buf) @@ -212,4 +263,4 @@ namespace llarp } // namespace llarp -#endif \ No newline at end of file +#endif diff --git a/include/llarp/dht.h b/include/llarp/dht.h index c1f6a48f4..d35358917 100644 --- a/include/llarp/dht.h +++ b/include/llarp/dht.h @@ -24,39 +24,13 @@ llarp_dht_context_free(struct llarp_dht_context* dht); void llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key); -struct llarp_router_lookup_job; - -typedef void (*llarp_router_lookup_handler)(struct llarp_router_lookup_job*); - -struct llarp_router_lookup_job -{ - /// can be anything but usually a class context for hook - void* user; - llarp_router_lookup_handler hook; - 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 void llarp_dht_allow_transit(struct llarp_dht_context* ctx); -/// put router as a dht peer -/// internal function do not use -void -__llarp_dht_put_peer(struct llarp_dht_context* ctx, struct llarp_rc* rc); - /// remove router from tracked dht peer list /// internal function do not use void __llarp_dht_remove_peer(struct llarp_dht_context* ctx, const byte_t* id); -void -llarp_dht_lookup_router(struct llarp_dht_context* ctx, - struct llarp_router_lookup_job* job); - #endif diff --git a/include/llarp/dht/context.hpp b/include/llarp/dht/context.hpp index aadfd60ec..fb61886cd 100644 --- a/include/llarp/dht/context.hpp +++ b/include/llarp/dht/context.hpp @@ -106,6 +106,9 @@ namespace llarp typedef std::function< void(const std::vector< service::IntroSet >&) > IntroSetLookupHandler; + typedef std::function< void(const std::vector< RouterContact >&) > + RouterLookupHandler; + struct Context { Context(); @@ -130,7 +133,17 @@ namespace llarp void LookupRouterRecursive(const RouterID& target, const Key_t& whoasked, uint64_t whoaskedTX, const Key_t& askpeer, - llarp_router_lookup_job* job = nullptr); + RouterLookupHandler result = nullptr); + + bool + LookupRouter(const RouterID& target, RouterLookupHandler result) + { + Key_t askpeer; + if(!nodes->FindClosest(target.data(), askpeer)) + return false; + LookupRouterRecursive(target, OurKey(), 0, askpeer, result); + return true; + } /// on behalf of whoasked request introsets with tag from dht router with /// key askpeer with Recursion depth R @@ -138,14 +151,16 @@ namespace llarp LookupTagRecursive(const service::Tag& tag, const Key_t& whoasked, uint64_t whoaskedTX, const Key_t& askpeer, uint64_t R); - void - LookupRouterViaJob(llarp_router_lookup_job* job); - /// issue dht lookup for tag via askpeer and send reply to local path void LookupTagForPath(const service::Tag& tag, uint64_t txid, const llarp::PathID_t& path, const Key_t& askpeer); + /// issue dht lookup for router via askpeer and send reply to local path + void + LookupRouterForPath(const RouterID& target, uint64_t txid, + const llarp::PathID_t& path, const Key_t& askpeer); + /// issue dht lookup for introset for addr via askpeer and send reply to /// local path void @@ -193,10 +208,6 @@ namespace llarp const llarp::service::IntroSet* GetIntroSetByServiceAddress(const llarp::service::Address& addr) const; - /// queue lookup router via job - void - QueueRouterLookup(llarp_router_lookup_job* job); - static void handle_cleaner_timer(void* user, uint64_t orig, uint64_t left); @@ -207,9 +218,6 @@ namespace llarp void Explore(); - static void - queue_router_lookup(void* user); - llarp_router* router = nullptr; // for router contacts Bucket< RCNode >* nodes = nullptr; @@ -340,7 +348,7 @@ namespace llarp TXHolder< service::Tag, service::IntroSet, service::Tag::Hash > pendingTagLookups; - TXHolder< RouterID, llarp_rc, RouterID::Hash > pendingRouterLookups; + TXHolder< RouterID, RouterContact, RouterID::Hash > pendingRouterLookups; TXHolder< RouterID, RouterID, RouterID::Hash > pendingExploreLookups; diff --git a/include/llarp/dht/messages/gotrouter.hpp b/include/llarp/dht/messages/gotrouter.hpp index 5e55ff0c5..e89d33874 100644 --- a/include/llarp/dht/messages/gotrouter.hpp +++ b/include/llarp/dht/messages/gotrouter.hpp @@ -1,6 +1,7 @@ #ifndef LLARP_DHT_MESSAGES_GOT_ROUTER_HPP #define LLARP_DHT_MESSAGES_GOT_ROUTER_HPP #include +#include namespace llarp { @@ -12,16 +13,11 @@ namespace llarp : IMessage(from), relayed(tunneled) { } - GotRouterMessage(const Key_t& from, uint64_t id, const llarp_rc* result, + GotRouterMessage(const Key_t& from, uint64_t id, + const std::vector< RouterContact >& results, bool tunneled) - : IMessage(from), txid(id), relayed(tunneled) + : IMessage(from), R(results), txid(id), relayed(tunneled) { - if(result) - { - R.emplace_back(); - llarp_rc_clear(&R.back()); - llarp_rc_copy(&R.back(), result); - } } GotRouterMessage(uint64_t id, const std::vector< RouterID >& near, @@ -42,7 +38,7 @@ namespace llarp HandleMessage(llarp_dht_context* ctx, std::vector< IMessage* >& replies) const; - std::vector< llarp_rc > R; + std::vector< RouterContact > R; std::vector< RouterID > N; uint64_t txid = 0; uint64_t version = 0; diff --git a/include/llarp/dht/node.hpp b/include/llarp/dht/node.hpp index 41790fc25..c4ec36047 100644 --- a/include/llarp/dht/node.hpp +++ b/include/llarp/dht/node.hpp @@ -1,7 +1,7 @@ #ifndef LLARP_DHT_NODE_HPP #define LLARP_DHT_NODE_HPP -#include +#include #include #include @@ -11,18 +11,19 @@ namespace llarp { struct RCNode { - llarp_rc* rc; + llarp::RouterContact rc; Key_t ID; - RCNode() : rc(nullptr) + RCNode() { ID.Zero(); } - RCNode(llarp_rc* other) : rc(other) + RCNode(const llarp::RouterContact& other) { - ID = other->pubkey; + rc = other; + ID = other.pubkey.data(); } }; @@ -47,4 +48,4 @@ namespace llarp } // namespace dht } // namespace llarp -#endif \ No newline at end of file +#endif diff --git a/include/llarp/encrypted.hpp b/include/llarp/encrypted.hpp index 00e84af9b..641ed234a 100644 --- a/include/llarp/encrypted.hpp +++ b/include/llarp/encrypted.hpp @@ -5,12 +5,15 @@ #include #include #include +#include namespace llarp { /// encrypted buffer base type struct Encrypted { + static const size_t MAX_SIZE = (1024 * 8); + Encrypted(Encrypted&&) = delete; Encrypted(const Encrypted& other); Encrypted(); @@ -31,15 +34,13 @@ namespace llarp } Encrypted& - operator=(llarp_buffer_t buf) + operator=(const llarp_buffer_t& buf) { - if(_data) - delete[] _data; - _data = nullptr; - _sz = buf.sz; + if(buf.sz > MAX_SIZE) + return *this; + _sz = buf.sz; if(_sz) { - _data = new byte_t[_sz]; memcpy(_data, buf.base, _sz); } UpdateBuffer(); @@ -69,10 +70,9 @@ namespace llarp return false; if(strbuf.sz == 0) return false; - if(_data) - delete[] _data; - _sz = strbuf.sz; - _data = new byte_t[_sz]; + if(strbuf.sz > MAX_SIZE) + return false; + _sz = strbuf.sz; memcpy(_data, strbuf.base, _sz); UpdateBuffer(); return true; @@ -116,10 +116,10 @@ namespace llarp m_Buffer.cur = data(); m_Buffer.sz = size(); } - byte_t* _data = nullptr; - size_t _sz = 0; + byte_t _data[MAX_SIZE]; + size_t _sz = 0; llarp_buffer_t m_Buffer; }; } // namespace llarp -#endif \ No newline at end of file +#endif diff --git a/include/llarp/encrypted_frame.hpp b/include/llarp/encrypted_frame.hpp index c52c5b976..a811fede8 100644 --- a/include/llarp/encrypted_frame.hpp +++ b/include/llarp/encrypted_frame.hpp @@ -33,10 +33,9 @@ namespace llarp EncryptedFrame& operator=(const EncryptedFrame& other) { - if(_data) - delete[] _data; - _sz = other._sz; - _data = new byte_t[_sz]; + if(other._sz > MAX_SIZE) + throw std::logic_error("encrypted frame too big"); + _sz = other._sz; memcpy(_data, other._data, _sz); return *this; } diff --git a/include/llarp/exit_info.hpp b/include/llarp/exit_info.hpp new file mode 100644 index 000000000..5cf6a11a3 --- /dev/null +++ b/include/llarp/exit_info.hpp @@ -0,0 +1,45 @@ +#ifndef LLARP_XI_HPP +#define LLARP_XI_HPP +#include +#include +#include +#include +#include + +/** + * exit_info.h + * + * utilities for handling exits on the llarp network + */ + +/// Exit info model +namespace llarp +{ + struct ExitInfo + { + struct in6_addr address; + struct in6_addr netmask; + PubKey pubkey; + + bool + BEncode(llarp_buffer_t *buf) const; + + bool + BDecode(llarp_buffer_t *buf); + + friend std::ostream & + operator<<(std::ostream &out, const ExitInfo &xi) + { + char tmp[128] = {0}; + if(inet_ntop(AF_INET6, &xi.address, tmp, sizeof(tmp))) + out << std::string(tmp); + else + return out; + out << std::string("/"); + return out << std::to_string( + llarp::bits::count_array_bits(xi.netmask.s6_addr)); + } + }; +} // namespace llarp + +#endif diff --git a/include/llarp/iwp/establish_job.hpp b/include/llarp/iwp/establish_job.hpp index 9d861330f..bbf7ad060 100644 --- a/include/llarp/iwp/establish_job.hpp +++ b/include/llarp/iwp/establish_job.hpp @@ -1,6 +1,6 @@ #pragma once -#include "llarp/address_info.h" +#include "llarp/address_info.hpp" struct llarp_link; struct llarp_link_session; @@ -9,13 +9,13 @@ struct llarp_link_establish_job { void *user; void (*result)(struct llarp_link_establish_job *); - struct llarp_ai ai; + llarp::AddressInfo ai; uint64_t timeout; uint16_t retries; - byte_t pubkey[PUBKEYSIZE]; + llarp::PubKey pubkey; /** set on success by try_establish */ struct llarp_link *link; /** set on success by try_establish */ struct llarp_link_session *session; -}; \ No newline at end of file +}; diff --git a/include/llarp/iwp/frame_state.hpp b/include/llarp/iwp/frame_state.hpp index 6349e4069..fad91d506 100644 --- a/include/llarp/iwp/frame_state.hpp +++ b/include/llarp/iwp/frame_state.hpp @@ -86,7 +86,7 @@ struct frame_state clear(); bool - inbound_frame_complete(uint64_t id); + inbound_frame_complete(const std::unique_ptr< transit_message > &msg); void push_ackfor(uint64_t id, uint32_t bitmask); diff --git a/include/llarp/iwp/inbound_message.hpp b/include/llarp/iwp/inbound_message.hpp index cc3e15974..c98a7779e 100644 --- a/include/llarp/iwp/inbound_message.hpp +++ b/include/llarp/iwp/inbound_message.hpp @@ -9,12 +9,26 @@ struct InboundMessage { uint64_t msgid; - std::vector< byte_t > msg; + byte_t *_buf; + size_t sz; llarp_time_t queued = 0; - InboundMessage(uint64_t id, const std::vector< byte_t > &m) - : msgid(id), msg(m) + InboundMessage(uint64_t id, const std::vector< byte_t > &m) : msgid(id) { + sz = m.size(); + if(sz) + { + _buf = new byte_t[sz]; + memcpy(_buf, m.data(), sz); + } + else + _buf = nullptr; + } + + ~InboundMessage() + { + if(_buf) + delete[] _buf; } bool @@ -27,7 +41,7 @@ struct InboundMessage llarp_buffer_t Buffer() const { - return llarp::ConstBuffer< decltype(msg) >(msg); + return llarp::InitBuffer(_buf, sz); } struct GetTime diff --git a/include/llarp/iwp/sendbuf.hpp b/include/llarp/iwp/sendbuf.hpp index c646d1a06..0423ef33a 100644 --- a/include/llarp/iwp/sendbuf.hpp +++ b/include/llarp/iwp/sendbuf.hpp @@ -7,25 +7,35 @@ struct sendbuf_t { - sendbuf_t(size_t s) : sz(s) + sendbuf_t() { - _buf = new byte_t[s]; + _sz = 0; } - ~sendbuf_t() + sendbuf_t(sendbuf_t &&other) { - if(_buf) - delete[] _buf; + if(other._sz > sizeof(_buf)) + throw std::logic_error("sendbuf too big"); + memcpy(_buf, other._buf, other._sz); + _sz = other._sz; + other._sz = 0; } - size_t sz; + sendbuf_t(size_t s) + { + if(s > sizeof(_buf)) + throw std::logic_error("sendbuf too big"); + _sz = s; + } - byte_t priority = 255; + ~sendbuf_t() + { + } size_t size() const { - return sz; + return _sz; } byte_t * @@ -39,7 +49,7 @@ struct sendbuf_t { llarp_buffer_t buf; buf.base = _buf; - buf.sz = sz; + buf.sz = _sz; buf.cur = buf.base; return buf; } @@ -74,5 +84,6 @@ struct sendbuf_t llarp_time_t timestamp = 0; private: - byte_t *_buf = nullptr; + size_t _sz; + byte_t _buf[1500]; }; diff --git a/include/llarp/iwp/server.hpp b/include/llarp/iwp/server.hpp index cafa41f47..3870588c8 100644 --- a/include/llarp/iwp/server.hpp +++ b/include/llarp/iwp/server.hpp @@ -139,7 +139,7 @@ struct llarp_link issue_cleanup_timer(uint64_t timeout); void - get_our_address(struct llarp_ai *addr); + get_our_address(llarp::AddressInfo &addr); static void after_recv(llarp_udp_io *udp); diff --git a/include/llarp/iwp/session.hpp b/include/llarp/iwp/session.hpp index 341799037..ea726540b 100644 --- a/include/llarp/iwp/session.hpp +++ b/include/llarp/iwp/session.hpp @@ -7,7 +7,7 @@ #include "llarp/crypto.hpp" #include "llarp/crypto_async.h" #include "llarp/net.hpp" -#include "llarp/router_contact.h" +#include "llarp/router_contact.hpp" #include "llarp/time.h" #include "llarp/types.h" @@ -47,8 +47,9 @@ struct llarp_link_session llarp_link * get_parent(); - llarp_rc * - get_remote_router(); + + const llarp::RouterContact & + get_remote_router() const; bool CheckRCValid(); @@ -110,8 +111,8 @@ struct llarp_link_session llarp_link *serv = nullptr; - llarp_rc *our_router = nullptr; - llarp_rc remote_router; + llarp::RouterContact *our_router = nullptr; + llarp::RouterContact remote_router; llarp::SecretKey eph_seckey; llarp::PubKey remote; diff --git a/include/llarp/messages/link_intro.hpp b/include/llarp/messages/link_intro.hpp index 1d86eafb8..ab0502173 100644 --- a/include/llarp/messages/link_intro.hpp +++ b/include/llarp/messages/link_intro.hpp @@ -5,13 +5,17 @@ namespace llarp { struct LinkIntroMessage : public ILinkMessage { - LinkIntroMessage(llarp_rc* rc) : ILinkMessage(), RC(rc) + LinkIntroMessage(const RouterContact& rc) : ILinkMessage(), RC(rc) { + hasRC = true; } + LinkIntroMessage(); + ~LinkIntroMessage(); - llarp_rc* RC; + bool hasRC = false; + RouterContact RC; bool DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf); diff --git a/include/llarp/messages/relay_commit.hpp b/include/llarp/messages/relay_commit.hpp index acf70dd85..cdef455bf 100644 --- a/include/llarp/messages/relay_commit.hpp +++ b/include/llarp/messages/relay_commit.hpp @@ -45,7 +45,7 @@ namespace llarp struct LR_CommitMessage : public ILinkMessage { - std::vector< EncryptedFrame > frames; + std::array< EncryptedFrame, 8 > frames; uint64_t version; LR_CommitMessage() : ILinkMessage() diff --git a/include/llarp/net.hpp b/include/llarp/net.hpp index 37db22c51..1fb15196f 100644 --- a/include/llarp/net.hpp +++ b/include/llarp/net.hpp @@ -1,6 +1,6 @@ #ifndef LLARP_NET_HPP #define LLARP_NET_HPP -#include +#include #include #include #include @@ -55,7 +55,7 @@ namespace llarp return (const in_addr*)&_addr.sin6_addr.s6_addr[12]; } - Addr(const llarp_ai& other) + Addr(const AddressInfo& other) { memcpy(addr6(), other.ip.s6_addr, 16); _addr.sin6_port = htons(other.port); diff --git a/include/llarp/nodedb.h b/include/llarp/nodedb.hpp similarity index 80% rename from include/llarp/nodedb.h rename to include/llarp/nodedb.hpp index 403e20322..a9d80fe55 100644 --- a/include/llarp/nodedb.h +++ b/include/llarp/nodedb.hpp @@ -1,11 +1,12 @@ -#ifndef LLARP_NODEDB_H -#define LLARP_NODEDB_H +#ifndef LLARP_NODEDB_HPP +#define LLARP_NODEDB_HPP #include #include -#include +#include +#include /** - * nodedb.h + * nodedb.hpp * * persistent storage API for router contacts */ @@ -39,7 +40,7 @@ llarp_nodedb_store_dir(struct llarp_nodedb *n, const char *dir); struct llarp_nodedb_iter { void *user; - struct llarp_rc *rc; + llarp::RouterContact *rc; size_t index; bool (*visit)(struct llarp_nodedb_iter *); }; @@ -48,15 +49,6 @@ struct llarp_nodedb_iter int llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i); -/// get a random rc that is loaded -void -llarp_nodedb_get_random_rc(struct llarp_nodedb *n, struct llarp_rc *result); - -/// select a random rc at hop number N -void -llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev, - struct llarp_rc *result, size_t N); - /// return number of RC loaded size_t llarp_nodedb_num_loaded(struct llarp_nodedb *n); @@ -68,11 +60,11 @@ llarp_nodedb_num_loaded(struct llarp_nodedb *n); returns true on success and false on error */ bool -llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc); +llarp_nodedb_put_rc(struct llarp_nodedb *n, const llarp::RouterContact &rc); -/// return a pointer to an already loaded RC or nullptr if it's not there -struct llarp_rc * -llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk); +bool +llarp_nodedb_get_rc(struct llarp_nodedb *n, const llarp::RouterID &pk, + llarp::RouterContact &result); /// struct for async rc verification struct llarp_async_verify_rc; @@ -94,7 +86,7 @@ struct llarp_async_verify_rc struct llarp_threadpool *diskworker; /// router contact - struct llarp_rc rc; + llarp::RouterContact rc; /// result bool valid; /// hook @@ -125,9 +117,9 @@ struct llarp_async_load_rc /// disk worker threadpool struct llarp_threadpool *diskworker; /// target pubkey - byte_t pubkey[PUBKEYSIZE]; + llarp::PubKey pubkey; /// router contact result - struct llarp_rc rc; + llarp::RouterContact result; /// set to true if we loaded the rc bool loaded; /// hook function called in logic thread @@ -138,4 +130,9 @@ struct llarp_async_load_rc void llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job); +void +llarp_nodedb_select_random_hop(struct llarp_nodedb *n, + const llarp::RouterContact &prev, + llarp::RouterContact &result, size_t N); + #endif diff --git a/include/llarp/path.h b/include/llarp/path.h deleted file mode 100644 index 368218e15..000000000 --- a/include/llarp/path.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LLARP_PATH_H -#define LLARP_PATH_H - -#include - -#define MAXHOPS (8) -#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000) -#define PATH_BUILD_TIMEOUT (10 * 1000) -#define MESSAGE_PAD_SIZE (1024) - -struct llarp_path_hop -{ - struct llarp_rc router; - byte_t nextHop[PUBKEYSIZE]; - byte_t sessionkey[SHAREDKEYSIZE]; - byte_t pathid[PATHIDSIZE]; -}; - -struct llarp_path_hops -{ - struct llarp_path_hop hops[MAXHOPS]; - size_t numHops; -}; - -void -llarp_path_hops_free(struct llarp_path_hops* hops); - -#endif \ No newline at end of file diff --git a/include/llarp/path.hpp b/include/llarp/path.hpp index 0c7d73790..a0bedb12e 100644 --- a/include/llarp/path.hpp +++ b/include/llarp/path.hpp @@ -1,6 +1,5 @@ #ifndef LLARP_PATH_HPP #define LLARP_PATH_HPP -#include #include #include #include @@ -10,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +22,11 @@ #include #include +#define MAXHOPS (8) +#define DEFAULT_PATH_LIFETIME (10 * 60 * 1000) +#define PATH_BUILD_TIMEOUT (10 * 1000) +#define MESSAGE_PAD_SIZE (1024) + namespace llarp { namespace path @@ -193,7 +198,7 @@ namespace llarp /// path id PathID_t txID, rxID; // router contact of router - llarp_rc router; + RouterContact rc; // temp public encryption key SecretKey commkey; /// shared secret at this hop @@ -226,7 +231,7 @@ namespace llarp llarp_time_t buildStarted; PathStatus status; - Path(llarp_path_hops* path); + Path(const std::vector< RouterContact >& routers); void SetBuildResultHook(BuildResultHookFunc func); @@ -338,7 +343,7 @@ namespace llarp /// track a path builder with this context void - AddPathBuilder(llarp_pathbuilder_context* set); + AddPathBuilder(Builder* set); void AllowTransit(); @@ -371,7 +376,7 @@ namespace llarp bool ForwardLRCM(const RouterID& nextHop, - std::deque< EncryptedFrame >& frames); + const std::array< EncryptedFrame, 8 >& frames); bool HopIsUs(const PubKey& k) const; @@ -386,7 +391,7 @@ namespace llarp AddOwnPath(PathSet* set, Path* p); void - RemovePathBuilder(llarp_pathbuilder_context* ctx); + RemovePathBuilder(Builder* ctx); void RemovePathSet(PathSet* set); @@ -423,7 +428,7 @@ namespace llarp SyncTransitMap_t m_TransitPaths; SyncTransitMap_t m_Paths; SyncOwnedPathsMap_t m_OurPaths; - std::list< llarp_pathbuilder_context* > m_PathBuilders; + std::list< Builder* > m_PathBuilders; bool m_AllowTransit; }; } // namespace path diff --git a/include/llarp/pathbuilder.h b/include/llarp/pathbuilder.h deleted file mode 100644 index 54fcacfa6..000000000 --- a/include/llarp/pathbuilder.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef LLARP_PATHFINDER_H_ -#define LLARP_PATHFINDER_H_ - -#include -#include - -/** - * path_base.h - * - * path api functions - */ - -/// forard declare -struct llarp_router; -struct llarp_dht_context; - -// fwd declr -struct llarp_pathbuilder_context; - -/// alloc -struct llarp_pathbuilder_context* -llarp_pathbuilder_context_new(struct llarp_router* router, - struct llarp_dht_context* dht, size_t numpaths, - size_t defaultNumHops); -/// dealloc -void -llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx); - -// fwd declr -struct llarp_pathbuild_job; - -/// response callback -typedef void (*llarp_pathbuilder_hook)(struct llarp_pathbuild_job*); -// select hop function (user, nodedb, prevhop, result, hopnnumber) called in -// logic thread -typedef bool (*llarp_pathbuilder_select_hop_func)(void*, struct llarp_nodedb*, - struct llarp_rc*, - struct llarp_rc*, size_t); - -// request struct -struct llarp_pathbuild_job -{ - // opaque pointer for user data - void* user; - // router context (set by llarp_pathbuilder_build_path) - struct llarp_router* router; - // context - struct llarp_pathbuilder_context* context; - // path hop selection - llarp_pathbuilder_select_hop_func selectHop; - // called when the path build started - llarp_pathbuilder_hook pathBuildStarted; - // path - struct llarp_path_hops hops; -}; - -/// request func -// or find_path but thought pathfinder_find_path was a bit redundant -void -llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job); - -#endif diff --git a/include/llarp/pathbuilder.hpp b/include/llarp/pathbuilder.hpp index ed366e17a..f2958e50c 100644 --- a/include/llarp/pathbuilder.hpp +++ b/include/llarp/pathbuilder.hpp @@ -1,37 +1,41 @@ #ifndef LLARP_PATHBUILDER_HPP_ #define LLARP_PATHBUILDER_HPP_ -#include -#include -#include + #include -struct llarp_pathbuilder_context : public llarp::path::PathSet +namespace llarp { - struct llarp_router* router; - struct llarp_dht_context* dht; - llarp::SecretKey enckey; - size_t numHops; - /// construct - llarp_pathbuilder_context(llarp_router* p_router, - struct llarp_dht_context* p_dht, size_t numPaths, - size_t numHops); - - virtual ~llarp_pathbuilder_context(); - - virtual bool - SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, size_t hop); - - virtual bool - ShouldBuildMore() const; - - void - BuildOne(); - - void - ManualRebuild(size_t N); - - virtual byte_t* - GetTunnelEncryptionSecretKey(); -}; - + namespace path + { + struct Builder : public PathSet + { + struct llarp_router* router; + struct llarp_dht_context* dht; + llarp::SecretKey enckey; + size_t numHops; + /// construct + Builder(llarp_router* p_router, struct llarp_dht_context* p_dht, + size_t numPaths, size_t numHops); + + virtual ~Builder(); + + virtual bool + SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur, + size_t hop); + + virtual bool + ShouldBuildMore() const; + + void + BuildOne(); + + void + ManualRebuild(size_t N); + + virtual const byte_t* + GetTunnelEncryptionSecretKey() const; + }; + } // namespace path + +} // namespace llarp #endif diff --git a/include/llarp/pathset.hpp b/include/llarp/pathset.hpp index 3a8ef7ac9..00840e224 100644 --- a/include/llarp/pathset.hpp +++ b/include/llarp/pathset.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -114,17 +115,9 @@ namespace llarp } virtual bool - SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, + SelectHop(llarp_nodedb* db, const RouterContact& prev, RouterContact& cur, size_t hop) = 0; - static bool - SelectHopCallback(void* user, llarp_nodedb* db, llarp_rc* prev, - llarp_rc* cur, size_t hopno) - { - PathSet* self = static_cast< PathSet* >(user); - return self->SelectHop(db, prev, cur, hopno); - } - private: typedef std::pair< RouterID, PathID_t > PathInfo_t; typedef std::map< PathInfo_t, Path* > PathMap_t; diff --git a/include/llarp/router.h b/include/llarp/router.h index 11d7be22d..d29212fec 100644 --- a/include/llarp/router.h +++ b/include/llarp/router.h @@ -3,11 +3,10 @@ #include #include #include -#include -#include -#include #include +#include +struct llarp_nodedb; struct llarp_router; bool @@ -19,16 +18,6 @@ llarp_init_router(struct llarp_threadpool *worker, struct llarp_ev_loop *netloop, struct llarp_logic *logic); void llarp_free_router(struct llarp_router **router); - -bool -llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote, - uint16_t numretries); - -/// override default path builder function (FFI) -void -llarp_router_override_path_selection(struct llarp_router *router, - llarp_pathbuilder_select_hop_func func); - bool llarp_configure_router(struct llarp_router *router, struct llarp_config *conf); diff --git a/include/llarp/router_contact.h b/include/llarp/router_contact.h deleted file mode 100644 index 946066a55..000000000 --- a/include/llarp/router_contact.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef LLARP_RC_H -#define LLARP_RC_H -#include -#include -#include - -#ifdef __cplusplus -#include -#endif - -// forward declare -struct llarp_alloc; -struct llarp_rc; - -#define MAX_RC_SIZE (1024) -#define NICKLEN (32) - -bool -llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buf); -bool -llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buf); - -struct llarp_rc -{ - struct llarp_ai_list *addrs; - // public encryption public key - byte_t enckey[PUBKEYSIZE]; - // public signing public key - byte_t pubkey[PUBKEYSIZE]; - struct llarp_xi_list *exits; - byte_t signature[SIGSIZE]; - /// node nickname, yw kee - byte_t nickname[NICKLEN]; - - uint64_t last_updated; - -#ifdef __cplusplus - bool - BEncode(llarp_buffer_t *buf) const - { - return llarp_rc_bencode(this, buf); - } - - bool - BDecode(llarp_buffer_t *buf) - { - return llarp_rc_bdecode(this, buf); - } - - bool - HasNick() const - { - return nickname[0] != 0; - } - - std::string - Nick() const - { - const char *nick = (const char *)nickname; - return std::string(nick, strnlen(nick, sizeof(nickname))); - } - -#endif -}; - -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); - -void -llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src); - -bool -llarp_rc_is_public_router(const struct llarp_rc *const rc); - -void -llarp_rc_set_addrs(struct llarp_rc *rc, struct llarp_alloc *mem, - struct llarp_ai_list *addr); - -bool -llarp_rc_set_nickname(struct llarp_rc *rc, const char *name); - -void -llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey); - -void -llarp_rc_set_pubsigkey(struct llarp_rc *rc, const uint8_t *pubkey); - -/// combo -void -llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubenckey, - const uint8_t *pubsigkey); - -void -llarp_rc_sign(struct llarp_crypto *crypto, const byte_t *seckey, - struct llarp_rc *rc); - -void -llarp_rc_clear(struct llarp_rc *rc); - -bool -llarp_rc_addr_list_iter(struct llarp_ai_list_iter *iter, struct llarp_ai *ai); - -bool -llarp_rc_read(const char *fpath, struct llarp_rc *result); - -bool -llarp_rc_write(struct llarp_rc *rc, const char *our_rc_file); - -#endif diff --git a/include/llarp/router_contact.hpp b/include/llarp/router_contact.hpp new file mode 100644 index 000000000..c5f26d6a1 --- /dev/null +++ b/include/llarp/router_contact.hpp @@ -0,0 +1,67 @@ +#ifndef LLARP_RC_HPP +#define LLARP_RC_HPP +#include +#include +#include +#include + +#include + +#define MAX_RC_SIZE (1024) +#define NICKLEN (32) + +namespace llarp +{ + struct RouterContact : public IBEncodeMessage + { + // advertised addresses + std::list< AddressInfo > addrs; + // public encryption public key + llarp::PubKey enckey; + // public signing public key + llarp::PubKey pubkey; + // advertised exits + std::list< ExitInfo > exits; + // signature + llarp::Signature signature; + /// node nickname, yw kee + llarp::AlignedBuffer< NICKLEN > nickname; + + uint64_t last_updated; + + bool + BEncode(llarp_buffer_t *buf) const; + + bool + DecodeKey(llarp_buffer_t k, llarp_buffer_t *buf); + + RouterContact & + operator=(const RouterContact &other); + + bool + HasNick() const; + + std::string + Nick() const; + + bool + IsPublicRouter() const; + + void + SetNick(const std::string &nick); + + bool + VerifySignature(llarp_crypto *crypto) const; + + bool + Sign(llarp_crypto *crypto, const llarp::SecretKey &secret); + + bool + Read(const char *fname); + + bool + Write(const char *fname) const; + }; +} // namespace llarp + +#endif diff --git a/include/llarp/service/endpoint.hpp b/include/llarp/service/endpoint.hpp index 8b8832a9e..f9b733b6f 100644 --- a/include/llarp/service/endpoint.hpp +++ b/include/llarp/service/endpoint.hpp @@ -5,12 +5,13 @@ #include #include #include +#include namespace llarp { namespace service { - struct Endpoint : public llarp_pathbuilder_context, + struct Endpoint : public path::Builder, public ILookupHolder, public IDataHandler { @@ -145,7 +146,7 @@ namespace llarp typedef std::queue< PendingBuffer > PendingBufferQueue; /// context needed to initiate an outbound hidden service session - struct OutboundContext : public llarp_pathbuilder_context + struct OutboundContext : public path::Builder { OutboundContext(const IntroSet& introSet, Endpoint* parent); ~OutboundContext(); @@ -176,7 +177,8 @@ namespace llarp HandlePathBuilt(path::Path* path); bool - SelectHop(llarp_nodedb* db, llarp_rc* prev, llarp_rc* cur, size_t hop); + SelectHop(llarp_nodedb* db, const RouterContact& prev, + RouterContact& cur, size_t hop); bool HandleHiddenServiceFrame(const ProtocolFrame* frame); diff --git a/llarp/context.cpp b/llarp/context.cpp index e3185bca4..de12a72c1 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -122,24 +122,6 @@ namespace llarp return 1; } - int - Context::IterateDatabase(struct llarp_nodedb_iter i) - { - return llarp_nodedb_iterate_all(nodedb, i); - } - - bool - Context::PutDatabase(struct llarp_rc *rc) - { - return llarp_nodedb_put_rc(nodedb, rc); - } - - struct llarp_rc * - Context::GetDatabase(const byte_t *pk) - { - return llarp_nodedb_get_rc(nodedb, pk); - } - int Context::Setup() { @@ -371,25 +353,6 @@ extern "C" return ptr->ctx->GetDatabase(pk); } - struct llarp_rc * - llarp_main_getLocalRC(struct llarp_main *ptr) - { - // - /* - llarp_config_iterator iter; - iter.user = this; - iter.visit = &iter_config; - llarp_config_iter(ctx->config, &iter); - */ - llarp_rc *rc = new llarp_rc; - llarp_rc_new(rc); - llarp::LogInfo("Loading ", ptr->ctx->conatctFile); - if(llarp_rc_read(ptr->ctx->conatctFile, rc)) - return rc; - else - return nullptr; - } - void llarp_main_checkOnline(void *u, uint64_t orig, uint64_t left) { @@ -423,7 +386,6 @@ extern "C" request->first = true; llarp::LogInfo("llarp_main_queryDHT_online - We're online"); llarp::LogInfo("llarp_main_queryDHT_online - Querying DHT"); - llarp_dht_lookup_router(request->ptr->ctx->router->dht, request->job); } } diff --git a/llarp/crypto_async.cpp b/llarp/crypto_async.cpp index db636fbb6..b56a190b2 100644 --- a/llarp/crypto_async.cpp +++ b/llarp/crypto_async.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/llarp/dht.cpp b/llarp/dht.cpp index 753ce8373..e7750084a 100644 --- a/llarp/dht.cpp +++ b/llarp/dht.cpp @@ -19,15 +19,6 @@ llarp_dht_context_free(struct llarp_dht_context *ctx) delete ctx; } -void -__llarp_dht_put_peer(struct llarp_dht_context *ctx, struct llarp_rc *rc) - -{ - llarp::dht::RCNode n(rc); - llarp::LogDebug("Adding ", n.ID, " to DHT"); - ctx->impl.nodes->PutNode(n); -} - void __llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id) { @@ -47,14 +38,3 @@ llarp_dht_context_start(struct llarp_dht_context *ctx, const byte_t *key) { ctx->impl.Init(key, ctx->parent, 20000); } - -void -llarp_dht_lookup_router(struct llarp_dht_context *ctx, - struct llarp_router_lookup_job *job) -{ - job->dht = ctx; - job->found = false; - llarp_rc_clear(&job->result); - llarp_logic_queue_job(ctx->parent->logic, - {job, &llarp::dht::Context::queue_router_lookup}); -} diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index f3283c0f6..47890de66 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -70,7 +70,8 @@ namespace llarp llarp::LogInfo("got ", valuesFound.size(), " routers from exploration"); for(const auto &pk : valuesFound) { - if(llarp_nodedb_get_rc(parent->router->nodedb, pk) == nullptr) + RouterContact rc; + if(!llarp_nodedb_get_rc(parent->router->nodedb, pk, rc)) { // try connecting to it we don't know it // this triggers a dht lookup @@ -191,7 +192,7 @@ namespace llarp { // we are the target, give them our RC replies.push_back( - new GotRouterMessage(requester, txid, &router->rc, false)); + new GotRouterMessage(requester, txid, {router->rc}, false)); return; } Key_t next; @@ -202,7 +203,7 @@ namespace llarp { // we know it replies.push_back(new GotRouterMessage( - requester, txid, nodes->nodes[target].rc, false)); + requester, txid, {nodes->nodes[target].rc}, false)); } else if(recursive) // are we doing a recursive lookup? { @@ -216,22 +217,19 @@ namespace llarp { // no we are closer to the target so tell requester it's not there // so they switch to iterative lookup - replies.push_back( - new GotRouterMessage(requester, txid, nullptr, false)); + replies.push_back(new GotRouterMessage(requester, txid, {}, false)); } } else // iterative lookup and we don't have it tell them we don't have // the target router { - replies.push_back( - new GotRouterMessage(requester, txid, nullptr, false)); + replies.push_back(new GotRouterMessage(requester, txid, {}, false)); } } else { // we don't know it and have no closer peers to ask - replies.push_back( - new GotRouterMessage(requester, txid, nullptr, false)); + replies.push_back(new GotRouterMessage(requester, txid, {}, false)); } } @@ -600,15 +598,15 @@ namespace llarp return true; } - struct RecursiveRouterLookup : public TX< RouterID, llarp_rc > + struct RecursiveRouterLookup : public TX< RouterID, RouterContact > { - llarp_router_lookup_job *job; + RouterLookupHandler resultHandler; RecursiveRouterLookup(const TXOwner &whoasked, const RouterID &target, - Context *ctx, llarp_router_lookup_job *j) - : TX< RouterID, llarp_rc >(whoasked, target, ctx) + Context *ctx, RouterLookupHandler result) + : TX< RouterID, RouterContact >(whoasked, target, ctx) + , resultHandler(result) { - job = j; peersAsked.insert(ctx->OurKey()); } @@ -641,32 +639,16 @@ namespace llarp void SendReply() { - if(job) + if(resultHandler) { - job->found = false; - if(valuesFound.size()) - { - job->found = - memcmp(valuesFound[0].pubkey, job->target, PUBKEYSIZE) == 0; - if(job->found) - llarp_rc_copy(&job->result, &valuesFound[0]); - } - if(job->hook) - job->hook(job); - else - delete job; + resultHandler(valuesFound); } else { - llarp_rc *found = nullptr; - if(valuesFound.size()) - found = &valuesFound[0]; parent->DHTSendTo( whoasked.node, - new GotRouterMessage({}, whoasked.txid, found, false)); + new GotRouterMessage({}, whoasked.txid, valuesFound, false)); } - for(auto rc : valuesFound) - llarp_rc_free(&rc); } }; @@ -674,38 +656,15 @@ namespace llarp Context::LookupRouterRecursive(const RouterID &target, const Key_t &whoasked, uint64_t txid, const Key_t &askpeer, - llarp_router_lookup_job *job) + RouterLookupHandler handler) { TXOwner asker(whoasked, txid); TXOwner peer(askpeer, ++ids); auto tx = pendingRouterLookups.NewTX( - peer, target, new RecursiveRouterLookup(asker, target, this, job)); + peer, target, + new RecursiveRouterLookup(asker, target, this, handler)); tx->Start(peer); } - void - Context::LookupRouterViaJob(llarp_router_lookup_job *job) - { - Key_t peer; - - if(nodes->FindClosest(job->target, peer)) - LookupRouterRecursive(job->target, ourKey, 0, peer, job); - else if(job->hook) - { - job->found = false; - job->hook(job); - } - else - delete job; - } - - void - Context::queue_router_lookup(void *user) - { - struct llarp_router_lookup_job *job = - static_cast< llarp_router_lookup_job * >(user); - job->dht->impl.LookupRouterViaJob(job); - } - } // namespace dht } // namespace llarp diff --git a/llarp/dht/find_router.cpp b/llarp/dht/find_router.cpp index 9e6457efa..c255ba717 100644 --- a/llarp/dht/find_router.cpp +++ b/llarp/dht/find_router.cpp @@ -9,60 +9,6 @@ namespace llarp { namespace dht { - struct PathLookupInformer - { - llarp_router *router; - PathID_t pathID; - uint64_t txid; - - PathLookupInformer(llarp_router *r, const PathID_t &id, uint64_t tx) - : router(r), pathID(id), txid(tx) - { - } - - void - SendReply(llarp::routing::IMessage *msg) - { - auto path = router->paths.GetByUpstream(router->pubkey(), pathID); - if(path == nullptr) - { - llarp::LogWarn("Path not found for relayed DHT message txid=", txid, - " pathid=", pathID); - return; - } - if(!path->SendRoutingMessage(msg, router)) - llarp::LogWarn("Failed to send reply for relayed DHT message txid=", - txid, "pathid=", pathID); - } - - static void - InformReply(llarp_router_lookup_job *job) - { - PathLookupInformer *self = - static_cast< PathLookupInformer * >(job->user); - llarp::routing::DHTMessage reply; - if(job->found) - { - if(llarp_rc_verify_sig(&self->router->crypto, &job->result)) - { - reply.M.push_back(new GotRouterMessage(job->target, self->txid, - &job->result, false)); - } - llarp_rc_free(&job->result); - llarp_rc_clear(&job->result); - } - else - { - reply.M.push_back( - new GotRouterMessage(job->target, self->txid, nullptr, false)); - } - self->SendReply(&reply); - // TODO: is this okay? - delete self; - delete job; - } - }; - bool RelayedFindRouterMessage::HandleMessage( llarp_dht_context *ctx, std::vector< IMessage * > &replies) const @@ -75,24 +21,16 @@ namespace llarp if(path) { replies.push_back( - new GotRouterMessage(K.data(), txid, &dht.router->rc, false)); + new GotRouterMessage(K.data(), txid, {dht.router->rc}, false)); return true; } return false; } - llarp_router_lookup_job *job = new llarp_router_lookup_job; - PathLookupInformer *informer = - new PathLookupInformer(dht.router, pathID, txid); - job->user = informer; - job->hook = &PathLookupInformer::InformReply; - job->found = false; - llarp_rc_clear(&job->result); - job->dht = ctx; - memcpy(job->target, K, sizeof(job->target)); + Key_t peer; Key_t k = K.data(); if(dht.nodes->FindClosest(k, peer)) - dht.LookupRouterRecursive(K, dht.OurKey(), txid, peer, job); + dht.LookupRouterForPath(K, txid, pathID, peer); return true; } diff --git a/llarp/dht/got_router.cpp b/llarp/dht/got_router.cpp index 92ae46425..0ef9f2257 100644 --- a/llarp/dht/got_router.cpp +++ b/llarp/dht/got_router.cpp @@ -9,9 +9,6 @@ namespace llarp { GotRouterMessage::~GotRouterMessage() { - for(auto rc : R) - llarp_rc_free(&rc); - R.clear(); } bool diff --git a/llarp/encrypted_frame.cpp b/llarp/encrypted_frame.cpp index 32b482cde..b05887cff 100644 --- a/llarp/encrypted_frame.cpp +++ b/llarp/encrypted_frame.cpp @@ -17,17 +17,17 @@ namespace llarp Encrypted::Encrypted(const byte_t* buf, size_t sz) : _sz(sz) { - _data = new byte_t[sz]; + if(sz > MAX_SIZE) + throw std::logic_error("encrypted frame too big"); if(buf) memcpy(data(), buf, sz); else llarp::Zero(data(), sz); UpdateBuffer(); } + Encrypted::~Encrypted() { - if(_data) - delete[] _data; } Encrypted::Encrypted(size_t sz) : Encrypted(nullptr, sz) diff --git a/llarp/iwp/frame_state.cpp b/llarp/iwp/frame_state.cpp index a666aa5b4..718317375 100644 --- a/llarp/iwp/frame_state.cpp +++ b/llarp/iwp/frame_state.cpp @@ -94,22 +94,30 @@ frame_state::got_xmit(frame_header hdr, size_t sz) auto itr = rx.find(h); if(itr == rx.end()) { - auto msg = rx.insert(std::make_pair(h, - std::unique_ptr< transit_message >( - new transit_message(x)))) - .first->second.get(); - rxIDs.insert(std::make_pair(id, h)); - llarp::LogDebug("got message XMIT with ", (int)x.numfrags(), - " fragment" - "s"); - // inserted, put last fragment - msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag()); - push_ackfor(id, 0); - if(x.numfrags() == 0) + if(x.numfrags() > 0) { - return inbound_frame_complete(id); + auto msg = rx.insert(std::make_pair(h, + std::unique_ptr< transit_message >( + new transit_message(x)))) + .first->second.get(); + rxIDs.insert(std::make_pair(id, h)); + llarp::LogDebug("got message XMIT with ", (int)x.numfrags(), + " fragment" + "s"); + // inserted, put last fragment + msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag()); + push_ackfor(id, 0); + return true; + } + else + { + // handle zero fragment message immediately + std::unique_ptr< transit_message > msg = + std::unique_ptr< transit_message >(new transit_message(x)); + msg->put_lastfrag(hdr.data() + sizeof(x.buffer), x.lastfrag()); + push_ackfor(id, 0); + return inbound_frame_complete(msg); } - return true; } else llarp::LogWarn("duplicate XMIT h=", llarp::ShortHash(h)); @@ -170,7 +178,10 @@ frame_state::got_frag(frame_header hdr, size_t sz) if(itr->second->completed()) { push_ackfor(msgid, mask); - return inbound_frame_complete(msgid); + bool result = inbound_frame_complete(itr->second); + rxIDs.erase(idItr); + rx.erase(itr); + return result; } else if(itr->second->should_send_ack(llarp_time_now_ms())) { @@ -191,14 +202,15 @@ frame_state::push_ackfor(uint64_t id, uint32_t bitmask) } bool -frame_state::inbound_frame_complete(uint64_t id) +frame_state::inbound_frame_complete( + const std::unique_ptr< transit_message > &rxmsg) { bool success = false; std::vector< byte_t > msg; - std::unique_ptr< transit_message > rxmsg = std::move(rx[rxIDs[id]]); - rx.erase(rxIDs[id]); - rxIDs.erase(id); llarp::ShortHash digest; + + auto id = rxmsg->msginfo.msgid(); + if(rxmsg->reassemble(msg)) { auto router = Router(); @@ -334,8 +346,8 @@ frame_state::process(byte_t *buf, size_t sz) void frame_state::queue_tx(uint64_t id, transit_message *msg) { - tx.insert(std::make_pair(id, std::unique_ptr< transit_message >(msg))); msg->generate_xmit(sendqueue, txflags); + tx.insert(std::make_pair(id, std::unique_ptr< transit_message >(msg))); // msg->retransmit_frags(sendqueue, txflags); } diff --git a/llarp/iwp/server.cpp b/llarp/iwp/server.cpp index 3ebf910c2..5ca7623dc 100644 --- a/llarp/iwp/server.cpp +++ b/llarp/iwp/server.cpp @@ -111,8 +111,7 @@ llarp_link::TickSessions() { if(itr->second->Tick(now)) { - if(itr->second->get_remote_router()) - m_Connected.erase(itr->second->get_remote_router()->pubkey); + m_Connected.erase(itr->second->get_remote_router().pubkey); itr = m_sessions.erase(itr); } else @@ -289,13 +288,13 @@ llarp_link::issue_cleanup_timer(uint64_t timeout) } void -llarp_link::get_our_address(llarp_ai* addr) +llarp_link::get_our_address(llarp::AddressInfo& addr) { - addr->rank = 1; - strncpy(addr->dialect, "IWP", sizeof(addr->dialect)); - memcpy(addr->enc_key, pubkey(), 32); - memcpy(addr->ip.s6_addr, this->addr.addr6(), 16); - addr->port = this->addr.port(); + addr.rank = 1; + addr.dialect = "IWP"; + addr.pubkey = pubkey(); + addr.port = this->addr.port(); + memcpy(addr.ip.s6_addr, this->addr.addr6(), 16); } void @@ -411,7 +410,7 @@ llarp_link::try_establish(struct llarp_link_establish_job* job) visit_session(dst, [job](const std::unique_ptr< llarp_link_session >& s) { s->establish_job = job; s->frame.alive(); // mark it alive - s->introduce(job->ai.enc_key); + s->introduce(job->ai.pubkey); }); return true; } diff --git a/llarp/iwp/session.cpp b/llarp/iwp/session.cpp index b1a6c5818..bc265fc05 100644 --- a/llarp/iwp/session.cpp +++ b/llarp/iwp/session.cpp @@ -35,7 +35,6 @@ llarp_link_session::llarp_link_session(llarp_link *l, const byte_t *seckey, eph_seckey = seckey; else crypto->encryption_keygen(eph_seckey); - llarp_rc_clear(&remote_router); crypto->randbytes(token, 32); frame.alive(); working.store(false); @@ -44,7 +43,6 @@ llarp_link_session::llarp_link_session(llarp_link *l, const byte_t *seckey, llarp_link_session::~llarp_link_session() { - llarp_rc_free(&remote_router); frame.clear(); } @@ -72,6 +70,8 @@ llarp_link_session::sendto(llarp_buffer_t msg) bool llarp_link_session::timedout(llarp_time_t now, llarp_time_t timeout) { + if(frame.lastEvent == 0) + return false; if(now <= frame.lastEvent) return false; auto diff = now - frame.lastEvent; @@ -127,10 +127,10 @@ llarp_link_session::session_established() llarp_logic_cancel_call(serv->logic, establish_job_id); } -llarp_rc * -llarp_link_session::get_remote_router() +const llarp::RouterContact & +llarp_link_session::get_remote_router() const { - return &remote_router; + return remote_router; } void @@ -150,16 +150,16 @@ bool llarp_link_session::CheckRCValid() { // verify signatuire - if(!llarp_rc_verify_sig(crypto, &remote_router)) + if(!remote_router.VerifySignature(crypto)) return false; - auto &list = remote_router.addrs->list; - if(list.size() == 0) // the remote node is a client node so accept it + if(remote_router.addrs.size() + == 0) // the remote node is a client node so accept it return true; // check if the RC owns a pubkey that we are using - for(auto &ai : list) + for(auto &ai : remote_router.addrs) { - if(memcmp(ai.enc_key, remote, PUBKEYSIZE) == 0) + if(ai.pubkey == remote) return true; } return false; @@ -240,7 +240,6 @@ handle_verify_introack(iwp_async_introack *introack) { // invalid signature llarp::LogError("introack verify failed from ", link->addr); - link->serv->remove_intro_from(link->addr); return; } // cancel resend @@ -271,7 +270,8 @@ handle_establish_timeout(void *user, uint64_t orig, uint64_t left) // timer timeout job->session = nullptr; } - job->result(job); + if(!self->working) + job->result(job); } } @@ -425,12 +425,10 @@ llarp_link_session::keepalive() void llarp_link_session::EncryptOutboundFrames() { - llarp_link_session *self = this; - outboundFrames.Process([self](iwp_async_frame *frame) { + outboundFrames.Process([&](iwp_async_frame *frame) { if(iwp_encrypt_frame(frame)) - if(llarp_ev_udp_sendto(self->udp, self->addr, frame->buf, frame->sz) - == -1) - llarp::LogError("sendto ", self->addr, " failed"); + if(llarp_ev_udp_sendto(udp, addr, frame->buf, frame->sz) == -1) + llarp::LogError("sendto ", addr, " failed"); }); } @@ -753,6 +751,8 @@ llarp_link_session::encrypt_frame_async_send(const void *buf, size_t sz) { // 64 bytes frame overhead for nonce and hmac auto frame = alloc_frame(nullptr, sz + 64); + if(frame == nullptr) + return; memcpy(frame->buf + 64, buf, sz); // maybe add upto 128 random bytes to the packet auto padding = llarp_randint() % MAX_PAD; diff --git a/llarp/link/encoder.cpp b/llarp/link/encoder.cpp index e869a68c1..b0756ed1c 100644 --- a/llarp/link/encoder.cpp +++ b/llarp/link/encoder.cpp @@ -5,7 +5,7 @@ namespace llarp /// encode Link Introduce Message onto a buffer /// if router is nullptr then the LIM's r member is omitted. bool - EncodeLIM(llarp_buffer_t* buff, llarp_rc* router) + EncodeLIM(llarp_buffer_t* buff, const llarp::RouterContact* router) { if(!bencode_start_dict(buff)) return false; @@ -21,7 +21,7 @@ namespace llarp { if(!bencode_write_bytestring(buff, "r", 1)) return false; - if(!llarp_rc_bencode(router, buff)) + if(!router->BEncode(buff)) return false; } diff --git a/llarp/link/encoder.hpp b/llarp/link/encoder.hpp index ebc9433d1..216983a11 100644 --- a/llarp/link/encoder.hpp +++ b/llarp/link/encoder.hpp @@ -3,14 +3,14 @@ #include #include -#include +#include namespace llarp { /// encode Link Introduce Message onto a buffer /// if router is nullptr then the LIM's r member is omitted. bool - EncodeLIM(llarp_buffer_t* buff, llarp_rc* router); + EncodeLIM(llarp_buffer_t* buff, const RouterContact* router); } // namespace llarp #endif diff --git a/llarp/link_intro.cpp b/llarp/link_intro.cpp index 87db409f5..cc1ee6692 100644 --- a/llarp/link_intro.cpp +++ b/llarp/link_intro.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include "logger.hpp" #include "router.hpp" @@ -15,13 +15,9 @@ namespace llarp { if(llarp_buffer_eq(key, "r")) { - if(!llarp_rc_bdecode(RC, buf)) - { - llarp::LogWarn("failed to decode RC"); + if(!RC.BDecode(buf)) return false; - } - remote = (byte_t*)RC->pubkey; - llarp::LogDebug("decoded RC from ", remote); + hasRC = true; return true; } else if(llarp_buffer_eq(key, "v")) @@ -55,12 +51,11 @@ namespace llarp if(!bencode_write_bytestring(buf, "i", 1)) return false; - if(RC) + if(hasRC) { if(!bencode_write_bytestring(buf, "r", 1)) return false; - if(!llarp_rc_bencode(RC, buf)) - return false; + return RC.BEncode(buf); } if(!bencode_write_version_entry(buf)) @@ -72,7 +67,7 @@ namespace llarp bool LinkIntroMessage::HandleMessage(llarp_router* router) const { - router->async_verify_RC(RC, !llarp_rc_is_public_router(RC)); + router->async_verify_RC(RC, !RC.IsPublicRouter()); return true; } } // namespace llarp diff --git a/llarp/link_message.cpp b/llarp/link_message.cpp index 7ad52df54..a96c65dd9 100644 --- a/llarp/link_message.cpp +++ b/llarp/link_message.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include "buffer.hpp" #include "llarp/iwp/session.hpp" @@ -88,8 +88,7 @@ namespace llarp RouterID InboundMessageParser::GetCurrentFrom() { - auto rc = from->get_remote_router(); - return rc->pubkey; + return from->get_remote_router().pubkey; } bool diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 50543fc23..4384c2937 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include #include @@ -22,89 +22,36 @@ struct llarp_nodedb llarp_crypto *crypto; // std::map< llarp::pubkey, llarp_rc > entries; - std::unordered_map< llarp::PubKey, llarp_rc, llarp::PubKey::Hash > entries; + llarp::util::Mutex access; + std::unordered_map< llarp::PubKey, llarp::RouterContact, llarp::PubKey::Hash > + entries; fs::path nodePath; void Clear() { - auto itr = entries.begin(); - while(itr != entries.end()) - { - llarp_rc_clear(&itr->second); - itr = entries.erase(itr); - } - } - - llarp_rc * - getRC(const llarp::PubKey &pk) - { - return &entries.at(pk); + llarp::util::Lock lock(access); + entries.clear(); } bool - Has(const llarp::PubKey &pk) const + Get(const llarp::PubKey &pk, llarp::RouterContact &result) { - return entries.find(pk) != entries.end(); + llarp::util::Lock lock(access); + auto itr = entries.find(pk); + if(itr == entries.end()) + return false; + result = itr->second; + return true; } - /* - bool - Has(const byte_t *pk) - { - llarp::PubKey test(pk); - auto itr = this->entries.begin(); - while(itr != this->entries.end()) - { - llarp::LogInfo("Has byte_t [", test.size(), "] vs [", itr->first.size(), - "]"); if (memcmp(test.data(), itr->first.data(), 32) == 0) { - llarp::LogInfo("Match"); - } - itr++; - } - return entries.find(pk) != entries.end(); - } - */ - bool - pubKeyExists(llarp_rc *rc) const + Has(const llarp::PubKey &pk) { - // extract pk from rc - llarp::PubKey pk = rc->pubkey; - // return true if we found before end + llarp::util::Lock lock(access); return entries.find(pk) != entries.end(); } - bool - check(llarp_rc *rc) - { - if(!pubKeyExists(rc)) - { - // we don't have it - return false; - } - llarp::PubKey pk = rc->pubkey; - - // TODO: zero out any fields you don't want to compare - // XXX: make a copy and then do modifications on the copy - // touching external data in here is HARAM >:[ - - // serialize both and memcmp - byte_t nodetmp[MAX_RC_SIZE]; - auto nodebuf = llarp::StackBuffer< decltype(nodetmp) >(nodetmp); - if(llarp_rc_bencode(&entries[pk], &nodebuf)) - { - byte_t paramtmp[MAX_RC_SIZE]; - auto parambuf = llarp::StackBuffer< decltype(paramtmp) >(paramtmp); - if(llarp_rc_bencode(rc, ¶mbuf)) - { - if(nodebuf.sz == parambuf.sz) - return memcmp(¶mbuf, &nodebuf, parambuf.sz) == 0; - } - } - return false; - } - std::string getRCFilePath(const byte_t *pubkey) const { @@ -119,40 +66,34 @@ struct llarp_nodedb return filepath.string(); } + /// insert and write to disk bool - setRC(llarp_rc *rc) + Insert(const llarp::RouterContact &rc) { byte_t tmp[MAX_RC_SIZE]; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); + { + llarp::util::Lock lock(access); + entries.insert(std::make_pair(rc.pubkey, rc)); + } + if(!rc.BEncode(&buf)) + return false; - // extract pk from rc - llarp::PubKey pk = rc->pubkey; - - // set local db entry to have a copy we own - llarp_rc entry; - llarp::Zero(&entry, sizeof(entry)); - llarp_rc_copy(&entry, rc); - entries.insert(std::make_pair(pk, entry)); - - if(llarp_rc_bencode(&entry, &buf)) + buf.sz = buf.cur - buf.base; + auto filepath = getRCFilePath(rc.pubkey); + llarp::LogDebug("saving RC.pubkey ", filepath); + std::ofstream ofs( + filepath, + std::ofstream::out & std::ofstream::binary & std::ofstream::trunc); + ofs.write((char *)buf.base, buf.sz); + ofs.close(); + if(!ofs) { - buf.sz = buf.cur - buf.base; - auto filepath = getRCFilePath(pk); - llarp::LogDebug("saving RC.pubkey ", filepath); - std::ofstream ofs( - filepath, - std::ofstream::out & std::ofstream::binary & std::ofstream::trunc); - ofs.write((char *)buf.base, buf.sz); - ofs.close(); - if(!ofs) - { - llarp::LogError("Failed to write: ", filepath); - return false; - } - llarp::LogDebug("saved RC.pubkey: ", filepath); - return true; + llarp::LogError("Failed to write: ", filepath); + return false; } - return false; + llarp::LogDebug("saved RC.pubkey: ", filepath); + return true; } ssize_t @@ -197,28 +138,30 @@ struct llarp_nodedb { if(fpath.extension() != RC_FILE_EXT) return false; - llarp_rc rc; - llarp_rc_clear(&rc); + llarp::RouterContact rc; - if(!llarp_rc_read(fpath.string().c_str(), &rc)) + if(!rc.Read(fpath.string().c_str())) { - llarp::LogError("Signature read failed", fpath); + llarp::LogError("failed to read file ", fpath); return false; } - if(!llarp_rc_verify_sig(crypto, &rc)) + if(!rc.VerifySignature(crypto)) { llarp::LogError("Signature verify failed", fpath); return false; } - llarp::PubKey pk(rc.pubkey); - entries[pk] = rc; + { + llarp::util::Lock lock(access); + entries.insert(std::make_pair(rc.pubkey, rc)); + } return true; } bool iterate(struct llarp_nodedb_iter i) { - i.index = 0; + i.index = 0; + llarp::util::Lock lock(access); auto itr = entries.begin(); while(itr != entries.end()) { @@ -263,7 +206,7 @@ disk_threadworker_setRC(void *user) { llarp_async_verify_rc *verify_request = static_cast< llarp_async_verify_rc * >(user); - verify_request->valid = verify_request->nodedb->setRC(&verify_request->rc); + verify_request->valid = verify_request->nodedb->Insert(verify_request->rc); if(verify_request->logic) llarp_logic_queue_job(verify_request->logic, {verify_request, &logic_threadworker_callback}); @@ -276,9 +219,9 @@ crypto_threadworker_verifyrc(void *user) llarp_async_verify_rc *verify_request = static_cast< llarp_async_verify_rc * >(user); verify_request->valid = - llarp_rc_verify_sig(verify_request->nodedb->crypto, &verify_request->rc); + verify_request->rc.VerifySignature(verify_request->nodedb->crypto); // if it's valid we need to set it - if(verify_request->valid && llarp_rc_is_public_router(&verify_request->rc)) + if(verify_request->valid && verify_request->rc.IsPublicRouter()) { llarp::LogDebug("RC is valid, saving to disk"); llarp_threadpool_queue_job(verify_request->diskworker, @@ -310,8 +253,7 @@ nodedb_async_load_rc(void *user) job->loaded = job->nodedb->loadfile(fpath); if(job->loaded) { - llarp_rc_clear(&job->rc); - llarp_rc_copy(&job->rc, job->nodedb->getRC(job->pubkey)); + job->nodedb->Get(job->pubkey, job->result); } llarp_logic_queue_job(job->logic, {job, &nodedb_inform_load_rc}); } @@ -384,14 +326,6 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir) return n->Load(dir); } -/// c api for nodedb::setRC -/// maybe better to use llarp_nodedb_async_verify -bool -llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc) -{ - return n->setRC(rc); -} - int llarp_nodedb_iterate_all(struct llarp_nodedb *n, struct llarp_nodedb_iter i) { @@ -419,14 +353,12 @@ llarp_nodedb_async_load_rc(struct llarp_async_load_rc *job) } */ -struct llarp_rc * -llarp_nodedb_get_rc(struct llarp_nodedb *n, const byte_t *pk) +bool +llarp_nodedb_get_rc(struct llarp_nodedb *n, const llarp::RouterID &pk, + llarp::RouterContact &result) { // llarp::LogInfo("llarp_nodedb_get_rc [", pk, "]"); - if(n->Has(pk)) - return n->getRC(pk); - else - return nullptr; + return n->Get(pk, result); } size_t @@ -436,14 +368,15 @@ llarp_nodedb_num_loaded(struct llarp_nodedb *n) } void -llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev, - struct llarp_rc *result, size_t N) +llarp_nodedb_select_random_hop(struct llarp_nodedb *n, + const llarp::RouterContact &prev, + llarp::RouterContact &result, size_t N) { /// checking for "guard" status for N = 0 is done by caller inside of /// pathbuilder's scope auto sz = n->entries.size(); - if(prev) + if(N) { do { @@ -451,13 +384,14 @@ llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev, if(sz > 1) { auto idx = llarp_randint() % sz; - std::advance(itr, idx); + if(idx) + std::advance(itr, idx - 1); } - if(memcmp(prev->pubkey, itr->second.pubkey, PUBKEYSIZE) == 0) + if(prev.pubkey == itr->second.pubkey) continue; - if(itr->second.addrs && llarp_ai_list_size(itr->second.addrs)) + if(itr->second.addrs.size()) { - llarp_rc_copy(result, &itr->second); + result = itr->second; return; } } while(true); @@ -468,8 +402,9 @@ llarp_nodedb_select_random_hop(struct llarp_nodedb *n, struct llarp_rc *prev, if(sz > 1) { auto idx = llarp_randint() % sz; - std::advance(itr, idx); + if(idx) + std::advance(itr, idx - 1); } - llarp_rc_copy(result, &itr->second); + result = itr->second; } } diff --git a/llarp/path.cpp b/llarp/path.cpp index c06dc6a2f..301881a75 100644 --- a/llarp/path.cpp +++ b/llarp/path.cpp @@ -62,15 +62,11 @@ namespace llarp bool PathContext::ForwardLRCM(const RouterID& nextHop, - std::deque< EncryptedFrame >& frames) + const std::array< EncryptedFrame, 8 >& frames) { llarp::LogDebug("fowarding LRCM to ", nextHop); LR_CommitMessage* msg = new LR_CommitMessage(); - while(frames.size()) - { - msg->frames.push_back(frames.front()); - frames.pop_front(); - } + msg->frames = frames; return m_Router->SendToOrQueue(nextHop, msg); } template < typename Map_t, typename Key_t, typename CheckValue_t, @@ -290,7 +286,7 @@ namespace llarp } void - PathContext::AddPathBuilder(llarp_pathbuilder_context* ctx) + PathContext::AddPathBuilder(Builder* ctx) { m_PathBuilders.push_back(ctx); } @@ -311,7 +307,7 @@ namespace llarp } void - PathContext::RemovePathBuilder(llarp_pathbuilder_context* ctx) + PathContext::RemovePathBuilder(Builder* ctx) { m_PathBuilders.remove(ctx); RemovePathSet(ctx); @@ -319,31 +315,30 @@ namespace llarp PathHopConfig::PathHopConfig() { - llarp_rc_clear(&router); } PathHopConfig::~PathHopConfig() { - llarp_rc_free(&router); } - Path::Path(llarp_path_hops* h) : hops(h->numHops) + Path::Path(const std::vector< RouterContact >& h) : hops(h.size()) { - for(size_t idx = 0; idx < h->numHops; ++idx) + size_t hsz = h.size(); + for(size_t idx = 0; idx < hsz; ++idx) { - llarp_rc_copy(&hops[idx].router, &h->hops[idx].router); + hops[idx].rc = h[idx]; hops[idx].txID.Randomize(); hops[idx].rxID.Randomize(); } - for(size_t idx = 0; idx < h->numHops - 1; ++idx) + for(size_t idx = 0; idx < hsz - 1; ++idx) { hops[idx].txID = hops[idx + 1].rxID; } // initialize parts of the introduction - intro.router = hops[h->numHops - 1].router.pubkey; + intro.router = hops[hsz - 1].rc.pubkey; // TODO: or is it rxid ? - intro.pathID = hops[h->numHops - 1].txID; + intro.pathID = hops[hsz - 1].txID; } void @@ -355,7 +350,7 @@ namespace llarp RouterID Path::Endpoint() const { - return hops[hops.size() - 1].router.pubkey; + return hops[hops.size() - 1].rc.pubkey; } const PathID_t& @@ -379,7 +374,7 @@ namespace llarp RouterID Path::Upstream() const { - return hops[0].router.pubkey; + return hops[0].rc.pubkey; } void diff --git a/llarp/pathbuilder.cpp b/llarp/pathbuilder.cpp index 4659fe944..fd4bea41d 100644 --- a/llarp/pathbuilder.cpp +++ b/llarp/pathbuilder.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -44,7 +44,7 @@ namespace llarp ctx->crypto->encryption_keygen(hop.commkey); hop.nonce.Randomize(); // do key exchange - if(!ctx->crypto->dh_client(hop.shared, hop.router.enckey, hop.commkey, + if(!ctx->crypto->dh_client(hop.shared, hop.rc.enckey, hop.commkey, hop.nonce)) { llarp::LogError("Failed to generate shared key for path build"); @@ -59,11 +59,11 @@ namespace llarp if(isFarthestHop) { - hop.upstream = hop.router.pubkey; + hop.upstream = hop.rc.pubkey; } else { - hop.upstream = ctx->path->hops[ctx->idx].router.pubkey; + hop.upstream = ctx->path->hops[ctx->idx].rc.pubkey; } // build record @@ -87,7 +87,7 @@ namespace llarp // use ephameral keypair for frame SecretKey framekey; ctx->crypto->encryption_keygen(framekey); - if(!frame.EncryptInPlace(framekey, hop.router.enckey, ctx->crypto)) + if(!frame.EncryptInPlace(framekey, hop.rc.enckey, ctx->crypto)) { llarp::LogError("Failed to encrypt LRCR"); return; @@ -123,16 +123,14 @@ namespace llarp for(size_t idx = 0; idx < MAXHOPS; ++idx) { - LRCM->frames.emplace_back(); - LRCM->frames.back().Randomize(); + LRCM->frames[idx].Randomize(); } llarp_threadpool_queue_job(pool, {this, &GenerateNextKey}); } }; void - pathbuilder_generated_keys( - AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx) + pathbuilder_generated_keys(AsyncPathKeyExchangeContext< path::Builder >* ctx) { auto remote = ctx->path->Upstream(); auto router = ctx->user->router; @@ -148,131 +146,104 @@ namespace llarp router->PersistSessionUntil(remote, ctx->path->ExpireTime()); // add own path router->paths.AddOwnPath(ctx->pathset, ctx->path); - ctx->user->pathBuildStarted(ctx->user); } - void - pathbuilder_start_build(void* user) + namespace path { - llarp_pathbuild_job* job = static_cast< llarp_pathbuild_job* >(user); - // select hops - size_t idx = 0; - llarp_rc* prev = nullptr; - while(idx < job->hops.numHops) + Builder::Builder(llarp_router* p_router, struct llarp_dht_context* p_dht, + size_t pathNum, size_t hops) + : llarp::path::PathSet(pathNum) + , router(p_router) + , dht(p_dht) + , numHops(hops) { - llarp_rc* rc = &job->hops.hops[idx].router; - llarp_rc_clear(rc); - if(!job->selectHop(job->user, job->router->nodedb, prev, rc, idx)) - { - /// TODO: handle this failure properly - llarp::LogWarn("Failed to select hop ", idx); - return; - } - prev = rc; - ++idx; + p_router->paths.AddPathBuilder(this); + p_router->crypto.encryption_keygen(enckey); } - // async generate keys - AsyncPathKeyExchangeContext< llarp_pathbuild_job >* ctx = - new AsyncPathKeyExchangeContext< llarp_pathbuild_job >( - &job->router->crypto); - ctx->pathset = job->context; - auto path = new llarp::path::Path(&job->hops); - path->SetBuildResultHook(std::bind(&llarp::path::PathSet::HandlePathBuilt, - ctx->pathset, std::placeholders::_1)); - ctx->AsyncGenerateKeys(path, job->router->logic, job->router->tp, job, - &pathbuilder_generated_keys); - } -} // namespace llarp - -llarp_pathbuilder_context::llarp_pathbuilder_context( - llarp_router* p_router, struct llarp_dht_context* p_dht, size_t pathNum, - size_t hops) - : llarp::path::PathSet(pathNum), router(p_router), dht(p_dht), numHops(hops) -{ - p_router->paths.AddPathBuilder(this); - p_router->crypto.encryption_keygen(enckey); -} - -llarp_pathbuilder_context::~llarp_pathbuilder_context() -{ - router->paths.RemovePathBuilder(this); -} - -bool -llarp_pathbuilder_context::SelectHop(llarp_nodedb* db, llarp_rc* prev, - llarp_rc* cur, size_t hop) -{ - if(hop == 0) - { - return router->GetRandomConnectedRouter(cur); - } - else - llarp_nodedb_select_random_hop(db, prev, cur, hop); - return true; -} - -byte_t* -llarp_pathbuilder_context::GetTunnelEncryptionSecretKey() -{ - return enckey; -} + Builder::~Builder() + { + router->paths.RemovePathBuilder(this); + } -bool -llarp_pathbuilder_context::ShouldBuildMore() const -{ - return llarp::path::PathSet::ShouldBuildMore() - || router->NumberOfConnectedRouters() == 0; -} + bool + Builder::SelectHop(llarp_nodedb* db, const RouterContact& prev, + RouterContact& cur, size_t hop) + { + if(hop == 0) + { + if(router->NumberOfConnectedRouters()) + return router->GetRandomConnectedRouter(cur); + else + { + llarp_nodedb_select_random_hop(db, prev, cur, 0); + return true; + } + } + else + llarp_nodedb_select_random_hop(db, prev, cur, hop); + return true; + } -void -llarp_pathbuilder_context::BuildOne() -{ - llarp_pathbuild_job* job = new llarp_pathbuild_job; - job->context = this; - job->selectHop = &PathSet::SelectHopCallback; - job->hops.numHops = numHops; - job->user = this; - job->pathBuildStarted = [](llarp_pathbuild_job* j) { delete j; }; - llarp_pathbuilder_build_path(job); -} + const byte_t* + Builder::GetTunnelEncryptionSecretKey() const + { + return enckey; + } -void -llarp_pathbuilder_context::ManualRebuild(size_t num) -{ - llarp::LogDebug("manual rebuild ", num); - while(num--) - BuildOne(); -} + bool + Builder::ShouldBuildMore() const + { + return llarp::path::PathSet::ShouldBuildMore() + || router->NumberOfConnectedRouters() == 0; + } -struct llarp_pathbuilder_context* -llarp_pathbuilder_context_new(struct llarp_router* router, - struct llarp_dht_context* dht, size_t sz, - size_t hops) -{ - return new llarp_pathbuilder_context(router, dht, sz, hops); -} + void + Builder::BuildOne() + { + // select hops + std::vector< RouterContact > hops(numHops); + size_t idx = 0; + RouterContact prev; + while(idx < numHops) + { + if(idx == 0) + { + if(!SelectHop(router->nodedb, hops[0], hops[0], 0)) + { + llarp::LogError("failed to select first hop"); + return; + } + } + else + { + if(!SelectHop(router->nodedb, hops[idx - 1], hops[idx], idx)) + { + /// TODO: handle this failure properly + llarp::LogWarn("Failed to select hop ", idx); + return; + } + } + ++idx; + } + // async generate keys + AsyncPathKeyExchangeContext< Builder >* ctx = + new AsyncPathKeyExchangeContext< Builder >(&router->crypto); + ctx->pathset = this; + auto path = new llarp::path::Path(hops); + path->SetBuildResultHook(std::bind(&llarp::path::PathSet::HandlePathBuilt, + ctx->pathset, std::placeholders::_1)); + ctx->AsyncGenerateKeys(path, router->logic, router->tp, this, + &pathbuilder_generated_keys); + } -void -llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx) -{ - delete ctx; -} + void + Builder::ManualRebuild(size_t num) + { + llarp::LogDebug("manual rebuild ", num); + while(num--) + BuildOne(); + } -void -llarp_pathbuilder_build_path(struct llarp_pathbuild_job* job) -{ - if(!job->context) - { - llarp::LogError("failed to build path because no context is set in job"); - return; - } - if(job->selectHop == nullptr) - { - llarp::LogError("No callback provided for hop selection"); - return; - } - job->router = job->context->router; - llarp_logic_queue_job(job->router->logic, - {job, &llarp::pathbuilder_start_build}); -} + } // namespace path +} // namespace llarp diff --git a/llarp/relay_commit.cpp b/llarp/relay_commit.cpp index f811dc7e9..c5204412f 100644 --- a/llarp/relay_commit.cpp +++ b/llarp/relay_commit.cpp @@ -16,7 +16,7 @@ namespace llarp { if(llarp_buffer_eq(key, "c")) { - return BEncodeReadList(frames, buf); + return BEncodeReadArray(frames, buf); } bool read = false; if(!BEncodeMaybeReadVersion("v", version, LLARP_PROTO_VERSION, read, key, @@ -35,7 +35,7 @@ namespace llarp if(!BEncodeWriteDictMsgType(buf, "a", "c")) return false; // frames - if(!BEncodeWriteDictList("c", frames, buf)) + if(!BEncodeWriteDictArray("c", frames, buf)) return false; // version if(!bencode_write_version_entry(buf)) @@ -165,7 +165,7 @@ namespace llarp typedef llarp::path::TransitHop Hop; typedef AsyncFrameDecrypter< LRCMFrameDecrypt > Decrypter; Decrypter* decrypter; - std::deque< EncryptedFrame > frames; + std::array< EncryptedFrame, 8 > frames; Context* context; // decrypted record LR_CommitRecord record; @@ -174,10 +174,8 @@ namespace llarp LRCMFrameDecrypt(Context* ctx, Decrypter* dec, const LR_CommitMessage* commit) - : decrypter(dec), context(ctx), hop(new Hop()) + : decrypter(dec), frames(commit->frames), context(ctx), hop(new Hop()) { - for(const auto& f : commit->frames) - frames.push_back(f); hop->info.downstream = commit->remote; } @@ -281,14 +279,21 @@ namespace llarp llarp::LogDebug("Accepted ", self->hop->info); self->context->PutTransitHop(self->hop); - size_t sz = self->frames.front().size(); - // we pop the front element it was ours - self->frames.pop_front(); + size_t sz = self->frames[0].size(); + // shift + std::array< EncryptedFrame, 8 > frames; + frames[0] = self->frames[1]; + frames[1] = self->frames[2]; + frames[2] = self->frames[3]; + frames[3] = self->frames[4]; + frames[4] = self->frames[5]; + frames[5] = self->frames[6]; + frames[6] = self->frames[7]; // put our response on the end - self->frames.emplace_back(sz - EncryptedFrame::OverheadSize); + frames[7] = EncryptedFrame(sz - EncryptedFrame::OverheadSize); // random junk for now - self->frames.back().Randomize(); - + frames[7].Randomize(); + self->frames = std::move(frames); if(self->context->HopIsUs(info.upstream)) { // we are the farthest hop @@ -315,7 +320,7 @@ namespace llarp LRCMFrameDecrypt* frames = new LRCMFrameDecrypt(context, decrypter, this); // decrypt frames async - decrypter->AsyncDecrypt(context->Worker(), &frames->frames.front(), frames); + decrypter->AsyncDecrypt(context->Worker(), &frames->frames[0], frames); return true; } } // namespace llarp diff --git a/llarp/router.cpp b/llarp/router.cpp index 42ccdc07f..5495f56a7 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -28,6 +28,47 @@ namespace llarp } // namespace llarp +bool +llarp_router_try_connect(struct llarp_router *router, + const llarp::RouterContact &remote, + uint16_t numretries) +{ + // do we already have a pending job for this remote? + if(router->HasPendingConnectJob(remote.pubkey)) + { + llarp::LogDebug("We have pending connect jobs to ", remote.pubkey); + return false; + } + // try first address only + if(remote.addrs.size()) + + { + auto link = router->outboundLink; + auto itr = router->pendingEstablishJobs.insert( + std::make_pair(remote.pubkey, llarp_link_establish_job())); + auto job = &itr.first->second; + job->ai = remote.addrs.front(); + job->pubkey = remote.pubkey; + job->retries = numretries; + job->timeout = 10000; + job->result = &llarp_router::on_try_connect_result; + // give router as user pointer + job->user = router; + job->link = link; + // try establishing async + llarp_logic_queue_job(router->logic, + {job, [](void *u) { + llarp_link_establish_job *j = + static_cast< llarp_link_establish_job * >(u); + j->link->try_establish(j); + j->link = nullptr; + }}); + return true; + } + llarp::LogWarn("couldn't get first address for ", remote.pubkey); + return false; +} + llarp_router::llarp_router() : ready(false) , paths(this) @@ -39,13 +80,11 @@ llarp_router::llarp_router() // set rational defaults this->ip4addr.sin_family = AF_INET; this->ip4addr.sin_port = htons(1090); - llarp_rc_clear(&rc); } llarp_router::~llarp_router() { llarp_dht_context_free(dht); - llarp_rc_free(&rc); } bool @@ -104,8 +143,7 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote, outboundMessageQueue[remote].push(std::move(msg)); // we don't have an open session to that router right now - auto rc = llarp_nodedb_get_rc(nodedb, remote); - if(rc) + if(llarp_nodedb_get_rc(nodedb, remote, rc)) { // try connecting directly as the rc is loaded from disk llarp_router_try_connect(this, rc, 10); @@ -113,55 +151,45 @@ llarp_router::SendToOrQueue(const llarp::RouterID &remote, } // we don't have the RC locally so do a dht lookup - llarp_router_lookup_job *lookup = new llarp_router_lookup_job(); - lookup->user = this; - lookup->iterative = false; - llarp_rc_clear(&lookup->result); - memcpy(lookup->target, remote, PUBKEYSIZE); - lookup->hook = &llarp_router::HandleDHTLookupForSendTo; - lookup->user = this; - llarp_dht_lookup_router(dht, lookup); - + dht->impl.LookupRouter(remote, + std::bind(&llarp_router::HandleDHTLookupForSendTo, + this, remote, std::placeholders::_1)); return true; } void -llarp_router::HandleDHTLookupForSendTo(llarp_router_lookup_job *job) +llarp_router::HandleDHTLookupForSendTo( + llarp::RouterID remote, const std::vector< llarp::RouterContact > &results) { - llarp_router *self = static_cast< llarp_router * >(job->user); - if(job->found) + if(results.size()) { - llarp_nodedb_put_rc(self->nodedb, &job->result); - llarp_router_try_connect(self, &job->result, 10); - llarp_rc_free(&job->result); + llarp_nodedb_put_rc(nodedb, results[0]); + llarp_router_try_connect(this, results[0], 10); } else { - self->DiscardOutboundFor(job->target); + DiscardOutboundFor(remote); } - delete job; } void llarp_router::try_connect(fs::path rcfile) { - llarp_rc remote; - llarp_rc_new(&remote); - if(!llarp_rc_read(rcfile.string().c_str(), &remote)) + llarp::RouterContact remote; + if(!remote.Read(rcfile.string().c_str())) { llarp::LogError("failure to decode or verify of remote RC"); return; } - if(llarp_rc_verify_sig(&crypto, &remote)) + if(remote.VerifySignature(&crypto)) { llarp::LogDebug("verified signature"); // store into filesystem - // TODO: should this be async? - if(!llarp_nodedb_put_rc(nodedb, &remote)) + if(!llarp_nodedb_put_rc(nodedb, remote)) { llarp::LogWarn("failed to store"); } - if(!llarp_router_try_connect(this, &remote, 10)) + if(!llarp_router_try_connect(this, remote, 10)) { // or error? llarp::LogWarn("session already made"); @@ -169,7 +197,6 @@ llarp_router::try_connect(fs::path rcfile) } else llarp::LogError("failed to verify signature of RC", rcfile); - llarp_rc_free(&remote); } bool @@ -185,7 +212,7 @@ bool llarp_router::EnsureEncryptionKey() { return llarp_findOrCreateEncryption( - &crypto, encryption_keyfile.string().c_str(), &this->encryption); + &crypto, encryption_keyfile.string().c_str(), encryption); } void @@ -204,7 +231,7 @@ bool llarp_router::SaveRC() { llarp::LogDebug("verify RC signature"); - if(!llarp_rc_verify_sig(&crypto, &rc)) + if(!rc.VerifySignature(&crypto)) { llarp::LogError("RC has bad signature not saving"); return false; @@ -213,7 +240,7 @@ llarp_router::SaveRC() byte_t tmp[MAX_RC_SIZE]; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); - if(llarp_rc_bencode(&rc, &buf)) + if(rc.BEncode(&buf)) { std::ofstream f(our_rc_file.string()); @@ -272,9 +299,7 @@ llarp_router::on_verify_client_rc(llarp_async_verify_rc *job) { llarp::async_verify_context *ctx = static_cast< llarp::async_verify_context * >(job->user); - llarp::PubKey pk = job->rc.pubkey; - llarp_rc_free(&job->rc); - ctx->router->pendingEstablishJobs.erase(pk); + ctx->router->pendingEstablishJobs.erase(job->rc.pubkey); delete ctx; } @@ -295,7 +320,6 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job) if(session) session->close(); } - llarp_rc_free(&job->rc); router->pendingEstablishJobs.erase(pk); router->DiscardOutboundFor(pk); return; @@ -305,16 +329,10 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job) llarp::LogDebug("rc verified and saved to nodedb"); // refresh valid routers RC value if it's there - auto v = router->validRouters.find(pk); - if(v != router->validRouters.end()) - { - // free previous RC members - llarp_rc_free(&v->second); - } router->validRouters[pk] = job->rc; // track valid router in dht - __llarp_dht_put_peer(router->dht, &router->validRouters[pk]); + router->dht->impl.nodes->PutNode(job->rc); // this was an outbound establish job if(ctx->establish_job) @@ -342,42 +360,31 @@ llarp_router::handle_router_ticker(void *user, uint64_t orig, uint64_t left) void llarp_router::TryEstablishTo(const llarp::RouterID &remote) { - auto rc = llarp_nodedb_get_rc(nodedb, remote); - if(rc) + llarp::RouterContact rc; + if(llarp_nodedb_get_rc(nodedb, remote, rc)) { - // try connecting + // try connecting async llarp_router_try_connect(this, rc, 5); } else { // dht lookup as we don't know it - llarp_router_lookup_job *lookup = new llarp_router_lookup_job; - llarp_rc_clear(&lookup->result); - memcpy(lookup->target, remote, PUBKEYSIZE); - lookup->hook = &llarp_router::HandleDHTLookupForTryEstablishTo; - lookup->iterative = false; - lookup->user = this; - llarp_dht_lookup_router(dht, lookup); + dht->impl.LookupRouter( + remote, + std::bind(&llarp_router::HandleDHTLookupForTryEstablishTo, this, + std::placeholders::_1)); } } void -llarp_router::HandleDHTLookupForTryEstablishTo(llarp_router_lookup_job *job) +llarp_router::HandleDHTLookupForTryEstablishTo( + const std::vector< llarp::RouterContact > &results) { - if(job->found) + if(results.size()) { - llarp_router *self = static_cast< llarp_router * >(job->user); - llarp_nodedb_put_rc(self->nodedb, &job->result); - llarp_router_try_connect(self, &job->result, 5); - llarp_rc_free(&job->result); + llarp_nodedb_put_rc(nodedb, results[0]); + llarp_router_try_connect(this, results[0], 5); } - delete job; -} - -void -llarp_router::HandleExploritoryPathBuildStarted(llarp_pathbuild_job *job) -{ - delete job; } size_t @@ -487,9 +494,7 @@ llarp_router::SessionClosed(const llarp::RouterID &remote) auto itr = validRouters.find(remote); if(itr == validRouters.end()) return; - __llarp_dht_remove_peer(dht, remote); - llarp_rc_free(&itr->second); validRouters.erase(itr); } @@ -585,7 +590,7 @@ llarp_router::DiscardOutboundFor(const llarp::RouterID &remote) } bool -llarp_router::GetRandomConnectedRouter(llarp_rc *result) const +llarp_router::GetRandomConnectedRouter(llarp::RouterContact &result) const { auto sz = validRouters.size(); if(sz) @@ -593,21 +598,25 @@ llarp_router::GetRandomConnectedRouter(llarp_rc *result) const auto itr = validRouters.begin(); if(sz > 1) std::advance(itr, llarp_randint() % sz); - llarp_rc_copy(result, &itr->second); + result = itr->second; return true; } return false; } void -llarp_router::async_verify_RC(llarp_rc *rc, bool isExpectingClient, +llarp_router::async_verify_RC(const llarp::RouterContact &rc, + bool isExpectingClient, llarp_link_establish_job *establish_job) { - llarp_async_verify_rc *job = new llarp_async_verify_rc(); - job->user = new llarp::async_verify_context{this, establish_job}; - job->rc = {}; - job->valid = false; - job->hook = nullptr; + llarp_async_verify_rc *job = new llarp_async_verify_rc(); + llarp::async_verify_context *ctx = new llarp::async_verify_context(); + ctx->router = this; + ctx->establish_job = establish_job; + job->user = ctx; + job->rc = rc; + job->valid = false; + job->hook = nullptr; job->nodedb = nodedb; job->logic = logic; @@ -615,7 +624,6 @@ llarp_router::async_verify_RC(llarp_rc *rc, bool isExpectingClient, job->cryptoworker = tp; job->diskworker = disk; - llarp_rc_copy(&job->rc, rc); if(isExpectingClient) job->hook = &llarp_router::on_verify_client_rc; else @@ -627,10 +635,6 @@ void llarp_router::Run() { // zero out router contact - llarp::Zero(&rc, sizeof(llarp_rc)); - // fill our address list - rc.addrs = llarp_ai_list_new(); - sockaddr *dest = (sockaddr *)&this->ip4addr; llarp::Addr publicAddr(*dest); if(this->publicOverride) @@ -644,8 +648,8 @@ llarp_router::Run() llarp::LogInfo("You have ", inboundLinks.size(), " inbound links"); for(auto link : inboundLinks) { - llarp_ai addr; - link->get_our_address(&addr); + llarp::AddressInfo addr; + link->get_our_address(addr); llarp::Addr a(addr); if(this->publicOverride && a.sameAddr(publicAddr)) { @@ -654,7 +658,7 @@ llarp_router::Run() if(!a.isPrivate()) { llarp::LogInfo("Loading Addr: ", a, " into our RC"); - llarp_ai_list_pushback(rc.addrs, &addr); + rc.addrs.push_back(addr); } }; if(this->publicOverride) @@ -674,47 +678,27 @@ llarp_router::Run() return; } link = inboundLinks.front(); - /* - // create a new link - link = new llarp_link; - llarp::Zero(link, sizeof(llarp_link)); - - llarp_iwp_args args = { - .crypto = &this->crypto, - .logic = this->logic, - .cryptoworker = this->tp, - .router = this, - .keyfile = this->transport_keyfile.c_str(), - }; - iwp_link_init(link, args); - if(llarp_link_initialized(link)) - { - - } - */ } - link->get_our_address(&this->addrInfo); + link->get_our_address(this->addrInfo); // override ip and port this->addrInfo.ip = *publicAddr.addr6(); this->addrInfo.port = publicAddr.port(); llarp::LogInfo("Loaded our public ", publicAddr, " override into RC!"); // we need the link to set the pubkey - llarp_ai_list_pushback(rc.addrs, &this->addrInfo); + rc.addrs.push_back(this->addrInfo); } // set public encryption key - llarp_rc_set_pubenckey(&rc, llarp::seckey_topublic(encryption)); - - char ftmp[68] = {0}; - const char *hexKey = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >( - llarp::seckey_topublic(encryption), ftmp); - llarp::LogInfo("Your Encryption pubkey ", hexKey); + rc.enckey = llarp::seckey_topublic(encryption); + llarp::LogInfo("Your Encryption pubkey ", rc.enckey); // set public signing key - llarp_rc_set_pubsigkey(&rc, llarp::seckey_topublic(identity)); - hexKey = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >( - llarp::seckey_topublic(identity), ftmp); - llarp::LogInfo("Your Identity pubkey ", hexKey); + rc.pubkey = llarp::seckey_topublic(identity); + llarp::LogInfo("Your Identity pubkey ", rc.pubkey); - llarp_rc_sign(&crypto, identity, &rc); + if(!rc.Sign(&crypto, identity)) + { + llarp::LogError("failed to sign rc"); + return; + } if(!SaveRC()) { @@ -865,166 +849,6 @@ llarp_run_router(struct llarp_router *router, struct llarp_nodedb *nodedb) router->Run(); } -bool -llarp_router_try_connect(struct llarp_router *router, struct llarp_rc *remote, - uint16_t numretries) -{ - char ftmp[68] = {0}; - const char *hexname = - llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(remote->pubkey, ftmp); - - // do we already have a pending job for this remote? - if(router->HasPendingConnectJob(remote->pubkey)) - { - llarp::LogDebug("We have pending connect jobs to ", hexname); - 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.insert( - 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(job); - return true; - } - llarp::LogWarn("couldn't get first address for ", hexname); - return false; -} - -void -llarp_rc_clear(struct llarp_rc *rc) -{ - // zero out router contact - llarp::Zero(rc, sizeof(llarp_rc)); -} - -void -llarp_rc_set_pubenckey(struct llarp_rc *rc, const uint8_t *pubenckey) -{ - // set public encryption key - memcpy(rc->enckey, pubenckey, PUBKEYSIZE); -} - -void -llarp_rc_set_pubsigkey(struct llarp_rc *rc, const uint8_t *pubsigkey) -{ - // set public signing key - memcpy(rc->pubkey, pubsigkey, PUBKEYSIZE); -} - -void -llarp_rc_set_pubkey(struct llarp_rc *rc, const uint8_t *pubenckey, - const uint8_t *pubsigkey) -{ - // set public encryption key - llarp_rc_set_pubenckey(rc, pubenckey); - // set public signing key - llarp_rc_set_pubsigkey(rc, pubsigkey); -} - -bool -llarp_rc_read(const char *fpath, llarp_rc *result) -{ - fs::path our_rc_file(fpath); - std::error_code ec; - if(!fs::exists(our_rc_file, ec)) - { - printf("File[%s] not found\n", fpath); - return false; - } - - std::ifstream f(our_rc_file.string(), std::ios::binary); - - if(!f.is_open()) - { - printf("Can't open file [%s]\n", fpath); - return false; - } - byte_t tmp[MAX_RC_SIZE]; - llarp_buffer_t buf = llarp::StackBuffer< decltype(tmp) >(tmp); - f.seekg(0, std::ios::end); - size_t sz = f.tellg(); - f.seekg(0, std::ios::beg); - - if(sz > buf.sz) - return false; - - f.read((char *)buf.base, sz); - // printf("contents[%s]\n", tmpc); - llarp::Zero(result, sizeof(llarp_rc)); - if(!llarp_rc_bdecode(result, &buf)) - { - llarp::LogError("Can't decode ", fpath); - return false; - } - 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); -} - -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.string(), std::ios::binary); - if(f.is_open()) - { - f.write((char *)buf.base, buf.cur - buf.base); - return true; - } - } - 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)) - { - // sign - signbuf.sz = signbuf.cur - signbuf.base; - crypto->sign(rc->signature, seckey, signbuf); - } -} - void llarp_stop_router(struct llarp_router *router) { @@ -1052,14 +876,6 @@ llarp_free_router(struct llarp_router **router) *router = nullptr; } -void -llarp_router_override_path_selection(struct llarp_router *router, - llarp_pathbuilder_select_hop_func func) -{ - if(func) - router->selectHopFunc = func; -} - bool llarp_findOrCreateIdentity(llarp_crypto *crypto, const char *fpath, byte_t *secretkey) @@ -1226,13 +1042,9 @@ namespace llarp { if(StrEq(key, "nickname")) { - if(llarp_rc_set_nickname(&self->rc, val)) - { - // set logger name here - _glog.nodeName = self->rc.Nick(); - } - else - llarp::LogWarn("failed to set nickname to ", val); + self->rc.SetNick(val); + // set logger name here + _glog.nodeName = self->rc.Nick(); } if(StrEq(key, "encryption-privkey")) { diff --git a/llarp/router.hpp b/llarp/router.hpp index cad7bf00c..d7b38853e 100644 --- a/llarp/router.hpp +++ b/llarp/router.hpp @@ -1,8 +1,8 @@ #ifndef LLARP_ROUTER_HPP #define LLARP_ROUTER_HPP #include -#include -#include +#include +#include #include #include @@ -24,25 +24,12 @@ /** 2^15 bytes */ #define MAX_LINK_MSG_SIZE (32768) -// TODO: unused. remove? -// struct try_connect_ctx -// { -// llarp_router *router = nullptr; -// llarp_ai addr; -// }; - -// // forward declare -// namespace path -// { -// struct TransitHop; -// } - struct llarp_link; struct llarp_link_session_iter; bool llarp_findOrCreateEncryption(llarp_crypto *crypto, const char *fpath, - llarp::SecretKey *encryption); + llarp::SecretKey &encryption); struct llarp_router { @@ -62,12 +49,12 @@ struct llarp_router fs::path our_rc_file = "rc.signed"; // our router contact - llarp_rc rc; + llarp::RouterContact rc; // our ipv4 public setting bool publicOverride = false; struct sockaddr_in ip4addr; - llarp_ai addrInfo; + llarp::AddressInfo addrInfo; llarp_ev_loop *netloop; llarp_threadpool *tp; @@ -92,9 +79,6 @@ struct llarp_router llarp::InboundMessageParser inbound_link_msg_parser; llarp::routing::InboundMessageParser inbound_routing_msg_parser; - llarp_pathbuilder_select_hop_func selectHopFunc = nullptr; - llarp_pathbuilder_context *explorePool = nullptr; - llarp::service::Context hiddenServiceContext; llarp_link *outboundLink = nullptr; @@ -107,7 +91,7 @@ struct llarp_router std::map< llarp::RouterID, MessageQueue > outboundMessageQueue; /// loki verified routers - std::map< llarp::RouterID, llarp_rc > validRouters; + std::map< llarp::RouterID, llarp::RouterContact > validRouters; // pending establishing session with routers std::map< llarp::PubKey, llarp_link_establish_job > pendingEstablishJobs; @@ -222,12 +206,20 @@ struct llarp_router NumberOfConnectedRouters() const; bool - GetRandomConnectedRouter(llarp_rc *result) const; + GetRandomConnectedRouter(llarp::RouterContact &result) const; void - async_verify_RC(llarp_rc *rc, bool isExpectingClient, + async_verify_RC(const llarp::RouterContact &rc, bool isExpectingClient, llarp_link_establish_job *job = nullptr); + void + HandleDHTLookupForSendTo(llarp::RouterID remote, + const std::vector< llarp::RouterContact > &results); + + void + HandleDHTLookupForTryEstablishTo( + const std::vector< llarp::RouterContact > &results); + static bool iter_try_connect(llarp_router_link_iter *i, llarp_router *router, llarp_link *l); @@ -253,15 +245,6 @@ struct llarp_router static void HandleAsyncLoadRCForSendTo(llarp_async_load_rc *async); - - static void - HandleDHTLookupForSendTo(llarp_router_lookup_job *job); - - static void - HandleExploritoryPathBuildStarted(llarp_pathbuild_job *job); - - static void - HandleDHTLookupForTryEstablishTo(llarp_router_lookup_job *job); }; #endif diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index fc587a8da..dc72c9cb4 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -1,264 +1,98 @@ -#include -#include +#include +#include #include #include #include "buffer.hpp" #include "logger.hpp" #include "mem.hpp" -bool -llarp_rc_new(struct llarp_rc *rc) +namespace llarp { - rc->addrs = llarp_ai_list_new(); - rc->exits = llarp_xi_list_new(); - rc->last_updated = 0; - llarp::Zero(rc->nickname, sizeof(rc->nickname)); - return true; -} - -void -llarp_rc_free(struct llarp_rc *rc) -{ - if(rc->exits) - llarp_xi_list_free(rc->exits); - if(rc->addrs) - llarp_ai_list_free(rc->addrs); - - rc->exits = 0; - rc->addrs = 0; -} - -struct llarp_rc_decoder -{ - struct llarp_rc *rc; - struct llarp_alloc *mem; -}; - -static bool -llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key) -{ - uint64_t v; - llarp_buffer_t strbuf; - llarp_rc *rc = static_cast< llarp_rc * >(r->user); - - if(!key) - return true; - - if(llarp_buffer_eq(*key, "a")) + bool + RouterContact::BEncode(llarp_buffer_t *buf) const { - if(rc->addrs) - { - llarp_ai_list_free(rc->addrs); - } - rc->addrs = llarp_ai_list_new(); - return llarp_ai_list_bdecode(rc->addrs, r->buffer); - } - - if(llarp_buffer_eq(*key, "k")) - { - if(!bencode_read_string(r->buffer, &strbuf)) + /* write dict begin */ + if(!bencode_start_dict(buf)) return false; - if(strbuf.sz != PUBKEYSIZE) - return false; - memcpy(rc->pubkey, strbuf.base, PUBKEYSIZE); - return true; - } - if(llarp_buffer_eq(*key, "n")) - { - if(!bencode_read_string(r->buffer, &strbuf)) - return false; - if(strbuf.sz > sizeof(rc->nickname)) - return false; - llarp::Zero(rc->nickname, sizeof(rc->nickname)); - memcpy(rc->nickname, strbuf.base, strbuf.sz); - return true; - } - - if(llarp_buffer_eq(*key, "p")) - { - if(!bencode_read_string(r->buffer, &strbuf)) + /* write ai if they exist */ + if(!bencode_write_bytestring(buf, "a", 1)) return false; - if(strbuf.sz != PUBKEYSIZE) + if(!BEncodeWriteList(addrs.begin(), addrs.end(), buf)) return false; - memcpy(rc->enckey, strbuf.base, PUBKEYSIZE); - return true; - } - if(llarp_buffer_eq(*key, "u")) - { - if(!bencode_read_integer(r->buffer, &rc->last_updated)) + /* write signing pubkey */ + if(!bencode_write_bytestring(buf, "k", 1)) return false; - return true; - } - - if(llarp_buffer_eq(*key, "v")) - { - if(!bencode_read_integer(r->buffer, &v)) + if(!pubkey.BEncode(buf)) return false; - return v == LLARP_PROTO_VERSION; - } - if(llarp_buffer_eq(*key, "x")) - { - if(rc->exits) + std::string nick = Nick(); + if(nick.size()) { - llarp_xi_list_free(rc->exits); + /* write nickname */ + if(!bencode_write_bytestring(buf, "n", 1)) + return false; + if(!bencode_write_bytestring(buf, nick.c_str(), nick.size())) + return false; } - rc->exits = llarp_xi_list_new(); - return llarp_xi_list_bdecode(rc->exits, r->buffer); - } - if(llarp_buffer_eq(*key, "z")) - { - if(!bencode_read_string(r->buffer, &strbuf)) + /* write encryption pubkey */ + if(!bencode_write_bytestring(buf, "p", 1)) return false; - if(strbuf.sz != SIGSIZE) + if(!enckey.BEncode(buf)) return false; - memcpy(rc->signature, strbuf.base, SIGSIZE); - return true; - } - - return false; -} - -bool -llarp_rc_is_public_router(const struct llarp_rc *const rc) -{ - return rc->addrs && llarp_ai_list_size(rc->addrs) > 0; -} - -bool -llarp_rc_set_nickname(struct llarp_rc *rc, const char *nick) -{ - strncpy((char *)rc->nickname, nick, sizeof(rc->nickname)); - /// TODO: report nickname truncation - return true; -} - -void -llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src) -{ - llarp_rc_free(dst); - llarp_rc_clear(dst); - memcpy(dst->pubkey, src->pubkey, PUBKEYSIZE); - memcpy(dst->enckey, src->enckey, PUBKEYSIZE); - memcpy(dst->signature, src->signature, SIGSIZE); - dst->last_updated = src->last_updated; - - if(src->addrs) - { - dst->addrs = llarp_ai_list_new(); - llarp_ai_list_copy(dst->addrs, src->addrs); - } - if(src->exits) - { - dst->exits = llarp_xi_list_new(); - llarp_xi_list_copy(dst->exits, src->exits); - } - memcpy(dst->nickname, src->nickname, sizeof(dst->nickname)); -} - -bool -llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buff) -{ - dict_reader r = {buff, rc, &llarp_rc_decode_dict}; - return bencode_read_dict(buff, &r); -} - -bool -llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc) -{ - // maybe we should copy rc before modifying it - // would that make it more thread safe? - // jeff agrees - bool result = false; - llarp::Signature sig; - byte_t tmp[MAX_RC_SIZE]; - auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); - // copy sig - memcpy(sig, rc->signature, SIGSIZE); - // zero sig - size_t sz = 0; - while(sz < SIGSIZE) - rc->signature[sz++] = 0; - - // bencode - if(llarp_rc_bencode(rc, &buf)) - { - buf.sz = buf.cur - buf.base; - buf.cur = buf.base; - result = crypto->verify(rc->pubkey, buf, sig); - } - else - llarp::LogWarn("RC encode failed"); - // restore sig - memcpy(rc->signature, sig, SIGSIZE); - return result; -} + /* write last updated */ + if(!bencode_write_bytestring(buf, "u", 1)) + return false; + if(!bencode_write_uint64(buf, last_updated)) + return false; -bool -llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buff) -{ - /* write dict begin */ - if(!bencode_start_dict(buff)) - return false; + /* write version */ + if(!bencode_write_version_entry(buf)) + return false; - if(rc->addrs) - { /* write ai if they exist */ - if(!bencode_write_bytestring(buff, "a", 1)) + if(!bencode_write_bytestring(buf, "x", 1)) return false; - if(!llarp_ai_list_bencode(rc->addrs, buff)) + if(!BEncodeWriteList(exits.begin(), exits.end(), buf)) return false; - } - /* write signing pubkey */ - if(!bencode_write_bytestring(buff, "k", 1)) - return false; - if(!bencode_write_bytestring(buff, rc->pubkey, PUBKEYSIZE)) - return false; + /* write signature */ + if(!bencode_write_bytestring(buf, "z", 1)) + return false; + if(!signature.BEncode(buf)) + return false; + return bencode_end(buf); + } - auto nicklen = strnlen((char *)rc->nickname, sizeof(rc->nickname)); - if(nicklen) + bool + RouterContact::DecodeKey(llarp_buffer_t key, llarp_buffer_t *buf) { - /* write nickname */ - if(!bencode_write_bytestring(buff, "n", 1)) + bool read = false; + if(!BEncodeMaybeReadDictList("a", addrs, read, key, buf)) return false; - if(!bencode_write_bytestring(buff, rc->nickname, nicklen)) + + if(!BEncodeMaybeReadDictEntry("k", pubkey, read, key, buf)) return false; - } - /* write encryption pubkey */ - if(!bencode_write_bytestring(buff, "p", 1)) - return false; - if(!bencode_write_bytestring(buff, rc->enckey, PUBKEYSIZE)) - return false; + if(!BEncodeMaybeReadDictEntry("n", nickname, read, key, buf)) + return false; - /* write last updated */ - if(!bencode_write_bytestring(buff, "u", 1)) - return false; - if(!bencode_write_uint64(buff, rc->last_updated)) - return false; + if(!BEncodeMaybeReadDictEntry("p", enckey, read, key, buf)) + return false; - /* write version */ - if(!bencode_write_version_entry(buff)) - return false; + if(!BEncodeMaybeReadDictInt("u", last_updated, read, key, buf)) + return false; - if(rc->exits) - { - /* write ai if they exist */ - if(!bencode_write_bytestring(buff, "x", 1)) + if(!BEncodeMaybeReadDictList("x", exits, read, key, buf)) return false; - if(!llarp_xi_list_bencode(rc->exits, buff)) + + if(!BEncodeMaybeReadDictEntry("z", signature, read, key, buf)) return false; + + return read; } - /* write signature */ - if(!bencode_write_bytestring(buff, "z", 1)) - return false; - if(!bencode_write_bytestring(buff, rc->signature, SIGSIZE)) - return false; - return bencode_end(buff); -} +} // namespace llarp diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp index 236a3f7ca..e69de29bb 100644 --- a/llarp/router_contact.hpp +++ b/llarp/router_contact.hpp @@ -1,5 +0,0 @@ -#ifndef LLARP_RC_HPP -#define LLARP_RC_HPP -#include - -#endif diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 3274b4fb5..5d1e955dc 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -11,7 +11,7 @@ namespace llarp namespace service { Endpoint::Endpoint(const std::string& name, llarp_router* r) - : llarp_pathbuilder_context(r, r->dht, 2, 4), m_Router(r), m_Name(name) + : path::Builder(r, r->dht, 2, 4), m_Router(r), m_Name(name) { m_Tag.Zero(); } @@ -594,8 +594,7 @@ namespace llarp job->diskworker = m_Router->disk; job->logic = nullptr; job->hook = nullptr; - llarp_rc_clear(&job->rc); - llarp_rc_copy(&job->rc, &msg->R[0]); + job->rc = msg->R[0]; llarp_nodedb_async_verify(job); return true; } @@ -607,7 +606,8 @@ namespace llarp { if(router.IsZero()) return; - if(!llarp_nodedb_get_rc(m_Router->nodedb, router)) + RouterContact rc; + if(!llarp_nodedb_get_rc(m_Router->nodedb, router, rc)) { if(m_PendingRouters.find(router) == m_PendingRouters.end()) { @@ -712,8 +712,7 @@ namespace llarp Endpoint::OutboundContext::OutboundContext(const IntroSet& intro, Endpoint* parent) - : llarp_pathbuilder_context(parent->m_Router, parent->m_Router->dht, 2, - 4) + : path::Builder(parent->m_Router, parent->m_Router->dht, 2, 4) , currentIntroSet(intro) , m_Parent(parent) @@ -976,15 +975,14 @@ namespace llarp } bool - Endpoint::OutboundContext::SelectHop(llarp_nodedb* db, llarp_rc* prev, - llarp_rc* cur, size_t hop) + Endpoint::OutboundContext::SelectHop(llarp_nodedb* db, + const RouterContact& prev, + RouterContact& cur, size_t hop) { if(hop == numHops - 1) { - auto localcopy = llarp_nodedb_get_rc(db, selectedIntro.router); - if(localcopy) + if(llarp_nodedb_get_rc(db, selectedIntro.router, cur)) { - llarp_rc_copy(cur, localcopy); return true; } else @@ -999,7 +997,7 @@ namespace llarp } } else - return llarp_pathbuilder_context::SelectHop(db, prev, cur, hop); + return path::Builder::SelectHop(db, prev, cur, hop); } uint64_t diff --git a/llarp/threadpool.cpp b/llarp/threadpool.cpp index f958c3441..966f6e86d 100644 --- a/llarp/threadpool.cpp +++ b/llarp/threadpool.cpp @@ -49,7 +49,7 @@ namespace llarp } for(;;) { - llarp_thread_job job; + Job_t job; { lock_t lock(this->queue_mutex); this->condition.WaitUntil( @@ -59,18 +59,15 @@ namespace llarp // discard pending jobs while(this->jobs.size()) { - delete this->jobs.top().job; this->jobs.pop(); } return; } - job.user = this->jobs.top().job->user; - job.work = this->jobs.top().job->work; - delete this->jobs.top().job; + job = std::move(this->jobs.top()); this->jobs.pop(); } // do work - job.work(job.user); + job(); } }); } @@ -104,8 +101,7 @@ namespace llarp // don't allow enqueueing after stopping the pool if(stop) return; - - jobs.emplace(ids++, new llarp_thread_job(job.user, job.work)); + jobs.emplace(ids++, job); } condition.NotifyOne(); } @@ -197,7 +193,8 @@ struct llarp_threadpool llarp::thread::Pool *impl; llarp::util::Mutex m_access; - std::queue< llarp_thread_job * > jobs; + uint32_t ids = 0; + std::queue< llarp::thread::Pool::Job_t > jobs; llarp_threadpool(int workers, const char *name, bool isolate, setup_net_func setup = nullptr, @@ -284,15 +281,11 @@ llarp_threadpool_queue_job(struct llarp_threadpool *pool, { if(pool->impl) pool->impl->QueueJob(job); - else if(job.user && job.work) + else { - auto j = new llarp_thread_job; - j->work = job.work; - j->user = job.user; - { - llarp::util::Lock lock(pool->m_access); - pool->jobs.push(j); - } + // single threaded mode + llarp::util::Lock lock(pool->m_access); + pool->jobs.emplace(++pool->ids, job); } } @@ -301,14 +294,13 @@ llarp_threadpool_tick(struct llarp_threadpool *pool) { while(pool->jobs.size()) { - llarp_thread_job *job; + llarp::thread::Pool::Job_t job; { llarp::util::Lock lock(pool->m_access); - job = pool->jobs.front(); + job = std::move(pool->jobs.front()); pool->jobs.pop(); } - job->work(job->user); - delete job; + job(); } } diff --git a/llarp/threadpool.hpp b/llarp/threadpool.hpp index 72b5f8634..69af6c023 100644 --- a/llarp/threadpool.hpp +++ b/llarp/threadpool.hpp @@ -34,8 +34,13 @@ namespace llarp struct Job_t { uint32_t id; - llarp_thread_job* job; - Job_t(uint32_t jobid, llarp_thread_job* j) : id(jobid), job(j) + void* user; + llarp_thread_work_func work; + + Job_t() = default; + + Job_t(uint32_t jobid, const llarp_thread_job& j) + : id(jobid), user(j.user), work(j.work) { } @@ -44,6 +49,12 @@ namespace llarp { return id < j.id; } + + void + operator()() const + { + work(user); + } }; std::priority_queue< Job_t > jobs; diff --git a/llarp/timer.cpp b/llarp/timer.cpp index 0377c14ba..5cfe773e6 100644 --- a/llarp/timer.cpp +++ b/llarp/timer.cpp @@ -56,8 +56,8 @@ namespace llarp struct llarp_timer_context { llarp::util::Mutex timersMutex; - std::unordered_map< uint32_t, llarp::timer* > timers; - std::priority_queue< llarp::timer* > calling; + std::unordered_map< uint32_t, std::unique_ptr< llarp::timer > > timers; + std::priority_queue< std::unique_ptr< llarp::timer > > calling; llarp::util::Mutex tickerMutex; llarp::util::Condition* ticker = nullptr; std::chrono::milliseconds nextTickLen = std::chrono::milliseconds(100); @@ -87,7 +87,7 @@ struct llarp_timer_context cancel(uint32_t id) { llarp::util::Lock lock(timersMutex); - auto itr = timers.find(id); + const auto& itr = timers.find(id); if(itr == timers.end()) return; itr->second->canceled = true; @@ -97,7 +97,7 @@ struct llarp_timer_context remove(uint32_t id) { llarp::util::Lock lock(timersMutex); - auto itr = timers.find(id); + const auto& itr = timers.find(id); if(itr == timers.end()) return; itr->second->func = nullptr; @@ -109,7 +109,10 @@ struct llarp_timer_context { llarp::util::Lock lock(timersMutex); uint32_t id = ++ids; - timers[id] = new llarp::timer(timeout_ms, user, func); + timers.insert( + std::make_pair(id, + std::unique_ptr< llarp::timer >( + new llarp::timer(timeout_ms, user, func)))); return id; } @@ -184,24 +187,30 @@ llarp_timer_tick_all(struct llarp_timer_context* t) if(!t->run()) return; auto now = llarp_time_now_ms(); - auto itr = t->timers.begin(); - while(itr != t->timers.end()) + std::list< std::unique_ptr< llarp::timer > > hit; { - if(now - itr->second->started >= itr->second->timeout - || itr->second->canceled) + llarp::util::Lock lock(t->timersMutex); + auto itr = t->timers.begin(); + while(itr != t->timers.end()) { - if(itr->second->func && itr->second->called_at == 0) + if(now - itr->second->started >= itr->second->timeout + || itr->second->canceled) { // timer hit - itr->second->called_at = now; - itr->second->exec(); - llarp::timer* timer = itr->second; - itr = t->timers.erase(itr); - delete timer; - continue; + hit.emplace_back(std::move(itr->second)); + itr = t->timers.erase(itr); } + else + ++itr; + } + } + for(const auto& h : hit) + { + if(h->func) + { + h->called_at = now; + h->exec(); } - ++itr; } }