Browse Source

check for transport protocols compatibility between routers

pull/14/head
orignal 11 years ago
parent
commit
a4c25e773c
  1. 30
      NetDb.cpp
  2. 2
      NetDb.h
  3. 32
      RouterInfo.cpp
  4. 11
      RouterInfo.h
  5. 9
      Tunnel.cpp
  6. 3
      Tunnel.h

30
NetDb.cpp

@ -427,7 +427,7 @@ namespace data
auto inbound = i2p::tunnel::tunnels.GetNextInboundTunnel (); auto inbound = i2p::tunnel::tunnels.GetNextInboundTunnel ();
if (outbound && inbound) if (outbound && inbound)
{ {
auto floodfill = GetRandomNTCPRouter (true); auto floodfill = GetRandomRouter (outbound->GetEndpointRouter (), true);
if (floodfill) if (floodfill)
{ {
LogPrint ("Exploring new routers ..."); LogPrint ("Exploring new routers ...");
@ -495,19 +495,29 @@ namespace data
return last; return last;
} }
const RouterInfo * NetDb::GetRandomRouter () const const RouterInfo * NetDb::GetRandomRouter (const RouterInfo * compatibleWith, bool floodfillOnly) const
{ {
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator (); CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1), i = 0; uint32_t ind = rnd.GenerateWord32 (0, m_RouterInfos.size () - 1);
RouterInfo * last = nullptr; for (int j = 0; j < 2; j++)
for (auto it: m_RouterInfos)
{ {
if (!it.second->IsUnreachable ()) uint32_t i = 0;
last = it.second; for (auto it: m_RouterInfos)
if (i >= ind) break; {
else i++; if (i >= ind)
{
if (!it.second->IsUnreachable () &&
(!compatibleWith || it.second->IsCompatible (*compatibleWith)) &&
(!floodfillOnly || it.second->IsFloodfill ()))
return it.second;
}
else
i++;
}
// we couldn't find anything, try second pass
ind = 0;
} }
return last; return nullptr; // seem we have too few routers
} }
void NetDb::PostI2NPMsg (I2NPMessage * msg) void NetDb::PostI2NPMsg (I2NPMessage * msg)

2
NetDb.h

@ -68,7 +68,7 @@ namespace data
void HandleDatabaseSearchReplyMsg (I2NPMessage * msg); void HandleDatabaseSearchReplyMsg (I2NPMessage * msg);
const RouterInfo * GetRandomNTCPRouter (bool floodfillOnly = false) const; const RouterInfo * GetRandomNTCPRouter (bool floodfillOnly = false) const;
const RouterInfo * GetRandomRouter () const; const RouterInfo * GetRandomRouter (const RouterInfo * compatibleWith = nullptr, bool floodfillOnly = false) const;
void PostI2NPMsg (I2NPMessage * msg); void PostI2NPMsg (I2NPMessage * msg);

32
RouterInfo.cpp

@ -13,19 +13,18 @@
#include "RouterContext.h" #include "RouterContext.h"
namespace i2p namespace i2p
{ {
namespace data namespace data
{ {
RouterInfo::RouterInfo (const char * filename): RouterInfo::RouterInfo (const char * filename):
m_IsUpdated (false), m_IsUnreachable (false) m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0)
{ {
ReadFromFile (filename); ReadFromFile (filename);
} }
RouterInfo::RouterInfo (const uint8_t * buf, int len): RouterInfo::RouterInfo (const uint8_t * buf, int len):
m_IsUpdated (true) m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0)
{ {
memcpy (m_Buffer, buf, len); memcpy (m_Buffer, buf, len);
m_BufferLen = len; m_BufferLen = len;
@ -111,7 +110,15 @@ namespace data
// TODO: we should try to resolve address here // TODO: we should try to resolve address here
LogPrint ("Unexpected address ", value); LogPrint ("Unexpected address ", value);
SetUnreachable (true); SetUnreachable (true);
} }
else
{
// add supported protocol
if (address.host.is_v4 ())
m_SupportedTransports |= (address.transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4;
else
m_SupportedTransports |= (address.transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6;
}
} }
else if (!strcmp (key, "port")) else if (!strcmp (key, "port"))
address.port = boost::lexical_cast<int>(value); address.port = boost::lexical_cast<int>(value);
@ -275,17 +282,12 @@ namespace data
bool RouterInfo::IsNTCP (bool v4only) const bool RouterInfo::IsNTCP (bool v4only) const
{ {
for (auto& address : m_Addresses) if (v4only)
{ return m_SupportedTransports & eNTCPV4;
if (address.transportStyle == eTransportNTCP) else
{ return m_SupportedTransports & (eNTCPV4 | eNTCPV6);
if (!v4only || address.host.is_v4 ()) }
return true;
}
}
return false;
}
RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only)
{ {
for (auto& address : m_Addresses) for (auto& address : m_Addresses)

11
RouterInfo.h

@ -17,6 +17,14 @@ namespace data
{ {
public: public:
enum SupportedTranports
{
eNTCPV4 = 0x01,
eNTCPV6 = 0x20,
eSSUV4 = 0x40,
eSSUV6 = 0x80
};
enum TransportStyle enum TransportStyle
{ {
eTransportUnknown = 0, eTransportUnknown = 0,
@ -53,6 +61,8 @@ namespace data
const char * GetProperty (const char * key) const; const char * GetProperty (const char * key) const;
bool IsFloodfill () const; bool IsFloodfill () const;
bool IsNTCP (bool v4only = true) const; bool IsNTCP (bool v4only = true) const;
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; }; void SetUnreachable (bool unreachable) { m_IsUnreachable = unreachable; };
bool IsUnreachable () const { return m_IsUnreachable; }; bool IsUnreachable () const { return m_IsUnreachable; };
@ -91,6 +101,7 @@ namespace data
std::vector<Address> m_Addresses; std::vector<Address> m_Addresses;
std::map<std::string, std::string> m_Properties; std::map<std::string, std::string> m_Properties;
bool m_IsUpdated, m_IsUnreachable; bool m_IsUpdated, m_IsUnreachable;
uint8_t m_SupportedTransports;
}; };
} }
} }

9
Tunnel.cpp

@ -397,11 +397,12 @@ namespace tunnel
{ {
LogPrint ("Creating two hops outbound tunnel..."); LogPrint ("Creating two hops outbound tunnel...");
auto firstHop = i2p::data::netdb.GetRandomNTCPRouter (); // first hop must be NTCP
CreateTunnel<OutboundTunnel> ( CreateTunnel<OutboundTunnel> (
new TunnelConfig (std::vector<const i2p::data::RouterInfo *> new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
{ {
i2p::data::netdb.GetRandomNTCPRouter (), // first hop must be NTCP firstHop,
i2p::data::netdb.GetRandomRouter () i2p::data::netdb.GetRandomRouter (firstHop)
}, },
inboundTunnel->GetTunnelConfig ())); inboundTunnel->GetTunnelConfig ()));
} }
@ -449,8 +450,8 @@ namespace tunnel
CreateTunnel<InboundTunnel> ( CreateTunnel<InboundTunnel> (
new TunnelConfig (std::vector<const i2p::data::RouterInfo *> new TunnelConfig (std::vector<const i2p::data::RouterInfo *>
{ {
i2p::data::netdb.GetRandomNTCPRouter (), i2p::data::netdb.GetRandomRouter (outboundTunnel->GetEndpointRouter ()),
router != &i2p::context.GetRouterInfo () ? router : i2p::data::netdb.GetRandomNTCPRouter () router != &i2p::context.GetRouterInfo () ? router : i2p::data::netdb.GetRandomNTCPRouter () // last hop must be NTCP
}), }),
outboundTunnel); outboundTunnel);
} }

3
Tunnel.h

@ -67,7 +67,8 @@ namespace tunnel
void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg); void SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, i2p::I2NPMessage * msg);
void SendTunnelDataMsg (std::vector<TunnelMessageBlock> msgs); // multiple messages void SendTunnelDataMsg (std::vector<TunnelMessageBlock> msgs); // multiple messages
const i2p::data::RouterInfo * GetEndpointRouter () const
{ return GetTunnelConfig ()->GetLastHop ()->router; };
size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); }; size_t GetNumSentBytes () const { return m_Gateway.GetNumSentBytes (); };
// implements TunnelBase // implements TunnelBase

Loading…
Cancel
Save