diff --git a/Destination.cpp b/Destination.cpp index 484c0679..eefd9700 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -654,13 +654,14 @@ namespace client bool ClientDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request) { - auto replyTunnel = m_Pool->GetNextInboundTunnel (); - if (!replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found"); - - auto outboundTunnel = m_Pool->GetNextOutboundTunnel (); - if (!outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); + if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) + request->replyTunnel = m_Pool->GetNextInboundTunnel (); + if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found"); + if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) + request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); + if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); - if (replyTunnel && outboundTunnel) + if (request->replyTunnel && request->outboundTunnel) { request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTime = i2p::util::GetSecondsSinceEpoch (); @@ -673,8 +674,8 @@ namespace client auto msg = WrapMessage (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - replyTunnel.get (), replyKey, replyTag)); - outboundTunnel->SendTunnelDataMsg ( + request->replyTunnel, replyKey, replyTag)); + request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock { @@ -704,7 +705,12 @@ namespace client { auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, it->second->excluded); if (floodfill) - done = !SendLeaseSetRequest (dest, floodfill, it->second); + { + // reset tunnels, because one them might fail + it->second->outboundTunnel = nullptr; + it->second->replyTunnel = nullptr; + done = !SendLeaseSetRequest (dest, floodfill, it->second); + } else done = true; } diff --git a/Destination.h b/Destination.h index 34e7fa38..2da4c8e5 100644 --- a/Destination.h +++ b/Destination.h @@ -61,6 +61,8 @@ namespace client uint64_t requestTime; boost::asio::deadline_timer requestTimeoutTimer; RequestComplete requestComplete; + std::shared_ptr outboundTunnel; + std::shared_ptr replyTunnel; }; diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index db3330e2..dff66951 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -157,7 +157,7 @@ namespace i2p std::shared_ptr CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, const std::set& excludedFloodfills, - const i2p::tunnel::InboundTunnel * replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag) + std::shared_ptr replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag) { int cnt = excludedFloodfills.size (); auto m = cnt > 0 ? NewI2NPMessage () : NewI2NPShortMessage (); diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 173b57fb..6450e958 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -222,7 +222,7 @@ namespace tunnel uint32_t replyTunnelID, bool exploratory = false, std::set * excludedPeers = nullptr); std::shared_ptr CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, const std::set& excludedFloodfills, - const i2p::tunnel::InboundTunnel * replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag); + std::shared_ptr replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag); std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector routers); std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router = nullptr, uint32_t replyToken = 0);