Browse Source

handle and publish NTCP2 address

pull/1194/head
orignal 7 years ago
parent
commit
706b976a28
  1. 24
      libi2pd/RouterContext.cpp
  2. 6
      libi2pd/RouterContext.h
  3. 61
      libi2pd/RouterInfo.cpp
  4. 7
      libi2pd/RouterInfo.h

24
libi2pd/RouterContext.cpp

@ -2,6 +2,7 @@
#include <openssl/rand.h> #include <openssl/rand.h>
#include "Config.h" #include "Config.h"
#include "Crypto.h" #include "Crypto.h"
#include "Ed25519.h"
#include "Timestamp.h" #include "Timestamp.h"
#include "I2NPProtocol.h" #include "I2NPProtocol.h"
#include "NetDb.hpp" #include "NetDb.hpp"
@ -36,7 +37,7 @@ namespace i2p
void RouterContext::CreateNewRouter () void RouterContext::CreateNewRouter ()
{ {
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
SaveKeys (); SaveKeys ();
NewRouterInfo (); NewRouterInfo ();
} }
@ -49,7 +50,8 @@ namespace i2p
port = rand () % (30777 - 9111) + 9111; // I2P network ports range port = rand () % (30777 - 9111) + 9111; // I2P network ports range
bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv4; i2p::config::GetOption("ipv4", ipv4);
bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool nat; i2p::config::GetOption("nat", nat); bool ntcp2; i2p::config::GetOption("ntcp2", ntcp2);
bool nat; i2p::config::GetOption("nat", nat);
std::string ifname; i2p::config::GetOption("ifname", ifname); std::string ifname; i2p::config::GetOption("ifname", ifname);
std::string ifname4; i2p::config::GetOption("ifname4", ifname4); std::string ifname4; i2p::config::GetOption("ifname4", ifname4);
std::string ifname6; i2p::config::GetOption("ifname6", ifname6); std::string ifname6; i2p::config::GetOption("ifname6", ifname6);
@ -82,6 +84,11 @@ namespace i2p
routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ());
routerInfo.AddNTCPAddress (host.c_str(), port); routerInfo.AddNTCPAddress (host.c_str(), port);
} }
if (ntcp2)
{
NewNTCP2Keys ();
routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
}
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
@ -102,11 +109,14 @@ namespace i2p
void RouterContext::NewNTCP2Keys () void RouterContext::NewNTCP2Keys ()
{ {
m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
RAND_bytes (m_NTCP2Keys->staticKey, 32); RAND_bytes (m_NTCP2Keys->staticPrivateKey, 32);
RAND_bytes (m_NTCP2Keys->iv, 16); RAND_bytes (m_NTCP2Keys->iv, 16);
BN_CTX * ctx = BN_CTX_new ();
i2p::crypto::GetEd25519 ()->ScalarMulB (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey, ctx);
BN_CTX_free (ctx);
// save // save
std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
} }
void RouterContext::SetStatus (RouterStatus status) void RouterContext::SetStatus (RouterStatus status)
@ -455,9 +465,13 @@ namespace i2p
m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
} }
n2k.close ();
} }
if (!m_NTCP2Keys) if (!m_NTCP2Keys)
{
NewNTCP2Keys (); NewNTCP2Keys ();
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
}
} }
return true; return true;

6
libi2pd/RouterContext.h

@ -37,7 +37,8 @@ namespace i2p
struct NTCP2PrivateKeys struct NTCP2PrivateKeys
{ {
uint8_t staticKey[32]; uint8_t staticPublicKey[32];
uint8_t staticPrivateKey[32];
uint8_t iv[16]; uint8_t iv[16];
}; };
@ -58,6 +59,9 @@ namespace i2p
return std::shared_ptr<i2p::garlic::GarlicDestination> (this, return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
[](i2p::garlic::GarlicDestination *) {}); [](i2p::garlic::GarlicDestination *) {});
} }
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
uint32_t GetUptime () const; uint32_t GetUptime () const;
uint32_t GetStartupTime () const { return m_StartupTime; }; uint32_t GetStartupTime () const { return m_StartupTime; };

61
libi2pd/RouterInfo.cpp

@ -176,10 +176,14 @@ namespace data
auto address = std::make_shared<Address>(); auto address = std::make_shared<Address>();
s.read ((char *)&address->cost, sizeof (address->cost)); s.read ((char *)&address->cost, sizeof (address->cost));
s.read ((char *)&address->date, sizeof (address->date)); s.read ((char *)&address->date, sizeof (address->date));
char transportStyle[5]; bool isNtcp2 = false;
ReadString (transportStyle, 5, s); char transportStyle[6];
if (!strcmp (transportStyle, "NTCP")) auto transportStyleLen = ReadString (transportStyle, 6, s) - 1;
if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2
{
address->transportStyle = eTransportNTCP; address->transportStyle = eTransportNTCP;
if (transportStyleLen > 4 || transportStyle[4] == '2') isNtcp2= true;
}
else if (!strcmp (transportStyle, "SSU")) else if (!strcmp (transportStyle, "SSU"))
{ {
address->transportStyle = eTransportSSU; address->transportStyle = eTransportSSU;
@ -288,7 +292,7 @@ namespace data
if (!s) return; if (!s) return;
} }
if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented
if (supportedTransports) if (supportedTransports && !isNtcp2) // we ignore NTCP2 addresses for now. TODO:
{ {
addresses->push_back(address); addresses->push_back(address);
m_SupportedTransports |= supportedTransports; m_SupportedTransports |= supportedTransports;
@ -435,7 +439,7 @@ namespace data
s.write ((const char *)&address.date, sizeof (address.date)); s.write ((const char *)&address.date, sizeof (address.date));
std::stringstream properties; std::stringstream properties;
if (address.transportStyle == eTransportNTCP) if (address.transportStyle == eTransportNTCP)
WriteString ("NTCP", s); WriteString (address.IsNTCP2 () ? "NTCP2" : "NTCP", s);
else if (address.transportStyle == eTransportSSU) else if (address.transportStyle == eTransportSSU)
{ {
WriteString ("SSU", s); WriteString ("SSU", s);
@ -451,10 +455,13 @@ namespace data
else else
WriteString ("", s); WriteString ("", s);
WriteString ("host", properties); if (!address.IsNTCP2 ()) // we don't publish NTCP2 address fow now. TODO: implement
properties << '='; {
WriteString (address.host.to_string (), properties); WriteString ("host", properties);
properties << ';'; properties << '=';
WriteString (address.host.to_string (), properties);
properties << ';';
}
if (address.transportStyle == eTransportSSU) if (address.transportStyle == eTransportSSU)
{ {
// write introducers if any // write introducers if any
@ -529,10 +536,23 @@ namespace data
properties << ';'; properties << ';';
} }
} }
WriteString ("port", properties);
properties << '='; if (!address.IsNTCP2 ()) // we don't publish NTCP2 address fow now. TODO: implement
WriteString (boost::lexical_cast<std::string>(address.port), properties); {
properties << ';'; WriteString ("port", properties);
properties << '=';
WriteString (boost::lexical_cast<std::string>(address.port), properties);
properties << ';';
}
if (address.IsNTCP2 ())
{
// publish s and v for NTCP2
WriteString ("s", properties); properties << '=';
WriteString (address.ntcp2->staticKey.ToBase64 (), properties); properties << ';';
WriteString ("v", properties); properties << '=';
WriteString ("2", properties); properties << ';';
// TODO: publish "i"
}
uint16_t size = htobe16 (properties.str ().size ()); uint16_t size = htobe16 (properties.str ().size ());
s.write ((char *)&size, sizeof (size)); s.write ((char *)&size, sizeof (size));
@ -668,6 +688,21 @@ namespace data
m_Caps |= eSSUIntroducer; m_Caps |= eSSUIntroducer;
} }
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv)
{
for (const auto& it: *m_Addresses) // don't insert one more NTCP2
if (it->ntcp2) return;
auto addr = std::make_shared<Address>();
addr->port = 0;
addr->transportStyle = eTransportNTCP;
addr->cost = 14;
addr->date = 0;
addr->ntcp2.reset (new NTCP2Ext ());
memcpy (addr->ntcp2->staticKey, staticKey, 32);
memcpy (addr->ntcp2->iv, iv, 32);
m_Addresses->push_back(std::move(addr));
}
bool RouterInfo::AddIntroducer (const Introducer& introducer) bool RouterInfo::AddIntroducer (const Introducer& introducer)
{ {
for (auto& addr : *m_Addresses) for (auto& addr : *m_Addresses)

7
libi2pd/RouterInfo.h

@ -92,8 +92,8 @@ namespace data
struct NTCP2Ext struct NTCP2Ext
{ {
uint8_t staticKey[32]; Tag<32> staticKey;
uint8_t iv[16]; Tag<16> iv;
}; };
struct Address struct Address
@ -122,6 +122,8 @@ namespace data
{ {
return !(*this == other); return !(*this == other);
} }
bool IsNTCP2 () const { return (bool)ntcp2; };
}; };
typedef std::list<std::shared_ptr<Address> > Addresses; typedef std::list<std::shared_ptr<Address> > Addresses;
@ -143,6 +145,7 @@ namespace data
void AddNTCPAddress (const char * host, int port); void AddNTCPAddress (const char * host, int port);
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv);
bool AddIntroducer (const Introducer& introducer); bool AddIntroducer (const Introducer& introducer);
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only

Loading…
Cancel
Save