| 254 | } |
| 255 | |
| 256 | bool NetDbRequests::SendNextRequest (std::shared_ptr<RequestedDestination> dest) |
| 257 | { |
| 258 | if (!dest || !dest->IsActive ()) return false; |
| 259 | bool ret = true; |
| 260 | auto count = dest->GetNumAttempts (); |
| 261 | if (!dest->IsExploratory () && count < MAX_NUM_REQUEST_ATTEMPTS) |
| 262 | { |
| 263 | auto nextFloodfill = netdb.GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); |
| 264 | if (nextFloodfill) |
| 265 | { |
| 266 | bool direct = dest->IsDirect (); |
| 267 | if (direct && !nextFloodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) && |
| 268 | !i2p::transport::transports.IsConnected (nextFloodfill->GetIdentHash ())) |
| 269 | direct = false; // floodfill can't be reached directly |
| 270 | auto s = shared_from_this (); |
| 271 | auto onDrop = [s, dest]() |
| 272 | { |
| 273 | if (dest->IsActive ()) |
| 274 | { |
| 275 | boost::asio::post (s->GetIOService (), [s, dest]() |
| 276 | { |
| 277 | if (dest->IsActive ()) s->SendNextRequest (dest); |
| 278 | }); |
| 279 | } |
| 280 | }; |
| 281 | if (direct) |
| 282 | { |
| 283 | if (CheckLogLevel (eLogDebug)) |
| 284 | LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination ().ToBase64 (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 (), " directly"); |
| 285 | auto msg = dest->CreateRequestMessage (nextFloodfill->GetIdentHash ()); |
| 286 | msg->onDrop = onDrop; |
| 287 | i2p::transport::transports.SendMessage (nextFloodfill->GetIdentHash (), msg); |
| 288 | } |
| 289 | else |
| 290 | { |
| 291 | auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); |
| 292 | if (pool) |
| 293 | { |
| 294 | auto outbound = pool->GetNextOutboundTunnel (); |
| 295 | auto inbound = pool->GetNextInboundTunnel (); |
| 296 | if (nextFloodfill && outbound && inbound) |
| 297 | { |
| 298 | if (CheckLogLevel (eLogDebug)) |
| 299 | LogPrint (eLogDebug, "NetDbReq: Try ", dest->GetDestination ().ToBase64 (), " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 (), " through tunnels"); |
| 300 | auto msg = dest->CreateRequestMessage (nextFloodfill, inbound); |
| 301 | msg->onDrop = onDrop; |
| 302 | outbound->SendTunnelDataMsgTo (nextFloodfill->GetIdentHash (), 0, |
| 303 | i2p::garlic::WrapECIESX25519MessageForRouter (msg, nextFloodfill->GetIdentity ()->GetEncryptionPublicKey ())); |
| 304 | } |
| 305 | else |
| 306 | { |
| 307 | ret = false; |
| 308 | if (!inbound) LogPrint (eLogWarning, "NetDbReq: No inbound tunnels"); |
| 309 | if (!outbound) LogPrint (eLogWarning, "NetDbReq: No outbound tunnels"); |
| 310 | } |
| 311 | } |
| 312 | else |
| 313 | { |
nothing calls this directly
no test coverage detected