diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 126de7fc..a7bc305c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -59,6 +59,7 @@ namespace config { ("ntcp", value()->default_value(true), "Enable NTCP transport") ("ssu", value()->default_value(true), "Enable SSU transport") ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") + ("ntcp2", value()->zero_tokens()->default_value(false), "Enable NTCP2 (experimental)") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", value()->zero_tokens()->default_value(false), "Prevent system from sleeping") diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index a82ace85..b0f1aa51 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,4 +1,5 @@ #include +#include #include "Config.h" #include "Crypto.h" #include "Timestamp.h" @@ -98,6 +99,16 @@ namespace i2p m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch (); } + void RouterContext::NewNTCP2Keys () + { + m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); + RAND_bytes (m_NTCP2Keys->staticKey, 32); + RAND_bytes (m_NTCP2Keys->iv, 16); + // save + std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); + fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); + } + void RouterContext::SetStatus (RouterStatus status) { if (status != m_Status) @@ -429,6 +440,26 @@ namespace i2p if (IsUnreachable ()) SetReachable (); // we assume reachable until we discover firewall through peer tests + // read NTCP2 + bool ntcp2; i2p::config::GetOption("ntcp2", ntcp2); + if (ntcp2) + { + std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary); + if (n2k) + { + n2k.seekg (0, std::ios::end); + len = fk.tellg(); + n2k.seekg (0, std::ios::beg); + if (len == sizeof (NTCP2PrivateKeys)) + { + m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); + n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); + } + } + if (!m_NTCP2Keys) + NewNTCP2Keys (); + } + return true; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 4bd324f5..02c0156b 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -14,6 +14,7 @@ namespace i2p { const char ROUTER_INFO[] = "router.info"; const char ROUTER_KEYS[] = "router.keys"; + const char NTCP2_KEYS[] = "ntcp2.keys"; const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes enum RouterStatus @@ -32,6 +33,14 @@ namespace i2p class RouterContext: public i2p::garlic::GarlicDestination { + private: + + struct NTCP2PrivateKeys + { + uint8_t staticKey[32]; + uint8_t iv[16]; + }; + public: RouterContext (); @@ -108,6 +117,7 @@ namespace i2p void CreateNewRouter (); void NewRouterInfo (); void UpdateRouterInfo (); + void NewNTCP2Keys (); bool Load (); void SaveKeys (); @@ -125,6 +135,7 @@ namespace i2p RouterError m_Error; int m_NetID; std::mutex m_GarlicMutex; + std::unique_ptr m_NTCP2Keys; }; extern RouterContext context;