From 8878e5c4d126e1f8a14b76180dc56f0db8faaabd Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 28 Sep 2018 08:22:50 -0400 Subject: [PATCH] redundancy with outbound contexts have multiple outbound contexts and send on the one that is alive --- include/llarp/service/endpoint.hpp | 10 ++++-- llarp/service/endpoint.cpp | 58 ++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/include/llarp/service/endpoint.hpp b/include/llarp/service/endpoint.hpp index c47083070..ae6eaa98f 100644 --- a/include/llarp/service/endpoint.hpp +++ b/include/llarp/service/endpoint.hpp @@ -29,6 +29,8 @@ namespace llarp static const llarp_time_t INTROSET_PUBLISH_RETRY_INTERVAL = 5000; + static const size_t MAX_OUTBOUND_CONTEXT_COUNT = 4; + Endpoint(const std::string& nickname, llarp_router* r); ~Endpoint(); @@ -243,6 +245,10 @@ namespace llarp bool MarkCurrentIntroBad(llarp_time_t now); + /// return true if we are ready to send + bool + ReadyToSend() const; + bool ShouldBuildMore() const; @@ -405,8 +411,8 @@ namespace llarp std::unordered_map< Address, PendingBufferQueue, Address::Hash > m_PendingTraffic; - std::unordered_map< Address, std::unique_ptr< OutboundContext >, - Address::Hash > + std::unordered_multimap< Address, std::unique_ptr< OutboundContext >, + Address::Hash > m_RemoteSessions; std::unordered_multimap< Address, std::unique_ptr< OutboundContext >, diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index c574c29f9..dc7fb1217 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -643,22 +643,32 @@ namespace llarp Address addr; introset.A.CalculateAddress(addr.data()); - // only add new session if it's not there - if(m_RemoteSessions.find(addr) == m_RemoteSessions.end()) + if(m_RemoteSessions.count(addr) >= MAX_OUTBOUND_CONTEXT_COUNT) { - OutboundContext* ctx = new OutboundContext(introset, this); - m_RemoteSessions.insert( - std::make_pair(addr, std::unique_ptr< OutboundContext >(ctx))); - llarp::LogInfo("Created New outbound context for ", addr.ToString()); + auto itr = m_RemoteSessions.find(addr); + + auto i = m_PendingServiceLookups.find(addr); + if(i != m_PendingServiceLookups.end()) + { + auto f = i->second; + m_PendingServiceLookups.erase(i); + f(addr, itr->second.get()); + } + return; } + OutboundContext* ctx = new OutboundContext(introset, this); + m_RemoteSessions.insert( + std::make_pair(addr, std::unique_ptr< OutboundContext >(ctx))); + llarp::LogInfo("Created New outbound context for ", addr.ToString()); + // inform pending auto itr = m_PendingServiceLookups.find(addr); if(itr != m_PendingServiceLookups.end()) { auto f = itr->second; m_PendingServiceLookups.erase(itr); - f(itr->first, m_RemoteSessions.at(addr).get()); + f(addr, ctx); } } @@ -917,10 +927,17 @@ namespace llarp return true; } + bool + Endpoint::OutboundContext::ReadyToSend() const + { + return GetPathByRouter(remoteIntro.router) != nullptr; + } + bool Endpoint::SendToOrQueue(const Address& remote, llarp_buffer_t data, ProtocolType t) { + // inbound converstation { auto itr = m_AddressToService.find(remote); if(itr != m_AddressToService.end()) @@ -974,20 +991,31 @@ namespace llarp llarp::LogError("failed to encrypt and sign"); return false; } - llarp::LogDebug(Name(), " send ", data.sz, " via ", remoteIntro); + llarp::LogDebug(Name(), " send ", data.sz, " via ", + remoteIntro.router); return p->SendRoutingMessage(&transfer, Router()); } } } + // outbound converstation if(HasPathToService(remote)) { - llarp::LogDebug(Name(), " has session to ", remote, " sending ", - data.sz, " bytes"); - auto itr = m_RemoteSessions.find(remote); - itr->second->AsyncEncryptAndSendTo(data, t); - return true; + auto range = m_RemoteSessions.equal_range(remote); + auto itr = range.first; + while(itr != range.second) + { + if(itr->second->ReadyToSend()) + { + itr->second->AsyncEncryptAndSendTo(data, t); + return true; + } + ++itr; + } + // all paths are not ready? + return false; } + // no converstation auto itr = m_PendingTraffic.find(remote); if(itr == m_PendingTraffic.end()) { @@ -1227,8 +1255,8 @@ namespace llarp routing::PathTransferMessage transfer(msg, remoteIntro.pathID); if(path->SendRoutingMessage(&transfer, m_Endpoint->Router())) { - llarp::LogInfo("sent data to ", remoteIntro.pathID, " on ", - remoteIntro.router); + llarp::LogDebug("sent data to ", remoteIntro.pathID, " on ", + remoteIntro.router); lastGoodSend = now; } else