mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
handle and publish NTCP2 address
This commit is contained in:
parent
2bd7a92d20
commit
706b976a28
@ -2,6 +2,7 @@
|
||||
#include <openssl/rand.h>
|
||||
#include "Config.h"
|
||||
#include "Crypto.h"
|
||||
#include "Ed25519.h"
|
||||
#include "Timestamp.h"
|
||||
#include "I2NPProtocol.h"
|
||||
#include "NetDb.hpp"
|
||||
@ -36,7 +37,7 @@ namespace i2p
|
||||
void RouterContext::CreateNewRouter ()
|
||||
{
|
||||
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
|
||||
SaveKeys ();
|
||||
SaveKeys ();
|
||||
NewRouterInfo ();
|
||||
}
|
||||
|
||||
@ -49,7 +50,8 @@ namespace i2p
|
||||
port = rand () % (30777 - 9111) + 9111; // I2P network ports range
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
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 ifname4; i2p::config::GetOption("ifname4", ifname4);
|
||||
std::string ifname6; i2p::config::GetOption("ifname6", ifname6);
|
||||
@ -82,6 +84,11 @@ namespace i2p
|
||||
routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ());
|
||||
routerInfo.AddNTCPAddress (host.c_str(), port);
|
||||
}
|
||||
if (ntcp2)
|
||||
{
|
||||
NewNTCP2Keys ();
|
||||
routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
|
||||
}
|
||||
|
||||
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
|
||||
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
|
||||
@ -102,11 +109,14 @@ namespace i2p
|
||||
void RouterContext::NewNTCP2Keys ()
|
||||
{
|
||||
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
|
||||
RAND_bytes (m_NTCP2Keys->staticKey, 32);
|
||||
RAND_bytes (m_NTCP2Keys->staticPrivateKey, 32);
|
||||
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
|
||||
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)
|
||||
@ -455,9 +465,13 @@ namespace i2p
|
||||
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
|
||||
n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
|
||||
}
|
||||
n2k.close ();
|
||||
}
|
||||
if (!m_NTCP2Keys)
|
||||
if (!m_NTCP2Keys)
|
||||
{
|
||||
NewNTCP2Keys ();
|
||||
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -37,7 +37,8 @@ namespace i2p
|
||||
|
||||
struct NTCP2PrivateKeys
|
||||
{
|
||||
uint8_t staticKey[32];
|
||||
uint8_t staticPublicKey[32];
|
||||
uint8_t staticPrivateKey[32];
|
||||
uint8_t iv[16];
|
||||
};
|
||||
|
||||
@ -58,6 +59,9 @@ namespace i2p
|
||||
return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
|
||||
[](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 GetStartupTime () const { return m_StartupTime; };
|
||||
|
@ -176,10 +176,14 @@ namespace data
|
||||
auto address = std::make_shared<Address>();
|
||||
s.read ((char *)&address->cost, sizeof (address->cost));
|
||||
s.read ((char *)&address->date, sizeof (address->date));
|
||||
char transportStyle[5];
|
||||
ReadString (transportStyle, 5, s);
|
||||
if (!strcmp (transportStyle, "NTCP"))
|
||||
bool isNtcp2 = false;
|
||||
char transportStyle[6];
|
||||
auto transportStyleLen = ReadString (transportStyle, 6, s) - 1;
|
||||
if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2
|
||||
{
|
||||
address->transportStyle = eTransportNTCP;
|
||||
if (transportStyleLen > 4 || transportStyle[4] == '2') isNtcp2= true;
|
||||
}
|
||||
else if (!strcmp (transportStyle, "SSU"))
|
||||
{
|
||||
address->transportStyle = eTransportSSU;
|
||||
@ -288,7 +292,7 @@ namespace data
|
||||
if (!s) return;
|
||||
}
|
||||
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);
|
||||
m_SupportedTransports |= supportedTransports;
|
||||
@ -435,7 +439,7 @@ namespace data
|
||||
s.write ((const char *)&address.date, sizeof (address.date));
|
||||
std::stringstream properties;
|
||||
if (address.transportStyle == eTransportNTCP)
|
||||
WriteString ("NTCP", s);
|
||||
WriteString (address.IsNTCP2 () ? "NTCP2" : "NTCP", s);
|
||||
else if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
WriteString ("SSU", s);
|
||||
@ -451,10 +455,13 @@ namespace data
|
||||
else
|
||||
WriteString ("", s);
|
||||
|
||||
WriteString ("host", properties);
|
||||
properties << '=';
|
||||
WriteString (address.host.to_string (), properties);
|
||||
properties << ';';
|
||||
if (!address.IsNTCP2 ()) // we don't publish NTCP2 address fow now. TODO: implement
|
||||
{
|
||||
WriteString ("host", properties);
|
||||
properties << '=';
|
||||
WriteString (address.host.to_string (), properties);
|
||||
properties << ';';
|
||||
}
|
||||
if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
// write introducers if any
|
||||
@ -529,10 +536,23 @@ namespace data
|
||||
properties << ';';
|
||||
}
|
||||
}
|
||||
WriteString ("port", properties);
|
||||
properties << '=';
|
||||
WriteString (boost::lexical_cast<std::string>(address.port), properties);
|
||||
properties << ';';
|
||||
|
||||
if (!address.IsNTCP2 ()) // we don't publish NTCP2 address fow now. TODO: implement
|
||||
{
|
||||
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 ());
|
||||
s.write ((char *)&size, sizeof (size));
|
||||
@ -668,6 +688,21 @@ namespace data
|
||||
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)
|
||||
{
|
||||
for (auto& addr : *m_Addresses)
|
||||
|
@ -92,8 +92,8 @@ namespace data
|
||||
|
||||
struct NTCP2Ext
|
||||
{
|
||||
uint8_t staticKey[32];
|
||||
uint8_t iv[16];
|
||||
Tag<32> staticKey;
|
||||
Tag<16> iv;
|
||||
};
|
||||
|
||||
struct Address
|
||||
@ -122,6 +122,8 @@ namespace data
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool IsNTCP2 () const { return (bool)ntcp2; };
|
||||
};
|
||||
typedef std::list<std::shared_ptr<Address> > Addresses;
|
||||
|
||||
@ -143,6 +145,7 @@ namespace data
|
||||
|
||||
void AddNTCPAddress (const char * host, int port);
|
||||
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 RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
|
||||
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only
|
||||
|
Loading…
Reference in New Issue
Block a user