|
|
@ -24,7 +24,7 @@ namespace data |
|
|
|
{ |
|
|
|
{ |
|
|
|
NetDb netdb; |
|
|
|
NetDb netdb; |
|
|
|
|
|
|
|
|
|
|
|
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat") |
|
|
|
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_HiddenMode(false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -122,7 +122,11 @@ namespace data |
|
|
|
} |
|
|
|
} |
|
|
|
lastSave = ts; |
|
|
|
lastSave = ts; |
|
|
|
} |
|
|
|
} |
|
|
|
if (ts - lastPublish >= 2400) // publish every 40 minutes
|
|
|
|
|
|
|
|
|
|
|
|
// if we're in hidden mode don't publish or explore
|
|
|
|
|
|
|
|
// if (m_HiddenMode) continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // publish
|
|
|
|
{ |
|
|
|
{ |
|
|
|
Publish (); |
|
|
|
Publish (); |
|
|
|
lastPublish = ts; |
|
|
|
lastPublish = ts; |
|
|
@ -161,6 +165,11 @@ namespace data |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void NetDb::SetHidden(bool hide) { |
|
|
|
|
|
|
|
// TODO: remove reachable addresses from router info
|
|
|
|
|
|
|
|
m_HiddenMode = hide; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len) |
|
|
|
bool NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool updated = true; |
|
|
|
bool updated = true; |
|
|
@ -174,10 +183,8 @@ namespace data |
|
|
|
// TODO: check if floodfill has been changed
|
|
|
|
// TODO: check if floodfill has been changed
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogDebug, "NetDb: RouterInfo is older: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogDebug, "NetDb: RouterInfo is older: ", ident.ToBase64()); |
|
|
|
updated = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
@ -217,29 +224,29 @@ namespace data |
|
|
|
it->second->Update (buf, len); |
|
|
|
it->second->Update (buf, len); |
|
|
|
if (it->second->IsValid ()) |
|
|
|
if (it->second->IsValid ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32()); |
|
|
|
updated = true; |
|
|
|
updated = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogWarning, "NetDb: LeaseSet update failed: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogWarning, "NetDb: LeaseSet update failed: ", ident.ToBase32()); |
|
|
|
m_LeaseSets.erase (it); |
|
|
|
m_LeaseSets.erase (it); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
LogPrint (eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase32()); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto leaseSet = std::make_shared<LeaseSet> (buf, len, false); // we don't need leases in netdb
|
|
|
|
auto leaseSet = std::make_shared<LeaseSet> (buf, len, false); // we don't need leases in netdb
|
|
|
|
if (leaseSet->IsValid ()) |
|
|
|
if (leaseSet->IsValid ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogInfo, "NetDb: LeaseSet added: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogInfo, "NetDb: LeaseSet added: ", ident.ToBase32()); |
|
|
|
m_LeaseSets[ident] = leaseSet; |
|
|
|
m_LeaseSets[ident] = leaseSet; |
|
|
|
updated = true; |
|
|
|
updated = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
LogPrint (eLogError, "NetDb: new LeaseSet validation failed: ", ident.ToBase64()); |
|
|
|
LogPrint (eLogError, "NetDb: new LeaseSet validation failed: ", ident.ToBase32()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return updated; |
|
|
|
return updated; |
|
|
@ -461,7 +468,7 @@ namespace data |
|
|
|
bool updated = false; |
|
|
|
bool updated = false; |
|
|
|
if (buf[DATABASE_STORE_TYPE_OFFSET]) // type
|
|
|
|
if (buf[DATABASE_STORE_TYPE_OFFSET]) // type
|
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogDebug, "NetDb: store request: LeaseSet"); |
|
|
|
LogPrint (eLogDebug, "NetDb: store request: LeaseSet for ", ident.ToBase32()); |
|
|
|
updated = AddLeaseSet (ident, buf + offset, len - offset, m->from); |
|
|
|
updated = AddLeaseSet (ident, buf + offset, len - offset, m->from); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
@ -487,7 +494,7 @@ namespace data |
|
|
|
uint8_t * payload = floodMsg->GetPayload (); |
|
|
|
uint8_t * payload = floodMsg->GetPayload (); |
|
|
|
memcpy (payload, buf, 33); // key + type
|
|
|
|
memcpy (payload, buf, 33); // key + type
|
|
|
|
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); // zero reply token
|
|
|
|
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); // zero reply token
|
|
|
|
auto msgLen = len - payloadOffset; |
|
|
|
size_t msgLen = len - payloadOffset; |
|
|
|
floodMsg->len += DATABASE_STORE_HEADER_SIZE + msgLen; |
|
|
|
floodMsg->len += DATABASE_STORE_HEADER_SIZE + msgLen; |
|
|
|
if (floodMsg->len < floodMsg->maxLen) |
|
|
|
if (floodMsg->len < floodMsg->maxLen) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -501,15 +508,17 @@ namespace data |
|
|
|
auto floodfill = GetClosestFloodfill (ident, excluded); |
|
|
|
auto floodfill = GetClosestFloodfill (ident, excluded); |
|
|
|
if (floodfill) |
|
|
|
if (floodfill) |
|
|
|
{ |
|
|
|
{ |
|
|
|
transports.SendMessage (floodfill->GetIdentHash (), CopyI2NPMessage(floodMsg)); |
|
|
|
auto h = floodfill->GetIdentHash(); |
|
|
|
excluded.insert (floodfill->GetIdentHash ()); |
|
|
|
LogPrint(eLogDebug, "NetDb: Flood lease set for ", ident.ToBase32(), " to ", h.ToBase64()); |
|
|
|
|
|
|
|
transports.SendMessage (h, CopyI2NPMessage(floodMsg)); |
|
|
|
|
|
|
|
excluded.insert (h); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
LogPrint (eLogError, "Database store message is too long ", floodMsg->len); |
|
|
|
LogPrint (eLogError, "NetDb: Database store message is too long ", floodMsg->len); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -615,13 +624,16 @@ namespace data |
|
|
|
int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48); |
|
|
|
int l = i2p::data::ByteStreamToBase64 (buf, 32, key, 48); |
|
|
|
key[l] = 0; |
|
|
|
key[l] = 0; |
|
|
|
uint8_t flag = buf[64]; |
|
|
|
uint8_t flag = buf[64]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IdentHash replyIdent(buf + 32); |
|
|
|
|
|
|
|
|
|
|
|
LogPrint (eLogDebug, "NetDb: DatabaseLookup for ", key, " recieved flags=", (int)flag); |
|
|
|
LogPrint (eLogDebug, "NetDb: DatabaseLookup for ", key, " recieved flags=", (int)flag); |
|
|
|
uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK; |
|
|
|
uint8_t lookupType = flag & DATABASE_LOOKUP_TYPE_FLAGS_MASK; |
|
|
|
const uint8_t * excluded = buf + 65; |
|
|
|
const uint8_t * excluded = buf + 65; |
|
|
|
uint32_t replyTunnelID = 0; |
|
|
|
uint32_t replyTunnelID = 0; |
|
|
|
if (flag & DATABASE_LOOKUP_DELIVERY_FLAG) //reply to tunnel
|
|
|
|
if (flag & DATABASE_LOOKUP_DELIVERY_FLAG) //reply to tunnel
|
|
|
|
{ |
|
|
|
{ |
|
|
|
replyTunnelID = bufbe32toh (buf + 64); |
|
|
|
replyTunnelID = bufbe32toh (buf + 65); |
|
|
|
excluded += 4; |
|
|
|
excluded += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
uint16_t numExcluded = bufbe16toh (excluded); |
|
|
|
uint16_t numExcluded = bufbe16toh (excluded); |
|
|
@ -673,7 +685,12 @@ namespace data |
|
|
|
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)) |
|
|
|
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto leaseSet = FindLeaseSet (ident); |
|
|
|
auto leaseSet = FindLeaseSet (ident); |
|
|
|
if (leaseSet && !leaseSet->IsExpired ()) // we don't send back our LeaseSets
|
|
|
|
if (!leaseSet) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// no lease set found
|
|
|
|
|
|
|
|
LogPrint(eLogDebug, "NetDb: requested LeaseSet not found for ", ident.ToBase32()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (!leaseSet->IsExpired ()) // we don't send back our LeaseSets
|
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogDebug, "NetDb: requested LeaseSet ", key, " found"); |
|
|
|
LogPrint (eLogDebug, "NetDb: requested LeaseSet ", key, " found"); |
|
|
|
replyMsg = CreateDatabaseStoreMsg (leaseSet); |
|
|
|
replyMsg = CreateDatabaseStoreMsg (leaseSet); |
|
|
@ -730,12 +747,12 @@ namespace data |
|
|
|
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); |
|
|
|
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); |
|
|
|
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; |
|
|
|
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; |
|
|
|
if (outbound) |
|
|
|
if (outbound) |
|
|
|
outbound->SendTunnelDataMsg (buf+32, replyTunnelID, replyMsg); |
|
|
|
outbound->SendTunnelDataMsg (replyIdent, replyTunnelID, replyMsg); |
|
|
|
else |
|
|
|
else |
|
|
|
transports.SendMessage (buf+32, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg)); |
|
|
|
transports.SendMessage (replyIdent, i2p::CreateTunnelGatewayMsg (replyTunnelID, replyMsg)); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
transports.SendMessage (buf+32, replyMsg); |
|
|
|
transports.SendMessage (replyIdent, replyMsg); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -966,6 +983,14 @@ namespace data |
|
|
|
return res; |
|
|
|
return res; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily(const std::string & fam) const { |
|
|
|
|
|
|
|
return GetRandomRouter( |
|
|
|
|
|
|
|
[fam](std::shared_ptr<const RouterInfo> router)->bool |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return router->IsFamily(fam); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<const RouterInfo> NetDb::GetClosestNonFloodfill (const IdentHash& destination, |
|
|
|
std::shared_ptr<const RouterInfo> NetDb::GetClosestNonFloodfill (const IdentHash& destination, |
|
|
|
const std::set<IdentHash>& excluded) const |
|
|
|
const std::set<IdentHash>& excluded) const |
|
|
|
{ |
|
|
|
{ |
|
|
|