void TunnelPool::RecreateInboundTunnel (std::shared_ptr<InboundTunnel> tunnel) { auto outboundTunnel = GetNextOutboundTunnel (); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); auto newTunnel = tunnels.CreateTunnel<InboundTunnel> (std::make_shared<TunnelConfig>(tunnel->GetPeers ()), outboundTunnel); newTunnel->SetTunnelPool (shared_from_this()); }
void NetDbRequests::ManageRequests() { uint64_t ts = i2p::util::GetSecondsSinceEpoch(); std::unique_lock<std::mutex> l(m_RequestedDestinationsMutex); for (auto it = m_RequestedDestinations.begin(); it != m_RequestedDestinations.end();) { auto& dest = it->second; bool done = false; // request is worthless after 1 minute if (ts < dest->GetCreationTime() + 60) { // no response for 5 seconds if (ts > dest->GetCreationTime() + 5) { auto count = dest->GetExcludedPeers().size(); std::size_t attempts(7); if (!dest->IsExploratory() && count < attempts) { auto pool = i2p::tunnel::tunnels.GetExploratoryPool(); auto outbound = pool->GetNextOutboundTunnel(); auto inbound = pool->GetNextInboundTunnel(); auto nextFloodfill = netdb.GetClosestFloodfill( dest->GetDestination(), dest->GetExcludedPeers()); if (nextFloodfill && outbound && inbound) { outbound->SendTunnelDataMsg( nextFloodfill->GetIdentHash(), 0, dest->CreateRequestMessage( nextFloodfill, inbound)); } else { done = true; if (!inbound) LogPrint(eLogWarn, "NetDbRequests: no inbound tunnels"); if (!outbound) LogPrint(eLogWarn, "NetDbRequests: no outbound tunnels"); if (!nextFloodfill) LogPrint(eLogWarn, "NetDbRequests: no more floodfills"); } } else { if (!dest->IsExploratory()) LogPrint(eLogWarn, "NetDbRequests: ", dest->GetDestination().ToBase64(), " not found after ", attempts, " attempts"); done = true; } } } else { // delete obsolete request done = true; } if (done) it = m_RequestedDestinations.erase(it); else it++; } }
void TunnelPool::RecreateInboundTunnel( std::shared_ptr<InboundTunnel> tunnel) { auto outboundTunnel = GetNextOutboundTunnel(); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel(); LogPrint("Re-creating destination inbound tunnel..."); auto newTunnel = tunnels.CreateTunnel<InboundTunnel> ( tunnel->GetTunnelConfig()->Clone(), outboundTunnel); newTunnel->SetTunnelPool(shared_from_this()); }
void TunnelPool::CreateInboundTunnel () { auto outboundTunnel = GetNextOutboundTunnel (); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel..."); std::vector<std::shared_ptr<const i2p::data::IdentityEx> > peers; if (SelectPeers (peers, true)) { std::reverse (peers.begin (), peers.end ()); auto tunnel = tunnels.CreateTunnel<InboundTunnel> (std::make_shared<TunnelConfig> (peers), outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); } else LogPrint (eLogError, "Tunnels: Can't create inbound tunnel, no peers available"); }
void TunnelPool::CreateInboundTunnel() { auto outboundTunnel = GetNextOutboundTunnel(); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel(); LogPrint("Creating destination inbound tunnel..."); std::vector<std::shared_ptr<const i2p::data::RouterInfo> > hops; if (SelectPeers(hops, true)) { std::reverse(hops.begin(), hops.end()); auto tunnel = tunnels.CreateTunnel<InboundTunnel> ( std::make_shared<TunnelConfig> (hops), outboundTunnel); tunnel->SetTunnelPool(shared_from_this()); } else { LogPrint(eLogError, "Can't create inbound tunnel. No peers available"); } }
std::shared_ptr<OutboundTunnel> TunnelPool::GetNewOutboundTunnel (std::shared_ptr<OutboundTunnel> old) const { if (old && old->IsEstablished ()) return old; std::shared_ptr<OutboundTunnel> tunnel; if (old) { std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex); for (auto it: m_OutboundTunnels) if (it->IsEstablished () && old->GetEndpointIdentHash () == it->GetEndpointIdentHash ()) { tunnel = it; break; } } if (!tunnel) tunnel = GetNextOutboundTunnel (); return tunnel; }