diff --git a/CMakeLists.txt b/CMakeLists.txt index 89f9bd4c1..d869b34cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,6 +175,7 @@ set(LIB_SRC llarp/dht/context.cpp llarp/dht/decode.cpp llarp/dht/dht_immediate.cpp + llarp/dht/find_intro.cpp llarp/dht/find_router.cpp llarp/dht/got_intro.cpp llarp/dht/got_router.cpp diff --git a/daemon/main.cpp b/daemon/main.cpp index b1c0c9eb6..462f8f3a7 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include // for MIN struct llarp_main *ctx = 0; @@ -18,15 +21,57 @@ int main(int argc, char *argv[]) { const char *conffname = "daemon.ini"; - if(argc > 1) - conffname = argv[1]; + int c; + while(1) + { + static struct option long_options[] = { + {"config", required_argument, 0, 'c'}, + {"logLevel", required_argument, 0, 'o'}, + {0, 0, 0, 0}}; + int option_index = 0; + c = getopt_long(argc, argv, "c:o:", long_options, &option_index); + if(c == -1) + break; + switch(c) + { + case 0: + break; + case 'c': + conffname = optarg; + break; + case 'o': + if (strncmp(optarg, "debug", MIN(strlen(optarg), (unsigned long)5))==0) + { + cSetLogLevel(eLogDebug); + } + else + if (strncmp(optarg, "info", MIN(strlen(optarg), (unsigned long)4))==0) + { + cSetLogLevel(eLogInfo); + } + else + if (strncmp(optarg, "warn", MIN(strlen(optarg), (unsigned long)4))==0) + { + cSetLogLevel(eLogWarn); + } + else + if (strncmp(optarg, "error", MIN(strlen(optarg), (unsigned long)5))==0) + { + cSetLogLevel(eLogError); + } + break; + default: + abort(); + } + } + ctx = llarp_main_init(conffname, !TESTNET); int code = 1; if(ctx) { signal(SIGINT, handle_signal); code = llarp_main_run(ctx); - llarp_main_free(ctx); + //llarp_main_free(ctx); } return code; } diff --git a/daemon/rcutil.cpp b/daemon/rcutil.cpp index 4f5a8bbd4..481566b63 100644 --- a/daemon/rcutil.cpp +++ b/daemon/rcutil.cpp @@ -2,6 +2,16 @@ #include #include "logger.hpp" +#include +#include +#include +#include +#include "buffer.hpp" +#include "crypto.hpp" +#include "fs.hpp" +#include "net.hpp" +#include "router.hpp" + struct llarp_main *ctx = 0; llarp_main *sllarp = nullptr; @@ -17,16 +27,6 @@ handle_signal(int sig) #define TESTNET 0 #endif -#include -#include -#include -#include -#include "buffer.hpp" -#include "crypto.hpp" -#include "fs.hpp" -#include "net.hpp" -#include "router.hpp" - bool printNode(struct llarp_nodedb_iter *iter) { @@ -38,16 +38,6 @@ printNode(struct llarp_nodedb_iter *iter) return false; } -// fwd declr -struct check_online_request; - -void -HandleDHTLocate(llarp_router_lookup_job *job) -{ - llarp::LogInfo("DHT result: ", job->found ? "found" : "not found"); - // save to nodedb? -} - bool aiLister(struct llarp_ai_list_iter *request, struct llarp_ai *addr) { @@ -58,10 +48,49 @@ aiLister(struct llarp_ai_list_iter *request, struct llarp_ai *addr) return true; } +void displayRC(llarp_rc *rc) +{ + char ftmp[68] = {0}; + const char *hexPubSigKey = + llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(rc->pubkey, ftmp); + printf("PubSigKey [%s]\n", hexPubSigKey); + + struct llarp_ai_list_iter iter; + // iter.user + iter.visit = &aiLister; + llarp_ai_list_iterate(rc->addrs, &iter); +} + +// fwd declr +struct check_online_request; + +void +HandleDHTLocate(llarp_router_lookup_job *job) +{ + llarp::LogInfo("DHT result: ", job->found ? "found" : "not found"); + if (job->found) + { + // save to nodedb? + displayRC(&job->result); + } + // shutdown router + + // well because we're in the gotroutermessage, we can't sigint because we'll deadlock because we're session locked + //llarp_main_signal(ctx, SIGINT); + + // llarp_timer_run(logic->timer, logic->thread); + // we'll we don't want logic thread + // but we want to switch back to the main thread + //llarp_logic_stop(); + // still need to exit this logic thread... + llarp_main_abort(ctx); +} + int main(int argc, char *argv[]) { // take -c to set location of daemon.ini + // take -o to set log level // --generate-blank /path/to/file.signed // --update-ifs /path/to/file.signed // --key /path/to/long_term_identity.key @@ -75,12 +104,14 @@ main(int argc, char *argv[]) { printf( "please specify: \n" - "--generate with a path to a router contact file\n" - "--update with a path to a router contact file\n" - "--list \n" - "--import with a path to a router contact file\n" - "--export a hex formatted public key\n" - "--locate a hex formatted public key" + "--generate with a path to a router contact file\n" + "--update with a path to a router contact file\n" + "--list \n" + "--import with a path to a router contact file\n" + "--export a hex formatted public key\n" + "--locate a hex formatted public key" + "--localInfo \n" + "--read with a path to a router contact file\n" "\n"); return 0; } @@ -91,6 +122,7 @@ main(int argc, char *argv[]) bool exportMode = false; bool locateMode = false; bool localMode = false; + bool readMode = false; int c; char *conffname; char defaultConfName[] = "daemon.ini"; @@ -103,6 +135,7 @@ main(int argc, char *argv[]) { static struct option long_options[] = { {"config", required_argument, 0, 'c'}, + {"logLevel", required_argument, 0, 'o'}, {"generate", required_argument, 0, 'g'}, {"update", required_argument, 0, 'u'}, {"list", no_argument, 0, 'l'}, @@ -110,9 +143,10 @@ main(int argc, char *argv[]) {"export", required_argument, 0, 'e'}, {"locate", required_argument, 0, 'q'}, {"localInfo", no_argument, 0, 'n'}, + {"read", required_argument, 0, 'r'}, {0, 0, 0, 0}}; int option_index = 0; - c = getopt_long(argc, argv, "cgluieqn", long_options, &option_index); + c = getopt_long(argc, argv, "c:o:g:lu:i:e:q:nr:", long_options, &option_index); if(c == -1) break; switch(c) @@ -122,6 +156,27 @@ main(int argc, char *argv[]) case 'c': conffname = optarg; break; + case 'o': + if (strncmp(optarg, "debug", std::min(strlen(optarg), static_cast(5)))==0) + { + llarp::SetLogLevel(llarp::eLogDebug); + } + else + if (strncmp(optarg, "info", std::min(strlen(optarg), static_cast(4)))==0) + { + llarp::SetLogLevel(llarp::eLogInfo); + } + else + if (strncmp(optarg, "warn", std::min(strlen(optarg), static_cast(4)))==0) + { + llarp::SetLogLevel(llarp::eLogWarn); + } + else + if (strncmp(optarg, "error", std::min(strlen(optarg), static_cast(5)))==0) + { + llarp::SetLogLevel(llarp::eLogError); + } + break; case 'l': haveRequiredOptions = true; listMode = true; @@ -160,6 +215,11 @@ main(int argc, char *argv[]) haveRequiredOptions = true; localMode = true; break; + case 'r': + rcfname = optarg; + haveRequiredOptions = true; + readMode = true; + break; default: abort(); } @@ -171,7 +231,7 @@ main(int argc, char *argv[]) } printf("parsed options\n"); if(!genMode && !updMode && !listMode && !importMode && !exportMode - && !locateMode && !localMode) + && !locateMode && !localMode && !readMode) { llarp::LogError( "I don't know what to do, no generate or update parameter\n"); @@ -295,13 +355,14 @@ main(int argc, char *argv[]) llarp::PubKey binaryPK; llarp::HexDecode(rcfname, binaryPK.data()); - // llarp::SetLogLevel(llarp::eLogDebug); - llarp::LogInfo("Queueing job"); llarp_router_lookup_job *job = new llarp_router_lookup_job; + job->iterative = true; job->found = false; job->hook = &HandleDHTLocate; + llarp_rc_new(&job->result); memcpy(job->target, binaryPK, PUBKEYSIZE); // set job's target + // create query DHT request check_online_request *request = new check_online_request; request->ptr = ctx; @@ -317,20 +378,15 @@ main(int argc, char *argv[]) } if(localMode) { - // llarp::LogInfo("find our local rc file"); - - // llarp_rc *rc = llarp_rc_read("router.signed"); llarp_rc *rc = llarp_main_getLocalRC(ctx); - char ftmp[68] = {0}; - const char *hexPubSigKey = - llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(rc->pubkey, ftmp); - printf("PubSigKey [%s]\n", hexPubSigKey); - - struct llarp_ai_list_iter iter; - // iter.user - iter.visit = &aiLister; - llarp_ai_list_iterate(rc->addrs, &iter); + displayRC(rc); + } + if(readMode) + { + llarp_rc *rc = llarp_rc_read(rcfname); + displayRC(rc); } - llarp_main_free(ctx); + // it's a unique_ptr, should clean up itself + //llarp_main_free(ctx); return 1; // success } diff --git a/doc/dht_v0.txt b/doc/dht_v0.txt index beddfb2c5..215c3fb70 100644 --- a/doc/dht_v0.txt +++ b/doc/dht_v0.txt @@ -11,6 +11,7 @@ recursively find an IS by SA { A: "F", + I: 0 or 1 if iterative request, R: r_counter, S: "<32 bytes SA>", T: transaction_id_uint64, @@ -123,33 +124,13 @@ find a router by long term RC.k public key { A: "R", + I: 0 or 1 if iterative lookup K: "<32 byte public key of router>", T: transaction_id_uint64, V: 0 } -find RC who's RC.k is closest to K: - -if A.k is equal to K: - -* reply with a GRCM with an R value of just A - -if A.k is not equal to K and we are closesr to A.k than anyone we know: - -* reply with a GRCM with an empty R value - -find a pending transaction id for K, P - -if P exists: - -* link transaction T to P - -if P does not exist: - -* generate a new transaction id, U -* start transaction U for A.k -* link transaction U to transaction T -* send FRCM to A.k requesting K +TODO: document me got router contact message (GRCM) diff --git a/doc/proto_v0.txt b/doc/proto_v0.txt index a9e552e79..35a34249f 100644 --- a/doc/proto_v0.txt +++ b/doc/proto_v0.txt @@ -516,20 +516,43 @@ B is set to a backoff value. R contains additional metadata text describing why the exit was rejected. +hidden service frame (HSF) -hidden service data message (HSDM) +TODO: document this better -signed data sent anonymously over the network to a recipiant from a sender. -sent inside a TDFM encrypted to the hidden service's public encryption key. +intro message (variant 1) { A: "H", - H: "", - I: Introducer for reply, - R: SA of recipiant, - S: SI of sender, + D: "", + H: "<32 bytes ephemeral public encryption key>", + N: "<32 bytes nonce for key exchange>", + S: 0, + V: 0, + Z: "<64 bytes signature of entire message using sender's signing key>" +} + +ordered data message (variant 2) + +{ + A: "H", + D: "", + N: "<32 bytes nonce for symettric cipher>", + S: sequence_number_uint64, V: 0, - Z: "<64 bytes signature from sender of the entire message>" + Z: "<64 bytes signature using sender's signing key>" +} + +hidden service data (HSD) + +data sent anonymously over the network to a recipiant from a sender. +sent inside a HSFM encrypted with a shared secret. + +{ + D: "", + I: Introduction for reply, + S: SI of sender, + V: 0 } transfer data fragment message (TDFM) @@ -539,12 +562,11 @@ transfer data between paths. { A: "T", P: "<16 bytes path id>", - T: "", - V: 0, - Y: "<32 bytes nounce>" + T: message_transfered_between_paths, + V: 0 } -transfer data to another path with id P on the local router place Y and T values +transfer data to another path with id P on the local router place a random 32 byte and T values into y and z values into a LRDM message (respectively) and send it in the downstream direction. diff --git a/include/llarp.h b/include/llarp.h index 87338f9fd..c932b2a3c 100644 --- a/include/llarp.h +++ b/include/llarp.h @@ -23,10 +23,6 @@ llarp_main_init(const char *fname, bool multiProcess); void llarp_main_signal(struct llarp_main *ptr, int sig); -/// set custom dht message handler function -void -llarp_main_set_dht_handler(struct llarp_main *ptr, llarp_dht_msg_handler h); - /// setup main context int llarp_main_setup(struct llarp_main *ptr); @@ -35,6 +31,9 @@ llarp_main_setup(struct llarp_main *ptr); int llarp_main_run(struct llarp_main *ptr); +void +llarp_main_abort(struct llarp_main *ptr); + /// load nodeDB into memory int llarp_main_loadDatabase(struct llarp_main *ptr); diff --git a/include/llarp.hpp b/include/llarp.hpp index 2f208cb51..e62434de4 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -18,15 +18,14 @@ namespace llarp bool singleThreaded = false; std::vector< std::thread > netio_threads; llarp_crypto crypto; - llarp_router *router = nullptr; - llarp_threadpool *worker = nullptr; - llarp_logic *logic = nullptr; - llarp_config *config = nullptr; - llarp_nodedb *nodedb = nullptr; - llarp_ev_loop *mainloop = nullptr; - llarp_dht_msg_handler custom_dht_func = nullptr; - char nodedb_dir[256] = {0}; - char conatctFile[256] = "router.signed"; + llarp_router *router = nullptr; + llarp_threadpool *worker = nullptr; + llarp_logic *logic = nullptr; + llarp_config *config = nullptr; + llarp_nodedb *nodedb = nullptr; + llarp_ev_loop *mainloop = nullptr; + char nodedb_dir[256] = {0}; + char conatctFile[256] = "router.signed"; bool LoadConfig(const std::string &fname); diff --git a/include/llarp/dht.h b/include/llarp/dht.h index 5b06c0611..3a979a48c 100644 --- a/include/llarp/dht.h +++ b/include/llarp/dht.h @@ -20,23 +20,10 @@ llarp_dht_context_new(struct llarp_router* parent); void llarp_dht_context_free(struct llarp_dht_context* dht); -struct llarp_dht_msg; - -/// handler function -/// f(outmsg, inmsg) -/// returns true if outmsg has been filled otherwise returns false -typedef bool (*llarp_dht_msg_handler)(struct llarp_dht_msg*, - struct llarp_dht_msg*); - /// start dht context with our location in keyspace void llarp_dht_context_start(struct llarp_dht_context* ctx, const byte_t* key); -// override dht message handler with custom handler -void -llarp_dht_set_msg_handler(struct llarp_dht_context* ctx, - llarp_dht_msg_handler func); - struct llarp_router_lookup_job; typedef void (*llarp_router_lookup_handler)(struct llarp_router_lookup_job*); @@ -49,7 +36,9 @@ struct llarp_router_lookup_job struct llarp_dht_context* dht; byte_t target[PUBKEYSIZE]; bool found; + // make sure you initialize addr and exits struct llarp_rc result; + bool iterative; }; /// start allowing dht participation on a context diff --git a/include/llarp/dht/context.hpp b/include/llarp/dht/context.hpp index 475337ee7..c98ea79b1 100644 --- a/include/llarp/dht/context.hpp +++ b/include/llarp/dht/context.hpp @@ -20,14 +20,19 @@ namespace llarp Context(); ~Context(); - llarp_dht_msg_handler custom_handler = nullptr; - SearchJob* FindPendingTX(const Key_t& owner, uint64_t txid); void RemovePendingLookup(const Key_t& owner, uint64_t txid); + void + LookupServiceDirect(const Key_t& target, const Key_t& whoasked, + uint64_t whoaskedTX, const Key_t& askpeer, + SearchJob::IntroSetHookFunc handler, + bool iterateive = false, + std::set< Key_t > excludes = {}); + void LookupRouter(const Key_t& target, const Key_t& whoasked, uint64_t whoaskedTX, const Key_t& askpeer, diff --git a/include/llarp/dht/messages/findintro.hpp b/include/llarp/dht/messages/findintro.hpp index 7c1e8f58e..35719643f 100644 --- a/include/llarp/dht/messages/findintro.hpp +++ b/include/llarp/dht/messages/findintro.hpp @@ -9,7 +9,8 @@ namespace llarp { struct FindIntroMessage : public IMessage { - uint64_t R = 0; + uint64_t R = 0; + bool iterative = false; llarp::service::Address S; uint64_t T = 0; @@ -25,6 +26,6 @@ namespace llarp HandleMessage(llarp_dht_context* ctx, std::vector< IMessage* >& replies) const; }; - } -} + } // namespace dht +} // namespace llarp #endif \ No newline at end of file diff --git a/include/llarp/logic.h b/include/llarp/logic.h index e9ef56346..c465b83a8 100644 --- a/include/llarp/logic.h +++ b/include/llarp/logic.h @@ -35,6 +35,9 @@ llarp_logic_cancel_call(struct llarp_logic* logic, uint32_t id); void llarp_logic_remove_call(struct llarp_logic* logic, uint32_t id); +void +llarp_logic_stop_timer(struct llarp_logic* logic); + void llarp_logic_stop(struct llarp_logic* logic); diff --git a/include/llarp/messages/hidden_service.hpp b/include/llarp/messages/hidden_service.hpp new file mode 100644 index 000000000..b417f81d2 --- /dev/null +++ b/include/llarp/messages/hidden_service.hpp @@ -0,0 +1,16 @@ +#ifndef LLARP_MESSAGES_HIDDEN_SERIVCE_HPP +#define LLARP_MESSAGES_HIDDEN_SERIVCE_HPP + +#include + +namespace llarp +{ + namespace routing + { + struct HiddenServiceFrame : public IMessage + { + }; + } // namespace routing +} // namespace llarp + +#endif \ No newline at end of file diff --git a/include/llarp/path.hpp b/include/llarp/path.hpp index 6ea399759..fcfada9c8 100644 --- a/include/llarp/path.hpp +++ b/include/llarp/path.hpp @@ -165,9 +165,6 @@ namespace llarp bool HandleDHTMessage(const llarp::dht::IMessage* msg, llarp_router* r); - bool - HandleHiddenServiceData(llarp_buffer_t buf, llarp_router* r); - // handle data in upstream direction bool HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r); @@ -246,9 +243,6 @@ namespace llarp bool HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r); - bool - HandleHiddenServiceData(llarp_buffer_t buf, llarp_router* r); - // handle data in upstream direction bool HandleUpstream(llarp_buffer_t X, const TunnelNonce& Y, llarp_router* r); diff --git a/include/llarp/pathbuilder.h b/include/llarp/pathbuilder.h index 4b4204a5c..89af36666 100644 --- a/include/llarp/pathbuilder.h +++ b/include/llarp/pathbuilder.h @@ -20,7 +20,7 @@ struct llarp_pathbuilder_context; /// alloc struct llarp_pathbuilder_context* llarp_pathbuilder_context_new(struct llarp_router* router, - struct llarp_dht_context* dht); + struct llarp_dht_context* dht, size_t numpaths); /// dealloc void llarp_pathbuilder_context_free(struct llarp_pathbuilder_context* ctx); diff --git a/include/llarp/pathbuilder.hpp b/include/llarp/pathbuilder.hpp index 80704249a..618454288 100644 --- a/include/llarp/pathbuilder.hpp +++ b/include/llarp/pathbuilder.hpp @@ -10,7 +10,7 @@ struct llarp_pathbuilder_context : public llarp::path::PathSet struct llarp_dht_context* dht; /// construct llarp_pathbuilder_context(llarp_router* p_router, - struct llarp_dht_context* p_dht); + struct llarp_dht_context* p_dht, size_t numPaths); virtual ~llarp_pathbuilder_context(){}; diff --git a/include/llarp/pathset.hpp b/include/llarp/pathset.hpp index d0155abbf..b7580c457 100644 --- a/include/llarp/pathset.hpp +++ b/include/llarp/pathset.hpp @@ -1,6 +1,7 @@ #ifndef LLARP_PATHSET_HPP #define LLARP_PATHSET_HPP #include +#include #include #include #include @@ -81,6 +82,18 @@ namespace llarp PublishIntroSet(const llarp::service::IntroSet& introset, llarp_router* r); + typedef std::function< void(const llarp::service::IntroSet*) > + ServiceLookupHandler; + + /// return false if we are already pending a lookup for this address + bool + LookupService(const llarp::service::Address& addr, + ServiceLookupHandler handler); + + protected: + void + IssueServiceLookup(const llarp::service::Address& addr); + private: typedef std::pair< RouterID, PathID_t > PathInfo_t; typedef std::map< PathInfo_t, Path* > PathMap_t; @@ -88,6 +101,9 @@ namespace llarp size_t m_NumPaths; PathMap_t m_Paths; uint64_t m_CurrentPublishTX = 0; + std::unordered_map< llarp::service::Address, ServiceLookupHandler, + llarp::service::Address::Hash > + m_ServiceLookups; }; } // namespace path diff --git a/include/llarp/router_contact.h b/include/llarp/router_contact.h index fa94cdd3e..ecada1960 100644 --- a/include/llarp/router_contact.h +++ b/include/llarp/router_contact.h @@ -42,6 +42,10 @@ struct llarp_rc void llarp_rc_free(struct llarp_rc *rc); +bool +llarp_rc_new(struct llarp_rc *rc); + + bool llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc); diff --git a/include/llarp/routing/handler.hpp b/include/llarp/routing/handler.hpp index e11ef4fda..02069953f 100644 --- a/include/llarp/routing/handler.hpp +++ b/include/llarp/routing/handler.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,10 @@ namespace llarp llarp_router *r) = 0; virtual bool - HandleHiddenServiceData(llarp_buffer_t buf, llarp_router *r) = 0; + HandleHiddenServiceFrame(const HiddenServiceFrame *msg) + { + return false; + } virtual bool HandlePathConfirmMessage(const PathConfirmMessage *msg, diff --git a/include/llarp/service/address.hpp b/include/llarp/service/address.hpp index 4113f3667..c64603741 100644 --- a/include/llarp/service/address.hpp +++ b/include/llarp/service/address.hpp @@ -20,6 +20,16 @@ namespace llarp Address(const byte_t* data) : llarp::AlignedBuffer< 32 >(data) { } + struct Hash + { + size_t + operator()(const Address& addr) const + { + size_t idx = 0; + memcpy(&idx, addr, sizeof(idx)); + return idx; + } + }; }; } // namespace service diff --git a/include/llarp/service/endpoint.hpp b/include/llarp/service/endpoint.hpp index ca2ff36db..c04408a92 100644 --- a/include/llarp/service/endpoint.hpp +++ b/include/llarp/service/endpoint.hpp @@ -1,5 +1,6 @@ #ifndef LLARP_SERVICE_ENDPOINT_HPP #define LLARP_SERVICE_ENDPOINT_HPP +#include #include #include @@ -24,11 +25,70 @@ namespace llarp bool HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg); + bool + HandleHiddenServiceFrame(const llarp::routing::HiddenServiceFrame* msg); + + /// return true if we have an established path to a hidden service + bool + HasPathToService(const Address& remote) const; + + /// return false if we don't have a path to the service + /// return true if we did and we removed it + bool + ForgetPathToService(const Address& remote); + + /// context needed to initiate an outbound hidden service session + struct OutboundContext : public llarp_pathbuilder_context + { + OutboundContext(Endpoint* parent); + ~OutboundContext(); + + /// the remote hidden service's curren intro set + IntroSet currentIntroSet; + + uint64_t sequenceNo = 0; + + /// encrypt asynchronously and send to remote endpoint from us + /// returns false if we cannot send yet otherwise returns true + bool + AsyncEncryptAndSendTo(llarp_buffer_t D); + + /// issues a lookup to find the current intro set of the remote service + void + UpdateIntroSet(); + + bool + HandleGotIntroMessage(const llarp::dht::GotIntroMessage* msg); + + private: + llarp::SharedSecret sharedKey; + Endpoint* m_Parent; + }; + + // passed a sendto context when we have a path established otherwise + // nullptr if the path was not made before the timeout + typedef std::function< void(OutboundContext*) > PathEnsureHook; + + /// return false if we have already called this function before for this + /// address + bool + EnsurePathToService(const Address& remote, PathEnsureHook h, + uint64_t timeoutMS); + + virtual bool + HandleAuthenticatedDataFrom(const Address& remote, llarp_buffer_t data) + { + /// TODO: imlement me + return true; + } + private: llarp_router* m_Router; std::string m_Keyfile; std::string m_Name; Identity m_Identity; + std::unordered_map< Address, OutboundContext*, Address::Hash > + m_RemoteSessions; }; } // namespace service } // namespace llarp diff --git a/llarp/context.cpp b/llarp/context.cpp index 3edefc2fe..60fa754d5 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -161,11 +161,6 @@ namespace llarp llarp::LogError("Failed to configure router"); return 1; } - if(custom_dht_func) - { - llarp::LogInfo("using custom dht function"); - llarp_dht_set_msg_handler(router->dht, custom_dht_func); - } // set nodedb, load our RC, establish DHT llarp_run_router(router, nodedb); @@ -325,12 +320,6 @@ llarp_main_init(const char *fname, bool multiProcess) return m; } -void -llarp_main_set_dht_handler(struct llarp_main *ptr, llarp_dht_msg_handler func) -{ - ptr->ctx->custom_dht_func = func; -} - void llarp_main_signal(struct llarp_main *ptr, int sig) { @@ -349,6 +338,12 @@ llarp_main_run(struct llarp_main *ptr) return ptr->ctx->Run(); } +void +llarp_main_abort(struct llarp_main *ptr) +{ + llarp_logic_stop_timer(ptr->ctx->router->logic); +} + int llarp_main_loadDatabase(struct llarp_main *ptr) { diff --git a/llarp/dht.cpp b/llarp/dht.cpp index cd6817ec5..246749e9d 100644 --- a/llarp/dht.cpp +++ b/llarp/dht.cpp @@ -24,6 +24,7 @@ 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); } @@ -31,16 +32,10 @@ void llarp_dht_remove_peer(struct llarp_dht_context *ctx, const byte_t *id) { llarp::dht::Key_t k = id; + llarp::LogDebug("Removing ", k, " to DHT"); ctx->impl.nodes->DelNode(k); } -void -llarp_dht_set_msg_handler(struct llarp_dht_context *ctx, - llarp_dht_msg_handler handler) -{ - ctx->impl.custom_handler = handler; -} - void llarp_dht_allow_transit(llarp_dht_context *ctx) { diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index 8b83cb27d..8beb46ee9 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -66,6 +66,9 @@ namespace llarp else { // yeah, ask neighboor recursively + // FIXME: we may need to pass a job here... + //auto sj = FindPendingTX(requester, txid); + //LookupRouter(target, requester, txid, next, sj->job); LookupRouter(target, requester, txid, next); } } @@ -189,8 +192,18 @@ namespace llarp Context::LookupRouterViaJob(llarp_router_lookup_job *job) { Key_t peer; + /* + llarp::LogInfo("LookupRouterViaJob dumping nodes"); + for(const auto &item : nodes->nodes) + { + llarp::LogInfo("LookupRouterViaJob dumping node: ", item.first); + } + */ + llarp::LogInfo("LookupRouterViaJob node count: ", nodes->nodes.size()); + llarp::LogInfo("LookupRouterViaJob recursive: ", job->iterative?"yes":"no"); + if(nodes->FindClosest(job->target, peer)) - LookupRouter(job->target, ourKey, 0, peer, job); + LookupRouter(job->target, ourKey, 0, peer, job, job->iterative); else if(job->hook) { job->found = false; @@ -207,4 +220,4 @@ namespace llarp } } // namespace dht -} // namespace llarp \ No newline at end of file +} // namespace llarp diff --git a/llarp/dht/find_intro.cpp b/llarp/dht/find_intro.cpp new file mode 100644 index 000000000..c113317c9 --- /dev/null +++ b/llarp/dht/find_intro.cpp @@ -0,0 +1,11 @@ +#include + +namespace llarp +{ + namespace dht + { + FindIntroMessage::~FindIntroMessage() + { + } + } // namespace dht +} // namespace llarp \ No newline at end of file diff --git a/llarp/dht/got_router.cpp b/llarp/dht/got_router.cpp index d50e880a6..08537e482 100644 --- a/llarp/dht/got_router.cpp +++ b/llarp/dht/got_router.cpp @@ -61,8 +61,8 @@ namespace llarp GotRouterMessage::HandleMessage(llarp_dht_context *ctx, std::vector< IMessage * > &replies) const { - auto &dht = ctx->impl; - auto pending = dht.FindPendingTX(From, txid); + auto &dht = ctx->impl; + SearchJob *pending = dht.FindPendingTX(From, txid); if(pending) { if(R.size()) @@ -87,9 +87,10 @@ namespace llarp " iterating to next peer ", nextPeer, " already asked ", pending->exclude.size(), " other peers"); + // REVIEW: is this ok to relay the pending->job as the current job (seems to make things work) dht.LookupRouter(pending->target, pending->requester, - pending->requesterTX, nextPeer, nullptr, true, - pending->exclude); + pending->requesterTX, nextPeer, pending->job, + true, pending->exclude); } else { @@ -111,4 +112,4 @@ namespace llarp return false; } } // namespace dht -} // namespace llarp \ No newline at end of file +} // namespace llarp diff --git a/llarp/logic.cpp b/llarp/logic.cpp index cde966028..939bb968a 100644 --- a/llarp/logic.cpp +++ b/llarp/logic.cpp @@ -43,6 +43,13 @@ llarp_free_logic(struct llarp_logic** logic) *logic = nullptr; } +void +llarp_logic_stop_timer(struct llarp_logic* logic) +{ + if(logic->timer) + llarp_timer_stop(logic->timer); +} + void llarp_logic_stop(struct llarp_logic* logic) { diff --git a/llarp/path.cpp b/llarp/path.cpp index f48761e8e..aad811228 100644 --- a/llarp/path.cpp +++ b/llarp/path.cpp @@ -381,13 +381,6 @@ namespace llarp return HandleRoutingMessage(buf, r); } - bool - Path::HandleHiddenServiceData(llarp_buffer_t buf, llarp_router* r) - { - // TODO: implement me - return false; - } - bool Path::HandleRoutingMessage(llarp_buffer_t buf, llarp_router* r) { diff --git a/llarp/pathbuilder.cpp b/llarp/pathbuilder.cpp index 669e76c93..7c5708ece 100644 --- a/llarp/pathbuilder.cpp +++ b/llarp/pathbuilder.cpp @@ -175,9 +175,8 @@ namespace llarp } // namespace llarp llarp_pathbuilder_context::llarp_pathbuilder_context( - llarp_router* p_router, struct llarp_dht_context* p_dht) - // TODO: hardcoded value - : llarp::path::PathSet(4), router(p_router), dht(p_dht) + llarp_router* p_router, struct llarp_dht_context* p_dht, size_t pathNum) + : llarp::path::PathSet(pathNum), router(p_router), dht(p_dht) { p_router->paths.AddPathBuilder(this); } @@ -196,9 +195,9 @@ llarp_pathbuilder_context::BuildOne() struct llarp_pathbuilder_context* llarp_pathbuilder_context_new(struct llarp_router* router, - struct llarp_dht_context* dht) + struct llarp_dht_context* dht, size_t sz) { - return new llarp_pathbuilder_context(router, dht); + return new llarp_pathbuilder_context(router, dht, sz); } void diff --git a/llarp/router.cpp b/llarp/router.cpp index 1f65f06c5..5a771ff06 100644 --- a/llarp/router.cpp +++ b/llarp/router.cpp @@ -34,7 +34,6 @@ llarp_router::llarp_router() , paths(this) , dht(llarp_dht_context_new(this)) , inbound_link_msg_parser(this) - , explorePool(llarp_pathbuilder_context_new(this, dht)) , hiddenServiceContext(this) { @@ -165,49 +164,26 @@ llarp_router::HandleDHTLookupForSendTo(llarp_router_lookup_job *job) void llarp_router::try_connect(fs::path rcfile) { - // FIXME: update API - byte_t tmp[MAX_RC_SIZE]; - llarp_rc remote = {0}; - llarp_buffer_t buf; - llarp::StackBuffer< decltype(tmp) >(buf, tmp); - // open file + llarp_rc *remote = new llarp_rc; + llarp_rc_new(remote); + remote = llarp_rc_read(rcfile.c_str()); + if (!remote) { - std::ifstream f(rcfile, std::ios::binary); - if(f.is_open()) - { - f.seekg(0, std::ios::end); - size_t sz = f.tellg(); - f.seekg(0, std::ios::beg); - if(sz <= buf.sz) - { - f.read((char *)buf.base, sz); - } - else - llarp::LogError(rcfile, " too large"); - } - else - { - llarp::LogError("failed to open ", rcfile); - return; - } + llarp::LogError("failure to decode or verify of remote RC"); + return; } - if(llarp_rc_bdecode(&remote, &buf)) + if(llarp_rc_verify_sig(&crypto, remote)) { - if(llarp_rc_verify_sig(&crypto, &remote)) + llarp::LogDebug("verified signature"); + if(!llarp_router_try_connect(this, remote, 10)) { - llarp::LogDebug("verified signature"); - if(!llarp_router_try_connect(this, &remote, 10)) - { - llarp::LogWarn("session already made"); - } + // or error? + llarp::LogWarn("session already made"); } - else - llarp::LogError("failed to verify signature of RC", rcfile); } else - llarp::LogError("failed to decode RC"); - - llarp_rc_free(&remote); + llarp::LogError("failed to verify signature of RC", rcfile); + llarp_rc_free(remote); } bool @@ -267,6 +243,7 @@ llarp_router::SaveRC() void llarp_router::Close() { + llarp::LogInfo("Closing ", inboundLinks.size(), " server bindings"); for(auto link : inboundLinks) { link->stop_link(); @@ -274,6 +251,7 @@ llarp_router::Close() } inboundLinks.clear(); + llarp::LogInfo("Closing LokiNetwork client"); outboundLink->stop_link(); delete outboundLink; outboundLink = nullptr; @@ -638,8 +616,8 @@ llarp_router::Run() } if(a.isPrivate()) { - llarp::LogWarn("Skipping private network link: ", a); - continue; + //llarp::LogWarn("Skipping private network link: ", a); + //continue; } llarp::LogInfo("Loading Addr: ", a, " into our RC"); diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 11db29931..c2e6dd1bc 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -5,6 +5,15 @@ #include "buffer.hpp" #include "logger.hpp" +bool +llarp_rc_new(struct llarp_rc *rc) +{ + rc->addrs = llarp_ai_list_new(); + rc->exits = llarp_xi_list_new(); + rc->last_updated = 0; + return true; +} + void llarp_rc_free(struct llarp_rc *rc) { diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index b0453f161..6ed0fcf34 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -6,7 +6,7 @@ namespace llarp namespace service { Endpoint::Endpoint(const std::string& name, llarp_router* r) - : llarp_pathbuilder_context(r, r->dht), m_Router(r), m_Name(name) + : llarp_pathbuilder_context(r, r->dht, 2), m_Router(r), m_Name(name) { } @@ -96,5 +96,23 @@ namespace llarp Endpoint::~Endpoint() { } - } -} \ No newline at end of file + + Endpoint::OutboundContext::OutboundContext(Endpoint* parent) + : llarp_pathbuilder_context(parent->m_Router, parent->m_Router->dht, 2) + , m_Parent(parent) + { + } + + Endpoint::OutboundContext::~OutboundContext() + { + } + + bool + Endpoint::OutboundContext::HandleGotIntroMessage( + const llarp::dht::GotIntroMessage* msg) + { + // TODO: implement me + return false; + } + } // namespace service +} // namespace llarp \ No newline at end of file diff --git a/llarp/transit_hop.cpp b/llarp/transit_hop.cpp index 9afc470e5..8f20c7251 100644 --- a/llarp/transit_hop.cpp +++ b/llarp/transit_hop.cpp @@ -136,12 +136,5 @@ namespace llarp return false; } - bool - TransitHop::HandleHiddenServiceData(llarp_buffer_t buf, llarp_router* r) - { - llarp::LogWarn("unwarrented hidden service data on ", info); - return false; - } - } // namespace path } // namespace llarp