Browse Source

publish and request through exploratory tunnel if floodfill is not reachable

pull/1634/head
orignal 4 years ago
parent
commit
313921da56
  1. 21
      libi2pd/I2NPProtocol.cpp
  2. 2
      libi2pd/I2NPProtocol.h
  3. 15
      libi2pd/NetDb.cpp

21
libi2pd/I2NPProtocol.cpp

@ -244,7 +244,8 @@ namespace i2p
return m; return m;
} }
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router, uint32_t replyToken) std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
{ {
if (!router) // we send own RouterInfo if (!router) // we send own RouterInfo
router = context.GetSharedRouterInfo (); router = context.GetSharedRouterInfo ();
@ -258,10 +259,20 @@ namespace i2p
uint8_t * buf = payload + DATABASE_STORE_HEADER_SIZE; uint8_t * buf = payload + DATABASE_STORE_HEADER_SIZE;
if (replyToken) if (replyToken)
{ {
memset (buf, 0, 4); // zero tunnelID means direct reply if (replyTunnel)
buf += 4; {
memcpy (buf, router->GetIdentHash (), 32); htobe32buf (buf, replyTunnel->GetNextTunnelID ());
buf += 32; buf += 4; // reply tunnelID
memcpy (buf, replyTunnel->GetNextIdentHash (), 32);
buf += 32; // reply tunnel gateway
}
else
{
memset (buf, 0, 4); // zero tunnelID means direct reply
buf += 4;
memcpy (buf, context.GetIdentHash (), 32);
buf += 32;
}
} }
uint8_t * sizePtr = buf; uint8_t * sizePtr = buf;

2
libi2pd/I2NPProtocol.h

@ -276,7 +276,7 @@ namespace tunnel
const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false); const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers); std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers);
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0); std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (const i2p::data::IdentHash& storeHash, std::shared_ptr<const i2p::data::LeaseSet> leaseSet); // for floodfill only std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (const i2p::data::IdentHash& storeHash, std::shared_ptr<const i2p::data::LeaseSet> leaseSet); // for floodfill only
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LocalLeaseSet> leaseSet, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr); std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LocalLeaseSet> leaseSet, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
bool IsRouterInfoMsg (std::shared_ptr<I2NPMessage> msg); bool IsRouterInfoMsg (std::shared_ptr<I2NPMessage> msg);

15
libi2pd/NetDb.cpp

@ -643,6 +643,7 @@ namespace data
auto floodfill = GetClosestFloodfill (destination, dest->GetExcludedPeers ()); auto floodfill = GetClosestFloodfill (destination, dest->GetExcludedPeers ());
if (floodfill) if (floodfill)
{ {
if (direct && !floodfill->IsCompatible (i2p::context.GetRouterInfo ())) direct = false; // check if fllodfill is reachable
if (direct) if (direct)
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
else else
@ -1087,7 +1088,19 @@ namespace data
LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken);
m_PublishExcluded.insert (floodfill->GetIdentHash ()); m_PublishExcluded.insert (floodfill->GetIdentHash ());
m_PublishReplyToken = replyToken; m_PublishReplyToken = replyToken;
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); if (floodfill->IsCompatible (i2p::context.GetRouterInfo ())) // able to connect?
// send directly
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
else
{
// otherwise through exploratory
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr;
auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr;
if (inbound && outbound)
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0,
CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound));
}
} }
} }

Loading…
Cancel
Save