diff --git a/llarp/handlers/tun.cpp b/llarp/handlers/tun.cpp index 4c9ac2ae4..88110dba9 100644 --- a/llarp/handlers/tun.cpp +++ b/llarp/handlers/tun.cpp @@ -297,9 +297,10 @@ namespace llarp } else { + dns::Message *replyMsg = new dns::Message(std::move(msg)); service::Endpoint::PathEnsureHook hook = std::bind( &TunEndpoint::SendDNSReply, this, std::placeholders::_1, - std::placeholders::_2, std::move(msg), reply); + std::placeholders::_2, replyMsg, reply); return EnsurePathToService(addr, hook, 2000); } } @@ -397,18 +398,19 @@ namespace llarp void TunEndpoint::SendDNSReply(service::Address addr, service::Endpoint::OutboundContext *ctx, - dns::Message request, + dns::Message *request, std::function< void(dns::Message) > reply) { if(ctx) { huint32_t ip = ObtainIPForAddr(addr, false); - request.AddINReply(ip); + request->AddINReply(ip); } else - request.AddNXReply(); + request->AddNXReply(); - reply(request); + reply(*request); + delete request; } bool diff --git a/llarp/handlers/tun.hpp b/llarp/handlers/tun.hpp index 824ec32a4..500360994 100644 --- a/llarp/handlers/tun.hpp +++ b/llarp/handlers/tun.hpp @@ -191,7 +191,7 @@ namespace llarp void SendDNSReply(service::Address addr, - service::Endpoint::OutboundContext* ctx, dns::Message query, + service::Endpoint::OutboundContext* ctx, dns::Message* query, std::function< void(dns::Message) > reply); #ifndef WIN32 diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 6cdea9290..f997c6d4a 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -87,8 +87,18 @@ namespace llarp bool Endpoint::HasPendingPathToService(const Address& addr) const { - return m_PendingServiceLookups.find(addr) - != m_PendingServiceLookups.end(); + if(m_PendingServiceLookups.find(addr) == m_PendingServiceLookups.end()) + { + auto range = m_RemoteSessions.equal_range(addr); + auto itr = range.first; + while(itr != range.second) + { + if(itr->second->ReadyToSend()) + return false; + ++itr; + } + } + return true; } void @@ -365,24 +375,7 @@ namespace llarp if(!introset.Verify(crypto, Now())) { if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T) - { IntroSetPublishFail(); - } - else - { - auto itr = m_PendingLookups.find(msg->T); - if(itr == m_PendingLookups.end()) - { - llarp::LogWarn( - "invalid lookup response for hidden service endpoint ", - Name(), " txid=", msg->T); - return true; - } - std::unique_ptr< IServiceLookup > lookup = std::move(itr->second); - m_PendingLookups.erase(itr); - lookup->HandleResponse({}); - return true; - } return true; } if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T) @@ -686,7 +679,13 @@ namespace llarp llarp::LogInfo("found ", results.size(), " for ", remote.ToString()); if(results.size() > 0) { - return handle(remote, &*results.begin(), endpoint); + IntroSet selected; + for(const auto& introset : results) + { + if(selected.OtherIsNewer(introset) && introset.A.Addr() == remote) + selected = introset; + } + return handle(remote, &selected, endpoint); } return handle(remote, nullptr, endpoint); } @@ -728,13 +727,14 @@ namespace llarp { auto itr = m_RemoteSessions.find(addr); - auto i = m_PendingServiceLookups.find(addr); - if(i != m_PendingServiceLookups.end()) + auto range = m_PendingServiceLookups.equal_range(addr); + auto i = range.first; + if(i != range.second) { - auto f = i->second; - m_PendingServiceLookups.erase(i); - f(addr, itr->second.get()); + i->second(addr, itr->second.get()); + ++i; } + m_PendingServiceLookups.erase(addr); return; } @@ -744,13 +744,14 @@ namespace llarp llarp::LogInfo("Created New outbound context for ", addr.ToString()); // inform pending - auto itr = m_PendingServiceLookups.find(addr); - if(itr != m_PendingServiceLookups.end()) + auto range = m_PendingServiceLookups.equal_range(addr); + auto itr = range.first; + if(itr != range.second) { - auto f = itr->second; - m_PendingServiceLookups.erase(itr); - f(addr, ctx); + itr->second(addr, ctx); + ++itr; } + m_PendingServiceLookups.erase(addr); } bool @@ -965,16 +966,18 @@ namespace llarp llarp::LogError(Name(), " failed to lookup ", addr.ToString(), " from ", endpoint); m_ServiceLookupFails[endpoint] = m_ServiceLookupFails[endpoint] + 1; - auto itr = m_PendingServiceLookups.find(addr); - if(itr != m_PendingServiceLookups.end()) + auto range = m_PendingServiceLookups.equal_range(addr); + auto itr = range.first; + if(itr != range.second) { - auto func = itr->second; - m_PendingServiceLookups.erase(itr); - func(addr, nullptr); + itr->second(addr, nullptr); + ++itr; } + m_PendingServiceLookups.erase(addr); return false; } - PutNewOutboundContext(*introset); + else + PutNewOutboundContext(*introset); return true; } @@ -1004,18 +1007,6 @@ namespace llarp return true; } } - { - auto itr = m_PendingServiceLookups.find(remote); - if(itr != m_PendingServiceLookups.end()) - { - // duplicate - llarp::LogWarn("duplicate pending service lookup to ", - remote.ToString()); - return false; - } - } - - m_PendingServiceLookups.insert(std::make_pair(remote, hook)); { RouterID endpoint = path->Endpoint(); auto itr = m_ServiceLookupFails.find(endpoint); @@ -1042,7 +1033,10 @@ namespace llarp remote, GenTXID()); llarp::LogInfo("doing lookup for ", remote, " via ", path->Endpoint()); if(job->SendRequestViaPath(path, Router())) + { + m_PendingServiceLookups.insert(std::make_pair(remote, hook)); return true; + } llarp::LogError("send via path failed"); return false; } diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index bc1ee8336..ef2a10051 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -485,7 +485,7 @@ namespace llarp std::unordered_map< Address, ServiceInfo, Address::Hash > m_AddressToService; - std::unordered_map< Address, PathEnsureHook, Address::Hash > + std::unordered_multimap< Address, PathEnsureHook, Address::Hash > m_PendingServiceLookups; std::unordered_map< RouterID, uint32_t, RouterID::Hash > diff --git a/llarp/service/lookup.hpp b/llarp/service/lookup.hpp index dadb91e56..93cb78583 100644 --- a/llarp/service/lookup.hpp +++ b/llarp/service/lookup.hpp @@ -33,7 +33,7 @@ namespace llarp /// determine if this request has timed out bool - IsTimedOut(llarp_time_t now, llarp_time_t timeout = 20000) const + IsTimedOut(llarp_time_t now, llarp_time_t timeout = 15000) const { if(now <= m_created) return false;