From eebb36683c08613d95267f50a1f7a2d9529184de Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Tue, 29 May 2018 17:40:02 -0700 Subject: [PATCH 01/15] new getter/setter style API --- llarp/nodedb.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 7 deletions(-) diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 7efa2283d..074362f7a 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -6,6 +6,20 @@ #include "crypto.hpp" #include "fs.hpp" #include "mem.hpp" +#include "logger.hpp" + +constexpr char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + +std::string hexStr(unsigned char *data, int len) +{ + std::string s(len * 2, ' '); + for (int i = 0; i < len; ++i) { + s[2 * i] = hexmap[(data[i] & 0xF0) >> 4]; + s[2 * i + 1] = hexmap[data[i] & 0x0F]; + } + return s; +} static const char skiplist_subdirs[] = "0123456789ABCDEF"; @@ -29,6 +43,74 @@ struct llarp_nodedb } } + inline llarp::pubkey getPubKeyFromRC(llarp_rc *rc) { + llarp::pubkey pk; + memcpy(pk.data(), rc->pubkey, pk.size()); + return pk; + } + + llarp_rc *getRC(llarp::pubkey pk) { + return entries[pk]; + } + + bool pubKeyExists(llarp_rc *rc) { + // extract pk from rc + llarp::pubkey pk = getPubKeyFromRC(rc); + // return true if we found before end + return entries.find(pk) != entries.end(); + } + + bool check(llarp_rc *rc) { + if (!pubKeyExists(rc)) { + // we don't have it + return false; + } + llarp::pubkey pk = getPubKeyFromRC(rc); + + // TODO: zero out any fields you don't want to compare + + // 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 (memcmp(¶mbuf, &nodebuf, MAX_RC_SIZE) == 0) { + return true; + } + } + } + return false; + } + + bool setRC(llarp_rc *rc) { + byte_t tmp[MAX_RC_SIZE]; + auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); + + // extract pk from rc + llarp::pubkey pk = getPubKeyFromRC(rc); + + // set local db + entries[pk] = rc; + + if (llarp_rc_bencode(rc, &buf)) { + // write buf to disk + auto filename = hexStr(pk.data(), sizeof(pk)) + ".rc"; + // FIXME: path? + printf("filename[%s]\n", filename.c_str()); + std::ofstream ofs (filename, std::ofstream::out & std::ofstream::binary & std::ofstream::trunc); + ofs.write((char *)buf.base, buf.sz); + ofs.close(); + if (!ofs) { + llarp::Error(__FILE__, "Failed to write", filename); + return false; + } + return true; + } + return false; + } + ssize_t Load(const fs::path &path) { @@ -54,6 +136,18 @@ struct llarp_nodedb return loaded; } + ssize_t + loadSubdir(const fs::path &dir) + { + ssize_t sz = 0; + for(auto &path : fs::directory_iterator(dir)) + { + if(loadfile(path)) + sz++; + } + return sz; + } + bool loadfile(const fs::path &fpath) { @@ -92,17 +186,20 @@ struct llarp_nodedb return false; } - ssize_t - loadSubdir(const fs::path &dir) + /* + bool Save() { - ssize_t sz = 0; - for(auto &path : fs::directory_iterator(dir)) + auto itr = entries.begin(); + while(itr != entries.end()) { - if(loadfile(path)) - sz++; + llarp::pubkey pk = itr->first; + llarp_rc *rc= itr->second; + + itr++; // advance } - return sz; + return true; } + */ }; extern "C" { From 5f3c2b4499e9b46b6f06d8bb030db9435dfc7b03 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 31 May 2018 06:06:28 -0700 Subject: [PATCH 02/15] implement missing llarp_alloc struct --- llarp/mem_std.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llarp/mem_std.cpp b/llarp/mem_std.cpp index a437e11de..ec492acb2 100644 --- a/llarp/mem_std.cpp +++ b/llarp/mem_std.cpp @@ -3,6 +3,11 @@ #include #include +struct llarp_alloc { + void *(*alloc)(struct llarp_alloc *mem, size_t sz, size_t align); + void (*free)(struct llarp_alloc *mem, void *ptr); +}; + namespace llarp { void * From 27e1d82c20ac3e1603605243a81656290064f3cd Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 31 May 2018 06:06:53 -0700 Subject: [PATCH 03/15] formatting --- include/llarp/string.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/llarp/string.h b/include/llarp/string.h index 33413e556..5e3983fd8 100644 --- a/include/llarp/string.h +++ b/include/llarp/string.h @@ -6,7 +6,7 @@ extern "C" { #endif #ifndef __FreeBSD__ -#if !(__APPLE__ && __MACH__) +# if !(__APPLE__ && __MACH__) size_t INLINE strnlen(const char* str, size_t sz) { @@ -15,7 +15,7 @@ strnlen(const char* str, size_t sz) slen++; return slen; } -#endif +# endif #endif #ifdef __cplusplus From ee28623dbffbbe8e41d254762275473c695cec0b Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 31 May 2018 06:07:52 -0700 Subject: [PATCH 04/15] important threading note --- llarp/router_contact.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 4d2f7b9af..cb0604ef9 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -123,6 +123,9 @@ llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buff) 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_sig_t sig; byte_t tmp[MAX_RC_SIZE]; From 40dedf74711c288a6f7ae765e29d82f253b5a8be Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 31 May 2018 06:08:06 -0700 Subject: [PATCH 05/15] start of async version of verifying router contacts --- include/llarp/crypto_async.h | 49 +++++++++++++- include/llarp/nodedb.h | 27 ++++++++ llarp/crypto_async.cpp | 59 ++++++++++++++++ llarp/nodedb.cpp | 127 +++++++++++++++++++++++++++++------ llarp/router.cpp | 11 ++- 5 files changed, 243 insertions(+), 30 deletions(-) diff --git a/include/llarp/crypto_async.h b/include/llarp/crypto_async.h index 8134436e2..73a7317ed 100644 --- a/include/llarp/crypto_async.h +++ b/include/llarp/crypto_async.h @@ -15,7 +15,7 @@ extern "C" { #endif -/// context for doing asynchronous crpytography for iwp +/// context for doing asynchronous cryptography for iwp /// with a worker threadpool /// defined in crypto_async.cpp struct llarp_async_iwp; @@ -32,6 +32,22 @@ llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic, void llarp_async_iwp_free(struct llarp_async_iwp *iwp); + +/// context for doing asynchronous cryptography for rc +/// with a worker threadpool +/// defined in crypto_async.cpp +struct llarp_async_rc; + +/// rc async context allocator +struct llarp_async_rc * +llarp_async_rc_new(struct llarp_crypto *crypto, struct llarp_logic *logic, + struct llarp_threadpool *worker); + +/// deallocator +void +llarp_async_rc_free(struct llarp_async_rc *rc); + + struct iwp_async_keygen; /// define functor for keygen @@ -42,7 +58,7 @@ struct iwp_async_keygen { /// internal wire protocol async configuration struct llarp_async_iwp *iwp; - /// a customizable pointer to pass data to iteration functor + /// a pointer to pass ourself to thread worker void *user; /// destination key buffer uint8_t *keybuf; @@ -167,6 +183,7 @@ struct iwp_async_frame /// true if decryption succeded bool success; struct llarp_async_iwp *iwp; + /// a pointer to pass ourself void *user; /// current session key uint8_t *sessionkey; @@ -188,6 +205,34 @@ void iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp, struct iwp_async_frame *frame); + + +/// define functor for rc_verify +typedef void (*rc_verify_hook)(struct rc_async_verify *); + +/// rc verify request +struct rc_async_verify +{ + /// router contact crypto async configuration + struct llarp_async_rc *context; + /// a pointer to pass ourself to thread worker + void *self; + /// the router contact + struct llarp_rc *rc; + /// result + bool result; + /// result handler callback + rc_verify_hook hook; + /// extra data to pass to hook + void *hook_user; +}; + + +/// rc verify +void rc_call_async_verify(struct llarp_async_rc *context, + struct rc_async_verify *request, + struct llarp_rc *rc); + #ifdef __cplusplus } #endif diff --git a/include/llarp/nodedb.h b/include/llarp/nodedb.h index 6f2a036e0..bd68d1e6f 100644 --- a/include/llarp/nodedb.h +++ b/include/llarp/nodedb.h @@ -3,6 +3,13 @@ #include #include #include + +/** + * nodedb.h + * + * persistent storage API for router contacts + */ + #ifdef __cplusplus extern "C" { #endif @@ -68,18 +75,38 @@ llarp_nodedb_has_rc(struct llarp_nodedb *n, llarp_pubkey_t k); bool llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc); +// defined in nodedb.cpp +/* +struct llarp_async_verify_job_context { + struct llarp_nodedb *nodedb; + struct llarp_logic *logic; + struct llarp_crypto *crypto; + struct llarp_threadpool *cryptoworker; + struct llarp_threadpool *diskworker; +}; +*/ + /** struct for async rc verification */ struct llarp_async_verify_rc; +struct llarp_async_verify_job_context; // forward definition (defined in nodedb.cpp) + typedef void (*llarp_async_verify_rc_hook_func)(struct llarp_async_verify_rc *); +/// verify rc request struct llarp_async_verify_rc { + /// user pointers void *user; + /// context + llarp_async_verify_job_context *context; + /// router contact (should this be a pointer?) struct llarp_rc rc; + /// result bool valid; + /// hook llarp_async_verify_rc_hook_func hook; }; diff --git a/llarp/crypto_async.cpp b/llarp/crypto_async.cpp index 71a10c250..5eb3c6400 100644 --- a/llarp/crypto_async.cpp +++ b/llarp/crypto_async.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include "buffer.hpp" @@ -381,6 +382,33 @@ namespace iwp } } +// REFACTOR: same as llarp_async_iwp (unify and rename) +struct llarp_async_rc +{ + struct llarp_crypto *crypto; + struct llarp_logic *logic; + struct llarp_threadpool *worker; +}; + +namespace rc { + + void + inform_verify(void *user) + { + rc_async_verify *request = static_cast< rc_async_verify * >(user); + request->hook(request); + } + + void + verify(void *user) + { + rc_async_verify *request = static_cast< rc_async_verify * >(user); + request->result = llarp_rc_verify_sig(request->context->crypto, request->rc); + llarp_thread_job job = {.user = user, .work = &inform_verify}; + llarp_logic_queue_job(request->context->logic, job); + } +} + extern "C" { void @@ -456,6 +484,16 @@ iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp, {session, &iwp::verify_session_start}); } +void rc_call_async_verify(struct llarp_async_rc *context, + struct rc_async_verify *request, + struct llarp_rc *rc) +{ + request->context = context; + request->rc = rc; + llarp_threadpool_queue_job(context->worker, + {request, &rc::verify}); +} + struct llarp_async_iwp * llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic, struct llarp_threadpool *worker) @@ -475,4 +513,25 @@ llarp_async_iwp_free(struct llarp_async_iwp *iwp) { delete iwp; } + +struct llarp_async_rc * +llarp_async_rc_new(struct llarp_crypto *crypto, struct llarp_logic *logic, + struct llarp_threadpool *worker) +{ + llarp_async_rc *context = new llarp_async_rc; + if(context) + { + context->crypto = crypto; + context->logic = logic; + context->worker = worker; + } + return context; +} + +void +llarp_async_rc_free(struct llarp_async_rc *context) +{ + delete context; +} + } diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 5335ea2aa..31ea5e992 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -1,28 +1,71 @@ #include #include +#include +#include + #include #include #include "buffer.hpp" #include "crypto.hpp" #include "fs.hpp" #include "mem.hpp" +#include "encode.hpp" #include "logger.hpp" -constexpr char hexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - -std::string hexStr(unsigned char *data, int len) +// probably used for more than verify tbh +struct llarp_async_verify_job_context { - std::string s(len * 2, ' '); - for (int i = 0; i < len; ++i) { - s[2 * i] = hexmap[(data[i] & 0xF0) >> 4]; - s[2 * i + 1] = hexmap[data[i] & 0x0F]; - } - return s; -} + struct llarp_logic *logic; + struct llarp_crypto *crypto; + struct llarp_threadpool *cryptoworker; + struct llarp_threadpool *diskworker; +}; static const char skiplist_subdirs[] = "0123456789ABCDEF"; +static void on_crypt_verify_rc(rc_async_verify *job) +{ + if (job->result) { + // set up disk request + // how do we get our diskworker? + } else { + // it's not valid, don't update db + // send back to logic thread + + // make generic job based on previous job + //llarp_thread_job job = {.user = job->user, .work = &inform_verify_rc}; + //llarp_logic_queue_job(job->context->logic, job); + } + // TODO: is there any deallocation we need to do + delete (llarp_async_verify_job_context*)job->context; // clean up our temp context created in verify_rc + delete job; // we're done with the rc_async_verify +} + +void verify_rc(void *user) +{ + llarp_async_verify_rc *verify_request = + static_cast< llarp_async_verify_rc * >(user); + // transfer context + // FIXME: move this allocation to more a long term home? + llarp_async_rc *async_rc_context = llarp_async_rc_new( + verify_request->context->crypto, verify_request->context->logic, + verify_request->context->cryptoworker); + // set up request + rc_async_verify *async_rc_request = new rc_async_verify; + // rc_call_async_verify will set up context, rc + // user? + async_rc_request->result = false; // just initialize it to something secure + async_rc_request->hook = &on_crypt_verify_rc; + + rc_call_async_verify(async_rc_context, async_rc_request, + &verify_request->rc); + // crypto verify + // if success write to disk + //verify_request->context->crypto + //llarp_thread_job job = {.user = user, .work = &inform_keygen}; + //llarp_logic_queue_job(keygen->iwp->logic, job); +} + struct llarp_nodedb { llarp_nodedb(llarp_crypto *c) : crypto(c) @@ -43,25 +86,30 @@ struct llarp_nodedb } } - inline llarp::pubkey getPubKeyFromRC(llarp_rc *rc) { + inline llarp::pubkey getPubKeyFromRC(llarp_rc *rc) + { llarp::pubkey pk; memcpy(pk.data(), rc->pubkey, pk.size()); return pk; } - llarp_rc *getRC(llarp::pubkey pk) { + llarp_rc *getRC(llarp::pubkey pk) + { return entries[pk]; } - bool pubKeyExists(llarp_rc *rc) { + bool pubKeyExists(llarp_rc *rc) + { // extract pk from rc llarp::pubkey pk = getPubKeyFromRC(rc); // return true if we found before end return entries.find(pk) != entries.end(); } - bool check(llarp_rc *rc) { - if (!pubKeyExists(rc)) { + bool check(llarp_rc *rc) + { + if (!pubKeyExists(rc)) + { // we don't have it return false; } @@ -72,11 +120,14 @@ struct llarp_nodedb // serialize both and memcmp byte_t nodetmp[MAX_RC_SIZE]; auto nodebuf = llarp::StackBuffer< decltype(nodetmp) >(nodetmp); - if (llarp_rc_bencode(entries[pk], &nodebuf)) { + 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 (memcmp(¶mbuf, &nodebuf, MAX_RC_SIZE) == 0) { + if (llarp_rc_bencode(rc, ¶mbuf)) + { + if (memcmp(¶mbuf, &nodebuf, MAX_RC_SIZE) == 0) + { return true; } } @@ -94,15 +145,21 @@ struct llarp_nodedb // set local db entries[pk] = rc; - if (llarp_rc_bencode(rc, &buf)) { + if (llarp_rc_bencode(rc, &buf)) + { // write buf to disk - auto filename = hexStr(pk.data(), sizeof(pk)) + ".rc"; + //auto filename = hexStr(pk.data(), sizeof(pk)) + ".rc"; + char ftmp[68] = {0}; + const char *hexname = + llarp::HexEncode< llarp::pubkey, decltype(ftmp) >(pk, ftmp); + std::string filename(hexname); // FIXME: path? printf("filename[%s]\n", filename.c_str()); std::ofstream ofs (filename, std::ofstream::out & std::ofstream::binary & std::ofstream::trunc); ofs.write((char *)buf.base, buf.sz); ofs.close(); - if (!ofs) { + if (!ofs) + { llarp::Error(__FILE__, "Failed to write", filename); return false; } @@ -254,6 +311,24 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir) return n->Load(dir); } +/// allocate verify job context +struct llarp_async_verify_job_context* +llarp_async_verify_job_new(struct llarp_threadpool *cryptoworker, + struct llarp_threadpool *diskworker) { + llarp_async_verify_job_context *context = new llarp_async_verify_job_context; + if (context) + { + context->cryptoworker = cryptoworker; + context->diskworker = diskworker; + } + return context; +} + +void +llarp_async_verify_job_free(struct llarp_async_verify_job_context *context) { + delete context; +} + void llarp_nodedb_async_verify(struct llarp_nodedb *nodedb, struct llarp_logic *logic, @@ -262,5 +337,13 @@ llarp_nodedb_async_verify(struct llarp_nodedb *nodedb, struct llarp_threadpool *diskworker, struct llarp_async_verify_rc *job) { + printf("llarp_nodedb_async_verify\n"); + // set up context + llarp_async_verify_job_context *context = llarp_async_verify_job_new( + cryptoworker, diskworker); + // set up anything we need (in job) + job->context = context; + // queue the crypto check + llarp_threadpool_queue_job(cryptoworker, { job, &verify_rc }); } } diff --git a/llarp/router.cpp b/llarp/router.cpp index 18596c928..d993b7aea 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -259,12 +259,11 @@ llarp_router::async_verify_RC(llarp_link_session *session, bool isExpectingClient, llarp_link_establish_job *establish_job) { - llarp_async_verify_rc *job = new llarp_async_verify_rc{ - new llarp::async_verify_context{this, establish_job}, - {}, - false, - nullptr, - }; + 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_rc_copy(&job->rc, session->get_remote_router(session)); if(isExpectingClient) job->hook = &llarp_router::on_verify_client_rc; From 34dca85780aac5289e4c3d75ed0f7ec91506f743 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Fri, 1 Jun 2018 15:39:30 -0700 Subject: [PATCH 06/15] fix BSD compile issue, added some debug, OSX compile fixes --- llarp/ev_kqueue.hpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/llarp/ev_kqueue.hpp b/llarp/ev_kqueue.hpp index 550b94b83..78bf43c5c 100644 --- a/llarp/ev_kqueue.hpp +++ b/llarp/ev_kqueue.hpp @@ -5,18 +5,24 @@ #if __FreeBSD__ // kqueue / kevent -//# include // already in net.h # include # include #endif +#if (__APPLE__ && __MACH__) +// kqueue / kevent +# include +# include +#endif -//#include -//#include +// MacOS needs this +#ifndef SOCK_NONBLOCK +# include +# define SOCK_NONBLOCK O_NONBLOCK +#endif // original upstream #include - #include #include "ev.hpp" #include "logger.hpp" @@ -50,7 +56,9 @@ namespace llarp virtual int sendto(const sockaddr* to, const void* data, size_t sz) { + printf("kqueue:::udp_listener::sendto size[%d]\n", sz); socklen_t slen; + printf("kqueue:::udp_listener::sendto af[%d]\n", to->sa_family); switch(to->sa_family) { case AF_INET: @@ -62,9 +70,10 @@ namespace llarp default: return -1; } + printf("kqueue:::udp_listener::sendto slen[%d]\n", slen); ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen); if(sent == -1) - perror("sendto()"); + perror("kqueue sendto()"); return sent; } }; @@ -164,7 +173,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop } } llarp::Addr a(*addr); - llarp::Info(__FILE__, "bind to ", a.to_string()); + llarp::Info(__FILE__, "bind to ", a); if(bind(fd, addr, slen) == -1) { perror("bind()"); From a6f3e09d8b54004d9a6a1da3096c4838e7d5b325 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Fri, 1 Jun 2018 15:41:10 -0700 Subject: [PATCH 07/15] remove debug --- llarp/ev_kqueue.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/llarp/ev_kqueue.hpp b/llarp/ev_kqueue.hpp index 78bf43c5c..5f9adcb35 100644 --- a/llarp/ev_kqueue.hpp +++ b/llarp/ev_kqueue.hpp @@ -56,9 +56,7 @@ namespace llarp virtual int sendto(const sockaddr* to, const void* data, size_t sz) { - printf("kqueue:::udp_listener::sendto size[%d]\n", sz); socklen_t slen; - printf("kqueue:::udp_listener::sendto af[%d]\n", to->sa_family); switch(to->sa_family) { case AF_INET: @@ -70,7 +68,6 @@ namespace llarp default: return -1; } - printf("kqueue:::udp_listener::sendto slen[%d]\n", slen); ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen); if(sent == -1) perror("kqueue sendto()"); From 87c6571bc2e2495b4360c3802322cbc8f67093dc Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Mon, 4 Jun 2018 01:42:21 +0000 Subject: [PATCH 08/15] fixed context, change deletion method --- llarp/nodedb.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 7705c9257..57080cf79 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -37,7 +37,8 @@ static void on_crypt_verify_rc(rc_async_verify *job) //llarp_logic_queue_job(job->context->logic, job); } // TODO: is there any deallocation we need to do - delete (llarp_async_verify_job_context*)job->context; // clean up our temp context created in verify_rc + llarp_async_rc_free(job->context); + //delete (llarp_async_rc*)job->context; // clean up our temp context created in verify_rc delete job; // we're done with the rc_async_verify } @@ -314,10 +315,13 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir) /// allocate verify job context struct llarp_async_verify_job_context* llarp_async_verify_job_new(struct llarp_threadpool *cryptoworker, - struct llarp_threadpool *diskworker) { + struct llarp_threadpool *diskworker, struct llarp_logic *logic, + struct llarp_crypto *crypto) { llarp_async_verify_job_context *context = new llarp_async_verify_job_context; if (context) { + context->logic = logic; + context->crypto = crypto; context->cryptoworker = cryptoworker; context->diskworker = diskworker; } @@ -337,10 +341,9 @@ llarp_nodedb_async_verify(struct llarp_nodedb *nodedb, struct llarp_threadpool *diskworker, struct llarp_async_verify_rc *job) { - printf("llarp_nodedb_async_verify\n"); // set up context llarp_async_verify_job_context *context = llarp_async_verify_job_new( - cryptoworker, diskworker); + cryptoworker, diskworker, logic, crypto); // set up anything we need (in job) job->context = context; // queue the crypto check From b7fe7e465c09f5c669a1089ecccd33aaf2626341 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Mon, 4 Jun 2018 06:07:31 -0700 Subject: [PATCH 09/15] llvm 3.8 compat --- llarp/iwp_link.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llarp/iwp_link.cpp b/llarp/iwp_link.cpp index 594826e4a..120e6456a 100644 --- a/llarp/iwp_link.cpp +++ b/llarp/iwp_link.cpp @@ -1300,9 +1300,10 @@ namespace iwp UnmapAddr(const llarp::Addr &src) { lock_t lock(m_Connected_Mutex); + // std::unordered_map< llarp::pubkey, llarp::Addr, llarp::pubkeyhash > auto itr = std::find_if( m_Connected.begin(), m_Connected.end(), - [src](const auto &item) -> bool { return src == item.second; }); + [src](const std::pair &item) -> bool { return src == item.second; }); if(itr == std::end(m_Connected)) return; From bbf9f2274c01ddcb700c41f609b482644d3723dc Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Mon, 4 Jun 2018 06:08:35 -0700 Subject: [PATCH 10/15] fix kqueue on OSX --- llarp/ev_kqueue.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/llarp/ev_kqueue.hpp b/llarp/ev_kqueue.hpp index 5f9adcb35..3e3a42817 100644 --- a/llarp/ev_kqueue.hpp +++ b/llarp/ev_kqueue.hpp @@ -68,7 +68,7 @@ namespace llarp default: return -1; } - ssize_t sent = ::sendto(fd, data, sz, SOCK_NONBLOCK, to, slen); + ssize_t sent = ::sendto(fd, data, sz, 0, to, slen); if(sent == -1) perror("kqueue sendto()"); return sent; @@ -131,6 +131,7 @@ struct llarp_kqueue_loop : public llarp_ev_loop udp_bind(const sockaddr* addr) { socklen_t slen; + llarp::Debug(__FILE__, "kqueue bind affam", addr->sa_family); switch(addr->sa_family) { case AF_INET: @@ -171,6 +172,10 @@ struct llarp_kqueue_loop : public llarp_ev_loop } llarp::Addr a(*addr); llarp::Info(__FILE__, "bind to ", a); + // FreeBSD handbook said to do this + if (addr->sa_family == AF_INET && INADDR_ANY) + a._addr4.sin_addr.s_addr = htonl(INADDR_ANY); + if(bind(fd, addr, slen) == -1) { perror("bind()"); From a7abaa7f02fbce7272720573ff1b5b85437a0ed6 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Mon, 4 Jun 2018 06:10:19 -0700 Subject: [PATCH 11/15] llvm 3.8 fixes --- llarp/dht.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/llarp/dht.cpp b/llarp/dht.cpp index 9e96cdfbd..2ae0478cc 100644 --- a/llarp/dht.cpp +++ b/llarp/dht.cpp @@ -6,6 +6,7 @@ #include #include +#include // std::find namespace llarp { @@ -414,7 +415,10 @@ namespace llarp void Context::RemovePendingLookup(const Key_t &owner, uint64_t id) { - auto itr = pendingTX.find({owner, id}); + TXOwner search; + search.requester = owner; + search.txid = id; + auto itr = pendingTX.find(search); if(itr == pendingTX.end()) return; pendingTX.erase(itr); @@ -423,7 +427,10 @@ namespace llarp SearchJob * Context::FindPendingTX(const Key_t &owner, uint64_t id) { - auto itr = pendingTX.find({owner, id}); + TXOwner search; + search.requester = owner; + search.txid = id; + auto itr = pendingTX.find(search); if(itr == pendingTX.end()) return nullptr; else @@ -478,7 +485,12 @@ namespace llarp const Key_t &askpeer, llarp_router_lookup_job *job) { auto id = ++ids; - pendingTX[{whoasked, id}] = SearchJob(whoasked, target, job); + + TXOwner ownerKey; + ownerKey.requester = whoasked; + ownerKey.txid = id; + + pendingTX[ownerKey] = SearchJob(whoasked, target, job); llarp::Info("Asking ", askpeer, " for router ", target, " for ", whoasked); From d0196fdc65fa81bcd6dfb96fc04a3dc8ac91298b Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Mon, 4 Jun 2018 06:11:13 -0700 Subject: [PATCH 12/15] comment and error output --- llarp/iwp_link.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llarp/iwp_link.cpp b/llarp/iwp_link.cpp index 120e6456a..ef193a262 100644 --- a/llarp/iwp_link.cpp +++ b/llarp/iwp_link.cpp @@ -1673,6 +1673,7 @@ namespace iwp break; // TODO: AF_PACKET default: + llarp::Error(__FILE__, "unsupported address family", af); return false; } @@ -1761,7 +1762,7 @@ namespace iwp link->put_session(dst, s); } s->establish_job = job; - s->frame.alive(); + s->frame.alive(); // mark it alive s->introduce(job->ai.enc_key); } return true; From 373fbc58dca692ecf078070c55618f8b1a118094 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 7 Jun 2018 07:14:52 +0000 Subject: [PATCH 13/15] move struct so we can compile --- include/llarp/nodedb.h | 22 +++++++++------------- llarp/nodedb.cpp | 2 ++ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/include/llarp/nodedb.h b/include/llarp/nodedb.h index bd68d1e6f..b60ebc712 100644 --- a/include/llarp/nodedb.h +++ b/include/llarp/nodedb.h @@ -75,23 +75,19 @@ llarp_nodedb_has_rc(struct llarp_nodedb *n, llarp_pubkey_t k); bool llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc); -// defined in nodedb.cpp -/* -struct llarp_async_verify_job_context { - struct llarp_nodedb *nodedb; - struct llarp_logic *logic; - struct llarp_crypto *crypto; - struct llarp_threadpool *cryptoworker; - struct llarp_threadpool *diskworker; -}; -*/ - /** struct for async rc verification */ struct llarp_async_verify_rc; -struct llarp_async_verify_job_context; // forward definition (defined in nodedb.cpp) +//struct llarp_async_verify_job_context; // forward definition (defined in nodedb.cpp) +struct llarp_async_verify_job_context +{ + struct llarp_logic *logic; + struct llarp_crypto *crypto; + struct llarp_threadpool *cryptoworker; + struct llarp_threadpool *diskworker; +}; typedef void (*llarp_async_verify_rc_hook_func)(struct llarp_async_verify_rc *); @@ -101,7 +97,7 @@ struct llarp_async_verify_rc /// user pointers void *user; /// context - llarp_async_verify_job_context *context; + struct llarp_async_verify_job_context *context; /// router contact (should this be a pointer?) struct llarp_rc rc; /// result diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index 57080cf79..af8f9810c 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -13,6 +13,7 @@ #include "logger.hpp" // probably used for more than verify tbh +/* struct llarp_async_verify_job_context { struct llarp_logic *logic; @@ -20,6 +21,7 @@ struct llarp_async_verify_job_context struct llarp_threadpool *cryptoworker; struct llarp_threadpool *diskworker; }; +*/ static const char skiplist_subdirs[] = "0123456789ABCDEF"; From 70579e684667eea3827985e2d0773215be7946ac Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 7 Jun 2018 02:36:30 -0700 Subject: [PATCH 14/15] finish implementing llarp_nodedb_async_verify, move context inside llarp_async_verify_rc --- i2p.rocks.signed.txt | 1 + include/llarp/nodedb.h | 21 +++--- llarp/nodedb.cpp | 148 ++++++++++++++++------------------------- llarp/router.cpp | 10 ++- 4 files changed, 75 insertions(+), 105 deletions(-) create mode 100644 i2p.rocks.signed.txt diff --git a/i2p.rocks.signed.txt b/i2p.rocks.signed.txt new file mode 100644 index 000000000..a8d567a50 --- /dev/null +++ b/i2p.rocks.signed.txt @@ -0,0 +1 @@ +d1:ald1:ci1e1:d3:IWP1:e32:8XG-KZC@&A QD1:i22:::ffff:162.243.164.2231:pi1090e1:vi0eee1:k32:,@L>jϳ1[cǙ,1:ui0e1:vi0e1:z64:8@SvHDؗU'Rʟ! i~ [&}h!|M^gs#xfMֲ>e \ No newline at end of file diff --git a/include/llarp/nodedb.h b/include/llarp/nodedb.h index b60ebc712..572967821 100644 --- a/include/llarp/nodedb.h +++ b/include/llarp/nodedb.h @@ -80,24 +80,21 @@ llarp_nodedb_put_rc(struct llarp_nodedb *n, struct llarp_rc *rc); */ struct llarp_async_verify_rc; -//struct llarp_async_verify_job_context; // forward definition (defined in nodedb.cpp) -struct llarp_async_verify_job_context -{ - struct llarp_logic *logic; - struct llarp_crypto *crypto; - struct llarp_threadpool *cryptoworker; - struct llarp_threadpool *diskworker; -}; - typedef void (*llarp_async_verify_rc_hook_func)(struct llarp_async_verify_rc *); /// verify rc request struct llarp_async_verify_rc { - /// user pointers + /// async_verify_context void *user; - /// context - struct llarp_async_verify_job_context *context; + /// nodedb storage + struct llarp_nodedb *nodedb; + // llarp_logic for llarp_logic_queue_job + struct llarp_logic *logic; // includes a llarp_threadpool + struct llarp_crypto *crypto; + struct llarp_threadpool *cryptoworker; + struct llarp_threadpool *diskworker; + /// router contact (should this be a pointer?) struct llarp_rc rc; /// result diff --git a/llarp/nodedb.cpp b/llarp/nodedb.cpp index af8f9810c..5f5cf427b 100644 --- a/llarp/nodedb.cpp +++ b/llarp/nodedb.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -12,63 +11,8 @@ #include "encode.hpp" #include "logger.hpp" -// probably used for more than verify tbh -/* -struct llarp_async_verify_job_context -{ - struct llarp_logic *logic; - struct llarp_crypto *crypto; - struct llarp_threadpool *cryptoworker; - struct llarp_threadpool *diskworker; -}; -*/ - static const char skiplist_subdirs[] = "0123456789ABCDEF"; -static void on_crypt_verify_rc(rc_async_verify *job) -{ - if (job->result) { - // set up disk request - // how do we get our diskworker? - } else { - // it's not valid, don't update db - // send back to logic thread - - // make generic job based on previous job - //llarp_thread_job job = {.user = job->user, .work = &inform_verify_rc}; - //llarp_logic_queue_job(job->context->logic, job); - } - // TODO: is there any deallocation we need to do - llarp_async_rc_free(job->context); - //delete (llarp_async_rc*)job->context; // clean up our temp context created in verify_rc - delete job; // we're done with the rc_async_verify -} - -void verify_rc(void *user) -{ - llarp_async_verify_rc *verify_request = - static_cast< llarp_async_verify_rc * >(user); - // transfer context - // FIXME: move this allocation to more a long term home? - llarp_async_rc *async_rc_context = llarp_async_rc_new( - verify_request->context->crypto, verify_request->context->logic, - verify_request->context->cryptoworker); - // set up request - rc_async_verify *async_rc_request = new rc_async_verify; - // rc_call_async_verify will set up context, rc - // user? - async_rc_request->result = false; // just initialize it to something secure - async_rc_request->hook = &on_crypt_verify_rc; - - rc_call_async_verify(async_rc_context, async_rc_request, - &verify_request->rc); - // crypto verify - // if success write to disk - //verify_request->context->crypto - //llarp_thread_job job = {.user = user, .work = &inform_keygen}; - //llarp_logic_queue_job(keygen->iwp->logic, job); -} - struct llarp_nodedb { llarp_nodedb(llarp_crypto *c) : crypto(c) @@ -150,22 +94,25 @@ struct llarp_nodedb if (llarp_rc_bencode(rc, &buf)) { - // write buf to disk - //auto filename = hexStr(pk.data(), sizeof(pk)) + ".rc"; char ftmp[68] = {0}; const char *hexname = - llarp::HexEncode< llarp::pubkey, decltype(ftmp) >(pk, ftmp); + llarp::HexEncode< llarp::pubkey, decltype(ftmp) >(pk, ftmp); std::string filename(hexname); + filename.append(".signed.txt"); + llarp::Info("saving RC.pubkey ", filename); + // write buf to disk + //auto filename = hexStr(pk.data(), sizeof(pk)) + ".rc"; // FIXME: path? - printf("filename[%s]\n", filename.c_str()); + //printf("filename[%s]\n", filename.c_str()); std::ofstream ofs (filename, std::ofstream::out & std::ofstream::binary & std::ofstream::trunc); ofs.write((char *)buf.base, buf.sz); ofs.close(); if (!ofs) { - llarp::Error(__FILE__, "Failed to write", filename); + llarp::Error("Failed to write", filename); return false; } + llarp::Info("saved RC.pubkey", filename); return true; } return false; @@ -262,6 +209,41 @@ struct llarp_nodedb */ }; +// call request hook +void logic_threadworker_callback(void *user) { + llarp_async_verify_rc *verify_request = + static_cast < llarp_async_verify_rc * >(user); + verify_request->hook(verify_request); +} + +// write it to disk +void 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); + llarp_logic_queue_job(verify_request->logic, { verify_request, &logic_threadworker_callback }); +} + +// we run the crypto verify in the crypto threadpool worker +void 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->crypto, &verify_request->rc); + // if it's valid we need to set it + if (verify_request->valid) + { + llarp::Debug("RC is valid, saving to disk"); + llarp_threadpool_queue_job(verify_request->diskworker, + { verify_request, &disk_threadworker_setRC }); + } else { + // callback to logic thread + llarp::Warn("RC is not valid, can't save to disk"); + llarp_logic_queue_job(verify_request->logic, + { verify_request, &logic_threadworker_callback }); + } +} + extern "C" { struct llarp_nodedb * @@ -314,27 +296,6 @@ llarp_nodedb_load_dir(struct llarp_nodedb *n, const char *dir) return n->Load(dir); } -/// allocate verify job context -struct llarp_async_verify_job_context* -llarp_async_verify_job_new(struct llarp_threadpool *cryptoworker, - struct llarp_threadpool *diskworker, struct llarp_logic *logic, - struct llarp_crypto *crypto) { - llarp_async_verify_job_context *context = new llarp_async_verify_job_context; - if (context) - { - context->logic = logic; - context->crypto = crypto; - context->cryptoworker = cryptoworker; - context->diskworker = diskworker; - } - return context; -} - -void -llarp_async_verify_job_free(struct llarp_async_verify_job_context *context) { - delete context; -} - void llarp_nodedb_async_verify(struct llarp_nodedb *nodedb, struct llarp_logic *logic, @@ -343,13 +304,18 @@ llarp_nodedb_async_verify(struct llarp_nodedb *nodedb, struct llarp_threadpool *diskworker, struct llarp_async_verify_rc *job) { - // set up context - llarp_async_verify_job_context *context = llarp_async_verify_job_new( - cryptoworker, diskworker, logic, crypto); - // set up anything we need (in job) - job->context = context; - // queue the crypto check - llarp_threadpool_queue_job(cryptoworker, { job, &verify_rc }); + // TODO: ask jeff is safe to remove the parameters + // we expect the following to be already set up at this point: user (context: router, llarp_link_establish_job), rc, hook + // do additional job set up + /* + job->logic = logic; + job->crypto = crypto; + job->cryptoworker = cryptoworker; + job->diskworker = diskworker; + job->nodedb = nodedb; + */ + // switch to crypto threadpool and continue with crypto_threadworker_verifyrc + llarp_threadpool_queue_job(cryptoworker, { job, &crypto_threadworker_verifyrc }); } bool @@ -357,5 +323,5 @@ llarp_nodedb_find_rc(struct llarp_nodedb *nodedb, struct llarp_rc *dst, llarp_pubkey_t k) { return false; -} -} +} // end function +} // end extern diff --git a/llarp/router.cpp b/llarp/router.cpp index 58ef076c6..933224aee 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -230,6 +230,7 @@ llarp_router::on_verify_server_rc(llarp_async_verify_rc *job) llarp::async_verify_context *ctx = static_cast< llarp::async_verify_context * >(job->user); auto router = ctx->router; + llarp::Info("rc verified? ", job->valid?"valid":"invalid"); if(!job->valid) { llarp::Warn("invalid server RC"); @@ -420,10 +421,8 @@ llarp_router::on_try_connect_result(llarp_link_establish_job *job) if(job->session) { delete job; - /* auto session = job->session; router->async_verify_RC(session, false, job); - */ return; } llarp::Info("session not established"); @@ -439,6 +438,13 @@ llarp_router::async_verify_RC(llarp_link_session *session, job->rc = {}; job->valid = false; job->hook = nullptr; + + job->nodedb = nodedb; + job->logic = logic; + job->crypto = &crypto; + job->cryptoworker = tp; + job->diskworker = disk; + llarp_rc_copy(&job->rc, session->get_remote_router(session)); if(isExpectingClient) job->hook = &llarp_router::on_verify_client_rc; From 716f64634d93cdc9fec210d4e7128b3a4beeb3f4 Mon Sep 17 00:00:00 2001 From: Ryan Tharp Date: Thu, 7 Jun 2018 02:40:06 -0700 Subject: [PATCH 15/15] compile fix and remove unneeded patterning --- include/llarp/crypto_async.h | 44 -------------------------- llarp/crypto_async.cpp | 61 ++---------------------------------- 2 files changed, 3 insertions(+), 102 deletions(-) diff --git a/include/llarp/crypto_async.h b/include/llarp/crypto_async.h index a72a2ffdb..773ac524c 100644 --- a/include/llarp/crypto_async.h +++ b/include/llarp/crypto_async.h @@ -32,22 +32,6 @@ llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic, void llarp_async_iwp_free(struct llarp_async_iwp *iwp); - -/// context for doing asynchronous cryptography for rc -/// with a worker threadpool -/// defined in crypto_async.cpp -struct llarp_async_rc; - -/// rc async context allocator -struct llarp_async_rc * -llarp_async_rc_new(struct llarp_crypto *crypto, struct llarp_logic *logic, - struct llarp_threadpool *worker); - -/// deallocator -void -llarp_async_rc_free(struct llarp_async_rc *rc); - - struct iwp_async_keygen; /// define functor for keygen @@ -205,34 +189,6 @@ void iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp, struct iwp_async_frame *frame); - - -/// define functor for rc_verify -typedef void (*rc_verify_hook)(struct rc_async_verify *); - -/// rc verify request -struct rc_async_verify -{ - /// router contact crypto async configuration - struct llarp_async_rc *context; - /// a pointer to pass ourself to thread worker - void *self; - /// the router contact - struct llarp_rc *rc; - /// result - bool result; - /// result handler callback - rc_verify_hook hook; - /// extra data to pass to hook - void *hook_user; -}; - - -/// rc verify -void rc_call_async_verify(struct llarp_async_rc *context, - struct rc_async_verify *request, - struct llarp_rc *rc); - #ifdef __cplusplus } #endif diff --git a/llarp/crypto_async.cpp b/llarp/crypto_async.cpp index 720963543..8e18d421f 100644 --- a/llarp/crypto_async.cpp +++ b/llarp/crypto_async.cpp @@ -26,7 +26,9 @@ namespace iwp { iwp_async_keygen *keygen = static_cast< iwp_async_keygen * >(user); keygen->iwp->crypto->encryption_keygen(keygen->keybuf); - llarp_thread_job job = {.user = user, .work = &inform_keygen}; + llarp_thread_job job; + job.user = user; + job.work = &inform_keygen; llarp_logic_queue_job(keygen->iwp->logic, job); } @@ -384,33 +386,6 @@ namespace iwp } } -// REFACTOR: same as llarp_async_iwp (unify and rename) -struct llarp_async_rc -{ - struct llarp_crypto *crypto; - struct llarp_logic *logic; - struct llarp_threadpool *worker; -}; - -namespace rc { - - void - inform_verify(void *user) - { - rc_async_verify *request = static_cast< rc_async_verify * >(user); - request->hook(request); - } - - void - verify(void *user) - { - rc_async_verify *request = static_cast< rc_async_verify * >(user); - request->result = llarp_rc_verify_sig(request->context->crypto, request->rc); - llarp_thread_job job = {.user = user, .work = &inform_verify}; - llarp_logic_queue_job(request->context->logic, job); - } -} - extern "C" { void @@ -486,16 +461,6 @@ iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp, {session, &iwp::verify_session_start}); } -void rc_call_async_verify(struct llarp_async_rc *context, - struct rc_async_verify *request, - struct llarp_rc *rc) -{ - request->context = context; - request->rc = rc; - llarp_threadpool_queue_job(context->worker, - {request, &rc::verify}); -} - struct llarp_async_iwp * llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic, struct llarp_threadpool *worker) @@ -516,24 +481,4 @@ llarp_async_iwp_free(struct llarp_async_iwp *iwp) delete iwp; } -struct llarp_async_rc * -llarp_async_rc_new(struct llarp_crypto *crypto, struct llarp_logic *logic, - struct llarp_threadpool *worker) -{ - llarp_async_rc *context = new llarp_async_rc; - if(context) - { - context->crypto = crypto; - context->logic = logic; - context->worker = worker; - } - return context; -} - -void -llarp_async_rc_free(struct llarp_async_rc *context) -{ - delete context; -} - }