diff --git a/Makefile b/Makefile index b68eb095b..72fb96aa9 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ ifneq ($(GIT_VERSION),"") endif REQUIRED_CFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c99 $(CFLAGS) $(DEBUG_FLAGS) $(VER_FLAGS) -REQUIRED_CXXFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c++14 $(CXXFLAGS) $(DEBUG_FLAGS) $(VER_FLAGS) +REQUIRED_CXXFLAGS = $(LIBUV_FLAGS) $(SODIUM_FLAGS) -I$(REPO)/include -std=c++17 $(CXXFLAGS) $(DEBUG_FLAGS) $(VER_FLAGS) REQUIRED_LDFLAGS = $(LDFLAGS) -ljemalloc $(SODIUM_LIBS) $(LIBUV_LIBS) all: build diff --git a/doc/proto_v0.txt b/doc/proto_v0.txt index 4177fc729..f4f2cff2d 100644 --- a/doc/proto_v0.txt +++ b/doc/proto_v0.txt @@ -295,8 +295,8 @@ router contact (RC) { a: [ one, or, many, AI, here ... ], k: "<32 bytes public signing/encryption identity key>", - x: [ Exit, Infos ], v: 0, + x: [ Exit, Infos ], z: "<64 bytes signature using identity key>" } diff --git a/include/llarp/address_info.h b/include/llarp/address_info.h index 25e329ee2..5a653e3b4 100644 --- a/include/llarp/address_info.h +++ b/include/llarp/address_info.h @@ -1,6 +1,7 @@ #ifndef LLARP_AI_H #define LLARP_AI_H #include +#include #include #include @@ -8,19 +9,43 @@ extern "C" { #endif - struct llarp_address_info +#define MAX_AI_DIALECT_SIZE 5 + + struct llarp_ai { uint16_t rank; llarp_pubkey_t enc_key; - char * dialect; + uint8_t dialect[MAX_AI_DIALECT_SIZE+1]; struct in6_addr ip; uint16_t port; }; - bool llarp_address_info_bencode(struct llarp_address_info * ai, llarp_buffer_t * buff); - bool llarp_address_info_bdecode(struct llarp_address_info * ai, llarp_buffer_t buff); + /** allocator for address info */ + extern struct llarp_alloc * llarp_ai_alloc; + + bool llarp_ai_bencode(struct llarp_ai * ai, llarp_buffer_t * buff); + bool llarp_ai_bdecode(struct llarp_ai * ai, llarp_buffer_t buff); + + struct llarp_ai_list; + + struct llarp_ai_list * llarp_ai_list_new(); + void llarp_ai_list_free(struct llarp_ai_list * l); - struct llarp_address_info_list; + struct llarp_ai llarp_ai_list_popfront(struct llarp_ai_list * l); + void llarp_ai_list_pushback(struct llarp_ai_list * l, struct llarp_ai * ai); + size_t llarp_ai_list_size(struct llarp_ai_list * l); + struct llarp_ai * llarp_ai_list_index(struct llarp_ai_list * l, ssize_t idx); + + struct llarp_ai_list_iter + { + void * user; + /** set by llarp_ai_list_iterate() */ + struct llarp_ai_list * list; + /** return false to break iteration */ + bool (*visit)(struct llarp_ai_list_iter *, struct llarp_ai *); + }; + + void llarp_ai_list_iterate(struct llarp_ai_list * l, struct llarp_ai_list_iter * iter); #ifdef __cplusplus } diff --git a/include/llarp/buffer.h b/include/llarp/buffer.h index da864481c..8530a9943 100644 --- a/include/llarp/buffer.h +++ b/include/llarp/buffer.h @@ -12,6 +12,7 @@ extern "C" { } llarp_buffer_t; size_t llarp_buffer_size_left(llarp_buffer_t * buff); + bool llarp_buffer_write(llarp_buffer_t * buff, const void * data, size_t sz); #ifdef __cplusplus } diff --git a/include/llarp/exit_info.h b/include/llarp/exit_info.h index c0c44de7f..0eb35af12 100644 --- a/include/llarp/exit_info.h +++ b/include/llarp/exit_info.h @@ -1,18 +1,23 @@ #ifndef LLARP_XI_H #define LLARP_XI_H +#include #include #ifdef __cplusplus extern "C" { #endif - struct llarp_exit_info + struct llarp_xi { in6_addr address; in6_addr netmask; }; - struct llarp_exit_info_list; + + bool llarp_xi_bdecode(struct llarp_xi * xi, llarp_buffer_t * buf); + bool llarp_xi_bencode(struct llarp_xi * xi, llarp_buffer_t * buf); + + struct llarp_xi_list; #ifdef __cplusplus } diff --git a/include/llarp/mem.h b/include/llarp/mem.h index e996b9b6e..fabf53448 100644 --- a/include/llarp/mem.h +++ b/include/llarp/mem.h @@ -9,17 +9,17 @@ extern "C" { struct llarp_alloc { - void * (*malloc)(size_t sz); - void * (*realloc)(void * ptr, size_t sz); - void * (*calloc)(size_t n, size_t sz); + void * (*alloc)(size_t sz, size_t align); void (*free)(void * ptr); }; /** global memory allocator */ extern struct llarp_alloc llarp_g_mem; - + /** init llarp_g_mem with stdlib malloc */ + void llarp_mem_stdlib(); + /** init llarp_g_mem with jemalloc */ void llarp_mem_jemalloc(); - void llarp_mem_std(); + /** init llarp_g_mem with dmalloc */ void llarp_mem_dmalloc(); #ifdef __cplusplus diff --git a/include/llarp/router_contact.h b/include/llarp/router_contact.h index 803d0e728..3499d6aeb 100644 --- a/include/llarp/router_contact.h +++ b/include/llarp/router_contact.h @@ -7,19 +7,19 @@ extern "C" { #endif - struct llarp_router_contact + struct llarp_rc { llarp_buffer_t raw; - struct llarp_address_info_list * addreses; + struct llarp_ai_list * addrs; llarp_pubkey_t pubkey; - struct llarp_exit_info_list * exits; + struct llarp_xi_list * exits; llarp_sig_t signature; }; - bool llarp_rc_bdecode(struct llarp_router_contact * rc, llarp_buffer_t buf); - bool llarp_rc_bencode(struct llarp_router_contact * rc, llarp_buffer_t * buf); - void llarp_rc_free(struct llarp_router_contact ** rc); - bool llarp_rc_verify_sig(struct llarp_rotuer_contact * rc); + bool llarp_rc_bdecode(struct llarp_rc * rc, llarp_buffer_t * buf); + bool llarp_rc_bencode(struct llarp_rc * rc, llarp_buffer_t * buf); + void llarp_rc_free(struct llarp_rc ** rc); + bool llarp_rc_verify_sig(struct llarp_rc * rc); diff --git a/llarp/address_info.c b/llarp/address_info.c deleted file mode 100644 index ff49f4345..000000000 --- a/llarp/address_info.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include - -bool llarp_address_info_bencode(struct llarp_address_info * ai, llarp_buffer_t * buff) -{ - char * ptr = buff->cur; - size_t sz = llarp_buffer_size_left(buff); - char * end = ptr + sz; - int r = 0; - r = snprintf(ptr, (end - ptr), "d1:ci%de1:e32:", ai->rank); - if (r == -1) return false; - ptr += r; - if( ( end - ptr ) <= 0 ) return false; - - memcpy(ptr, ai->enc_key, sizeof(ai->enc_key)); - ptr += sizeof(ai->enc_key); - if( ( end - ptr ) <= 0 ) return false; - - r = snprintf(ptr, (end - ptr), "1:d%ld:%s", strlen(ai->dialect), ai->dialect); - if (r == -1) return false; - ptr += r; - if( ( end - ptr ) <= 0 ) return false; - - r = snprintf(ptr, (end - ptr), "1:i%ld:", sizeof(ai->ip)); - if(r == -1) return false; - ptr += r; - if( ( end - ptr ) <= 0) return false; - - memcpy(ptr, &ai->ip, sizeof(ai->ip)); - ptr += sizeof(ai->ip); - if( ( end - ptr ) <= 0) return false; - - r = snprintf(ptr, (end - ptr), "1:pi%dee", ai->port); - if( r == -1) return false; - ptr += r; - buff->cur = ptr; - return end - ptr <= sz; -} diff --git a/llarp/address_info.cpp b/llarp/address_info.cpp new file mode 100644 index 000000000..4ef740e68 --- /dev/null +++ b/llarp/address_info.cpp @@ -0,0 +1,49 @@ +#include "address_info.hpp" +#include "bencode.hpp" +#include "str.hpp" + +namespace llarp +{ + static void * ai_alloc(size_t sz, size_t align) + { + + } +} + +extern "C" { + + struct llarp_alloc * llarp_ai_alloc = &llarp_g_mem; + + bool llarp_ai_bencode(struct llarp_ai * ai, llarp_buffer_t * buff) + { + return llarp::BEncode(*ai, buff); + } + + void llarp_ai_list_iterate(struct llarp_ai_list * l, struct llarp_ai_list_iter * itr) + { + itr->list = l; + struct llarp_ai_list * cur = l; + do + { + if(!itr->visit(itr, cur->data)) + return; + cur = cur->next; + } + while(cur->next); + } +} + +namespace llarp +{ + bool BEncode(const llarp_ai & a, llarp_buffer_t * buff) + { + return bencodeDict(buff) && + bencodeDict_Int(buff, "c", a.rank) && + bencodeDict_Bytes(buff, "e", a.enc_key, sizeof(a.enc_key)) && + bencodeDict_Bytes(buff, "d", a.dialect, UStrLen(a.dialect, sizeof(a.dialect))) && + bencodeDict_Bytes(buff, "i", &a.ip, sizeof(a.ip)) && + bencodeDict_Int(buff, "p", a.port) && + bencodeDict_Int(buff, "v", 0) && + bencodeEnd(buff); + } +} diff --git a/llarp/address_info.hpp b/llarp/address_info.hpp new file mode 100644 index 000000000..b1cc0846b --- /dev/null +++ b/llarp/address_info.hpp @@ -0,0 +1,31 @@ +#ifndef LLARP_AI_HPP +#define LLARP_AI_HPP +#include +#include +#include + +struct llarp_ai_list +{ + llarp_ai * data; + llarp_ai_list * next = nullptr; +}; + +static std::list ai_list_to_std(struct llarp_ai_list * l) +{ + std::list list; + if(l->data) + { + do + { + llarp_ai copy; + memcpy(©, l->data, sizeof(llarp_ai)); + list.push_back(copy); + l = l->next; + } + while(l->next); + } + return list; +} + +#endif + diff --git a/llarp/bencode.hpp b/llarp/bencode.hpp new file mode 100644 index 000000000..b09cf3d9a --- /dev/null +++ b/llarp/bencode.hpp @@ -0,0 +1,70 @@ +#ifndef LLARP_BENCODE_HPP +#define LLARP_BENCODE_HPP +#include +#include +#include + +namespace llarp +{ + template + bool BEncode(const ValType & t, llarp_buffer_t * buff); + + template + bool BDecode(ValType & t, llarp_buffer_t * buff); + + static bool bencodeDict(llarp_buffer_t * buff) + { + static uint8_t c = 'd'; + return llarp_buffer_write(buff, &c, 1); + } + + static bool bencodeList(llarp_buffer_t * buff) + { + static uint8_t c = 'l'; + return llarp_buffer_write(buff, &c, 1); + } + + static bool bencodeEnd(llarp_buffer_t * buff) + { + static char c = 'e'; + return llarp_buffer_write(buff, &c, 1); + } + + static bool bencodeDictKey(llarp_buffer_t * buff, const std::string & key) + { + std::string kstr = std::to_string(key.size()) + ":" + key; + return llarp_buffer_write(buff, kstr.c_str(), kstr.size()); + } + + template + static bool bencodeDict_Int(llarp_buffer_t * buff, const std::string & key, IntType i) + { + std::string istr = "i" + std::to_string(i) + "e"; + return bencodeDictKey(buff, key) && + llarp_buffer_write(buff, istr.c_str(), istr.size()); + } + + static bool bencodeDict_Bytes(llarp_buffer_t * buff, const std::string & key, const void * data, size_t sz) + { + std::string sz_str = std::to_string(sz) + ":"; + return bencodeDictKey(buff, key) && + llarp_buffer_write(buff, sz_str.c_str(), sz_str.size()) && + llarp_buffer_write(buff, data, sz); + } + + + template + bool BEncode(const std::list & l, llarp_buffer_t * buff) + { + if(bencodeList(buff)) + { + for(const auto & itr : l) + if(!BEncode(itr, buff)) + return false; + return bencodeEnd(buff); + } + return false; + } +} + +#endif diff --git a/llarp/config.cpp b/llarp/config.cpp index 176882c77..1be3dc6a2 100644 --- a/llarp/config.cpp +++ b/llarp/config.cpp @@ -1,7 +1,7 @@ #include -#include #include "config.hpp" #include "ini.hpp" +#include "mem.hpp" namespace llarp { @@ -42,7 +42,7 @@ extern "C" { void llarp_new_config(struct llarp_config ** conf) { - llarp_config * c = static_cast(llarp_g_mem.malloc(sizeof(llarp_config))); + llarp_config * c = llarp::alloc(); *conf = c; } diff --git a/llarp/ev.cpp b/llarp/ev.cpp index 8502a3bb7..235df42bc 100644 --- a/llarp/ev.cpp +++ b/llarp/ev.cpp @@ -1,6 +1,6 @@ #include -#include #include +#include "mem.hpp" struct llarp_ev_loop { @@ -35,7 +35,7 @@ namespace llarp static void udp_alloc_cb(uv_handle_t * h, size_t sz, uv_buf_t * buf) { - buf->base = static_cast(llarp_g_mem.malloc(sz)); + buf->base = static_cast(llarp_g_mem.alloc(sz, 512)); buf->len = sz; } @@ -58,7 +58,7 @@ namespace llarp extern "C" { void llarp_ev_loop_alloc(struct llarp_ev_loop ** ev) { - *ev = static_cast(llarp_g_mem.malloc(sizeof(struct llarp_ev_loop))); + *ev = llarp::alloc(); if (*ev) { uv_loop_init((*ev)->loop()); @@ -85,7 +85,7 @@ extern "C" { sockaddr_in6 addr; uv_ip6_addr(listener->host, listener->port, &addr); int ret = 0; - llarp::udp_listener * l = static_cast(llarp_g_mem.malloc(sizeof(llarp::udp_listener))); + llarp::udp_listener * l = llarp::alloc(); listener->impl = l; l->udp()->data = l; l->listener = listener; diff --git a/llarp/exit_info.cpp b/llarp/exit_info.cpp new file mode 100644 index 000000000..16f1f4ac4 --- /dev/null +++ b/llarp/exit_info.cpp @@ -0,0 +1,21 @@ +#include "exit_info.hpp" +#include "bencode.hpp" + +extern "C" { + bool llarp_xi_bencode(struct llarp_xi * xi, llarp_buffer_t * buff) + { + return llarp::BEncode(*xi, buff); + } +} + +namespace llarp +{ + bool BEncode(const llarp_xi & xi, llarp_buffer_t * buff) + { + return bencodeDict(buff) && + bencodeDict_Bytes(buff, "a", &xi.address, sizeof(xi.address)) && + bencodeDict_Bytes(buff, "b", &xi.netmask, sizeof(xi.netmask)) && + bencodeDict_Int(buff, "v", 0) && + bencodeEnd(buff); + } +} diff --git a/llarp/exit_info.hpp b/llarp/exit_info.hpp new file mode 100644 index 000000000..6f10ad6e9 --- /dev/null +++ b/llarp/exit_info.hpp @@ -0,0 +1,20 @@ +#ifndef LLARP_XI_HPP +#define LLARP_XI_HPP +#include +#include + +struct llarp_xi_list +{ + std::list list; +}; + +static std::list xi_list_to_std(struct llarp_xi_list * l) +{ + std::list list; + if(l->list.size()) + for(const auto & xi : l->list) + list.push_back(xi); + return list; +} + +#endif diff --git a/llarp/link.cpp b/llarp/link.cpp index fb2ab7b11..a9e71f510 100644 --- a/llarp/link.cpp +++ b/llarp/link.cpp @@ -42,7 +42,6 @@ namespace llarp _crypto(crypto), state(eHandshakeInboundInit) { - memset(remotePubkey, 0, sizeof(remotePubkey)); memset(sessionKey, 0, sizeof(sessionKey)); } diff --git a/llarp/link.hpp b/llarp/link.hpp index 38875d603..6aef9d451 100644 --- a/llarp/link.hpp +++ b/llarp/link.hpp @@ -5,8 +5,10 @@ #include #include #include +#include #include +#include namespace llarp { @@ -15,7 +17,7 @@ namespace llarp struct PeerSession { sockaddr_in6 remoteAddr; - llarp_pubkey_t remotePubkey; + llarp_rc rc; llarp_sharedkey_t sessionKey; uint64_t lastRX; @@ -39,9 +41,8 @@ namespace llarp /** inbound session */ PeerSession(llarp_crypto * crypto, sockaddr_in6 remote); - /** outbound session */ - PeerSession(llarp_crypto * crypto, sockaddr_in6 remote, llarp_pubkey_t remotePubkey); + PeerSession(llarp_crypto * crypto, llarp_rc rc); PeerSession & operator=(const PeerSession & other); @@ -52,6 +53,8 @@ namespace llarp }; typedef std::unique_ptr PeerSession_ptr; + + typedef std::function PeerSessionVisitor; struct Link { @@ -69,6 +72,8 @@ namespace llarp llarp_udp_listener _listener; llarp_udp_listener * Listener() { return &_listener; } + + bool VisitPeerByIdent(PeerSessionVisitor v); }; } diff --git a/llarp/mem.cpp b/llarp/mem.cpp index 0e4f19ee1..36d65b928 100644 --- a/llarp/mem.cpp +++ b/llarp/mem.cpp @@ -2,9 +2,7 @@ extern "C" { struct llarp_alloc llarp_g_mem = { - .malloc = nullptr, - .realloc = nullptr, - .calloc = nullptr, + .alloc = nullptr, .free = nullptr }; } diff --git a/llarp/mem.hpp b/llarp/mem.hpp new file mode 100644 index 000000000..b486eb457 --- /dev/null +++ b/llarp/mem.hpp @@ -0,0 +1,21 @@ +#ifndef LLARP_MEM_HPP +#define LLARP_MEM_HPP +#include +#include +namespace llarp +{ + template + static constexpr size_t alignment() + { + return std::exp2(1+std::floor(std::log2(sizeof(T)))); + } + + template + static T * alloc(llarp_alloc * mem=nullptr) + { + if(!mem) mem = &llarp_g_mem; + return static_cast(mem->alloc(sizeof(T), alignment())); + } +} + +#endif diff --git a/llarp/mem_jemalloc.cpp b/llarp/mem_jemalloc.cpp index 5cef3dec3..8d68d59d7 100644 --- a/llarp/mem_jemalloc.cpp +++ b/llarp/mem_jemalloc.cpp @@ -3,33 +3,21 @@ namespace llarp { - static void * jem_malloc(size_t sz) + static void * jem_malloc(size_t sz, size_t align) { - return mallocx(sz, MALLOCX_ZERO); + return mallocx(sz, MALLOCX_ZERO | MALLOCX_ALIGN(align)); } static void jem_free(void * ptr) { if(ptr) free(ptr); } - - static void * jem_calloc(size_t n, size_t sz) - { - return mallocx(n * sz, MALLOCX_ZERO); - } - - static void * jem_realloc(void * ptr, size_t sz) - { - return rallocx(ptr, sz, MALLOCX_ZERO); - } } extern "C" { void llarp_mem_jemalloc() { - llarp_g_mem.malloc = llarp::jem_malloc; + llarp_g_mem.alloc = llarp::jem_malloc; llarp_g_mem.free = llarp::jem_free; - llarp_g_mem.calloc = llarp::jem_calloc; - llarp_g_mem.realloc = llarp::jem_realloc; } } diff --git a/llarp/mem_std.cpp b/llarp/mem_std.cpp index 0a41ff75a..863098ace 100644 --- a/llarp/mem_std.cpp +++ b/llarp/mem_std.cpp @@ -2,8 +2,9 @@ namespace llarp { - void * std_malloc(size_t sz) + void * std_malloc(size_t sz, size_t align) { + (void) align; void * ptr = malloc(sz); if(ptr) return ptr; abort(); @@ -13,29 +14,13 @@ namespace llarp { if(ptr) free(ptr); } - - void * std_calloc(size_t n, size_t sz) - { - void * ptr = calloc(n, sz); - if (ptr) return ptr; - abort(); - } - - void * std_realloc(void * ptr, size_t sz) - { - ptr = realloc(ptr, sz); - if (ptr) return ptr; - abort(); - } } extern "C" { void llarp_mem_std() { - llarp_g_mem.malloc = llarp::std_malloc; + llarp_g_mem.alloc = llarp::std_malloc; llarp_g_mem.free = llarp::std_free; - llarp_g_mem.calloc = llarp::std_calloc; - llarp_g_mem.realloc = llarp::std_realloc; } } diff --git a/llarp/router.cpp b/llarp/router.cpp index 1eba66be0..9dc41500a 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -1,6 +1,7 @@ #include #include #include "link.hpp" +#include "mem.hpp" #include #include "str.hpp" @@ -45,7 +46,7 @@ extern "C" { void llarp_init_router(struct llarp_router ** router) { - *router = static_cast(llarp_g_mem.malloc(sizeof(llarp_router))); + *router = llarp::alloc(&llarp_g_mem); if(*router) { llarp_crypto_libsodium_init(&(*router)->crypto); @@ -74,7 +75,7 @@ extern "C" { { llarp_router * r = *router; r->impl.Close(); - llarp_g_mem.free(*router); + llarp_g_mem.free(r); } *router = nullptr; } @@ -86,13 +87,13 @@ namespace llarp void router_iter_config(llarp_config_iterator * iter, const char * section, const char * key, const char * val) { llarp_router * self = static_cast(iter->user); - if (streq(section, "links")) + if (StrEq(section, "links")) { - if(streq(val, "ip")) + if(StrEq(val, "ip")) { self->impl.Links.push_back(new Link(&self->crypto)); } - else if (streq(val, "eth")) + else if (StrEq(val, "eth")) { /** todo: ethernet link */ } diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp new file mode 100644 index 000000000..03796c565 --- /dev/null +++ b/llarp/router_contact.cpp @@ -0,0 +1,24 @@ +#include "router_contact.hpp" +#include "exit_info.hpp" +#include "address_info.hpp" +#include "bencode.hpp" + +extern "C" { + +} + +namespace llarp +{ + bool BEncode(const llarp_rc & a, llarp_buffer_t * buff) + { + std::list addresses = ai_list_to_std(a.addrs); + std::list exits = xi_list_to_std(a.exits); + return bencodeDict(buff) && + bencodeDictKey(buff, "a") && BEncode(addresses, buff) && + bencodeDict_Bytes(buff, "k", a.pubkey, sizeof(a.pubkey)) && + bencodeDict_Int(buff, "v", 0) && + bencodeDictKey(buff, "x") && BEncode(exits, buff) && + bencodeDict_Bytes(buff, "z", a.signature, sizeof(a.signature)) && + bencodeEnd(buff); + } +} diff --git a/llarp/router_contact.hpp b/llarp/router_contact.hpp new file mode 100644 index 000000000..efb202c77 --- /dev/null +++ b/llarp/router_contact.hpp @@ -0,0 +1,6 @@ +#ifndef LLARP_RC_HPP +#define LLARP_RC_HPP +#include + + +#endif diff --git a/llarp/str.hpp b/llarp/str.hpp index ae516d26d..6d2e8bbcc 100644 --- a/llarp/str.hpp +++ b/llarp/str.hpp @@ -4,7 +4,7 @@ namespace llarp { - static bool streq(const char * s1, const char * s2) + static bool StrEq(const char * s1, const char * s2) { size_t sz1 = strlen(s1); size_t sz2 = strlen(s2); @@ -15,6 +15,17 @@ namespace llarp else return false; } + + static size_t UStrLen(const uint8_t * data, size_t maxsz) + { + size_t sz = 0; + while(*data++) + { + sz ++; + if(maxsz >= sz) return maxsz; + } + return sz; + } } #endif