From 43d458cf726d59f352082d414f8436b343c32ee0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Mar 2021 13:08:10 -0400 Subject: [PATCH 0001/2193] publish and upublish NTCP2 and yggdrasil addresses separatly --- daemon/Daemon.cpp | 6 +++--- libi2pd/RouterContext.cpp | 10 ++++++---- libi2pd/RouterContext.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 51783068..882e94f6 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -218,7 +218,7 @@ namespace util { uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port); if (!ntcp2port) ntcp2port = port; // use standard port - i2p::context.PublishNTCP2Address (ntcp2port, true); // publish + i2p::context.PublishNTCP2Address (ntcp2port, true, ipv4, ipv6, false); // publish if (ipv6) { std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr); @@ -228,12 +228,12 @@ namespace util } } else - i2p::context.PublishNTCP2Address (port, false); // unpublish + i2p::context.PublishNTCP2Address (port, false, ipv4, ipv6, false); // unpublish } if (ygg) { if (!ntcp2) - i2p::context.PublishNTCP2Address (port, true); + i2p::context.PublishNTCP2Address (port, true, false, false, true); i2p::context.UpdateNTCP2V6Address (yggaddr); if (!ipv4 && !ipv6) i2p::context.SetStatus (eRouterStatusMesh); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 00d467db..9451cca5 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -225,13 +225,15 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4only) + void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg) { if (!m_NTCP2Keys) return; bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { - if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish) && (!v4only || address->IsV4 ())) + if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish) + && ((v4 && address->IsV4 ()) || (v6 && address->IsV6 ()) || + (ygg && i2p::util::net::IsYggdrasilAddress (address->host)))) { if (!port && !address->port) { @@ -457,7 +459,7 @@ namespace i2p // remove NTCP2 v4 address bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) - PublishNTCP2Address (port, false, true); + PublishNTCP2Address (port, false, true, false, false); // ipv4 only // update UpdateRouterInfo (); } @@ -491,7 +493,7 @@ namespace i2p { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; - PublishNTCP2Address (ntcp2Port, true, true); + PublishNTCP2Address (ntcp2Port, true, true, false, false); // ipv4 only } } // update diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index fe6c9ec9..ee66a83c 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -97,7 +97,7 @@ namespace garlic void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon - void PublishNTCP2Address (int port, bool publish = true, bool v4only = false); + void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); void UpdateNTCP2Address (bool enable); void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); From 1d5d06f7311a3e82a4a888c7ad8306b3c1efe3a5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Mar 2021 15:23:00 -0400 Subject: [PATCH 0002/2193] find actual router for peer --- libi2pd/Transports.cpp | 13 +++++++++---- libi2pd/TunnelPool.cpp | 6 ++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 9265f289..9f3e75b7 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -772,10 +772,15 @@ namespace transport std::shared_ptr Transports::GetRandomPeer () const { if (m_Peers.empty ()) return nullptr; - std::unique_lock l(m_PeersMutex); - auto it = m_Peers.begin (); - std::advance (it, rand () % m_Peers.size ()); - return it != m_Peers.end () ? it->second.router : nullptr; + i2p::data::IdentHash ident; + { + std::unique_lock l(m_PeersMutex); + auto it = m_Peers.begin (); + std::advance (it, rand () % m_Peers.size ()); + if (it == m_Peers.end () || it->second.router) return nullptr; // not connected + ident = it->first; + } + return i2p::data::netdb.FindRouter (ident); } void Transports::RestrictRoutesToFamilies(std::set families) { diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 417f5f15..038bbb0f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -406,6 +406,7 @@ namespace tunnel bool StandardSelectPeers(Path & peers, int numHops, bool inbound, SelectHopFunc nextHop) { + int start = 0; auto prevHop = i2p::context.GetSharedRouterInfo (); if(i2p::transport::transports.RoutesRestricted()) { @@ -414,6 +415,7 @@ namespace tunnel if(!hop) return false; peers.push_back(hop->GetRouterIdentity()); prevHop = hop; + start++; } else if (i2p::transport::transports.GetNumPeers () > 25) { @@ -423,11 +425,11 @@ namespace tunnel { prevHop = r; peers.push_back (r->GetRouterIdentity ()); - numHops--; + start++; } } - for(int i = 0; i < numHops; i++ ) + for(int i = start; i < numHops; i++ ) { auto hop = nextHop (prevHop, inbound); if (!hop && !i) // if no suitable peer found for first hop, try already connected From 820a36547465a5d21cc7d0bf47a5af37a44d32d8 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Mar 2021 18:45:51 -0400 Subject: [PATCH 0003/2193] select random peer for first hop for outbound tunnel if number of connections < 100 --- libi2pd/TunnelPool.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 038bbb0f..7cb79956 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -417,7 +417,8 @@ namespace tunnel prevHop = hop; start++; } - else if (i2p::transport::transports.GetNumPeers () > 25) + else if (i2p::transport::transports.GetNumPeers () > 100 || + (inbound && i2p::transport::transports.GetNumPeers () > 25)) { auto r = i2p::transport::transports.GetRandomPeer (); if (r && !r->GetProfile ()->IsBad () && From a7b56bbbb748c05bfdaf0c13a68493817ef7d41f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Mar 2021 11:26:52 -0400 Subject: [PATCH 0004/2193] publish Yggdrasil address when enabled --- daemon/Daemon.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 882e94f6..9fffe5a8 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -232,8 +232,7 @@ namespace util } if (ygg) { - if (!ntcp2) - i2p::context.PublishNTCP2Address (port, true, false, false, true); + i2p::context.PublishNTCP2Address (port, true, false, false, true); i2p::context.UpdateNTCP2V6Address (yggaddr); if (!ipv4 && !ipv6) i2p::context.SetStatus (eRouterStatusMesh); From ff9ee5873f9591cdc4704dc1deab7eabfd911199 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Mar 2021 15:10:14 -0400 Subject: [PATCH 0005/2193] post LeaseSet creation to I2CP destnation's thread --- libi2pd_client/I2CP.cpp | 5 +++++ libi2pd_client/I2CP.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index c9db4a82..5cd1812a 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -85,6 +85,11 @@ namespace client } void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) + { + GetService ().post (std::bind (&I2CPDestination::PostCreateNewLeaseSet, this, tunnels)); + } + + void I2CPDestination::PostCreateNewLeaseSet (std::vector > tunnels) { if (m_IsCreatingLeaseSet) { diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index da7d8ffa..983951a4 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -101,6 +101,8 @@ namespace client { return std::static_pointer_cast(shared_from_this ()); } bool SendMsg (std::shared_ptr msg, std::shared_ptr remote); + void PostCreateNewLeaseSet (std::vector > tunnels); + private: std::shared_ptr m_Owner; From ef1dfb153cad6158584e4e90b2cf4d3912f71c1e Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 18 Mar 2021 18:37:02 -0400 Subject: [PATCH 0006/2193] handle ipv6 address for RelayIntro --- libi2pd/SSUSession.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index f9dbee5e..5e0c9b9b 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -716,18 +716,36 @@ namespace transport void SSUSession::ProcessRelayIntro (const uint8_t * buf, size_t len) { + if (!len) return; uint8_t size = *buf; + if ((int)len < 1 + size + 2) // size + address + port + { + LogPrint (eLogWarning, "SSU: Relay intro is too short ", len); + return; + } + buf++; // size + boost::asio::ip::address ip; if (size == 4) { - buf++; // size - boost::asio::ip::address_v4 address (bufbe32toh (buf)); - buf += 4; // address - uint16_t port = bufbe16toh (buf); - // send hole punch of 0 bytes - m_Server.Send (buf, 0, boost::asio::ip::udp::endpoint (address, port)); + boost::asio::ip::address_v4::bytes_type bytes; + memcpy (bytes.data (), buf, 4); + ip = boost::asio::ip::address_v4 (bytes); } + else if (size == 16) + { + boost::asio::ip::address_v6::bytes_type bytes; + memcpy (bytes.data (), buf, 16); + ip = boost::asio::ip::address_v6 (bytes); + } else + { LogPrint (eLogWarning, "SSU: Address size ", size, " is not supported"); + return; + } + buf += size; + uint16_t port = bufbe16toh (buf); + // send hole punch of 0 bytes + m_Server.Send (buf, 0, boost::asio::ip::udp::endpoint (ip, port)); } void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, From a9c7d0d59878c5e7eb231963c7309a6daf25a79a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 18 Mar 2021 20:11:24 -0400 Subject: [PATCH 0007/2193] common ExtractIPAddressAndPort --- libi2pd/SSUSession.cpp | 94 ++++++++++++++++++++---------------------- libi2pd/SSUSession.h | 2 + 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 5e0c9b9b..47c5e017 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -257,27 +257,14 @@ namespace transport s.Insert (m_DHKeysPair->GetPublicKey (), 256); // x s.Insert (y, 256); // y payload += 256; - uint8_t addressSize = *payload; - payload += 1; // size - uint8_t * ourAddress = payload; boost::asio::ip::address ourIP; - if (addressSize == 4) // v4 - { - boost::asio::ip::address_v4::bytes_type bytes; - memcpy (bytes.data (), ourAddress, 4); - ourIP = boost::asio::ip::address_v4 (bytes); - } - else // v6 - { - boost::asio::ip::address_v6::bytes_type bytes; - memcpy (bytes.data (), ourAddress, 16); - ourIP = boost::asio::ip::address_v6 (bytes); - } - s.Insert (ourAddress, addressSize); // our IP - payload += addressSize; // address - uint16_t ourPort = bufbe16toh (payload); - s.Insert (payload, 2); // our port - payload += 2; // port + uint16_t ourPort = 0; + auto addressAndPortLen = ExtractIPAddressAndPort (payload, len, ourIP, ourPort); + if (!addressAndPortLen) return; + uint8_t * ourAddressAndPort = payload + 1; + payload += addressAndPortLen; + addressAndPortLen--; // -1 byte address size + s.Insert (ourAddressAndPort, addressAndPortLen); // address + port if (m_RemoteEndpoint.address ().is_v4 ()) s.Insert (m_RemoteEndpoint.address ().to_v4 ().to_bytes ().data (), 4); // remote IP v4 else @@ -309,7 +296,7 @@ namespace transport { LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); i2p::context.UpdateAddress (ourIP); - SendSessionConfirmed (y, ourAddress, addressSize + 2); + SendSessionConfirmed (y, ourAddressAndPort, addressAndPortLen); } else { @@ -716,36 +703,12 @@ namespace transport void SSUSession::ProcessRelayIntro (const uint8_t * buf, size_t len) { - if (!len) return; - uint8_t size = *buf; - if ((int)len < 1 + size + 2) // size + address + port - { - LogPrint (eLogWarning, "SSU: Relay intro is too short ", len); - return; - } - buf++; // size boost::asio::ip::address ip; - if (size == 4) - { - boost::asio::ip::address_v4::bytes_type bytes; - memcpy (bytes.data (), buf, 4); - ip = boost::asio::ip::address_v4 (bytes); - } - else if (size == 16) - { - boost::asio::ip::address_v6::bytes_type bytes; - memcpy (bytes.data (), buf, 16); - ip = boost::asio::ip::address_v6 (bytes); - } - else - { - LogPrint (eLogWarning, "SSU: Address size ", size, " is not supported"); - return; - } - buf += size; - uint16_t port = bufbe16toh (buf); - // send hole punch of 0 bytes - m_Server.Send (buf, 0, boost::asio::ip::udp::endpoint (ip, port)); + uint16_t port = 0; + ExtractIPAddressAndPort (buf, len, ip, port); + if (!ip.is_unspecified () && port) + // send hole punch of 0 bytes + m_Server.Send (buf, 0, boost::asio::ip::udp::endpoint (ip, port)); } void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, @@ -1251,5 +1214,36 @@ namespace transport i2p::transport::transports.UpdateSentBytes (size); m_Server.Send (buf, size, m_RemoteEndpoint); } + + size_t SSUSession::ExtractIPAddressAndPort (const uint8_t * buf, size_t len, boost::asio::ip::address& ip, uint16_t& port) + { + if (!len) return 0; + uint8_t size = *buf; + size_t s = 1 + size + 2; // size + address + port + if (len < s) + { + LogPrint (eLogWarning, "SSU: Address is too short ", len); + port = 0; + return len; + } + buf++; // size + if (size == 4) + { + boost::asio::ip::address_v4::bytes_type bytes; + memcpy (bytes.data (), buf, 4); + ip = boost::asio::ip::address_v4 (bytes); + } + else if (size == 16) + { + boost::asio::ip::address_v6::bytes_type bytes; + memcpy (bytes.data (), buf, 16); + ip = boost::asio::ip::address_v6 (bytes); + } + else + LogPrint (eLogWarning, "SSU: Address size ", size, " is not supported"); + buf += size; + port = bufbe16toh (buf); + return s; + } } } diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 3aa04638..ece8f5bf 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -145,6 +145,8 @@ namespace transport void Reset (); + static size_t ExtractIPAddressAndPort (const uint8_t * buf, size_t len, boost::asio::ip::address& ip, uint16_t& port); // returns actual buf size + private: friend class SSUData; // TODO: change in later From 6b0c7c2313b60bb218d8924480fb6820ffe3b59a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 18 Mar 2021 21:29:39 -0400 Subject: [PATCH 0008/2193] handle ipv6 address in RelayResponse --- libi2pd/SSUSession.cpp | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 47c5e017..d1dc7aec 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -645,30 +645,16 @@ namespace transport void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len) { LogPrint (eLogDebug, "SSU message: Relay response received"); - uint8_t remoteSize = *buf; - buf++; // remote size - boost::asio::ip::address_v4 remoteIP (bufbe32toh (buf)); - buf += remoteSize; // remote address - uint16_t remotePort = bufbe16toh (buf); - buf += 2; // remote port - uint8_t ourSize = *buf; - buf++; // our size + boost::asio::ip::address remoteIP; + uint16_t remotePort = 0; + auto remoteSize = ExtractIPAddressAndPort (buf, len, remoteIP, remotePort); + if (!remoteSize) return; + buf += remoteSize; len -= remoteSize; boost::asio::ip::address ourIP; - if (ourSize == 4) - { - boost::asio::ip::address_v4::bytes_type bytes; - memcpy (bytes.data (), buf, 4); - ourIP = boost::asio::ip::address_v4 (bytes); - } - else - { - boost::asio::ip::address_v6::bytes_type bytes; - memcpy (bytes.data (), buf, 16); - ourIP = boost::asio::ip::address_v6 (bytes); - } - buf += ourSize; // our address - uint16_t ourPort = bufbe16toh (buf); - buf += 2; // our port + uint16_t ourPort = 0; + auto ourSize = ExtractIPAddressAndPort (buf, len, ourIP, ourPort); + if (!ourSize) return; + buf += ourSize; len -= ourSize; LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); i2p::context.UpdateAddress (ourIP); if (ourPort != m_Server.GetPort ()) From 589049ef0f20b0d19480d509386a2aab66ecbada Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Mar 2021 10:20:02 -0400 Subject: [PATCH 0009/2193] connect to ipv6 address through introducer --- libi2pd/SSU.cpp | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 3b2dc122..04da5f7c 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -482,12 +482,16 @@ namespace transport { if (router && router->UsesIntroducer () && address) { + if (address->IsV4 () && !i2p::context.SupportsV4 ()) return; + if (address->IsV6 () && !i2p::context.SupportsV6 ()) return; if (!address->host.is_unspecified () && address->port) { + // we rarely come here + auto& sessions = address->host.is_v6 () ? m_SessionsV6 : m_Sessions; boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port); - auto it = m_Sessions.find (remoteEndpoint); + auto it = sessions.find (remoteEndpoint); // check if session is presented already - if (it != m_Sessions.end ()) + if (it != sessions.end ()) { auto session = it->second; if (peerTest && session->GetState () == eSessionStateEstablished) @@ -508,9 +512,9 @@ namespace transport auto intr = &(address->ssu->introducers[i]); if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort); - if (ep.address ().is_v4 ()) // ipv4 only + if (ep.address ().is_v4 () && address->IsV4 ()) // ipv4 { - if (!introducer) introducer = intr; // we pick first one for now + if (!introducer) introducer = intr; auto it = m_Sessions.find (ep); if (it != m_Sessions.end ()) { @@ -518,10 +522,20 @@ namespace transport break; } } + if (ep.address ().is_v6 () && address->IsV6 ()) // ipv6 + { + if (!introducer) introducer = intr; + auto it = m_SessionsV6.find (ep); + if (it != m_SessionsV6.end ()) + { + introducerSession = it->second; + break; + } + } } if (!introducer) { - LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented"); + LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no compatibe non-expired introducers presented"); return; } @@ -532,14 +546,20 @@ namespace transport LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost); boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort); introducerSession = std::make_shared (*this, introducerEndpoint, router); - m_Sessions[introducerEndpoint] = introducerSession; + if (introducerEndpoint.address ().is_v4 ()) + m_Sessions[introducerEndpoint] = introducerSession; + else if (introducerEndpoint.address ().is_v6 ()) + m_SessionsV6[introducerEndpoint] = introducerSession; } if (!address->host.is_unspecified () && address->port) { // create session boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port); auto session = std::make_shared (*this, remoteEndpoint, router, peerTest); - m_Sessions[remoteEndpoint] = session; + if (address->host.is_v4 ()) + m_Sessions[remoteEndpoint] = session; + else if (address->host.is_v6 ()) + m_SessionsV6[remoteEndpoint] = session; // introduce LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), From 991b74f036acae38e717ab1dc1d65ccafd876b12 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Mar 2021 13:10:24 -0400 Subject: [PATCH 0010/2193] bind ipv6 or yggdrasil acceptor to specified address --- libi2pd/NTCP2.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ffd9bb7d..e872eeaa 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1193,7 +1193,12 @@ namespace transport m_NTCP2V6Acceptor->open (boost::asio::ip::tcp::v6()); m_NTCP2V6Acceptor->set_option (boost::asio::ip::v6_only (true)); m_NTCP2V6Acceptor->set_option (boost::asio::socket_base::reuse_address (true)); - m_NTCP2V6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); + auto ep = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port); + if (m_Address6 && !context.SupportsMesh ()) + ep = boost::asio::ip::tcp::endpoint (m_Address6->address(), address->port); + else if (m_YggdrasilAddress && !context.SupportsV6 ()) + ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port); + m_NTCP2V6Acceptor->bind (ep); m_NTCP2V6Acceptor->listen (); LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); From ac10f3055d648c8718c668ae772d4f94c0145503 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 19 Mar 2021 21:51:45 -0400 Subject: [PATCH 0011/2193] pick correct local SSU address for sending peer test --- libi2pd/SSUSession.cpp | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index d1dc7aec..f7d5214e 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -953,15 +953,15 @@ namespace transport void SSUSession::ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) { uint32_t nonce = bufbe32toh (buf); // 4 bytes - uint8_t size = buf[4]; // 1 byte - const uint8_t * address = buf + 5; // big endian, size bytes - uint16_t port = buf16toh(buf + size + 5); // big endian, 2 bytes - const uint8_t * introKey = buf + size + 7; - if (port && (size != 4) && (size != 16)) + boost::asio::ip::address addr; // Alice's addresss + uint16_t port = 0; // and port + auto size = ExtractIPAddressAndPort (buf + 4, len - 4, addr, port); + if (port && (size != 7) && (size != 19)) { - LogPrint (eLogWarning, "SSU: Address of ", size, " bytes not supported"); + LogPrint (eLogWarning, "SSU: Address of ", size - 3, " bytes not supported"); return; } + const uint8_t * introKey = buf + 4 + size; switch (m_Server.GetPeerTestParticipant (nonce)) { // existing test @@ -1027,20 +1027,7 @@ namespace transport LogPrint (eLogDebug, "SSU: peer test from Bob. We are Charlie"); m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie); Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Bob - boost::asio::ip::address addr; // Alice's address - if (size == 4) // v4 - { - boost::asio::ip::address_v4::bytes_type bytes; - memcpy (bytes.data (), address, 4); - addr = boost::asio::ip::address_v4 (bytes); - } - else // v6 - { - boost::asio::ip::address_v6::bytes_type bytes; - memcpy (bytes.data (), address, 16); - addr = boost::asio::ip::address_v6 (bytes); - } - SendPeerTest (nonce, addr, be16toh (port), introKey); // to Alice with her address received from Bob + SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob } else { @@ -1097,7 +1084,8 @@ namespace transport if (toAddress) { // send our intro key to address instead of its own - auto addr = i2p::context.GetRouterInfo ().GetSSUAddress (); + auto addr = address.is_v4 () ? i2p::context.GetRouterInfo ().GetSSUAddress (true) : // ipv4 + i2p::context.GetRouterInfo ().GetSSUV6Address (); if (addr) memcpy (payload, addr->ssu->key, 32); // intro key else From 34eee2fc26826b5a9544523d148c8a47f4ccfc73 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 22 Mar 2021 20:12:58 -0400 Subject: [PATCH 0012/2193] fixed #1644. check leaseset buffer size --- libi2pd/LeaseSet.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index b90d6d85..2279319a 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -72,6 +72,12 @@ namespace data } size += 256; // encryption key size += m_Identity->GetSigningPublicKeyLen (); // unused signing key + if (size + 1 > m_BufferLen) + { + LogPrint (eLogError, "LeaseSet: ", size, " exceeds buffer size ", m_BufferLen); + m_IsValid = false; + return; + } uint8_t num = m_Buffer[size]; size++; // num LogPrint (eLogDebug, "LeaseSet: read num=", (int)num); @@ -81,9 +87,14 @@ namespace data m_IsValid = false; return; } - + if (size + num*LEASE_SIZE > m_BufferLen) + { + LogPrint (eLogError, "LeaseSet: ", size, " exceeds buffer size ", m_BufferLen); + m_IsValid = false; + return; + } + UpdateLeasesBegin (); - // process leases m_ExpirationTime = 0; auto ts = i2p::util::GetMillisecondsSinceEpoch (); @@ -106,14 +117,22 @@ namespace data return; } m_ExpirationTime += LEASE_ENDDATE_THRESHOLD; - UpdateLeasesEnd (); // verify - if (verifySignature && !m_Identity->Verify (m_Buffer, leases - m_Buffer, leases)) - { - LogPrint (eLogWarning, "LeaseSet: verification failed"); - m_IsValid = false; + if (verifySignature) + { + auto signedSize = leases - m_Buffer; + if (signedSize + m_Identity->GetSignatureLen () > m_BufferLen) + { + LogPrint (eLogError, "LeaseSet: Signature exceeds buffer size ", m_BufferLen); + m_IsValid = false; + } + else if (!m_Identity->Verify (m_Buffer, signedSize, leases)) + { + LogPrint (eLogWarning, "LeaseSet: verification failed"); + m_IsValid = false; + } } } From 9e050d1a23678f0adbe156a33b343d858e8da7e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 23 Mar 2021 15:36:57 -0400 Subject: [PATCH 0013/2193] peer test for ipv6 --- daemon/HTTPServer.cpp | 23 +++++++++---- libi2pd/NetDb.cpp | 6 ++-- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterContext.cpp | 8 ++++- libi2pd/RouterContext.h | 4 ++- libi2pd/RouterInfo.cpp | 12 +++---- libi2pd/RouterInfo.h | 2 +- libi2pd/SSUSession.cpp | 17 ++++++++-- libi2pd/Transports.cpp | 70 +++++++++++++++++---------------------- 9 files changed, 82 insertions(+), 62 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 4741e5cf..c263cea9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -242,13 +242,9 @@ namespace http { s << "ERROR: " << string << "
\r\n"; } - void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) + static void ShowNetworkStatus (std::stringstream& s, RouterStatus status) { - s << "Uptime: "; - ShowUptime(s, i2p::context.GetUptime ()); - s << "
\r\n"; - s << "Network status: "; - switch (i2p::context.GetStatus ()) + switch (status) { case eRouterStatusOK: s << "OK"; break; case eRouterStatusTesting: s << "Testing"; break; @@ -276,7 +272,22 @@ namespace http { } default: s << "Unknown"; } + } + + void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) + { + s << "Uptime: "; + ShowUptime(s, i2p::context.GetUptime ()); s << "
\r\n"; + s << "Network status: "; + ShowNetworkStatus (s, i2p::context.GetStatus ()); + s << "
\r\n"; + if (i2p::context.SupportsV6 ()) + { + s << "Network status 6: "; + ShowNetworkStatus (s, i2p::context.GetStatusV6 ()); + s << "
\r\n"; + } #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (auto remains = Daemon.gracefulShutdownInterval) { s << "Stopping in: "; diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 076a8665..a50a796f 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1149,12 +1149,12 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4only) const + std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4) const { return GetRandomRouter ( - [v4only](std::shared_ptr router)->bool + [v4](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsPeerTesting (v4only); + return !router->IsHidden () && router->IsPeerTesting (v4); }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 5dbef743..891bc35d 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -85,7 +85,7 @@ namespace data std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; - std::shared_ptr GetRandomPeerTestRouter (bool v4only = true) const; + std::shared_ptr GetRandomPeerTestRouter (bool v4) const; std::shared_ptr GetRandomSSUV6Router () const; // TODO: change to v6 peer test later std::shared_ptr GetRandomIntroducer () const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 9451cca5..ff0063a7 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -28,7 +28,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_ShareRatio (100), m_Status (eRouterStatusUnknown), + m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusOK), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -210,6 +210,12 @@ namespace i2p } } + void RouterContext::SetStatusV6 (RouterStatus status) + { + if (status != m_StatusV6) + m_StatusV6 = status; + } + void RouterContext::UpdatePort (int port) { bool updated = false; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ee66a83c..158dd809 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -91,6 +91,8 @@ namespace garlic void SetStatus (RouterStatus status); RouterError GetError () const { return m_Error; }; void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; }; + RouterStatus GetStatusV6 () const { return m_StatusV6; }; + void SetStatusV6 (RouterStatus status); int GetNetID () const { return m_NetID; }; void SetNetID (int netID) { m_NetID = netID; }; bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); @@ -168,7 +170,7 @@ namespace garlic std::chrono::time_point m_StartupTime; uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; - RouterStatus m_Status; + RouterStatus m_Status, m_StatusV6; RouterError m_Error; int m_NetID; std::mutex m_GarlicMutex; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 2157dd37..53077235 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1100,15 +1100,15 @@ namespace data GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } - bool RouterInfo::IsPeerTesting (bool v4only) const + bool RouterInfo::IsPeerTesting (bool v4) const { - auto supportedTransports = m_SupportedTransports & (eSSUV4 | eSSUV6); - if (!supportedTransports) return false; // no SSU - if (v4only && !(supportedTransports & eSSUV4)) return false; // no SSU v4 + auto supportedTransports = m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6); + if (!supportedTransports) return false; return (bool)GetAddress ( - [](std::shared_ptr address)->bool + [v4](std::shared_ptr address)->bool { - return (address->transportStyle == eTransportSSU) && address->IsPeerTesting (); + return (address->transportStyle == eTransportSSU) && address->IsPeerTesting () && + ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())); }); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 93746e95..72818931 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -209,7 +209,7 @@ namespace data bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsEligibleFloodfill () const; - bool IsPeerTesting (bool v4only) const; + bool IsPeerTesting (bool v4) const; bool IsIntroducer () const; uint8_t GetCaps () const { return m_Caps; }; diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index f7d5214e..66579a16 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -970,7 +970,12 @@ namespace transport if (m_Server.GetPeerTestSession (nonce) == shared_from_this ()) // Alice-Bob { LogPrint (eLogDebug, "SSU: peer test from Bob. We are Alice"); - if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK + if (IsV6 ()) + { + if (i2p::context.GetStatusV6 () == eRouterStatusTesting) + i2p::context.SetStatusV6 (eRouterStatusFirewalled); + } + else if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK { i2p::context.SetStatus (eRouterStatusFirewalled); m_Server.RescheduleIntroducersUpdateTimer (); @@ -981,7 +986,10 @@ namespace transport LogPrint (eLogDebug, "SSU: first peer test from Charlie. We are Alice"); if (m_State == eSessionStateEstablished) LogPrint (eLogWarning, "SSU: first peer test from Charlie through established session. We are Alice"); - i2p::context.SetStatus (eRouterStatusOK); + if (IsV6 ()) + i2p::context.SetStatusV6 (eRouterStatusOK); + else + i2p::context.SetStatus (eRouterStatusOK); m_Server.UpdatePeerTest (nonce, ePeerTestParticipantAlice2); SendPeerTest (nonce, senderEndpoint.address (), senderEndpoint.port (), introKey, true, false); // to Charlie } @@ -995,7 +1003,10 @@ namespace transport { // peer test successive LogPrint (eLogDebug, "SSU: second peer test from Charlie. We are Alice"); - i2p::context.SetStatus (eRouterStatusOK); + if (IsV6 ()) + i2p::context.SetStatusV6 (eRouterStatusOK); + else + i2p::context.SetStatus (eRouterStatusOK); m_Server.RemovePeerTest (nonce); } break; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 9f3e75b7..78b45e32 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -576,55 +576,21 @@ namespace transport return; } if (m_SSUServer) - { - bool isv4 = i2p::context.SupportsV4 (); - if (m_IsNAT && isv4) - i2p::context.SetStatus (eRouterStatusTesting); - for (int i = 0; i < 5; i++) - { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4 - if (router) - m_SSUServer->CreateSession (router, true, isv4); // peer test - else - { - // if not peer test capable routers found pick any - router = i2p::data::netdb.GetRandomRouter (); - if (router && router->IsSSU ()) - m_SSUServer->CreateSession (router); // no peer test - } - } - if (i2p::context.SupportsV6 ()) - { - // try to connect to few v6 addresses to get our address back - for (int i = 0; i < 3; i++) - { - auto router = i2p::data::netdb.GetRandomSSUV6Router (); - if (router) - { - auto addr = router->GetSSUV6Address (); - if (addr) - m_SSUServer->GetService ().post ([this, router, addr] - { - m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); - }); - } - } - } - } + PeerTest (); else LogPrint (eLogError, "Transports: Can't detect external IP. SSU is not available"); } void Transports::PeerTest () { - if (RoutesRestricted() || !i2p::context.SupportsV4 ()) return; - if (m_SSUServer) + if (RoutesRestricted() || !m_SSUServer) return; + if (i2p::context.SupportsV4 ()) { - LogPrint (eLogInfo, "Transports: Started peer test"); + LogPrint (eLogInfo, "Transports: Started peer test ipv4"); bool statusChanged = false; for (int i = 0; i < 5; i++) { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 only + auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 if (router) { if (!statusChanged) @@ -636,8 +602,32 @@ namespace transport } } if (!statusChanged) - LogPrint (eLogWarning, "Transports: Can't find routers for peer test"); + LogPrint (eLogWarning, "Transports: Can't find routers for peer test ipv4"); } + if (i2p::context.SupportsV6 ()) + { + LogPrint (eLogInfo, "Transports: Started peer test ipv6"); + bool statusChanged = false; + for (int i = 0; i < 5; i++) + { + auto router = i2p::data::netdb.GetRandomPeerTestRouter (false); // v6 + if (router) + { + auto addr = router->GetSSUV6Address (); + if (addr) + { + if (!statusChanged) + { + statusChanged = true; + i2p::context.SetStatusV6 (eRouterStatusTesting); // first time only + } + m_SSUServer->CreateSession (router, addr, true); // peer test v6 + } + } + } + if (!statusChanged) + LogPrint (eLogWarning, "Transports: Can't find routers for peer test ipv6"); + } } std::shared_ptr Transports::GetNextX25519KeysPair () From 3695aa924b723f9e25ad66a1f427a15c7bff6ac4 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Mar 2021 10:32:15 -0400 Subject: [PATCH 0014/2193] doesn't send peer test to a reserved address --- libi2pd/SSUSession.cpp | 22 +++++++++++++--------- libi2pd/Transports.cpp | 16 ++++++++++------ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 66579a16..2e49e970 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -273,7 +273,7 @@ namespace transport s.Insert (payload, 8); // relayTag and signed on time m_RelayTag = bufbe32toh (payload); payload += 4; // relayTag - if (i2p::context.GetStatus () == eRouterStatusTesting) + if (ourIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusTesting) { auto ts = i2p::util::GetSecondsSinceEpoch (); uint32_t signedOnTime = bufbe32toh(payload); @@ -358,7 +358,9 @@ namespace transport uint8_t * payload = buf + sizeof (SSUHeader); uint8_t flag = 0; // fill extended options, 3 bytes extended options don't change message size - if (i2p::context.GetStatus () == eRouterStatusOK) // we don't need relays + bool isV4 = m_RemoteEndpoint.address ().is_v4 (); + if ((isV4 && i2p::context.GetStatus () == eRouterStatusOK) || + (!isV4 && i2p::context.GetStatusV6 () == eRouterStatusOK)) // we don't need relays { // tell out peer to now assign relay tag flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED; @@ -369,7 +371,6 @@ namespace transport } // fill payload memcpy (payload, m_DHKeysPair->GetPublicKey (), 256); // x - bool isV4 = m_RemoteEndpoint.address ().is_v4 (); if (isV4) { payload[256] = 4; @@ -657,13 +658,16 @@ namespace transport buf += ourSize; len -= ourSize; LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); i2p::context.UpdateAddress (ourIP); - if (ourPort != m_Server.GetPort ()) + if (ourIP.is_v4 ()) { - if (i2p::context.GetStatus () == eRouterStatusTesting) - i2p::context.SetError (eRouterErrorSymmetricNAT); - } - else if (i2p::context.GetStatus () == eRouterStatusError && i2p::context.GetError () == eRouterErrorSymmetricNAT) - i2p::context.SetStatus (eRouterStatusTesting); + if (ourPort != m_Server.GetPort ()) + { + if (i2p::context.GetStatus () == eRouterStatusTesting) + i2p::context.SetError (eRouterErrorSymmetricNAT); + } + else if (i2p::context.GetStatus () == eRouterStatusError && i2p::context.GetError () == eRouterErrorSymmetricNAT) + i2p::context.SetStatus (eRouterStatusTesting); + } uint32_t nonce = bufbe32toh (buf); buf += 4; // nonce auto it = m_RelayRequests.find (nonce); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 78b45e32..13c1d210 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -593,12 +593,16 @@ namespace transport auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 if (router) { - if (!statusChanged) + auto addr = router->GetSSUAddress (true); // ipv4 + if (addr && !i2p::util::net::IsInReservedRange(addr->host)) { - statusChanged = true; - i2p::context.SetStatus (eRouterStatusTesting); // first time only - } - m_SSUServer->CreateSession (router, true, true); // peer test v4 + if (!statusChanged) + { + statusChanged = true; + i2p::context.SetStatus (eRouterStatusTesting); // first time only + } + m_SSUServer->CreateSession (router, addr, true); // peer test v4 + } } } if (!statusChanged) @@ -614,7 +618,7 @@ namespace transport if (router) { auto addr = router->GetSSUV6Address (); - if (addr) + if (addr && !i2p::util::net::IsInReservedRange(addr->host)) { if (!statusChanged) { From a6ea37a21ed637d4c5220455ca64843626b9da83 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 27 Mar 2021 15:16:56 -0400 Subject: [PATCH 0015/2193] set ipv6 address caps depending on peer test --- libi2pd/RouterContext.cpp | 37 +++++++++++++++++++++++++------------ libi2pd/RouterContext.h | 4 ++-- libi2pd/SSU.cpp | 2 +- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index ff0063a7..fadbb51a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -28,7 +28,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusOK), + m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -199,10 +199,10 @@ namespace i2p switch (m_Status) { case eRouterStatusOK: - SetReachable (); + SetReachable (true, false); // ipv4 break; case eRouterStatusFirewalled: - SetUnreachable (); + SetUnreachable (true, false); // ipv4 break; default: ; @@ -213,7 +213,20 @@ namespace i2p void RouterContext::SetStatusV6 (RouterStatus status) { if (status != m_StatusV6) + { m_StatusV6 = status; + switch (m_StatusV6) + { + case eRouterStatusOK: + SetReachable (false, true); // ipv6 + break; + case eRouterStatusFirewalled: + SetUnreachable (false, true); // ipv6 + break; + default: + ; + } + } } void RouterContext::UpdatePort (int port) @@ -443,7 +456,7 @@ namespace i2p } } - void RouterContext::SetUnreachable () + void RouterContext::SetUnreachable (bool v4, bool v6) { // set caps uint8_t caps = m_RouterInfo.GetCaps (); @@ -455,22 +468,22 @@ namespace i2p // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr : addresses) - if (addr->ssu) + if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) { addr->cost = i2p::data::COST_SSU_THROUGH_INTRODUCERS; addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer addr->ssu->introducers.clear (); port = addr->port; } - // remove NTCP2 v4 address + // unpiblish NTCP2 addreeses bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) - PublishNTCP2Address (port, false, true, false, false); // ipv4 only + PublishNTCP2Address (port, false, v4, v6, false); // update UpdateRouterInfo (); } - void RouterContext::SetReachable () + void RouterContext::SetReachable (bool v4, bool v6) { // update caps uint8_t caps = m_RouterInfo.GetCaps (); @@ -483,14 +496,14 @@ namespace i2p // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr : addresses) - if (addr->ssu) + if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) { addr->cost = i2p::data::COST_SSU_DIRECT; addr->caps |= i2p::data::RouterInfo::eSSUIntroducer; addr->ssu->introducers.clear (); port = addr->port; } - // insert NTCP2 back + // publish NTCP2 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -499,7 +512,7 @@ namespace i2p { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; - PublishNTCP2Address (ntcp2Port, true, true, false, false); // ipv4 only + PublishNTCP2Address (ntcp2Port, true, v4, v6, false); } } // update @@ -757,7 +770,7 @@ namespace i2p } if (IsUnreachable ()) - SetReachable (); // we assume reachable until we discover firewall through peer tests + SetReachable (true, true); // we assume reachable until we discover firewall through peer tests // read NTCP2 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 158dd809..a7594e36 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -105,8 +105,8 @@ namespace garlic bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); bool IsUnreachable () const; - void SetUnreachable (); - void SetReachable (); + void SetUnreachable (bool v4, bool v6); + void SetReachable (bool v4, bool v6); bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 04da5f7c..b9b3a04e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -706,7 +706,7 @@ namespace transport return; } // we are firewalled - if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable (); + if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable (true, false); // ipv4 std::list newList; size_t numIntroducers = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); From 86415bc61f784922399ea2df719ba6469fbf5eb7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 27 Mar 2021 18:49:35 -0400 Subject: [PATCH 0016/2193] publish introducer cap for ipv6 address --- libi2pd/RouterInfo.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 53077235..1644d93d 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -558,7 +558,10 @@ namespace data caps += CAPS_FLAG_V4; } else if (address.host.is_v6 ()) + { isPublished = true; + if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER; + } else { if (address.caps & AddressCaps::eV4) caps += CAPS_FLAG_V4; From 167d3a0e3cdaad6b3b82cea9835359855b896a8a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 28 Mar 2021 12:14:02 -0400 Subject: [PATCH 0017/2193] don't create BN_CTX for ECIES tunnel build record decryption --- libi2pd/I2NPProtocol.cpp | 5 +---- libi2pd/RouterContext.cpp | 11 ++++++++--- libi2pd/RouterContext.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 6897148b..7f059d72 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -371,10 +371,7 @@ namespace i2p if (!memcmp (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16)) { LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours"); - BN_CTX * ctx = BN_CTX_new (); - bool success = i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); - BN_CTX_free (ctx); - if(!success) return false; + if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; bool isECIES = i2p::context.IsECIES (); // replace record to reply diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index fadbb51a..4d1cdec3 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -865,7 +865,7 @@ namespace i2p return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, true) : false; } - bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) { if (!m_TunnelDecryptor) return false; if (IsECIES ()) @@ -875,7 +875,7 @@ namespace i2p m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; - if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, ctx, false)) + if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; @@ -894,7 +894,12 @@ namespace i2p return true; } else - return m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); + { + BN_CTX * ctx = BN_CTX_new (); + bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); + BN_CTX_free (ctx); + return success; + } } i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index a7594e36..a4d18f82 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -95,7 +95,7 @@ namespace garlic void SetStatusV6 (RouterStatus status); int GetNetID () const { return m_NetID; }; void SetNetID (int netID) { m_NetID = netID; }; - bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); + bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data); void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon From edf3b7e2fcee704a1dab809545597257b3f3a8ff Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 28 Mar 2021 13:13:00 -0400 Subject: [PATCH 0018/2193] set X bandiwth for floodfill by default --- daemon/Daemon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 9fffe5a8..c87de4aa 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -280,7 +280,7 @@ namespace util else if (isFloodfill) { LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'"); - i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2); } else { From 2b0d18a6d745cb5e6dbaaf9b16f2ef73326afca9 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Mar 2021 14:44:50 -0400 Subject: [PATCH 0019/2193] don't change router status from ipv6 --- libi2pd/RouterContext.cpp | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 4d1cdec3..48240c89 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -458,12 +458,15 @@ namespace i2p void RouterContext::SetUnreachable (bool v4, bool v6) { - // set caps - uint8_t caps = m_RouterInfo.GetCaps (); - caps &= ~i2p::data::RouterInfo::eReachable; - caps |= i2p::data::RouterInfo::eUnreachable; - caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill - m_RouterInfo.SetCaps (caps); + if (v4) + { + // set caps + uint8_t caps = m_RouterInfo.GetCaps (); + caps &= ~i2p::data::RouterInfo::eReachable; + caps |= i2p::data::RouterInfo::eUnreachable; + caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill + m_RouterInfo.SetCaps (caps); + } uint16_t port = 0; // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); @@ -485,13 +488,16 @@ namespace i2p void RouterContext::SetReachable (bool v4, bool v6) { - // update caps - uint8_t caps = m_RouterInfo.GetCaps (); - caps &= ~i2p::data::RouterInfo::eUnreachable; - caps |= i2p::data::RouterInfo::eReachable; - if (m_IsFloodfill) - caps |= i2p::data::RouterInfo::eFloodfill; - m_RouterInfo.SetCaps (caps); + if (v4) + { + // update caps + uint8_t caps = m_RouterInfo.GetCaps (); + caps &= ~i2p::data::RouterInfo::eUnreachable; + caps |= i2p::data::RouterInfo::eReachable; + if (m_IsFloodfill) + caps |= i2p::data::RouterInfo::eFloodfill; + m_RouterInfo.SetCaps (caps); + } uint16_t port = 0; // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); From 8462d382f4e5ab12e2b6b01c071cf83dce63f22d Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Mar 2021 15:16:39 -0400 Subject: [PATCH 0020/2193] don't create SSU session for HolePunch --- libi2pd/SSU.cpp | 4 ++-- libi2pd/SSUSession.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index b9b3a04e..111f9407 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -385,7 +385,7 @@ namespace transport auto it = sessions->find (packet->from); if (it != sessions->end ()) session = it->second; - if (!session) + if (!session && packet->len > 0) { session = std::make_shared (*this, packet->from); session->WaitForConnect (); diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 2e49e970..09be219f 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -418,6 +418,7 @@ namespace transport else FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, introducer.iKey, iv, introducer.iKey); m_Server.Send (buf, 96, m_RemoteEndpoint); + LogPrint (eLogDebug, "SSU: relay request sent"); } void SSUSession::SendSessionCreated (const uint8_t * x, bool sendRelayTag) @@ -682,6 +683,7 @@ namespace transport LogPrint (eLogInfo, "SSU: RelayReponse connecting to endpoint ", remoteEndpoint); if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch + // we assume that HolePunch has been sent by this time and our SessionRequest will go through m_Server.CreateDirectSession (it->second, remoteEndpoint, false); } // delete request From 5cca5472e615cb76ea13270dc69e1c8d123931ee Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Mar 2021 15:50:33 -0400 Subject: [PATCH 0021/2193] don't handle unsilicited HolePunch --- libi2pd/SSU.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 111f9407..2ee0d2a4 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -393,7 +393,8 @@ namespace transport LogPrint (eLogDebug, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created"); } } - session->ProcessNextMessage (packet->buf, packet->len, packet->from); + if (session) + session->ProcessNextMessage (packet->buf, packet->len, packet->from); } catch (std::exception& ex) { From 25eae3c1162c401d99b134944fca04d0ff1881ea Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Mar 2021 11:31:11 -0400 Subject: [PATCH 0022/2193] return relay tag for ipv6 introducer --- libi2pd/NetDb.cpp | 2 +- libi2pd/RouterInfo.cpp | 13 ++++++------- libi2pd/RouterInfo.h | 2 +- libi2pd/SSUSession.cpp | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index a50a796f..18228d72 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1172,7 +1172,7 @@ namespace data return GetRandomRouter ( [](std::shared_ptr router)->bool { - return router->IsIntroducer () && !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag + return router->IsIntroducer (true) && !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag }); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 1644d93d..554be691 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1105,8 +1105,7 @@ namespace data bool RouterInfo::IsPeerTesting (bool v4) const { - auto supportedTransports = m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6); - if (!supportedTransports) return false; + if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false; return (bool)GetAddress ( [v4](std::shared_ptr address)->bool { @@ -1115,14 +1114,14 @@ namespace data }); } - bool RouterInfo::IsIntroducer () const + bool RouterInfo::IsIntroducer (bool v4) const { - // TODO: support ipv6 - if (!(m_SupportedTransports & eSSUV4)) return false; + if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false; return (bool)GetAddress ( - [](std::shared_ptr address)->bool + [v4](std::shared_ptr address)->bool { - return (address->transportStyle == eTransportSSU) && address->IsIntroducer (); + return (address->transportStyle == eTransportSSU) && address->IsIntroducer () && + ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())); }); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 72818931..8572741d 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -210,7 +210,7 @@ namespace data bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; bool IsEligibleFloodfill () const; bool IsPeerTesting (bool v4) const; - bool IsIntroducer () const; + bool IsIntroducer (bool v4) const; uint8_t GetCaps () const { return m_Caps; }; void SetCaps (uint8_t caps); diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 09be219f..d699f2c4 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -212,7 +212,7 @@ namespace transport { uint8_t extendedOptionsLen = buf[headerSize]; headerSize++; - if (extendedOptionsLen >= 3) // options are presented + if (extendedOptionsLen >= 2) // options are presented { uint16_t flags = bufbe16toh (buf + headerSize); sendRelayTag = flags & EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG; @@ -464,7 +464,7 @@ namespace transport else s.Insert (address->host.to_v6 ().to_bytes ().data (), 16); // our IP V6 s.Insert (htobe16 (address->port)); // our port - if (sendRelayTag && i2p::context.GetRouterInfo ().IsIntroducer () && !IsV6 ()) + if (sendRelayTag && i2p::context.GetRouterInfo ().IsIntroducer (!IsV6 ())) { RAND_bytes((uint8_t *)&m_SentRelayTag, 4); if (!m_SentRelayTag) m_SentRelayTag = 1; From bd7328345fff56ad37758f453d94268b1c5c0aba Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Mar 2021 19:27:40 -0400 Subject: [PATCH 0023/2193] Don't change Yddrasil address if router becomes unreachable through ipv6 --- libi2pd/RouterContext.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 48240c89..e1e19604 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -250,21 +250,30 @@ namespace i2p bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { - if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish) - && ((v4 && address->IsV4 ()) || (v6 && address->IsV6 ()) || - (ygg && i2p::util::net::IsYggdrasilAddress (address->host)))) + if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish)) { - if (!port && !address->port) - { - // select random port only if address's port is not set - port = rand () % (30777 - 9111) + 9111; // I2P network ports range - if (port == 9150) port = 9151; // Tor browser + bool isAddr = v4 && address->IsV4 (); + if (!isAddr && (v6 || ygg)) + { + if (i2p::util::net::IsYggdrasilAddress (address->host)) + isAddr = ygg; + else + isAddr = v6 && address->IsV6 (); } - if (port) address->port = port; - address->cost = publish ? i2p::data::COST_NTCP2_PUBLISHED : i2p::data::COST_NTCP2_NON_PUBLISHED; - address->ntcp2->isPublished = publish; - address->ntcp2->iv = m_NTCP2Keys->iv; - updated = true; + if (isAddr) + { + if (!port && !address->port) + { + // select random port only if address's port is not set + port = rand () % (30777 - 9111) + 9111; // I2P network ports range + if (port == 9150) port = 9151; // Tor browser + } + if (port) address->port = port; + address->cost = publish ? i2p::data::COST_NTCP2_PUBLISHED : i2p::data::COST_NTCP2_NON_PUBLISHED; + address->ntcp2->isPublished = publish; + address->ntcp2->iv = m_NTCP2Keys->iv; + updated = true; + } } } if (updated) From f3b728d82841373a36bc213ac0ce26968fcc8506 Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Wed, 31 Mar 2021 08:45:56 -0400 Subject: [PATCH 0024/2193] Yggdrasil configuration added [meshnets] section --- contrib/i2pd.conf | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 0c2ec5bc..3fb585c2 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -171,6 +171,13 @@ enabled = true ## Name i2pd appears in UPnP forwardings list (default = I2Pd) # name = I2Pd +[meshnets] +## Enable connectivity over the Yggdrasil network +# yggdrasil = false +## You can bind address from your Yggdrasil subnet 300::/64 +## The address must first be added to the network interface +# yggaddress = + [reseed] ## Options for bootstrapping into I2P network, aka reseeding ## Enable or disable reseed data verification. @@ -195,7 +202,7 @@ verify = true ## Default: reg.i2p at "mainline" I2P Network # defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt ## Optional subscriptions URLs, separated by comma -# subscriptions = http://inr.i2p/export/alive-hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt +# subscriptions = http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt [limits] ## Maximum active transit sessions (default:2500) From 22865f8ee4f68ddae68f3a2bcaa2cf010d43c5fb Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Wed, 31 Mar 2021 12:05:23 -0400 Subject: [PATCH 0025/2193] reseed.yggurl and persist.addressbook added --- contrib/i2pd.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 3fb585c2..bc3554fa 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -185,6 +185,8 @@ verify = true ## URLs to request reseed data from, separated by comma ## Default: "mainline" I2P Network reseeds # urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/ +## Reseed URLs through the Yggdrasil, separated by comma +# yggurls = http://[324:9de3:fea4:f6ac::ace]:7070/ ## Path to local reseed data file (.su3) for manual reseeding # file = /path/to/i2pseeds.su3 ## or HTTPS URL to reseed from @@ -236,6 +238,8 @@ verify = true [persist] ## Save peer profiles on disk (default: true) # profiles = true +## Save full addresses on disk (default: true) +# addressbook = true [cpuext] ## Use CPU AES-NI instructions set when work with cryptography when available (default: true) From 881bca6ae379678f77b55b01affce35eced5d555 Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Wed, 31 Mar 2021 12:09:06 -0400 Subject: [PATCH 0026/2193] Depricated "nat" deleted --- contrib/i2pd.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index bc3554fa..fa75b68d 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -68,9 +68,6 @@ ipv6 = false ## Enable SSU transport (default = true) # ssu = true -## Should we assume we are behind NAT? (false only in MeshNet) -# nat = true - ## Bandwidth configuration ## L limit bandwidth to 32KBs/sec, O - to 256KBs/sec, P - to 2048KBs/sec, ## X - unlimited From 094541caa6b74a19f94b6cee5c6c4556132451df Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Wed, 31 Mar 2021 12:16:06 -0400 Subject: [PATCH 0027/2193] reg.i2p to subscriptions --- contrib/i2pd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index fa75b68d..523fd41b 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -201,7 +201,7 @@ verify = true ## Default: reg.i2p at "mainline" I2P Network # defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt ## Optional subscriptions URLs, separated by comma -# subscriptions = http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt +# subscriptions = http://reg.i2p/hosts.txt,http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt [limits] ## Maximum active transit sessions (default:2500) From 5412352dec60172a5b7abd5cdc75fb8414fe44f7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 31 Mar 2021 13:42:57 -0400 Subject: [PATCH 0028/2193] publish ipv6 introducers for ipv6 addresses --- libi2pd/RouterInfo.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 554be691..abe923d1 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -826,7 +826,8 @@ namespace data { for (auto& addr : *m_Addresses) { - if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ()) + if (addr->transportStyle == eTransportSSU && + ((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ()))) { for (auto& intro: addr->ssu->introducers) if (intro.iTag == introducer.iTag) return false; // already presented @@ -841,10 +842,11 @@ namespace data { for (auto& addr: *m_Addresses) { - if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ()) + if (addr->transportStyle == eTransportSSU && + ((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ()))) { for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it) - if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e) + if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e) { addr->ssu->introducers.erase (it); return true; From 94ca2514af5a5a07d35efa18d84159eee550cf39 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Apr 2021 10:29:03 -0400 Subject: [PATCH 0029/2193] set zero expiration timeout if no tunnels --- libi2pd/LeaseSet.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 2279319a..e986092f 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -862,9 +862,18 @@ namespace data offset += 4; // end date } // update expiration - SetExpirationTime (expirationTime*1000LL); - auto expires = expirationTime - timestamp; - htobe16buf (expiresBuf, expires > 0 ? expires : 0); + if (expirationTime) + { + SetExpirationTime (expirationTime*1000LL); + auto expires = (int)expirationTime - timestamp; + htobe16buf (expiresBuf, expires > 0 ? expires : 0); + } + else + { + // no tunnels or withdraw + SetExpirationTime (timestamp*1000LL); + memset (expiresBuf, 0, 2); // expires immeditely + } // sign keys.Sign (m_Buffer, offset, m_Buffer + offset); // LS + leading store type } From bb5ed0b40c8b58a1c377dbd9452af0d4ad926091 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Apr 2021 11:02:29 -0400 Subject: [PATCH 0030/2193] assign correct 6 or 4 cap to unpublished address --- libi2pd/RouterInfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index abe923d1..2c5cdd49 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -529,8 +529,8 @@ namespace data WriteString ("caps", properties); properties << '='; std::string caps; - if (address.caps & AddressCaps::eV4) caps += CAPS_FLAG_V4; - if (address.caps & AddressCaps::eV6) caps += CAPS_FLAG_V6; + if (address.IsV4 ()) caps += CAPS_FLAG_V4; + if (address.IsV6 ()) caps += CAPS_FLAG_V6; if (caps.empty ()) caps += CAPS_FLAG_V4; WriteString (caps, properties); properties << ';'; @@ -564,8 +564,8 @@ namespace data } else { - if (address.caps & AddressCaps::eV4) caps += CAPS_FLAG_V4; - if (address.caps & AddressCaps::eV6) caps += CAPS_FLAG_V6; + if (address.IsV4 ()) caps += CAPS_FLAG_V4; + if (address.IsV6 ()) caps += CAPS_FLAG_V6; if (caps.empty ()) caps += CAPS_FLAG_V4; } WriteString (caps, properties); From 823b499a0207801f17a56024282d824c4921e400 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Apr 2021 11:45:50 -0400 Subject: [PATCH 0031/2193] remove already expired LeaseSets --- libi2pd/Destination.cpp | 4 ++-- libi2pd/NetDb.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 52ede959..7b8d32d7 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -386,7 +386,7 @@ namespace client if (leaseSet->IsNewer (buf + offset, len - offset)) { leaseSet->Update (buf + offset, len - offset); - if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) + if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ()) LogPrint (eLogDebug, "Destination: Remote LeaseSet updated"); else { @@ -405,7 +405,7 @@ namespace client leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetPreferredCryptoType () ); // LeaseSet2 - if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) + if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ()) { if (leaseSet->GetIdentHash () != GetIdentHash ()) { diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 18228d72..d52f9844 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -336,7 +336,7 @@ namespace data if (it == m_LeaseSets.end () || it->second->GetStoreType () != storeType || leaseSet->GetPublishedTimestamp () > it->second->GetPublishedTimestamp ()) { - if (leaseSet->IsPublic ()) + if (leaseSet->IsPublic () && !leaseSet->IsExpired ()) { // TODO: implement actual update LogPrint (eLogInfo, "NetDb: LeaseSet2 updated: ", ident.ToBase32()); @@ -345,7 +345,7 @@ namespace data } else { - LogPrint (eLogWarning, "NetDb: Unpublished LeaseSet2 received: ", ident.ToBase32()); + LogPrint (eLogWarning, "NetDb: Unpublished or expired LeaseSet2 received: ", ident.ToBase32()); m_LeaseSets.erase (ident); } } From 51ef7ef61cf02cc5bc3b9ea122747b21c643bba8 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Apr 2021 13:37:21 -0400 Subject: [PATCH 0032/2193] don't publish LeaseSet without tunnels --- libi2pd/Destination.cpp | 8 ++++++-- libi2pd/Destination.h | 4 ++-- libi2pd/LeaseSet.cpp | 2 +- libi2pd/LeaseSet.h | 2 +- libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 2 +- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 7b8d32d7..f47ac421 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -300,7 +300,11 @@ namespace client { int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum - CreateNewLeaseSet (m_Pool->GetInboundTunnels (numTunnels)); + auto tunnels = m_Pool->GetInboundTunnels (numTunnels); + if (!tunnels.empty ()) + CreateNewLeaseSet (tunnels); + else + LogPrint (eLogInfo, "Destination: No inbound tunnels for LeaseSet"); } bool LeaseSetDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) @@ -1176,7 +1180,7 @@ namespace client LogPrint(eLogError, "Destinations: Can't save keys to ", path); } - void ClientDestination::CreateNewLeaseSet (std::vector > tunnels) + void ClientDestination::CreateNewLeaseSet (const std::vector >& tunnels) { std::shared_ptr leaseSet; if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index ffe41212..f04431c7 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -152,7 +152,7 @@ namespace client virtual void CleanupDestination () {}; // additional clean up in derived classes // I2CP virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0; - virtual void CreateNewLeaseSet (std::vector > tunnels) = 0; + virtual void CreateNewLeaseSet (const std::vector >& tunnels) = 0; private: @@ -262,7 +262,7 @@ namespace client void CleanupDestination (); // I2CP void HandleDataMessage (const uint8_t * buf, size_t len); - void CreateNewLeaseSet (std::vector > tunnels); + void CreateNewLeaseSet (const std::vector >& tunnels); private: diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index e986092f..a0b14385 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -797,7 +797,7 @@ namespace data } LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, std::vector > tunnels, + const KeySections& encryptionKeys, const std::vector >& tunnels, bool isPublic, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) { diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index cd31bf30..cd6535df 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -251,7 +251,7 @@ namespace data LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, const KeySections& encryptionKeys, - std::vector > tunnels, + const std::vector >& tunnels, bool isPublic, bool isPublishedEncrypted = false); LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 5cd1812a..d07c6248 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -84,7 +84,7 @@ namespace client m_Owner->SendMessagePayloadMessage (buf + 4, length); } - void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) + void I2CPDestination::CreateNewLeaseSet (const std::vector >& tunnels) { GetService ().post (std::bind (&I2CPDestination::PostCreateNewLeaseSet, this, tunnels)); } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 983951a4..085bf30a 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -93,7 +93,7 @@ namespace client // I2CP void HandleDataMessage (const uint8_t * buf, size_t len); - void CreateNewLeaseSet (std::vector > tunnels); + void CreateNewLeaseSet (const std::vector >& tunnels); private: From 43033695f6e911521ee0da56d2863fbc01f9da23 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Apr 2021 21:31:14 -0400 Subject: [PATCH 0033/2193] select apropriate address for peer test --- libi2pd/SSUSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index d699f2c4..c2fa86a8 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1132,7 +1132,7 @@ namespace transport { // we are Alice LogPrint (eLogDebug, "SSU: sending peer test"); - auto address = i2p::context.GetRouterInfo ().GetSSUAddress (i2p::context.SupportsV4 ()); + auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () : i2p::context.GetRouterInfo ().GetSSUAddress (true); if (!address) { LogPrint (eLogInfo, "SSU is not supported. Can't send peer test"); From bea384abea9ad8722027c52be7373c25832429d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Apr 2021 18:56:50 -0400 Subject: [PATCH 0034/2193] recongnize v4 and v6 SSU addresses without host --- libi2pd/RouterInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 2c5cdd49..ed7e3757 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1017,7 +1017,7 @@ namespace data return GetAddress ( [v4only](std::shared_ptr address)->bool { - return (address->transportStyle == eTransportSSU) && (!v4only || address->host.is_v4 ()); + return (address->transportStyle == eTransportSSU) && (!v4only || address->IsV4 ()); }); } @@ -1026,7 +1026,7 @@ namespace data return GetAddress ( [](std::shared_ptr address)->bool { - return (address->transportStyle == eTransportSSU) && address->host.is_v6 (); + return (address->transportStyle == eTransportSSU) && address->IsV6(); }); } From 4f3333c841543a9ef00888b5a111cfb8b4a651ef Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Apr 2021 19:24:07 -0400 Subject: [PATCH 0035/2193] don't check range ffor unspecified address --- libi2pd/util.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index e75b7c19..69fc366a 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -524,6 +524,7 @@ namespace net bool IsInReservedRange (const boost::asio::ip::address& host) { // https://en.wikipedia.org/wiki/Reserved_IP_addresses + if (host.is_unspecified ()) return false; if(host.is_v4()) { static const std::vector< std::pair > reservedIPv4Ranges { From 0f166973cac0fb30cffae59f60c96e0ba876a40b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Apr 2021 20:03:19 -0400 Subject: [PATCH 0036/2193] check ureachable cap and actual introducers separately --- libi2pd/NetDb.cpp | 4 ++-- libi2pd/RouterInfo.cpp | 5 ----- libi2pd/RouterInfo.h | 3 ++- libi2pd/SSU.cpp | 6 +++--- libi2pd/SSUSession.cpp | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index d52f9844..cfd4bff6 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -454,7 +454,7 @@ namespace data { auto r = std::make_shared(path); if (r->GetRouterIdentity () && !r->IsUnreachable () && - (!r->UsesIntroducer () || m_LastLoad < r->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)) // 1 hour + (!r->HasUnreachableCap () || m_LastLoad < r->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)) // 1 hour { r->DeleteBuffer (); r->ClearProperties (); // properties are not used for regular routers @@ -584,7 +584,7 @@ namespace data if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS) it.second->SetUnreachable (false); // find & mark expired routers - if (it.second->UsesIntroducer ()) + if (it.second->HasUnreachableCap ()) { if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) // RouterInfo expires after 1 hour if uses introducer diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index ed7e3757..0fc8c2dc 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1007,11 +1007,6 @@ namespace data } } - bool RouterInfo::UsesIntroducer () const - { - return m_Caps & Caps::eUnreachable; // non-reachable - } - std::shared_ptr RouterInfo::GetSSUAddress (bool v4only) const { return GetAddress ( diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 8572741d..b91fa682 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -148,6 +148,7 @@ namespace data bool IsNTCP2 () const { return (bool)ntcp2; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; }; bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); }; + bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); }; bool IsIntroducer () const { return caps & eSSUIntroducer; }; bool IsPeerTesting () const { return caps & eSSUTesting; }; @@ -188,6 +189,7 @@ namespace data void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; + bool HasUnreachableCap () const { return m_Caps & Caps::eUnreachable; }; bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; @@ -204,7 +206,6 @@ namespace data bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool IsReachableFrom (const RouterInfo& other) const; bool HasValidAddresses () const { return m_SupportedTransports; }; - bool UsesIntroducer () const; bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 2ee0d2a4..f8bdd9a0 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -445,7 +445,7 @@ namespace transport { if (router && address) { - if (router->UsesIntroducer ()) + if (address->UsesIntroducer ()) m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, address, peerTest)); // always V4 thread else { @@ -481,7 +481,7 @@ namespace transport void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr router, std::shared_ptr address, bool peerTest) { - if (router && router->UsesIntroducer () && address) + if (router && address && address->UsesIntroducer ()) { if (address->IsV4 () && !i2p::context.SupportsV4 ()) return; if (address->IsV6 () && !i2p::context.SupportsV6 ()) return; @@ -566,7 +566,7 @@ namespace transport LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] through introducer ", introducer->iHost, ":", introducer->iPort); session->WaitForIntroduction (); - if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable + if (i2p::context.GetRouterInfo ().HasUnreachableCap ()) // if we are unreachable. TODO: ipv4 and ipv6 { uint8_t buf[1]; Send (buf, 0, remoteEndpoint); // send HolePunch diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index c2fa86a8..8ca24805 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -681,7 +681,7 @@ namespace transport // we didn't have correct endpoint when sent relay request // now we do LogPrint (eLogInfo, "SSU: RelayReponse connecting to endpoint ", remoteEndpoint); - if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable + if (i2p::context.GetRouterInfo ().HasUnreachableCap ()) // if we are unreachable. TODO: ipv4 and ipv6 m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch // we assume that HolePunch has been sent by this time and our SessionRequest will go through m_Server.CreateDirectSession (it->second, remoteEndpoint, false); From 67b32005f6f31461ccbcafa1f14130ef2c46a00f Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Apr 2021 22:18:09 -0400 Subject: [PATCH 0037/2193] check if host if unspecified --- libi2pd/RouterInfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b91fa682..46472bdf 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -153,8 +153,8 @@ namespace data bool IsIntroducer () const { return caps & eSSUIntroducer; }; bool IsPeerTesting () const { return caps & eSSUTesting; }; - bool IsV4 () const { return (caps & AddressCaps::eV4) || host.is_v4 (); }; - bool IsV6 () const { return (caps & AddressCaps::eV6) || host.is_v6 (); }; + bool IsV4 () const { return (caps & AddressCaps::eV4) || (host.is_v4 () && !host.is_unspecified ()); }; + bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); }; }; typedef std::list > Addresses; From 2cc9791bf2b5845da64229cd74ef1490352201b2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Apr 2021 10:36:22 -0400 Subject: [PATCH 0038/2193] exclude already expired introducers --- libi2pd/RouterInfo.cpp | 15 +++++++++++++++ libi2pd/RouterInfo.h | 2 +- libi2pd/SSU.cpp | 12 +++++++++--- libi2pd/SSU.h | 4 ++-- libi2pd/Transports.cpp | 4 ++-- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0fc8c2dc..ad57f685 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -333,6 +333,21 @@ namespace data } else supportedTransports |= eSSUV4; // in case if host or 6 caps is not preasented, we assume 4 + if (address->ssu && !address->ssu->introducers.empty ()) + { + // exclude invalid introducers + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + int numValid = 0; + for (auto& it: address->ssu->introducers) + { + if (ts <= it.iExp && it.iPort > 0 && + ((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ()))) + numValid++; + else + it.iPort = 0; + } + if (!numValid) address->ssu->introducers.resize (0); + } } } if (supportedTransports) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 46472bdf..336d7741 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -96,7 +96,7 @@ namespace data typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey struct Introducer { - Introducer (): iExp (0) {}; + Introducer (): iPort (0), iExp (0) {}; boost::asio::ip::address iHost; int iPort; IntroKey iKey; diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f8bdd9a0..b3118c96 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -431,16 +431,17 @@ namespace transport return nullptr; } - void SSUServer::CreateSession (std::shared_ptr router, bool peerTest, bool v4only) + bool SSUServer::CreateSession (std::shared_ptr router, bool peerTest, bool v4only) { auto address = router->GetSSUAddress (v4only || !context.SupportsV6 ()); if (address) - CreateSession (router, address, peerTest); + return CreateSession (router, address, peerTest); else LogPrint (eLogWarning, "SSU: Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address"); + return false; } - void SSUServer::CreateSession (std::shared_ptr router, + bool SSUServer::CreateSession (std::shared_ptr router, std::shared_ptr address, bool peerTest) { if (router && address) @@ -449,10 +450,14 @@ namespace transport m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, address, peerTest)); // always V4 thread else { + if (address->host.is_unspecified ()) return false; boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port); m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest)); } } + else + return false; + return true; } void SSUServer::CreateDirectSession (std::shared_ptr router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest) @@ -511,6 +516,7 @@ namespace transport for (int i = 0; i < numIntroducers; i++) { auto intr = &(address->ssu->introducers[i]); + if (!intr->iPort) continue; // skip invalid introducer if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort); if (ep.address ().is_v4 () && address->IsV4 ()) // ipv4 diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index daaa83f3..606651d7 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -51,8 +51,8 @@ namespace transport ~SSUServer (); void Start (); void Stop (); - void CreateSession (std::shared_ptr router, bool peerTest = false, bool v4only = false); - void CreateSession (std::shared_ptr router, + bool CreateSession (std::shared_ptr router, bool peerTest = false, bool v4only = false); + bool CreateSession (std::shared_ptr router, std::shared_ptr address, bool peerTest = false); void CreateDirectSession (std::shared_ptr router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest); std::shared_ptr FindSession (std::shared_ptr router) const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 13c1d210..cf136608 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -505,8 +505,8 @@ namespace transport } if (address && address->IsReachableSSU ()) { - m_SSUServer->CreateSession (peer.router, address); - return true; + if (m_SSUServer->CreateSession (peer.router, address)) + return true; } } else From ff89edf1272c0146e05f4381193ab53ecad7b75e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 5 Apr 2021 18:22:48 -0400 Subject: [PATCH 0039/2193] pick random introducer --- libi2pd/SSU.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index b3118c96..bc036d51 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -513,9 +513,10 @@ namespace transport std::shared_ptr introducerSession; const i2p::data::RouterInfo::Introducer * introducer = nullptr; // we might have a session to introducer already + auto offset = rand (); for (int i = 0; i < numIntroducers; i++) { - auto intr = &(address->ssu->introducers[i]); + auto intr = &(address->ssu->introducers[(offset + i)%numIntroducers]); if (!intr->iPort) continue; // skip invalid introducer if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort); From 5c9b478e46ab1b7def7389f4d057e116a8ae644d Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 5 Apr 2021 21:45:48 -0400 Subject: [PATCH 0040/2193] published field for SSU addresses --- libi2pd/RouterContext.cpp | 6 ++++-- libi2pd/RouterInfo.cpp | 20 ++++++++++++++------ libi2pd/RouterInfo.h | 4 ++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index e1e19604..a75b0201 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -250,7 +250,7 @@ namespace i2p bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { - if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish)) + if (address->IsNTCP2 () && (address->port != port || address->published != publish)) { bool isAddr = v4 && address->IsV4 (); if (!isAddr && (v6 || ygg)) @@ -270,7 +270,7 @@ namespace i2p } if (port) address->port = port; address->cost = publish ? i2p::data::COST_NTCP2_PUBLISHED : i2p::data::COST_NTCP2_NON_PUBLISHED; - address->ntcp2->isPublished = publish; + address->published = publish; address->ntcp2->iv = m_NTCP2Keys->iv; updated = true; } @@ -483,6 +483,7 @@ namespace i2p if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) { addr->cost = i2p::data::COST_SSU_THROUGH_INTRODUCERS; + addr->published = false; addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer addr->ssu->introducers.clear (); port = addr->port; @@ -514,6 +515,7 @@ namespace i2p if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) { addr->cost = i2p::data::COST_SSU_DIRECT; + addr->published = true; addr->caps |= i2p::data::RouterInfo::eSSUIntroducer; addr->ssu->introducers.clear (); port = addr->port; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index ad57f685..9d4826dc 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -260,7 +260,7 @@ namespace data else if (!strcmp (key, "i")) // ntcp2 iv { Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); - address->ntcp2->isPublished = true; // presence if "i" means "published" + address->published = true; // presence if "i" means "published" } else if (key[0] == 'i') { @@ -308,7 +308,7 @@ namespace data else supportedTransports |= eNTCP2V4; } - else if (!address->ntcp2->isPublished) + else if (!address->published) { if (address->caps) { @@ -348,6 +348,8 @@ namespace data } if (!numValid) address->ssu->introducers.resize (0); } + else if (isHost && address->port) + address->published = true; } } if (supportedTransports) @@ -564,7 +566,7 @@ namespace data if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING; if (address.host.is_v4 ()) { - if (IsReachable ()) + if (address.published) { isPublished = true; if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER; @@ -574,8 +576,13 @@ namespace data } else if (address.host.is_v6 ()) { - isPublished = true; - if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER; + if (address.published) + { + isPublished = true; + if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER; + } + else + caps += CAPS_FLAG_V6; } else { @@ -807,6 +814,7 @@ namespace data addr->port = port; addr->transportStyle = eTransportSSU; addr->cost = COST_SSU_DIRECT; // NTCP2 should have priority over SSU + addr->published = true; addr->caps = i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // BC; addr->date = 0; addr->ssu.reset (new SSUExt ()); @@ -831,7 +839,7 @@ namespace data addr->caps = 0; addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); - if (port) addr->ntcp2->isPublished = true; + if (port) addr->published = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->iv, iv, 16); m_Addresses->push_back(std::move(addr)); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 336d7741..284d9301 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -115,7 +115,6 @@ namespace data { Tag<32> staticKey; Tag<16> iv; - bool isPublished = false; }; struct Address @@ -125,6 +124,7 @@ namespace data int port; uint64_t date; uint8_t cost, caps; + bool published = false; std::unique_ptr ssu; // not null for SSU std::unique_ptr ntcp2; // not null for NTCP2 @@ -146,7 +146,7 @@ namespace data } bool IsNTCP2 () const { return (bool)ntcp2; }; - bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; }; + bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; }; bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); }; bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); }; From 277cef5ec43169fa47d5fc6b4597cc5710cfae1c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Apr 2021 13:05:38 -0400 Subject: [PATCH 0041/2193] eliminate cost field --- libi2pd/RouterContext.cpp | 3 --- libi2pd/RouterInfo.cpp | 15 ++++++++++----- libi2pd/RouterInfo.h | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index a75b0201..54843073 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -269,7 +269,6 @@ namespace i2p if (port == 9150) port = 9151; // Tor browser } if (port) address->port = port; - address->cost = publish ? i2p::data::COST_NTCP2_PUBLISHED : i2p::data::COST_NTCP2_NON_PUBLISHED; address->published = publish; address->ntcp2->iv = m_NTCP2Keys->iv; updated = true; @@ -482,7 +481,6 @@ namespace i2p for (auto& addr : addresses) if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) { - addr->cost = i2p::data::COST_SSU_THROUGH_INTRODUCERS; addr->published = false; addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer addr->ssu->introducers.clear (); @@ -514,7 +512,6 @@ namespace i2p for (auto& addr : addresses) if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) { - addr->cost = i2p::data::COST_SSU_DIRECT; addr->published = true; addr->caps |= i2p::data::RouterInfo::eSSUIntroducer; addr->ssu->introducers.clear (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9d4826dc..e9f27d96 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -197,7 +197,8 @@ namespace data { uint8_t supportedTransports = 0; auto address = std::make_shared
(); - s.read ((char *)&address->cost, sizeof (address->cost)); + uint8_t cost; // ignore + s.read ((char *)&cost, sizeof (cost)); s.read ((char *)&address->date, sizeof (address->date)); bool isHost = false, isIntroKey = false, isStaticKey = false; char transportStyle[6]; @@ -530,7 +531,13 @@ namespace data for (const auto& addr_ptr : *m_Addresses) { const Address& address = *addr_ptr; - s.write ((const char *)&address.cost, sizeof (address.cost)); + // calculate cost + uint8_t cost = 0x7f; + if (address.transportStyle == eTransportNTCP) + cost = address.published ? COST_NTCP2_PUBLISHED : COST_NTCP2_NON_PUBLISHED; + else if (address.transportStyle == eTransportSSU) + cost = address.published ? COST_SSU_DIRECT : COST_SSU_THROUGH_INTRODUCERS; + s.write ((const char *)&cost, sizeof (cost)); s.write ((const char *)&address.date, sizeof (address.date)); std::stringstream properties; bool isPublished = false; @@ -813,7 +820,6 @@ namespace data addr->host = boost::asio::ip::address::from_string (host); addr->port = port; addr->transportStyle = eTransportSSU; - addr->cost = COST_SSU_DIRECT; // NTCP2 should have priority over SSU addr->published = true; addr->caps = i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // BC; addr->date = 0; @@ -834,8 +840,7 @@ namespace data auto addr = std::make_shared
(); addr->host = host; addr->port = port; - addr->transportStyle = eTransportNTCP; - addr->cost = port ? COST_NTCP2_PUBLISHED : COST_NTCP2_NON_PUBLISHED; // override from RouterContext::PublishNTCP2Address + addr->transportStyle = eTransportNTCP; addr->caps = 0; addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 284d9301..bdb92b8a 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -123,7 +123,7 @@ namespace data boost::asio::ip::address host; int port; uint64_t date; - uint8_t cost, caps; + uint8_t caps; bool published = false; std::unique_ptr ssu; // not null for SSU std::unique_ptr ntcp2; // not null for NTCP2 From 3e873f88c98ce1e1e8145fa875eb79d62e488393 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Apr 2021 15:55:38 -0400 Subject: [PATCH 0042/2193] don't drop introducers without iExp --- libi2pd/RouterInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index e9f27d96..00b78771 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -341,7 +341,7 @@ namespace data int numValid = 0; for (auto& it: address->ssu->introducers) { - if (ts <= it.iExp && it.iPort > 0 && + if ((!it.iExp || ts <= it.iExp) && it.iPort > 0 && ((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ()))) numValid++; else From b9a2d5df02dc0adf12e751237669ee751295ed59 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Apr 2021 21:07:14 -0400 Subject: [PATCH 0043/2193] send HolePunch back based on actual address type --- libi2pd/SSU.cpp | 3 ++- libi2pd/SSUSession.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index bc036d51..31269558 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -573,7 +573,8 @@ namespace transport LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] through introducer ", introducer->iHost, ":", introducer->iPort); session->WaitForIntroduction (); - if (i2p::context.GetRouterInfo ().HasUnreachableCap ()) // if we are unreachable. TODO: ipv4 and ipv6 + if ((address->host.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) || + (address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled)) { uint8_t buf[1]; Send (buf, 0, remoteEndpoint); // send HolePunch diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 8ca24805..0833d994 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -681,7 +681,8 @@ namespace transport // we didn't have correct endpoint when sent relay request // now we do LogPrint (eLogInfo, "SSU: RelayReponse connecting to endpoint ", remoteEndpoint); - if (i2p::context.GetRouterInfo ().HasUnreachableCap ()) // if we are unreachable. TODO: ipv4 and ipv6 + if ((remoteIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) || + (remoteIP.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled)) m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch // we assume that HolePunch has been sent by this time and our SessionRequest will go through m_Server.CreateDirectSession (it->second, remoteEndpoint, false); From ac47c9c67333764351a3df1680a4e93871265eb9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Apr 2021 10:56:46 -0400 Subject: [PATCH 0044/2193] don't check U cap --- libi2pd/NetDb.cpp | 4 ++-- libi2pd/RouterInfo.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index cfd4bff6..bc49d720 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -454,7 +454,7 @@ namespace data { auto r = std::make_shared(path); if (r->GetRouterIdentity () && !r->IsUnreachable () && - (!r->HasUnreachableCap () || m_LastLoad < r->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)) // 1 hour + (r->IsReachable () || !r->IsSSU (false) || m_LastLoad < r->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)) // 1 hour { r->DeleteBuffer (); r->ClearProperties (); // properties are not used for regular routers @@ -584,7 +584,7 @@ namespace data if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS) it.second->SetUnreachable (false); // find & mark expired routers - if (it.second->HasUnreachableCap ()) + if (!it.second->IsReachable () && it.second->IsSSU (false)) { if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) // RouterInfo expires after 1 hour if uses introducer diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index bdb92b8a..dd3e7e13 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -189,7 +189,6 @@ namespace data void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; - bool HasUnreachableCap () const { return m_Caps & Caps::eUnreachable; }; bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; From df858d9143dbf302d742f90157b167bc59016c7d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Apr 2021 13:29:07 -0400 Subject: [PATCH 0045/2193] publish iexp --- libi2pd/RouterInfo.cpp | 24 ++++++++++++------------ libi2pd/SSU.cpp | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 00b78771..d54c2e97 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -617,6 +617,18 @@ namespace data { int i = 0; for (const auto& introducer: address.ssu->introducers) + { + if (introducer.iExp) // expiration is specified + { + WriteString ("iexp" + boost::lexical_cast(i), properties); + properties << '='; + WriteString (boost::lexical_cast(introducer.iExp), properties); + properties << ';'; + } + i++; + } + i = 0; + for (const auto& introducer: address.ssu->introducers) { WriteString ("ihost" + boost::lexical_cast(i), properties); properties << '='; @@ -654,18 +666,6 @@ namespace data properties << ';'; i++; } - i = 0; - for (const auto& introducer: address.ssu->introducers) - { - if (introducer.iExp) // expiration is specified - { - WriteString ("iexp" + boost::lexical_cast(i), properties); - properties << '='; - WriteString (boost::lexical_cast(introducer.iExp), properties); - properties << ';'; - } - i++; - } } // write intro key WriteString ("key", properties); diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 31269558..aad117cd 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -744,6 +744,7 @@ namespace transport introducer.iPort = ep.port (); introducer.iTag = it1->GetRelayTag (); introducer.iKey = it1->GetIntroKey (); + introducer.iExp = it1->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; if (i2p::context.AddIntroducer (introducer)) { newList.push_back (ep); From 83fc1b0b8e945759becce8c03a1d651802fd2eeb Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Apr 2021 17:26:45 -0400 Subject: [PATCH 0046/2193] support b32 and b33 addresses in STREAM CONNECT --- libi2pd_client/SAM.cpp | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 9f7e771e..1eb38a7e 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -495,20 +495,39 @@ namespace client else m_BufferOffset = 0; - auto dest = std::make_shared (); - size_t l = dest->FromBase64(destination); - if (l > 0) + std::shared_ptr
addr; + auto pos = destination.find(".b32.i2p"); + if (pos != std::string::npos) + addr = std::make_shared
(destination.substr (0, pos)); + else { - context.GetAddressBook().InsertFullAddress(dest); - auto leaseSet = session->localDestination->FindLeaseSet(dest->GetIdentHash()); - if (leaseSet) - Connect(leaseSet, session); - else + auto dest = std::make_shared (); + size_t l = dest->FromBase64(destination); + if (l > 0) { - session->localDestination->RequestDestination(dest->GetIdentHash(), + context.GetAddressBook().InsertFullAddress(dest); + addr = std::make_shared
(dest->GetIdentHash ()); + } + } + + if (addr && addr->IsValid ()) + { + if (addr->IsIdentHash ()) + { + auto leaseSet = session->localDestination->FindLeaseSet(addr->identHash); + if (leaseSet) + Connect(leaseSet, session); + else + { + session->localDestination->RequestDestination(addr->identHash, + std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, + shared_from_this(), std::placeholders::_1)); + } + } + else // B33 + session->localDestination->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, shared_from_this(), std::placeholders::_1)); - } } else SendMessageReply (SAM_STREAM_STATUS_INVALID_KEY, strlen(SAM_STREAM_STATUS_INVALID_KEY), true); From 4543e14c57e6ae884ebcadd9d773f2e7a948a1a8 Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Tue, 13 Apr 2021 02:43:42 -0400 Subject: [PATCH 0047/2193] SAM section fixed --- contrib/i2pd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 523fd41b..6979d4d8 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -128,7 +128,7 @@ port = 4447 ## socksproxy section also accepts I2CP parameters, like "inbound.length" etc. [sam] -## Uncomment and set to 'true' to enable SAM Bridge +## Comment or set to 'false' to disable SAM Bridge enabled = true ## Address and port service will listen on # address = 127.0.0.1 From 27833372841b73f489ec5fcc06afa9ce6b8e41d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 13 Apr 2021 09:16:52 -0400 Subject: [PATCH 0048/2193] require ipv4 for IBGW --- libi2pd/TunnelPool.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7cb79956..ed9a1a82 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -422,7 +422,7 @@ namespace tunnel { auto r = i2p::transport::transports.GetRandomPeer (); if (r && !r->GetProfile ()->IsBad () && - (numHops > 1 || (!inbound && r->IsV4 ()) || r->IsReachable ())) // first inbound must be reachable + (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { prevHop = r; peers.push_back (r->GetRouterIdentity ()); @@ -443,9 +443,8 @@ namespace tunnel LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); return false; } - if ((i == numHops - 1) && - ((inbound && !hop->IsReachable ()) || // IBGW is not reachable - (!inbound && !hop->IsV4 ()))) // OBEP is not ipv4 + if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4 + (inbound && !hop->IsReachable ()))) // IBGW is not reachable { auto hop1 = nextHop (prevHop, true); if (hop1) hop = hop1; From be48dc6e870f5017be00940e1daceaeef244a8f4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 13 Apr 2021 15:11:37 -0400 Subject: [PATCH 0049/2193] pick correct local address for intro key --- libi2pd/SSUSession.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 0833d994..433b6513 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -120,7 +120,8 @@ namespace transport else { // try own intro key - auto address = i2p::context.GetRouterInfo ().GetSSUAddress (false); + auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () : + i2p::context.GetRouterInfo ().GetSSUAddress (true); if (!address) { LogPrint (eLogInfo, "SSU is not supported"); @@ -390,7 +391,8 @@ namespace transport void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce) { - auto address = i2p::context.GetRouterInfo ().GetSSUAddress (false); + auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () : + i2p::context.GetRouterInfo ().GetSSUAddress (true); if (!address) { LogPrint (eLogInfo, "SSU is not supported"); @@ -689,6 +691,8 @@ namespace transport } // delete request m_RelayRequests.erase (it); + // cancel connect timer + m_ConnectTimer.cancel (); } else LogPrint (eLogError, "SSU: Unsolicited RelayResponse, nonce=", nonce); From 39d4464be072e99d3468101c8f511ae17bb6eea6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Apr 2021 11:43:43 -0400 Subject: [PATCH 0050/2193] make sure that introducer or peer test router is reachable by SSU --- libi2pd/RouterInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index d54c2e97..87a987fe 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1135,7 +1135,7 @@ namespace data [v4](std::shared_ptr address)->bool { return (address->transportStyle == eTransportSSU) && address->IsPeerTesting () && - ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())); + ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())) && address->IsReachableSSU (); }); } @@ -1146,7 +1146,7 @@ namespace data [v4](std::shared_ptr address)->bool { return (address->transportStyle == eTransportSSU) && address->IsIntroducer () && - ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())); + ((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())) && !address->host.is_unspecified (); }); } From 74d0c04314b7244afa0614430827f0f13a575312 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Apr 2021 16:06:02 -0400 Subject: [PATCH 0051/2193] ipv6 address for relay reponse and relay intro --- libi2pd/SSUSession.cpp | 60 +++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 433b6513..c135ae1d 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -570,22 +570,33 @@ namespace transport void SSUSession::SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from, const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to) { - // Charlie's address always v4 - if (!to.address ().is_v4 ()) + bool isV4 = to.address ().is_v4 (); // Charle's + bool isV4A = from.address ().is_v4 (); // Alice's + if ((isV4 && !isV4A) || (!isV4 && isV4A)) { - LogPrint (eLogWarning, "SSU: Charlie's IP must be v4"); + LogPrint (eLogWarning, "SSU: Charlie's IP and Alice's IP belong to different networks for relay response"); return; } - uint8_t buf[80 + 18] = {0}; // 64 Alice's ipv4 and 80 Alice's ipv6 + uint8_t buf[80 + 18] = {0}; // 64 for ipv4 and 80 for ipv6 uint8_t * payload = buf + sizeof (SSUHeader); - *payload = 4; - payload++; // size - htobe32buf (payload, to.address ().to_v4 ().to_ulong ()); // Charlie's IP - payload += 4; // address + // Charlie + if (isV4) + { + *payload = 4; + payload++; // size + memcpy (payload, to.address ().to_v4 ().to_bytes ().data (), 4); // Charlie's IP V4 + payload += 4; // address + } + else + { + *payload = 16; + payload++; // size + memcpy (payload, to.address ().to_v6 ().to_bytes ().data (), 16); // Alice's IP V6 + payload += 16; // address + } htobe16buf (payload, to.port ()); // Charlie's port payload += 2; // port // Alice - bool isV4 = from.address ().is_v4 (); // Alice's if (isV4) { *payload = 4; @@ -624,25 +635,36 @@ namespace transport void SSUSession::SendRelayIntro (std::shared_ptr session, const boost::asio::ip::udp::endpoint& from) { if (!session) return; - // Alice's address always v4 - if (!from.address ().is_v4 ()) + bool isV4 = from.address ().is_v4 (); // Alice's + bool isV4C = session->m_RemoteEndpoint.address ().is_v4 (); // Charlie's + if ((isV4 && !isV4C) || (!isV4 && isV4C)) { - LogPrint (eLogWarning, "SSU: Alice's IP must be v4"); + LogPrint (eLogWarning, "SSU: Charlie's IP and Alice's IP belong to different networks for relay intro"); return; } - uint8_t buf[48 + 18] = {0}; + uint8_t buf[64 + 18] = {0}; // 48 for ipv4 and 64 for ipv6 uint8_t * payload = buf + sizeof (SSUHeader); - *payload = 4; - payload++; // size - htobe32buf (payload, from.address ().to_v4 ().to_ulong ()); // Alice's IP - payload += 4; // address + if (isV4) + { + *payload = 4; + payload++; // size + memcpy (payload, from.address ().to_v4 ().to_bytes ().data (), 4); // Alice's IP V4 + payload += 4; // address + } + else + { + *payload = 16; + payload++; // size + memcpy (payload, from.address ().to_v6 ().to_bytes ().data (), 16); // Alice's IP V6 + payload += 16; // address + } htobe16buf (payload, from.port ()); // Alice's port payload += 2; // port *payload = 0; // challenge size uint8_t iv[16]; RAND_bytes (iv, 16); // random iv - FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, 48, session->m_SessionKey, iv, session->m_MacKey); - m_Server.Send (buf, 48, session->m_RemoteEndpoint); + FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, isV4 ? 48 : 64, session->m_SessionKey, iv, session->m_MacKey); + m_Server.Send (buf, isV4 ? 48 : 64, session->m_RemoteEndpoint); LogPrint (eLogDebug, "SSU: relay intro sent"); } From 5edb2569907a9a8bd880f93907e500ade61d811c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Apr 2021 19:31:49 -0400 Subject: [PATCH 0052/2193] check if our external IP is valid --- libi2pd/SSUSession.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index c135ae1d..19ccd1ce 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -296,8 +296,16 @@ namespace transport if (s.Verify (m_RemoteIdentity, payload)) { LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); - i2p::context.UpdateAddress (ourIP); - SendSessionConfirmed (y, ourAddressAndPort, addressAndPortLen); + if (!i2p::util::net::IsInReservedRange (ourIP)) + { + i2p::context.UpdateAddress (ourIP); + SendSessionConfirmed (y, ourAddressAndPort, addressAndPortLen); + } + else + { + LogPrint (eLogError, "SSU: Wrong external address ", ourIP.to_string ()); + Failed (); + } } else { @@ -682,7 +690,10 @@ namespace transport if (!ourSize) return; buf += ourSize; len -= ourSize; LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); - i2p::context.UpdateAddress (ourIP); + if (!i2p::util::net::IsInReservedRange (ourIP)) + i2p::context.UpdateAddress (ourIP); + else + LogPrint (eLogWarning, "SSU: Wrong external address ", ourIP.to_string ()); if (ourIP.is_v4 ()) { if (ourPort != m_Server.GetPort ()) From d5b61ed544db61662832fcd7d5ad1eaf03268fb3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 17 Apr 2021 14:33:53 -0400 Subject: [PATCH 0053/2193] select different routers for peer test --- libi2pd/NetDb.cpp | 7 ++++--- libi2pd/NetDb.hpp | 2 +- libi2pd/Transports.cpp | 10 +++++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index bc49d720..80029ece 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1149,12 +1149,13 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4) const + std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4, const std::set& excluded) const { return GetRandomRouter ( - [v4](std::shared_ptr router)->bool + [v4, &excluded](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsPeerTesting (v4); + return !router->IsHidden () && router->IsPeerTesting (v4) && + !excluded.count (router->GetIdentHash ()); }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 891bc35d..b782872c 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -85,7 +85,7 @@ namespace data std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; - std::shared_ptr GetRandomPeerTestRouter (bool v4) const; + std::shared_ptr GetRandomPeerTestRouter (bool v4, const std::set& excluded) const; std::shared_ptr GetRandomSSUV6Router () const; // TODO: change to v6 peer test later std::shared_ptr GetRandomIntroducer () const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index cf136608..4ad13518 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -587,10 +587,11 @@ namespace transport if (i2p::context.SupportsV4 ()) { LogPrint (eLogInfo, "Transports: Started peer test ipv4"); + std::set excluded; bool statusChanged = false; for (int i = 0; i < 5; i++) { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 + auto router = i2p::data::netdb.GetRandomPeerTestRouter (true, excluded); // v4 if (router) { auto addr = router->GetSSUAddress (true); // ipv4 @@ -601,8 +602,9 @@ namespace transport statusChanged = true; i2p::context.SetStatus (eRouterStatusTesting); // first time only } - m_SSUServer->CreateSession (router, addr, true); // peer test v4 + m_SSUServer->CreateSession (router, addr, true); // peer test v4 } + excluded.insert (router->GetIdentHash ()); } } if (!statusChanged) @@ -611,10 +613,11 @@ namespace transport if (i2p::context.SupportsV6 ()) { LogPrint (eLogInfo, "Transports: Started peer test ipv6"); + std::set excluded; bool statusChanged = false; for (int i = 0; i < 5; i++) { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (false); // v6 + auto router = i2p::data::netdb.GetRandomPeerTestRouter (false, excluded); // v6 if (router) { auto addr = router->GetSSUV6Address (); @@ -627,6 +630,7 @@ namespace transport } m_SSUServer->CreateSession (router, addr, true); // peer test v6 } + excluded.insert (router->GetIdentHash ()); } } if (!statusChanged) From ca77ca6ef0eeb00263da3656d6852c461634d3d3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 18 Apr 2021 17:27:50 -0400 Subject: [PATCH 0054/2193] reseed from compatible address --- libi2pd/Reseed.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index a712975e..41111ecc 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -678,8 +678,31 @@ namespace data // direct connection auto it = boost::asio::ip::tcp::resolver(service).resolve ( boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode); - if(!ecode) - s.lowest_layer().connect (*it, ecode); + if (!ecode) + { + bool connected = false; + boost::asio::ip::tcp::resolver::iterator end; + while (it != end) + { + boost::asio::ip::tcp::endpoint ep = *it; + if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) || + (ep.address ().is_v6 () && i2p::context.SupportsV6 ())) + { + s.lowest_layer().connect (ep, ecode); + if (!ecode) + { + connected = true; + break; + } + } + it++; + } + if (!connected) + { + LogPrint(eLogError, "Reseed: Failed to connect to ", url.host); + return ""; + } + } } if (!ecode) { From 7978adc5778be4a0798f12978ca611e0eee6a0ae Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Mon, 19 Apr 2021 06:43:51 -0400 Subject: [PATCH 0055/2193] =?UTF-8?q?=D0=A3=D1=82=D0=BE=D1=87=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B2=20Win?= =?UTF-8?q?dows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/i2pd.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 6979d4d8..2e1b296a 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -20,6 +20,7 @@ ## Logging configuration section ## By default logs go to stdout with level 'info' and higher +## For Windows OS by default logs go to file with level 'warn' and higher ## ## Logs destination (valid values: stdout, file, syslog) ## * stdout - print log entries to stdout From ad019da5535b9599973e3e7aea736b229fb41498 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Apr 2021 20:02:30 -0400 Subject: [PATCH 0056/2193] publish ipv6 introducers --- libi2pd/RouterContext.cpp | 4 +- libi2pd/SSU.cpp | 107 ++++++++++++++++++++++++++------------ libi2pd/SSU.h | 12 +++-- libi2pd/SSUSession.cpp | 3 ++ 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 54843073..e4697f2b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -466,7 +466,7 @@ namespace i2p void RouterContext::SetUnreachable (bool v4, bool v6) { - if (v4) + if (v4 || (v6 && !SupportsV4 ())) { // set caps uint8_t caps = m_RouterInfo.GetCaps (); @@ -496,7 +496,7 @@ namespace i2p void RouterContext::SetReachable (bool v4, bool v6) { - if (v4) + if (v4 || (v6 && !SupportsV4 ())) { // update caps uint8_t caps = m_RouterInfo.GetCaps (); diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index aad117cd..5ffcf890 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -28,8 +28,8 @@ namespace transport m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port), m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6), - m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service), - m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service) + m_IntroducersUpdateTimer (m_Service), m_IntroducersUpdateTimerV6 (m_Service), + m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service) { } @@ -82,6 +82,7 @@ namespace transport m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this)); m_ReceiversService.post (std::bind (&SSUServer::Receive, this)); ScheduleTermination (); + ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers } if (context.SupportsV6 ()) { @@ -89,9 +90,9 @@ namespace transport m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this)); m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this)); ScheduleTerminationV6 (); + ScheduleIntroducersUpdateTimerV6 (); // wait for 30 seconds and decide if we need introducers } SchedulePeerTestsCleanupTimer (); - ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers } void SSUServer::Stop () @@ -100,6 +101,8 @@ namespace transport m_IsRunning = false; m_TerminationTimer.cancel (); m_TerminationTimerV6.cancel (); + m_IntroducersUpdateTimer.cancel (); + m_IntroducersUpdateTimerV6.cancel (); m_Service.stop (); m_Socket.close (); m_SocketV6.close (); @@ -659,20 +662,19 @@ namespace transport ); } - std::set SSUServer::FindIntroducers (int maxNumIntroducers) + std::set SSUServer::FindIntroducers (int maxNumIntroducers, bool v4) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); std::set ret; + auto filter = [&ret, ts](std::shared_ptr session)->bool + { + return session->GetRelayTag () && !ret.count (session.get ()) && + session->GetState () == eSessionStateEstablished && + ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; + }; for (int i = 0; i < maxNumIntroducers; i++) { - auto session = GetRandomV4Session ( - [&ret, ts](std::shared_ptr session)->bool - { - return session->GetRelayTag () && !ret.count (session.get ()) && - session->GetState () == eSessionStateEstablished && - ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; - } - ); + auto session = v4 ? GetRandomV4Session (filter) : GetRandomV6Session (filter); if (session) { ret.insert (session.get ()); @@ -687,39 +689,73 @@ namespace transport m_IntroducersUpdateTimer.cancel (); m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL/2)); m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, - this, std::placeholders::_1)); + this, std::placeholders::_1, true)); } void SSUServer::ScheduleIntroducersUpdateTimer () { m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL)); m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, - this, std::placeholders::_1)); + this, std::placeholders::_1, true)); } - void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode) + void SSUServer::RescheduleIntroducersUpdateTimerV6 () + { + m_IntroducersUpdateTimerV6.cancel (); + m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL/2)); + m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, + this, std::placeholders::_1, false)); + } + + void SSUServer::ScheduleIntroducersUpdateTimerV6 () + { + m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL)); + m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, + this, std::placeholders::_1, false)); + } + + void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4) { if (ecode != boost::asio::error::operation_aborted) { // timeout expired - if (i2p::context.GetStatus () == eRouterStatusTesting) - { - // we still don't know if we need introducers - ScheduleIntroducersUpdateTimer (); - return; - } - if (i2p::context.GetStatus () != eRouterStatusFirewalled) + if (v4) { - // we don't need introducers - m_Introducers.clear (); - return; + if (i2p::context.GetStatus () == eRouterStatusTesting) + { + // we still don't know if we need introducers + ScheduleIntroducersUpdateTimer (); + return; + } + if (i2p::context.GetStatus () != eRouterStatusFirewalled) + { + // we don't need introducers + m_Introducers.clear (); + return; + } + } + else + { + if (i2p::context.GetStatusV6 () == eRouterStatusTesting) + { + // we still don't know if we need introducers + ScheduleIntroducersUpdateTimerV6 (); + return; + } + if (i2p::context.GetStatusV6 () != eRouterStatusFirewalled) + { + // we don't need introducers + m_IntroducersV6.clear (); + return; + } } // we are firewalled - if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable (true, false); // ipv4 + if (!i2p::context.IsUnreachable () || !v4) i2p::context.SetUnreachable (v4, !v4); std::list newList; size_t numIntroducers = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - for (const auto& it : m_Introducers) + auto& introducers = v4 ? m_Introducers : m_IntroducersV6; + for (const auto& it : introducers) { auto session = FindSession (it); if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) @@ -735,8 +771,8 @@ namespace transport if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new - auto introducers = FindIntroducers (SSU_MAX_NUM_INTRODUCERS); - for (const auto& it1: introducers) + auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, true); + for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); i2p::data::RouterInfo::Introducer introducer; @@ -752,11 +788,11 @@ namespace transport } } } - m_Introducers = newList; - if (m_Introducers.size () < SSU_MAX_NUM_INTRODUCERS) + introducers = newList; + if (introducers.size () < SSU_MAX_NUM_INTRODUCERS) { std::set > requested; - for (auto i = m_Introducers.size (); i < SSU_MAX_NUM_INTRODUCERS; i++) + for (auto i = introducers.size (); i < SSU_MAX_NUM_INTRODUCERS; i++) { auto introducer = i2p::data::netdb.GetRandomIntroducer (); if (introducer && !requested.count (introducer)) // not requested already @@ -765,7 +801,7 @@ namespace transport if (address && !address->host.is_unspecified ()) { boost::asio::ip::udp::endpoint ep (address->host, address->port); - if (std::find (m_Introducers.begin (), m_Introducers.end (), ep) == m_Introducers.end ()) // not connected yet + if (std::find (introducers.begin (), introducers.end (), ep) == introducers.end ()) // not connected yet { CreateDirectSession (introducer, ep, false); requested.insert (introducer); @@ -774,7 +810,10 @@ namespace transport } } } - ScheduleIntroducersUpdateTimer (); + if (v4) + ScheduleIntroducersUpdateTimer (); + else + ScheduleIntroducersUpdateTimerV6 (); } } diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 606651d7..cfeaf85f 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -71,6 +71,7 @@ namespace transport void RemoveRelay (uint32_t tag); std::shared_ptr FindRelaySession (uint32_t tag); void RescheduleIntroducersUpdateTimer (); + void RescheduleIntroducersUpdateTimerV6 (); void NewPeerTest (uint32_t nonce, PeerTestParticipant role, std::shared_ptr session = nullptr); PeerTestParticipant GetPeerTestParticipant (uint32_t nonce); @@ -99,9 +100,10 @@ namespace transport template std::shared_ptr GetRandomV6Session (Filter filter); - std::set FindIntroducers (int maxNumIntroducers); + std::set FindIntroducers (int maxNumIntroducers, bool v4); void ScheduleIntroducersUpdateTimer (); - void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode); + void ScheduleIntroducersUpdateTimerV6 (); + void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4); void SchedulePeerTestsCleanupTimer (); void HandlePeerTestsCleanupTimer (const boost::system::error_code& ecode); @@ -127,9 +129,9 @@ namespace transport boost::asio::io_service::work m_Work, m_ReceiversWork, m_ReceiversWorkV6; boost::asio::ip::udp::endpoint m_Endpoint, m_EndpointV6; boost::asio::ip::udp::socket m_Socket, m_SocketV6; - boost::asio::deadline_timer m_IntroducersUpdateTimer, m_PeerTestsCleanupTimer, - m_TerminationTimer, m_TerminationTimerV6; - std::list m_Introducers; // introducers we are connected to + boost::asio::deadline_timer m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6, + m_PeerTestsCleanupTimer, m_TerminationTimer, m_TerminationTimerV6; + std::list m_Introducers, m_IntroducersV6; // introducers we are connected to std::map > m_Sessions, m_SessionsV6; std::map > m_Relays; // we are introducer std::map m_PeerTests; // nonce -> creation time in milliseconds diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 19ccd1ce..7b7355a4 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1017,7 +1017,10 @@ namespace transport if (IsV6 ()) { if (i2p::context.GetStatusV6 () == eRouterStatusTesting) + { i2p::context.SetStatusV6 (eRouterStatusFirewalled); + m_Server.RescheduleIntroducersUpdateTimerV6 (); + } } else if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK { From 060e30d2830a7bfae519880a208aa46ffabca24e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Apr 2021 08:16:13 -0400 Subject: [PATCH 0057/2193] select ipv6 random introducer --- libi2pd/NetDb.cpp | 6 +++--- libi2pd/NetDb.hpp | 2 +- libi2pd/SSU.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 80029ece..a71bb891 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1168,12 +1168,12 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomIntroducer () const + std::shared_ptr NetDb::GetRandomIntroducer (bool v4) const { return GetRandomRouter ( - [](std::shared_ptr router)->bool + [v4](std::shared_ptr router)->bool { - return router->IsIntroducer (true) && !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag + return router->IsIntroducer (v4) && !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index b782872c..244ff39b 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -87,7 +87,7 @@ namespace data std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; std::shared_ptr GetRandomPeerTestRouter (bool v4, const std::set& excluded) const; std::shared_ptr GetRandomSSUV6Router () const; // TODO: change to v6 peer test later - std::shared_ptr GetRandomIntroducer () const; + std::shared_ptr GetRandomIntroducer (bool v4) const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 5ffcf890..b0ad1710 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -794,10 +794,10 @@ namespace transport std::set > requested; for (auto i = introducers.size (); i < SSU_MAX_NUM_INTRODUCERS; i++) { - auto introducer = i2p::data::netdb.GetRandomIntroducer (); + auto introducer = i2p::data::netdb.GetRandomIntroducer (v4); if (introducer && !requested.count (introducer)) // not requested already { - auto address = introducer->GetSSUAddress (true); // v4 + auto address = v4 ? introducer->GetSSUAddress (true) : introducer->GetSSUV6Address (); if (address && !address->host.is_unspecified ()) { boost::asio::ip::udp::endpoint ep (address->host, address->port); From 01e591b2617219875273a9e1a5bad16bad19a85d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Apr 2021 09:55:36 -0400 Subject: [PATCH 0058/2193] find ipv6 intrioducer session --- libi2pd/SSU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index b0ad1710..fb7b7da1 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -771,7 +771,7 @@ namespace transport if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new - auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, true); + auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); From 9c8c3b91747f8f557db8011005b1f4c07e2c2fc4 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Apr 2021 10:56:39 -0400 Subject: [PATCH 0059/2193] select few introducers at the time --- libi2pd/SSU.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index fb7b7da1..578c09eb 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -676,10 +676,9 @@ namespace transport { auto session = v4 ? GetRandomV4Session (filter) : GetRandomV6Session (filter); if (session) - { ret.insert (session.get ()); + else break; - } } return ret; } @@ -771,7 +770,7 @@ namespace transport if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new - auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); + auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS - numIntroducers, v4); for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); From b5618af308301b5f8eec1204202ec80c68b1d639 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Apr 2021 15:41:04 -0400 Subject: [PATCH 0060/2193] find all introducers at the time --- libi2pd/SSU.cpp | 37 +++++++++++++++++++++---------------- libi2pd/SSU.h | 2 +- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 578c09eb..7a7400f9 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -662,24 +662,29 @@ namespace transport ); } - std::set SSUServer::FindIntroducers (int maxNumIntroducers, bool v4) + std::list > SSUServer::FindIntroducers (int maxNumIntroducers, bool v4) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - std::set ret; - auto filter = [&ret, ts](std::shared_ptr session)->bool - { - return session->GetRelayTag () && !ret.count (session.get ()) && - session->GetState () == eSessionStateEstablished && - ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; - }; - for (int i = 0; i < maxNumIntroducers; i++) + std::list > ret; + const auto& sessions = v4 ? m_Sessions : m_SessionsV6; + for (const auto& s : sessions) + { + if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && + ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) + ret.push_back (s.second); + } + if ((int)ret.size () > maxNumIntroducers) { - auto session = v4 ? GetRandomV4Session (filter) : GetRandomV6Session (filter); - if (session) - ret.insert (session.get ()); - else - break; - } + // shink ret randomly + int sz = ret.size () - maxNumIntroducers; + for (int i = 0; i < sz; i++) + { + auto ind = rand () % ret.size (); + auto it = ret.begin (); + std::advance (it, ind); + ret.erase (it); + } + } return ret; } @@ -770,7 +775,7 @@ namespace transport if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new - auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS - numIntroducers, v4); + auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); // try to find if duplicates for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index cfeaf85f..e1751e0d 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -100,7 +100,7 @@ namespace transport template std::shared_ptr GetRandomV6Session (Filter filter); - std::set FindIntroducers (int maxNumIntroducers, bool v4); + std::list > FindIntroducers (int maxNumIntroducers, bool v4); void ScheduleIntroducersUpdateTimer (); void ScheduleIntroducersUpdateTimerV6 (); void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4); From b43a9cc80d63d770aa4d29b25347d639bc3185d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Apr 2021 19:30:20 -0400 Subject: [PATCH 0061/2193] handle master session creation --- libi2pd_client/SAM.cpp | 1 + libi2pd_client/SAM.h | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 1eb38a7e..c662c283 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -352,6 +352,7 @@ namespace client if (style == SAM_VALUE_STREAM) type = eSAMSessionTypeStream; else if (style == SAM_VALUE_DATAGRAM) type = eSAMSessionTypeDatagram; else if (style == SAM_VALUE_RAW) type = eSAMSessionTypeRaw; + else if (style == SAM_VALUE_MASTER) type = eSAMSessionTypeMaster; if (type == eSAMSessionTypeUnknown) { // unknown style diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 9495bf6f..8969c50e 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -76,6 +76,7 @@ namespace client const char SAM_VALUE_STREAM[] = "STREAM"; const char SAM_VALUE_DATAGRAM[] = "DATAGRAM"; const char SAM_VALUE_RAW[] = "RAW"; + const char SAM_VALUE_MASTER[] = "MASTER"; const char SAM_VALUE_TRUE[] = "true"; const char SAM_VALUE_FALSE[] = "false"; @@ -171,7 +172,8 @@ namespace client eSAMSessionTypeUnknown, eSAMSessionTypeStream, eSAMSessionTypeDatagram, - eSAMSessionTypeRaw + eSAMSessionTypeRaw, + eSAMSessionTypeMaster }; struct SAMSession @@ -187,7 +189,7 @@ namespace client void CloseStreams (); }; - + class SAMBridge: private i2p::util::RunnableService { public: From 9d79b265060d8afb9667fab473fef8c0364d09f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Apr 2021 19:32:47 -0400 Subject: [PATCH 0062/2193] check if port if specified --- libi2pd/SSU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 7a7400f9..6bdd8661 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -453,7 +453,7 @@ namespace transport m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, address, peerTest)); // always V4 thread else { - if (address->host.is_unspecified ()) return false; + if (address->host.is_unspecified () || !address->port) return false; boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port); m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest)); } @@ -802,7 +802,7 @@ namespace transport if (introducer && !requested.count (introducer)) // not requested already { auto address = v4 ? introducer->GetSSUAddress (true) : introducer->GetSSUV6Address (); - if (address && !address->host.is_unspecified ()) + if (address && !address->host.is_unspecified () && address->port) { boost::asio::ip::udp::endpoint ep (address->host, address->port); if (std::find (introducers.begin (), introducers.end (), ep) == introducers.end ()) // not connected yet From 7a19533380195a1a2d42c68bac34ab42d522dc89 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Apr 2021 12:17:48 -0400 Subject: [PATCH 0063/2193] reuse current introducers if no more available --- libi2pd/SSU.cpp | 33 ++++++++++++++++++++++++++------- libi2pd/SSU.h | 1 + libi2pd/SSUSession.h | 3 ++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 6bdd8661..49ce7e3e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -670,7 +670,7 @@ namespace transport for (const auto& s : sessions) { if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && - ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) + ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION) ret.push_back (s.second); } if ((int)ret.size () > maxNumIntroducers) @@ -762,13 +762,19 @@ namespace transport for (const auto& it : introducers) { auto session = FindSession (it); - if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) + if (session) { - session->SendKeepAlive (); - newList.push_back (it); - numIntroducers++; + if (ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION) + session->SendKeepAlive (); + if (ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) + { + newList.push_back (it); + numIntroducers++; + } + else + session = nullptr; } - else + if (!session) i2p::context.RemoveIntroducer (it); } @@ -776,6 +782,19 @@ namespace transport { // create new auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); // try to find if duplicates + if (sessions.empty () && !introducers.empty ()) + { + // bump creation time for previous introducers if no new sessions found + LogPrint (eLogDebug, "SSU: no new introducers found. Trying to reuse existing"); + for (const auto& it : introducers) + { + auto session = FindSession (it); + if (session) + session->SetCreationTime (session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION); + } + // try again + sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); + } for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); @@ -784,7 +803,7 @@ namespace transport introducer.iPort = ep.port (); introducer.iTag = it1->GetRelayTag (); introducer.iKey = it1->GetIntroKey (); - introducer.iExp = it1->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; + introducer.iExp = it1->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION; if (i2p::context.AddIntroducer (introducer)) { newList.push_back (ep); diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index e1751e0d..cbe51e6b 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -31,6 +31,7 @@ namespace transport const int SSU_KEEP_ALIVE_INTERVAL = 30; // 30 seconds const int SSU_PEER_TEST_TIMEOUT = 60; // 60 seconds const int SSU_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour + const int SSU_TO_INTRODUCER_SESSION_EXPIRATION = 4800; // 80 minutes const int SSU_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds const size_t SSU_MAX_NUM_INTRODUCERS = 3; const size_t SSU_SOCKET_RECEIVE_BUFFER_SIZE = 0x1FFFF; // 128K diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index ece8f5bf..43d0d595 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -102,7 +102,8 @@ namespace transport uint32_t GetRelayTag () const { return m_RelayTag; }; const i2p::data::RouterInfo::IntroKey& GetIntroKey () const { return m_IntroKey; }; uint32_t GetCreationTime () const { return m_CreationTime; }; - + void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers + void FlushData (); private: From db93a7315f7408cfd5438a6e7ec194e8f3fdb50a Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 24 Apr 2021 11:11:12 -0400 Subject: [PATCH 0064/2193] find new introducers to connect --- libi2pd/NetDb.cpp | 7 ++++--- libi2pd/NetDb.hpp | 2 +- libi2pd/SSU.cpp | 9 +++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index a71bb891..a1d97cba 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1168,12 +1168,13 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomIntroducer (bool v4) const + std::shared_ptr NetDb::GetRandomIntroducer (bool v4, const std::set& excluded) const { return GetRandomRouter ( - [v4](std::shared_ptr router)->bool + [v4, &excluded](std::shared_ptr router)->bool { - return router->IsIntroducer (v4) && !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag + return router->IsIntroducer (v4) && !excluded.count (router->GetIdentHash ()) && + !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 244ff39b..364cae4b 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -87,7 +87,7 @@ namespace data std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith, bool reverse) const; std::shared_ptr GetRandomPeerTestRouter (bool v4, const std::set& excluded) const; std::shared_ptr GetRandomSSUV6Router () const; // TODO: change to v6 peer test later - std::shared_ptr GetRandomIntroducer (bool v4) const; + std::shared_ptr GetRandomIntroducer (bool v4, const std::set& excluded) const; std::shared_ptr GetClosestFloodfill (const IdentHash& destination, const std::set& excluded, bool closeThanUsOnly = false) const; std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 49ce7e3e..9d75a069 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -778,6 +778,7 @@ namespace transport i2p::context.RemoveIntroducer (it); } + std::set excluded; if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new @@ -809,16 +810,16 @@ namespace transport newList.push_back (ep); if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break; } + excluded.insert (it1->GetRemoteIdentity ()->GetIdentHash ()); } } introducers = newList; if (introducers.size () < SSU_MAX_NUM_INTRODUCERS) { - std::set > requested; for (auto i = introducers.size (); i < SSU_MAX_NUM_INTRODUCERS; i++) { - auto introducer = i2p::data::netdb.GetRandomIntroducer (v4); - if (introducer && !requested.count (introducer)) // not requested already + auto introducer = i2p::data::netdb.GetRandomIntroducer (v4, excluded); + if (introducer) { auto address = v4 ? introducer->GetSSUAddress (true) : introducer->GetSSUV6Address (); if (address && !address->host.is_unspecified () && address->port) @@ -827,7 +828,7 @@ namespace transport if (std::find (introducers.begin (), introducers.end (), ep) == introducers.end ()) // not connected yet { CreateDirectSession (introducer, ep, false); - requested.insert (introducer); + excluded.insert (introducer->GetIdentHash ()); } } } From 94555b9c431ff5fb7ed8d1fb1887cbd6cddc5af5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 24 Apr 2021 14:56:34 -0400 Subject: [PATCH 0065/2193] don't select next introducers from existing sessions --- libi2pd/SSU.cpp | 29 ++++++++++++----------------- libi2pd/SSU.h | 3 +-- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 9d75a069..ad91a7c4 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -410,20 +410,6 @@ namespace transport if (session) session->FlushData (); } - std::shared_ptr SSUServer::FindSession (std::shared_ptr router) const - { - if (!router) return nullptr; - auto address = router->GetSSUAddress (true); // v4 only - if (!address) return nullptr; - auto session = FindSession (boost::asio::ip::udp::endpoint (address->host, address->port)); - if (session || !context.SupportsV6 ()) - return session; - // try v6 - address = router->GetSSUV6Address (); - if (!address) return nullptr; - return FindSession (boost::asio::ip::udp::endpoint (address->host, address->port)); - } - std::shared_ptr SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const { auto& sessions = e.address ().is_v6 () ? m_SessionsV6 : m_Sessions; @@ -662,7 +648,8 @@ namespace transport ); } - std::list > SSUServer::FindIntroducers (int maxNumIntroducers, bool v4) + std::list > SSUServer::FindIntroducers (int maxNumIntroducers, + bool v4, std::set& excluded) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); std::list > ret; @@ -672,6 +659,8 @@ namespace transport if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION) ret.push_back (s.second); + else + excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ()); } if ((int)ret.size () > maxNumIntroducers) { @@ -782,7 +771,7 @@ namespace transport if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new - auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); // try to find if duplicates + auto sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4, excluded); // try to find if duplicates if (sessions.empty () && !introducers.empty ()) { // bump creation time for previous introducers if no new sessions found @@ -794,7 +783,8 @@ namespace transport session->SetCreationTime (session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION); } // try again - sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4); + excluded.clear (); + sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4, excluded); } for (const auto& it1: sessions) { @@ -831,6 +821,11 @@ namespace transport excluded.insert (introducer->GetIdentHash ()); } } + } + else + { + LogPrint (eLogDebug, "SSU: can't find more introducers"); + break; } } } diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index cbe51e6b..aad3a384 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -56,7 +56,6 @@ namespace transport bool CreateSession (std::shared_ptr router, std::shared_ptr address, bool peerTest = false); void CreateDirectSession (std::shared_ptr router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest); - std::shared_ptr FindSession (std::shared_ptr router) const; std::shared_ptr FindSession (const boost::asio::ip::udp::endpoint& e) const; std::shared_ptr GetRandomEstablishedV4Session (std::shared_ptr excluded); std::shared_ptr GetRandomEstablishedV6Session (std::shared_ptr excluded); @@ -101,7 +100,7 @@ namespace transport template std::shared_ptr GetRandomV6Session (Filter filter); - std::list > FindIntroducers (int maxNumIntroducers, bool v4); + std::list > FindIntroducers (int maxNumIntroducers, bool v4, std::set& excluded); void ScheduleIntroducersUpdateTimer (); void ScheduleIntroducersUpdateTimerV6 (); void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4); From 90dee900f043ad34908e75dfec5b2085b5bd0528 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Apr 2021 10:57:31 -0400 Subject: [PATCH 0066/2193] fixed crash --- libi2pd/SSU.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index ad91a7c4..38e0196b 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -659,7 +659,7 @@ namespace transport if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION) ret.push_back (s.second); - else + else if (s.second->GetRemoteIdentity ()) excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ()); } if ((int)ret.size () > maxNumIntroducers) @@ -800,7 +800,8 @@ namespace transport newList.push_back (ep); if (newList.size () >= SSU_MAX_NUM_INTRODUCERS) break; } - excluded.insert (it1->GetRemoteIdentity ()->GetIdentHash ()); + if (it1->GetRemoteIdentity ()) + excluded.insert (it1->GetRemoteIdentity ()->GetIdentHash ()); } } introducers = newList; From 4a0dbec4fbdc389334457423404a664f2ba54d33 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Apr 2021 16:42:09 -0400 Subject: [PATCH 0067/2193] recognize non-published NTCP2 address --- libi2pd/RouterContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index e4697f2b..a59f0602 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -547,7 +547,7 @@ namespace i2p { if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) foundSSU = true; - else if (addr->IsPublishedNTCP2 ()) + else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP) foundNTCP2 = true; } port = addr->port; From e091eba83107e22d8a656c7fe28bc9a030f7f467 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Apr 2021 17:55:13 -0400 Subject: [PATCH 0068/2193] don't cleanup ipv6 introducers list twice --- libi2pd/SSU.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 38e0196b..11fab97f 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -726,6 +726,8 @@ namespace transport m_Introducers.clear (); return; } + // we are firewalled + if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable (true, false); // v4 } else { @@ -740,13 +742,17 @@ namespace transport // we don't need introducers m_IntroducersV6.clear (); return; - } + } + // we are firewalled + auto addr = i2p::context.GetRouterInfo ().GetSSUV6Address (); + if (addr && addr->ssu && addr->ssu->introducers.empty ()) + i2p::context.SetUnreachable (false, true); // v6 } - // we are firewalled - if (!i2p::context.IsUnreachable () || !v4) i2p::context.SetUnreachable (v4, !v4); + std::list newList; size_t numIntroducers = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + std::set excluded; auto& introducers = v4 ? m_Introducers : m_IntroducersV6; for (const auto& it : introducers) { @@ -759,6 +765,8 @@ namespace transport { newList.push_back (it); numIntroducers++; + if (session->GetRemoteIdentity ()) + excluded.insert (session->GetRemoteIdentity ()->GetIdentHash ()); } else session = nullptr; @@ -766,8 +774,6 @@ namespace transport if (!session) i2p::context.RemoveIntroducer (it); } - - std::set excluded; if (numIntroducers < SSU_MAX_NUM_INTRODUCERS) { // create new From bd33ac202f7fc2a255524e9c8538d06642e6d577 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Apr 2021 18:21:00 -0400 Subject: [PATCH 0069/2193] handle hostname for STREAM CREATE --- libi2pd_client/SAM.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index c662c283..41d08147 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -496,10 +496,9 @@ namespace client else m_BufferOffset = 0; - std::shared_ptr
addr; - auto pos = destination.find(".b32.i2p"); - if (pos != std::string::npos) - addr = std::make_shared
(destination.substr (0, pos)); + std::shared_ptr addr; + if (destination.find(".i2p") != std::string::npos) + addr = context.GetAddressBook().GetAddress (destination); else { auto dest = std::make_shared (); From 4018cf9d76f330cceb92ab51a35dd28bbafa1d64 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Apr 2021 21:11:36 -0400 Subject: [PATCH 0070/2193] SAM single and master sessions --- daemon/HTTPServer.cpp | 4 +-- daemon/I2PControl.cpp | 4 +-- libi2pd_client/SAM.cpp | 68 ++++++++++++++++++++++-------------------- libi2pd_client/SAM.h | 31 ++++++++++++++----- 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c263cea9..6410a044 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -842,7 +842,7 @@ namespace http { s << "SAM Sessions:
\r\n
\r\n"; for (auto& it: sam->GetSessions ()) { - auto& name = it.second->localDestination->GetNickname (); + auto& name = it.second->GetLocalDestination ()->GetNickname (); s << "\r\n" << std::endl; } @@ -868,7 +868,7 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); s << "SAM Session:
\r\n
\r\n"; - auto& ident = session->localDestination->GetIdentHash(); + auto& ident = session->GetLocalDestination ()->GetIdentHash(); s << "\r\n"; s << "
\r\n"; diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 3f0033e5..d71a9f1c 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -714,8 +714,8 @@ namespace client for (auto& it: sam->GetSessions ()) { boost::property_tree::ptree sam_session, sam_session_sockets; - auto& name = it.second->localDestination->GetNickname (); - auto& ident = it.second->localDestination->GetIdentHash(); + auto& name = it.second->GetLocalDestination ()->GetNickname (); + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); sam_session.put("name", name); sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 41d08147..c9c88709 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -58,8 +58,8 @@ namespace client { if (Session) { - if (m_IsAccepting && Session->localDestination) - Session->localDestination->StopAcceptingStreams (); + if (m_IsAccepting && Session->GetLocalDestination ()) + Session->GetLocalDestination ()->StopAcceptingStreams (); } break; } @@ -410,7 +410,7 @@ namespace client if (type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) { session->UDPEndpoint = forward; - auto dest = session->localDestination->CreateDatagramDestination (); + auto dest = session->GetLocalDestination ()->CreateDatagramDestination (); if (type == eSAMSessionTypeDatagram) dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); @@ -419,7 +419,7 @@ namespace client std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } - if (session->localDestination->IsReady ()) + if (session->GetLocalDestination ()->IsReady ()) SendSessionCreateReplyOk (); else { @@ -439,7 +439,7 @@ namespace client auto session = m_Owner.FindSession(m_ID); if(session) { - if (session->localDestination->IsReady ()) + if (session->GetLocalDestination ()->IsReady ()) SendSessionCreateReplyOk (); else { @@ -458,7 +458,7 @@ namespace client { uint8_t buf[1024]; char priv[1024]; - size_t l = session->localDestination->GetPrivateKeys ().ToBuffer (buf, 1024); + size_t l = session->GetLocalDestination ()->GetPrivateKeys ().ToBuffer (buf, 1024); size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, priv, 1024); priv[l1] = 0; #ifdef _MSC_VER @@ -514,18 +514,18 @@ namespace client { if (addr->IsIdentHash ()) { - auto leaseSet = session->localDestination->FindLeaseSet(addr->identHash); + auto leaseSet = session->GetLocalDestination ()->FindLeaseSet(addr->identHash); if (leaseSet) Connect(leaseSet, session); else { - session->localDestination->RequestDestination(addr->identHash, + session->GetLocalDestination ()->RequestDestination(addr->identHash, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, shared_from_this(), std::placeholders::_1)); } } else // B33 - session->localDestination->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, + session->GetLocalDestination ()->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, shared_from_this(), std::placeholders::_1)); } @@ -542,7 +542,7 @@ namespace client if (session) { m_SocketType = eSAMSocketTypeStream; - m_Stream = session->localDestination->CreateStream (remote); + m_Stream = session->GetLocalDestination ()->CreateStream (remote); if (m_Stream) { m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send @@ -586,10 +586,10 @@ namespace client if (session) { m_SocketType = eSAMSocketTypeAcceptor; - if (!session->localDestination->IsAcceptingStreams ()) + if (!session->GetLocalDestination ()->IsAcceptingStreams ()) { m_IsAccepting = true; - session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); + session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } @@ -609,7 +609,7 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); return; } - if (session->localDestination->IsAcceptingStreams ()) + if (session->GetLocalDestination ()->IsAcceptingStreams ()) { SendI2PError ("Already accepting"); return; @@ -639,7 +639,7 @@ namespace client m_IsAccepting = true; std::string& silent = params[SAM_PARAM_SILENT]; if (silent == SAM_VALUE_TRUE) m_IsSilent = true; - session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PForward, + session->GetLocalDestination ()->AcceptStreams (std::bind (&SAMSocket::HandleI2PForward, shared_from_this (), std::placeholders::_1, ep)); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } @@ -655,7 +655,7 @@ namespace client auto session = m_Owner.FindSession(m_ID); if (session) { - auto d = session->localDestination->GetDatagramDestination (); + auto d = session->GetLocalDestination ()->GetDatagramDestination (); if (d) { i2p::data::IdentityEx dest; @@ -725,7 +725,7 @@ namespace client std::shared_ptr identity; std::shared_ptr addr; auto session = m_Owner.FindSession(m_ID); - auto dest = session == nullptr ? context.GetSharedLocalDestination() : session->localDestination; + auto dest = session == nullptr ? context.GetSharedLocalDestination() : session->GetLocalDestination (); if (name == "ME") SendNamingLookupReply (name, dest->GetIdentity ()); else if ((identity = context.GetAddressBook ().GetFullAddress (name)) != nullptr) @@ -971,7 +971,7 @@ namespace client if (it->m_SocketType == eSAMSocketTypeAcceptor) { it->m_IsAccepting = true; - session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1)); + session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1)); break; } } @@ -1109,19 +1109,11 @@ namespace client m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); } - SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type, std::shared_ptr dest): - m_Bridge(parent), - localDestination (dest), - UDPEndpoint(nullptr), - Name(id), Type (type) + SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type): + m_Bridge(parent), Name(id), Type (type), UDPEndpoint(nullptr) { } - SAMSession::~SAMSession () - { - i2p::client::context.DeleteLocalDestination (localDestination); - } - void SAMSession::CloseStreams () { for(const auto & itr : m_Bridge.ListSockets(Name)) @@ -1130,6 +1122,17 @@ namespace client } } + SAMSingleSession::SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest): + SAMSession (parent, name, type), + localDestination (dest) + { + } + + SAMSingleSession::~SAMSingleSession () + { + i2p::client::context.DeleteLocalDestination (localDestination); + } + SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): RunnableService ("SAM"), m_IsSingleThread (singleThread), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), @@ -1267,7 +1270,8 @@ namespace client if (localDestination) { localDestination->Acquire (); - auto session = std::make_shared(*this, id, type, localDestination); + auto session = (type == eSAMSessionTypeMaster) ? std::make_shared(*this, id, localDestination) : + std::make_shared(*this, id, type, localDestination); std::unique_lock l(m_SessionsMutex); auto ret = m_Sessions.insert (std::make_pair(id, session)); if (!ret.second) @@ -1291,8 +1295,8 @@ namespace client } if (session) { - session->localDestination->Release (); - session->localDestination->StopAcceptingStreams (); + session->GetLocalDestination ()->Release (); + session->GetLocalDestination ()->StopAcceptingStreams (); session->CloseStreams (); if (m_IsSingleThread) { @@ -1368,10 +1372,10 @@ namespace client i2p::data::IdentityEx dest; dest.FromBase64 (destination); if (session->Type == eSAMSessionTypeDatagram) - session->localDestination->GetDatagramDestination ()-> + session->GetLocalDestination ()->GetDatagramDestination ()-> SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); else // raw - session->localDestination->GetDatagramDestination ()-> + session->GetLocalDestination ()->GetDatagramDestination ()-> SendRawDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); } else diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 8969c50e..2c2729cf 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -179,17 +179,34 @@ namespace client struct SAMSession { SAMBridge & m_Bridge; - std::shared_ptr localDestination; - std::shared_ptr UDPEndpoint; std::string Name; SAMSessionType Type; - - SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest); - ~SAMSession (); - + std::shared_ptr UDPEndpoint; // TODO: move + + SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type); + virtual ~SAMSession () {}; + + virtual std::shared_ptr GetLocalDestination () = 0; + void CloseStreams (); }; - + + struct SAMSingleSession: public SAMSession + { + std::shared_ptr localDestination; + + SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest); + ~SAMSingleSession (); + + std::shared_ptr GetLocalDestination () { return localDestination; }; + }; + + struct SAMMasterSession: public SAMSingleSession + { + SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr dest): + SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {}; + }; + class SAMBridge: private i2p::util::RunnableService { public: From d8d8a688143cc3bf9f69fd34a730e70c97da1b6b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 30 Apr 2021 15:19:31 -0400 Subject: [PATCH 0071/2193] rekey all routers but floodfills --- libi2pd/RouterContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index a59f0602..9602fe17 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -740,8 +740,8 @@ namespace i2p if (!rekey && m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) { // rekey routers with bandwidth = L (or default) this time - std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); - if (bandwidth.empty () || bandwidth[0] == 'L') rekey = true; + bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); + if (!isFloodfill) rekey = true; } if (rekey) { From 7f143a7f232584ea269b467e8ac0ce3ecc6d40e1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 2 May 2021 15:02:52 -0400 Subject: [PATCH 0072/2193] support EdDSA for blinding --- libi2pd/Blinding.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 6770d223..dbab9b94 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -272,11 +272,19 @@ namespace data case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: publicKeyLength = BlindECDSA (m_SigType, priv, seed, BlindEncodedPrivateKeyECDSA, blindedPriv, blindedPub); - break; + break; case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub); publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; break; + case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: + { + uint8_t exp[64]; + i2p::crypto::Ed25519::ExpandPrivateKey (priv, exp); + i2p::crypto::GetEd25519 ()->BlindPrivateKey (exp, seed, blindedPriv, blindedPub); + publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; + break; + } default: LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); } From 0b9cb4e75b8931fd9bdde52a60f1615871a59799 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 May 2021 19:05:25 -0400 Subject: [PATCH 0073/2193] check identity and signature length for SessionConfirmed --- libi2pd/SSUSession.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 7b7355a4..3c519d6b 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -321,12 +321,17 @@ namespace transport auto headerSize = GetSSUHeaderSize (buf); if (headerSize >= len) { - LogPrint (eLogError, "SSU: Session confirmed header size ", len, " exceeds packet length ", len); + LogPrint (eLogError, "SSU: Session confirmed header size ", headerSize, " exceeds packet length ", len); return; } const uint8_t * payload = buf + headerSize; payload++; // identity fragment info uint16_t identitySize = bufbe16toh (payload); + if (identitySize + headerSize + 7 > len) // 7 = fragment info + fragment size + signed on time + { + LogPrint (eLogError, "SSU: Session confirmed identity size ", identitySize, " exceeds packet length ", len); + return; + } payload += 2; // size of identity fragment auto identity = std::make_shared (payload, identitySize); auto existing = i2p::data::netdb.FindRouter (identity->GetIdentHash ()); // check if exists already @@ -344,10 +349,15 @@ namespace transport if (m_SignedData) m_SignedData->Insert (payload, 4); // insert Alice's signed on time payload += 4; // signed-on time - size_t paddingSize = (payload - buf) + m_RemoteIdentity->GetSignatureLen (); - paddingSize &= 0x0F; // %16 + size_t fullSize = (payload - buf) + m_RemoteIdentity->GetSignatureLen (); + size_t paddingSize = fullSize & 0x0F; // %16 if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; + if (fullSize + paddingSize > len) + { + LogPrint (eLogError, "SSU: Session confirmed message is too short ", len); + return; + } // verify signature if (m_SignedData && m_SignedData->Verify (m_RemoteIdentity, payload)) { From fffa550bb0bfeda045a6b98dc1631ec68cf0166d Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 May 2021 14:27:06 -0400 Subject: [PATCH 0074/2193] SAM subsessions --- libi2pd/Destination.cpp | 19 ++++++++++++++-- libi2pd/Destination.h | 1 + libi2pd_client/SAM.cpp | 50 +++++++++++++++++++++++++++++++++++++++-- libi2pd_client/SAM.h | 19 +++++++++++++++- 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f47ac421..22ba0b39 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1131,13 +1131,28 @@ namespace client return dest; } + std::shared_ptr ClientDestination::RemoveStreamingDestination (int port) + { + if (port) + { + auto it = m_StreamingDestinationsByPorts.find (port); + if (it != m_StreamingDestinationsByPorts.end ()) + { + auto ret = it->second; + m_StreamingDestinationsByPorts.erase (it); + return ret; + } + } + return nullptr; + } + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) { if (m_DatagramDestination == nullptr) m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip); return m_DatagramDestination; - } - + } + std::vector > ClientDestination::GetAllStreams () const { std::vector > ret; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f04431c7..6e149cf5 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -236,6 +236,7 @@ namespace client // streaming std::shared_ptr CreateStreamingDestination (int port, bool gzip = true); // additional std::shared_ptr GetStreamingDestination (int port = 0) const; + std::shared_ptr RemoveStreamingDestination (int port); // following methods operate with default streaming destination void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0); void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port = 0); diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index c9c88709..061cc820 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -270,6 +270,10 @@ namespace client ProcessDestGenerate (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); else if (!strcmp (m_Buffer, SAM_NAMING_LOOKUP)) ProcessNamingLookup (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); + else if (!strcmp (m_Buffer, SAM_SESSION_ADD)) + ProcessSessionAdd (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); + else if (!strcmp (m_Buffer, SAM_SESSION_REMOVE)) + ProcessSessionRemove (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); else if (!strcmp (m_Buffer, SAM_DATAGRAM_SEND) || !strcmp (m_Buffer, SAM_RAW_SEND)) { size_t len = bytes_transferred - (separator - m_Buffer) - 1; @@ -759,6 +763,16 @@ namespace client } } + void SAMSocket::ProcessSessionAdd (char * buf, size_t len) + { + // TODO: implement + } + + void SAMSocket::ProcessSessionRemove (char * buf, size_t len) + { + // TODO: implement + } + void SAMSocket::SendI2PError(const std::string & msg) { LogPrint (eLogError, "SAM: i2p error ", msg); @@ -1132,6 +1146,39 @@ namespace client { i2p::client::context.DeleteLocalDestination (localDestination); } + + void SAMSingleSession::StopLocalDestination () + { + localDestination->Release (); + localDestination->StopAcceptingStreams (); + } + + SAMSubSession::SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, int port): + SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port) + { + if (Type == eSAMSessionTypeStream) + { + auto d = masterSession->GetLocalDestination ()->CreateStreamingDestination (inPort); + if (d) d->Start (); + } + // TODO: implement datagrams + } + + std::shared_ptr SAMSubSession::GetLocalDestination () + { + return masterSession ? masterSession->GetLocalDestination () : nullptr; + } + + void SAMSubSession::StopLocalDestination () + { + auto dest = GetLocalDestination (); + if (dest && Type == eSAMSessionTypeStream) + { + auto d = dest->RemoveStreamingDestination (inPort); + if (d) d->Stop (); + } + // TODO: implement datagrams + } SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): RunnableService ("SAM"), m_IsSingleThread (singleThread), @@ -1295,8 +1342,7 @@ namespace client } if (session) { - session->GetLocalDestination ()->Release (); - session->GetLocalDestination ()->StopAcceptingStreams (); + session->StopLocalDestination (); session->CloseStreams (); if (m_IsSingleThread) { diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 2c2729cf..8669538a 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -41,6 +41,8 @@ namespace client const char SAM_SESSION_CREATE_INVALID_ID[] = "SESSION STATUS RESULT=INVALID_ID\n"; const char SAM_SESSION_STATUS_INVALID_KEY[] = "SESSION STATUS RESULT=INVALID_KEY\n"; const char SAM_SESSION_STATUS_I2P_ERROR[] = "SESSION STATUS RESULT=I2P_ERROR MESSAGE=%s\n"; + const char SAM_SESSION_ADD[] = "SESSION ADD"; + const char SAM_SESSION_REMOVE[] = "SESSION REMOVE"; const char SAM_STREAM_CONNECT[] = "STREAM CONNECT"; const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n"; const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n"; @@ -135,6 +137,8 @@ namespace client void ProcessStreamForward (char * buf, size_t len); void ProcessDestGenerate (char * buf, size_t len); void ProcessNamingLookup (char * buf, size_t len); + void ProcessSessionAdd (char * buf, size_t len); + void ProcessSessionRemove (char * buf, size_t len); void SendI2PError(const std::string & msg); size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 void ExtractParams (char * buf, std::map& params); @@ -187,6 +191,7 @@ namespace client virtual ~SAMSession () {}; virtual std::shared_ptr GetLocalDestination () = 0; + virtual void StopLocalDestination () = 0; void CloseStreams (); }; @@ -199,6 +204,7 @@ namespace client ~SAMSingleSession (); std::shared_ptr GetLocalDestination () { return localDestination; }; + void StopLocalDestination (); }; struct SAMMasterSession: public SAMSingleSession @@ -206,7 +212,18 @@ namespace client SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr dest): SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {}; }; - + + struct SAMSubSession: public SAMSession + { + std::shared_ptr masterSession; + int inPort; + + SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, int port); + // implements SAMSession + std::shared_ptr GetLocalDestination (); + void StopLocalDestination (); + }; + class SAMBridge: private i2p::util::RunnableService { public: From 5ad4c2a65ec3d8338e03c67ed57aee8b2708cec0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 May 2021 14:59:25 -0400 Subject: [PATCH 0075/2193] run ipv6 peer test again if still testing --- libi2pd/Transports.cpp | 15 +++++++++------ libi2pd/Transports.h | 6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 4ad13518..8413c859 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -581,10 +581,10 @@ namespace transport LogPrint (eLogError, "Transports: Can't detect external IP. SSU is not available"); } - void Transports::PeerTest () + void Transports::PeerTest (bool ipv4, bool ipv6) { if (RoutesRestricted() || !m_SSUServer) return; - if (i2p::context.SupportsV4 ()) + if (ipv4 && i2p::context.SupportsV4 ()) { LogPrint (eLogInfo, "Transports: Started peer test ipv4"); std::set excluded; @@ -610,7 +610,7 @@ namespace transport if (!statusChanged) LogPrint (eLogWarning, "Transports: Can't find routers for peer test ipv4"); } - if (i2p::context.SupportsV6 ()) + if (ipv6 && i2p::context.SupportsV6 ()) { LogPrint (eLogInfo, "Transports: Started peer test ipv6"); std::set excluded; @@ -750,9 +750,12 @@ namespace transport ++it; } UpdateBandwidth (); // TODO: use separate timer(s) for it - if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test - DetectExternalIP (); - m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); + bool ipv4Testing = i2p::context.GetStatus () == eRouterStatusTesting; + bool ipv6Testing = i2p::context.GetStatusV6 () == eRouterStatusTesting; + // if still testing, repeat peer test + if (ipv4Testing || ipv6Testing) + PeerTest (ipv4Testing, ipv6Testing); + m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(3*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index d480840a..9377286c 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -76,9 +76,9 @@ namespace transport } }; - const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds + const size_t SESSION_CREATION_TIMEOUT = 15; // in seconds const int PEER_TEST_INTERVAL = 71; // in minutes - const int MAX_NUM_DELAYED_MESSAGES = 50; + const int MAX_NUM_DELAYED_MESSAGES = 150; class Transports { public: @@ -131,7 +131,7 @@ namespace transport bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; - void PeerTest (); + void PeerTest (bool ipv4 = true, bool ipv6 = true); void SetCheckReserved (bool check) { m_CheckReserved = check; }; bool IsCheckReserved () { return m_CheckReserved; }; From 79dbf2a43e3b5b2bdbecb9c3727e04f22b4c3edb Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 7 May 2021 22:15:12 -0400 Subject: [PATCH 0076/2193] request encrypted LeaseSet if expired --- libi2pd/Streaming.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 0d482303..a484c433 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -942,15 +942,21 @@ namespace stream { if (!m_RemoteLeaseSet || m_RemoteLeaseSet->IsExpired ()) { - m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ()); - if (!m_RemoteLeaseSet) + auto remoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ()); + if (!remoteLeaseSet) { - LogPrint (eLogWarning, "Streaming: LeaseSet ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " not found"); - m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); // try to request for a next attempt + LogPrint (eLogWarning, "Streaming: LeaseSet ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), m_RemoteLeaseSet ? " expired" : " not found"); + if (m_RemoteLeaseSet && m_RemoteLeaseSet->IsPublishedEncrypted ()) + m_LocalDestination.GetOwner ()->RequestDestinationWithEncryptedLeaseSet ( + std::make_shared(m_RemoteIdentity)); + else + m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); // try to request for a next attempt + return; } else { // LeaseSet updated + m_RemoteLeaseSet = remoteLeaseSet; m_RemoteIdentity = m_RemoteLeaseSet->GetIdentity (); m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier (); } From d6f5640685dd542454771882181a29ec23885feb Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 9 May 2021 07:33:26 -0400 Subject: [PATCH 0077/2193] attach updated LeaseSet to ECIESx25519 incoming sessions --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 6 ++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Streaming.cpp | 9 +++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index f956fa67..0f2518f7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -160,9 +160,10 @@ namespace garlic return true; } - ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): - GarlicRoutingSession (owner, attachLeaseSet) + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSetNS): + GarlicRoutingSession (owner, true) { + if (!attachLeaseSetNS) SetLeaseSetUpdateStatus (eLeaseSetUpToDate); RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0; } @@ -1101,6 +1102,7 @@ namespace garlic RouterIncomingRatchetSession::RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState): ECIESX25519AEADRatchetSession (&i2p::context, false) { + SetLeaseSetUpdateStatus (eLeaseSetDoNotSend); SetNoiseState (initState); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index bd6d55e3..24bffae2 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -160,7 +160,7 @@ namespace garlic public: - ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); + ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSetNS); ~ECIESX25519AEADRatchetSession (); bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index a484c433..612b1058 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -946,12 +946,17 @@ namespace stream if (!remoteLeaseSet) { LogPrint (eLogWarning, "Streaming: LeaseSet ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), m_RemoteLeaseSet ? " expired" : " not found"); - if (m_RemoteLeaseSet && m_RemoteLeaseSet->IsPublishedEncrypted ()) + if (m_RemoteLeaseSet && m_RemoteLeaseSet->IsPublishedEncrypted ()) + { m_LocalDestination.GetOwner ()->RequestDestinationWithEncryptedLeaseSet ( std::make_shared(m_RemoteIdentity)); + return; // we keep m_RemoteLeaseSet for possible next request + } else + { + m_RemoteLeaseSet = nullptr; m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); // try to request for a next attempt - return; + } } else { From a8e1cd9a13d14978af7a6df8e9ccded9bb8f4dd1 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 10 May 2021 11:04:08 -0400 Subject: [PATCH 0078/2193] don't throw exception if local bind fails --- libi2pd_client/I2PTunnel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index b15b47b0..5476bfe2 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -84,7 +84,11 @@ namespace client // bind to 127.x.x.x address // where x.x.x are first three bytes from ident auto ourIP = GetLoopbackAddressFor(addr); - sock->bind (boost::asio::ip::tcp::endpoint (ourIP, 0)); + boost::system::error_code ec; + sock->bind (boost::asio::ip::tcp::endpoint (ourIP, 0), ec); + if (ec) + LogPrint (eLogError, "I2PTunnel: can't bind ourIP to ", ourIP.to_string (), ": ", ec.message ()); + } #endif From 1285e30b3ec13c6c9a1e69ec3217ec1ac7c85b45 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 10 May 2021 18:55:39 -0400 Subject: [PATCH 0079/2193] more pre-calculated x25519 --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/Garlic.cpp | 1 + libi2pd/Transports.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 0f2518f7..9eab8af2 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -196,7 +196,7 @@ namespace garlic i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); } // we still didn't find elligator eligible pair - for (int i = 0; i < 10; i++) + for (int i = 0; i < 25; i++) { // create new m_EphemeralKeys = std::make_shared(); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 42aca5be..220c5fed 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -556,6 +556,7 @@ namespace garlic if (m_LastTagset && m_LastTagset->GetNextIndex () < 2*ECIESX25519_TAGSET_MAX_NUM_TAGS) { auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); + LogPrint (eLogWarning, "Garlic: trying to generate more ECIES-X25519-AEAD-Ratchet tags"); for (int i = 0; i < maxTags; i++) { auto nextTag = AddECIESx25519SessionNextTag (m_LastTagset); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 8413c859..1e40f88c 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -137,7 +137,7 @@ namespace transport m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), - m_X25519KeysPairSupplier (5), // 5 pre-generated keys + m_X25519KeysPairSupplier (15), // 15 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), From c6cdb26f47cb09befb1a973cd8855f987b3acac4 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 10 May 2021 20:20:25 -0400 Subject: [PATCH 0080/2193] reduce range for extra tags --- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- libi2pd/Garlic.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 24bffae2..bdbb7111 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -88,7 +88,8 @@ namespace garlic bool IsNS () const { return m_IsNS; }; std::shared_ptr GetSession () { return m_Session; }; void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; - + int GetTrimBehind () const { return m_TrimBehindIndex; }; + void Expire (); bool IsExpired (uint64_t ts) const; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 220c5fed..27db6b63 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -553,7 +553,7 @@ namespace garlic if (!session->HandleNextMessage (buf, length, nullptr, 0)) { // try to gererate more tags for last tagset - if (m_LastTagset && m_LastTagset->GetNextIndex () < 2*ECIESX25519_TAGSET_MAX_NUM_TAGS) + if (m_LastTagset && (m_LastTagset->GetNextIndex () - m_LastTagset->GetTrimBehind () < 3*ECIESX25519_MAX_NUM_GENERATED_TAGS)) { auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); LogPrint (eLogWarning, "Garlic: trying to generate more ECIES-X25519-AEAD-Ratchet tags"); From 43b587636b783326fdf7f6c5300ff52785e5d743 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 11 May 2021 18:49:17 -0400 Subject: [PATCH 0081/2193] delete tags of termiated session right away --- libi2pd/Garlic.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 27db6b63..66a3b62f 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -880,8 +880,12 @@ namespace garlic { auto session = it->second.tagset->GetSession (); if (!session || session->IsTerminated()) - it->second.tagset->Expire (); - ++it; + { + it = m_ECIESx25519Tags.erase (it); + numExpiredTags++; + } + else + ++it; } } if (numExpiredTags > 0) From baec22610e3936cf5ea7678e6ef70f2b00c06e16 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 12 May 2021 07:57:37 -0400 Subject: [PATCH 0082/2193] always set expiration time for NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9eab8af2..f9d5672f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -512,6 +512,7 @@ namespace garlic { auto tagsetNsr = std::make_shared(shared_from_this (), true); InitNewSessionTagset (tagsetNsr); + tagsetNsr->Expire (); // let non-replied session expire GenerateMoreReceiveTags (tagsetNsr, ECIESX25519_NSR_NUM_GENERATED_TAGS); } } @@ -814,7 +815,6 @@ namespace garlic case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: - receiveTagset->Expire (); // NSR tagset return HandleNewOutgoingSessionReply (buf, len); default: return false; From 2b22bfadbc81810ecb985fcadf975d310ffa4c32 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 12 May 2021 11:48:27 -0400 Subject: [PATCH 0083/2193] show version in hidden content --- daemon/HTTPServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 6410a044..f0a4b616 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -325,6 +325,7 @@ namespace http { if (!i2p::context.GetRouterInfo().GetProperty("family").empty()) s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; + s << "Version: " VERSION "
\r\n"; s << "Our external address:" << "
\r\n\r\n"; for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) { From d299cbaabdf46e88549a350e4d23e4289b36a61a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 13 May 2021 19:30:54 -0400 Subject: [PATCH 0084/2193] Add/Remove subsession --- libi2pd_client/SAM.cpp | 80 +++++++++++++++++++++++++++++++++++++++--- libi2pd_client/SAM.h | 6 ++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 061cc820..af9ba6a8 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -765,12 +765,69 @@ namespace client void SAMSocket::ProcessSessionAdd (char * buf, size_t len) { - // TODO: implement + auto session = m_Owner.FindSession(m_ID); + if (session && session->Type == eSAMSessionTypeMaster) + { + LogPrint (eLogDebug, "SAM: subsession add: ", buf); + auto masterSession = std::static_pointer_cast(session); + std::map params; + ExtractParams (buf, params); + std::string& id = params[SAM_PARAM_ID]; + if (masterSession->subsessions.count (id) > 1) + { + // session exists + SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false); + return; + } + std::string& style = params[SAM_PARAM_STYLE]; + SAMSessionType type = eSAMSessionTypeUnknown; + if (style == SAM_VALUE_STREAM) type = eSAMSessionTypeStream; + // TODO: implement other styles + if (type == eSAMSessionTypeUnknown) + { + // unknown style + SendI2PError("Unsupported STYLE"); + return; + } + auto fromPort = std::stoi(params[SAM_PARAM_FROM_PORT]); + if (fromPort == -1) + { + SendI2PError("Invalid from port"); + return; + } + auto subsession = std::make_shared(masterSession, id, type, fromPort); + if (m_Owner.AddSession (subsession)) + { + masterSession->subsessions.insert (id); + SendSessionCreateReplyOk (); + } + else + SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false); + } + else + SendI2PError ("Wrong session type"); } void SAMSocket::ProcessSessionRemove (char * buf, size_t len) { - // TODO: implement + auto session = m_Owner.FindSession(m_ID); + if (session && session->Type == eSAMSessionTypeMaster) + { + LogPrint (eLogDebug, "SAM: subsession remove: ", buf); + auto masterSession = std::static_pointer_cast(session); + std::map params; + ExtractParams (buf, params); + std::string& id = params[SAM_PARAM_ID]; + if (!masterSession->subsessions.erase (id)) + { + SendMessageReply (SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), false); + return; + } + m_Owner.CloseSession (id); + SendSessionCreateReplyOk (); + } + else + SendI2PError ("Wrong session type"); } void SAMSocket::SendI2PError(const std::string & msg) @@ -1153,6 +1210,14 @@ namespace client localDestination->StopAcceptingStreams (); } + void SAMMasterSession::Close () + { + SAMSingleSession::Close (); + for (const auto& it: subsessions) + m_Bridge.CloseSession (it); + subsessions.clear (); + } + SAMSubSession::SAMSubSession (std::shared_ptr master, const std::string& name, SAMSessionType type, int port): SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port) { @@ -1225,7 +1290,7 @@ namespace client { std::unique_lock l(m_SessionsMutex); for (auto& it: m_Sessions) - it.second->CloseStreams (); + it.second->Close (); m_Sessions.clear (); } StopIOService (); @@ -1328,6 +1393,13 @@ namespace client return nullptr; } + bool SAMBridge::AddSession (std::shared_ptr session) + { + if (!session) return false; + auto ret = m_Sessions.emplace (session->Name, session); + return ret.second; + } + void SAMBridge::CloseSession (const std::string& id) { std::shared_ptr session; @@ -1343,7 +1415,7 @@ namespace client if (session) { session->StopLocalDestination (); - session->CloseStreams (); + session->Close (); if (m_IsSingleThread) { auto timer = std::make_shared(GetService ()); diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 8669538a..d92cf009 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,7 @@ namespace client const char SAM_PARAM_SIZE[] = "SIZE"; const char SAM_PARAM_HOST[] = "HOST"; const char SAM_PARAM_PORT[] = "PORT"; + const char SAM_PARAM_FROM_PORT[] = "FROM_PORT"; const char SAM_VALUE_TRANSIENT[] = "TRANSIENT"; const char SAM_VALUE_STREAM[] = "STREAM"; const char SAM_VALUE_DATAGRAM[] = "DATAGRAM"; @@ -192,6 +194,7 @@ namespace client virtual std::shared_ptr GetLocalDestination () = 0; virtual void StopLocalDestination () = 0; + virtual void Close () { CloseStreams (); }; void CloseStreams (); }; @@ -209,8 +212,10 @@ namespace client struct SAMMasterSession: public SAMSingleSession { + std::set subsessions; SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr dest): SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {}; + void Close (); }; struct SAMSubSession: public SAMSession @@ -237,6 +242,7 @@ namespace client boost::asio::io_service& GetService () { return GetIOService (); }; std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); + bool AddSession (std::shared_ptr session); void CloseSession (const std::string& id); std::shared_ptr FindSession (const std::string& id) const; From c359c6e634fdc106298291c8630b3a1ccb8aa131 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 15 May 2021 16:28:16 +0300 Subject: [PATCH 0085/2193] update config file example, add v6 status to windows daemon window, code cleanup Signed-off-by: R4SAS --- Win32/Win32App.cpp | 50 +++++++++---- contrib/i2pd.conf | 54 +++++++------ daemon/Daemon.cpp | 26 +++---- daemon/HTTPServer.cpp | 22 +++--- daemon/I2PControl.cpp | 4 + libi2pd/Config.cpp | 14 ++-- libi2pd/Destination.cpp | 5 +- libi2pd/NTCP2.cpp | 56 +++++++------- libi2pd/RouterContext.cpp | 154 +++++++++++++++++++------------------- libi2pd/SSU.cpp | 98 ++++++++++++------------ libi2pd/SSUSession.cpp | 2 +- 11 files changed, 258 insertions(+), 227 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 15157355..db5a1f3d 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -142,25 +142,47 @@ namespace win32 s << bytes << " Bytes\n"; } + static void ShowNetworkStatus (std::stringstream& s, RouterStatus status) + { + switch (status) + { + case eRouterStatusOK: s << "OK"; break; + case eRouterStatusTesting: s << "Test"; break; + case eRouterStatusFirewalled: s << "FW"; break; + case eRouterStatusUnknown: s << "Unk"; break; + case eRouterStatusProxy: s << "Proxy"; break; + case eRouterStatusMesh: s << "Mesh"; break; + case eRouterStatusError: + { + s << "Err"; + switch (i2p::context.GetError ()) + { + case eRouterErrorClockSkew: + s << " - Clock skew"; + break; + case eRouterErrorOffline: + s << " - Offline"; + break; + case eRouterErrorSymmetricNAT: + s << " - Symmetric NAT"; + break; + default: ; + } + break; + } + default: s << "Unk"; + } + } + static void PrintMainWindowText (std::stringstream& s) { s << "\n"; s << "Status: "; - switch (i2p::context.GetStatus()) + ShowNetworkStatus (s, i2p::context.GetStatus ()); + if (i2p::context.SupportsV6 ()) { - case eRouterStatusOK: s << "OK"; break; - case eRouterStatusTesting: s << "Testing"; break; - case eRouterStatusFirewalled: s << "Firewalled"; break; - case eRouterStatusError: - { - switch (i2p::context.GetError()) - { - case eRouterErrorClockSkew: s << "Clock skew"; break; - default: s << "Error"; - } - break; - } - default: s << "Unknown"; + s << " / "; + ShowNetworkStatus (s, i2p::context.GetStatusV6 ()); } s << "; "; s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 2e1b296a..09f9c155 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -35,14 +35,30 @@ ## Write full CLF-formatted date and time to log (default: write only time) # logclftime = true -## Daemon mode. Router will go to background after start +## Daemon mode. Router will go to background after start. Ignored on Windows # daemon = true ## Specify a family, router belongs to (default - none) # family = -## External IP address to listen for connections +## Network interface to bind to +## Updates address4/6 options if they are not set +# ifname = +## You can specify different interfaces for IPv4 and IPv6 +# ifname4 = +# ifname6 = + +## Local address to bind transport sockets to +## Overrides host option if: +## For ipv4: if ipv4 = true and nat = false +## For ipv6: if 'host' is not set or ipv4 = true +# address4 = +# address6 = + +## External IPv4 or IPv6 address to listen for connections ## By default i2pd sets IP automatically +## Sets published NTCP2v4/SSUv4 address to 'host' value if nat = true +## Sets published NTCP2v6/SSUv6 address to 'host' value if ipv4 = false # host = 1.2.3.4 ## Port to listen for connections @@ -55,17 +71,6 @@ ipv4 = true ## Enable communication through ipv6 ipv6 = false -## Network interface to bind to -# ifname = -## You can specify different interfaces for IPv4 and IPv6 -# ifname4 = -# ifname6 = - -## Enable NTCP transport (default = true) -# ntcp = true -## If you run i2pd behind a proxy server, you can only use NTCP transport with ntcpproxy option -## Should be http://address:port or socks://address:port -# ntcpproxy = http://127.0.0.1:8118 ## Enable SSU transport (default = true) # ssu = true @@ -82,6 +87,7 @@ ipv6 = false # notransit = true ## Router will be floodfill +## Note: that mode uses much more network connections and CPU! # floodfill = true [http] @@ -93,7 +99,7 @@ address = 127.0.0.1 port = 7070 ## Path to web console, default "/" # webroot = / -## Uncomment following lines to enable Web Console authentication +## Uncomment following lines to enable Web Console authentication # auth = true # user = i2pd # pass = changeme @@ -170,11 +176,11 @@ enabled = true # name = I2Pd [meshnets] -## Enable connectivity over the Yggdrasil network +## Enable connectivity over the Yggdrasil network # yggdrasil = false ## You can bind address from your Yggdrasil subnet 300::/64 -## The address must first be added to the network interface -# yggaddress = +## The address must first be added to the network interface +# yggaddress = [reseed] ## Options for bootstrapping into I2P network, aka reseeding @@ -207,13 +213,13 @@ verify = true [limits] ## Maximum active transit sessions (default:2500) # transittunnels = 2500 -## Limit number of open file descriptors (0 - use system limit) +## Limit number of open file descriptors (0 - use system limit) # openfiles = 0 -## Maximum size of corefile in Kb (0 - use system limit) +## Maximum size of corefile in Kb (0 - use system limit) # coresize = 0 -## Threshold to start probabalistic backoff with ntcp sessions (0 - use system limit) +## Threshold to start probabalistic backoff with ntcp sessions (0 - use system limit) # ntcpsoft = 0 -## Maximum number of ntcp sessions (0 - use system limit) +## Maximum number of ntcp sessions (0 - use system limit) # ntcphard = 0 [trust] @@ -222,13 +228,13 @@ verify = true ## Make direct I2P connections only to routers in specified Family. # family = MyFamily ## Make direct I2P connections only to routers specified here. Comma separated list of base64 identities. -# routers = +# routers = ## Should we hide our router from other routers? false by default # hidden = true [exploratory] ## Exploratory tunnels settings with default values -# inbound.length = 2 +# inbound.length = 2 # inbound.quantity = 3 # outbound.length = 2 # outbound.quantity = 3 @@ -237,7 +243,7 @@ verify = true ## Save peer profiles on disk (default: true) # profiles = true ## Save full addresses on disk (default: true) -# addressbook = true +# addressbook = true [cpuext] ## Use CPU AES-NI instructions set when work with cryptography when available (default: true) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index c87de4aa..77000652 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -142,23 +142,23 @@ namespace util i2p::context.SetNetID (netID); i2p::context.Init (); - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); + bool ipv6; i2p::config::GetOption("ipv6", ipv6); + bool ipv4; i2p::config::GetOption("ipv4", ipv4); #ifdef MESHNET // manual override for meshnet ipv4 = false; ipv6 = true; #endif // ifname -> address - std::string ifname; i2p::config::GetOption("ifname", ifname); + std::string ifname; i2p::config::GetOption("ifname", ifname); if (ipv4 && i2p::config::IsDefault ("address4")) { std::string ifname4; i2p::config::GetOption("ifname4", ifname4); if (!ifname4.empty ()) i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname4, false).to_string ()); // v4 else if (!ifname.empty ()) - i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname, false).to_string ()); // v4 - } + i2p::config::SetOption ("address4", i2p::util::net::GetInterfaceAddress(ifname, false).to_string ()); // v4 + } if (ipv6 && i2p::config::IsDefault ("address6")) { std::string ifname6; i2p::config::GetOption("ifname6", ifname6); @@ -166,8 +166,8 @@ namespace util i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname6, true).to_string ()); // v6 else if (!ifname.empty ()) i2p::config::SetOption ("address6", i2p::util::net::GetInterfaceAddress(ifname, true).to_string ()); // v6 - } - + } + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); boost::asio::ip::address_v6 yggaddr; if (ygg) @@ -210,10 +210,10 @@ namespace util { bool published; i2p::config::GetOption("ntcp2.published", published); if (published) - { + { std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); if (!ntcp2proxy.empty ()) published = false; - } + } if (published) { uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port); @@ -232,12 +232,12 @@ namespace util } if (ygg) { - i2p::context.PublishNTCP2Address (port, true, false, false, true); + i2p::context.PublishNTCP2Address (port, true, false, false, true); i2p::context.UpdateNTCP2V6Address (yggaddr); if (!ipv4 && !ipv6) - i2p::context.SetStatus (eRouterStatusMesh); - } - + i2p::context.SetStatus (eRouterStatusMesh); + } + bool transit; i2p::config::GetOption("notransit", transit); i2p::context.SetAcceptsTunnels (!transit); uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index f0a4b616..d56c2894 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -265,15 +265,15 @@ namespace http { break; case eRouterErrorSymmetricNAT: s << " - Symmetric NAT"; - break; + break; default: ; } break; } default: s << "Unknown"; } - } - + } + void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) { s << "Uptime: "; @@ -287,7 +287,7 @@ namespace http { s << "Network status 6: "; ShowNetworkStatus (s, i2p::context.GetStatusV6 ()); s << "
\r\n"; - } + } #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (auto remains = Daemon.gracefulShutdownInterval) { s << "Stopping in: "; @@ -1276,14 +1276,14 @@ namespace http { ident.FromBase32 (b32); auto dest = i2p::client::context.FindLocalDestination (ident); - if (dest) + if (dest) { std::size_t pos; pos = name.find (".i2p"); - if (pos == (name.length () - 4)) + if (pos == (name.length () - 4)) { pos = name.find (".b32.i2p"); - if (pos == std::string::npos) + if (pos == std::string::npos) { auto signatureLen = dest->GetIdentity ()->GetSignatureLen (); uint8_t * signature = new uint8_t[signatureLen]; @@ -1303,13 +1303,13 @@ namespace http { "\r\n
\r\n"; delete[] signature; delete[] sig; - } - else + } + else s << "ERROR: Domain can't end with .b32.i2p\r\n
\r\n
\r\n"; - } + } else s << "ERROR: Domain must end with .i2p\r\n
\r\n
\r\n"; - } + } else s << "ERROR: Such destination is not found\r\n
\r\n
\r\n"; diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index d71a9f1c..12602c99 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -2,6 +2,10 @@ #include #include #include + +// Use global placeholders from boost introduced when local_time.hpp is loaded +#define BOOST_BIND_GLOBAL_PLACEHOLDERS + #include #include #include diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index cdbe1bff..b316ba83 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -62,11 +62,11 @@ namespace config { ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)") ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") - ("ntcp", bool_switch()->default_value(false), "Ignored. Always false") + ("ntcp", bool_switch()->default_value(false), "Deprecated option. Always false") ("ssu", bool_switch()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Ignored") + ("ntcpproxy", value()->default_value(""), "Deprecated option") #ifdef _WIN32 - ("svcctl", value()->default_value(""), "Ignored") + ("svcctl", value()->default_value(""), "Deprecated option") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") #endif @@ -77,9 +77,9 @@ namespace config { ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") ("limits.openfiles", value()->default_value(0), "Maximum number of open files (0 - use system default)") ("limits.transittunnels", value()->default_value(2500), "Maximum active transit sessions (default:2500)") - ("limits.ntcpsoft", value()->default_value(0), "Threshold to start probabilistic backoff with ntcp sessions (default: use system limit)") - ("limits.ntcphard", value()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)") - ("limits.ntcpthreads", value()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)") + ("limits.ntcpsoft", value()->default_value(0), "Deprecated option") + ("limits.ntcphard", value()->default_value(0), "Deprecated option") + ("limits.ntcpthreads", value()->default_value(1), "Deprecated option") ; options_description httpserver("HTTP Server options"); @@ -281,7 +281,7 @@ namespace config { options_description meshnets("Meshnet transports options"); meshnets.add_options() - ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)") + ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)") ("meshnets.yggaddress", value()->default_value(""), "Yggdrasil address to publish") ; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 22ba0b39..9962599b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -509,7 +509,7 @@ namespace client // schedule verification m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); } else i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msgID); @@ -592,8 +592,7 @@ namespace client // assume it successive and try to verify m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); - + shared_from_this (), std::placeholders::_1)); } } } diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e872eeaa..d5a03d1c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -342,7 +342,7 @@ namespace transport else LogPrint (eLogWarning, "NTCP2: Missing NTCP2 address"); } - m_NextRouterInfoResendTime = i2p::util::GetSecondsSinceEpoch () + NTCP2_ROUTERINFO_RESEND_INTERVAL + + m_NextRouterInfoResendTime = i2p::util::GetSecondsSinceEpoch () + NTCP2_ROUTERINFO_RESEND_INTERVAL + rand ()%NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD; } @@ -717,7 +717,7 @@ namespace transport m_Establisher->m_SessionRequestBuffer = new uint8_t[287]; // 287 bytes max for now boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer, 64), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestReceived, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2)); } void NTCP2Session::ReceiveLength () @@ -726,7 +726,7 @@ namespace transport #ifdef __linux__ const int one = 1; setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); -#endif +#endif boost::asio::async_read (m_Socket, boost::asio::buffer(&m_NextReceivedLen, 2), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleReceivedLength, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -780,8 +780,8 @@ namespace transport if (IsTerminated ()) return; #ifdef __linux__ const int one = 1; - setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); -#endif + setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); +#endif boost::asio::async_read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -1009,11 +1009,11 @@ namespace transport LogPrint (eLogDebug, "NTCP2: Next frame sent ", bytes_transferred); if (m_LastActivityTimestamp > m_NextRouterInfoResendTime) { - m_NextRouterInfoResendTime += NTCP2_ROUTERINFO_RESEND_INTERVAL + + m_NextRouterInfoResendTime += NTCP2_ROUTERINFO_RESEND_INTERVAL + rand ()%NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD; - SendRouterInfo (); - } - else + SendRouterInfo (); + } + else SendQueue (); } } @@ -1113,7 +1113,7 @@ namespace transport SendQueue (); else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) { - LogPrint (eLogWarning, "NTCP2: outgoing messages queue size to ", + LogPrint (eLogWarning, "NTCP2: outgoing messages queue size to ", GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); Terminate (); } @@ -1279,7 +1279,7 @@ namespace transport { LogPrint (eLogError, "NTCP2: Can't connect to unspecified address"); return; - } + } LogPrint (eLogDebug, "NTCP2: Connecting to ", conn->GetRemoteEndpoint ()); GetService ().post([this, conn]() { @@ -1300,25 +1300,25 @@ namespace transport // bind to local address std::shared_ptr localAddress; if (conn->GetRemoteEndpoint ().address ().is_v6 ()) - { + { if (i2p::util::net::IsYggdrasilAddress (conn->GetRemoteEndpoint ().address ())) localAddress = m_YggdrasilAddress; - else + else localAddress = m_Address6; conn->GetSocket ().open (boost::asio::ip::tcp::v6 ()); - } + } else - { + { localAddress = m_Address4; conn->GetSocket ().open (boost::asio::ip::tcp::v4 ()); - } + } if (localAddress) { boost::system::error_code ec; conn->GetSocket ().bind (*localAddress, ec); if (ec) - LogPrint (eLogError, "NTCP2: can't bind to ", localAddress->address ().to_string (), ": ", ec.message ()); - } + LogPrint (eLogError, "NTCP2: can't bind to ", localAddress->address ().to_string (), ": ", ec.message ()); + } conn->GetSocket ().async_connect (conn->GetRemoteEndpoint (), std::bind (&NTCP2Server::HandleConnect, this, std::placeholders::_1, conn, timer)); } else @@ -1448,8 +1448,8 @@ namespace transport { LogPrint (eLogError, "NTCP2: Can't connect to unspecified address"); return; - } - GetService().post([this, conn]() + } + GetService().post([this, conn]() { if (this->AddNTCP2Session (conn)) { @@ -1546,10 +1546,10 @@ namespace transport if(ep.address ().is_v6 ()) req.uri = "[" + ep.address ().to_string() + "]:" + std::to_string(ep.port ()); else - req.uri = ep.address ().to_string() + ":" + std::to_string(ep.port ()); + req.uri = ep.address ().to_string() + ":" + std::to_string(ep.port ()); if (!m_ProxyAuthorization.empty ()) req.AddHeader("Proxy-Authorization", m_ProxyAuthorization); - + boost::asio::streambuf writebuff; std::ostream out(&writebuff); out << req.to_string(); @@ -1627,7 +1627,7 @@ namespace transport sz += 16; memcpy(buff->data () + 4, addrbytes.data(), 16); } - else + else { // We mustn't really fall here because all connections are made to IP addresses LogPrint(eLogError, "NTCP2: Tried to connect to unexpected address via proxy"); @@ -1666,17 +1666,17 @@ namespace transport } void NTCP2Server::SetLocalAddress (const boost::asio::ip::address& localAddress) - { + { auto addr = std::make_shared(boost::asio::ip::tcp::endpoint(localAddress, 0)); if (localAddress.is_v6 ()) - { + { if (i2p::util::net::IsYggdrasilAddress (localAddress)) m_YggdrasilAddress = addr; - else + else m_Address6 = addr; - } + } else m_Address4 = addr; - } + } } } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 9602fe17..ad6576ed 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -28,7 +28,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), + m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -44,12 +44,12 @@ namespace i2p m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr); UpdateRouterInfo (); if (IsECIES ()) - { + { auto initState = new i2p::crypto::NoiseSymmetricState (); i2p::crypto::InitNoiseNState (*initState, GetIdentity ()->GetEncryptionPublicKey ()); - m_InitialNoiseState.reset (initState); + m_InitialNoiseState.reset (initState); m_ECIESSession = std::make_shared(*initState); - } + } } void RouterContext::CreateNewRouter () @@ -74,21 +74,21 @@ namespace i2p bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ssu; i2p::config::GetOption("ssu", ssu); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); bool nat; i2p::config::GetOption("nat", nat); - + if ((ntcp2 || ygg) && !m_NTCP2Keys) - NewNTCP2Keys (); - bool ntcp2Published = false; + NewNTCP2Keys (); + bool ntcp2Published = false; if (ntcp2) - { + { i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published) { std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); if (!ntcp2proxy.empty ()) ntcp2Published = false; - } - } + } + } uint8_t caps = 0, addressCaps = 0; if (ipv4) { @@ -100,8 +100,8 @@ namespace i2p // we have no NAT so set external address from local address std::string address4; i2p::config::GetOption("address4", address4); if (!address4.empty ()) host = address4; - } - + } + if (ntcp2) { if (ntcp2Published) @@ -109,26 +109,26 @@ namespace i2p else // add non-published NTCP2 address { addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; - routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); - } - } + routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + } + } if (ssu) - { + { routerInfo.AddSSUAddress (host.c_str(), port, nullptr); caps |= i2p::data::RouterInfo::eReachable; // R - } + } } if (ipv6) { std::string host = "::1"; if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only i2p::config::GetOption("host", host); - else + else { std::string address6; i2p::config::GetOption("address6", address6); if (!address6.empty ()) host = address6; } - + if (ntcp2) { if (ntcp2Published) @@ -140,29 +140,29 @@ namespace i2p ntcp2Host = host; routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port); } - else - { + else + { if (!ipv4) // no other ntcp2 addresses yet routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; - } - } + } + } if (ssu) - { + { routerInfo.AddSSUAddress (host.c_str(), port, nullptr); caps |= i2p::data::RouterInfo::eReachable; // R - } + } } if (ygg) { auto yggaddr = i2p::util::net::GetYggdrasilAddress (); if (!yggaddr.is_unspecified ()) routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); - } + } if (addressCaps) routerInfo.SetUnreachableAddressesTransportCaps (addressCaps); - routerInfo.SetCaps (caps); // caps + L + routerInfo.SetCaps (caps); // caps + L routerInfo.SetProperty ("netId", std::to_string (m_NetID)); routerInfo.SetProperty ("router.version", I2P_VERSION); routerInfo.CreateBuffer (m_Keys); @@ -213,7 +213,7 @@ namespace i2p void RouterContext::SetStatusV6 (RouterStatus status) { if (status != m_StatusV6) - { + { m_StatusV6 = status; switch (m_StatusV6) { @@ -226,9 +226,9 @@ namespace i2p default: ; } - } - } - + } + } + void RouterContext::UpdatePort (int port) { bool updated = false; @@ -250,18 +250,18 @@ namespace i2p bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { - if (address->IsNTCP2 () && (address->port != port || address->published != publish)) + if (address->IsNTCP2 () && (address->port != port || address->published != publish)) { bool isAddr = v4 && address->IsV4 (); if (!isAddr && (v6 || ygg)) - { + { if (i2p::util::net::IsYggdrasilAddress (address->host)) isAddr = ygg; else isAddr = v6 && address->IsV6 (); } if (isAddr) - { + { if (!port && !address->port) { // select random port only if address's port is not set @@ -272,7 +272,7 @@ namespace i2p address->published = publish; address->ntcp2->iv = m_NTCP2Keys->iv; updated = true; - } + } } } if (updated) @@ -310,7 +310,7 @@ namespace i2p bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { - if (address->host != host && address->IsCompatible (host) && + if (address->host != host && address->IsCompatible (host) && !i2p::util::net::IsYggdrasilAddress (address->host)) { address->host = host; @@ -402,7 +402,7 @@ namespace i2p case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break; case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 1000000; type = unlim; break; // 1Gbyte/s default: - limit = 48; type = low; + limit = 48; type = low; } /* update caps & flags in RI */ auto caps = m_RouterInfo.GetCaps (); @@ -416,8 +416,8 @@ namespace i2p #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif - // no break here, extra + high means 'X' - case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; + // no break here, extra + high means 'X' + case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; } m_RouterInfo.SetCaps (caps); UpdateRouterInfo (); @@ -467,14 +467,14 @@ namespace i2p void RouterContext::SetUnreachable (bool v4, bool v6) { if (v4 || (v6 && !SupportsV4 ())) - { + { // set caps uint8_t caps = m_RouterInfo.GetCaps (); caps &= ~i2p::data::RouterInfo::eReachable; caps |= i2p::data::RouterInfo::eUnreachable; caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill m_RouterInfo.SetCaps (caps); - } + } uint16_t port = 0; // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); @@ -497,7 +497,7 @@ namespace i2p void RouterContext::SetReachable (bool v4, bool v6) { if (v4 || (v6 && !SupportsV4 ())) - { + { // update caps uint8_t caps = m_RouterInfo.GetCaps (); caps &= ~i2p::data::RouterInfo::eUnreachable; @@ -505,7 +505,7 @@ namespace i2p if (m_IsFloodfill) caps |= i2p::data::RouterInfo::eFloodfill; m_RouterInfo.SetCaps (caps); - } + } uint16_t port = 0; // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); @@ -526,7 +526,7 @@ namespace i2p { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; - PublishNTCP2Address (ntcp2Port, true, v4, v6, false); + PublishNTCP2Address (ntcp2Port, true, v4, v6, false); } } // update @@ -596,7 +596,7 @@ namespace i2p if (supportsV4) { bool foundSSU = false, foundNTCP2 = false; - std::string host = "127.0.0.1"; + std::string host = "127.0.0.1"; uint16_t port = 0; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) @@ -626,26 +626,26 @@ namespace i2p { bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2Published) - { + { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port); - } + } else m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); - } - } + } + } m_RouterInfo.EnableV4 (); - } + } else m_RouterInfo.DisableV4 (); UpdateRouterInfo (); } void RouterContext::SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host) - { + { if (supportsmesh) - { + { m_RouterInfo.EnableMesh (); uint16_t port = 0; i2p::config::GetOption ("ntcp2.port", port); @@ -659,16 +659,16 @@ namespace i2p { foundMesh = true; break; - } + } } if (!foundMesh) m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); - } + } else m_RouterInfo.DisableMesh (); UpdateRouterInfo (); } - + void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) { bool isYgg = i2p::util::net::IsYggdrasilAddress (host); @@ -742,7 +742,7 @@ namespace i2p // rekey routers with bandwidth = L (or default) this time bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); if (!isFloodfill) rekey = true; - } + } if (rekey) { // update keys @@ -751,7 +751,7 @@ namespace i2p m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); SaveKeys (); - } + } // read NTCP2 keys if available std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary); if (n2k) @@ -787,8 +787,8 @@ namespace i2p SetReachable (true, true); // we assume reachable until we discover firewall through peer tests // read NTCP2 - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); if (ntcp2 || ygg) { if (!m_NTCP2Keys) NewNTCP2Keys (); @@ -821,15 +821,15 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); } - bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) - { + bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) + { auto msg = CreateI2NPMessage (typeID, payload, len); if (!msg) return false; i2p::HandleI2NPMessage (msg); - return true; - } + return true; + } + - void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); @@ -847,8 +847,8 @@ namespace i2p m_ECIESSession->HandleNextMessage (buf, len); else LogPrint (eLogError, "Router: Session is not set for ECIES router"); - } - else + } + else i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); } @@ -857,10 +857,10 @@ namespace i2p if (i2p::data::netdb.GetPublishReplyToken () == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) i2p::data::netdb.PostI2NPMsg (msg); else - { + { std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); - } + } } void RouterContext::CleanupDestination () @@ -886,34 +886,34 @@ namespace i2p { if (!m_InitialNoiseState) return false; // m_InitialNoiseState is h = SHA256(h || hepk) - m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); + m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; - } - m_CurrentNoiseState->MixKey (sharedSecret); + } + m_CurrentNoiseState->MixKey (sharedSecret); encrypted += 32; uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK + 32, nonce, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, false)) // decrypt { LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); return false; - } + } m_CurrentNoiseState->MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) return true; - } - else + } + else { BN_CTX * ctx = BN_CTX_new (); bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); BN_CTX_free (ctx); return success; - } + } } i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 11fab97f..f7801bb0 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -28,7 +28,7 @@ namespace transport m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port), m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversServiceV6), - m_IntroducersUpdateTimer (m_Service), m_IntroducersUpdateTimerV6 (m_Service), + m_IntroducersUpdateTimer (m_Service), m_IntroducersUpdateTimerV6 (m_Service), m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service) { } @@ -79,7 +79,7 @@ namespace transport if (context.SupportsV4 ()) { OpenSocket (); - m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this)); + m_ReceiversThread = new std::thread (std::bind (&SSUServer::RunReceivers, this)); m_ReceiversService.post (std::bind (&SSUServer::Receive, this)); ScheduleTermination (); ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers @@ -125,7 +125,7 @@ namespace transport m_Thread->join (); delete m_Thread; m_Thread = nullptr; - } + } } void SSUServer::Run () @@ -198,8 +198,8 @@ namespace transport m_EndpointV6.address (localAddress); else if (localAddress.is_v4 ()) m_Endpoint.address (localAddress); - } - + } + void SSUServer::AddRelay (uint32_t tag, std::shared_ptr relay) { m_Relays[tag] = relay; @@ -412,7 +412,7 @@ namespace transport std::shared_ptr SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const { - auto& sessions = e.address ().is_v6 () ? m_SessionsV6 : m_Sessions; + auto& sessions = e.address ().is_v6 () ? m_SessionsV6 : m_Sessions; auto it = sessions.find (e); if (it != sessions.end ()) return it->second; @@ -439,7 +439,7 @@ namespace transport m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, address, peerTest)); // always V4 thread else { - if (address->host.is_unspecified () || !address->port) return false; + if (address->host.is_unspecified () || !address->port) return false; boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port); m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest)); } @@ -472,15 +472,15 @@ namespace transport } } - void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr router, + void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr router, std::shared_ptr address, bool peerTest) { if (router && address && address->UsesIntroducer ()) - { + { if (address->IsV4 () && !i2p::context.SupportsV4 ()) return; if (address->IsV6 () && !i2p::context.SupportsV6 ()) return; if (!address->host.is_unspecified () && address->port) - { + { // we rarely come here auto& sessions = address->host.is_v6 () ? m_SessionsV6 : m_Sessions; boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port); @@ -493,7 +493,7 @@ namespace transport session->SendPeerTest (); return; } - } + } // create new session int numIntroducers = address->ssu->introducers.size (); if (numIntroducers > 0) @@ -509,9 +509,9 @@ namespace transport if (!intr->iPort) continue; // skip invalid introducer if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort); - if (ep.address ().is_v4 () && address->IsV4 ()) // ipv4 + if (ep.address ().is_v4 () && address->IsV4 ()) // ipv4 { - if (!introducer) introducer = intr; + if (!introducer) introducer = intr; auto it = m_Sessions.find (ep); if (it != m_Sessions.end ()) { @@ -519,9 +519,9 @@ namespace transport break; } } - if (ep.address ().is_v6 () && address->IsV6 ()) // ipv6 + if (ep.address ().is_v6 () && address->IsV6 ()) // ipv6 { - if (!introducer) introducer = intr; + if (!introducer) introducer = intr; auto it = m_SessionsV6.find (ep); if (it != m_SessionsV6.end ()) { @@ -546,7 +546,7 @@ namespace transport if (introducerEndpoint.address ().is_v4 ()) m_Sessions[introducerEndpoint] = introducerSession; else if (introducerEndpoint.address ().is_v6 ()) - m_SessionsV6[introducerEndpoint] = introducerSession; + m_SessionsV6[introducerEndpoint] = introducerSession; } if (!address->host.is_unspecified () && address->port) { @@ -563,7 +563,7 @@ namespace transport "] through introducer ", introducer->iHost, ":", introducer->iPort); session->WaitForIntroduction (); if ((address->host.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) || - (address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled)) + (address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled)) { uint8_t buf[1]; Send (buf, 0, remoteEndpoint); // send HolePunch @@ -648,23 +648,23 @@ namespace transport ); } - std::list > SSUServer::FindIntroducers (int maxNumIntroducers, + std::list > SSUServer::FindIntroducers (int maxNumIntroducers, bool v4, std::set& excluded) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); std::list > ret; const auto& sessions = v4 ? m_Sessions : m_SessionsV6; for (const auto& s : sessions) - { + { if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION) ret.push_back (s.second); else if (s.second->GetRemoteIdentity ()) excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ()); - } + } if ((int)ret.size () > maxNumIntroducers) { - // shink ret randomly + // shink ret randomly int sz = ret.size () - maxNumIntroducers; for (int i = 0; i < sz; i++) { @@ -672,8 +672,8 @@ namespace transport auto it = ret.begin (); std::advance (it, ind); ret.erase (it); - } - } + } + } return ret; } @@ -683,8 +683,8 @@ namespace transport m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL/2)); m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, this, std::placeholders::_1, true)); - } - + } + void SSUServer::ScheduleIntroducersUpdateTimer () { m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL)); @@ -698,22 +698,22 @@ namespace transport m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL/2)); m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, this, std::placeholders::_1, false)); - } - + } + void SSUServer::ScheduleIntroducersUpdateTimerV6 () { m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL)); m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer, this, std::placeholders::_1, false)); } - + void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4) { if (ecode != boost::asio::error::operation_aborted) { // timeout expired if (v4) - { + { if (i2p::context.GetStatus () == eRouterStatusTesting) { // we still don't know if we need introducers @@ -721,14 +721,14 @@ namespace transport return; } if (i2p::context.GetStatus () != eRouterStatusFirewalled) - { + { // we don't need introducers m_Introducers.clear (); - return; - } + return; + } // we are firewalled if (!i2p::context.IsUnreachable ()) i2p::context.SetUnreachable (true, false); // v4 - } + } else { if (i2p::context.GetStatusV6 () == eRouterStatusTesting) @@ -738,17 +738,17 @@ namespace transport return; } if (i2p::context.GetStatusV6 () != eRouterStatusFirewalled) - { + { // we don't need introducers m_IntroducersV6.clear (); - return; + return; } // we are firewalled auto addr = i2p::context.GetRouterInfo ().GetSSUV6Address (); if (addr && addr->ssu && addr->ssu->introducers.empty ()) i2p::context.SetUnreachable (false, true); // v6 - } - + } + std::list newList; size_t numIntroducers = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); @@ -762,7 +762,7 @@ namespace transport if (ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION) session->SendKeepAlive (); if (ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION) - { + { newList.push_back (it); numIntroducers++; if (session->GetRemoteIdentity ()) @@ -787,11 +787,11 @@ namespace transport auto session = FindSession (it); if (session) session->SetCreationTime (session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION); - } + } // try again excluded.clear (); sessions = FindIntroducers (SSU_MAX_NUM_INTRODUCERS, v4, excluded); - } + } for (const auto& it1: sessions) { const auto& ep = it1->GetRemoteEndpoint (); @@ -814,27 +814,27 @@ namespace transport if (introducers.size () < SSU_MAX_NUM_INTRODUCERS) { for (auto i = introducers.size (); i < SSU_MAX_NUM_INTRODUCERS; i++) - { + { auto introducer = i2p::data::netdb.GetRandomIntroducer (v4, excluded); if (introducer) - { + { auto address = v4 ? introducer->GetSSUAddress (true) : introducer->GetSSUV6Address (); if (address && !address->host.is_unspecified () && address->port) { boost::asio::ip::udp::endpoint ep (address->host, address->port); if (std::find (introducers.begin (), introducers.end (), ep) == introducers.end ()) // not connected yet - { - CreateDirectSession (introducer, ep, false); + { + CreateDirectSession (introducer, ep, false); excluded.insert (introducer->GetIdentHash ()); - } - } + } + } } else - { + { LogPrint (eLogDebug, "SSU: can't find more introducers"); break; - } - } + } + } } if (v4) ScheduleIntroducersUpdateTimer (); diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 3c519d6b..339ac8df 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -383,7 +383,7 @@ namespace transport { // tell out peer to now assign relay tag flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED; - *payload = 2; payload++; // 1 byte length + *payload = 2; payload++; // 1 byte length uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG htobe16buf (payload, flags); payload += 2; From e37244fa0df8dcb281b78e2f46c5ee6014b23234 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 15 May 2021 16:35:38 +0300 Subject: [PATCH 0086/2193] remove deprecated options from config file example Signed-off-by: R4SAS --- contrib/i2pd.conf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 09f9c155..e8c397f5 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -217,10 +217,6 @@ verify = true # openfiles = 0 ## Maximum size of corefile in Kb (0 - use system limit) # coresize = 0 -## Threshold to start probabalistic backoff with ntcp sessions (0 - use system limit) -# ntcpsoft = 0 -## Maximum number of ntcp sessions (0 - use system limit) -# ntcphard = 0 [trust] ## Enable explicit trust options. false by default From f22eaa6db51e36d0a064c56907589164752035c5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 16 May 2021 14:26:00 -0400 Subject: [PATCH 0087/2193] 2.38.0 --- ChangeLog | 31 +++++++++++++++++++++++++++++++ appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b2f40eb..9a79440e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,37 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.38.0] - 2021-03-17 +### Added +- Publish ipv6 introducers +- Bind ipv6 or yggdrasil NTCP2 acceptor to specified address +- Support .b32.i2p addresses and hostnames for SAM STREAM CREATE +- ipv6 peer tests +- Publish iexp param for introducers +- Show ipv6 network status on the webconsole +- EdDSA signing keys can also be blinded +- Show router version on the webconsole +### Changed +- Rekey of all routers but floodfills to ECIES +- Increased number of precalculated x25519 keys to 15 +- Don't publish LeaseSet without inbound tunnels +- Reseed from compatible address(ipv4 or ipv6) +- Recongnize v4 and v6 SSU addresses without host +- Inbound tunnel gateway must be ipv4 compatible +- Don't select next introducers from existing sessions +- Set X bandwidth for floodfill by default +### Fixed +- Incoming ECIES-x25519 session doesn't send updated LeaseSet +- Unique local address for server tunnels +- Race condition for LeaseSet creation in I2CP +- Relay tag for ipv6 introducer +- Already expired introducers +- Find connected router for first peer in tunnel +- Failed outgoing ECIES-x25519 session's tagset stays forever +- Yggdrasil address disappears if router becomes unreachable through ipv6 +- Ignore SSU address/introducers if port is not specified +- Check identity and signature length for SSU SessionConfirmed + ## [2.37.0] - 2021-03-15 ### Added - Address registration line for reg.i2p and stats.i2p through the web console diff --git a/appveyor.yml b/appveyor.yml index cf760242..89d85494 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.37.0.{build} +version: 2.38.0.{build} pull_requests: do_not_increment_build_number: true branches: diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index e0985eda..1061fc8f 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.37.0 +Version: 2.38.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -137,6 +137,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon May 17 2021 orignal - 2.38.0 +- update to 2.38.0 + * Mon Mar 15 2021 orignal - 2.37.0 - update to 2.37.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 8cb54bba..a2994f28 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.37.0 +Version: 2.38.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -135,6 +135,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon May 17 2021 orignal - 2.38.0 +- update to 2.38.0 + * Mon Mar 15 2021 orignal - 2.37.0 - update to 2.37.0 diff --git a/debian/changelog b/debian/changelog index fa7d1a92..777b6216 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.38.0-1) unstable; urgency=medium + + * updated to version 2.38.0/0.9.50 + + -- orignal Mon, 17 May 2021 16:00:00 +0000 + i2pd (2.37.0-1) unstable; urgency=medium * updated to version 2.37.0 diff --git a/libi2pd/version.h b/libi2pd/version.h index dd6511f1..028d1692 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -16,7 +16,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 37 +#define I2PD_VERSION_MINOR 38 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -30,7 +30,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 49 +#define I2P_VERSION_MICRO 50 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 59b471b9a2edd38fe4de7a9f449a746a439157ec Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 May 2021 14:10:31 -0400 Subject: [PATCH 0088/2193] i2cp.leaseSetPrivKey for HTTP and SOCKS proxy --- libi2pd/Config.cpp | 16 +++++++++------- libi2pd_client/ClientContext.cpp | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b316ba83..5b584e35 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -62,11 +62,11 @@ namespace config { ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)") ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") - ("ntcp", bool_switch()->default_value(false), "Deprecated option. Always false") + ("ntcp", bool_switch()->default_value(false), "Ignored. Always false") ("ssu", bool_switch()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Deprecated option") + ("ntcpproxy", value()->default_value(""), "Ignored") #ifdef _WIN32 - ("svcctl", value()->default_value(""), "Deprecated option") + ("svcctl", value()->default_value(""), "Ignored") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") #endif @@ -77,9 +77,9 @@ namespace config { ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") ("limits.openfiles", value()->default_value(0), "Maximum number of open files (0 - use system default)") ("limits.transittunnels", value()->default_value(2500), "Maximum active transit sessions (default:2500)") - ("limits.ntcpsoft", value()->default_value(0), "Deprecated option") - ("limits.ntcphard", value()->default_value(0), "Deprecated option") - ("limits.ntcpthreads", value()->default_value(1), "Deprecated option") + ("limits.ntcpsoft", value()->default_value(0), "Threshold to start probabilistic backoff with ntcp sessions (default: use system limit)") + ("limits.ntcphard", value()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)") + ("limits.ntcpthreads", value()->default_value(1), "Maximum number of threads used by NTCP DH worker (default: 1)") ; options_description httpserver("HTTP Server options"); @@ -113,6 +113,7 @@ namespace config { ("httpproxy.addresshelper", value()->default_value(true), "Enable or disable addresshelper") ("httpproxy.i2cp.leaseSetType", value()->default_value("3"), "Local destination's LeaseSet type") ("httpproxy.i2cp.leaseSetEncType", value()->default_value("0,4"), "Local destination's LeaseSet encryption type") + ("httpproxy.i2cp.leaseSetPrivKey", value()->default_value(""), "LeaseSet private key") ; options_description socksproxy("SOCKS Proxy options"); @@ -134,6 +135,7 @@ namespace config { ("socksproxy.outproxyport", value()->default_value(9050), "Upstream outproxy port for SOCKS Proxy") ("socksproxy.i2cp.leaseSetType", value()->default_value("3"), "Local destination's LeaseSet type") ("socksproxy.i2cp.leaseSetEncType", value()->default_value("0,4"), "Local destination's LeaseSet encryption type") + ("socksproxy.i2cp.leaseSetPrivKey", value()->default_value(""), "LeaseSet private key") ; options_description sam("SAM bridge options"); @@ -281,7 +283,7 @@ namespace config { options_description meshnets("Meshnet transports options"); meshnets.add_options() - ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)") + ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)") ("meshnets.yggaddress", value()->default_value(""), "Yggdrasil address to publish") ; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 2f3d4d48..94311297 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -495,6 +495,8 @@ namespace client options[I2CP_PARAM_LEASESET_TYPE] = value; if (i2p::config::GetOption(prefix + I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, value)) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = value; + if (i2p::config::GetOption(prefix + I2CP_PARAM_LEASESET_PRIV_KEY, value) && !value.empty ()) + options[I2CP_PARAM_LEASESET_PRIV_KEY] = value; } void ClientContext::ReadTunnels () From 0e68fe4a57bd782faf9ef59e77a7d683b3dac8d2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 22 May 2021 08:39:05 +0300 Subject: [PATCH 0089/2193] [i18n] start multilang support for webconsole Signed-off-by: R4SAS --- Makefile | 9 ++++--- daemon/HTTPServer.cpp | 36 +++++++++++++++++++++------- filelist.mk | 2 ++ i18n/I18N.h | 39 ++++++++++++++++++++++++++++++ i18n/russian.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++ libi2pd/FS.cpp | 17 +++++++------ 6 files changed, 140 insertions(+), 19 deletions(-) create mode 100644 i18n/I18N.h create mode 100644 i18n/russian.cpp diff --git a/Makefile b/Makefile index 7ff74787..40e72918 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ I2PD := i2pd LIB_SRC_DIR := libi2pd LIB_CLIENT_SRC_DIR := libi2pd_client +LANG_SRC_DIR := i18n DAEMON_SRC_DIR := daemon # import source files lists @@ -49,12 +50,13 @@ ifeq ($(USE_MESHNET),yes) NEEDED_CXXFLAGS += -DMESHNET endif -NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) +NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) +LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) -DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) +DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD) @@ -63,6 +65,7 @@ mk_obj_dir: @mkdir -p obj/Win32 @mkdir -p obj/$(LIB_SRC_DIR) @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) + @mkdir -p obj/$(LANG_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) api: mk_obj_dir $(SHLIB) $(ARLIB) @@ -82,7 +85,7 @@ obj/%.o: %.cpp # '-' is 'ignore if missing' on first run -include $(DEPS) -$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) +$(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) $(SHLIB): $(LIB_OBJS) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d56c2894..043d1630 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -30,6 +30,12 @@ #include "Daemon.h" #include "util.h" #include "ECIESX25519AEADRatchetSession.h" +#include "I18N.h" + +#ifdef _WIN32 +#include +#include +#endif #ifdef WIN32_APP #include "Win32App.h" @@ -130,23 +136,37 @@ namespace http { static std::string ConvertTime (uint64_t time); std::map HTTPConnection::m_Tokens; + std::string DataPath; + + static void SetDataDir () + { +#ifdef _WIN32 + boost::filesystem::wpath path (i2p::fs::GetDataDir()); + auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16() ) ); + i2p::http::DataPath = path.string(); + boost::filesystem::path::imbue(loc); // Return it back +#else + i2p::http::DataPath = i2p::fs::GetDataDir(); +#endif + } + static void ShowUptime (std::stringstream& s, int seconds) { int num; if ((num = seconds / 86400) > 0) { - s << num << " days, "; + s << num << " " << tr("days", num) << ", "; seconds -= num * 86400; } if ((num = seconds / 3600) > 0) { - s << num << " hours, "; + s << num << " " << tr("hours", num) << ", "; seconds -= num * 3600; } if ((num = seconds / 60) > 0) { - s << num << " min, "; + s << num << " " << tr("minutes", num) << ", "; seconds -= num * 60; } - s << seconds << " seconds"; + s << seconds << " " << tr("seconds", seconds); } static void ShowTraffic (std::stringstream& s, uint64_t bytes) @@ -197,11 +217,7 @@ namespace http { "\r\n" "\r\n" /* TODO: Add support for locale */ " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ -#if (!defined(WIN32)) " \r\n" -#else - " \r\n" -#endif " \r\n" " \r\n" " Purple I2P " VERSION " Webconsole\r\n" @@ -315,7 +331,7 @@ namespace http { s << "Transit: "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; - s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; + s << "Data path: " << i2p::http::DataPath << "
\r\n"; s << "
"; if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { s << "\r\n\r\n
\r\n"; @@ -1374,6 +1390,8 @@ namespace http { LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } + i2p::http::SetDataDir(); + m_IsRunning = true; m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); diff --git a/filelist.mk b/filelist.mk index 7d13fb2f..e2a5d40e 100644 --- a/filelist.mk +++ b/filelist.mk @@ -19,4 +19,6 @@ LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp) #DAEMON_SRC = \ # HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp +LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp) + DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp) diff --git a/i18n/I18N.h b/i18n/I18N.h new file mode 100644 index 00000000..4556fe25 --- /dev/null +++ b/i18n/I18N.h @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef __I18N_H__ +#define __I18N_H__ + +namespace i2p { +namespace i18n { + + namespace russian { + std::string GetString (std::string arg); + std::string GetPlural (std::string arg, int n); + } + + std::string translate (std::string arg) + { + return i2p::i18n::russian::GetString (arg); + } + + template + std::string translate (std::string arg, inttype&& n) + { + return i2p::i18n::russian::GetPlural (arg, (int) n); + } + +} // i18n +} // i2p + +template +std::string tr (TArgs&&... args) { + return i2p::i18n::translate(std::forward(args)...); +} + +#endif // __I18N_H__ diff --git a/i18n/russian.cpp b/i18n/russian.cpp new file mode 100644 index 00000000..892ee203 --- /dev/null +++ b/i18n/russian.cpp @@ -0,0 +1,56 @@ +#include +#include +#include + +// Russian localization file + +namespace i2p { +namespace i18n { +namespace russian { // language + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + int plural (int n) { + return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; + } + + static std::map strings + { + {"Enabled", "Включено"}, + {"Disabled", "Выключено"} + }; + + static std::map> plurals + { + {"days", {"день", "дня", "дней"}}, + {"hours", {"час", "часа", "часов"}}, + {"minutes", {"минута", "минуты", "минут"}}, + {"seconds", {"секунда", "секунды", "секунд"}} + }; + + std::string GetString (std::string arg) + { + auto it = strings.find(arg); + if (it == strings.end()) + { + return arg; + } else { + return it->second; + } + } + + std::string GetPlural (std::string arg, int n) + { + auto it = plurals.find(arg); + if (it == plurals.end()) + { + return arg; + } else { + int form = plural(n); + return it->second[form]; + } + } + +} // language +} // i18n +} // i2p diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index bd1a7ad2..250b24ef 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -47,10 +47,10 @@ namespace fs { return; } #ifdef _WIN32 - char localAppData[MAX_PATH]; + wchar_t localAppData[MAX_PATH]; // check executable directory first - if(!GetModuleFileName(NULL, localAppData, MAX_PATH)) + if(!GetModuleFileNameW(NULL, localAppData, MAX_PATH)) { #ifdef WIN32_APP MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK); @@ -61,14 +61,15 @@ namespace fs { } else { - auto execPath = boost::filesystem::path(localAppData).parent_path(); + auto execPath = boost::filesystem::wpath(localAppData).parent_path(); // if config file exists in .exe's folder use it if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string - dataDir = execPath.string (); - else // otherwise %appdata% { - if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK) + dataDir = execPath.string (); + } else // otherwise %appdata% + { + if(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK) { #ifdef WIN32_APP MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK); @@ -78,7 +79,9 @@ namespace fs { exit(1); } else - dataDir = std::string(localAppData) + "\\" + appName; + { + dataDir = boost::filesystem::wpath(localAppData).string() + "\\" + appName; + } } } return; From 80b44fc9a9c6a90872ccaa1988737bda67f73e3f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 22 May 2021 18:29:05 +0300 Subject: [PATCH 0090/2193] Support multilang, update code Signed-off-by: R4SAS --- contrib/i2pd.conf | 3 +++ daemon/Daemon.cpp | 7 +++++ daemon/HTTPServer.cpp | 23 +--------------- i18n/English.cpp | 56 +++++++++++++++++++++++++++++++++++++++ i18n/I18N.h | 21 +++++++++++++-- libi2pd/Config.cpp | 1 + libi2pd/FS.cpp | 13 +++++++++ libi2pd/FS.h | 3 +++ libi2pd/RouterContext.cpp | 7 ++++- libi2pd/RouterContext.h | 18 ++++++++++--- 10 files changed, 124 insertions(+), 28 deletions(-) create mode 100644 i18n/English.cpp diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index e8c397f5..3c9c71ff 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -103,6 +103,9 @@ port = 7070 # auth = true # user = i2pd # pass = changeme +## Select webconsole language +## Currently supported only english (default) and russian languages +# lang = english [httpproxy] ## Uncomment and set to 'false' to disable HTTP Proxy diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 77000652..ec62f5d6 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -343,6 +343,13 @@ namespace util LogPrint(eLogInfo, "Daemon: using hidden mode"); i2p::data::netdb.SetHidden(true); } + + std::string httpLang; i2p::config::GetOption("http.lang", httpLang); + if (!httpLang.compare("russian")) + i2p::context.SetLanguage (eRussian); + else + i2p::context.SetLanguage (eEnglish); + return true; } diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 043d1630..87744f37 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -32,11 +32,6 @@ #include "ECIESX25519AEADRatchetSession.h" #include "I18N.h" -#ifdef _WIN32 -#include -#include -#endif - #ifdef WIN32_APP #include "Win32App.h" #endif @@ -136,20 +131,6 @@ namespace http { static std::string ConvertTime (uint64_t time); std::map HTTPConnection::m_Tokens; - std::string DataPath; - - static void SetDataDir () - { -#ifdef _WIN32 - boost::filesystem::wpath path (i2p::fs::GetDataDir()); - auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16() ) ); - i2p::http::DataPath = path.string(); - boost::filesystem::path::imbue(loc); // Return it back -#else - i2p::http::DataPath = i2p::fs::GetDataDir(); -#endif - } - static void ShowUptime (std::stringstream& s, int seconds) { int num; @@ -331,7 +312,7 @@ namespace http { s << "Transit: "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; - s << "Data path: " << i2p::http::DataPath << "
\r\n"; + s << "Data path: " << i2p::fs::GetUTF8DataDir() << "
\r\n"; s << "
"; if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { s << "\r\n\r\n
\r\n"; @@ -1390,8 +1371,6 @@ namespace http { LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - i2p::http::SetDataDir(); - m_IsRunning = true; m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); diff --git a/i18n/English.cpp b/i18n/English.cpp new file mode 100644 index 00000000..8664a0f0 --- /dev/null +++ b/i18n/English.cpp @@ -0,0 +1,56 @@ +#include +#include +#include + +// Russian localization file + +namespace i2p { +namespace i18n { +namespace english { // language + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + int plural (int n) { + return n != 1 ? 1 : 0; + } + + static std::map strings + { + {"Enabled", "Enabled"}, + {"Disabled", "Disabled"} + }; + + static std::map> plurals + { + {"days", {"day", "days"}}, + {"hours", {"hour", "hours"}}, + {"minutes", {"minute", "minutes"}}, + {"seconds", {"second", "seconds"}} + }; + + std::string GetString (std::string arg) + { + auto it = strings.find(arg); + if (it == strings.end()) + { + return arg; + } else { + return it->second; + } + } + + std::string GetPlural (std::string arg, int n) + { + auto it = plurals.find(arg); + if (it == plurals.end()) + { + return arg; + } else { + int form = plural(n); + return it->second[form]; + } + } + +} // language +} // i18n +} // i2p diff --git a/i18n/I18N.h b/i18n/I18N.h index 4556fe25..eddec514 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -9,9 +9,16 @@ #ifndef __I18N_H__ #define __I18N_H__ +#include "RouterContext.h" + namespace i2p { namespace i18n { + namespace english { + std::string GetString (std::string arg); + std::string GetPlural (std::string arg, int n); + } + namespace russian { std::string GetString (std::string arg); std::string GetPlural (std::string arg, int n); @@ -19,13 +26,23 @@ namespace i18n { std::string translate (std::string arg) { - return i2p::i18n::russian::GetString (arg); + switch (i2p::context.GetLanguage ()) + { + case eEnglish: return i2p::i18n::english::GetString (arg); + case eRussian: return i2p::i18n::russian::GetString (arg); + default: return arg; + } } template std::string translate (std::string arg, inttype&& n) { - return i2p::i18n::russian::GetPlural (arg, (int) n); + switch (i2p::context.GetLanguage ()) + { + case eEnglish: return i2p::i18n::english::GetPlural (arg, (int) n); + case eRussian: return i2p::i18n::russian::GetPlural (arg, (int) n); + default: return arg; + } } } // i18n diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 5b584e35..f5316860 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -93,6 +93,7 @@ namespace config { ("http.strictheaders", value()->default_value(true), "Enable strict host checking on WebUI") ("http.hostname", value()->default_value("localhost"), "Expected hostname for WebUI") ("http.webroot", value()->default_value("/"), "WebUI root path (default: / )") + ("http.lang", value()->default_value("english"), "WebUI language (default: english )") ; options_description httpproxy("HTTP Proxy options"); diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 250b24ef..6ac302b0 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -12,6 +12,7 @@ #ifdef _WIN32 #include #include +#include #endif #include "Base.h" @@ -41,6 +42,18 @@ namespace fs { return dataDir; } + const std::string GetUTF8DataDir () { +#ifdef _WIN32 + boost::filesystem::wpath path (dataDir); + auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16() ) ); // convert path to UTF-8 + auto dataDirUTF8 = path.string(); + boost::filesystem::path::imbue(loc); // Return locale settings back + return dataDirUTF8; +#else + return dataDir; // linux, osx, android uses UTF-8 by default +#endif + } + void DetectDataDir(const std::string & cmdline_param, bool isService) { if (cmdline_param != "") { dataDir = cmdline_param; diff --git a/libi2pd/FS.h b/libi2pd/FS.h index 698e9b6b..f07ee35c 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -75,6 +75,9 @@ namespace fs { /** @brief Returns datadir path */ const std::string & GetDataDir(); + /** @brief Returns datadir path in UTF-8 encoding */ + const std::string GetUTF8DataDir(); + /** * @brief Set datadir either from cmdline option or using autodetection * @param cmdline_param Value of cmdline parameter --datadir= diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index ad6576ed..0cfcb18a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -29,7 +29,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), - m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) + m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID), m_Language (eEnglish) { } @@ -916,6 +916,11 @@ namespace i2p } } + void RouterContext::SetLanguage (Lang language) + { + m_Language = language; + } + i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () { if (!m_StaticKeys) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index a4d18f82..dad3fdca 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -24,7 +24,7 @@ namespace i2p namespace garlic { class RouterIncomingRatchetSession; -} +} const char ROUTER_INFO[] = "router.info"; const char ROUTER_KEYS[] = "router.keys"; @@ -39,7 +39,7 @@ namespace garlic eRouterStatusError = 3, eRouterStatusUnknown = 4, eRouterStatusProxy = 5, - eRouterStatusMesh = 6 + eRouterStatusMesh = 6 }; enum RouterError @@ -49,7 +49,12 @@ namespace garlic eRouterErrorOffline = 2, eRouterErrorSymmetricNAT = 3 }; - + + enum Lang { + eEnglish = 0, + eRussian + }; + class RouterContext: public i2p::garlic::GarlicDestination { private: @@ -144,6 +149,10 @@ namespace garlic void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatusMessage (std::shared_ptr msg); + // i18n + Lang GetLanguage () const { return m_Language; }; + void SetLanguage (Lang language); + protected: // implements GarlicDestination @@ -178,6 +187,9 @@ namespace garlic std::unique_ptr m_StaticKeys; // for ECIESx25519 std::unique_ptr m_InitialNoiseState, m_CurrentNoiseState; + + // i18n + Lang m_Language; }; extern RouterContext context; From f321eb66c04fa6b7af9070bd139ad75f3f451937 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 22 May 2021 18:41:25 -0400 Subject: [PATCH 0091/2193] rename DatabaseLookupTageSet to SymmetricKeyTagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- libi2pd/Garlic.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index f9d5672f..45affde7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -117,14 +117,14 @@ namespace garlic return session->HandleNextMessage (buf, len, shared_from_this (), index); } - DatabaseLookupTagSet::DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key): + SymmetricKeyTagSet::SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key): ReceiveRatchetTagSet (nullptr), m_Destination (destination) { memcpy (m_Key, key, 32); Expire (); } - bool DatabaseLookupTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + bool SymmetricKeyTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) { if (len < 24) return false; uint8_t nonce[12]; @@ -133,18 +133,18 @@ namespace garlic len -= 16; // poly1305 if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len - offset, buf, 8, m_Key, nonce, buf + offset, len - offset, false)) // decrypt { - LogPrint (eLogWarning, "Garlic: Lookup reply AEAD decryption failed"); + LogPrint (eLogWarning, "Garlic: Symmetric key tagset AEAD decryption failed"); return false; } // we assume 1 I2NP block with delivery type local if (offset + 3 > len) { - LogPrint (eLogWarning, "Garlic: Lookup reply is too short ", len); + LogPrint (eLogWarning, "Garlic: Symmetric key tagset is too short ", len); return false; } if (buf[offset] != eECIESx25519BlkGalicClove) { - LogPrint (eLogWarning, "Garlic: Lookup reply unexpected block ", (int)buf[offset]); + LogPrint (eLogWarning, "Garlic: Symmetric key tagset unexpected block ", (int)buf[offset]); return false; } offset++; @@ -152,7 +152,7 @@ namespace garlic offset += 2; if (offset + size > len) { - LogPrint (eLogWarning, "Garlic: Lookup reply block is too long ", size); + LogPrint (eLogWarning, "Garlic: Symmetric key tagset block is too long ", size); return false; } if (m_Destination) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index bdbb7111..43e88ca6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -104,11 +104,11 @@ namespace garlic uint64_t m_ExpirationTimestamp = 0; }; - class DatabaseLookupTagSet: public ReceiveRatchetTagSet + class SymmetricKeyTagSet: public ReceiveRatchetTagSet { public: - DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key); + SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key); bool IsIndexExpired (int index) const { return false; }; bool HandleNextMessage (uint8_t * buf, size_t len, int index); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 66a3b62f..2bf89556 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -471,7 +471,7 @@ namespace garlic { uint64_t t; memcpy (&t, tag, 8); - auto tagset = std::make_shared(this, key); + auto tagset = std::make_shared(this, key); m_ECIESx25519Tags.emplace (t, ECIESX25519AEADRatchetIndexTagset{0, tagset}); } From df66c2d2dcc55355c9812e6b8cf265a753cd4595 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 06:06:04 +0300 Subject: [PATCH 0092/2193] [i18n] translate HTTP proxy Signed-off-by: R4SAS --- i18n/I18N.h | 16 ++------ i18n/I18N_langs.h | 34 ++++++++++++++++ i18n/russian.cpp | 43 +++++++++++++++++++-- libi2pd/HTTP.cpp | 2 + libi2pd/RouterContext.h | 6 +-- libi2pd_client/HTTPProxy.cpp | 75 +++++++++++++++++++----------------- 6 files changed, 120 insertions(+), 56 deletions(-) create mode 100644 i18n/I18N_langs.h diff --git a/i18n/I18N.h b/i18n/I18N.h index eddec514..cb3e5c1c 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -11,20 +11,11 @@ #include "RouterContext.h" + namespace i2p { namespace i18n { - namespace english { - std::string GetString (std::string arg); - std::string GetPlural (std::string arg, int n); - } - - namespace russian { - std::string GetString (std::string arg); - std::string GetPlural (std::string arg, int n); - } - - std::string translate (std::string arg) + inline std::string translate (std::string arg) { switch (i2p::context.GetLanguage ()) { @@ -49,7 +40,8 @@ namespace i18n { } // i2p template -std::string tr (TArgs&&... args) { +std::string tr (TArgs&&... args) +{ return i2p::i18n::translate(std::forward(args)...); } diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h new file mode 100644 index 00000000..24c683b4 --- /dev/null +++ b/i18n/I18N_langs.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef __I18N_LANGS_H__ +#define __I18N_LANGS_H__ + +namespace i2p { + +enum Lang { + eEnglish = 0, + eRussian +}; + +namespace i18n { + + namespace english { + std::string GetString (std::string arg); + std::string GetPlural (std::string arg, int n); + } + + namespace russian { + std::string GetString (std::string arg); + std::string GetPlural (std::string arg, int n); + } + +} // i18n +} // i2p + +#endif // __I18N_LANGS_H__ diff --git a/i18n/russian.cpp b/i18n/russian.cpp index 892ee203..feb6fc63 100644 --- a/i18n/russian.cpp +++ b/i18n/russian.cpp @@ -16,8 +16,44 @@ namespace russian { // language static std::map strings { - {"Enabled", "Включено"}, - {"Disabled", "Выключено"} + // HTTP Proxy + {"Proxy error", "Ошибка прокси"}, + {"Proxy info", "Информация прокси"}, + {"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"}, + {"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"}, + {"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"}, + {"Invalid request", "Некорректный запрос"}, + {"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"}, + {"addresshelper is not supported", "addresshelper не поддерживается"}, + {"Host", "Адрес"}, + {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, + {"already in router's addressbook", "уже а адресной книге роутера"}, + {"Click", "Нажмите"}, + {"here", "здесь"}, + {"to proceed", "чтобы продолжить"}, + {"to update record", "чтобы обновить запись"}, + {"Addresshelper found", "Найден addresshelper"}, + {"invalid request uri", "некорректный URI запроса"}, + {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, + {"Outproxy failure", "Ошибка внешнего прокси"}, + {"bad outproxy settings", "некорректные настройки внешнего прокси"}, + {"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"}, + {"unknown outproxy url", "неизвестный URL внешнего прокси"}, + {"cannot resolve upstream proxy", "не удается определить внешний прокси"}, + {"hostname too long", "имя хоста слишком длинное"}, + {"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"}, + {"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"}, + {"CONNECT error", "Ошибка CONNECT запроса"}, + {"Failed to Connect", "Не удалось подключиться"}, + {"socks proxy error", "ошибка SOCKS прокси"}, + {"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"}, + {"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"}, + {"cannot connect", "не удалось подключиться"}, + {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"}, + {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"}, + {"Host is down", "Адрес недоступен"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."}, + {"", ""}, }; static std::map> plurals @@ -25,7 +61,8 @@ namespace russian { // language {"days", {"день", "дня", "дней"}}, {"hours", {"час", "часа", "часов"}}, {"minutes", {"минута", "минуты", "минут"}}, - {"seconds", {"секунда", "секунды", "секунд"}} + {"seconds", {"секунда", "секунды", "секунд"}}, + {"", {"", ""}}, }; std::string GetString (std::string arg) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index da4299e9..6ad245f0 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -187,6 +187,8 @@ namespace http params.clear(); for (const auto& it : tokens) { + if (!it.length()) // empty + continue; std::size_t eq = it.find ('='); if (eq != std::string::npos) { auto e = std::pair(it.substr(0, eq), it.substr(eq + 1)); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index dad3fdca..1cb77a74 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -18,6 +18,7 @@ #include "Identity.h" #include "RouterInfo.h" #include "Garlic.h" +#include "I18N_langs.h" namespace i2p { @@ -50,11 +51,6 @@ namespace garlic eRouterErrorSymmetricNAT = 3 }; - enum Lang { - eEnglish = 0, - eRussian - }; - class RouterContext: public i2p::garlic::GarlicDestination { private: diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 6b2b8df7..aff165b0 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -28,6 +28,7 @@ #include "I2PTunnel.h" #include "Config.h" #include "HTTP.h" +#include "I18N.h" namespace i2p { namespace proxy { @@ -71,8 +72,8 @@ namespace proxy { void SentHTTPFailed(const boost::system::error_code & ecode); void HandleStreamRequestComplete (std::shared_ptr stream); /* error helpers */ - void GenericProxyError(const char *title, const char *description); - void GenericProxyInfo(const char *title, const char *description); + void GenericProxyError(const std::string& title, const std::string& description); + void GenericProxyInfo(const std::string& title, const std::string& description); void HostNotFound(std::string & host); void SendProxyError(std::string & content); @@ -151,17 +152,17 @@ namespace proxy { Done(shared_from_this()); } - void HTTPReqHandler::GenericProxyError(const char *title, const char *description) { + void HTTPReqHandler::GenericProxyError(const std::string& title, const std::string& description) { std::stringstream ss; - ss << "

Proxy error: " << title << "

\r\n"; + ss << "

" << tr("Proxy error") << ": " << title << "

\r\n"; ss << "

" << description << "

\r\n"; std::string content = ss.str(); SendProxyError(content); } - void HTTPReqHandler::GenericProxyInfo(const char *title, const char *description) { + void HTTPReqHandler::GenericProxyInfo(const std::string& title, const std::string& description) { std::stringstream ss; - ss << "

Proxy info: " << title << "

\r\n"; + ss << "

" << tr("Proxy info") << ": " << title << "

\r\n"; ss << "

" << description << "

\r\n"; std::string content = ss.str(); SendProxyError(content); @@ -169,9 +170,9 @@ namespace proxy { void HTTPReqHandler::HostNotFound(std::string & host) { std::stringstream ss; - ss << "

Proxy error: Host not found

\r\n" - << "

Remote host not found in router's addressbook

\r\n" - << "

You may try to find this host on jump services below:

\r\n" + ss << "

" << tr("Proxy error: Host not found") << "

\r\n" + << "

" << tr("Remote host not found in router's addressbook") << "

\r\n" + << "

" << tr("You may try to find this host on jump services below") << ":

\r\n" << "
    \r\n"; for (const auto& js : jumpservices) { ss << "
  • " << js.first << "
  • \r\n"; @@ -216,7 +217,7 @@ namespace proxy { b64 = i2p::http::UrlDecode(value); // if we need update exists, request formed with update param if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; } - url.query.replace(pos, len, ""); + url.query.replace(pos - 1, len + 1, ""); // +-1 for taking ? and & before parameter return true; } @@ -268,7 +269,7 @@ namespace proxy { if (m_req_len < 0) { LogPrint(eLogError, "HTTPProxy: unable to parse request"); - GenericProxyError("Invalid request", "Proxy unable to parse your request"); + GenericProxyError(tr("Invalid request"), tr("Proxy unable to parse your request")); return true; /* parse error */ } @@ -283,7 +284,7 @@ namespace proxy { if (!m_Addresshelper) { LogPrint(eLogWarning, "HTTPProxy: addresshelper request rejected"); - GenericProxyError("Invalid request", "addresshelper is not supported"); + GenericProxyError(tr("Invalid request"), tr("addresshelper is not supported")); return true; } if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm) @@ -292,17 +293,19 @@ namespace proxy { LogPrint (eLogInfo, "HTTPProxy: added address from addresshelper for ", m_RequestURL.host); std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << "Host " << m_RequestURL.host << " added to router's addressbook from helper. " - << "Click here to proceed."; - GenericProxyInfo("Addresshelper found", ss.str().c_str()); + ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". "; + ss << tr("Click") << " " << tr("here") << " " << tr("to proceed") << "."; + GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } else { + std::string full_url = m_RequestURL.to_string(); std::stringstream ss; - ss << "Host " << m_RequestURL.host << " already in router's addressbook. " - << "Click here to update record."; - GenericProxyInfo("Addresshelper found", ss.str().c_str()); + ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; + ss << tr("Click") << " " << tr("here") << " " << tr("to update record") << "."; + GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } } @@ -315,7 +318,7 @@ namespace proxy { auto pos = uri.find(":"); if(pos == std::string::npos || pos == uri.size() - 1) { - GenericProxyError("Invalid Request", "invalid request uri"); + GenericProxyError(tr("Invalid Request"), tr("invalid request uri")); return true; } else @@ -358,7 +361,7 @@ namespace proxy { else { /* relative url and missing 'Host' header */ - GenericProxyError("Invalid request", "Can't detect destination host from request"); + GenericProxyError(tr("Invalid request"), tr("Can't detect destination host from request")); return true; } } @@ -375,11 +378,11 @@ namespace proxy { if(m_ProxyURL.parse(m_OutproxyUrl)) ForwardToUpstreamProxy(); else - GenericProxyError("Outproxy failure", "bad outproxy settings"); + GenericProxyError(tr("Outproxy failure"), tr("bad outproxy settings")); } else { LogPrint (eLogWarning, "HTTPProxy: outproxy failure for ", dest_host, ": no outproxy enabled"); - std::string message = "Host " + dest_host + " not inside I2P network, but outproxy is not enabled"; - GenericProxyError("Outproxy failure", message.c_str()); + std::stringstream ss; ss << tr("Host") << " " << dest_host << " " << tr("not inside I2P network, but outproxy is not enabled"); + GenericProxyError(tr("Outproxy failure"), ss.str()); } return true; } @@ -467,13 +470,13 @@ namespace proxy { else { // unknown type, complain - GenericProxyError("unknown outproxy url", m_ProxyURL.to_string().c_str()); + GenericProxyError(tr("unknown outproxy url"), m_ProxyURL.to_string()); } } void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler) { - if(ec) GenericProxyError("cannot resolve upstream proxy", ec.message().c_str()); + if(ec) GenericProxyError(tr("cannot resolve upstream proxy"), ec.message()); else handler(*it); } @@ -481,7 +484,7 @@ namespace proxy { { if(!ec) { if(m_RequestURL.host.size() > 255) { - GenericProxyError("hostname too long", m_RequestURL.host.c_str()); + GenericProxyError(tr("hostname too long"), m_RequestURL.host); return; } uint16_t port = m_RequestURL.port; @@ -508,13 +511,13 @@ namespace proxy { reqsize += host.size(); m_socks_buf[++reqsize] = 0; boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2)); - } else GenericProxyError("cannot connect to upstream socks proxy", ec.message().c_str()); + } else GenericProxyError(tr("cannot connect to upstream socks proxy"), ec.message()); } void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred) { LogPrint(eLogDebug, "HTTPProxy: upstream socks handshake sent"); - if(ec) GenericProxyError("Cannot negotiate with socks proxy", ec.message().c_str()); + if(ec) GenericProxyError(tr("Cannot negotiate with socks proxy"), ec.message()); else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2)); } @@ -556,7 +559,7 @@ namespace proxy { } else { - GenericProxyError("CONNECT error", "Failed to Connect"); + GenericProxyError(tr("CONNECT error"), tr("Failed to Connect")); } } @@ -567,7 +570,7 @@ namespace proxy { m_send_buf = m_ClientResponse.to_string(); boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) GenericProxyError("socks proxy error", ec.message().c_str()); + if(ec) GenericProxyError(tr("socks proxy error"), ec.message()); else HandoverToUpstreamProxy(); }); } else { @@ -575,7 +578,7 @@ namespace proxy { LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes"); boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred) { - if(ec) GenericProxyError("failed to send request to upstream", ec.message().c_str()); + if(ec) GenericProxyError(tr("failed to send request to upstream"), ec.message()); else HandoverToUpstreamProxy(); }); } @@ -593,18 +596,18 @@ namespace proxy { ss << "error code: "; ss << (int) m_socks_buf[1]; std::string msg = ss.str(); - GenericProxyError("Socks Proxy error", msg.c_str()); + GenericProxyError(tr("socks proxy error"), msg); } } - else GenericProxyError("No Reply From socks proxy", ec.message().c_str()); + else GenericProxyError(tr("No Reply From socks proxy"), ec.message()); } void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec) { if(!ec) { LogPrint(eLogDebug, "HTTPProxy: connected to http upstream"); - GenericProxyError("cannot connect", "http out proxy not implemented"); - } else GenericProxyError("cannot connect to upstream http proxy", ec.message().c_str()); + GenericProxyError(tr("cannot connect"), tr("http out proxy not implemented")); + } else GenericProxyError(tr("cannot connect to upstream http proxy"), ec.message()); } /* will be called after some data received from client */ @@ -637,7 +640,7 @@ namespace proxy { { if (!stream) { LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info"); - GenericProxyError("Host is down", "Can't create connection to requested host, it may be down. Please try again later."); + GenericProxyError(tr("Host is down"), tr("Can't create connection to requested host, it may be down. Please try again later.")); return; } if (Kill()) From e687773b412d62c16d332a39f703c3d0db3ef037 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 10:50:26 +0300 Subject: [PATCH 0093/2193] [18n] translate webconsole Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 434 ++++++++++++++++++++++-------------------- i18n/russian.cpp | 160 +++++++++++++++- 2 files changed, 381 insertions(+), 213 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 87744f37..22cefedd 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -41,7 +41,7 @@ namespace i2p { namespace http { - const char *itoopieFavicon = + const std::string itoopieFavicon = "data:image/png;base64," "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx" "jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0" @@ -59,49 +59,51 @@ namespace http { "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" "RU5ErkJggg=="; - const char *cssStyles = - "\r\n"; + static void GetStyles (std::stringstream& s) + { + s << "\r\n"; + } const char HTTP_PAGE_TUNNELS[] = "tunnels"; const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels"; @@ -155,28 +157,35 @@ namespace http { s << std::fixed << std::setprecision(2); auto numKBytes = (double) bytes / 1024; if (numKBytes < 1024) - s << numKBytes << " KiB"; + s << numKBytes << " " << tr("KiB"); else if (numKBytes < 1024 * 1024) - s << numKBytes / 1024 << " MiB"; + s << numKBytes / 1024 << " " << tr("MiB"); else - s << numKBytes / 1024 / 1024 << " GiB"; + s << numKBytes / 1024 / 1024 << " " << tr("GiB"); } static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes) { - std::string state; + std::string state, stateText; switch (eState) { case i2p::tunnel::eTunnelStateBuildReplyReceived : - case i2p::tunnel::eTunnelStatePending : state = "building"; break; + case i2p::tunnel::eTunnelStatePending : state = "building"; break; case i2p::tunnel::eTunnelStateBuildFailed : case i2p::tunnel::eTunnelStateTestFailed : - case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; - case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; + case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; + case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; case i2p::tunnel::eTunnelStateEstablished : state = "established"; break; default: state = "unknown"; break; } - s << " " << state << ((explr) ? " (exploratory)" : "") << ", "; - s << " " << (int) (bytes / 1024) << " KiB\r\n"; + + if (state == "building") stateText = tr("building"); + else if (state == "failed") stateText = tr("failed"); + else if (state == "expiring") stateText = tr("expiring"); + else if (state == "established") stateText = tr("established"); + else stateText = tr("unknown"); + + s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; + s << " " << (int) (bytes / 1024) << " " << tr("KiB") << "\r\n"; } static void SetLogLevel (const std::string& level) @@ -192,35 +201,40 @@ namespace http { static void ShowPageHead (std::stringstream& s) { - std::string webroot; - i2p::config::GetOption("http.webroot", webroot); + std::string webroot; i2p::config::GetOption("http.webroot", webroot); + + // Page language + std::string lang, langCode; i2p::config::GetOption("http.lang", lang); + if (lang == "russian") langCode = "ru"; + else langCode = "en"; + s << "\r\n" - "\r\n" /* TODO: Add support for locale */ + "\r\n" " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ " \r\n" " \r\n" " \r\n" - " Purple I2P " VERSION " Webconsole\r\n" - << cssStyles << - "\r\n"; + " Purple I2P " VERSION " Webconsole\r\n"; + GetStyles(s); s << + "\r\n" "\r\n" - "
    i2pd webconsole
    \r\n" + "
    " << tr("i2pd webconsole") << "
    \r\n" "
    \r\n" "
    \r\n" - " Main page
    \r\n" - " Router commands\r\n" - " Local destinations\r\n"; + " " << tr("Main page") << "
    \r\n" + " " << tr("Router commands") << "\r\n" + " " << tr("Local destinations") << "\r\n"; if (i2p::context.IsFloodfill ()) - s << " LeaseSets\r\n"; + s << " " << tr("LeaseSets") << "\r\n"; s << - " Tunnels\r\n" - " Transit tunnels\r\n" - " Transports\r\n" - " I2P tunnels\r\n"; + " " << tr("Tunnels") << "\r\n" + " " << tr("Transit tunnels") << "\r\n" + " " << tr ("Transports") << "\r\n" + " " << tr("I2P tunnels") << "\r\n"; if (i2p::client::context.GetSAMBridge ()) - s << " SAM sessions\r\n"; + s << " " << tr("SAM sessions") << "\r\n"; s << "
    \r\n" "
    "; @@ -236,94 +250,94 @@ namespace http { static void ShowError(std::stringstream& s, const std::string& string) { - s << "ERROR: " << string << "
    \r\n"; + s << "" << tr("ERROR") << ": " << string << "
    \r\n"; } static void ShowNetworkStatus (std::stringstream& s, RouterStatus status) { switch (status) { - case eRouterStatusOK: s << "OK"; break; - case eRouterStatusTesting: s << "Testing"; break; - case eRouterStatusFirewalled: s << "Firewalled"; break; - case eRouterStatusUnknown: s << "Unknown"; break; - case eRouterStatusProxy: s << "Proxy"; break; - case eRouterStatusMesh: s << "Mesh"; break; + case eRouterStatusOK: s << tr("OK"); break; + case eRouterStatusTesting: s << tr("Testing"); break; + case eRouterStatusFirewalled: s << tr("Firewalled"); break; + case eRouterStatusUnknown: s << tr("Unknown"); break; + case eRouterStatusProxy: s << tr("Proxy"); break; + case eRouterStatusMesh: s << tr("Mesh"); break; case eRouterStatusError: { - s << "Error"; + s << tr("Error"); switch (i2p::context.GetError ()) { case eRouterErrorClockSkew: - s << " - Clock skew"; + s << " - " << tr("Clock skew"); break; case eRouterErrorOffline: - s << " - Offline"; + s << " - " << tr("Offline"); break; case eRouterErrorSymmetricNAT: - s << " - Symmetric NAT"; + s << " - " << tr("Symmetric NAT"); break; default: ; } break; } - default: s << "Unknown"; + default: s << tr("Unknown"); } } void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) { - s << "Uptime: "; + s << "" << tr("Uptime") << ": "; ShowUptime(s, i2p::context.GetUptime ()); s << "
    \r\n"; - s << "Network status: "; + s << "" << tr("Network status") << ": "; ShowNetworkStatus (s, i2p::context.GetStatus ()); s << "
    \r\n"; if (i2p::context.SupportsV6 ()) { - s << "Network status 6: "; + s << "" << tr("Network status v6") << ": "; ShowNetworkStatus (s, i2p::context.GetStatusV6 ()); s << "
    \r\n"; } #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (auto remains = Daemon.gracefulShutdownInterval) { - s << "Stopping in: "; + s << "" << tr("Stopping in") << ": "; ShowUptime(s, remains); s << "
    \r\n"; } #elif defined(WIN32_APP) if (i2p::win32::g_GracefulShutdownEndtime != 0) { uint16_t remains = (i2p::win32::g_GracefulShutdownEndtime - GetTickCount()) / 1000; - s << "Stopping in: "; + s << "" << tr("Stopping in") << ": "; ShowUptime(s, remains); s << "
    \r\n"; } #endif auto family = i2p::context.GetFamily (); if (family.length () > 0) - s << "Family: " << family << "
    \r\n"; - s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
    \r\n"; - s << "Received: "; + s << ""<< tr("Family") << ": " << family << "
    \r\n"; + s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
    \r\n"; + s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); - s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " KiB/s)
    \r\n"; - s << "Sent: "; + s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr("KiB/s") << ")
    \r\n"; + s << "" << tr("Sent") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); - s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)
    \r\n"; - s << "Transit: "; + s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr("KiB/s") << ")
    \r\n"; + s << "" << tr("Transit") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
    \r\n"; - s << "Data path: " << i2p::fs::GetUTF8DataDir() << "
    \r\n"; + s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr("KiB/s") << ")
    \r\n"; + s << "" << tr("Data path") << ": " << i2p::fs::GetUTF8DataDir() << "
    \r\n"; s << "
    "; - if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n
    \r\n"; + if((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { + s << "\r\n\r\n
    \r\n"; } if(includeHiddenContent) { - s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
    \r\n"; + s << "" << tr("Router Ident") << ": " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
    \r\n"; if (!i2p::context.GetRouterInfo().GetProperty("family").empty()) - s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
    \r\n"; - s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
    \r\n"; - s << "Version: " VERSION "
    \r\n"; - s << "Our external address:" << "
    \r\n
\r\n"; + s << "" << tr("Router Family") << ": " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; + s << "" << tr("Router Caps") << ": " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; + s << "" << tr("Version") << ": " VERSION "
\r\n"; + s << ""<< tr("Our external address") << ":" << "
\r\n
\r\n"; for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) { s << "\r\n"; @@ -331,7 +345,7 @@ namespace http { { s << "\r\n\r\n"; + s << "\r\n\r\n"; continue; } switch (address->transportStyle) @@ -353,32 +367,32 @@ namespace http { break; } default: - s << "\r\n"; + s << "\r\n"; } s << "\r\n\r\n"; } s << "
NTCP2"; if (address->host.is_v6 ()) s << "v6"; - s << "supported
" << tr("supported") << "
Unknown" << tr("Unknown") << "" << address->host.to_string() << ":" << address->port << "
\r\n"; } s << "
\r\n
\r\n"; - if(outputFormat==OutputFormatEnum::forQtUi) { + if(outputFormat == OutputFormatEnum::forQtUi) { s << "
"; } - s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; - s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; - s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; + s << "" << tr("Routers") << ": " << i2p::data::netdb.GetNumRouters () << " "; + s << "" << tr("Floodfills") << ": " << i2p::data::netdb.GetNumFloodfills () << " "; + s << "" << tr("LeaseSets") << ": " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); - s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; - s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; + s << "" << tr("Client Tunnels") << ": " << std::to_string(clientTunnelCount) << " "; + s << "" << tr("Transit Tunnels") << ": " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forWebConsole) { bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; + s << "
Services
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
\r\n"; + s << "\r\n"; + s << "\r\n"; s << "\r\n"; s << "\r\n"; s << "\r\n"; @@ -390,7 +404,7 @@ namespace http { void ShowLocalDestinations (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "Local Destinations:
\r\n
\r\n"; + s << "" << tr("Local Destinations") << ":
\r\n
\r\n"; for (auto& it: i2p::client::context.GetDestinations ()) { auto ident = it.second->GetIdentHash (); @@ -402,7 +416,7 @@ namespace http { auto i2cpServer = i2p::client::context.GetI2CPServer (); if (i2cpServer && !(i2cpServer->GetSessions ().empty ())) { - s << "
I2CP Local Destinations:
\r\n
\r\n"; + s << "
I2CP "<< tr("Local Destinations") << ":
\r\n
\r\n"; for (auto& it: i2cpServer->GetSessions ()) { auto dest = it.second->GetDestination (); @@ -425,7 +439,7 @@ namespace http { if (dest->IsEncryptedLeaseSet ()) { i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); - s << "
\r\n\r\n
\r\n"; + s << "
\r\n\r\n
\r\n"; s << blinded.ToB33 () << ".b32.i2p
\r\n"; s << "
\r\n
\r\n"; } @@ -434,67 +448,67 @@ namespace http { { std::string webroot; i2p::config::GetOption("http.webroot", webroot); auto base32 = dest->GetIdentHash ().ToBase32 (); - s << "
\r\n\r\n
\r\n" + s << "
\r\n\r\n
\r\n" "
\r\n" " \r\n" " \r\n" " \r\n" - " Domain:\r\n\r\n" - " \r\n" + " " << tr("Domain") << ":\r\n\r\n" + " \r\n" "\r\nNote: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.\r\n
\r\n
\r\n
\r\n"; } if(dest->GetNumRemoteLeaseSets()) { - s << "
\r\n\r\n
\r\n
" << tr("Services") << "
" << "HTTP " << tr("Proxy") << "
" << "SOCKS " << tr("Proxy") << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
"; + s << "
\r\n\r\n
\r\n
AddressTypeEncType
"; for(auto& it: dest->GetLeaseSets ()) s << "\r\n"; s << "
"<< tr("Address") << "" << tr("Type") << "" << tr("EncType") << "
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
\r\n\r\n\r\n
\r\n"; } else - s << "LeaseSets: 0
\r\n
\r\n"; + s << "" << tr("LeaseSets") << ": 0
\r\n
\r\n"; auto pool = dest->GetTunnelPool (); if (pool) { - s << "Inbound tunnels:
\r\n
\r\n"; + s << "" << tr("Inbound tunnels") << ":
\r\n
\r\n"; for (auto & it : pool->GetInboundTunnels ()) { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << "ms )"; + s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } s << "
\r\n"; - s << "Outbound tunnels:
\r\n
\r\n"; + s << "" << tr("Outbound tunnels") << ":
\r\n
\r\n"; for (auto & it : pool->GetOutboundTunnels ()) { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << "ms )"; + s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); s << "
\r\n"; } } s << "
\r\n"; - s << "Tags
\r\nIncoming: " << dest->GetNumIncomingTags () << "
\r\n"; + s << "" << tr("Tags") << "
\r\n" << tr("Incoming") << ": " << dest->GetNumIncomingTags () << "
\r\n"; if (!dest->GetSessions ().empty ()) { std::stringstream tmp_s; uint32_t out_tags = 0; for (const auto& it: dest->GetSessions ()) { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "" << it.second->GetNumOutgoingTags () << "\r\n"; out_tags += it.second->GetNumOutgoingTags (); } - s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; + s << "
\r\n\r\n" + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Amount") << "
\r\n
\r\n
\r\n"; } else - s << "Outgoing: 0
\r\n"; + s << tr("Outgoing") << ": 0
\r\n"; s << "
\r\n"; auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); if (numECIESx25519Tags > 0) { - s << "ECIESx25519
\r\nIncoming Tags: " << numECIESx25519Tags << "
\r\n"; + s << "ECIESx25519
\r\n" << tr("Incoming Tags") << ": " << numECIESx25519Tags << "
\r\n"; if (!dest->GetECIESx25519Sessions ().empty ()) { std::stringstream tmp_s; uint32_t ecies_sessions = 0; @@ -502,17 +516,17 @@ namespace http { tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "" << it.second->GetState () << "\r\n"; ecies_sessions++; } - s << "
\r\n\r\n" - << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + s << "
\r\n\r\n" + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Status") << "
\r\n
\r\n
\r\n"; } else - s << "Tags sessions: 0
\r\n"; + s << tr("Tags sessions") << ": 0
\r\n"; s << "
\r\n"; } } void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token) { - s << "Local Destination:
\r\n
\r\n"; + s << "" << tr("Local Destination") << ":
\r\n
\r\n"; i2p::data::IdentHash ident; ident.FromBase32 (b32); auto dest = i2p::client::context.FindLocalDestination (ident); @@ -521,7 +535,7 @@ namespace http { { ShowLeaseSetDestination (s, dest, token); // show streams - s << "\r\n\r\n\r\n"; + s << "
Streams
\r\n\r\n\r\n"; s << ""; s << ""; @@ -543,7 +557,7 @@ namespace http { s << ""; if (it->GetRecvStreamID ()) { s << ""; + << it->GetRecvStreamID () << "&token=" << token << "\" title=\"" << tr("Close stream") << "\"> ✘ "; } else { s << "
" << tr("Streams") << "
StreamID"; // Stream closing button column s << "Destination" << it->GetRecvStreamID () << ""; } @@ -567,22 +581,22 @@ namespace http { auto i2cpServer = i2p::client::context.GetI2CPServer (); if (i2cpServer) { - s << "I2CP Local Destination:
\r\n
\r\n"; + s << "I2CP " << tr("Local Destination") << ":
\r\n
\r\n"; auto it = i2cpServer->GetSessions ().find (std::stoi (id)); if (it != i2cpServer->GetSessions ().end ()) ShowLeaseSetDestination (s, it->second->GetDestination (), 0); else - ShowError(s, "I2CP session not found"); + ShowError(s, tr("I2CP session not found")); } else - ShowError(s, "I2CP is not enabled"); + ShowError(s, tr("I2CP is not enabled")); } void ShowLeasesSets(std::stringstream& s) { if (i2p::data::netdb.GetNumLeaseSets ()) { - s << "LeaseSets:
\r\n
\r\n"; + s << "" << tr("LeaseSets") << ":
\r\n
\r\n"; int counter = 1; // for each lease set i2p::data::netdb.VisitLeaseSets( @@ -601,21 +615,21 @@ namespace http { s << " expired"; // additional css class for expired s << "\">\r\n"; if (!ls->IsValid()) - s << "
!! Invalid !!
\r\n"; + s << "
!! " << tr("Invalid") << " !!
\r\n"; s << "
\r\n"; s << "\r\n
\r\n"; - s << "Store type: " << (int)storeType << "
\r\n"; - s << "Expires: " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; + s << "" << tr("Store type") << ": " << (int)storeType << "
\r\n"; + s << "" << tr("Expires") << ": " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) { // leases information is available auto leases = ls->GetNonExpiredLeases(); - s << "Non Expired Leases: " << leases.size() << "
\r\n"; + s << "" << tr("Non Expired Leases") << ": " << leases.size() << "
\r\n"; for ( auto & l : leases ) { - s << "Gateway: " << l->tunnelGateway.ToBase64() << "
\r\n"; - s << "TunnelID: " << l->tunnelID << "
\r\n"; - s << "EndDate: " << ConvertTime(l->endDate) << "
\r\n"; + s << "" << tr("Gateway") << ": " << l->tunnelGateway.ToBase64() << "
\r\n"; + s << "" << tr("TunnelID") << ": " << l->tunnelID << "
\r\n"; + s << "" << tr("EndDate") << ": " << ConvertTime(l->endDate) << "
\r\n"; } } s << "
\r\n
\r\n
\r\n"; @@ -625,37 +639,37 @@ namespace http { } else if (!i2p::context.IsFloodfill ()) { - s << "LeaseSets: not floodfill.
\r\n"; + s << "" << tr("LeaseSets") << ": " << tr("not floodfill") << ".
\r\n"; } else { - s << "LeaseSets: 0
\r\n"; + s << "" << tr("LeaseSets") << ": 0
\r\n"; } } void ShowTunnels (std::stringstream& s) { - s << "Tunnels:
\r\n"; - s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n
\r\n"; + s << "" << tr("Tunnels") << ":
\r\n"; + s << "" << tr("Queue size") << ": " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n
\r\n"; auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool (); - s << "Inbound tunnels:
\r\n
\r\n"; + s << "" << tr("Inbound tunnels") << ":
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << "ms )"; + s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ()); s << "
\r\n"; } s << "
\r\n
\r\n"; - s << "Outbound tunnels:
\r\n
\r\n"; + s << "" << tr("Outbound tunnels") << ":
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << "ms )"; + s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ()); s << "
\r\n"; } @@ -666,30 +680,30 @@ namespace http { { std::string webroot; i2p::config::GetOption("http.webroot", webroot); /* commands */ - s << "Router Commands
\r\n
\r\n
\r\n"; - s << " Run peer test\r\n"; + s << "" << tr("Router commands") << "
\r\n
\r\n
\r\n"; + s << " " << tr("Run peer test") << "\r\n"; //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << " Decline transit tunnels\r\n"; + s << " " << tr("Decline transit tunnels") << "\r\n"; else - s << " Accept transit tunnels\r\n"; + s << " " << tr("Accept transit tunnels") << "\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) - s << " Cancel graceful shutdown\r\n"; + s << " " << tr("Cancel graceful shutdown") << "\r\n"; else - s << " Start graceful shutdown
\r\n"; + s << " " << tr("Start graceful shutdown") << "
\r\n"; #elif defined(WIN32_APP) if (i2p::util::DaemonWin32::Instance().isGraceful) - s << " Cancel graceful shutdown\r\n"; + s << " " << tr("Cancel graceful shutdown") << "\r\n"; else - s << " Graceful shutdown\r\n"; + s << " " << tr("Start graceful shutdown") << "\r\n"; #endif - s << " Force shutdown\r\n"; + s << " " << tr("Force shutdown") << "\r\n"; s << "
"; - s << "
\r\nNote: any action done here are not persistent and not changes your config files.\r\n
\r\n"; + s << "
\r\n" << tr("Note: any action done here are not persistent and not changes your config files.") << "\r\n
\r\n"; - s << "Logging level
\r\n"; + s << "" << tr("Logging level") << "
\r\n"; s << " none \r\n"; s << " error \r\n"; s << " warn \r\n"; @@ -697,12 +711,12 @@ namespace http { s << " debug
\r\n
\r\n"; uint16_t maxTunnels = GetMaxNumTransitTunnels (); - s << "Transit tunnels limit
\r\n"; + s << "" << tr("Transit tunnels limit") << "
\r\n"; s << "
\r\n"; s << " \r\n"; s << " \r\n"; s << " \r\n"; - s << " \r\n"; + s << " \r\n"; s << "
\r\n
\r\n"; } @@ -710,7 +724,7 @@ namespace http { { if(i2p::tunnel::tunnels.CountTransitTunnels()) { - s << "Transit tunnels:
\r\n
\r\n"; + s << "" << tr("Transit tunnels") << ":
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { s << "
\r\n"; @@ -726,7 +740,7 @@ namespace http { } else { - s << "Transit tunnels: no transit tunnels currently built.
\r\n"; + s << "" << tr("Transit tunnels") << ": " << tr("no transit tunnels currently built") << ".
\r\n"; } } @@ -775,7 +789,7 @@ namespace http { void ShowTransports (std::stringstream& s) { - s << "Transports:
\r\n"; + s << "" << tr("Transports") << ":
\r\n"; auto ntcp2Server = i2p::transport::transports.GetNTCP2Server (); if (ntcp2Server) { @@ -831,13 +845,13 @@ namespace http { auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { - ShowError(s, "SAM disabled"); + ShowError(s, tr("SAM disabled")); return; } if(sam->GetSessions ().size ()) { - s << "SAM Sessions:
\r\n
\r\n"; + s << "" << tr("SAM sessions") << ":
\r\n
\r\n"; for (auto& it: sam->GetSessions ()) { auto& name = it.second->GetLocalDestination ()->GetNickname (); @@ -847,30 +861,30 @@ namespace http { s << "
\r\n"; } else - s << "SAM Sessions: no sessions currently running.
\r\n"; + s << "" << tr("SAM sessions") << ": " << tr("no sessions currently running") << ".
\r\n"; } void ShowSAMSession (std::stringstream& s, const std::string& id) { auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { - ShowError(s, "SAM disabled"); + ShowError(s, tr("SAM disabled")); return; } auto session = sam->FindSession (id); if (!session) { - ShowError(s, "SAM session not found"); + ShowError(s, tr("SAM session not found")); return; } std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "SAM Session:
\r\n
\r\n"; + s << "" << tr("SAM Session") << ":
\r\n
\r\n"; auto& ident = session->GetLocalDestination ()->GetIdentHash(); s << "\r\n"; s << "
\r\n"; - s << "Streams:
\r\n
\r\n"; + s << "" << tr("Streams") << ":
\r\n
\r\n"; for (const auto& it: sam->ListSockets(id)) { s << "
"; @@ -879,7 +893,7 @@ namespace http { case i2p::client::eSAMSocketTypeSession : s << "session"; break; case i2p::client::eSAMSocketTypeStream : s << "stream"; break; case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break; - case i2p::client::eSAMSocketTypeForward : s << "forward"; break; + case i2p::client::eSAMSocketTypeForward : s << "forward"; break; default: s << "unknown"; break; } s << " [" << it->GetSocket ().remote_endpoint() << "]"; @@ -891,7 +905,7 @@ namespace http { void ShowI2PTunnels (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "Client Tunnels:
\r\n
\r\n"; + s << "" << tr("Client Tunnels") << ":
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); @@ -905,7 +919,7 @@ namespace http { { auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); s << "
"; - s << "HTTP Proxy" << " ⇐ "; + s << "HTTP " << tr("Proxy") << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; } @@ -914,7 +928,7 @@ namespace http { { auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); s << "
"; - s << "SOCKS Proxy" << " ⇐ "; + s << "SOCKS " << tr("Proxy") << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; } @@ -922,7 +936,7 @@ namespace http { auto& serverTunnels = i2p::client::context.GetServerTunnels (); if (!serverTunnels.empty ()) { - s << "
\r\nServer Tunnels:
\r\n
\r\n"; + s << "
\r\n" << tr("Server Tunnels") << ":
\r\n
\r\n"; for (auto& it: serverTunnels) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); @@ -938,7 +952,7 @@ namespace http { auto& clientForwards = i2p::client::context.GetClientForwards (); if (!clientForwards.empty ()) { - s << "
\r\nClient Forwards:
\r\n
\r\n"; + s << "
\r\n" << tr("Client Forwards") << ":
\r\n
\r\n"; for (auto& it: clientForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); @@ -952,7 +966,7 @@ namespace http { auto& serverForwards = i2p::client::context.GetServerForwards (); if (!serverForwards.empty ()) { - s << "
\r\nServer Forwards:
\r\n
\r\n"; + s << "
\r\n" << tr("Server Forwards") << ":
\r\n
\r\n"; for (auto& it: serverForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); @@ -1084,7 +1098,7 @@ namespace http { return; } } - // Html5 head start + // HTML head start ShowPageHead (s); if (req.uri.find("page=") != std::string::npos) { HandlePage (req, res, s); @@ -1158,7 +1172,7 @@ namespace http { ShowLeasesSets(s); else { res.code = 400; - ShowError(s, "Unknown page: " + page); + ShowError(s, tr("Unknown page") + ": " + page); return; } } @@ -1177,7 +1191,7 @@ namespace http { if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) { - ShowError(s, "Invalid token"); + ShowError(s, tr("Invalid token")); return; } @@ -1235,18 +1249,18 @@ namespace http { if (dest) { if(dest->DeleteStream (streamID)) - s << "SUCCESS: Stream closed
\r\n
\r\n"; + s << "" << tr("SUCCESS") << ": " << tr("Stream closed") << "
\r\n
\r\n"; else - s << "ERROR: Stream not found or already was closed
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("Stream not found or already was closed") << "
\r\n
\r\n"; } else - s << "ERROR: Destination not found
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("Destination not found") << "
\r\n
\r\n"; } else - s << "ERROR: StreamID can be null
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("StreamID can't be null") << "
\r\n
\r\n"; - s << "Return to destination page
\r\n"; - s << "

You will be redirected back in 5 seconds"; + s << "" << tr("Return to destination page") << "
\r\n"; + s << "

" << tr("You will be redirected back in 5 seconds") << ""; redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32; res.add_header("Refresh", redirect.c_str()); return; @@ -1257,9 +1271,9 @@ namespace http { if (limit > 0 && limit <= 65535) SetMaxNumTransitTunnels (limit); else { - s << "ERROR: Transit tunnels count must not exceed 65535\r\n
\r\n
\r\n"; - s << "Back to commands list\r\n
\r\n"; - s << "

You will be redirected back in 5 seconds"; + s << "" << tr("ERROR") << ": " << tr("Transit tunnels count must not exceed 65535") << "\r\n
\r\n
\r\n"; + s << "" << tr("Back to commands list") << "\r\n
\r\n"; + s << "

" << tr("You will be redirected back in 5 seconds") << ""; res.add_header("Refresh", redirect.c_str()); return; } @@ -1292,37 +1306,37 @@ namespace http { auto len = i2p::data::ByteStreamToBase64 (signature, signatureLen, sig, signatureLen*2); sig[len] = 0; out << "#!sig=" << sig; - s << "SUCCESS:
\r\n

\r\n" + s << "" << tr("SUCCESS") << ":
\r\n\r\n" "\r\n
\r\n
\r\n" - "Register at reg.i2p:\r\n
\r\n" - "Description:\r\n\r\n" - "\r\n" + "" << tr("Register at reg.i2p") << ":\r\n
\r\n" + "" << tr("Description") << ":\r\n\r\n" + "\r\n" "
\r\n
\r\n"; delete[] signature; delete[] sig; } else - s << "ERROR: Domain can't end with .b32.i2p\r\n
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("Domain can't end with .b32.i2p") << "\r\n
\r\n
\r\n"; } else - s << "ERROR: Domain must end with .i2p\r\n
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("Domain must end with .i2p") << "\r\n
\r\n
\r\n"; } else - s << "ERROR: Such destination is not found\r\n
\r\n
\r\n"; + s << "" << tr("ERROR") << ": " << tr("Such destination is not found") << "\r\n
\r\n
\r\n"; - s << "Return to destination page\r\n"; + s << "" << tr("Return to destination page") << "\r\n"; return; } else { res.code = 400; - ShowError(s, "Unknown command: " + cmd); + ShowError(s, tr("Unknown command") + ": " + cmd); return; } - s << "SUCCESS: Command accepted

\r\n"; - s << "Back to commands list
\r\n"; - s << "

You will be redirected in 5 seconds"; + s << "" << tr("SUCCESS") << ": " << tr("Command accepted") << "

\r\n"; + s << "" << tr("Back to commands list") << "
\r\n"; + s << "

" << tr("You will be redirected in 5 seconds") << ""; res.add_header("Refresh", redirect.c_str()); } diff --git a/i18n/russian.cpp b/i18n/russian.cpp index feb6fc63..71f27613 100644 --- a/i18n/russian.cpp +++ b/i18n/russian.cpp @@ -52,16 +52,170 @@ namespace russian { // language {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"}, {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"}, {"Host is down", "Адрес недоступен"}, - {"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."}, + {"Can't create connection to requested host, it may be down. Please try again later.", + "Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."}, + + // Webconsole // + // cssStyles + {"Disabled", "Выключено"}, + {"Enabled", "Включено"}, + // ShowTraffic + {"KiB", "КиБ"}, + {"MiB", "МиБ"}, + {"GiB", "ГиБ"}, + // ShowTunnelDetails + {"building", "строится"}, + {"failed", "неудачный"}, + {"expiring", "заканчивается"}, + {"established", "работает"}, + {"exploratory", "исследовательский"}, + {"unknown", "неизвестно"}, + {"i2pd webconsole", "Веб-консоль i2pd"}, + // ShowPageHead + {"Main page", "Главная"}, + {"Router commands", "Команды роутера"}, + {"Local destinations", "Локальные назнач."}, + {"LeaseSets", "Лизсеты"}, + {"Tunnels", "Туннели"}, + {"Transit tunnels", "Транзит. туннели"}, + {"Transports", "Транспорты"}, + {"I2P tunnels", "I2P туннели"}, + {"SAM sessions", "SAM сессии"}, + // Network Status + {"OK", "OK"}, + {"Testing", "Тестирование"}, + {"Firewalled", "Файрвол"}, + {"Unknown", "Неизвестно"}, + {"Proxy", "Прокси"}, + {"Mesh", "MESH-сеть"}, + {"Error", "Ошибка"}, + {"Clock skew", "Не точное время"}, + {"Offline", "Оффлайн"}, + {"Symmetric NAT", "Симметричный NAT"}, + // Status + {"Uptime", "В сети"}, + {"Network status", "Сетевой статус"}, + {"Network status v6", "Сетевой статус v6"}, + {"Stopping in", "Остановка через"}, + {"Family", "Семейство"}, + {"Tunnel creation success rate", "Успешно построенных туннелей"}, + {"Received", "Получено"}, + {"Sent", "Отправлено"}, + {"Transit", "Транзит"}, + {"KiB/s", "КиБ/с"}, + {"Data path", "Путь к данным"}, + {"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."}, + {"Router Ident", "Идентификатор роутера"}, + {"Router Family", "Семейство роутера"}, + {"Router Caps", "Флаги роутера"}, + {"Version", "Версия"}, + {"Our external address", "Наш внешний адрес"}, + {"supported", "поддерживается"}, + {"Routers", "Роутеры"}, + {"Floodfills", "Флудфилы"}, + {"LeaseSets", "Лизсеты"}, + {"Client Tunnels", "Клиентские туннели"}, + {"Transit Tunnels", "Транзитные туннели"}, + {"Services", "Сервисы"}, + // ShowLocalDestinations + {"Local Destinations", "Локальные назначения"}, + // ShowLeaseSetDestination + {"Encrypted B33 address", "Шифрованные B33 адреса"}, + {"Address registration line", "Строка регистрации адреса"}, + {"Domain", "Домен"}, + {"Generate", "Сгенерировать"}, + {"Address", "Адрес"}, + {"Type", "Тип"}, + {"EncType", "ТипШифр"}, + {"Inbound tunnels", "Входящие туннели"}, + {"Outbound tunnels", "Исходящие туннели"}, + {"ms", "мс"}, // milliseconds + {"Tags", "Теги"}, + {"Incoming", "Входящие"}, + {"Outgoing", "Исходящие"}, + {"Destination", "Назначение"}, + {"Amount", "Количество"}, + {"Incoming Tags", "Входящие Теги"}, + {"Tags sessions", "Сессии Тегов"}, + {"Status", "Статус"}, + // ShowLocalDestination + {"Local Destination", "Локальное назначение"}, + {"Streams", "Стримы"}, + {"Close stream", "Закрыть стрим"}, + // ShowI2CPLocalDestination + {"I2CP session not found", "I2CP сессия не найдена"}, + {"I2CP is not enabled", "I2CP не включен"}, + // ShowLeasesSets + {"Invalid", "Некорректный"}, + {"Store type", "Тип хранилища"}, + {"Expires", "Истекает"}, + {"Non Expired Leases", "Не истекшие Lease-ы"}, + {"Gateway", "Шлюз"}, + {"TunnelID", "ID туннеля"}, + {"EndDate", "Заканчивается"}, + {"not floodfill", "не флудфил"}, + // ShowTunnels + {"Queue size", "Размер очереди"}, + // ShowCommands + {"Run peer test", "Запустить тестирование"}, + {"Decline transit tunnels", "Отклонять транзитные туннели"}, + {"Accept transit tunnels", "Принимать транзитные туннели"}, + {"Cancel graceful shutdown", "Отменить плавную остановку"}, + {"Start graceful shutdown", "Запустить плавную остановку"}, + {"Force shutdown", "Принудительная остановка"}, + {"Note: any action done here are not persistent and not changes your config files.", + "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, + {"Logging level", "Уровень логирования"}, + {"Transit tunnels limit", "Лимит транзитных туннелей"}, + {"Change", "Изменить"}, + // ShowTransitTunnels + {"no transit tunnels currently built", "нет построенных транзитных туннелей"}, + // ShowSAMSessions/ShowSAMSession + {"SAM disabled", "SAM выключен"}, + {"SAM session not found", "SAM сессия не найдена"}, + {"no sessions currently running", "нет запущенных сессий"}, + {"SAM Session", "SAM сессия"}, + // ShowI2PTunnels + {"Server Tunnels", "Серверные туннели"}, + {"Client Forwards", "Клиентские переадресации"}, + {"Server Forwards", "Серверные переадресации"}, + // HandlePage + {"Unknown page", "Неизвестная страница"}, + // HandleCommand, ShowError + {"Invalid token", "Неверный токен"}, + {"SUCCESS", "УСПЕШНО"}, + {"ERROR", "ОШИБКА"}, + {"Unknown command", "Неизвестная команда"}, + {"Command accepted", "Команда принята"}, + {"Back to commands list", "Вернуться к списку команд"}, + {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, + // HTTP_COMMAND_KILLSTREAM + {"Stream closed", "Стрим закрыт"}, + {"Stream not found or already was closed", "Стрим не найден или уже закрыт"}, + {"Destination not found", "Точка назначения не найдена"}, + {"StreamID can't be null", "StreamID не может быть пустым"}, + {"Return to destination page", "Вернуться на страницу точки назначения"}, + {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, + // HTTP_COMMAND_LIMITTRANSIT + {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, + // HTTP_COMMAND_GET_REG_STRING + {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, + {"Description", "Описание"}, + {"A bit information about service on domain", "Немного информации о сервисе на домене"}, + {"Submit", "Отправить"}, + {"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"}, + {"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"}, + {"Such destination is not found", "Такая точка назначения не найдена"}, {"", ""}, }; static std::map> plurals { + // ShowUptime {"days", {"день", "дня", "дней"}}, {"hours", {"час", "часа", "часов"}}, - {"minutes", {"минута", "минуты", "минут"}}, - {"seconds", {"секунда", "секунды", "секунд"}}, + {"minutes", {"минуту", "минуты", "минут"}}, + {"seconds", {"секунду", "секунды", "секунд"}}, {"", {"", ""}}, }; From a4b84517dc66267354a962ca7f1487b8ded14cf2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 10:56:20 +0300 Subject: [PATCH 0094/2193] [i18n] rename Russian translation, fix typo Signed-off-by: R4SAS --- i18n/{russian.cpp => Russian.cpp} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename i18n/{russian.cpp => Russian.cpp} (99%) diff --git a/i18n/russian.cpp b/i18n/Russian.cpp similarity index 99% rename from i18n/russian.cpp rename to i18n/Russian.cpp index 71f27613..d208e18f 100644 --- a/i18n/russian.cpp +++ b/i18n/Russian.cpp @@ -66,7 +66,7 @@ namespace russian { // language // ShowTunnelDetails {"building", "строится"}, {"failed", "неудачный"}, - {"expiring", "заканчивается"}, + {"expiring", "истекает"}, {"established", "работает"}, {"exploratory", "исследовательский"}, {"unknown", "неизвестно"}, From 2db035d23cff8ca17b6ec78d4e8e9a3295968fa7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 13:16:52 +0300 Subject: [PATCH 0095/2193] [i18n] fix addresshelper Signed-off-by: R4SAS --- libi2pd_client/HTTPProxy.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index aff165b0..d8b84e82 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -217,7 +217,8 @@ namespace proxy { b64 = i2p::http::UrlDecode(value); // if we need update exists, request formed with update param if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; } - url.query.replace(pos - 1, len + 1, ""); // +-1 for taking ? and & before parameter + if (pos != 0 && url.query[pos-1] == '&') { pos--; len++; } // if helper is not only one query option + url.query.replace(pos, len, ""); return true; } From 919bf4e144a838a73e4561119fe0b5bc7723e571 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 15:39:29 +0300 Subject: [PATCH 0096/2193] [i18n] add cmake build Signed-off-by: R4SAS --- build/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 6f9fbae6..f6d69b04 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -33,10 +33,12 @@ target_architecture(ARCHITECTURE) set(LIBI2PD_SRC_DIR ../libi2pd) set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client) +set(LANG_SRC_DIR ../i18n) set(DAEMON_SRC_DIR ../daemon) include_directories(${LIBI2PD_SRC_DIR}) include_directories(${LIBI2PD_CLIENT_SRC_DIR}) +include_directories(${LANG_SRC_DIR}) include_directories(${DAEMON_SRC_DIR}) set(LIBI2PD_SRC @@ -126,6 +128,11 @@ if(WITH_LIBRARY) COMPONENT Libraries) endif() +set(LANG_SRC + "${LANG_SRC_DIR}/English.cpp" + "${LANG_SRC_DIR}/Russian.cpp" +) + set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" "${DAEMON_SRC_DIR}/HTTPServer.cpp" @@ -321,7 +328,7 @@ message(STATUS "---------------------------------------") include(GNUInstallDirs) if(WITH_BINARY) - add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) + add_executable("${PROJECT_NAME}" ${LANG_SRC} ${DAEMON_SRC}) if(WITH_STATIC) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") From 5207dd4c9eb9178cd0e0867693a359cc91712e3d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 15:43:04 +0300 Subject: [PATCH 0097/2193] [gha] update freebsd action --- .github/workflows/build-freebsd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-freebsd.yml b/.github/workflows/build-freebsd.yml index 4e31bed7..c6e0addf 100644 --- a/.github/workflows/build-freebsd.yml +++ b/.github/workflows/build-freebsd.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - name: Test in FreeBSD id: test - uses: vmactions/freebsd-vm@v0.1.2 + uses: vmactions/freebsd-vm@v0.1.4 with: usesh: true prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc From 69a0fe3040325cbe8c554609d9ec0a2fd617bf82 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 May 2021 08:52:27 -0400 Subject: [PATCH 0098/2193] pass arg as reference --- i18n/I18N.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/i18n/I18N.h b/i18n/I18N.h index cb3e5c1c..8ce2aa84 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -15,24 +15,30 @@ namespace i2p { namespace i18n { - inline std::string translate (std::string arg) + inline std::string translate (const std::string& arg) { switch (i2p::context.GetLanguage ()) { - case eEnglish: return i2p::i18n::english::GetString (arg); - case eRussian: return i2p::i18n::russian::GetString (arg); - default: return arg; + case eEnglish: + return i2p::i18n::english::GetString (arg); + case eRussian: + return i2p::i18n::russian::GetString (arg); + default: + return arg; } } template - std::string translate (std::string arg, inttype&& n) + std::string translate (const std::string& arg, inttype&& n) { switch (i2p::context.GetLanguage ()) { - case eEnglish: return i2p::i18n::english::GetPlural (arg, (int) n); - case eRussian: return i2p::i18n::russian::GetPlural (arg, (int) n); - default: return arg; + case eEnglish: + return i2p::i18n::english::GetPlural (arg, (int) n); + case eRussian: + return i2p::i18n::russian::GetPlural (arg, (int) n); + default: + return arg; } } From b676d7034f2e784c06c7ffa45f2527545b5bf971 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 May 2021 16:30:42 +0300 Subject: [PATCH 0099/2193] [i18n] update translation Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- i18n/Russian.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 22cefedd..e184dd06 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -455,7 +455,7 @@ namespace http { " \r\n" " " << tr("Domain") << ":\r\n\r\n" " \r\n" - "\r\nNote: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.\r\n

\r\n
\r\n
\r\n"; + "\r\n" << tr("Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.") << "\r\n
\r\n
\r\n
\r\n"; } if(dest->GetNumRemoteLeaseSets()) diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index d208e18f..033ee33d 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -124,6 +124,8 @@ namespace russian { // language {"Address registration line", "Строка регистрации адреса"}, {"Domain", "Домен"}, {"Generate", "Сгенерировать"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", + "Примечание: полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."}, {"Address", "Адрес"}, {"Type", "Тип"}, {"EncType", "ТипШифр"}, From 585116a51f9557038f49630ea4b41d25b47e010c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 May 2021 14:20:23 -0400 Subject: [PATCH 0100/2193] XMR added --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d21df6e7..1aa96fb0 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ ETH: 0x9e5bac70d20d1079ceaa111127f4fb3bccce379d DASH: Xw8YUrQpYzP9tZBmbjqxS3M97Q7v3vJKUF ZEC: t1cTckLuXsr1dwVrK4NDzfhehss4NvMadAJ GST: GbD2JSQHBHCKLa9WTHmigJRpyFgmBj4woG +XMR: 497pJc7X4xqKvcLBLpSUtRgWqMMyo24u4btCos3cak6gbMkpobgSU6492ztUcUBghyeHpYeczB55s38NpuHoH5WGNSPDRMH License ------- From d06924b33940170bc6209f5c51b8b38f35e35e2a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 May 2021 14:28:10 -0400 Subject: [PATCH 0101/2193] LeaseSet type 3 by default --- libi2pd/Destination.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 6e149cf5..40c9e9ab 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -62,7 +62,7 @@ namespace client const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname"; const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType"; - const int DEFAULT_LEASESET_TYPE = 1; + const int DEFAULT_LEASESET_TYPE = 3; const char I2CP_PARAM_LEASESET_ENCRYPTION_TYPE[] = "i2cp.leaseSetEncType"; const char I2CP_PARAM_LEASESET_PRIV_KEY[] = "i2cp.leaseSetPrivKey"; // PSK decryption key, base64 const char I2CP_PARAM_LEASESET_AUTH_TYPE[] = "i2cp.leaseSetAuthType"; From 08fafe267add1de917b2cca1dba1de3efb7e2c0c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 23 May 2021 17:27:14 -0400 Subject: [PATCH 0102/2193] rekey all routers to ECIES --- libi2pd/RouterContext.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 0cfcb18a..78f63137 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -736,14 +736,8 @@ namespace i2p } } std::shared_ptr oldIdentity; - bool rekey = m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1; - if (!rekey && m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) - { - // rekey routers with bandwidth = L (or default) this time - bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - if (!isFloodfill) rekey = true; - } - if (rekey) + if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 || + m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) { // update keys LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new"); From 1a4250d8cc60afb55e06b5244ca1335c5ef4d20b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 25 May 2021 00:22:28 +0300 Subject: [PATCH 0103/2193] [i18n] update russian translation Signed-off-by: R4SAS --- i18n/Russian.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 033ee33d..489bee7b 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -179,8 +179,8 @@ namespace russian { // language {"SAM Session", "SAM сессия"}, // ShowI2PTunnels {"Server Tunnels", "Серверные туннели"}, - {"Client Forwards", "Клиентские переадресации"}, - {"Server Forwards", "Серверные переадресации"}, + {"Client Forwards", "Клиентские перенаправления"}, + {"Server Forwards", "Серверные перенаправления"}, // HandlePage {"Unknown page", "Неизвестная страница"}, // HandleCommand, ShowError From 779f2fa451ac759d9de88820898025ce7c71ec30 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 25 May 2021 22:03:29 +0300 Subject: [PATCH 0104/2193] [i18n] rework localization system Signed-off-by: R4SAS --- daemon/Daemon.cpp | 6 ++-- i18n/English.cpp | 52 +++++++++++++++------------------- i18n/I18N.h | 38 ++++++++++--------------- i18n/I18N_langs.h | 59 +++++++++++++++++++++++++++++---------- i18n/Russian.cpp | 46 +++++++++++++----------------- libi2pd/RouterContext.cpp | 7 +---- libi2pd/RouterContext.h | 12 ++++---- 7 files changed, 111 insertions(+), 109 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index ec62f5d6..f7f2ef2f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -32,6 +32,7 @@ #include "UPnP.h" #include "Timestamp.h" #include "util.h" +#include "I18N.h" namespace i2p { @@ -345,10 +346,7 @@ namespace util } std::string httpLang; i2p::config::GetOption("http.lang", httpLang); - if (!httpLang.compare("russian")) - i2p::context.SetLanguage (eRussian); - else - i2p::context.SetLanguage (eEnglish); + i2p::i18n::SetLanguage(httpLang); return true; } diff --git a/i18n/English.cpp b/i18n/English.cpp index 8664a0f0..8b13279a 100644 --- a/i18n/English.cpp +++ b/i18n/English.cpp @@ -1,23 +1,34 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include +#include +#include "I18N.h" -// Russian localization file - -namespace i2p { -namespace i18n { -namespace english { // language +// English localization file +namespace i2p +{ +namespace i18n +{ +namespace english // language +{ // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html - int plural (int n) { + static int plural (int n) { return n != 1 ? 1 : 0; } static std::map strings { - {"Enabled", "Enabled"}, - {"Disabled", "Disabled"} + {"", ""}, }; static std::map> plurals @@ -25,30 +36,13 @@ namespace english { // language {"days", {"day", "days"}}, {"hours", {"hour", "hours"}}, {"minutes", {"minute", "minutes"}}, - {"seconds", {"second", "seconds"}} + {"seconds", {"second", "seconds"}}, + {"", {"", ""}}, }; - std::string GetString (std::string arg) + std::shared_ptr GetLocale() { - auto it = strings.find(arg); - if (it == strings.end()) - { - return arg; - } else { - return it->second; - } - } - - std::string GetPlural (std::string arg, int n) - { - auto it = plurals.find(arg); - if (it == plurals.end()) - { - return arg; - } else { - int form = plural(n); - return it->second[form]; - } + return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/I18N.h b/i18n/I18N.h index 8ce2aa84..ccb8f413 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -11,37 +11,27 @@ #include "RouterContext.h" - -namespace i2p { -namespace i18n { +namespace i2p +{ +namespace i18n +{ + inline void SetLanguage(const std::string &lang) + { + if (!lang.compare("russian")) + i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); + else + i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); + } inline std::string translate (const std::string& arg) { - switch (i2p::context.GetLanguage ()) - { - case eEnglish: - return i2p::i18n::english::GetString (arg); - case eRussian: - return i2p::i18n::russian::GetString (arg); - default: - return arg; - } + return i2p::context.GetLanguage ()->GetString (arg); } - template - std::string translate (const std::string& arg, inttype&& n) + inline std::string translate (const std::string& arg, const int& n) { - switch (i2p::context.GetLanguage ()) - { - case eEnglish: - return i2p::i18n::english::GetPlural (arg, (int) n); - case eRussian: - return i2p::i18n::russian::GetPlural (arg, (int) n); - default: - return arg; - } + return i2p::context.GetLanguage ()->GetPlural (arg, n); } - } // i18n } // i2p diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 24c683b4..07bdc087 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -9,24 +9,55 @@ #ifndef __I18N_LANGS_H__ #define __I18N_LANGS_H__ -namespace i2p { +namespace i2p +{ +namespace i18n +{ + class Locale + { + public: + Locale ( + const std::map& strings, + const std::map>& plurals, + std::function formula + ): m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { }; -enum Lang { - eEnglish = 0, - eRussian -}; + std::string GetString (const std::string& arg) const + { + const auto it = m_Strings.find(arg); + if (it == m_Strings.end()) + { + return arg; + } + else + { + return it->second; + } + } -namespace i18n { + std::string GetPlural (const std::string& arg, const int& n) const + { + const auto it = m_Plurals.find(arg); + if (it == m_Plurals.end()) + { + return arg; + } + else + { + int form = m_Formula(n); + return it->second[form]; + } + } - namespace english { - std::string GetString (std::string arg); - std::string GetPlural (std::string arg, int n); - } + private: + const std::map m_Strings; + const std::map> m_Plurals; + std::function m_Formula; + }; - namespace russian { - std::string GetString (std::string arg); - std::string GetPlural (std::string arg, int n); - } + // Add localization here with language name as namespace + namespace english { std::shared_ptr GetLocale (); } + namespace russian { std::shared_ptr GetLocale (); } } // i18n } // i2p diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 489bee7b..1f2c25da 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -1,16 +1,28 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include #include +#include +#include "I18N.h" // Russian localization file -namespace i2p { -namespace i18n { -namespace russian { // language - +namespace i2p +{ +namespace i18n +{ +namespace russian // language +{ // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html - int plural (int n) { + static int plural (int n) { return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; } @@ -218,30 +230,12 @@ namespace russian { // language {"hours", {"час", "часа", "часов"}}, {"minutes", {"минуту", "минуты", "минут"}}, {"seconds", {"секунду", "секунды", "секунд"}}, - {"", {"", ""}}, + {"", {"", "", ""}}, }; - std::string GetString (std::string arg) + std::shared_ptr GetLocale() { - auto it = strings.find(arg); - if (it == strings.end()) - { - return arg; - } else { - return it->second; - } - } - - std::string GetPlural (std::string arg, int n) - { - auto it = plurals.find(arg); - if (it == plurals.end()) - { - return arg; - } else { - int form = plural(n); - return it->second[form]; - } + return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 78f63137..664b457c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -29,7 +29,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), - m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID), m_Language (eEnglish) + m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -910,11 +910,6 @@ namespace i2p } } - void RouterContext::SetLanguage (Lang language) - { - m_Language = language; - } - i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () { if (!m_StaticKeys) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 1cb77a74..ee34c2d8 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -99,7 +99,7 @@ namespace garlic bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data); void UpdatePort (int port); // called from Daemon - void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon + void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); void UpdateNTCP2Address (bool enable); void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later @@ -125,11 +125,11 @@ namespace garlic void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host); bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; std::unique_ptr& GetCurrentNoiseState () { return m_CurrentNoiseState; }; - + void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove void UpdateStats (); void UpdateTimestamp (uint64_t ts); // in seconds, called from NetDb before publishing - void CleanupDestination (); // garlic destination + void CleanupDestination (); // garlic destination // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; @@ -146,8 +146,8 @@ namespace garlic void ProcessDeliveryStatusMessage (std::shared_ptr msg); // i18n - Lang GetLanguage () const { return m_Language; }; - void SetLanguage (Lang language); + std::shared_ptr GetLanguage () { return m_Language; }; + void SetLanguage (const std::shared_ptr language) { m_Language = language; }; protected: @@ -185,7 +185,7 @@ namespace garlic std::unique_ptr m_InitialNoiseState, m_CurrentNoiseState; // i18n - Lang m_Language; + std::shared_ptr m_Language; }; extern RouterContext context; From 0275f7f574b03e2ac8b2f7d1797d7437336bc8e1 Mon Sep 17 00:00:00 2001 From: Artem M Date: Wed, 26 May 2021 10:05:10 +0300 Subject: [PATCH 0105/2193] [i18n] fix two typos in the russian translation (#1659) --- i18n/Russian.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 1f2c25da..28e07cc1 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -39,7 +39,7 @@ namespace russian // language {"addresshelper is not supported", "addresshelper не поддерживается"}, {"Host", "Адрес"}, {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, - {"already in router's addressbook", "уже а адресной книге роутера"}, + {"already in router's addressbook", "уже в адресной книге роутера"}, {"Click", "Нажмите"}, {"here", "здесь"}, {"to proceed", "чтобы продолжить"}, @@ -51,7 +51,7 @@ namespace russian // language {"bad outproxy settings", "некорректные настройки внешнего прокси"}, {"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"}, {"unknown outproxy url", "неизвестный URL внешнего прокси"}, - {"cannot resolve upstream proxy", "не удается определить внешний прокси"}, + {"cannot resolve upstream proxy", "не удается определить вышестоящий прокси"}, {"hostname too long", "имя хоста слишком длинное"}, {"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"}, {"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"}, From bdf63cf82ca38a97e08f7c1cf278664844bd12a0 Mon Sep 17 00:00:00 2001 From: Artem M Date: Wed, 26 May 2021 10:38:58 +0300 Subject: [PATCH 0106/2193] [i18n] add Ukrainian (#1658) --- i18n/Ukrainian.cpp | 243 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 i18n/Ukrainian.cpp diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp new file mode 100644 index 00000000..94c61d80 --- /dev/null +++ b/i18n/Ukrainian.cpp @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Russian localization file + +namespace i2p +{ +namespace i18n +{ +namespace ukrainian // language +{ + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; + } + + static std::map strings + { + // HTTP Proxy + {"Proxy error", "Помилка проксі"}, + {"Proxy info", "Інформація проксі"}, + {"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"}, + {"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі роутера"}, + {"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"}, + {"Invalid request", "Некоректний запит"}, + {"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"}, + {"addresshelper is not supported", "addresshelper не підтримується"}, + {"Host", "Адреса"}, + {"added to router's addressbook from helper", "доданий в адресну книгу роутера через хелпер"}, + {"already in router's addressbook", "вже в адресній книзі роутера"}, + {"Click", "Натисніть"}, + {"here", "тут"}, + {"to proceed", "щоб продовжити"}, + {"to update record", "щоб оновити запис"}, + {"Addresshelper found", "Знайдено addresshelper"}, + {"invalid request uri", "некоректний URI запиту"}, + {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, + {"Outproxy failure", "Помилка зовнішнього проксі"}, + {"bad outproxy settings", "некоректні налаштування зовнішнього проксі"}, + {"not inside I2P network, but outproxy is not enabled", "не в I2P мережі, але зовнішній проксі не включений"}, + {"unknown outproxy url", "невідомий URL зовнішнього проксі"}, + {"cannot resolve upstream proxy", "не вдається визначити висхідний проксі"}, + {"hostname too long", "ім'я вузла надто довге"}, + {"cannot connect to upstream socks proxy", "не вдається підключитися до висхідного SOCKS проксі"}, + {"Cannot negotiate with socks proxy", "Не вдається домовитися з висхідним SOCKS проксі"}, + {"CONNECT error", "Помилка CONNECT запиту"}, + {"Failed to Connect", "Не вдалося підключитися"}, + {"socks proxy error", "помилка SOCKS проксі"}, + {"failed to send request to upstream", "не вдалося відправити запит висхідному проксі"}, + {"No Reply From socks proxy", "Немає відповіді від SOCKS проксі сервера"}, + {"cannot connect", "не вдалося підключитися"}, + {"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"}, + {"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"}, + {"Host is down", "Вузол недоступний"}, + {"Can't create connection to requested host, it may be down. Please try again later.", + "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."}, + + // Webconsole // + // cssStyles + {"Disabled", "Вимкнуто"}, + {"Enabled", "Увімкнуто"}, + // ShowTraffic + {"KiB", "КіБ"}, + {"MiB", "МіБ"}, + {"GiB", "ГіБ"}, + // ShowTunnelDetails + {"building", "будується"}, + {"failed", "невдалий"}, + {"expiring", "завершується"}, + {"established", "працює"}, + {"exploratory", "дослідницький"}, + {"unknown", "невідомо"}, + {"i2pd webconsole", "Веб-консоль i2pd"}, + // ShowPageHead + {"Main page", "Головна"}, + {"Router commands", "Команди роутера"}, + {"Local destinations", "Локальні признач."}, + {"LeaseSets", "Лізсети"}, + {"Tunnels", "Тунелі"}, + {"Transit tunnels", "Транзит. тунелі"}, + {"Transports", "Транспорти"}, + {"I2P tunnels", "I2P тунелі"}, + {"SAM sessions", "SAM сесії"}, + // Network Status + {"OK", "OK"}, + {"Testing", "Тестування"}, + {"Firewalled", "Файрвол"}, + {"Unknown", "Невідомо"}, + {"Proxy", "Проксі"}, + {"Mesh", "MESH-мережа"}, + {"Error", "Помилка"}, + {"Clock skew", "Неточний час"}, + {"Offline", "Офлайн"}, + {"Symmetric NAT", "Симетричний NAT"}, + // Status + {"Uptime", "В мережі"}, + {"Network status", "Мережевий статус"}, + {"Network status v6", "Мережевий статус v6"}, + {"Stopping in", "Зупинка через"}, + {"Family", "Сімейство"}, + {"Tunnel creation success rate", "Успішно побудованих тунелів"}, + {"Received", "Отримано"}, + {"Sent", "Відправлено"}, + {"Transit", "Транзит"}, + {"KiB/s", "КіБ/с"}, + {"Data path", "Шлях до даних"}, + {"Hidden content. Press on text to see.", "Прихований вміст. Натисніть на текст щоб відобразити."}, + {"Router Ident", "Ідентифікатор Роутера"}, + {"Router Family", "Сімейство Роутера"}, + {"Router Caps", "Прапорці Роутера"}, + {"Version", "Версія"}, + {"Our external address", "Наша зовнішня адреса"}, + {"supported", "підтримується"}, + {"Routers", "Роутери"}, + {"Floodfills", "Флудфіли"}, + {"LeaseSets", "Лізсети"}, + {"Client Tunnels", "Клієнтські Тунелі"}, + {"Transit Tunnels", "Транзитні Тунелі"}, + {"Services", "Сервіси"}, + // ShowLocalDestinations + {"Local Destinations", "Локальні Призначення"}, + // ShowLeaseSetDestination + {"Encrypted B33 address", "Шифровані B33 адреси"}, + {"Address registration line", "Рядок реєстрації адреси"}, + {"Domain", "Домен"}, + {"Generate", "Згенерувати"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", + "Примітка: отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня. Для реєстрації піддоменів використовуйте i2pd-tools."}, + {"Address", "Адреса"}, + {"Type", "Тип"}, + {"EncType", "ТипШифр"}, + {"Inbound tunnels", "Вхідні тунелі"}, + {"Outbound tunnels", "Вихідні тунелі"}, + {"ms", "мс"}, // milliseconds + {"Tags", "Теги"}, + {"Incoming", "Вхідні"}, + {"Outgoing", "Вихідні"}, + {"Destination", "Призначення"}, + {"Amount", "Кількість"}, + {"Incoming Tags", "Вхідні Теги"}, + {"Tags sessions", "Сесії тегів"}, + {"Status", "Статус"}, + // ShowLocalDestination + {"Local Destination", "Локальне Призначення"}, + {"Streams", "Потоки"}, + {"Close stream", "Закрити потік"}, + // ShowI2CPLocalDestination + {"I2CP session not found", "I2CP сесія не знайдена"}, + {"I2CP is not enabled", "I2CP не увікнуто"}, + // ShowLeasesSets + {"Invalid", "Некоректний"}, + {"Store type", "Тип сховища"}, + {"Expires", "Завершується"}, + {"Non Expired Leases", "Не завершені Lease-и"}, + {"Gateway", "Шлюз"}, + {"TunnelID", "ID тунеля"}, + {"EndDate", "Закінчується"}, + {"not floodfill", "не флудфіл"}, + // ShowTunnels + {"Queue size", "Розмір черги"}, + // ShowCommands + {"Run peer test", "Запустити тестування"}, + {"Decline transit tunnels", "Відхиляти транзитні тунелі"}, + {"Accept transit tunnels", "Ухвалювати транзитні тунелі"}, + {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, + {"Start graceful shutdown", "Запустити плавну зупинку"}, + {"Force shutdown", "Примусова зупинка"}, + {"Note: any action done here are not persistent and not changes your config files.", + "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, + {"Logging level", "Рівень логування"}, + {"Transit tunnels limit", "Обмеження транзитних тунелів"}, + {"Change", "Змінити"}, + // ShowTransitTunnels + {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, + // ShowSAMSessions/ShowSAMSession + {"SAM disabled", "SAM вимкнуто"}, + {"SAM session not found", "SAM сесія не знайдена"}, + {"no sessions currently running", "немає запущених сесій"}, + {"SAM Session", "SAM сесія"}, + // ShowI2PTunnels + {"Server Tunnels", "Серверні Тунелі"}, + {"Client Forwards", "Клієнтські Переспрямування"}, + {"Server Forwards", "Серверні Переспрямування"}, + // HandlePage + {"Unknown page", "Невідома сторінка"}, + // HandleCommand, ShowError + {"Invalid token", "Невірний токен"}, + {"SUCCESS", "ВДАЛО"}, + {"ERROR", "ПОМИЛКА"}, + {"Unknown command", "Невідома команда"}, + {"Command accepted", "Команда прийнята"}, + {"Back to commands list", "Повернутися до списку команд"}, + {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, + // HTTP_COMMAND_KILLSTREAM + {"Stream closed", "Потік зачинений"}, + {"Stream not found or already was closed", "Потік не знайдений або вже зачинений"}, + {"Destination not found", "Точка призначення не знайдена"}, + {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, + {"Return to destination page", "Повернутися на сторінку точки призначення"}, + {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, + // HTTP_COMMAND_LIMITTRANSIT + {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, + // HTTP_COMMAND_GET_REG_STRING + {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, + {"Description", "Опис"}, + {"A bit information about service on domain", "Трохи інформації про сервіс на домені"}, + {"Submit", "Надіслати"}, + {"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"}, + {"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"}, + {"Such destination is not found", "Така точка призначення не знайдена"}, + {"", ""}, + }; + + static std::map> plurals + { + // ShowUptime + {"days", {"день", "дня", "днів"}}, + {"hours", {"годину", "години", "годин"}}, + {"minutes", {"хвилину", "хвилини", "хвилин"}}, + {"seconds", {"секунду", "секунди", "секунд"}}, + {"", {"", "", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p From cc1244126cd6e526aa40e637d6e032ba102a1558 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 May 2021 10:50:02 +0300 Subject: [PATCH 0107/2193] [i18n] enable Ukrainian in source Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- i18n/I18N.h | 4 +++- i18n/I18N_langs.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 3c9c71ff..3b20a809 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -104,7 +104,7 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported only english (default) and russian languages +## Currently supported english (default), russian and ukrainian languages # lang = english [httpproxy] diff --git a/i18n/I18N.h b/i18n/I18N.h index ccb8f413..a1a78b77 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -19,7 +19,9 @@ namespace i18n { if (!lang.compare("russian")) i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); - else + if (!lang.compare("ukrainian")) + i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale()); + else // fallback i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); } diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 07bdc087..c094cb79 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -58,6 +58,7 @@ namespace i18n // Add localization here with language name as namespace namespace english { std::shared_ptr GetLocale (); } namespace russian { std::shared_ptr GetLocale (); } + namespace ukrainian { std::shared_ptr GetLocale (); } } // i18n } // i2p From ebce1e34d8ff325e32f6871a66e8300ac5d10f55 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 May 2021 12:56:47 +0300 Subject: [PATCH 0108/2193] [i18n] enable Ukrainian in source Signed-off-by: R4SAS --- build/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index f6d69b04..b96cfb6a 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -131,6 +131,7 @@ endif() set(LANG_SRC "${LANG_SRC_DIR}/English.cpp" "${LANG_SRC_DIR}/Russian.cpp" + "${LANG_SRC_DIR}/Ukrainian.cpp" ) set(DAEMON_SRC From 0292227a6b1c5330b04224ae6d4930ba8cb65854 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 May 2021 13:15:17 +0300 Subject: [PATCH 0109/2193] [cmake] switch to glob instead filling sources list Signed-off-by: R4SAS --- build/CMakeLists.txt | 70 ++------------------------------------------ 1 file changed, 3 insertions(+), 67 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index b96cfb6a..d1b51f23 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -41,55 +41,7 @@ include_directories(${LIBI2PD_CLIENT_SRC_DIR}) include_directories(${LANG_SRC_DIR}) include_directories(${DAEMON_SRC_DIR}) -set(LIBI2PD_SRC - "${LIBI2PD_SRC_DIR}/api.cpp" - "${LIBI2PD_SRC_DIR}/Base.cpp" - "${LIBI2PD_SRC_DIR}/Blinding.cpp" - "${LIBI2PD_SRC_DIR}/BloomFilter.cpp" - "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" - "${LIBI2PD_SRC_DIR}/Config.cpp" - "${LIBI2PD_SRC_DIR}/CPU.cpp" - "${LIBI2PD_SRC_DIR}/Crypto.cpp" - "${LIBI2PD_SRC_DIR}/CryptoKey.cpp" - "${LIBI2PD_SRC_DIR}/Datagram.cpp" - "${LIBI2PD_SRC_DIR}/Destination.cpp" - "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp" - "${LIBI2PD_SRC_DIR}/Ed25519.cpp" - "${LIBI2PD_SRC_DIR}/Elligator.cpp" - "${LIBI2PD_SRC_DIR}/Family.cpp" - "${LIBI2PD_SRC_DIR}/FS.cpp" - "${LIBI2PD_SRC_DIR}/Garlic.cpp" - "${LIBI2PD_SRC_DIR}/Gost.cpp" - "${LIBI2PD_SRC_DIR}/Gzip.cpp" - "${LIBI2PD_SRC_DIR}/HTTP.cpp" - "${LIBI2PD_SRC_DIR}/I2NPProtocol.cpp" - "${LIBI2PD_SRC_DIR}/Identity.cpp" - "${LIBI2PD_SRC_DIR}/LeaseSet.cpp" - "${LIBI2PD_SRC_DIR}/Log.cpp" - "${LIBI2PD_SRC_DIR}/NetDb.cpp" - "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" - "${LIBI2PD_SRC_DIR}/NTCP2.cpp" - "${LIBI2PD_SRC_DIR}/Poly1305.cpp" - "${LIBI2PD_SRC_DIR}/Profiling.cpp" - "${LIBI2PD_SRC_DIR}/Reseed.cpp" - "${LIBI2PD_SRC_DIR}/RouterContext.cpp" - "${LIBI2PD_SRC_DIR}/RouterInfo.cpp" - "${LIBI2PD_SRC_DIR}/Signature.cpp" - "${LIBI2PD_SRC_DIR}/SSU.cpp" - "${LIBI2PD_SRC_DIR}/SSUData.cpp" - "${LIBI2PD_SRC_DIR}/SSUSession.cpp" - "${LIBI2PD_SRC_DIR}/Streaming.cpp" - "${LIBI2PD_SRC_DIR}/Timestamp.cpp" - "${LIBI2PD_SRC_DIR}/TransitTunnel.cpp" - "${LIBI2PD_SRC_DIR}/Transports.cpp" - "${LIBI2PD_SRC_DIR}/Tunnel.cpp" - "${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp" - "${LIBI2PD_SRC_DIR}/TunnelGateway.cpp" - "${LIBI2PD_SRC_DIR}/TunnelPool.cpp" - "${LIBI2PD_SRC_DIR}/TunnelConfig.cpp" - "${LIBI2PD_SRC_DIR}/util.cpp" -) - +FILE(GLOB LIBI2PD_SRC ${LIBI2PD_SRC_DIR}/*.cpp) add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") @@ -104,19 +56,7 @@ if(WITH_LIBRARY) # install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() -set(CLIENT_SRC - "${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/BOB.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/ClientContext.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/MatchedDestination.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/I2PTunnel.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/I2PService.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/SAM.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/SOCKS.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/HTTPProxy.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/I2CP.cpp" -) - +FILE(GLOB CLIENT_SRC ${LIBI2PD_CLIENT_SRC_DIR}/*.cpp) add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") @@ -128,11 +68,7 @@ if(WITH_LIBRARY) COMPONENT Libraries) endif() -set(LANG_SRC - "${LANG_SRC_DIR}/English.cpp" - "${LANG_SRC_DIR}/Russian.cpp" - "${LANG_SRC_DIR}/Ukrainian.cpp" -) +FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp) set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" From 35b1842a7204dd30b72b407d3ccd90a3bcd1afef Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 May 2021 13:21:15 +0300 Subject: [PATCH 0110/2193] [gha] add cmake build on ubuntu Signed-off-by: R4SAS --- .github/workflows/build.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a776df92..c7b5a667 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,8 +3,8 @@ name: Build on Ubuntu on: [push, pull_request] jobs: - build: - name: With USE_UPNP=${{ matrix.with_upnp }} + build-make: + name: Make with USE_UPNP=${{ matrix.with_upnp }} runs-on: ubuntu-16.04 strategy: fail-fast: true @@ -19,3 +19,22 @@ jobs: sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application run: make USE_UPNP=${{ matrix.with_upnp }} -j3 + build-cmake: + name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }} + runs-on: ubuntu-16.04 + strategy: + fail-fast: true + matrix: + with_upnp: ['ON', 'OFF'] + steps: + - uses: actions/checkout@v2 + - name: install packages + run: | + sudo add-apt-repository ppa:mhier/libboost-latest + sudo apt-get update + sudo apt-get install build-essential cmake libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application + run: | + cd build + cmake -DWITH_UPNP=${{ matrix.with_upnp }} . + make -j3 From 5011ecaaa65427e83badde130c1185de27f2dae5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 May 2021 13:27:13 +0300 Subject: [PATCH 0111/2193] [i18n] fix language selection Signed-off-by: R4SAS --- i18n/I18N.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/I18N.h b/i18n/I18N.h index a1a78b77..366e9269 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -19,7 +19,7 @@ namespace i18n { if (!lang.compare("russian")) i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); - if (!lang.compare("ukrainian")) + else if (!lang.compare("ukrainian")) i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale()); else // fallback i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); From 3a53e049bd4fbb085af75810e13970e4471c8a64 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 May 2021 13:43:24 +0300 Subject: [PATCH 0112/2193] [gha] switch ubuntu to 18.04 Signed-off-by: R4SAS --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7b5a667..d8828f61 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: [push, pull_request] jobs: build-make: name: Make with USE_UPNP=${{ matrix.with_upnp }} - runs-on: ubuntu-16.04 + runs-on: ubuntu-18.04 strategy: fail-fast: true matrix: @@ -21,7 +21,7 @@ jobs: run: make USE_UPNP=${{ matrix.with_upnp }} -j3 build-cmake: name: CMake with -DWITH_UPNP=${{ matrix.with_upnp }} - runs-on: ubuntu-16.04 + runs-on: ubuntu-18.04 strategy: fail-fast: true matrix: From 8ce5ceef5970478ff39eb59544278f9c633579d7 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 27 May 2021 17:47:59 -0400 Subject: [PATCH 0113/2193] Correct transaltion for "Firewalled" --- i18n/Russian.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 28e07cc1..7df82d54 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -96,7 +96,7 @@ namespace russian // language // Network Status {"OK", "OK"}, {"Testing", "Тестирование"}, - {"Firewalled", "Файрвол"}, + {"Firewalled", "Заблокировано извне"}, {"Unknown", "Неизвестно"}, {"Proxy", "Прокси"}, {"Mesh", "MESH-сеть"}, From e77e383efa8021fdcb21557a8073df91b26214c9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 28 May 2021 18:59:59 +0300 Subject: [PATCH 0114/2193] [docker] add UPnP at compile time (closes #1649) --- contrib/docker/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index adb7ba75..dc9f5501 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -25,24 +25,24 @@ RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \ # 1. install deps, clone and build. # 2. strip binaries. # 3. Purge all dependencies and other unrelated packages, including build directory. -RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl git \ +RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \ && mkdir -p /tmp/build \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd i2pd \ && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \ - && make \ + && make USE_UPNP=yes \ && cp -R contrib/certificates /i2pd_certificates \ && mkdir -p /usr/local/bin \ && mv i2pd /usr/local/bin \ && cd /usr/local/bin \ && strip i2pd \ && rm -fr /tmp/build && apk --no-cache --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \ - boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \ + miniupnpc-dev boost-python3 python3 gdbm boost-unit_test_framework linux-headers boost-prg_exec_monitor \ boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre2 \ libtool g++ gcc # 2. Adding required libraries to run i2pd to ensure it will run. -RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl musl-utils libstdc++ +RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++ COPY entrypoint.sh /entrypoint.sh RUN chmod a+x /entrypoint.sh From a0e545a6f1ed29b9f077371857a587349059416a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 May 2021 12:11:24 -0400 Subject: [PATCH 0115/2193] always create new tunnel from exploratory pool --- libi2pd/TunnelPool.cpp | 18 ++++++++++++++++-- libi2pd/TunnelPool.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index ed9a1a82..f2f0b4c8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -393,10 +393,14 @@ namespace tunnel } } + bool TunnelPool::IsExploratory () const + { + return i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this (); + } + std::shared_ptr TunnelPool::SelectNextHop (std::shared_ptr prevHop, bool reverse) const { - bool isExploratory = (i2p::tunnel::tunnels.GetExploratoryPool () == shared_from_this ()); - auto hop = isExploratory ? i2p::data::netdb.GetRandomRouter (prevHop, reverse): + auto hop = IsExploratory () ? i2p::data::netdb.GetRandomRouter (prevHop, reverse): i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop, reverse); if (!hop || hop->GetProfile ()->IsBad ()) @@ -521,6 +525,11 @@ namespace tunnel void TunnelPool::RecreateInboundTunnel (std::shared_ptr tunnel) { + if (IsExploratory ()) // always create new exploratory tunnel + { + CreateInboundTunnel (); + return; + } auto outboundTunnel = GetNextOutboundTunnel (); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); @@ -567,6 +576,11 @@ namespace tunnel void TunnelPool::RecreateOutboundTunnel (std::shared_ptr tunnel) { + if (IsExploratory ()) // always create new exploratory tunnel + { + CreateOutboundTunnel (); + return; + } auto inboundTunnel = GetNextInboundTunnel (); if (!inboundTunnel) inboundTunnel = tunnels.GetNextInboundTunnel (); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 5fd1d83c..164ca7a1 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -77,6 +77,7 @@ namespace tunnel void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatus (std::shared_ptr msg); + bool IsExploratory () const; bool IsActive () const { return m_IsActive; }; void SetActive (bool isActive) { m_IsActive = isActive; }; void DetachTunnels (); From ed42948051afb308cd7585d4284d286f49829a08 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 30 May 2021 03:23:00 +0300 Subject: [PATCH 0116/2193] prefer public ipv6 instead rfc4941 (closes #1251) Wokrs only on linux-based systems. Not tested on other *nix systems, and not works on windows. Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 9 +++++++++ libi2pd/SSU.cpp | 9 +++++++++ libi2pd/util.h | 6 +++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index d5a03d1c..54d6483c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -23,6 +23,10 @@ #include "HTTP.h" #include "util.h" +#ifdef __linux__ + #include +#endif + namespace i2p { namespace transport @@ -1198,6 +1202,11 @@ namespace transport ep = boost::asio::ip::tcp::endpoint (m_Address6->address(), address->port); else if (m_YggdrasilAddress && !context.SupportsV6 ()) ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port); +#ifdef __linux__ + // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others + typedef boost::asio::detail::socket_option::boolean ipv6PreferPubAddr; + m_NTCP2V6Acceptor->set_option (ipv6PreferPubAddr (true)); +#endif m_NTCP2V6Acceptor->bind (ep); m_NTCP2V6Acceptor->listen (); diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f7801bb0..0836f84e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -14,6 +14,10 @@ #include "SSU.h" #include "util.h" +#ifdef __linux__ + #include +#endif + #ifdef _WIN32 #include #endif @@ -62,6 +66,11 @@ namespace transport m_SocketV6.set_option (boost::asio::ip::v6_only (true)); m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); +#ifdef __linux__ + // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others + typedef boost::asio::detail::socket_option::boolean ipv6PreferPubAddr; + m_SocketV6.set_option (ipv6PreferPubAddr(true)); +#endif m_SocketV6.bind (m_EndpointV6); LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); } diff --git a/libi2pd/util.h b/libi2pd/util.h index 0cab4121..000cb74e 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -177,13 +177,13 @@ namespace util SaveStateHelper (T& orig): m_Original (orig), m_Copy (orig) {}; ~SaveStateHelper () { m_Original = m_Copy; }; - + private: T& m_Original; T m_Copy; - }; - + }; + namespace net { int GetMTU (const boost::asio::ip::address& localAddress); From 39319853ab79c3cadd74cfe69e525a4e247d4bab Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 30 May 2021 21:38:14 +0300 Subject: [PATCH 0117/2193] [i18n] add Turkmen translation Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- i18n/I18N.h | 2 + i18n/I18N_langs.h | 1 + i18n/Turkmen.cpp | 243 +++++++++++++++++++++++++++++++++++++++++++++ i18n/Ukrainian.cpp | 2 +- 5 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 i18n/Turkmen.cpp diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 3b20a809..f3cea2b5 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -104,7 +104,7 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), russian and ukrainian languages +## Currently supported english (default), russian, turkmen and ukrainian languages # lang = english [httpproxy] diff --git a/i18n/I18N.h b/i18n/I18N.h index 366e9269..7d0baf1a 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -19,6 +19,8 @@ namespace i18n { if (!lang.compare("russian")) i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); + else if (!lang.compare("turkmen")) + i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale()); else if (!lang.compare("ukrainian")) i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale()); else // fallback diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index c094cb79..435141bf 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -58,6 +58,7 @@ namespace i18n // Add localization here with language name as namespace namespace english { std::shared_ptr GetLocale (); } namespace russian { std::shared_ptr GetLocale (); } + namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } } // i18n diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp new file mode 100644 index 00000000..93bd92fe --- /dev/null +++ b/i18n/Turkmen.cpp @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Turkmen localization file + +namespace i2p +{ +namespace i18n +{ +namespace turkmen // language +{ + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + static std::map strings + { + // HTTP Proxy + {"Proxy error", "Proksi ýalňyşlygy"}, + {"Proxy info", "Proksi maglumat"}, + {"Proxy error: Host not found", "Proksi ýalňyşlygy: Host tapylmady"}, + {"Remote host not found in router's addressbook", "Uzakdaky öý eýesi marşruteriň salgy kitabynda tapylmady"}, + {"You may try to find this host on jump services below", "Aşakdaky böküş hyzmatlarynda bu öý eýesini tapmaga synanyşyp bilersiňiz"}, + {"Invalid request", "Nädogry haýyş"}, + {"Proxy unable to parse your request", "Proksi haýyşyňyzy derňäp bilmeýär"}, + {"addresshelper is not supported", "Salgylandyryjy goldanok"}, + {"Host", "Adres"}, + {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"}, + {"already in router's addressbook", "marşruteriň adres kitaby"}, + {"Click", "Basyň"}, + {"here", "bu ýerde"}, + {"to proceed", "dowam etmek"}, + {"to update record", "recordazgyny täzelemek üçin"}, + {"Addresshelper found", "Forgelper tapyldy"}, + {"invalid request uri", "nädogry haýyş URI"}, + {"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"}, + {"Outproxy failure", "Daşarky proksi ýalňyşlyk"}, + {"bad outproxy settings", "daşarky daşarky proksi sazlamalary nädogry"}, + {"not inside I2P network, but outproxy is not enabled", "I2P torunda däl, ýöne daşarky proksi goşulmaýar"}, + {"unknown outproxy url", "näbelli daşarky proksi URL"}, + {"cannot resolve upstream proxy", "has ýokary proksi kesgitläp bilmeýär"}, + {"hostname too long", "hoster eýesi ady gaty uzyn"}, + {"cannot connect to upstream socks proxy", "ýokary jorap SOCKS proksi bilen birigip bolmaýar"}, + {"Cannot negotiate with socks proxy", "Iň ýokary jorap SOCKS proksi bilen ylalaşyp bilmeýärler"}, + {"CONNECT error", "Bagyr haýyşy säwligi"}, + {"Failed to Connect", "Birikdirip bilmedi"}, + {"socks proxy error", "socks proksi ýalňyşlygy"}, + {"failed to send request to upstream", "öý eýesi proksi üçin haýyş iberip bilmedi"}, + {"No Reply From socks proxy", "Jorap proksi serwerinden hiç hili jogap ýok"}, + {"cannot connect", "birikdirip bilmedi"}, + {"http out proxy not implemented", "daşarky http proksi serwerini goldamak amala aşyrylmaýar"}, + {"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"}, + {"Host is down", "Salgy elýeterli däl"}, + {"Can't create connection to requested host, it may be down. Please try again later.", + "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."}, + + // Webconsole // + // cssStyles + {"Disabled", "Öçürildi"}, + {"Enabled", "Goşuldy"}, + // ShowTraffic + {"KiB", "KiB"}, + {"MiB", "MiB"}, + {"GiB", "GiB"}, + // ShowTunnelDetails + {"building", "bina"}, + {"failed", "şowsuz"}, + {"expiring", "möhleti gutarýar"}, + {"established", "işleýär"}, + {"exploratory", "gözleg"}, + {"unknown", "näbelli"}, + {"i2pd webconsole", "Web konsoly i2pd"}, + // ShowPageHead + {"Main page", "Esasy sahypa"}, + {"Router commands", "Marşrutizator buýruklary"}, + {"Local destinations", "Ýerli ýerler"}, + {"LeaseSets", "Lizset"}, + {"Tunnels", "Tuneller"}, + {"Transit tunnels", "Tranzit Tunels"}, + {"Transports", "Daşamak"}, + {"I2P tunnels", "I2P tuneller"}, + {"SAM sessions", "SAM Sessiýasy"}, + // Network Status + {"OK", "OK"}, + {"Testing", "Synag etmek"}, + {"Firewalled", "Daşynda petiklendi"}, + {"Unknown", "Näbelli"}, + {"Proxy", "Proksi"}, + {"Mesh", "MESH-tor"}, + {"Error", "Ýalňyşlyk"}, + {"Clock skew", "Takyk wagt däl"}, + {"Offline", "Awtonom"}, + {"Symmetric NAT", "Simmetriklik NAT"}, + // Status + {"Uptime", "Onlaýn onlaýn sözlügi"}, + {"Network status", "Tor ýagdaýy"}, + {"Network status v6", "Tor ýagdaýy v6"}, + {"Stopping in", "soň duruň"}, + {"Family", "Maşgala"}, + {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, + {"Received", "Alnan"}, + {"Sent", "Ýerleşdirildi"}, + {"Transit", "Tranzit"}, + {"KiB/s", "KiB/s"}, + {"Data path", "Maglumat ýoly"}, + {"Hidden content. Press on text to see.", "Gizlin mazmun. Görkezmek üçin tekste basyň."}, + {"Router Ident", "Marşrutly kesgitleýji"}, + {"Router Family", "Marşrutler maşgalasy"}, + {"Router Caps", "Baýdaklar marşruteri"}, + {"Version", "Wersiýasy"}, + {"Our external address", "Daşarky salgymyz"}, + {"supported", "Goldanýar"}, + {"Routers", "Marşrutizatorlar"}, + {"Floodfills", "Fludfillar"}, + {"LeaseSets", "Lizsetllar"}, + {"Client Tunnels", "Müşderi tunelleri"}, + {"Transit Tunnels", "Tranzit Tunelleri"}, + {"Services", "Hyzmatlar"}, + // ShowLocalDestinations + {"Local Destinations", "Ýerli ýerler"}, + // ShowLeaseSetDestination + {"Encrypted B33 address", "Şifrlenen B33 salgylar"}, + {"Address registration line", "Hasaba alyş salgysy"}, + {"Domain", "Domen"}, + {"Generate", "Öndürmek"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", + "Bellik: Alnan setir diňe ikinji derejeli domenleri bellige almak üçin ulanylyp bilner. Subýutmalary hasaba almak üçin i2pd ulanyň-tools."}, + {"Address", "Salgysy"}, + {"Type", "Görnüş"}, + {"EncType", "Şifrlemek görnüşi"}, + {"Inbound tunnels", "Gelýän tuneller"}, + {"Outbound tunnels", "Çykýan tuneller"}, + {"ms", "ms"}, // milliseconds + {"Tags", "Bellikler"}, + {"Incoming", "Gelýän"}, + {"Outgoing", "Çykýan"}, + {"Destination", "Maksat"}, + {"Amount", "Sany"}, + {"Incoming Tags", "Gelýän bellikler"}, + {"Tags sessions", "Sapaklar Tag."}, + {"Status", "Ýagdaýy"}, + // ShowLocalDestination + {"Local Destination", "Ýerli maksat"}, + {"Streams", "Strimlary"}, + {"Close stream", "Yap strim"}, + // ShowI2CPLocalDestination + {"I2CP session not found", "I2CP Sessiýa tapylmady"}, + {"I2CP is not enabled", "I2CP goşulmaýar"}, + // ShowLeasesSets + {"Invalid", "Nädogry"}, + {"Store type", "Ammar görnüşi"}, + {"Expires", "Möhleti gutarýar"}, + {"Non Expired Leases", "Möhleti gutarmady Lizsetlary"}, + {"Gateway", "Derweze"}, + {"TunnelID", "Tuneliň ID"}, + {"EndDate", "Gutarýar"}, + {"not floodfill", "fludfil däl"}, + // ShowTunnels + {"Queue size", "Nobatyň ululygy"}, + // ShowCommands + {"Run peer test", "Synag başlaň"}, + {"Decline transit tunnels", "Tranzit tunellerini ret ediň"}, + {"Accept transit tunnels", "Tranzit tunellerini alyň"}, + {"Cancel graceful shutdown", "Tekiz durmagy ýatyryň"}, + {"Start graceful shutdown", "Tekiz durmak"}, + {"Force shutdown", "Mejbury duralga"}, + {"Note: any action done here are not persistent and not changes your config files.", + "Bellik: Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär.."}, + {"Logging level", "Giriş derejesi"}, + {"Transit tunnels limit", "Tranzit tunelleriniň çägi"}, + {"Change", "Üýtgetmek"}, + // ShowTransitTunnels + {"no transit tunnels currently built", "gurlan tranzit tunelleri ýok"}, + // ShowSAMSessions/ShowSAMSession + {"SAM disabled", "SAM öçürilen"}, + {"SAM session not found", "SAM Sessiýa tapylmady"}, + {"no sessions currently running", "başlamagyň sessiýalary ýok"}, + {"SAM Session", "SAM Sessiýa"}, + // ShowI2PTunnels + {"Server Tunnels", "Serwer tunelleri"}, + {"Client Forwards", "Müşderi gönükdirýär"}, + {"Server Forwards", "Serweriň täzeden düzlüleri"}, + // HandlePage + {"Unknown page", "Näbelli sahypa"}, + // HandleCommand, ShowError + {"Invalid token", "Nädogry token"}, + {"SUCCESS", "Üstünlikli"}, + {"ERROR", "Ýalňyşlyk"}, + {"Unknown command", "Näbelli topar"}, + {"Command accepted", "Topar kabul edilýär"}, + {"Back to commands list", "Topar sanawyna dolan"}, + {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"}, + // HTTP_COMMAND_KILLSTREAM + {"Stream closed", "Strim ýapyk"}, + {"Stream not found or already was closed", "Strim tapylmady ýa-da eýýäm ýapyldy"}, + {"Destination not found", "Niýetlenen ýeri tapylmady"}, + {"StreamID can't be null", "StreamID boş bolup bilmez"}, + {"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"}, + {"You will be redirected back in 5 seconds", "5 sekuntda yzyna iberiler"}, + // HTTP_COMMAND_LIMITTRANSIT + {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"}, + // HTTP_COMMAND_GET_REG_STRING + {"Register at reg.i2p", "Reg.i2P-de hasaba duruň"}, + {"Description", "Beýany"}, + {"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"}, + {"Submit", "Iber"}, + {"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez."}, + {"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"}, + {"Such destination is not found", "Bu barmaly ýer tapylmady"}, + {"", ""}, + }; + + static std::map> plurals + { + // ShowUptime + {"days", {"gün", "gün"}}, + {"hours", {"sagat", "sagat"}}, + {"minutes", {"minut", "minut"}}, + {"seconds", {"sekunt", "sekunt"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 94c61d80..05e7c786 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -12,7 +12,7 @@ #include #include "I18N.h" -// Russian localization file +// Ukrainian localization file namespace i2p { From be31640010ab6fe6777435302fc231ae3279f73e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 31 May 2021 00:23:50 +0300 Subject: [PATCH 0118/2193] fix ipv6 preference on linux Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 13 ++++++++----- libi2pd/SSU.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 54d6483c..72e822cd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1197,16 +1197,19 @@ namespace transport m_NTCP2V6Acceptor->open (boost::asio::ip::tcp::v6()); m_NTCP2V6Acceptor->set_option (boost::asio::ip::v6_only (true)); m_NTCP2V6Acceptor->set_option (boost::asio::socket_base::reuse_address (true)); +#ifdef __linux__ + if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address + { + // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others + typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; + m_NTCP2V6Acceptor->set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA)); + } +#endif auto ep = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port); if (m_Address6 && !context.SupportsMesh ()) ep = boost::asio::ip::tcp::endpoint (m_Address6->address(), address->port); else if (m_YggdrasilAddress && !context.SupportsV6 ()) ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port); -#ifdef __linux__ - // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others - typedef boost::asio::detail::socket_option::boolean ipv6PreferPubAddr; - m_NTCP2V6Acceptor->set_option (ipv6PreferPubAddr (true)); -#endif m_NTCP2V6Acceptor->bind (ep); m_NTCP2V6Acceptor->listen (); diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 0836f84e..f625c89b 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -67,9 +67,12 @@ namespace transport m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); #ifdef __linux__ - // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others - typedef boost::asio::detail::socket_option::boolean ipv6PreferPubAddr; - m_SocketV6.set_option (ipv6PreferPubAddr(true)); + if (m_EndpointV6.address() != boost::asio::ip::address().from_string("::")) // only if not binded to address + { + // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others + typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; + m_SocketV6.set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA)); + } #endif m_SocketV6.bind (m_EndpointV6); LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); From 0547d590e1f1cefc1f93204cae17e2795487b61a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 31 May 2021 00:24:54 +0300 Subject: [PATCH 0119/2193] fix typo Signed-off-by: R4SAS --- libi2pd/SSU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f625c89b..e4901f7c 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -67,7 +67,7 @@ namespace transport m_SocketV6.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); #ifdef __linux__ - if (m_EndpointV6.address() != boost::asio::ip::address().from_string("::")) // only if not binded to address + if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address { // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; From ef8c4389e104cf217dae6c3e15d9bff83d6abfd9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Jun 2021 12:55:08 -0400 Subject: [PATCH 0120/2193] reachable transports added --- libi2pd/RouterInfo.cpp | 45 ++++++++++++++++++++++++++++++++++++++---- libi2pd/RouterInfo.h | 7 ++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 87a987fe..3035bd31 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -36,7 +36,7 @@ namespace data RouterInfo::RouterInfo (const std::string& fullPath): m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), - m_SupportedTransports (0), m_Caps (0), m_Version (0) + m_SupportedTransports (0), m_ReachableTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; @@ -45,7 +45,7 @@ namespace data RouterInfo::RouterInfo (const uint8_t * buf, int len): m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), - m_Caps (0), m_Version (0) + m_ReachableTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) @@ -84,6 +84,7 @@ namespace data m_IsUpdated = true; m_IsUnreachable = false; m_SupportedTransports = 0; + m_ReachableTransports = 0; m_Caps = 0; // don't clean up m_Addresses, it will be replaced in ReadFromStream m_Properties.clear (); @@ -305,9 +306,10 @@ namespace data if (isHost) { if (address->host.is_v6 ()) - supportedTransports |= i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6; + supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6); else supportedTransports |= eNTCP2V4; + m_ReachableTransports |= supportedTransports; } else if (!address->published) { @@ -347,10 +349,16 @@ namespace data else it.iPort = 0; } - if (!numValid) address->ssu->introducers.resize (0); + if (numValid) + m_ReachableTransports |= supportedTransports; + else + address->ssu->introducers.resize (0); } else if (isHost && address->port) + { address->published = true; + m_ReachableTransports |= supportedTransports; + } } } if (supportedTransports) @@ -860,6 +868,7 @@ namespace data for (auto& intro: addr->ssu->introducers) if (intro.iTag == introducer.iTag) return false; // already presented addr->ssu->introducers.push_back (introducer); + m_ReachableTransports |= (addr->IsV4 () ? eSSUV4 : eSSUV6); return true; } } @@ -877,6 +886,8 @@ namespace data if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e) { addr->ssu->introducers.erase (it); + if (addr->ssu->introducers.empty ()) + m_ReachableTransports &= ~(addr->IsV4 () ? eSSUV4 : eSSUV6); return true; } } @@ -1184,5 +1195,31 @@ namespace data } } } + + void RouterInfo::UpdateSupportedTransports () + { + m_SupportedTransports = 0; + m_ReachableTransports = 0; + for (const auto& addr: *m_Addresses) + { + uint8_t transports = 0; + if (addr->transportStyle == eTransportNTCP) + { + if (addr->IsV4 ()) transports |= eNTCP2V4; + if (addr->IsV6 ()) + transports |= (i2p::util::net::IsYggdrasilAddress (addr->host) ? eNTCP2V6Mesh : eNTCP2V6); + if (addr->IsPublishedNTCP2 ()) + m_ReachableTransports |= transports; + } + else if (addr->transportStyle == eTransportSSU) + { + if (addr->IsV4 ()) transports |= eSSUV4; + if (addr->IsV6 ()) transports |= eSSUV6; + if (addr->IsReachableSSU ()) + m_ReachableTransports |= transports; + } + m_SupportedTransports |= transports; + } + } } } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index dd3e7e13..bea83fda 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -59,7 +59,7 @@ namespace data { public: - enum SupportedTranports + enum SupportedTransports { eNTCP2V4 = 0x01, eNTCP2V6 = 0x02, @@ -147,7 +147,7 @@ namespace data bool IsNTCP2 () const { return (bool)ntcp2; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; }; - bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); }; + bool IsReachableSSU () const { return (bool)ssu && (published || !ssu->introducers.empty ()); }; bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); }; bool IsIntroducer () const { return caps & eSSUIntroducer; }; @@ -187,6 +187,7 @@ namespace data std::string GetProperty (const std::string& key) const; // called from RouterContext only void ClearProperties () { m_Properties.clear (); }; void SetUnreachableAddressesTransportCaps (uint8_t transports); // bitmask of AddressCaps + void UpdateSupportedTransports (); bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; bool IsSSU (bool v4only = true) const; @@ -269,7 +270,7 @@ namespace data boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 std::map m_Properties; bool m_IsUpdated, m_IsUnreachable; - uint8_t m_SupportedTransports, m_Caps; + uint8_t m_SupportedTransports, m_ReachableTransports, m_Caps; int m_Version; mutable std::shared_ptr m_Profile; }; From 5ce9c0f1e20079505a2549c708f6d3ac8049c88a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Jun 2021 14:45:21 -0400 Subject: [PATCH 0121/2193] build new tunnels instead slow --- libi2pd/Tunnel.h | 3 +++ libi2pd/TunnelPool.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 7e8edca7..f30eab14 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -38,6 +38,7 @@ namespace tunnel const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds const int STANDARD_NUM_RECORDS = 4; // in VariableTunnelBuild message const int MAX_NUM_RECORDS = 8; + const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds enum TunnelState { @@ -98,6 +99,8 @@ namespace tunnel bool LatencyFitsRange(uint64_t lowerbound, uint64_t upperbound) const; bool LatencyIsKnown() const { return m_Latency > 0; } + bool IsSlow () const { return LatencyIsKnown() && (int)m_Latency > HIGH_LATENCY_PER_HOP*GetNumHops (); } + protected: void PrintHops (std::stringstream& s) const; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index f2f0b4c8..b025219f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -525,7 +525,7 @@ namespace tunnel void TunnelPool::RecreateInboundTunnel (std::shared_ptr tunnel) { - if (IsExploratory ()) // always create new exploratory tunnel + if (IsExploratory () || tunnel->IsSlow ()) // always create new exploratory tunnel or if slow { CreateInboundTunnel (); return; @@ -576,7 +576,7 @@ namespace tunnel void TunnelPool::RecreateOutboundTunnel (std::shared_ptr tunnel) { - if (IsExploratory ()) // always create new exploratory tunnel + if (IsExploratory () || tunnel->IsSlow ()) // always create new exploratory tunnel or if slow { CreateOutboundTunnel (); return; From 8e3e35a36d2f4db0929a88f08bf37dc04e2b81c0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 2 Jun 2021 19:50:29 -0400 Subject: [PATCH 0122/2193] decrypt short request record --- libi2pd/I2NPProtocol.h | 3 ++ libi2pd/RouterContext.cpp | 64 ++++++++++++++++++++++++--------------- libi2pd/RouterContext.h | 5 ++- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index c9b0fc04..56afeb0e 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -100,6 +100,9 @@ namespace i2p // ECIES BuildResponseRecord const size_t ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET = 0; const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511; + + // ShortRequestRecordClearText + const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172; enum I2NPMessageType { diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 664b457c..d1f503bb 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -875,34 +875,11 @@ namespace i2p bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) { - if (!m_TunnelDecryptor) return false; if (IsECIES ()) - { - if (!m_InitialNoiseState) return false; - // m_InitialNoiseState is h = SHA256(h || hepk) - m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); - m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) - uint8_t sharedSecret[32]; - if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) - { - LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); - return false; - } - m_CurrentNoiseState->MixKey (sharedSecret); - encrypted += 32; - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, - m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK + 32, nonce, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, false)) // decrypt - { - LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); - return false; - } - m_CurrentNoiseState->MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) - return true; - } + return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); else { + if (!m_TunnelDecryptor) return false; BN_CTX * ctx = BN_CTX_new (); bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); BN_CTX_free (ctx); @@ -910,6 +887,43 @@ namespace i2p } } + bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize) + { + if (!m_InitialNoiseState || !m_TunnelDecryptor) return false; + // m_InitialNoiseState is h = SHA256(h || hepk) + m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); + m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) + uint8_t sharedSecret[32]; + if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) + { + LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); + return false; + } + m_CurrentNoiseState->MixKey (sharedSecret); + encrypted += 32; + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState->m_H, 32, + m_CurrentNoiseState->m_CK + 32, nonce, data, clearTextSize, false)) // decrypt + { + LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); + return false; + } + m_CurrentNoiseState->MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext) + return true; + } + + bool RouterContext::DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data) + { + if (IsECIES ()) + return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); + else + { + LogPrint (eLogWarning, "Router: Can't decrypt short request record on non-ECIES router"); + return false; + } + } + i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () { if (!m_StaticKeys) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ee34c2d8..10498b3b 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -97,7 +97,8 @@ namespace garlic int GetNetID () const { return m_NetID; }; void SetNetID (int netID) { m_NetID = netID; }; bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data); - + bool DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data); + void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg); @@ -164,6 +165,8 @@ namespace garlic bool Load (); void SaveKeys (); + bool DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize); + private: i2p::data::RouterInfo m_RouterInfo; From e740d5fc4fd2c56960fc3e635195a282f302459b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 4 Jun 2021 12:16:50 -0400 Subject: [PATCH 0123/2193] try to pick non-slow tunnel --- libi2pd/TunnelPool.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b025219f..f5af249a 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -172,13 +172,16 @@ namespace tunnel { if (tunnels.empty ()) return nullptr; uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0; + bool skipped = false; typename TTunnels::value_type tunnel = nullptr; for (const auto& it: tunnels) { if (it->IsEstablished () && it != excluded) { - if(HasLatencyRequirement() && it->LatencyIsKnown() && !it->LatencyFitsRange(m_MinLatency, m_MaxLatency)) { - i ++; + if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() && + !it->LatencyFitsRange(m_MinLatency, m_MaxLatency))) + { + i++; skipped = true; continue; } tunnel = it; @@ -186,7 +189,8 @@ namespace tunnel } if (i > ind && tunnel) break; } - if(HasLatencyRequirement() && !tunnel) { + if (!tunnel && skipped) + { ind = rand () % (tunnels.size ()/2 + 1), i = 0; for (const auto& it: tunnels) { From d752a83eb568c34d529e3437205393e29a7a7cfd Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 4 Jun 2021 18:28:30 -0400 Subject: [PATCH 0124/2193] handle i2cp.dontPublishLeaseSet for all destinations --- libi2pd/Destination.cpp | 13 +++++++++++-- libi2pd/Destination.h | 5 +++-- libi2pd_client/I2CP.cpp | 6 ++---- libi2pd_client/I2CP.h | 1 - 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 9962599b..7bcfe111 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -82,6 +82,14 @@ namespace client if (it != params->end ()) m_Nickname = it->second; // otherwise we set default nickname in Start when we know local address } + it = params->find (I2CP_PARAM_DONT_PUBLISH_LEASESET); + if (it != params->end ()) + { + // oveeride isPublic + bool dontpublish = false; + i2p::config::GetOption (it->second, dontpublish); + m_IsPublic = !dontpublish; + } it = params->find (I2CP_PARAM_LEASESET_TYPE); if (it != params->end ()) m_LeaseSetType = std::stoi(it->second); @@ -509,7 +517,7 @@ namespace client // schedule verification m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); } else i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msgID); @@ -592,7 +600,8 @@ namespace client // assume it successive and try to verify m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); + } } } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 40c9e9ab..6695796d 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -61,14 +61,15 @@ namespace client const char I2CP_PARAM_RATCHET_OUTBOUND_TAGS[] = "crypto.ratchet.outboundTags"; // not used yet const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; const char I2CP_PARAM_OUTBOUND_NICKNAME[] = "outbound.nickname"; + const char I2CP_PARAM_DONT_PUBLISH_LEASESET[] = "i2cp.dontPublishLeaseSet"; const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType"; const int DEFAULT_LEASESET_TYPE = 3; const char I2CP_PARAM_LEASESET_ENCRYPTION_TYPE[] = "i2cp.leaseSetEncType"; const char I2CP_PARAM_LEASESET_PRIV_KEY[] = "i2cp.leaseSetPrivKey"; // PSK decryption key, base64 const char I2CP_PARAM_LEASESET_AUTH_TYPE[] = "i2cp.leaseSetAuthType"; const char I2CP_PARAM_LEASESET_CLIENT_DH[] = "i2cp.leaseSetClient.dh"; // group of i2cp.leaseSetClient.dh.nnn - const char I2CP_PARAM_LEASESET_CLIENT_PSK[] = "i2cp.leaseSetClient.psk"; // group of i2cp.leaseSetClient.psk.nnn - + const char I2CP_PARAM_LEASESET_CLIENT_PSK[] = "i2cp.leaseSetClient.psk"; // group of i2cp.leaseSetClient.psk.nnn + // latency const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; const int DEFAULT_MIN_TUNNEL_LATENCY = 0; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index d07c6248..25a5504a 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -544,13 +544,11 @@ namespace client offset += 8; // date if (identity->Verify (buf, offset, buf + offset)) // signature { - bool isPublic = true; - if (params[I2CP_PARAM_DONT_PUBLISH_LEASESET] == "true") isPublic = false; if (!m_Destination) { m_Destination = m_Owner.IsSingleThread () ? - std::make_shared(m_Owner.GetService (), shared_from_this (), identity, isPublic, params): - std::make_shared(shared_from_this (), identity, isPublic, params); + std::make_shared(m_Owner.GetService (), shared_from_this (), identity, true, params): + std::make_shared(shared_from_this (), identity, true, params); SendSessionStatusMessage (1); // created LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " created"); m_Destination->Start (); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 085bf30a..9a8bda4e 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -62,7 +62,6 @@ namespace client }; // params - const char I2CP_PARAM_DONT_PUBLISH_LEASESET[] = "i2cp.dontPublishLeaseSet"; const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; class I2CPSession; From 5fb426b33612d983d3cb78f2e503e1c12d226512 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 6 Jun 2021 13:55:38 -0400 Subject: [PATCH 0125/2193] decrypt and encrypt reply for short tunnel build message --- libi2pd/I2NPProtocol.cpp | 73 +++++++++++++++++++++++++++++++++++++--- libi2pd/I2NPProtocol.h | 8 +++-- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 7f059d72..e47c9add 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -458,7 +458,7 @@ namespace i2p LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records"); if (len < num*TUNNEL_BUILD_RECORD_SIZE + 1) { - LogPrint (eLogError, "VaribleTunnelBuild message of ", num, " records is too short ", len); + LogPrint (eLogError, "I2NP: VaribleTunnelBuild message of ", num, " records is too short ", len); return; } @@ -526,12 +526,12 @@ namespace i2p { if (i2p::context.IsECIES ()) { - LogPrint (eLogWarning, "TunnelBuild is too old for ECIES router"); + LogPrint (eLogWarning, "I2NP: TunnelBuild is too old for ECIES router"); return; } if (len < NUM_TUNNEL_BUILD_RECORDS*TUNNEL_BUILD_RECORD_SIZE) { - LogPrint (eLogError, "TunnelBuild message is too short ", len); + LogPrint (eLogError, "I2NP: TunnelBuild message is too short ", len); return; } uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; @@ -558,7 +558,7 @@ namespace i2p LogPrint (eLogDebug, "I2NP: VariableTunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID); if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1) { - LogPrint (eLogError, "VaribleTunnelBuildReply message of ", num, " records is too short ", len); + LogPrint (eLogError, "I2NP: VaribleTunnelBuildReply message of ", num, " records is too short ", len); return; } @@ -582,7 +582,66 @@ namespace i2p LogPrint (eLogWarning, "I2NP: Pending tunnel for message ", replyMsgID, " not found"); } - + void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + { + if (!i2p::context.IsECIES ()) + { + LogPrint (eLogWarning, "I2NP: ShortTunnelBuild can be handled by ECIES router only"); + return; + } + int num = buf[0]; + LogPrint (eLogDebug, "I2NP: ShortTunnelBuild ", num, " records"); + if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1) + { + LogPrint (eLogError, "I2NP: ShortTunnelBuild message of ", num, " records is too short ", len); + return; + } + // TODO: check replyMsgID + const uint8_t * record = buf + 1; + for (int i = 0; i < num; i++) + { + if (!memcmp (record, (const uint8_t *)i2p::context.GetRouterInfo ().GetIdentHash (), 16)) + { + LogPrint (eLogDebug, "I2NP: Short request record ", i, " is ours"); + uint8_t clearText[SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + if (!i2p::context.DecryptTunnelShortRequestRecord (record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) + { + LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i); + return; + } + // TODO: fill reply + // encrypt reply + auto noiseState = std::move (i2p::context.GetCurrentNoiseState ()); + if (!noiseState) + { + LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption"); + return; + } + uint8_t nonce[12]; + memset (nonce, 0, 12); + uint8_t * reply = buf + 1; + for (int j = 0; j < num; j++) + { + if (j == i) + { + if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, + noiseState->m_H, 32, noiseState->m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt + { + LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); + return; + } + } + else + i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply); + reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + // TODO: send + return; + } + record += SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + } + std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf) { auto msg = NewI2NPTunnelMessage (); @@ -700,6 +759,9 @@ namespace i2p case eI2NPVariableTunnelBuildReply: HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; + case eI2NPShortTunnelBuild: + HandleShortTunnelBuildMsg (msgID, buf, size); + break; case eI2NPTunnelBuild: HandleTunnelBuildMsg (buf, size); break; @@ -756,6 +818,7 @@ namespace i2p case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: + case eI2NPShortTunnelBuild: // forward to tunnel thread i2p::tunnel::tunnels.PostTunnelData (msg); break; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 56afeb0e..5db93978 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -55,7 +55,8 @@ namespace i2p // TunnelBuild const size_t TUNNEL_BUILD_RECORD_SIZE = 528; - + const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 236; + //BuildRequestRecordClearText const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; const size_t BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET = BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; @@ -102,6 +103,7 @@ namespace i2p const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511; // ShortRequestRecordClearText + const size_t SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET = 16; const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172; enum I2NPMessageType @@ -118,7 +120,8 @@ namespace i2p eI2NPTunnelBuild = 21, eI2NPTunnelBuildReply = 22, eI2NPVariableTunnelBuild = 23, - eI2NPVariableTunnelBuildReply = 24 + eI2NPVariableTunnelBuildReply = 24, + eI2NPShortTunnelBuild = 25 }; const int NUM_TUNNEL_BUILD_RECORDS = 8; @@ -287,6 +290,7 @@ namespace tunnel bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText); void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); + void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); void HandleTunnelBuildMsg (uint8_t * buf, size_t len); std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf); From 48d9a03aa894169aab777917a9f8b7bace87909c Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Mon, 7 Jun 2021 12:58:57 -0400 Subject: [PATCH 0126/2193] tbytes in WinApp --- Win32/Win32App.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index db5a1f3d..133b57b6 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -132,7 +132,11 @@ namespace win32 auto mbytes = transfer & 0x03ff; transfer >>= 10; auto gbytes = transfer & 0x03ff; + transfer >>= 10; + auto tbytes = transfer & 0x03ff; + if (tbytes) + s << tbytes << " TB, "; if (gbytes) s << gbytes << " GB, "; if (mbytes) From 857183048513220dc6c29751b094eeb7a193758f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 7 Jun 2021 18:28:36 -0400 Subject: [PATCH 0127/2193] create transit tunnel and reply for short tunnel build --- libi2pd/I2NPProtocol.cpp | 20 +++++++++++++++++--- libi2pd/I2NPProtocol.h | 9 +++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index e47c9add..760bdf59 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -424,7 +424,7 @@ namespace i2p { uint8_t nonce[12]; memset (nonce, 0, 12); - auto noiseState = std::move (i2p::context.GetCurrentNoiseState ()); + auto& noiseState = i2p::context.GetCurrentNoiseState (); if (!noiseState || !i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16, noiseState->m_H, 32, noiseState->m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { @@ -609,9 +609,19 @@ namespace i2p LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i); return; } + auto& noiseState = i2p::context.GetCurrentNoiseState (); + uint8_t layerKeys[64]; // (layer key, iv key) + i2p::crypto::HKDF (noiseState->m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain + auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( + bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), + clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, + bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + layerKeys, layerKeys + 32, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & 0x80, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & 0x40); + i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); // TODO: fill reply // encrypt reply - auto noiseState = std::move (i2p::context.GetCurrentNoiseState ()); if (!noiseState) { LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption"); @@ -622,6 +632,7 @@ namespace i2p uint8_t * reply = buf + 1; for (int j = 0; j < num; j++) { + nonce[4] = j; // nonce is record # if (j == i) { if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, @@ -635,7 +646,10 @@ namespace i2p i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply); reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } - // TODO: send + // TODO: send reply + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, + CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, + bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); return; } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 5db93978..76030e91 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -104,6 +104,15 @@ namespace i2p // ShortRequestRecordClearText const size_t SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET = 16; + const size_t SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; + const size_t SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; + const size_t SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET = SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4; + const size_t SHORT_REQUEST_RECORD_FLAG_OFFSET = SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32; + const size_t SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET = SHORT_REQUEST_RECORD_FLAG_OFFSET + 1; + const size_t SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE = SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET + 2; + const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1; + const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; + const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172; enum I2NPMessageType From d599502b1a31c45095e545f84de4f90c3fc88a4a Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Mon, 7 Jun 2021 23:49:56 -0400 Subject: [PATCH 0128/2193] 1000Gb+ display --- Win32/Win32App.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 133b57b6..7104ec7f 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -131,12 +131,8 @@ namespace win32 transfer >>= 10; auto mbytes = transfer & 0x03ff; transfer >>= 10; - auto gbytes = transfer & 0x03ff; - transfer >>= 10; - auto tbytes = transfer & 0x03ff; + auto gbytes = transfer; - if (tbytes) - s << tbytes << " TB, "; if (gbytes) s << gbytes << " GB, "; if (mbytes) From 8e4781b0f7d82f2e048d0334a5069e2d8b3ff3f0 Mon Sep 17 00:00:00 2001 From: acetone <63557806+acetoneRu@users.noreply.github.com> Date: Tue, 8 Jun 2021 09:39:28 -0400 Subject: [PATCH 0129/2193] tbytes in WinApp (#1660) --- Win32/Win32App.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index db5a1f3d..7104ec7f 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -131,7 +131,7 @@ namespace win32 transfer >>= 10; auto mbytes = transfer & 0x03ff; transfer >>= 10; - auto gbytes = transfer & 0x03ff; + auto gbytes = transfer; if (gbytes) s << gbytes << " GB, "; From 3b051dbba34bcfd3c985ef93e194c1cfc586a270 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 8 Jun 2021 15:36:27 -0400 Subject: [PATCH 0130/2193] send OutboundTunnelBuildReply --- libi2pd/I2NPProtocol.cpp | 114 ++++++++++++++++++++++++++------------- libi2pd/I2NPProtocol.h | 7 ++- libi2pd/TunnelConfig.cpp | 6 +-- 3 files changed, 84 insertions(+), 43 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 760bdf59..5ed875c5 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -18,6 +18,7 @@ #include "Tunnel.h" #include "Transports.h" #include "Garlic.h" +#include "ECIESX25519AEADRatchetSession.h" #include "I2NPProtocol.h" #include "version.h" @@ -387,16 +388,16 @@ namespace i2p bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, - clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80, - clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) : + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) : i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40); + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); } else @@ -486,7 +487,7 @@ namespace i2p uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (HandleBuildRequestRecords (num, buf + 1, clearText)) { - if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outboud tunnel + if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel { // so we send it to reply tunnel transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -505,7 +506,7 @@ namespace i2p uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (HandleBuildRequestRecords (num, buf + 1, clearText)) { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outboud tunnel + if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel { // so we send it to reply tunnel transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -537,7 +538,7 @@ namespace i2p uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, buf, clearText)) { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outbound tunnel + if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outbound tunnel { // so we send it to reply tunnel transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -610,6 +611,11 @@ namespace i2p return; } auto& noiseState = i2p::context.GetCurrentNoiseState (); + if (!noiseState) + { + LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption"); + return; + } uint8_t layerKeys[64]; // (layer key, iv key) i2p::crypto::HKDF (noiseState->m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( @@ -617,39 +623,71 @@ namespace i2p clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), layerKeys, layerKeys + 32, - clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & 0x80, - clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & 0x40); + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - // TODO: fill reply - // encrypt reply - if (!noiseState) - { - LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption"); - return; - } - uint8_t nonce[12]; - memset (nonce, 0, 12); - uint8_t * reply = buf + 1; - for (int j = 0; j < num; j++) - { - nonce[4] = j; // nonce is record # - if (j == i) + if (clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) + { + // we are endpoint, create OutboundTunnelBuildReply + auto otbrm = NewI2NPShortMessage (); + auto payload = otbrm->GetPayload (); + payload[0] = num; // num + payload[1] = i; // slot + payload +=2; + // reply + htobe16buf (payload, 3); payload += 2; // length, TODO + memset (payload, 0, 3); payload += 3; // ClearText: no options, and zero ret code. TODO + // ShortBuildReplyRecords. Exclude ours + uint8_t * records = buf + 1; + if (i > 0) + { + memcpy (payload, records, i*SHORT_TUNNEL_BUILD_RECORD_SIZE); + payload += i*SHORT_TUNNEL_BUILD_RECORD_SIZE; + records += i*SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + if (i < num-1) { - if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState->m_H, 32, noiseState->m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt - { - LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); - return; - } - } - else - i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply); - reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + memcpy (payload, records, (num-1-i)*SHORT_TUNNEL_BUILD_RECORD_SIZE); + payload += (num-1-i)*SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + otbrm->len += (payload - otbrm->GetPayload ()); + otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); + uint8_t replyKeys[64]; // (reply key, tag) + i2p::crypto::HKDF (noiseState->m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain + uint64_t tag; + memcpy (&tag, replyKeys + 32, 8); + // send garlic to reply tunnel + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, replyKeys, tag))); } - // TODO: send reply - transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, - CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, - bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + else + { + // we are participant, encrypt reply + uint8_t nonce[12]; + memset (nonce, 0, 12); + uint8_t * reply = buf + 1; + for (int j = 0; j < num; j++) + { + nonce[4] = j; // nonce is record # + if (j == i) + { + // TODO: fill reply + if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, + noiseState->m_H, 32, noiseState->m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt + { + LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); + return; + } + } + else + i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply); + reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, + CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, + bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + } return; } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 76030e91..ee143734 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -130,9 +130,12 @@ namespace i2p eI2NPTunnelBuildReply = 22, eI2NPVariableTunnelBuild = 23, eI2NPVariableTunnelBuildReply = 24, - eI2NPShortTunnelBuild = 25 + eI2NPShortTunnelBuild = 25, + eI2NPOutboundTunnelBuildReply = 26 }; + const uint8_t TUNNEL_BUILD_RECORD_GATEWAY_FLAG = 0x80; + const uint8_t TUNNEL_BUILD_RECORD_ENDPOINT_FLAG = 0x40; const int NUM_TUNNEL_BUILD_RECORDS = 8; // DatabaseLookup flags diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index d43483c0..8f515c5d 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -81,8 +81,8 @@ namespace tunnel void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { uint8_t flag = 0; - if (isGateway) flag |= 0x80; - if (isEndpoint) flag |= 0x40; + if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; + if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; auto encryptor = ident->CreateEncryptor (nullptr); if (IsECIES ()) { From ed53cbb7b7b544e7c593b9d2bde8d5159fdd36bd Mon Sep 17 00:00:00 2001 From: idk Date: Tue, 8 Jun 2021 16:25:45 -0400 Subject: [PATCH 0131/2193] OK that's my first working C wrapper, but I don't yet know how to do anything other than initialize, start, and stop a router --- libi2pd/capi.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ libi2pd/capi.h | 43 ++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 libi2pd/capi.cpp create mode 100644 libi2pd/capi.h diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp new file mode 100644 index 00000000..1decb717 --- /dev/null +++ b/libi2pd/capi.cpp @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include "capi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void C_InitI2P (int argc, char* argv[], const char * appName) +{ + return i2p::api::InitI2P(argc, argv, appName); +} + +void C_TerminateI2P () +{ + return i2p::api::TerminateI2P(); +} + +void C_StartI2P (std::shared_ptr logStream) +{ + return i2p::api::StartI2P(logStream); +} + +void C_StopI2P () +{ + return i2p::api::StopI2P(); +} + +void C_RunPeerTest () +{ + return i2p::api::RunPeerTest(); +} + +std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, + const std::map * params) +{ + return i2p::api::CreateLocalDestination(keys, isPublic, params); +} + +std::shared_ptr C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, + const std::map * params) +{ + return i2p::api::CreateLocalDestination(isPublic, sigType, params); +} + +void C_DestroyLocalDestination (std::shared_ptr dest) +{ + return i2p::api::DestroyLocalDestination(dest); +} + +void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote) +{ + return i2p::api::RequestLeaseSet(dest, remote); +} + +std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote) +{ + return i2p::api::CreateStream(dest, remote); +} + +void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) +{ + return i2p::api::AcceptStream(dest, acceptor); +} + +void C_DestroyStream (std::shared_ptr stream) +{ + return i2p::api::DestroyStream(stream); +} + +#ifdef __cplusplus +} +#endif + diff --git a/libi2pd/capi.h b/libi2pd/capi.h new file mode 100644 index 00000000..70b9228e --- /dev/null +++ b/libi2pd/capi.h @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef CAPI_H__ +#define CAPI_H__ + +#include "api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// initialization start and stop +void C_InitI2P (int argc, char* argv[], const char * appName); +void C_TerminateI2P (); +void C_StartI2P (std::shared_ptr logStream = nullptr); +// write system log to logStream, if not specified to .log in application's folder +void C_StopI2P (); +void C_RunPeerTest (); // should be called after UPnP + +// destinations +std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, + const std::map * params = nullptr); +std::shared_ptr C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, + const std::map * params = nullptr); // transient destinations usually not published +void C_DestroyLocalDestination (std::shared_ptr dest); + +// streams +void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote); +std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote); +void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); +void C_DestroyStream (std::shared_ptr stream); + +#ifdef __cplusplus +} +#endif + +#endif From 83fd289e4651b4e23c2ebc7b7a58222b5fbcf9b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 9 Jun 2021 12:49:50 -0400 Subject: [PATCH 0132/2193] don't re-create noise state for every message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 +++++---- libi2pd/ECIESX25519AEADRatchetSession.h | 5 +++++ libi2pd/I2NPProtocol.cpp | 17 ++++++----------- libi2pd/RouterContext.cpp | 19 ++++++++----------- libi2pd/RouterContext.h | 4 ++-- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 45affde7..55e962d8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1109,21 +1109,22 @@ namespace garlic bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len) { if (!GetOwner ()) return false; - i2p::crypto::NoiseSymmetricState state (GetNoiseState ()); + m_CurrentNoiseState = GetNoiseState (); // we are Bob - state.MixHash (buf, 32); + m_CurrentNoiseState.MixHash (buf, 32); uint8_t sharedSecret[32]; if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) { LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key"); return false; } - state.MixKey (sharedSecret); + m_CurrentNoiseState.MixKey (sharedSecret); buf += 32; len -= 32; uint8_t nonce[12]; CreateNonce (0, nonce); std::vector payload (len - 16); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, state.m_H, 32, state.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_CurrentNoiseState.m_H, 32, + m_CurrentNoiseState.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload for router AEAD verification failed"); return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 43e88ca6..cd7b9b40 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -249,6 +249,11 @@ namespace garlic RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState); bool HandleNextMessage (const uint8_t * buf, size_t len); + i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; }; + + private: + + i2p::crypto::NoiseSymmetricState m_CurrentNoiseState; }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5ed875c5..7c4d84c3 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -426,8 +426,8 @@ namespace i2p uint8_t nonce[12]; memset (nonce, 0, 12); auto& noiseState = i2p::context.GetCurrentNoiseState (); - if (!noiseState || !i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState->m_H, 32, noiseState->m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16, + noiseState.m_H, 32, noiseState.m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); return false; @@ -611,13 +611,8 @@ namespace i2p return; } auto& noiseState = i2p::context.GetCurrentNoiseState (); - if (!noiseState) - { - LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption"); - return; - } uint8_t layerKeys[64]; // (layer key, iv key) - i2p::crypto::HKDF (noiseState->m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain + i2p::crypto::HKDF (noiseState.m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -653,7 +648,7 @@ namespace i2p otbrm->len += (payload - otbrm->GetPayload ()); otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); uint8_t replyKeys[64]; // (reply key, tag) - i2p::crypto::HKDF (noiseState->m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain uint64_t tag; memcpy (&tag, replyKeys + 32, 8); // send garlic to reply tunnel @@ -674,14 +669,14 @@ namespace i2p { // TODO: fill reply if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState->m_H, 32, noiseState->m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt + noiseState.m_H, 32, noiseState.m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); return; } } else - i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply); + i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply); reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index d1f503bb..78be6305 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -45,10 +45,8 @@ namespace i2p UpdateRouterInfo (); if (IsECIES ()) { - auto initState = new i2p::crypto::NoiseSymmetricState (); - i2p::crypto::InitNoiseNState (*initState, GetIdentity ()->GetEncryptionPublicKey ()); - m_InitialNoiseState.reset (initState); - m_ECIESSession = std::make_shared(*initState); + i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ()); + m_ECIESSession = std::make_shared(m_InitialNoiseState); } } @@ -889,27 +887,26 @@ namespace i2p bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize) { - if (!m_InitialNoiseState || !m_TunnelDecryptor) return false; // m_InitialNoiseState is h = SHA256(h || hepk) - m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); - m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) + m_CurrentNoiseState = m_InitialNoiseState; + m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; } - m_CurrentNoiseState->MixKey (sharedSecret); + m_CurrentNoiseState.MixKey (sharedSecret); encrypted += 32; uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState->m_H, 32, - m_CurrentNoiseState->m_CK + 32, nonce, data, clearTextSize, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState.m_H, 32, + m_CurrentNoiseState.m_CK + 32, nonce, data, clearTextSize, false)) // decrypt { LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); return false; } - m_CurrentNoiseState->MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext) + m_CurrentNoiseState.MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext) return true; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 10498b3b..acb33795 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -125,7 +125,7 @@ namespace garlic void SetSupportsV4 (bool supportsV4); void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host); bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; - std::unique_ptr& GetCurrentNoiseState () { return m_CurrentNoiseState; }; + i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; }; void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove void UpdateStats (); @@ -185,7 +185,7 @@ namespace garlic std::unique_ptr m_NTCP2Keys; std::unique_ptr m_StaticKeys; // for ECIESx25519 - std::unique_ptr m_InitialNoiseState, m_CurrentNoiseState; + i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; // i18n std::shared_ptr m_Language; From 8708a0076f34c25cd9ffd03eb341d055f8e1b45e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 9 Jun 2021 22:22:57 +0300 Subject: [PATCH 0133/2193] fix build with boost < 1.55.0 (closes #1661) Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 4 ++++ libi2pd/SSU.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 72e822cd..c231863d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1201,7 +1201,11 @@ namespace transport if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address { // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others +#if (BOOST_VERSION >= 105500) typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; +#else + typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; +#endif m_NTCP2V6Acceptor->set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA)); } #endif diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index e4901f7c..f3da611c 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -70,7 +70,11 @@ namespace transport if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address { // Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others +#if (BOOST_VERSION >= 105500) typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; +#else + typedef boost::asio::detail::socket_option::integer ipv6PreferAddr; +#endif m_SocketV6.set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA)); } #endif From a92b93192d843c63f19618c5ad39bd71bba89e31 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Jun 2021 13:24:04 -0400 Subject: [PATCH 0134/2193] reg.i2p for subscriptions --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index f5316860..a80778a1 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -221,7 +221,7 @@ namespace config { ("addressbook.defaulturl", value()->default_value( "http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt" ), "AddressBook subscription URL for initial setup") - ("addressbook.subscriptions", value()->default_value(""), "AddressBook subscriptions URLs, separated by comma") + ("addressbook.subscriptions", value()->default_value("http://reg.i2p/hosts.txt"), "AddressBook subscriptions URLs, separated by comma") ("addressbook.hostsfile", value()->default_value(""), "File to dump addresses in hosts.txt format"); options_description trust("Trust options"); From e412b17f709af249ffa20a08cb111090631e8d0e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 11 Jun 2021 08:34:56 -0400 Subject: [PATCH 0135/2193] don't publish slow tunnel in LeaseSet if possible --- libi2pd/TunnelPool.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index f5af249a..e45c6090 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -142,16 +142,24 @@ namespace tunnel { std::vector > v; int i = 0; + std::shared_ptr slowTunnel; std::unique_lock l(m_InboundTunnelsMutex); for (const auto& it : m_InboundTunnels) { if (i >= num) break; if (it->IsEstablished ()) { - v.push_back (it); - i++; + if (it->IsSlow () && !slowTunnel) + slowTunnel = it; + else + { + v.push_back (it); + i++; + } } } + if (slowTunnel && (int)v.size () < (num/2+1)) + v.push_back (slowTunnel); return v; } From bce6685d0cda5127ff072aeb6a701b666fcd5d49 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Jun 2021 12:36:54 -0400 Subject: [PATCH 0136/2193] correct check of ipv4/ipv6 address --- libi2pd/RouterContext.cpp | 4 ++-- libi2pd/RouterInfo.cpp | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 78be6305..50dd6c59 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -484,7 +484,7 @@ namespace i2p addr->ssu->introducers.clear (); port = addr->port; } - // unpiblish NTCP2 addreeses + // unpublish NTCP2 addreeses bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) PublishNTCP2Address (port, false, v4, v6, false); @@ -677,7 +677,7 @@ namespace i2p if (addr->IsPublishedNTCP2 ()) { bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host); - if (addr->host.is_v6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1))) + if (addr->IsV6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1))) { if (addr->host != host) { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3035bd31..dcef9463 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -554,7 +554,7 @@ namespace data if (address.IsNTCP2 ()) { WriteString ("NTCP2", s); - if (address.IsPublishedNTCP2 () && !address.host.is_unspecified ()) + if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port) isPublished = true; else { @@ -998,9 +998,16 @@ namespace data for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; - addr->caps &= ~AddressCaps::eV6; - if (addr->host.is_v6 ()) - it = m_Addresses->erase (it); + if (addr->IsV6 ()) + { + if (addr->IsV4 ()) + { + addr->caps &= ~AddressCaps::eV6; + ++it; + } + else + it = m_Addresses->erase (it); + } else ++it; } @@ -1015,9 +1022,16 @@ namespace data for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; - addr->caps &= ~AddressCaps::eV4; - if (addr->host.is_v4 ()) - it = m_Addresses->erase (it); + if (addr->IsV4 ()) + { + if (addr->IsV6 ()) + { + addr->caps &= ~AddressCaps::eV4; + ++it; + } + else + it = m_Addresses->erase (it); + } else ++it; } @@ -1188,7 +1202,7 @@ namespace data for (auto& addr: *m_Addresses) { // TODO: implement SSU - if (addr->transportStyle == eTransportNTCP && (!addr->IsPublishedNTCP2 () || addr->port)) + if (addr->transportStyle == eTransportNTCP && !addr->IsPublishedNTCP2 ()) { addr->caps &= ~(eV4 | eV6); addr->caps |= transports; From 631c8c9870bf48b9a4ff7f57daf82ae28c783251 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Jun 2021 21:19:44 -0400 Subject: [PATCH 0137/2193] use correct address type for NTCP2 acceptors --- libi2pd/NTCP2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index c231863d..cb200b42 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1170,7 +1170,7 @@ namespace transport if (!address) continue; if (address->IsPublishedNTCP2 () && address->port) { - if (address->host.is_v4()) + if (address->IsV4()) { try { @@ -1189,7 +1189,7 @@ namespace transport auto conn = std::make_shared(*this); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } - else if (address->host.is_v6() && (context.SupportsV6 () || context.SupportsMesh ())) + else if (address->IsV6() && (context.SupportsV6 () || context.SupportsMesh ())) { m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ())); try From 1d973bc3aca52e2aab02876fa6d851911c522d15 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 15 Jun 2021 17:55:09 +0300 Subject: [PATCH 0138/2193] [webconsole] remove extra line break Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index e184dd06..dadb2f8f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -691,7 +691,7 @@ namespace http { if (Daemon.gracefulShutdownInterval) s << " " << tr("Cancel graceful shutdown") << "\r\n"; else - s << " " << tr("Start graceful shutdown") << "
\r\n"; + s << " " << tr("Start graceful shutdown") << "\r\n"; #elif defined(WIN32_APP) if (i2p::util::DaemonWin32::Instance().isGraceful) s << " " << tr("Cancel graceful shutdown") << "\r\n"; From b962a330ad863d7c5a8cbbdb7ab156902e8dc7d1 Mon Sep 17 00:00:00 2001 From: idk Date: Tue, 15 Jun 2021 12:02:57 -0400 Subject: [PATCH 0139/2193] Allow passing raw pointers to C wrapper functions, I think --- Makefile | 5 +++++ libi2pd/Destination.h | 8 ++++++++ libi2pd/capi.cpp | 38 ++++++++++++++++++++++---------------- libi2pd/capi.h | 17 +++++++++-------- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 40e72918..7a033bf2 100644 --- a/Makefile +++ b/Makefile @@ -136,3 +136,8 @@ doxygen: .PHONY: mk_obj_dir .PHONY: install .PHONY: strip + +##TODO: delete this before a PR +testc: api api_client + g++ -Ii18n -c test.c -o test.o + g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 6695796d..f24e31ca 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -28,6 +28,10 @@ #include "Datagram.h" #include "util.h" +#ifdef __cplusplus +extern "C" { +#endif + namespace i2p { namespace client @@ -312,4 +316,8 @@ namespace client } } +#ifdef __cplusplus +} +#endif + #endif diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index 1decb717..b1f94d1f 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -22,9 +22,10 @@ void C_TerminateI2P () return i2p::api::TerminateI2P(); } -void C_StartI2P (std::shared_ptr logStream) +void C_StartI2P (std::ostream *logStream) { - return i2p::api::StartI2P(logStream); + std::shared_ptr cppLogStream(logStream); + return i2p::api::StartI2P(cppLogStream); } void C_StopI2P () @@ -37,41 +38,46 @@ void C_RunPeerTest () return i2p::api::RunPeerTest(); } -std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, +i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params) { - return i2p::api::CreateLocalDestination(keys, isPublic, params); + return i2p::api::CreateLocalDestination(keys, isPublic, params).get(); } -std::shared_ptr C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, +i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, const std::map * params) { - return i2p::api::CreateLocalDestination(isPublic, sigType, params); + return i2p::api::CreateLocalDestination(isPublic, sigType, params).get(); } -void C_DestroyLocalDestination (std::shared_ptr dest) +void C_DestroyLocalDestination (i2p::client::ClientDestination *dest) { - return i2p::api::DestroyLocalDestination(dest); + std::shared_ptr cppDest(dest); + return i2p::api::DestroyLocalDestination(cppDest); } -void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote) +void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) { - return i2p::api::RequestLeaseSet(dest, remote); + std::shared_ptr cppDest(dest); + return i2p::api::RequestLeaseSet(cppDest, remote); } -std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote) +i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) { - return i2p::api::CreateStream(dest, remote); + std::shared_ptr cppDest(dest); + return i2p::api::CreateStream(cppDest, remote).get(); } -void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) +void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) { - return i2p::api::AcceptStream(dest, acceptor); + std::shared_ptr cppDest(dest); + return i2p::api::AcceptStream(cppDest, acceptor); } -void C_DestroyStream (std::shared_ptr stream) +void C_DestroyStream (i2p::stream::Stream *stream) { - return i2p::api::DestroyStream(stream); + std::shared_ptr cppStream(stream); + return i2p::api::DestroyStream(cppStream); } #ifdef __cplusplus diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 70b9228e..341cf39e 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -11,6 +11,7 @@ #include "api.h" + #ifdef __cplusplus extern "C" { #endif @@ -18,23 +19,23 @@ extern "C" { // initialization start and stop void C_InitI2P (int argc, char* argv[], const char * appName); void C_TerminateI2P (); -void C_StartI2P (std::shared_ptr logStream = nullptr); +void C_StartI2P (std::ostream *logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP // destinations -std::shared_ptr C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, +i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); -std::shared_ptr C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, +i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, const std::map * params = nullptr); // transient destinations usually not published -void C_DestroyLocalDestination (std::shared_ptr dest); +void C_DestroyLocalDestination (i2p::client::ClientDestination *dest); // streams -void C_RequestLeaseSet (std::shared_ptr dest, const i2p::data::IdentHash& remote); -std::shared_ptr C_CreateStream (std::shared_ptr dest, const i2p::data::IdentHash& remote); -void C_AcceptStream (std::shared_ptr dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); -void C_DestroyStream (std::shared_ptr stream); +void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); +i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); +void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); +void C_DestroyStream (i2p::stream::Stream *stream); #ifdef __cplusplus } From 29c1173e148da874755052a0d4d9606465dc5e25 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 15 Jun 2021 23:22:11 +0300 Subject: [PATCH 0140/2193] [i18n] fixes in translations Signed-off-by: R4SAS --- i18n/Turkmen.cpp | 15 +++++++-------- i18n/Ukrainian.cpp | 11 +++++------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 93bd92fe..0edc9a6e 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -61,7 +61,7 @@ namespace turkmen // language {"failed to send request to upstream", "öý eýesi proksi üçin haýyş iberip bilmedi"}, {"No Reply From socks proxy", "Jorap proksi serwerinden hiç hili jogap ýok"}, {"cannot connect", "birikdirip bilmedi"}, - {"http out proxy not implemented", "daşarky http proksi serwerini goldamak amala aşyrylmaýar"}, + {"http out proxy not implemented", "daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"}, {"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"}, {"Host is down", "Salgy elýeterli däl"}, {"Can't create connection to requested host, it may be down. Please try again later.", @@ -89,7 +89,7 @@ namespace turkmen // language {"Local destinations", "Ýerli ýerler"}, {"LeaseSets", "Lizset"}, {"Tunnels", "Tuneller"}, - {"Transit tunnels", "Tranzit Tunels"}, + {"Transit tunnels", "Tranzit tunels"}, {"Transports", "Daşamak"}, {"I2P tunnels", "I2P tuneller"}, {"SAM sessions", "SAM Sessiýasy"}, @@ -108,7 +108,7 @@ namespace turkmen // language {"Uptime", "Onlaýn onlaýn sözlügi"}, {"Network status", "Tor ýagdaýy"}, {"Network status v6", "Tor ýagdaýy v6"}, - {"Stopping in", "soň duruň"}, + {"Stopping in", "Soň duruň"}, {"Family", "Maşgala"}, {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, {"Received", "Alnan"}, @@ -122,10 +122,9 @@ namespace turkmen // language {"Router Caps", "Baýdaklar marşruteri"}, {"Version", "Wersiýasy"}, {"Our external address", "Daşarky salgymyz"}, - {"supported", "Goldanýar"}, + {"supported", "goldanýar"}, {"Routers", "Marşrutizatorlar"}, {"Floodfills", "Fludfillar"}, - {"LeaseSets", "Lizsetllar"}, {"Client Tunnels", "Müşderi tunelleri"}, {"Transit Tunnels", "Tranzit Tunelleri"}, {"Services", "Hyzmatlar"}, @@ -150,7 +149,7 @@ namespace turkmen // language {"Destination", "Maksat"}, {"Amount", "Sany"}, {"Incoming Tags", "Gelýän bellikler"}, - {"Tags sessions", "Sapaklar Tag."}, + {"Tags sessions", "Sapaklar bellikler"}, {"Status", "Ýagdaýy"}, // ShowLocalDestination {"Local Destination", "Ýerli maksat"}, @@ -178,7 +177,7 @@ namespace turkmen // language {"Start graceful shutdown", "Tekiz durmak"}, {"Force shutdown", "Mejbury duralga"}, {"Note: any action done here are not persistent and not changes your config files.", - "Bellik: Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär.."}, + "Bellik: Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär."}, {"Logging level", "Giriş derejesi"}, {"Transit tunnels limit", "Tranzit tunelleriniň çägi"}, {"Change", "Üýtgetmek"}, @@ -217,7 +216,7 @@ namespace turkmen // language {"Description", "Beýany"}, {"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"}, {"Submit", "Iber"}, - {"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez."}, + {"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez"}, {"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"}, {"Such destination is not found", "Bu barmaly ýer tapylmady"}, {"", ""}, diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 05e7c786..11878cde 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -86,17 +86,17 @@ namespace ukrainian // language // ShowPageHead {"Main page", "Головна"}, {"Router commands", "Команди роутера"}, - {"Local destinations", "Локальні признач."}, + {"Local destinations", "Локальні призначення"}, {"LeaseSets", "Лізсети"}, {"Tunnels", "Тунелі"}, - {"Transit tunnels", "Транзит. тунелі"}, + {"Transit tunnels", "Транзитні тунелі"}, {"Transports", "Транспорти"}, {"I2P tunnels", "I2P тунелі"}, {"SAM sessions", "SAM сесії"}, // Network Status {"OK", "OK"}, {"Testing", "Тестування"}, - {"Firewalled", "Файрвол"}, + {"Firewalled", "Заблоковано ззовні"}, {"Unknown", "Невідомо"}, {"Proxy", "Проксі"}, {"Mesh", "MESH-мережа"}, @@ -125,7 +125,6 @@ namespace ukrainian // language {"supported", "підтримується"}, {"Routers", "Роутери"}, {"Floodfills", "Флудфіли"}, - {"LeaseSets", "Лізсети"}, {"Client Tunnels", "Клієнтські Тунелі"}, {"Transit Tunnels", "Транзитні Тунелі"}, {"Services", "Сервіси"}, @@ -153,7 +152,7 @@ namespace ukrainian // language {"Tags sessions", "Сесії тегів"}, {"Status", "Статус"}, // ShowLocalDestination - {"Local Destination", "Локальне Призначення"}, + {"Local Destination", "Локальні Призначення"}, {"Streams", "Потоки"}, {"Close stream", "Закрити потік"}, // ShowI2CPLocalDestination @@ -197,7 +196,7 @@ namespace ukrainian // language {"Unknown page", "Невідома сторінка"}, // HandleCommand, ShowError {"Invalid token", "Невірний токен"}, - {"SUCCESS", "ВДАЛО"}, + {"SUCCESS", "УСПІШНО"}, {"ERROR", "ПОМИЛКА"}, {"Unknown command", "Невідома команда"}, {"Command accepted", "Команда прийнята"}, From eebea7b342e607f312b5d832e16c0ab08eeb38eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 15 Jun 2021 23:22:59 +0300 Subject: [PATCH 0141/2193] [i18n] Add translation source in gettext format Signed-off-by: R4SAS --- i18n/English.po | 741 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 741 insertions(+) create mode 100644 i18n/English.po diff --git a/i18n/English.po b/i18n/English.po new file mode 100644 index 00000000..e9317528 --- /dev/null +++ b/i18n/English.po @@ -0,0 +1,741 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: i2pd\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-06-15 20:41+0300\n" +"PO-Revision-Date: 2021-06-15 20:42+0300\n" +"Last-Translator: \n" +"Language-Team: PurpleI2P\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"X-Generator: Poedit 3.0\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-KeywordsList: ;tr\n" +"X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" +"X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" + +#: daemon/HTTPServer.cpp:85 +msgid "Disabled" +msgstr "" + +#: daemon/HTTPServer.cpp:86 +msgid "Enabled" +msgstr "" + +#: daemon/HTTPServer.cpp:141 +msgid "days" +msgid_plural "days" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: daemon/HTTPServer.cpp:145 +msgid "hours" +msgid_plural "hours" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: daemon/HTTPServer.cpp:149 +msgid "minutes" +msgid_plural "minutes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: daemon/HTTPServer.cpp:152 +msgid "seconds" +msgid_plural "seconds" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188 +msgid "KiB" +msgstr "" + +#: daemon/HTTPServer.cpp:162 +msgid "MiB" +msgstr "" + +#: daemon/HTTPServer.cpp:164 +msgid "GiB" +msgstr "" + +#: daemon/HTTPServer.cpp:181 +msgid "building" +msgstr "" + +#: daemon/HTTPServer.cpp:182 +msgid "failed" +msgstr "" + +#: daemon/HTTPServer.cpp:183 +msgid "expiring" +msgstr "" + +#: daemon/HTTPServer.cpp:184 +msgid "established" +msgstr "" + +#: daemon/HTTPServer.cpp:185 +msgid "unknown" +msgstr "" + +#: daemon/HTTPServer.cpp:187 +msgid "exploratory" +msgstr "" + +#: daemon/HTTPServer.cpp:223 +msgid "i2pd webconsole" +msgstr "" + +#: daemon/HTTPServer.cpp:226 +msgid "Main page" +msgstr "" + +#: daemon/HTTPServer.cpp:227 daemon/HTTPServer.cpp:683 +msgid "Router commands" +msgstr "" + +#: daemon/HTTPServer.cpp:228 +msgid "Local destinations" +msgstr "" + +#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:382 +#: daemon/HTTPServer.cpp:463 daemon/HTTPServer.cpp:469 +#: daemon/HTTPServer.cpp:599 daemon/HTTPServer.cpp:642 +#: daemon/HTTPServer.cpp:646 +msgid "LeaseSets" +msgstr "" + +#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:652 +msgid "Tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:727 +#: daemon/HTTPServer.cpp:743 +msgid "Transit tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:792 +msgid "Transports" +msgstr "" + +#: daemon/HTTPServer.cpp:235 +msgid "I2P tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:237 daemon/HTTPServer.cpp:854 +#: daemon/HTTPServer.cpp:864 +msgid "SAM sessions" +msgstr "" + +#: daemon/HTTPServer.cpp:253 daemon/HTTPServer.cpp:1254 +#: daemon/HTTPServer.cpp:1257 daemon/HTTPServer.cpp:1260 +#: daemon/HTTPServer.cpp:1274 daemon/HTTPServer.cpp:1319 +#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1325 +msgid "ERROR" +msgstr "" + +#: daemon/HTTPServer.cpp:260 +msgid "OK" +msgstr "" + +#: daemon/HTTPServer.cpp:261 +msgid "Testing" +msgstr "" + +#: daemon/HTTPServer.cpp:262 +msgid "Firewalled" +msgstr "" + +#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:284 +#: daemon/HTTPServer.cpp:370 +msgid "Unknown" +msgstr "" + +#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:394 +#: daemon/HTTPServer.cpp:395 daemon/HTTPServer.cpp:922 +#: daemon/HTTPServer.cpp:931 +msgid "Proxy" +msgstr "" + +#: daemon/HTTPServer.cpp:265 +msgid "Mesh" +msgstr "" + +#: daemon/HTTPServer.cpp:268 +msgid "Error" +msgstr "" + +#: daemon/HTTPServer.cpp:272 +msgid "Clock skew" +msgstr "" + +#: daemon/HTTPServer.cpp:275 +msgid "Offline" +msgstr "" + +#: daemon/HTTPServer.cpp:278 +msgid "Symmetric NAT" +msgstr "" + +#: daemon/HTTPServer.cpp:290 +msgid "Uptime" +msgstr "" + +#: daemon/HTTPServer.cpp:293 +msgid "Network status" +msgstr "" + +#: daemon/HTTPServer.cpp:298 +msgid "Network status v6" +msgstr "" + +#: daemon/HTTPServer.cpp:304 daemon/HTTPServer.cpp:311 +msgid "Stopping in" +msgstr "" + +#: daemon/HTTPServer.cpp:318 +msgid "Family" +msgstr "" + +#: daemon/HTTPServer.cpp:319 +msgid "Tunnel creation success rate" +msgstr "" + +#: daemon/HTTPServer.cpp:320 +msgid "Received" +msgstr "" + +#: daemon/HTTPServer.cpp:322 daemon/HTTPServer.cpp:325 +#: daemon/HTTPServer.cpp:328 +msgid "KiB/s" +msgstr "" + +#: daemon/HTTPServer.cpp:323 +msgid "Sent" +msgstr "" + +#: daemon/HTTPServer.cpp:326 +msgid "Transit" +msgstr "" + +#: daemon/HTTPServer.cpp:329 +msgid "Data path" +msgstr "" + +#: daemon/HTTPServer.cpp:332 +msgid "Hidden content. Press on text to see." +msgstr "" + +#: daemon/HTTPServer.cpp:335 +msgid "Router Ident" +msgstr "" + +#: daemon/HTTPServer.cpp:337 +msgid "Router Family" +msgstr "" + +#: daemon/HTTPServer.cpp:338 +msgid "Router Caps" +msgstr "" + +#: daemon/HTTPServer.cpp:339 +msgid "Version" +msgstr "" + +#: daemon/HTTPServer.cpp:340 +msgid "Our external address" +msgstr "" + +#: daemon/HTTPServer.cpp:348 +msgid "supported" +msgstr "" + +#: daemon/HTTPServer.cpp:380 +msgid "Routers" +msgstr "" + +#: daemon/HTTPServer.cpp:381 +msgid "Floodfills" +msgstr "" + +#: daemon/HTTPServer.cpp:388 daemon/HTTPServer.cpp:908 +msgid "Client Tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:389 +msgid "Transit Tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:393 +msgid "Services" +msgstr "" + +#: daemon/HTTPServer.cpp:407 daemon/HTTPServer.cpp:419 +msgid "Local Destinations" +msgstr "" + +#: daemon/HTTPServer.cpp:442 +msgid "Encrypted B33 address" +msgstr "" + +#: daemon/HTTPServer.cpp:451 +msgid "Address registration line" +msgstr "" + +#: daemon/HTTPServer.cpp:456 +msgid "Domain" +msgstr "" + +#: daemon/HTTPServer.cpp:457 +msgid "Generate" +msgstr "" + +#: daemon/HTTPServer.cpp:458 +msgid "" +"Note: result string can be used only for registering 2LD domains " +"(example.i2p). For registering subdomains please use i2pd-tools." +msgstr "" + +#: daemon/HTTPServer.cpp:464 +msgid "Address" +msgstr "" + +#: daemon/HTTPServer.cpp:464 +msgid "Type" +msgstr "" + +#: daemon/HTTPServer.cpp:464 +msgid "EncType" +msgstr "" + +#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:657 +msgid "Inbound tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489 +#: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672 +msgid "ms" +msgstr "" + +#: daemon/HTTPServer.cpp:484 daemon/HTTPServer.cpp:667 +msgid "Outbound tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:496 +msgid "Tags" +msgstr "" + +#: daemon/HTTPServer.cpp:496 +msgid "Incoming" +msgstr "" + +#: daemon/HTTPServer.cpp:503 daemon/HTTPServer.cpp:506 +msgid "Outgoing" +msgstr "" + +#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:520 +msgid "Destination" +msgstr "" + +#: daemon/HTTPServer.cpp:504 +msgid "Amount" +msgstr "" + +#: daemon/HTTPServer.cpp:511 +msgid "Incoming Tags" +msgstr "" + +#: daemon/HTTPServer.cpp:519 daemon/HTTPServer.cpp:522 +msgid "Tags sessions" +msgstr "" + +#: daemon/HTTPServer.cpp:520 +msgid "Status" +msgstr "" + +#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:584 +msgid "Local Destination" +msgstr "" + +#: daemon/HTTPServer.cpp:538 daemon/HTTPServer.cpp:887 +msgid "Streams" +msgstr "" + +#: daemon/HTTPServer.cpp:560 +msgid "Close stream" +msgstr "" + +#: daemon/HTTPServer.cpp:589 +msgid "I2CP session not found" +msgstr "" + +#: daemon/HTTPServer.cpp:592 +msgid "I2CP is not enabled" +msgstr "" + +#: daemon/HTTPServer.cpp:618 +msgid "Invalid" +msgstr "" + +#: daemon/HTTPServer.cpp:621 +msgid "Store type" +msgstr "" + +#: daemon/HTTPServer.cpp:622 +msgid "Expires" +msgstr "" + +#: daemon/HTTPServer.cpp:627 +msgid "Non Expired Leases" +msgstr "" + +#: daemon/HTTPServer.cpp:630 +msgid "Gateway" +msgstr "" + +#: daemon/HTTPServer.cpp:631 +msgid "TunnelID" +msgstr "" + +#: daemon/HTTPServer.cpp:632 +msgid "EndDate" +msgstr "" + +#: daemon/HTTPServer.cpp:642 +msgid "not floodfill" +msgstr "" + +#: daemon/HTTPServer.cpp:653 +msgid "Queue size" +msgstr "" + +#: daemon/HTTPServer.cpp:684 +msgid "Run peer test" +msgstr "" + +#: daemon/HTTPServer.cpp:687 +msgid "Decline transit tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:689 +msgid "Accept transit tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:692 daemon/HTTPServer.cpp:697 +msgid "Cancel graceful shutdown" +msgstr "" + +#: daemon/HTTPServer.cpp:694 daemon/HTTPServer.cpp:699 +msgid "Start graceful shutdown" +msgstr "" + +#: daemon/HTTPServer.cpp:701 +msgid "Force shutdown" +msgstr "" + +#: daemon/HTTPServer.cpp:704 +msgid "" +"Note: any action done here are not persistent and not changes your " +"config files." +msgstr "" + +#: daemon/HTTPServer.cpp:706 +msgid "Logging level" +msgstr "" + +#: daemon/HTTPServer.cpp:714 +msgid "Transit tunnels limit" +msgstr "" + +#: daemon/HTTPServer.cpp:719 +msgid "Change" +msgstr "" + +#: daemon/HTTPServer.cpp:743 +msgid "no transit tunnels currently built" +msgstr "" + +#: daemon/HTTPServer.cpp:848 daemon/HTTPServer.cpp:871 +msgid "SAM disabled" +msgstr "" + +#: daemon/HTTPServer.cpp:864 +msgid "no sessions currently running" +msgstr "" + +#: daemon/HTTPServer.cpp:877 +msgid "SAM session not found" +msgstr "" + +#: daemon/HTTPServer.cpp:882 +msgid "SAM Session" +msgstr "" + +#: daemon/HTTPServer.cpp:939 +msgid "Server Tunnels" +msgstr "" + +#: daemon/HTTPServer.cpp:955 +msgid "Client Forwards" +msgstr "" + +#: daemon/HTTPServer.cpp:969 +msgid "Server Forwards" +msgstr "" + +#: daemon/HTTPServer.cpp:1175 +msgid "Unknown page" +msgstr "" + +#: daemon/HTTPServer.cpp:1194 +msgid "Invalid token" +msgstr "" + +#: daemon/HTTPServer.cpp:1252 daemon/HTTPServer.cpp:1309 +#: daemon/HTTPServer.cpp:1337 +msgid "SUCCESS" +msgstr "" + +#: daemon/HTTPServer.cpp:1252 +msgid "Stream closed" +msgstr "" + +#: daemon/HTTPServer.cpp:1254 +msgid "Stream not found or already was closed" +msgstr "" + +#: daemon/HTTPServer.cpp:1257 +msgid "Destination not found" +msgstr "" + +#: daemon/HTTPServer.cpp:1260 +msgid "StreamID can't be null" +msgstr "" + +#: daemon/HTTPServer.cpp:1262 daemon/HTTPServer.cpp:1327 +msgid "Return to destination page" +msgstr "" + +#: daemon/HTTPServer.cpp:1263 daemon/HTTPServer.cpp:1276 +msgid "You will be redirected back in 5 seconds" +msgstr "" + +#: daemon/HTTPServer.cpp:1274 +msgid "Transit tunnels count must not exceed 65535" +msgstr "" + +#: daemon/HTTPServer.cpp:1275 daemon/HTTPServer.cpp:1338 +msgid "Back to commands list" +msgstr "" + +#: daemon/HTTPServer.cpp:1311 +msgid "Register at reg.i2p" +msgstr "" + +#: daemon/HTTPServer.cpp:1312 +msgid "Description" +msgstr "" + +#: daemon/HTTPServer.cpp:1312 +msgid "A bit information about service on domain" +msgstr "" + +#: daemon/HTTPServer.cpp:1313 +msgid "Submit" +msgstr "" + +#: daemon/HTTPServer.cpp:1319 +msgid "Domain can't end with .b32.i2p" +msgstr "" + +#: daemon/HTTPServer.cpp:1322 +msgid "Domain must end with .i2p" +msgstr "" + +#: daemon/HTTPServer.cpp:1325 +msgid "Such destination is not found" +msgstr "" + +#: daemon/HTTPServer.cpp:1333 +msgid "Unknown command" +msgstr "" + +#: daemon/HTTPServer.cpp:1337 +msgid "Command accepted" +msgstr "" + +#: daemon/HTTPServer.cpp:1339 +msgid "You will be redirected in 5 seconds" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:157 +msgid "Proxy error" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:165 +msgid "Proxy info" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:173 +msgid "Proxy error: Host not found" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:174 +msgid "Remote host not found in router's addressbook" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:175 +msgid "You may try to find this host on jump services below" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:273 libi2pd_client/HTTPProxy.cpp:288 +#: libi2pd_client/HTTPProxy.cpp:365 +msgid "Invalid request" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:273 +msgid "Proxy unable to parse your request" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:288 +msgid "addresshelper is not supported" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:297 libi2pd_client/HTTPProxy.cpp:306 +#: libi2pd_client/HTTPProxy.cpp:385 +msgid "Host" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:297 +msgid "added to router's addressbook from helper" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:307 +msgid "Click" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:308 +msgid "here" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:298 +msgid "to proceed" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:299 libi2pd_client/HTTPProxy.cpp:309 +msgid "Addresshelper found" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:306 +msgid "already in router's addressbook" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:308 +msgid "to update record" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:322 +msgid "Invalid Request" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:322 +msgid "invalid request uri" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:365 +msgid "Can't detect destination host from request" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:382 libi2pd_client/HTTPProxy.cpp:386 +msgid "Outproxy failure" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:382 +msgid "bad outproxy settings" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:385 +msgid "not inside I2P network, but outproxy is not enabled" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:474 +msgid "unknown outproxy url" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:480 +msgid "cannot resolve upstream proxy" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:488 +msgid "hostname too long" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:515 +msgid "cannot connect to upstream socks proxy" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:521 +msgid "Cannot negotiate with socks proxy" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:563 +msgid "CONNECT error" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:563 +msgid "Failed to Connect" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:574 libi2pd_client/HTTPProxy.cpp:600 +msgid "socks proxy error" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:582 +msgid "failed to send request to upstream" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:603 +msgid "No Reply From socks proxy" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:610 +msgid "cannot connect" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:610 +msgid "http out proxy not implemented" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:611 +msgid "cannot connect to upstream http proxy" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:644 +msgid "Host is down" +msgstr "" + +#: libi2pd_client/HTTPProxy.cpp:644 +msgid "" +"Can't create connection to requested host, it may be down. Please try again " +"later." +msgstr "" + +#~ msgid "day" +#~ msgid_plural "days" +#~ msgstr[0] "день" +#~ msgstr[1] "дня" +#~ msgstr[2] "дней" From b91eaf548798a64f54f4be900e0e2289d9f440ba Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 15 Jun 2021 23:30:28 +0300 Subject: [PATCH 0142/2193] [i18n] update gettext description Signed-off-by: R4SAS --- i18n/English.po | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/i18n/English.po b/i18n/English.po index e9317528..37acdb65 100644 --- a/i18n/English.po +++ b/i18n/English.po @@ -1,15 +1,15 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. +# i2pd +# Copyright (C) 2021 PurpleI2P team +# This file is distributed under the same license as the i2pd package. +# R4SAS , 2021. # msgid "" msgstr "" "Project-Id-Version: i2pd\n" -"Report-Msgid-Bugs-To: \n" +"Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n" "POT-Creation-Date: 2021-06-15 20:41+0300\n" "PO-Revision-Date: 2021-06-15 20:42+0300\n" -"Last-Translator: \n" +"Last-Translator: R4SAS\n" "Language-Team: PurpleI2P\n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -733,9 +733,3 @@ msgid "" "Can't create connection to requested host, it may be down. Please try again " "later." msgstr "" - -#~ msgid "day" -#~ msgid_plural "days" -#~ msgstr[0] "день" -#~ msgstr[1] "дня" -#~ msgstr[2] "дней" From 0bacd4df5fcaace1750fe84853b63fef125f8d8b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 15 Jun 2021 23:43:33 +0300 Subject: [PATCH 0143/2193] [i18n] update gettext description Signed-off-by: R4SAS --- i18n/English.po | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/i18n/English.po b/i18n/English.po index 37acdb65..10b5b01e 100644 --- a/i18n/English.po +++ b/i18n/English.po @@ -7,16 +7,10 @@ msgid "" msgstr "" "Project-Id-Version: i2pd\n" "Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n" -"POT-Creation-Date: 2021-06-15 20:41+0300\n" -"PO-Revision-Date: 2021-06-15 20:42+0300\n" -"Last-Translator: R4SAS\n" -"Language-Team: PurpleI2P\n" -"Language: ru\n" +"POT-Creation-Date: 2021-06-15 17:40\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 3.0\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-Basepath: .\n" @@ -37,28 +31,22 @@ msgid "days" msgid_plural "days" msgstr[0] "" msgstr[1] "" -msgstr[2] "" - #: daemon/HTTPServer.cpp:145 msgid "hours" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -msgstr[2] "" - #: daemon/HTTPServer.cpp:149 msgid "minutes" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -msgstr[2] "" #: daemon/HTTPServer.cpp:152 msgid "seconds" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" -msgstr[2] "" #: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188 msgid "KiB" @@ -328,6 +316,7 @@ msgstr "" #: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489 #: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672 +#: Means milliseconds msgid "ms" msgstr "" From c06a5609464c88a6edf4e38a8cc3daa34eb6b65e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 00:13:26 +0300 Subject: [PATCH 0144/2193] [i18n] use xgettext compatible function format for plural Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 8 ++++---- i18n/English.cpp | 5 +---- i18n/I18N.h | 4 ++-- i18n/I18N_langs.h | 8 ++++---- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index dadb2f8f..7eb296c4 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -138,18 +138,18 @@ namespace http { int num; if ((num = seconds / 86400) > 0) { - s << num << " " << tr("days", num) << ", "; + s << num << " " << tr("day", "days", num) << ", "; seconds -= num * 86400; } if ((num = seconds / 3600) > 0) { - s << num << " " << tr("hours", num) << ", "; + s << num << " " << tr("hour", "hours", num) << ", "; seconds -= num * 3600; } if ((num = seconds / 60) > 0) { - s << num << " " << tr("minutes", num) << ", "; + s << num << " " << tr("minute", "minutes", num) << ", "; seconds -= num * 60; } - s << seconds << " " << tr("seconds", seconds); + s << seconds << " " << tr("second", "seconds", seconds); } static void ShowTraffic (std::stringstream& s, uint64_t bytes) diff --git a/i18n/English.cpp b/i18n/English.cpp index 8b13279a..6015f8e1 100644 --- a/i18n/English.cpp +++ b/i18n/English.cpp @@ -13,6 +13,7 @@ #include "I18N.h" // English localization file +// This is an example translation file without strings in it. namespace i2p { @@ -33,10 +34,6 @@ namespace english // language static std::map> plurals { - {"days", {"day", "days"}}, - {"hours", {"hour", "hours"}}, - {"minutes", {"minute", "minutes"}}, - {"seconds", {"second", "seconds"}}, {"", {"", ""}}, }; diff --git a/i18n/I18N.h b/i18n/I18N.h index 7d0baf1a..4857df15 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -32,9 +32,9 @@ namespace i18n return i2p::context.GetLanguage ()->GetString (arg); } - inline std::string translate (const std::string& arg, const int& n) + inline std::string translate (const std::string& arg, const std::string& arg2, const int& n) { - return i2p::context.GetLanguage ()->GetPlural (arg, n); + return i2p::context.GetLanguage ()->GetPlural (arg, arg2, n); } } // i18n } // i2p diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 435141bf..3c560a2f 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -35,12 +35,12 @@ namespace i18n } } - std::string GetPlural (const std::string& arg, const int& n) const + std::string GetPlural (const std::string& arg, const std::string& arg2, const int& n) const { - const auto it = m_Plurals.find(arg); - if (it == m_Plurals.end()) + const auto it = m_Plurals.find(arg2); + if (it == m_Plurals.end()) // not found, fallback to english { - return arg; + return n == 1 ? arg : arg2; } else { From dc75868bd392fe86e9546a924d7d184d288ef939 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Jun 2021 19:09:36 -0400 Subject: [PATCH 0145/2193] check Alice's IP address in PeerTest --- libi2pd/SSUSession.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 339ac8df..59ee578b 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -383,7 +383,7 @@ namespace transport { // tell out peer to now assign relay tag flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED; - *payload = 2; payload++; // 1 byte length + *payload = 2; payload++; // 1 byte length uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG htobe16buf (payload, flags); payload += 2; @@ -1073,7 +1073,10 @@ namespace transport LogPrint (eLogDebug, "SSU: peer test from Charlie. We are Bob"); auto session = m_Server.GetPeerTestSession (nonce); // session with Alice from PeerTest if (session && session->m_State == eSessionStateEstablished) - session->Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Alice + { + const auto& ep = session->GetRemoteEndpoint (); // Alice's endpoint as known to Bob + session->SendPeerTest (nonce, ep.address (), ep.port (), introKey, false, true); // send back to Alice + } m_Server.RemovePeerTest (nonce); // nonce has been used break; } @@ -1093,9 +1096,12 @@ namespace transport if (port) { LogPrint (eLogDebug, "SSU: peer test from Bob. We are Charlie"); - m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie); Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Bob - SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob + if (!addr.is_unspecified () && !i2p::util::net::IsInReservedRange(addr)) + { + m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie); + SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob + } } else { From 2ba3f4758a33769d6f50c12beda0a7b0944c5021 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 17:56:08 +0300 Subject: [PATCH 0146/2193] [i18n] move gettext translation template to contrib Signed-off-by: R4SAS --- {i18n => contrib/i18n}/English.po | 8 ++++---- contrib/i18n/regex.txt | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) rename {i18n => contrib/i18n}/English.po (99%) create mode 100644 contrib/i18n/regex.txt diff --git a/i18n/English.po b/contrib/i18n/English.po similarity index 99% rename from i18n/English.po rename to contrib/i18n/English.po index 10b5b01e..1de2ddaa 100644 --- a/i18n/English.po +++ b/contrib/i18n/English.po @@ -27,23 +27,23 @@ msgid "Enabled" msgstr "" #: daemon/HTTPServer.cpp:141 -msgid "days" +msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" #: daemon/HTTPServer.cpp:145 -msgid "hours" +msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" #: daemon/HTTPServer.cpp:149 -msgid "minutes" +msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" #: daemon/HTTPServer.cpp:152 -msgid "seconds" +msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" diff --git a/contrib/i18n/regex.txt b/contrib/i18n/regex.txt new file mode 100644 index 00000000..768a4b01 --- /dev/null +++ b/contrib/i18n/regex.txt @@ -0,0 +1,7 @@ +Regex for transforming gettext translations to our format + +msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? +#{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n + +msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n +{"$1", "$2"},\n From 954711e98069da66c06f91c5c5ea38a81c8c0126 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 17:57:02 +0300 Subject: [PATCH 0147/2193] [i18n] pull afrikaans translation from crowdin Signed-off-by: R4SAS --- i18n/Afrikaans.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++ i18n/I18N.h | 4 ++- i18n/I18N_langs.h | 7 +++-- 3 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 i18n/Afrikaans.cpp diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp new file mode 100644 index 00000000..098c1105 --- /dev/null +++ b/i18n/Afrikaans.cpp @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Afrikaans localization file +// This is an example translation file without strings in it. + +namespace i2p +{ +namespace i18n +{ +namespace afrikaans // language +{ + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n != 1 ? 1 : 0; + } + + static std::map strings + { + {"Disabled", "Gedeaktiveer"}, + {"Enabled", "Geaktiveer"}, + {"failed", "Het misluk"}, + {"unknown", "onbekend"}, + {"Tunnels", "Tonnels"}, + {"Transit tunnels", "Deurgang tonnels"}, + {"I2P tunnels", "I2P tonnels"}, + {"SAM sessions", "SAM sessies"}, + {"OK", "LEKKER"}, + {"Testing", "Besig om te toets"}, + {"Firewalled", "Vuurmuur'd"}, + {"Unknown", "Onbekend"}, + {"Error", "Fout"}, + {"Offline", "Aflyn"}, + {"Uptime", "Optyd"}, + {"Network status", "Netwerk status"}, + {"Network status v6", "Netwerk status v6"}, + {"Family", "Familie"}, + {"Received", "Ontvang"}, + {"Sent", "Gestuur"}, + {"Hidden content. Press on text to see.", "Hidden content. Druk om te sien."}, + {"Router Ident", "Router Ident"}, + {"Router Family", "Router Familie"}, + {"", ""}, + }; + + static std::map> plurals + { + {"days", {"dag", "dae"}}, + {"hours", {"uur", "ure"}}, + {"minutes", {"minuut", "minute"}}, + {"seconds", {"seconde", "sekondes"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p diff --git a/i18n/I18N.h b/i18n/I18N.h index 4857df15..272f65e8 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -17,7 +17,9 @@ namespace i18n { inline void SetLanguage(const std::string &lang) { - if (!lang.compare("russian")) + if (!lang.compare("afrikaans")) + i2p::context.SetLanguage (i2p::i18n::afrikaans::GetLocale()); + else if (!lang.compare("russian")) i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); else if (!lang.compare("turkmen")) i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale()); diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 3c560a2f..181a4793 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -56,9 +56,10 @@ namespace i18n }; // Add localization here with language name as namespace - namespace english { std::shared_ptr GetLocale (); } - namespace russian { std::shared_ptr GetLocale (); } - namespace turkmen { std::shared_ptr GetLocale (); } + namespace afrikaans { std::shared_ptr GetLocale (); } + namespace english { std::shared_ptr GetLocale (); } + namespace russian { std::shared_ptr GetLocale (); } + namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } } // i18n From ac594dbd2646542b9a58cfb58c446638ca681015 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 19:12:05 +0300 Subject: [PATCH 0148/2193] Update status badges in README --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1aa96fb0..92a2f46f 100644 --- a/README.md +++ b/README.md @@ -68,15 +68,15 @@ Build instructions: **Supported systems:** -* GNU/Linux - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) +* GNU/Linux - [![Build on Ubuntu](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build.yml) * CentOS / Fedora / Mageia - [![Build Status](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/supervillain/i2pd/package/i2pd-git/) * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. -* Windows - [![Build status](https://ci.appveyor.com/api/projects/status/1908qe4p48ff1x23?svg=true)](https://ci.appveyor.com/project/PurpleI2P/i2pd) -* Mac OS X - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) +* Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml) +* Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml) * Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) -* Snap -* FreeBSD -* Android +* Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd) +* FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml) +* Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml) * iOS Using i2pd From a6be32392d153b57ac266b5b4232d5962bd166a3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 20:41:41 +0000 Subject: [PATCH 0149/2193] update debian packaging files Signed-off-by: R4SAS --- {debian => contrib/openrc}/i2pd.openrc | 0 {debian => contrib/upstart}/i2pd.upstart | 0 debian/compat | 2 +- debian/control | 18 ++------------- debian/copyright | 29 ------------------------ debian/docs | 4 ---- debian/i2pd.dirs | 2 -- debian/i2pd.install | 2 +- debian/postinst | 3 +-- debian/rules | 26 ++++++++------------- debian/watch | 6 ++--- 11 files changed, 18 insertions(+), 74 deletions(-) rename {debian => contrib/openrc}/i2pd.openrc (100%) rename {debian => contrib/upstart}/i2pd.upstart (100%) delete mode 100644 debian/i2pd.dirs diff --git a/debian/i2pd.openrc b/contrib/openrc/i2pd.openrc similarity index 100% rename from debian/i2pd.openrc rename to contrib/openrc/i2pd.openrc diff --git a/debian/i2pd.upstart b/contrib/upstart/i2pd.upstart similarity index 100% rename from debian/i2pd.upstart rename to contrib/upstart/i2pd.upstart diff --git a/debian/compat b/debian/compat index 9a037142..ec635144 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -10 \ No newline at end of file +9 diff --git a/debian/control b/debian/control index 843a153c..318463bc 100644 --- a/debian/control +++ b/debian/control @@ -3,30 +3,16 @@ Section: net Priority: optional Maintainer: r4sas Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev -Standards-Version: 3.9.6 +Standards-Version: 3.9.8 Homepage: http://i2pd.website/ Vcs-Git: git://github.com/PurpleI2P/i2pd.git Vcs-Browser: https://github.com/PurpleI2P/i2pd Package: i2pd Architecture: any -Pre-Depends: adduser +Pre-Depends: ${misc:Pre-Depends}, adduser Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base, Description: Full-featured C++ implementation of I2P client. I2P (Invisible Internet Protocol) is a universal anonymous network layer. All communications over I2P are anonymous and end-to-end encrypted, participants don't reveal their real IP addresses. - . - This package contains the full-featured C++ implementation of I2P router. - -Package: i2pd-dbg -Architecture: any -Priority: extra -Section: debug -Depends: i2pd (= ${binary:Version}), ${misc:Depends} -Description: i2pd debugging symbols - I2P (Invisible Internet Protocol) is a universal anonymous network layer. All - communications over I2P are anonymous and end-to-end encrypted, participants - don't reveal their real IP addresses. - . - This package contains symbols required for debugging. diff --git a/debian/copyright b/debian/copyright index 9f18f53a..73df9da0 100644 --- a/debian/copyright +++ b/debian/copyright @@ -6,13 +6,6 @@ Files: * Copyright: 2013-2020 PurpleI2P License: BSD-3-clause -Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl - qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl - qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java - qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java -Copyright: 2011-2013 BogDan Vatra -License: BSD-2-Clause - Files: debian/* Copyright: 2013-2015 Kill Your TV 2014-2016 hagen @@ -49,28 +42,6 @@ License: BSD-3-clause TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -License: BSD-2-Clause - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/debian/docs b/debian/docs index dfa6f572..b43bf86b 100644 --- a/debian/docs +++ b/debian/docs @@ -1,5 +1 @@ README.md -contrib/i2pd.conf -contrib/subscriptions.txt -contrib/tunnels.conf -contrib/tunnels.d diff --git a/debian/i2pd.dirs b/debian/i2pd.dirs deleted file mode 100644 index 3b643352..00000000 --- a/debian/i2pd.dirs +++ /dev/null @@ -1,2 +0,0 @@ -etc/i2pd -var/lib/i2pd diff --git a/debian/i2pd.install b/debian/i2pd.install index d20b2c17..6eb6c8c2 100644 --- a/debian/i2pd.install +++ b/debian/i2pd.install @@ -1,5 +1,5 @@ i2pd usr/sbin/ -contrib/i2pd.conf etc/i2pd/ +contrib/i2pd.conf etc/i2pd/ contrib/tunnels.conf etc/i2pd/ contrib/subscriptions.txt etc/i2pd/ contrib/certificates/ usr/share/i2pd/ diff --git a/debian/postinst b/debian/postinst index 9c9e74ae..720753fd 100755 --- a/debian/postinst +++ b/debian/postinst @@ -12,7 +12,6 @@ case "$1" in # Create user and group as a system user. if getent passwd $I2PDUSER > /dev/null 2>&1; then groupadd -f $I2PDUSER || true - usermod -s "/bin/false" -e 1 $I2PDUSER > /dev/null || true else adduser --system --quiet --group --home $I2PDHOME $I2PDUSER fi @@ -23,7 +22,7 @@ case "$1" in chmod 640 $LOGFILE chown -f ${I2PDUSER}:adm $LOGFILE mkdir -p -m0750 $I2PDHOME - chown -f -R -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME} + chown -f -P ${I2PDUSER}:${I2PDUSER} ${I2PDHOME} ;; abort-upgrade|abort-remove|abort-deconfigure) echo "Aborting upgrade" diff --git a/debian/rules b/debian/rules index 77ecd7b7..24a44f55 100755 --- a/debian/rules +++ b/debian/rules @@ -1,22 +1,16 @@ #!/usr/bin/make -f -# -*- makefile -*- - -# Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow -#DPKG_EXPORT_BUILDFLAGS = 1 -#include /usr/share/dpkg/buildflags.mk -#CXXFLAGS+=$(CPPFLAGS) -#PREFIX=/usr + +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + + +include /usr/share/dpkg/architecture.mk + +export DEB_CXXFLAGS_MAINT_APPEND = -Wall -pedantic -O3 + +export DEB_LDFLAGS_MAINT_APPEND = + %: dh $@ --parallel -# dh_apparmor --profile-name=usr.sbin.i2pd -pi2pd - -override_dh_strip: - dh_strip --dbg-package=i2pd-dbg - -## uncomment this if you have "missing info" problem when building package -#override_dh_shlibdeps: -# dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info diff --git a/debian/watch b/debian/watch index 55cda021..64367c81 100644 --- a/debian/watch +++ b/debian/watch @@ -1,3 +1,3 @@ -version=3 -opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/i2pd-$1\.tar\.gz/ \ - https://github.com/PurpleI2P/i2pd/tags .*/v?(\d\S*)\.tar\.gz +version=4 opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%i2pd-$1.tar.gz%" \ + https://github.com/PurpleI2P/i2pd/tags \ + (?:.*?/)?(\d[\d.]*)\.tar\.gz debian uupdate From f07241bff76e949557e9ec8f5df514b8b4a594f8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 21:14:22 +0000 Subject: [PATCH 0150/2193] add deb building Signed-off-by: R4SAS --- .github/workflows/build.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8828f61..b948380f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,3 +38,35 @@ jobs: cd build cmake -DWITH_UPNP=${{ matrix.with_upnp }} . make -j3 + build-deb-stretch: + name: Build package for stretch + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: change debian changelog + run: | + debchange -v `git describe --tags` -M "trunk build" + - uses: singingwolfboy/build-dpkg-stretch@v1 + id: build + with: + args: --unsigned-source --unsigned-changes + - uses: actions/upload-artifact@v1 + with: + name: ${{ steps.build.outputs.filename }} + path: ${{ steps.build.outputs.filename }} + build-deb-buster: + name: Build package for buster + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: change debian changelog + run: | + debchange -v `git describe --tags` -M "trunk build" + - uses: singingwolfboy/build-dpkg-buster@v1 + id: build + with: + args: --unsigned-source --unsigned-changes + - uses: actions/upload-artifact@v1 + with: + name: ${{ steps.build.outputs.filename }} + path: ${{ steps.build.outputs.filename }} From f9d378f1ceb7c5c39a620658b5f59f000c560803 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 21:19:05 +0000 Subject: [PATCH 0151/2193] [gha] add deb building Signed-off-by: R4SAS --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b948380f..42ec76b8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,8 @@ jobs: - uses: actions/checkout@v2 - name: change debian changelog run: | + sudo apt-get update + sudo apt-get install devscripts debchange -v `git describe --tags` -M "trunk build" - uses: singingwolfboy/build-dpkg-stretch@v1 id: build @@ -61,6 +63,8 @@ jobs: - uses: actions/checkout@v2 - name: change debian changelog run: | + sudo apt-get update + sudo apt-get install devscripts debchange -v `git describe --tags` -M "trunk build" - uses: singingwolfboy/build-dpkg-buster@v1 id: build From 8ec478324979ca804d6bce5dc0b42a000d3477c1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 21:34:59 +0000 Subject: [PATCH 0152/2193] [gha] fetch all history of git repo for packages (needs for describe) Signed-off-by: R4SAS --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 42ec76b8..5027e180 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,6 +43,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: change debian changelog run: | sudo apt-get update @@ -61,6 +63,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: change debian changelog run: | sudo apt-get update From 064ecdb5ec1c8acfd5faa5d00c2a6775bfb706d3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 21:40:45 +0000 Subject: [PATCH 0153/2193] [gha] do no check source archive for deb build Signed-off-by: R4SAS --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5027e180..3df73f90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: - uses: singingwolfboy/build-dpkg-stretch@v1 id: build with: - args: --unsigned-source --unsigned-changes + args: --unsigned-source --unsigned-changes --no-tgz-check - uses: actions/upload-artifact@v1 with: name: ${{ steps.build.outputs.filename }} @@ -73,7 +73,7 @@ jobs: - uses: singingwolfboy/build-dpkg-buster@v1 id: build with: - args: --unsigned-source --unsigned-changes + args: --unsigned-source --unsigned-changes --no-tgz-check - uses: actions/upload-artifact@v1 with: name: ${{ steps.build.outputs.filename }} From 71df1fc4d6b20f3a74f5d524a95727d459bf239b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 21:45:14 +0000 Subject: [PATCH 0154/2193] [gha] do not check source archive for deb build Signed-off-by: R4SAS --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3df73f90..fb820daa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: - uses: singingwolfboy/build-dpkg-stretch@v1 id: build with: - args: --unsigned-source --unsigned-changes --no-tgz-check + args: --unsigned-source --unsigned-changes -b - uses: actions/upload-artifact@v1 with: name: ${{ steps.build.outputs.filename }} @@ -73,7 +73,7 @@ jobs: - uses: singingwolfboy/build-dpkg-buster@v1 id: build with: - args: --unsigned-source --unsigned-changes --no-tgz-check + args: --unsigned-source --unsigned-changes -b - uses: actions/upload-artifact@v1 with: name: ${{ steps.build.outputs.filename }} From 2c7fff077b0544cd98c69657921f3db0262dd15c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 16 Jun 2021 22:06:48 +0000 Subject: [PATCH 0155/2193] [gha] add dist name in package changelog Signed-off-by: R4SAS --- .github/workflows/build.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb820daa..22ba60bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,7 +49,7 @@ jobs: run: | sudo apt-get update sudo apt-get install devscripts - debchange -v `git describe --tags` -M "trunk build" + debchange -v "`git describe --tags`-stretch" -M --distribution stretch "trunk build" - uses: singingwolfboy/build-dpkg-stretch@v1 id: build with: @@ -58,6 +58,10 @@ jobs: with: name: ${{ steps.build.outputs.filename }} path: ${{ steps.build.outputs.filename }} + - uses: actions/upload-artifact@v1 + with: + name: ${{ steps.build.outputs.filename-dbgsym }} + path: ${{ steps.build.outputs.filename-dbgsym }} build-deb-buster: name: Build package for buster runs-on: ubuntu-latest @@ -69,7 +73,7 @@ jobs: run: | sudo apt-get update sudo apt-get install devscripts - debchange -v `git describe --tags` -M "trunk build" + debchange -v "`git describe --tags`-buster" -M --distribution buster "trunk build" - uses: singingwolfboy/build-dpkg-buster@v1 id: build with: @@ -78,3 +82,7 @@ jobs: with: name: ${{ steps.build.outputs.filename }} path: ${{ steps.build.outputs.filename }} + - uses: actions/upload-artifact@v1 + with: + name: ${{ steps.build.outputs.filename-dbgsym }} + path: ${{ steps.build.outputs.filename-dbgsym }} From a6af4908d55e11600e698a814bf731c5434799d6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 16 Jun 2021 18:14:33 -0400 Subject: [PATCH 0156/2193] use m_ReachableTransports bitmask --- libi2pd/RouterContext.cpp | 2 ++ libi2pd/RouterInfo.cpp | 31 +++++++++---------------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 50dd6c59..c527aede 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -489,6 +489,7 @@ namespace i2p if (ntcp2) PublishNTCP2Address (port, false, v4, v6, false); // update + m_RouterInfo.UpdateSupportedTransports (); UpdateRouterInfo (); } @@ -528,6 +529,7 @@ namespace i2p } } // update + m_RouterInfo.UpdateSupportedTransports (); UpdateRouterInfo (); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index dcef9463..da456549 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -971,10 +971,10 @@ namespace data { if (!IsV6 ()) { - m_SupportedTransports |= eSSUV6 | eNTCP2V6; uint8_t addressCaps = AddressCaps::eV6; if (IsV4 ()) addressCaps |= AddressCaps::eV4; SetUnreachableAddressesTransportCaps (addressCaps); + UpdateSupportedTransports (); } } @@ -982,10 +982,10 @@ namespace data { if (!IsV4 ()) { - m_SupportedTransports |= eSSUV4 | eNTCP2V4; uint8_t addressCaps = AddressCaps::eV4; if (IsV6 ()) addressCaps |= AddressCaps::eV6; SetUnreachableAddressesTransportCaps (addressCaps); + UpdateSupportedTransports (); } } @@ -994,7 +994,6 @@ namespace data { if (IsV6 ()) { - m_SupportedTransports &= ~(eSSUV6 | eNTCP2V6); for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; @@ -1011,6 +1010,7 @@ namespace data else ++it; } + UpdateSupportedTransports (); } } @@ -1018,7 +1018,6 @@ namespace data { if (IsV4 ()) { - m_SupportedTransports &= ~(eSSUV4 | eNTCP2V4); for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; @@ -1035,13 +1034,17 @@ namespace data else ++it; } + UpdateSupportedTransports (); } } void RouterInfo::EnableMesh () { if (!IsMesh ()) + { m_SupportedTransports |= eNTCP2V6Mesh; + m_ReachableTransports |= eNTCP2V6Mesh; + } } void RouterInfo::DisableMesh () @@ -1049,6 +1052,7 @@ namespace data if (IsMesh ()) { m_SupportedTransports &= ~eNTCP2V6Mesh; + m_ReachableTransports &= ~eNTCP2V6Mesh; for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; @@ -1177,24 +1181,7 @@ namespace data bool RouterInfo::IsReachableFrom (const RouterInfo& other) const { - auto commonTransports = m_SupportedTransports & other.m_SupportedTransports; - if (!commonTransports) return false; - if (commonTransports & eNTCP2V6Mesh) return true; - return (bool)GetAddress ( - [commonTransports](std::shared_ptr address)->bool - { - if (address->IsPublishedNTCP2 ()) - { - if ((commonTransports & eNTCP2V4) && address->IsV4 ()) return true; - if ((commonTransports & eNTCP2V6) && address->IsV6 ()) return true; - } - else if (address->IsReachableSSU ()) - { - if ((commonTransports & eSSUV4) && address->IsV4 ()) return true; - if ((commonTransports & eSSUV6) && address->IsV6 ()) return true; - } - return false; - }); + return m_ReachableTransports & other.m_SupportedTransports; } void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports) From 1dda832e39a5bed13a3d973267e1d9f702589d07 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 10:35:10 +0300 Subject: [PATCH 0157/2193] [gha] build docker containers Build docker containers and publish them to GitHub Container Registry --- .github/workflows/docker.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..d6afa613 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,28 @@ +name: Build Docker containers + +on: push + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + file: contrib/docker/Dockerfile + platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le + push: true + tags: ghcr.io/PurpleI2P/i2pd:latest From d058b9a5959d1c501442d96a5ee924a3341e7fcf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 10:38:38 +0300 Subject: [PATCH 0158/2193] [gha] fix repository name to lowercase --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d6afa613..9f15c30b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,4 +25,4 @@ jobs: file: contrib/docker/Dockerfile platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le push: true - tags: ghcr.io/PurpleI2P/i2pd:latest + tags: ghcr.io/purplei2p/i2pd:latest From 2ee7ed8dda5997c14228b9eb98191e5983d33dea Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 10:59:47 +0300 Subject: [PATCH 0159/2193] [gha] temporary build only amd64 container --- .github/workflows/docker.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9f15c30b..51509008 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,6 +23,7 @@ jobs: with: context: . file: contrib/docker/Dockerfile - platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le + # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le + platforms: linux/amd64 push: true tags: ghcr.io/purplei2p/i2pd:latest From 970f47ce3323ec7966885f1fce8c1f42a6f1207c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 11:03:30 +0300 Subject: [PATCH 0160/2193] [gha] remove context --- .github/workflows/docker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 51509008..50cfe2d2 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -21,7 +21,6 @@ jobs: - name: Build and push uses: docker/build-push-action@v2 with: - context: . file: contrib/docker/Dockerfile # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le platforms: linux/amd64 From 3dc19bfd318e5d0bb093c41f0f7d0503d0e5bb70 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 11:07:56 +0300 Subject: [PATCH 0161/2193] [gha] docker - disable cache (test) --- .github/workflows/docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 50cfe2d2..d0e5e28c 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,4 +25,5 @@ jobs: # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le platforms: linux/amd64 push: true + no-cache: true tags: ghcr.io/purplei2p/i2pd:latest From 08a82a0bcd95855c8e02b91b4377929226dc1729 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Jun 2021 12:12:06 -0400 Subject: [PATCH 0162/2193] don't try to connect to a router not reachable from us --- libi2pd/Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 1e40f88c..3aaa12ba 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -401,7 +401,7 @@ namespace transport try { auto r = netdb.FindRouter (ident); - if (!r || r->IsUnreachable () || !r->IsCompatible (i2p::context.GetRouterInfo ())) return; + if (!r || r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ())) return; { std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, From f56f75bb3f474d7a29c4c6efd85ca99cd90716da Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 17:37:47 +0100 Subject: [PATCH 0163/2193] [gha] add docker building (#1664) --- .github/workflows/docker.yml | 19 +++++++++++++------ contrib/docker/Dockerfile | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d0e5e28c..81c0fcfb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,29 +1,36 @@ -name: Build Docker containers +name: Build containers on: push jobs: docker: runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: - name: Checkout uses: actions/checkout@v2 + - name: Set up QEMU uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 + - name: Login to DockerHub uses: docker/login-action@v1 with: registry: ghcr.io - username: ${{ github.repository_owner }} + username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push uses: docker/build-push-action@v2 with: - file: contrib/docker/Dockerfile - # platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64,linux/ppc64le - platforms: linux/amd64 + context: ./contrib/docker + file: ./contrib/docker/Dockerfile + platforms: linux/amd64,linux/386 push: true - no-cache: true tags: ghcr.io/purplei2p/i2pd:latest diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index dc9f5501..71af141e 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -25,7 +25,8 @@ RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \ # 1. install deps, clone and build. # 2. strip binaries. # 3. Purge all dependencies and other unrelated packages, including build directory. -RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \ +RUN apk update \ + && apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib-dev boost-dev build-base openssl-dev openssl miniupnpc-dev git \ && mkdir -p /tmp/build \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd i2pd \ From a97d2bbb6393c161b5f51dba67d531fc312e7517 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 20:07:10 +0300 Subject: [PATCH 0164/2193] [gha] publish containers to docker hub --- .github/workflows/docker.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 81c0fcfb..0946b431 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,6 +20,12 @@ jobs: uses: docker/setup-buildx-action@v1 - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to GitHub Container registry uses: docker/login-action@v1 with: registry: ghcr.io @@ -33,4 +39,6 @@ jobs: file: ./contrib/docker/Dockerfile platforms: linux/amd64,linux/386 push: true - tags: ghcr.io/purplei2p/i2pd:latest + tags: | + purplei2p/i2pd:latest + ghcr.io/purplei2p/i2pd:latest From 3330d2bb0ca098067e39ac41aa4f27e44ab5f05e Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 13:24:19 -0400 Subject: [PATCH 0165/2193] Also Extern Identity, Destination, Streaming headers --- Makefile | 11 ++++++++++- libi2pd/capi.cpp | 9 +++++---- libi2pd/capi.h | 9 +++++---- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 7a033bf2..0569ab7c 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,13 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) obj/%.o: %.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< +flags: + @echo $(CXXFLAGS) + @echo $(NEEDED_CXXFLAGS) + @echo $(INCFLAGS) + @echo $(LDFLAGS) + @echo $(LDLIBS) + # '-' is 'ignore if missing' on first run -include $(DEPS) @@ -139,5 +146,7 @@ doxygen: ##TODO: delete this before a PR testc: api api_client - g++ -Ii18n -c test.c -o test.o +# g++ -Ii18n -c test.c -o test.o + gcc -Ii18n -c _test.c -o test.o +# gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index b1f94d1f..d507f64e 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -6,6 +6,7 @@ * See full license text in LICENSE file at top of project tree */ +#include "api.h" #include "capi.h" #ifdef __cplusplus @@ -22,10 +23,10 @@ void C_TerminateI2P () return i2p::api::TerminateI2P(); } -void C_StartI2P (std::ostream *logStream) +void C_StartI2P ()//std::ostream *logStream) { - std::shared_ptr cppLogStream(logStream); - return i2p::api::StartI2P(cppLogStream); +// std::shared_ptr cppLogStream(logStream); + return i2p::api::StartI2P(nullptr); } void C_StopI2P () @@ -80,7 +81,7 @@ void C_DestroyStream (i2p::stream::Stream *stream) return i2p::api::DestroyStream(cppStream); } + #ifdef __cplusplus } #endif - diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 341cf39e..0ad92b49 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -9,17 +9,18 @@ #ifndef CAPI_H__ #define CAPI_H__ -#include "api.h" - - #ifdef __cplusplus extern "C" { #endif +#include "Identity.h" +#include "Destination.h" +#include "Streaming.h" + // initialization start and stop void C_InitI2P (int argc, char* argv[], const char * appName); void C_TerminateI2P (); -void C_StartI2P (std::ostream *logStream = nullptr); +void C_StartI2P (); //std::ostream *logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP From 45ef6cba9d07127d1001911c7072c01ba436efb4 Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 13:46:57 -0400 Subject: [PATCH 0166/2193] Un-mangle Destination in case we need to somehow pass one to DestroyLocalDestination,RequestLeaseSet, etc --- Makefile | 2 +- libi2pd/Identity.h | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0569ab7c..29a03fc1 100644 --- a/Makefile +++ b/Makefile @@ -147,6 +147,6 @@ doxygen: ##TODO: delete this before a PR testc: api api_client # g++ -Ii18n -c test.c -o test.o - gcc -Ii18n -c _test.c -o test.o + gcc -llibi2pd.so -c _test.c -o test.o # gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index e9cf63ed..2e7cd32d 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -20,6 +20,10 @@ #include "Signature.h" #include "CryptoKey.h" +#ifdef __cplusplus +extern "C" { +#endif + namespace i2p { namespace data @@ -244,4 +248,8 @@ namespace data } } +#ifdef __cplusplus +} +#endif + #endif From 669720d8f5f0b84abdc97175dfccaf563a92c6e4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 21:37:48 +0300 Subject: [PATCH 0167/2193] [gha] build and publish release containers --- .github/workflows/docker.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0946b431..aced7f39 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,6 +1,6 @@ name: Build containers -on: push +on: [push] jobs: docker: @@ -32,7 +32,8 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push + - name: Build and push trunk container + if: ${{ !startsWith(github.ref, 'refs/tags/') }} uses: docker/build-push-action@v2 with: context: ./contrib/docker @@ -42,3 +43,21 @@ jobs: tags: | purplei2p/i2pd:latest ghcr.io/purplei2p/i2pd:latest + + - name: Set env + if: ${{ startsWith(github.ref, 'refs/tags/') }} + run: echo "RELEASE_VERSION=${GITHUB_REF:10}" >> $GITHUB_ENV + + - name: Build and push release container + if: ${{ startsWith(github.ref, 'refs/tags/') }} + uses: docker/build-push-action@v2 + with: + context: ./contrib/docker + file: ./contrib/docker/Dockerfile + platforms: linux/amd64,linux/386 + push: true + tags: | + purplei2p/i2pd:latest + purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} + ghcr.io/purplei2p/i2pd:latest + ghcr.io/purplei2p/i2pd:release-${{ env.RELEASE_VERSION }} From 82bb3a9b25f0eeddd59a0dcfdff53e66ab172fab Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 01:26:08 +0300 Subject: [PATCH 0168/2193] [i18n] remove comment line in afrikaans Signed-off-by: R4SAS --- i18n/Afrikaans.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index 098c1105..d2b652b4 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -13,7 +13,6 @@ #include "I18N.h" // Afrikaans localization file -// This is an example translation file without strings in it. namespace i2p { From e14d3584205d20e232510a8b555ed5fab600bac9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 22:11:46 +0300 Subject: [PATCH 0169/2193] [docker] add debug commands Adding `g++ -dumpmachine` command on build stage to figure out why docker hub is unable to build container. --- contrib/docker/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 71af141e..d8140412 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -31,6 +31,7 @@ RUN apk update \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd i2pd \ && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \ + && g++ -dumpmachine \ && make USE_UPNP=yes \ && cp -R contrib/certificates /i2pd_certificates \ && mkdir -p /usr/local/bin \ From 5e11a03f0aa4c9fe75f9a20fb953e2428c7ad5c0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 17 Jun 2021 22:41:37 +0300 Subject: [PATCH 0170/2193] [docker] fallback to alpine 3.13 https://wiki.alpinelinux.org/wiki/Draft_Release_Notes_for_Alpine_3.14.0#faccessat2 --- contrib/docker/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index d8140412..6470e148 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:latest +FROM alpine:3.13 LABEL authors "Mikal Villa , Darknet Villain " # Expose git branch, tag and URL variables as arguments @@ -31,7 +31,6 @@ RUN apk update \ && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ && cd i2pd \ && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \ - && g++ -dumpmachine \ && make USE_UPNP=yes \ && cp -R contrib/certificates /i2pd_certificates \ && mkdir -p /usr/local/bin \ From 5013ce56491131b824685efb9b83e07c23236d55 Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 18:25:55 -0400 Subject: [PATCH 0171/2193] Try and figure out why the C Compiler thinks it needs to find iostream when the C++ library has already been compiled. Make the makefile aware of variables in the environment --- Makefile | 35 +++++++++++++++++++++-------------- libi2pd/api.swigcxx | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 libi2pd/api.swigcxx diff --git a/Makefile b/Makefile index 29a03fc1..97e75c15 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ DAEMON_SRC_DIR := daemon # import source files lists include filelist.mk -USE_AESNI := yes -USE_STATIC := no -USE_MESHNET := no -USE_UPNP := no -DEBUG := yes +USE_AESNI := $(or $(USE_AESNI),yes) +USE_STATIC := $(or $(USE_STATIC),no) +USE_MESHNET := $(or $(USE_MESHNET),no) +USE_UPNP := $(or $(USE_UPNP),no) +DEBUG := $(or $(DEBUG),yes) ifeq ($(DEBUG),yes) CXX_DEBUG = -g @@ -82,13 +82,6 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) obj/%.o: %.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< -flags: - @echo $(CXXFLAGS) - @echo $(NEEDED_CXXFLAGS) - @echo $(INCFLAGS) - @echo $(LDFLAGS) - @echo $(LDLIBS) - # '-' is 'ignore if missing' on first run -include $(DEPS) @@ -144,9 +137,23 @@ doxygen: .PHONY: install .PHONY: strip +flags: + @echo $(CXXFLAGS) + @echo $(NEEDED_CXXFLAGS) + @echo $(INCFLAGS) + @echo $(LDFLAGS) + @echo $(LDLIBS) + @echo $(USE_AESNI) + @echo $(USE_STATIC) + @echo $(USE_MESHNET) + @echo $(USE_UPNP) + @echo $(DEBUG) + ##TODO: delete this before a PR testc: api api_client # g++ -Ii18n -c test.c -o test.o - gcc -llibi2pd.so -c _test.c -o test.o +# gcc -llibi2pd.so -c _test.c -o test.o + $(CC) -g -Wall -o test.o _test.c libi2pd.a +# gcc -o i2pd _test.c libi2pd.a -lstdc++ -llibi2pd -Llibi2pd # gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o - g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file +# g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file diff --git a/libi2pd/api.swigcxx b/libi2pd/api.swigcxx new file mode 100644 index 00000000..324967ee --- /dev/null +++ b/libi2pd/api.swigcxx @@ -0,0 +1,16 @@ +// See swig.org for more inteface options, +// e.g. map std::string to Go string + +%{ +#include "api.h" +//#include "Streaming.h" +#include "Destination.h" +//#include "Identity.h" +//#include "Tag.h" +%} + +%include "api.h" +//%include "Streaming.h" +//%include "Destination.h" +//%include "Identity.h" +//%include "Tag.h" \ No newline at end of file From 81c83f0d54aca38fb82d1a60e9108cd341ceb69f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Jun 2021 19:10:57 -0400 Subject: [PATCH 0172/2193] pick ECIES routers only for non-x64 --- libi2pd/NetDb.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index a1d97cba..5e93fabb 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1187,7 +1187,11 @@ namespace data (reverse ? compatibleWith->IsReachableFrom (*router) : router->IsReachableFrom (*compatibleWith)) && (router->GetCaps () & RouterInfo::eHighBandwidth) && +#if defined(__x86_64__) router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION; +#else + router->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; +#endif }); } From 2185019b59b3a54fb5280508f3130805a9b7f9e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Jun 2021 19:46:05 -0400 Subject: [PATCH 0173/2193] check if router is reachable by transport before obtaining address --- libi2pd/RouterInfo.cpp | 5 ----- libi2pd/RouterInfo.h | 3 ++- libi2pd/Transports.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index da456549..3f50a4b7 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1179,11 +1179,6 @@ namespace data }); } - bool RouterInfo::IsReachableFrom (const RouterInfo& other) const - { - return m_ReachableTransports & other.m_SupportedTransports; - } - void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports) { for (auto& addr: *m_Addresses) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index bea83fda..89654757 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -204,7 +204,8 @@ namespace data void EnableMesh (); void DisableMesh (); bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; - bool IsReachableFrom (const RouterInfo& other) const; + bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; + bool IsReachableBy (SupportedTransports transport) const { return m_ReachableTransports & transport; }; bool HasValidAddresses () const { return m_SupportedTransports; }; bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 3aaa12ba..c2bed2ab 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -447,7 +447,7 @@ namespace transport std::shared_ptr address; if (!peer.numAttempts) // NTCP2 ipv6 { - if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsNTCP2V6 ()) + if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsReachableBy (RouterInfo::eNTCP2V6)) { address = peer.router->GetPublishedNTCP2V6Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) @@ -457,7 +457,7 @@ namespace transport } if (!address && peer.numAttempts == 1) // NTCP2 ipv4 { - if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsNTCP2 (true) && !peer.router->IsUnreachable ()) + if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsReachableBy (RouterInfo::eNTCP2V4)) { address = peer.router->GetPublishedNTCP2V4Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) @@ -485,7 +485,7 @@ namespace transport std::shared_ptr address; if (peer.numAttempts == 2) // SSU ipv6 { - if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsSSUV6 ()) + if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsReachableBy (RouterInfo::eSSUV6)) { address = peer.router->GetSSUV6Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) @@ -495,7 +495,7 @@ namespace transport } if (!address && peer.numAttempts == 3) // SSU ipv4 { - if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsSSU (true)) + if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsReachableBy (RouterInfo::eSSUV4)) { address = peer.router->GetSSUAddress (true); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) From 7bc2e74683307952c8c8dd442fffe73519c86882 Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 17 Jun 2021 23:12:22 -0400 Subject: [PATCH 0174/2193] Get it to build from go build --- Makefile | 39 +++++++++++++++++++++++++++++---------- libi2pd/Destination.h | 8 -------- libi2pd/Identity.h | 8 -------- libi2pd/api.go | 10 ++++++++++ libi2pd/api.swigcxx | 6 +++--- libi2pd/capi.cpp | 9 +++++---- libi2pd/capi.h | 11 ++++++----- 7 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 libi2pd/api.go diff --git a/Makefile b/Makefile index 97e75c15..62a64584 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ SYS := $(shell $(CXX) -dumpmachine) SHLIB := libi2pd.so ARLIB := libi2pd.a +SHLIB_LANG := libi2pdlang.so +ARLIB_LANG := libi2pdlang.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a I2PD := i2pd @@ -26,6 +28,12 @@ else LD_DEBUG = -s endif +ifeq ($(USE_STATIC),yes) + NEEDED_CXXFLAGS+= -static +else + +endif + ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) @@ -68,9 +76,10 @@ mk_obj_dir: @mkdir -p obj/$(LANG_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api: mk_obj_dir $(SHLIB) $(ARLIB) +client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -88,22 +97,31 @@ obj/%.o: %.cpp $(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) +$(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif -$(ARLIB): $(LIB_OBJS) +$(SHLIB_LANG): $(LANG_OBJS) +ifneq ($(USE_STATIC),yes) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) +endif + +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ -$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ +$(ARLIB_LANG): $(LANG_OBJS) + $(AR) -r $@ $^ + + clean: $(RM) -r obj $(RM) -r docs/generated @@ -151,9 +169,10 @@ flags: ##TODO: delete this before a PR testc: api api_client -# g++ -Ii18n -c test.c -o test.o + g++ -Ii18n -c _test.c -o test.o # gcc -llibi2pd.so -c _test.c -o test.o - $(CC) -g -Wall -o test.o _test.c libi2pd.a +# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -Ilibi2pd -Ilibi2pd_client -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so +# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so # gcc -o i2pd _test.c libi2pd.a -lstdc++ -llibi2pd -Llibi2pd # gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o -# g++ test.o libi2pd.so libi2pdclient.so -o test.main \ No newline at end of file + g++ test.o libi2pd.a libi2pdclient.a libi2pdlang.a -o test.main \ No newline at end of file diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f24e31ca..6695796d 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -28,10 +28,6 @@ #include "Datagram.h" #include "util.h" -#ifdef __cplusplus -extern "C" { -#endif - namespace i2p { namespace client @@ -316,8 +312,4 @@ namespace client } } -#ifdef __cplusplus -} -#endif - #endif diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 2e7cd32d..e9cf63ed 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -20,10 +20,6 @@ #include "Signature.h" #include "CryptoKey.h" -#ifdef __cplusplus -extern "C" { -#endif - namespace i2p { namespace data @@ -248,8 +244,4 @@ namespace data } } -#ifdef __cplusplus -} -#endif - #endif diff --git a/libi2pd/api.go b/libi2pd/api.go new file mode 100644 index 00000000..d7a19bc9 --- /dev/null +++ b/libi2pd/api.go @@ -0,0 +1,10 @@ +package api + +/* +//void Go_InitI2P (int argc, char argv[], const char * appName){ + +//} +#cgo CPPFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes +#cgo LDFLAGS: -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ +*/ +import "C" diff --git a/libi2pd/api.swigcxx b/libi2pd/api.swigcxx index 324967ee..fbb1b95a 100644 --- a/libi2pd/api.swigcxx +++ b/libi2pd/api.swigcxx @@ -2,14 +2,14 @@ // e.g. map std::string to Go string %{ -#include "api.h" +#include "capi.h" //#include "Streaming.h" -#include "Destination.h" +//#include "Destination.h" //#include "Identity.h" //#include "Tag.h" %} -%include "api.h" +%include "capi.h" //%include "Streaming.h" //%include "Destination.h" //%include "Identity.h" diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index d507f64e..1a2498b6 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -13,9 +13,9 @@ extern "C" { #endif -void C_InitI2P (int argc, char* argv[], const char * appName) +void C_InitI2P (int argc, char argv[], const char * appName) { - return i2p::api::InitI2P(argc, argv, appName); + return i2p::api::InitI2P(argc, &argv, appName); } void C_TerminateI2P () @@ -25,8 +25,9 @@ void C_TerminateI2P () void C_StartI2P ()//std::ostream *logStream) { -// std::shared_ptr cppLogStream(logStream); - return i2p::api::StartI2P(nullptr); + std::shared_ptr logStream; + //cppLogStream(&out); + return i2p::api::StartI2P(logStream); } void C_StopI2P () diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 0ad92b49..8395cfca 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -9,16 +9,17 @@ #ifndef CAPI_H__ #define CAPI_H__ -#ifdef __cplusplus -extern "C" { -#endif - #include "Identity.h" #include "Destination.h" #include "Streaming.h" +#ifdef __cplusplus +extern "C" { +#endif + // initialization start and stop -void C_InitI2P (int argc, char* argv[], const char * appName); +void C_InitI2P (int argc, char argv[], const char * appName); +//void C_InitI2P (int argc, char** argv, const char * appName); void C_TerminateI2P (); void C_StartI2P (); //std::ostream *logStream = nullptr); // write system log to logStream, if not specified to .log in application's folder From 5bfab0a79639924b666ce20647a8fe469838f0fe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 06:38:10 +0300 Subject: [PATCH 0175/2193] add certsdir option (#1642) Signed-off-by: R4SAS --- contrib/i2pd.conf | 4 ++++ libi2pd/Config.cpp | 1 + libi2pd/Family.cpp | 9 ++++++++- libi2pd/Reseed.cpp | 9 ++++++++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index f3cea2b5..7b85a61b 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -15,6 +15,10 @@ ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d # tunnelsdir = /var/lib/i2pd/tunnels.d +## Path to certificates used for verifying .su3, families +## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates +# certsdir = /var/lib/i2pd/certificates + ## Where to write pidfile (default: i2pd.pid, not used in Windows) # pidfile = /run/i2pd.pid diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index a80778a1..16d50e8c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -37,6 +37,7 @@ namespace config { ("conf", value()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)") ("tunconf", value()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)") ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") + ("certsdir", value()->default_value(""), "Path to certificates used for verifying .su3, families (default: ~/.i2pd/certificates or /var/lib/i2pd/certificates") ("pidfile", value()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)") ("log", value()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)") ("logfile", value()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)") diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index fbb7b9ee..baf846f6 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -98,7 +98,14 @@ namespace data void Families::LoadCertificates () { - std::string certDir = i2p::fs::DataDirPath("certificates", "family"); + std::string certDir; + std::string certsdir; i2p::config::GetOption("certsdir", certsdir); + if (!i2p::config::IsDefault("certsdir")) + certDir = certsdir + i2p::fs::dirSep + "family"; + + if (certDir.empty() || !i2p::fs::Exists(certDir)) + std::string certDir = i2p::fs::DataDirPath("certificates", "family"); + std::vector files; int numCertificates = 0; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 41111ecc..a78058cf 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -497,7 +497,14 @@ namespace data void Reseeder::LoadCertificates () { - std::string certDir = i2p::fs::DataDirPath("certificates", "reseed"); + std::string certDir; + std::string certsdir; i2p::config::GetOption("certsdir", certsdir); + if (!i2p::config::IsDefault("certsdir")) + certDir = certsdir + i2p::fs::dirSep + "reseed"; + + if (certDir.empty() || !i2p::fs::Exists(certDir)) + std::string certDir = i2p::fs::DataDirPath("certificates", "reseed"); + std::vector files; int numCertificates = 0; From d3a49e513c75ba4a78ac8d68a4def828feb6bfcb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 06:40:58 +0300 Subject: [PATCH 0176/2193] remove repeatable type definition, add include (#1642) Signed-off-by: R4SAS --- libi2pd/Family.cpp | 3 ++- libi2pd/Reseed.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index baf846f6..f37a5f54 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -13,6 +13,7 @@ #include "FS.h" #include "Log.h" #include "Family.h" +#include "Config.h" namespace i2p { @@ -104,7 +105,7 @@ namespace data certDir = certsdir + i2p::fs::dirSep + "family"; if (certDir.empty() || !i2p::fs::Exists(certDir)) - std::string certDir = i2p::fs::DataDirPath("certificates", "family"); + certDir = i2p::fs::DataDirPath("certificates", "family"); std::vector files; int numCertificates = 0; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index a78058cf..482506b2 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -503,7 +503,7 @@ namespace data certDir = certsdir + i2p::fs::dirSep + "reseed"; if (certDir.empty() || !i2p::fs::Exists(certDir)) - std::string certDir = i2p::fs::DataDirPath("certificates", "reseed"); + certDir = i2p::fs::DataDirPath("certificates", "reseed"); std::vector files; int numCertificates = 0; From e8ad7b4f79292c8ccded1c22e80089ad9f6a501f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 10:04:48 +0300 Subject: [PATCH 0177/2193] rework of storing certificates path (#1642) Signed-off-by: R4SAS --- daemon/Daemon.cpp | 6 ++++++ libi2pd/FS.cpp | 20 ++++++++++++++++++++ libi2pd/FS.h | 18 +++++++++++++++++- libi2pd/Family.cpp | 8 +------- libi2pd/Reseed.cpp | 8 +------- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index f7f2ef2f..445c4dfd 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -94,6 +94,11 @@ namespace util i2p::config::GetOption("daemon", isDaemon); + std::string certsdir; i2p::config::GetOption("certsdir", certsdir); + i2p::fs::SetCertsDir(certsdir); + + certsdir = i2p::fs::GetCertsDir(); + std::string logs = ""; i2p::config::GetOption("log", logs); std::string logfile = ""; i2p::config::GetOption("logfile", logfile); std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel); @@ -132,6 +137,7 @@ namespace util LogPrint(eLogNone, "i2pd v", VERSION, " starting"); LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); + LogPrint(eLogDebug, "FS: certificates directory: ", certsdir); bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 6ac302b0..f6653e55 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -24,6 +24,7 @@ namespace i2p { namespace fs { std::string appName = "i2pd"; std::string dataDir = ""; + std::string certsDir = ""; #ifdef _WIN32 std::string dirSep = "\\"; #else @@ -42,6 +43,10 @@ namespace fs { return dataDir; } + const std::string & GetCertsDir () { + return certsDir; + } + const std::string GetUTF8DataDir () { #ifdef _WIN32 boost::filesystem::wpath path (dataDir); @@ -126,6 +131,21 @@ namespace fs { #endif } + void SetCertsDir(const std::string & cmdline_certsdir) { + if (cmdline_certsdir != "") + { + if (cmdline_certsdir[cmdline_certsdir.length()-1] == '/') + certsDir = cmdline_certsdir.substr(0, cmdline_certsdir.size()-1); // strip trailing slash + else + certsDir = cmdline_certsdir; + } + else + { + certsDir = i2p::fs::DataDirPath("certificates"); + } + return; + } + bool Init() { if (!boost::filesystem::exists(dataDir)) boost::filesystem::create_directory(dataDir); diff --git a/libi2pd/FS.h b/libi2pd/FS.h index f07ee35c..d51aa955 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -75,6 +75,9 @@ namespace fs { /** @brief Returns datadir path */ const std::string & GetDataDir(); + /** @brief Returns certsdir path */ + const std::string & GetCertsDir(); + /** @brief Returns datadir path in UTF-8 encoding */ const std::string GetUTF8DataDir(); @@ -90,7 +93,20 @@ namespace fs { * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/ * Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/ */ - void DetectDataDir(const std::string & cmdline_datadir, bool isService = false); + void DetectDataDir(const std::string & cmdline_datadir, bool isService = false); + + /** + * @brief Set certsdir either from cmdline option or using autodetection + * @param cmdline_param Value of cmdline parameter --certsdir= + * + * Examples of autodetected paths: + * + * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\certificates + * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\certificates + * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates + * Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates + */ + void SetCertsDir(const std::string & cmdline_certsdir); /** * @brief Create subdirectories inside datadir diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index f37a5f54..a6f0e2ee 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -99,13 +99,7 @@ namespace data void Families::LoadCertificates () { - std::string certDir; - std::string certsdir; i2p::config::GetOption("certsdir", certsdir); - if (!i2p::config::IsDefault("certsdir")) - certDir = certsdir + i2p::fs::dirSep + "family"; - - if (certDir.empty() || !i2p::fs::Exists(certDir)) - certDir = i2p::fs::DataDirPath("certificates", "family"); + std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "family"; std::vector files; int numCertificates = 0; diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 482506b2..aec683d4 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -497,13 +497,7 @@ namespace data void Reseeder::LoadCertificates () { - std::string certDir; - std::string certsdir; i2p::config::GetOption("certsdir", certsdir); - if (!i2p::config::IsDefault("certsdir")) - certDir = certsdir + i2p::fs::dirSep + "reseed"; - - if (certDir.empty() || !i2p::fs::Exists(certDir)) - certDir = i2p::fs::DataDirPath("certificates", "reseed"); + std::string certDir = i2p::fs::GetCertsDir() + i2p::fs::dirSep + "reseed"; std::vector files; int numCertificates = 0; From 8e5d2e1b73fa28133c0e51aa0455bd77155ecdf9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 18 Jun 2021 17:26:18 +0300 Subject: [PATCH 0178/2193] [readme] add gha container build badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92a2f46f..37c4553a 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Build instructions: * Alpine, ArchLinux, openSUSE, Gentoo, Debian, Ubuntu, etc. * Windows - [![Build on Windows](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-windows.yml) * Mac OS X - [![Build on OSX](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-osx.yml) -* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) +* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) [![Build containers](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/docker.yml) * Snap - [![i2pd](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![i2pd](https://snapcraft.io/i2pd/trending.svg?name=0)](https://snapcraft.io/i2pd) * FreeBSD - [![Build on FreeBSD](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml/badge.svg)](https://github.com/PurpleI2P/i2pd/actions/workflows/build-freebsd.yml) * Android - [![Android CI](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml/badge.svg)](https://github.com/PurpleI2P/i2pd-android/actions/workflows/android.yml) From 6ca28adcbb29df8fd94d1e735ae5791bbd2e5a54 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 18 Jun 2021 18:19:05 -0400 Subject: [PATCH 0179/2193] set address caps and available transports for new address --- libi2pd/RouterContext.cpp | 23 ++++++++++++++--------- libi2pd/RouterInfo.cpp | 16 ++++++++++++++-- libi2pd/RouterInfo.h | 3 ++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index c527aede..adce291c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -568,16 +568,21 @@ namespace i2p { bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); - if (ntcp2 && ntcp2Published) + if (ntcp2) { - std::string ntcp2Host; - if (!i2p::config::IsDefault ("ntcp2.addressv6")) - i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); + if (ntcp2Published) + { + std::string ntcp2Host; + if (!i2p::config::IsDefault ("ntcp2.addressv6")) + i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); + else + ntcp2Host = "::1"; + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); + } else - ntcp2Host = "::1"; - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6); } } m_RouterInfo.EnableV6 (); @@ -632,7 +637,7 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port); } else - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4); } } m_RouterInfo.EnableV4 (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3f50a4b7..a426d9b7 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -840,21 +840,33 @@ namespace data for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; + m_ReachableTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; m_Addresses->push_back(std::move(addr)); } - void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port) + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, + const boost::asio::ip::address& host, int port, uint8_t caps) { auto addr = std::make_shared
(); addr->host = host; addr->port = port; addr->transportStyle = eTransportNTCP; - addr->caps = 0; + addr->caps = caps; addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); if (port) addr->published = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->iv, iv, 16); + if (addr->IsV4 ()) + { + m_SupportedTransports |= eNTCP2V4; + if (addr->published) m_ReachableTransports |= eNTCP2V4; + } + if (addr->IsV6 ()) + { + m_SupportedTransports |= eNTCP2V6; + if (addr->published) m_ReachableTransports |= eNTCP2V6; + } m_Addresses->push_back(std::move(addr)); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 89654757..f27a5d68 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -179,7 +179,8 @@ namespace data std::shared_ptr GetYggdrasilAddress () const; void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); - void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0); + void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, + const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0, uint8_t caps = 0); 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 From f5e7d87f5b8b63424e544729fd475bfd41a4892e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Jun 2021 14:25:50 -0400 Subject: [PATCH 0180/2193] don't disable floodfill if still reachable by ipv6 --- libi2pd/RouterContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index adce291c..b2a19890 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -470,7 +470,8 @@ namespace i2p uint8_t caps = m_RouterInfo.GetCaps (); caps &= ~i2p::data::RouterInfo::eReachable; caps |= i2p::data::RouterInfo::eUnreachable; - caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill + if (v6 || !SupportsV6 ()) + caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill m_RouterInfo.SetCaps (caps); } uint16_t port = 0; From fed04c1a199c4d97f46ae3f64915fbf4e1217934 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Jun 2021 14:44:33 -0400 Subject: [PATCH 0181/2193] requsted router to send to if not in netdb --- libi2pd/Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c2bed2ab..181c3663 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -401,7 +401,7 @@ namespace transport try { auto r = netdb.FindRouter (ident); - if (!r || r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ())) return; + if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return; // router found but non-reachable { std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, From 84d987810f9a6f657ea854069754d979e648442a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 20 Jun 2021 09:36:14 +0300 Subject: [PATCH 0182/2193] add afrikaans in config example --- contrib/i2pd.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 7b85a61b..599a2081 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -108,7 +108,8 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), russian, turkmen and ukrainian languages +## Currently supported english (default), afrikaans, russian, turkmen and ukrainian languages + # lang = english [httpproxy] From 6971b1e9da863a7260b145dde29f5961c74feaf0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 20 Jun 2021 20:02:20 +0300 Subject: [PATCH 0183/2193] fix typo in config option description Kudos @iBicha https://github.com/PurpleI2P/i2pd/pull/1662#pullrequestreview-687850246 Signed-off-by: R4SAS --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 16d50e8c..e5640ad0 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -285,7 +285,7 @@ namespace config { options_description meshnets("Meshnet transports options"); meshnets.add_options() - ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)") + ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (default: false)") ("meshnets.yggaddress", value()->default_value(""), "Yggdrasil address to publish") ; From 35ba16ff3b986749aaf1b1a2065196a1578c1be4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 20 Jun 2021 17:20:29 -0400 Subject: [PATCH 0184/2193] fixed #1665. cast to int64_t --- daemon/I2PControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 12602c99..73dde618 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -406,7 +406,7 @@ namespace client void I2PControlService::UptimeHandler (std::ostringstream& results) { - InsertParam (results, "i2p.router.uptime", (int)i2p::context.GetUptime ()*1000); + InsertParam (results, "i2p.router.uptime", std::to_string (i2p::context.GetUptime ()*1000LL)); } void I2PControlService::VersionHandler (std::ostringstream& results) From 7d51b4c6ed83fe9e9edf0be04998df6404ff1be8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 21 Jun 2021 21:16:25 +0300 Subject: [PATCH 0185/2193] [i18n] pull ukrainian translation from crowdin (closes #1666) Signed-off-by: R4SAS --- contrib/i18n/regex.txt | 3 + i18n/Ukrainian.cpp | 299 +++++++++++++++++++---------------------- 2 files changed, 139 insertions(+), 163 deletions(-) diff --git a/contrib/i18n/regex.txt b/contrib/i18n/regex.txt index 768a4b01..e74f9d2d 100644 --- a/contrib/i18n/regex.txt +++ b/contrib/i18n/regex.txt @@ -5,3 +5,6 @@ msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"( msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n {"$1", "$2"},\n + +^#:(.*)$\n + diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 11878cde..5e856c52 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -28,23 +28,151 @@ namespace ukrainian // language static std::map strings { - // HTTP Proxy + {"Disabled", "Вимкнуто"}, + {"Enabled", "Увімкнуто"}, + {"KiB", "КіБ"}, + {"MiB", "МіБ"}, + {"GiB", "ГіБ"}, + {"building", "будується"}, + {"failed", "невдалий"}, + {"expiring", "завершується"}, + {"established", "працює"}, + {"unknown", "невідомо"}, + {"exploratory", "дослідницький"}, + {"i2pd webconsole", "Веб-консоль i2pd"}, + {"Main page", "Головна"}, + {"Router commands", "Команди маршрутизатора"}, + {"Local destinations", "Локальні призначення"}, + {"LeaseSets", "Лізсети"}, + {"Tunnels", "Тунелі"}, + {"Transit tunnels", "Транзитні тунелі"}, + {"Transports", "Транспорти"}, + {"I2P tunnels", "I2P тунелі"}, + {"SAM sessions", "SAM сесії"}, + {"ERROR", "ПОМИЛКА"}, + {"OK", "OK"}, + {"Testing", "Тестування"}, + {"Firewalled", "Заблоковано ззовні"}, + {"Unknown", "Невідомо"}, + {"Proxy", "Проксі"}, + {"Mesh", "MESH-мережа"}, + {"Error", "Помилка"}, + {"Clock skew", "Неточний час"}, + {"Offline", "Офлайн"}, + {"Symmetric NAT", "Симетричний NAT"}, + {"Uptime", "У мережі"}, + {"Network status", "Мережевий статус"}, + {"Network status v6", "Мережевий статус v6"}, + {"Stopping in", "Зупинка через"}, + {"Family", "Сімейство"}, + {"Tunnel creation success rate", "Успішно побудованих тунелів"}, + {"Received", "Отримано"}, + {"KiB/s", "КіБ/с"}, + {"Sent", "Відправлено"}, + {"Transit", "Транзит"}, + {"Data path", "Шлях до даних"}, + {"Hidden content. Press on text to see.", "Прихований вміст. Щоб відобразити, натисніть на текст."}, + {"Router Ident", "Ідентифікатор маршрутизатора"}, + {"Router Family", "Сімейство маршрутизатора"}, + {"Router Caps", "Прапорці маршрутизатора"}, + {"Version", "Версія"}, + {"Our external address", "Наша зовнішня адреса"}, + {"supported", "підтримується"}, + {"Routers", "Маршрутизатори"}, + {"Floodfills", "Флудфіли"}, + {"Client Tunnels", "Клієнтські Тунелі"}, + {"Transit Tunnels", "Транзитні Тунелі"}, + {"Services", "Сервіси"}, + {"Local Destinations", "Локальні Призначення"}, + {"Encrypted B33 address", "Шифровані B33 адреси"}, + {"Address registration line", "Рядок реєстрації адреси"}, + {"Domain", "Домен"}, + {"Generate", "Згенерувати"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Примітка: отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня (example.i2p). Для реєстрації піддоменів використовуйте i2pd-tools."}, + {"Address", "Адреса"}, + {"Type", "Тип"}, + {"EncType", "ТипШифр"}, + {"Inbound tunnels", "Вхідні тунелі"}, + {"ms", "мс"}, + {"Outbound tunnels", "Вихідні тунелі"}, + {"Tags", "Теги"}, + {"Incoming", "Вхідні"}, + {"Outgoing", "Вихідні"}, + {"Destination", "Призначення"}, + {"Amount", "Кількість"}, + {"Incoming Tags", "Вхідні Теги"}, + {"Tags sessions", "Сесії Тегів"}, + {"Status", "Статус"}, + {"Local Destination", "Локальні Призначення"}, + {"Streams", "Потоки"}, + {"Close stream", "Закрити потік"}, + {"I2CP session not found", "I2CP сесія не знайдена"}, + {"I2CP is not enabled", "I2CP не увікнуто"}, + {"Invalid", "Некоректний"}, + {"Store type", "Тип сховища"}, + {"Expires", "Завершується"}, + {"Non Expired Leases", "Не завершені Lease-и"}, + {"Gateway", "Шлюз"}, + {"TunnelID", "ID тунеля"}, + {"EndDate", "Закінчується"}, + {"not floodfill", "не флудфіл"}, + {"Queue size", "Розмір черги"}, + {"Run peer test", "Запустити тестування"}, + {"Decline transit tunnels", "Відхиляти транзитні тунелі"}, + {"Accept transit tunnels", "Ухвалювати транзитні тунелі"}, + {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, + {"Start graceful shutdown", "Запустити плавну зупинку"}, + {"Force shutdown", "Примусова зупинка"}, + {"Note: any action done here are not persistent and not changes your config files.", "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, + {"Logging level", "Рівень логування"}, + {"Transit tunnels limit", "Обмеження транзитних тунелів"}, + {"Change", "Змінити"}, + {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, + {"SAM disabled", "SAM вимкнуто"}, + {"no sessions currently running", "немає запущених сесій"}, + {"SAM session not found", "SAM сесія не знайдена"}, + {"SAM Session", "SAM сесія"}, + {"Server Tunnels", "Серверні Тунелі"}, + {"Client Forwards", "Клієнтські Переспрямування"}, + {"Server Forwards", "Серверні Переспрямування"}, + {"Unknown page", "Невідома сторінка"}, + {"Invalid token", "Невірний токен"}, + {"SUCCESS", "УСПІШНО"}, + {"Stream closed", "Потік зачинений"}, + {"Stream not found or already was closed", "Потік не знайдений або вже зачинений"}, + {"Destination not found", "Точка призначення не знайдена"}, + {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, + {"Return to destination page", "Повернутися на сторінку точки призначення"}, + {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, + {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, + {"Back to commands list", "Повернутися до списку команд"}, + {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, + {"Description", "Опис"}, + {"A bit information about service on domain", "Трохи інформації про сервіс на домені"}, + {"Submit", "Надіслати"}, + {"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"}, + {"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"}, + {"Such destination is not found", "Така точка призначення не знайдена"}, + {"Unknown command", "Невідома команда"}, + {"Command accepted", "Команда прийнята"}, + {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, {"Proxy error", "Помилка проксі"}, {"Proxy info", "Інформація проксі"}, {"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"}, - {"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі роутера"}, + {"Remote host not found in router's addressbook", "Віддалена адреса не знайдена в адресній книзі маршрутизатора"}, {"You may try to find this host on jump services below", "Ви можете спробувати знайти дану адресу на джамп сервісах нижче"}, {"Invalid request", "Некоректний запит"}, {"Proxy unable to parse your request", "Проксі не може розібрати ваш запит"}, {"addresshelper is not supported", "addresshelper не підтримується"}, {"Host", "Адреса"}, - {"added to router's addressbook from helper", "доданий в адресну книгу роутера через хелпер"}, - {"already in router's addressbook", "вже в адресній книзі роутера"}, + {"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"}, {"Click", "Натисніть"}, {"here", "тут"}, {"to proceed", "щоб продовжити"}, - {"to update record", "щоб оновити запис"}, {"Addresshelper found", "Знайдено addresshelper"}, + {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, + {"to update record", "щоб оновити запис"}, + {"Invalid Request", "Некоректний Запит"}, {"invalid request uri", "некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, @@ -64,169 +192,14 @@ namespace ukrainian // language {"http out proxy not implemented", "підтримка зовнішнього HTTP проксі сервера не реалізована"}, {"cannot connect to upstream http proxy", "не вдалося підключитися до висхідного HTTP проксі сервера"}, {"Host is down", "Вузол недоступний"}, - {"Can't create connection to requested host, it may be down. Please try again later.", - "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."}, - - // Webconsole // - // cssStyles - {"Disabled", "Вимкнуто"}, - {"Enabled", "Увімкнуто"}, - // ShowTraffic - {"KiB", "КіБ"}, - {"MiB", "МіБ"}, - {"GiB", "ГіБ"}, - // ShowTunnelDetails - {"building", "будується"}, - {"failed", "невдалий"}, - {"expiring", "завершується"}, - {"established", "працює"}, - {"exploratory", "дослідницький"}, - {"unknown", "невідомо"}, - {"i2pd webconsole", "Веб-консоль i2pd"}, - // ShowPageHead - {"Main page", "Головна"}, - {"Router commands", "Команди роутера"}, - {"Local destinations", "Локальні призначення"}, - {"LeaseSets", "Лізсети"}, - {"Tunnels", "Тунелі"}, - {"Transit tunnels", "Транзитні тунелі"}, - {"Transports", "Транспорти"}, - {"I2P tunnels", "I2P тунелі"}, - {"SAM sessions", "SAM сесії"}, - // Network Status - {"OK", "OK"}, - {"Testing", "Тестування"}, - {"Firewalled", "Заблоковано ззовні"}, - {"Unknown", "Невідомо"}, - {"Proxy", "Проксі"}, - {"Mesh", "MESH-мережа"}, - {"Error", "Помилка"}, - {"Clock skew", "Неточний час"}, - {"Offline", "Офлайн"}, - {"Symmetric NAT", "Симетричний NAT"}, - // Status - {"Uptime", "В мережі"}, - {"Network status", "Мережевий статус"}, - {"Network status v6", "Мережевий статус v6"}, - {"Stopping in", "Зупинка через"}, - {"Family", "Сімейство"}, - {"Tunnel creation success rate", "Успішно побудованих тунелів"}, - {"Received", "Отримано"}, - {"Sent", "Відправлено"}, - {"Transit", "Транзит"}, - {"KiB/s", "КіБ/с"}, - {"Data path", "Шлях до даних"}, - {"Hidden content. Press on text to see.", "Прихований вміст. Натисніть на текст щоб відобразити."}, - {"Router Ident", "Ідентифікатор Роутера"}, - {"Router Family", "Сімейство Роутера"}, - {"Router Caps", "Прапорці Роутера"}, - {"Version", "Версія"}, - {"Our external address", "Наша зовнішня адреса"}, - {"supported", "підтримується"}, - {"Routers", "Роутери"}, - {"Floodfills", "Флудфіли"}, - {"Client Tunnels", "Клієнтські Тунелі"}, - {"Transit Tunnels", "Транзитні Тунелі"}, - {"Services", "Сервіси"}, - // ShowLocalDestinations - {"Local Destinations", "Локальні Призначення"}, - // ShowLeaseSetDestination - {"Encrypted B33 address", "Шифровані B33 адреси"}, - {"Address registration line", "Рядок реєстрації адреси"}, - {"Domain", "Домен"}, - {"Generate", "Згенерувати"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", - "Примітка: отриманий рядок може бути використаний тільки для реєстрації доменів другого рівня. Для реєстрації піддоменів використовуйте i2pd-tools."}, - {"Address", "Адреса"}, - {"Type", "Тип"}, - {"EncType", "ТипШифр"}, - {"Inbound tunnels", "Вхідні тунелі"}, - {"Outbound tunnels", "Вихідні тунелі"}, - {"ms", "мс"}, // milliseconds - {"Tags", "Теги"}, - {"Incoming", "Вхідні"}, - {"Outgoing", "Вихідні"}, - {"Destination", "Призначення"}, - {"Amount", "Кількість"}, - {"Incoming Tags", "Вхідні Теги"}, - {"Tags sessions", "Сесії тегів"}, - {"Status", "Статус"}, - // ShowLocalDestination - {"Local Destination", "Локальні Призначення"}, - {"Streams", "Потоки"}, - {"Close stream", "Закрити потік"}, - // ShowI2CPLocalDestination - {"I2CP session not found", "I2CP сесія не знайдена"}, - {"I2CP is not enabled", "I2CP не увікнуто"}, - // ShowLeasesSets - {"Invalid", "Некоректний"}, - {"Store type", "Тип сховища"}, - {"Expires", "Завершується"}, - {"Non Expired Leases", "Не завершені Lease-и"}, - {"Gateway", "Шлюз"}, - {"TunnelID", "ID тунеля"}, - {"EndDate", "Закінчується"}, - {"not floodfill", "не флудфіл"}, - // ShowTunnels - {"Queue size", "Розмір черги"}, - // ShowCommands - {"Run peer test", "Запустити тестування"}, - {"Decline transit tunnels", "Відхиляти транзитні тунелі"}, - {"Accept transit tunnels", "Ухвалювати транзитні тунелі"}, - {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, - {"Start graceful shutdown", "Запустити плавну зупинку"}, - {"Force shutdown", "Примусова зупинка"}, - {"Note: any action done here are not persistent and not changes your config files.", - "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, - {"Logging level", "Рівень логування"}, - {"Transit tunnels limit", "Обмеження транзитних тунелів"}, - {"Change", "Змінити"}, - // ShowTransitTunnels - {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, - // ShowSAMSessions/ShowSAMSession - {"SAM disabled", "SAM вимкнуто"}, - {"SAM session not found", "SAM сесія не знайдена"}, - {"no sessions currently running", "немає запущених сесій"}, - {"SAM Session", "SAM сесія"}, - // ShowI2PTunnels - {"Server Tunnels", "Серверні Тунелі"}, - {"Client Forwards", "Клієнтські Переспрямування"}, - {"Server Forwards", "Серверні Переспрямування"}, - // HandlePage - {"Unknown page", "Невідома сторінка"}, - // HandleCommand, ShowError - {"Invalid token", "Невірний токен"}, - {"SUCCESS", "УСПІШНО"}, - {"ERROR", "ПОМИЛКА"}, - {"Unknown command", "Невідома команда"}, - {"Command accepted", "Команда прийнята"}, - {"Back to commands list", "Повернутися до списку команд"}, - {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, - // HTTP_COMMAND_KILLSTREAM - {"Stream closed", "Потік зачинений"}, - {"Stream not found or already was closed", "Потік не знайдений або вже зачинений"}, - {"Destination not found", "Точка призначення не знайдена"}, - {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, - {"Return to destination page", "Повернутися на сторінку точки призначення"}, - {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, - // HTTP_COMMAND_LIMITTRANSIT - {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, - // HTTP_COMMAND_GET_REG_STRING - {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, - {"Description", "Опис"}, - {"A bit information about service on domain", "Трохи інформації про сервіс на домені"}, - {"Submit", "Надіслати"}, - {"Domain can't end with .b32.i2p", "Домен не може закінчуватися на .b32.i2p"}, - {"Domain must end with .i2p", "Домен повинен закінчуватися на .i2p"}, - {"Such destination is not found", "Така точка призначення не знайдена"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Не вдалося встановити з'єднання до запитаного вузла, можливо він не в мережі. Спробуйте повторити запит пізніше."}, {"", ""}, }; static std::map> plurals { - // ShowUptime - {"days", {"день", "дня", "днів"}}, - {"hours", {"годину", "години", "годин"}}, + {"days", {"день", "дня", "днів"}}, + {"hours", {"годину", "години", "годин"}}, {"minutes", {"хвилину", "хвилини", "хвилин"}}, {"seconds", {"секунду", "секунди", "секунд"}}, {"", {"", "", ""}}, From f7f50d049b98366726a6fd2518c109930f23e997 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 22 Jun 2021 13:11:02 -0400 Subject: [PATCH 0186/2193] reduce short tunnel build record length --- libi2pd/I2NPProtocol.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index ee143734..cc7c94af 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -55,7 +55,7 @@ namespace i2p // TunnelBuild const size_t TUNNEL_BUILD_RECORD_SIZE = 528; - const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 236; + const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 218; //BuildRequestRecordClearText const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; @@ -113,7 +113,7 @@ namespace i2p const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1; const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; - const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 172; + const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154; enum I2NPMessageType { From 3c076654794c619eed228adcac075e9c1dea732f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 22 Jun 2021 15:35:44 -0400 Subject: [PATCH 0187/2193] use unordered_map for incomplete messages --- libi2pd/TunnelEndpoint.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index 43b836f1..6466df3a 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -11,6 +11,7 @@ #include #include +#include #include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -54,7 +55,7 @@ namespace tunnel private: - std::map m_IncompleteMessages; + std::unordered_map m_IncompleteMessages; std::map, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; From f5db34b98b4a081bdfac694c82eb5ebe4f3c171b Mon Sep 17 00:00:00 2001 From: idk Date: Wed, 23 Jun 2021 11:18:53 -0400 Subject: [PATCH 0188/2193] C_InitI2P is compatible with more things if it passes argv by reference, it would appear. So to pass arguments to InitI2P you need to turn them back into char* argv[] by tokenizing them and copying them into an array which you then pass to InitI2P from C_InitI2P. The Streaming and Destination Creation parts need to have wrappers for over Identity.h, Streaming.h to be useful so remove them. --- Makefile | 47 ++++--------------- libi2pd/api.go | 5 +-- libi2pd/api.swigcxx | 8 ---- libi2pd/capi.cpp | 107 ++++++++++++++++++++++++++------------------ libi2pd/capi.h | 17 ------- 5 files changed, 73 insertions(+), 111 deletions(-) diff --git a/Makefile b/Makefile index 62a64584..72e68118 100644 --- a/Makefile +++ b/Makefile @@ -28,12 +28,6 @@ else LD_DEBUG = -s endif -ifeq ($(USE_STATIC),yes) - NEEDED_CXXFLAGS+= -static -else - -endif - ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) @@ -76,9 +70,9 @@ mk_obj_dir: @mkdir -p obj/$(LANG_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api: mk_obj_dir $(SHLIB) $(ARLIB) +client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time @@ -97,31 +91,30 @@ obj/%.o: %.cpp $(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) +$(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif -$(SHLIB_LANG): $(LANG_OBJS) +$(SHLIB_LANG): $(LANG_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(ARLIB): $(LIB_OBJS) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ -$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ -$(ARLIB_LANG): $(LANG_OBJS) +$(ARLIB_LANG): $(LANG_OBJS) $(AR) -r $@ $^ - clean: $(RM) -r obj $(RM) -r docs/generated @@ -154,25 +147,3 @@ doxygen: .PHONY: mk_obj_dir .PHONY: install .PHONY: strip - -flags: - @echo $(CXXFLAGS) - @echo $(NEEDED_CXXFLAGS) - @echo $(INCFLAGS) - @echo $(LDFLAGS) - @echo $(LDLIBS) - @echo $(USE_AESNI) - @echo $(USE_STATIC) - @echo $(USE_MESHNET) - @echo $(USE_UPNP) - @echo $(DEBUG) - -##TODO: delete this before a PR -testc: api api_client - g++ -Ii18n -c _test.c -o test.o -# gcc -llibi2pd.so -c _test.c -o test.o -# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -Ilibi2pd -Ilibi2pd_client -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so -# $(CXX) $(LDFLAGS) $(LDLIBS) -static -Ii18n -g -Wall -o test.o _test.c libi2pd.a libi2pdclient.a #obj/libi2pd/*.o obj/i18n/*.o #libi2pd.so -# gcc -o i2pd _test.c libi2pd.a -lstdc++ -llibi2pd -Llibi2pd -# gcc -Ii18n -I/usr/include/c++/10 -I/usr/include/x86_64-linux-gnu/c++/10 -llibi2pd.a -c test.c -o test.o - g++ test.o libi2pd.a libi2pdclient.a libi2pdlang.a -o test.main \ No newline at end of file diff --git a/libi2pd/api.go b/libi2pd/api.go index d7a19bc9..48a41a4f 100644 --- a/libi2pd/api.go +++ b/libi2pd/api.go @@ -1,10 +1,7 @@ package api /* -//void Go_InitI2P (int argc, char argv[], const char * appName){ - -//} -#cgo CPPFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes +#cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes #cgo LDFLAGS: -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ */ import "C" diff --git a/libi2pd/api.swigcxx b/libi2pd/api.swigcxx index fbb1b95a..3ef6bd36 100644 --- a/libi2pd/api.swigcxx +++ b/libi2pd/api.swigcxx @@ -3,14 +3,6 @@ %{ #include "capi.h" -//#include "Streaming.h" -//#include "Destination.h" -//#include "Identity.h" -//#include "Tag.h" %} %include "capi.h" -//%include "Streaming.h" -//%include "Destination.h" -//%include "Identity.h" -//%include "Tag.h" \ No newline at end of file diff --git a/libi2pd/capi.cpp b/libi2pd/capi.cpp index 1a2498b6..55b1b051 100644 --- a/libi2pd/capi.cpp +++ b/libi2pd/capi.cpp @@ -8,6 +8,64 @@ #include "api.h" #include "capi.h" +#include +#include +#include +#include + + +// Uses the example from: https://stackoverflow.com/a/9210560 +// See also https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c/9210560# +// Does not handle consecutive delimiters, this is only for passing +// lists of arguments by value to InitI2P from C_InitI2P +char** str_split(char* a_str, const char a_delim) +{ + char** result = 0; + size_t count = 0; + char* tmp = a_str; + char* last_comma = 0; + char delim[2]; + delim[0] = a_delim; + delim[1] = 0; + + /* Count how many elements will be extracted. */ + while (*tmp) + { + if (a_delim == *tmp) + { + count++; + last_comma = tmp; + } + tmp++; + } + + /* Add space for trailing token. */ + count += last_comma < (a_str + strlen(a_str) - 1); + + /* Add space for terminating null string so caller + knows where the list of returned strings ends. */ + count++; + + result = (char**) malloc(sizeof(char*) * count); + + if (result) + { + size_t idx = 0; + char* token = strtok(a_str, delim); + + while (token) + { + assert(idx < count); + *(result + idx++) = strdup(token); + token = strtok(0, delim); + } + assert(idx == count - 1); + *(result + idx) = 0; + } + + return result; +} + #ifdef __cplusplus extern "C" { @@ -15,7 +73,11 @@ extern "C" { void C_InitI2P (int argc, char argv[], const char * appName) { - return i2p::api::InitI2P(argc, &argv, appName); + const char* delim = " "; + char* vargs = strdup(argv); + char** args = str_split(vargs, *delim); + std::cout << argv; + return i2p::api::InitI2P(argc, args, appName); } void C_TerminateI2P () @@ -40,49 +102,6 @@ void C_RunPeerTest () return i2p::api::RunPeerTest(); } -i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, - const std::map * params) -{ - return i2p::api::CreateLocalDestination(keys, isPublic, params).get(); -} - -i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, - const std::map * params) -{ - return i2p::api::CreateLocalDestination(isPublic, sigType, params).get(); -} - -void C_DestroyLocalDestination (i2p::client::ClientDestination *dest) -{ - std::shared_ptr cppDest(dest); - return i2p::api::DestroyLocalDestination(cppDest); -} - -void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) -{ - std::shared_ptr cppDest(dest); - return i2p::api::RequestLeaseSet(cppDest, remote); -} - -i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote) -{ - std::shared_ptr cppDest(dest); - return i2p::api::CreateStream(cppDest, remote).get(); -} - -void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor) -{ - std::shared_ptr cppDest(dest); - return i2p::api::AcceptStream(cppDest, acceptor); -} - -void C_DestroyStream (i2p::stream::Stream *stream) -{ - std::shared_ptr cppStream(stream); - return i2p::api::DestroyStream(cppStream); -} - - #ifdef __cplusplus } #endif diff --git a/libi2pd/capi.h b/libi2pd/capi.h index 8395cfca..3e33a0ee 100644 --- a/libi2pd/capi.h +++ b/libi2pd/capi.h @@ -9,10 +9,6 @@ #ifndef CAPI_H__ #define CAPI_H__ -#include "Identity.h" -#include "Destination.h" -#include "Streaming.h" - #ifdef __cplusplus extern "C" { #endif @@ -26,19 +22,6 @@ void C_StartI2P (); //std::ostream *logStream = nullptr); void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP -// destinations -i2p::client::ClientDestination *C_CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, - const std::map * params = nullptr); -i2p::client::ClientDestination *C_CreateTransientLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256, - const std::map * params = nullptr); // transient destinations usually not published -void C_DestroyLocalDestination (i2p::client::ClientDestination *dest); - -// streams -void C_RequestLeaseSet (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); -i2p::stream::Stream *C_CreateStream (i2p::client::ClientDestination *dest, const i2p::data::IdentHash& remote); -void C_AcceptStream (i2p::client::ClientDestination *dest, const i2p::stream::StreamingDestination::Acceptor& acceptor); -void C_DestroyStream (i2p::stream::Stream *stream); - #ifdef __cplusplus } #endif From f9d9aa0306eae1c19849e7ea40d0cfb2a15eb76d Mon Sep 17 00:00:00 2001 From: idk Date: Thu, 24 Jun 2021 09:35:42 -0400 Subject: [PATCH 0189/2193] move wrapper code to own directory --- Makefile | 14 ++++++++++++++ filelist.mk | 2 ++ {libi2pd => libi2pd_wrapper}/api.go | 0 {libi2pd => libi2pd_wrapper}/api.swigcxx | 0 {libi2pd => libi2pd_wrapper}/capi.cpp | 0 {libi2pd => libi2pd_wrapper}/capi.h | 0 6 files changed, 16 insertions(+) rename {libi2pd => libi2pd_wrapper}/api.go (100%) rename {libi2pd => libi2pd_wrapper}/api.swigcxx (100%) rename {libi2pd => libi2pd_wrapper}/capi.cpp (100%) rename {libi2pd => libi2pd_wrapper}/capi.h (100%) diff --git a/Makefile b/Makefile index 72e68118..59faa94b 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,13 @@ SHLIB_LANG := libi2pdlang.so ARLIB_LANG := libi2pdlang.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a +SHLIB_WRAP := libi2pdwrapper.so +ARLIB_WRAP := libi2pdwrapper.a I2PD := i2pd LIB_SRC_DIR := libi2pd LIB_CLIENT_SRC_DIR := libi2pd_client +WRAP_SRC_DIR := libi2pd_wrapper LANG_SRC_DIR := i18n DAEMON_SRC_DIR := daemon @@ -56,6 +59,7 @@ NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SR LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) +WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC)) LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) @@ -68,11 +72,13 @@ mk_obj_dir: @mkdir -p obj/$(LIB_SRC_DIR) @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) @mkdir -p obj/$(LANG_SRC_DIR) + @mkdir -p obj/$(WRAP_SRC_DIR) @mkdir -p obj/$(DAEMON_SRC_DIR) api: mk_obj_dir $(SHLIB) $(ARLIB) client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) langs: mk_obj_dir $(LANG_OBJS) $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time @@ -101,6 +107,11 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif +$(SHLIB_WRAP): $(WRAP_LIB_OBJS) +ifneq ($(USE_STATIC),yes) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) +endif + $(SHLIB_LANG): $(LANG_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) @@ -112,6 +123,9 @@ $(ARLIB): $(LIB_OBJS) $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ +$(ARLIB_WRAP): $(LIB_OBJS) + $(AR) -r $@ $^ + $(ARLIB_LANG): $(LANG_OBJS) $(AR) -r $@ $^ diff --git a/filelist.mk b/filelist.mk index e2a5d40e..d8f503e6 100644 --- a/filelist.mk +++ b/filelist.mk @@ -21,4 +21,6 @@ LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp) LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp) +WRAP_LIB_SRC = $(wildcard $(WRAP_SRC_DIR)/*.cpp) + DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp) diff --git a/libi2pd/api.go b/libi2pd_wrapper/api.go similarity index 100% rename from libi2pd/api.go rename to libi2pd_wrapper/api.go diff --git a/libi2pd/api.swigcxx b/libi2pd_wrapper/api.swigcxx similarity index 100% rename from libi2pd/api.swigcxx rename to libi2pd_wrapper/api.swigcxx diff --git a/libi2pd/capi.cpp b/libi2pd_wrapper/capi.cpp similarity index 100% rename from libi2pd/capi.cpp rename to libi2pd_wrapper/capi.cpp diff --git a/libi2pd/capi.h b/libi2pd_wrapper/capi.h similarity index 100% rename from libi2pd/capi.h rename to libi2pd_wrapper/capi.h From d0c5732e16d28f0be86c4026ef23e0b70518f8ea Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jun 2021 07:18:42 -0400 Subject: [PATCH 0190/2193] eliminate extra lookups for sequential fragments --- libi2pd/TunnelEndpoint.cpp | 143 +++++++++++++++++++++++++++---------- libi2pd/TunnelEndpoint.h | 12 ++-- 2 files changed, 113 insertions(+), 42 deletions(-) diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index eb70bdca..a07230cb 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -52,11 +52,13 @@ namespace tunnel bool isFollowOnFragment = flag & 0x80, isLastFragment = true; uint32_t msgID = 0; int fragmentNum = 0; - TunnelMessageBlockEx m; + TunnelMessageBlockEx& m = m_CurrentMessage; if (!isFollowOnFragment) { // first fragment - + if (m_CurrentMsgID) + AddIncompleteCurrentMessage (); // we have got a new message while previous is not complete + m.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03); switch (m.deliveryType) { @@ -81,6 +83,7 @@ namespace tunnel // Message ID msgID = bufbe32toh (fragment); fragment += 4; + m_CurrentMsgID = msgID; isLastFragment = false; } } @@ -96,11 +99,20 @@ namespace tunnel uint16_t size = bufbe16toh (fragment); fragment += 2; + if (isFollowOnFragment && m_CurrentMsgID && m_CurrentMsgID == msgID && + m_CurrentMessage.nextFragmentNum == fragmentNum) + { + HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); + fragment += size; + continue; + } + msg->offset = fragment - msg->buf; msg->len = msg->offset + size; if (msg->len > msg->maxLen) { LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; return; } if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) @@ -114,31 +126,31 @@ namespace tunnel else m.data = msg; - if (!isFollowOnFragment && isLastFragment) - HandleNextMessage (m); + if (!isFollowOnFragment) + { + if (isLastFragment) + { + HandleNextMessage (m); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + else if (msgID) + { + m_CurrentMessage.nextFragmentNum = 1; + m_CurrentMessage.receiveTime = i2p::util::GetMillisecondsSinceEpoch (); + HandleOutOfSequenceFragments (msgID, m_CurrentMessage); + } + else + { + LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented"); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + } else { - if (msgID) // msgID is presented, assume message is fragmented - { - if (!isFollowOnFragment) // create new incomlete message - { - m.nextFragmentNum = 1; - m.receiveTime = i2p::util::GetMillisecondsSinceEpoch (); - auto ret = m_IncompleteMessages.insert (std::pair(msgID, m)); - if (ret.second) - HandleOutOfSequenceFragments (msgID, ret.first->second); - else - LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists"); - } - else - { - m.nextFragmentNum = fragmentNum; - HandleFollowOnFragment (msgID, isLastFragment, m); - } - } - else - LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented"); - } + m.nextFragmentNum = fragmentNum; + HandleFollowOnFragment (msgID, isLastFragment, m); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } fragment += size; } @@ -157,17 +169,8 @@ namespace tunnel auto& msg = it->second; if (m.nextFragmentNum == msg.nextFragmentNum) { - if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long + if (ConcatFollowOnFragment (msg, fragment, size)) { - if (msg.data->len + size > msg.data->maxLen) - { - // LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough"); - auto newMsg = NewI2NPMessage (); - *newMsg = *(msg.data); - msg.data = newMsg; - } - if (msg.data->Concat (fragment, size) < size) // concatenate fragment - LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen); if (isLastFragment) { // message complete @@ -199,9 +202,67 @@ namespace tunnel } } + bool TunnelEndpoint::ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const + { + if (msg.data->len + size < I2NP_MAX_MESSAGE_SIZE) // check if message is not too long + { + if (msg.data->len + size > msg.data->maxLen) + { + // LogPrint (eLogWarning, "TunnelMessage: I2NP message size ", msg.data->maxLen, " is not enough"); + auto newMsg = NewI2NPMessage (); + *newMsg = *(msg.data); + msg.data = newMsg; + } + if (msg.data->Concat (fragment, size) < size) // concatenate fragment + { + LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen); + return false; + } + } + else + return false; + return true; + } + + void TunnelEndpoint::HandleCurrenMessageFollowOnFragment (const uint8_t * fragment, size_t size, bool isLastFragment) + { + if (ConcatFollowOnFragment (m_CurrentMessage, fragment, size)) + { + if (isLastFragment) + { + // message complete + HandleNextMessage (m_CurrentMessage); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + else + { + m_CurrentMessage.nextFragmentNum++; + HandleOutOfSequenceFragments (m_CurrentMsgID, m_CurrentMessage); + } + } + else + { + LogPrint (eLogError, "TunnelMessage: Fragment ", m_CurrentMessage.nextFragmentNum, " of message ", m_CurrentMsgID, " exceeds max I2NP message size, message dropped"); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } + } + + void TunnelEndpoint::AddIncompleteCurrentMessage () + { + if (m_CurrentMsgID) + { + auto ret = m_IncompleteMessages.emplace (m_CurrentMsgID, m_CurrentMessage); + if (!ret.second) + LogPrint (eLogError, "TunnelMessage: Incomplete message ", m_CurrentMsgID, " already exists"); + m_CurrentMessage.data = nullptr; + m_CurrentMsgID = 0; + } + } + void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data) { - if (!m_OutOfSequenceFragments.insert ({{msgID, fragmentNum}, {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second) + if (!m_OutOfSequenceFragments.insert ({(uint64_t)msgID << 32 | fragmentNum, + {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second) LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID); } @@ -212,7 +273,13 @@ namespace tunnel if (!msg.nextFragmentNum) // message complete { HandleNextMessage (msg); - m_IncompleteMessages.erase (msgID); + if (&msg == &m_CurrentMessage) + { + m_CurrentMsgID = 0; + m_CurrentMessage.data = nullptr; + } + else + m_IncompleteMessages.erase (msgID); break; } } @@ -220,7 +287,7 @@ namespace tunnel bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg) { - auto it = m_OutOfSequenceFragments.find ({msgID, msg.nextFragmentNum}); + auto it = m_OutOfSequenceFragments.find ((uint64_t)msgID << 32 | msg.nextFragmentNum); if (it != m_OutOfSequenceFragments.end ()) { LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)msg.nextFragmentNum, " of message ", msgID, " found"); diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index 6466df3a..70514e35 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -10,7 +10,6 @@ #define TUNNEL_ENDPOINT_H__ #include -#include #include #include #include "I2NPProtocol.h" @@ -37,7 +36,7 @@ namespace tunnel public: - TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0) {}; + TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0), m_CurrentMsgID (0) {}; ~TunnelEndpoint (); size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; void Cleanup (); @@ -47,18 +46,23 @@ namespace tunnel private: void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m); + bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success + void HandleCurrenMessageFollowOnFragment (const uint8_t * frgament, size_t size, bool isLastFragment); void HandleNextMessage (const TunnelMessageBlock& msg); void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data); bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg); - + void AddIncompleteCurrentMessage (); + private: std::unordered_map m_IncompleteMessages; - std::map, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment + std::unordered_map m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; + TunnelMessageBlockEx m_CurrentMessage; + uint32_t m_CurrentMsgID; }; } } From da20cae25ca13f66603d9095fff208fc066829a8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 26 Jun 2021 18:59:48 +0300 Subject: [PATCH 0191/2193] [webconsole] urldecode domain for registration string generator Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7eb296c4..0b9e8f0f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1281,7 +1281,7 @@ namespace http { else if (cmd == HTTP_COMMAND_GET_REG_STRING) { std::string b32 = params["b32"]; - std::string name = params["name"]; + std::string name = i2p::http::UrlDecode(params["name"]); i2p::data::IdentHash ident; ident.FromBase32 (b32); From 377a50fa1301063e2c3398a87ec0e84790e8659e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 26 Jun 2021 23:45:55 +0300 Subject: [PATCH 0192/2193] [make] build translations as library Signed-off-by: R4SAS --- Makefile | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 40e72918..4117234e 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ SHLIB := libi2pd.so ARLIB := libi2pd.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a +SHLIB_LANG := libi2pdlang.so +ARLIB_LANG := libi2pdlang.a I2PD := i2pd LIB_SRC_DIR := libi2pd @@ -71,6 +73,7 @@ mk_obj_dir: api: mk_obj_dir $(SHLIB) $(ARLIB) client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -85,7 +88,7 @@ obj/%.o: %.cpp # '-' is 'ignore if missing' on first run -include $(DEPS) -$(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) +$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) $(SHLIB): $(LIB_OBJS) @@ -98,18 +101,26 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) endif +$(SHLIB_LANG): $(LANG_OBJS) +ifneq ($(USE_STATIC),yes) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) +endif + $(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ +$(ARLIB_LANG): $(LANG_OBJS) + $(AR) -r $@ $^ + clean: $(RM) -r obj $(RM) -r docs/generated - $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) + $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) -strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB) +strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) strip $^ LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl) @@ -133,6 +144,7 @@ doxygen: .PHONY: api .PHONY: api_client .PHONY: client +.PHONY: lang .PHONY: mk_obj_dir .PHONY: install .PHONY: strip From 9fb8e8a582e8f23e39da0c635ee8c0efe4fcf0c5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 26 Jun 2021 23:59:34 +0300 Subject: [PATCH 0193/2193] [cmake] build translations as library Signed-off-by: R4SAS --- .gitignore | 2 ++ build/CMakeLists.txt | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2506fd93..1fc6cefe 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,10 @@ netDb /i2pd /libi2pd.a /libi2pdclient.a +/libi2pdlang.a /libi2pd.so /libi2pdclient.so +/libi2pdlang.so *.exe diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d1b51f23..d1502deb 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -69,6 +69,16 @@ if(WITH_LIBRARY) endif() FILE(GLOB LANG_SRC ${LANG_SRC_DIR}/*.cpp) +add_library(libi2pdlang ${LANG_SRC}) +set_target_properties(libi2pdlang PROPERTIES PREFIX "") + +if(WITH_LIBRARY) + install(TARGETS libi2pdlang + EXPORT libi2pdlang + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + COMPONENT Libraries) +endif() set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" @@ -198,10 +208,11 @@ if(WITH_PCH) ) target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) + target_compile_options(libi2pdlang PRIVATE -include libi2pd/stdafx.h) target_link_libraries(libi2pd stdafx) endif() -target_link_libraries(libi2pdclient libi2pd) +target_link_libraries(libi2pdclient libi2pd libi2pdlang) find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED) if(NOT DEFINED Boost_INCLUDE_DIRS) @@ -265,7 +276,7 @@ message(STATUS "---------------------------------------") include(GNUInstallDirs) if(WITH_BINARY) - add_executable("${PROJECT_NAME}" ${LANG_SRC} ${DAEMON_SRC}) + add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) if(WITH_STATIC) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") @@ -295,7 +306,7 @@ if(WITH_BINARY) endif() target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY}) - target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + target_link_libraries("${PROJECT_NAME}" libi2pd libi2pdclient libi2pdlang ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${UPNP_LIB} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") From b9476791f4b6b2a46f5f2fc59d491c5d34b85db1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jun 2021 17:40:25 -0400 Subject: [PATCH 0194/2193] eliminated extra I2NP messages for fragments --- libi2pd/TunnelEndpoint.cpp | 115 +++++++++++++++++++------------------ libi2pd/TunnelEndpoint.h | 10 ++-- 2 files changed, 65 insertions(+), 60 deletions(-) diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index a07230cb..70004ede 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -52,26 +52,25 @@ namespace tunnel bool isFollowOnFragment = flag & 0x80, isLastFragment = true; uint32_t msgID = 0; int fragmentNum = 0; - TunnelMessageBlockEx& m = m_CurrentMessage; if (!isFollowOnFragment) { // first fragment if (m_CurrentMsgID) AddIncompleteCurrentMessage (); // we have got a new message while previous is not complete - m.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03); - switch (m.deliveryType) + m_CurrentMessage.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03); + switch (m_CurrentMessage.deliveryType) { case eDeliveryTypeLocal: // 0 break; case eDeliveryTypeTunnel: // 1 - m.tunnelID = bufbe32toh (fragment); + m_CurrentMessage.tunnelID = bufbe32toh (fragment); fragment += 4; // tunnelID - m.hash = i2p::data::IdentHash (fragment); + m_CurrentMessage.hash = i2p::data::IdentHash (fragment); fragment += 32; // hash break; case eDeliveryTypeRouter: // 2 - m.hash = i2p::data::IdentHash (fragment); + m_CurrentMessage.hash = i2p::data::IdentHash (fragment); fragment += 32; // to hash break; default: ; @@ -99,42 +98,51 @@ namespace tunnel uint16_t size = bufbe16toh (fragment); fragment += 2; - if (isFollowOnFragment && m_CurrentMsgID && m_CurrentMsgID == msgID && - m_CurrentMessage.nextFragmentNum == fragmentNum) - { - HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); - fragment += size; - continue; + // handle fragment + if (isFollowOnFragment) + { + // existing message + if (m_CurrentMsgID && m_CurrentMsgID == msgID && m_CurrentMessage.nextFragmentNum == fragmentNum) + HandleCurrenMessageFollowOnFragment (fragment, size, isLastFragment); // previous + else + { + HandleFollowOnFragment (msgID, isLastFragment, fragmentNum, fragment, size); // another + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + } } - - msg->offset = fragment - msg->buf; - msg->len = msg->offset + size; - if (msg->len > msg->maxLen) - { - LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size); - m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; - return; - } - if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) - { - // this is not last message. we have to copy it - m.data = NewI2NPTunnelMessage (); - m.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - m.data->len += TUNNEL_GATEWAY_HEADER_SIZE; - *(m.data) = *msg; - } else - m.data = msg; - - if (!isFollowOnFragment) - { + { + // new message + msg->offset = fragment - msg->buf; + msg->len = msg->offset + size; + // check message size + if (msg->len > msg->maxLen) + { + LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size); + m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; + return; + } + // create new or assign I2NP message + if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) + { + // this is not last message. we have to copy it + m_CurrentMessage.data = NewI2NPTunnelMessage (); + m_CurrentMessage.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + m_CurrentMessage.data->len += TUNNEL_GATEWAY_HEADER_SIZE; + *(m_CurrentMessage.data) = *msg; + } + else + m_CurrentMessage.data = msg; + if (isLastFragment) { - HandleNextMessage (m); + // single message + HandleNextMessage (m_CurrentMessage); m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; } else if (msgID) { + // first fragment of a new message m_CurrentMessage.nextFragmentNum = 1; m_CurrentMessage.receiveTime = i2p::util::GetMillisecondsSinceEpoch (); HandleOutOfSequenceFragments (msgID, m_CurrentMessage); @@ -145,13 +153,7 @@ namespace tunnel m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; } } - else - { - m.nextFragmentNum = fragmentNum; - HandleFollowOnFragment (msgID, isLastFragment, m); - m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr; - } - + fragment += size; } } @@ -159,15 +161,14 @@ namespace tunnel LogPrint (eLogError, "TunnelMessage: zero not found"); } - void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m) + void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, + uint8_t fragmentNum, const uint8_t * fragment, size_t size) { - auto fragment = m.data->GetBuffer (); - auto size = m.data->GetLength (); auto it = m_IncompleteMessages.find (msgID); if (it != m_IncompleteMessages.end()) { auto& msg = it->second; - if (m.nextFragmentNum == msg.nextFragmentNum) + if (fragmentNum == msg.nextFragmentNum) { if (ConcatFollowOnFragment (msg, fragment, size)) { @@ -185,20 +186,20 @@ namespace tunnel } else { - LogPrint (eLogError, "TunnelMessage: Fragment ", m.nextFragmentNum, " of message ", msgID, "exceeds max I2NP message size, message dropped"); + LogPrint (eLogError, "TunnelMessage: Fragment ", fragmentNum, " of message ", msgID, "exceeds max I2NP message size, message dropped"); m_IncompleteMessages.erase (it); } } else { - LogPrint (eLogWarning, "TunnelMessage: Unexpected fragment ", (int)m.nextFragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ", saved"); - AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data); + LogPrint (eLogWarning, "TunnelMessage: Unexpected fragment ", (int)fragmentNum, " instead ", (int)msg.nextFragmentNum, " of message ", msgID, ", saved"); + AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size); } } else { LogPrint (eLogWarning, "TunnelMessage: First fragment of message ", msgID, " not found, saved"); - AddOutOfSequenceFragment (msgID, m.nextFragmentNum, isLastFragment, m.data); + AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size); } } @@ -259,10 +260,12 @@ namespace tunnel } } - void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data) + void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, + bool isLastFragment, const uint8_t * fragment, size_t size) { - if (!m_OutOfSequenceFragments.insert ({(uint64_t)msgID << 32 | fragmentNum, - {isLastFragment, data, i2p::util::GetMillisecondsSinceEpoch () }}).second) + std::unique_ptr f(new Fragment (isLastFragment, i2p::util::GetMillisecondsSinceEpoch (), size)); + memcpy (f->data.data (), fragment, size); + if (!m_OutOfSequenceFragments.emplace ((uint64_t)msgID << 32 | fragmentNum, std::move (f)).second) LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID); } @@ -291,7 +294,7 @@ namespace tunnel if (it != m_OutOfSequenceFragments.end ()) { LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)msg.nextFragmentNum, " of message ", msgID, " found"); - size_t size = it->second.data->GetLength (); + size_t size = it->second->data.size (); if (msg.data->len + size > msg.data->maxLen) { LogPrint (eLogWarning, "TunnelMessage: Tunnel endpoint I2NP message size ", msg.data->maxLen, " is not enough"); @@ -299,9 +302,9 @@ namespace tunnel *newMsg = *(msg.data); msg.data = newMsg; } - if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment + if (msg.data->Concat (it->second->data.data (), size) < size) // concatenate out-of-sync fragment LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); - if (it->second.isLastFragment) + if (it->second->isLastFragment) // message complete msg.nextFragmentNum = 0; else @@ -354,7 +357,7 @@ namespace tunnel // out-of-sequence fragments for (auto it = m_OutOfSequenceFragments.begin (); it != m_OutOfSequenceFragments.end ();) { - if (ts > it->second.receiveTime + i2p::I2NP_MESSAGE_EXPIRATION_TIMEOUT) + if (ts > it->second->receiveTime + i2p::I2NP_MESSAGE_EXPIRATION_TIMEOUT) it = m_OutOfSequenceFragments.erase (it); else ++it; diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index 70514e35..f9878165 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -11,6 +11,7 @@ #include #include +#include #include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -29,9 +30,10 @@ namespace tunnel struct Fragment { + Fragment (bool last, uint64_t t, size_t size): isLastFragment (last), receiveTime (t), data (size) {}; bool isLastFragment; - std::shared_ptr data; uint64_t receiveTime; // milliseconds since epoch + std::vector data; }; public: @@ -45,12 +47,12 @@ namespace tunnel private: - void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, const TunnelMessageBlockEx& m); + void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, uint8_t fragmentNum, const uint8_t * fragment, size_t size); bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success void HandleCurrenMessageFollowOnFragment (const uint8_t * frgament, size_t size, bool isLastFragment); void HandleNextMessage (const TunnelMessageBlock& msg); - void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr data); + void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, const uint8_t * fragment, size_t size); bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg); void AddIncompleteCurrentMessage (); @@ -58,7 +60,7 @@ namespace tunnel private: std::unordered_map m_IncompleteMessages; - std::unordered_map m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment + std::unordered_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; TunnelMessageBlockEx m_CurrentMessage; From 66422d6d837ce25f4cf7eb2b90fa6f9e5f9a9d22 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Jun 2021 21:44:51 -0400 Subject: [PATCH 0195/2193] double size tunnel message --- libi2pd/I2NPProtocol.cpp | 3 ++- libi2pd/TunnelEndpoint.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 7c4d84c3..f570a2a1 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -38,7 +38,8 @@ namespace i2p std::shared_ptr NewI2NPTunnelMessage () { - auto msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 + // should fit two tunnel message, enough for one garlic encrypted streaming packet + auto msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12 msg->Align (12); return std::shared_ptr(msg); } diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 70004ede..109f3120 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -198,7 +198,7 @@ namespace tunnel } else { - LogPrint (eLogWarning, "TunnelMessage: First fragment of message ", msgID, " not found, saved"); + LogPrint (eLogDebug, "TunnelMessage: First fragment of message ", msgID, " not found, saved"); AddOutOfSequenceFragment (msgID, fragmentNum, isLastFragment, fragment, size); } } @@ -283,6 +283,7 @@ namespace tunnel } else m_IncompleteMessages.erase (msgID); + LogPrint (eLogDebug, "TunnelMessage: All fragments of message ", msgID, " found"); break; } } From 6d2c9e367bb35e0d3b4d19db734a243744a92fc9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 27 Jun 2021 12:24:41 +0300 Subject: [PATCH 0196/2193] remove unused CI and docker files Signed-off-by: R4SAS --- .travis.yml | 54 ---------------------- appveyor.yml | 57 ------------------------ build/docker/README.md | 34 -------------- build/docker/old-ubuntu-based/Dockerfile | 11 ----- build/fig.yml | 2 - contrib/docker/Dockerfile | 2 +- 6 files changed, 1 insertion(+), 159 deletions(-) delete mode 100644 .travis.yml delete mode 100644 appveyor.yml delete mode 100644 build/docker/README.md delete mode 100644 build/docker/old-ubuntu-based/Dockerfile delete mode 100644 build/fig.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index af47f458..00000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -language: cpp -cache: - apt: true -os: -- linux -#- osx -dist: xenial -sudo: required -compiler: -- g++ -- clang++ -env: - global: - - MAKEFLAGS="-j 2" - matrix: - - BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes - - BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no - - BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes - - BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no -matrix: - exclude: - - os: osx - env: BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes - - os: osx - env: BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no - - os: linux - compiler: clang++ - env: BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes - - os: linux - compiler: clang++ - env: BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no -addons: - apt: - packages: - - build-essential - - cmake - - g++ - - clang - - libboost-chrono-dev - - libboost-date-time-dev - - libboost-filesystem-dev - - libboost-program-options-dev - - libboost-system-dev - - libboost-thread-dev - - libminiupnpc-dev - - libssl-dev -before_install: -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libressl miniupnpc ; fi -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated boost || brew upgrade boost ; fi -script: -- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "cmake" ]]; then cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_UPNP=${UPNP} && make ; fi -- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "make" ]]; then make USE_UPNP=${MAKE_UPNP} ; fi -- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then make HOMEBREW=1 USE_UPNP=${MAKE_UPNP} ; fi diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 89d85494..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,57 +0,0 @@ -version: 2.38.0.{build} -pull_requests: - do_not_increment_build_number: true -branches: - only: - - openssl -skip_tags: true -os: Visual Studio 2015 -shallow_clone: true -clone_depth: 1 - -# avoid building 32-bit if 64-bit failed already -matrix: - fast_finish: true - -environment: - APPVEYOR_SAVE_CACHE_ON_ERROR: true - MSYS2_PATH_TYPE: inherit - CHERE_INVOKING: enabled_from_arguments - matrix: - - MSYSTEM: MINGW64 - - MSYSTEM: MINGW32 - -cache: - - c:\msys64\var\cache\pacman\pkg\ - -install: -# install new signing keyring -- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -- c:\msys64\usr\bin\bash -lc "curl -O https://mirror.selfnet.de/msys2/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -# remove packages which can break build -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc mingw-w64-{i686,x86_64}-gcc-ada mingw-w64-{i686,x86_64}-gcc-objc" -# update runtime -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" -# Kill bash before next try -- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 -# update packages and install required -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc" - -build_script: -- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes DEBUG=no -j3" -# prepare archive for uploading -- set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d" -- echo This is development build, use it carefully! For running in portable mode, move all files from contrib directory here. > README.txt -- 7z a -tzip -mx9 -mmt i2pd-%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,7%-mingw-win%MSYSTEM:~-2%.zip %FILELIST% - -after_build: -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sc" - -test: off - -deploy: off - -artifacts: -- path: i2pd-*.zip diff --git a/build/docker/README.md b/build/docker/README.md deleted file mode 100644 index 877a9ce5..00000000 --- a/build/docker/README.md +++ /dev/null @@ -1,34 +0,0 @@ -Howto build & run -================== - -**Build** - -Assuming you're in the root directory of the anoncoin source code. - -$ `cd build/docker` -$ `docker -t meeh/i2pd:latest .` - -**Run** - -To run either the local build, or if not found - fetched prebuild from hub.docker.io, run the following command. - -$ `docker run --name anonnode -v /path/to/i2pd/datadir/on/host:/var/lib/i2pd -p 7070:7070 -p 4444:4444 -p 4447:4447 -p 7656:7656 -p 2827:2827 -p 7654:7654 -p 7650:7650 -d meeh/i2pd` - -All the ports ( -p HOSTPORT:DOCKERPORT ) is optional. However the command above enable all features (Webconsole, HTTP Proxy, BOB, SAM, i2cp, etc) - -The volume ( -v HOSTDIR:DOCKERDIR ) is also optional, but if you don't use it, your config, routerid and private keys will die along with the container. - -**Options** - -Options are set via docker environment variables. This can be set at run with -e parameters. - -* **ENABLE_IPV6** - Enable IPv6 support. Any value can be used - it triggers as long as it's not empty. -* **LOGLEVEL** - Set the loglevel. -* **ENABLE_AUTH** - Enable auth for the webconsole. Username and password needs to be set manually in i2pd.conf cause security reasons. - -**Logging** - -Logging happens to STDOUT as the best practise with docker containers, since infrastructure systems like kubernetes with ELK integration can automatically forward the log to say, kibana or greylog without manual setup. :) - - - diff --git a/build/docker/old-ubuntu-based/Dockerfile b/build/docker/old-ubuntu-based/Dockerfile deleted file mode 100644 index 3faddf2e..00000000 --- a/build/docker/old-ubuntu-based/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM ubuntu - -RUN apt-get update && apt-get install -y libboost-dev libboost-filesystem-dev \ - libboost-program-options-dev libboost-date-time-dev \ - libssl-dev git build-essential - -RUN git clone https://github.com/PurpleI2P/i2pd.git -WORKDIR /i2pd -RUN make - -CMD ./i2pd diff --git a/build/fig.yml b/build/fig.yml deleted file mode 100644 index 372ef350..00000000 --- a/build/fig.yml +++ /dev/null @@ -1,2 +0,0 @@ -i2pd: - build: . diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 6470e148..71af141e 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:latest LABEL authors "Mikal Villa , Darknet Villain " # Expose git branch, tag and URL variables as arguments From 12d6f03dc9d1adef53abeba13b0499d52242220d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 27 Jun 2021 17:14:45 +0300 Subject: [PATCH 0197/2193] [i18n] add language changing at runtime in webconsole Signed-off-by: R4SAS --- contrib/i18n/English.po | 296 +++++++++++++++++++------------------- daemon/HTTPServer.cpp | 75 ++++++---- i18n/Afrikaans.cpp | 7 +- i18n/English.cpp | 7 +- i18n/I18N.h | 13 +- i18n/I18N_langs.h | 28 +++- i18n/Russian.cpp | 310 ++++++++++++++++++---------------------- i18n/Turkmen.cpp | 7 +- i18n/Ukrainian.cpp | 7 +- 9 files changed, 396 insertions(+), 354 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 1de2ddaa..011d0fee 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -26,548 +26,554 @@ msgstr "" msgid "Enabled" msgstr "" -#: daemon/HTTPServer.cpp:141 +#: daemon/HTTPServer.cpp:147 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:145 + +#: daemon/HTTPServer.cpp:151 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:149 + +#: daemon/HTTPServer.cpp:155 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:152 +#: daemon/HTTPServer.cpp:158 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:160 daemon/HTTPServer.cpp:188 +#: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194 msgid "KiB" msgstr "" -#: daemon/HTTPServer.cpp:162 +#: daemon/HTTPServer.cpp:168 msgid "MiB" msgstr "" -#: daemon/HTTPServer.cpp:164 +#: daemon/HTTPServer.cpp:170 msgid "GiB" msgstr "" -#: daemon/HTTPServer.cpp:181 +#: daemon/HTTPServer.cpp:187 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:182 +#: daemon/HTTPServer.cpp:188 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:183 +#: daemon/HTTPServer.cpp:189 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:184 +#: daemon/HTTPServer.cpp:190 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:185 +#: daemon/HTTPServer.cpp:191 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:187 +#: daemon/HTTPServer.cpp:193 msgid "exploratory" msgstr "" -#: daemon/HTTPServer.cpp:223 +#: daemon/HTTPServer.cpp:229 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:226 +#: daemon/HTTPServer.cpp:232 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:227 daemon/HTTPServer.cpp:683 +#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:689 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:228 +#: daemon/HTTPServer.cpp:234 msgid "Local destinations" msgstr "" -#: daemon/HTTPServer.cpp:230 daemon/HTTPServer.cpp:382 -#: daemon/HTTPServer.cpp:463 daemon/HTTPServer.cpp:469 -#: daemon/HTTPServer.cpp:599 daemon/HTTPServer.cpp:642 -#: daemon/HTTPServer.cpp:646 +#: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388 +#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475 +#: daemon/HTTPServer.cpp:605 daemon/HTTPServer.cpp:648 +#: daemon/HTTPServer.cpp:652 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:232 daemon/HTTPServer.cpp:652 +#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:658 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:727 -#: daemon/HTTPServer.cpp:743 +#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:746 +#: daemon/HTTPServer.cpp:762 msgid "Transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:792 +#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:811 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:235 +#: daemon/HTTPServer.cpp:241 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:237 daemon/HTTPServer.cpp:854 -#: daemon/HTTPServer.cpp:864 +#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:873 +#: daemon/HTTPServer.cpp:883 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:253 daemon/HTTPServer.cpp:1254 -#: daemon/HTTPServer.cpp:1257 daemon/HTTPServer.cpp:1260 -#: daemon/HTTPServer.cpp:1274 daemon/HTTPServer.cpp:1319 -#: daemon/HTTPServer.cpp:1322 daemon/HTTPServer.cpp:1325 +#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1273 +#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1279 +#: daemon/HTTPServer.cpp:1293 daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1341 daemon/HTTPServer.cpp:1344 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:260 +#: daemon/HTTPServer.cpp:266 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:261 +#: daemon/HTTPServer.cpp:267 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:262 +#: daemon/HTTPServer.cpp:268 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:284 -#: daemon/HTTPServer.cpp:370 +#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:290 +#: daemon/HTTPServer.cpp:376 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:394 -#: daemon/HTTPServer.cpp:395 daemon/HTTPServer.cpp:922 -#: daemon/HTTPServer.cpp:931 +#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400 +#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:941 +#: daemon/HTTPServer.cpp:950 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:265 +#: daemon/HTTPServer.cpp:271 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:268 +#: daemon/HTTPServer.cpp:274 msgid "Error" msgstr "" -#: daemon/HTTPServer.cpp:272 +#: daemon/HTTPServer.cpp:278 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:275 +#: daemon/HTTPServer.cpp:281 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:278 +#: daemon/HTTPServer.cpp:284 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:290 +#: daemon/HTTPServer.cpp:296 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:293 +#: daemon/HTTPServer.cpp:299 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:298 +#: daemon/HTTPServer.cpp:304 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:304 daemon/HTTPServer.cpp:311 +#: daemon/HTTPServer.cpp:310 daemon/HTTPServer.cpp:317 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:318 +#: daemon/HTTPServer.cpp:324 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:319 +#: daemon/HTTPServer.cpp:325 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:320 +#: daemon/HTTPServer.cpp:326 msgid "Received" msgstr "" -#: daemon/HTTPServer.cpp:322 daemon/HTTPServer.cpp:325 -#: daemon/HTTPServer.cpp:328 +#: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331 +#: daemon/HTTPServer.cpp:334 msgid "KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:323 +#: daemon/HTTPServer.cpp:329 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:326 +#: daemon/HTTPServer.cpp:332 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:329 +#: daemon/HTTPServer.cpp:335 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:332 +#: daemon/HTTPServer.cpp:338 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:335 +#: daemon/HTTPServer.cpp:341 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:337 +#: daemon/HTTPServer.cpp:343 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:338 +#: daemon/HTTPServer.cpp:344 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:339 +#: daemon/HTTPServer.cpp:345 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:340 +#: daemon/HTTPServer.cpp:346 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:348 +#: daemon/HTTPServer.cpp:354 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:380 +#: daemon/HTTPServer.cpp:386 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:381 +#: daemon/HTTPServer.cpp:387 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:388 daemon/HTTPServer.cpp:908 +#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:927 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:389 +#: daemon/HTTPServer.cpp:395 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:393 +#: daemon/HTTPServer.cpp:399 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:407 daemon/HTTPServer.cpp:419 +#: daemon/HTTPServer.cpp:413 daemon/HTTPServer.cpp:425 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:442 +#: daemon/HTTPServer.cpp:448 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:451 +#: daemon/HTTPServer.cpp:457 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:456 +#: daemon/HTTPServer.cpp:462 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:457 +#: daemon/HTTPServer.cpp:463 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:458 +#: daemon/HTTPServer.cpp:464 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:470 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:470 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:470 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:474 daemon/HTTPServer.cpp:657 +#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:663 msgid "Inbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:479 daemon/HTTPServer.cpp:489 -#: daemon/HTTPServer.cpp:662 daemon/HTTPServer.cpp:672 -#: Means milliseconds +#. Milliseconds +#: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495 +#: daemon/HTTPServer.cpp:668 daemon/HTTPServer.cpp:678 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:484 daemon/HTTPServer.cpp:667 +#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:673 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:502 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:502 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:503 daemon/HTTPServer.cpp:506 +#: daemon/HTTPServer.cpp:509 daemon/HTTPServer.cpp:512 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:520 +#: daemon/HTTPServer.cpp:510 daemon/HTTPServer.cpp:526 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:504 +#: daemon/HTTPServer.cpp:510 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:511 +#: daemon/HTTPServer.cpp:517 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:519 daemon/HTTPServer.cpp:522 +#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:528 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:520 +#: daemon/HTTPServer.cpp:526 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:529 daemon/HTTPServer.cpp:584 +#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:590 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:538 daemon/HTTPServer.cpp:887 +#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:906 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:560 +#: daemon/HTTPServer.cpp:566 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:589 +#: daemon/HTTPServer.cpp:595 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:592 +#: daemon/HTTPServer.cpp:598 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:618 +#: daemon/HTTPServer.cpp:624 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:621 +#: daemon/HTTPServer.cpp:627 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:622 +#: daemon/HTTPServer.cpp:628 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:627 +#: daemon/HTTPServer.cpp:633 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:630 +#: daemon/HTTPServer.cpp:636 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:631 +#: daemon/HTTPServer.cpp:637 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:632 +#: daemon/HTTPServer.cpp:638 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:642 +#: daemon/HTTPServer.cpp:648 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:653 +#: daemon/HTTPServer.cpp:659 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:684 +#: daemon/HTTPServer.cpp:690 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:687 +#: daemon/HTTPServer.cpp:693 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:689 +#: daemon/HTTPServer.cpp:695 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:692 daemon/HTTPServer.cpp:697 +#: daemon/HTTPServer.cpp:698 daemon/HTTPServer.cpp:703 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:694 daemon/HTTPServer.cpp:699 +#: daemon/HTTPServer.cpp:700 daemon/HTTPServer.cpp:705 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:701 +#: daemon/HTTPServer.cpp:707 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:704 +#: daemon/HTTPServer.cpp:710 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:706 +#: daemon/HTTPServer.cpp:712 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:714 +#: daemon/HTTPServer.cpp:720 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:719 +#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:737 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:743 +#: daemon/HTTPServer.cpp:729 +msgid "Change language" +msgstr "" + +#: daemon/HTTPServer.cpp:762 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:848 daemon/HTTPServer.cpp:871 +#: daemon/HTTPServer.cpp:867 daemon/HTTPServer.cpp:890 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:864 +#: daemon/HTTPServer.cpp:883 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:877 +#: daemon/HTTPServer.cpp:896 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:882 +#: daemon/HTTPServer.cpp:901 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:939 +#: daemon/HTTPServer.cpp:958 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:955 +#: daemon/HTTPServer.cpp:974 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:969 +#: daemon/HTTPServer.cpp:988 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1175 +#: daemon/HTTPServer.cpp:1194 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1194 +#: daemon/HTTPServer.cpp:1213 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1252 daemon/HTTPServer.cpp:1309 -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1271 daemon/HTTPServer.cpp:1328 +#: daemon/HTTPServer.cpp:1364 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1252 +#: daemon/HTTPServer.cpp:1271 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1254 +#: daemon/HTTPServer.cpp:1273 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1257 +#: daemon/HTTPServer.cpp:1276 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1260 +#: daemon/HTTPServer.cpp:1279 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1262 daemon/HTTPServer.cpp:1327 +#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1346 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1263 daemon/HTTPServer.cpp:1276 +#: daemon/HTTPServer.cpp:1282 daemon/HTTPServer.cpp:1295 msgid "You will be redirected back in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1274 +#: daemon/HTTPServer.cpp:1293 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1275 daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1294 daemon/HTTPServer.cpp:1365 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1311 +#: daemon/HTTPServer.cpp:1330 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1312 +#: daemon/HTTPServer.cpp:1331 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1312 +#: daemon/HTTPServer.cpp:1331 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1313 +#: daemon/HTTPServer.cpp:1332 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1319 +#: daemon/HTTPServer.cpp:1338 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1322 +#: daemon/HTTPServer.cpp:1341 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1325 +#: daemon/HTTPServer.cpp:1344 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1333 +#: daemon/HTTPServer.cpp:1360 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1364 msgid "Command accepted" msgstr "" -#: daemon/HTTPServer.cpp:1339 +#: daemon/HTTPServer.cpp:1366 msgid "You will be redirected in 5 seconds" msgstr "" diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 0b9e8f0f..8ed4511f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -68,11 +68,11 @@ namespace http { << " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" << " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n" << " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" - << " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" - << " .menu { float: left; } .menu a, .commands a { display: block; }\r\n" + << " .wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n" + << " .menu { display: block; float: left; overflow: hidden; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; }\r\n" << " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n" << " .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n" - << " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n" + << " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 48em; overflow: auto; }\r\n" << " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n" << " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n" << " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" @@ -84,19 +84,24 @@ namespace http { << " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n" << " .disabled:after { color: #D33F3F; content: \"" << tr("Disabled") << "\" }\r\n" << " .enabled:after { color: #56B734; content: \"" << tr("Enabled") << "\" }\r\n" - << " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ + << " @media screen and (max-width: 1150px) {\r\n" /* adaptive style */ + << " .wrapper { max-width: 58em; } .menu { max-width: 10em; }\r\n" + << " .content { margin-left: 2em; max-width: 42em; }\r\n" + << " }\r\n" + << " @media screen and (max-width: 980px) {\r\n" << " body { padding: 1.5em 0 0 0; }\r\n" - << " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n" + << " .menu { width: 100%; max-width: unset; display: block; float: none; position: unset; font-size: 16px;\r\n" << " text-align: center; }\r\n" - << " .menu a, .commands a { padding: 2px; }\r\n" + << " .menu a, .commands a { display: inline-block; padding: 4px; }\r\n" << " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n" << " text-align: center; }\r\n" << " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" << " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n" << " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" << " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" - << " input { width: 35%; text-align: center; padding: 5px;\r\n" + << " input, select { width: 35%; text-align: center; padding: 5px;\r\n" << " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n" + << " table.extaddr { margin: auto; text-align: unset; }\r\n" << " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n" << " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n" << " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n" @@ -127,6 +132,7 @@ namespace http { const char HTTP_COMMAND_KILLSTREAM[] = "closestream"; const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit"; const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string"; + const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; @@ -223,18 +229,18 @@ namespace http { "
" << tr("i2pd webconsole") << "
\r\n" "
\r\n" "\r\n" "
"; @@ -476,7 +482,7 @@ namespace http { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << it->GetMeanLatency() << tr(/* Milliseconds */ "ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -681,22 +687,22 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); /* commands */ s << "" << tr("Router commands") << "
\r\n
\r\n
\r\n"; - s << " " << tr("Run peer test") << "\r\n"; + s << " " << tr("Run peer test") << "
\r\n"; //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << " " << tr("Decline transit tunnels") << "\r\n"; + s << " " << tr("Decline transit tunnels") << "
\r\n"; else - s << " " << tr("Accept transit tunnels") << "\r\n"; + s << " " << tr("Accept transit tunnels") << "
\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) - s << " " << tr("Cancel graceful shutdown") << "\r\n"; + s << " " << tr("Cancel graceful shutdown") << "
\r\n"; else - s << " " << tr("Start graceful shutdown") << "\r\n"; + s << " " << tr("Start graceful shutdown") << "
\r\n"; #elif defined(WIN32_APP) if (i2p::util::DaemonWin32::Instance().isGraceful) - s << " " << tr("Cancel graceful shutdown") << "\r\n"; + s << " " << tr("Cancel graceful shutdown") << "
\r\n"; else - s << " " << tr("Start graceful shutdown") << "\r\n"; + s << " " << tr("Start graceful shutdown") << "
\r\n"; #endif s << " " << tr("Force shutdown") << "\r\n"; s << "
"; @@ -718,6 +724,19 @@ namespace http { s << " \r\n"; s << " \r\n"; s << "\r\n
\r\n"; + + std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + s << "" << tr("Change language") << "
\r\n"; + s << "
\r\n"; + s << " \r\n"; + s << " \r\n"; + s << " \r\n"; + s << " \r\n"; + s << "
\r\n
\r\n"; + } void ShowTransitTunnels (std::stringstream& s) @@ -1327,6 +1346,14 @@ namespace http { s << "" << tr("Return to destination page") << "\r\n"; return; } + else if (cmd == HTTP_COMMAND_SETLANGUAGE) + { + std::string lang = params["lang"]; + std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); + + if (currLang.compare(lang) != 0) + i2p::i18n::SetLanguage(lang); + } else { res.code = 400; diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index d2b652b4..96ee52ee 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace afrikaans // language +namespace afrikaans // language namespace { + // language name in lowercase + static std::string language = "afrikaans"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -65,7 +68,7 @@ namespace afrikaans // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/English.cpp b/i18n/English.cpp index 6015f8e1..2670e984 100644 --- a/i18n/English.cpp +++ b/i18n/English.cpp @@ -19,8 +19,11 @@ namespace i2p { namespace i18n { -namespace english // language +namespace english // language namespace { + // language name in lowercase + static std::string language = "english"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -39,7 +42,7 @@ namespace english // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/I18N.h b/i18n/I18N.h index 272f65e8..03add48d 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -17,16 +17,11 @@ namespace i18n { inline void SetLanguage(const std::string &lang) { - if (!lang.compare("afrikaans")) - i2p::context.SetLanguage (i2p::i18n::afrikaans::GetLocale()); - else if (!lang.compare("russian")) - i2p::context.SetLanguage (i2p::i18n::russian::GetLocale()); - else if (!lang.compare("turkmen")) - i2p::context.SetLanguage (i2p::i18n::turkmen::GetLocale()); - else if (!lang.compare("ukrainian")) - i2p::context.SetLanguage (i2p::i18n::ukrainian::GetLocale()); - else // fallback + const auto it = i2p::i18n::languages.find(lang); + if (it == i2p::i18n::languages.end()) // fallback i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); + else + i2p::context.SetLanguage (it->second.LocaleFunc()); } inline std::string translate (const std::string& arg) diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 181a4793..949e5844 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -17,10 +17,17 @@ namespace i18n { public: Locale ( + const std::string& language, const std::map& strings, const std::map>& plurals, std::function formula - ): m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { }; + ): m_Language (language), m_Strings (strings), m_Plurals (plurals), m_Formula (formula) { }; + + // Get activated language name for webconsole + std::string GetLanguage() const + { + return m_Language; + } std::string GetString (const std::string& arg) const { @@ -50,11 +57,18 @@ namespace i18n } private: + const std::string m_Language; const std::map m_Strings; const std::map> m_Plurals; std::function m_Formula; }; + struct langData + { + std::string LocaleName; //localized name + std::function (void)> LocaleFunc; + }; + // Add localization here with language name as namespace namespace afrikaans { std::shared_ptr GetLocale (); } namespace english { std::shared_ptr GetLocale (); } @@ -62,6 +76,18 @@ namespace i18n namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } + /** + * That map contains international language name lower-case and name in it's language + */ + static std::map languages + { + { "afrikaans", {"Afrikaans", i2p::i18n::afrikaans::GetLocale} }, + { "english", {"English", i2p::i18n::english::GetLocale} }, + { "russian", {"русский язык", i2p::i18n::russian::GetLocale} }, + { "turkmen", {"türkmen dili", i2p::i18n::turkmen::GetLocale} }, + { "ukrainian", {"украї́нська мо́ва", i2p::i18n::ukrainian::GetLocale} }, + }; + } // i18n } // i2p diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 7df82d54..5e7f9c6b 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace russian // language +namespace russian // language namespace { + // language name in lowercase + static std::string language = "russian"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -28,23 +31,152 @@ namespace russian // language static std::map strings { - // HTTP Proxy + {"Disabled", "Выключено"}, + {"Enabled", "Включено"}, + {"KiB", "КиБ"}, + {"MiB", "МиБ"}, + {"GiB", "ГиБ"}, + {"building", "строится"}, + {"failed", "неудачный"}, + {"expiring", "истекает"}, + {"established", "работает"}, + {"unknown", "неизвестно"}, + {"exploratory", "исследовательский"}, + {"i2pd webconsole", "Веб-консоль i2pd"}, + {"Main page", "Главная"}, + {"Router commands", "Команды роутера"}, + {"Local destinations", "Локальные назначения"}, + {"LeaseSets", "Лизсеты"}, + {"Tunnels", "Туннели"}, + {"Transit tunnels", "Транзитные туннели"}, + {"Transports", "Транспорты"}, + {"I2P tunnels", "I2P туннели"}, + {"SAM sessions", "SAM сессии"}, + {"ERROR", "ОШИБКА"}, + {"OK", "OK"}, + {"Testing", "Тестирование"}, + {"Firewalled", "Заблокировано извне"}, + {"Unknown", "Неизвестно"}, + {"Proxy", "Прокси"}, + {"Mesh", "MESH-сеть"}, + {"Error", "Ошибка"}, + {"Clock skew", "Не точное время"}, + {"Offline", "Оффлайн"}, + {"Symmetric NAT", "Симметричный NAT"}, + {"Uptime", "В сети"}, + {"Network status", "Сетевой статус"}, + {"Network status v6", "Сетевой статус v6"}, + {"Stopping in", "Остановка через"}, + {"Family", "Семейство"}, + {"Tunnel creation success rate", "Успешно построенных туннелей"}, + {"Received", "Получено"}, + {"KiB/s", "КиБ/с"}, + {"Sent", "Отправлено"}, + {"Transit", "Транзит"}, + {"Data path", "Путь к данным"}, + {"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."}, + {"Router Ident", "Идентификатор роутера"}, + {"Router Family", "Семейство роутера"}, + {"Router Caps", "Флаги роутера"}, + {"Version", "Версия"}, + {"Our external address", "Наш внешний адрес"}, + {"supported", "поддерживается"}, + {"Routers", "Роутеры"}, + {"Floodfills", "Флудфилы"}, + {"Client Tunnels", "Клиентские туннели"}, + {"Transit Tunnels", "Транзитные туннели"}, + {"Services", "Сервисы"}, + {"Local Destinations", "Локальные назначения"}, + {"Encrypted B33 address", "Шифрованные B33 адреса"}, + {"Address registration line", "Строка регистрации адреса"}, + {"Domain", "Домен"}, + {"Generate", "Сгенерировать"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Примечание: полученная строка может быть использована только для регистрации доменов второго уровня (example.i2p). Для регистрации поддоменов используйте i2pd-tools."}, + {"Address", "Адрес"}, + {"Type", "Тип"}, + {"EncType", "ТипШифр"}, + {"Inbound tunnels", "Входящие туннели"}, + {"ms", "мс"}, + {"Outbound tunnels", "Исходящие туннели"}, + {"Tags", "Теги"}, + {"Incoming", "Входящие"}, + {"Outgoing", "Исходящие"}, + {"Destination", "Назначение"}, + {"Amount", "Количество"}, + {"Incoming Tags", "Входящие Теги"}, + {"Tags sessions", "Сессии Тегов"}, + {"Status", "Статус"}, + {"Local Destination", "Локальное назначение"}, + {"Streams", "Стримы"}, + {"Close stream", "Закрыть стрим"}, + {"I2CP session not found", "I2CP сессия не найдена"}, + {"I2CP is not enabled", "I2CP не включен"}, + {"Invalid", "Некорректный"}, + {"Store type", "Тип хранилища"}, + {"Expires", "Истекает"}, + {"Non Expired Leases", "Не истекшие Lease-ы"}, + {"Gateway", "Шлюз"}, + {"TunnelID", "ID туннеля"}, + {"EndDate", "Заканчивается"}, + {"not floodfill", "не флудфил"}, + {"Queue size", "Размер очереди"}, + {"Run peer test", "Запустить тестирование"}, + {"Decline transit tunnels", "Отклонять транзитные туннели"}, + {"Accept transit tunnels", "Принимать транзитные туннели"}, + {"Cancel graceful shutdown", "Отменить плавную остановку"}, + {"Start graceful shutdown", "Запустить плавную остановку"}, + {"Force shutdown", "Принудительная остановка"}, + {"Note: any action done here are not persistent and not changes your config files.", "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, + {"Logging level", "Уровень логирования"}, + {"Transit tunnels limit", "Лимит транзитных туннелей"}, + {"Change", "Изменить"}, + {"Change language", "Изменение языка"}, + {"no transit tunnels currently built", "нет построенных транзитных туннелей"}, + {"SAM disabled", "SAM выключен"}, + {"no sessions currently running", "нет запущенных сессий"}, + {"SAM session not found", "SAM сессия не найдена"}, + {"SAM Session", "SAM сессия"}, + {"Server Tunnels", "Серверные туннели"}, + {"Client Forwards", "Клиентские перенаправления"}, + {"Server Forwards", "Серверные перенаправления"}, + {"Unknown page", "Неизвестная страница"}, + {"Invalid token", "Неверный токен"}, + {"SUCCESS", "УСПЕШНО"}, + {"Stream closed", "Стрим закрыт"}, + {"Stream not found or already was closed", "Стрим не найден или уже закрыт"}, + {"Destination not found", "Точка назначения не найдена"}, + {"StreamID can't be null", "StreamID не может быть пустым"}, + {"Return to destination page", "Вернуться на страницу точки назначения"}, + {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, + {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, + {"Back to commands list", "Вернуться к списку команд"}, + {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, + {"Description", "Описание"}, + {"A bit information about service on domain", "Немного информации о сервисе на домене"}, + {"Submit", "Отправить"}, + {"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"}, + {"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"}, + {"Such destination is not found", "Такая точка назначения не найдена"}, + {"Unknown command", "Неизвестная команда"}, + {"Command accepted", "Команда принята"}, + {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, {"Proxy error", "Ошибка прокси"}, {"Proxy info", "Информация прокси"}, - {"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"}, - {"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"}, - {"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"}, + {"Proxy error: Host not found", "Ошибка прокси: Узел не найден"}, + {"Remote host not found in router's addressbook", "Запрошенный узел не найден в адресной книге роутера"}, + {"You may try to find this host on jump services below", "Вы можете попробовать найти узел через джамп сервисы ниже"}, {"Invalid request", "Некорректный запрос"}, {"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"}, {"addresshelper is not supported", "addresshelper не поддерживается"}, - {"Host", "Адрес"}, + {"Host", "Узел"}, {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, - {"already in router's addressbook", "уже в адресной книге роутера"}, {"Click", "Нажмите"}, {"here", "здесь"}, {"to proceed", "чтобы продолжить"}, - {"to update record", "чтобы обновить запись"}, {"Addresshelper found", "Найден addresshelper"}, + {"already in router's addressbook", "уже в адресной книге роутера"}, + {"to update record", "чтобы обновить запись"}, + {"Invalid Request", "неверный запрос"}, {"invalid request uri", "некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, @@ -63,169 +195,13 @@ namespace russian // language {"cannot connect", "не удалось подключиться"}, {"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"}, {"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"}, - {"Host is down", "Адрес недоступен"}, - {"Can't create connection to requested host, it may be down. Please try again later.", - "Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."}, - - // Webconsole // - // cssStyles - {"Disabled", "Выключено"}, - {"Enabled", "Включено"}, - // ShowTraffic - {"KiB", "КиБ"}, - {"MiB", "МиБ"}, - {"GiB", "ГиБ"}, - // ShowTunnelDetails - {"building", "строится"}, - {"failed", "неудачный"}, - {"expiring", "истекает"}, - {"established", "работает"}, - {"exploratory", "исследовательский"}, - {"unknown", "неизвестно"}, - {"i2pd webconsole", "Веб-консоль i2pd"}, - // ShowPageHead - {"Main page", "Главная"}, - {"Router commands", "Команды роутера"}, - {"Local destinations", "Локальные назнач."}, - {"LeaseSets", "Лизсеты"}, - {"Tunnels", "Туннели"}, - {"Transit tunnels", "Транзит. туннели"}, - {"Transports", "Транспорты"}, - {"I2P tunnels", "I2P туннели"}, - {"SAM sessions", "SAM сессии"}, - // Network Status - {"OK", "OK"}, - {"Testing", "Тестирование"}, - {"Firewalled", "Заблокировано извне"}, - {"Unknown", "Неизвестно"}, - {"Proxy", "Прокси"}, - {"Mesh", "MESH-сеть"}, - {"Error", "Ошибка"}, - {"Clock skew", "Не точное время"}, - {"Offline", "Оффлайн"}, - {"Symmetric NAT", "Симметричный NAT"}, - // Status - {"Uptime", "В сети"}, - {"Network status", "Сетевой статус"}, - {"Network status v6", "Сетевой статус v6"}, - {"Stopping in", "Остановка через"}, - {"Family", "Семейство"}, - {"Tunnel creation success rate", "Успешно построенных туннелей"}, - {"Received", "Получено"}, - {"Sent", "Отправлено"}, - {"Transit", "Транзит"}, - {"KiB/s", "КиБ/с"}, - {"Data path", "Путь к данным"}, - {"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."}, - {"Router Ident", "Идентификатор роутера"}, - {"Router Family", "Семейство роутера"}, - {"Router Caps", "Флаги роутера"}, - {"Version", "Версия"}, - {"Our external address", "Наш внешний адрес"}, - {"supported", "поддерживается"}, - {"Routers", "Роутеры"}, - {"Floodfills", "Флудфилы"}, - {"LeaseSets", "Лизсеты"}, - {"Client Tunnels", "Клиентские туннели"}, - {"Transit Tunnels", "Транзитные туннели"}, - {"Services", "Сервисы"}, - // ShowLocalDestinations - {"Local Destinations", "Локальные назначения"}, - // ShowLeaseSetDestination - {"Encrypted B33 address", "Шифрованные B33 адреса"}, - {"Address registration line", "Строка регистрации адреса"}, - {"Domain", "Домен"}, - {"Generate", "Сгенерировать"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", - "Примечание: полученная строка может быть использована только для регистрации доменов второго уровня. Для регистрации поддоменов используйте i2pd-tools."}, - {"Address", "Адрес"}, - {"Type", "Тип"}, - {"EncType", "ТипШифр"}, - {"Inbound tunnels", "Входящие туннели"}, - {"Outbound tunnels", "Исходящие туннели"}, - {"ms", "мс"}, // milliseconds - {"Tags", "Теги"}, - {"Incoming", "Входящие"}, - {"Outgoing", "Исходящие"}, - {"Destination", "Назначение"}, - {"Amount", "Количество"}, - {"Incoming Tags", "Входящие Теги"}, - {"Tags sessions", "Сессии Тегов"}, - {"Status", "Статус"}, - // ShowLocalDestination - {"Local Destination", "Локальное назначение"}, - {"Streams", "Стримы"}, - {"Close stream", "Закрыть стрим"}, - // ShowI2CPLocalDestination - {"I2CP session not found", "I2CP сессия не найдена"}, - {"I2CP is not enabled", "I2CP не включен"}, - // ShowLeasesSets - {"Invalid", "Некорректный"}, - {"Store type", "Тип хранилища"}, - {"Expires", "Истекает"}, - {"Non Expired Leases", "Не истекшие Lease-ы"}, - {"Gateway", "Шлюз"}, - {"TunnelID", "ID туннеля"}, - {"EndDate", "Заканчивается"}, - {"not floodfill", "не флудфил"}, - // ShowTunnels - {"Queue size", "Размер очереди"}, - // ShowCommands - {"Run peer test", "Запустить тестирование"}, - {"Decline transit tunnels", "Отклонять транзитные туннели"}, - {"Accept transit tunnels", "Принимать транзитные туннели"}, - {"Cancel graceful shutdown", "Отменить плавную остановку"}, - {"Start graceful shutdown", "Запустить плавную остановку"}, - {"Force shutdown", "Принудительная остановка"}, - {"Note: any action done here are not persistent and not changes your config files.", - "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, - {"Logging level", "Уровень логирования"}, - {"Transit tunnels limit", "Лимит транзитных туннелей"}, - {"Change", "Изменить"}, - // ShowTransitTunnels - {"no transit tunnels currently built", "нет построенных транзитных туннелей"}, - // ShowSAMSessions/ShowSAMSession - {"SAM disabled", "SAM выключен"}, - {"SAM session not found", "SAM сессия не найдена"}, - {"no sessions currently running", "нет запущенных сессий"}, - {"SAM Session", "SAM сессия"}, - // ShowI2PTunnels - {"Server Tunnels", "Серверные туннели"}, - {"Client Forwards", "Клиентские перенаправления"}, - {"Server Forwards", "Серверные перенаправления"}, - // HandlePage - {"Unknown page", "Неизвестная страница"}, - // HandleCommand, ShowError - {"Invalid token", "Неверный токен"}, - {"SUCCESS", "УСПЕШНО"}, - {"ERROR", "ОШИБКА"}, - {"Unknown command", "Неизвестная команда"}, - {"Command accepted", "Команда принята"}, - {"Back to commands list", "Вернуться к списку команд"}, - {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, - // HTTP_COMMAND_KILLSTREAM - {"Stream closed", "Стрим закрыт"}, - {"Stream not found or already was closed", "Стрим не найден или уже закрыт"}, - {"Destination not found", "Точка назначения не найдена"}, - {"StreamID can't be null", "StreamID не может быть пустым"}, - {"Return to destination page", "Вернуться на страницу точки назначения"}, - {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, - // HTTP_COMMAND_LIMITTRANSIT - {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, - // HTTP_COMMAND_GET_REG_STRING - {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, - {"Description", "Описание"}, - {"A bit information about service on domain", "Немного информации о сервисе на домене"}, - {"Submit", "Отправить"}, - {"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"}, - {"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"}, - {"Such destination is not found", "Такая точка назначения не найдена"}, + {"Host is down", "Узел недоступен"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Не удалось установить соединение к запрошенному узлу, возможно он не в сети. Попробуйте повторить запрос позже."}, {"", ""}, }; static std::map> plurals { - // ShowUptime {"days", {"день", "дня", "дней"}}, {"hours", {"час", "часа", "часов"}}, {"minutes", {"минуту", "минуты", "минут"}}, @@ -235,7 +211,7 @@ namespace russian // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 0edc9a6e..8af89f6f 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace turkmen // language +namespace turkmen // language namespace { + // language name in lowercase + static std::string language = "turkmen"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -234,7 +237,7 @@ namespace turkmen // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 5e856c52..8da132d7 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -18,8 +18,11 @@ namespace i2p { namespace i18n { -namespace ukrainian // language +namespace ukrainian // language namespace { + // language name in lowercase + static std::string language = "ukrainian"; + // See for language plural forms here: // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html static int plural (int n) { @@ -207,7 +210,7 @@ namespace ukrainian // language std::shared_ptr GetLocale() { - return std::make_shared(strings, plurals, [] (int n)->int { return plural(n); }); + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); } } // language From 25f63ac22a8604f05cabee447c28337190be404d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Jun 2021 15:49:57 -0400 Subject: [PATCH 0198/2193] create different I2NP tunnel messages for endpoint and non-endpoint --- libi2pd/I2NPProtocol.cpp | 26 ++++++++++++++++++-------- libi2pd/I2NPProtocol.h | 4 ++-- libi2pd/TransitTunnel.cpp | 4 ++-- libi2pd/Tunnel.cpp | 2 +- libi2pd/TunnelEndpoint.cpp | 4 +--- libi2pd/TunnelGateway.cpp | 2 +- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index f570a2a1..a040e25b 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -36,11 +36,21 @@ namespace i2p return std::make_shared >(); } - std::shared_ptr NewI2NPTunnelMessage () + std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { - // should fit two tunnel message, enough for one garlic encrypted streaming packet - auto msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12 - msg->Align (12); + I2NPMessage * msg = nullptr; + if (endpoint) + { + // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet + msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6 + msg->Align (6); + msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + } + else + { + msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 + msg->Align (12); + } return std::shared_ptr(msg); } @@ -692,7 +702,7 @@ namespace i2p std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf) { - auto msg = NewI2NPTunnelMessage (); + auto msg = NewI2NPTunnelMessage (false); msg->Concat (buf, i2p::tunnel::TUNNEL_DATA_MSG_SIZE); msg->FillI2NPMessageHeader (eI2NPTunnelData); return msg; @@ -700,7 +710,7 @@ namespace i2p std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload) { - auto msg = NewI2NPTunnelMessage (); + auto msg = NewI2NPTunnelMessage (false); htobe32buf (msg->GetPayload (), tunnelID); msg->len += 4; // tunnelID msg->Concat (payload, i2p::tunnel::TUNNEL_DATA_MSG_SIZE - 4); @@ -708,9 +718,9 @@ namespace i2p return msg; } - std::shared_ptr CreateEmptyTunnelDataMsg () + std::shared_ptr CreateEmptyTunnelDataMsg (bool endpoint) { - auto msg = NewI2NPTunnelMessage (); + auto msg = NewI2NPTunnelMessage (endpoint); msg->len += i2p::tunnel::TUNNEL_DATA_MSG_SIZE; return msg; } diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index cc7c94af..69d6bb04 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -278,7 +278,7 @@ namespace tunnel std::shared_ptr NewI2NPMessage (); std::shared_ptr NewI2NPShortMessage (); - std::shared_ptr NewI2NPTunnelMessage (); + std::shared_ptr NewI2NPTunnelMessage (bool endpoint); std::shared_ptr NewI2NPMessage (size_t len); std::shared_ptr CreateI2NPMessage (I2NPMessageType msgType, const uint8_t * buf, size_t len, uint32_t replyMsgID = 0); @@ -307,7 +307,7 @@ namespace tunnel std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf); std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); - std::shared_ptr CreateEmptyTunnelDataMsg (); + std::shared_ptr CreateEmptyTunnelDataMsg (bool endpoint); std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, const uint8_t * buf, size_t len); std::shared_ptr CreateTunnelGatewayMsg (uint32_t tunnelID, I2NPMessageType msgType, diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 73ca977c..dc7655d1 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -39,7 +39,7 @@ namespace tunnel void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (false); EncryptTunnelMsg (tunnelMsg, newMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); @@ -87,7 +87,7 @@ namespace tunnel void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) { - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (true); EncryptTunnelMsg (tunnelMsg, newMsg); LogPrint (eLogDebug, "TransitTunnel: handle msg for endpoint ", GetTunnelID ()); diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index e016e9e4..ba01ae20 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -234,7 +234,7 @@ namespace tunnel void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (true); EncryptTunnelMsg (msg, newMsg); newMsg->from = shared_from_this (); m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 109f3120..4885c090 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -126,9 +126,7 @@ namespace tunnel if (fragment + size < decrypted + TUNNEL_DATA_ENCRYPTED_SIZE) { // this is not last message. we have to copy it - m_CurrentMessage.data = NewI2NPTunnelMessage (); - m_CurrentMessage.data->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - m_CurrentMessage.data->len += TUNNEL_GATEWAY_HEADER_SIZE; + m_CurrentMessage.data = NewI2NPTunnelMessage (true); *(m_CurrentMessage.data) = *msg; } else diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 317926ae..08df569c 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -215,7 +215,7 @@ namespace tunnel const auto& tunnelDataMsgs = m_Buffer.GetTunnelDataMsgs (); for (auto& tunnelMsg : tunnelDataMsgs) { - auto newMsg = CreateEmptyTunnelDataMsg (); + auto newMsg = CreateEmptyTunnelDataMsg (false); m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg); htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ()); newMsg->FillI2NPMessageHeader (eI2NPTunnelData); From f036b8df2dc74977b700bd543fec9d9754dbb4ce Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Jun 2021 12:45:28 +0300 Subject: [PATCH 0199/2193] [i18n] update translatable strings (remove douplicates) Signed-off-by: R4SAS --- contrib/i18n/English.po | 180 +++++++++++++++++------------------ daemon/HTTPServer.cpp | 39 ++++---- libi2pd_client/HTTPProxy.cpp | 2 +- 3 files changed, 108 insertions(+), 113 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 011d0fee..76d58390 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -50,14 +50,17 @@ msgid_plural "seconds" msgstr[0] "" msgstr[1] "" +#. tr: Kibibit #: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194 msgid "KiB" msgstr "" +#. tr: Mebibit #: daemon/HTTPServer.cpp:168 msgid "MiB" msgstr "" +#. tr: Gibibit #: daemon/HTTPServer.cpp:170 msgid "GiB" msgstr "" @@ -94,31 +97,32 @@ msgstr "" msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:689 +#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:690 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:234 -msgid "Local destinations" +#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:413 +#: daemon/HTTPServer.cpp:425 +msgid "Local Destinations" msgstr "" #: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388 #: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475 -#: daemon/HTTPServer.cpp:605 daemon/HTTPServer.cpp:648 -#: daemon/HTTPServer.cpp:652 +#: daemon/HTTPServer.cpp:606 daemon/HTTPServer.cpp:649 +#: daemon/HTTPServer.cpp:653 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:658 +#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:659 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:746 -#: daemon/HTTPServer.cpp:762 -msgid "Transit tunnels" +#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:395 +#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:769 +msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:811 +#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:818 msgid "Transports" msgstr "" @@ -126,15 +130,15 @@ msgstr "" msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:873 -#: daemon/HTTPServer.cpp:883 +#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:880 +#: daemon/HTTPServer.cpp:890 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1273 -#: daemon/HTTPServer.cpp:1276 daemon/HTTPServer.cpp:1279 -#: daemon/HTTPServer.cpp:1293 daemon/HTTPServer.cpp:1338 -#: daemon/HTTPServer.cpp:1341 daemon/HTTPServer.cpp:1344 +#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1280 +#: daemon/HTTPServer.cpp:1283 daemon/HTTPServer.cpp:1286 +#: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1345 +#: daemon/HTTPServer.cpp:1348 daemon/HTTPServer.cpp:1351 msgid "ERROR" msgstr "" @@ -156,8 +160,8 @@ msgid "Unknown" msgstr "" #: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400 -#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:941 -#: daemon/HTTPServer.cpp:950 +#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:948 +#: daemon/HTTPServer.cpp:957 msgid "Proxy" msgstr "" @@ -209,6 +213,7 @@ msgstr "" msgid "Received" msgstr "" +#. tr: Kibibit/s #: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331 #: daemon/HTTPServer.cpp:334 msgid "KiB/s" @@ -262,22 +267,14 @@ msgstr "" msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:927 +#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:934 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:395 -msgid "Transit Tunnels" -msgstr "" - #: daemon/HTTPServer.cpp:399 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:413 daemon/HTTPServer.cpp:425 -msgid "Local Destinations" -msgstr "" - #: daemon/HTTPServer.cpp:448 msgid "Encrypted B33 address" msgstr "" @@ -312,17 +309,17 @@ msgstr "" msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:663 +#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:664 msgid "Inbound tunnels" msgstr "" -#. Milliseconds +#. tr: Milliseconds #: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495 -#: daemon/HTTPServer.cpp:668 daemon/HTTPServer.cpp:678 +#: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:679 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:673 +#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:674 msgid "Outbound tunnels" msgstr "" @@ -358,225 +355,222 @@ msgstr "" msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:590 +#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:591 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:906 +#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:913 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:566 +#: daemon/HTTPServer.cpp:567 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:595 +#: daemon/HTTPServer.cpp:596 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:598 +#: daemon/HTTPServer.cpp:599 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:624 +#: daemon/HTTPServer.cpp:625 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:627 +#: daemon/HTTPServer.cpp:628 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:628 +#: daemon/HTTPServer.cpp:629 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:633 +#: daemon/HTTPServer.cpp:634 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:636 +#: daemon/HTTPServer.cpp:637 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:637 +#: daemon/HTTPServer.cpp:638 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:638 +#: daemon/HTTPServer.cpp:639 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:648 +#: daemon/HTTPServer.cpp:649 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:659 +#: daemon/HTTPServer.cpp:660 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:690 +#: daemon/HTTPServer.cpp:691 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:693 +#: daemon/HTTPServer.cpp:698 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:695 +#: daemon/HTTPServer.cpp:700 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:698 daemon/HTTPServer.cpp:703 +#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:709 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:700 daemon/HTTPServer.cpp:705 +#: daemon/HTTPServer.cpp:706 daemon/HTTPServer.cpp:711 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:707 +#: daemon/HTTPServer.cpp:714 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:710 +#: daemon/HTTPServer.cpp:717 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:712 +#: daemon/HTTPServer.cpp:719 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:720 +#: daemon/HTTPServer.cpp:727 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:725 daemon/HTTPServer.cpp:737 +#: daemon/HTTPServer.cpp:732 daemon/HTTPServer.cpp:744 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:729 +#: daemon/HTTPServer.cpp:736 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:762 +#: daemon/HTTPServer.cpp:769 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:867 daemon/HTTPServer.cpp:890 +#: daemon/HTTPServer.cpp:874 daemon/HTTPServer.cpp:897 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:883 +#: daemon/HTTPServer.cpp:890 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:896 +#: daemon/HTTPServer.cpp:903 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:901 +#: daemon/HTTPServer.cpp:908 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:958 +#: daemon/HTTPServer.cpp:965 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:974 +#: daemon/HTTPServer.cpp:981 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:988 +#: daemon/HTTPServer.cpp:995 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1194 +#: daemon/HTTPServer.cpp:1201 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1213 +#: daemon/HTTPServer.cpp:1220 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1271 daemon/HTTPServer.cpp:1328 -#: daemon/HTTPServer.cpp:1364 +#: daemon/HTTPServer.cpp:1278 daemon/HTTPServer.cpp:1335 +#: daemon/HTTPServer.cpp:1371 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1271 +#: daemon/HTTPServer.cpp:1278 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1273 +#: daemon/HTTPServer.cpp:1280 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1276 +#: daemon/HTTPServer.cpp:1283 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1279 +#: daemon/HTTPServer.cpp:1286 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1281 daemon/HTTPServer.cpp:1346 +#: daemon/HTTPServer.cpp:1288 daemon/HTTPServer.cpp:1353 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1282 daemon/HTTPServer.cpp:1295 -msgid "You will be redirected back in 5 seconds" +#: daemon/HTTPServer.cpp:1289 daemon/HTTPServer.cpp:1302 +#: daemon/HTTPServer.cpp:1373 +msgid "You will be redirected in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1293 +#: daemon/HTTPServer.cpp:1300 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1294 daemon/HTTPServer.cpp:1365 +#: daemon/HTTPServer.cpp:1301 daemon/HTTPServer.cpp:1372 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1330 +#: daemon/HTTPServer.cpp:1337 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1331 +#: daemon/HTTPServer.cpp:1338 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1331 +#: daemon/HTTPServer.cpp:1338 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1332 +#: daemon/HTTPServer.cpp:1339 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1345 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1341 +#: daemon/HTTPServer.cpp:1348 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1344 +#: daemon/HTTPServer.cpp:1351 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1360 +#: daemon/HTTPServer.cpp:1367 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1364 +#: daemon/HTTPServer.cpp:1371 msgid "Command accepted" msgstr "" -#: daemon/HTTPServer.cpp:1366 -msgid "You will be redirected in 5 seconds" -msgstr "" - #: libi2pd_client/HTTPProxy.cpp:157 msgid "Proxy error" msgstr "" @@ -598,7 +592,7 @@ msgid "You may try to find this host on jump services below" msgstr "" #: libi2pd_client/HTTPProxy.cpp:273 libi2pd_client/HTTPProxy.cpp:288 -#: libi2pd_client/HTTPProxy.cpp:365 +#: libi2pd_client/HTTPProxy.cpp:322 libi2pd_client/HTTPProxy.cpp:365 msgid "Invalid request" msgstr "" @@ -643,10 +637,6 @@ msgstr "" msgid "to update record" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:322 -msgid "Invalid Request" -msgstr "" - #: libi2pd_client/HTTPProxy.cpp:322 msgid "invalid request uri" msgstr "" diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 8ed4511f..fd26d8f1 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -163,11 +163,11 @@ namespace http { s << std::fixed << std::setprecision(2); auto numKBytes = (double) bytes / 1024; if (numKBytes < 1024) - s << numKBytes << " " << tr("KiB"); + s << numKBytes << " " << tr(/* tr: Kibibit */ "KiB"); else if (numKBytes < 1024 * 1024) - s << numKBytes / 1024 << " " << tr("MiB"); + s << numKBytes / 1024 << " " << tr(/* tr: Mebibit */ "MiB"); else - s << numKBytes / 1024 / 1024 << " " << tr("GiB"); + s << numKBytes / 1024 / 1024 << " " << tr(/* tr: Gibibit */ "GiB"); } static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes) @@ -191,7 +191,7 @@ namespace http { else stateText = tr("unknown"); s << " " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << ", "; - s << " " << (int) (bytes / 1024) << " " << tr("KiB") << "\r\n"; + s << " " << (int) (bytes / 1024) << " " << tr(/* tr: Kibibit */ "KiB") << "\r\n"; } static void SetLogLevel (const std::string& level) @@ -231,12 +231,12 @@ namespace http { "
\r\n" " " << tr("Main page") << "

\r\n" " " << tr("Router commands") << "
\r\n" - " " << tr("Local destinations") << "
\r\n"; + " " << tr("Local Destinations") << "
\r\n"; if (i2p::context.IsFloodfill ()) s << " " << tr("LeaseSets") << "
\r\n"; s << " " << tr("Tunnels") << "
\r\n" - " " << tr("Transit tunnels") << "
\r\n" + " " << tr("Transit Tunnels") << "
\r\n" " " << tr ("Transports") << "
\r\n" " " << tr("I2P tunnels") << "
\r\n"; if (i2p::client::context.GetSAMBridge ()) @@ -325,13 +325,13 @@ namespace http { s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); - s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr("KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Sent") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); - s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr("KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Transit") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr("KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Data path") << ": " << i2p::fs::GetUTF8DataDir() << "
\r\n"; s << "
"; if((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { @@ -482,7 +482,7 @@ namespace http { s << "
"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr(/* Milliseconds */ "ms") << " )"; + s << " ( " << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -540,7 +540,8 @@ namespace http { if (dest) { ShowLeaseSetDestination (s, dest, token); - // show streams + + // Print table with streams information s << "\r\n\r\n\r\n"; s << ""; s << "
" << tr("Streams") << "
StreamID"; // Stream closing button column @@ -685,14 +686,17 @@ namespace http { static void ShowCommands (std::stringstream& s, uint32_t token) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - /* commands */ + s << "" << tr("Router commands") << "
\r\n
\r\n
\r\n"; s << " " << tr("Run peer test") << "
\r\n"; - //s << " Reload config
\r\n"; + + // s << " Reload config
\r\n"; + if (i2p::context.AcceptsTunnels ()) s << " " << tr("Decline transit tunnels") << "
\r\n"; else s << " " << tr("Accept transit tunnels") << "
\r\n"; + #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) s << " " << tr("Cancel graceful shutdown") << "
\r\n"; @@ -704,6 +708,7 @@ namespace http { else s << " " << tr("Start graceful shutdown") << "
\r\n"; #endif + s << " " << tr("Force shutdown") << "\r\n"; s << "
"; @@ -743,7 +748,7 @@ namespace http { { if(i2p::tunnel::tunnels.CountTransitTunnels()) { - s << "" << tr("Transit tunnels") << ":
\r\n
\r\n"; + s << "" << tr("Transit Tunnels") << ":
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { s << "
\r\n"; @@ -759,7 +764,7 @@ namespace http { } else { - s << "" << tr("Transit tunnels") << ": " << tr("no transit tunnels currently built") << ".
\r\n"; + s << "" << tr("Transit Tunnels") << ": " << tr("no transit tunnels currently built") << ".
\r\n"; } } @@ -1279,7 +1284,7 @@ namespace http { s << "" << tr("ERROR") << ": " << tr("StreamID can't be null") << "
\r\n
\r\n"; s << "" << tr("Return to destination page") << "
\r\n"; - s << "

" << tr("You will be redirected back in 5 seconds") << ""; + s << "

" << tr("You will be redirected in 5 seconds") << ""; redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32; res.add_header("Refresh", redirect.c_str()); return; @@ -1292,7 +1297,7 @@ namespace http { else { s << "" << tr("ERROR") << ": " << tr("Transit tunnels count must not exceed 65535") << "\r\n
\r\n
\r\n"; s << "" << tr("Back to commands list") << "\r\n
\r\n"; - s << "

" << tr("You will be redirected back in 5 seconds") << ""; + s << "

" << tr("You will be redirected in 5 seconds") << ""; res.add_header("Refresh", redirect.c_str()); return; } diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index d8b84e82..70cf78a8 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -319,7 +319,7 @@ namespace proxy { auto pos = uri.find(":"); if(pos == std::string::npos || pos == uri.size() - 1) { - GenericProxyError(tr("Invalid Request"), tr("invalid request uri")); + GenericProxyError(tr("Invalid request"), tr("invalid request uri")); return true; } else From 5781335814b1c3766ccaadb66418c715daa88e55 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 29 Jun 2021 19:08:11 -0400 Subject: [PATCH 0200/2193] save and check last stream --- libi2pd/Streaming.cpp | 21 +++++++++++++++------ libi2pd/Streaming.h | 11 ++++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 612b1058..3269e040 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1050,6 +1050,7 @@ namespace stream it.second->Terminate (false); // we delete here m_Streams.clear (); m_IncomingStreams.clear (); + m_LastStream = nullptr; } } @@ -1058,9 +1059,16 @@ namespace stream uint32_t sendStreamID = packet->GetSendStreamID (); if (sendStreamID) { - auto it = m_Streams.find (sendStreamID); - if (it != m_Streams.end ()) - it->second->HandleNextPacket (packet); + if (!m_LastStream || sendStreamID != m_LastStream->GetRecvStreamID ()) + { + auto it = m_Streams.find (sendStreamID); + if (it != m_Streams.end ()) + m_LastStream = it->second; + else + m_LastStream = nullptr; + } + if (m_LastStream) + m_LastStream->HandleNextPacket (packet); else if (packet->IsEcho () && m_Owner->IsStreamingAnswerPings ()) { // ping @@ -1166,7 +1174,7 @@ namespace stream { auto s = std::make_shared (m_Owner->GetService (), *this, remote, port); std::unique_lock l(m_StreamsMutex); - m_Streams[s->GetRecvStreamID ()] = s; + m_Streams.emplace (s->GetRecvStreamID (), s); return s; } @@ -1174,8 +1182,8 @@ namespace stream { auto s = std::make_shared (m_Owner->GetService (), *this); std::unique_lock l(m_StreamsMutex); - m_Streams[s->GetRecvStreamID ()] = s; - m_IncomingStreams[receiveStreamID] = s; + m_Streams.emplace (s->GetRecvStreamID (), s); + m_IncomingStreams.emplace (receiveStreamID, s); return s; } @@ -1186,6 +1194,7 @@ namespace stream std::unique_lock l(m_StreamsMutex); m_Streams.erase (stream->GetRecvStreamID ()); m_IncomingStreams.erase (stream->GetSendStreamID ()); + if (m_LastStream == stream) m_LastStream = nullptr; } } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index fe035136..c40c49f5 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -297,12 +297,13 @@ namespace stream uint16_t m_LocalPort; bool m_Gzip; // gzip compression of data messages std::mutex m_StreamsMutex; - std::map > m_Streams; // sendStreamID->stream - std::map > m_IncomingStreams; // receiveStreamID->stream + std::unordered_map > m_Streams; // sendStreamID->stream + std::unordered_map > m_IncomingStreams; // receiveStreamID->stream + std::shared_ptr m_LastStream; Acceptor m_Acceptor; std::list > m_PendingIncomingStreams; boost::asio::deadline_timer m_PendingIncomingTimer; - std::map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN + std::unordered_map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN i2p::util::MemoryPool m_PacketsPool; i2p::util::MemoryPool > m_I2NPMsgsPool; From abee29719d57c6569ad0bc462cd13cdcd4b466b3 Mon Sep 17 00:00:00 2001 From: idk Date: Fri, 2 Jul 2021 10:47:55 -0400 Subject: [PATCH 0201/2193] fix go linking --- Makefile | 2 +- libi2pd_wrapper/api.go | 14 ++++++++++++-- libi2pd_wrapper/capi.cpp | 3 +-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 59faa94b..b1db36a8 100644 --- a/Makefile +++ b/Makefile @@ -123,7 +123,7 @@ $(ARLIB): $(LIB_OBJS) $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ -$(ARLIB_WRAP): $(LIB_OBJS) +$(ARLIB_WRAP): $(WRAP_LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_LANG): $(LANG_OBJS) diff --git a/libi2pd_wrapper/api.go b/libi2pd_wrapper/api.go index 48a41a4f..4674f16f 100644 --- a/libi2pd_wrapper/api.go +++ b/libi2pd_wrapper/api.go @@ -1,7 +1,17 @@ package api /* -#cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes -#cgo LDFLAGS: -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +/* +#cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -I${SRCDIR}/../libi2pd -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes +#cgo LDFLAGS: -L${SRCDIR}/../ -l:libi2pd.a -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ */ import "C" + +// -D, -U, -I, and \ No newline at end of file diff --git a/libi2pd_wrapper/capi.cpp b/libi2pd_wrapper/capi.cpp index 55b1b051..fc4df917 100644 --- a/libi2pd_wrapper/capi.cpp +++ b/libi2pd_wrapper/capi.cpp @@ -85,10 +85,9 @@ void C_TerminateI2P () return i2p::api::TerminateI2P(); } -void C_StartI2P ()//std::ostream *logStream) +void C_StartI2P () { std::shared_ptr logStream; - //cppLogStream(&out); return i2p::api::StartI2P(logStream); } From ff0e23d2c40fd52ba1fd1f7fba67c09444c57b9f Mon Sep 17 00:00:00 2001 From: r4sas Date: Fri, 2 Jul 2021 16:43:41 +0000 Subject: [PATCH 0202/2193] [cmake] use GNUInstallDirs for libraries destination path (#1672) Signed-off-by: r4sas --- build/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d1502deb..2cd598f4 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -27,6 +27,9 @@ option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") set(CMAKE_SOURCE_DIR "..") +#Handle paths nicely +include(GNUInstallDirs) + # architecture include(TargetArch) target_architecture(ARCHITECTURE) @@ -48,8 +51,8 @@ set_target_properties(libi2pd PROPERTIES PREFIX "") if(WITH_LIBRARY) install(TARGETS libi2pd EXPORT libi2pd - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) # TODO Make libi2pd available to 3rd party projects via CMake as imported target # FIXME This pulls stdafx @@ -63,8 +66,8 @@ set_target_properties(libi2pdclient PROPERTIES PREFIX "") if(WITH_LIBRARY) install(TARGETS libi2pdclient EXPORT libi2pdclient - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) endif() @@ -75,8 +78,8 @@ set_target_properties(libi2pdlang PROPERTIES PREFIX "") if(WITH_LIBRARY) install(TARGETS libi2pdlang EXPORT libi2pdlang - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries) endif() @@ -272,9 +275,6 @@ message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS "---------------------------------------") -#Handle paths nicely -include(GNUInstallDirs) - if(WITH_BINARY) add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) From 8b35ce33202591c092fc57be6f8e27eb91ead2b1 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Jul 2021 13:20:24 -0400 Subject: [PATCH 0203/2193] separate decryption between own record and other records --- libi2pd/Tunnel.cpp | 36 ++++++++++++++++++------------------ libi2pd/TunnelConfig.cpp | 23 +++++++++++++++++++++++ libi2pd/TunnelConfig.h | 1 + 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index ba01ae20..7e154cbf 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -111,31 +111,31 @@ namespace tunnel TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { + // decrypt current hop + auto idx = hop->recordIndex; + if (idx >= 0 && idx < msg[0]) + { + uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; + if (!hop->DecryptBuildResponseRecord (record, record)) + return false; + } + else + { + LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); + return false; + } + + // decrypt records before current hop decryption.SetKey (hop->replyKey); - // decrypt records before and current hop - TunnelHopConfig * hop1 = hop; + TunnelHopConfig * hop1 = hop->prev; while (hop1) { auto idx = hop1->recordIndex; if (idx >= 0 && idx < msg[0]) { uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - if (hop1 == hop && hop1->IsECIES ()) - { - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16, - hop->m_H, 32, hop->m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt - { - LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); - return false; - } - } - else - { - decryption.SetIV (hop->replyIV); - decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); - } + decryption.SetIV (hop->replyIV); + decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); } else LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 8f515c5d..9079e134 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -147,5 +147,28 @@ namespace tunnel } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } + + bool TunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + if (IsECIES ()) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, + m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); + return false; + } + } + else + { + i2p::crypto::CBCDecryption decryption; + decryption.SetKey (replyKey); + decryption.SetIV (replyIV); + decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + } + return true; + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 45693970..548ef031 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -43,6 +43,7 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); void EncryptECIES (std::shared_ptr& encryptor, const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); }; class TunnelConfig From 5d01ee95810aa72ccb6d0aca5c39a9b8eca37ef5 Mon Sep 17 00:00:00 2001 From: idk Date: Fri, 2 Jul 2021 13:20:28 -0400 Subject: [PATCH 0204/2193] Also add the languages to the linker flags in the api.go file --- libi2pd_wrapper/api.go | 4 +--- libi2pd_wrapper/capi.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libi2pd_wrapper/api.go b/libi2pd_wrapper/api.go index 4674f16f..64403aae 100644 --- a/libi2pd_wrapper/api.go +++ b/libi2pd_wrapper/api.go @@ -10,8 +10,6 @@ package api /* #cgo CXXFLAGS: -I${SRCDIR}/../i18n -I${SRCDIR}/../libi2pd_client -I${SRCDIR}/../libi2pd -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi -fPIC -D__AES__ -maes -#cgo LDFLAGS: -L${SRCDIR}/../ -l:libi2pd.a -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ +#cgo LDFLAGS: -L${SRCDIR}/../ -l:libi2pd.a -l:libi2pdlang.a -latomic -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lstdc++ */ import "C" - -// -D, -U, -I, and \ No newline at end of file diff --git a/libi2pd_wrapper/capi.h b/libi2pd_wrapper/capi.h index 3e33a0ee..bfc4f88b 100644 --- a/libi2pd_wrapper/capi.h +++ b/libi2pd_wrapper/capi.h @@ -17,7 +17,7 @@ extern "C" { void C_InitI2P (int argc, char argv[], const char * appName); //void C_InitI2P (int argc, char** argv, const char * appName); void C_TerminateI2P (); -void C_StartI2P (); //std::ostream *logStream = nullptr); +void C_StartI2P (); // write system log to logStream, if not specified to .log in application's folder void C_StopI2P (); void C_RunPeerTest (); // should be called after UPnP From 0ae170531e942f9488889d2f4367f90109f35928 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Jul 2021 15:41:33 -0400 Subject: [PATCH 0205/2193] different ElGamal and ECIES hops configs --- libi2pd/TunnelConfig.cpp | 122 ++++++++++++++++++++------------------- libi2pd/TunnelConfig.h | 42 +++++++++++--- 2 files changed, 99 insertions(+), 65 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 9079e134..6a314ec3 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -78,53 +78,42 @@ namespace tunnel } } - void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { + // fill clear text uint8_t flag = 0; if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); + htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; + htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); + htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); + // encrypt auto encryptor = ident->CreateEncryptor (nullptr); - if (IsECIES ()) - { - uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - memset (clearText + ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 3); // set to 0 for compatibility - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ()); - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET, 600); // +10 minutes - htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); - if (encryptor) - EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); - } - else - { - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); - htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); - htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - if (encryptor) - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); - } + if (encryptor) + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); - } + } - void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + i2p::crypto::CBCDecryption decryption; + decryption.SetKey (replyKey); + decryption.SetIV (replyIV); + decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + return true; + } + + void ECIESTunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { uint8_t hepk[32]; @@ -147,26 +136,43 @@ namespace tunnel } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } - - bool TunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + + void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { - if (IsECIES ()) + // fill clear text + uint8_t flag = 0; + if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; + if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); + memcpy (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; + memset (clearText + ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 3); // set to 0 for compatibility + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ()); + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET, 600); // +10 minutes + htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); + // encrypt + auto encryptor = ident->CreateEncryptor (nullptr); + if (encryptor) + EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); + } + + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, + m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt { - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, - m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt - { - LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); - return false; - } - } - else - { - i2p::crypto::CBCDecryption decryption; - decryption.SetKey (replyKey); - decryption.SetIV (replyIV); - decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); + return false; } return true; } diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 548ef031..f64db0b0 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -18,7 +18,7 @@ namespace i2p { namespace tunnel { - struct TunnelHopConfig: public i2p::crypto::NoiseSymmetricState + struct TunnelHopConfig { std::shared_ptr ident; i2p::data::IdentHash nextIdent; @@ -33,18 +33,42 @@ namespace tunnel int recordIndex; // record # in tunnel build message TunnelHopConfig (std::shared_ptr r); + virtual ~TunnelHopConfig () {}; void SetNextIdent (const i2p::data::IdentHash& ident); void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent); void SetNext (TunnelHopConfig * n); void SetPrev (TunnelHopConfig * p); - bool IsECIES () const { return ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - void EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + virtual bool IsECIES () const { return false; }; + virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; + virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) = 0; }; + + struct ElGamalTunnelHopConfig: public TunnelHopConfig + { + ElGamalTunnelHopConfig (std::shared_ptr r): + TunnelHopConfig (r) {}; + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + }; + + struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState + { + ECIESTunnelHopConfig (std::shared_ptr r): + TunnelHopConfig (r) {}; + bool IsECIES () const { return true; }; + void EncryptECIES (std::shared_ptr& encryptor, + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + }; + + struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig + { + LongECIESTunnelHopConfig (std::shared_ptr r): + ECIESTunnelHopConfig (r) {}; + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + }; class TunnelConfig { @@ -154,7 +178,11 @@ namespace tunnel TunnelHopConfig * prev = nullptr; for (const auto& it: peers) { - auto hop = new TunnelHopConfig (it); + TunnelHopConfig * hop; + if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + hop = new LongECIESTunnelHopConfig (it); + else + hop = new ElGamalTunnelHopConfig (it); if (prev) prev->SetNext (hop); else From aace644815dbf170b3e9e8e720b2116922de0f8a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Jul 2021 22:06:24 -0400 Subject: [PATCH 0206/2193] added ShortECIESTunnelHopConfig --- libi2pd/I2NPProtocol.h | 1 + libi2pd/TunnelConfig.cpp | 59 ++++++++++++++++++++++++++++++++-------- libi2pd/TunnelConfig.h | 12 ++++++-- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 69d6bb04..8cb68856 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -113,6 +113,7 @@ namespace i2p const size_t SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET = SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE + 1; const size_t SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; + const size_t SHORT_REQUEST_RECORD_PADDING_OFFSET = SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154; enum I2NPMessageType diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 6a314ec3..505f66cc 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -113,9 +113,10 @@ namespace tunnel return true; } - void ECIESTunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) + void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted) { + auto encryptor = ident->CreateEncryptor (nullptr); + if (!encryptor) return; uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); i2p::crypto::InitNoiseNState (*this, hepk); @@ -128,13 +129,19 @@ namespace tunnel MixKey (sharedSecret); uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, m_H, 32, - m_CK + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, len, m_H, 32, m_CK + 32, nonce, encrypted, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Tunnel: Plaintext AEAD encryption failed"); return; } - MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) + MixHash (encrypted, len + 16); // h = SHA256(h || ciphertext) + } + + bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, m_CK, nonce, clearText, len - 16, false); // decrypt } void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) @@ -158,18 +165,46 @@ namespace tunnel htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); // encrypt - auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) - EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + EncryptECIES (clearText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) { - uint8_t nonce[12]; - memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, - m_H, 32, m_CK, nonce, clearText, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + if (!DecryptECIES (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + { + LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); + return false; + } + return true; + } + + void ShortECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + { + // fill clear text + uint8_t flag = 0; + if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; + if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + uint8_t clearText[SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE ]; + htobe32buf (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + htobe32buf (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] = flag; + memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2); + clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE] = 0; // AES + htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ()); + htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes + htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET); + // TODO: derive layer and reply keys + // encrypt + EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); + memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); + } + + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + { + if (!DecryptECIES (encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index f64db0b0..7d6456fd 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -58,8 +58,8 @@ namespace tunnel ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; bool IsECIES () const { return true; }; - void EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); + bool DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText); }; struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig @@ -69,6 +69,14 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); }; + + struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig + { + ShortECIESTunnelHopConfig (std::shared_ptr r): + ECIESTunnelHopConfig (r) {}; + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + }; class TunnelConfig { From a71754273319bd12f6f92007d943f62714a49e67 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Jul 2021 07:33:28 -0400 Subject: [PATCH 0207/2193] update yggdrasil reseed to 0.4 --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index e5640ad0..de294357 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -213,7 +213,7 @@ namespace config { "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( - "http://[324:9de3:fea4:f6ac::ace]:7070/" + "http://[324:71e:281a:9ed3::ace]:7070/" ), "Reseed URLs through the Yggdrasil, separated by comma") ; From 9000b3df4edcbe7f2c8afd0e1e30609746311ace Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 5 Jul 2021 14:31:07 -0400 Subject: [PATCH 0208/2193] KDF for short tunnel build messages --- libi2pd/I2NPProtocol.cpp | 28 +++++++++++++++++++--------- libi2pd/TunnelConfig.cpp | 22 +++++++++++++++++----- libi2pd/TunnelConfig.h | 2 +- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index a040e25b..6034e5f4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -622,17 +622,28 @@ namespace i2p return; } auto& noiseState = i2p::context.GetCurrentNoiseState (); - uint8_t layerKeys[64]; // (layer key, iv key) - i2p::crypto::HKDF (noiseState.m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain + uint8_t replyKey[32], layerKey[32], ivKey[32]; + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK); + memcpy (replyKey, noiseState.m_CK + 32, 32); + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelLayerKey", noiseState.m_CK); + memcpy (layerKey, noiseState.m_CK + 32, 32); + bool isEndpoint = clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; + if (isEndpoint) + { + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "TunnelLayerIVKey", noiseState.m_CK); + memcpy (ivKey, noiseState.m_CK + 32, 32); + } + else + memcpy (ivKey, noiseState.m_CK , 32); auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - layerKeys, layerKeys + 32, + layerKey, ivKey, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - if (clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) + if (isEndpoint) { // we are endpoint, create OutboundTunnelBuildReply auto otbrm = NewI2NPShortMessage (); @@ -658,14 +669,13 @@ namespace i2p } otbrm->len += (payload - otbrm->GetPayload ()); otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); - uint8_t replyKeys[64]; // (reply key, tag) - i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); uint64_t tag; - memcpy (&tag, replyKeys + 32, 8); + memcpy (&tag, noiseState.m_CK, 8); // send garlic to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, replyKeys, tag))); + i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, noiseState.m_CK + 32, tag))); } else { @@ -680,7 +690,7 @@ namespace i2p { // TODO: fill reply if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState.m_H, 32, noiseState.m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt + noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); return; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 505f66cc..cc612c00 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -137,11 +137,11 @@ namespace tunnel MixHash (encrypted, len + 16); // h = SHA256(h || ciphertext) } - bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText) + bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText) { uint8_t nonce[12]; memset (nonce, 0, 12); - return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, m_CK, nonce, clearText, len - 16, false); // decrypt + return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, key, nonce, clearText, len - 16, false); // decrypt } void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) @@ -171,7 +171,7 @@ namespace tunnel bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) { - if (!DecryptECIES (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (m_CK, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -196,15 +196,27 @@ namespace tunnel htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET); - // TODO: derive layer and reply keys // encrypt EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); + // derive reply and layer key + i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelReplyKey", m_CK); + memcpy (replyKey, m_CK + 32, 32); + i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelLayerKey", m_CK); + memcpy (layerKey, m_CK + 32, 32); + if (isEndpoint) + { + i2p::crypto::HKDF (m_CK, nullptr, 0, "TunnelLayerIVKey", m_CK); + memcpy (ivKey, m_CK + 32, 32); + i2p::crypto::HKDF (m_CK, nullptr, 0, "RGarlicKeyAndTag", m_CK); // OTBRM garlic key m_CK + 32, tag first 8 bytes of m_CK + } + else + memcpy (ivKey, m_CK, 32); // last HKDF memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) { - if (!DecryptECIES (encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (replyKey, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 7d6456fd..d4c85558 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -59,7 +59,7 @@ namespace tunnel TunnelHopConfig (r) {}; bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); - bool DecryptECIES (const uint8_t * encrypted, size_t len, uint8_t * clearText); + bool DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText); }; struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig From 4255c4901de8199ffae805ff040cb0bf54d2ad82 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Jul 2021 17:44:39 -0400 Subject: [PATCH 0209/2193] orignal's reseed ceritifcate --- contrib/certificates/{router => reseed}/orignal_at_mail.i2p.crt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/certificates/{router => reseed}/orignal_at_mail.i2p.crt (100%) diff --git a/contrib/certificates/router/orignal_at_mail.i2p.crt b/contrib/certificates/reseed/orignal_at_mail.i2p.crt similarity index 100% rename from contrib/certificates/router/orignal_at_mail.i2p.crt rename to contrib/certificates/reseed/orignal_at_mail.i2p.crt From 431265a86af2979b37ef1a1cb679b7a462a5bf15 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Jul 2021 18:22:08 -0400 Subject: [PATCH 0210/2193] update orignal's certificate --- .../reseed/orignal_at_mail.i2p.crt | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/contrib/certificates/reseed/orignal_at_mail.i2p.crt b/contrib/certificates/reseed/orignal_at_mail.i2p.crt index c1229f3b..799b601b 100644 --- a/contrib/certificates/reseed/orignal_at_mail.i2p.crt +++ b/contrib/certificates/reseed/orignal_at_mail.i2p.crt @@ -1,31 +1,32 @@ -----BEGIN CERTIFICATE----- -MIIFVDCCAzwCCQC2r1XWYtqtAzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJY -WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMRMwEQYDVQQKDApQdXJwbGUgSTJQ -MQ0wCwYDVQQLDARJMlBEMR8wHQYJKoZIhvcNAQkBFhBvcmlnbmFsQG1haWwuaTJw -MB4XDTE1MDIyMjEzNTgxOFoXDTI1MDIxOTEzNTgxOFowbDELMAkGA1UEBhMCWFgx -CzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDETMBEGA1UECgwKUHVycGxlIEkyUDEN -MAsGA1UECwwESTJQRDEfMB0GCSqGSIb3DQEJARYQb3JpZ25hbEBtYWlsLmkycDCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALp3D/gdvFjrMm+IE8tHZCWE -hQ6Pp0CCgCGDBC3WQFLqR98bqVPl4UwRG/MKY/LY7Woai06JNmGcpfw0LMoNnHxT -bvKtDRe/8kQdhdLHhgIkWKSbMvTAl7uUdV6FzsPgDR0x7scoFVWEhkF0wfmzGF2V -yr/WCBQejFPu69z03m5tRQ8Xjp2txWV45RawUmFu50bgbZvLCSLfTkIvxmfJzgPN -pJ3sPa/g7TBZl2uEiAu4uaEKvTuuzStOWCGgFaHYFVlTfFXTvmhFMqHfaidtzrlu -H35WGrmIWTDl6uGPC5QkSppvkj73rDj5aEyPzWMz5DN3YeECoVSchN+OJJCM6m7+ -rLFYXghVEp2h+T9O1GBRfcHlQ2E3CrWWvxhmK8dfteJmd501dyNX2paeuIg/aPFO -54/8m2r11uyF29hgY8VWLdXtqvwhKuK36PCzofEwDp9QQX8GRsEV4pZTrn4bDhGo -kb9BF7TZTqtL3uyiRmIyBXrNNiYlA1Xm4fyKRtxl0mrPaUXdgdnCt3KxOAJ8WM2B -7L/kk9U8C/nexHbMxIZfTap49XcUg5dxSO9kOBosIOcCUms8sAzBPDV2tWAByhYF -jI/Tutbd3F0+fvcmTcIFOlGbOxKgO2SfwXjv/44g/3LMK6IAMFB9UOc8KhnnJP0f -uAHvMXn1ahRs4pM1VizLAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAIOxdaXT+wfu -nv/+1hy5T4TlRMNNsuj79ROcy6Mp+JwMG50HjTc0qTlXh8C7nHybDJn4v7DA+Nyn -RxT0J5I+Gqn+Na9TaC9mLeX/lwe8/KomyhBWxjrsyWj1V6v/cLO924S2rtcfzMDm -l3SFh9YHM1KF/R9N1XYBwtMzr3bupWDnE1yycYp1F4sMLr5SMzMQ0svQpQEM2/y5 -kly8+eUzryhm+ag9x1686uEG5gxhQ1eHQoZEaClHUOsV+28+d5If7cqcYx9Hf5Tt -CiVjJQzdxBF+6GeiJtKxnLtevqlkbyIJt6Cm9/7YIy/ovRGF2AKSYN6oCwmZQ6i1 -8nRnFq5zE7O94m+GXconWZxy0wVqA6472HThMi7S+Tk/eLYen2ilGY+KCb9a0FH5 -5MOuWSoJZ8/HfW2VeQmL8EjhWm5F2ybg28wgXK4BOGR3jQi03Fsc+AFidnWxSKo0 -aiJoPgOsfyu8/fnCcAi07kSmjzUKIWskApgcpGQLNXHFK9mtg7+VA8esRnfLlKtP -tJf+nNAPY1sqHfGBzh7WWGWal5RGHF5nEm3ta3oiFF5sMKCJ6C87zVwFkEcRytGC -xOGmiG1O1RPrO5NG7rZUaQ4y1OKl2Y1H+nGONzZ3mvoAOvxEq6JtUnU2kZscpPlk -fpeOSDoGBYJGbIpzDreBDhxaZrwGq36k +MIIFfzCCA2egAwIBAgIEbNbRPjANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY +WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt +b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEZMBcGA1UEAwwQb3JpZ25hbEBtYWls +LmkycDAeFw0yMTA3MDYyMjExMDFaFw0zMTA3MDQyMjExMDFaMHAxCzAJBgNVBAYT +AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNVBAoMFUkyUCBBbm9u +eW1vdXMgTmV0d29yazEMMAoGA1UECwwDSTJQMRkwFwYDVQQDDBBvcmlnbmFsQG1h +aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvNJz2KGuAkHP +tGFobfLvpybtxB50fkcEsTc9opmiy7wBKK9rSI01VS616IhABkWKZVfK2A9NqpGv +v/CyhTKoaeSNeXY7+zORUWgWK/zA9fA4GRZFqlW8j4tbompDwcLYNqRBCsn1C0OY +YA5JhXPBixMcnXl8N8x4sXhQ4l9R3+QrydhUHRvgDc8dOxRyIX7zuQAyf8tmA2Xo +xZLdvDcCJdLBIbFwxhIceIhgcOwaOx7oRkZDZdYcLJd3zjyPbu8JtOM2ZkwH7r+0 +ro5PktuDp2LAS6SII5yYNcwcrvPZGPqhLdifIw1BrdTIb/rIkQZ5iXOOdyPmT7e8 +IwAJcPFlfvrS4Vbi9oDqyx3aDUBoubgmFnO1TirL56ck83R/ubcKtdnyzAn5dp+f +ZNYW6/foSBpDDOCViylbFAR5H0HJEbBns7PZx6mGEEI4tUAJdNYl7Ly7Df60a9Rz +cD/gz08U9UwFXYKoT6roEjToADGAzb5MI4cVlAb2AmQaMNXNe04HcDL1bU50mkNU +amqPv8nxf72fBQCEmZz2G57T6QiYTtcCwiWS1QdWsuaOtCo9zO0MKcjzSdUxuxEc +dXhjQdNegsgg/Xk7bJ8lKOsACqMpFftdPmuyeZU2t+3RPuBpV/0j2qUfg/y6kb0z +CxAOYmlcL4kqw4VT+5V/EeZLIG0h9I0CAwEAAaMhMB8wHQYDVR0OBBYEFD/wJObg +CCDuhMJCVWTSTj+B3rsUMA0GCSqGSIb3DQEBDQUAA4ICAQC0PjsTSPWlGbLNeeI8 +F0B5xAwXYJzZ7/LRxh8u42HDUqVIDjqkuls1l3v9D7htty2Gr3Ws2dcvcOr2KcOy +mEWg+jdP/N3vt9IkZeVS4YQoPgq6orn7lVkk00bcKb24f7ZnoQnnVV0/m42Y5P4j +LLh+8MBxsez9azXyZbDVEkgsMUAkdVO6KNz6scqz7wb8egV2GAMAp7cwChC6lanK +gv9ZyJhG/HdTv6VyuMZhJy6rX4geM97tm1iHu1VLsQcIzBKAdEvWJv8ofMeiyINe +hqAP9NYaeowKi975NOrmf+XZwxd0niApIohV684RCVUfL8H7HSPbdXhBJ/WslyDP +cTGhA2BLqEXZBn/nLQknlnl0SZTQxG2n4fEgD1E5YS/aoBrig/uXtWm2Zdf8U3mM ++bNXhbi9s7LneN2ye8LlNJBSRklNn/bNo8OmzLII1RQwf1+vaHT96lASbTVepMZ/ +Y9VcC8fAmho/zfQEKueLEB03K+gr2dGD+1crmMtUBjWJ9vPjtooZArtkDbh+kVYA +cx4N4NXULRwxVWZe5wTQOqcZ3qSS1ClMwaziwychGaj8xRAirHMZnlPOZO1UK4+5 +8F4RMJktyZjNgSLP76XPS4rJK5fobuPqFeA4OpDFn/5+/XeQFF6i6wntx1tzztzH +zc+BrVZOdcYPqu9iLXyRQ9JwwA== -----END CERTIFICATE----- From a6294df9e8bbfae39a71bd39fd3248699f8b41e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Jul 2021 20:15:55 -0400 Subject: [PATCH 0211/2193] decrypt one-time message encrypted with tag on router --- libi2pd/Garlic.cpp | 37 +++++++++++++++++++++---------------- libi2pd/Garlic.h | 1 + libi2pd/RouterContext.cpp | 12 ++++++++---- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 2bf89556..38eda05a 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -494,22 +494,9 @@ namespace garlic buf += 4; // length bool found = false; - uint64_t tag; if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) - { // try ECIESx25519 tag - memcpy (&tag, buf, 8); - auto it1 = m_ECIESx25519Tags.find (tag); - if (it1 != m_ECIESx25519Tags.end ()) - { - found = true; - if (it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) - m_LastTagset = it1->second.tagset; - else - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); - m_ECIESx25519Tags.erase (it1); - } - } + found = HandleECIESx25519TagMessage (buf, length); if (!found) { auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16 @@ -555,6 +542,7 @@ namespace garlic // try to gererate more tags for last tagset if (m_LastTagset && (m_LastTagset->GetNextIndex () - m_LastTagset->GetTrimBehind () < 3*ECIESX25519_MAX_NUM_GENERATED_TAGS)) { + uint64_t missingTag; memcpy (&missingTag, buf, 8); auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); LogPrint (eLogWarning, "Garlic: trying to generate more ECIES-X25519-AEAD-Ratchet tags"); for (int i = 0; i < maxTags; i++) @@ -565,10 +553,10 @@ namespace garlic LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for last tagset"); break; } - if (nextTag == tag) + if (nextTag == missingTag) { LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); - if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[tag].index)) + if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[nextTag].index)) found = true; break; } @@ -585,6 +573,23 @@ namespace garlic } } + bool GarlicDestination::HandleECIESx25519TagMessage (uint8_t * buf, size_t len) + { + uint64_t tag; + memcpy (&tag, buf, 8); + auto it = m_ECIESx25519Tags.find (tag); + if (it != m_ECIESx25519Tags.end ()) + { + if (it->second.tagset->HandleNextMessage (buf, len, it->second.index)) + m_LastTagset = it->second.tagset; + else + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + m_ECIESx25519Tags.erase (it); + return true; + } + return false; + } + void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr decryption, std::shared_ptr from) { diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 4288e74b..a898e6a1 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -260,6 +260,7 @@ namespace garlic protected: + bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; void HandleGarlicMessage (std::shared_ptr msg); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b2a19890..c25f5064 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -843,10 +843,14 @@ namespace i2p return; } buf += 4; - if (m_ECIESSession) - m_ECIESSession->HandleNextMessage (buf, len); - else - LogPrint (eLogError, "Router: Session is not set for ECIES router"); + if (!HandleECIESx25519TagMessage (buf, len)) // try tag first + { + // then Noise_N one-time decryption + if (m_ECIESSession) + m_ECIESSession->HandleNextMessage (buf, len); + else + LogPrint (eLogError, "Router: Session is not set for ECIES router"); + } } else i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); From 847225c6bfa0d8e83ff27606104805b2870b93ad Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Jul 2021 08:24:01 -0400 Subject: [PATCH 0212/2193] more yggdrasil reseeds added --- libi2pd/Config.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index de294357..a8516e00 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -213,7 +213,9 @@ namespace config { "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ("reseed.yggurls", value()->default_value( - "http://[324:71e:281a:9ed3::ace]:7070/" + "http://[324:71e:281a:9ed3::ace]:7070/," + "http://[301:65b9:c7cd:9a36::1]:18801/," + "http://[320:8936:ec1a:31f1::216]/" ), "Reseed URLs through the Yggdrasil, separated by comma") ; From ed0c2e68a5e45f06caf5d394ff240129967c68ae Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Jul 2021 21:16:30 -0400 Subject: [PATCH 0213/2193] DecryptRecord per tunnel hop --- libi2pd/Tunnel.cpp | 12 ++---------- libi2pd/TunnelConfig.cpp | 37 +++++++++++++++++++++++++++++-------- libi2pd/TunnelConfig.h | 19 ++++++++++--------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 7e154cbf..84df9b56 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -78,18 +78,14 @@ namespace tunnel } // decrypt real records - i2p::crypto::CBCDecryption decryption; hop = m_Config->GetLastHop ()->prev; while (hop) { - decryption.SetKey (hop->replyKey); // decrypt records after current hop TunnelHopConfig * hop1 = hop->next; while (hop1) { - decryption.SetIV (hop->replyIV); - uint8_t * record = records + hop1->recordIndex*TUNNEL_BUILD_RECORD_SIZE; - decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); + hop->DecryptRecord (records, hop1->recordIndex); hop1 = hop1->next; } hop = hop->prev; @@ -132,11 +128,7 @@ namespace tunnel { auto idx = hop1->recordIndex; if (idx >= 0 && idx < msg[0]) - { - uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - decryption.SetIV (hop->replyIV); - decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); - } + hop->DecryptRecord (msg + 1, idx); else LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); hop1 = hop1->prev; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index cc612c00..1680a0b1 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -77,6 +77,15 @@ namespace tunnel isGateway = false; } } + + void TunnelHopConfig::DecryptRecord (uint8_t * records, int index) const + { + uint8_t * record = records + index*TUNNEL_BUILD_RECORD_SIZE; + i2p::crypto::CBCDecryption decryption; + decryption.SetKey (replyKey); + decryption.SetIV (replyIV); + decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); + } void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { @@ -104,7 +113,7 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const { i2p::crypto::CBCDecryption decryption; decryption.SetKey (replyKey); @@ -137,10 +146,8 @@ namespace tunnel MixHash (encrypted, len + 16); // h = SHA256(h || ciphertext) } - bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText) + bool ECIESTunnelHopConfig::DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const { - uint8_t nonce[12]; - memset (nonce, 0, 12); return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, key, nonce, clearText, len - 16, false); // decrypt } @@ -169,9 +176,11 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const { - if (!DecryptECIES (m_CK, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!DecryptECIES (m_CK, nonce, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -214,14 +223,26 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const { - if (!DecryptECIES (replyKey, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + uint8_t nonce[12]; + memset (nonce, 0, 12); + nonce[4] = recordIndex; // nonce is record index + if (!DecryptECIES (replyKey, nonce, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; } return true; } + + void ShortECIESTunnelHopConfig::DecryptRecord (uint8_t * records, int index) const + { + uint8_t * record = records + index*SHORT_TUNNEL_BUILD_RECORD_SIZE; + uint8_t nonce[12]; + memset (nonce, 0, 12); + nonce[4] = index; // nonce is index + i2p::crypto::ChaCha20 (record, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, record); + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index d4c85558..e356a9f0 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -42,7 +42,8 @@ namespace tunnel virtual bool IsECIES () const { return false; }; virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; - virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) = 0; + virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const = 0; + virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; struct ElGamalTunnelHopConfig: public TunnelHopConfig @@ -50,7 +51,7 @@ namespace tunnel ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState @@ -59,7 +60,7 @@ namespace tunnel TunnelHopConfig (r) {}; bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); - bool DecryptECIES (const uint8_t * key, const uint8_t * encrypted, size_t len, uint8_t * clearText); + bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig @@ -67,7 +68,7 @@ namespace tunnel LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig @@ -75,20 +76,21 @@ namespace tunnel ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText); + bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 }; class TunnelConfig { public: - TunnelConfig (std::vector > peers) // inbound + TunnelConfig (const std::vector >& peers) // inbound { CreatePeers (peers); m_LastHop->SetNextIdent (i2p::context.GetIdentHash ()); } - TunnelConfig (std::vector > peers, + TunnelConfig (const std::vector >& peers, uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) // outbound { CreatePeers (peers); @@ -180,8 +182,7 @@ namespace tunnel private: - template - void CreatePeers (const Peers& peers) + void CreatePeers (const std::vector >& peers) { TunnelHopConfig * prev = nullptr; for (const auto& it: peers) From d73b42b7266233ae399cd54a949c382f755803e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Jul 2021 16:39:38 -0400 Subject: [PATCH 0214/2193] extract ret code per hop --- libi2pd/Tunnel.cpp | 13 ++++--------- libi2pd/TunnelConfig.cpp | 15 +++++++++------ libi2pd/TunnelConfig.h | 17 +++++++++++------ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 84df9b56..fe219214 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -103,26 +103,22 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records."); - i2p::crypto::CBCDecryption decryption; TunnelHopConfig * hop = m_Config->GetLastHop (); while (hop) { // decrypt current hop - auto idx = hop->recordIndex; - if (idx >= 0 && idx < msg[0]) + if (hop->recordIndex >= 0 && hop->recordIndex < msg[0]) { - uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE; - if (!hop->DecryptBuildResponseRecord (record, record)) + if (!hop->DecryptBuildResponseRecord (msg + 1)) return false; } else { - LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); + LogPrint (eLogWarning, "Tunnel: hop index ", hop->recordIndex, " is out of range"); return false; } // decrypt records before current hop - decryption.SetKey (hop->replyKey); TunnelHopConfig * hop1 = hop->prev; while (hop1) { @@ -140,8 +136,7 @@ namespace tunnel hop = m_Config->GetFirstHop (); while (hop) { - const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE; - uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET]; + uint8_t ret = hop->GetRetCode (msg + 1); LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret); auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ()); if (profile) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 1680a0b1..b461a3d5 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -113,12 +113,13 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; i2p::crypto::CBCDecryption decryption; decryption.SetKey (replyKey); decryption.SetIV (replyIV); - decryption.Decrypt (encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText); + decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record); return true; } @@ -176,11 +177,12 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool LongECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; uint8_t nonce[12]; memset (nonce, 0, 12); - if (!DecryptECIES (m_CK, nonce, encrypted, TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (m_CK, nonce, record, TUNNEL_BUILD_RECORD_SIZE, record)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; @@ -223,12 +225,13 @@ namespace tunnel memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } - bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const + bool ShortECIESTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const { + uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; uint8_t nonce[12]; memset (nonce, 0, 12); nonce[4] = recordIndex; // nonce is record index - if (!DecryptECIES (replyKey, nonce, encrypted, SHORT_TUNNEL_BUILD_RECORD_SIZE, clearText)) + if (!DecryptECIES (replyKey, nonce, record, SHORT_TUNNEL_BUILD_RECORD_SIZE, record)) { LogPrint (eLogWarning, "Tunnel: Response AEAD decryption failed"); return false; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index e356a9f0..b2bf26b7 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -40,9 +40,9 @@ namespace tunnel void SetNext (TunnelHopConfig * n); void SetPrev (TunnelHopConfig * p); - virtual bool IsECIES () const { return false; }; + virtual uint8_t GetRetCode (const uint8_t * records) const = 0; virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; - virtual bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const = 0; + virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; @@ -50,15 +50,16 @@ namespace tunnel { ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - bool IsECIES () const { return true; }; void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; @@ -67,16 +68,20 @@ namespace tunnel { LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig { ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); - bool DecryptBuildResponseRecord (const uint8_t * encrypted, uint8_t * clearText) const; + bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 }; From 84f6024cc92182793ea974fccf791cae1dcde799 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Jul 2021 19:00:25 -0400 Subject: [PATCH 0215/2193] locate record to build inside CreateBuildRequestRecord --- libi2pd/Tunnel.cpp | 8 ++------ libi2pd/TunnelConfig.cpp | 13 ++++++++++--- libi2pd/TunnelConfig.h | 8 ++++---- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index fe219214..1eb30db2 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -55,7 +55,6 @@ namespace tunnel uint8_t * records = msg->GetPayload () + 1; TunnelHopConfig * hop = m_Config->GetFirstHop (); int i = 0; - BN_CTX * ctx = BN_CTX_new (); while (hop) { uint32_t msgID; @@ -63,13 +62,10 @@ namespace tunnel RAND_bytes ((uint8_t *)&msgID, 4); else msgID = replyMsgID; - int idx = recordIndicies[i]; - hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx); - hop->recordIndex = idx; - i++; + hop->recordIndex = recordIndicies[i]; i++; + hop->CreateBuildRequestRecord (records, msgID); hop = hop->next; } - BN_CTX_free (ctx); // fill up fake records with random data for (int i = numHops; i < numRecords; i++) { diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index b461a3d5..948ffc01 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -87,7 +87,7 @@ namespace tunnel decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); } - void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { // fill clear text uint8_t flag = 0; @@ -107,9 +107,14 @@ namespace tunnel htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); // encrypt + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; auto encryptor = ident->CreateEncryptor (nullptr); if (encryptor) + { + BN_CTX * ctx = BN_CTX_new (); encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); + BN_CTX_free (ctx); + } memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } @@ -152,7 +157,7 @@ namespace tunnel return i2p::crypto::AEADChaCha20Poly1305 (encrypted, len - 16, m_H, 32, key, nonce, clearText, len - 16, false); // decrypt } - void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { // fill clear text uint8_t flag = 0; @@ -173,6 +178,7 @@ namespace tunnel htobe32buf (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET, 0, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET); // encrypt + uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; EncryptECIES (clearText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } @@ -190,7 +196,7 @@ namespace tunnel return true; } - void ShortECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) + void ShortECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { // fill clear text uint8_t flag = 0; @@ -208,6 +214,7 @@ namespace tunnel htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET); // encrypt + uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); // derive reply and layer key i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelReplyKey", m_CK); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index b2bf26b7..591fed52 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -41,7 +41,7 @@ namespace tunnel void SetPrev (TunnelHopConfig * p); virtual uint8_t GetRetCode (const uint8_t * records) const = 0; - virtual void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) = 0; + virtual void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) = 0; virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES }; @@ -52,7 +52,7 @@ namespace tunnel TunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; }; @@ -70,7 +70,7 @@ namespace tunnel ECIESTunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; }; @@ -80,7 +80,7 @@ namespace tunnel ECIESTunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx); + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 }; From c02a0c4da9f417c9958812ebd682f1abdf443f59 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 8 Jul 2021 22:22:00 -0400 Subject: [PATCH 0216/2193] process DELAY_REQUESTED option --- libi2pd/Streaming.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3269e040..bbb649df 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -276,7 +276,20 @@ namespace stream const uint8_t * optionData = packet->GetOptionData (); size_t optionSize = packet->GetOptionSize (); if (flags & PACKET_FLAG_DELAY_REQUESTED) + { + if (!m_IsAckSendScheduled) + { + uint16_t delayRequested = bufbe16toh (optionData); + if (delayRequested > 0 && delayRequested < m_RTT) + { + m_IsAckSendScheduled = true; + m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(delayRequested)); + m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer, + shared_from_this (), std::placeholders::_1)); + } + } optionData += 2; + } if (flags & PACKET_FLAG_FROM_INCLUDED) { @@ -793,7 +806,7 @@ namespace stream if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD) { std::vector msgs; - for (auto it: packets) + for (const auto& it: packets) { auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage ( it->GetBuffer (), it->GetLength (), m_Port, !m_RoutingSession->IsRatchets ())); From 59dd60f5cbc458830d4f7eec30f3e4251f95347b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Jul 2021 19:24:28 -0400 Subject: [PATCH 0217/2193] genarate keys in CreateBuildRequestRecord --- libi2pd/TunnelConfig.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 948ffc01..930c565b 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -23,10 +23,6 @@ namespace tunnel { TunnelHopConfig::TunnelHopConfig (std::shared_ptr r) { - RAND_bytes (layerKey, 32); - RAND_bytes (ivKey, 32); - RAND_bytes (replyKey, 32); - RAND_bytes (replyIV, 16); RAND_bytes ((uint8_t *)&tunnelID, 4); if (!tunnelID) tunnelID = 1; // tunnelID can't be zero isGateway = true; @@ -89,6 +85,11 @@ namespace tunnel void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { + // generate keys + RAND_bytes (layerKey, 32); + RAND_bytes (ivKey, 32); + RAND_bytes (replyKey, 32); + RAND_bytes (replyIV, 16); // fill clear text uint8_t flag = 0; if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; @@ -159,6 +160,11 @@ namespace tunnel void LongECIESTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) { + // generate keys + RAND_bytes (layerKey, 32); + RAND_bytes (ivKey, 32); + RAND_bytes (replyKey, 32); + RAND_bytes (replyIV, 16); // fill clear text uint8_t flag = 0; if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; @@ -216,7 +222,7 @@ namespace tunnel // encrypt uint8_t * record = records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE; EncryptECIES (clearText, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET); - // derive reply and layer key + // derive keys i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelReplyKey", m_CK); memcpy (replyKey, m_CK + 32, 32); i2p::crypto::HKDF (m_CK, nullptr, 0, "SMTunnelLayerKey", m_CK); From d47bf1bada8621e0ac084bef8639a609f99a83b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 9 Jul 2021 19:26:14 -0400 Subject: [PATCH 0218/2193] different tunnel build record size --- libi2pd/Tunnel.cpp | 7 ++++--- libi2pd/TunnelConfig.h | 14 +++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 1eb30db2..34105962 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -42,10 +42,11 @@ namespace tunnel void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel) { auto numHops = m_Config->GetNumHops (); - int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : MAX_NUM_RECORDS; + const int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : MAX_NUM_RECORDS; auto msg = numRecords <= STANDARD_NUM_RECORDS ? NewI2NPShortMessage () : NewI2NPMessage (); *msg->GetPayload () = numRecords; - msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1; + const size_t recordSize = m_Config->IsShort () ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; + msg->len += numRecords*recordSize + 1; // shuffle records std::vector recordIndicies; for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i); @@ -70,7 +71,7 @@ namespace tunnel for (int i = numHops; i < numRecords; i++) { int idx = recordIndicies[i]; - RAND_bytes (records + idx*TUNNEL_BUILD_RECORD_SIZE, TUNNEL_BUILD_RECORD_SIZE); + RAND_bytes (records + idx*recordSize, recordSize); } // decrypt real records diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 591fed52..b33f7668 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -115,6 +115,8 @@ namespace tunnel } } + bool IsShort () const { return m_IsShort; } + TunnelHopConfig * GetFirstHop () const { return m_FirstHop; @@ -193,10 +195,15 @@ namespace tunnel for (const auto& it: peers) { TunnelHopConfig * hop; - if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - hop = new LongECIESTunnelHopConfig (it); + if (m_IsShort) + hop = new ShortECIESTunnelHopConfig (it); else - hop = new ElGamalTunnelHopConfig (it); + { + if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + hop = new LongECIESTunnelHopConfig (it); + else + hop = new ElGamalTunnelHopConfig (it); + } if (prev) prev->SetNext (hop); else @@ -209,6 +216,7 @@ namespace tunnel private: TunnelHopConfig * m_FirstHop, * m_LastHop; + bool m_IsShort = false; }; class ZeroHopsTunnelConfig: public TunnelConfig From 1e9eb30aa32b73e7a15929ecaf72e873926830ce Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 14:33:23 -0400 Subject: [PATCH 0219/2193] garlic encryption of inbound tunnel build message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 ++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- libi2pd/I2NPProtocol.cpp | 2 +- libi2pd/NetDb.cpp | 2 +- libi2pd/Tunnel.cpp | 6 ++++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 55e962d8..9a76ea3c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1133,7 +1133,7 @@ namespace garlic return true; } - std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage (); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -1167,5 +1167,12 @@ namespace garlic return m; } + std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) + { + // TODO: implement without session + auto session = std::make_shared(nullptr, false); + session->SetRemoteStaticKey (routerPublicKey); + return session->WrapOneTimeMessage (msg, true); + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cd7b9b40..71e0a803 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -256,7 +256,8 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_CurrentNoiseState; }; - std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag); + std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey); } } diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 6034e5f4..b9b15c8d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -675,7 +675,7 @@ namespace i2p // send garlic to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519AEADRatchetMessage (otbrm, noiseState.m_CK + 32, tag))); + i2p::garlic::WrapECIESX25519Message (otbrm, noiseState.m_CK + 32, tag))); } else { diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5e93fabb..e3a55832 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -988,7 +988,7 @@ namespace data { uint64_t tag; memcpy (&tag, excluded + 33, 8); - replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag); + replyMsg = i2p::garlic::WrapECIESX25519Message (replyMsg, sessionKey, tag); } else { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 34105962..63f90077 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -23,6 +23,7 @@ #include "Tunnel.h" #include "TunnelPool.h" #include "util.h" +#include "ECIESX25519AEADRatchetSession.h" namespace i2p { @@ -91,7 +92,12 @@ namespace tunnel // send message if (outboundTunnel) + { + auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; + if (ident && ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + msg = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); + } else i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); } From ba1b8c7c2b57f84ccc7fe9011688b64a5437406b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 16:15:15 -0400 Subject: [PATCH 0220/2193] WrapECIESX25519MessageForRouter wihout session --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 108 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 8 +- 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9a76ea3c..09bbfe53 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -518,36 +518,7 @@ namespace garlic } return true; } - - bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Alice, router's bpk is m_RemoteStaticKey - i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey); - size_t offset = 0; - m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32); - MixHash (out + offset, 32); // h = SHA256(h || aepk) - offset += 32; - uint8_t sharedSecret[32]; - if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); - return false; - } - MixKey (sharedSecret); - uint8_t nonce[12]; - CreateNonce (0, nonce); - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt - { - LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); - return false; - } - - m_State = eSessionStateNewSessionSent; - return true; - } - + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob @@ -858,11 +829,6 @@ namespace garlic return nullptr; len += 96; break; - case eSessionStateForRouter: - if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 48; - break; default: return nullptr; } @@ -873,9 +839,9 @@ namespace garlic return m; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter) + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) { - m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime; + m_State = eSessionStateOneTime; return WrapSingleMessage (msg); } @@ -1132,19 +1098,10 @@ namespace garlic HandlePayload (payload.data (), len - 16, nullptr, 0); return true; } - - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + + static size_t CreateGarlicCloveBlock (std::shared_ptr msg, uint8_t * payload) { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 - size_t offset = 0; - memcpy (buf + offset, &tag, 8); offset += 8; - auto payload = buf + offset; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - size_t len = cloveSize + 3; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; @@ -1153,14 +1110,26 @@ namespace garlic htobe32buf (payload + 1, msg->GetMsgID ()); // msgID htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); - - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt + return cloveSize + 3; + } + + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; + size_t len = CreateGarlicCloveBlock (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; } offset += len + 16; - htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); @@ -1169,10 +1138,39 @@ namespace garlic std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { - // TODO: implement without session - auto session = std::make_shared(nullptr, false); - session->SetRemoteStaticKey (routerPublicKey); - return session->WrapOneTimeMessage (msg, true); + // Noise_N, we are Alice, routerPublicKey is Bob's + i2p::crypto::NoiseSymmetricState noiseState; + i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32); + noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk) + offset += 32; + uint8_t sharedSecret[32]; + if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return nullptr; + } + noiseState.MixKey (sharedSecret); + auto payload = buf + offset; + size_t len = CreateGarlicCloveBlock (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); + return nullptr; + } + offset += len + 16; + htobe32buf (m->GetPayload (), offset); + m->len += offset + 4; + m->FillI2NPMessageHeader (eI2NPGarlic); + return m; } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 71e0a803..762e00ef 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -147,8 +147,7 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime, - eSessionStateForRouter + eSessionStateOneTime }; struct DHRatchet @@ -166,7 +165,7 @@ namespace garlic bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); + std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -207,8 +206,7 @@ namespace garlic bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - + std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); From 6a467a09bd6be0800478fa68ca6fcb3c001c505e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 16:47:28 -0400 Subject: [PATCH 0221/2193] fixed build error --- libi2pd/Garlic.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 38eda05a..d91c75f5 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -754,11 +754,7 @@ namespace garlic std::shared_ptr msg) { if (router->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - { - auto session = std::make_shared(this, false); - session->SetRemoteStaticKey (router->GetIdentity ()->GetEncryptionPublicKey ()); - return session->WrapOneTimeMessage (msg, true); - } + return WrapECIESX25519MessageForRouter (msg, router->GetIdentity ()->GetEncryptionPublicKey ()); else { auto session = GetRoutingSession (router, false); From 15c3d46492cc9b04e51a210bce554b9fe40b12d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Jul 2021 17:28:18 -0400 Subject: [PATCH 0222/2193] encrypt inbound tunnel build message for short tunnel build only --- libi2pd/Tunnel.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 63f90077..6c9d59e9 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -93,9 +93,15 @@ namespace tunnel // send message if (outboundTunnel) { - auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; - if (ident && ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - msg = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); + if (m_Config->IsShort ()) + { + auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; + if (ident) + { + auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); + if (msg1) msg = msg; + } + } outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); } else From 3e281d47907234110569083c4b23b24e53e1fa47 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 11 Jul 2021 23:10:53 +0300 Subject: [PATCH 0223/2193] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 37c4553a..6f2d23ec 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE) [![Packaging status](https://repology.org/badge/tiny-repos/i2pd.svg)](https://repology.org/project/i2pd/versions) [![Docker Pulls](https://img.shields.io/docker/pulls/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd) +[![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](https://crowdin.com/project/i2pd) *note: i2pd for Android can be found in [i2pd-android](https://github.com/PurpleI2P/i2pd-android) repository and with Qt GUI in [i2pd-qt](https://github.com/PurpleI2P/i2pd-qt) repository* @@ -85,6 +86,16 @@ Using i2pd See [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/run/) and [example config file](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf). +Localization +------------ + +You can help us with translation i2pd to your language using Crowdin platform! +Translation project can be found [here](https://crowdin.com/project/i2pd). + +New languages can be requested on project's [discussion page](https://crowdin.com/project/i2pd/discussions). + +Current status: [![Crowdin](https://badges.crowdin.net/i2pd/localized.svg)](https://crowdin.com/project/i2pd) + Donations --------- From dbe427d5eb43c4a5abb5d7c43be10048c39788ca Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Jul 2021 19:29:16 -0400 Subject: [PATCH 0224/2193] set reply code for short tunnel build messages --- libi2pd/I2NPProtocol.cpp | 22 ++++++++++++++++++++-- libi2pd/I2NPProtocol.h | 4 ++++ libi2pd/TunnelConfig.h | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index b9b15c8d..6ffa1551 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -608,7 +608,24 @@ namespace i2p LogPrint (eLogError, "I2NP: ShortTunnelBuild message of ", num, " records is too short ", len); return; } - // TODO: check replyMsgID + auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); + if (tunnel) + { + // endpoint of inbound tunnel + LogPrint (eLogDebug, "I2NP: ShortTunnelBuild reply for tunnel ", tunnel->GetTunnelID ()); + if (tunnel->HandleTunnelBuildResponse (buf, len)) + { + LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been created"); + tunnel->SetState (i2p::tunnel::eTunnelStateEstablished); + i2p::tunnel::tunnels.AddInboundTunnel (tunnel); + } + else + { + LogPrint (eLogInfo, "I2NP: Inbound tunnel ", tunnel->GetTunnelID (), " has been declined"); + tunnel->SetState (i2p::tunnel::eTunnelStateBuildFailed); + } + return; + } const uint8_t * record = buf + 1; for (int i = 0; i < num; i++) { @@ -688,7 +705,8 @@ namespace i2p nonce[4] = j; // nonce is record # if (j == i) { - // TODO: fill reply + memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options + reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 8cb68856..e20a0c0d 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -115,6 +115,10 @@ namespace i2p const size_t SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET = SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_PADDING_OFFSET = SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; const size_t SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE = 154; + + // ShortResponseRecord + const size_t SHORT_RESPONSE_RECORD_OPTIONS_OFFSET = 0; + const size_t SHORT_RESPONSE_RECORD_RET_OFFSET = 201; enum I2NPMessageType { diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index b33f7668..306d8a72 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -79,7 +79,7 @@ namespace tunnel ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; // TODO + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[SHORT_RESPONSE_RECORD_RET_OFFSET]; }; void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 From 2c129b6d39607f84a8372f3d731d232f342f1b22 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Jul 2021 19:40:40 -0400 Subject: [PATCH 0225/2193] create and handle short tunnel build reply --- libi2pd/Garlic.cpp | 7 +++- libi2pd/Garlic.h | 3 +- libi2pd/I2NPProtocol.cpp | 87 ++++++++++++++++------------------------ libi2pd/I2NPProtocol.h | 2 +- libi2pd/Tunnel.cpp | 13 +++++- libi2pd/TunnelConfig.cpp | 8 ++++ libi2pd/TunnelConfig.h | 2 + 7 files changed, 65 insertions(+), 57 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index d91c75f5..94dadab2 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -471,8 +471,13 @@ namespace garlic { uint64_t t; memcpy (&t, tag, 8); + AddECIESx25519Key (key, t); + } + + void GarlicDestination::AddECIESx25519Key (const uint8_t * key, uint64_t tag) + { auto tagset = std::make_shared(this, key); - m_ECIESx25519Tags.emplace (t, ECIESX25519AEADRatchetIndexTagset{0, tagset}); + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{0, tagset}); } bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index a898e6a1..d3d11641 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -243,7 +243,7 @@ namespace garlic std::shared_ptr msg); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag - void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag + void AddECIESx25519Key (const uint8_t * key, uint64_t tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset); @@ -260,6 +260,7 @@ namespace garlic protected: + void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 6ffa1551..07ce2518 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -660,68 +660,47 @@ namespace i2p clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + + // encrypt reply + uint8_t nonce[12]; + memset (nonce, 0, 12); + uint8_t * reply = buf + 1; + for (int j = 0; j < num; j++) + { + nonce[4] = j; // nonce is record # + if (j == i) + { + memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options + reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code + if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, + noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt + { + LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); + return; + } + } + else + i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply); + reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + } + // send reply if (isEndpoint) { - // we are endpoint, create OutboundTunnelBuildReply - auto otbrm = NewI2NPShortMessage (); - auto payload = otbrm->GetPayload (); - payload[0] = num; // num - payload[1] = i; // slot - payload +=2; - // reply - htobe16buf (payload, 3); payload += 2; // length, TODO - memset (payload, 0, 3); payload += 3; // ClearText: no options, and zero ret code. TODO - // ShortBuildReplyRecords. Exclude ours - uint8_t * records = buf + 1; - if (i > 0) - { - memcpy (payload, records, i*SHORT_TUNNEL_BUILD_RECORD_SIZE); - payload += i*SHORT_TUNNEL_BUILD_RECORD_SIZE; - records += i*SHORT_TUNNEL_BUILD_RECORD_SIZE; - } - if (i < num-1) - { - memcpy (payload, records, (num-1-i)*SHORT_TUNNEL_BUILD_RECORD_SIZE); - payload += (num-1-i)*SHORT_TUNNEL_BUILD_RECORD_SIZE; - } - otbrm->len += (payload - otbrm->GetPayload ()); - otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); + auto replyMsg = NewI2NPShortMessage (); + replyMsg->Concat (buf, len); + replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); uint64_t tag; memcpy (&tag, noiseState.m_CK, 8); - // send garlic to reply tunnel + // we send it to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519Message (otbrm, noiseState.m_CK + 32, tag))); - } - else - { - // we are participant, encrypt reply - uint8_t nonce[12]; - memset (nonce, 0, 12); - uint8_t * reply = buf + 1; - for (int j = 0; j < num; j++) - { - nonce[4] = j; // nonce is record # - if (j == i) - { - memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options - reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code - if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt - { - LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); - return; - } - } - else - i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply); - reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; - } + CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); + } + else transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } return; } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; @@ -843,6 +822,7 @@ namespace i2p HandleVariableTunnelBuildMsg (msgID, buf, size); break; case eI2NPVariableTunnelBuildReply: + case eI2NPShortTunnelBuildReply: HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; case eI2NPShortTunnelBuild: @@ -905,6 +885,7 @@ namespace i2p case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: case eI2NPShortTunnelBuild: + case eI2NPShortTunnelBuildReply: // forward to tunnel thread i2p::tunnel::tunnels.PostTunnelData (msg); break; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index e20a0c0d..a0b5802c 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -136,7 +136,7 @@ namespace i2p eI2NPVariableTunnelBuild = 23, eI2NPVariableTunnelBuildReply = 24, eI2NPShortTunnelBuild = 25, - eI2NPOutboundTunnelBuildReply = 26 + eI2NPShortTunnelBuildReply = 26 }; const uint8_t TUNNEL_BUILD_RECORD_GATEWAY_FLAG = 0x80; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 6c9d59e9..f9f5ac38 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -105,7 +105,16 @@ namespace tunnel outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); } else + { + if (m_Config->IsShort () && m_Config->GetLastHop ()) + { + // add garlic key/tag for reply + uint8_t key[32]; + uint64_t tag = m_Config->GetLastHop ()->GetGarlicKey (key); + i2p::context.AddECIESx25519Key (key, tag); + } i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); + } } bool Tunnel::HandleTunnelBuildResponse (uint8_t * msg, size_t len) @@ -513,8 +522,10 @@ namespace tunnel } case eI2NPVariableTunnelBuild: case eI2NPVariableTunnelBuildReply: + case eI2NPShortTunnelBuild: + case eI2NPShortTunnelBuildReply: case eI2NPTunnelBuild: - case eI2NPTunnelBuildReply: + case eI2NPTunnelBuildReply: HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ()); break; default: diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 930c565b..45e8a12a 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -260,5 +260,13 @@ namespace tunnel nonce[4] = index; // nonce is index i2p::crypto::ChaCha20 (record, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, record); } + + uint64_t ShortECIESTunnelHopConfig::GetGarlicKey (uint8_t * key) const + { + uint64_t tag; + memcpy (&tag, m_CK, 8); + memcpy (key, m_CK + 32, 32); + return tag; + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 306d8a72..d6441b03 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -44,6 +44,7 @@ namespace tunnel virtual void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) = 0; virtual bool DecryptBuildResponseRecord (uint8_t * records) const = 0; virtual void DecryptRecord (uint8_t * records, int index) const; // AES + virtual uint64_t GetGarlicKey (uint8_t * key) const { return 0; }; // return tag }; struct ElGamalTunnelHopConfig: public TunnelHopConfig @@ -83,6 +84,7 @@ namespace tunnel void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); bool DecryptBuildResponseRecord (uint8_t * records) const; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 + uint64_t GetGarlicKey (uint8_t * key) const override; }; class TunnelConfig From 41bfc7899dbf00332a74083cb86ffb251eecd11e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Jul 2021 14:46:56 -0400 Subject: [PATCH 0226/2193] keep own RouterInfo in netdb --- libi2pd/I2NPProtocol.cpp | 6 ++++++ libi2pd/NetDb.cpp | 24 +++++++++++++++++++++++- libi2pd/RouterContext.h | 8 ++++---- libi2pd/TunnelPool.cpp | 2 +- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 07ce2518..15b51e7d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -262,6 +262,12 @@ namespace i2p if (!router) // we send own RouterInfo router = context.GetSharedRouterInfo (); + if (!router->GetBuffer ()) + { + LogPrint (eLogError, "I2NP: Invalid RouterInfo buffer for DatabaseStore"); + return nullptr; + } + auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index e3a55832..b81289f3 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -59,6 +59,18 @@ namespace data Reseed (); else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false)) Reseed (); // we don't have a router we can connect to. Trying to reseed + + auto it = m_RouterInfos.find (i2p::context.GetIdentHash ()); + if (it != m_RouterInfos.end ()) + { + // remove own router + m_RouterInfos.erase (it); + m_Floodfills.remove (it->second); + } + // insert own router + m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); + if (i2p::context.IsFloodfill ()) + m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ()); i2p::config::GetOption("persist.profiles", m_PersistProfiles); @@ -162,10 +174,18 @@ namespace data bool publish = false; if (m_PublishReplyToken) { + // next publishing attempt if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true; } else if (i2p::context.GetLastUpdateTime () > lastPublish || - ts - lastPublish >= NETDB_PUBLISH_INTERVAL) publish = true; + ts - lastPublish >= NETDB_PUBLISH_INTERVAL) + { + // new publish + m_PublishExcluded.clear (); + if (i2p::context.IsFloodfill ()) + m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // do publish to ourselves + publish = true; + } if (publish) // update timestamp and publish { i2p::context.UpdateTimestamp (ts); @@ -567,8 +587,10 @@ namespace data expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL : NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total; + auto own = i2p::context.GetSharedRouterInfo (); for (auto& it: m_RouterInfos) { + if (it.second == own) continue; // skip own std::string ident = it.second->GetIdentHashBase64(); std::string path = m_Storage.Path(ident); if (it.second->IsUpdated ()) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index acb33795..978490ae 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -68,11 +68,11 @@ namespace garlic void Init (); const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; - i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; }; - std::shared_ptr GetSharedRouterInfo () const + i2p::data::RouterInfo& GetRouterInfo () { return m_RouterInfo; }; + std::shared_ptr GetSharedRouterInfo () { - return std::shared_ptr (&m_RouterInfo, - [](const i2p::data::RouterInfo *) {}); + return std::shared_ptr (&m_RouterInfo, + [](i2p::data::RouterInfo *) {}); } std::shared_ptr GetSharedDestination () { diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index e45c6090..faa28e69 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -423,7 +423,7 @@ namespace tunnel bool StandardSelectPeers(Path & peers, int numHops, bool inbound, SelectHopFunc nextHop) { int start = 0; - auto prevHop = i2p::context.GetSharedRouterInfo (); + std::shared_ptr prevHop = i2p::context.GetSharedRouterInfo (); if(i2p::transport::transports.RoutesRestricted()) { /** if routes are restricted prepend trusted first hop */ From 197f13f9c0e241c75f30ce75c50d0883c2089ecb Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 14:02:20 -0400 Subject: [PATCH 0227/2193] rollback --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 113 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 10 +- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 09bbfe53..7b3947f1 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -518,7 +518,36 @@ namespace garlic } return true; } - + + bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Alice, router's bpk is m_RemoteStaticKey + i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey); + size_t offset = 0; + m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32); + MixHash (out + offset, 32); // h = SHA256(h || aepk) + offset += 32; + uint8_t sharedSecret[32]; + if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return false; + } + MixKey (sharedSecret); + uint8_t nonce[12]; + CreateNonce (0, nonce); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); + return false; + } + + m_State = eSessionStateNewSessionSent; + return true; + } + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob @@ -829,6 +858,11 @@ namespace garlic return nullptr; len += 96; break; + case eSessionStateForRouter: + if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 48; + break; default: return nullptr; } @@ -839,9 +873,9 @@ namespace garlic return m; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter) { - m_State = eSessionStateOneTime; + m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime; return WrapSingleMessage (msg); } @@ -1098,10 +1132,19 @@ namespace garlic HandlePayload (payload.data (), len - 16, nullptr, 0); return true; } - - static size_t CreateGarlicCloveBlock (std::shared_ptr msg, uint8_t * payload) + + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + size_t len = cloveSize + 3; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; @@ -1110,26 +1153,14 @@ namespace garlic htobe32buf (payload + 1, msg->GetMsgID ()); // msgID htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); - return cloveSize + 3; - } - - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) - { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - size_t offset = 0; - memcpy (buf + offset, &tag, 8); offset += 8; - auto payload = buf + offset; - size_t len = CreateGarlicCloveBlock (msg, payload); - uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt + + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; } offset += len + 16; + htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); @@ -1138,39 +1169,13 @@ namespace garlic std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { - // Noise_N, we are Alice, routerPublicKey is Bob's - i2p::crypto::NoiseSymmetricState noiseState; - i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - size_t offset = 0; - auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32); - noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk) - offset += 32; - uint8_t sharedSecret[32]; - if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); - return nullptr; - } - noiseState.MixKey (sharedSecret); - auto payload = buf + offset; - size_t len = CreateGarlicCloveBlock (msg, payload); - uint8_t nonce[12]; - memset (nonce, 0, 12); - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt - { - LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); - return nullptr; - } - offset += len + 16; - htobe32buf (m->GetPayload (), offset); - m->len += offset + 4; - m->FillI2NPMessageHeader (eI2NPGarlic); - return m; + // TODO: implement without session + auto session = std::make_shared(nullptr, false); + session->SetRemoteStaticKey (routerPublicKey); + return session->WrapOneTimeMessage (msg, true); } } } + + + \ No newline at end of file diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 762e00ef..68599c3e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -147,7 +147,8 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime + eSessionStateOneTime, + eSessionStateForRouter }; struct DHRatchet @@ -165,7 +166,7 @@ namespace garlic bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); + std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -206,7 +207,8 @@ namespace garlic bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - + bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); From a1d1a5df74536e2c5ae194beeca98c97c76b0721 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 18:18:55 -0400 Subject: [PATCH 0228/2193] datetime block for message for router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 126 ++++++++++++---------- libi2pd/ECIESX25519AEADRatchetSession.h | 10 +- 2 files changed, 73 insertions(+), 63 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7b3947f1..a29f0ded 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -518,36 +518,7 @@ namespace garlic } return true; } - - bool ECIESX25519AEADRatchetSession::NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Alice, router's bpk is m_RemoteStaticKey - i2p::crypto::InitNoiseNState (GetNoiseState (), m_RemoteStaticKey); - size_t offset = 0; - m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (out + offset, m_EphemeralKeys->GetPublicKey (), 32); - MixHash (out + offset, 32); // h = SHA256(h || aepk) - offset += 32; - uint8_t sharedSecret[32]; - if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) - { - LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); - return false; - } - MixKey (sharedSecret); - uint8_t nonce[12]; - CreateNonce (0, nonce); - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt - { - LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); - return false; - } - - m_State = eSessionStateNewSessionSent; - return true; - } - + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob @@ -858,11 +829,6 @@ namespace garlic return nullptr; len += 96; break; - case eSessionStateForRouter: - if (!NewOutgoingMessageForRouter (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 48; - break; default: return nullptr; } @@ -873,9 +839,9 @@ namespace garlic return m; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter) + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) { - m_State = isForRouter ? eSessionStateForRouter : eSessionStateOneTime; + m_State = eSessionStateOneTime; return WrapSingleMessage (msg); } @@ -1132,19 +1098,17 @@ namespace garlic HandlePayload (payload.data (), len - 16, nullptr, 0); return true; } - - std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + + static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload) { - auto m = NewI2NPMessage (); - m->Align (12); // in order to get buf aligned to 16 (12 + 4) - uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 - size_t offset = 0; - memcpy (buf + offset, &tag, 8); offset += 8; - auto payload = buf + offset; + size_t len = 7; + // DateTime + payload[0] = eECIESx25519BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); + // I2NP + payload += len; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - size_t len = cloveSize + 3; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; @@ -1153,14 +1117,34 @@ namespace garlic htobe32buf (payload + 1, msg->GetMsgID ()); // msgID htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); - - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt + len += cloveSize + 3; + /* payload += cloveSize + 3; + // padding + uint8_t paddingSize = (rand () & 0x0F) + 1; // 1 - 16 + payload[0] = eECIESx25519BlkPadding; + htobe16buf (payload + 1, paddingSize); + memset (payload + 3, 0, paddingSize); + len += paddingSize + 3;*/ + return len; + } + + std::shared_ptr WrapECIESX25519Message (std::shared_ptr msg, const uint8_t * key, uint64_t tag) + { + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + memcpy (buf + offset, &tag, 8); offset += 8; + auto payload = buf + offset; + size_t len = CreateGarlicPayload (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return nullptr; } offset += len + 16; - htobe32buf (m->GetPayload (), offset); m->len += offset + 4; m->FillI2NPMessageHeader (eI2NPGarlic); @@ -1169,13 +1153,39 @@ namespace garlic std::shared_ptr WrapECIESX25519MessageForRouter (std::shared_ptr msg, const uint8_t * routerPublicKey) { - // TODO: implement without session - auto session = std::make_shared(nullptr, false); - session->SetRemoteStaticKey (routerPublicKey); - return session->WrapOneTimeMessage (msg, true); + // Noise_N, we are Alice, routerPublicKey is Bob's + i2p::crypto::NoiseSymmetricState noiseState; + i2p::crypto::InitNoiseNState (noiseState, routerPublicKey); + auto m = NewI2NPMessage (); + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + size_t offset = 0; + auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (buf + offset, ephemeralKeys->GetPublicKey (), 32); + noiseState.MixHash (buf + offset, 32); // h = SHA256(h || aepk) + offset += 32; + uint8_t sharedSecret[32]; + if (!ephemeralKeys->Agree (routerPublicKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return nullptr; + } + noiseState.MixKey (sharedSecret); + auto payload = buf + offset; + size_t len = CreateGarlicPayload (msg, payload); + uint8_t nonce[12]; + memset (nonce, 0, 12); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, noiseState.m_H, 32, noiseState.m_CK + 32, nonce, payload, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD encryption failed"); + return nullptr; + } + offset += len + 16; + htobe32buf (m->GetPayload (), offset); + m->len += offset + 4; + m->FillI2NPMessageHeader (eI2NPGarlic); + return m; } } } - - - \ No newline at end of file diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 68599c3e..3e627fff 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 2013-2021, The PurpleI2P Project * @@ -147,8 +148,7 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime, - eSessionStateForRouter + eSessionStateOneTime }; struct DHRatchet @@ -166,7 +166,7 @@ namespace garlic bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); + std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -207,8 +207,7 @@ namespace garlic bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - bool NewOutgoingMessageForRouter (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - + std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); @@ -262,3 +261,4 @@ namespace garlic } #endif + From cd0751d3f172dace381483d403f208c5934afffc Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 18:30:32 -0400 Subject: [PATCH 0229/2193] padding block for message for router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a29f0ded..8a525d19 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1108,23 +1108,23 @@ namespace garlic htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); // I2NP payload += len; - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + uint16_t cloveSize = msg->GetPayloadLength () + 10; payload[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (payload + 1, cloveSize); // size payload += 3; - *payload = 0; payload++; // flag and delivery instructions - *payload = msg->GetTypeID (); // I2NP msg type - htobe32buf (payload + 1, msg->GetMsgID ()); // msgID - htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds - memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ()); + payload[0] = 0; // flag and delivery instructions + payload[1] = msg->GetTypeID (); // I2NP msg type + htobe32buf (payload + 2, msg->GetMsgID ()); // msgID + htobe32buf (payload + 6, msg->GetExpiration () / 1000); // expiration in seconds + memcpy (payload + 10, msg->GetPayload (), msg->GetPayloadLength ()); len += cloveSize + 3; - /* payload += cloveSize + 3; + payload += cloveSize; // padding uint8_t paddingSize = (rand () & 0x0F) + 1; // 1 - 16 payload[0] = eECIESx25519BlkPadding; htobe16buf (payload + 1, paddingSize); memset (payload + 3, 0, paddingSize); - len += paddingSize + 3;*/ + len += paddingSize + 3; return len; } From 0cd9f1b0028bd0f5ae9b971b9b2d380d21848393 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 15 Jul 2021 19:01:43 -0400 Subject: [PATCH 0230/2193] precalculate padding sizes --- libi2pd/NTCP2.cpp | 13 +++++++++++-- libi2pd/NTCP2.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index cb200b42..ed84b8e7 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -332,7 +332,8 @@ namespace transport m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), #endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), - m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false) + m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false), + m_NextPaddingSize (16) { if (in_RemoteRouter) // Alice { @@ -1058,7 +1059,15 @@ namespace transport size_t paddingSize = (msgLen*NTCP2_MAX_PADDING_RATIO)/100; if (msgLen + paddingSize + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) paddingSize = NTCP2_UNENCRYPTED_FRAME_MAX_SIZE - msgLen -3; if (paddingSize > len) paddingSize = len; - if (paddingSize) paddingSize = rand () % paddingSize; + if (paddingSize) + { + if (m_NextPaddingSize >= 16) + { + RAND_bytes ((uint8_t *)m_PaddingSizes, sizeof (m_PaddingSizes)); + m_NextPaddingSize = 0; + } + paddingSize = m_PaddingSizes[m_NextPaddingSize++] % paddingSize; + } buf[0] = eNTCP2BlkPadding; // blk htobe16buf (buf + 1, paddingSize); // size memset (buf + 3, 0, paddingSize); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 01ee3e34..bcee1b09 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -218,6 +218,9 @@ namespace transport bool m_IsSending; std::list > m_SendQueue; uint64_t m_NextRouterInfoResendTime; // seconds since epoch + + uint16_t m_PaddingSizes[16]; + int m_NextPaddingSize; }; class NTCP2Server: private i2p::util::RunnableServiceWithWork From 5d022c25ba8924ec09e89c8c261b0b00fdaf9e53 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Jul 2021 09:44:22 -0400 Subject: [PATCH 0231/2193] don't send datetime for one time key message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 24 +++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8a525d19..03c5b00e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1099,13 +1099,17 @@ namespace garlic return true; } - static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload) + static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload, bool datetime) { - size_t len = 7; - // DateTime - payload[0] = eECIESx25519BlkDateTime; - htobe16buf (payload + 1, 4); - htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); + size_t len = 0; + if (datetime) + { + // DateTime + payload[0] = eECIESx25519BlkDateTime; + htobe16buf (payload + 1, 4); + htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ()); + len = 7; + } // I2NP payload += len; uint16_t cloveSize = msg->GetPayloadLength () + 10; @@ -1120,10 +1124,10 @@ namespace garlic len += cloveSize + 3; payload += cloveSize; // padding - uint8_t paddingSize = (rand () & 0x0F) + 1; // 1 - 16 + uint8_t paddingSize = rand () & 0x0F; // 0 - 15 payload[0] = eECIESx25519BlkPadding; htobe16buf (payload + 1, paddingSize); - memset (payload + 3, 0, paddingSize); + if (paddingSize) memset (payload + 3, 0, paddingSize); len += paddingSize + 3; return len; } @@ -1136,7 +1140,7 @@ namespace garlic size_t offset = 0; memcpy (buf + offset, &tag, 8); offset += 8; auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload); + size_t len = CreateGarlicPayload (msg, payload, false); uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt @@ -1172,7 +1176,7 @@ namespace garlic } noiseState.MixKey (sharedSecret); auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload); + size_t len = CreateGarlicPayload (msg, payload, true); uint8_t nonce[12]; memset (nonce, 0, 12); // encrypt payload From f4902e66422c829d519d163997f7a185bb7ba624 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Jul 2021 13:53:12 -0400 Subject: [PATCH 0232/2193] eligble floodfill must be reachable by ipv4 --- libi2pd/RouterInfo.cpp | 5 ++--- libi2pd/RouterInfo.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index a426d9b7..65470a88 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1163,9 +1163,8 @@ namespace data bool RouterInfo::IsEligibleFloodfill () const { - // floodfill must be reachable somehow, >= 0.9.28 and not DSA - return (IsReachable () || (m_SupportedTransports & eSSUV4)) && - m_Version >= NETDB_MIN_FLOODFILL_VERSION && + // floodfill must be reachable by ipv4, >= 0.9.28 and not DSA + return IsReachableBy (eNTCP2V4 | eSSUV4) && m_Version >= NETDB_MIN_FLOODFILL_VERSION && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index f27a5d68..b2b6df61 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -206,7 +206,7 @@ namespace data void DisableMesh (); bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; - bool IsReachableBy (SupportedTransports transport) const { return m_ReachableTransports & transport; }; + bool IsReachableBy (uint8_t transports) const { return m_ReachableTransports & transports; }; bool HasValidAddresses () const { return m_SupportedTransports; }; bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; From a37cf058cd7834c207d5f8b5daca901afdc9239c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 16 Jul 2021 20:12:41 -0400 Subject: [PATCH 0233/2193] router with expired introducer is still valid --- libi2pd/NetDb.cpp | 13 +++++++------ libi2pd/RouterInfo.cpp | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b81289f3..1f63c054 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -473,14 +473,15 @@ namespace data bool NetDb::LoadRouterInfo (const std::string & path) { auto r = std::make_shared(path); - if (r->GetRouterIdentity () && !r->IsUnreachable () && - (r->IsReachable () || !r->IsSSU (false) || m_LastLoad < r->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)) // 1 hour - { + if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses ()) + { r->DeleteBuffer (); r->ClearProperties (); // properties are not used for regular routers - m_RouterInfos[r->GetIdentHash ()] = r; - if (r->IsFloodfill () && r->IsReachable ()) // floodfill must be reachable - m_Floodfills.push_back (r); + if (m_RouterInfos.emplace (r->GetIdentHash (), r).second) + { + if (r->IsFloodfill () && r->IsEligibleFloodfill ()) + m_Floodfills.push_back (r); + } } else { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 65470a88..3feaa504 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -343,7 +343,8 @@ namespace data int numValid = 0; for (auto& it: address->ssu->introducers) { - if ((!it.iExp || ts <= it.iExp) && it.iPort > 0 && + if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT; + if (ts <= it.iExp && it.iPort > 0 && ((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ()))) numValid++; else From 6ecfe0789f4a07e9737cc53e7287802beb5e40c6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 18 Jul 2021 18:45:08 -0400 Subject: [PATCH 0234/2193] don't allocate payload buffer for every single ECIESx25519 message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 81 ++++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 11 ++- libi2pd/Garlic.h | 4 +- 4 files changed, 57 insertions(+), 41 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 03c5b00e..9c76320b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -795,8 +795,9 @@ namespace garlic std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { - auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); - size_t len = payload.size (); + uint8_t * payload = GetOwner ()->GetPayloadBuffer (); + if (!payload) return nullptr; + size_t len = CreatePayload (msg, m_State != eSessionStateEstablished, payload); if (!len) return nullptr; auto m = NewI2NPMessage (len + 100); // 96 + 4 m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -805,27 +806,27 @@ namespace garlic switch (m_State) { case eSessionStateEstablished: - if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NewExistingSessionMessage (payload, len, buf, m->maxLen)) return nullptr; len += 24; break; case eSessionStateNew: - if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen)) return nullptr; len += 96; break; case eSessionStateNewSessionReceived: - if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NewSessionReplyMessage (payload, len, buf, m->maxLen)) return nullptr; len += 72; break; case eSessionStateNewSessionReplySent: - if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + if (!NextNewSessionReplyMessage (payload, len, buf, m->maxLen)) return nullptr; len += 72; break; case eSessionStateOneTime: - if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen, false)) + if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen, false)) return nullptr; len += 96; break; @@ -845,7 +846,7 @@ namespace garlic return WrapSingleMessage (msg); } - std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) + size_t ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first, uint8_t * payload) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); size_t payloadLen = 0; @@ -907,89 +908,93 @@ namespace garlic payloadLen += paddingSize + 3; } } - std::vector v(payloadLen); if (payloadLen) - { + { + if (payloadLen > I2NP_MAX_MESSAGE_SIZE) + { + LogPrint (eLogError, "Garlic: payload length ", payloadLen, " is too long"); + return 0; + } m_LastSentTimestamp = ts; size_t offset = 0; // DateTime if (first) { - v[offset] = eECIESx25519BlkDateTime; offset++; - htobe16buf (v.data () + offset, 4); offset += 2; - htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds + payload[offset] = eECIESx25519BlkDateTime; offset++; + htobe16buf (payload + offset, 4); offset += 2; + htobe32buf (payload + offset, ts/1000); offset += 4; // in seconds } // LeaseSet if (leaseSet) { - offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); + offset += CreateLeaseSetClove (leaseSet, ts, payload + offset, payloadLen - offset); if (!first) { // ack request - v[offset] = eECIESx25519BlkAckRequest; offset++; - htobe16buf (v.data () + offset, 1); offset += 2; - v[offset] = 0; offset++; // flags + payload[offset] = eECIESx25519BlkAckRequest; offset++; + htobe16buf (payload + offset, 1); offset += 2; + payload[offset] = 0; offset++; // flags } } // msg if (msg) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); + offset += CreateGarlicClove (msg, payload + offset, payloadLen - offset); // ack if (m_AckRequests.size () > 0) { - v[offset] = eECIESx25519BlkAck; offset++; - htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2; + payload[offset] = eECIESx25519BlkAck; offset++; + htobe16buf (payload + offset, m_AckRequests.size () * 4); offset += 2; for (auto& it: m_AckRequests) { - htobe16buf (v.data () + offset, it.first); offset += 2; - htobe16buf (v.data () + offset, it.second); offset += 2; + htobe16buf (payload + offset, it.first); offset += 2; + htobe16buf (payload + offset, it.second); offset += 2; } m_AckRequests.clear (); } // next keys if (m_SendReverseKey) { - v[offset] = eECIESx25519BlkNextKey; offset++; - htobe16buf (v.data () + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2; - v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; + payload[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (payload + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2; + payload[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; int keyID = m_NextReceiveRatchet->keyID - 1; if (m_NextReceiveRatchet->newKey) { - v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; + payload[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; keyID++; } offset++; // flag - htobe16buf (v.data () + offset, keyID); offset += 2; // keyid + htobe16buf (payload + offset, keyID); offset += 2; // keyid if (m_NextReceiveRatchet->newKey) { - memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); + memcpy (payload + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); offset += 32; // public key } m_SendReverseKey = false; } if (m_SendForwardKey) { - v[offset] = eECIESx25519BlkNextKey; offset++; - htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2; - v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; - if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only + payload[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (payload + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2; + payload[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; + if (!m_NextSendRatchet->keyID) payload[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only offset++; // flag - htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid + htobe16buf (payload + offset, m_NextSendRatchet->keyID); offset += 2; // keyid if (m_NextSendRatchet->newKey) { - memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32); + memcpy (payload + offset, m_NextSendRatchet->key->GetPublicKey (), 32); offset += 32; // public key } } // padding if (paddingSize) { - v[offset] = eECIESx25519BlkPadding; offset++; - htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + payload[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (payload + offset, paddingSize); offset += 2; + memset (payload + offset, 0, paddingSize); offset += paddingSize; } } - return v; + return payloadLen; } size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 3e627fff..aa72e4b0 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -208,7 +208,7 @@ namespace garlic bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - std::vector CreatePayload (std::shared_ptr msg, bool first); + size_t CreatePayload (std::shared_ptr msg, bool first, uint8_t * payload); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 94dadab2..62e9e423 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -433,7 +433,7 @@ namespace garlic } GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default - m_NumRatchetInboundTags (0) // 0 means standard + m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard { m_Ctx = BN_CTX_new (); } @@ -441,6 +441,8 @@ namespace garlic GarlicDestination::~GarlicDestination () { BN_CTX_free (m_Ctx); + if (m_PayloadBuffer) + delete[] m_PayloadBuffer; } void GarlicDestination::CleanUp () @@ -1121,5 +1123,12 @@ namespace garlic m_ECIESx25519Sessions.erase (it); } } + + uint8_t * GarlicDestination::GetPayloadBuffer () + { + if (!m_PayloadBuffer) + m_PayloadBuffer = new uint8_t[I2NP_MAX_MESSAGE_SIZE]; + return m_PayloadBuffer; + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index d3d11641..561f4ff7 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -250,7 +250,8 @@ namespace garlic void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); - + uint8_t * GetPayloadBuffer (); + virtual void ProcessGarlicMessage (std::shared_ptr msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); virtual void SetLeaseSetUpdated (); @@ -284,6 +285,7 @@ namespace garlic std::mutex m_SessionsMutex; std::unordered_map m_Sessions; std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session + uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet // incoming int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; From db9223b0d57f5dc94f3fd94403348ab958eedd62 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 19 Jul 2021 17:50:55 -0400 Subject: [PATCH 0235/2193] set minimal version for floodfill to 0.9.38 --- libi2pd/NetDb.hpp | 2 +- libi2pd/RouterInfo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 364cae4b..ccab664b 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -44,7 +44,7 @@ namespace data const int NETDB_PUBLISH_CONFIRMATION_TIMEOUT = 5; // in seconds const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 - const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 28); // 0.9.28 + const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3feaa504..0d439dfc 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1164,7 +1164,7 @@ namespace data bool RouterInfo::IsEligibleFloodfill () const { - // floodfill must be reachable by ipv4, >= 0.9.28 and not DSA + // floodfill must be reachable by ipv4, >= 0.9.38 and not DSA return IsReachableBy (eNTCP2V4 | eSSUV4) && m_Version >= NETDB_MIN_FLOODFILL_VERSION && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; } From bdc1107c9608da51fe69492b054c7291842af136 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 14:35:02 -0400 Subject: [PATCH 0236/2193] correct message type for ShortTunnelBuild --- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/TunnelConfig.h | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f9f5ac38..9f096282 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -88,7 +88,7 @@ namespace tunnel } hop = hop->prev; } - msg->FillI2NPMessageHeader (eI2NPVariableTunnelBuild); + msg->FillI2NPMessageHeader (m_Config->IsShort () ? eI2NPShortTunnelBuild : eI2NPVariableTunnelBuild); // send message if (outboundTunnel) @@ -99,7 +99,7 @@ namespace tunnel if (ident) { auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); - if (msg1) msg = msg; + if (msg1) msg = msg1; } } outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index d6441b03..76aa0b34 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -91,14 +91,17 @@ namespace tunnel { public: - TunnelConfig (const std::vector >& peers) // inbound + TunnelConfig (const std::vector >& peers, + bool isShort = false): // inbound + m_IsShort (isShort) { CreatePeers (peers); m_LastHop->SetNextIdent (i2p::context.GetIdentHash ()); } TunnelConfig (const std::vector >& peers, - uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) // outbound + uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort = false): // outbound + m_IsShort (isShort) { CreatePeers (peers); m_FirstHop->isGateway = false; @@ -185,7 +188,7 @@ namespace tunnel protected: // this constructor can't be called from outside - TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr) + TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false) { } @@ -218,7 +221,7 @@ namespace tunnel private: TunnelHopConfig * m_FirstHop, * m_LastHop; - bool m_IsShort = false; + bool m_IsShort; }; class ZeroHopsTunnelConfig: public TunnelConfig From 4807092df63499ceaa2e1f205ecc83a8ad812c6e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 15:17:58 -0400 Subject: [PATCH 0237/2193] fixed typo --- libi2pd/I2NPProtocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 15b51e7d..48b4a34c 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -704,7 +704,7 @@ namespace i2p i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); } else - transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); return; From c2334db8f8f51494678be698c8557f1992865790 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 18:02:48 -0400 Subject: [PATCH 0238/2193] correct reply key for short tunnel build record --- libi2pd/I2NPProtocol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 48b4a34c..9c71632a 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -686,7 +686,7 @@ namespace i2p } } else - i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply); + i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, reply); reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } // send reply From 0b14c810fbd9453259acc68a567a822c1a517166 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 19:38:36 -0400 Subject: [PATCH 0239/2193] handle ShortTunnelBuildReply --- libi2pd/I2NPProtocol.cpp | 27 +++++++++++++++------------ libi2pd/I2NPProtocol.h | 6 ------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 9c71632a..1123407d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -381,7 +381,7 @@ namespace i2p return g_MaxNumTransitTunnels; } - bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) + static bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) { @@ -470,7 +470,7 @@ namespace i2p return false; } - void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + static void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { int num = buf[0]; LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records"); @@ -540,7 +540,7 @@ namespace i2p } } - void HandleTunnelBuildMsg (uint8_t * buf, size_t len) + static void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { if (i2p::context.IsECIES ()) { @@ -570,13 +570,14 @@ namespace i2p } } - void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + static void HandleTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len, bool isShort) { int num = buf[0]; - LogPrint (eLogDebug, "I2NP: VariableTunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID); - if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1) + LogPrint (eLogDebug, "I2NP: TunnelBuildReplyMsg of ", num, " records replyMsgID=", replyMsgID); + size_t recordSize = isShort ? SHORT_TUNNEL_BUILD_RECORD_SIZE : TUNNEL_BUILD_RECORD_SIZE; + if (len < num*recordSize + 1) { - LogPrint (eLogError, "I2NP: VaribleTunnelBuildReply message of ", num, " records is too short ", len); + LogPrint (eLogError, "I2NP: TunnelBuildReply message of ", num, " records is too short ", len); return; } @@ -600,7 +601,7 @@ namespace i2p LogPrint (eLogWarning, "I2NP: Pending tunnel for message ", replyMsgID, " not found"); } - void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) + static void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { if (!i2p::context.IsECIES ()) { @@ -827,12 +828,14 @@ namespace i2p case eI2NPVariableTunnelBuild: HandleVariableTunnelBuildMsg (msgID, buf, size); break; - case eI2NPVariableTunnelBuildReply: - case eI2NPShortTunnelBuildReply: - HandleVariableTunnelBuildReplyMsg (msgID, buf, size); - break; case eI2NPShortTunnelBuild: HandleShortTunnelBuildMsg (msgID, buf, size); + break; + case eI2NPVariableTunnelBuildReply: + HandleTunnelBuildReplyMsg (msgID, buf, size, false); + break; + case eI2NPShortTunnelBuildReply: + HandleTunnelBuildReplyMsg (msgID, buf, size, true); break; case eI2NPTunnelBuild: HandleTunnelBuildMsg (buf, size); diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index a0b5802c..32aebbb2 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -304,12 +304,6 @@ namespace tunnel std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken = 0, std::shared_ptr replyTunnel = nullptr); bool IsRouterInfoMsg (std::shared_ptr msg); - bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText); - void HandleVariableTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len); - void HandleTunnelBuildMsg (uint8_t * buf, size_t len); - std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf); std::shared_ptr CreateTunnelDataMsg (uint32_t tunnelID, const uint8_t * payload); std::shared_ptr CreateEmptyTunnelDataMsg (bool endpoint); From 5cb1f5986dc3e5a29e2a8e4ccf3ba2f287ae848b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 20 Jul 2021 22:00:06 -0400 Subject: [PATCH 0240/2193] use msgID from ECIESx25519 block --- libi2pd/Destination.cpp | 5 +++-- libi2pd/Destination.h | 2 +- libi2pd/Garlic.cpp | 10 ++++++---- libi2pd/Garlic.h | 2 +- libi2pd/RouterContext.cpp | 4 ++-- libi2pd/RouterContext.h | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 7bcfe111..62f8ed26 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -345,10 +345,11 @@ namespace client void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len) { I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]); - LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); + uint32_t msgID = bufbe32toh (buf + I2NP_HEADER_MSGID_OFFSET); + LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE, msgID); } - bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) + bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { switch (typeID) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 6695796d..2effff27 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -144,7 +144,7 @@ namespace client // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID); void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 62e9e423..e5b74624 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1044,10 +1044,11 @@ namespace garlic { LogPrint (eLogDebug, "Garlic: type local"); I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid - buf += (4 + 4); // msgID + expiration + int32_t msgID = bufbe32toh (buf); buf += 4; // msgID + buf += 4; // expiration ptrdiff_t offset = buf - buf1; if (offset <= (int)len) - HandleCloveI2NPMessage (typeID, buf, len - offset); + HandleCloveI2NPMessage (typeID, buf, len - offset, msgID); else LogPrint (eLogError, "Garlic: clove is too long"); break; @@ -1066,13 +1067,14 @@ namespace garlic } uint32_t gwTunnel = bufbe32toh (buf); buf += 4; I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid - buf += (4 + 4); // msgID + expiration + uint32_t msgID = bufbe32toh (buf); buf += 4; // msgID + buf += 4; // expiration offset += 13; if (GetTunnelPool ()) { auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); if (tunnel) - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset, msgID)); else LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 561f4ff7..b150e78d 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -264,7 +264,7 @@ namespace garlic void AddECIESx25519Key (const uint8_t * key, const uint8_t * tag); // one tag bool HandleECIESx25519TagMessage (uint8_t * buf, size_t len); // return true if found virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only - virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; + virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index c25f5064..edabcdfa 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -821,9 +821,9 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); } - bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) + bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) { - auto msg = CreateI2NPMessage (typeID, payload, len); + auto msg = CreateI2NPMessage (typeID, payload, len, msgID); if (!msg) return false; i2p::HandleI2NPMessage (msg); return true; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 978490ae..b52e20d9 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -154,7 +154,7 @@ namespace garlic // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID); private: From cfbf5862f9643b6b74e5d90b6487eaa402dc7073 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Jul 2021 13:08:12 -0400 Subject: [PATCH 0241/2193] set pool for tunnel before build --- libi2pd/Tunnel.cpp | 24 +++++++++++++++--------- libi2pd/Tunnel.h | 7 ++++--- libi2pd/TunnelPool.cpp | 17 ++++++----------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 9f096282..d0aaa482 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -111,7 +111,10 @@ namespace tunnel // add garlic key/tag for reply uint8_t key[32]; uint64_t tag = m_Config->GetLastHop ()->GetGarlicKey (key); - i2p::context.AddECIESx25519Key (key, tag); + if (m_Pool && m_Pool->GetLocalDestination ()) + m_Pool->GetLocalDestination ()->AddECIESx25519Key (key, tag); + else + i2p::context.AddECIESx25519Key (key, tag); } i2p::transport::transports.SendMessage (GetNextIdentHash (), msg); } @@ -710,7 +713,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel"); CreateTunnel ( std::make_shared (std::vector > { router->GetRouterIdentity () }, - inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) + inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()), nullptr ); } } @@ -786,7 +789,7 @@ namespace tunnel } LogPrint (eLogDebug, "Tunnel: creating one hop inbound tunnel"); CreateTunnel ( - std::make_shared (std::vector > { router->GetRouterIdentity () }) + std::make_shared (std::vector > { router->GetRouterIdentity () }), nullptr ); } } @@ -832,9 +835,11 @@ namespace tunnel } template - std::shared_ptr Tunnels::CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) + std::shared_ptr Tunnels::CreateTunnel (std::shared_ptr config, + std::shared_ptr pool, std::shared_ptr outboundTunnel) { auto newTunnel = std::make_shared (config); + newTunnel->SetTunnelPool (pool); uint32_t replyMsgID; RAND_bytes ((uint8_t *)&replyMsgID, 4); AddPendingTunnel (replyMsgID, newTunnel); @@ -842,18 +847,19 @@ namespace tunnel return newTunnel; } - std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) + std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, + std::shared_ptr pool, std::shared_ptr outboundTunnel) { if (config) - return CreateTunnel(config, outboundTunnel); + return CreateTunnel(config, pool, outboundTunnel); else return CreateZeroHopsInboundTunnel (); } - std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config) + std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config, std::shared_ptr pool) { if (config) - return CreateTunnel(config); + return CreateTunnel(config, pool); else return CreateZeroHopsOutboundTunnel (); } @@ -889,7 +895,7 @@ namespace tunnel { // build symmetric outbound tunnel CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), - newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), + newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), nullptr, GetNextOutboundTunnel ()); } else diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index f30eab14..c85b734b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -205,8 +205,8 @@ namespace tunnel void AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); - std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel); - std::shared_ptr CreateOutboundTunnel (std::shared_ptr config); + std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr pool, std::shared_ptr outboundTunnel); + std::shared_ptr CreateOutboundTunnel (std::shared_ptr config, std::shared_ptr pool); void PostTunnelData (std::shared_ptr msg); void PostTunnelData (const std::vector >& msgs); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); @@ -219,7 +219,8 @@ namespace tunnel private: template - std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); + std::shared_ptr CreateTunnel (std::shared_ptr config, + std::shared_ptr pool, std::shared_ptr outboundTunnel = nullptr); template std::shared_ptr GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index faa28e69..8abab3d6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -526,8 +526,7 @@ namespace tunnel std::reverse (peers.begin (), peers.end ()); config = std::make_shared (peers); } - auto tunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); - tunnel->SetTunnelPool (shared_from_this ()); + auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } @@ -551,10 +550,9 @@ namespace tunnel { config = std::make_shared(tunnel->GetPeers ()); } - if (m_NumInboundHops == 0 || config) + if (!m_NumInboundHops || config) { - auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); - newTunnel->SetTunnelPool (shared_from_this()); + auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); } @@ -574,8 +572,7 @@ namespace tunnel std::shared_ptr config; if (m_NumOutboundHops > 0) config = std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); - auto tunnel = tunnels.CreateOutboundTunnel (config); - tunnel->SetTunnelPool (shared_from_this ()); + auto tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } @@ -606,8 +603,7 @@ namespace tunnel } if (!m_NumOutboundHops || config) { - auto newTunnel = tunnels.CreateOutboundTunnel (config); - newTunnel->SetTunnelPool (shared_from_this ()); + auto newTunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); } @@ -621,8 +617,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); auto tunnel = tunnels.CreateInboundTunnel ( m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers ()) : nullptr, - outboundTunnel); - tunnel->SetTunnelPool (shared_from_this ()); + shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } From 911ab9813e76098b39435b6d2b3a9f6bf5767a0f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Jul 2021 14:55:38 -0400 Subject: [PATCH 0242/2193] handle encrypteed I2NPShortTunnelBuildReply in destination --- libi2pd/Destination.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 62f8ed26..bc6ca31e 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -366,6 +366,9 @@ namespace client case eI2NPDatabaseSearchReply: HandleDatabaseSearchReplyMessage (payload, len); break; + case eI2NPShortTunnelBuildReply: // might come as garlic encrypted + i2p::HandleI2NPMessage (CreateI2NPMessage (typeID, payload, len, msgID)); + break; default: LogPrint (eLogWarning, "Destination: Unexpected I2NP message type ", typeID); return false; From f28024cfe849a1eb54f716df8671982d551392e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Jul 2021 18:12:37 -0400 Subject: [PATCH 0243/2193] decline transit tunnels from short tunnel build message --- libi2pd/I2NPProtocol.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 1123407d..5c6e6e02 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -645,6 +645,11 @@ namespace i2p LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i); return; } + if (clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE]) // not AES + { + LogPrint (eLogWarning, "I2NP: Unknown layer encryption type ", clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE], " in short request record"); + return; + } auto& noiseState = i2p::context.GetCurrentNoiseState (); uint8_t replyKey[32], layerKey[32], ivKey[32]; i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK); @@ -659,15 +664,27 @@ namespace i2p } else memcpy (ivKey, noiseState.m_CK , 32); - auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( - bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), - clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - layerKey, ivKey, - clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, - clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); - i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - + + // check if we accept this tunnel + uint8_t retCode = 0; + if (!i2p::context.AcceptsTunnels () || + i2p::tunnel::tunnels.GetTransitTunnels ().size () > g_MaxNumTransitTunnels || + i2p::transport::transports.IsBandwidthExceeded () || + i2p::transport::transports.IsTransitBandwidthExceeded ()) + retCode = 30; + if (!retCode) + { + // create new transit tunnel + auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( + bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), + clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, + bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + layerKey, ivKey, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, + clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); + i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); + } + // encrypt reply uint8_t nonce[12]; memset (nonce, 0, 12); @@ -678,7 +695,7 @@ namespace i2p if (j == i) { memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options - reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = 0; // TODO: correct ret code + reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = retCode; if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16, noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { From 7078ca53c32f3619d5b61bb3aeaf62778d478dbd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jul 2021 13:23:05 +0000 Subject: [PATCH 0244/2193] [debian] update patch for upnp --- debian/patches/02-upnp.patch | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 7b9bb317..5098b098 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -6,12 +6,12 @@ Last-Update: 2021-01-16 --- i2pd.orig/Makefile +++ i2pd/Makefile -@@ -15,7 +15,7 @@ include filelist.mk - USE_AESNI := yes - USE_STATIC := no - USE_MESHNET := no --USE_UPNP := no -+USE_UPNP := yes - DEBUG := yes - +@@ -21,7 +21,7 @@ include filelist.mk + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) + USE_MESHNET := $(or $(USE_MESHNET),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) + ifeq ($(DEBUG),yes) From 445c5f47ae58abe33dbc4be11c9cb6f09c8610cc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jul 2021 13:24:42 +0000 Subject: [PATCH 0245/2193] [debian] update patch for upnp --- debian/patches/02-upnp.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 5098b098..379b2f60 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -13,5 +13,5 @@ Last-Update: 2021-01-16 -USE_UPNP := $(or $(USE_UPNP),no) +USE_UPNP := $(or $(USE_UPNP),yes) DEBUG := $(or $(DEBUG),yes) - + ifeq ($(DEBUG),yes) From 28369faa0079eaf610557e5fd9ffc41a7e8dc60f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jul 2021 13:35:58 +0000 Subject: [PATCH 0246/2193] [debian] fix tabulation in patch --- debian/patches/02-upnp.patch | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 379b2f60..75ea2bfa 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -7,11 +7,11 @@ Last-Update: 2021-01-16 --- i2pd.orig/Makefile +++ i2pd/Makefile @@ -21,7 +21,7 @@ include filelist.mk - USE_AESNI := $(or $(USE_AESNI),yes) - USE_STATIC := $(or $(USE_STATIC),no) - USE_MESHNET := $(or $(USE_MESHNET),no) --USE_UPNP := $(or $(USE_UPNP),no) -+USE_UPNP := $(or $(USE_UPNP),yes) - DEBUG := $(or $(DEBUG),yes) + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) + USE_MESHNET := $(or $(USE_MESHNET),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) ifeq ($(DEBUG),yes) From c153471c4980e5d0b29808d9c2a63a5600c9d663 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Jul 2021 20:58:35 -0400 Subject: [PATCH 0247/2193] use short tunnel build if possible --- libi2pd/NetDb.hpp | 1 + libi2pd/TunnelPool.cpp | 63 +++++++++++++++++++-------- libi2pd/TunnelPool.h | 18 +++++--- libi2pd_client/MatchedDestination.cpp | 10 ++--- 4 files changed, 62 insertions(+), 30 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index ccab664b..c52be02b 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -45,6 +45,7 @@ namespace data const int NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 const int NETDB_MIN_FLOODFILL_VERSION = MAKE_VERSION_NUMBER(0, 9, 38); // 0.9.38 + const int NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION = MAKE_VERSION_NUMBER(0, 9, 51); // 0.9.51 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 8abab3d6..614a04f0 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -24,6 +24,22 @@ namespace i2p { namespace tunnel { + void Path::Add (std::shared_ptr r) + { + if (r) + { + peers.push_back (r->GetRouterIdentity ()); + if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION || + r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + isShort = false; + } + } + + void Path::Reverse () + { + std::reverse (peers.begin (), peers.end ()); + } + TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), @@ -420,7 +436,7 @@ namespace tunnel return hop; } - bool StandardSelectPeers(Path & peers, int numHops, bool inbound, SelectHopFunc nextHop) + bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop) { int start = 0; std::shared_ptr prevHop = i2p::context.GetSharedRouterInfo (); @@ -429,7 +445,7 @@ namespace tunnel /** if routes are restricted prepend trusted first hop */ auto hop = i2p::transport::transports.GetRestrictedPeer(); if(!hop) return false; - peers.push_back(hop->GetRouterIdentity()); + path.Add (hop); prevHop = hop; start++; } @@ -441,7 +457,7 @@ namespace tunnel (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { prevHop = r; - peers.push_back (r->GetRouterIdentity ()); + path.Add (r); start++; } } @@ -466,12 +482,12 @@ namespace tunnel if (hop1) hop = hop1; } prevHop = hop; - peers.push_back (hop->GetRouterIdentity ()); + path.Add (hop); } return true; } - bool TunnelPool::SelectPeers (std::vector >& peers, bool isInbound) + bool TunnelPool::SelectPeers (Path& path, bool isInbound) { int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; // peers is empty @@ -480,14 +496,14 @@ namespace tunnel { std::lock_guard lock(m_CustomPeerSelectorMutex); if (m_CustomPeerSelector) - return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); + return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } // explicit peers in use - if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); - return StandardSelectPeers(peers, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); + if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound); + return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); } - bool TunnelPool::SelectExplicitPeers (std::vector >& peers, bool isInbound) + bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { int size = m_ExplicitPeers->size (); std::vector peerIndicies; @@ -500,7 +516,7 @@ namespace tunnel auto& ident = (*m_ExplicitPeers)[peerIndicies[i]]; auto r = i2p::data::netdb.FindRouter (ident); if (r) - peers.push_back (r->GetRouterIdentity ()); + path.Add (r); else { LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ()); @@ -517,14 +533,14 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel..."); - std::vector > peers; - if (SelectPeers (peers, true)) + Path path; + if (SelectPeers (path, true)) { std::shared_ptr config; if (m_NumInboundHops > 0) { - std::reverse (peers.begin (), peers.end ()); - config = std::make_shared (peers); + path.Reverse (); + config = std::make_shared (path.peers, path.isShort); } auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops @@ -566,14 +582,23 @@ namespace tunnel if (inboundTunnel) { LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); - std::vector > peers; - if (SelectPeers (peers, false)) + Path path; + if (SelectPeers (path, false)) { std::shared_ptr config; if (m_NumOutboundHops > 0) - config = std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); - auto tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); - if (tunnel->IsEstablished ()) // zero hops + config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), path.isShort); + + std::shared_ptr tunnel; + if (path.isShort) + { + // TODO: implement it better + tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ()); + tunnel->SetTunnelPool (shared_from_this ()); + } + else + tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); + if (tunnel && tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); } else diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 164ca7a1..97ca0419 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -36,7 +36,14 @@ namespace tunnel class OutboundTunnel; typedef std::shared_ptr Peer; - typedef std::vector Path; + struct Path + { + std::vector peers; + bool isShort = true; + + void Add (std::shared_ptr r); + void Reverse (); + }; /** interface for custom tunnel peer selection algorithm */ struct ITunnelPeerSelector @@ -47,9 +54,8 @@ namespace tunnel typedef std::function(std::shared_ptr, bool)> SelectHopFunc; - // standard peer selection algorithm - bool StandardSelectPeers(Path & path, int hops, bool inbound, SelectHopFunc nextHop); - + bool StandardSelectPeers(Path & path, int numHops, bool inbound, SelectHopFunc nextHop); + class TunnelPool: public std::enable_shared_from_this // per local destination { public: @@ -114,8 +120,8 @@ namespace tunnel void CreatePairedInboundTunnel (std::shared_ptr outboundTunnel); template typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; - bool SelectPeers (std::vector >& hops, bool isInbound); - bool SelectExplicitPeers (std::vector >& hops, bool isInbound); + bool SelectPeers (Path& path, bool isInbound); + bool SelectExplicitPeers (Path& path, bool isInbound); private: diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index c0766096..8d17632b 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -79,23 +79,23 @@ namespace client if(!inbound && m_RemoteLeaseSet) { if(m_RemoteLeaseSet->IsExpired()) - { ResolveCurrentLeaseSet(); - } if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired()) { // remote lease set is good auto leases = m_RemoteLeaseSet->GetNonExpiredLeases(); // pick lease std::shared_ptr obep; - while(!obep && leases.size() > 0) { + while(!obep && leases.size() > 0) + { auto idx = rand() % leases.size(); auto lease = leases[idx]; obep = i2p::data::netdb.FindRouter(lease->tunnelGateway); leases.erase(leases.begin()+idx); } - if(obep) { - path.push_back(obep->GetRouterIdentity()); + if(obep) + { + path.Add (obep); LogPrint(eLogDebug, "Destination: found OBEP matching IBGW"); } else LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel"); From c7234f705a5a74dc5169ae5d0847c2376d368b5e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Jul 2021 18:34:51 -0400 Subject: [PATCH 0248/2193] let NTCP sync through ipv6 --- libi2pd/Timestamp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 3cd336ed..4664061f 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -60,14 +60,14 @@ namespace util { LogPrint (eLogInfo, "Timestamp: NTP request to ", address); boost::asio::io_service service; - boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp"); boost::system::error_code ec; - auto it = boost::asio::ip::udp::resolver (service).resolve (query, ec); + auto it = boost::asio::ip::udp::resolver (service).resolve ( + boost::asio::ip::udp::resolver::query (address, "ntp"), ec); if (!ec && it != boost::asio::ip::udp::resolver::iterator()) { auto ep = (*it).endpoint (); // take first one boost::asio::ip::udp::socket socket (service); - socket.open (boost::asio::ip::udp::v4 (), ec); + socket.open (ep.protocol (), ec); if (!ec) { uint8_t buf[48];// 48 bytes NTP request/response @@ -103,7 +103,7 @@ namespace util LogPrint (eLogError, "Timestamp: Couldn't open UDP socket"); } else - LogPrint (eLogError, "Timestamp: Couldn't resove address ", address); + LogPrint (eLogError, "Timestamp: Couldn't resolve address ", address); } NTPTimeSync::NTPTimeSync (): m_IsRunning (false), m_Timer (m_Service) From 26d5ced2efce37eb80662bcc7984eca36dd361dc Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Jul 2021 20:28:55 -0400 Subject: [PATCH 0249/2193] optimal padding for one-time messages --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 26 ++++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9c76320b..8faf1cd9 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1104,7 +1104,8 @@ namespace garlic return true; } - static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload, bool datetime) + static size_t CreateGarlicPayload (std::shared_ptr msg, uint8_t * payload, + bool datetime, size_t optimalSize) { size_t len = 0; if (datetime) @@ -1129,11 +1130,20 @@ namespace garlic len += cloveSize + 3; payload += cloveSize; // padding - uint8_t paddingSize = rand () & 0x0F; // 0 - 15 - payload[0] = eECIESx25519BlkPadding; - htobe16buf (payload + 1, paddingSize); - if (paddingSize) memset (payload + 3, 0, paddingSize); - len += paddingSize + 3; + int delta = (int)optimalSize - (int)len; + if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size + { + uint8_t paddingSize = rand () & 0x0F; // 0 - 15 + if (delta > 3) + { + delta -= 3; + if (paddingSize > delta) paddingSize %= delta; + } + payload[0] = eECIESx25519BlkPadding; + htobe16buf (payload + 1, paddingSize); + if (paddingSize) memset (payload + 3, 0, paddingSize); + len += paddingSize + 3; + } return len; } @@ -1145,7 +1155,7 @@ namespace garlic size_t offset = 0; memcpy (buf + offset, &tag, 8); offset += 8; auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload, false); + size_t len = CreateGarlicPayload (msg, payload, false, 956); // 1003 - 8 tag - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 3 local tunnel delivery uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, buf, 8, key, nonce, payload, len + 16, true)) // encrypt @@ -1181,7 +1191,7 @@ namespace garlic } noiseState.MixKey (sharedSecret); auto payload = buf + offset; - size_t len = CreateGarlicPayload (msg, payload, true); + size_t len = CreateGarlicPayload (msg, payload, true, 900); // 1003 - 32 eph key - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 35 router tunnel delivery uint8_t nonce[12]; memset (nonce, 0, 12); // encrypt payload From cd8e8970deb28a87d2d3b554d62139c351dfe032 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 24 Jul 2021 16:01:11 -0400 Subject: [PATCH 0250/2193] NTP request through compatible address --- libi2pd/Timestamp.cpp | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 4664061f..ec0c25f2 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -16,6 +16,7 @@ #include #include "Config.h" #include "Log.h" +#include "RouterContext.h" #include "I2PEndian.h" #include "Timestamp.h" #include "util.h" @@ -63,9 +64,38 @@ namespace util boost::system::error_code ec; auto it = boost::asio::ip::udp::resolver (service).resolve ( boost::asio::ip::udp::resolver::query (address, "ntp"), ec); - if (!ec && it != boost::asio::ip::udp::resolver::iterator()) + if (!ec) { - auto ep = (*it).endpoint (); // take first one + bool found = false; + boost::asio::ip::udp::resolver::iterator end; + boost::asio::ip::udp::endpoint ep; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) + { + if (ep.address ().is_v4 ()) + { + if (i2p::context.SupportsV4 ()) found = true; + } + else if (ep.address ().is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (i2p::context.SupportsMesh ()) found = true; + } + else if (i2p::context.SupportsV6 ()) found = true; + } + } + if (found) break; + it++; + } + if (!found) + { + LogPrint (eLogError, "Timestamp: can't find compatible address for ", address); + return; + } + boost::asio::ip::udp::socket socket (service); socket.open (ep.protocol (), ec); if (!ec) From 99c7d5c23a08526357d3cdf97b1af8a656297139 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Jul 2021 22:30:54 -0400 Subject: [PATCH 0251/2193] don't create enryptor for ECIES record encryption --- libi2pd/TunnelConfig.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 45e8a12a..543ba0fa 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -131,17 +131,14 @@ namespace tunnel void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted) { - auto encryptor = ident->CreateEncryptor (nullptr); - if (!encryptor) return; - uint8_t hepk[32]; - encryptor->Encrypt (nullptr, hepk, nullptr, false); - i2p::crypto::InitNoiseNState (*this, hepk); + if (!ident) return; + i2p::crypto::InitNoiseNState (*this, ident->GetEncryptionPublicKey ()); auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); memcpy (encrypted, ephemeralKeys->GetPublicKey (), 32); MixHash (encrypted, 32); // h = SHA256(h || sepk) encrypted += 32; uint8_t sharedSecret[32]; - ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk) + ephemeralKeys->Agree (ident->GetEncryptionPublicKey (), sharedSecret); // x25519(sesk, hepk) MixKey (sharedSecret); uint8_t nonce[12]; memset (nonce, 0, 12); From a6937c792fba9c3736fdd5c6b39c70498e74136f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Jul 2021 17:51:32 -0400 Subject: [PATCH 0252/2193] more precise router selection --- libi2pd/NetDb.cpp | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 1f63c054..c8d8dc38 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1223,24 +1223,34 @@ namespace data { if (m_RouterInfos.empty()) return 0; - uint32_t ind = rand () % m_RouterInfos.size (); - for (int j = 0; j < 2; j++) + std::unique_lock l(m_RouterInfosMutex); + auto ind = rand () % m_RouterInfos.size (); + auto it = m_RouterInfos.begin (); + std::advance (it, ind); + // try random router + if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second)) + return it->second; + // try closest routers + auto it1 = it; it1++; + // forward + while (it1 != m_RouterInfos.end ()) { - uint32_t i = 0; - std::unique_lock l(m_RouterInfosMutex); - for (const auto& it: m_RouterInfos) + if (!it1->second->IsUnreachable () && filter (it1->second)) + return it1->second; + it1++; + } + // still not found, try from the beginning + if (ind) + { + it1 = m_RouterInfos.begin (); + while (it1 != it || it1 != m_RouterInfos.end ()) { - if (i >= ind) - { - if (!it.second->IsUnreachable () && filter (it.second)) - return it.second; - } - else - i++; - } - // we couldn't find anything, try second pass - ind = 0; - } + if (!it1->second->IsUnreachable () && filter (it1->second)) + return it1->second; + it1++; + } + } + return nullptr; // seems we have too few routers } From 513493fa78973bb81540bd1d39145f1b48963335 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Jul 2021 18:46:29 -0400 Subject: [PATCH 0253/2193] fixed typo --- libi2pd/NetDb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index c8d8dc38..429d06b2 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1243,10 +1243,10 @@ namespace data if (ind) { it1 = m_RouterInfos.begin (); - while (it1 != it || it1 != m_RouterInfos.end ()) + while (it1 != it && it1 != m_RouterInfos.end ()) { if (!it1->second->IsUnreachable () && filter (it1->second)) - return it1->second; + return it1->second; it1++; } } From e68cff8bba374a2d06478a6732886cf76b452afe Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Jul 2021 18:35:30 -0400 Subject: [PATCH 0254/2193] try routers before random router --- libi2pd/NetDb.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 429d06b2..edbd7800 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1230,25 +1230,38 @@ namespace data // try random router if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second)) return it->second; - // try closest routers + // try routers after auto it1 = it; it1++; - // forward while (it1 != m_RouterInfos.end ()) { if (!it1->second->IsUnreachable () && filter (it1->second)) return it1->second; it1++; } - // still not found, try from the beginning + // still not found, try some routers before if (ind) { + ind = rand () % ind; it1 = m_RouterInfos.begin (); - while (it1 != it && it1 != m_RouterInfos.end ()) + std::advance (it1, ind); + auto it2 = it1; + while (it2 != it && it2 != m_RouterInfos.end ()) { - if (!it1->second->IsUnreachable () && filter (it1->second)) - return it1->second; - it1++; - } + if (!it2->second->IsUnreachable () && filter (it2->second)) + return it2->second; + it2++; + } + if (ind) + { + // still not found, try from the begining + it2 = m_RouterInfos.begin (); + while (it2 != it1 && it2 != m_RouterInfos.end ()) + { + if (!it2->second->IsUnreachable () && filter (it2->second)) + return it2->second; + it2++; + } + } } return nullptr; // seems we have too few routers From 9a3c22f47d42b88a6ff42ee7d4cb70b856d6decf Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Jul 2021 15:06:24 -0400 Subject: [PATCH 0255/2193] don't encrypt ShortTunnelBuild and ShortTunnelBuildReply if on the same router --- libi2pd/I2NPProtocol.cpp | 30 ++++++++++++++++++++++-------- libi2pd/Tunnel.cpp | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5c6e6e02..54924451 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -709,17 +709,31 @@ namespace i2p } // send reply if (isEndpoint) - { + { auto replyMsg = NewI2NPShortMessage (); replyMsg->Concat (buf, len); replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); - i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); - uint64_t tag; - memcpy (&tag, noiseState.m_CK, 8); - // we send it to reply tunnel - transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); + if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (), + clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, 32)) // reply IBGW is not local? + { + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); + uint64_t tag; + memcpy (&tag, noiseState.m_CK, 8); + // we send it to reply tunnel + transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); + } + else + { + // IBGW is local + uint32_t tunnelID = bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET); + auto tunnel = i2p::tunnel::tunnels.GetTunnel (tunnelID); + if (tunnel) + tunnel->SendTunnelDataMsg (replyMsg); + else + LogPrint (eLogWarning, "I2NP: Tunnel ", tunnelID, " not found for short tunnel build reply"); + } } else transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index d0aaa482..54b24d37 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -96,7 +96,7 @@ namespace tunnel if (m_Config->IsShort ()) { auto ident = m_Config->GetFirstHop () ? m_Config->GetFirstHop ()->ident : nullptr; - if (ident) + if (ident && ident->GetIdentHash () != outboundTunnel->GetNextIdentHash ()) // don't encrypt if IBGW = OBEP { auto msg1 = i2p::garlic::WrapECIESX25519MessageForRouter (msg, ident->GetEncryptionPublicKey ()); if (msg1) msg = msg1; From f8623b612148c490a9148d91d916226e10646da6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Jul 2021 19:08:55 -0400 Subject: [PATCH 0256/2193] consistent path for explicit peers --- libi2pd/TunnelPool.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 614a04f0..1745ebb8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -505,15 +505,12 @@ namespace tunnel bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { - int size = m_ExplicitPeers->size (); - std::vector peerIndicies; - for (int i = 0; i < size; i++) peerIndicies.push_back(i); - std::shuffle (peerIndicies.begin(), peerIndicies.end(), std::mt19937(std::random_device()())); - int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; + if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); + if (!numHops) return false; for (int i = 0; i < numHops; i++) { - auto& ident = (*m_ExplicitPeers)[peerIndicies[i]]; + auto& ident = (*m_ExplicitPeers)[i]; auto r = i2p::data::netdb.FindRouter (ident); if (r) path.Add (r); From 7a55d1fc38451c40ec4c215106a85ee0b8954e95 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Jul 2021 21:14:03 -0400 Subject: [PATCH 0257/2193] don't insert garlic tag for short tunnel build reply if the same router --- libi2pd/Tunnel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 54b24d37..416519a4 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -106,7 +106,8 @@ namespace tunnel } else { - if (m_Config->IsShort () && m_Config->GetLastHop ()) + if (m_Config->IsShort () && m_Config->GetLastHop () && + m_Config->GetLastHop ()->ident->GetIdentHash () != m_Config->GetLastHop ()->nextIdent) { // add garlic key/tag for reply uint8_t key[32]; From b16b753ed2e1d47702072fd6d8f5d935ab8a8fbb Mon Sep 17 00:00:00 2001 From: TomasGl Date: Fri, 30 Jul 2021 17:49:19 +0300 Subject: [PATCH 0258/2193] Change default irc server to IRC ILITA (#1677) --- contrib/tunnels.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/tunnels.conf b/contrib/tunnels.conf index 3358ffc4..55723c43 100644 --- a/contrib/tunnels.conf +++ b/contrib/tunnels.conf @@ -1,16 +1,16 @@ -[IRC-IRC2P] +[IRC-ILITA] type = client address = 127.0.0.1 port = 6668 -destination = irc.postman.i2p +destination = irc.ilita.i2p destinationport = 6667 keys = irc-keys.dat -#[IRC-ILITA] +#[IRC-IRC2P] #type = client #address = 127.0.0.1 #port = 6669 -#destination = irc.ilita.i2p +#destination = irc.postman.i2p #destinationport = 6667 #keys = irc-keys.dat From 1e01c30e63b45c3ccf9bb1b1189d485509426c12 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 30 Jul 2021 14:12:50 -0400 Subject: [PATCH 0259/2193] set pool for zero-hops tunnels --- libi2pd/Tunnel.cpp | 14 ++++++++------ libi2pd/Tunnel.h | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 416519a4..f1f0d087 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -763,8 +763,8 @@ namespace tunnel if (m_InboundTunnels.empty ()) { LogPrint (eLogDebug, "Tunnel: Creating zero hops inbound tunnel"); - CreateZeroHopsInboundTunnel (); - CreateZeroHopsOutboundTunnel (); + CreateZeroHopsInboundTunnel (nullptr); + CreateZeroHopsOutboundTunnel (nullptr); if (!m_ExploratoryPool) { int ibLen; i2p::config::GetOption("exploratory.inbound.length", ibLen); @@ -854,7 +854,7 @@ namespace tunnel if (config) return CreateTunnel(config, pool, outboundTunnel); else - return CreateZeroHopsInboundTunnel (); + return CreateZeroHopsInboundTunnel (pool); } std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config, std::shared_ptr pool) @@ -862,7 +862,7 @@ namespace tunnel if (config) return CreateTunnel(config, pool); else - return CreateZeroHopsOutboundTunnel (); + return CreateZeroHopsOutboundTunnel (pool); } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) @@ -912,18 +912,20 @@ namespace tunnel } - std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel (std::shared_ptr pool) { auto inboundTunnel = std::make_shared (); + inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetState (eTunnelStateEstablished); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; } - std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel (std::shared_ptr pool) { auto outboundTunnel = std::make_shared (); + outboundTunnel->SetTunnelPool (pool); outboundTunnel->SetState (eTunnelStateEstablished); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index c85b734b..acfa21e8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -237,8 +237,8 @@ namespace tunnel void ManagePendingTunnels (PendingTunnels& pendingTunnels); void ManageTunnelPools (uint64_t ts); - std::shared_ptr CreateZeroHopsInboundTunnel (); - std::shared_ptr CreateZeroHopsOutboundTunnel (); + std::shared_ptr CreateZeroHopsInboundTunnel (std::shared_ptr pool); + std::shared_ptr CreateZeroHopsOutboundTunnel (std::shared_ptr pool); private: From d88fe203e1296bea928726f9f6d257b9d661e3a2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 1 Aug 2021 09:25:02 +0300 Subject: [PATCH 0260/2193] [tunnels] count outbound traffic for zero-hop tunnels Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 +- libi2pd/Tunnel.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index fd26d8f1..283313fb 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -492,7 +492,7 @@ namespace http { s << "

"; it->Print(s); if(it->LatencyIsKnown()) - s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; + s << " ( " << it->GetMeanLatency() << tr("ms") << " )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); s << "
\r\n"; } diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f1f0d087..e7b38686 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -328,10 +328,11 @@ namespace tunnel for (auto& msg : msgs) { if (!msg.data) continue; + m_NumSentBytes += msg.data->GetLength (); switch (msg.deliveryType) { case eDeliveryTypeLocal: - i2p::HandleI2NPMessage (msg.data); + HandleI2NPMessage (msg.data); break; case eDeliveryTypeTunnel: i2p::transport::transports.SendMessage (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data)); From da7e41c188ced4921c2963a71da0396dc26bbb71 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 1 Aug 2021 18:42:13 -0400 Subject: [PATCH 0261/2193] use Tag<64> for ratechet tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 11 +---------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8faf1cd9..5ff2ae5c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -31,16 +31,16 @@ namespace garlic uint8_t keydata[64]; i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31] - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf); + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_SessionTagKeyData); // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) - memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32); + memcpy (m_SymmKeyCK, (const uint8_t *)m_SessionTagKeyData + 32, 32); m_NextSymmKeyIndex = 0; } void RatchetTagSet::NextSessionTagRatchet () { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) - memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32); + i2p::crypto::HKDF (m_SessionTagKeyData, nullptr, 0, "STInitialization", m_SessionTagKeyData); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) + memcpy (m_SessTagConstant, (const uint8_t *)m_SessionTagKeyData + 32, 32); // SESSTAG_CONSTANT = keydata[32:63] m_NextIndex = 0; } @@ -52,8 +52,8 @@ namespace garlic LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty"); return 0; } - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) - return m_KeyData.GetTag (); + i2p::crypto::HKDF (m_SessionTagKeyData, m_SessTagConstant, 32, "SessionTagKeyGen", m_SessionTagKeyData); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + return m_SessionTagKeyData.GetLL ()[4]; // tag = keydata[32:39] } void RatchetTagSet::GetSymmKey (int index, uint8_t * key) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index aa72e4b0..5fd2c929 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -60,16 +60,7 @@ namespace garlic private: - union - { - uint64_t ll[8]; - uint8_t buf[64]; - - const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31] - const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63] - uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39] - - } m_KeyData; + i2p::data::Tag<64> m_SessionTagKeyData; uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; int m_NextIndex, m_NextSymmKeyIndex; std::unordered_map > m_ItermediateSymmKeys; From 367df4d0dbb90b1b272a9575343304f0dc5acc8c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Aug 2021 15:43:58 -0400 Subject: [PATCH 0262/2193] RAND_bytes from random router selection --- libi2pd/NetDb.cpp | 75 ++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index edbd7800..825242b5 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1223,47 +1223,54 @@ namespace data { if (m_RouterInfos.empty()) return 0; + uint16_t inds[3]; + RAND_bytes ((uint8_t *)inds, sizeof (inds)); std::unique_lock l(m_RouterInfosMutex); - auto ind = rand () % m_RouterInfos.size (); + inds[0] %= m_RouterInfos.size (); auto it = m_RouterInfos.begin (); - std::advance (it, ind); + std::advance (it, inds[0]); // try random router if (it != m_RouterInfos.end () && !it->second->IsUnreachable () && filter (it->second)) return it->second; - // try routers after - auto it1 = it; it1++; - while (it1 != m_RouterInfos.end ()) + // try some routers around + auto it1 = m_RouterInfos.begin (); + if (inds[0]) { - if (!it1->second->IsUnreachable () && filter (it1->second)) - return it1->second; - it1++; + // before + inds[1] %= inds[0]; + std::advance (it1, inds[1]); } - // still not found, try some routers before - if (ind) - { - ind = rand () % ind; - it1 = m_RouterInfos.begin (); - std::advance (it1, ind); - auto it2 = it1; - while (it2 != it && it2 != m_RouterInfos.end ()) - { - if (!it2->second->IsUnreachable () && filter (it2->second)) - return it2->second; - it2++; - } - if (ind) - { - // still not found, try from the begining - it2 = m_RouterInfos.begin (); - while (it2 != it1 && it2 != m_RouterInfos.end ()) - { - if (!it2->second->IsUnreachable () && filter (it2->second)) - return it2->second; - it2++; - } - } - } - + auto it2 = it; + if (inds[0] < m_RouterInfos.size () - 1) + { + // after + inds[2] %= (m_RouterInfos.size () - 1 - inds[0]); + std::advance (it2, inds[2]); + } + // it1 - from, it2 - to + it = it1; + while (it != it2 && it != m_RouterInfos.end ()) + { + if (!it->second->IsUnreachable () && filter (it->second)) + return it->second; + it++; + } + // still not found, try from the begining + it = m_RouterInfos.begin (); + while (it != it1 && it != m_RouterInfos.end ()) + { + if (!it->second->IsUnreachable () && filter (it->second)) + return it->second; + it++; + } + // still not found, try to the begining + it = it2; + while (it != m_RouterInfos.end ()) + { + if (!it->second->IsUnreachable () && filter (it->second)) + return it->second; + it++; + } return nullptr; // seems we have too few routers } From 64ec7dd559e9fe11dd28c1ea0fbeb664b50f4127 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Aug 2021 19:26:09 -0400 Subject: [PATCH 0263/2193] narrow down random range --- libi2pd/NetDb.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 825242b5..4bc144e4 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1237,14 +1237,16 @@ namespace data if (inds[0]) { // before - inds[1] %= inds[0]; - std::advance (it1, inds[1]); + inds[1] %= inds[0]; + std::advance (it1, (inds[1] + inds[0])/2); } + else + it1 = it; auto it2 = it; if (inds[0] < m_RouterInfos.size () - 1) { // after - inds[2] %= (m_RouterInfos.size () - 1 - inds[0]); + inds[2] %= (m_RouterInfos.size () - 1 - inds[0]); inds[2] /= 2; std::advance (it2, inds[2]); } // it1 - from, it2 - to From 37f1a551479eab1627c842b1484869a9b2f98092 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Aug 2021 12:32:21 -0400 Subject: [PATCH 0264/2193] encryption type 0,4 by default for server tunnel --- libi2pd_client/ClientContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 94311297..f8bc5667 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -457,7 +457,7 @@ namespace client options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption(section, I2CP_PARAM_STREAMING_ANSWER_PINGS, isServer ? DEFAULT_ANSWER_PINGS : false); options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); - std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, isServer ? "" : "0,4"); + std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, "0,4"); if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; std::string privKey = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_PRIV_KEY, ""); if (privKey.length () > 0) options[I2CP_PARAM_LEASESET_PRIV_KEY] = privKey; From 28a055bd78d6d3c413a74ca9dc1fa6ac3019b354 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Aug 2021 17:42:08 +0000 Subject: [PATCH 0265/2193] [webconsole] add external CSS support (#1682) Signed-off-by: R4SAS --- contrib/i18n/English.po | 314 ++++++++++++++++++----------------- contrib/i18n/README.md | 29 ++++ contrib/i18n/regex.txt | 10 -- contrib/webconsole/style.css | 245 +++++++++++++++++++++++++++ daemon/HTTPServer.cpp | 172 +++++++++++-------- i18n/I18N_langs.h | 13 +- i18n/Russian.cpp | 19 +-- i18n/Turkmen.cpp | 288 +++++++++++++++----------------- i18n/Ukrainian.cpp | 16 +- 9 files changed, 689 insertions(+), 417 deletions(-) create mode 100644 contrib/i18n/README.md delete mode 100644 contrib/i18n/regex.txt create mode 100644 contrib/webconsole/style.css diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 76d58390..5a7cc09c 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: i2pd\n" "Report-Msgid-Bugs-To: https://github.com/PurpleI2P/i2pd/issues\n" -"POT-Creation-Date: 2021-06-15 17:40\n" +"POT-Creation-Date: 2021-08-06 17:12\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,556 +18,564 @@ msgstr "" "X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" "X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" -#: daemon/HTTPServer.cpp:85 -msgid "Disabled" -msgstr "" - -#: daemon/HTTPServer.cpp:86 -msgid "Enabled" -msgstr "" - -#: daemon/HTTPServer.cpp:147 +#: daemon/HTTPServer.cpp:175 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:151 +#: daemon/HTTPServer.cpp:179 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:155 +#: daemon/HTTPServer.cpp:183 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:158 +#: daemon/HTTPServer.cpp:186 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" #. tr: Kibibit -#: daemon/HTTPServer.cpp:166 daemon/HTTPServer.cpp:194 +#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:222 msgid "KiB" msgstr "" #. tr: Mebibit -#: daemon/HTTPServer.cpp:168 +#: daemon/HTTPServer.cpp:196 msgid "MiB" msgstr "" #. tr: Gibibit -#: daemon/HTTPServer.cpp:170 +#: daemon/HTTPServer.cpp:198 msgid "GiB" msgstr "" -#: daemon/HTTPServer.cpp:187 +#: daemon/HTTPServer.cpp:215 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:188 +#: daemon/HTTPServer.cpp:216 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:189 +#: daemon/HTTPServer.cpp:217 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:190 +#: daemon/HTTPServer.cpp:218 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:191 +#: daemon/HTTPServer.cpp:219 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:193 +#: daemon/HTTPServer.cpp:221 msgid "exploratory" msgstr "" -#: daemon/HTTPServer.cpp:229 +#: daemon/HTTPServer.cpp:257 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:232 +#: daemon/HTTPServer.cpp:260 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:233 daemon/HTTPServer.cpp:690 +#: daemon/HTTPServer.cpp:261 daemon/HTTPServer.cpp:723 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:234 daemon/HTTPServer.cpp:413 -#: daemon/HTTPServer.cpp:425 +#: daemon/HTTPServer.cpp:262 daemon/HTTPServer.cpp:446 +#: daemon/HTTPServer.cpp:458 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:236 daemon/HTTPServer.cpp:388 -#: daemon/HTTPServer.cpp:469 daemon/HTTPServer.cpp:475 -#: daemon/HTTPServer.cpp:606 daemon/HTTPServer.cpp:649 -#: daemon/HTTPServer.cpp:653 +#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:416 +#: daemon/HTTPServer.cpp:502 daemon/HTTPServer.cpp:508 +#: daemon/HTTPServer.cpp:639 daemon/HTTPServer.cpp:682 +#: daemon/HTTPServer.cpp:686 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:238 daemon/HTTPServer.cpp:659 +#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:692 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:239 daemon/HTTPServer.cpp:395 -#: daemon/HTTPServer.cpp:753 daemon/HTTPServer.cpp:769 +#: daemon/HTTPServer.cpp:267 daemon/HTTPServer.cpp:423 +#: daemon/HTTPServer.cpp:785 daemon/HTTPServer.cpp:801 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:240 daemon/HTTPServer.cpp:818 +#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:850 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:241 +#: daemon/HTTPServer.cpp:269 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:243 daemon/HTTPServer.cpp:880 -#: daemon/HTTPServer.cpp:890 +#: daemon/HTTPServer.cpp:271 daemon/HTTPServer.cpp:912 +#: daemon/HTTPServer.cpp:922 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:259 daemon/HTTPServer.cpp:1280 -#: daemon/HTTPServer.cpp:1283 daemon/HTTPServer.cpp:1286 -#: daemon/HTTPServer.cpp:1300 daemon/HTTPServer.cpp:1345 -#: daemon/HTTPServer.cpp:1348 daemon/HTTPServer.cpp:1351 +#: daemon/HTTPServer.cpp:287 daemon/HTTPServer.cpp:1304 +#: daemon/HTTPServer.cpp:1307 daemon/HTTPServer.cpp:1310 +#: daemon/HTTPServer.cpp:1324 daemon/HTTPServer.cpp:1369 +#: daemon/HTTPServer.cpp:1372 daemon/HTTPServer.cpp:1375 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:266 +#: daemon/HTTPServer.cpp:294 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:267 +#: daemon/HTTPServer.cpp:295 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:268 +#: daemon/HTTPServer.cpp:296 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:290 -#: daemon/HTTPServer.cpp:376 +#: daemon/HTTPServer.cpp:297 daemon/HTTPServer.cpp:318 +#: daemon/HTTPServer.cpp:404 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:400 -#: daemon/HTTPServer.cpp:401 daemon/HTTPServer.cpp:948 -#: daemon/HTTPServer.cpp:957 +#: daemon/HTTPServer.cpp:298 daemon/HTTPServer.cpp:433 +#: daemon/HTTPServer.cpp:434 daemon/HTTPServer.cpp:980 +#: daemon/HTTPServer.cpp:989 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:271 +#: daemon/HTTPServer.cpp:299 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:274 +#: daemon/HTTPServer.cpp:302 msgid "Error" msgstr "" -#: daemon/HTTPServer.cpp:278 +#: daemon/HTTPServer.cpp:306 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:281 +#: daemon/HTTPServer.cpp:309 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:284 +#: daemon/HTTPServer.cpp:312 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:296 +#: daemon/HTTPServer.cpp:324 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:299 +#: daemon/HTTPServer.cpp:327 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:304 +#: daemon/HTTPServer.cpp:332 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:310 daemon/HTTPServer.cpp:317 +#: daemon/HTTPServer.cpp:338 daemon/HTTPServer.cpp:345 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:324 +#: daemon/HTTPServer.cpp:352 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:325 +#: daemon/HTTPServer.cpp:353 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:326 +#: daemon/HTTPServer.cpp:354 msgid "Received" msgstr "" #. tr: Kibibit/s -#: daemon/HTTPServer.cpp:328 daemon/HTTPServer.cpp:331 -#: daemon/HTTPServer.cpp:334 +#: daemon/HTTPServer.cpp:356 daemon/HTTPServer.cpp:359 +#: daemon/HTTPServer.cpp:362 msgid "KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:329 +#: daemon/HTTPServer.cpp:357 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:332 +#: daemon/HTTPServer.cpp:360 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:335 +#: daemon/HTTPServer.cpp:363 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:338 +#: daemon/HTTPServer.cpp:366 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:341 +#: daemon/HTTPServer.cpp:369 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:343 +#: daemon/HTTPServer.cpp:371 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:344 +#: daemon/HTTPServer.cpp:372 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:345 +#: daemon/HTTPServer.cpp:373 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:346 +#: daemon/HTTPServer.cpp:374 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:354 +#: daemon/HTTPServer.cpp:382 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:386 +#: daemon/HTTPServer.cpp:414 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:387 +#: daemon/HTTPServer.cpp:415 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:394 daemon/HTTPServer.cpp:934 +#: daemon/HTTPServer.cpp:422 daemon/HTTPServer.cpp:966 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:399 +#: daemon/HTTPServer.cpp:432 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:448 +#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 +#: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 +#: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +msgid "Enabled" +msgstr "" + +#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 +#: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 +#: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +msgid "Disabled" +msgstr "" + +#: daemon/HTTPServer.cpp:481 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:457 +#: daemon/HTTPServer.cpp:490 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:462 +#: daemon/HTTPServer.cpp:495 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:463 +#: daemon/HTTPServer.cpp:496 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:464 +#: daemon/HTTPServer.cpp:497 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:470 +#: daemon/HTTPServer.cpp:503 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:470 +#: daemon/HTTPServer.cpp:503 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:470 +#: daemon/HTTPServer.cpp:503 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:480 daemon/HTTPServer.cpp:664 +#: daemon/HTTPServer.cpp:513 daemon/HTTPServer.cpp:697 msgid "Inbound tunnels" msgstr "" #. tr: Milliseconds -#: daemon/HTTPServer.cpp:485 daemon/HTTPServer.cpp:495 -#: daemon/HTTPServer.cpp:669 daemon/HTTPServer.cpp:679 +#: daemon/HTTPServer.cpp:518 daemon/HTTPServer.cpp:528 +#: daemon/HTTPServer.cpp:702 daemon/HTTPServer.cpp:712 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:490 daemon/HTTPServer.cpp:674 +#: daemon/HTTPServer.cpp:523 daemon/HTTPServer.cpp:707 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:502 +#: daemon/HTTPServer.cpp:535 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:502 +#: daemon/HTTPServer.cpp:535 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:509 daemon/HTTPServer.cpp:512 +#: daemon/HTTPServer.cpp:542 daemon/HTTPServer.cpp:545 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:510 daemon/HTTPServer.cpp:526 +#: daemon/HTTPServer.cpp:543 daemon/HTTPServer.cpp:559 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:510 +#: daemon/HTTPServer.cpp:543 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:517 +#: daemon/HTTPServer.cpp:550 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:528 +#: daemon/HTTPServer.cpp:558 daemon/HTTPServer.cpp:561 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:526 +#: daemon/HTTPServer.cpp:559 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:535 daemon/HTTPServer.cpp:591 +#: daemon/HTTPServer.cpp:568 daemon/HTTPServer.cpp:624 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:913 +#: daemon/HTTPServer.cpp:578 daemon/HTTPServer.cpp:945 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:567 +#: daemon/HTTPServer.cpp:600 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:596 +#: daemon/HTTPServer.cpp:629 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:599 +#: daemon/HTTPServer.cpp:632 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:625 +#: daemon/HTTPServer.cpp:658 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:628 +#: daemon/HTTPServer.cpp:661 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:629 +#: daemon/HTTPServer.cpp:662 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:634 +#: daemon/HTTPServer.cpp:667 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:637 +#: daemon/HTTPServer.cpp:670 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:638 +#: daemon/HTTPServer.cpp:671 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:639 +#: daemon/HTTPServer.cpp:672 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:649 +#: daemon/HTTPServer.cpp:682 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:660 +#: daemon/HTTPServer.cpp:693 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:691 +#: daemon/HTTPServer.cpp:724 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:698 +#: daemon/HTTPServer.cpp:729 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:700 +#: daemon/HTTPServer.cpp:731 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:709 +#: daemon/HTTPServer.cpp:735 daemon/HTTPServer.cpp:740 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:706 daemon/HTTPServer.cpp:711 +#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:714 +#: daemon/HTTPServer.cpp:745 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:717 +#: daemon/HTTPServer.cpp:746 +msgid "Reload external CSS styles" +msgstr "" + +#: daemon/HTTPServer.cpp:749 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:719 +#: daemon/HTTPServer.cpp:751 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:727 +#: daemon/HTTPServer.cpp:759 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:732 daemon/HTTPServer.cpp:744 +#: daemon/HTTPServer.cpp:764 daemon/HTTPServer.cpp:776 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:736 +#: daemon/HTTPServer.cpp:768 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:769 +#: daemon/HTTPServer.cpp:801 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:874 daemon/HTTPServer.cpp:897 +#: daemon/HTTPServer.cpp:906 daemon/HTTPServer.cpp:929 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:890 +#: daemon/HTTPServer.cpp:922 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:903 +#: daemon/HTTPServer.cpp:935 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:908 +#: daemon/HTTPServer.cpp:940 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:965 +#: daemon/HTTPServer.cpp:997 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:981 +#: daemon/HTTPServer.cpp:1013 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:995 +#: daemon/HTTPServer.cpp:1027 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1201 +#: daemon/HTTPServer.cpp:1225 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1220 +#: daemon/HTTPServer.cpp:1244 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1278 daemon/HTTPServer.cpp:1335 -#: daemon/HTTPServer.cpp:1371 +#: daemon/HTTPServer.cpp:1302 daemon/HTTPServer.cpp:1359 +#: daemon/HTTPServer.cpp:1399 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1278 +#: daemon/HTTPServer.cpp:1302 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1280 +#: daemon/HTTPServer.cpp:1304 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1283 +#: daemon/HTTPServer.cpp:1307 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1286 +#: daemon/HTTPServer.cpp:1310 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1288 daemon/HTTPServer.cpp:1353 +#: daemon/HTTPServer.cpp:1312 daemon/HTTPServer.cpp:1377 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1289 daemon/HTTPServer.cpp:1302 -#: daemon/HTTPServer.cpp:1373 +#: daemon/HTTPServer.cpp:1313 daemon/HTTPServer.cpp:1326 +#: daemon/HTTPServer.cpp:1401 msgid "You will be redirected in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1300 +#: daemon/HTTPServer.cpp:1324 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1301 daemon/HTTPServer.cpp:1372 +#: daemon/HTTPServer.cpp:1325 daemon/HTTPServer.cpp:1400 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1337 +#: daemon/HTTPServer.cpp:1361 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1362 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1338 +#: daemon/HTTPServer.cpp:1362 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1339 +#: daemon/HTTPServer.cpp:1363 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1345 +#: daemon/HTTPServer.cpp:1369 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1348 +#: daemon/HTTPServer.cpp:1372 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1351 +#: daemon/HTTPServer.cpp:1375 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1367 +#: daemon/HTTPServer.cpp:1395 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1371 +#: daemon/HTTPServer.cpp:1399 msgid "Command accepted" msgstr "" diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md new file mode 100644 index 00000000..be44e87f --- /dev/null +++ b/contrib/i18n/README.md @@ -0,0 +1,29 @@ +`xgettext` command for extracting translation +=== + +``` +xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp +``` + +Regex for transforming gettext translations to our format: +=== + +``` +in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? +out: #{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n +``` + +``` +in: msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n +out: {"$1", "$2"},\n +``` + +``` +in: ^#[:.](.*)$\n +out: +``` + +``` +in: \n\n +out: \n +``` diff --git a/contrib/i18n/regex.txt b/contrib/i18n/regex.txt deleted file mode 100644 index e74f9d2d..00000000 --- a/contrib/i18n/regex.txt +++ /dev/null @@ -1,10 +0,0 @@ -Regex for transforming gettext translations to our format - -msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? -#{"$2", {"$3", "$4", "$6", "$8", "$10"}},\n - -msgid\ \"(.*)\"\nmsgstr\ \"(.*)\"\n -{"$1", "$2"},\n - -^#:(.*)$\n - diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css new file mode 100644 index 00000000..b6e56477 --- /dev/null +++ b/contrib/webconsole/style.css @@ -0,0 +1,245 @@ +body { + font: 100%/1.5em sans-serif; + margin: 0; + padding: 1.5em; + background: #FAFAFA; + color: #103456; +} + +a, .slide label { + text-decoration: none; + color: #894C84; +} + +a:hover, .slide label:hover { + color: #FAFAFA; + background: #894C84; +} + +a.button { + -webkit-appearance: button; + -moz-appearance: button; + appearance: button; + text-decoration: none; + color: initial; + padding: 0 5px; + border: 1px solid #894C84; +} + +.header { + font-size: 2.5em; + text-align: center; + margin: 1em 0; + color: #894C84; +} + +.wrapper { + margin: 0 auto; + padding: 1em; + max-width: 64em; +} + +.menu { + display: block; + float: left; + overflow: hidden; + max-width: 12em; + white-space: nowrap; + text-overflow: ellipsis; +} + +.listitem { + display: block; + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.tableitem { + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.content { + float: left; + font-size: 1em; + margin-left: 4em; + max-width: 48em; + overflow: auto; +} + +.tunnel.established { + color: #56B734; +} + +.tunnel.expiring { + color: #D3AE3F; +} + +.tunnel.failed { + color: #D33F3F; +} + +.tunnel.building { + color: #434343; +} + +caption { + font-size: 1.5em; + text-align: center; + color: #894C84; +} + +table { + display: table; + border-collapse: collapse; + text-align: center; +} + +table.extaddr { + text-align: left; +} + +table.services { + width: 100%; +} + +textarea { + word-break: break-all; +} + +.streamdest { + width: 120px; + max-width: 240px; + overflow: hidden; + text-overflow: ellipsis; +} + +.slide div.slidecontent, .slide [type="checkbox"] { + display: none; +} + +.slide [type="checkbox"]:checked ~ div.slidecontent { + display: block; + margin-top: 0; + padding: 0; +} + +.disabled { + color: #D33F3F; +} + +.enabled { + color: #56B734; +} + +@media screen and (max-width: 1150px) { /* adaptive style */ + .wrapper { + max-width: 58em; + } + + .menu { + max-width: 10em; + } + + .content { + margin-left: 2em; + max-width: 42em; + } +} + +@media screen and (max-width: 980px) { + body { + padding: 1.5em 0 0 0; + } + + .menu { + width: 100%; + max-width: unset; + display: block; + float: none; + position: unset; + font-size: 16px; + text-align: center; + } + + .menu a, .commands a { + display: inline-block; + padding: 4px; + } + + .content { + float: none; + margin-left: unset; + margin-top: 16px; + max-width: 100%; + width: 100%; + text-align: center; + } + + a, .slide label { + /* margin-right: 10px; */ + display: block; + /* font-size: 18px; */ + } + + .header { + margin: unset; + font-size: 1.5em; + } + + small { + display: block + } + + a.button { + -webkit-appearance: button; + -moz-appearance: button; + appearance: button; + text-decoration: none; + color: initial; + margin-top: 10px; + padding: 6px; + border: 1px solid #894c84; + width: -webkit-fill-available; + } + + input, select { + width: 35%; + text-align: center; + padding: 5px; + border: 2px solid #ccc; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 18px; + } + + table.extaddr { + margin: auto; + text-align: unset; + } + + textarea { + width: -webkit-fill-available; + height: auto; + padding:5px; + border:2px solid #ccc; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 12px; + } + + button[type=submit] { + padding: 5px 15px; + background: #ccc; + border: 0 none; + cursor: pointer; + -webkit-border-radius: 5px; + border-radius: 5px; + position: relative; + height: 36px; + display: -webkit-inline-box; + margin-top: 10px; + } +} \ No newline at end of file diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 283313fb..5c6a3cd8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -59,55 +59,75 @@ namespace http { "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" "RU5ErkJggg=="; + // Bundled style + const std::string internalCSS = + "\r\n"; + + // for external style sheet + std::string externalCSS; + + static void LoadExtCSS () + { + std::stringstream s; + std::string styleFile = i2p::fs::DataDirPath ("webconsole/style.css"); + if (i2p::fs::Exists(styleFile)) { + std::ifstream f(styleFile, std::ifstream::binary); + s << f.rdbuf(); + externalCSS = s.str(); + } + } + static void GetStyles (std::stringstream& s) { - s << "\r\n"; + if (externalCSS.length() != 0) + s << "\r\n"; + else + s << internalCSS; } const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -133,11 +153,19 @@ namespace http { const char HTTP_COMMAND_LIMITTRANSIT[] = "limittransit"; const char HTTP_COMMAND_GET_REG_STRING[] = "get_reg_string"; const char HTTP_COMMAND_SETLANGUAGE[] = "setlanguage"; + const char HTTP_COMMAND_RELOAD_CSS[] = "reload_css"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; - static std::string ConvertTime (uint64_t time); - std::map HTTPConnection::m_Tokens; + static std::string ConvertTime (uint64_t time) + { + lldiv_t divTime = lldiv(time, 1000); + time_t t = divTime.quot; + struct tm *tm = localtime(&t); + char date[128]; + snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03lld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); + return date; + } static void ShowUptime (std::stringstream& s, int seconds) { @@ -210,9 +238,9 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); // Page language - std::string lang, langCode; i2p::config::GetOption("http.lang", lang); - if (lang == "russian") langCode = "ru"; - else langCode = "en"; + std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + auto it = i2p::i18n::languages.find(currLang); + std::string langCode = it->second.ShortCode; s << "\r\n" @@ -395,14 +423,19 @@ namespace http { s << "" << tr("Transit Tunnels") << ": " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forWebConsole) { - bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); + bool httpproxy = i2p::client::context.GetHttpProxy () ? true : false; + bool socksproxy = i2p::client::context.GetSocksProxy () ? true : false; + bool bob = i2p::client::context.GetBOBCommandChannel () ? true : false; + bool sam = i2p::client::context.GetSAMBridge () ? true : false; + bool i2cp = i2p::client::context.GetI2CPServer () ? true : false; + bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; s << "
" << tr("Services") << "
" << "HTTP " << tr("Proxy") << "
" << "SOCKS " << tr("Proxy") << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
" << "HTTP " << tr("Proxy") << "" << (httpproxy ? tr("Enabled") : tr("Disabled")) << "
" << "SOCKS " << tr("Proxy") << "" << (socksproxy ? tr("Enabled") : tr("Disabled")) << "
" << "BOB" << "" << (bob ? tr("Enabled") : tr("Disabled")) << "
" << "SAM" << "" << (sam ? tr("Enabled") : tr("Disabled")) << "
" << "I2CP" << "" << (i2cp ? tr("Enabled") : tr("Disabled")) << "
" << "I2PControl" << "" << (i2pcontrol ? tr("Enabled") : tr("Disabled")) << "
\r\n"; } } @@ -709,7 +742,8 @@ namespace http { s << " " << tr("Start graceful shutdown") << "
\r\n"; #endif - s << " " << tr("Force shutdown") << "\r\n"; + s << " " << tr("Force shutdown") << "

\r\n"; + s << " " << tr("Reload external CSS styles") << "\r\n"; s << "
"; s << "
\r\n" << tr("Note: any action done here are not persistent and not changes your config files.") << "\r\n
\r\n"; @@ -1003,16 +1037,6 @@ namespace http { } } - std::string ConvertTime (uint64_t time) - { - lldiv_t divTime = lldiv(time, 1000); - time_t t = divTime.quot; - struct tm *tm = localtime(&t); - char date[128]; - snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03lld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); - return date; - } - HTTPConnection::HTTPConnection (std::string hostname, std::shared_ptr socket): m_Socket (socket), m_BufferLen (0), expected_host(hostname) { @@ -1139,6 +1163,8 @@ namespace http { SendReply (res, content); } + std::map HTTPConnection::m_Tokens; + uint32_t HTTPConnection::CreateToken () { uint32_t token; @@ -1359,6 +1385,10 @@ namespace http { if (currLang.compare(lang) != 0) i2p::i18n::SetLanguage(lang); } + else if (cmd == HTTP_COMMAND_RELOAD_CSS) + { + LoadExtCSS(); + } else { res.code = 400; @@ -1421,6 +1451,8 @@ namespace http { m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); Accept (); + + LoadExtCSS(); } void HTTPServer::Stop () diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 949e5844..a5029782 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -65,7 +65,8 @@ namespace i18n struct langData { - std::string LocaleName; //localized name + std::string LocaleName; // localized name + std::string ShortCode; // short language code, like "en" std::function (void)> LocaleFunc; }; @@ -81,11 +82,11 @@ namespace i18n */ static std::map languages { - { "afrikaans", {"Afrikaans", i2p::i18n::afrikaans::GetLocale} }, - { "english", {"English", i2p::i18n::english::GetLocale} }, - { "russian", {"русский язык", i2p::i18n::russian::GetLocale} }, - { "turkmen", {"türkmen dili", i2p::i18n::turkmen::GetLocale} }, - { "ukrainian", {"украї́нська мо́ва", i2p::i18n::ukrainian::GetLocale} }, + { "afrikaans", {"Afrikaans", "af", i2p::i18n::afrikaans::GetLocale} }, + { "english", {"English", "en", i2p::i18n::english::GetLocale} }, + { "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} }, + { "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, + { "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, }; } // i18n diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index 5e7f9c6b..a826cdda 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -31,8 +31,6 @@ namespace russian // language namespace static std::map strings { - {"Disabled", "Выключено"}, - {"Enabled", "Включено"}, {"KiB", "КиБ"}, {"MiB", "МиБ"}, {"GiB", "ГиБ"}, @@ -45,10 +43,10 @@ namespace russian // language namespace {"i2pd webconsole", "Веб-консоль i2pd"}, {"Main page", "Главная"}, {"Router commands", "Команды роутера"}, - {"Local destinations", "Локальные назначения"}, + {"Local Destinations", "Локальные назначения"}, {"LeaseSets", "Лизсеты"}, {"Tunnels", "Туннели"}, - {"Transit tunnels", "Транзитные туннели"}, + {"Transit Tunnels", "Транзитные туннели"}, {"Transports", "Транспорты"}, {"I2P tunnels", "I2P туннели"}, {"SAM sessions", "SAM сессии"}, @@ -84,9 +82,9 @@ namespace russian // language namespace {"Routers", "Роутеры"}, {"Floodfills", "Флудфилы"}, {"Client Tunnels", "Клиентские туннели"}, - {"Transit Tunnels", "Транзитные туннели"}, {"Services", "Сервисы"}, - {"Local Destinations", "Локальные назначения"}, + {"Enabled", "Включено"}, + {"Disabled", "Выключено"}, {"Encrypted B33 address", "Шифрованные B33 адреса"}, {"Address registration line", "Строка регистрации адреса"}, {"Domain", "Домен"}, @@ -103,8 +101,8 @@ namespace russian // language namespace {"Outgoing", "Исходящие"}, {"Destination", "Назначение"}, {"Amount", "Количество"}, - {"Incoming Tags", "Входящие Теги"}, - {"Tags sessions", "Сессии Тегов"}, + {"Incoming Tags", "Входящие теги"}, + {"Tags sessions", "Сессии тегов"}, {"Status", "Статус"}, {"Local Destination", "Локальное назначение"}, {"Streams", "Стримы"}, @@ -126,6 +124,7 @@ namespace russian // language namespace {"Cancel graceful shutdown", "Отменить плавную остановку"}, {"Start graceful shutdown", "Запустить плавную остановку"}, {"Force shutdown", "Принудительная остановка"}, + {"Reload external CSS styles", "Перезагрузить внешние CSS стили"}, {"Note: any action done here are not persistent and not changes your config files.", "Примечание: любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."}, {"Logging level", "Уровень логирования"}, {"Transit tunnels limit", "Лимит транзитных туннелей"}, @@ -147,7 +146,7 @@ namespace russian // language namespace {"Destination not found", "Точка назначения не найдена"}, {"StreamID can't be null", "StreamID не может быть пустым"}, {"Return to destination page", "Вернуться на страницу точки назначения"}, - {"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"}, + {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, {"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"}, {"Back to commands list", "Вернуться к списку команд"}, {"Register at reg.i2p", "Зарегистрировать на reg.i2p"}, @@ -159,7 +158,6 @@ namespace russian // language namespace {"Such destination is not found", "Такая точка назначения не найдена"}, {"Unknown command", "Неизвестная команда"}, {"Command accepted", "Команда принята"}, - {"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"}, {"Proxy error", "Ошибка прокси"}, {"Proxy info", "Информация прокси"}, {"Proxy error: Host not found", "Ошибка прокси: Узел не найден"}, @@ -176,7 +174,6 @@ namespace russian // language namespace {"Addresshelper found", "Найден addresshelper"}, {"already in router's addressbook", "уже в адресной книге роутера"}, {"to update record", "чтобы обновить запись"}, - {"Invalid Request", "неверный запрос"}, {"invalid request uri", "некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 8af89f6f..2bcd77cd 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -31,7 +31,133 @@ namespace turkmen // language namespace static std::map strings { - // HTTP Proxy + {"KiB", "KiB"}, + {"MiB", "MiB"}, + {"GiB", "GiB"}, + {"building", "bina"}, + {"failed", "şowsuz"}, + {"expiring", "möhleti gutarýar"}, + {"established", "işleýär"}, + {"unknown", "näbelli"}, + {"exploratory", "gözleg"}, + {"i2pd webconsole", "Web konsoly i2pd"}, + {"Main page", "Esasy sahypa"}, + {"Router commands", "Marşrutizator buýruklary"}, + {"Local Destinations", "Ýerli ýerler"}, + {"LeaseSets", "Lizset"}, + {"Tunnels", "Tuneller"}, + {"Transit Tunnels", "Tranzit Tunelleri"}, + {"Transports", "Daşamak"}, + {"I2P tunnels", "I2P tuneller"}, + {"SAM sessions", "SAM Sessiýasy"}, + {"ERROR", "Ýalňyşlyk"}, + {"OK", "OK"}, + {"Testing", "Synag etmek"}, + {"Firewalled", "Daşynda petiklendi"}, + {"Unknown", "Näbelli"}, + {"Proxy", "Proksi"}, + {"Mesh", "MESH-tor"}, + {"Error", "Ýalňyşlyk"}, + {"Clock skew", "Takyk wagt däl"}, + {"Offline", "Awtonom"}, + {"Symmetric NAT", "Simmetriklik NAT"}, + {"Uptime", "Onlaýn onlaýn sözlügi"}, + {"Network status", "Tor ýagdaýy"}, + {"Network status v6", "Tor ýagdaýy v6"}, + {"Stopping in", "Soň duruň"}, + {"Family", "Maşgala"}, + {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, + {"Received", "Alnan"}, + {"KiB/s", "KiB/s"}, + {"Sent", "Ýerleşdirildi"}, + {"Transit", "Tranzit"}, + {"Data path", "Maglumat ýoly"}, + {"Hidden content. Press on text to see.", "Gizlin mazmun. Görkezmek üçin tekste basyň."}, + {"Router Ident", "Marşrutly kesgitleýji"}, + {"Router Family", "Marşrutler maşgalasy"}, + {"Router Caps", "Baýdaklar marşruteri"}, + {"Version", "Wersiýasy"}, + {"Our external address", "Daşarky salgymyz"}, + {"supported", "goldanýar"}, + {"Routers", "Marşrutizatorlar"}, + {"Floodfills", "Fludfillar"}, + {"Client Tunnels", "Müşderi tunelleri"}, + {"Services", "Hyzmatlar"}, + {"Enabled", "Goşuldy"}, + {"Disabled", "Öçürildi"}, + {"Encrypted B33 address", "Şifrlenen B33 salgylar"}, + {"Address registration line", "Hasaba alyş salgysy"}, + {"Domain", "Domen"}, + {"Generate", "Öndürmek"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Bellik: Alnan setir diňe ikinji derejeli domenleri bellige almak üçin ulanylyp bilner (example.i2p). Subýutmalary hasaba almak üçin i2pd ulanyň-tools."}, + {"Address", "Salgysy"}, + {"Type", "Görnüş"}, + {"EncType", "Şifrlemek görnüşi"}, + {"Inbound tunnels", "Gelýän tuneller"}, + {"ms", "ms"}, + {"Outbound tunnels", "Çykýan tuneller"}, + {"Tags", "Bellikler"}, + {"Incoming", "Gelýän"}, + {"Outgoing", "Çykýan"}, + {"Destination", "Maksat"}, + {"Amount", "Sany"}, + {"Incoming Tags", "Gelýän bellikler"}, + {"Tags sessions", "Sapaklar bellikler"}, + {"Status", "Ýagdaýy"}, + {"Local Destination", "Ýerli maksat"}, + {"Streams", "Strimlary"}, + {"Close stream", "Yap strim"}, + {"I2CP session not found", "I2CP Sessiýa tapylmady"}, + {"I2CP is not enabled", "I2CP goşulmaýar"}, + {"Invalid", "Nädogry"}, + {"Store type", "Ammar görnüşi"}, + {"Expires", "Möhleti gutarýar"}, + {"Non Expired Leases", "Möhleti gutarmady Lizsetlary"}, + {"Gateway", "Derweze"}, + {"TunnelID", "Tuneliň ID"}, + {"EndDate", "Gutarýar"}, + {"not floodfill", "fludfil däl"}, + {"Queue size", "Nobatyň ululygy"}, + {"Run peer test", "Synag başlaň"}, + {"Decline transit tunnels", "Tranzit tunellerini ret ediň"}, + {"Accept transit tunnels", "Tranzit tunellerini alyň"}, + {"Cancel graceful shutdown", "Tekiz durmagy ýatyryň"}, + {"Start graceful shutdown", "Tekiz durmak"}, + {"Force shutdown", "Mejbury duralga"}, + {"Reload external CSS styles", "Daşarky CSS stillerini täzeden ýükläň"}, + {"Note: any action done here are not persistent and not changes your config files.", "Bellik: Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär."}, + {"Logging level", "Giriş derejesi"}, + {"Transit tunnels limit", "Tranzit tunelleriniň çägi"}, + {"Change", "Üýtgetmek"}, + {"Change language", "Dil üýtgetmek"}, + {"no transit tunnels currently built", "gurlan tranzit tunelleri ýok"}, + {"SAM disabled", "SAM öçürilen"}, + {"no sessions currently running", "başlamagyň sessiýalary ýok"}, + {"SAM session not found", "SAM Sessiýa tapylmady"}, + {"SAM Session", "SAM Sessiýa"}, + {"Server Tunnels", "Serwer tunelleri"}, + {"Client Forwards", "Müşderi gönükdirýär"}, + {"Server Forwards", "Serweriň täzeden düzlüleri"}, + {"Unknown page", "Näbelli sahypa"}, + {"Invalid token", "Nädogry token"}, + {"SUCCESS", "Üstünlikli"}, + {"Stream closed", "Strim ýapyk"}, + {"Stream not found or already was closed", "Strim tapylmady ýa-da eýýäm ýapyldy"}, + {"Destination not found", "Niýetlenen ýeri tapylmady"}, + {"StreamID can't be null", "StreamID boş bolup bilmez"}, + {"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"}, + {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"}, + {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"}, + {"Back to commands list", "Topar sanawyna dolan"}, + {"Register at reg.i2p", "Reg.i2P-de hasaba duruň"}, + {"Description", "Beýany"}, + {"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"}, + {"Submit", "Iber"}, + {"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez"}, + {"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"}, + {"Such destination is not found", "Bu barmaly ýer tapylmady"}, + {"Unknown command", "Näbelli topar"}, + {"Command accepted", "Topar kabul edilýär"}, {"Proxy error", "Proksi ýalňyşlygy"}, {"Proxy info", "Proksi maglumat"}, {"Proxy error: Host not found", "Proksi ýalňyşlygy: Host tapylmady"}, @@ -42,12 +168,12 @@ namespace turkmen // language namespace {"addresshelper is not supported", "Salgylandyryjy goldanok"}, {"Host", "Adres"}, {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"}, - {"already in router's addressbook", "marşruteriň adres kitaby"}, {"Click", "Basyň"}, {"here", "bu ýerde"}, {"to proceed", "dowam etmek"}, - {"to update record", "recordazgyny täzelemek üçin"}, {"Addresshelper found", "Forgelper tapyldy"}, + {"already in router's addressbook", "marşruteriň adres kitaby"}, + {"to update record", "recordazgyny täzelemek üçin"}, {"invalid request uri", "nädogry haýyş URI"}, {"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"}, {"Outproxy failure", "Daşarky proksi ýalňyşlyk"}, @@ -67,161 +193,7 @@ namespace turkmen // language namespace {"http out proxy not implemented", "daşarky HTTP proksi serwerini goldamak amala aşyrylmaýar"}, {"cannot connect to upstream http proxy", "ýokary akym HTTP proksi serwerine birigip bilmedi"}, {"Host is down", "Salgy elýeterli däl"}, - {"Can't create connection to requested host, it may be down. Please try again later.", - "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."}, - - // Webconsole // - // cssStyles - {"Disabled", "Öçürildi"}, - {"Enabled", "Goşuldy"}, - // ShowTraffic - {"KiB", "KiB"}, - {"MiB", "MiB"}, - {"GiB", "GiB"}, - // ShowTunnelDetails - {"building", "bina"}, - {"failed", "şowsuz"}, - {"expiring", "möhleti gutarýar"}, - {"established", "işleýär"}, - {"exploratory", "gözleg"}, - {"unknown", "näbelli"}, - {"i2pd webconsole", "Web konsoly i2pd"}, - // ShowPageHead - {"Main page", "Esasy sahypa"}, - {"Router commands", "Marşrutizator buýruklary"}, - {"Local destinations", "Ýerli ýerler"}, - {"LeaseSets", "Lizset"}, - {"Tunnels", "Tuneller"}, - {"Transit tunnels", "Tranzit tunels"}, - {"Transports", "Daşamak"}, - {"I2P tunnels", "I2P tuneller"}, - {"SAM sessions", "SAM Sessiýasy"}, - // Network Status - {"OK", "OK"}, - {"Testing", "Synag etmek"}, - {"Firewalled", "Daşynda petiklendi"}, - {"Unknown", "Näbelli"}, - {"Proxy", "Proksi"}, - {"Mesh", "MESH-tor"}, - {"Error", "Ýalňyşlyk"}, - {"Clock skew", "Takyk wagt däl"}, - {"Offline", "Awtonom"}, - {"Symmetric NAT", "Simmetriklik NAT"}, - // Status - {"Uptime", "Onlaýn onlaýn sözlügi"}, - {"Network status", "Tor ýagdaýy"}, - {"Network status v6", "Tor ýagdaýy v6"}, - {"Stopping in", "Soň duruň"}, - {"Family", "Maşgala"}, - {"Tunnel creation success rate", "Gurlan teneller üstünlikli gurlan teneller"}, - {"Received", "Alnan"}, - {"Sent", "Ýerleşdirildi"}, - {"Transit", "Tranzit"}, - {"KiB/s", "KiB/s"}, - {"Data path", "Maglumat ýoly"}, - {"Hidden content. Press on text to see.", "Gizlin mazmun. Görkezmek üçin tekste basyň."}, - {"Router Ident", "Marşrutly kesgitleýji"}, - {"Router Family", "Marşrutler maşgalasy"}, - {"Router Caps", "Baýdaklar marşruteri"}, - {"Version", "Wersiýasy"}, - {"Our external address", "Daşarky salgymyz"}, - {"supported", "goldanýar"}, - {"Routers", "Marşrutizatorlar"}, - {"Floodfills", "Fludfillar"}, - {"Client Tunnels", "Müşderi tunelleri"}, - {"Transit Tunnels", "Tranzit Tunelleri"}, - {"Services", "Hyzmatlar"}, - // ShowLocalDestinations - {"Local Destinations", "Ýerli ýerler"}, - // ShowLeaseSetDestination - {"Encrypted B33 address", "Şifrlenen B33 salgylar"}, - {"Address registration line", "Hasaba alyş salgysy"}, - {"Domain", "Domen"}, - {"Generate", "Öndürmek"}, - {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", - "Bellik: Alnan setir diňe ikinji derejeli domenleri bellige almak üçin ulanylyp bilner. Subýutmalary hasaba almak üçin i2pd ulanyň-tools."}, - {"Address", "Salgysy"}, - {"Type", "Görnüş"}, - {"EncType", "Şifrlemek görnüşi"}, - {"Inbound tunnels", "Gelýän tuneller"}, - {"Outbound tunnels", "Çykýan tuneller"}, - {"ms", "ms"}, // milliseconds - {"Tags", "Bellikler"}, - {"Incoming", "Gelýän"}, - {"Outgoing", "Çykýan"}, - {"Destination", "Maksat"}, - {"Amount", "Sany"}, - {"Incoming Tags", "Gelýän bellikler"}, - {"Tags sessions", "Sapaklar bellikler"}, - {"Status", "Ýagdaýy"}, - // ShowLocalDestination - {"Local Destination", "Ýerli maksat"}, - {"Streams", "Strimlary"}, - {"Close stream", "Yap strim"}, - // ShowI2CPLocalDestination - {"I2CP session not found", "I2CP Sessiýa tapylmady"}, - {"I2CP is not enabled", "I2CP goşulmaýar"}, - // ShowLeasesSets - {"Invalid", "Nädogry"}, - {"Store type", "Ammar görnüşi"}, - {"Expires", "Möhleti gutarýar"}, - {"Non Expired Leases", "Möhleti gutarmady Lizsetlary"}, - {"Gateway", "Derweze"}, - {"TunnelID", "Tuneliň ID"}, - {"EndDate", "Gutarýar"}, - {"not floodfill", "fludfil däl"}, - // ShowTunnels - {"Queue size", "Nobatyň ululygy"}, - // ShowCommands - {"Run peer test", "Synag başlaň"}, - {"Decline transit tunnels", "Tranzit tunellerini ret ediň"}, - {"Accept transit tunnels", "Tranzit tunellerini alyň"}, - {"Cancel graceful shutdown", "Tekiz durmagy ýatyryň"}, - {"Start graceful shutdown", "Tekiz durmak"}, - {"Force shutdown", "Mejbury duralga"}, - {"Note: any action done here are not persistent and not changes your config files.", - "Bellik: Bu ýerde öndürilen islendik çäre hemişelik däl we konfigurasiýa faýllaryňyzy üýtgetmeýär."}, - {"Logging level", "Giriş derejesi"}, - {"Transit tunnels limit", "Tranzit tunelleriniň çägi"}, - {"Change", "Üýtgetmek"}, - // ShowTransitTunnels - {"no transit tunnels currently built", "gurlan tranzit tunelleri ýok"}, - // ShowSAMSessions/ShowSAMSession - {"SAM disabled", "SAM öçürilen"}, - {"SAM session not found", "SAM Sessiýa tapylmady"}, - {"no sessions currently running", "başlamagyň sessiýalary ýok"}, - {"SAM Session", "SAM Sessiýa"}, - // ShowI2PTunnels - {"Server Tunnels", "Serwer tunelleri"}, - {"Client Forwards", "Müşderi gönükdirýär"}, - {"Server Forwards", "Serweriň täzeden düzlüleri"}, - // HandlePage - {"Unknown page", "Näbelli sahypa"}, - // HandleCommand, ShowError - {"Invalid token", "Nädogry token"}, - {"SUCCESS", "Üstünlikli"}, - {"ERROR", "Ýalňyşlyk"}, - {"Unknown command", "Näbelli topar"}, - {"Command accepted", "Topar kabul edilýär"}, - {"Back to commands list", "Topar sanawyna dolan"}, - {"You will be redirected in 5 seconds", "5 sekuntdan soň täzeden ugrukdyrylarsyňyz"}, - // HTTP_COMMAND_KILLSTREAM - {"Stream closed", "Strim ýapyk"}, - {"Stream not found or already was closed", "Strim tapylmady ýa-da eýýäm ýapyldy"}, - {"Destination not found", "Niýetlenen ýeri tapylmady"}, - {"StreamID can't be null", "StreamID boş bolup bilmez"}, - {"Return to destination page", "Barmaly nokadynyň nokadyna gaýdyp geliň"}, - {"You will be redirected back in 5 seconds", "5 sekuntda yzyna iberiler"}, - // HTTP_COMMAND_LIMITTRANSIT - {"Transit tunnels count must not exceed 65535", "Tranzit tagtalaryň sany 65535-den geçmeli däldir"}, - // HTTP_COMMAND_GET_REG_STRING - {"Register at reg.i2p", "Reg.i2P-de hasaba duruň"}, - {"Description", "Beýany"}, - {"A bit information about service on domain", "Domendäki hyzmat barada käbir maglumatlar"}, - {"Submit", "Iber"}, - {"Domain can't end with .b32.i2p", "Domain .b32.i2p bilen gutaryp bilmez"}, - {"Domain must end with .i2p", "Domeni .i2p bilen gutarmaly"}, - {"Such destination is not found", "Bu barmaly ýer tapylmady"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Talap edilýän salgyda birikmäni gurup bilmedim, onlaýn bolup bilmez. Soňra haýyşy soň gaýtalamaga synanyşyň."}, {"", ""}, }; diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 8da132d7..413375ba 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -31,8 +31,6 @@ namespace ukrainian // language namespace static std::map strings { - {"Disabled", "Вимкнуто"}, - {"Enabled", "Увімкнуто"}, {"KiB", "КіБ"}, {"MiB", "МіБ"}, {"GiB", "ГіБ"}, @@ -45,10 +43,10 @@ namespace ukrainian // language namespace {"i2pd webconsole", "Веб-консоль i2pd"}, {"Main page", "Головна"}, {"Router commands", "Команди маршрутизатора"}, - {"Local destinations", "Локальні призначення"}, + {"Local Destinations", "Локальні Призначення"}, {"LeaseSets", "Лізсети"}, {"Tunnels", "Тунелі"}, - {"Transit tunnels", "Транзитні тунелі"}, + {"Transit Tunnels", "Транзитні Тунелі"}, {"Transports", "Транспорти"}, {"I2P tunnels", "I2P тунелі"}, {"SAM sessions", "SAM сесії"}, @@ -84,9 +82,9 @@ namespace ukrainian // language namespace {"Routers", "Маршрутизатори"}, {"Floodfills", "Флудфіли"}, {"Client Tunnels", "Клієнтські Тунелі"}, - {"Transit Tunnels", "Транзитні Тунелі"}, {"Services", "Сервіси"}, - {"Local Destinations", "Локальні Призначення"}, + {"Enabled", "Увімкнуто"}, + {"Disabled", "Вимкнуто"}, {"Encrypted B33 address", "Шифровані B33 адреси"}, {"Address registration line", "Рядок реєстрації адреси"}, {"Domain", "Домен"}, @@ -126,10 +124,12 @@ namespace ukrainian // language namespace {"Cancel graceful shutdown", "Скасувати плавну зупинку"}, {"Start graceful shutdown", "Запустити плавну зупинку"}, {"Force shutdown", "Примусова зупинка"}, + {"Reload external CSS styles", "Перезавантажити зовнішні стилі CSS"}, {"Note: any action done here are not persistent and not changes your config files.", "Примітка: будь-яка зроблена тут дія не є постійною та не змінює ваші конфігураційні файли."}, {"Logging level", "Рівень логування"}, {"Transit tunnels limit", "Обмеження транзитних тунелів"}, {"Change", "Змінити"}, + {"Change language", "Змінити мову"}, {"no transit tunnels currently built", "немає побудованих транзитних тунелів"}, {"SAM disabled", "SAM вимкнуто"}, {"no sessions currently running", "немає запущених сесій"}, @@ -146,7 +146,7 @@ namespace ukrainian // language namespace {"Destination not found", "Точка призначення не знайдена"}, {"StreamID can't be null", "Ідентифікатор потоку не може бути порожнім"}, {"Return to destination page", "Повернутися на сторінку точки призначення"}, - {"You will be redirected back in 5 seconds", "Ви будете переадресовані назад через 5 секунд"}, + {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, {"Transit tunnels count must not exceed 65535", "Кількість транзитних тунелів не повинна перевищувати 65535"}, {"Back to commands list", "Повернутися до списку команд"}, {"Register at reg.i2p", "Зареєструвати на reg.i2p"}, @@ -158,7 +158,6 @@ namespace ukrainian // language namespace {"Such destination is not found", "Така точка призначення не знайдена"}, {"Unknown command", "Невідома команда"}, {"Command accepted", "Команда прийнята"}, - {"You will be redirected in 5 seconds", "Ви будете переадресовані через 5 секунд"}, {"Proxy error", "Помилка проксі"}, {"Proxy info", "Інформація проксі"}, {"Proxy error: Host not found", "Помилка проксі: Адреса не знайдена"}, @@ -175,7 +174,6 @@ namespace ukrainian // language namespace {"Addresshelper found", "Знайдено addresshelper"}, {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, {"to update record", "щоб оновити запис"}, - {"Invalid Request", "Некоректний Запит"}, {"invalid request uri", "некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, From 939682737950f53cd5b6dc68d029b3218c2efe6a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 4 Aug 2021 07:03:54 +0300 Subject: [PATCH 0266/2193] [makefile] build libraries on default target Signed-off-by: R4SAS --- .gitignore | 3 +++ Makefile | 49 +++++++++++++++++++++++++++---------------------- Makefile.mingw | 4 ++-- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 1fc6cefe..bafe2e18 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ netDb /libi2pd.so /libi2pdclient.so /libi2pdlang.so +/libi2pd.dll +/libi2pdclient.dll +/libi2pdlang.dll *.exe diff --git a/Makefile b/Makefile index abea5fd7..1db11c21 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,20 @@ SYS := $(shell $(CXX) -dumpmachine) -SHLIB := libi2pd.so + +ifneq (, $(findstring darwin, $(SYS))) + SHARED_PREFIX = dylib +else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) + SHARED_PREFIX = dll +else + SHARED_PREFIX = so +endif + +SHLIB := libi2pd.$(SHARED_PREFIX) ARLIB := libi2pd.a -SHLIB_LANG := libi2pdlang.so +SHLIB_LANG := libi2pdlang.$(SHARED_PREFIX) ARLIB_LANG := libi2pdlang.a -SHLIB_CLIENT := libi2pdclient.so +SHLIB_CLIENT := libi2pdclient.$(SHARED_PREFIX) ARLIB_CLIENT := libi2pdclient.a -SHLIB_WRAP := libi2pdwrapper.so +SHLIB_WRAP := libi2pdwrapper.$(SHARED_PREFIX) ARLIB_WRAP := libi2pdwrapper.a I2PD := i2pd @@ -64,22 +73,18 @@ LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) -all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD) +## Build all code (libi2pd, libi2pdclient, libi2pdlang), link code to .a and .so (.dll on windows) and build binary +## Windows binary is not depending on output dlls +all: | api_client $(I2PD) mk_obj_dir: - @mkdir -p obj - @mkdir -p obj/Win32 - @mkdir -p obj/$(LIB_SRC_DIR) - @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) - @mkdir -p obj/$(LANG_SRC_DIR) - @mkdir -p obj/$(WRAP_SRC_DIR) - @mkdir -p obj/$(DAEMON_SRC_DIR) + @mkdir -p obj/{Win32,$(LIB_SRC_DIR),$(LIB_CLIENT_SRC_DIR),$(LANG_SRC_DIR),$(WRAP_SRC_DIR),$(DAEMON_SRC_DIR)} -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) -wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) -lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api: | mk_obj_dir $(SHLIB) $(ARLIB) +client: | mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: | mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api_client: | api client lang +wrapper: | mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time @@ -98,14 +103,14 @@ obj/%.o: %.cpp $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) -$(SHLIB): $(LIB_OBJS) +$(SHLIB): $(LIB_OBJS) $(SHLIB_LANG) ifneq ($(USE_STATIC),yes) - $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB_LANG) endif -$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) $(SHLIB) $(SHLIB_LANG) ifneq ($(USE_STATIC),yes) - $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(SHLIB_LANG) endif $(SHLIB_WRAP): $(WRAP_LIB_OBJS) @@ -118,7 +123,7 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(ARLIB): $(LIB_OBJS) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) diff --git a/Makefile.mingw b/Makefile.mingw index ce1966a1..b57860b4 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -3,9 +3,9 @@ USE_WIN32_APP := yes WINDRES = windres -CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32_LEAN_AND_MEAN -fPIC -msse +CXXFLAGS := $(CXX_DEBUG) -DWIN32_LEAN_AND_MEAN -fPIC -msse INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32 -LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc +LDFLAGS := ${LD_DEBUG} -static # detect proper flag for c++11 support by compilers CXXVER := $(shell $(CXX) -dumpversion) From dc9e5dc2f1479c519db5bab16a9258d025e8f99c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Aug 2021 20:51:25 +0300 Subject: [PATCH 0267/2193] [makefile] suffix, not prefix Signed-off-by: R4SAS --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1db11c21..328214cd 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,20 @@ SYS := $(shell $(CXX) -dumpmachine) ifneq (, $(findstring darwin, $(SYS))) - SHARED_PREFIX = dylib + SHARED_SUFFIX = dylib else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) - SHARED_PREFIX = dll + SHARED_SUFFIX = dll else - SHARED_PREFIX = so + SHARED_SUFFIX = so endif -SHLIB := libi2pd.$(SHARED_PREFIX) +SHLIB := libi2pd.$(SHARED_SUFFIX) ARLIB := libi2pd.a -SHLIB_LANG := libi2pdlang.$(SHARED_PREFIX) +SHLIB_LANG := libi2pdlang.$(SHARED_SUFFIX) ARLIB_LANG := libi2pdlang.a -SHLIB_CLIENT := libi2pdclient.$(SHARED_PREFIX) +SHLIB_CLIENT := libi2pdclient.$(SHARED_SUFFIX) ARLIB_CLIENT := libi2pdclient.a -SHLIB_WRAP := libi2pdwrapper.$(SHARED_PREFIX) +SHLIB_WRAP := libi2pdwrapper.$(SHARED_SUFFIX) ARLIB_WRAP := libi2pdwrapper.a I2PD := i2pd From 2f945a4fce3fafa3dc34abccf9e08c059026331d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 6 Aug 2021 21:27:37 +0300 Subject: [PATCH 0268/2193] [makefile] dont build .so and .dll on default target Signed-off-by: R4SAS --- Makefile | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 328214cd..a4b3c3fa 100644 --- a/Makefile +++ b/Makefile @@ -73,19 +73,17 @@ LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) -## Build all code (libi2pd, libi2pdclient, libi2pdlang), link code to .a and .so (.dll on windows) and build binary -## Windows binary is not depending on output dlls -all: | api_client $(I2PD) +## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary +all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD) mk_obj_dir: @mkdir -p obj/{Win32,$(LIB_SRC_DIR),$(LIB_CLIENT_SRC_DIR),$(LANG_SRC_DIR),$(WRAP_SRC_DIR),$(DAEMON_SRC_DIR)} -api: | mk_obj_dir $(SHLIB) $(ARLIB) -client: | mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -lang: | mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) -api_client: | api client lang -wrapper: | mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) - +api: mk_obj_dir $(SHLIB) $(ARLIB) +client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api_client: api client lang +wrapper: mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -138,7 +136,7 @@ $(ARLIB_LANG): $(LANG_OBJS) clean: $(RM) -r obj $(RM) -r docs/generated - $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) + $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) $(SHLIB_LANG) $(ARLIB_LANG) $(SHLIB_WRAP) $(ARLIB_WRAP) strip: $(I2PD) $(SHLIB) $(SHLIB_CLIENT) $(SHLIB_LANG) strip $^ From a3b172bbcbdd279514e37c78ad6d8a67e315eda2 Mon Sep 17 00:00:00 2001 From: r4sas Date: Fri, 6 Aug 2021 22:18:02 +0200 Subject: [PATCH 0269/2193] [makefile] change back directories creation, create them before compiling object files --- Makefile | 25 +++++++++++++++---------- build/.gitignore | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index a4b3c3fa..d7765af7 100644 --- a/Makefile +++ b/Makefile @@ -68,22 +68,27 @@ NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SR LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) -WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC)) LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC)) DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) -DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) +WRAP_LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(WRAP_LIB_SRC)) +DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) $(WRAP_LIB_OBJS:.o=.d) ## Build all code (libi2pd, libi2pdclient, libi2pdlang), link it to .a and build binary -all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD) +all: $(ARLIB) $(ARLIB_CLIENT) $(ARLIB_LANG) $(I2PD) mk_obj_dir: - @mkdir -p obj/{Win32,$(LIB_SRC_DIR),$(LIB_CLIENT_SRC_DIR),$(LANG_SRC_DIR),$(WRAP_SRC_DIR),$(DAEMON_SRC_DIR)} + @mkdir -p obj/$(LIB_SRC_DIR) + @mkdir -p obj/$(LIB_CLIENT_SRC_DIR) + @mkdir -p obj/$(LANG_SRC_DIR) + @mkdir -p obj/$(DAEMON_SRC_DIR) + @mkdir -p obj/$(WRAP_SRC_DIR) + @mkdir -p obj/Win32 -api: mk_obj_dir $(SHLIB) $(ARLIB) -client: mk_obj_dir $(SHLIB_CLIENT) $(ARLIB_CLIENT) -lang: mk_obj_dir $(SHLIB_LANG) $(ARLIB_LANG) +api: $(SHLIB) $(ARLIB) +client: $(SHLIB_CLIENT) $(ARLIB_CLIENT) +lang: $(SHLIB_LANG) $(ARLIB_LANG) api_client: api client lang -wrapper: mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) +wrapper: api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## NOTE: The NEEDED_CXXFLAGS are here so that CXXFLAGS can be specified at build time ## **without** overwriting the CXXFLAGS which we need in order to build. @@ -92,7 +97,7 @@ wrapper: mk_obj_dir api_client $(SHLIB_WRAP) $(ARLIB_WRAP) ## -std=c++11. If you want to remove this variable please do so in a way that allows setting ## custom FLAGS to work at build-time. -obj/%.o: %.cpp +obj/%.o: %.cpp | mk_obj_dir $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< # '-' is 'ignore if missing' on first run @@ -121,7 +126,7 @@ ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(ARLIB): $(LIB_OBJS) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ $(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) diff --git a/build/.gitignore b/build/.gitignore index b595141b..872332c5 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -3,6 +3,7 @@ /i2pd /libi2pd.a /libi2pdclient.a +/libi2pdlang.a /cmake_install.cmake /CMakeCache.txt /CPackConfig.cmake @@ -11,4 +12,4 @@ /arch.c # windows build script i2pd*.zip -build*.log \ No newline at end of file +build*.log From fcbc16f2fd8e34734cfda6c8fd3ba635863fcce9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Aug 2021 01:37:45 +0300 Subject: [PATCH 0270/2193] [webconsole] fix style issues, clean external style in file was not found on reload Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 5c6a3cd8..ac83f87c 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -66,7 +66,7 @@ namespace http { " a, .slide label { text-decoration: none; color: #894C84; }\r\n" " a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n" " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" - " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n" + " padding: 0 5px; border: 1px solid #894C84; }\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" " .wrapper { margin: 0 auto; padding: 1em; max-width: 64em; }\r\n" " .menu { display: block; float: left; overflow: hidden; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; }\r\n" @@ -97,7 +97,7 @@ namespace http { " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n" " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n" - " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" + " margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n" " input, select { width: 35%; text-align: center; padding: 5px;\r\n" " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n" " table.extaddr { margin: auto; text-align: unset; }\r\n" @@ -119,6 +119,8 @@ namespace http { std::ifstream f(styleFile, std::ifstream::binary); s << f.rdbuf(); externalCSS = s.str(); + } else if (externalCSS.length() != 0) { // clean up external style if file was removed + externalCSS = ""; } } From bef8587d8fa6684575939d8a2ed5f042aff1a935 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Aug 2021 01:38:35 +0300 Subject: [PATCH 0271/2193] [makefile] create object dirs on windres (race condition) Signed-off-by: R4SAS --- Makefile.mingw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.mingw b/Makefile.mingw index b57860b4..e31d895e 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -61,5 +61,5 @@ ifeq ($(USE_ASLR),yes) LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols endif -obj/%.o : %.rc +obj/%.o : %.rc | mk_obj_dir $(WINDRES) -i $< -o $@ From ba369d9b3064eaf01a4b9bf523fa680928e7cafa Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Aug 2021 17:31:26 +0300 Subject: [PATCH 0272/2193] [webconsole] fix style in css Signed-off-by: R4SAS --- contrib/webconsole/style.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index b6e56477..047839a6 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -21,7 +21,6 @@ a.button { -moz-appearance: button; appearance: button; text-decoration: none; - color: initial; padding: 0 5px; border: 1px solid #894C84; } @@ -198,7 +197,6 @@ textarea { -moz-appearance: button; appearance: button; text-decoration: none; - color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; From d124d4caceb17a0fb212b79ab258d90184b893c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Aug 2021 11:36:12 -0400 Subject: [PATCH 0273/2193] allow ipv6 adresses for UDP server tunnels --- libi2pd_client/ClientContext.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index f8bc5667..6e9ac391 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -720,9 +720,15 @@ namespace client { // udp server tunnel // TODO: hostnames - if (address.empty ()) address = "127.0.0.1"; - auto localAddress = boost::asio::ip::address::from_string(address); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); + if (address.empty ()) + { + if (!endpoint.address ().is_unspecified () && endpoint.address ().is_v6 ()) + address = "::1"; + else + address = "127.0.0.1"; + } + auto localAddress = boost::asio::ip::address::from_string(address); auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); if(!isUniqueLocal) { From 49b3ac7f77431723f88bb79cf2390778ddfadac8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 Aug 2021 12:23:43 -0400 Subject: [PATCH 0274/2193] don't reschedule resend timer for terminated streams --- libi2pd/Streaming.cpp | 16 ++++++++++------ libi2pd/Streaming.h | 3 ++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index bbb649df..95f6a150 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -104,6 +104,7 @@ namespace stream void Stream::Terminate (bool deleteFromDestination) // shoudl be called from StreamingDestination::Stop only { + m_Status = eStreamStatusTerminated; m_AckSendTimer.cancel (); m_ReceiveTimer.cancel (); m_ResendTimer.cancel (); @@ -857,12 +858,15 @@ namespace stream void Stream::ScheduleResend () { - m_ResendTimer.cancel (); - // check for invalid value - if (m_RTO <= 0) m_RTO = INITIAL_RTO; - m_ResendTimer.expires_from_now (boost::posix_time::milliseconds(m_RTO)); - m_ResendTimer.async_wait (std::bind (&Stream::HandleResendTimer, - shared_from_this (), std::placeholders::_1)); + if (m_Status != eStreamStatusTerminated) + { + m_ResendTimer.cancel (); + // check for invalid value + if (m_RTO <= 0) m_RTO = INITIAL_RTO; + m_ResendTimer.expires_from_now (boost::posix_time::milliseconds(m_RTO)); + m_ResendTimer.async_wait (std::bind (&Stream::HandleResendTimer, + shared_from_this (), std::placeholders::_1)); + } } void Stream::HandleResendTimer (const boost::system::error_code& ecode) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index c40c49f5..9d206098 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -152,7 +152,8 @@ namespace stream eStreamStatusOpen, eStreamStatusReset, eStreamStatusClosing, - eStreamStatusClosed + eStreamStatusClosed, + eStreamStatusTerminated }; class StreamingDestination; From 38a2d45a3c24a3be48aee1b16ffec63500e374f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 Aug 2021 12:31:46 -0400 Subject: [PATCH 0275/2193] close all existing streams when command SAM socket got closed --- libi2pd_client/SAM.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index af9ba6a8..c2983f43 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1207,7 +1207,11 @@ namespace client void SAMSingleSession::StopLocalDestination () { localDestination->Release (); + // stop accepting new streams localDestination->StopAcceptingStreams (); + // terminate existing streams + auto s = localDestination->GetStreamingDestination (); // TODO: take care about datagrams + if (s) s->Stop (); } void SAMMasterSession::Close () From b3e7b1b5ac79e2283835a07e15efab3f9083756e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 13 Aug 2021 09:11:56 +0300 Subject: [PATCH 0276/2193] Squashed commit of the following: commit 40ec4e8b59e91efe2ef7654c8c0938facfddef1b Author: Simon Vetter Date: Fri Jul 30 21:23:27 2021 +0200 libi2pd: mark additional ipv6 addresses/nets as reserved This adds :: (undefined address), ::1 (loopback address) as well as ff00::/8 (multicast prefix) to reservedIPv6Ranges. A bunch of nodes seem to be publishing bogus addresses (mostly ::1) in the netDB, resulting in unnecessary tunnel build failures. Signed-off-by: R4SAS --- libi2pd/util.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 69fc366a..2d5617b6 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -555,7 +555,10 @@ namespace net static const std::vector< std::pair > reservedIPv6Ranges { address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"), address_pair_v6("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), - address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff") + address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("ff00::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("::", "::"), + address_pair_v6("::1", "::1") }; boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes (); From 1e17ef2f21b83a9b49fb803354b377aff6998ca1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 13 Aug 2021 09:17:27 +0300 Subject: [PATCH 0277/2193] [webconsole] show v4 status only ipv4 is enabled Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ac83f87c..d13aeb32 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -326,9 +326,12 @@ namespace http { s << "" << tr("Uptime") << ": "; ShowUptime(s, i2p::context.GetUptime ()); s << "
\r\n"; - s << "" << tr("Network status") << ": "; - ShowNetworkStatus (s, i2p::context.GetStatus ()); - s << "
\r\n"; + if (i2p::context.SupportsV4 ()) + { + s << "" << tr("Network status") << ": "; + ShowNetworkStatus (s, i2p::context.GetStatus ()); + s << "
\r\n"; + } if (i2p::context.SupportsV6 ()) { s << "" << tr("Network status v6") << ": "; From fc29911ffda418cfa94d39f16ebdc425e920032b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Aug 2021 11:36:04 -0400 Subject: [PATCH 0278/2193] rollback --- daemon/HTTPServer.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d13aeb32..ac83f87c 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -326,12 +326,9 @@ namespace http { s << "" << tr("Uptime") << ": "; ShowUptime(s, i2p::context.GetUptime ()); s << "
\r\n"; - if (i2p::context.SupportsV4 ()) - { - s << "" << tr("Network status") << ": "; - ShowNetworkStatus (s, i2p::context.GetStatus ()); - s << "
\r\n"; - } + s << "" << tr("Network status") << ": "; + ShowNetworkStatus (s, i2p::context.GetStatus ()); + s << "
\r\n"; if (i2p::context.SupportsV6 ()) { s << "" << tr("Network status v6") << ": "; From 797f5eb714a9c4accf7dce10fc865c9e3a816f2c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Aug 2021 13:31:04 -0400 Subject: [PATCH 0279/2193] select compatible resolved address for server tunnel --- libi2pd_client/I2PTunnel.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5476bfe2..378dc705 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -605,7 +605,40 @@ namespace client { if (!ecode) { - auto addr = (*it).endpoint ().address (); + bool found = false; + boost::asio::ip::tcp::resolver::iterator end; + boost::asio::ip::tcp::endpoint ep; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) + { + if (ep.address ().is_v4 ()) + { + if (!m_LocalAddress || m_LocalAddress->is_v4 ()) // look for ipv4 if not specified + found = true; + } + else if (ep.address ().is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (m_LocalAddress && i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + found = true; + } + else if (m_LocalAddress && m_LocalAddress->is_v6 ()) + found = true; + } + } + if (found) break; + it++; + } + if (!found) + { + LogPrint (eLogError, "I2PTunnel: Unable to reslove to compatible address"); + return; + } + + auto addr = ep.address (); LogPrint (eLogInfo, "I2PTunnel: server tunnel ", (*it).host_name (), " has been resolved to ", addr); m_Endpoint.address (addr); Accept (); From b0874410f1a48a158461c4971a74604b6e7a9542 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Aug 2021 13:54:23 -0400 Subject: [PATCH 0280/2193] take first avalable resolved address if local address is not specified --- libi2pd_client/I2PTunnel.cpp | 51 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 378dc705..e8a66228 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -606,35 +606,42 @@ namespace client if (!ecode) { bool found = false; - boost::asio::ip::tcp::resolver::iterator end; boost::asio::ip::tcp::endpoint ep; - while (it != end) + if (m_LocalAddress) { - ep = *it; - if (!ep.address ().is_unspecified ()) - { - if (ep.address ().is_v4 ()) - { - if (!m_LocalAddress || m_LocalAddress->is_v4 ()) // look for ipv4 if not specified - found = true; - } - else if (ep.address ().is_v6 ()) + boost::asio::ip::tcp::resolver::iterator end; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) { - if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + if (ep.address ().is_v4 ()) + { + if (m_LocalAddress->is_v4 ()) found = true; + } + else if (ep.address ().is_v6 ()) { - if (m_LocalAddress && i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + found = true; + } + else if (m_LocalAddress->is_v6 ()) found = true; - } - else if (m_LocalAddress && m_LocalAddress->is_v6 ()) - found = true; - } - } - if (found) break; - it++; - } + } + } + if (found) break; + it++; + } + } + else + { + found = true; + ep = *it; // first available + } if (!found) { - LogPrint (eLogError, "I2PTunnel: Unable to reslove to compatible address"); + LogPrint (eLogError, "I2PTunnel: Unable to resolve to compatible address"); return; } From 8c3823fc920578eb09efd330f3b33c1408ab30b7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 15 Aug 2021 16:53:10 +0300 Subject: [PATCH 0281/2193] [gha] build docker containers for arm/arm64 Signed-off-by: R4SAS --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index aced7f39..1c01d373 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -38,7 +38,7 @@ jobs: with: context: ./contrib/docker file: ./contrib/docker/Dockerfile - platforms: linux/amd64,linux/386 + platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7 push: true tags: | purplei2p/i2pd:latest @@ -54,7 +54,7 @@ jobs: with: context: ./contrib/docker file: ./contrib/docker/Dockerfile - platforms: linux/amd64,linux/386 + platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7 push: true tags: | purplei2p/i2pd:latest From 86e118f2b78d6f8ce6c1e50fe79220a546c1f27f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Aug 2021 22:23:39 +0300 Subject: [PATCH 0282/2193] [i18n] change string in HTTPProxy Signed-off-by: R4SAS --- contrib/i18n/English.po | 308 +++++++++++++++++------------------ contrib/i18n/README.md | 4 +- libi2pd_client/HTTPProxy.cpp | 6 +- 3 files changed, 157 insertions(+), 161 deletions(-) diff --git a/contrib/i18n/English.po b/contrib/i18n/English.po index 5a7cc09c..25378f82 100644 --- a/contrib/i18n/English.po +++ b/contrib/i18n/English.po @@ -18,564 +18,564 @@ msgstr "" "X-Poedit-SearchPath-0: daemon/HTTPServer.cpp\n" "X-Poedit-SearchPath-1: libi2pd_client/HTTPProxy.cpp\n" -#: daemon/HTTPServer.cpp:175 +#: daemon/HTTPServer.cpp:177 msgid "day" msgid_plural "days" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:179 +#: daemon/HTTPServer.cpp:181 msgid "hour" msgid_plural "hours" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:183 +#: daemon/HTTPServer.cpp:185 msgid "minute" msgid_plural "minutes" msgstr[0] "" msgstr[1] "" -#: daemon/HTTPServer.cpp:186 +#: daemon/HTTPServer.cpp:188 msgid "second" msgid_plural "seconds" msgstr[0] "" msgstr[1] "" #. tr: Kibibit -#: daemon/HTTPServer.cpp:194 daemon/HTTPServer.cpp:222 +#: daemon/HTTPServer.cpp:196 daemon/HTTPServer.cpp:224 msgid "KiB" msgstr "" #. tr: Mebibit -#: daemon/HTTPServer.cpp:196 +#: daemon/HTTPServer.cpp:198 msgid "MiB" msgstr "" #. tr: Gibibit -#: daemon/HTTPServer.cpp:198 +#: daemon/HTTPServer.cpp:200 msgid "GiB" msgstr "" -#: daemon/HTTPServer.cpp:215 +#: daemon/HTTPServer.cpp:217 msgid "building" msgstr "" -#: daemon/HTTPServer.cpp:216 +#: daemon/HTTPServer.cpp:218 msgid "failed" msgstr "" -#: daemon/HTTPServer.cpp:217 +#: daemon/HTTPServer.cpp:219 msgid "expiring" msgstr "" -#: daemon/HTTPServer.cpp:218 +#: daemon/HTTPServer.cpp:220 msgid "established" msgstr "" -#: daemon/HTTPServer.cpp:219 +#: daemon/HTTPServer.cpp:221 msgid "unknown" msgstr "" -#: daemon/HTTPServer.cpp:221 +#: daemon/HTTPServer.cpp:223 msgid "exploratory" msgstr "" -#: daemon/HTTPServer.cpp:257 +#: daemon/HTTPServer.cpp:259 msgid "i2pd webconsole" msgstr "" -#: daemon/HTTPServer.cpp:260 +#: daemon/HTTPServer.cpp:262 msgid "Main page" msgstr "" -#: daemon/HTTPServer.cpp:261 daemon/HTTPServer.cpp:723 +#: daemon/HTTPServer.cpp:263 daemon/HTTPServer.cpp:725 msgid "Router commands" msgstr "" -#: daemon/HTTPServer.cpp:262 daemon/HTTPServer.cpp:446 -#: daemon/HTTPServer.cpp:458 +#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:448 +#: daemon/HTTPServer.cpp:460 msgid "Local Destinations" msgstr "" -#: daemon/HTTPServer.cpp:264 daemon/HTTPServer.cpp:416 -#: daemon/HTTPServer.cpp:502 daemon/HTTPServer.cpp:508 -#: daemon/HTTPServer.cpp:639 daemon/HTTPServer.cpp:682 -#: daemon/HTTPServer.cpp:686 +#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:418 +#: daemon/HTTPServer.cpp:504 daemon/HTTPServer.cpp:510 +#: daemon/HTTPServer.cpp:641 daemon/HTTPServer.cpp:684 +#: daemon/HTTPServer.cpp:688 msgid "LeaseSets" msgstr "" -#: daemon/HTTPServer.cpp:266 daemon/HTTPServer.cpp:692 +#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:694 msgid "Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:267 daemon/HTTPServer.cpp:423 -#: daemon/HTTPServer.cpp:785 daemon/HTTPServer.cpp:801 +#: daemon/HTTPServer.cpp:269 daemon/HTTPServer.cpp:425 +#: daemon/HTTPServer.cpp:787 daemon/HTTPServer.cpp:803 msgid "Transit Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:268 daemon/HTTPServer.cpp:850 +#: daemon/HTTPServer.cpp:270 daemon/HTTPServer.cpp:852 msgid "Transports" msgstr "" -#: daemon/HTTPServer.cpp:269 +#: daemon/HTTPServer.cpp:271 msgid "I2P tunnels" msgstr "" -#: daemon/HTTPServer.cpp:271 daemon/HTTPServer.cpp:912 -#: daemon/HTTPServer.cpp:922 +#: daemon/HTTPServer.cpp:273 daemon/HTTPServer.cpp:914 +#: daemon/HTTPServer.cpp:924 msgid "SAM sessions" msgstr "" -#: daemon/HTTPServer.cpp:287 daemon/HTTPServer.cpp:1304 -#: daemon/HTTPServer.cpp:1307 daemon/HTTPServer.cpp:1310 -#: daemon/HTTPServer.cpp:1324 daemon/HTTPServer.cpp:1369 -#: daemon/HTTPServer.cpp:1372 daemon/HTTPServer.cpp:1375 +#: daemon/HTTPServer.cpp:289 daemon/HTTPServer.cpp:1306 +#: daemon/HTTPServer.cpp:1309 daemon/HTTPServer.cpp:1312 +#: daemon/HTTPServer.cpp:1326 daemon/HTTPServer.cpp:1371 +#: daemon/HTTPServer.cpp:1374 daemon/HTTPServer.cpp:1377 msgid "ERROR" msgstr "" -#: daemon/HTTPServer.cpp:294 +#: daemon/HTTPServer.cpp:296 msgid "OK" msgstr "" -#: daemon/HTTPServer.cpp:295 +#: daemon/HTTPServer.cpp:297 msgid "Testing" msgstr "" -#: daemon/HTTPServer.cpp:296 +#: daemon/HTTPServer.cpp:298 msgid "Firewalled" msgstr "" -#: daemon/HTTPServer.cpp:297 daemon/HTTPServer.cpp:318 -#: daemon/HTTPServer.cpp:404 +#: daemon/HTTPServer.cpp:299 daemon/HTTPServer.cpp:320 +#: daemon/HTTPServer.cpp:406 msgid "Unknown" msgstr "" -#: daemon/HTTPServer.cpp:298 daemon/HTTPServer.cpp:433 -#: daemon/HTTPServer.cpp:434 daemon/HTTPServer.cpp:980 -#: daemon/HTTPServer.cpp:989 +#: daemon/HTTPServer.cpp:300 daemon/HTTPServer.cpp:435 +#: daemon/HTTPServer.cpp:436 daemon/HTTPServer.cpp:982 +#: daemon/HTTPServer.cpp:991 msgid "Proxy" msgstr "" -#: daemon/HTTPServer.cpp:299 +#: daemon/HTTPServer.cpp:301 msgid "Mesh" msgstr "" -#: daemon/HTTPServer.cpp:302 +#: daemon/HTTPServer.cpp:304 msgid "Error" msgstr "" -#: daemon/HTTPServer.cpp:306 +#: daemon/HTTPServer.cpp:308 msgid "Clock skew" msgstr "" -#: daemon/HTTPServer.cpp:309 +#: daemon/HTTPServer.cpp:311 msgid "Offline" msgstr "" -#: daemon/HTTPServer.cpp:312 +#: daemon/HTTPServer.cpp:314 msgid "Symmetric NAT" msgstr "" -#: daemon/HTTPServer.cpp:324 +#: daemon/HTTPServer.cpp:326 msgid "Uptime" msgstr "" -#: daemon/HTTPServer.cpp:327 +#: daemon/HTTPServer.cpp:329 msgid "Network status" msgstr "" -#: daemon/HTTPServer.cpp:332 +#: daemon/HTTPServer.cpp:334 msgid "Network status v6" msgstr "" -#: daemon/HTTPServer.cpp:338 daemon/HTTPServer.cpp:345 +#: daemon/HTTPServer.cpp:340 daemon/HTTPServer.cpp:347 msgid "Stopping in" msgstr "" -#: daemon/HTTPServer.cpp:352 +#: daemon/HTTPServer.cpp:354 msgid "Family" msgstr "" -#: daemon/HTTPServer.cpp:353 +#: daemon/HTTPServer.cpp:355 msgid "Tunnel creation success rate" msgstr "" -#: daemon/HTTPServer.cpp:354 +#: daemon/HTTPServer.cpp:356 msgid "Received" msgstr "" #. tr: Kibibit/s -#: daemon/HTTPServer.cpp:356 daemon/HTTPServer.cpp:359 -#: daemon/HTTPServer.cpp:362 +#: daemon/HTTPServer.cpp:358 daemon/HTTPServer.cpp:361 +#: daemon/HTTPServer.cpp:364 msgid "KiB/s" msgstr "" -#: daemon/HTTPServer.cpp:357 +#: daemon/HTTPServer.cpp:359 msgid "Sent" msgstr "" -#: daemon/HTTPServer.cpp:360 +#: daemon/HTTPServer.cpp:362 msgid "Transit" msgstr "" -#: daemon/HTTPServer.cpp:363 +#: daemon/HTTPServer.cpp:365 msgid "Data path" msgstr "" -#: daemon/HTTPServer.cpp:366 +#: daemon/HTTPServer.cpp:368 msgid "Hidden content. Press on text to see." msgstr "" -#: daemon/HTTPServer.cpp:369 +#: daemon/HTTPServer.cpp:371 msgid "Router Ident" msgstr "" -#: daemon/HTTPServer.cpp:371 +#: daemon/HTTPServer.cpp:373 msgid "Router Family" msgstr "" -#: daemon/HTTPServer.cpp:372 +#: daemon/HTTPServer.cpp:374 msgid "Router Caps" msgstr "" -#: daemon/HTTPServer.cpp:373 +#: daemon/HTTPServer.cpp:375 msgid "Version" msgstr "" -#: daemon/HTTPServer.cpp:374 +#: daemon/HTTPServer.cpp:376 msgid "Our external address" msgstr "" -#: daemon/HTTPServer.cpp:382 +#: daemon/HTTPServer.cpp:384 msgid "supported" msgstr "" -#: daemon/HTTPServer.cpp:414 +#: daemon/HTTPServer.cpp:416 msgid "Routers" msgstr "" -#: daemon/HTTPServer.cpp:415 +#: daemon/HTTPServer.cpp:417 msgid "Floodfills" msgstr "" -#: daemon/HTTPServer.cpp:422 daemon/HTTPServer.cpp:966 +#: daemon/HTTPServer.cpp:424 daemon/HTTPServer.cpp:968 msgid "Client Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:432 +#: daemon/HTTPServer.cpp:434 msgid "Services" msgstr "" -#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 #: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 #: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +#: daemon/HTTPServer.cpp:439 daemon/HTTPServer.cpp:440 msgid "Enabled" msgstr "" -#: daemon/HTTPServer.cpp:433 daemon/HTTPServer.cpp:434 #: daemon/HTTPServer.cpp:435 daemon/HTTPServer.cpp:436 #: daemon/HTTPServer.cpp:437 daemon/HTTPServer.cpp:438 +#: daemon/HTTPServer.cpp:439 daemon/HTTPServer.cpp:440 msgid "Disabled" msgstr "" -#: daemon/HTTPServer.cpp:481 +#: daemon/HTTPServer.cpp:483 msgid "Encrypted B33 address" msgstr "" -#: daemon/HTTPServer.cpp:490 +#: daemon/HTTPServer.cpp:492 msgid "Address registration line" msgstr "" -#: daemon/HTTPServer.cpp:495 +#: daemon/HTTPServer.cpp:497 msgid "Domain" msgstr "" -#: daemon/HTTPServer.cpp:496 +#: daemon/HTTPServer.cpp:498 msgid "Generate" msgstr "" -#: daemon/HTTPServer.cpp:497 +#: daemon/HTTPServer.cpp:499 msgid "" "Note: result string can be used only for registering 2LD domains " "(example.i2p). For registering subdomains please use i2pd-tools." msgstr "" -#: daemon/HTTPServer.cpp:503 +#: daemon/HTTPServer.cpp:505 msgid "Address" msgstr "" -#: daemon/HTTPServer.cpp:503 +#: daemon/HTTPServer.cpp:505 msgid "Type" msgstr "" -#: daemon/HTTPServer.cpp:503 +#: daemon/HTTPServer.cpp:505 msgid "EncType" msgstr "" -#: daemon/HTTPServer.cpp:513 daemon/HTTPServer.cpp:697 +#: daemon/HTTPServer.cpp:515 daemon/HTTPServer.cpp:699 msgid "Inbound tunnels" msgstr "" #. tr: Milliseconds -#: daemon/HTTPServer.cpp:518 daemon/HTTPServer.cpp:528 -#: daemon/HTTPServer.cpp:702 daemon/HTTPServer.cpp:712 +#: daemon/HTTPServer.cpp:520 daemon/HTTPServer.cpp:530 +#: daemon/HTTPServer.cpp:704 daemon/HTTPServer.cpp:714 msgid "ms" msgstr "" -#: daemon/HTTPServer.cpp:523 daemon/HTTPServer.cpp:707 +#: daemon/HTTPServer.cpp:525 daemon/HTTPServer.cpp:709 msgid "Outbound tunnels" msgstr "" -#: daemon/HTTPServer.cpp:535 +#: daemon/HTTPServer.cpp:537 msgid "Tags" msgstr "" -#: daemon/HTTPServer.cpp:535 +#: daemon/HTTPServer.cpp:537 msgid "Incoming" msgstr "" -#: daemon/HTTPServer.cpp:542 daemon/HTTPServer.cpp:545 +#: daemon/HTTPServer.cpp:544 daemon/HTTPServer.cpp:547 msgid "Outgoing" msgstr "" -#: daemon/HTTPServer.cpp:543 daemon/HTTPServer.cpp:559 +#: daemon/HTTPServer.cpp:545 daemon/HTTPServer.cpp:561 msgid "Destination" msgstr "" -#: daemon/HTTPServer.cpp:543 +#: daemon/HTTPServer.cpp:545 msgid "Amount" msgstr "" -#: daemon/HTTPServer.cpp:550 +#: daemon/HTTPServer.cpp:552 msgid "Incoming Tags" msgstr "" -#: daemon/HTTPServer.cpp:558 daemon/HTTPServer.cpp:561 +#: daemon/HTTPServer.cpp:560 daemon/HTTPServer.cpp:563 msgid "Tags sessions" msgstr "" -#: daemon/HTTPServer.cpp:559 +#: daemon/HTTPServer.cpp:561 msgid "Status" msgstr "" -#: daemon/HTTPServer.cpp:568 daemon/HTTPServer.cpp:624 +#: daemon/HTTPServer.cpp:570 daemon/HTTPServer.cpp:626 msgid "Local Destination" msgstr "" -#: daemon/HTTPServer.cpp:578 daemon/HTTPServer.cpp:945 +#: daemon/HTTPServer.cpp:580 daemon/HTTPServer.cpp:947 msgid "Streams" msgstr "" -#: daemon/HTTPServer.cpp:600 +#: daemon/HTTPServer.cpp:602 msgid "Close stream" msgstr "" -#: daemon/HTTPServer.cpp:629 +#: daemon/HTTPServer.cpp:631 msgid "I2CP session not found" msgstr "" -#: daemon/HTTPServer.cpp:632 +#: daemon/HTTPServer.cpp:634 msgid "I2CP is not enabled" msgstr "" -#: daemon/HTTPServer.cpp:658 +#: daemon/HTTPServer.cpp:660 msgid "Invalid" msgstr "" -#: daemon/HTTPServer.cpp:661 +#: daemon/HTTPServer.cpp:663 msgid "Store type" msgstr "" -#: daemon/HTTPServer.cpp:662 +#: daemon/HTTPServer.cpp:664 msgid "Expires" msgstr "" -#: daemon/HTTPServer.cpp:667 +#: daemon/HTTPServer.cpp:669 msgid "Non Expired Leases" msgstr "" -#: daemon/HTTPServer.cpp:670 +#: daemon/HTTPServer.cpp:672 msgid "Gateway" msgstr "" -#: daemon/HTTPServer.cpp:671 +#: daemon/HTTPServer.cpp:673 msgid "TunnelID" msgstr "" -#: daemon/HTTPServer.cpp:672 +#: daemon/HTTPServer.cpp:674 msgid "EndDate" msgstr "" -#: daemon/HTTPServer.cpp:682 +#: daemon/HTTPServer.cpp:684 msgid "not floodfill" msgstr "" -#: daemon/HTTPServer.cpp:693 +#: daemon/HTTPServer.cpp:695 msgid "Queue size" msgstr "" -#: daemon/HTTPServer.cpp:724 +#: daemon/HTTPServer.cpp:726 msgid "Run peer test" msgstr "" -#: daemon/HTTPServer.cpp:729 +#: daemon/HTTPServer.cpp:731 msgid "Decline transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:731 +#: daemon/HTTPServer.cpp:733 msgid "Accept transit tunnels" msgstr "" -#: daemon/HTTPServer.cpp:735 daemon/HTTPServer.cpp:740 +#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742 msgid "Cancel graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:737 daemon/HTTPServer.cpp:742 +#: daemon/HTTPServer.cpp:739 daemon/HTTPServer.cpp:744 msgid "Start graceful shutdown" msgstr "" -#: daemon/HTTPServer.cpp:745 +#: daemon/HTTPServer.cpp:747 msgid "Force shutdown" msgstr "" -#: daemon/HTTPServer.cpp:746 +#: daemon/HTTPServer.cpp:748 msgid "Reload external CSS styles" msgstr "" -#: daemon/HTTPServer.cpp:749 +#: daemon/HTTPServer.cpp:751 msgid "" "Note: any action done here are not persistent and not changes your " "config files." msgstr "" -#: daemon/HTTPServer.cpp:751 +#: daemon/HTTPServer.cpp:753 msgid "Logging level" msgstr "" -#: daemon/HTTPServer.cpp:759 +#: daemon/HTTPServer.cpp:761 msgid "Transit tunnels limit" msgstr "" -#: daemon/HTTPServer.cpp:764 daemon/HTTPServer.cpp:776 +#: daemon/HTTPServer.cpp:766 daemon/HTTPServer.cpp:778 msgid "Change" msgstr "" -#: daemon/HTTPServer.cpp:768 +#: daemon/HTTPServer.cpp:770 msgid "Change language" msgstr "" -#: daemon/HTTPServer.cpp:801 +#: daemon/HTTPServer.cpp:803 msgid "no transit tunnels currently built" msgstr "" -#: daemon/HTTPServer.cpp:906 daemon/HTTPServer.cpp:929 +#: daemon/HTTPServer.cpp:908 daemon/HTTPServer.cpp:931 msgid "SAM disabled" msgstr "" -#: daemon/HTTPServer.cpp:922 +#: daemon/HTTPServer.cpp:924 msgid "no sessions currently running" msgstr "" -#: daemon/HTTPServer.cpp:935 +#: daemon/HTTPServer.cpp:937 msgid "SAM session not found" msgstr "" -#: daemon/HTTPServer.cpp:940 +#: daemon/HTTPServer.cpp:942 msgid "SAM Session" msgstr "" -#: daemon/HTTPServer.cpp:997 +#: daemon/HTTPServer.cpp:999 msgid "Server Tunnels" msgstr "" -#: daemon/HTTPServer.cpp:1013 +#: daemon/HTTPServer.cpp:1015 msgid "Client Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1027 +#: daemon/HTTPServer.cpp:1029 msgid "Server Forwards" msgstr "" -#: daemon/HTTPServer.cpp:1225 +#: daemon/HTTPServer.cpp:1227 msgid "Unknown page" msgstr "" -#: daemon/HTTPServer.cpp:1244 +#: daemon/HTTPServer.cpp:1246 msgid "Invalid token" msgstr "" -#: daemon/HTTPServer.cpp:1302 daemon/HTTPServer.cpp:1359 -#: daemon/HTTPServer.cpp:1399 +#: daemon/HTTPServer.cpp:1304 daemon/HTTPServer.cpp:1361 +#: daemon/HTTPServer.cpp:1401 msgid "SUCCESS" msgstr "" -#: daemon/HTTPServer.cpp:1302 +#: daemon/HTTPServer.cpp:1304 msgid "Stream closed" msgstr "" -#: daemon/HTTPServer.cpp:1304 +#: daemon/HTTPServer.cpp:1306 msgid "Stream not found or already was closed" msgstr "" -#: daemon/HTTPServer.cpp:1307 +#: daemon/HTTPServer.cpp:1309 msgid "Destination not found" msgstr "" -#: daemon/HTTPServer.cpp:1310 +#: daemon/HTTPServer.cpp:1312 msgid "StreamID can't be null" msgstr "" -#: daemon/HTTPServer.cpp:1312 daemon/HTTPServer.cpp:1377 +#: daemon/HTTPServer.cpp:1314 daemon/HTTPServer.cpp:1379 msgid "Return to destination page" msgstr "" -#: daemon/HTTPServer.cpp:1313 daemon/HTTPServer.cpp:1326 -#: daemon/HTTPServer.cpp:1401 +#: daemon/HTTPServer.cpp:1315 daemon/HTTPServer.cpp:1328 +#: daemon/HTTPServer.cpp:1403 msgid "You will be redirected in 5 seconds" msgstr "" -#: daemon/HTTPServer.cpp:1324 +#: daemon/HTTPServer.cpp:1326 msgid "Transit tunnels count must not exceed 65535" msgstr "" -#: daemon/HTTPServer.cpp:1325 daemon/HTTPServer.cpp:1400 +#: daemon/HTTPServer.cpp:1327 daemon/HTTPServer.cpp:1402 msgid "Back to commands list" msgstr "" -#: daemon/HTTPServer.cpp:1361 +#: daemon/HTTPServer.cpp:1363 msgid "Register at reg.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1362 +#: daemon/HTTPServer.cpp:1364 msgid "Description" msgstr "" -#: daemon/HTTPServer.cpp:1362 +#: daemon/HTTPServer.cpp:1364 msgid "A bit information about service on domain" msgstr "" -#: daemon/HTTPServer.cpp:1363 +#: daemon/HTTPServer.cpp:1365 msgid "Submit" msgstr "" -#: daemon/HTTPServer.cpp:1369 +#: daemon/HTTPServer.cpp:1371 msgid "Domain can't end with .b32.i2p" msgstr "" -#: daemon/HTTPServer.cpp:1372 +#: daemon/HTTPServer.cpp:1374 msgid "Domain must end with .i2p" msgstr "" -#: daemon/HTTPServer.cpp:1375 +#: daemon/HTTPServer.cpp:1377 msgid "Such destination is not found" msgstr "" -#: daemon/HTTPServer.cpp:1395 +#: daemon/HTTPServer.cpp:1397 msgid "Unknown command" msgstr "" -#: daemon/HTTPServer.cpp:1399 +#: daemon/HTTPServer.cpp:1401 msgid "Command accepted" msgstr "" @@ -621,16 +621,12 @@ msgstr "" msgid "added to router's addressbook from helper" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:307 -msgid "Click" +#: libi2pd_client/HTTPProxy.cpp:298 +msgid "Click here to proceed:" msgstr "" #: libi2pd_client/HTTPProxy.cpp:298 libi2pd_client/HTTPProxy.cpp:308 -msgid "here" -msgstr "" - -#: libi2pd_client/HTTPProxy.cpp:298 -msgid "to proceed" +msgid "Continue" msgstr "" #: libi2pd_client/HTTPProxy.cpp:299 libi2pd_client/HTTPProxy.cpp:309 @@ -641,8 +637,8 @@ msgstr "" msgid "already in router's addressbook" msgstr "" -#: libi2pd_client/HTTPProxy.cpp:308 -msgid "to update record" +#: libi2pd_client/HTTPProxy.cpp:307 +msgid "Click here to update record:" msgstr "" #: libi2pd_client/HTTPProxy.cpp:322 diff --git a/contrib/i18n/README.md b/contrib/i18n/README.md index be44e87f..04779473 100644 --- a/contrib/i18n/README.md +++ b/contrib/i18n/README.md @@ -1,12 +1,12 @@ `xgettext` command for extracting translation -=== +--- ``` xgettext --omit-header -ctr: -ktr -ktr:1,2 daemon/HTTPServer.cpp libi2pd_client/HTTPProxy.cpp ``` Regex for transforming gettext translations to our format: -=== +--- ``` in: msgid\ \"(.*)\"\nmsgid_plural\ \"(.*)\"\nmsgstr\[0\]\ \"(.*)\"\nmsgstr\[1\]\ \"(.*)\"\n(msgstr\[2\]\ \"(.*)\"\n)?(msgstr\[3\]\ \"(.*)\"\n)?(msgstr\[4\]\ \"(.*)\"\n)?(msgstr\[5\]\ \"(.*)\"\n)? diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 70cf78a8..7acdc333 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -295,7 +295,7 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". "; - ss << tr("Click") << " " << tr("here") << " " << tr("to proceed") << "."; + ss << tr("Click here to proceed:") << " " << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } @@ -304,8 +304,8 @@ namespace proxy { std::string full_url = m_RequestURL.to_string(); std::stringstream ss; ss << tr("Host") << " " << m_RequestURL.host << " " << tr("already in router's addressbook") << ". "; - ss << tr("Click") << " " << tr("here") << " " << tr("to update record") << "."; + ss << tr("Click here to update record:") << " " << tr("Continue") << "."; GenericProxyInfo(tr("Addresshelper found"), ss.str()); return true; /* request processed */ } From 8943d212ee16f297f2bb09789f6fd22e9f299d67 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Aug 2021 22:55:14 +0300 Subject: [PATCH 0283/2193] [i18n] add Uzbek translation (partial) Signed-off-by: R4SAS --- i18n/Afrikaans.cpp | 11 ++- i18n/I18N_langs.h | 1 + i18n/Russian.cpp | 7 +- i18n/Turkmen.cpp | 7 +- i18n/Ukrainian.cpp | 7 +- i18n/Uzbek.cpp | 206 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 224 insertions(+), 15 deletions(-) create mode 100644 i18n/Uzbek.cpp diff --git a/i18n/Afrikaans.cpp b/i18n/Afrikaans.cpp index 96ee52ee..5860facf 100644 --- a/i18n/Afrikaans.cpp +++ b/i18n/Afrikaans.cpp @@ -31,12 +31,9 @@ namespace afrikaans // language namespace static std::map strings { - {"Disabled", "Gedeaktiveer"}, - {"Enabled", "Geaktiveer"}, {"failed", "Het misluk"}, {"unknown", "onbekend"}, {"Tunnels", "Tonnels"}, - {"Transit tunnels", "Deurgang tonnels"}, {"I2P tunnels", "I2P tonnels"}, {"SAM sessions", "SAM sessies"}, {"OK", "LEKKER"}, @@ -54,6 +51,14 @@ namespace afrikaans // language namespace {"Hidden content. Press on text to see.", "Hidden content. Druk om te sien."}, {"Router Ident", "Router Ident"}, {"Router Family", "Router Familie"}, + {"Enabled", "Geaktiveer"}, + {"Disabled", "Gedeaktiveer"}, + {"Change", "Verander"}, + {"Change language", "Verander taal"}, + {"Description", "Beskrywing"}, + {"Submit", "Stuur"}, + {"Proxy error", "Proxy-fout"}, + {"Host", "Gasheer"}, {"", ""}, }; diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index a5029782..957d550d 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -87,6 +87,7 @@ namespace i18n { "russian", {"русский язык", "ru", i2p::i18n::russian::GetLocale} }, { "turkmen", {"türkmen dili", "tk", i2p::i18n::turkmen::GetLocale} }, { "ukrainian", {"украї́нська мо́ва", "uk", i2p::i18n::ukrainian::GetLocale} }, + { "uzbek", {"Oʻzbek", "uz", i2p::i18n::uzbek::GetLocale} }, }; } // i18n diff --git a/i18n/Russian.cpp b/i18n/Russian.cpp index a826cdda..f6a19c7c 100644 --- a/i18n/Russian.cpp +++ b/i18n/Russian.cpp @@ -168,12 +168,11 @@ namespace russian // language namespace {"addresshelper is not supported", "addresshelper не поддерживается"}, {"Host", "Узел"}, {"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"}, - {"Click", "Нажмите"}, - {"here", "здесь"}, - {"to proceed", "чтобы продолжить"}, + {"Click here to proceed:", "Нажмите здесь, чтобы продолжить:"}, + {"Continue", "Продолжить"}, {"Addresshelper found", "Найден addresshelper"}, {"already in router's addressbook", "уже в адресной книге роутера"}, - {"to update record", "чтобы обновить запись"}, + {"Click here to update record:", "Нажмите здесь, чтобы обновить запись:"}, {"invalid request uri", "некорректный URI запроса"}, {"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"}, {"Outproxy failure", "Ошибка внешнего прокси"}, diff --git a/i18n/Turkmen.cpp b/i18n/Turkmen.cpp index 2bcd77cd..1d4f5ee1 100644 --- a/i18n/Turkmen.cpp +++ b/i18n/Turkmen.cpp @@ -168,12 +168,11 @@ namespace turkmen // language namespace {"addresshelper is not supported", "Salgylandyryjy goldanok"}, {"Host", "Adres"}, {"added to router's addressbook from helper", "marşruteriň adresini kömekçiden goşdy"}, - {"Click", "Basyň"}, - {"here", "bu ýerde"}, - {"to proceed", "dowam etmek"}, + {"Click here to proceed:", "Dowam etmek bu ýerde basyň:"}, + {"Continue", "Dowam et"}, {"Addresshelper found", "Forgelper tapyldy"}, {"already in router's addressbook", "marşruteriň adres kitaby"}, - {"to update record", "recordazgyny täzelemek üçin"}, + {"Click here to update record:", "Recordazgyny täzelemek üçin bu ýerde basyň:"}, {"invalid request uri", "nädogry haýyş URI"}, {"Can't detect destination host from request", "Haýyşdan barmaly ýerini tapyp bilemok"}, {"Outproxy failure", "Daşarky proksi ýalňyşlyk"}, diff --git a/i18n/Ukrainian.cpp b/i18n/Ukrainian.cpp index 413375ba..abbe8f81 100644 --- a/i18n/Ukrainian.cpp +++ b/i18n/Ukrainian.cpp @@ -168,12 +168,11 @@ namespace ukrainian // language namespace {"addresshelper is not supported", "addresshelper не підтримується"}, {"Host", "Адреса"}, {"added to router's addressbook from helper", "доданий в адресну книгу маршрутизатора через хелпер"}, - {"Click", "Натисніть"}, - {"here", "тут"}, - {"to proceed", "щоб продовжити"}, + {"Click here to proceed:", "Натисніть тут щоб продовжити:"}, + {"Continue", "Продовжити"}, {"Addresshelper found", "Знайдено addresshelper"}, {"already in router's addressbook", "вже в адресній книзі маршрутизатора"}, - {"to update record", "щоб оновити запис"}, + {"Click here to update record:", "Натисніть тут щоб оновити запис:"}, {"invalid request uri", "некоректний URI запиту"}, {"Can't detect destination host from request", "Не вдалось визначити адресу призначення з запиту"}, {"Outproxy failure", "Помилка зовнішнього проксі"}, diff --git a/i18n/Uzbek.cpp b/i18n/Uzbek.cpp new file mode 100644 index 00000000..72734b58 --- /dev/null +++ b/i18n/Uzbek.cpp @@ -0,0 +1,206 @@ +/* +* Copyright (c) 2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include +#include +#include +#include "I18N.h" + +// Ukrainian localization file + +namespace i2p +{ +namespace i18n +{ +namespace uzbek // language namespace +{ + // language name in lowercase + static std::string language = "uzbek"; + + // See for language plural forms here: + // https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html + static int plural (int n) { + return n > 1 ? 1 : 0; + } + + static std::map strings + { + {"KiB", "KiB"}, + {"MiB", "MiB"}, + {"GiB", "GiB"}, + {"building", "qurilish"}, + {"failed", "muvaffaqiyatsiz"}, + {"expiring", "muddati tugaydi"}, + {"established", "aloqa o'rnatildi"}, + {"unknown", "noma'lum"}, + {"exploratory", "tadqiqiy"}, + {"i2pd webconsole", "i2pd veb -konsoli"}, + {"Main page", "Asosiy sahifa"}, + {"Router commands", "Router buyruqlari"}, + {"LeaseSets", "LeaseSets"}, + {"Tunnels", "Tunnellar"}, + {"Transit Tunnels", "Tranzit Tunellar"}, + {"Transports", "Transportlar"}, + {"I2P tunnels", "I2P tunnellar"}, + {"SAM sessions", "SAM sessiyalari"}, + {"ERROR", "XATO"}, + {"OK", "OK"}, + {"Testing", "Testlash"}, + {"Firewalled", "Xavfsizlik devori bilan himoyalangan"}, + {"Unknown", "Notanish"}, + {"Proxy", "Proksi"}, + {"Mesh", "Mesh To'r"}, + {"Error", "Xato"}, + {"Clock skew", "Aniq vaqt emas"}, + {"Offline", "Oflayn"}, + {"Symmetric NAT", "Simmetrik NAT"}, + {"Uptime", "Ish vaqti"}, + {"Network status", "Tarmoq holati"}, + {"Network status v6", "Tarmoq holati v6"}, + {"Stopping in", "Ichida to'xtatish"}, + {"Family", "Oila"}, + {"Tunnel creation success rate", "Tunnel yaratish muvaffaqiyat darajasi"}, + {"Received", "Qabul qilindi"}, + {"KiB/s", "KiB/s"}, + {"Sent", "Yuborilgan"}, + {"Transit", "Tranzit"}, + {"Data path", "Ma'lumotlar yo'li"}, + {"Hidden content. Press on text to see.", "Yashirin tarkib. Ko'rish uchun matn ustida bosing."}, + {"Router Ident", "Router identifikatori"}, + {"Router Family", "Router Oila"}, + {"Router Caps", "Router bayroqlari"}, + {"Version", "Versiya"}, + {"Our external address", "Bizning tashqi manzilimiz"}, + {"supported", "qo'llab -quvvatlanadi"}, + {"Routers", "Routerlar"}, + {"Floodfills", "Floodfills"}, + {"Client Tunnels", "Mijoz tunellari"}, + {"Services", "Xizmatlar"}, + {"Enabled", "Yoqilgan"}, + {"Disabled", "O'chirilgan"}, + {"Encrypted B33 address", "Shifrlangan B33 manzil"}, + {"Address registration line", "Manzilni ro'yxatga olish liniyasi"}, + {"Domain", "Domen"}, + {"Generate", "Varatish"}, + {"Note: result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.", "Eslatma: natija satridan faqat 2LD domenlarini ro'yxatdan o'tkazish uchun foydalanish mumkin (example.i2p). Subdomenlarni ro'yxatdan o'tkazish uchun i2pd-tools dan foydalaning."}, + {"Address", "Manzil"}, + {"Type", "Turi"}, + {"EncType", "ShifrlashTuri"}, + {"Inbound tunnels", "Kirish tunnellari"}, + {"ms", "ms"}, + {"Outbound tunnels", "Chiquvchi tunnellar"}, + {"Tags", "Teglar"}, + {"Incoming", "Kiruvchi"}, + {"Outgoing", "Chiquvchi"}, + {"Destination", "Manzilgoh"}, + {"Amount", "Yig'indi"}, + {"Incoming Tags", "Kiruvchi teglar"}, + {"Tags sessions", "Teglar sessiyalari"}, + {"Status", "Holat"}, + {"Streams", "Strim"}, + {"Close stream", "Strimni o'chirish"}, + {"I2CP session not found", "I2CP sessiyasi topilmadi"}, + {"I2CP is not enabled", "I2CP yoqilmagan"}, + {"Invalid", "Noto'g'ri"}, + {"Store type", "Saqlash turi"}, + {"Expires", "Muddati tugaydi"}, + {"Non Expired Leases", "Muddati O'tmagan Leases"}, + {"Gateway", "Kirish yo'li"}, + {"TunnelID", "TunnelID"}, + {"EndDate", "Tugash Sanasi"}, + {"not floodfill", "floodfill emas"}, + {"Queue size", "Navbat hajmi"}, + {"Run peer test", "Sinovni boshlang"}, + {"Decline transit tunnels", "Tranzit tunnellarni rad etish"}, + {"Accept transit tunnels", "Tranzit tunnellarni qabul qilish"}, + {"Cancel graceful shutdown", "Yumshoq to'xtashni bekor qiling"}, + {"Start graceful shutdown", "Yumshoq to'xtashni boshlang"}, + {"Force shutdown", "Bizning tashqi manzilimiz"}, + {"Reload external CSS styles", "Tashqi CSS uslublarini qayta yuklang"}, + {"Note: any action done here are not persistent and not changes your config files.", "Eslatma: bu erda qilingan har qanday harakat doimiy emas va konfiguratsiya fayllarini o'zgartirmaydi."}, + {"Transit tunnels limit", "Tranzit tunellar chegarasi"}, + {"Change", "O'zgartirish"}, + {"Change language", "Tilni o'zgartirish"}, + {"no transit tunnels currently built", "qurilgan tranzit tunnellari yo'q"}, + {"SAM disabled", "SAM o'chirilgan"}, + {"no sessions currently running", "hech qanday ishlaydigan sessiyalar yo'q"}, + {"SAM session not found", "SAM sessiyasi topilmadi"}, + {"SAM Session", "SAM sessiyasi"}, + {"Server Tunnels", "Server Tunellari"}, + {"Client Forwards", "Mijozlarni Yo'naltirish"}, + {"Server Forwards", "Serverni Yo'naltirish"}, + {"Unknown page", "Noma'lum sahifa"}, + {"Invalid token", "Noto‘g‘ri belgi"}, + {"SUCCESS", "Muvaffaqiyat"}, + {"Stream closed", "Strim yopiq"}, + {"Stream not found or already was closed", "Strim topilmadi yoki allaqachon yopilgan"}, + {"Destination not found", "Yo'nalish topilmadi"}, + {"StreamID can't be null", "StreamID bo'sh bo'lishi mumkin emas"}, + {"Return to destination page", "Belgilangan sahifaga qaytish"}, + {"You will be redirected in 5 seconds", "Siz 5 soniyada qayta yo'naltirilasiz"}, + {"Transit tunnels count must not exceed 65535", "Tranzit tunnellar soni 65535 dan oshmasligi kerak"}, + {"Back to commands list", "Buyruqlar ro'yxatiga qaytish"}, + {"Register at reg.i2p", "Reg.i2p-da ro'yxatdan o'ting"}, + {"Description", "Tavsif"}, + {"A bit information about service on domain", "Domen xizmatlari haqida bir oz ma'lumot"}, + {"Submit", "Yuborish"}, + {"Domain can't end with .b32.i2p", "Domen .b32.i2p bilan tugashi mumkin emas"}, + {"Domain must end with .i2p", "Domen .i2p bilan tugashi kerak"}, + {"Such destination is not found", "Bunday yo'nalish topilmadi"}, + {"Unknown command", "Noma'lum buyruq"}, + {"Command accepted", "Buyruq qabul qilindi"}, + {"Proxy error", "Proksi xatosi"}, + {"Proxy info", "Proksi ma'lumotlari"}, + {"Proxy error: Host not found", "Proksi xatosi: Xost topilmadi"}, + {"Remote host not found in router's addressbook", "Masofaviy xost yo'riqnoma manzillar kitobida topilmadi"}, + {"Invalid request", "Noto‘g‘ri so‘rov"}, + {"Proxy unable to parse your request", "Proksi sizning so'rovingizni tahlil qila olmaydi"}, + {"addresshelper is not supported", "addresshelper qo'llab -quvvatlanmaydi"}, + {"Host", "Xost"}, + {"Addresshelper found", "Addresshelper topildi"}, + {"invalid request uri", "noto'g'ri URI so'rovi"}, + {"Can't detect destination host from request", "So‘rov orqali manzil xostini aniqlab bo'lmayapti"}, + {"Outproxy failure", "Tashqi proksi muvaffaqiyatsizligi"}, + {"bad outproxy settings", "noto'g'ri tashqi proksi -server sozlamalari"}, + {"not inside I2P network, but outproxy is not enabled", "I2P tarmog'ida emas, lekin tashqi proksi yoqilmagan"}, + {"unknown outproxy url", "noma'lum outproxy url"}, + {"cannot resolve upstream proxy", "yuqoridagi proksi -serverni aniqlab olib bolmaydi"}, + {"hostname too long", "xost nomi juda uzun"}, + {"cannot connect to upstream socks proxy", "yuqori soks proksi -serveriga ulanib bo'lmaydi"}, + {"Cannot negotiate with socks proxy", "Soks proksi bilan muzokara olib bo'lmaydi"}, + {"CONNECT error", "CONNECT xatosi"}, + {"Failed to Connect", "Ulanmadi"}, + {"socks proxy error", "soks proksi xatosi"}, + {"failed to send request to upstream", "yuqori http proksi-serveriga ulanib bo'lmadi"}, + {"No Reply From socks proxy", "Soks-proksidan javob yo'q"}, + {"cannot connect", "ulab bo'lmaydi"}, + {"http out proxy not implemented", "tashqi HTTP proksi -serverni qo'llab -quvvatlash amalga oshirilmagan"}, + {"cannot connect to upstream http proxy", "yuqori http proksi-serveriga ulanib bo'lmadi"}, + {"Host is down", "Xost ishlamayapti"}, + {"Can't create connection to requested host, it may be down. Please try again later.", "Talab qilingan xost bilan aloqa o'rnatilmadi, u ishlamay qolishi mumkin. Iltimos keyinroq qayta urinib ko'ring."}, + {"", ""}, + }; + + static std::map> plurals + { + {"days", {"kun", "kunlar"}}, + {"hours", {"soat", "soat"}}, + {"minutes", {"daqiqa", "daqiqalar"}}, + {"seconds", {"soniya", "soniyalar"}}, + {"", {"", ""}}, + }; + + std::shared_ptr GetLocale() + { + return std::make_shared(language, strings, plurals, [] (int n)->int { return plural(n); }); + } + +} // language +} // i18n +} // i2p From 97765ef895c7fe4187bfea60cf0103ba8a2efcbb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 18 Aug 2021 23:04:52 +0300 Subject: [PATCH 0284/2193] [i18n] add namespace Signed-off-by: R4SAS --- i18n/I18N_langs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/I18N_langs.h b/i18n/I18N_langs.h index 957d550d..559b17be 100644 --- a/i18n/I18N_langs.h +++ b/i18n/I18N_langs.h @@ -76,6 +76,7 @@ namespace i18n namespace russian { std::shared_ptr GetLocale (); } namespace turkmen { std::shared_ptr GetLocale (); } namespace ukrainian { std::shared_ptr GetLocale (); } + namespace uzbek { std::shared_ptr GetLocale (); } /** * That map contains international language name lower-case and name in it's language From b830babcf41e6bb8b3be3f60f3ed9cdf830012af Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 22:32:03 +0300 Subject: [PATCH 0285/2193] [rpm] try fix build on fedora rawhide Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 1061fc8f..46ed8a51 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -56,33 +56,38 @@ cd build %endif %endif -%if 0%{?fedora} >= 33 -pushd %{_target_platform} + +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} > 7 -pushd build + pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 -popd + popd %endif %if 0%{?mageia} > 7 -popd + popd %endif %install pushd build %if 0%{?fedora} >= 33 -pushd %{_target_platform} + pushd %{_target_platform} %endif %if 0%{?mageia} -pushd build + pushd build %endif chrpath -d i2pd From 33355c0abe752095742190019ba8b4c6255bfe19 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 22:44:04 +0300 Subject: [PATCH 0286/2193] [rpm] try fix build on fedora rawhide Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 12 ++++++++---- contrib/rpm/i2pd.spec | 28 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 46ed8a51..c99c2c8b 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -11,9 +11,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 + BuildRequires: cmake3 %else -BuildRequires: cmake + BuildRequires: cmake %endif BuildRequires: chrpath @@ -82,8 +82,12 @@ make %{?_smp_mflags} %install pushd build -%if 0%{?fedora} >= 33 - pushd %{_target_platform} +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index a2994f28..1339fe90 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -9,9 +9,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 -BuildRequires: cmake3 + BuildRequires: cmake3 %else -BuildRequires: cmake + BuildRequires: cmake %endif BuildRequires: chrpath @@ -54,33 +54,41 @@ cd build %endif %endif -%if 0%{?fedora} >= 33 -pushd %{_target_platform} +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} > 7 -pushd build + pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 -popd + popd %endif %if 0%{?mageia} > 7 -popd + popd %endif %install pushd build -%if 0%{?fedora} >= 33 -pushd %{_target_platform} +%if 0%{?fedora} >= 36 + pushd redhat-linux-build +%else + %if 0%{?fedora} >= 33 + pushd %{_target_platform} + %endif %endif %if 0%{?mageia} -pushd build + pushd build %endif chrpath -d i2pd From 8abd08bd1b3bc845d4c7b33a564bee79060ae360 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Aug 2021 15:58:46 -0400 Subject: [PATCH 0287/2193] change log for 2.39.0 --- ChangeLog | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9a79440e..d12bdd22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,45 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog -## [2.38.0] - 2021-03-17 +## [2.39.0] - 2021-08-23 +### Added +- Short tunnel build messages +- Localization. To: Russian, Ukrainian, Turkmen, Uzbek and Afrikaans +- Custom CSS styles for webconsole +- Avoid slow tunnels with more than 250 ms per hop +- Process DELAY_REQUESTED streaming option +- "certsdir" options for certificates location +- Keep own RouterInfo in NetBb +- Pick ECIES routers only for tunneln on non-x64 +- NTP sync through ipv6 +- Allow ipv6 adresses for UDP server tunnels +### Changed +- Rekey of all routers to ECIES +- Better distribution for random tunnel's peer selection +- Yggdrasil reseed for v0.4, added two more +- Encyption type 0,4 by default for server tunnels +- Handle i2cp.dontPublishLeaseSet param for all destinations +- reg.i2p for subscriptions +- LeaseSet type 3 by default +- Don't allocate payload buffer for every single ECIESx25519 message +- Prefer public ipv6 instead rfc4941 +- Optimal padding for one-time ECIESx25519 message +- Don't send datetime block for one-time ECIESx25519 message with one-time key +- Router with expired introducer is still valid +- Don't disable floodfill if still reachable by ipv6 +- Set minimal version for floodfill to 0.9.38 +- Eliminate extra lookups for sequential fragments on tunnel endpoint +- Consistent path for explicit peers +### Fixed +- Zero-hop tunnels +- Crash upon SAM session termination +- Build with boost < 1.55.0 +- Address type for NTCP2 acceptors +- Check of ipv4/ipv6 address +- Requst router to send to if not in NetDb +- Count outbound traffic for zero-hop tunnels + +## [2.38.0] - 2021-05-17 ### Added - Publish ipv6 introducers - Bind ipv6 or yggdrasil NTCP2 acceptor to specified address From c93ab8f829a1f2afb6d6b7d2855a0927df0201fe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 23:36:08 +0300 Subject: [PATCH 0288/2193] update changelog, i2pd.conf Signed-off-by: R4SAS --- ChangeLog | 16 ++++++++++------ contrib/i2pd.conf | 3 +-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d12bdd22..2128f5d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,14 +10,14 @@ - Process DELAY_REQUESTED streaming option - "certsdir" options for certificates location - Keep own RouterInfo in NetBb -- Pick ECIES routers only for tunneln on non-x64 +- Pick ECIES routers only for tunnels on non-x64 - NTP sync through ipv6 -- Allow ipv6 adresses for UDP server tunnels +- Allow ipv6 addresses for UDP server tunnels ### Changed - Rekey of all routers to ECIES - Better distribution for random tunnel's peer selection - Yggdrasil reseed for v0.4, added two more -- Encyption type 0,4 by default for server tunnels +- Encryption type 0,4 by default for server tunnels - Handle i2cp.dontPublishLeaseSet param for all destinations - reg.i2p for subscriptions - LeaseSet type 3 by default @@ -30,14 +30,18 @@ - Set minimal version for floodfill to 0.9.38 - Eliminate extra lookups for sequential fragments on tunnel endpoint - Consistent path for explicit peers +- Always create new tunnel from exploratory pool +- Don't try to connect to a router not reachable from us +- Mark additional ipv6 addresses/nets as reserved (#1679) ### Fixed - Zero-hop tunnels - Crash upon SAM session termination -- Build with boost < 1.55.0 +- Build with boost < 1.55.0 - Address type for NTCP2 acceptors - Check of ipv4/ipv6 address -- Requst router to send to if not in NetDb -- Count outbound traffic for zero-hop tunnels +- Request router to send to if not in NetDb +- Count outbound traffic for zero-hop tunnels +- URLdecode domain for registration string generator in webconsole ## [2.38.0] - 2021-05-17 ### Added diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 599a2081..25402629 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -108,8 +108,7 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), afrikaans, russian, turkmen and ukrainian languages - +## Currently supported english (default), afrikaans, russian, turkmen ukrainian and uzbek languages # lang = english [httpproxy] From 2bdfcedd0e7acf9616b7204896fa8497043b8b07 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 23:37:56 +0300 Subject: [PATCH 0289/2193] [docs] add comma to description Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 25402629..dbf74002 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -108,7 +108,7 @@ port = 7070 # user = i2pd # pass = changeme ## Select webconsole language -## Currently supported english (default), afrikaans, russian, turkmen ukrainian and uzbek languages +## Currently supported english (default), afrikaans, russian, turkmen, ukrainian and uzbek languages # lang = english [httpproxy] From 6ba992dabd22520dd2a9b99674dbd9c0fe796a9f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 22 Aug 2021 23:41:36 +0300 Subject: [PATCH 0290/2193] [rpm] try fix build on fedora rawhide [try 3] Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 28 ++++++++++++++-------------- contrib/rpm/i2pd.spec | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index c99c2c8b..c9a848ee 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -11,9 +11,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz %if 0%{?rhel} == 7 - BuildRequires: cmake3 +BuildRequires: cmake3 %else - BuildRequires: cmake +BuildRequires: cmake %endif BuildRequires: chrpath @@ -58,40 +58,40 @@ cd build %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} > 7 - pushd build +pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 - popd +popd %endif %if 0%{?mageia} > 7 - popd +popd %endif %install pushd build %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} - pushd build +pushd build %endif chrpath -d i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 1339fe90..218a6bf7 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -9,9 +9,9 @@ URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz %if 0%{?rhel} == 7 - BuildRequires: cmake3 +BuildRequires: cmake3 %else - BuildRequires: cmake +BuildRequires: cmake %endif BuildRequires: chrpath @@ -55,40 +55,40 @@ cd build %endif %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} > 7 - pushd build +pushd build %endif make %{?_smp_mflags} %if 0%{?fedora} >= 33 - popd +popd %endif %if 0%{?mageia} > 7 - popd +popd %endif %install pushd build %if 0%{?fedora} >= 36 - pushd redhat-linux-build +pushd redhat-linux-build %else - %if 0%{?fedora} >= 33 - pushd %{_target_platform} - %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif %endif %if 0%{?mageia} - pushd build +pushd build %endif chrpath -d i2pd From 96850da31e2ddde169b53b81c98c70d2849ceffd Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Aug 2021 06:58:36 -0400 Subject: [PATCH 0291/2193] 2.39.0 --- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 6 +++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index c9a848ee..880d937e 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.38.0 +Version: 2.39.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -146,6 +146,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 23 2021 orignal - 2.39.0 +- update to 2.39.0 + * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 218a6bf7..5bdc5231 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.38.0 +Version: 2.39.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -143,6 +143,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 23 2021 orignal - 2.39.0 +- update to 2.39.0 + * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 diff --git a/debian/changelog b/debian/changelog index 777b6216..c675f263 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.39.0-1) unstable; urgency=medium + + * updated to version 2.39.0/0.9.51 + + -- orignal Mon, 23 Aug 2021 16:00:00 +0000 + i2pd (2.38.0-1) unstable; urgency=medium * updated to version 2.38.0/0.9.50 diff --git a/libi2pd/version.h b/libi2pd/version.h index 028d1692..97351c40 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -16,7 +16,7 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 38 +#define I2PD_VERSION_MINOR 39 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -30,7 +30,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 50 +#define I2P_VERSION_MICRO 51 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) #define I2P_VERSION_NUMBER MAKE_VERSION_NUMBER(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 455c71ff2557dde7104744cb0e8822ba8177440e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Aug 2021 17:00:46 +0300 Subject: [PATCH 0292/2193] fix warning about ifr_name size Signed-off-by: R4SAS --- libi2pd/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 2d5617b6..f7b376f6 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -344,7 +344,7 @@ namespace net if(fd > 0) { ifreq ifr; - strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ); // set interface for query + strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ-1); // set interface for query if(ioctl(fd, SIOCGIFMTU, &ifr) >= 0) mtu = ifr.ifr_mtu; // MTU else From 24eeadea765931d46697b3e44746f24eb65d1c53 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Aug 2021 17:03:26 +0300 Subject: [PATCH 0293/2193] [rpm] add changelog note Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 1 + contrib/rpm/i2pd.spec | 1 + 2 files changed, 2 insertions(+) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 880d937e..0643ea8b 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -148,6 +148,7 @@ getent passwd i2pd >/dev/null || \ %changelog * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 +- fixed build on fedora 36 * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5bdc5231..844901c9 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -145,6 +145,7 @@ getent passwd i2pd >/dev/null || \ %changelog * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 +- fixed build on fedora 36 * Mon May 17 2021 orignal - 2.38.0 - update to 2.38.0 From f0c49b58fbffd2afcb56a39e2294105298866275 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Aug 2021 19:29:55 +0300 Subject: [PATCH 0294/2193] suppress inconsistent-missing-override warning message Signed-off-by: R4SAS --- libi2pd/TunnelConfig.h | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 76aa0b34..875c20bb 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -31,14 +31,14 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - + TunnelHopConfig (std::shared_ptr r); virtual ~TunnelHopConfig () {}; - + void SetNextIdent (const i2p::data::IdentHash& ident); void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent); void SetNext (TunnelHopConfig * n); - void SetPrev (TunnelHopConfig * p); + void SetPrev (TunnelHopConfig * p); virtual uint8_t GetRetCode (const uint8_t * records) const = 0; virtual void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) = 0; @@ -51,47 +51,47 @@ namespace tunnel { ElGamalTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; - }; + uint8_t GetRetCode (const uint8_t * records) const + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); + bool DecryptBuildResponseRecord (uint8_t * records) const; + }; struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): TunnelHopConfig (r) {}; - void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); + void EncryptECIES (const uint8_t * clearText, size_t len, uint8_t * encrypted); bool DecryptECIES (const uint8_t * key, const uint8_t * nonce, const uint8_t * encrypted, size_t len, uint8_t * clearText) const; }; - + struct LongECIESTunnelHopConfig: public ECIESTunnelHopConfig { LongECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; - }; + uint8_t GetRetCode (const uint8_t * records) const override + { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET]; }; + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) override; + bool DecryptBuildResponseRecord (uint8_t * records) const override; + }; struct ShortECIESTunnelHopConfig: public ECIESTunnelHopConfig { ShortECIESTunnelHopConfig (std::shared_ptr r): ECIESTunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[SHORT_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; + uint8_t GetRetCode (const uint8_t * records) const override + { return (records + recordIndex*SHORT_TUNNEL_BUILD_RECORD_SIZE)[SHORT_RESPONSE_RECORD_RET_OFFSET]; }; + void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) override; + bool DecryptBuildResponseRecord (uint8_t * records) const override; void DecryptRecord (uint8_t * records, int index) const override; // Chacha20 - uint64_t GetGarlicKey (uint8_t * key) const override; - }; - + uint64_t GetGarlicKey (uint8_t * key) const override; + }; + class TunnelConfig { public: - TunnelConfig (const std::vector >& peers, + TunnelConfig (const std::vector >& peers, bool isShort = false): // inbound m_IsShort (isShort) { @@ -121,7 +121,7 @@ namespace tunnel } bool IsShort () const { return m_IsShort; } - + TunnelHopConfig * GetFirstHop () const { return m_FirstHop; @@ -203,12 +203,12 @@ namespace tunnel if (m_IsShort) hop = new ShortECIESTunnelHopConfig (it); else - { + { if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) hop = new LongECIESTunnelHopConfig (it); else hop = new ElGamalTunnelHopConfig (it); - } + } if (prev) prev->SetNext (hop); else From 7d220fb2ebc1213030defa79cf265d56c7a9621a Mon Sep 17 00:00:00 2001 From: Daniel Bermond Date: Mon, 23 Aug 2021 17:22:28 -0300 Subject: [PATCH 0295/2193] [tests] fix compilation of test-blinding test-blinding currently fails to build with the following error: In file included from ../libi2pd/Timestamp.cpp:19: ../libi2pd/RouterContext.h:21:10: fatal error: I18N_langs.h: No such file or directory 21 | #include "I18N_langs.h" | ^~~~~~~~~~~~~~ compilation terminated. --- tests/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Makefile b/tests/Makefile index 4c80c37c..2cb5348f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,5 @@ CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread -Wl,--unresolved-symbols=ignore-in-object-files +INCFLAGS += -I ../i18n TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator From af2c6c5575d28fa320f3b048b9d791d98fe77761 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 24 Aug 2021 03:16:28 +0300 Subject: [PATCH 0296/2193] [rpm] change if statement to cover fedora 35 Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 7 +++++-- contrib/rpm/i2pd.spec | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 0643ea8b..b1354173 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -57,7 +57,7 @@ cd build %endif -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -82,7 +82,7 @@ popd %install pushd build -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -146,6 +146,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2021 r4sas - 2.39.0-2 +- changed if statements to cover fedora 35 + * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 - fixed build on fedora 36 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 844901c9..ef8e32f2 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.39.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -54,7 +54,7 @@ cd build %endif %endif -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -79,7 +79,7 @@ popd %install pushd build -%if 0%{?fedora} >= 36 +%if 0%{?fedora} >= 35 pushd redhat-linux-build %else %if 0%{?fedora} >= 33 @@ -143,6 +143,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2021 r4sas - 2.39.0-2 +- changed if statements to cover fedora 35 + * Mon Aug 23 2021 orignal - 2.39.0 - update to 2.39.0 - fixed build on fedora 36 From ec98ff297c2d8050e3a525abe1b4203a3c97a0db Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 24 Aug 2021 13:23:10 +0300 Subject: [PATCH 0297/2193] Make blinding test runnable --- tests/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 2cb5348f..89fceeec 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,7 @@ -CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread -Wl,--unresolved-symbols=ignore-in-object-files -INCFLAGS += -I ../i18n +CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -pthread -Wl,--unresolved-symbols=ignore-in-object-files +INCFLAGS += -I../libi2pd -I../i18n + +LOCALESRC = ../i18n/Afrikaans.cpp ../i18n/English.cpp ../i18n/Russian.cpp ../i18n/Turkmen.cpp ../i18n/Ukrainian.cpp ../i18n/Uzbek.cpp TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator @@ -23,7 +25,7 @@ test-x25519: ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system -test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp test-blinding.cpp +test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp $(LOCALESRC) test-blinding.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system test-elligator: ../libi2pd/Elligator.cpp ../libi2pd/Crypto.cpp test-elligator.cpp From 541464b7057095a220db0d094fdaef16d8191fd5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Aug 2021 15:13:58 -0400 Subject: [PATCH 0298/2193] don't delete floodfill if number of remaining floodfills is less than minimal --- libi2pd/NetDb.cpp | 9 ++++++--- libi2pd/NetDb.hpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4bc144e4..904782cf 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -577,8 +577,9 @@ namespace data void NetDb::SaveUpdated () { - int updatedCount = 0, deletedCount = 0; + int updatedCount = 0, deletedCount = 0, deletedFloodfillsCount = 0; auto total = m_RouterInfos.size (); + auto totalFloodfills = m_Floodfills.size (); uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); auto uptime = i2p::context.GetUptime (); @@ -603,8 +604,9 @@ namespace data updatedCount++; continue; } - // make router reachable back if too few routers - if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS) + // make router reachable back if too few routers or floodfills + if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS || + (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS))) it.second->SetUnreachable (false); // find & mark expired routers if (!it.second->IsReachable () && it.second->IsSSU (false)) @@ -618,6 +620,7 @@ namespace data if (it.second->IsUnreachable ()) { + if (it.second->IsFloodfill ()) deletedFloodfillsCount++; // delete RI file m_Storage.Remove(ident); deletedCount++; diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index c52be02b..097f92e7 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -36,6 +36,7 @@ namespace i2p namespace data { const int NETDB_MIN_ROUTERS = 90; + const int NETDB_MIN_FLOODFILLS = 5; const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60; const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours From c45e202fabbb7a0763428d81a06a6d681a22b020 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 29 Aug 2021 14:22:01 -0400 Subject: [PATCH 0299/2193] removed ElGamal encryption support for own router --- libi2pd/Crypto.cpp | 29 +++++++++-------------------- libi2pd/Crypto.h | 8 ++++---- libi2pd/CryptoKey.cpp | 16 ++++++++-------- libi2pd/CryptoKey.h | 30 +++++++++++++++--------------- libi2pd/Destination.cpp | 4 ++-- libi2pd/RouterContext.cpp | 13 +++++-------- libi2pd_client/I2CP.cpp | 6 +++--- 7 files changed, 46 insertions(+), 60 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 14ef83ae..136a2072 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -451,15 +451,15 @@ namespace crypto BN_CTX_end (ctx); } - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, - uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, + uint8_t * data, BN_CTX * ctx) { BN_CTX_start (ctx); BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx); BN_bin2bn (key, 256, x); BN_sub (x, elgp, x); BN_sub_word (x, 1); // x = elgp - x- 1 - BN_bin2bn (zeroPadding ? encrypted + 1 : encrypted, 256, a); - BN_bin2bn (zeroPadding ? encrypted + 258 : encrypted + 256, 256, b); + BN_bin2bn (encrypted + 1, 256, a); + BN_bin2bn (encrypted + 258, 256, b); // m = b*(a^x mod p) mod p BN_mod_exp (x, a, x, elgp, ctx); BN_mod_mul (b, b, x, elgp, ctx); @@ -552,7 +552,7 @@ namespace crypto BN_CTX_end (ctx); } - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { bool ret = true; BN_CTX_start (ctx); @@ -561,16 +561,8 @@ namespace crypto int len = BN_num_bytes (q); // point for shared secret BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); - if (zeroPadding) - { - BN_bin2bn (encrypted + 1, len, x); - BN_bin2bn (encrypted + 1 + len, len, y); - } - else - { - BN_bin2bn (encrypted, len, x); - BN_bin2bn (encrypted + len, len, y); - } + BN_bin2bn (encrypted + 1, len, x); + BN_bin2bn (encrypted + 1 + len, len, y); auto p = EC_POINT_new (curve); if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr)) { @@ -587,10 +579,7 @@ namespace crypto CBCDecryption decryption; decryption.SetKey (shared); decryption.SetIV (iv); - if (zeroPadding) - decryption.Decrypt (encrypted + 258, 256, m); - else - decryption.Decrypt (encrypted + 256, 256, m); + decryption.Decrypt (encrypted + 258, 256, m); // verify and copy uint8_t hash[32]; SHA256 (m + 33, 222, hash); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index a6c64c70..56791ceb 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -108,13 +108,13 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); // HMAC diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index ad93d386..3b2105a4 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -31,10 +31,10 @@ namespace crypto memcpy (m_PrivateKey, priv, 256); } - bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (!ctx) return false; - return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding); + return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx); } ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) @@ -72,10 +72,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_Curve && m_PrivateKey) - return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, zeroPadding); + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); return false; } @@ -130,10 +130,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) + bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { if (m_PrivateKey) - return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, zeroPadding); + return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx); return false; } @@ -171,7 +171,7 @@ namespace crypto m_StaticKeys.SetPrivateKey (priv, calculatePublic); } - bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) + bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) { return m_StaticKeys.Agree (epub, sharedSecret); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index fb69558f..a5b96c47 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; // 222 bytes data, 512/514 bytes encrypted + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; }; class CryptoKeyDecryptor @@ -29,7 +29,7 @@ namespace crypto public: virtual ~CryptoKeyDecryptor () {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) = 0; // 512/514 bytes encrypted, 222 bytes data + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; virtual size_t GetPublicKeyLen () const = 0; // we need it to set key in LS2 }; @@ -39,7 +39,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted private: @@ -51,8 +51,8 @@ namespace crypto public: ElGamalDecryptor (const uint8_t * priv); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); - size_t GetPublicKeyLen () const { return 256; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; // 514 bytes encrypted, 222 bytes data + size_t GetPublicKeyLen () const override { return 256; }; private: @@ -67,7 +67,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; private: @@ -82,8 +82,8 @@ namespace crypto ECIESP256Decryptor (const uint8_t * priv); ~ECIESP256Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); - size_t GetPublicKeyLen () const { return 64; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + size_t GetPublicKeyLen () const override { return 64; }; private: @@ -101,7 +101,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding); + void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; private: @@ -115,8 +115,8 @@ namespace crypto ECIESGOSTR3410Decryptor (const uint8_t * priv); ~ECIESGOSTR3410Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); - size_t GetPublicKeyLen () const { return 64; }; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + size_t GetPublicKeyLen () const override { return 64; }; private: @@ -133,7 +133,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool); + void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) override; // copies m_PublicKey to pub private: @@ -147,9 +147,9 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false); ~ECIESX25519AEADRatchetDecryptor () {}; - bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); + bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) override; // agree with static and return in sharedSecret (32 bytes) - size_t GetPublicKeyLen () const { return 32; }; + size_t GetPublicKeyLen () const override { return 32; }; const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); }; private: diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index bc6ca31e..f269c092 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1249,9 +1249,9 @@ namespace client { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) if (m_ECIESx25519EncryptionKey && m_ECIESx25519EncryptionKey->decryptor) - return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true); + return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx); if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor) - return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true); + return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx); else LogPrint (eLogError, "Destinations: decryptor is not set"); return false; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index edabcdfa..92dc5aea 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -880,7 +880,7 @@ namespace i2p bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { - return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, true) : false; + return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx) : false; } bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) @@ -889,11 +889,8 @@ namespace i2p return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); else { - if (!m_TunnelDecryptor) return false; - BN_CTX * ctx = BN_CTX_new (); - bool success = m_TunnelDecryptor->Decrypt (encrypted, data, ctx, false); - BN_CTX_free (ctx); - return success; + LogPrint (eLogError, "Router: Non-ECIES router is not longer supported"); + return false; } } @@ -903,7 +900,7 @@ namespace i2p m_CurrentNoiseState = m_InitialNoiseState; m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; - if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false)) + if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; @@ -928,7 +925,7 @@ namespace i2p return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); else { - LogPrint (eLogWarning, "Router: Can't decrypt short request record on non-ECIES router"); + LogPrint (eLogError, "Router: Can't decrypt short request record on non-ECIES router"); return false; } } diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 25a5504a..b6618ff9 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -55,9 +55,9 @@ namespace client bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor) - return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true); + return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx); if (m_Decryptor) - return m_Decryptor->Decrypt (encrypted, data, ctx, true); + return m_Decryptor->Decrypt (encrypted, data, ctx); else LogPrint (eLogError, "I2CP: decryptor is not set"); return false; From bb518d3d51bda9d965952d786558825fd877b27a Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Aug 2021 18:51:40 -0400 Subject: [PATCH 0300/2193] don't pass BN_CTX to encrypt/decrypt functions --- libi2pd/Crypto.cpp | 17 +++++++++---- libi2pd/Crypto.h | 8 +++--- libi2pd/CryptoKey.cpp | 30 +++++++++++------------ libi2pd/CryptoKey.h | 20 +++++++-------- libi2pd/Destination.cpp | 8 +++--- libi2pd/Destination.h | 4 +-- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 ++++---- libi2pd/Garlic.cpp | 12 +++------ libi2pd/Garlic.h | 3 +-- libi2pd/Identity.h | 6 ++--- libi2pd/LeaseSet.cpp | 10 ++++---- libi2pd/LeaseSet.h | 6 ++--- libi2pd/RouterContext.cpp | 8 +++--- libi2pd/RouterContext.h | 4 +-- libi2pd/RouterInfo.cpp | 4 +-- libi2pd/RouterInfo.h | 2 +- libi2pd/TunnelConfig.cpp | 6 +---- libi2pd_client/I2CP.cpp | 6 ++--- libi2pd_client/I2CP.h | 2 +- 19 files changed, 81 insertions(+), 85 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 136a2072..9c9d5252 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -398,8 +398,9 @@ namespace crypto } // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); // everything, but a, because a might come from table BIGNUM * k = BN_CTX_get (ctx); @@ -449,11 +450,12 @@ namespace crypto } BN_free (a); BN_CTX_end (ctx); + BN_CTX_free (ctx); } - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, - uint8_t * data, BN_CTX * ctx) + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data) { + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * x = BN_CTX_get (ctx), * a = BN_CTX_get (ctx), * b = BN_CTX_get (ctx); BN_bin2bn (key, 256, x); @@ -466,6 +468,7 @@ namespace crypto uint8_t m[255]; bn2buf (b, m, 255); BN_CTX_end (ctx); + BN_CTX_free (ctx); uint8_t hash[32]; SHA256 (m + 33, 222, hash); if (memcmp (m + 1, hash, 32)) @@ -499,8 +502,9 @@ namespace crypto } // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order(curve, q, ctx); @@ -550,11 +554,13 @@ namespace crypto encryption.Encrypt (m, 256, encrypted + 256); EC_POINT_free (p); BN_CTX_end (ctx); + BN_CTX_free (ctx); } - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data) { bool ret = true; + BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order(curve, q, ctx); @@ -599,6 +605,7 @@ namespace crypto EC_POINT_free (p); BN_CTX_end (ctx); + BN_CTX_free (ctx); return ret; } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 56791ceb..f165d59d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -108,13 +108,13 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without - bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without - bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // 514 bytes encrypted, 222 data + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); // HMAC diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 3b2105a4..8e49792a 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -20,10 +20,9 @@ namespace crypto memcpy (m_PublicKey, pub, 256); } - void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { - if (!ctx) return; - ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding); + ElGamalEncrypt (m_PublicKey, data, encrypted, zeroPadding); } ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) @@ -31,10 +30,9 @@ namespace crypto memcpy (m_PrivateKey, priv, 256); } - bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) { - if (!ctx) return false; - return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx); + return ElGamalDecrypt (m_PrivateKey, encrypted, data); } ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub) @@ -54,10 +52,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { if (m_Curve && m_PublicKey) - ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, zeroPadding); + ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, zeroPadding); } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -72,10 +70,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) { if (m_Curve && m_PrivateKey) - return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx); + return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data); return false; } @@ -114,10 +112,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) + void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) { if (m_PublicKey) - ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, zeroPadding); + ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, zeroPadding); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv) @@ -130,10 +128,10 @@ namespace crypto if (m_PrivateKey) BN_free (m_PrivateKey); } - bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data) { if (m_PrivateKey) - return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx); + return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data); return false; } @@ -161,7 +159,7 @@ namespace crypto memcpy (m_PublicKey, pub, 32); } - void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, bool) { memcpy (pub, m_PublicKey, 32); } @@ -171,7 +169,7 @@ namespace crypto m_StaticKeys.SetPrivateKey (priv, calculatePublic); } - bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) + bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret) { return m_StaticKeys.Agree (epub, sharedSecret); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index a5b96c47..705de49e 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) = 0; + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) = 0; }; class CryptoKeyDecryptor @@ -29,7 +29,7 @@ namespace crypto public: virtual ~CryptoKeyDecryptor () {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) = 0; + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data) = 0; virtual size_t GetPublicKeyLen () const = 0; // we need it to set key in LS2 }; @@ -39,7 +39,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted private: @@ -51,7 +51,7 @@ namespace crypto public: ElGamalDecryptor (const uint8_t * priv); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; // 514 bytes encrypted, 222 bytes data + bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; // 514 bytes encrypted, 222 bytes data size_t GetPublicKeyLen () const override { return 256; }; private: @@ -67,7 +67,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; private: @@ -82,7 +82,7 @@ namespace crypto ECIESP256Decryptor (const uint8_t * priv); ~ECIESP256Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; size_t GetPublicKeyLen () const override { return 64; }; private: @@ -101,7 +101,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; private: @@ -115,7 +115,7 @@ namespace crypto ECIESGOSTR3410Decryptor (const uint8_t * priv); ~ECIESGOSTR3410Decryptor (); - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) override; + bool Decrypt (const uint8_t * encrypted, uint8_t * data) override; size_t GetPublicKeyLen () const override { return 64; }; private: @@ -133,7 +133,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) override; + void Encrypt (const uint8_t *, uint8_t * pub, bool) override; // copies m_PublicKey to pub private: @@ -147,7 +147,7 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false); ~ECIESX25519AEADRatchetDecryptor () {}; - bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx) override; + bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret) override; // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const override { return 32; }; const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); }; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f269c092..438b3f19 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1245,13 +1245,13 @@ namespace client if (m_DatagramDestination) m_DatagramDestination->CleanUp (); } - bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const + bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) if (m_ECIESx25519EncryptionKey && m_ECIESx25519EncryptionKey->decryptor) - return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data, ctx); + return m_ECIESx25519EncryptionKey->decryptor->Decrypt (encrypted, data); if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor) - return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx); + return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data); else LogPrint (eLogError, "Destinations: decryptor is not set"); return false; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 2effff27..9e63d9bb 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -254,7 +254,7 @@ namespace client i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5ff2ae5c..c9671a7e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -239,7 +239,7 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key"); return false; @@ -263,7 +263,7 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - if (!GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) + if (!GetOwner ()->Decrypt (fs, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) { LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); return false; @@ -492,7 +492,7 @@ namespace garlic // KDF2 if (isStatic) { - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk) MixKey (sharedSecret); } else @@ -639,7 +639,7 @@ namespace garlic return false; } MixKey (sharedSecret); - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) MixKey (sharedSecret); uint8_t nonce[12]; @@ -1084,7 +1084,7 @@ namespace garlic // we are Bob m_CurrentNoiseState.MixHash (buf, 32); uint8_t sharedSecret[32]; - if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + if (!GetOwner ()->Decrypt (buf, sharedSecret, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) { LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key"); return false; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index e5b74624..ea30a249 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -164,9 +164,7 @@ namespace garlic RAND_bytes (elGamal.preIV, 32); // Pre-IV uint8_t iv[32]; // IV is first 16 bytes SHA256(elGamal.preIV, 32, iv); - BN_CTX * ctx = BN_CTX_new (); - m_Destination->Encrypt ((uint8_t *)&elGamal, buf, ctx); - BN_CTX_free (ctx); + m_Destination->Encrypt ((uint8_t *)&elGamal, buf); m_Encryption.SetIV (iv); buf += 514; len += 514; @@ -435,12 +433,10 @@ namespace garlic GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default m_PayloadBuffer (nullptr), m_NumRatchetInboundTags (0) // 0 means standard { - m_Ctx = BN_CTX_new (); } GarlicDestination::~GarlicDestination () { - BN_CTX_free (m_Ctx); if (m_PayloadBuffer) delete[] m_PayloadBuffer; } @@ -531,7 +527,7 @@ namespace garlic // try ElGamal/AES first if leading block is 514 ElGamalBlock elGamal; if (mod == 2 && length >= 514 && SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) && - Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) + Decrypt (buf, (uint8_t *)&elGamal, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) { auto decryption = std::make_shared(elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes @@ -777,7 +773,7 @@ namespace garlic { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; - destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key + destination->Encrypt (nullptr, staticKey); // we are supposed to get static key auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) { diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index b150e78d..0d7b8461 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -279,7 +279,6 @@ namespace garlic private: - BN_CTX * m_Ctx; // incoming // outgoing sessions int m_NumTags; std::mutex m_SessionsMutex; diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index e9cf63ed..b52f36cf 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -222,7 +222,7 @@ namespace data virtual ~RoutingDestination () {}; virtual std::shared_ptr GetIdentity () const = 0; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const = 0; // encrypt data for + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for virtual bool IsDestination () const = 0; // for garlic const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; @@ -234,7 +234,7 @@ namespace data public: virtual ~LocalDestination() {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL) const = 0; + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL) const = 0; virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index a0b14385..4d5e58d4 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -254,12 +254,12 @@ namespace data return ts > m_ExpirationTime; } - void LeaseSet::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const + void LeaseSet::Encrypt (const uint8_t * data, uint8_t * encrypted) const { if (!m_EncryptionKey) return; auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey); if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, true); } void LeaseSet::SetBuffer (const uint8_t * buf, size_t len) @@ -658,11 +658,11 @@ namespace data return offset - 1; } - void LeaseSet2::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const + void LeaseSet2::Encrypt (const uint8_t * data, uint8_t * encrypted) const { auto encryptor = m_Encryptor; // TODO: atomic if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, true); } uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index cd6535df..8d501cb1 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -93,7 +93,7 @@ namespace data // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_Identity; }; - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted) const; bool IsDestination () const { return true; }; protected: @@ -156,7 +156,7 @@ namespace data bool IsNewer (const uint8_t * buf, size_t len) const; // implements RoutingDestination - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted) const; CryptoKeyType GetEncryptionType () const { return m_EncryptionType; }; private: diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 92dc5aea..1a2dd335 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -878,9 +878,9 @@ namespace i2p return std::chrono::duration_cast (std::chrono::steady_clock::now() - m_StartupTime).count (); } - bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const + bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { - return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx) : false; + return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data) : false; } bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) @@ -900,7 +900,7 @@ namespace i2p m_CurrentNoiseState = m_InitialNoiseState; m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; - if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr)) + if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret)) { LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); return false; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index b52e20d9..98ee6a72 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -134,7 +134,7 @@ namespace garlic // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; void SetLeaseSetUpdated () {}; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 0d439dfc..78abbb51 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1155,11 +1155,11 @@ namespace data return m_Profile; } - void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const + void RouterInfo::Encrypt (const uint8_t * data, uint8_t * encrypted) const { auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, true); } bool RouterInfo::IsEligibleFloodfill () const diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b2b6df61..6ba52c7f 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -243,7 +243,7 @@ namespace data // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_RouterIdentity; }; - void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted) const; bool IsDestination () const { return false; }; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 543ba0fa..3eee2067 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -111,11 +111,7 @@ namespace tunnel uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; auto encryptor = ident->CreateEncryptor (nullptr); if (encryptor) - { - BN_CTX * ctx = BN_CTX_new (); - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); - BN_CTX_free (ctx); - } + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, false); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index b6618ff9..7c76d359 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -52,12 +52,12 @@ namespace client } } - bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const + bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const { if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor) - return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx); + return m_ECIESx25519Decryptor->Decrypt (encrypted, data); if (m_Decryptor) - return m_Decryptor->Decrypt (encrypted, data, ctx); + return m_Decryptor->Decrypt (encrypted, data); else LogPrint (eLogError, "I2CP: decryptor is not set"); return false; diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 9a8bda4e..08a96af6 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -83,7 +83,7 @@ namespace client void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only std::shared_ptr GetIdentity () const { return m_Identity; }; From 349022ae42791e2ce39da84ae81fbd40742cf85e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Sep 2021 13:30:01 -0400 Subject: [PATCH 0301/2193] don't select ElGamal routers for tunnels --- libi2pd/Crypto.cpp | 47 ++++++++------------------- libi2pd/Crypto.h | 4 +-- libi2pd/CryptoKey.cpp | 14 ++++---- libi2pd/CryptoKey.h | 10 +++--- libi2pd/LeaseSet.cpp | 4 +-- libi2pd/NetDb.cpp | 12 +++---- libi2pd/RouterInfo.cpp | 2 +- libi2pd/RouterInfo.h | 1 + libi2pd/TunnelConfig.cpp | 69 ++++++++++++++++------------------------ libi2pd/TunnelConfig.h | 34 +------------------- libi2pd/TunnelPool.cpp | 13 ++++++-- 11 files changed, 75 insertions(+), 135 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 9c9d5252..427bbbd6 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -398,7 +398,7 @@ namespace crypto } // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted) { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -436,18 +436,11 @@ namespace crypto BN_bin2bn (m, 255, b); BN_mod_mul (b, b1, b, elgp, ctx); // copy a and b - if (zeroPadding) - { - encrypted[0] = 0; - bn2buf (a, encrypted + 1, 256); - encrypted[257] = 0; - bn2buf (b, encrypted + 258, 256); - } - else - { - bn2buf (a, encrypted, 256); - bn2buf (b, encrypted + 256, 256); - } + encrypted[0] = 0; + bn2buf (a, encrypted + 1, 256); + encrypted[257] = 0; + bn2buf (b, encrypted + 258, 256); + BN_free (a); BN_CTX_end (ctx); BN_CTX_free (ctx); @@ -502,7 +495,7 @@ namespace crypto } // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted) { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -516,19 +509,10 @@ namespace crypto EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx); BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); - if (zeroPadding) - { - encrypted[0] = 0; - bn2buf (x, encrypted + 1, len); - bn2buf (y, encrypted + 1 + len, len); - RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); - } - else - { - bn2buf (x, encrypted, len); - bn2buf (y, encrypted + len, len); - RAND_bytes (encrypted + 2*len, 256 - 2*len); - } + encrypted[0] = 0; + bn2buf (x, encrypted + 1, len); + bn2buf (y, encrypted + 1 + len, len); + RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len); // encryption key and iv EC_POINT_mul (curve, p, nullptr, key, k, ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); @@ -545,13 +529,8 @@ namespace crypto CBCEncryption encryption; encryption.SetKey (shared); encryption.SetIV (iv); - if (zeroPadding) - { - encrypted[257] = 0; - encryption.Encrypt (m, 256, encrypted + 258); - } - else - encryption.Encrypt (m, 256, encrypted + 256); + encrypted[257] = 0; + encryption.Encrypt (m, 256, encrypted + 258); EC_POINT_free (p); BN_CTX_end (ctx); BN_CTX_free (ctx); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index f165d59d..5f42b527 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -108,12 +108,12 @@ namespace crypto }; // ElGamal - void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 514 bytes encrypted bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); // ECIES - void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false); // 222 bytes data, 514 bytes encrypted with zeropadding, 512 without + void ECIESEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted); // 222 bytes data, 514 bytes encrypted bool ECIESDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data); // 514 bytes encrypted, 222 data void GenerateECIESKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 8e49792a..ad986129 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -20,9 +20,9 @@ namespace crypto memcpy (m_PublicKey, pub, 256); } - void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) { - ElGamalEncrypt (m_PublicKey, data, encrypted, zeroPadding); + ElGamalEncrypt (m_PublicKey, data, encrypted); } ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv) @@ -52,10 +52,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) { if (m_Curve && m_PublicKey) - ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, zeroPadding); + ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted); } ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv) @@ -112,10 +112,10 @@ namespace crypto if (m_PublicKey) EC_POINT_free (m_PublicKey); } - void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) + void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted) { if (m_PublicKey) - ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, zeroPadding); + ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv) @@ -159,7 +159,7 @@ namespace crypto memcpy (m_PublicKey, pub, 32); } - void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, bool) + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub) { memcpy (pub, m_PublicKey, 32); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 705de49e..0ac0bdd5 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -21,7 +21,7 @@ namespace crypto public: virtual ~CryptoKeyEncryptor () {}; - virtual void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) = 0; + virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) = 0; }; class CryptoKeyDecryptor @@ -39,7 +39,7 @@ namespace crypto public: ElGamalEncryptor (const uint8_t * pub); - void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; // 222 bytes data, 512/514 bytes encrypted + void Encrypt (const uint8_t * data, uint8_t * encrypted) override; // 222 bytes data, 514 bytes encrypted private: @@ -67,7 +67,7 @@ namespace crypto ECIESP256Encryptor (const uint8_t * pub); ~ECIESP256Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted) override; private: @@ -101,7 +101,7 @@ namespace crypto ECIESGOSTR3410Encryptor (const uint8_t * pub); ~ECIESGOSTR3410Encryptor (); - void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) override; + void Encrypt (const uint8_t * data, uint8_t * encrypted) override; private: @@ -133,7 +133,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t *, uint8_t * pub, bool) override; + void Encrypt (const uint8_t *, uint8_t * pub) override; // copies m_PublicKey to pub private: diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 4d5e58d4..75187cfe 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -259,7 +259,7 @@ namespace data if (!m_EncryptionKey) return; auto encryptor = m_Identity->CreateEncryptor (m_EncryptionKey); if (encryptor) - encryptor->Encrypt (data, encrypted, true); + encryptor->Encrypt (data, encrypted); } void LeaseSet::SetBuffer (const uint8_t * buf, size_t len) @@ -662,7 +662,7 @@ namespace data { auto encryptor = m_Encryptor; // TODO: atomic if (encryptor) - encryptor->Encrypt (data, encrypted, true); + encryptor->Encrypt (data, encrypted); } uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 904782cf..7c473a09 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1171,7 +1171,8 @@ namespace data { return !router->IsHidden () && router != compatibleWith && (reverse ? compatibleWith->IsReachableFrom (*router) : - router->IsReachableFrom (*compatibleWith)); + router->IsReachableFrom (*compatibleWith)) && + router->IsECIES (); }); } @@ -1212,12 +1213,9 @@ namespace data return !router->IsHidden () && router != compatibleWith && (reverse ? compatibleWith->IsReachableFrom (*router) : router->IsReachableFrom (*compatibleWith)) && - (router->GetCaps () & RouterInfo::eHighBandwidth) && -#if defined(__x86_64__) - router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION; -#else - router->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; -#endif + (router->GetCaps () & RouterInfo::eHighBandwidth) && + router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION && + router->IsECIES (); }); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 78abbb51..5d66e0e4 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1159,7 +1159,7 @@ namespace data { auto encryptor = m_RouterIdentity->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (data, encrypted, true); + encryptor->Encrypt (data, encrypted); } bool RouterInfo::IsEligibleFloodfill () const diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 6ba52c7f..8ffd81cd 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -191,6 +191,7 @@ namespace data void UpdateSupportedTransports (); bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; + bool IsECIES () const { return m_RouterIdentity->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 3eee2067..4592c663 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -82,48 +82,6 @@ namespace tunnel decryption.SetIV (replyIV); decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record); } - - void ElGamalTunnelHopConfig::CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID) - { - // generate keys - RAND_bytes (layerKey, 32); - RAND_bytes (ivKey, 32); - RAND_bytes (replyKey, 32); - RAND_bytes (replyIV, 16); - // fill clear text - uint8_t flag = 0; - if (isGateway) flag |= TUNNEL_BUILD_RECORD_GATEWAY_FLAG; - if (isEndpoint) flag |= TUNNEL_BUILD_RECORD_ENDPOINT_FLAG; - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); - htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); - htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - // encrypt - uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; - auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, false); - memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); - } - - bool ElGamalTunnelHopConfig::DecryptBuildResponseRecord (uint8_t * records) const - { - uint8_t * record = records + recordIndex*TUNNEL_BUILD_RECORD_SIZE; - i2p::crypto::CBCDecryption decryption; - decryption.SetKey (replyKey); - decryption.SetIV (replyIV); - decryption.Decrypt (record, TUNNEL_BUILD_RECORD_SIZE, record); - return true; - } void ECIESTunnelHopConfig::EncryptECIES (const uint8_t * plainText, size_t len, uint8_t * encrypted) { @@ -261,5 +219,32 @@ namespace tunnel memcpy (key, m_CK + 32, 32); return tag; } + + void TunnelConfig::CreatePeers (const std::vector >& peers) + { + TunnelHopConfig * prev = nullptr; + for (const auto& it: peers) + { + TunnelHopConfig * hop = nullptr; + if (m_IsShort) + hop = new ShortECIESTunnelHopConfig (it); + else + { + if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) + hop = new LongECIESTunnelHopConfig (it); + else + LogPrint (eLogError, "Tunnel: ElGamal router is not supported"); + } + if (hop) + { + if (prev) + prev->SetNext (hop); + else + m_FirstHop = hop; + prev = hop; + } + } + m_LastHop = prev; + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 875c20bb..8cb46d09 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -47,16 +47,6 @@ namespace tunnel virtual uint64_t GetGarlicKey (uint8_t * key) const { return 0; }; // return tag }; - struct ElGamalTunnelHopConfig: public TunnelHopConfig - { - ElGamalTunnelHopConfig (std::shared_ptr r): - TunnelHopConfig (r) {}; - uint8_t GetRetCode (const uint8_t * records) const - { return (records + recordIndex*TUNNEL_BUILD_RECORD_SIZE)[BUILD_RESPONSE_RECORD_RET_OFFSET]; }; - void CreateBuildRequestRecord (uint8_t * records, uint32_t replyMsgID); - bool DecryptBuildResponseRecord (uint8_t * records) const; - }; - struct ECIESTunnelHopConfig: public TunnelHopConfig, public i2p::crypto::NoiseSymmetricState { ECIESTunnelHopConfig (std::shared_ptr r): @@ -194,29 +184,7 @@ namespace tunnel private: - void CreatePeers (const std::vector >& peers) - { - TunnelHopConfig * prev = nullptr; - for (const auto& it: peers) - { - TunnelHopConfig * hop; - if (m_IsShort) - hop = new ShortECIESTunnelHopConfig (it); - else - { - if (it->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) - hop = new LongECIESTunnelHopConfig (it); - else - hop = new ElGamalTunnelHopConfig (it); - } - if (prev) - prev->SetNext (hop); - else - m_FirstHop = hop; - prev = hop; - } - m_LastHop = prev; - } + void CreatePeers (const std::vector >& peers); private: diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 1745ebb8..b885f69f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -453,7 +453,7 @@ namespace tunnel (inbound && i2p::transport::transports.GetNumPeers () > 25)) { auto r = i2p::transport::transports.GetRandomPeer (); - if (r && !r->GetProfile ()->IsBad () && + if (r && r->IsECIES () && !r->GetProfile ()->IsBad () && (numHops > 1 || (r->IsV4 () && (!inbound || r->IsReachable ())))) // first inbound must be reachable { prevHop = r; @@ -469,6 +469,7 @@ namespace tunnel { LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected"); hop = i2p::transport::transports.GetRandomPeer (); + if (!hop->IsECIES ()) hop = nullptr; } if (!hop) { @@ -513,7 +514,15 @@ namespace tunnel auto& ident = (*m_ExplicitPeers)[i]; auto r = i2p::data::netdb.FindRouter (ident); if (r) - path.Add (r); + { + if (r->IsECIES ()) + path.Add (r); + else + { + LogPrint (eLogError, "Tunnels: ElGamal router ", ident.ToBase64 (), " is not supported"); + return false; + } + } else { LogPrint (eLogInfo, "Tunnels: Can't find router for ", ident.ToBase64 ()); From 6b1ef6e1b97081617816a95e8bea3be86dd1ea79 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 3 Sep 2021 23:25:47 +0300 Subject: [PATCH 0302/2193] tunnels reload changes: fix tcp tunnels reload Signed-off-by: R4SAS --- libi2pd_client/ClientContext.cpp | 132 ++++++++++++++++++++----------- libi2pd_client/ClientContext.h | 3 +- libi2pd_client/I2PTunnel.cpp | 10 ++- libi2pd_client/I2PTunnel.h | 10 ++- 4 files changed, 100 insertions(+), 55 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 6e9ac391..41efa611 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -185,7 +185,7 @@ namespace client LogPrint(eLogInfo, "Clients: stopping AddressBook"); m_AddressBook.Stop (); - { + { std::lock_guard lock(m_ForwardsMutex); m_ServerForwards.clear(); m_ClientForwards.clear(); @@ -200,6 +200,8 @@ namespace client for (auto& it: m_Destinations) it.second->Stop (); m_Destinations.clear (); + + m_SharedLocalDestination->Release (); m_SharedLocalDestination = nullptr; } @@ -209,14 +211,6 @@ namespace client /*std::string config; i2p::config::GetOption("conf", config); i2p::config::ParseConfig(config);*/ - // handle tunnels - // reset isUpdated for each tunnel - VisitTunnels ([](I2PService * s)->bool { s->isUpdated = false; return true; }); - // reload tunnels - ReadTunnels(); - // delete not updated tunnels (not in config anymore) - VisitTunnels ([](I2PService * s)->bool { return s->isUpdated; }); - // change shared local destination m_SharedLocalDestination->Release (); CreateNewSharedLocalDestination (); @@ -225,6 +219,7 @@ namespace client if (m_HttpProxy) { m_HttpProxy->Stop (); + delete m_HttpProxy; m_HttpProxy = nullptr; } ReadHttpProxy (); @@ -233,10 +228,19 @@ namespace client if (m_SocksProxy) { m_SocksProxy->Stop (); + delete m_SocksProxy; m_SocksProxy = nullptr; } ReadSocksProxy (); + // handle tunnels + // reset isUpdated for each tunnel + VisitTunnels (false); + // reload tunnels + ReadTunnels(); + // delete not updated tunnels (not in config anymore) + VisitTunnels (true); + // delete unused destinations std::unique_lock l(m_DestinationsMutex); for (auto it = m_Destinations.begin (); it != m_Destinations.end ();) @@ -504,20 +508,15 @@ namespace client int numClientTunnels = 0, numServerTunnels = 0; std::string tunConf; i2p::config::GetOption("tunconf", tunConf); if (tunConf.empty ()) - { - // TODO: cleanup this in 2.8.0 - tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); - if (i2p::fs::Exists(tunConf)) - LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); - else - tunConf = i2p::fs::DataDirPath ("tunnels.conf"); - } + tunConf = i2p::fs::DataDirPath ("tunnels.conf"); + LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf); ReadTunnels (tunConf, numClientTunnels, numServerTunnels); std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir); if (tunDir.empty ()) tunDir = i2p::fs::DataDirPath ("tunnels.d"); + if (i2p::fs::Exists (tunDir)) { std::vector files; @@ -582,7 +581,7 @@ namespace client if (it != destinations.end ()) localDestination = it->second; else - { + { i2p::data::PrivateKeys k; if(LoadPrivateKeys (k, keys, sigType, cryptoType)) { @@ -597,7 +596,7 @@ namespace client destinations[keys] = localDestination; } } - } + } } if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { @@ -609,10 +608,18 @@ namespace client bool gzip = section.second.get (I2P_CLIENT_TUNNEL_GZIP, true); auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort, gzip); - if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second) + + auto ins = m_ClientForwards.insert(std::make_pair(end, clientTunnel)); + if (ins.second) + { clientTunnel->Start(); + numClientTunnels++; + } else + { + ins.first->second->isUpdated = true; LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists"); + } } else { boost::asio::ip::tcp::endpoint clientEndpoint; @@ -666,13 +673,16 @@ namespace client if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ()) { LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated"); + ins.first->second->Stop (); ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ()); + ins.first->second->Start (); } ins.first->second->isUpdated = true; LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists"); } } } + else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP || type == I2P_TUNNELS_SECTION_TYPE_IRC @@ -705,17 +715,17 @@ namespace client if (it != destinations.end ()) localDestination = it->second; else - { + { i2p::data::PrivateKeys k; if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) continue; localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); if (!localDestination) - { + { localDestination = CreateNewLocalDestination (k, true, &options); destinations[keys] = localDestination; - } - } + } + } if (type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { // udp server tunnel @@ -727,8 +737,8 @@ namespace client address = "::1"; else address = "127.0.0.1"; - } - auto localAddress = boost::asio::ip::address::from_string(address); + } + auto localAddress = boost::asio::ip::address::from_string(address); auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); if(!isUniqueLocal) { @@ -736,16 +746,16 @@ namespace client serverTunnel->SetUniqueLocal(isUniqueLocal); } std::lock_guard lock(m_ForwardsMutex); - if(m_ServerForwards.insert( - std::make_pair( - std::make_pair( - localDestination->GetIdentHash(), port), - serverTunnel)).second) + auto ins = m_ServerForwards.insert(std::make_pair( + std::make_pair(localDestination->GetIdentHash(), port), + serverTunnel)); + if (ins.second) { serverTunnel->Start(); LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32()); } else + ins.first->second->isUpdated = true; LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, "already exists"); continue; @@ -795,7 +805,9 @@ namespace client if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ()) { LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated"); + ins.first->second->Stop (); ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ()); + ins.first->second->Start (); } ins.first->second->isUpdated = true; LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); @@ -872,7 +884,7 @@ namespace client { localDestination = m_HttpProxy->GetLocalDestination (); localDestination->Acquire (); - } + } else if (socksProxyKeys.length () > 0) { i2p::data::PrivateKeys keys; @@ -920,27 +932,51 @@ namespace client } } - template - void VisitTunnelsContainer (Container& c, Visitor v) + void ClientContext::VisitTunnels (bool clean) { - for (auto it = c.begin (); it != c.end ();) + for (auto it = m_ClientTunnels.begin (); it != m_ClientTunnels.end ();) { - if (!v (it->second.get ())) - { + if(clean && !it->second->isUpdated) { it->second->Stop (); - it = c.erase (it); - } - else + it = m_ClientTunnels.erase(it); + } else { + it->second->isUpdated = false; it++; + } + } + + for (auto it = m_ServerTunnels.begin (); it != m_ServerTunnels.end ();) + { + if(clean && !it->second->isUpdated) { + it->second->Stop (); + it = m_ServerTunnels.erase(it); + } else { + it->second->isUpdated = false; + it++; + } + } + + for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();) + { + if(clean && !it->second->isUpdated) { + it->second = nullptr; + it = m_ClientForwards.erase(it); + } else { + it->second->isUpdated = false; + it++; + } + } + + for (auto it = m_ServerForwards.begin (); it != m_ServerForwards.end ();) + { + if(clean && !it->second->isUpdated) { + it->second = nullptr; + it = m_ServerForwards.erase(it); + } else { + it->second->isUpdated = false; + it++; + } } } - - template - void ClientContext::VisitTunnels (Visitor v) - { - VisitTunnelsContainer (m_ClientTunnels, v); - VisitTunnelsContainer (m_ServerTunnels, v); - // TODO: implement UDP forwards - } } } diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 076aaa5f..90a21a60 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -121,8 +121,7 @@ namespace client void CleanupUDP(const boost::system::error_code & ecode); void ScheduleCleanupUDP(); - template - void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain + void VisitTunnels (bool clean); void CreateNewSharedLocalDestination (); void AddLocalDestination (std::shared_ptr localDestination); diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index e8a66228..c01f0fe3 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -303,7 +303,7 @@ namespace client m_ProxyConnectionSent = true; } else - m_OutHeader << line << "\n"; + m_OutHeader << line << "\n"; } } else @@ -888,7 +888,8 @@ namespace client LogPrint(eLogInfo, "UDPServer: done"); } - void I2PUDPServerTunnel::Start() { + void I2PUDPServerTunnel::Start() + { m_LocalDest->Start(); } @@ -1064,8 +1065,9 @@ namespace client else LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); } - - I2PUDPClientTunnel::~I2PUDPClientTunnel() { + + I2PUDPClientTunnel::~I2PUDPClientTunnel() + { auto dgram = m_LocalDest->GetDatagramDestination(); if (dgram) dgram->ResetReceiver(); diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 3b52ea1a..1db34b6c 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -254,6 +254,10 @@ namespace client std::vector m_Sessions; std::shared_ptr m_LocalDest; UDPSessionPtr m_LastSession; + + public: + + bool isUpdated; // transient, used during reload only }; class I2PUDPClientTunnel @@ -283,7 +287,7 @@ namespace client void TryResolving(); private: - + const std::string m_Name; std::mutex m_SessionsMutex; std::unordered_map > m_Sessions; // maps i2p port -> local udp convo @@ -298,6 +302,10 @@ namespace client uint16_t RemotePort, m_LastPort; bool m_cancel_resolve; std::shared_ptr m_LastSession; + + public: + + bool isUpdated; // transient, used during reload only }; class I2PServerTunnel: public I2PService From 3f46ca41cad15f5bf5c66b53581d7ff48fa6811d Mon Sep 17 00:00:00 2001 From: yangfl Date: Sat, 4 Sep 2021 15:07:09 +0800 Subject: [PATCH 0303/2193] disable pthread_setname_np on GNU/Hurd which does not exist on GNU/Hurd --- libi2pd/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index f7b376f6..2b5c79f2 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -129,7 +129,7 @@ namespace util pthread_set_name_np(pthread_self(), name); #elif defined(__NetBSD__) pthread_setname_np(pthread_self(), "%s", (void *)name); -#else +#elif !defined(__gnu_hurd__) pthread_setname_np(pthread_self(), name); #endif } From bce8469e59ca714c06ea35b6898517f89c35b114 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 08:53:39 -0400 Subject: [PATCH 0304/2193] eliminate extra error message --- libi2pd_client/ClientContext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 41efa611..a0ebb315 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -755,8 +755,10 @@ namespace client LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32()); } else + { ins.first->second->isUpdated = true; - LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, "already exists"); + LogPrint(eLogError, "Clients: I2P Server Forward for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash()), "/", port, " already exists"); + } continue; } From e8f4c42bfb297ec8d5ee64d9889b47685acfbdd6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 14:01:57 -0400 Subject: [PATCH 0305/2193] moved current language from RouterContext to ClientContext --- daemon/HTTPServer.cpp | 6 +++--- i18n/I18N.h | 10 +++++----- libi2pd/RouterContext.h | 8 -------- libi2pd_client/ClientContext.h | 8 ++++++++ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ac83f87c..c2aee205 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -240,7 +240,7 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); // Page language - std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + std::string currLang = i2p::client::context.GetLanguage ()->GetLanguage(); // get current used language auto it = i2p::i18n::languages.find(currLang); std::string langCode = it->second.ShortCode; @@ -766,7 +766,7 @@ namespace http { s << " \r\n"; s << "\r\n
\r\n"; - std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); // get current used language + std::string currLang = i2p::client::context.GetLanguage ()->GetLanguage(); // get current used language s << "" << tr("Change language") << "
\r\n"; s << "
\r\n"; s << " \r\n"; @@ -1382,7 +1382,7 @@ namespace http { else if (cmd == HTTP_COMMAND_SETLANGUAGE) { std::string lang = params["lang"]; - std::string currLang = i2p::context.GetLanguage ()->GetLanguage(); + std::string currLang = i2p::client::context.GetLanguage ()->GetLanguage(); if (currLang.compare(lang) != 0) i2p::i18n::SetLanguage(lang); diff --git a/i18n/I18N.h b/i18n/I18N.h index 03add48d..5024fb56 100644 --- a/i18n/I18N.h +++ b/i18n/I18N.h @@ -9,7 +9,7 @@ #ifndef __I18N_H__ #define __I18N_H__ -#include "RouterContext.h" +#include "ClientContext.h" namespace i2p { @@ -19,19 +19,19 @@ namespace i18n { const auto it = i2p::i18n::languages.find(lang); if (it == i2p::i18n::languages.end()) // fallback - i2p::context.SetLanguage (i2p::i18n::english::GetLocale()); + i2p::client::context.SetLanguage (i2p::i18n::english::GetLocale()); else - i2p::context.SetLanguage (it->second.LocaleFunc()); + i2p::client::context.SetLanguage (it->second.LocaleFunc()); } inline std::string translate (const std::string& arg) { - return i2p::context.GetLanguage ()->GetString (arg); + return i2p::client::context.GetLanguage ()->GetString (arg); } inline std::string translate (const std::string& arg, const std::string& arg2, const int& n) { - return i2p::context.GetLanguage ()->GetPlural (arg, arg2, n); + return i2p::client::context.GetLanguage ()->GetPlural (arg, arg2, n); } } // i18n } // i2p diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 98ee6a72..3535f1ac 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -18,7 +18,6 @@ #include "Identity.h" #include "RouterInfo.h" #include "Garlic.h" -#include "I18N_langs.h" namespace i2p { @@ -146,10 +145,6 @@ namespace garlic void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatusMessage (std::shared_ptr msg); - // i18n - std::shared_ptr GetLanguage () { return m_Language; }; - void SetLanguage (const std::shared_ptr language) { m_Language = language; }; - protected: // implements GarlicDestination @@ -186,9 +181,6 @@ namespace garlic std::unique_ptr m_StaticKeys; // for ECIESx25519 i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; - - // i18n - std::shared_ptr m_Language; }; extern RouterContext context; diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 90a21a60..801dc0cd 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -22,6 +22,7 @@ #include "BOB.h" #include "I2CP.h" #include "AddressBook.h" +#include "I18N_langs.h" namespace i2p { @@ -102,6 +103,10 @@ namespace client std::vector > GetForwardInfosFor(const i2p::data::IdentHash & destination); + // i18n + std::shared_ptr GetLanguage () { return m_Language; }; + void SetLanguage (const std::shared_ptr language) { m_Language = language; }; + private: void ReadTunnels (); @@ -149,6 +154,9 @@ namespace client std::unique_ptr m_CleanupUDPTimer; + // i18n + std::shared_ptr m_Language; + public: // for HTTP From 41d6c117ee2063c4328d9e35d77eaaf2016de4e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 18:45:32 -0400 Subject: [PATCH 0306/2193] make sure server tunnel is published --- libi2pd/Destination.h | 1 + libi2pd_client/ClientContext.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 9e63d9bb..0dc5450b 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -139,6 +139,7 @@ namespace client void SetLeaseSetUpdated (); bool IsPublic () const { return m_IsPublic; }; + void SetPublic (bool pub) { m_IsPublic = pub; }; protected: diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index a0ebb315..081fa67d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -713,7 +713,10 @@ namespace client std::shared_ptr localDestination = nullptr; auto it = destinations.find (keys); if (it != destinations.end ()) + { localDestination = it->second; + localDestination->SetPublic (true); + } else { i2p::data::PrivateKeys k; @@ -725,6 +728,8 @@ namespace client localDestination = CreateNewLocalDestination (k, true, &options); destinations[keys] = localDestination; } + else + localDestination->SetPublic (true); } if (type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { From 3a77e7ba2dc892d75c4a823901aab31324bab86c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 4 Sep 2021 18:55:51 -0400 Subject: [PATCH 0307/2193] remove dependancy from localization --- tests/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 89fceeec..8eb52fde 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,7 +1,5 @@ CXXFLAGS += -Wall -Wno-unused-parameter -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -pthread -Wl,--unresolved-symbols=ignore-in-object-files -INCFLAGS += -I../libi2pd -I../i18n - -LOCALESRC = ../i18n/Afrikaans.cpp ../i18n/English.cpp ../i18n/Russian.cpp ../i18n/Turkmen.cpp ../i18n/Ukrainian.cpp ../i18n/Uzbek.cpp +INCFLAGS += -I../libi2pd TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator @@ -25,7 +23,7 @@ test-x25519: ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi2pd/Poly1305.cpp test-aeadchacha20poly1305.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system -test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp $(LOCALESRC) test-blinding.cpp +test-blinding: ../libi2pd/Crypto.cpp ../libi2pd/Blinding.cpp ../libi2pd/Ed25519.cpp ../libi2pd/I2PEndian.cpp ../libi2pd/Log.cpp ../libi2pd/util.cpp ../libi2pd/Identity.cpp ../libi2pd/Signature.cpp ../libi2pd/Timestamp.cpp test-blinding.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system test-elligator: ../libi2pd/Elligator.cpp ../libi2pd/Crypto.cpp test-elligator.cpp From c76347291429164f977e6e30de5c21804e2e7697 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 08:41:32 -0400 Subject: [PATCH 0308/2193] select ECIES routers only for peer tests and introducers --- libi2pd/NetDb.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 7c473a09..2ac5408c 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1181,8 +1181,8 @@ namespace data return GetRandomRouter ( [v4, &excluded](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsPeerTesting (v4) && - !excluded.count (router->GetIdentHash ()); + return !router->IsHidden () && router->IsECIES () && + router->IsPeerTesting (v4) && !excluded.count (router->GetIdentHash ()); }); } @@ -1191,7 +1191,7 @@ namespace data return GetRandomRouter ( [](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsSSUV6 (); + return !router->IsHidden () && router->IsECIES () && router->IsSSUV6 (); }); } @@ -1200,8 +1200,8 @@ namespace data return GetRandomRouter ( [v4, &excluded](std::shared_ptr router)->bool { - return router->IsIntroducer (v4) && !excluded.count (router->GetIdentHash ()) && - !router->IsHidden () && !router->IsFloodfill (); // floodfills don't send relay tag + return !router->IsHidden () && router->IsECIES () && !router->IsFloodfill () && // floodfills don't send relay tag + router->IsIntroducer (v4) && !excluded.count (router->GetIdentHash ()); }); } From a54b5c18c63d97a2e1f93b5e66b63cdf13cfe84b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 09:08:29 -0400 Subject: [PATCH 0309/2193] fixed crash --- libi2pd/TunnelPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b885f69f..05eed7e5 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -469,7 +469,7 @@ namespace tunnel { LogPrint (eLogInfo, "Tunnels: Can't select first hop for a tunnel. Trying already connected"); hop = i2p::transport::transports.GetRandomPeer (); - if (!hop->IsECIES ()) hop = nullptr; + if (hop && !hop->IsECIES ()) hop = nullptr; } if (!hop) { From 76dca1b46b2b19b2937dc65c2358682891dc483c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 09:10:13 -0400 Subject: [PATCH 0310/2193] don't handle ElGamal build record --- libi2pd/I2NPProtocol.cpp | 133 +++++++++------------------------------ libi2pd/I2NPProtocol.h | 21 ------- 2 files changed, 29 insertions(+), 125 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 54924451..07ecb19e 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -391,76 +391,48 @@ namespace i2p LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours"); if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; - bool isECIES = i2p::context.IsECIES (); // replace record to reply if (i2p::context.AcceptsTunnels () && i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && !i2p::transport::transports.IsBandwidthExceeded () && !i2p::transport::transports.IsTransitBandwidthExceeded ()) { - auto transitTunnel = isECIES ? - i2p::tunnel::CreateTransitTunnel ( + auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), clearText + ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, - clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) : - i2p::tunnel::CreateTransitTunnel ( - bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), - clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, - clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); } else retCode = 30; // always reject with bandwidth reason (30) - if (isECIES) - { - memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options - record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode; - } - else - { - record[BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode; - SHA256 (record + BUILD_RESPONSE_RECORD_PADDING_OFFSET, BUILD_RESPONSE_RECORD_PADDING_SIZE + 1, // + 1 byte of ret - record + BUILD_RESPONSE_RECORD_HASH_OFFSET); - } + memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options + record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode; // encrypt reply i2p::crypto::CBCEncryption encryption; for (int j = 0; j < num; j++) { uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE; - if (isECIES) - { - if (j == i) + if (j == i) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + auto& noiseState = i2p::context.GetCurrentNoiseState (); + if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16, + noiseState.m_H, 32, noiseState.m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt { - uint8_t nonce[12]; - memset (nonce, 0, 12); - auto& noiseState = i2p::context.GetCurrentNoiseState (); - if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16, - noiseState.m_H, 32, noiseState.m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt - { - LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); - return false; - } - } - else - { - encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); - encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); + LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); + return false; } } else - { - encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); + { + encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); + encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); } } @@ -499,75 +471,28 @@ namespace i2p } else { - if (i2p::context.IsECIES ()) + uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + if (HandleBuildRequestRecords (num, buf + 1, clearText)) { - uint8_t clearText[ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (num, buf + 1, clearText)) + if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel { - if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel - { - // so we send it to reply tunnel - transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - eI2NPVariableTunnelBuildReply, buf, len, - bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - else - transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, - bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); + // so we send it to reply tunnel + transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateTunnelGatewayMsg (bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), + eI2NPVariableTunnelBuildReply, buf, len, + bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } + else + transports.SendMessage (clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, + CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, + bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } - else - { - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (num, buf + 1, clearText)) - { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outboud tunnel - { - // so we send it to reply tunnel - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - eI2NPVariableTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - else - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - } } } static void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { - if (i2p::context.IsECIES ()) - { - LogPrint (eLogWarning, "I2NP: TunnelBuild is too old for ECIES router"); - return; - } - if (len < NUM_TUNNEL_BUILD_RECORDS*TUNNEL_BUILD_RECORD_SIZE) - { - LogPrint (eLogError, "I2NP: TunnelBuild message is too short ", len); - return; - } - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (NUM_TUNNEL_BUILD_RECORDS, buf, clearText)) - { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG) // we are endpoint of outbound tunnel - { - // so we send it to reply tunnel - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), - eI2NPTunnelBuildReply, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } - else - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPTunnelBuild, buf, len, - bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); - } + LogPrint (eLogWarning, "I2NP: TunnelBuild is too old for ECIES router"); } static void HandleTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len, bool isShort) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 32aebbb2..f0777ac2 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -57,31 +57,10 @@ namespace i2p const size_t TUNNEL_BUILD_RECORD_SIZE = 528; const size_t SHORT_TUNNEL_BUILD_RECORD_SIZE = 218; - //BuildRequestRecordClearText - const size_t BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; - const size_t BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET = BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET = BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET = BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_IV_KEY_OFFSET = BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET = BUILD_REQUEST_RECORD_IV_KEY_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_REPLY_IV_OFFSET = BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET + 32; - const size_t BUILD_REQUEST_RECORD_FLAG_OFFSET = BUILD_REQUEST_RECORD_REPLY_IV_OFFSET + 16; - const size_t BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET = BUILD_REQUEST_RECORD_FLAG_OFFSET + 1; - const size_t BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_PADDING_OFFSET = BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; - const size_t BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 222; - // BuildRequestRecordEncrypted const size_t BUILD_REQUEST_RECORD_TO_PEER_OFFSET = 0; const size_t BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET = BUILD_REQUEST_RECORD_TO_PEER_OFFSET + 16; - // BuildResponseRecord - const size_t BUILD_RESPONSE_RECORD_HASH_OFFSET = 0; - const size_t BUILD_RESPONSE_RECORD_PADDING_OFFSET = 32; - const size_t BUILD_RESPONSE_RECORD_PADDING_SIZE = 495; - const size_t BUILD_RESPONSE_RECORD_RET_OFFSET = BUILD_RESPONSE_RECORD_PADDING_OFFSET + BUILD_RESPONSE_RECORD_PADDING_SIZE; - // ECIES BuildRequestRecordClearText const size_t ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET = 0; const size_t ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET = ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET + 4; From 292fe94352d4b55fed148edb6a37be87717b5b7b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 5 Sep 2021 11:16:41 -0400 Subject: [PATCH 0311/2193] RouterContext is always ECIES --- libi2pd/I2NPProtocol.cpp | 5 ---- libi2pd/RouterContext.cpp | 56 +++++++++++++-------------------------- libi2pd/RouterContext.h | 1 - 3 files changed, 18 insertions(+), 44 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 07ecb19e..5a2fa9c1 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -528,11 +528,6 @@ namespace i2p static void HandleShortTunnelBuildMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { - if (!i2p::context.IsECIES ()) - { - LogPrint (eLogWarning, "I2NP: ShortTunnelBuild can be handled by ECIES router only"); - return; - } int num = buf[0]; LogPrint (eLogDebug, "I2NP: ShortTunnelBuild ", num, " records"); if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 1a2dd335..3710092b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -43,11 +43,8 @@ namespace i2p m_Decryptor = m_Keys.CreateDecryptor (nullptr); m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr); UpdateRouterInfo (); - if (IsECIES ()) - { - i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ()); - m_ECIESSession = std::make_shared(m_InitialNoiseState); - } + i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ()); + m_ECIESSession = std::make_shared(m_InitialNoiseState); } void RouterContext::CreateNewRouter () @@ -833,27 +830,22 @@ namespace i2p void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); - if (IsECIES ()) + uint8_t * buf = msg->GetPayload (); + uint32_t len = bufbe32toh (buf); + if (len > msg->GetLength ()) { - uint8_t * buf = msg->GetPayload (); - uint32_t len = bufbe32toh (buf); - if (len > msg->GetLength ()) - { - LogPrint (eLogWarning, "Router: garlic message length ", len, " exceeds I2NP message length ", msg->GetLength ()); - return; - } - buf += 4; - if (!HandleECIESx25519TagMessage (buf, len)) // try tag first - { - // then Noise_N one-time decryption - if (m_ECIESSession) - m_ECIESSession->HandleNextMessage (buf, len); - else - LogPrint (eLogError, "Router: Session is not set for ECIES router"); - } + LogPrint (eLogWarning, "Router: garlic message length ", len, " exceeds I2NP message length ", msg->GetLength ()); + return; } - else - i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); + buf += 4; + if (!HandleECIESx25519TagMessage (buf, len)) // try tag first + { + // then Noise_N one-time decryption + if (m_ECIESSession) + m_ECIESSession->HandleNextMessage (buf, len); + else + LogPrint (eLogError, "Router: Session is not set for ECIES router"); + } } void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) @@ -885,13 +877,7 @@ namespace i2p bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) { - if (IsECIES ()) - return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); - else - { - LogPrint (eLogError, "Router: Non-ECIES router is not longer supported"); - return false; - } + return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); } bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize) @@ -921,13 +907,7 @@ namespace i2p bool RouterContext::DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data) { - if (IsECIES ()) - return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); - else - { - LogPrint (eLogError, "Router: Can't decrypt short request record on non-ECIES router"); - return false; - } + return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); } i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 3535f1ac..647c1a7f 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -123,7 +123,6 @@ namespace garlic void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host); - bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; }; void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove From 20652f799569039470416e8997d6a25892cb4734 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Sep 2021 15:12:53 -0400 Subject: [PATCH 0312/2193] resseed if too few floodfills --- libi2pd/NetDb.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 2ac5408c..9c079d57 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -55,8 +55,10 @@ namespace data Load (); uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold); - if (m_RouterInfos.size () < threshold) // reseed if # of router less than threshold + if (m_RouterInfos.size () < threshold || m_Floodfills.size () < NETDB_MIN_FLOODFILLS) // reseed if # of router less than threshold or too few floodfiils + { Reseed (); + } else if (!GetRandomRouter (i2p::context.GetSharedRouterInfo (), false)) Reseed (); // we don't have a router we can connect to. Trying to reseed From ad036de69d3009bf55efce21aa083c3c72529a10 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Sep 2021 21:19:52 -0400 Subject: [PATCH 0313/2193] eliminate allocation of m_ExtendedBuffer --- libi2pd/Identity.cpp | 33 ++++++++++++--------------------- libi2pd/Identity.h | 5 +++-- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 9dfaa1fc..aa03bfb7 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -42,7 +42,7 @@ namespace data } IdentityEx::IdentityEx (): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { } @@ -119,11 +119,15 @@ namespace data m_StandardIdentity.certificate[0] = CERTIFICATE_TYPE_KEY; htobe16buf (m_StandardIdentity.certificate + 1, m_ExtendedLen); // fill extended buffer - m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; htobe16buf (m_ExtendedBuffer, type); htobe16buf (m_ExtendedBuffer + 2, cryptoType); if (excessLen && excessBuf) { + if (excessLen > MAX_EXTENDED_BUFFER_SIZE - 4) + { + LogPrint (eLogError, "Identity: Unexpected excessive signing key len ", excessLen); + excessLen = MAX_EXTENDED_BUFFER_SIZE - 4; + } memcpy (m_ExtendedBuffer + 4, excessBuf, excessLen); delete[] excessBuf; } @@ -136,7 +140,6 @@ namespace data memset (m_StandardIdentity.certificate, 0, sizeof (m_StandardIdentity.certificate)); m_IdentHash = m_StandardIdentity.Hash (); m_ExtendedLen = 0; - m_ExtendedBuffer = nullptr; } CreateVerifier (); } @@ -154,26 +157,25 @@ namespace data } IdentityEx::IdentityEx (const uint8_t * buf, size_t len): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { FromBuffer (buf, len); } IdentityEx::IdentityEx (const IdentityEx& other): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { *this = other; } IdentityEx::IdentityEx (const Identity& standard): - m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0) { *this = standard; } IdentityEx::~IdentityEx () { - delete[] m_ExtendedBuffer; delete m_Verifier; } @@ -182,15 +184,12 @@ namespace data memcpy (&m_StandardIdentity, &other.m_StandardIdentity, DEFAULT_IDENTITY_SIZE); m_IdentHash = other.m_IdentHash; - delete[] m_ExtendedBuffer; m_ExtendedLen = other.m_ExtendedLen; if (m_ExtendedLen > 0) { - m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); } - else - m_ExtendedBuffer = nullptr; delete m_Verifier; m_Verifier = nullptr; @@ -203,8 +202,6 @@ namespace data m_StandardIdentity = standard; m_IdentHash = m_StandardIdentity.Hash (); - delete[] m_ExtendedBuffer; - m_ExtendedBuffer = nullptr; m_ExtendedLen = 0; delete m_Verifier; @@ -222,15 +219,12 @@ namespace data } memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE); - if(m_ExtendedBuffer) delete[] m_ExtendedBuffer; - m_ExtendedBuffer = nullptr; - m_ExtendedLen = bufbe16toh (m_StandardIdentity.certificate + 1); if (m_ExtendedLen) { if (m_ExtendedLen + DEFAULT_IDENTITY_SIZE <= len) { - m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; + if (m_ExtendedLen > MAX_EXTENDED_BUFFER_SIZE) m_ExtendedLen = MAX_EXTENDED_BUFFER_SIZE; memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); } else @@ -241,10 +235,7 @@ namespace data } } else - { m_ExtendedLen = 0; - m_ExtendedBuffer = nullptr; - } SHA256(buf, GetFullLen (), m_IdentHash); delete m_Verifier; @@ -258,7 +249,7 @@ namespace data const size_t fullLen = GetFullLen(); if (fullLen > len) return 0; // buffer is too small and may overflow somewhere else memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE); - if (m_ExtendedLen > 0 && m_ExtendedBuffer) + if (m_ExtendedLen > 0) memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen); return fullLen; } diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index b52f36cf..f96d5f41 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -84,8 +84,9 @@ namespace data typedef uint16_t SigningKeyType; typedef uint16_t CryptoKeyType; + const size_t MAX_EXTENDED_BUFFER_SIZE = 8; // cryptoKeyType + signingKeyType + 4 extra bytes of P521 class IdentityEx - { + { public: IdentityEx (); @@ -137,7 +138,7 @@ namespace data mutable i2p::crypto::Verifier * m_Verifier = nullptr; mutable std::mutex m_VerifierMutex; size_t m_ExtendedLen; - uint8_t * m_ExtendedBuffer; + uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; }; class PrivateKeys // for eepsites From 5e2e1a1e3d08e563b9d4db656c17325507df1de9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Sep 2021 19:57:38 -0400 Subject: [PATCH 0314/2193] don't include old tunnel to LeaseSet if recreated --- libi2pd/Tunnel.cpp | 6 +++--- libi2pd/Tunnel.h | 6 +++--- libi2pd/TunnelPool.cpp | 13 +++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index e7b38686..76504e1f 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -692,7 +692,7 @@ namespace tunnel // let it die if the tunnel pool has been reconfigured and this is old if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops()) { - tunnel->SetIsRecreated (); + tunnel->SetRecreated (true); pool->RecreateOutboundTunnel (tunnel); } } @@ -746,7 +746,7 @@ namespace tunnel // let it die if the tunnel pool was reconfigured and has different number of hops if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops()) { - tunnel->SetIsRecreated (); + tunnel->SetRecreated (true); pool->RecreateInboundTunnel (tunnel); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index acfa21e8..a1fd247a 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -76,7 +76,7 @@ namespace tunnel bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; bool IsFailed () const { return m_State == eTunnelStateFailed; }; bool IsRecreated () const { return m_IsRecreated; }; - void SetIsRecreated () { m_IsRecreated = true; }; + void SetRecreated (bool recreated) { m_IsRecreated = recreated; }; int GetNumHops () const { return m_Hops.size (); }; virtual bool IsInbound() const = 0; @@ -111,7 +111,7 @@ namespace tunnel std::vector > m_Hops; std::shared_ptr m_Pool; // pool, tunnel belongs to, or null TunnelState m_State; - bool m_IsRecreated; + bool m_IsRecreated; // if tunnel is replaced by new, or new tunnel requested to replace uint64_t m_Latency; // in milliseconds }; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 05eed7e5..7a5721fb 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -113,6 +113,17 @@ namespace tunnel if (!m_IsActive) return; { std::unique_lock l(m_InboundTunnelsMutex); + if (createdTunnel->IsRecreated ()) + { + // find and mark old tunnel as expired + createdTunnel->SetRecreated (false); + for (auto& it: m_InboundTunnels) + if (it->IsRecreated () && it->GetNextIdentHash () == createdTunnel->GetNextIdentHash ()) + { + it->SetState (eTunnelStateExpiring); + break; + } + } m_InboundTunnels.insert (createdTunnel); } if (m_LocalDestination) @@ -577,6 +588,8 @@ namespace tunnel auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); + else + newTunnel->SetRecreated (true); } } From e054c6e82caa489285f8abb9a3165930272d7478 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 Sep 2021 18:58:27 -0400 Subject: [PATCH 0315/2193] memory pool for SSU messages and fragments --- libi2pd/SSU.cpp | 5 +++++ libi2pd/SSU.h | 11 ++++++++++- libi2pd/SSUData.cpp | 20 ++++++++++---------- libi2pd/SSUData.h | 12 ++++++------ libi2pd/SSUSession.h | 3 ++- libi2pd/util.h | 11 ++++++++--- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f3da611c..a4fec82e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -919,6 +919,11 @@ namespace transport } if (numDeleted > 0) LogPrint (eLogDebug, "SSU: ", numDeleted, " peer tests have been expired"); + // some cleaups. TODO: use separate timer + m_FragmentsPool.CleanUp (); + m_IncompleteMessagesPool.CleanUp (); + m_SentMessagesPool.CleanUp (); + SchedulePeerTestsCleanupTimer (); } } diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index aad3a384..586d7089 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -18,6 +18,7 @@ #include #include #include "Crypto.h" +#include "util.h" #include "I2PEndian.h" #include "Identity.h" #include "RouterInfo.h" @@ -63,6 +64,10 @@ namespace transport void DeleteAllSessions (); boost::asio::io_service& GetService () { return m_Service; }; + i2p::util::MemoryPool& GetFragmentsPool () { return m_FragmentsPool; }; + i2p::util::MemoryPool& GetIncompleteMessagesPool () { return m_IncompleteMessagesPool; }; + i2p::util::MemoryPool& GetSentMessagesPool () { return m_SentMessagesPool; }; + uint16_t GetPort () const { return m_Endpoint.port (); }; void SetLocalAddress (const boost::asio::ip::address& localAddress); @@ -136,6 +141,10 @@ namespace transport std::map > m_Relays; // we are introducer std::map m_PeerTests; // nonce -> creation time in milliseconds + i2p::util::MemoryPool m_FragmentsPool; + i2p::util::MemoryPool m_IncompleteMessagesPool; + i2p::util::MemoryPool m_SentMessagesPool; + public: // for HTTP only const decltype(m_Sessions)& GetSessions () const { return m_Sessions; }; diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 5458cc97..2c6f72e1 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -140,7 +140,7 @@ namespace transport if (bitfield & mask) { if (fragment < numSentFragments) - it->second->fragments[fragment].reset (nullptr); + it->second->fragments[fragment] = nullptr; } fragment++; mask <<= 1; @@ -182,9 +182,9 @@ namespace transport auto msg = NewI2NPShortMessage (); msg->len -= I2NP_SHORT_HEADER_SIZE; it = m_IncompleteMessages.insert (std::make_pair (msgID, - std::unique_ptr(new IncompleteMessage (msg)))).first; + m_Session.GetServer ().GetIncompleteMessagesPool ().AcquireShared (msg))).first; } - std::unique_ptr& incompleteMessage = it->second; + auto& incompleteMessage = it->second; // mark fragment as received if (fragmentNum < 64) incompleteMessage->receivedFragmentsBits |= (0x01 << fragmentNum); @@ -224,8 +224,8 @@ namespace transport { // missing fragment LogPrint (eLogWarning, "SSU: Missing fragments from ", (int)incompleteMessage->nextFragmentNum, " to ", fragmentNum - 1, " of message ", msgID); - auto savedFragment = new Fragment (fragmentNum, buf, fragmentSize, isLast); - if (incompleteMessage->savedFragments.insert (std::unique_ptr(savedFragment)).second) + auto savedFragment = m_Session.GetServer ().GetFragmentsPool ().AcquireShared (fragmentNum, buf, fragmentSize, isLast); + if (incompleteMessage->savedFragments.insert (savedFragment).second) incompleteMessage->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); else LogPrint (eLogWarning, "SSU: Fragment ", (int)fragmentNum, " of message ", msgID, " already saved"); @@ -313,8 +313,8 @@ namespace transport if (m_SentMessages.empty ()) // schedule resend at first message only ScheduleResend (); - auto ret = m_SentMessages.insert (std::make_pair (msgID, std::unique_ptr(new SentMessage))); - std::unique_ptr& sentMessage = ret.first->second; + auto ret = m_SentMessages.insert (std::make_pair (msgID, m_Session.GetServer ().GetSentMessagesPool ().AcquireShared ())); + auto& sentMessage = ret.first->second; if (ret.second) { sentMessage->nextResendTime = i2p::util::GetSecondsSinceEpoch () + RESEND_INTERVAL; @@ -328,7 +328,7 @@ namespace transport uint32_t fragmentNum = 0; while (len > 0 && fragmentNum <= 127) { - Fragment * fragment = new Fragment; + auto fragment = m_Session.GetServer ().GetFragmentsPool ().AcquireShared (); fragment->fragmentNum = fragmentNum; uint8_t * payload = fragment->buf + sizeof (SSUHeader); *payload = DATA_FLAG_WANT_REPLY; // for compatibility @@ -358,7 +358,7 @@ namespace transport size += padding; } fragment->len = size; - fragments.push_back (std::unique_ptr (fragment)); + fragments.push_back (fragment); // encrypt message with session key uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 902c009a..1eb98b1d 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -64,7 +64,7 @@ namespace transport struct FragmentCmp { - bool operator() (const std::unique_ptr& f1, const std::unique_ptr& f2) const + bool operator() (const std::shared_ptr& f1, const std::shared_ptr& f2) const { return f1->fragmentNum < f2->fragmentNum; }; @@ -76,7 +76,7 @@ namespace transport int nextFragmentNum; uint32_t lastFragmentInsertTime; // in seconds uint64_t receivedFragmentsBits; - std::set, FragmentCmp> savedFragments; + std::set, FragmentCmp> savedFragments; IncompleteMessage (std::shared_ptr m): msg (m), nextFragmentNum (0), lastFragmentInsertTime (0), receivedFragmentsBits (0) {}; @@ -85,7 +85,7 @@ namespace transport struct SentMessage { - std::vector > fragments; + std::vector > fragments; uint32_t nextResendTime; // in seconds int numResends; }; @@ -126,8 +126,8 @@ namespace transport private: SSUSession& m_Session; - std::unordered_map > m_IncompleteMessages; - std::unordered_map > m_SentMessages; + std::unordered_map > m_IncompleteMessages; + std::unordered_map > m_SentMessages; std::unordered_set m_ReceivedMessages; boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; int m_MaxPacketSize, m_PacketSize; diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 43d0d595..462afc35 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -89,7 +89,8 @@ namespace transport void Done (); void Failed (); const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; - + SSUServer& GetServer () { return m_Server; }; + bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); }; void SendI2NPMessages (const std::vector >& msgs); void SendPeerTest (); // Alice diff --git a/libi2pd/util.h b/libi2pd/util.h index 000cb74e..282ce7aa 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -50,6 +50,11 @@ namespace util MemoryPool (): m_Head (nullptr) {} ~MemoryPool () + { + CleanUp (); + } + + void CleanUp () { while (m_Head) { @@ -57,8 +62,8 @@ namespace util m_Head = static_cast(*(void * *)m_Head); // next ::operator delete ((void *)tmp); } - } - + } + template T * Acquire (TArgs&&... args) { From f7f36568efb3f9b9feffc3d6a6caee9816dd237e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Sep 2021 14:29:43 -0400 Subject: [PATCH 0316/2193] set gzip compression to false by default --- libi2pd/Streaming.h | 2 +- libi2pd_client/ClientContext.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 9d206098..51fb03ab 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -261,7 +261,7 @@ namespace stream typedef std::function)> Acceptor; - StreamingDestination (std::shared_ptr owner, uint16_t localPort = 0, bool gzip = true); + StreamingDestination (std::shared_ptr owner, uint16_t localPort = 0, bool gzip = false); ~StreamingDestination (); void Start (); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 081fa67d..09516bb9 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -699,7 +699,7 @@ namespace client accessList=section.second.get (I2P_SERVER_TUNNEL_WHITE_LIST, ""); std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); - bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); + bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, false); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); From 247b6a0ed236202eb0d5778ef02d71044c8d3a92 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Sep 2021 13:13:27 -0400 Subject: [PATCH 0317/2193] memory pool for SSU packets --- libi2pd/SSU.cpp | 18 +++++++++--------- libi2pd/SSU.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index a4fec82e..86e76b8e 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -255,14 +255,14 @@ namespace transport void SSUServer::Receive () { - SSUPacket * packet = new SSUPacket (); + SSUPacket * packet = m_PacketsPool.AcquireMt (); m_Socket.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, std::bind (&SSUServer::HandleReceivedFrom, this, std::placeholders::_1, std::placeholders::_2, packet)); } void SSUServer::ReceiveV6 () { - SSUPacket * packet = new SSUPacket (); + SSUPacket * packet = m_PacketsPool.AcquireMt (); m_SocketV6.async_receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from, std::bind (&SSUServer::HandleReceivedFromV6, this, std::placeholders::_1, std::placeholders::_2, packet)); } @@ -293,7 +293,7 @@ namespace transport { while (moreBytes && packets.size () < 25) { - packet = new SSUPacket (); + packet = m_PacketsPool.AcquireMt (); packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, 0, ec); if (!ec) { @@ -304,7 +304,7 @@ namespace transport else { LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ()); - delete packet; + m_PacketsPool.ReleaseMt (packet); break; } } @@ -315,7 +315,7 @@ namespace transport } else { - delete packet; + m_PacketsPool.ReleaseMt (packet); if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ()); @@ -352,7 +352,7 @@ namespace transport { while (moreBytes && packets.size () < 25) { - packet = new SSUPacket (); + packet = m_PacketsPool.AcquireMt (); packet->len = m_SocketV6.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from, 0, ec); if (!ec) { @@ -363,7 +363,7 @@ namespace transport else { LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ()); - delete packet; + m_PacketsPool.ReleaseMt (packet);; break; } } @@ -374,7 +374,7 @@ namespace transport } else { - delete packet; + m_PacketsPool.ReleaseMt (packet); if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogError, "SSU: v6 receive error: code ", ecode.value(), ": ", ecode.message ()); @@ -421,8 +421,8 @@ namespace transport if (session) session->FlushData (); session = nullptr; } - delete packet; } + m_PacketsPool.ReleaseMt (packets); if (session) session->FlushData (); } diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 586d7089..b97cacb4 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -144,6 +144,7 @@ namespace transport i2p::util::MemoryPool m_FragmentsPool; i2p::util::MemoryPool m_IncompleteMessagesPool; i2p::util::MemoryPool m_SentMessagesPool; + i2p::util::MemoryPoolMt m_PacketsPool; public: // for HTTP only From ec86c4611d527cf9c9b3e4d9b9db53f7bde8e393 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 10 Sep 2021 05:19:55 +0300 Subject: [PATCH 0318/2193] disable reload checks for UDP tunnels (TODO) Signed-off-by: R4SAS --- libi2pd_client/ClientContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 09516bb9..4eab189f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -963,6 +963,7 @@ namespace client } } + /* // TODO: Write correct UDP tunnels stop for (auto it = m_ClientForwards.begin (); it != m_ClientForwards.end ();) { if(clean && !it->second->isUpdated) { @@ -983,7 +984,7 @@ namespace client it->second->isUpdated = false; it++; } - } + } */ } } } From e5c773a3eb22e95c33a293a8ccdd6bdf4899a607 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 13 Sep 2021 13:27:29 +0300 Subject: [PATCH 0319/2193] [webconsole] move resources to separate header file Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 73 +---------------------------- daemon/HTTPServerResources.h | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 71 deletions(-) create mode 100644 daemon/HTTPServerResources.h diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c2aee205..1e002b1b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -36,81 +36,12 @@ #include "Win32App.h" #endif -// For image and info +// For image, style and info #include "version.h" +#include "HTTPServerResources.h" namespace i2p { namespace http { - const std::string itoopieFavicon = - "data:image/png;base64," - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx" - "jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0" - "d2FyZQBwYWludC5uZXQgNC4wLjEyQwRr7AAAAoJJREFUOE9jwAUqi4Q1oEwwcDTV1+5sETaBclGB" - "vb09C5QJB6kWpvFQJoOCeLC5kmjEHCgXE2SlyETLi3h6QrkM4VL+ssWSCZUgtopITLKqaOotRTEn" - "cbAkLqAkGtOqLBLVAWLXyWSVFkkmRiqLxuaqiWb/VBYJMAYrwgckJY25VEUzniqKhjU2y+RtCRSP" - "6lUXy/1jIBV5tlYxZUaFVMq2NInwIi9hO8fSfOEAqDZUoCwal6MulvOvyS7gi69K4j9zxZT/m0ps" - "/28ptvvvquXXryIa7QYMMdTwqi0WNtVi0GIDseXl7TnUxFKfnGlxAGp0+D8j2eH/8Ub7/9e7nf7X" - "+Af/B7rwt6pI0h0l0WhQADOC9DBkhSirpImHNVZKp24ukkyoshGLnN8d5fA/y13t/44Kq/8hlnL/" - "z7fZ/58f6vcxSNpbVUVFhV1RLNBVTsQzVYZPSwhsCAhkiIfpNMrkbO6TLf071Sfk/5ZSi/+7q6z/" - "P5ns+v9mj/P/CpuI/20y+aeNGYxZoVoYGmsF3aFMBAAZlCwftnF9ke3//bU2//fXWP8/UGv731Am" - "+V+DdNblSqnUYqhSTKAiYSOqJBrVqiaa+S3UNPr/gmyH/xuKXf63hnn/B8bIP0UxHfEyyeSNQKVM" - "EB1AEB2twhcTLp+gIBJUoyKasEpVJHmqskh8qryovUG/ffCHHRU2q/Tk/YuB6eGPsbExa7ZkpLu1" - "oLEcVDtuUCgV1w60rQzElpRUE1EVSX0BYidHiInXF4nagNhYQW60EF+ApH1ktni0A1SIITSUgVlZ" - "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" - "RU5ErkJggg=="; - - // Bundled style - const std::string internalCSS = - "\r\n"; - - // for external style sheet - std::string externalCSS; - static void LoadExtCSS () { std::stringstream s; diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h new file mode 100644 index 00000000..876948e8 --- /dev/null +++ b/daemon/HTTPServerResources.h @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2013-2021, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#ifndef HTTP_SERVER_RESOURCES_H__ +#define HTTP_SERVER_RESOURCES_H__ + +namespace i2p +{ +namespace http +{ + const std::string itoopieFavicon = + "data:image/png;base64," + "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx" + "jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0" + "d2FyZQBwYWludC5uZXQgNC4wLjEyQwRr7AAAAoJJREFUOE9jwAUqi4Q1oEwwcDTV1+5sETaBclGB" + "vb09C5QJB6kWpvFQJoOCeLC5kmjEHCgXE2SlyETLi3h6QrkM4VL+ssWSCZUgtopITLKqaOotRTEn" + "cbAkLqAkGtOqLBLVAWLXyWSVFkkmRiqLxuaqiWb/VBYJMAYrwgckJY25VEUzniqKhjU2y+RtCRSP" + "6lUXy/1jIBV5tlYxZUaFVMq2NInwIi9hO8fSfOEAqDZUoCwal6MulvOvyS7gi69K4j9zxZT/m0ps" + "/28ptvvvquXXryIa7QYMMdTwqi0WNtVi0GIDseXl7TnUxFKfnGlxAGp0+D8j2eH/8Ub7/9e7nf7X" + "+Af/B7rwt6pI0h0l0WhQADOC9DBkhSirpImHNVZKp24ukkyoshGLnN8d5fA/y13t/44Kq/8hlnL/" + "z7fZ/58f6vcxSNpbVUVFhV1RLNBVTsQzVYZPSwhsCAhkiIfpNMrkbO6TLf071Sfk/5ZSi/+7q6z/" + "P5ns+v9mj/P/CpuI/20y+aeNGYxZoVoYGmsF3aFMBAAZlCwftnF9ke3//bU2//fXWP8/UGv731Am" + "+V+DdNblSqnUYqhSTKAiYSOqJBrVqiaa+S3UNPr/gmyH/xuKXf63hnn/B8bIP0UxHfEyyeSNQKVM" + "EB1AEB2twhcTLp+gIBJUoyKasEpVJHmqskh8qryovUG/ffCHHRU2q/Tk/YuB6eGPsbExa7ZkpLu1" + "oLEcVDtuUCgV1w60rQzElpRUE1EVSX0BYidHiInXF4nagNhYQW60EF+ApH1ktni0A1SIITSUgVlZ" + "JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ" + "RU5ErkJggg=="; + + // bundled style sheet + const std::string internalCSS = + "\r\n"; + + // for external style sheet + std::string externalCSS; + +} // http +} // i2p + +#endif /* HTTP_SERVER_RESOURCES_H__ */ From d2faec70be9cfac055c0296e58a8299d47d6d01b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 14 Sep 2021 14:48:21 +0300 Subject: [PATCH 0320/2193] [gzip] do not initialize deflator if gzip is not enabled for tunnel Signed-off-by: R4SAS --- libi2pd/Datagram.cpp | 14 ++++++-- libi2pd/Datagram.h | 4 +-- libi2pd/I2NPProtocol.cpp | 72 ++++++++++++++++++++-------------------- libi2pd/Streaming.cpp | 14 +++++--- libi2pd/Streaming.h | 2 +- 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index d000a9e0..627c0481 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -21,6 +21,9 @@ namespace datagram DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { + if (m_Gzip) + m_Deflator.reset (new i2p::data::GzipDeflator); + auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); m_From.resize (identityLen); m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); @@ -152,11 +155,16 @@ namespace datagram const std::vector >& payloads, uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { + size_t size; auto msg = m_I2NPMsgsPool.AcquireShared (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length - size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) : - i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); + + if (m_Gzip && m_Deflator) + size = m_Deflator->Deflate (payloads, buf, msg->maxLen - msg->len); + else + size = i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); + if (size) { htobe32buf (msg->GetPayload (), size); // length diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 5dd6c8b6..564eb10b 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -164,7 +164,7 @@ namespace datagram std::map m_ReceiversByPorts; i2p::data::GzipInflator m_Inflator; - i2p::data::GzipDeflator m_Deflator; + std::unique_ptr m_Deflator; std::vector m_From, m_Signature; i2p::util::MemoryPool > m_I2NPMsgsPool; }; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5a2fa9c1..29d68b3c 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -40,7 +40,7 @@ namespace i2p { I2NPMessage * msg = nullptr; if (endpoint) - { + { // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6 msg->Align (6); @@ -50,7 +50,7 @@ namespace i2p { msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 msg->Align (12); - } + } return std::shared_ptr(msg); } @@ -222,12 +222,12 @@ namespace i2p { memcpy (buf + 33, replyTag, 8); // 8 bytes tag buf += 41; - } - else - { + } + else + { memcpy (buf + 33, replyTag, 32); // 32 bytes tag buf += 65; - } + } m->len += (buf - m->GetPayload ()); m->FillI2NPMessageHeader (eI2NPDatabaseLookup); @@ -267,7 +267,7 @@ namespace i2p LogPrint (eLogError, "I2NP: Invalid RouterInfo buffer for DatabaseStore"); return nullptr; } - + auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); @@ -285,12 +285,12 @@ namespace i2p buf += 32; // reply tunnel gateway } else - { + { memset (buf, 0, 4); // zero tunnelID means direct reply buf += 4; memcpy (buf, context.GetIdentHash (), 32); buf += 32; - } + } } uint8_t * sizePtr = buf; @@ -303,7 +303,7 @@ namespace i2p { i2p::data::GzipDeflator deflator; size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); - } + } if (size) { htobe16buf (sizePtr, size); // size @@ -427,14 +427,14 @@ namespace i2p { LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); return false; - } + } } else - { + { encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); + encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); - } + } } return true; } @@ -561,7 +561,7 @@ namespace i2p LogPrint (eLogDebug, "I2NP: Short request record ", i, " is ours"); uint8_t clearText[SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE]; if (!i2p::context.DecryptTunnelShortRequestRecord (record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) - { + { LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i); return; } @@ -569,7 +569,7 @@ namespace i2p { LogPrint (eLogWarning, "I2NP: Unknown layer encryption type ", clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE], " in short request record"); return; - } + } auto& noiseState = i2p::context.GetCurrentNoiseState (); uint8_t replyKey[32], layerKey[32], ivKey[32]; i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK); @@ -581,7 +581,7 @@ namespace i2p { i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "TunnelLayerIVKey", noiseState.m_CK); memcpy (ivKey, noiseState.m_CK + 32, 32); - } + } else memcpy (ivKey, noiseState.m_CK , 32); @@ -593,7 +593,7 @@ namespace i2p i2p::transport::transports.IsTransitBandwidthExceeded ()) retCode = 30; if (!retCode) - { + { // create new transit tunnel auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), @@ -604,13 +604,13 @@ namespace i2p clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); } - + // encrypt reply uint8_t nonce[12]; memset (nonce, 0, 12); uint8_t * reply = buf + 1; for (int j = 0; j < num; j++) - { + { nonce[4] = j; // nonce is record # if (j == i) { @@ -621,29 +621,29 @@ namespace i2p { LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed"); return; - } + } } else i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, reply); - reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; + reply += SHORT_TUNNEL_BUILD_RECORD_SIZE; } // send reply if (isEndpoint) - { + { auto replyMsg = NewI2NPShortMessage (); replyMsg->Concat (buf, len); replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)); if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (), clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, 32)) // reply IBGW is not local? { - i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); + i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK); uint64_t tag; memcpy (&tag, noiseState.m_CK, 8); // we send it to reply tunnel transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET), i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag))); - } + } else { // IBGW is local @@ -653,18 +653,18 @@ namespace i2p tunnel->SendTunnelDataMsg (replyMsg); else LogPrint (eLogWarning, "I2NP: Tunnel ", tunnelID, " not found for short tunnel build reply"); - } - } - else + } + } + else transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); return; - } + } record += SHORT_TUNNEL_BUILD_RECORD_SIZE; - } - } - + } + } + std::shared_ptr CreateTunnelDataMsg (const uint8_t * buf) { auto msg = NewI2NPTunnelMessage (false); @@ -781,13 +781,13 @@ namespace i2p break; case eI2NPShortTunnelBuild: HandleShortTunnelBuildMsg (msgID, buf, size); - break; + break; case eI2NPVariableTunnelBuildReply: HandleTunnelBuildReplyMsg (msgID, buf, size, false); break; case eI2NPShortTunnelBuildReply: HandleTunnelBuildReplyMsg (msgID, buf, size, true); - break; + break; case eI2NPTunnelBuild: HandleTunnelBuildMsg (buf, size); break; @@ -844,8 +844,8 @@ namespace i2p case eI2NPVariableTunnelBuildReply: case eI2NPTunnelBuild: case eI2NPTunnelBuildReply: - case eI2NPShortTunnelBuild: - case eI2NPShortTunnelBuildReply: + case eI2NPShortTunnelBuild: + case eI2NPShortTunnelBuildReply: // forward to tunnel thread i2p::tunnel::tunnels.PostTunnelData (msg); break; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 95f6a150..c6447b5f 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -1040,6 +1040,8 @@ namespace stream m_Owner (owner), m_LocalPort (localPort), m_Gzip (gzip), m_PendingIncomingTimer (m_Owner->GetService ()) { + if (m_Gzip) + m_Deflator.reset (new i2p::data::GzipDeflator); } StreamingDestination::~StreamingDestination () @@ -1296,13 +1298,17 @@ namespace stream std::shared_ptr StreamingDestination::CreateDataMessage ( const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { + size_t size; auto msg = m_I2NPMsgsPool.AcquireShared (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for lengthlength msg->len += 4; - size_t size = (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE)? - i2p::data::GzipNoCompression (payload, len, buf, msg->maxLen - msg->len): - m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); + + if (m_Gzip && m_Deflator) + size = m_Deflator->Deflate (payload, len, buf, msg->maxLen - msg->len); + else + size = i2p::data::GzipNoCompression (payload, len, buf, msg->maxLen - msg->len); + if (size) { htobe32buf (msg->GetPayload (), size); // length diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 51fb03ab..189b1a64 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -312,7 +312,7 @@ namespace stream public: i2p::data::GzipInflator m_Inflator; - i2p::data::GzipDeflator m_Deflator; + std::unique_ptr m_Deflator; // for HTTP only const decltype(m_Streams)& GetStreams () const { return m_Streams; }; From 3dd9e812968f7f75a4730b1287d42483f8eecd99 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 17 Sep 2021 02:53:30 +0300 Subject: [PATCH 0321/2193] [addressbook] check domain ending when processing subscriptions Signed-off-by: R4SAS --- libi2pd_client/AddressBook.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index ba2d8276..3d5c83c0 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -470,6 +470,20 @@ namespace client if (pos != std::string::npos) addr = addr.substr(0, pos); // remove comments + pos = name.find(".b32.i2p"); + if (pos != std::string::npos) + { + LogPrint (eLogError, "Addressbook: skipped adding of b32 address: ", name); + continue; + } + + pos = name.find(".i2p"); + if (pos == std::string::npos) + { + LogPrint (eLogError, "Addressbook: malformed domain: ", name); + continue; + } + auto ident = std::make_shared (); if (!ident->FromBase64(addr)) { LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name); From 5b2b9e00a2d5ddb673ea443c73d381251e54e4ea Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Sep 2021 21:52:39 -0400 Subject: [PATCH 0322/2193] reuse receive buffer --- libi2pd/NTCP2.cpp | 35 ++++++++++++++++++++++++++++++----- libi2pd/NTCP2.h | 8 ++++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ed84b8e7..5b542187 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -332,8 +332,8 @@ namespace transport m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), #endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), - m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false), - m_NextPaddingSize (16) + m_NextReceivedBufferSize (0), m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), + m_IsSending (false), m_IsReceiving (false), m_NextPaddingSize (16) { if (in_RemoteRouter) // Alice { @@ -405,7 +405,30 @@ namespace transport htole64buf (nonce + 4, seqn); } + void NTCP2Session::CreateNextReceivedBuffer (size_t size) + { + if (m_NextReceivedBuffer) + { + if (size <= m_NextReceivedBufferSize) + return; // buffer is good, do nothing + else + delete[] m_NextReceivedBuffer; + } + m_NextReceivedBuffer = new uint8_t[size]; + m_NextReceivedBufferSize = size; + } + void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts) + { + if (m_NextReceivedBuffer && !m_IsReceiving && + ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT) + { + delete[] m_NextReceivedBuffer; + m_NextReceivedBuffer = nullptr; + m_NextReceivedBufferSize = 0; + } + } + void NTCP2Session::KeyDerivationFunctionDataPhase () { uint8_t k[64]; @@ -759,8 +782,7 @@ namespace transport LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen); if (m_NextReceivedLen >= 16) { - if (m_NextReceivedBuffer) delete[] m_NextReceivedBuffer; - m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen]; + CreateNextReceivedBuffer (m_NextReceivedLen); boost::system::error_code ec; size_t moreBytes = m_Socket.available(ec); if (!ec && moreBytes >= m_NextReceivedLen) @@ -787,6 +809,7 @@ namespace transport const int one = 1; setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); #endif + m_IsReceiving = true; boost::asio::async_read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -810,7 +833,7 @@ namespace transport { LogPrint (eLogDebug, "NTCP2: received message decrypted"); ProcessNextFrame (m_NextReceivedBuffer, m_NextReceivedLen-16); - delete[] m_NextReceivedBuffer; m_NextReceivedBuffer = nullptr; // we don't need received buffer anymore + m_IsReceiving = false; ReceiveLength (); } else @@ -1448,6 +1471,8 @@ namespace transport LogPrint (eLogDebug, "NTCP2: No activity for ", session->GetTerminationTimeout (), " seconds"); session->TerminateByTimeout (); // it doesn't change m_NTCP2Session right a way } + else + it.second->DeleteNextReceiveBuffer (ts); // pending for (auto it = m_PendingIncomingSessions.begin (); it != m_PendingIncomingSessions.end ();) { diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index bcee1b09..b54c1634 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -34,6 +34,7 @@ namespace transport const int NTCP2_ESTABLISH_TIMEOUT = 10; // 10 seconds const int NTCP2_TERMINATION_TIMEOUT = 120; // 2 minutes const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds + const int NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT = 3; // 3 seconds const int NTCP2_ROUTERINFO_RESEND_INTERVAL = 25*60; // 25 minuntes in seconds const int NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD = 25*60; // 25 minuntes @@ -132,7 +133,8 @@ namespace transport void TerminateByTimeout (); void Done (); void Close () { m_Socket.close (); }; // for accept - + void DeleteNextReceiveBuffer (uint64_t ts); + boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; const boost::asio::ip::tcp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; void SetRemoteEndpoint (const boost::asio::ip::tcp::endpoint& ep) { m_RemoteEndpoint = ep; }; @@ -151,6 +153,7 @@ namespace transport void Established (); void CreateNonce (uint64_t seqn, uint8_t * nonce); + void CreateNextReceivedBuffer (size_t size); void KeyDerivationFunctionDataPhase (); void SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey); @@ -206,6 +209,7 @@ namespace transport #endif uint16_t m_NextReceivedLen; uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer; + size_t m_NextReceivedBufferSize; union { uint8_t buf[8]; @@ -215,7 +219,7 @@ namespace transport i2p::I2NPMessagesHandler m_Handler; - bool m_IsSending; + bool m_IsSending, m_IsReceiving; std::list > m_SendQueue; uint64_t m_NextRouterInfoResendTime; // seconds since epoch From 317d8cdc48c2e7934fe14406190d23fdb8e3030d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 18 Sep 2021 15:44:43 -0400 Subject: [PATCH 0323/2193] don't allocate separate buffers for SessionRequest and SessionCreated --- libi2pd/NTCP2.cpp | 18 ++++++------------ libi2pd/NTCP2.h | 9 ++++++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 5b542187..05d68203 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -32,14 +32,12 @@ namespace i2p namespace transport { NTCP2Establisher::NTCP2Establisher (): - m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) + m_SessionConfirmedBuffer (nullptr) { } NTCP2Establisher::~NTCP2Establisher () { - delete[] m_SessionRequestBuffer; - delete[] m_SessionCreatedBuffer; delete[] m_SessionConfirmedBuffer; } @@ -112,9 +110,8 @@ namespace transport void NTCP2Establisher::CreateSessionRequestMessage () { // create buffer and fill padding - auto paddingLength = rand () % (287 - 64); // message length doesn't exceed 287 bytes + auto paddingLength = rand () % (NTCP2_SESSION_REQUEST_MAX_SIZE - 64); // message length doesn't exceed 287 bytes m_SessionRequestBufferLen = paddingLength + 64; - m_SessionRequestBuffer = new uint8_t[m_SessionRequestBufferLen]; RAND_bytes (m_SessionRequestBuffer + 64, paddingLength); // encrypt X i2p::crypto::CBCEncryption encryption; @@ -152,9 +149,8 @@ namespace transport void NTCP2Establisher::CreateSessionCreatedMessage () { - auto paddingLen = rand () % (287 - 64); + auto paddingLen = rand () % (NTCP2_SESSION_CREATED_MAX_SIZE - 64); m_SessionCreatedBufferLen = paddingLen + 64; - m_SessionCreatedBuffer = new uint8_t[m_SessionCreatedBufferLen]; RAND_bytes (m_SessionCreatedBuffer + 64, paddingLen); // encrypt Y i2p::crypto::CBCEncryption encryption; @@ -463,7 +459,6 @@ namespace transport } else { - m_Establisher->m_SessionCreatedBuffer = new uint8_t[287]; // TODO: determine actual max size // we receive first 64 bytes (32 Y, and 32 ChaCha/Poly frame) first boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionCreatedBuffer, 64), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionCreatedReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -486,7 +481,7 @@ namespace transport { if (paddingLen > 0) { - if (paddingLen <= 287 - 64) // session request is 287 bytes max + if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max { boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer + 64, paddingLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -539,7 +534,7 @@ namespace transport { if (paddingLen > 0) { - if (paddingLen <= 287 - 64) // session created is 287 bytes max + if (paddingLen <= NTCP2_SESSION_CREATED_MAX_SIZE - 64) // session created is 287 bytes max { boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionCreatedBuffer + 64, paddingLen), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionCreatedPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -742,7 +737,6 @@ namespace transport void NTCP2Session::ServerLogin () { m_Establisher->CreateEphemeralKey (); - m_Establisher->m_SessionRequestBuffer = new uint8_t[287]; // 287 bytes max for now boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer, 64), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionRequestReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index b54c1634..f9f3e751 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -28,6 +28,8 @@ namespace transport { const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519; + const size_t NTCP2_SESSION_REQUEST_MAX_SIZE = 287; + const size_t NTCP2_SESSION_CREATED_MAX_SIZE = 287; const int NTCP2_MAX_PADDING_RATIO = 6; // in % const int NTCP2_CONNECT_TIMEOUT = 5; // 5 seconds @@ -40,7 +42,7 @@ namespace transport const int NTCP2_CLOCK_SKEW = 60; // in seconds const int NTCP2_MAX_OUTGOING_QUEUE_SIZE = 500; // how many messages we can queue up - + enum NTCP2BlockType { eNTCP2BlkDateTime = 0, @@ -116,7 +118,8 @@ namespace transport i2p::data::IdentHash m_RemoteIdentHash; uint16_t m3p2Len; - uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer; + uint8_t m_SessionRequestBuffer[NTCP2_SESSION_REQUEST_MAX_SIZE], + m_SessionCreatedBuffer[NTCP2_SESSION_CREATED_MAX_SIZE], * m_SessionConfirmedBuffer; size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen; }; From 31bdce1f1f37d6fafb83cb202b0b6f759b00e470 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Sep 2021 19:01:22 -0400 Subject: [PATCH 0324/2193] cleanup received messages list by timestamp --- libi2pd/SSUData.cpp | 19 +++++++++++++++---- libi2pd/SSUData.h | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 2c6f72e1..7d048799 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -246,8 +246,8 @@ namespace transport { if (!m_ReceivedMessages.count (msgID)) { - m_ReceivedMessages.insert (msgID); m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch (); + m_ReceivedMessages.emplace (msgID, m_LastMessageReceivedTime); if (!msg->IsExpired ()) { m_Handler.PutNextMessage (msg); @@ -511,10 +511,21 @@ namespace transport else ++it; } - // decay - if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || - i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) + + if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || ts > m_LastMessageReceivedTime + DECAY_INTERVAL) + // decay m_ReceivedMessages.clear (); + else + { + // delete old received messages + for (auto it = m_ReceivedMessages.begin (); it != m_ReceivedMessages.end ();) + { + if (ts > it->second + RECEIVED_MESSAGES_CLEANUP_TIMEOUT) + it = m_ReceivedMessages.erase (it); + else + ++it; + } + } ScheduleIncompleteMessagesCleanup (); } diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 1eb98b1d..3dcff1d4 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -40,6 +40,7 @@ namespace transport const int MAX_NUM_RESENDS = 5; const int DECAY_INTERVAL = 20; // in seconds const int INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds + const int RECEIVED_MESSAGES_CLEANUP_TIMEOUT = 40; // in seconds const unsigned int MAX_NUM_RECEIVED_MESSAGES = 1000; // how many msgID we store for duplicates check const int MAX_OUTGOING_WINDOW_SIZE = 200; // how many unacked message we can store // data flags @@ -128,7 +129,7 @@ namespace transport SSUSession& m_Session; std::unordered_map > m_IncompleteMessages; std::unordered_map > m_SentMessages; - std::unordered_set m_ReceivedMessages; + std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; From 8debdc264c863ed81380b3b2e010ffe1612ad0d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Sep 2021 22:13:34 -0400 Subject: [PATCH 0325/2193] use common cleanup timer for all SSU sessions --- libi2pd/SSU.cpp | 4 +++ libi2pd/SSUData.cpp | 63 +++++++++++++++--------------------------- libi2pd/SSUData.h | 10 ++----- libi2pd/SSUSession.cpp | 6 ++++ libi2pd/SSUSession.h | 3 +- 5 files changed, 38 insertions(+), 48 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 86e76b8e..7b129811 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -952,6 +952,8 @@ namespace transport session->Failed (); }); } + else + it.second->CleanUp (); ScheduleTermination (); } } @@ -980,6 +982,8 @@ namespace transport session->Failed (); }); } + else + it.second->CleanUp (); ScheduleTerminationV6 (); } } diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 7d048799..0468956b 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -33,7 +33,6 @@ namespace transport SSUData::SSUData (SSUSession& session): m_Session (session), m_ResendTimer (session.GetService ()), - m_IncompleteMessagesCleanupTimer (session.GetService ()), m_MaxPacketSize (session.IsV6 () ? SSU_V6_MAX_PACKET_SIZE : SSU_V4_MAX_PACKET_SIZE), m_PacketSize (m_MaxPacketSize), m_LastMessageReceivedTime (0) { @@ -45,13 +44,11 @@ namespace transport void SSUData::Start () { - ScheduleIncompleteMessagesCleanup (); } void SSUData::Stop () { m_ResendTimer.cancel (); - m_IncompleteMessagesCleanupTimer.cancel (); m_IncompleteMessages.clear (); m_SentMessages.clear (); m_ReceivedMessages.clear (); @@ -487,48 +484,34 @@ namespace transport } } - void SSUData::ScheduleIncompleteMessagesCleanup () + void SSUData::CleanUp () { - m_IncompleteMessagesCleanupTimer.cancel (); - m_IncompleteMessagesCleanupTimer.expires_from_now (boost::posix_time::seconds(INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT)); - auto s = m_Session.shared_from_this(); - m_IncompleteMessagesCleanupTimer.async_wait ([s](const boost::system::error_code& ecode) - { s->m_Data.HandleIncompleteMessagesCleanupTimer (ecode); }); - } - - void SSUData::HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) + if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) { - if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) - { - LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); - it = m_IncompleteMessages.erase (it); - } + LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); + it = m_IncompleteMessages.erase (it); + } + else + ++it; + } + + if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || ts > m_LastMessageReceivedTime + DECAY_INTERVAL) + // decay + m_ReceivedMessages.clear (); + else + { + // delete old received messages + for (auto it = m_ReceivedMessages.begin (); it != m_ReceivedMessages.end ();) + { + if (ts > it->second + RECEIVED_MESSAGES_CLEANUP_TIMEOUT) + it = m_ReceivedMessages.erase (it); else ++it; - } - - if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || ts > m_LastMessageReceivedTime + DECAY_INTERVAL) - // decay - m_ReceivedMessages.clear (); - else - { - // delete old received messages - for (auto it = m_ReceivedMessages.begin (); it != m_ReceivedMessages.end ();) - { - if (ts > it->second + RECEIVED_MESSAGES_CLEANUP_TIMEOUT) - it = m_ReceivedMessages.erase (it); - else - ++it; - } } - - ScheduleIncompleteMessagesCleanup (); - } - } + } + } } } diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 3dcff1d4..590a538c 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include "I2NPProtocol.h" @@ -101,7 +100,8 @@ namespace transport void Start (); void Stop (); - + void CleanUp (); + void ProcessMessage (uint8_t * buf, size_t len); void FlushReceivedMessage (); void Send (std::shared_ptr msg); @@ -120,17 +120,13 @@ namespace transport void ScheduleResend (); void HandleResendTimer (const boost::system::error_code& ecode); - void ScheduleIncompleteMessagesCleanup (); - void HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode); - - private: SSUSession& m_Session; std::unordered_map > m_IncompleteMessages; std::unordered_map > m_SentMessages; std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds - boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer; + boost::asio::deadline_timer m_ResendTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; uint32_t m_LastMessageReceivedTime; // in second diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 59ee578b..e01b0c0e 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1004,6 +1004,12 @@ namespace transport } } + void SSUSession::CleanUp () + { + m_Data.CleanUp (); + // TODO: clean up m_RelayRequests + } + void SSUSession::ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) { uint32_t nonce = bufbe32toh (buf); // 4 bytes diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 462afc35..acf232b9 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -106,6 +106,7 @@ namespace transport void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers void FlushData (); + void CleanUp (); private: From 18b6ba80f2cfaa52c2c5609ac54a1a96360db422 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Sep 2021 19:09:56 -0400 Subject: [PATCH 0326/2193] cleanup RelayRequests --- libi2pd/SSU.cpp | 10 ++++++---- libi2pd/SSUData.cpp | 3 +-- libi2pd/SSUData.h | 2 +- libi2pd/SSUSession.cpp | 17 ++++++++++++----- libi2pd/SSUSession.h | 4 ++-- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 7b129811..9e814303 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -930,7 +930,8 @@ namespace transport void SSUServer::ScheduleTermination () { - m_TerminationTimer.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_CHECK_TIMEOUT)); + uint64_t timeout = SSU_TERMINATION_CHECK_TIMEOUT + (rand () % SSU_TERMINATION_CHECK_TIMEOUT)/5; + m_TerminationTimer.expires_from_now (boost::posix_time::seconds(timeout)); m_TerminationTimer.async_wait (std::bind (&SSUServer::HandleTerminationTimer, this, std::placeholders::_1)); } @@ -953,14 +954,15 @@ namespace transport }); } else - it.second->CleanUp (); + it.second->CleanUp (ts); ScheduleTermination (); } } void SSUServer::ScheduleTerminationV6 () { - m_TerminationTimerV6.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_CHECK_TIMEOUT)); + uint64_t timeout = SSU_TERMINATION_CHECK_TIMEOUT + (rand () % SSU_TERMINATION_CHECK_TIMEOUT)/5; + m_TerminationTimerV6.expires_from_now (boost::posix_time::seconds(timeout)); m_TerminationTimerV6.async_wait (std::bind (&SSUServer::HandleTerminationTimerV6, this, std::placeholders::_1)); } @@ -983,7 +985,7 @@ namespace transport }); } else - it.second->CleanUp (); + it.second->CleanUp (ts); ScheduleTerminationV6 (); } } diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 0468956b..18621fe0 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -484,9 +484,8 @@ namespace transport } } - void SSUData::CleanUp () + void SSUData::CleanUp (uint64_t ts) { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) { if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 590a538c..35311bb6 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -100,7 +100,7 @@ namespace transport void Start (); void Stop (); - void CleanUp (); + void CleanUp (uint64_t ts); void ProcessMessage (uint8_t * buf, size_t len); void FlushReceivedMessage (); diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index e01b0c0e..3e4eecb8 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -730,7 +730,7 @@ namespace transport (remoteIP.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled)) m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch // we assume that HolePunch has been sent by this time and our SessionRequest will go through - m_Server.CreateDirectSession (it->second, remoteEndpoint, false); + m_Server.CreateDirectSession (it->second.first, remoteEndpoint, false); } // delete request m_RelayRequests.erase (it); @@ -905,7 +905,8 @@ namespace transport } uint32_t nonce; RAND_bytes ((uint8_t *)&nonce, 4); - m_RelayRequests[nonce] = to; + auto ts = i2p::util::GetSecondsSinceEpoch (); + m_RelayRequests.emplace (nonce, std::make_pair (to, ts)); SendRelayRequest (introducer, nonce); } @@ -1004,10 +1005,16 @@ namespace transport } } - void SSUSession::CleanUp () + void SSUSession::CleanUp (uint64_t ts) { - m_Data.CleanUp (); - // TODO: clean up m_RelayRequests + m_Data.CleanUp (ts); + for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();) + { + if (ts > it->second.second + SSU_CONNECT_TIMEOUT) + it = m_RelayRequests.erase (it); + else + ++it; + } } void SSUSession::ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint) diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index acf232b9..95697a91 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -106,7 +106,7 @@ namespace transport void SetCreationTime (uint32_t ts) { m_CreationTime = ts; }; // for introducers void FlushData (); - void CleanUp (); + void CleanUp (uint64_t ts); private: @@ -170,7 +170,7 @@ namespace transport SSUData m_Data; bool m_IsDataReceived; std::unique_ptr m_SignedData; // we need it for SessionConfirmed only - std::map > m_RelayRequests; // nonce->Charlie + std::unordered_map, uint64_t > > m_RelayRequests; // nonce->(Charlie, timestamp) std::shared_ptr m_DHKeysPair; // X - for client and Y - for server }; } From 518e53a61c2491a1f97fcc317aee871f343ece12 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Sep 2021 14:23:39 -0400 Subject: [PATCH 0327/2193] use flat_map for smaller tables --- libi2pd/SSU.cpp | 2 +- libi2pd/SSU.h | 2 +- libi2pd/SSUData.cpp | 2 +- libi2pd/SSUData.h | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 9e814303..be263370 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -218,7 +218,7 @@ namespace transport void SSUServer::AddRelay (uint32_t tag, std::shared_ptr relay) { - m_Relays[tag] = relay; + m_Relays.emplace (tag, relay); } void SSUServer::RemoveRelay (uint32_t tag) diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index b97cacb4..4b561be0 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -139,7 +139,7 @@ namespace transport std::list m_Introducers, m_IntroducersV6; // introducers we are connected to std::map > m_Sessions, m_SessionsV6; std::map > m_Relays; // we are introducer - std::map m_PeerTests; // nonce -> creation time in milliseconds + boost::container::flat_map m_PeerTests; // nonce -> creation time in milliseconds i2p::util::MemoryPool m_FragmentsPool; i2p::util::MemoryPool m_IncompleteMessagesPool; diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 18621fe0..ccc89b41 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -310,7 +310,7 @@ namespace transport if (m_SentMessages.empty ()) // schedule resend at first message only ScheduleResend (); - auto ret = m_SentMessages.insert (std::make_pair (msgID, m_Session.GetServer ().GetSentMessagesPool ().AcquireShared ())); + auto ret = m_SentMessages.emplace (msgID, m_Session.GetServer ().GetSentMessagesPool ().AcquireShared ()); auto& sentMessage = ret.first->second; if (ret.second) { diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 35311bb6..fa6aa92c 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -11,10 +11,10 @@ #include #include -#include #include #include #include +#include #include "I2NPProtocol.h" #include "Identity.h" #include "RouterInfo.h" @@ -123,9 +123,9 @@ namespace transport private: SSUSession& m_Session; - std::unordered_map > m_IncompleteMessages; - std::unordered_map > m_SentMessages; - std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds + boost::container::flat_map > m_IncompleteMessages; + boost::container::flat_map > m_SentMessages; + boost::container::flat_map m_ReceivedMessages; // msgID -> timestamp in seconds boost::asio::deadline_timer m_ResendTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; From b9dd4aee8d58de3051a0883a2484555227541b74 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Sep 2021 19:12:12 -0400 Subject: [PATCH 0328/2193] use flat_map for incompete messages --- libi2pd/TunnelEndpoint.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index f9878165..aa87537a 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -10,9 +10,9 @@ #define TUNNEL_ENDPOINT_H__ #include -#include #include #include +#include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -59,8 +59,8 @@ namespace tunnel private: - std::unordered_map m_IncompleteMessages; - std::unordered_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment + boost::container::flat_map m_IncompleteMessages; + boost::container::flat_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; TunnelMessageBlockEx m_CurrentMessage; From 1bb1d89fab14577be5fe1d33eaab630d05ede136 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 25 Sep 2021 18:30:17 -0400 Subject: [PATCH 0329/2193] change back to map and unodered_map --- libi2pd/SSU.h | 2 +- libi2pd/SSUData.h | 9 +++++---- libi2pd/SSUSession.h | 2 +- libi2pd/TunnelEndpoint.h | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 4b561be0..b97cacb4 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -139,7 +139,7 @@ namespace transport std::list m_Introducers, m_IntroducersV6; // introducers we are connected to std::map > m_Sessions, m_SessionsV6; std::map > m_Relays; // we are introducer - boost::container::flat_map m_PeerTests; // nonce -> creation time in milliseconds + std::map m_PeerTests; // nonce -> creation time in milliseconds i2p::util::MemoryPool m_FragmentsPool; i2p::util::MemoryPool m_IncompleteMessagesPool; diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index fa6aa92c..8fe33a33 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -12,9 +12,10 @@ #include #include #include +#include +#include #include #include -#include #include "I2NPProtocol.h" #include "Identity.h" #include "RouterInfo.h" @@ -123,9 +124,9 @@ namespace transport private: SSUSession& m_Session; - boost::container::flat_map > m_IncompleteMessages; - boost::container::flat_map > m_SentMessages; - boost::container::flat_map m_ReceivedMessages; // msgID -> timestamp in seconds + std::map > m_IncompleteMessages; + std::map > m_SentMessages; + std::unordered_map m_ReceivedMessages; // msgID -> timestamp in seconds boost::asio::deadline_timer m_ResendTimer; int m_MaxPacketSize, m_PacketSize; i2p::I2NPMessagesHandler m_Handler; diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 95697a91..bd4b4b93 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -170,7 +170,7 @@ namespace transport SSUData m_Data; bool m_IsDataReceived; std::unique_ptr m_SignedData; // we need it for SessionConfirmed only - std::unordered_map, uint64_t > > m_RelayRequests; // nonce->(Charlie, timestamp) + std::map, uint64_t > > m_RelayRequests; // nonce->(Charlie, timestamp) std::shared_ptr m_DHKeysPair; // X - for client and Y - for server }; } diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index aa87537a..e5a6bbc8 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "I2NPProtocol.h" #include "TunnelBase.h" @@ -59,8 +59,8 @@ namespace tunnel private: - boost::container::flat_map m_IncompleteMessages; - boost::container::flat_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment + std::unordered_map m_IncompleteMessages; + std::unordered_map > m_OutOfSequenceFragments; // ((msgID << 8) + fragment#)->fragment bool m_IsInbound; size_t m_NumReceivedBytes; TunnelMessageBlockEx m_CurrentMessage; From b10e5ce35819397d105b122396ce4c6f8cfc7716 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Sep 2021 11:20:20 -0400 Subject: [PATCH 0330/2193] send ping --- libi2pd/Streaming.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++- libi2pd/Streaming.h | 4 +++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index c6447b5f..be3d09d8 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -490,7 +490,7 @@ namespace stream handler(boost::system::error_code ()); m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ())); } - + void Stream::SendBuffer () { int numMsgs = m_WindowSize - m_SentPackets.size (); @@ -665,6 +665,42 @@ namespace stream LogPrint (eLogDebug, "Streaming: Quick Ack sent. ", (int)numNacks, " NACKs"); } + void Stream::SendPing () + { + Packet p; + uint8_t * packet = p.GetBuffer (); + size_t size = 0; + htobe32buf (packet, m_RecvStreamID); + size += 4; // sendStreamID + memset (packet + size, 0, 14); + size += 14; // all zeroes + uint16_t flags = PACKET_FLAG_ECHO | PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_FROM_INCLUDED; + bool isOfflineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().IsOfflineSignature (); + if (isOfflineSignature) flags |= PACKET_FLAG_OFFLINE_SIGNATURE; + htobe16buf (packet + size, flags); + size += 2; // flags + size_t identityLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetFullLen (); + size_t signatureLen = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetSignatureLen (); + uint8_t * optionsSize = packet + size; // set options size later + size += 2; // options size + m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); + size += identityLen; // from + if (isOfflineSignature) + { + const auto& offlineSignature = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetOfflineSignature (); + memcpy (packet + size, offlineSignature.data (), offlineSignature.size ()); + size += offlineSignature.size (); // offline signature + } + uint8_t * signature = packet + size; // set it later + memset (signature, 0, signatureLen); // zeroes for now + size += signatureLen; // signature + htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size + m_LocalDestination.GetOwner ()->Sign (packet, size, signature); + p.len = size; + SendPackets (std::vector { &p }); + LogPrint (eLogDebug, "Streaming: Ping of ", p.len, " bytes sent"); + } + void Stream::Close () { LogPrint(eLogDebug, "Streaming: closing stream with sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID, ", status=", m_Status); @@ -1103,6 +1139,13 @@ namespace stream } else { + if (packet->IsEcho ()) + { + // pong + LogPrint (eLogInfo, "Streaming: Pong received rSID=", packet->GetReceiveStreamID ()); + DeletePacket (packet); + return; + } if (packet->IsSYN () && !packet->GetSeqn ()) // new incoming stream { uint32_t receiveStreamID = packet->GetReceiveStreamID (); @@ -1197,6 +1240,12 @@ namespace stream return s; } + void StreamingDestination::SendPing (std::shared_ptr remote) + { + auto s = std::make_shared (m_Owner->GetService (), *this, remote, 0); + s->SendPing (); + } + std::shared_ptr StreamingDestination::CreateNewIncomingStream (uint32_t receiveStreamID) { auto s = std::make_shared (m_Owner->GetService (), *this); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 189b1a64..c13dcab1 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -179,7 +179,8 @@ namespace stream void HandlePing (Packet * packet); size_t Send (const uint8_t * buf, size_t len); void AsyncSend (const uint8_t * buf, size_t len, SendHandler handler); - + void SendPing (); + template void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0); size_t ReadSome (uint8_t * buf, size_t len) { return ConcatenatePackets (buf, len); }; @@ -268,6 +269,7 @@ namespace stream void Stop (); std::shared_ptr CreateNewOutgoingStream (std::shared_ptr remote, int port = 0); + void SendPing (std::shared_ptr remote); void DeleteStream (std::shared_ptr stream); bool DeleteStream (uint32_t recvStreamID); void SetAcceptor (const Acceptor& acceptor); From 2eded7cdd7cec2ce964e2695daf3ef56072064db Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Sep 2021 16:25:12 -0400 Subject: [PATCH 0331/2193] send ping every keealive interval for client tunnels --- libi2pd/Destination.cpp | 25 ++++++++++++++++++++ libi2pd/Destination.h | 2 ++ libi2pd_client/ClientContext.cpp | 9 +++++++- libi2pd_client/ClientContext.h | 3 ++- libi2pd_client/I2PTunnel.cpp | 39 ++++++++++++++++++++++++++++++-- libi2pd_client/I2PTunnel.h | 10 ++++++-- 6 files changed, 82 insertions(+), 6 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 438b3f19..dd811593 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1096,6 +1096,31 @@ namespace client return nullptr; } + void ClientDestination::SendPing (const i2p::data::IdentHash& to) + { + if (m_StreamingDestination) + { + auto leaseSet = FindLeaseSet (to); + if (leaseSet) + m_StreamingDestination->SendPing (leaseSet); + else + RequestDestination (to, + [s = m_StreamingDestination](std::shared_ptr ls) + { + if (ls) s->SendPing (ls); + }); + } + } + + void ClientDestination::SendPing (std::shared_ptr to) + { + RequestDestinationWithEncryptedLeaseSet (to, + [s = m_StreamingDestination](std::shared_ptr ls) + { + if (ls) s->SendPing (ls); + }); + } + std::shared_ptr ClientDestination::GetStreamingDestination (int port) const { if (port) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 0dc5450b..54df8706 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -243,6 +243,8 @@ namespace client void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0); void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port = 0); std::shared_ptr CreateStream (std::shared_ptr remote, int port = 0); + void SendPing (const i2p::data::IdentHash& to); + void SendPing (std::shared_ptr to); void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor); void StopAcceptingStreams (); bool IsAcceptingStreams () const; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 4eab189f..d6871fbe 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -652,6 +652,13 @@ namespace client auto tun = std::make_shared (name, dest, address, port, localDestination, destinationPort); clientTunnel = tun; clientEndpoint = tun->GetLocalEndpoint (); + + uint32_t keepAlive = section.second.get(I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL, 0); + if (keepAlive) + { + tun->SetKeepAliveInterval (keepAlive); + LogPrint(eLogInfo, "Clients: I2P Client tunnel keep alive interval set to ", keepAlive); + } } uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 801dc0cd..cb28e40e 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -48,6 +48,7 @@ namespace client const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels"; const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout"; + const char I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL[] = "keepaliveinterval"; const char I2P_SERVER_TUNNEL_HOST[] = "host"; const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride"; const char I2P_SERVER_TUNNEL_PORT[] = "port"; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index c01f0fe3..f70ebb8f 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -532,7 +532,7 @@ namespace client I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), - m_DestinationPort (destinationPort) + m_DestinationPort (destinationPort), m_KeepAliveInterval (0) { } @@ -540,14 +540,24 @@ namespace client { TCPIPAcceptor::Start (); GetAddress (); + if (m_KeepAliveInterval) + ScheduleKeepAliveTimer (); } void I2PClientTunnel::Stop () { TCPIPAcceptor::Stop(); m_Address = nullptr; + if (m_KeepAliveTimer) m_KeepAliveTimer->cancel (); } + void I2PClientTunnel::SetKeepAliveInterval (uint32_t keepAliveInterval) + { + m_KeepAliveInterval = keepAliveInterval; + if (m_KeepAliveInterval) + m_KeepAliveTimer.reset (new boost::asio::deadline_timer (GetLocalDestination ()->GetService ())); + } + /* HACK: maybe we should create a caching IdentHash provider in AddressBook */ std::shared_ptr I2PClientTunnel::GetAddress () { @@ -569,6 +579,31 @@ namespace client return nullptr; } + void I2PClientTunnel::ScheduleKeepAliveTimer () + { + if (m_KeepAliveTimer) + { + m_KeepAliveTimer->expires_from_now (boost::posix_time::seconds(m_KeepAliveInterval)); + m_KeepAliveTimer->async_wait (std::bind (&I2PClientTunnel::HandleKeepAliveTimer, + this, std::placeholders::_1)); + } + } + + void I2PClientTunnel::HandleKeepAliveTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + if (m_Address && m_Address->IsValid ()) + { + if (m_Address->IsIdentHash ()) + GetLocalDestination ()->SendPing (m_Address->identHash); + else + GetLocalDestination ()->SendPing (m_Address->blindedPublicKey); + } + ScheduleKeepAliveTimer (); + } + } + I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, int inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 1db34b6c..d21b2e11 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -153,16 +153,22 @@ namespace client void Stop (); const char* GetName() { return m_Name.c_str (); } - + void SetKeepAliveInterval (uint32_t keepAliveInterval); + private: std::shared_ptr GetAddress (); + + void ScheduleKeepAliveTimer (); + void HandleKeepAliveTimer (const boost::system::error_code& ecode); private: std::string m_Name, m_Destination; std::shared_ptr m_Address; int m_DestinationPort; + uint32_t m_KeepAliveInterval; + std::unique_ptr m_KeepAliveTimer; }; From cc75efcbca2673a33ca6dfcc76b03e09a54278a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Sep 2021 18:25:15 -0400 Subject: [PATCH 0332/2193] fixed build for C++11 --- libi2pd/Destination.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index dd811593..54137664 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1104,18 +1104,22 @@ namespace client if (leaseSet) m_StreamingDestination->SendPing (leaseSet); else + { + auto s = m_StreamingDestination; RequestDestination (to, - [s = m_StreamingDestination](std::shared_ptr ls) + [s](std::shared_ptr ls) { if (ls) s->SendPing (ls); }); + } } } void ClientDestination::SendPing (std::shared_ptr to) { + auto s = m_StreamingDestination; RequestDestinationWithEncryptedLeaseSet (to, - [s = m_StreamingDestination](std::shared_ptr ls) + [s](std::shared_ptr ls) { if (ls) s->SendPing (ls); }); From d723faaaa3a3539bc1b09ca52351c73297a38680 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 28 Sep 2021 14:27:22 +0300 Subject: [PATCH 0333/2193] [UDPTunnel] restart local listener on error Signed-off-by: R4SAS --- libi2pd_client/I2PTunnel.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index f70ebb8f..b97270e4 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -964,7 +964,8 @@ namespace client RemotePort(remotePort), m_LastPort (0), m_cancel_resolve(false) { - m_LocalSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU )); + m_LocalSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU)); + m_LocalSocket.set_option (boost::asio::socket_base::reuse_address (true)); auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, @@ -991,7 +992,8 @@ namespace client void I2PUDPClientTunnel::HandleRecvFromLocal(const boost::system::error_code & ec, std::size_t transferred) { if(ec) { - LogPrint(eLogError, "UDP Client: ", ec.message()); + LogPrint(eLogError, "UDP Client: Reading from socket error: ", ec.message(), ". Restarting listener..."); + RecvFromLocal(); // Restart listener and continue work return; } if(!m_RemoteIdent) { @@ -1016,7 +1018,7 @@ namespace client auto ts = i2p::util::GetMillisecondsSinceEpoch(); LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent); - if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) + if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); else m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); From af133f4968946d3074e8a70799ba8f9a776b1896 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Sep 2021 12:38:38 -0400 Subject: [PATCH 0334/2193] fixed crash if incorrect blinded signature type --- libi2pd/LeaseSet.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 75187cfe..f6734b10 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -912,6 +912,11 @@ namespace data uint8_t blindedPriv[64], blindedPub[128]; // 64 and 128 max size_t publicKeyLen = blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub); std::unique_ptr blindedSigner (i2p::data::PrivateKeys::CreateSigner (blindedKey.GetBlindedSigType (), blindedPriv)); + if (!blindedSigner) + { + LogPrint (eLogError, "LeaseSet2: Can't create blinded signer for signature type ", blindedKey.GetSigType ()); + return; + } auto offset = 1; htobe16buf (m_Buffer + offset, blindedKey.GetBlindedSigType ()); offset += 2; // Blinded Public Key Sig Type memcpy (m_Buffer + offset, blindedPub, publicKeyLen); offset += publicKeyLen; // Blinded Public Key From e6bcd04a36a705cd24956534a6df28024f664b39 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Oct 2021 19:38:33 -0400 Subject: [PATCH 0335/2193] short build message for re-created tunnels and far end transports --- libi2pd/RouterInfo.h | 13 ++++++++----- libi2pd/Tunnel.cpp | 13 ++++++++----- libi2pd/Tunnel.h | 3 +++ libi2pd/TunnelConfig.h | 18 +++++++++++++----- libi2pd/TunnelPool.cpp | 19 ++++++++++++++----- libi2pd/TunnelPool.h | 1 + 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 8ffd81cd..c16f8e5f 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -67,7 +67,8 @@ namespace data eSSUV6 = 0x08, eNTCP2V6Mesh = 0x10 }; - + typedef uint8_t CompatibleTransports; + enum Caps { eFloodfill = 0x01, @@ -206,9 +207,10 @@ namespace data void EnableMesh (); void DisableMesh (); bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; - bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; - bool IsReachableBy (uint8_t transports) const { return m_ReachableTransports & transports; }; - bool HasValidAddresses () const { return m_SupportedTransports; }; + bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; }; + bool IsReachableBy (CompatibleTransports transports) const { return m_ReachableTransports & transports; }; + CompatibleTransports GetCompatibleTransports (bool incoming) const { return incoming ? m_ReachableTransports : m_SupportedTransports; }; + bool HasValidAddresses () const { return m_SupportedTransports; }; bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; @@ -273,7 +275,8 @@ namespace data boost::shared_ptr m_Addresses; // TODO: use std::shared_ptr and std::atomic_store for gcc >= 4.9 std::map m_Properties; bool m_IsUpdated, m_IsUnreachable; - uint8_t m_SupportedTransports, m_ReachableTransports, m_Caps; + CompatibleTransports m_SupportedTransports, m_ReachableTransports; + uint8_t m_Caps; int m_Version; mutable std::shared_ptr m_Profile; }; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 76504e1f..1f69470c 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -31,8 +31,9 @@ namespace tunnel { Tunnel::Tunnel (std::shared_ptr config): TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()), - m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false), - m_Latency (0) + m_Config (config), m_IsShortBuildMessage (false), m_Pool (nullptr), + m_State (eTunnelStatePending), m_FarEndTransports (0), + m_IsRecreated (false), m_Latency (0) { } @@ -180,6 +181,8 @@ namespace tunnel m_Hops.push_back (std::unique_ptr(tunnelHop)); hop = hop->prev; } + m_IsShortBuildMessage = m_Config->IsShort (); + m_FarEndTransports = m_Config->GetFarEndTransports (); m_Config = nullptr; } if (established) m_State = eTunnelStateEstablished; @@ -715,7 +718,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel"); CreateTunnel ( std::make_shared (std::vector > { router->GetRouterIdentity () }, - inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()), nullptr + inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), false), nullptr ); } } @@ -791,7 +794,7 @@ namespace tunnel } LogPrint (eLogDebug, "Tunnel: creating one hop inbound tunnel"); CreateTunnel ( - std::make_shared (std::vector > { router->GetRouterIdentity () }), nullptr + std::make_shared (std::vector > { router->GetRouterIdentity () }, false), nullptr ); } } @@ -897,7 +900,7 @@ namespace tunnel { // build symmetric outbound tunnel CreateTunnel (std::make_shared(newTunnel->GetInvertedPeers (), - newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()), nullptr, + newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash (), false), nullptr, GetNextOutboundTunnel ()); } else diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a1fd247a..2e1c9534 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -71,6 +71,7 @@ namespace tunnel std::shared_ptr GetTunnelConfig () const { return m_Config; } std::vector > GetPeers () const; std::vector > GetInvertedPeers () const; + bool IsShortBuildMessage () const { return m_IsShortBuildMessage; }; TunnelState GetState () const { return m_State; }; void SetState (TunnelState state); bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; @@ -109,8 +110,10 @@ namespace tunnel std::shared_ptr m_Config; std::vector > m_Hops; + bool m_IsShortBuildMessage; std::shared_ptr m_Pool; // pool, tunnel belongs to, or null TunnelState m_State; + i2p::data::RouterInfo::CompatibleTransports m_FarEndTransports; bool m_IsRecreated; // if tunnel is replaced by new, or new tunnel requested to replace uint64_t m_Latency; // in milliseconds }; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 8cb46d09..f198dffd 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -82,16 +82,17 @@ namespace tunnel public: TunnelConfig (const std::vector >& peers, - bool isShort = false): // inbound - m_IsShort (isShort) + bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // inbound + m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); m_LastHop->SetNextIdent (i2p::context.GetIdentHash ()); } TunnelConfig (const std::vector >& peers, - uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort = false): // outbound - m_IsShort (isShort) + uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort, + i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // outbound + m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); m_FirstHop->isGateway = false; @@ -112,6 +113,11 @@ namespace tunnel bool IsShort () const { return m_IsShort; } + i2p::data::RouterInfo::CompatibleTransports GetFarEndTransports () const + { + return m_FarEndTransports; + } + TunnelHopConfig * GetFirstHop () const { return m_FirstHop; @@ -178,7 +184,8 @@ namespace tunnel protected: // this constructor can't be called from outside - TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false) + TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false), + m_FarEndTransports (0) { } @@ -190,6 +197,7 @@ namespace tunnel TunnelHopConfig * m_FirstHop, * m_LastHop; bool m_IsShort; + i2p::data::RouterInfo::CompatibleTransports m_FarEndTransports; }; class ZeroHopsTunnelConfig: public TunnelConfig diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7a5721fb..b349ada6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -495,6 +495,8 @@ namespace tunnel } prevHop = hop; path.Add (hop); + if (i == numHops - 1) + path.farEndTransports = hop->GetCompatibleTransports (inbound); } return true; } @@ -527,7 +529,11 @@ namespace tunnel if (r) { if (r->IsECIES ()) + { path.Add (r); + if (i == numHops - 1) + path.farEndTransports = r->GetCompatibleTransports (isInbound); + } else { LogPrint (eLogError, "Tunnels: ElGamal router ", ident.ToBase64 (), " is not supported"); @@ -557,7 +563,7 @@ namespace tunnel if (m_NumInboundHops > 0) { path.Reverse (); - config = std::make_shared (path.peers, path.isShort); + config = std::make_shared (path.peers, path.isShort, path.farEndTransports); } auto tunnel = tunnels.CreateInboundTunnel (config, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops @@ -581,7 +587,7 @@ namespace tunnel std::shared_ptr config; if (m_NumInboundHops > 0 && tunnel->GetPeers().size()) { - config = std::make_shared(tunnel->GetPeers ()); + config = std::make_shared(tunnel->GetPeers (), tunnel->IsShortBuildMessage ()); } if (!m_NumInboundHops || config) { @@ -606,7 +612,8 @@ namespace tunnel { std::shared_ptr config; if (m_NumOutboundHops > 0) - config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash (), path.isShort); + config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), path.isShort, path.farEndTransports); std::shared_ptr tunnel; if (path.isShort) @@ -643,7 +650,8 @@ namespace tunnel std::shared_ptr config; if (m_NumOutboundHops > 0 && tunnel->GetPeers().size()) { - config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); + config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage ()); } if (!m_NumOutboundHops || config) { @@ -660,7 +668,8 @@ namespace tunnel { LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); auto tunnel = tunnels.CreateInboundTunnel ( - m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers ()) : nullptr, + m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers (), + outboundTunnel->IsShortBuildMessage ()) : nullptr, shared_from_this (), outboundTunnel); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 97ca0419..875a9955 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -40,6 +40,7 @@ namespace tunnel { std::vector peers; bool isShort = true; + i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0; void Add (std::shared_ptr r); void Reverse (); From 49e8cf89d83339ae44ec8f155d8e40dfef1da2aa Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Oct 2021 12:42:32 -0400 Subject: [PATCH 0336/2193] don't send short tunnel build messages for ElGamal only destinations --- libi2pd/TunnelPool.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b349ada6..5ed330c8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -610,6 +610,9 @@ namespace tunnel Path path; if (SelectPeers (path, false)) { + if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + path.isShort = false; // because can't handle ECIES encrypted reply + std::shared_ptr config; if (m_NumOutboundHops > 0) config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), From 48131f4597dcb9a62e539d9a713e9dadaf493d7d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 7 Oct 2021 15:08:33 -0400 Subject: [PATCH 0337/2193] don't store full path with RouterInfo --- libi2pd/NetDb.cpp | 3 ++- libi2pd/RouterInfo.cpp | 26 +++++++++++++------------- libi2pd/RouterInfo.h | 8 ++++---- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 9c079d57..8d0025ec 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -963,7 +963,8 @@ namespace data if (router) { LogPrint (eLogDebug, "NetDb: requested RouterInfo ", key, " found"); - router->LoadBuffer (); + if (!router->GetBuffer ()) + router->LoadBuffer (m_Storage.Path (router->GetIdentHashBase64 ())); if (router->GetBuffer ()) replyMsg = CreateDatabaseStoreMsg (router); } diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 5d66e0e4..f2eefcd6 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -35,12 +35,12 @@ namespace data } RouterInfo::RouterInfo (const std::string& fullPath): - m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), - m_SupportedTransports (0), m_ReachableTransports (0), m_Caps (0), m_Version (0) + m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0), + m_ReachableTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; - ReadFromFile (); + ReadFromFile (fullPath); } RouterInfo::RouterInfo (const uint8_t * buf, int len): @@ -113,16 +113,16 @@ namespace data m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); } - bool RouterInfo::LoadFile () + bool RouterInfo::LoadFile (const std::string& fullPath) { - std::ifstream s(m_FullPath, std::ifstream::binary); + std::ifstream s(fullPath, std::ifstream::binary); if (s.is_open ()) { s.seekg (0,std::ios::end); m_BufferLen = s.tellg (); if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE) { - LogPrint(eLogError, "RouterInfo: File", m_FullPath, " is malformed"); + LogPrint(eLogError, "RouterInfo: File", fullPath, " is malformed"); return false; } s.seekg(0, std::ios::beg); @@ -131,15 +131,15 @@ namespace data } else { - LogPrint (eLogError, "RouterInfo: Can't open file ", m_FullPath); + LogPrint (eLogError, "RouterInfo: Can't open file ", fullPath); return false; } return true; } - void RouterInfo::ReadFromFile () + void RouterInfo::ReadFromFile (const std::string& fullPath) { - if (LoadFile ()) + if (LoadFile (fullPath)) ReadFromBuffer (false); else m_IsUnreachable = true; @@ -748,11 +748,11 @@ namespace data return bufbe64toh (buf + size) > m_Timestamp; } - const uint8_t * RouterInfo::LoadBuffer () + const uint8_t * RouterInfo::LoadBuffer (const std::string& fullPath) { if (!m_Buffer) { - if (LoadFile ()) + if (LoadFile (fullPath)) LogPrint (eLogDebug, "RouterInfo: Buffer for ", GetIdentHashAbbreviation (GetIdentHash ()), " loaded from file"); } return m_Buffer; @@ -783,8 +783,8 @@ namespace data bool RouterInfo::SaveToFile (const std::string& fullPath) { - m_FullPath = fullPath; - if (!m_Buffer) { + if (!m_Buffer) + { LogPrint (eLogError, "RouterInfo: Can't save, m_Buffer == NULL"); return false; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index c16f8e5f..38acbb16 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -226,7 +226,7 @@ namespace data bool IsUnreachable () const { return m_IsUnreachable; }; const uint8_t * GetBuffer () const { return m_Buffer; }; - const uint8_t * LoadBuffer (); // load if necessary + const uint8_t * LoadBuffer (const std::string& fullPath); // load if necessary int GetBufferLen () const { return m_BufferLen; }; void CreateBuffer (const PrivateKeys& privateKeys); @@ -252,8 +252,8 @@ namespace data private: - bool LoadFile (); - void ReadFromFile (); + bool LoadFile (const std::string& fullPath); + void ReadFromFile (const std::string& fullPath); void ReadFromStream (std::istream& s); void ReadFromBuffer (bool verifySignature); void WriteToStream (std::ostream& s) const; @@ -267,7 +267,7 @@ namespace data private: - std::string m_FullPath, m_Family; + std::string m_Family; std::shared_ptr m_RouterIdentity; uint8_t * m_Buffer; size_t m_BufferLen; From 7def2fa6a34d85dde1bdb436862a9b24a163b2e1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Oct 2021 09:53:21 -0400 Subject: [PATCH 0338/2193] use std::vector for address list --- libi2pd/RouterInfo.cpp | 1 + libi2pd/RouterInfo.h | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index f2eefcd6..7747736c 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -194,6 +194,7 @@ namespace data auto addresses = boost::make_shared(); uint8_t numAddresses; s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return; + addresses->reserve (numAddresses); for (int i = 0; i < numAddresses; i++) { uint8_t supportedTransports = 0; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 38acbb16..b2b883dc 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -157,7 +156,7 @@ namespace data bool IsV4 () const { return (caps & AddressCaps::eV4) || (host.is_v4 () && !host.is_unspecified ()); }; bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); }; }; - typedef std::list > Addresses; + typedef std::vector > Addresses; RouterInfo (); RouterInfo (const std::string& fullPath); From 44e01b41f8cf166d26fd3555f79690260792ba51 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Oct 2021 13:28:16 -0400 Subject: [PATCH 0339/2193] reserve address for 3 introducers --- libi2pd/RouterInfo.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 7747736c..cb5a3db7 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -187,13 +187,14 @@ namespace data void RouterInfo::ReadFromStream (std::istream& s) { + if (!s) return; m_Caps = 0; s.read ((char *)&m_Timestamp, sizeof (m_Timestamp)); m_Timestamp = be64toh (m_Timestamp); // read addresses auto addresses = boost::make_shared(); uint8_t numAddresses; - s.read ((char *)&numAddresses, sizeof (numAddresses)); if (!s) return; + s.read ((char *)&numAddresses, sizeof (numAddresses)); addresses->reserve (numAddresses); for (int i = 0; i < numAddresses; i++) { @@ -282,7 +283,11 @@ namespace data if (s) continue; else return; } if (index >= address->ssu->introducers.size ()) + { + if (address->ssu->introducers.empty ()) // first time + address->ssu->introducers.reserve (3); address->ssu->introducers.resize (index + 1); + } Introducer& introducer = address->ssu->introducers.at (index); if (!strcmp (key, "ihost")) { From 1af9117b80ec0461d32eb7229d81ba57f2ed8775 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 15 Oct 2021 14:01:41 -0400 Subject: [PATCH 0340/2193] don't create new tunnel message for encryption/decryption --- libi2pd/TransitTunnel.cpp | 17 ++++++++--------- libi2pd/TransitTunnel.h | 8 ++++---- libi2pd/Tunnel.cpp | 13 ++++++------- libi2pd/Tunnel.h | 4 ++-- libi2pd/TunnelBase.h | 2 +- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index dc7655d1..c4f3fa19 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -37,15 +37,14 @@ namespace tunnel { } - void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnelParticipant::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { - auto newMsg = CreateEmptyTunnelDataMsg (false); - EncryptTunnelMsg (tunnelMsg, newMsg); + EncryptTunnelMsg (tunnelMsg, tunnelMsg); m_NumTransmittedBytes += tunnelMsg->GetLength (); - htobe32buf (newMsg->GetPayload (), GetNextTunnelID ()); - newMsg->FillI2NPMessageHeader (eI2NPTunnelData); - m_TunnelDataMsgs.push_back (newMsg); + htobe32buf (tunnelMsg->GetPayload (), GetNextTunnelID ()); + tunnelMsg->FillI2NPMessageHeader (eI2NPTunnelData); + m_TunnelDataMsgs.push_back (tunnelMsg); } void TransitTunnelParticipant::FlushTunnelDataMsgs () @@ -65,7 +64,7 @@ namespace tunnel LogPrint (eLogError, "TransitTunnel: We are not a gateway for ", GetTunnelID ()); } - void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { LogPrint (eLogError, "TransitTunnel: Incoming tunnel message is not supported ", GetTunnelID ()); } @@ -85,7 +84,7 @@ namespace tunnel m_Gateway.SendBuffer (); } - void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { auto newMsg = CreateEmptyTunnelDataMsg (true); EncryptTunnelMsg (tunnelMsg, newMsg); diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index e71ec750..bce90958 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -35,7 +35,7 @@ namespace tunnel // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out); private: @@ -54,7 +54,7 @@ namespace tunnel ~TransitTunnelParticipant (); size_t GetNumTransmittedBytes () const { return m_NumTransmittedBytes; }; - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); void FlushTunnelDataMsgs (); private: @@ -95,7 +95,7 @@ namespace tunnel void Cleanup () { m_Endpoint.Cleanup (); } - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } private: diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 1f69470c..c8a1cc99 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -243,13 +243,12 @@ namespace tunnel } } - void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr msg) + void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr&& msg) { if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive - auto newMsg = CreateEmptyTunnelDataMsg (true); - EncryptTunnelMsg (msg, newMsg); - newMsg->from = shared_from_this (); - m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg); + EncryptTunnelMsg (msg, msg); + msg->from = shared_from_this (); + m_Endpoint.HandleDecryptedTunnelDataMsg (msg); } void InboundTunnel::Print (std::stringstream& s) const @@ -308,7 +307,7 @@ namespace tunnel m_Gateway.SendBuffer (); } - void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr tunnelMsg) + void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) { LogPrint (eLogError, "Tunnel: incoming message for outbound tunnel ", GetTunnelID ()); } @@ -519,7 +518,7 @@ namespace tunnel if (tunnel) { if (typeID == eI2NPTunnelData) - tunnel->HandleTunnelDataMsg (msg); + tunnel->HandleTunnelDataMsg (std::move (msg)); else // tunnel gateway assumed HandleTunnelGatewayMsg (tunnel, msg); } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 2e1c9534..930d0c58 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -132,7 +132,7 @@ namespace tunnel void Print (std::stringstream& s) const; // implements TunnelBase - void HandleTunnelDataMsg (std::shared_ptr tunnelMsg); + void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg); bool IsInbound() const { return false; } @@ -148,7 +148,7 @@ namespace tunnel public: InboundTunnel (std::shared_ptr config): Tunnel (config), m_Endpoint (true) {}; - void HandleTunnelDataMsg (std::shared_ptr msg); + void HandleTunnelDataMsg (std::shared_ptr&& msg); virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; void Print (std::stringstream& s) const; bool IsInbound() const { return true; } diff --git a/libi2pd/TunnelBase.h b/libi2pd/TunnelBase.h index f98066d3..8d0edff1 100644 --- a/libi2pd/TunnelBase.h +++ b/libi2pd/TunnelBase.h @@ -47,7 +47,7 @@ namespace tunnel virtual ~TunnelBase () {}; virtual void Cleanup () {}; - virtual void HandleTunnelDataMsg (std::shared_ptr tunnelMsg) = 0; + virtual void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) = 0; virtual void SendTunnelDataMsg (std::shared_ptr msg) = 0; virtual void FlushTunnelDataMsgs () {}; virtual void EncryptTunnelMsg (std::shared_ptr in, std::shared_ptr out) = 0; From d310efcb5cbe5f81cbd1b5705109b8f9caf14294 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Oct 2021 11:31:37 -0400 Subject: [PATCH 0341/2193] pass I2NPMessage by move --- libi2pd/I2NPProtocol.cpp | 2 +- libi2pd/I2NPProtocol.h | 2 +- libi2pd/NTCP2.cpp | 5 +++-- libi2pd/SSUData.cpp | 2 +- libi2pd/Transports.cpp | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 29d68b3c..0bc721ec 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -860,7 +860,7 @@ namespace i2p Flush (); } - void I2NPMessagesHandler::PutNextMessage (std::shared_ptr msg) + void I2NPMessagesHandler::PutNextMessage (std::shared_ptr&& msg) { if (msg) { diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index f0777ac2..c8bf1697 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -301,7 +301,7 @@ namespace tunnel public: ~I2NPMessagesHandler (); - void PutNextMessage (std::shared_ptr msg); + void PutNextMessage (std::shared_ptr&& msg); void Flush (); private: diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 05d68203..296139a3 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -876,11 +876,12 @@ namespace transport break; } auto nextMsg = NewI2NPMessage (size); - nextMsg->Align (12); // for possible tunnel msg + nextMsg->Align (6); // for possible tunnel msg + nextMsg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); nextMsg->FromNTCP2 (); - m_Handler.PutNextMessage (nextMsg); + m_Handler.PutNextMessage (std::move (nextMsg)); break; } case eNTCP2BlkTermination: diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index ccc89b41..18b471e2 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -247,7 +247,7 @@ namespace transport m_ReceivedMessages.emplace (msgID, m_LastMessageReceivedTime); if (!msg->IsExpired ()) { - m_Handler.PutNextMessage (msg); + m_Handler.PutNextMessage (std::move (msg)); } else LogPrint (eLogDebug, "SSU: message expired"); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 181c3663..6fd5fad9 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -389,7 +389,7 @@ namespace transport { // we send it to ourself for (auto& it: msgs) - m_LoopbackHandler.PutNextMessage (it); + m_LoopbackHandler.PutNextMessage (std::move (it)); m_LoopbackHandler.Flush (); return; } From 197882a4c9e15ab6b3a40f4c658c3e6720019417 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Oct 2021 15:30:24 -0400 Subject: [PATCH 0342/2193] create I2NP depending on type in I2NP block --- libi2pd/NTCP2.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 296139a3..9e18c81e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -875,13 +875,16 @@ namespace transport LogPrint (eLogError, "NTCP2: I2NP block is too long ", size); break; } - auto nextMsg = NewI2NPMessage (size); - nextMsg->Align (6); // for possible tunnel msg - nextMsg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + auto nextMsg = (frame[offset] == eI2NPTunnelData) ? NewI2NPTunnelMessage (true) : NewI2NPMessage (size); nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header - memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); - nextMsg->FromNTCP2 (); - m_Handler.PutNextMessage (std::move (nextMsg)); + if (nextMsg->len <= nextMsg->maxLen) + { + memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); + nextMsg->FromNTCP2 (); + m_Handler.PutNextMessage (std::move (nextMsg)); + } + else + LogPrint (eLogError, "NTCP2: I2NP block is too long for I2NP message"); break; } case eNTCP2BlkTermination: From 278fd2d8d58210a126abfbbe4eb6a3b7d4b2063b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Oct 2021 19:03:08 -0400 Subject: [PATCH 0343/2193] create tunnel I2NP message for tunnel data --- libi2pd/SSUData.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 18b471e2..6bf01778 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -176,7 +176,8 @@ namespace transport if (it == m_IncompleteMessages.end ()) { // create new message - auto msg = NewI2NPShortMessage (); + auto msg = (!fragmentNum && fragmentSize > 0 && buf[I2NP_SHORT_HEADER_TYPEID_OFFSET] == eI2NPTunnelData) ? + NewI2NPTunnelMessage (true) : NewI2NPShortMessage (); msg->len -= I2NP_SHORT_HEADER_SIZE; it = m_IncompleteMessages.insert (std::make_pair (msgID, m_Session.GetServer ().GetIncompleteMessagesPool ().AcquireShared (msg))).first; From efd84a240483de954c688cc12ebdf78e03968b24 Mon Sep 17 00:00:00 2001 From: xanoni <77220130+xanoni@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:10:17 -0400 Subject: [PATCH 0344/2193] Makefile: set default target ("all") Fixes compilation on Darwin, see: https://github.com/PurpleI2P/i2pd/pull/1698#issuecomment-946304938 --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index d7765af7..59b1df1a 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.DEFAULT_GOAL := all + SYS := $(shell $(CXX) -dumpmachine) ifneq (, $(findstring darwin, $(SYS))) From ff3d2db85e4c49600adf38c6de9087881b57247e Mon Sep 17 00:00:00 2001 From: xanoni <77220130+xanoni@users.noreply.github.com> Date: Mon, 18 Oct 2021 22:29:30 -0400 Subject: [PATCH 0345/2193] Darwin: allow calling make install more than once This commit ensures that `gzip` does not overwrite any of the repo files, because that prevents `make install` from executing more than once. --- .gitignore | 1 + Makefile.homebrew | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bafe2e18..75bd6abb 100644 --- a/.gitignore +++ b/.gitignore @@ -260,6 +260,7 @@ docs/generated build/Makefile # debian stuff +debian/i2pd.1.gz .pc/ # qt diff --git a/Makefile.homebrew b/Makefile.homebrew index c1992296..8d6dd7a3 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -44,7 +44,7 @@ install: all install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd @cp -R contrib/certificates ${PREFIX}/share/i2pd/ install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd - @gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1 + @gzip -kf debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1 @ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/ @ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf @ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt From 0c25e8f1eb0f90089c8f95158cfa147672d28af8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 6 Oct 2021 21:35:23 +0300 Subject: [PATCH 0346/2193] [build] changes in windows build script Signed-off-by: R4SAS --- build/build_mingw.cmd | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index e8f1378b..a4e6d8de 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -34,13 +34,19 @@ del /S build_*.log >> nul 2>&1 echo Receiving latest commit and cleaning up... %xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1 -echo. REM set to variable current commit hash -FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO ( +FOR /F "usebackq" %%a IN (`%xSH% "git describe --tags"`) DO ( set tag=%%a ) +REM set to variable latest released tag +FOR /F "usebackq" %%b IN (`%xSH% "git describe --abbrev=0"`) DO ( + set reltag=%%b +) + +echo Preparing configuration files and README for packaging... + %xSH% "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul REM converting configuration files to DOS format (usable in default notepad) @@ -64,8 +70,9 @@ call :BUILDING_XP echo. REM compile installer -C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%tag%.0" build\win_installer.iss >> build\build.log 2>&1 +C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%reltag%.0" build\win_installer.iss >> build\build.log 2>&1 +%xSH% "git checkout contrib/*" >> build\build.log 2>&1 del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul echo Build complete... @@ -74,13 +81,13 @@ exit /b 0 :BUILDING %xSH% "make clean" >> nul -echo Building i2pd %tag% for win%bitness% +echo Building i2pd %tag% for win%bitness%... %xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && cp i2pd.exe i2pd_x%bitness%.exe && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build\build_win%bitness%_%tag%.log 2>&1 goto EOF :BUILDING_XP %xSH% "make clean" >> nul -echo Building i2pd %tag% for winxp +echo Building i2pd %tag% for winxp... %xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && cp i2pd.exe i2pd_xp.exe && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build\build_winxp_%tag%.log 2>&1 :EOF \ No newline at end of file From 8a58572b342449b1e6c90cb9bfb201b9c6614be3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 19 Oct 2021 18:24:49 +0300 Subject: [PATCH 0347/2193] [webconsole] upload example dark style Signed-off-by: R4SAS --- contrib/webconsole/style-dark.css | 272 ++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 contrib/webconsole/style-dark.css diff --git a/contrib/webconsole/style-dark.css b/contrib/webconsole/style-dark.css new file mode 100644 index 00000000..6ec19023 --- /dev/null +++ b/contrib/webconsole/style-dark.css @@ -0,0 +1,272 @@ +:root { + --main-bg-color: #121212; + --main-text-color: #156A3D; + --main-link-color: #894C84; +} + +body { + font: 100%/1.5em sans-serif; + margin: 0; + padding: 1.5em; + background: var(--main-bg-color); + color: var(--main-text-color); +} + +a, .slide label { + text-decoration: none; + color: var(--main-link-color); +} + +a:hover, .slide label:hover, button[type=submit]:hover { + color: #FAFAFA; + background: var(--main-link-color); +} + +a.button { + appearance: button; + text-decoration: none; + padding: 0 5px; + border: 1px solid var(--main-link-color); +} + +.header { + font-size: 2.5em; + text-align: center; + margin: 1em 0; + color: var(--main-link-color); +} + +.wrapper { + margin: 0 auto; + padding: 1em; + max-width: 64em; +} + +.menu { + display: block; + float: left; + overflow: hidden; + max-width: 12em; + white-space: nowrap; + text-overflow: ellipsis; +} + +.listitem { + display: block; + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.tableitem { + font-family: monospace; + font-size: 1.2em; + white-space: nowrap; +} + +.content { + float: left; + font-size: 1em; + margin-left: 4em; + max-width: 48em; + overflow: auto; +} + +.tunnel.established { + color: #56B734; +} + +.tunnel.expiring { + color: #D3AE3F; +} + +.tunnel.failed { + color: #D33F3F; +} + +.tunnel.building { + color: #434343; +} + +caption { + font-size: 1.5em; + text-align: center; + color: var(--main-link-color); +} + +table { + display: table; + border-collapse: collapse; + text-align: center; +} + +table.extaddr { + text-align: left; +} + +table.services { + width: 100%; +} + +textarea { + background-color: var(--main-bg-color); + color: var(--main-text-color); + word-break: break-all; +} + +.streamdest { + width: 120px; + max-width: 240px; + overflow: hidden; + text-overflow: ellipsis; +} + +.slide div.slidecontent, .slide [type="checkbox"] { + display: none; +} + +.slide [type="checkbox"]:checked ~ div.slidecontent { + display: block; + margin-top: 0; + padding: 0; +} + +.disabled { + color: #D33F3F; +} + +.enabled { + color: #56B734; +} + +button[type=submit] { + background-color: transparent; + color: var(--main-link-color); + text-decoration: none; + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input, select, select option { + background-color: var(--main-bg-color); + color: var(--main-link-color); + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input:focus, select:focus, select option:focus { + outline: none; +} + +input[type=number]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +@media screen and (max-width: 1150px) { /* adaptive style */ + .wrapper { + max-width: 58em; + } + + .menu { + max-width: 10em; + } + + .content { + margin-left: 2em; + max-width: 42em; + } +} + +@media screen and (max-width: 980px) { + body { + font: 100%/1.2em sans-serif; + padding: 1.2em 0 0 0; + } + + .menu { + width: 100%; + max-width: unset; + display: block; + float: none; + position: unset; + font-size: 16px; + text-align: center; + } + + .menu a, .commands a { + display: inline-block; + padding: 4px; + } + + .content { + float: none; + margin-left: unset; + margin-top: 16px; + max-width: 100%; + width: 100%; + text-align: center; + } + + a, .slide label { + /* margin-right: 10px; */ + display: block; + /* font-size: 18px; */ + } + + .header { + margin: unset; + font-size: 1.5em; + } + + small { + display: block + } + + a.button { + appearance: button; + text-decoration: none; + margin-top: 10px; + padding: 6px; + border: 2px solid var(--main-link-color); + border-radius: 5px; + width: -webkit-fill-available; + } + + input, select { + width: 35%; + text-align: center; + padding: 5px; + border: 2px solid var(--main-link-color); + border-radius: 5px; + font-size: 18px; + } + + table.extaddr { + margin: auto; + text-align: unset; + } + + textarea { + width: -webkit-fill-available; + height: auto; + padding: 5px; + border: 2px solid var(--main-link-color); + border-radius: 5px; + font-size: 12px; + } + + button[type=submit] { + padding: 5px 15px; + background: transparent; + border: 2px solid var(--main-link-color); + cursor: pointer; + -webkit-border-radius: 5px; + border-radius: 5px; + position: relative; + height: 36px; + display: -webkit-inline-box; + margin-top: 10px; + } +} \ No newline at end of file From af794f901f5b4474de41168873d1cadc674b2988 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Fri, 8 Oct 2021 11:31:47 +0200 Subject: [PATCH 0348/2193] libi2pd: minor logging fixes --- libi2pd/SSUSession.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 3e4eecb8..b28f324b 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -303,7 +303,7 @@ namespace transport } else { - LogPrint (eLogError, "SSU: Wrong external address ", ourIP.to_string ()); + LogPrint (eLogError, "SSU: External address ", ourIP.to_string (), " is in reserved range"); Failed (); } } @@ -609,7 +609,7 @@ namespace transport { *payload = 16; payload++; // size - memcpy (payload, to.address ().to_v6 ().to_bytes ().data (), 16); // Alice's IP V6 + memcpy (payload, to.address ().to_v6 ().to_bytes ().data (), 16); // Charlie's IP V6 payload += 16; // address } htobe16buf (payload, to.port ()); // Charlie's port @@ -703,7 +703,7 @@ namespace transport if (!i2p::util::net::IsInReservedRange (ourIP)) i2p::context.UpdateAddress (ourIP); else - LogPrint (eLogWarning, "SSU: Wrong external address ", ourIP.to_string ()); + LogPrint (eLogError, "SSU: External address ", ourIP.to_string (), " is in reserved range"); if (ourIP.is_v4 ()) { if (ourPort != m_Server.GetPort ()) @@ -1301,7 +1301,7 @@ namespace transport ip = boost::asio::ip::address_v6 (bytes); } else - LogPrint (eLogWarning, "SSU: Address size ", size, " is not supported"); + LogPrint (eLogWarning, "SSU: Address size ", int(size), " is not supported"); buf += size; port = bufbe16toh (buf); return s; From a348e106206a1871d33e01cb381eaff50b0ad29c Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Mon, 18 Oct 2021 12:09:56 +0200 Subject: [PATCH 0349/2193] libi2pd: fix undefined behaviour and memory overruns This fixes the following issues (flagged by cppcheck): [libi2pd/ECIESX25519AEADRatchetSession.cpp:537]: (error) Buffer is accessed out of bounds: m_NSREncodedKey [libi2pd/Identity.cpp:22]: (error) Buffer is accessed out of bounds: keys.publicKey [libi2pd/Identity.cpp:22]: (error) Buffer is accessed out of bounds: publicKey [libi2pd/NetDb.cpp:70] -> [libi2pd/NetDb.cpp:69]: (error) Iterator 'it' used after element has been erased [libi2pd/SSUData.cpp:186] -> [libi2pd/SSUData.cpp:187]: (warning) Shifting 32-bit value by 63 bits is undefined behaviour. --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/Identity.cpp | 3 ++- libi2pd/NetDb.cpp | 2 +- libi2pd/SSUData.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index c9671a7e..88d59c33 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -534,7 +534,7 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; } - memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR + memcpy (m_NSREncodedKey, out + offset, 32); // for possible next NSR memcpy (m_NSRH, m_H, 32); offset += 32; // KDF for Reply Key Section diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index aa03bfb7..fe876997 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -19,7 +19,8 @@ namespace data Identity& Identity::operator=(const Keys& keys) { // copy public and signing keys together - memcpy (publicKey, keys.publicKey, sizeof (publicKey) + sizeof (signingKey)); + memcpy (publicKey, keys.publicKey, sizeof (publicKey)); + memcpy (signingKey, keys.signingKey, sizeof (signingKey)); memset (certificate, 0, sizeof (certificate)); return *this; } diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 8d0025ec..b4ffe2bd 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -66,8 +66,8 @@ namespace data if (it != m_RouterInfos.end ()) { // remove own router - m_RouterInfos.erase (it); m_Floodfills.remove (it->second); + m_RouterInfos.erase (it); } // insert own router m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ()); diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 6bf01778..2f93218e 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -185,7 +185,7 @@ namespace transport auto& incompleteMessage = it->second; // mark fragment as received if (fragmentNum < 64) - incompleteMessage->receivedFragmentsBits |= (0x01 << fragmentNum); + incompleteMessage->receivedFragmentsBits |= (uint64_t(0x01) << fragmentNum); else LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64"); From ae0cf2e8311cd2b8cdaa5a0c9f33907a6b82bfeb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Oct 2021 21:05:22 -0400 Subject: [PATCH 0350/2193] use memory pool for tunnel messages --- libi2pd/I2NPProtocol.cpp | 12 +++--------- libi2pd/Tunnel.cpp | 16 +++++++++++++++- libi2pd/Tunnel.h | 6 ++++++ libi2pd/util.h | 38 ++++++++++++++++++++++++++++++++------ 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 0bc721ec..fa4fa7a6 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -38,20 +38,14 @@ namespace i2p std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { - I2NPMessage * msg = nullptr; if (endpoint) - { - // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet - msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6 - msg->Align (6); - msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - } + return i2p::tunnel::tunnels.NewI2NPTunnelMessage (); else { - msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 + auto msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 msg->Align (12); + return std::shared_ptr(msg); } - return std::shared_ptr(msg); } std::shared_ptr NewI2NPMessage (size_t len) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index c8a1cc99..3de91940 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -488,7 +488,7 @@ namespace tunnel i2p::util::SetThreadName("Tunnels"); std::this_thread::sleep_for (std::chrono::seconds(1)); // wait for other parts are ready - uint64_t lastTs = 0, lastPoolsTs = 0; + uint64_t lastTs = 0, lastPoolsTs = 0, lastMemoryPoolTs = 0; while (m_IsRunning) { try @@ -564,6 +564,11 @@ namespace tunnel ManageTunnelPools (ts); lastPoolsTs = ts; } + if (ts - lastMemoryPoolTs >= 120) // manage memory pool every 2 minutes + { + m_I2NPTunnelMessagesMemoryPool.CleanUpMt (); + lastMemoryPoolTs = ts; + } } } catch (std::exception& ex) @@ -935,6 +940,15 @@ namespace tunnel return outboundTunnel; } + std::shared_ptr Tunnels::NewI2NPTunnelMessage () + { + // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet + auto msg = m_I2NPTunnelMessagesMemoryPool.AcquireSharedMt (); + msg->Align (6); + msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + return msg; + } + int Tunnels::GetTransitTunnelsExpirationTimeout () { int timeout = 0; diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 930d0c58..30d9d565 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -18,6 +18,7 @@ #include #include #include +#include "util.h" #include "Queue.h" #include "Crypto.h" #include "TunnelConfig.h" @@ -40,6 +41,8 @@ namespace tunnel const int MAX_NUM_RECORDS = 8; const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds + const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6 + enum TunnelState { eTunnelStatePending, @@ -219,6 +222,8 @@ namespace tunnel void DeleteTunnelPool (std::shared_ptr pool); void StopTunnelPool (std::shared_ptr pool); + std::shared_ptr NewI2NPTunnelMessage (); + private: template @@ -257,6 +262,7 @@ namespace tunnel std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; + i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; diff --git a/libi2pd/util.h b/libi2pd/util.h index 282ce7aa..d681829c 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -56,12 +56,8 @@ namespace util void CleanUp () { - while (m_Head) - { - auto tmp = m_Head; - m_Head = static_cast(*(void * *)m_Head); // next - ::operator delete ((void *)tmp); - } + CleanUp (m_Head); + m_Head = nullptr; } template @@ -98,6 +94,18 @@ namespace util std::bind (&MemoryPool::Release, this, std::placeholders::_1)); } + protected: + + void CleanUp (T * head) + { + while (head) + { + auto tmp = head; + head = static_cast(*(void * *)head); // next + ::operator delete ((void *)tmp); + } + } + protected: T * m_Head; @@ -131,6 +139,24 @@ namespace util this->Release (it); } + template + std::shared_ptr AcquireSharedMt (TArgs&&... args) + { + return std::shared_ptr(AcquireMt (std::forward(args)...), + std::bind::*)(T *)> (&MemoryPoolMt::ReleaseMt, this, std::placeholders::_1)); + } + + void CleanUpMt () + { + T * head; + { + std::lock_guard l(m_Mutex); + head = this->m_Head; + this->m_Head = nullptr; + } + if (head) this->CleanUp (head); + } + private: std::mutex m_Mutex; From b0f043ec863cfe48332afc5edffc37a949e4ae5c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 Oct 2021 05:28:59 +0300 Subject: [PATCH 0351/2193] [make] USE_GIT_VERSION option to use commit info in version (closes #1702) Signed-off-by: R4SAS --- Makefile | 21 ++++++++++++++++----- daemon/Daemon.cpp | 2 +- libi2pd/version.h | 7 ++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 59b1df1a..f1258874 100644 --- a/Makefile +++ b/Makefile @@ -29,11 +29,17 @@ DAEMON_SRC_DIR := daemon # import source files lists include filelist.mk -USE_AESNI := $(or $(USE_AESNI),yes) -USE_STATIC := $(or $(USE_STATIC),no) -USE_MESHNET := $(or $(USE_MESHNET),no) -USE_UPNP := $(or $(USE_UPNP),no) -DEBUG := $(or $(DEBUG),yes) +USE_AESNI := $(or $(USE_AESNI),yes) +USE_STATIC := $(or $(USE_STATIC),no) +USE_MESHNET := $(or $(USE_MESHNET),no) +USE_UPNP := $(or $(USE_UPNP),no) +DEBUG := $(or $(DEBUG),yes) + +# for debugging purposes only, when commit hash needed in trunk builds in i2pd version string +USE_GIT_VERSION := $(or $(USE_GIT_VERSION),no) + +# for MacOS only, waiting for "1", not "yes" +HOMEBREW := $(or $(HOMEBREW),0) ifeq ($(DEBUG),yes) CXX_DEBUG = -g @@ -66,6 +72,11 @@ ifeq ($(USE_MESHNET),yes) NEEDED_CXXFLAGS += -DMESHNET endif +ifeq ($(USE_GIT_VERSION),yes) + GIT_VERSION := $(shell git describe --tags) + NEEDED_CXXFLAGS += -DGITVER=\"$(GIT_VERSION)\" +endif + NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR) LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 445c4dfd..8cee7852 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -134,7 +134,7 @@ namespace util // use stdout -- default } - LogPrint(eLogNone, "i2pd v", VERSION, " starting"); + LogPrint(eLogNone, "i2pd v", VERSION, " (", I2P_VERSION, ") starting"); LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); LogPrint(eLogDebug, "FS: certificates directory: ", certsdir); diff --git a/libi2pd/version.h b/libi2pd/version.h index 97351c40..5aba36bd 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -19,7 +19,12 @@ #define I2PD_VERSION_MINOR 39 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 -#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) +#ifdef GITVER + #define I2PD_VERSION GITVER +#else + #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) +#endif + #define VERSION I2PD_VERSION #ifdef MESHNET From 0a62a962d7d702d66acab122902521ae41d734b7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 Oct 2021 05:57:04 +0300 Subject: [PATCH 0352/2193] [debian] update upnp patch Signed-off-by: R4SAS --- debian/patches/02-upnp.patch | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/debian/patches/02-upnp.patch b/debian/patches/02-upnp.patch index 75ea2bfa..99698737 100644 --- a/debian/patches/02-upnp.patch +++ b/debian/patches/02-upnp.patch @@ -2,16 +2,16 @@ Description: Enable UPnP usage in package Author: r4sas Reviewed-By: r4sas -Last-Update: 2021-01-16 +Last-Update: 2021-10-22 --- i2pd.orig/Makefile +++ i2pd/Makefile -@@ -21,7 +21,7 @@ include filelist.mk - USE_AESNI := $(or $(USE_AESNI),yes) - USE_STATIC := $(or $(USE_STATIC),no) - USE_MESHNET := $(or $(USE_MESHNET),no) --USE_UPNP := $(or $(USE_UPNP),no) -+USE_UPNP := $(or $(USE_UPNP),yes) - DEBUG := $(or $(DEBUG),yes) +@@ -32,7 +32,7 @@ include filelist.mk + USE_AESNI := $(or $(USE_AESNI),yes) + USE_STATIC := $(or $(USE_STATIC),no) + USE_MESHNET := $(or $(USE_MESHNET),no) +-USE_UPNP := $(or $(USE_UPNP),no) ++USE_UPNP := $(or $(USE_UPNP),yes) + DEBUG := $(or $(DEBUG),yes) - ifeq ($(DEBUG),yes) + # for debugging purposes only, when commit hash needed in trunk builds in i2pd version string From cdc8e463b7e393458921d2d3788b0dd99feabc6d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 Oct 2021 19:18:45 -0400 Subject: [PATCH 0353/2193] use memory pool for outgoing tunnel gateway messages --- libi2pd/I2NPProtocol.cpp | 9 +-------- libi2pd/Tunnel.cpp | 22 ++++++++++++++++------ libi2pd/Tunnel.h | 6 ++++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index fa4fa7a6..bdd65d30 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -38,14 +38,7 @@ namespace i2p std::shared_ptr NewI2NPTunnelMessage (bool endpoint) { - if (endpoint) - return i2p::tunnel::tunnels.NewI2NPTunnelMessage (); - else - { - auto msg = new I2NPMessageBuffer(); // reserved for alignment and NTCP 16 + 6 + 12 - msg->Align (12); - return std::shared_ptr(msg); - } + return i2p::tunnel::tunnels.NewI2NPTunnelMessage (endpoint); } std::shared_ptr NewI2NPMessage (size_t len) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 3de91940..a315ff49 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -566,6 +566,7 @@ namespace tunnel } if (ts - lastMemoryPoolTs >= 120) // manage memory pool every 2 minutes { + m_I2NPTunnelEndpointMessagesMemoryPool.CleanUpMt (); m_I2NPTunnelMessagesMemoryPool.CleanUpMt (); lastMemoryPoolTs = ts; } @@ -940,13 +941,22 @@ namespace tunnel return outboundTunnel; } - std::shared_ptr Tunnels::NewI2NPTunnelMessage () + std::shared_ptr Tunnels::NewI2NPTunnelMessage (bool endpoint) { - // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet - auto msg = m_I2NPTunnelMessagesMemoryPool.AcquireSharedMt (); - msg->Align (6); - msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header - return msg; + if (endpoint) + { + // should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet + auto msg = m_I2NPTunnelEndpointMessagesMemoryPool.AcquireSharedMt (); + msg->Align (6); + msg->offset += TUNNEL_GATEWAY_HEADER_SIZE; // reserve room for TunnelGateway header + return msg; + } + else + { + auto msg = m_I2NPTunnelMessagesMemoryPool.AcquireSharedMt (); + msg->Align (12); + return msg; + } } int Tunnels::GetTransitTunnelsExpirationTimeout () diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 30d9d565..56166e0b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -41,6 +41,7 @@ namespace tunnel const int MAX_NUM_RECORDS = 8; const int HIGH_LATENCY_PER_HOP = 250; // in milliseconds + const size_t I2NP_TUNNEL_MESSAGE_SIZE = TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34; // reserved for alignment and NTCP 16 + 6 + 12 const size_t I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE = 2*TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28; // reserved for alignment and NTCP 16 + 6 + 6 enum TunnelState @@ -222,7 +223,7 @@ namespace tunnel void DeleteTunnelPool (std::shared_ptr pool); void StopTunnelPool (std::shared_ptr pool); - std::shared_ptr NewI2NPTunnelMessage (); + std::shared_ptr NewI2NPTunnelMessage (bool endpoint); private: @@ -262,7 +263,8 @@ namespace tunnel std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; - i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; + i2p::util::MemoryPoolMt > m_I2NPTunnelEndpointMessagesMemoryPool; + i2p::util::MemoryPoolMt > m_I2NPTunnelMessagesMemoryPool; // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; From f1990bc2ab1c6b9cc32c5f7a07b7a9d08ae0c8f1 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 Oct 2021 21:08:20 -0400 Subject: [PATCH 0354/2193] use tunnel endpoint memroy pool to split to tunnel messages at gateway --- libi2pd/TunnelGateway.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 08df569c..c9ad0357 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -158,8 +158,7 @@ namespace tunnel void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage () { m_CurrentTunnelDataMsg = nullptr; - m_CurrentTunnelDataMsg = NewI2NPShortMessage (); - m_CurrentTunnelDataMsg->Align (12); + m_CurrentTunnelDataMsg = NewI2NPTunnelMessage (true); // tunnel endpoint is at least of two tunnel messages size // we reserve space for padding m_CurrentTunnelDataMsg->offset += TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE; m_CurrentTunnelDataMsg->len = m_CurrentTunnelDataMsg->offset; From 921ec9ec12ead861994c98d96087b93a31051ef5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 Oct 2021 18:10:02 -0400 Subject: [PATCH 0355/2193] fix build with openssl 3.0.0 --- libi2pd/Crypto.cpp | 2 +- libi2pd/Reseed.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 427bbbd6..d38d489a 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1277,7 +1277,7 @@ namespace crypto EVP_PKEY_CTX_set1_hkdf_key (pctx, tempKey, len); } if (info.length () > 0) - EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str (), info.length ()); + EVP_PKEY_CTX_add1_hkdf_info (pctx, (const uint8_t *)info.c_str (), info.length ()); EVP_PKEY_derive (pctx, out, &outLen); EVP_PKEY_CTX_free (pctx); #else diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index aec683d4..2e8eccf7 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -478,7 +478,7 @@ namespace data if (terminator) terminator[0] = 0; } // extract RSA key (we need n only, e = 65537) - RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert)); + const RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert)); const BIGNUM * n, * e, * d; RSA_get0_key(key, &n, &e, &d); PublicKey value; From 9965d72990b704a8c724fb6f5d3a951fce8ca4aa Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Oct 2021 21:36:34 -0400 Subject: [PATCH 0356/2193] don't store EVP_PKEY with EdDSA signer and verifier --- libi2pd/Signature.cpp | 27 +++++++++++---------------- libi2pd/Signature.h | 5 ++--- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 88ee4060..28ae5fa6 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,8 +15,7 @@ namespace i2p namespace crypto { #if OPENSSL_EDDSA - EDDSA25519Verifier::EDDSA25519Verifier (): - m_Pkey (nullptr) + EDDSA25519Verifier::EDDSA25519Verifier () { m_MDCtx = EVP_MD_CTX_create (); } @@ -24,13 +23,13 @@ namespace crypto EDDSA25519Verifier::~EDDSA25519Verifier () { EVP_MD_CTX_destroy (m_MDCtx); - if (m_Pkey) EVP_PKEY_free (m_Pkey); } void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey) { - m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); - EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + EVP_PKEY * pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); + EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, pkey); + EVP_PKEY_free (pkey); } bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const @@ -100,33 +99,29 @@ namespace crypto #if OPENSSL_EDDSA EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): - m_Fallback (nullptr) + m_MDCtx (nullptr), m_Fallback (nullptr) { - m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); + EVP_PKEY * pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; - EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); + EVP_PKEY_get_raw_public_key (pkey, publicKey, &len); if (signingPublicKey && memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) { LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); - EVP_PKEY_free (m_Pkey); m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); } else { m_MDCtx = EVP_MD_CTX_create (); - EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, pkey); } + EVP_PKEY_free (pkey); } EDDSA25519Signer::~EDDSA25519Signer () { if (m_Fallback) delete m_Fallback; - else - { - EVP_MD_CTX_destroy (m_MDCtx); - EVP_PKEY_free (m_Pkey); - } + EVP_MD_CTX_destroy (m_MDCtx); } void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 18084603..caf9b274 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -304,7 +304,6 @@ namespace crypto private: #if OPENSSL_EDDSA - EVP_PKEY * m_Pkey; EVP_MD_CTX * m_MDCtx; #else EDDSAPoint m_PublicKey; @@ -341,7 +340,7 @@ namespace crypto void Sign (const uint8_t * buf, int len, uint8_t * signature) const; private: - EVP_PKEY * m_Pkey; + EVP_MD_CTX * m_MDCtx; EDDSA25519SignerCompat * m_Fallback; }; From bb8dc679421ae8e116ebc4a1bc4648e6887d4c62 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 19:05:16 -0400 Subject: [PATCH 0357/2193] don't use openssl's SipHash from 3.0.0 due regression --- libi2pd/Crypto.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 5f42b527..75942905 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -39,7 +39,9 @@ # define OPENSSL_HKDF 1 # define OPENSSL_EDDSA 1 # define OPENSSL_X25519 1 -# define OPENSSL_SIPHASH 1 +# if (OPENSSL_VERSION_NUMBER < 0x030000000) // 3.0.0, regression in SipHash +# define OPENSSL_SIPHASH 1 +# endif # endif # if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them # define OPENSSL_AEAD_CHACHA20_POLY1305 1 From 8566f6c127eb54825cdbabefa32c25a611c5f241 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 21:18:21 -0400 Subject: [PATCH 0358/2193] don't store EVP_PKEY sip keys --- libi2pd/NTCP2.cpp | 19 ++++++++++--------- libi2pd/NTCP2.h | 1 - 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 9e18c81e..b4f290dd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -323,9 +323,10 @@ namespace transport m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_Establisher (new NTCP2Establisher), - m_SendSipKey (nullptr), m_ReceiveSipKey (nullptr), #if OPENSSL_SIPHASH m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), +#else + m_SendSipKey (nullptr), m_ReceiveSipKey (nullptr), #endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), m_NextReceivedBufferSize (0), m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), @@ -352,8 +353,6 @@ namespace transport delete[] m_NextReceivedBuffer; delete[] m_NextSendBuffer; #if OPENSSL_SIPHASH - if (m_SendSipKey) EVP_PKEY_free (m_SendSipKey); - if (m_ReceiveSipKey) EVP_PKEY_free (m_ReceiveSipKey); if (m_SendMDCtx) EVP_MD_CTX_destroy (m_SendMDCtx); if (m_ReceiveMDCtx) EVP_MD_CTX_destroy (m_ReceiveMDCtx); #endif @@ -711,17 +710,19 @@ namespace transport void NTCP2Session::SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey) { #if OPENSSL_SIPHASH - m_SendSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, sendSipKey, 16); + EVP_PKEY * sipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, sendSipKey, 16); m_SendMDCtx = EVP_MD_CTX_create (); EVP_PKEY_CTX *ctx = nullptr; - EVP_DigestSignInit (m_SendMDCtx, &ctx, nullptr, nullptr, m_SendSipKey); + EVP_DigestSignInit (m_SendMDCtx, &ctx, nullptr, nullptr, sipKey); EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); - - m_ReceiveSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, receiveSipKey, 16); + EVP_PKEY_free (sipKey); + + sipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, receiveSipKey, 16); m_ReceiveMDCtx = EVP_MD_CTX_create (); ctx = nullptr; - EVP_DigestSignInit (m_ReceiveMDCtx, &ctx, NULL, NULL, m_ReceiveSipKey); + EVP_DigestSignInit (m_ReceiveMDCtx, &ctx, NULL, NULL, sipKey); EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); + EVP_PKEY_free (sipKey); #else m_SendSipKey = sendSipKey; m_ReceiveSipKey = receiveSipKey; @@ -1114,7 +1115,7 @@ namespace transport void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { - if (!m_SendKey || !m_SendSipKey) return; + if (!m_SendKey) return; m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block // termination block m_NextSendBuffer[2] = eNTCP2BlkTermination; diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index f9f3e751..3516ce6a 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -205,7 +205,6 @@ namespace transport uint8_t m_Kab[32], m_Kba[32], m_Sipkeysab[32], m_Sipkeysba[32]; const uint8_t * m_SendKey, * m_ReceiveKey; #if OPENSSL_SIPHASH - EVP_PKEY * m_SendSipKey, * m_ReceiveSipKey; EVP_MD_CTX * m_SendMDCtx, * m_ReceiveMDCtx; #else const uint8_t * m_SendSipKey, * m_ReceiveSipKey; From 876e98d91e2cf75f1c856e1d8ec2e3efac401ba9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 22:23:32 -0400 Subject: [PATCH 0359/2193] check if sip key is available --- libi2pd/NTCP2.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index b4f290dd..03aac04d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -910,12 +910,14 @@ namespace transport void NTCP2Session::SetNextSentFrameLength (size_t frameLen, uint8_t * lengthBuf) { - #if OPENSSL_SIPHASH +#if OPENSSL_SIPHASH + if (!m_SendMDCtx) return; EVP_DigestSignInit (m_SendMDCtx, nullptr, nullptr, nullptr, nullptr); EVP_DigestSignUpdate (m_SendMDCtx, m_SendIV.buf, 8); size_t l = 8; - EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); + EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); #else + if (!m_SendSipKey) return; i2p::crypto::Siphash<8> (m_SendIV.buf, m_SendIV.buf, 8, m_SendSipKey); #endif // length must be in BigEndian From 26db88d89be2cd9cba842593c8d597e768b5fa05 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Oct 2021 22:33:37 -0400 Subject: [PATCH 0360/2193] check if sip key is available --- libi2pd/NTCP2.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 03aac04d..e592a7f2 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -911,13 +911,11 @@ namespace transport void NTCP2Session::SetNextSentFrameLength (size_t frameLen, uint8_t * lengthBuf) { #if OPENSSL_SIPHASH - if (!m_SendMDCtx) return; EVP_DigestSignInit (m_SendMDCtx, nullptr, nullptr, nullptr, nullptr); EVP_DigestSignUpdate (m_SendMDCtx, m_SendIV.buf, 8); size_t l = 8; EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); #else - if (!m_SendSipKey) return; i2p::crypto::Siphash<8> (m_SendIV.buf, m_SendIV.buf, 8, m_SendSipKey); #endif // length must be in BigEndian @@ -1117,7 +1115,13 @@ namespace transport void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { - if (!m_SendKey) return; + if (!m_SendKey || +#if OPENSSL_SIPHASH + !m_SendMDCtx +#else + !m_SendSipKey +#endif + ) return; m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block // termination block m_NextSendBuffer[2] = eNTCP2BlkTermination; From 7073a6bf384e763b46dc891d0091f69d295bca58 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Thu, 28 Oct 2021 21:59:27 +0200 Subject: [PATCH 0361/2193] libi2pd: make Tunnel and TunnelConfig destructors virtual --- libi2pd/Tunnel.h | 2 +- libi2pd/TunnelConfig.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 56166e0b..80d29a15 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -68,7 +68,7 @@ namespace tunnel public: Tunnel (std::shared_ptr config); - ~Tunnel (); + virtual ~Tunnel (); void Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel = nullptr); diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index f198dffd..ae924ba6 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -99,7 +99,7 @@ namespace tunnel m_LastHop->SetReplyHop (replyTunnelID, replyIdent); } - ~TunnelConfig () + virtual ~TunnelConfig () { TunnelHopConfig * hop = m_FirstHop; From 1de1c79d4f72a1c7aa3ad51e6a582df5c8302c39 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Sun, 31 Oct 2021 14:51:41 +0100 Subject: [PATCH 0362/2193] libi2pd: add missing locks to i2p::tunnel::Tunnels m_InboundTunnelsMutex, m_OutboundTunnelsMutex and m_PoolsMutex have been changed to recursive_mutexes since they can be acquired multiple times by the same thread. --- libi2pd/Tunnel.cpp | 33 ++++++++++++++++++++++++++++----- libi2pd/Tunnel.h | 8 +++++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a315ff49..f3cdd432 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -366,6 +366,7 @@ namespace tunnel std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { + std::unique_lock l(m_TunnelsMutex); auto it = m_Tunnels.find(tunnelID); if (it != m_Tunnels.end ()) return it->second; @@ -374,11 +375,13 @@ namespace tunnel std::shared_ptr Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { + std::unique_lock l(m_PendingInboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); } std::shared_ptr Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID) { + std::unique_lock l(m_PendingOutboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); } @@ -459,9 +462,11 @@ namespace tunnel void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { - if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) + std::unique_lock l(m_TunnelsMutex); + if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) { + std::unique_lock l(m_TransitTunnelsMutex); m_TransitTunnels.push_back (tunnel); - else + } else LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists"); } @@ -616,7 +621,10 @@ namespace tunnel void Tunnels::ManagePendingTunnels () { + std::unique_lock li(m_PendingInboundTunnelsMutex); ManagePendingTunnels (m_PendingInboundTunnels); + li.unlock(); + std::unique_lock lo(m_PendingOutboundTunnelsMutex); ManagePendingTunnels (m_PendingOutboundTunnels); } @@ -676,6 +684,7 @@ namespace tunnel void Tunnels::ManageOutboundTunnels () { + std::unique_lock l(m_OutboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) @@ -730,6 +739,8 @@ namespace tunnel void Tunnels::ManageInboundTunnels () { + std::unique_lock lt(m_TunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) @@ -786,6 +797,7 @@ namespace tunnel return; } + std::unique_lock lo(m_OutboundTunnelsMutex); if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3) { // trying to create one more inbound tunnel @@ -806,6 +818,8 @@ namespace tunnel void Tunnels::ManageTransitTunnels () { + std::unique_lock lt(m_TunnelsMutex); + std::unique_lock l(m_TransitTunnelsMutex); uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) { @@ -876,17 +890,20 @@ namespace tunnel void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { + std::unique_lock l(m_PendingInboundTunnelsMutex); m_PendingInboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { + std::unique_lock l(m_PendingOutboundTunnelsMutex); m_PendingOutboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddOutboundTunnel (std::shared_ptr newTunnel) { // we don't need to insert it to m_Tunnels + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (pool && pool->IsActive ()) @@ -897,8 +914,10 @@ namespace tunnel void Tunnels::AddInboundTunnel (std::shared_ptr newTunnel) { + std::unique_lock l(m_TunnelsMutex); if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) { + std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (!pool) @@ -926,6 +945,8 @@ namespace tunnel auto inboundTunnel = std::make_shared (); inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetState (eTunnelStateEstablished); + std::unique_lock lt(m_TunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; @@ -936,6 +957,7 @@ namespace tunnel auto outboundTunnel = std::make_shared (); outboundTunnel->SetTunnelPool (pool); outboundTunnel->SetState (eTunnelStateEstablished); + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels return outboundTunnel; @@ -964,6 +986,7 @@ namespace tunnel int timeout = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); // TODO: possible race condition with I2PControl + std::unique_lock l(m_TransitTunnelsMutex); for (const auto& it : m_TransitTunnels) { int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; @@ -974,19 +997,19 @@ namespace tunnel size_t Tunnels::CountTransitTunnels() const { - // TODO: locking + std::unique_lock l(m_TransitTunnelsMutex); return m_TransitTunnels.size(); } size_t Tunnels::CountInboundTunnels() const { - // TODO: locking + std::unique_lock l(m_InboundTunnelsMutex); return m_InboundTunnels.size(); } size_t Tunnels::CountOutboundTunnels() const { - // TODO: locking + std::unique_lock l(m_OutboundTunnelsMutex); return m_OutboundTunnels.size(); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 80d29a15..640a9ca7 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -254,12 +254,18 @@ namespace tunnel bool m_IsRunning; std::thread * m_Thread; std::map > m_PendingInboundTunnels; // by replyMsgID + mutable std::mutex m_PendingInboundTunnelsMutex; std::map > m_PendingOutboundTunnels; // by replyMsgID + mutable std::mutex m_PendingOutboundTunnelsMutex; std::list > m_InboundTunnels; + mutable std::recursive_mutex m_InboundTunnelsMutex; std::list > m_OutboundTunnels; + mutable std::recursive_mutex m_OutboundTunnelsMutex; std::list > m_TransitTunnels; + mutable std::mutex m_TransitTunnelsMutex; std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id - std::mutex m_PoolsMutex; + mutable std::recursive_mutex m_TunnelsMutex; + mutable std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; From 58b7b7d7317df28a40a6bc620761eb218d551a02 Mon Sep 17 00:00:00 2001 From: Simon Vetter Date: Sat, 30 Oct 2021 23:14:48 +0200 Subject: [PATCH 0363/2193] libi2pd: add missing locks to i2p::tunnel::TunnelPool --- libi2pd/TunnelPool.cpp | 46 +++++++++++++++++++++++++++++++++--------- libi2pd/TunnelPool.h | 6 ++++-- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5ed330c8..4d00ad6f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -59,6 +59,7 @@ namespace tunnel void TunnelPool::SetExplicitPeers (std::shared_ptr > explicitPeers) { + std::unique_lock l(m_ExplicitPeersMutex); m_ExplicitPeers = explicitPeers; if (m_ExplicitPeers) { @@ -92,6 +93,7 @@ namespace tunnel it->SetTunnelPool (nullptr); m_OutboundTunnels.clear (); } + std::unique_lock l(m_TestsMutex); m_Tests.clear (); } @@ -126,6 +128,7 @@ namespace tunnel } m_InboundTunnels.insert (createdTunnel); } + std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -135,10 +138,11 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); + std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; - std::unique_lock l(m_InboundTunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.erase (expiredTunnel); } } @@ -157,10 +161,11 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); + std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; - std::unique_lock l(m_OutboundTunnelsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (expiredTunnel); } } @@ -261,11 +266,21 @@ namespace tunnel return tunnel; } + std::shared_ptr TunnelPool::GetLocalDestination () const { + std::unique_lock l(m_LocalDestinationMutex); + return m_LocalDestination; + } + + void TunnelPool::SetLocalDestination (std::shared_ptr destination) { + std::unique_lock l(m_LocalDestinationMutex); + m_LocalDestination = destination; + } + void TunnelPool::CreateTunnels () { int num = 0; { - std::unique_lock l(m_OutboundTunnelsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); for (const auto& it : m_OutboundTunnels) if (it->IsEstablished ()) num++; } @@ -274,10 +289,11 @@ namespace tunnel num = 0; { - std::unique_lock l(m_InboundTunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } + std::unique_lock lo(m_OutboundTunnelsMutex); if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0) { for (auto it: m_OutboundTunnels) @@ -287,9 +303,11 @@ namespace tunnel if (num >= m_NumInboundTunnels) break; } } + lo.unlock(); for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); + std::unique_lock l(m_LocalDestinationMutex); if (num < m_NumInboundTunnels && m_NumInboundHops <= 0 && m_LocalDestination) // zero hops IB m_LocalDestination->SetLeaseSetUpdated (); // update LeaseSet immediately } @@ -311,7 +329,7 @@ namespace tunnel if (it.second.first->GetState () == eTunnelStateTestFailed) { it.second.first->SetState (eTunnelStateFailed); - std::unique_lock l(m_OutboundTunnelsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (it.second.first); } else @@ -323,9 +341,10 @@ namespace tunnel { it.second.second->SetState (eTunnelStateFailed); { - std::unique_lock l(m_InboundTunnelsMutex); + std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } + std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -335,7 +354,10 @@ namespace tunnel } // new tests + std::unique_lock lt(m_TestsMutex); + std::unique_lock lo(m_OutboundTunnelsMutex); auto it1 = m_OutboundTunnels.begin (); + std::unique_lock li(m_InboundTunnelsMutex); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { @@ -355,7 +377,6 @@ namespace tunnel uint32_t msgID; RAND_bytes ((uint8_t *)&msgID, 4); { - std::unique_lock l(m_TestsMutex); m_Tests[msgID] = std::make_pair (*it1, *it2); } (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), @@ -377,10 +398,11 @@ namespace tunnel void TunnelPool::ProcessGarlicMessage (std::shared_ptr msg) { + std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else - LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, dropped"); + LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, garlic message dropped"); } void TunnelPool::ProcessDeliveryStatus (std::shared_ptr msg) @@ -425,10 +447,11 @@ namespace tunnel } else { + std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else - LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); + LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, delivery status message dropped"); } } @@ -512,13 +535,16 @@ namespace tunnel if (m_CustomPeerSelector) return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } + // explicit peers in use + std::lock_guard lock(m_ExplicitPeersMutex); if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound); return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); } bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { + std::unique_lock l(m_ExplicitPeersMutex); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); if (!numHops) return false; @@ -610,8 +636,10 @@ namespace tunnel Path path; if (SelectPeers (path, false)) { + std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) path.isShort = false; // because can't handle ECIES encrypted reply + ld.unlock(); std::shared_ptr config; if (m_NumOutboundHops > 0) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 875a9955..1069e1b9 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -64,8 +64,8 @@ namespace tunnel TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels); ~TunnelPool (); - std::shared_ptr GetLocalDestination () const { return m_LocalDestination; }; - void SetLocalDestination (std::shared_ptr destination) { m_LocalDestination = destination; }; + std::shared_ptr GetLocalDestination () const; + void SetLocalDestination (std::shared_ptr destination); void SetExplicitPeers (std::shared_ptr > explicitPeers); void CreateTunnels (); @@ -126,8 +126,10 @@ namespace tunnel private: + mutable std::mutex m_LocalDestinationMutex; std::shared_ptr m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; + mutable std::mutex m_ExplicitPeersMutex; std::shared_ptr > m_ExplicitPeers; mutable std::mutex m_InboundTunnelsMutex; std::set, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first From 4c5ec68ff14ea9f144b0cad792956315d4969233 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 1 Nov 2021 02:40:54 +0300 Subject: [PATCH 0364/2193] [win] add menu item for opening datadir Signed-off-by: R4SAS --- Win32/Win32App.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 7104ec7f..377e1076 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -31,6 +31,7 @@ #define ID_RELOAD 2006 #define ID_ACCEPT_TRANSIT 2007 #define ID_DECLINE_TRANSIT 2008 +#define ID_DATADIR 2009 #define ID_TRAY_ICON 2050 #define WM_TRAYICON (WM_USER + 1) @@ -49,7 +50,8 @@ namespace win32 { HMENU hPopup = CreatePopupMenu(); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DATADIR, "Open &datadir"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "&Show app"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); if(!i2p::context.AcceptsTunnels()) @@ -303,6 +305,12 @@ namespace win32 SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL); return 0; } + case ID_DATADIR: + { + std::string datadir(i2p::fs::GetUTF8DataDir()); + ShellExecute(NULL, "explore", datadir.c_str(), NULL, NULL, SW_SHOWNORMAL); + return 0; + } } break; } From 56ec8fe95b5490e4773ac6b90d1bdacc89884ad7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Oct 2021 21:20:16 -0400 Subject: [PATCH 0365/2193] eliminate local destination mutex --- libi2pd/TunnelPool.cpp | 17 ----------------- libi2pd/TunnelPool.h | 5 ++--- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 4d00ad6f..051ecdc6 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -128,7 +128,6 @@ namespace tunnel } m_InboundTunnels.insert (createdTunnel); } - std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -266,16 +265,6 @@ namespace tunnel return tunnel; } - std::shared_ptr TunnelPool::GetLocalDestination () const { - std::unique_lock l(m_LocalDestinationMutex); - return m_LocalDestination; - } - - void TunnelPool::SetLocalDestination (std::shared_ptr destination) { - std::unique_lock l(m_LocalDestinationMutex); - m_LocalDestination = destination; - } - void TunnelPool::CreateTunnels () { int num = 0; @@ -307,7 +296,6 @@ namespace tunnel for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); - std::unique_lock l(m_LocalDestinationMutex); if (num < m_NumInboundTunnels && m_NumInboundHops <= 0 && m_LocalDestination) // zero hops IB m_LocalDestination->SetLeaseSetUpdated (); // update LeaseSet immediately } @@ -344,7 +332,6 @@ namespace tunnel std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } - std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); } @@ -398,7 +385,6 @@ namespace tunnel void TunnelPool::ProcessGarlicMessage (std::shared_ptr msg) { - std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else @@ -447,7 +433,6 @@ namespace tunnel } else { - std::unique_lock l(m_LocalDestinationMutex); if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else @@ -636,10 +621,8 @@ namespace tunnel Path path; if (SelectPeers (path, false)) { - std::unique_lock ld(m_LocalDestinationMutex); if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) path.isShort = false; // because can't handle ECIES encrypted reply - ld.unlock(); std::shared_ptr config; if (m_NumOutboundHops > 0) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 1069e1b9..b32bafa3 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -64,8 +64,8 @@ namespace tunnel TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels); ~TunnelPool (); - std::shared_ptr GetLocalDestination () const; - void SetLocalDestination (std::shared_ptr destination); + std::shared_ptr GetLocalDestination () const { return m_LocalDestination; }; + void SetLocalDestination (std::shared_ptr destination) { m_LocalDestination = destination; }; void SetExplicitPeers (std::shared_ptr > explicitPeers); void CreateTunnels (); @@ -126,7 +126,6 @@ namespace tunnel private: - mutable std::mutex m_LocalDestinationMutex; std::shared_ptr m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; mutable std::mutex m_ExplicitPeersMutex; From c6e47581877e6f61ed3293b0f0b9c24eae161bb6 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 1 Nov 2021 05:03:34 +0300 Subject: [PATCH 0366/2193] Revert "Merge pull request #1703 from simonvetter/simon/memory-and-multithreading-fixes" This reverts commit 67863cfcf9784dd638f505b8052abb8070ed8a90, reversing changes made to 4c5ec68ff14ea9f144b0cad792956315d4969233. That change completly bloking transports thread on windows. Signed-off-by: R4SAS --- libi2pd/Tunnel.cpp | 33 +++++---------------------------- libi2pd/Tunnel.h | 10 ++-------- libi2pd/TunnelConfig.h | 2 +- libi2pd/TunnelPool.cpp | 29 +++++++++-------------------- libi2pd/TunnelPool.h | 1 - 5 files changed, 17 insertions(+), 58 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index f3cdd432..a315ff49 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -366,7 +366,6 @@ namespace tunnel std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { - std::unique_lock l(m_TunnelsMutex); auto it = m_Tunnels.find(tunnelID); if (it != m_Tunnels.end ()) return it->second; @@ -375,13 +374,11 @@ namespace tunnel std::shared_ptr Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { - std::unique_lock l(m_PendingInboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); } std::shared_ptr Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID) { - std::unique_lock l(m_PendingOutboundTunnelsMutex); return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); } @@ -462,11 +459,9 @@ namespace tunnel void Tunnels::AddTransitTunnel (std::shared_ptr tunnel) { - std::unique_lock l(m_TunnelsMutex); - if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) { - std::unique_lock l(m_TransitTunnelsMutex); + if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) m_TransitTunnels.push_back (tunnel); - } else + else LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists"); } @@ -621,10 +616,7 @@ namespace tunnel void Tunnels::ManagePendingTunnels () { - std::unique_lock li(m_PendingInboundTunnelsMutex); ManagePendingTunnels (m_PendingInboundTunnels); - li.unlock(); - std::unique_lock lo(m_PendingOutboundTunnelsMutex); ManagePendingTunnels (m_PendingOutboundTunnels); } @@ -684,7 +676,6 @@ namespace tunnel void Tunnels::ManageOutboundTunnels () { - std::unique_lock l(m_OutboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) @@ -739,8 +730,6 @@ namespace tunnel void Tunnels::ManageInboundTunnels () { - std::unique_lock lt(m_TunnelsMutex); - std::unique_lock li(m_InboundTunnelsMutex); uint64_t ts = i2p::util::GetSecondsSinceEpoch (); { for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) @@ -797,7 +786,6 @@ namespace tunnel return; } - std::unique_lock lo(m_OutboundTunnelsMutex); if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3) { // trying to create one more inbound tunnel @@ -818,8 +806,6 @@ namespace tunnel void Tunnels::ManageTransitTunnels () { - std::unique_lock lt(m_TunnelsMutex); - std::unique_lock l(m_TransitTunnelsMutex); uint32_t ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();) { @@ -890,20 +876,17 @@ namespace tunnel void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { - std::unique_lock l(m_PendingInboundTunnelsMutex); m_PendingInboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { - std::unique_lock l(m_PendingOutboundTunnelsMutex); m_PendingOutboundTunnels[replyMsgID] = tunnel; } void Tunnels::AddOutboundTunnel (std::shared_ptr newTunnel) { // we don't need to insert it to m_Tunnels - std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (pool && pool->IsActive ()) @@ -914,10 +897,8 @@ namespace tunnel void Tunnels::AddInboundTunnel (std::shared_ptr newTunnel) { - std::unique_lock l(m_TunnelsMutex); if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second) { - std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.push_back (newTunnel); auto pool = newTunnel->GetTunnelPool (); if (!pool) @@ -945,8 +926,6 @@ namespace tunnel auto inboundTunnel = std::make_shared (); inboundTunnel->SetTunnelPool (pool); inboundTunnel->SetState (eTunnelStateEstablished); - std::unique_lock lt(m_TunnelsMutex); - std::unique_lock li(m_InboundTunnelsMutex); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; return inboundTunnel; @@ -957,7 +936,6 @@ namespace tunnel auto outboundTunnel = std::make_shared (); outboundTunnel->SetTunnelPool (pool); outboundTunnel->SetState (eTunnelStateEstablished); - std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels return outboundTunnel; @@ -986,7 +964,6 @@ namespace tunnel int timeout = 0; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); // TODO: possible race condition with I2PControl - std::unique_lock l(m_TransitTunnelsMutex); for (const auto& it : m_TransitTunnels) { int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts; @@ -997,19 +974,19 @@ namespace tunnel size_t Tunnels::CountTransitTunnels() const { - std::unique_lock l(m_TransitTunnelsMutex); + // TODO: locking return m_TransitTunnels.size(); } size_t Tunnels::CountInboundTunnels() const { - std::unique_lock l(m_InboundTunnelsMutex); + // TODO: locking return m_InboundTunnels.size(); } size_t Tunnels::CountOutboundTunnels() const { - std::unique_lock l(m_OutboundTunnelsMutex); + // TODO: locking return m_OutboundTunnels.size(); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 640a9ca7..56166e0b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -68,7 +68,7 @@ namespace tunnel public: Tunnel (std::shared_ptr config); - virtual ~Tunnel (); + ~Tunnel (); void Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel = nullptr); @@ -254,18 +254,12 @@ namespace tunnel bool m_IsRunning; std::thread * m_Thread; std::map > m_PendingInboundTunnels; // by replyMsgID - mutable std::mutex m_PendingInboundTunnelsMutex; std::map > m_PendingOutboundTunnels; // by replyMsgID - mutable std::mutex m_PendingOutboundTunnelsMutex; std::list > m_InboundTunnels; - mutable std::recursive_mutex m_InboundTunnelsMutex; std::list > m_OutboundTunnels; - mutable std::recursive_mutex m_OutboundTunnelsMutex; std::list > m_TransitTunnels; - mutable std::mutex m_TransitTunnelsMutex; std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id - mutable std::recursive_mutex m_TunnelsMutex; - mutable std::mutex m_PoolsMutex; + std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index ae924ba6..f198dffd 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -99,7 +99,7 @@ namespace tunnel m_LastHop->SetReplyHop (replyTunnelID, replyIdent); } - virtual ~TunnelConfig () + ~TunnelConfig () { TunnelHopConfig * hop = m_FirstHop; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 051ecdc6..5ed330c8 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -59,7 +59,6 @@ namespace tunnel void TunnelPool::SetExplicitPeers (std::shared_ptr > explicitPeers) { - std::unique_lock l(m_ExplicitPeersMutex); m_ExplicitPeers = explicitPeers; if (m_ExplicitPeers) { @@ -93,7 +92,6 @@ namespace tunnel it->SetTunnelPool (nullptr); m_OutboundTunnels.clear (); } - std::unique_lock l(m_TestsMutex); m_Tests.clear (); } @@ -137,11 +135,10 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); - std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; - std::unique_lock li(m_InboundTunnelsMutex); + std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.erase (expiredTunnel); } } @@ -160,11 +157,10 @@ namespace tunnel if (expiredTunnel) { expiredTunnel->SetTunnelPool (nullptr); - std::unique_lock lt(m_TestsMutex); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; - std::unique_lock lo(m_OutboundTunnelsMutex); + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (expiredTunnel); } } @@ -269,7 +265,7 @@ namespace tunnel { int num = 0; { - std::unique_lock lo(m_OutboundTunnelsMutex); + std::unique_lock l(m_OutboundTunnelsMutex); for (const auto& it : m_OutboundTunnels) if (it->IsEstablished ()) num++; } @@ -278,11 +274,10 @@ namespace tunnel num = 0; { - std::unique_lock li(m_InboundTunnelsMutex); + std::unique_lock l(m_InboundTunnelsMutex); for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } - std::unique_lock lo(m_OutboundTunnelsMutex); if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0) { for (auto it: m_OutboundTunnels) @@ -292,7 +287,6 @@ namespace tunnel if (num >= m_NumInboundTunnels) break; } } - lo.unlock(); for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); @@ -317,7 +311,7 @@ namespace tunnel if (it.second.first->GetState () == eTunnelStateTestFailed) { it.second.first->SetState (eTunnelStateFailed); - std::unique_lock lo(m_OutboundTunnelsMutex); + std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.erase (it.second.first); } else @@ -329,7 +323,7 @@ namespace tunnel { it.second.second->SetState (eTunnelStateFailed); { - std::unique_lock li(m_InboundTunnelsMutex); + std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } if (m_LocalDestination) @@ -341,10 +335,7 @@ namespace tunnel } // new tests - std::unique_lock lt(m_TestsMutex); - std::unique_lock lo(m_OutboundTunnelsMutex); auto it1 = m_OutboundTunnels.begin (); - std::unique_lock li(m_InboundTunnelsMutex); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) { @@ -364,6 +355,7 @@ namespace tunnel uint32_t msgID; RAND_bytes ((uint8_t *)&msgID, 4); { + std::unique_lock l(m_TestsMutex); m_Tests[msgID] = std::make_pair (*it1, *it2); } (*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), @@ -388,7 +380,7 @@ namespace tunnel if (m_LocalDestination) m_LocalDestination->ProcessGarlicMessage (msg); else - LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, garlic message dropped"); + LogPrint (eLogWarning, "Tunnels: local destination doesn't exist, dropped"); } void TunnelPool::ProcessDeliveryStatus (std::shared_ptr msg) @@ -436,7 +428,7 @@ namespace tunnel if (m_LocalDestination) m_LocalDestination->ProcessDeliveryStatusMessage (msg); else - LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, delivery status message dropped"); + LogPrint (eLogWarning, "Tunnels: Local destination doesn't exist, dropped"); } } @@ -520,16 +512,13 @@ namespace tunnel if (m_CustomPeerSelector) return m_CustomPeerSelector->SelectPeers(path, numHops, isInbound); } - // explicit peers in use - std::lock_guard lock(m_ExplicitPeersMutex); if (m_ExplicitPeers) return SelectExplicitPeers (path, isInbound); return StandardSelectPeers(path, numHops, isInbound, std::bind(&TunnelPool::SelectNextHop, this, std::placeholders::_1, std::placeholders::_2)); } bool TunnelPool::SelectExplicitPeers (Path& path, bool isInbound) { - std::unique_lock l(m_ExplicitPeersMutex); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; if (numHops > (int)m_ExplicitPeers->size ()) numHops = m_ExplicitPeers->size (); if (!numHops) return false; diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index b32bafa3..875a9955 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -128,7 +128,6 @@ namespace tunnel std::shared_ptr m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels; - mutable std::mutex m_ExplicitPeersMutex; std::shared_ptr > m_ExplicitPeers; mutable std::mutex m_InboundTunnelsMutex; std::set, TunnelCreationTimeCmp> m_InboundTunnels; // recent tunnel appears first From c0400bfd0789940b118e444cca7d4d8f3d87b9de Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Oct 2021 22:14:59 -0400 Subject: [PATCH 0367/2193] virtual destructor for TunnelConfig --- libi2pd/TunnelConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index f198dffd..ae924ba6 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -99,7 +99,7 @@ namespace tunnel m_LastHop->SetReplyHop (replyTunnelID, replyIdent); } - ~TunnelConfig () + virtual ~TunnelConfig () { TunnelHopConfig * hop = m_FirstHop; From 1a8a32a773deffa80ccd03102cfa687eb1622a9e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Nov 2021 14:51:24 -0400 Subject: [PATCH 0368/2193] select next tunnel with compatible transports --- libi2pd/Destination.cpp | 28 ++++++++++++++-------------- libi2pd/RouterInfo.h | 3 ++- libi2pd/Tunnel.cpp | 2 +- libi2pd/Tunnel.h | 1 + libi2pd/TunnelConfig.h | 4 ++-- libi2pd/TunnelPool.cpp | 15 +++++++++------ libi2pd/TunnelPool.h | 9 ++++++--- 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 54137664..f523243a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -555,18 +555,6 @@ namespace client shared_from_this (), std::placeholders::_1)); return; } - auto outbound = m_Pool->GetNextOutboundTunnel (); - if (!outbound) - { - LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels"); - return; - } - auto inbound = m_Pool->GetNextInboundTunnel (); - if (!inbound) - { - LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); - return; - } auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills); if (!floodfill) { @@ -575,6 +563,18 @@ namespace client return; } m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); + auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); + if (!outbound) + { + LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels"); + return; + } + auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)); + if (!inbound) + { + LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); + return; + } LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); @@ -751,10 +751,10 @@ namespace client std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) - request->replyTunnel = m_Pool->GetNextInboundTunnel (); + request->replyTunnel = m_Pool->GetNextInboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (true)); if (!request->replyTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no inbound tunnels found"); if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) - request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); + request->outboundTunnel = m_Pool->GetNextOutboundTunnel (nullptr, nextFloodfill->GetCompatibleTransports (false)); if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); if (request->replyTunnel && request->outboundTunnel) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b2b883dc..de1fe235 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -64,7 +64,8 @@ namespace data eNTCP2V6 = 0x02, eSSUV4 = 0x04, eSSUV6 = 0x08, - eNTCP2V6Mesh = 0x10 + eNTCP2V6Mesh = 0x10, + eAllTransports = 0xFF }; typedef uint8_t CompatibleTransports; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a315ff49..ad048bb8 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -32,7 +32,7 @@ namespace tunnel Tunnel::Tunnel (std::shared_ptr config): TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()), m_Config (config), m_IsShortBuildMessage (false), m_Pool (nullptr), - m_State (eTunnelStatePending), m_FarEndTransports (0), + m_State (eTunnelStatePending), m_FarEndTransports (i2p::data::RouterInfo::eAllTransports), m_IsRecreated (false), m_Latency (0) { } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 56166e0b..3ab366c8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -76,6 +76,7 @@ namespace tunnel std::vector > GetPeers () const; std::vector > GetInvertedPeers () const; bool IsShortBuildMessage () const { return m_IsShortBuildMessage; }; + i2p::data::RouterInfo::CompatibleTransports GetFarEndTransports () const { return m_FarEndTransports; }; TunnelState GetState () const { return m_State; }; void SetState (TunnelState state); bool IsEstablished () const { return m_State == eTunnelStateEstablished; }; diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index ae924ba6..c514a404 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -82,7 +82,7 @@ namespace tunnel public: TunnelConfig (const std::vector >& peers, - bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // inbound + bool isShort, i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // inbound m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); @@ -91,7 +91,7 @@ namespace tunnel TunnelConfig (const std::vector >& peers, uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort, - i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0): // outbound + i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound m_IsShort (isShort), m_FarEndTransports (farEndTransports) { CreatePeers (peers); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 5ed330c8..c9897b29 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -190,20 +190,23 @@ namespace tunnel return v; } - std::shared_ptr TunnelPool::GetNextOutboundTunnel (std::shared_ptr excluded) const + std::shared_ptr TunnelPool::GetNextOutboundTunnel (std::shared_ptr excluded, + i2p::data::RouterInfo::CompatibleTransports compatible) const { std::unique_lock l(m_OutboundTunnelsMutex); - return GetNextTunnel (m_OutboundTunnels, excluded); + return GetNextTunnel (m_OutboundTunnels, excluded, compatible); } - std::shared_ptr TunnelPool::GetNextInboundTunnel (std::shared_ptr excluded) const + std::shared_ptr TunnelPool::GetNextInboundTunnel (std::shared_ptr excluded, + i2p::data::RouterInfo::CompatibleTransports compatible) const { std::unique_lock l(m_InboundTunnelsMutex); - return GetNextTunnel (m_InboundTunnels, excluded); + return GetNextTunnel (m_InboundTunnels, excluded, compatible); } template - typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const + typename TTunnels::value_type TunnelPool::GetNextTunnel (TTunnels& tunnels, + typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const { if (tunnels.empty ()) return nullptr; uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0; @@ -211,7 +214,7 @@ namespace tunnel typename TTunnels::value_type tunnel = nullptr; for (const auto& it: tunnels) { - if (it->IsEstablished () && it != excluded) + if (it->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ())) { if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() && !it->LatencyFitsRange(m_MinLatency, m_MaxLatency))) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 875a9955..2f4018ce 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -76,8 +76,10 @@ namespace tunnel void RecreateInboundTunnel (std::shared_ptr tunnel); void RecreateOutboundTunnel (std::shared_ptr tunnel); std::vector > GetInboundTunnels (int num) const; - std::shared_ptr GetNextOutboundTunnel (std::shared_ptr excluded = nullptr) const; - std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr) const; + std::shared_ptr GetNextOutboundTunnel (std::shared_ptr excluded = nullptr, + i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const; + std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr, + i2p::data::RouterInfo::CompatibleTransports compatible = i2p::data::RouterInfo::eAllTransports) const; std::shared_ptr GetNewOutboundTunnel (std::shared_ptr old) const; void TestTunnels (); void ManageTunnels (uint64_t ts); @@ -120,7 +122,8 @@ namespace tunnel void CreateOutboundTunnel (); void CreatePairedInboundTunnel (std::shared_ptr outboundTunnel); template - typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, typename TTunnels::value_type excluded) const; + typename TTunnels::value_type GetNextTunnel (TTunnels& tunnels, + typename TTunnels::value_type excluded, i2p::data::RouterInfo::CompatibleTransports compatible) const; bool SelectPeers (Path& path, bool isInbound); bool SelectExplicitPeers (Path& path, bool isInbound); From 8f0978cfd6439559803b5e6ba6c22dcd20f59dff Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Nov 2021 10:49:18 -0400 Subject: [PATCH 0369/2193] all transports by default --- libi2pd/TunnelConfig.h | 2 +- libi2pd/TunnelPool.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index c514a404..7934bc6b 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -185,7 +185,7 @@ namespace tunnel // this constructor can't be called from outside TunnelConfig (): m_FirstHop (nullptr), m_LastHop (nullptr), m_IsShort (false), - m_FarEndTransports (0) + m_FarEndTransports (i2p::data::RouterInfo::eAllTransports) { } diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 2f4018ce..41cc400f 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -40,7 +40,7 @@ namespace tunnel { std::vector peers; bool isShort = true; - i2p::data::RouterInfo::CompatibleTransports farEndTransports = 0; + i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports; void Add (std::shared_ptr r); void Reverse (); From f8c390cdd3a4b9f375f97b9ed1c7c15b8f8cc11a Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Nov 2021 15:44:56 -0400 Subject: [PATCH 0370/2193] pick compatible tunnels --- libi2pd/Destination.cpp | 2 +- libi2pd/NetDb.cpp | 8 ++--- libi2pd/TunnelPool.cpp | 72 ++++++++++++++++++++--------------------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f523243a..9341baa4 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -562,7 +562,6 @@ namespace client m_ExcludedFloodfills.clear (); return; } - m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); if (!outbound) { @@ -575,6 +574,7 @@ namespace client LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); return; } + m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b4ffe2bd..7123741a 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -681,8 +681,8 @@ namespace data else { auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; - auto inbound = pool ? pool->GetNextInboundTunnel () : nullptr; + auto outbound = pool ? pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; + auto inbound = pool ? pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; if (outbound && inbound) outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound)); else @@ -1129,8 +1129,8 @@ namespace data { // otherwise through exploratory auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); - auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; - auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr; + auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; + auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; if (inbound && outbound) outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound)); diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index c9897b29..a67b6618 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -498,9 +498,8 @@ namespace tunnel } prevHop = hop; path.Add (hop); - if (i == numHops - 1) - path.farEndTransports = hop->GetCompatibleTransports (inbound); } + path.farEndTransports = prevHop->GetCompatibleTransports (inbound); // last hop return true; } @@ -555,13 +554,13 @@ namespace tunnel void TunnelPool::CreateInboundTunnel () { - auto outboundTunnel = GetNextOutboundTunnel (); - if (!outboundTunnel) - outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Creating destination inbound tunnel..."); Path path; if (SelectPeers (path, true)) { + auto outboundTunnel = GetNextOutboundTunnel (nullptr, path.farEndTransports); + if (!outboundTunnel) + outboundTunnel = tunnels.GetNextOutboundTunnel (); std::shared_ptr config; if (m_NumInboundHops > 0) { @@ -583,7 +582,7 @@ namespace tunnel CreateInboundTunnel (); return; } - auto outboundTunnel = GetNextOutboundTunnel (); + auto outboundTunnel = GetNextOutboundTunnel (nullptr, tunnel->GetFarEndTransports ()); if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); @@ -604,40 +603,41 @@ namespace tunnel void TunnelPool::CreateOutboundTunnel () { - auto inboundTunnel = GetNextInboundTunnel (); - if (!inboundTunnel) - inboundTunnel = tunnels.GetNextInboundTunnel (); - if (inboundTunnel) + LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); + Path path; + if (SelectPeers (path, false)) { - LogPrint (eLogDebug, "Tunnels: Creating destination outbound tunnel..."); - Path path; - if (SelectPeers (path, false)) + auto inboundTunnel = GetNextInboundTunnel (nullptr, path.farEndTransports); + if (!inboundTunnel) + inboundTunnel = tunnels.GetNextInboundTunnel (); + if (!inboundTunnel) { - if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) - path.isShort = false; // because can't handle ECIES encrypted reply - - std::shared_ptr config; - if (m_NumOutboundHops > 0) - config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), - inboundTunnel->GetNextIdentHash (), path.isShort, path.farEndTransports); + LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no inbound tunnels found"); + return; + } + + if (m_LocalDestination && !m_LocalDestination->SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + path.isShort = false; // because can't handle ECIES encrypted reply + + std::shared_ptr config; + if (m_NumOutboundHops > 0) + config = std::make_shared(path.peers, inboundTunnel->GetNextTunnelID (), + inboundTunnel->GetNextIdentHash (), path.isShort, path.farEndTransports); - std::shared_ptr tunnel; - if (path.isShort) - { - // TODO: implement it better - tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ()); - tunnel->SetTunnelPool (shared_from_this ()); - } - else - tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); - if (tunnel && tunnel->IsEstablished ()) // zero hops - TunnelCreated (tunnel); - } - else - LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no peers available"); + std::shared_ptr tunnel; + if (path.isShort) + { + // TODO: implement it better + tunnel = tunnels.CreateOutboundTunnel (config, inboundTunnel->GetTunnelPool ()); + tunnel->SetTunnelPool (shared_from_this ()); + } + else + tunnel = tunnels.CreateOutboundTunnel (config, shared_from_this ()); + if (tunnel && tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } else - LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no inbound tunnels found"); + LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no peers available"); } void TunnelPool::RecreateOutboundTunnel (std::shared_ptr tunnel) @@ -647,7 +647,7 @@ namespace tunnel CreateOutboundTunnel (); return; } - auto inboundTunnel = GetNextInboundTunnel (); + auto inboundTunnel = GetNextInboundTunnel (nullptr, tunnel->GetFarEndTransports ()); if (!inboundTunnel) inboundTunnel = tunnels.GetNextInboundTunnel (); if (inboundTunnel) From 3f63f15b16e8c512e5dda777f1266d6a50d11409 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Nov 2021 19:16:45 -0400 Subject: [PATCH 0371/2193] copy compatible transports to new tunnel --- libi2pd/TunnelPool.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a67b6618..7bce0519 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -588,9 +588,7 @@ namespace tunnel LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); std::shared_ptr config; if (m_NumInboundHops > 0 && tunnel->GetPeers().size()) - { - config = std::make_shared(tunnel->GetPeers (), tunnel->IsShortBuildMessage ()); - } + config = std::make_shared(tunnel->GetPeers (), tunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); if (!m_NumInboundHops || config) { auto newTunnel = tunnels.CreateInboundTunnel (config, shared_from_this(), outboundTunnel); @@ -657,7 +655,7 @@ namespace tunnel if (m_NumOutboundHops > 0 && tunnel->GetPeers().size()) { config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), - inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage ()); + inboundTunnel->GetNextIdentHash (), inboundTunnel->IsShortBuildMessage (), tunnel->GetFarEndTransports ()); } if (!m_NumOutboundHops || config) { From d798faa1cad7a80dc7cc98d7ea9cc95e211c2a44 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Nov 2021 17:18:31 -0500 Subject: [PATCH 0372/2193] pick compatible ooutbound tunnel --- libi2pd/Streaming.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index be3d09d8..8be6811b 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -828,13 +828,6 @@ namespace stream m_RTO = m_RTT*1.5; // TODO: implement it better } } - if (!m_CurrentOutboundTunnel || !m_CurrentOutboundTunnel->IsEstablished ()) - m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNewOutboundTunnel (m_CurrentOutboundTunnel); - if (!m_CurrentOutboundTunnel) - { - LogPrint (eLogError, "Streaming: No outbound tunnels in the pool, sSID=", m_SendStreamID); - return; - } auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (!m_CurrentRemoteLease || !m_CurrentRemoteLease->endDate || // excluded from LeaseSet @@ -842,6 +835,21 @@ namespace stream UpdateCurrentRemoteLease (true); if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD) { + if (!m_CurrentOutboundTunnel) + { + auto leaseRouter = i2p::data::netdb.FindRouter (m_CurrentRemoteLease->tunnelGateway); + m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNextOutboundTunnel (nullptr, + leaseRouter ? leaseRouter->GetCompatibleTransports (false) : (i2p::data::RouterInfo::CompatibleTransports)i2p::data::RouterInfo::eAllTransports); + } + else if (!m_CurrentOutboundTunnel->IsEstablished ()) + m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNewOutboundTunnel (m_CurrentOutboundTunnel); + if (!m_CurrentOutboundTunnel) + { + LogPrint (eLogError, "Streaming: No outbound tunnels in the pool, sSID=", m_SendStreamID); + m_CurrentRemoteLease = nullptr; + return; + } + std::vector msgs; for (const auto& it: packets) { From 49883dc3ac43054ed1090107ed761d95074ef2eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Nov 2021 07:02:11 +0300 Subject: [PATCH 0373/2193] [webconsole] update stylesheet (closes #1699) Signed-off-by: R4SAS --- contrib/webconsole/style-dark.css | 272 ------------------------------ contrib/webconsole/style.css | 107 +++++++++--- daemon/HTTPServerResources.h | 97 ++++++----- 3 files changed, 133 insertions(+), 343 deletions(-) delete mode 100644 contrib/webconsole/style-dark.css diff --git a/contrib/webconsole/style-dark.css b/contrib/webconsole/style-dark.css deleted file mode 100644 index 6ec19023..00000000 --- a/contrib/webconsole/style-dark.css +++ /dev/null @@ -1,272 +0,0 @@ -:root { - --main-bg-color: #121212; - --main-text-color: #156A3D; - --main-link-color: #894C84; -} - -body { - font: 100%/1.5em sans-serif; - margin: 0; - padding: 1.5em; - background: var(--main-bg-color); - color: var(--main-text-color); -} - -a, .slide label { - text-decoration: none; - color: var(--main-link-color); -} - -a:hover, .slide label:hover, button[type=submit]:hover { - color: #FAFAFA; - background: var(--main-link-color); -} - -a.button { - appearance: button; - text-decoration: none; - padding: 0 5px; - border: 1px solid var(--main-link-color); -} - -.header { - font-size: 2.5em; - text-align: center; - margin: 1em 0; - color: var(--main-link-color); -} - -.wrapper { - margin: 0 auto; - padding: 1em; - max-width: 64em; -} - -.menu { - display: block; - float: left; - overflow: hidden; - max-width: 12em; - white-space: nowrap; - text-overflow: ellipsis; -} - -.listitem { - display: block; - font-family: monospace; - font-size: 1.2em; - white-space: nowrap; -} - -.tableitem { - font-family: monospace; - font-size: 1.2em; - white-space: nowrap; -} - -.content { - float: left; - font-size: 1em; - margin-left: 4em; - max-width: 48em; - overflow: auto; -} - -.tunnel.established { - color: #56B734; -} - -.tunnel.expiring { - color: #D3AE3F; -} - -.tunnel.failed { - color: #D33F3F; -} - -.tunnel.building { - color: #434343; -} - -caption { - font-size: 1.5em; - text-align: center; - color: var(--main-link-color); -} - -table { - display: table; - border-collapse: collapse; - text-align: center; -} - -table.extaddr { - text-align: left; -} - -table.services { - width: 100%; -} - -textarea { - background-color: var(--main-bg-color); - color: var(--main-text-color); - word-break: break-all; -} - -.streamdest { - width: 120px; - max-width: 240px; - overflow: hidden; - text-overflow: ellipsis; -} - -.slide div.slidecontent, .slide [type="checkbox"] { - display: none; -} - -.slide [type="checkbox"]:checked ~ div.slidecontent { - display: block; - margin-top: 0; - padding: 0; -} - -.disabled { - color: #D33F3F; -} - -.enabled { - color: #56B734; -} - -button[type=submit] { - background-color: transparent; - color: var(--main-link-color); - text-decoration: none; - padding: 5px; - border: 1px solid var(--main-link-color); - font-size: 14px; -} - -input, select, select option { - background-color: var(--main-bg-color); - color: var(--main-link-color); - padding: 5px; - border: 1px solid var(--main-link-color); - font-size: 14px; -} - -input:focus, select:focus, select option:focus { - outline: none; -} - -input[type=number]::-webkit-inner-spin-button { - -webkit-appearance: none; -} - -@media screen and (max-width: 1150px) { /* adaptive style */ - .wrapper { - max-width: 58em; - } - - .menu { - max-width: 10em; - } - - .content { - margin-left: 2em; - max-width: 42em; - } -} - -@media screen and (max-width: 980px) { - body { - font: 100%/1.2em sans-serif; - padding: 1.2em 0 0 0; - } - - .menu { - width: 100%; - max-width: unset; - display: block; - float: none; - position: unset; - font-size: 16px; - text-align: center; - } - - .menu a, .commands a { - display: inline-block; - padding: 4px; - } - - .content { - float: none; - margin-left: unset; - margin-top: 16px; - max-width: 100%; - width: 100%; - text-align: center; - } - - a, .slide label { - /* margin-right: 10px; */ - display: block; - /* font-size: 18px; */ - } - - .header { - margin: unset; - font-size: 1.5em; - } - - small { - display: block - } - - a.button { - appearance: button; - text-decoration: none; - margin-top: 10px; - padding: 6px; - border: 2px solid var(--main-link-color); - border-radius: 5px; - width: -webkit-fill-available; - } - - input, select { - width: 35%; - text-align: center; - padding: 5px; - border: 2px solid var(--main-link-color); - border-radius: 5px; - font-size: 18px; - } - - table.extaddr { - margin: auto; - text-align: unset; - } - - textarea { - width: -webkit-fill-available; - height: auto; - padding: 5px; - border: 2px solid var(--main-link-color); - border-radius: 5px; - font-size: 12px; - } - - button[type=submit] { - padding: 5px 15px; - background: transparent; - border: 2px solid var(--main-link-color); - cursor: pointer; - -webkit-border-radius: 5px; - border-radius: 5px; - position: relative; - height: 36px; - display: -webkit-inline-box; - margin-top: 10px; - } -} \ No newline at end of file diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index 047839a6..3a6ab059 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -1,35 +1,63 @@ +/* + * Copyright (c) 2013-2021, The PurpleI2P Project + * + * This file is part of Purple i2pd project and licensed under BSD3 + * + * See full license text in LICENSE file at top of project tree + * + ****************************************************************** + * + * This is styles heet for webconsole, with @media selectors for adaptive + * view on desktop and mobile devices, respecting preferred user's color + * scheme used in system/browser. + * + * Minified copy of that style sheet is bundled inside i2pd sources. +*/ + +:root { + --main-bg-color: #FAFAFA; + --main-text-color: #103456; + --main-link-color: #894C84; +} + +@media (prefers-color-scheme: dark) { + :root { + --main-bg-color: #121212; + --main-text-color: #156A3D; + --main-link-color: #894C84; + } +} + body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; - background: #FAFAFA; - color: #103456; + background: var(--main-bg-color); + color: var(--main-text-color); } a, .slide label { text-decoration: none; - color: #894C84; + color: var(--main-link-color); } -a:hover, .slide label:hover { +a:hover, .slide label:hover, button[type=submit]:hover { color: #FAFAFA; - background: #894C84; + background: var(--main-link-color); } a.button { - -webkit-appearance: button; - -moz-appearance: button; appearance: button; text-decoration: none; padding: 0 5px; - border: 1px solid #894C84; + border: 1px solid var(--main-link-color); } .header { font-size: 2.5em; text-align: center; margin: 1em 0; - color: #894C84; + color: var(--main-link-color); } .wrapper { @@ -42,6 +70,7 @@ a.button { display: block; float: left; overflow: hidden; + padding: 4px; max-width: 12em; white-space: nowrap; text-overflow: ellipsis; @@ -63,8 +92,9 @@ a.button { .content { float: left; font-size: 1em; - margin-left: 4em; - max-width: 48em; + margin-left: 2em; + padding: 4px; + max-width: 50em; overflow: auto; } @@ -87,7 +117,7 @@ a.button { caption { font-size: 1.5em; text-align: center; - color: #894C84; + color: var(--main-link-color); } table { @@ -105,6 +135,8 @@ table.services { } textarea { + background-color: var(--main-bg-color); + color: var(--main-text-color); word-break: break-all; } @@ -133,9 +165,34 @@ textarea { color: #56B734; } +button[type=submit] { + background-color: transparent; + color: var(--main-link-color); + text-decoration: none; + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input, select, select option { + background-color: var(--main-bg-color); + color: var(--main-link-color); + padding: 5px; + border: 1px solid var(--main-link-color); + font-size: 14px; +} + +input:focus, select:focus, select option:focus { + outline: none; +} + +input[type=number]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + @media screen and (max-width: 1150px) { /* adaptive style */ .wrapper { - max-width: 58em; + max-width: 60em; } .menu { @@ -144,13 +201,14 @@ textarea { .content { margin-left: 2em; - max-width: 42em; + max-width: 46em; } } @media screen and (max-width: 980px) { body { - padding: 1.5em 0 0 0; + font: 100%/1.2em sans-serif; + padding: 1.2em 0 0 0; } .menu { @@ -178,9 +236,7 @@ textarea { } a, .slide label { - /* margin-right: 10px; */ display: block; - /* font-size: 18px; */ } .header { @@ -193,13 +249,12 @@ textarea { } a.button { - -webkit-appearance: button; - -moz-appearance: button; appearance: button; text-decoration: none; margin-top: 10px; padding: 6px; - border: 1px solid #894c84; + border: 2px solid var(--main-link-color); + border-radius: 5px; width: -webkit-fill-available; } @@ -207,8 +262,7 @@ textarea { width: 35%; text-align: center; padding: 5px; - border: 2px solid #ccc; - -webkit-border-radius: 5px; + border: 2px solid var(--main-link-color); border-radius: 5px; font-size: 18px; } @@ -221,17 +275,16 @@ textarea { textarea { width: -webkit-fill-available; height: auto; - padding:5px; - border:2px solid #ccc; - -webkit-border-radius: 5px; + padding: 5px; + border: 2px solid var(--main-link-color); border-radius: 5px; font-size: 12px; } button[type=submit] { padding: 5px 15px; - background: #ccc; - border: 0 none; + background: transparent; + border: 2px solid var(--main-link-color); cursor: pointer; -webkit-border-radius: 5px; border-radius: 5px; diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h index 876948e8..75cf2d6e 100644 --- a/daemon/HTTPServerResources.h +++ b/daemon/HTTPServerResources.h @@ -34,50 +34,59 @@ namespace http // bundled style sheet const std::string internalCSS = "\r\n"; // for external style sheet From fdde197c5800c723eba76eb891b160a8dfc695de Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Nov 2021 07:40:39 +0300 Subject: [PATCH 0374/2193] [webconsole] update stylesheet Signed-off-by: R4SAS --- contrib/webconsole/style.css | 12 ++++++------ daemon/HTTPServerResources.h | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/contrib/webconsole/style.css b/contrib/webconsole/style.css index 3a6ab059..861e747a 100644 --- a/contrib/webconsole/style.css +++ b/contrib/webconsole/style.css @@ -7,7 +7,7 @@ * ****************************************************************** * - * This is styles heet for webconsole, with @media selectors for adaptive + * This is style sheet for webconsole, with @media selectors for adaptive * view on desktop and mobile devices, respecting preferred user's color * scheme used in system/browser. * @@ -22,7 +22,7 @@ @media (prefers-color-scheme: dark) { :root { - --main-bg-color: #121212; + --main-bg-color: #181818; --main-text-color: #156A3D; --main-link-color: #894C84; } @@ -63,7 +63,7 @@ a.button { .wrapper { margin: 0 auto; padding: 1em; - max-width: 64em; + max-width: 60em; } .menu { @@ -92,7 +92,7 @@ a.button { .content { float: left; font-size: 1em; - margin-left: 2em; + margin-left: 4em; padding: 4px; max-width: 50em; overflow: auto; @@ -192,7 +192,7 @@ input[type=number]::-webkit-inner-spin-button { @media screen and (max-width: 1150px) { /* adaptive style */ .wrapper { - max-width: 60em; + max-width: 56em; } .menu { @@ -201,7 +201,7 @@ input[type=number]::-webkit-inner-spin-button { .content { margin-left: 2em; - max-width: 46em; + max-width: 44em; } } diff --git a/daemon/HTTPServerResources.h b/daemon/HTTPServerResources.h index 75cf2d6e..89c742d3 100644 --- a/daemon/HTTPServerResources.h +++ b/daemon/HTTPServerResources.h @@ -35,17 +35,17 @@ namespace http const std::string internalCSS = "