From eceb55623c7c3976a8f9ea0083f32fd8f4783d94 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 7 Mar 2019 10:17:29 -0500 Subject: [PATCH 1/2] more --- llarp/exit/session.cpp | 32 +++-- llarp/exit/session.hpp | 9 ++ llarp/handlers/tun.cpp | 6 - llarp/link/iwp.cpp | 227 ++++++++++++++++++++++++++++++------ llarp/link/iwp_internal.hpp | 46 +++++--- llarp/link/server.cpp | 21 +++- llarp/link/server.hpp | 2 +- llarp/profiling.cpp | 8 +- llarp/service/endpoint.cpp | 12 +- llarp/util/buffer.cpp | 20 ++++ llarp/util/buffer.hpp | 25 ++++ 11 files changed, 329 insertions(+), 79 deletions(-) diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 8506c8562..100e8a1e7 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -110,25 +110,34 @@ namespace llarp bool BaseSession::HandleGotExit(llarp::path::Path* p, llarp_time_t b) { - BaseSession* self = this; - m_LastUse = router->Now(); + m_LastUse = router->Now(); if(b == 0) llarp::LogInfo("obtained an exit via ", p->Endpoint()); - else - self = nullptr; + if(IsReady()) + CallPendingCallbacks(true); + return true; + } - for(auto& f : m_PendingCallbacks) - f(self); + void + BaseSession::CallPendingCallbacks(bool success) + { + if(success) + { + for(auto& f : m_PendingCallbacks) + f(this); + } + else + { + for(auto& f : m_PendingCallbacks) + f(nullptr); + } m_PendingCallbacks.clear(); - return true; } bool BaseSession::Stop() { - for(auto& f : m_PendingCallbacks) - f(nullptr); - m_PendingCallbacks.clear(); + CallPendingCallbacks(false); auto sendExitClose = [&](llarp::path::Path* p) { if(p->SupportsAnyRoles(llarp::path::ePathRoleExit)) { @@ -199,7 +208,8 @@ namespace llarp bool BaseSession::IsReady() const { - return AvailablePaths(llarp::path::ePathRoleExit) > 0; + const size_t expect = (1 + (m_NumPaths / 2)); + return AvailablePaths(llarp::path::ePathRoleExit) >= expect; } bool diff --git a/llarp/exit/session.hpp b/llarp/exit/session.hpp index edf903b17..34adcb437 100644 --- a/llarp/exit/session.hpp +++ b/llarp/exit/session.hpp @@ -49,6 +49,12 @@ namespace llarp bool Flush(); + path::PathRole + GetRoles() const override + { + return path::ePathRoleExit; + } + /// send close and stop session bool Stop() override; @@ -116,6 +122,9 @@ namespace llarp llarp_time_t m_LastUse; std::vector< SessionReadyFunc > m_PendingCallbacks; + + void + CallPendingCallbacks(bool success); }; struct ExitSession final : public BaseSession diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 556466577..dfef74284 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -343,12 +343,6 @@ namespace llarp } else if(addr.FromString(qname, ".snode")) { - if(HasPathToSNode(addr.as_array())) - { - msg.AddINReply(ObtainIPForAddr(addr, true)); - reply(msg); - return true; - } dns::Message *replyMsg = new dns::Message(std::move(msg)); EnsurePathToSNode(addr.as_array(), [=](const RouterID &remote, exit::BaseSession *s) { diff --git a/llarp/link/iwp.cpp b/llarp/link/iwp.cpp index 72cf038e7..ac2383a80 100644 --- a/llarp/link/iwp.cpp +++ b/llarp/link/iwp.cpp @@ -6,62 +6,149 @@ namespace llarp { namespace iwp { + std::array< byte_t, 6 > OuterMessage::obtain_flow_id_magic = + std::array< byte_t, 6 >{'n', 'e', 't', 'i', 'd', '?'}; + + std::array< byte_t, 6 > OuterMessage::give_flow_id_magic = + std::array< byte_t, 6 >{'n', 'e', 't', 'i', 'd', '!'}; + + OuterMessage::OuterMessage() + { + Clear(); + } + + OuterMessage::~OuterMessage() + { + } + void OuterMessage::Clear() { command = 0; flow.Zero(); netid.Zero(); - nextFlowID.Zero(); - rejectReason.clear(); + reject.fill(0); N.Zero(); X.Zero(); Xsize = 0; - Z.Zero(); + Zsig.Zero(); + Zhash.Zero(); + pubkey.Zero(); + magic.fill(0); + uinteger = 0; + A.reset(); + } + + void + OuterMessage::CreateReject(const char* msg, llarp_time_t now, + const PubKey& pk) + { + Clear(); + std::copy_n(msg, std::min(strlen(msg), reject.size()), reject.begin()); + uinteger = now; + pubkey = pk; + } + + bool + OuterMessage::Encode(llarp_buffer_t* buf) const + { + if(buf->size_left() < 2) + return false; + *buf->cur = command; + buf->cur++; + *buf->cur = '='; + buf->cur++; + switch(command) + { + case eOCMD_ObtainFlowID: + + case eOCMD_GiveFlowID: + if(!buf->write(reject.begin(), reject.end())) + return false; + if(!buf->write(give_flow_id_magic.begin(), give_flow_id_magic.end())) + return false; + if(!buf->write(flow.begin(), flow.end())) + return false; + if(!buf->write(pubkey.begin(), pubkey.end())) + return false; + return buf->write(Zsig.begin(), Zsig.end()); + default: + return false; + } } bool OuterMessage::Decode(llarp_buffer_t* buf) { - if(buf->size_left() < 34) + static constexpr size_t header_size = 2; + + if(buf->size_left() < header_size) return false; command = *buf->cur; ++buf->cur; if(*buf->cur != '=') return false; - std::copy_n(flow.begin(), 32, buf->cur); - buf->cur += 32; + ++buf->cur; switch(command) { case eOCMD_ObtainFlowID: - if(buf->size_left() < 40) + if(!buf->read_into(magic.begin(), magic.end())) + return false; + if(!buf->read_into(netid.begin(), netid.end())) + return false; + if(!buf->read_uint64(uinteger)) + return false; + if(!buf->read_into(pubkey.begin(), pubkey.end())) + return false; + if(buf->size_left() <= Zsig.size()) return false; - buf->cur += 32; - std::copy_n(netid.begin(), 8, buf->cur); - return true; + Xsize = buf->size_left() - Zsig.size(); + if(!buf->read_into(X.begin(), X.begin() + Xsize)) + return false; + return buf->read_into(Zsig.begin(), Zsig.end()); case eOCMD_GiveFlowID: - if(buf->size_left() < 32) + if(!buf->read_into(magic.begin(), magic.end())) + return false; + if(!buf->read_into(flow.begin(), flow.end())) + return false; + if(!buf->read_into(pubkey.begin(), pubkey.end())) return false; - std::copy_n(nextFlowID.begin(), 32, buf->cur); - return true; + buf->cur += buf->size_left() - Zsig.size(); + return buf->read_into(Zsig.begin(), Zsig.end()); case eOCMD_Reject: - rejectReason = std::string(buf->cur, buf->base + buf->sz); - return true; + if(!buf->read_into(reject.begin(), reject.end())) + return false; + if(!buf->read_uint64(uinteger)) + return false; + if(!buf->read_into(pubkey.begin(), pubkey.end())) + return false; + buf->cur += buf->size_left() - Zsig.size(); + return buf->read_into(Zsig.begin(), Zsig.end()); case eOCMD_SessionNegotiate: - // explicit fallthrough + if(!buf->read_into(flow.begin(), flow.end())) + return false; + if(!buf->read_into(pubkey.begin(), pubkey.end())) + return false; + if(!buf->read_uint64(uinteger)) + return false; + if(buf->size_left() == Zsig.size() + 32) + { + A.reset(new AlignedBuffer< 32 >()); + if(!buf->read_into(A->begin(), A->end())) + return false; + } + return buf->read_into(Zsig.begin(), Zsig.end()); case eOCMD_TransmitData: - if(buf->size_left() <= 56) + if(!buf->read_into(flow.begin(), flow.end())) return false; - std::copy_n(N.begin(), N.size(), buf->cur); - buf->cur += N.size(); - Xsize = buf->size_left() - Z.size(); - if(Xsize > X.size()) + if(!buf->read_into(N.begin(), N.end())) return false; - std::copy_n(X.begin(), Xsize, buf->cur); - buf->cur += Xsize; - std::copy_n(Z.begin(), Z.size(), buf->cur); - return true; - + if(buf->size_left() <= Zhash.size()) + return false; + Xsize = buf->size_left() - Zhash.size(); + if(!buf->read_into(X.begin(), X.begin() + Xsize)) + return false; + return buf->read_into(Zhash.begin(), Zhash.end()); default: return false; } @@ -73,6 +160,7 @@ namespace llarp TimeoutHandler t, SessionClosedHandler closed) : ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed), crypto(c) { + m_FlowCookie.Randomize(); } LinkLayer::~LinkLayer() @@ -118,8 +206,9 @@ namespace llarp LinkLayer::RecvFrom(const Addr& from, const void* pkt, size_t sz) { m_OuterMsg.Clear(); - llarp_buffer_t buf(pkt, sz); - if(!m_OuterMsg.Decode(&buf)) + llarp_buffer_t sigbuf(pkt, sz); + llarp_buffer_t decodebuf(pkt, sz); + if(!m_OuterMsg.Decode(&decodebuf)) { LogError("failed to decode outer message"); return; @@ -128,13 +217,27 @@ namespace llarp switch(m_OuterMsg.command) { case eOCMD_ObtainFlowID: + sigbuf.sz -= m_OuterMsg.Zsig.size(); + if(!crypto->verify(m_OuterMsg.pubkey, sigbuf, m_OuterMsg.Zsig)) + { + LogError("failed to verify signature on '", + (char)m_OuterMsg.command, "' message from ", from); + return; + } if(!ShouldSendFlowID(from)) - return; // drop - + { + SendReject(from, "no flo 4u :^)"); + return; + } if(m_OuterMsg.netid == ourNetID) - SendFlowID(from, m_OuterMsg.flow); + { + if(GenFlowIDFor(m_OuterMsg.pubkey, from, m_OuterMsg.flow)) + SendFlowID(from, m_OuterMsg.flow); + else + SendReject(from, "genflow fail"); + } else - SendReject(from, m_OuterMsg.flow, "bad net id"); + SendReject(from, "bad netid"); } } @@ -156,6 +259,35 @@ namespace llarp (void)flow; } + bool + LinkLayer::VerifyFlowID(const PubKey& pk, const Addr& from, + const FlowID_t& flow) const + { + FlowID_t expected; + if(!GenFlowIDFor(pk, from, expected)) + return false; + return expected == flow; + } + + bool + LinkLayer::GenFlowIDFor(const PubKey& pk, const Addr& from, + FlowID_t& flow) const + { + std::array< byte_t, 128 > tmp = {0}; + if(inet_ntop(AF_INET6, from.addr6(), (char*)tmp.data(), tmp.size()) + == nullptr) + return false; + std::copy_n(pk.begin(), pk.size(), tmp.begin() + 64); + std::copy_n(m_FlowCookie.begin(), m_FlowCookie.size(), + tmp.begin() + 64 + pk.size()); + llarp_buffer_t buf(tmp); + ShortHash h; + if(!crypto->shorthash(h, buf)) + return false; + std::copy_n(h.begin(), flow.size(), flow.begin()); + return true; + } + bool LinkLayer::ShouldSendFlowID(const Addr& to) const { @@ -165,12 +297,33 @@ namespace llarp } void - LinkLayer::SendReject(const Addr& to, const FlowID_t& flow, const char* msg) + LinkLayer::SendReject(const Addr& to, const char* msg) { - // TODO: implement me - (void)to; - (void)flow; - (void)msg; + if(strlen(msg) > 14) + { + throw std::logic_error("reject message too big"); + } + std::array< byte_t, 120 > pkt; + auto now = Now(); + PubKey pk = GetOurRC().pubkey; + OuterMessage m; + m.CreateReject(msg, now, pk); + llarp_buffer_t encodebuf(pkt); + if(!m.Encode(&encodebuf)) + { + LogError("failed to encode reject message to ", to); + return; + } + llarp_buffer_t signbuf(pkt.data(), pkt.size() - m.Zsig.size()); + if(!Sign(m.Zsig, signbuf)) + { + LogError("failed to sign reject messsage to ", to); + return; + } + std::copy_n(m.Zsig.begin(), m.Zsig.size(), + pkt.begin() + (pkt.size() - m.Zsig.size())); + llarp_buffer_t pktbuf(pkt); + SendTo_LL(to, pktbuf); } std::unique_ptr< ILinkLayer > diff --git a/llarp/link/iwp_internal.hpp b/llarp/link/iwp_internal.hpp index 46ffcf988..acaf83261 100644 --- a/llarp/link/iwp_internal.hpp +++ b/llarp/link/iwp_internal.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -46,15 +47,35 @@ namespace llarp byte_t command; FlowID_t flow; + OuterMessage(); + ~OuterMessage(); + + // static members + static std::array< byte_t, 6 > obtain_flow_id_magic; + static std::array< byte_t, 6 > give_flow_id_magic; + + void + CreateReject(const char *msg, llarp_time_t now, const PubKey &pk); + // optional memebers follow + std::array< byte_t, 6 > magic; NetID netid; - FlowID_t nextFlowID; - std::string rejectReason; + // either timestamp or counter + uint64_t uinteger; + std::array< byte_t, 14 > reject; AlignedBuffer< 24 > N; - // TODO: compute optimal size - AlignedBuffer< 1440 > X; + PubKey pubkey; + + std::unique_ptr< AlignedBuffer< 32 > > A; + + static constexpr size_t ipv6_mtu = 1280; + static constexpr size_t overhead_size = 16 + 24 + 32; + static constexpr size_t payload_size = ipv6_mtu - overhead_size; + + AlignedBuffer< payload_size > X; size_t Xsize; - ShortHash Z; + ShortHash Zhash; + Signature Zsig; /// encode to buffer bool @@ -64,10 +85,6 @@ namespace llarp bool Decode(llarp_buffer_t *buf); - /// verify signature if needed - bool - Verify(const SharedSecret &K) const; - /// clear members void Clear(); @@ -264,20 +281,23 @@ namespace llarp uint16_t Rank() const override; - /// verify that a new flow id matches addresses and old flow id + /// verify that a new flow id matches addresses and pubkey bool - VerifyFlowID(const FlowID_t &newID, const Addr &from, - const FlowID_t &oldID) const; + VerifyFlowID(const PubKey &pk, const Addr &from, + const FlowID_t &flow) const; void RecvFrom(const llarp::Addr &from, const void *buf, size_t sz) override; private: + bool + GenFlowIDFor(const PubKey &pk, const Addr &from, FlowID_t &flow) const; + bool ShouldSendFlowID(const Addr &from) const; void - SendReject(const Addr &to, const FlowID_t &flow, const char *msg); + SendReject(const Addr &to, const char *msg); void SendFlowID(const Addr &to, const FlowID_t &flow); diff --git a/llarp/link/server.cpp b/llarp/link/server.cpp index e4ee6c449..7fdb84e4e 100644 --- a/llarp/link/server.cpp +++ b/llarp/link/server.cpp @@ -223,12 +223,23 @@ namespace llarp void ILinkLayer::Tick(llarp_time_t now) { - Lock l(m_AuthedLinksMutex); - auto itr = m_AuthedLinks.begin(); - while(itr != m_AuthedLinks.end()) { - itr->second->Tick(now); - ++itr; + Lock l(m_AuthedLinksMutex); + auto itr = m_AuthedLinks.begin(); + while(itr != m_AuthedLinks.end()) + { + itr->second->Tick(now); + ++itr; + } + } + { + Lock l(m_PendingMutex); + auto itr = m_Pending.begin(); + while(itr != m_Pending.end()) + { + itr->second->Tick(now); + ++itr; + } } } diff --git a/llarp/link/server.hpp b/llarp/link/server.hpp index 97a460f5e..67f9d5b1d 100644 --- a/llarp/link/server.hpp +++ b/llarp/link/server.hpp @@ -93,7 +93,7 @@ namespace llarp } void - SendTo_LL(const llarp::Addr& to, llarp_buffer_t pkt) + SendTo_LL(const llarp::Addr& to, const llarp_buffer_t& pkt) { llarp_ev_udp_sendto(&m_udp, to, pkt); } diff --git a/llarp/profiling.cpp b/llarp/profiling.cpp index 1a0d2c9ff..ea11b678c 100644 --- a/llarp/profiling.cpp +++ b/llarp/profiling.cpp @@ -70,9 +70,11 @@ namespace llarp bool RouterProfile::IsGood(uint64_t chances) const { - return connectTimeoutCount <= connectGoodCount - /// N chances - && (pathSuccessCount * chances) >= pathFailCount; + if(connectTimeoutCount > 3) + return connectTimeoutCount <= connectGoodCount + && (pathSuccessCount * chances) >= pathFailCount; + else + return (pathSuccessCount * chances) >= pathFailCount; } bool diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 08ed36b3b..cdc81a79e 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1223,7 +1223,10 @@ namespace llarp auto itr = range.first; while(itr != range.second) { - itr->second->AddReadyHook(std::bind(h, snode, std::placeholders::_1)); + if(itr->second->IsReady()) + h(snode, itr->second.get()); + else + itr->second->AddReadyHook(std::bind(h, snode, std::placeholders::_1)); ++itr; } } @@ -1749,7 +1752,7 @@ namespace llarp { // we can safely set remoteIntro to the next one SwapIntros(); - llarp::LogInfo(Name(), "swapped intro"); + llarp::LogInfo(Name(), " swapped intro"); } } // lookup router in intro if set and unknown @@ -1767,6 +1770,10 @@ namespace llarp // send control message if we look too quiet if(now - lastGoodSend > (sendTimeout / 2)) { + if(!GetNewestPathByRouter(remoteIntro.router)) + { + BuildOneAlignedTo(remoteIntro.router); + } Encrypted< 64 > tmp; tmp.Randomize(); llarp_buffer_t buf(tmp.data(), tmp.size()); @@ -1864,7 +1871,6 @@ namespace llarp { llarp::LogError("cannot encrypt and send: no path for intro ", remoteIntro); - return; } diff --git a/llarp/util/buffer.cpp b/llarp/util/buffer.cpp index 4518d9783..e82476495 100644 --- a/llarp/util/buffer.cpp +++ b/llarp/util/buffer.cpp @@ -43,6 +43,16 @@ llarp_buffer_t::put_uint16(uint16_t i) return true; } +bool +llarp_buffer_t::put_uint64(uint64_t i) +{ + if(size_left() < sizeof(uint64_t)) + return false; + htobe64buf(cur, i); + cur += sizeof(uint64_t); + return true; +} + bool llarp_buffer_t::put_uint32(uint32_t i) { @@ -73,6 +83,16 @@ llarp_buffer_t::read_uint32(uint32_t& i) return true; } +bool +llarp_buffer_t::read_uint64(uint64_t& i) +{ + if(size_left() < sizeof(uint64_t)) + return false; + i = bufbe64toh(cur); + cur += sizeof(uint64_t); + return true; +} + size_t llarp_buffer_t::read_until(char delim, byte_t* result, size_t resultsize) { diff --git a/llarp/util/buffer.hpp b/llarp/util/buffer.hpp index 3184084fc..407b9755c 100644 --- a/llarp/util/buffer.hpp +++ b/llarp/util/buffer.hpp @@ -12,6 +12,7 @@ #include #include #include +#include /** * buffer.h @@ -116,6 +117,10 @@ struct llarp_buffer_t size_t size_left() const; + template < typename OutputIt > + bool + read_into(OutputIt begin, OutputIt end); + template < typename InputIt > bool write(InputIt begin, InputIt end); @@ -136,11 +141,17 @@ struct llarp_buffer_t bool put_uint32(uint32_t i); + bool + put_uint64(uint64_t i); + bool read_uint16(uint16_t &i); bool read_uint32(uint32_t &i); + bool + read_uint64(uint64_t &i); + size_t read_until(char delim, byte_t *result, size_t resultlen); @@ -153,6 +164,20 @@ struct llarp_buffer_t bool operator==(const llarp_buffer_t &buff, const char *data); +template < typename OutputIt > +bool +llarp_buffer_t::read_into(OutputIt begin, OutputIt end) +{ + auto dist = std::distance(begin, end); + if(static_cast< decltype(dist) >(size_left()) >= dist) + { + std::copy_n(cur, dist, begin); + cur += dist; + return true; + } + return false; +} + template < typename InputIt > bool llarp_buffer_t::write(InputIt begin, InputIt end) From 6a09348c47e4fa444b65138935f729ed0d4f4aee Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 7 Mar 2019 17:53:36 -0500 Subject: [PATCH 2/2] today's work --- CMakeLists.txt | 5 +- Makefile | 8 ++-- contrib/shadow/genconf.py | 17 ++++--- llarp/ev/ev_kqueue.cpp | 6 +-- llarp/link/utp.cpp | 40 ++++++++-------- llarp/link/utp_internal.hpp | 7 ++- llarp/path/path.cpp | 2 +- llarp/path/pathbuilder.cpp | 4 +- llarp/path/pathbuilder.hpp | 7 +++ llarp/routing/message_parser.cpp | 1 + llarp/service/endpoint.cpp | 80 ++++++++++++++++---------------- llarp/util/logger.hpp | 5 +- 12 files changed, 98 insertions(+), 84 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 42fe13226..698c71b36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,8 +342,9 @@ add_log_tag(${ABYSS_EXE}) add_log_tag(${ABYSS_LIB}) if(SHADOW) - add_shadow_plugin(shadow-plugin-${SHARED_LIB} ${EXE_SRC} ${LIB_SRC} ${UTP_SRC} ${LIB_PLATFORM_SRC} ${CPP_BACKPORT_SRC} ${ABYSS_SRC} ${CRYPTOGRAPHY_SRC}) - target_link_libraries(shadow-plugin-${SHARED_LIB} ${LIBS}) + add_shadow_plugin(shadow-plugin-${SHARED_LIB} ${EXE_SRC}) + target_include_directories(shadow-plugin-${SHARED_LIB} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/llarp ${PROJECT_SOURCE_DIR}/crypto/include ${PROJECT_SOURCE_DIR}/vendor/cppbackport-master/lib) + target_link_libraries(shadow-plugin-${SHARED_LIB} ${STATIC_LIB} ${LIBS}) install(TARGETS shadow-plugin-${SHARED_LIB} DESTINATION plugins) else() if(NOT WIN32) diff --git a/Makefile b/Makefile index 01519a10a..2d752643f 100644 --- a/Makefile +++ b/Makefile @@ -16,12 +16,12 @@ SETCAP ?= which setcap && setcap cap_net_admin,cap_net_bind_service=+eip SHADOW_ROOT ?= $(HOME)/.shadow SHADOW_BIN=$(SHADOW_ROOT)/bin/shadow SHADOW_CONFIG=$(REPO)/shadow.config.xml -SHADOW_PLUGIN=$(REPO)/libshadow-plugin-llarp.so +SHADOW_PLUGIN=$(BUILD_ROOT)/libshadow-plugin-lokinet-shared.so SHADOW_LOG=$(REPO)/shadow.log.txt SHADOW_SRC ?= $(HOME)/local/shadow -SHADOW_PARSE ?= python $(SHADOW_SRC)/src/tools/parse-shadow.py - -m 0 --packet-data -SHADOW_PLOT ?= python $(SHADOW_SRC)/src/tools/plot-shadow.py -d $(REPO) LokiNET -c $(SHADOW_CONFIG) -r 10000 -e '.*' +SHADOW_PARSE ?= $(PYTHON) $(SHADOW_SRC)/src/tools/parse-shadow.py - -m 0 --packet-data +SHADOW_PLOT ?= $(PYTHON) $(SHADOW_SRC)/src/tools/plot-shadow.py -d $(REPO) LokiNET -c $(SHADOW_CONFIG) -r 10000 -e '.*' TESTNET_ROOT=/tmp/lokinet_testnet_tmp TESTNET_CONF=$(TESTNET_ROOT)/supervisor.conf @@ -135,11 +135,11 @@ shadow-configure: clean $(CONFIG_CMD) -DCMAKE_BUILD_TYPE=Debug -DSHADOW=ON -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) shadow-build: shadow-configure - $(MAKE) -C $(BUILD_ROOT) clean $(MAKE) -C $(BUILD_ROOT) shadow-run: shadow-build $(PYTHON) $(REPO)/contrib/shadow/genconf.py $(SHADOW_CONFIG) + cp $(SHADOW_PLUGIN) $(REPO) bash -c "$(SHADOW_BIN) -w $$(cat /proc/cpuinfo | grep processor | wc -l) $(SHADOW_CONFIG) | $(SHADOW_PARSE)" shadow-plot: shadow-run diff --git a/contrib/shadow/genconf.py b/contrib/shadow/genconf.py index 9629a657b..1f227860e 100644 --- a/contrib/shadow/genconf.py +++ b/contrib/shadow/genconf.py @@ -13,7 +13,7 @@ def getSetting(s, name, fallback): return name in s and s[name] or fallback shadowRoot = getSetting(os.environ, "SHADOW_ROOT", os.path.join(os.environ['HOME'], '.shadow')) -libpath = 'libshadow-plugin-lokinet.so' +libpath = 'libshadow-plugin-lokinet-shared.so' def nodeconf(conf, baseDir, name, ifname=None, port=None): @@ -59,11 +59,11 @@ def makeClient(settings, name, id): basedir = getSetting(settings, 'baseDir', 'tmp') nodeconf(peer['config'], basedir, name) fname = os.path.join(basedir, "test-service.ini") - peer['config']['services'] = { - 'test-service': fname + peer['config']['network'] = { + 'type': 'null', + 'tag':'test', + 'prefetch-tag':'test' } - with open(fname, 'w') as f: - f.write("[test-service]") return peer @@ -71,6 +71,9 @@ def makeSVCNode(settings, name, id, port): peer = makeBase(settings, name, id) nodeconf(peer['config'], getSetting( settings, 'baseDir', 'tmp'), name, 'eth0', port) + peer['config']['network'] = { + 'type': 'null' + } return peer @@ -81,7 +84,7 @@ def genconf(settings, outf): topology.attrib['path'] = getSetting(settings, 'topology', os.path.join( shadowRoot, 'share', 'topology.graphml.xml')) - pluginName = getSetting(settings, 'name', 'llarpd') + pluginName = getSetting(settings, 'name', 'lokinet-shared') kill = etree.SubElement(root, 'kill') kill.attrib['time'] = getSetting(settings, 'runFor', '600') @@ -96,7 +99,7 @@ def genconf(settings, outf): plugin.attrib['id'] = pluginName plugin.attrib['path'] = libpath basePort = getSetting(settings, 'svc-base-port', 19000) - svcNodeCount = getSetting(settings, 'service-nodes', 20) + svcNodeCount = getSetting(settings, 'service-nodes', 80) peers = list() for nodeid in range(svcNodeCount): peers.append(makeSVCNode( diff --git a/llarp/ev/ev_kqueue.cpp b/llarp/ev/ev_kqueue.cpp index e3ff995ca..c95c3c3bc 100644 --- a/llarp/ev/ev_kqueue.cpp +++ b/llarp/ev/ev_kqueue.cpp @@ -374,11 +374,7 @@ llarp_kqueue_loop::tick(int ms) llarp::ev_io* ev = static_cast< llarp::ev_io* >(events[idx].udata); if(ev) { - if(events[idx].filter & EV_ERROR) - { - ev->error(); - } - else if(events[idx.filter] & EV_EOF == 0) + if(events[idx.filter] & EV_EOF == 0) { if(events[idx].filter & EVFILT_WRITE) { diff --git a/llarp/link/utp.cpp b/llarp/link/utp.cpp index 40474ee64..e1fae145d 100644 --- a/llarp/link/utp.cpp +++ b/llarp/link/utp.cpp @@ -236,7 +236,7 @@ namespace llarp auto dlt = now - lastActive; if(dlt >= sessionTimeout) { - LogDebug("session timeout reached for ", remoteAddr); + LogInfo("session timeout reached for ", remoteAddr); return true; } return false; @@ -254,6 +254,17 @@ namespace llarp return remoteAddr; } + uint64 + LinkLayer::OnConnect(utp_callback_arguments* arg) + { + LinkLayer* l = + static_cast< LinkLayer* >(utp_context_get_userdata(arg->context)); + Session* session = static_cast< Session* >(utp_get_userdata(arg->socket)); + if(session && l) + session->OutboundLinkEstablished(l); + return 0; + } + uint64 LinkLayer::SendTo(utp_callback_arguments* arg) { @@ -374,6 +385,7 @@ namespace llarp utp_context_set_userdata(_utp_ctx, this); utp_set_callback(_utp_ctx, UTP_SENDTO, &LinkLayer::SendTo); utp_set_callback(_utp_ctx, UTP_ON_ACCEPT, &LinkLayer::OnAccept); + utp_set_callback(_utp_ctx, UTP_ON_CONNECT, &LinkLayer::OnConnect); utp_set_callback(_utp_ctx, UTP_ON_STATE_CHANGE, &LinkLayer::OnStateChange); utp_set_callback(_utp_ctx, UTP_ON_READ, &LinkLayer::OnRead); @@ -404,9 +416,11 @@ namespace llarp } #ifdef __linux__ + void LinkLayer::ProcessICMP() { +#ifndef TESTNET do { byte_t vec_buf[4096], ancillary_buf[4096]; @@ -475,13 +489,13 @@ namespace llarp } } } while(true); +#endif } #endif void LinkLayer::Pump() { - utp_issue_deferred_acks(_utp_ctx); #ifdef __linux__ ProcessICMP(); #endif @@ -507,6 +521,7 @@ namespace llarp } } } + utp_issue_deferred_acks(_utp_ctx); } void @@ -577,9 +592,7 @@ namespace llarp SendQueueBacklog = [&]() -> size_t { return sendq.size(); }; SendKeepAlive = [&]() -> bool { - auto now = parent->Now(); - if(sendq.size() == 0 && state == eSessionReady && now > lastActive - && now - lastActive > 5000) + if(state == eSessionReady) { DiscardMessage msg; std::array< byte_t, 128 > tmp; @@ -590,6 +603,7 @@ namespace llarp buf.cur = buf.base; if(!this->QueueWriteBuffers(buf)) return false; + PumpWrite(); } return true; }; @@ -840,6 +854,7 @@ namespace llarp if(sock) { utp_set_userdata(sock, nullptr); + sock = nullptr; } } @@ -872,7 +887,6 @@ namespace llarp else { LogWarn("utp_socket got data with no underlying session"); - utp_shutdown(arg->socket, SHUT_RDWR); utp_close(arg->socket); } return 0; @@ -881,20 +895,10 @@ namespace llarp uint64 LinkLayer::OnStateChange(utp_callback_arguments* arg) { - LinkLayer* l = - static_cast< LinkLayer* >(utp_context_get_userdata(arg->context)); Session* session = static_cast< Session* >(utp_get_userdata(arg->socket)); if(session) { - if(arg->state == UTP_STATE_CONNECT) - { - if(session->state == Session::eClose) - { - return 0; - } - session->OutboundLinkEstablished(l); - } - else if(arg->state == UTP_STATE_WRITABLE) + if(arg->state == UTP_STATE_WRITABLE) { session->PumpWrite(); } @@ -1155,11 +1159,9 @@ namespace llarp utp_close(sock); } LogDebug("utp_close ", remoteAddr); - utp_set_userdata(sock, nullptr); } } EnterState(eClose); - sock = nullptr; } void diff --git a/llarp/link/utp_internal.hpp b/llarp/link/utp_internal.hpp index ad4ea0436..9662d74ee 100644 --- a/llarp/link/utp_internal.hpp +++ b/llarp/link/utp_internal.hpp @@ -109,8 +109,8 @@ namespace llarp SharedSecret txKey; /// timestamp last active llarp_time_t lastActive; - /// session timeout (30s) - const static llarp_time_t sessionTimeout = 30 * 1000; + /// session timeout (60s) + const static llarp_time_t sessionTimeout = DefaultLinkSessionLifetime; /// send queue for utp std::deque< utp_iovec > vecq; @@ -298,6 +298,9 @@ namespace llarp static uint64 OnStateChange(utp_callback_arguments*); + static uint64 + OnConnect(utp_callback_arguments*); + /// accept callback static uint64 OnAccept(utp_callback_arguments*); diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 229f0d76e..d8fce7b8a 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -764,7 +764,7 @@ namespace llarp if(m_BuiltHook) m_BuiltHook(this); m_BuiltHook = nullptr; - + LogDebug("path latency is now ", intro.latency, " for ", Name()); return true; } else diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index 562b04ef7..5b2289f79 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -256,7 +256,9 @@ namespace llarp bool Builder::ShouldBuildMore(llarp_time_t now) const { - return PathSet::ShouldBuildMore(now) && !BuildCooldownHit(now); + if(llarp::randint() % 3 >= 1) + return PathSet::ShouldBuildMore(now) && !BuildCooldownHit(now); + return false; } void diff --git a/llarp/path/pathbuilder.hpp b/llarp/path/pathbuilder.hpp index 8e400a3d6..90827849a 100644 --- a/llarp/path/pathbuilder.hpp +++ b/llarp/path/pathbuilder.hpp @@ -52,6 +52,13 @@ namespace llarp bool BuildCooldownHit(llarp_time_t now) const; + /// get roles for this path builder + virtual PathRole + GetRoles() const + { + return ePathRoleAny; + } + virtual bool Stop() override; diff --git a/llarp/routing/message_parser.cpp b/llarp/routing/message_parser.cpp index ca56192ff..4619d5703 100644 --- a/llarp/routing/message_parser.cpp +++ b/llarp/routing/message_parser.cpp @@ -67,6 +67,7 @@ namespace llarp if(strbuf.sz != 1) return false; self->key = *strbuf.cur; + LogDebug("routing message '", self->key, "'"); switch(self->key) { case 'D': diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index cdc81a79e..60c6688f8 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -21,7 +21,7 @@ namespace llarp { Endpoint::Endpoint(const std::string& name, AbstractRouter* r, Context* parent) - : path::Builder(r, r->dht(), 6, DEFAULT_HOP_LENGTH) + : path::Builder(r, r->dht(), 3, DEFAULT_HOP_LENGTH) , context(parent) , m_Router(r) , m_Name(name) @@ -1272,53 +1272,51 @@ namespace llarp ProtocolFrame& f = transfer.T; path::Path* p = nullptr; std::set< ConvoTag > tags; - if(!GetConvoTagsForService(itr->second, tags)) + if(GetConvoTagsForService(itr->second, tags)) { - llarp::LogError("no convo tag"); - return false; - } - Introduction remoteIntro; - SharedSecret K; - // pick tag - for(const auto& tag : tags) - { - if(tag.IsZero()) - continue; - if(!GetCachedSessionKeyFor(tag, K)) - continue; - if(p == nullptr && GetIntroFor(tag, remoteIntro)) + Introduction remoteIntro; + SharedSecret K; + // pick tag + for(const auto& tag : tags) { - if(!remoteIntro.ExpiresSoon(now)) - p = GetNewestPathByRouter(remoteIntro.router); - if(p) + if(tag.IsZero()) + continue; + if(!GetCachedSessionKeyFor(tag, K)) + continue; + if(p == nullptr && GetIntroFor(tag, remoteIntro)) { - f.T = tag; - break; + if(!remoteIntro.ExpiresSoon(now)) + p = GetNewestPathByRouter(remoteIntro.router); + if(p) + { + f.T = tag; + break; + } } } - } - if(p) - { - // TODO: check expiration of our end - ProtocolMessage m(f.T); - m.proto = t; - m.introReply = p->intro; - PutReplyIntroFor(f.T, m.introReply); - m.sender = m_Identity.pub; - m.PutBuffer(data); - f.N.Randomize(); - f.S = GetSeqNoForConvo(f.T); - f.C.Zero(); - transfer.Y.Randomize(); - transfer.P = remoteIntro.pathID; - if(!f.EncryptAndSign(Router()->crypto(), m, K, m_Identity)) + if(p) { - llarp::LogError("failed to encrypt and sign"); - return false; + // TODO: check expiration of our end + ProtocolMessage m(f.T); + m.proto = t; + m.introReply = p->intro; + PutReplyIntroFor(f.T, m.introReply); + m.sender = m_Identity.pub; + m.PutBuffer(data); + f.N.Randomize(); + f.S = GetSeqNoForConvo(f.T); + f.C.Zero(); + transfer.Y.Randomize(); + transfer.P = remoteIntro.pathID; + if(!f.EncryptAndSign(Router()->crypto(), m, K, m_Identity)) + { + llarp::LogError("failed to encrypt and sign"); + return false; + } + llarp::LogDebug(Name(), " send ", data.sz, " via ", + remoteIntro.router); + return p->SendRoutingMessage(&transfer, Router()); } - llarp::LogDebug(Name(), " send ", data.sz, " via ", - remoteIntro.router); - return p->SendRoutingMessage(&transfer, Router()); } } } diff --git a/llarp/util/logger.hpp b/llarp/util/logger.hpp index 45a8a0f75..59400ac01 100644 --- a/llarp/util/logger.hpp +++ b/llarp/util/logger.hpp @@ -40,8 +40,6 @@ namespace llarp std::ostream& out; std::function< void(const std::string&) > customLog; - - llarp::util::Mutex access; #ifdef _WIN32 bool isConsoleModern = true; // qol fix so oldfag clients don't see ugly escapes @@ -240,6 +238,9 @@ namespace llarp #endif ss << (char)27 << "[0;0m"; _glog.out << ss.str() << std::endl; +#ifdef TESTNET + _glog.out << std::flush; +#endif #ifdef _WIN32 } else