From 1472637de71e5c6484525bab6bc640828a6112e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 11 May 2019 07:27:34 -0400 Subject: [PATCH 0001/2950] skip introducers for non-SSU address --- libi2pd/RouterInfo.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 6b520943..ee46a5b0 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -259,6 +259,11 @@ namespace data else if (key[0] == 'i') { // introducers + if (!address->ssu) + { + LogPrint (eLogError, "RouterInfo: Introducer is presented for non-SSU address. Skipped"); + continue; + } introducers = true; size_t l = strlen(key); unsigned char index = key[l-1] - '0'; // TODO: From ef76ed394c27ef4a699cfa8a3e337dc61a60fd12 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 May 2019 13:36:26 -0400 Subject: [PATCH 0002/2950] publish SSU ipv6 address if NTCP if disabled --- libi2pd/RouterContext.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 4a229546..7f2b704d 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -516,6 +516,24 @@ namespace i2p if (!found && port) // we have found NTCP2 v4 but not v6 { m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + if (!ntcp) + { + // we must publish SSU address + auto mtu = i2p::util::net::GetMTU (host); + if (mtu) + { + LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); + if (mtu > 1472) // TODO: magic constant + { + mtu = 1472; + LogPrint(eLogWarning, "Router: MTU dropped to upper limit of 1472 bytes"); + } + } + else + mtu = 1472; + m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), mtu); + } updated = true; } if (updated) From 5299ac35a61466beeadec96d78fa3a5ce5625191 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 May 2019 11:40:08 -0400 Subject: [PATCH 0003/2950] create NTCP2 ipv6 address --- libi2pd/RouterContext.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 7f2b704d..8293f1fd 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -110,7 +110,17 @@ namespace i2p { bool published; i2p::config::GetOption("ntcp2.published", published); if (published) + { PublishNTCP2Address (port, true); + if (ipv6) + { + // add NTCP2 ipv6 address + std::string host = "::1"; + if (!i2p::config::IsDefault ("ntcp2.addressv6")) + i2p::config::GetOption ("ntcp2.addressv6", host); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); + } + } } } } @@ -517,7 +527,8 @@ namespace i2p { m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (!ntcp) + bool ssu; i2p::config::GetOption("ssu", ssu); + if (!ntcp && ssu) { // we must publish SSU address auto mtu = i2p::util::net::GetMTU (host); From 39400fd3818f826c5d161a70c4cb057e764ef1e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 May 2019 11:42:25 -0400 Subject: [PATCH 0004/2950] move key blinding code from LeaseSet.cpp to Blinding.cpp --- build/CMakeLists.txt | 1 + libi2pd/Blinding.cpp | 157 +++++++++++++++++++++++++++++++++++++++++++ libi2pd/Blinding.h | 44 ++++++++++++ libi2pd/LeaseSet.cpp | 143 --------------------------------------- libi2pd/LeaseSet.h | 31 +-------- 5 files changed, 203 insertions(+), 173 deletions(-) create mode 100644 libi2pd/Blinding.cpp create mode 100644 libi2pd/Blinding.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index fa92da05..e50bbc86 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -81,6 +81,7 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/Poly1305.cpp" "${LIBI2PD_SRC_DIR}/Ed25519.cpp" "${LIBI2PD_SRC_DIR}/NTCP2.cpp" + "${LIBI2PD_SRC_DIR}/Blinding.cpp" ) if (WITH_WEBSOCKETS) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp new file mode 100644 index 00000000..4469123e --- /dev/null +++ b/libi2pd/Blinding.cpp @@ -0,0 +1,157 @@ +#include // for crc32 +#include +#include +#include "Base.h" +#include "Crypto.h" +#include "Log.h" +#include "Timestamp.h" +#include "I2PEndian.h" +#include "Ed25519.h" +#include "Blinding.h" + +namespace i2p +{ +namespace data +{ + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType): + m_BlindedSigType (blindedKeyType) + { + if (!identity) return; + auto len = identity->GetSigningPublicKeyLen (); + m_PublicKey.resize (len); + memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); + m_SigType = identity->GetSigningKeyType (); + } + + BlindedPublicKey::BlindedPublicKey (const std::string& b33) + { + uint8_t addr[40]; // TODO: define length from b33 + size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40); + uint32_t checksum = crc32 (0, addr + 3, l - 3); + // checksum is Little Endian + addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); + uint8_t flag = addr[0]; + size_t offset = 1; + if (flag & 0x01) // two bytes signatures + { + m_SigType = bufbe16toh (addr + offset); offset += 2; + m_BlindedSigType = bufbe16toh (addr + offset); offset += 2; + } + else // one byte sig + { + m_SigType = addr[offset]; offset++; + m_BlindedSigType = addr[offset]; offset++; + } + std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (m_SigType)); + if (blindedVerifier) + { + auto len = blindedVerifier->GetPublicKeyLen (); + if (offset + len <= l) + { + m_PublicKey.resize (len); + memcpy (m_PublicKey.data (), addr + offset, len); + } + else + LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType); + } + else + LogPrint (eLogError, "Blinding: unknown signature type ", (int)m_SigType, " in b33"); + } + + std::string BlindedPublicKey::ToB33 () const + { + if (m_PublicKey.size () > 32) return ""; // assume 25519 + uint8_t addr[35]; char str[60]; // TODO: define actual length + addr[0] = 0; // flags + addr[1] = m_SigType; // sig type + addr[2] = m_BlindedSigType; // blinded sig type + memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); + uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); + // checksum is Little Endian + addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); + auto l = ByteStreamToBase32 (addr, m_PublicKey.size () + 3, str, 60); + return std::string (str, str + l); + } + + void BlindedPublicKey::GetCredential (uint8_t * credential) const + { + // A = destination's signing public key + // stA = signature type of A, 2 bytes big endian + uint16_t stA = htobe16 (GetSigType ()); + // stA1 = signature type of blinded A, 2 bytes big endian + uint16_t stA1 = htobe16 (GetBlindedSigType ()); + // credential = H("credential", A || stA || stA1) + H ("credential", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, credential); + } + + void BlindedPublicKey::GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const + { + uint8_t credential[32]; + GetCredential (credential); + // subcredential = H("subcredential", credential || blindedPublicKey) + H ("subcredential", { {credential, 32}, {blinded, len} }, subcredential); + } + + void BlindedPublicKey::GenerateAlpha (const char * date, uint8_t * seed) const + { + uint16_t stA = htobe16 (GetSigType ()), stA1 = htobe16 (GetBlindedSigType ()); + uint8_t salt[32]; + //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) + H ("I2PGenerateAlpha", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); + i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); + } + + void BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const + { + uint8_t seed[64]; + GenerateAlpha (date, seed); + i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); + } + + void BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const + { + uint8_t seed[64]; + GenerateAlpha (date, seed); + i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub); + } + + void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, p.c_str (), p.length ()); + for (const auto& it: bufs) + SHA256_Update (&ctx, it.first, it.second); + SHA256_Final (hash, &ctx); + } + + i2p::data::IdentHash BlindedPublicKey::GetStoreHash (const char * date) const + { + i2p::data::IdentHash hash; + if (m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || + m_BlindedSigType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) + { + uint8_t blinded[32]; + if (date) + GetBlindedKey (date, blinded); + else + { + char currentDate[9]; + i2p::util::GetCurrentDate (currentDate); + GetBlindedKey (currentDate, blinded); + } + auto stA1 = htobe16 (m_BlindedSigType); + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, (const uint8_t *)&stA1, 2); + SHA256_Update (&ctx, blinded, 32); + SHA256_Final ((uint8_t *)hash, &ctx); + } + else + LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported"); + return hash; + } + +} +} + diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h new file mode 100644 index 00000000..9cfa76d2 --- /dev/null +++ b/libi2pd/Blinding.h @@ -0,0 +1,44 @@ +#ifndef BLINDING_H__ +#define BLINDING_H__ + +#include +#include +#include "Identity.h" + +namespace i2p +{ +namespace data +{ + class BlindedPublicKey // for encrypted LS2 + { + public: + + BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p + std::string ToB33 () const; + + const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; + size_t GetPublicKeyLen () const { return m_PublicKey.size (); }; + SigningKeyType GetSigType () const { return m_SigType; }; + SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; + + void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes + void GetBlindedKey (const char * date, uint8_t * blindedKey) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" + void BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" + i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null + + private: + + void GetCredential (uint8_t * credential) const; // 32 bytes + void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD" + void H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const; + + private: + + std::vector m_PublicKey; + i2p::data::SigningKeyType m_SigType, m_BlindedSigType; + }; +} +} + +#endif diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 8b9edb79..ad09ab2a 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,10 +1,6 @@ #include -#include -#include -#include // for crc32 #include "I2PEndian.h" #include "Crypto.h" -#include "Ed25519.h" #include "Log.h" #include "Timestamp.h" #include "NetDb.hpp" @@ -254,145 +250,6 @@ namespace data memcpy (m_Buffer, buf, len); } - BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType): - m_BlindedSigType (blindedKeyType) - { - if (!identity) return; - auto len = identity->GetSigningPublicKeyLen (); - m_PublicKey.resize (len); - memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); - m_SigType = identity->GetSigningKeyType (); - } - - BlindedPublicKey::BlindedPublicKey (const std::string& b33) - { - uint8_t addr[40]; // TODO: define length from b33 - size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40); - uint32_t checksum = crc32 (0, addr + 3, l - 3); - // checksum is Little Endian - addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); - uint8_t flag = addr[0]; - size_t offset = 1; - if (flag & 0x01) // two bytes signatures - { - m_SigType = bufbe16toh (addr + offset); offset += 2; - m_BlindedSigType = bufbe16toh (addr + offset); offset += 2; - } - else // one byte sig - { - m_SigType = addr[offset]; offset++; - m_BlindedSigType = addr[offset]; offset++; - } - std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (m_SigType)); - if (blindedVerifier) - { - auto len = blindedVerifier->GetPublicKeyLen (); - if (offset + len <= l) - { - m_PublicKey.resize (len); - memcpy (m_PublicKey.data (), addr + offset, len); - } - else - LogPrint (eLogError, "LeaseSet2: public key in b33 address is too short for signature type ", (int)m_SigType); - } - else - LogPrint (eLogError, "LeaseSet2: unknown signature type ", (int)m_SigType, " in b33"); - } - - std::string BlindedPublicKey::ToB33 () const - { - if (m_PublicKey.size () > 32) return ""; // assume 25519 - uint8_t addr[35]; char str[60]; // TODO: define actual length - addr[0] = 0; // flags - addr[1] = m_SigType; // sig type - addr[2] = m_BlindedSigType; // blinded sig type - memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); - uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); - // checksum is Little Endian - addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); - auto l = ByteStreamToBase32 (addr, m_PublicKey.size () + 3, str, 60); - return std::string (str, str + l); - } - - void BlindedPublicKey::GetCredential (uint8_t * credential) const - { - // A = destination's signing public key - // stA = signature type of A, 2 bytes big endian - uint16_t stA = htobe16 (GetSigType ()); - // stA1 = signature type of blinded A, 2 bytes big endian - uint16_t stA1 = htobe16 (GetBlindedSigType ()); - // credential = H("credential", A || stA || stA1) - H ("credential", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, credential); - } - - void BlindedPublicKey::GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const - { - uint8_t credential[32]; - GetCredential (credential); - // subcredential = H("subcredential", credential || blindedPublicKey) - H ("subcredential", { {credential, 32}, {blinded, len} }, subcredential); - } - - void BlindedPublicKey::GenerateAlpha (const char * date, uint8_t * seed) const - { - uint16_t stA = htobe16 (GetSigType ()), stA1 = htobe16 (GetBlindedSigType ()); - uint8_t salt[32]; - //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) - H ("I2PGenerateAlpha", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); - i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); - } - - void BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const - { - uint8_t seed[64]; - GenerateAlpha (date, seed); - i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); - } - - void BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const - { - uint8_t seed[64]; - GenerateAlpha (date, seed); - i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub); - } - - void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, p.c_str (), p.length ()); - for (const auto& it: bufs) - SHA256_Update (&ctx, it.first, it.second); - SHA256_Final (hash, &ctx); - } - - i2p::data::IdentHash BlindedPublicKey::GetStoreHash (const char * date) const - { - i2p::data::IdentHash hash; - if (m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || - m_BlindedSigType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) - { - uint8_t blinded[32]; - if (date) - GetBlindedKey (date, blinded); - else - { - char currentDate[9]; - i2p::util::GetCurrentDate (currentDate); - GetBlindedKey (currentDate, blinded); - } - auto stA1 = htobe16 (m_BlindedSigType); - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, (const uint8_t *)&stA1, 2); - SHA256_Update (&ctx, blinded, 32); - SHA256_Final ((uint8_t *)hash, &ctx); - } - else - LogPrint (eLogError, "LeaseSet2: blinded key type ", (int)m_BlindedSigType, " is not supported"); - return hash; - } - LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases): LeaseSet (storeLeases), m_StoreType (storeType), m_OrigStoreType (storeType) { diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 94a19b1b..8324a58d 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -9,6 +9,7 @@ #include "Identity.h" #include "Timestamp.h" #include "I2PEndian.h" +#include "Blinding.h" namespace i2p { @@ -128,36 +129,6 @@ namespace data const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7; const uint16_t LEASESET2_FLAG_OFFLINE_KEYS = 0x0001; - - class BlindedPublicKey // for encrypted LS2 - { - public: - - BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); - BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p - std::string ToB33 () const; - - const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; - size_t GetPublicKeyLen () const { return m_PublicKey.size (); }; - SigningKeyType GetSigType () const { return m_SigType; }; - SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; - - void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes - void GetBlindedKey (const char * date, uint8_t * blindedKey) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" - void BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" - i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null - - private: - - void GetCredential (uint8_t * credential) const; // 32 bytes - void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD" - void H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const; - - private: - - std::vector m_PublicKey; - i2p::data::SigningKeyType m_SigType, m_BlindedSigType; - }; class LeaseSet2: public LeaseSet { From 743fa745b7abcd837358c2f9bd7616495699a24f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 May 2019 14:42:10 -0400 Subject: [PATCH 0005/2950] show b33 address for encrypted LeaseSet2 --- daemon/HTTPServer.cpp | 6 ++++++ libi2pd/Blinding.h | 1 + libi2pd/Destination.h | 1 + 3 files changed, 8 insertions(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 20c9f3aa..963fed71 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -354,6 +354,12 @@ namespace http { { s << "Base64:
\r\n
\r\n
\r\n"; + if (dest->IsEncryptedLeaseSet ()) + { + i2p::data::BlindedPublicKey blinded (dest->GetIdentity ()); + s << "B33: " << blinded.ToB33 () << ".32.bi2p
\r\n"; + } + if(dest->GetNumRemoteLeaseSets()) { s << "
\r\n\r\n

\r\n"; diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 9cfa76d2..6c3671c6 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -3,6 +3,7 @@ #include #include +#include #include "Identity.h" namespace i2p diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index b55a7490..64dd0b58 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -181,6 +181,7 @@ namespace client // for HTTP only int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; }; + bool IsEncryptedLeaseSet () const { return m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; }; }; class ClientDestination: public LeaseSetDestination From f5b682619ff6f01c3a9dc3b97482e63536f3505f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 15 May 2019 14:15:10 +0300 Subject: [PATCH 0006/2950] [webconsole] move b33 to spoiler, fix typo --- daemon/HTTPServer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 963fed71..38b53ff3 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -357,7 +357,9 @@ namespace http { if (dest->IsEncryptedLeaseSet ()) { i2p::data::BlindedPublicKey blinded (dest->GetIdentity ()); - s << "B33: " << blinded.ToB33 () << ".32.bi2p
\r\n"; + s << "

\r\n\r\n

\r\n"; + s << blinded.ToB33 () << ".b32.i2p
\r\n"; + s << "

\r\n
\r\n"; } if(dest->GetNumRemoteLeaseSets()) From 5c3992018fe5b5dc13443b56f79ec1ecc08178f7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 15 May 2019 14:22:19 -0400 Subject: [PATCH 0007/2950] fixed #1350 use GetAddress insted GetIdentHash --- libi2pd_client/WebSocks.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libi2pd_client/WebSocks.cpp b/libi2pd_client/WebSocks.cpp index ee64001d..c80feac8 100644 --- a/libi2pd_client/WebSocks.cpp +++ b/libi2pd_client/WebSocks.cpp @@ -81,11 +81,14 @@ namespace client void CreateStreamTo(const std::string & addr, int port, StreamConnectFunc complete) { auto & addressbook = i2p::client::context.GetAddressBook(); - i2p::data::IdentHash ident; - if(addressbook.GetIdentHash(addr, ident)) { - // address found - m_Dest->CreateStream(complete, ident, port); - } else { + auto a = addressbook.GetAddress (addr); + if (a && a->IsIdentHash ()) + { + // address found + m_Dest->CreateStream(complete, a->identHash, port); + } + else + { // not found complete(nullptr); } @@ -443,12 +446,12 @@ namespace client addr = line.substr(0, itr); port = std::atoi(line.substr(itr+1).c_str()); } - i2p::data::IdentHash ident; - if(addressbook.GetIdentHash(addr, ident)) + auto a = addressbook.GetAddress (addr); + if (a && a->IsIdentHash ()) { const char * data = payload.c_str() + idx + 1; size_t len = payload.size() - (1 + line.size()); - m_Datagram->SendDatagramTo((const uint8_t*)data, len, ident, m_RemotePort, port); + m_Datagram->SendDatagramTo((const uint8_t*)data, len, a->identHash, m_RemotePort, port); } } else { // wtf? From a91641e427f9add861a80827df86122c4ea853a7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 16 May 2019 08:17:05 +0300 Subject: [PATCH 0008/2950] fix #823, reindent code --- libi2pd/HTTP.cpp | 822 +++++++++++++++++------------------ libi2pd/HTTP.h | 242 +++++------ libi2pd_client/HTTPProxy.cpp | 25 +- 3 files changed, 555 insertions(+), 534 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index c1a46e73..aaba3abc 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2017, The PurpleI2P Project +* Copyright (c) 2013-2019, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,282 +15,283 @@ namespace i2p { namespace http { - const std::vector HTTP_METHODS = { - "GET", "HEAD", "POST", "PUT", "PATCH", - "DELETE", "OPTIONS", "CONNECT" - }; - const std::vector HTTP_VERSIONS = { - "HTTP/1.0", "HTTP/1.1" - }; - const std::vector weekdays = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - const std::vector months = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; + const std::vector HTTP_METHODS = { + "GET", "HEAD", "POST", "PUT", "PATCH", + "DELETE", "OPTIONS", "CONNECT" + }; + const std::vector HTTP_VERSIONS = { + "HTTP/1.0", "HTTP/1.1" + }; + const std::vector weekdays = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + const std::vector months = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; - inline bool is_http_version(const std::string & str) { - return std::find(HTTP_VERSIONS.begin(), HTTP_VERSIONS.end(), str) != std::end(HTTP_VERSIONS); - } - - inline bool is_http_method(const std::string & str) { - return std::find(HTTP_METHODS.begin(), HTTP_METHODS.end(), str) != std::end(HTTP_METHODS); - } - - void strsplit(const std::string & line, std::vector &tokens, char delim, std::size_t limit = 0) { - std::size_t count = 0; - std::stringstream ss(line); - std::string token; - while (1) { - count++; - if (limit > 0 && count >= limit) - delim = '\n'; /* reset delimiter */ - if (!std::getline(ss, token, delim)) - break; - tokens.push_back(token); - } - } - - static std::pair parse_header_line(const std::string& line) - { - std::size_t pos = 0; - std::size_t len = 1; /*: */ - std::size_t max = line.length(); - if ((pos = line.find(':', pos)) == std::string::npos) - return std::make_pair("", ""); // no ':' found - if (pos + 1 < max) // ':' at the end of header is valid - { - while ((pos + len) < max && isspace(line.at(pos + len))) - len++; - if (len == 1) return std::make_pair("", ""); // no following space, but something else + inline bool is_http_version(const std::string & str) { + return std::find(HTTP_VERSIONS.begin(), HTTP_VERSIONS.end(), str) != std::end(HTTP_VERSIONS); } - return std::make_pair(line.substr(0, pos), line.substr(pos + len)); - } - void gen_rfc7231_date(std::string & out) { - std::time_t now = std::time(nullptr); - char buf[128]; - std::tm *tm = std::gmtime(&now); - snprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", - weekdays[tm->tm_wday], tm->tm_mday, months[tm->tm_mon], - tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec - ); - out = buf; - } + inline bool is_http_method(const std::string & str) { + return std::find(HTTP_METHODS.begin(), HTTP_METHODS.end(), str) != std::end(HTTP_METHODS); + } - bool URL::parse(const char *str, std::size_t len) { - std::string url(str, len ? len : strlen(str)); - return parse(url); - } + void strsplit(const std::string & line, std::vector &tokens, char delim, std::size_t limit = 0) { + std::size_t count = 0; + std::stringstream ss(line); + std::string token; + while (1) { + count++; + if (limit > 0 && count >= limit) + delim = '\n'; /* reset delimiter */ + if (!std::getline(ss, token, delim)) + break; + tokens.push_back(token); + } + } - bool URL::parse(const std::string& url) { - std::size_t pos_p = 0; /* < current parse position */ - std::size_t pos_c = 0; /* < work position */ - if(url.at(0) != '/' || pos_p > 0) { - std::size_t pos_s = 0; - /* schema */ - pos_c = url.find("://"); - if (pos_c != std::string::npos) { - schema = url.substr(0, pos_c); - pos_p = pos_c + 3; - } - /* user[:pass] */ - pos_s = url.find('/', pos_p); /* find first slash */ - pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */ - if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) { - std::size_t delim = url.find(':', pos_p); - if (delim && delim != std::string::npos && delim < pos_c) { - user = url.substr(pos_p, delim - pos_p); - delim += 1; - pass = url.substr(delim, pos_c - delim); - } else if(delim) { - user = url.substr(pos_p, pos_c - pos_p); - } - pos_p = pos_c + 1; - } - /* hostname[:port][/path] */ - pos_c = url.find_first_of(":/", pos_p); - if (pos_c == std::string::npos) { - /* only hostname, without post and path */ - host = url.substr(pos_p, std::string::npos); - return true; - } else if (url.at(pos_c) == ':') { - host = url.substr(pos_p, pos_c - pos_p); - /* port[/path] */ - pos_p = pos_c + 1; - pos_c = url.find('/', pos_p); - std::string port_str = (pos_c == std::string::npos) - ? url.substr(pos_p, std::string::npos) - : url.substr(pos_p, pos_c - pos_p); - /* stoi throws exception on failure, we don't need it */ - for (char c : port_str) { - if (c < '0' || c > '9') - return false; - port *= 10; - port += c - '0'; - } - if (pos_c == std::string::npos) - return true; /* no path part */ - pos_p = pos_c; - } else { - /* start of path part found */ - host = url.substr(pos_p, pos_c - pos_p); - pos_p = pos_c; - } - } + static std::pair parse_header_line(const std::string& line) + { + std::size_t pos = 0; + std::size_t len = 1; /*: */ + std::size_t max = line.length(); + if ((pos = line.find(':', pos)) == std::string::npos) + return std::make_pair("", ""); // no ':' found + if (pos + 1 < max) // ':' at the end of header is valid + { + while ((pos + len) < max && isspace(line.at(pos + len))) + len++; + if (len == 1) + return std::make_pair("", ""); // no following space, but something else + } + return std::make_pair(line.substr(0, pos), line.substr(pos + len)); + } - /* pos_p now at start of path part */ - pos_c = url.find_first_of("?#", pos_p); - if (pos_c == std::string::npos) { - /* only path, without fragment and query */ - path = url.substr(pos_p, std::string::npos); - return true; - } else if (url.at(pos_c) == '?') { - /* found query part */ - path = url.substr(pos_p, pos_c - pos_p); - pos_p = pos_c + 1; - pos_c = url.find('#', pos_p); - if (pos_c == std::string::npos) { - /* no fragment */ - query = url.substr(pos_p, std::string::npos); - return true; - } else { - query = url.substr(pos_p, pos_c - pos_p); - pos_p = pos_c + 1; - } - } else { - /* found fragment part */ - path = url.substr(pos_p, pos_c - pos_p); - pos_p = pos_c + 1; - } + void gen_rfc7231_date(std::string & out) { + std::time_t now = std::time(nullptr); + char buf[128]; + std::tm *tm = std::gmtime(&now); + snprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", + weekdays[tm->tm_wday], tm->tm_mday, months[tm->tm_mon], + tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec + ); + out = buf; + } - /* pos_p now at start of fragment part */ - frag = url.substr(pos_p, std::string::npos); - return true; - } + bool URL::parse(const char *str, std::size_t len) { + std::string url(str, len ? len : strlen(str)); + return parse(url); + } - bool URL::parse_query(std::map & params) { - std::vector tokens; - strsplit(query, tokens, '&'); + bool URL::parse(const std::string& url) { + std::size_t pos_p = 0; /* < current parse position */ + std::size_t pos_c = 0; /* < work position */ + if(url.at(0) != '/' || pos_p > 0) { + std::size_t pos_s = 0; + /* schema */ + pos_c = url.find("://"); + if (pos_c != std::string::npos) { + schema = url.substr(0, pos_c); + pos_p = pos_c + 3; + } + /* user[:pass] */ + pos_s = url.find('/', pos_p); /* find first slash */ + pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */ + if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) { + std::size_t delim = url.find(':', pos_p); + if (delim && delim != std::string::npos && delim < pos_c) { + user = url.substr(pos_p, delim - pos_p); + delim += 1; + pass = url.substr(delim, pos_c - delim); + } else if(delim) { + user = url.substr(pos_p, pos_c - pos_p); + } + pos_p = pos_c + 1; + } + /* hostname[:port][/path] */ + pos_c = url.find_first_of(":/", pos_p); + if (pos_c == std::string::npos) { + /* only hostname, without post and path */ + host = url.substr(pos_p, std::string::npos); + return true; + } else if (url.at(pos_c) == ':') { + host = url.substr(pos_p, pos_c - pos_p); + /* port[/path] */ + pos_p = pos_c + 1; + pos_c = url.find('/', pos_p); + std::string port_str = (pos_c == std::string::npos) + ? url.substr(pos_p, std::string::npos) + : url.substr(pos_p, pos_c - pos_p); + /* stoi throws exception on failure, we don't need it */ + for (char c : port_str) { + if (c < '0' || c > '9') + return false; + port *= 10; + port += c - '0'; + } + if (pos_c == std::string::npos) + return true; /* no path part */ + pos_p = pos_c; + } else { + /* start of path part found */ + host = url.substr(pos_p, pos_c - pos_p); + pos_p = pos_c; + } + } - params.clear(); - for (const auto& it : tokens) { - std::size_t eq = it.find ('='); - if (eq != std::string::npos) { - auto e = std::pair(it.substr(0, eq), it.substr(eq + 1)); - params.insert(e); - } else { - auto e = std::pair(it, ""); - params.insert(e); - } - } - return true; - } + /* pos_p now at start of path part */ + pos_c = url.find_first_of("?#", pos_p); + if (pos_c == std::string::npos) { + /* only path, without fragment and query */ + path = url.substr(pos_p, std::string::npos); + return true; + } else if (url.at(pos_c) == '?') { + /* found query part */ + path = url.substr(pos_p, pos_c - pos_p); + pos_p = pos_c + 1; + pos_c = url.find('#', pos_p); + if (pos_c == std::string::npos) { + /* no fragment */ + query = url.substr(pos_p, std::string::npos); + return true; + } else { + query = url.substr(pos_p, pos_c - pos_p); + pos_p = pos_c + 1; + } + } else { + /* found fragment part */ + path = url.substr(pos_p, pos_c - pos_p); + pos_p = pos_c + 1; + } - std::string URL::to_string() { - std::string out = ""; - if (schema != "") { - out = schema + "://"; - if (user != "" && pass != "") { - out += user + ":" + pass + "@"; - } else if (user != "") { - out += user + "@"; - } - if (port) { - out += host + ":" + std::to_string(port); - } else { - out += host; - } - } - out += path; - if (query != "") - out += "?" + query; - if (frag != "") - out += "#" + frag; - return out; - } + /* pos_p now at start of fragment part */ + frag = url.substr(pos_p, std::string::npos); + return true; + } + + bool URL::parse_query(std::map & params) { + std::vector tokens; + strsplit(query, tokens, '&'); + + params.clear(); + for (const auto& it : tokens) { + std::size_t eq = it.find ('='); + if (eq != std::string::npos) { + auto e = std::pair(it.substr(0, eq), it.substr(eq + 1)); + params.insert(e); + } else { + auto e = std::pair(it, ""); + params.insert(e); + } + } + return true; + } + + std::string URL::to_string() { + std::string out = ""; + if (schema != "") { + out = schema + "://"; + if (user != "" && pass != "") { + out += user + ":" + pass + "@"; + } else if (user != "") { + out += user + "@"; + } + if (port) { + out += host + ":" + std::to_string(port); + } else { + out += host; + } + } + out += path; + if (query != "") + out += "?" + query; + if (frag != "") + out += "#" + frag; + return out; + } bool URL::is_i2p() const { return host.rfind(".i2p") == ( host.size() - 4 ); } - void HTTPMsg::add_header(const char *name, std::string & value, bool replace) { - add_header(name, value.c_str(), replace); - } + void HTTPMsg::add_header(const char *name, std::string & value, bool replace) { + add_header(name, value.c_str(), replace); + } - void HTTPMsg::add_header(const char *name, const char *value, bool replace) { - std::size_t count = headers.count(name); - if (count && !replace) - return; - if (count) { - headers[name] = value; - return; - } - headers.insert(std::pair(name, value)); - } + void HTTPMsg::add_header(const char *name, const char *value, bool replace) { + std::size_t count = headers.count(name); + if (count && !replace) + return; + if (count) { + headers[name] = value; + return; + } + headers.insert(std::pair(name, value)); + } - void HTTPMsg::del_header(const char *name) { - headers.erase(name); - } + void HTTPMsg::del_header(const char *name) { + headers.erase(name); + } - int HTTPReq::parse(const char *buf, size_t len) { - std::string str(buf, len); - return parse(str); - } + int HTTPReq::parse(const char *buf, size_t len) { + std::string str(buf, len); + return parse(str); + } - int HTTPReq::parse(const std::string& str) { - enum { REQ_LINE, HEADER_LINE } expect = REQ_LINE; - std::size_t eoh = str.find(HTTP_EOH); /* request head size */ - std::size_t eol = 0, pos = 0; - URL url; + int HTTPReq::parse(const std::string& str) { + enum { REQ_LINE, HEADER_LINE } expect = REQ_LINE; + std::size_t eoh = str.find(HTTP_EOH); /* request head size */ + std::size_t eol = 0, pos = 0; + URL url; - if (eoh == std::string::npos) - return 0; /* str not contains complete request */ + if (eoh == std::string::npos) + return 0; /* str not contains complete request */ - while ((eol = str.find(CRLF, pos)) != std::string::npos) { - if (expect == REQ_LINE) { - std::string line = str.substr(pos, eol - pos); - std::vector tokens; - strsplit(line, tokens, ' '); - if (tokens.size() != 3) - return -1; - if (!is_http_method(tokens[0])) - return -1; - if (!is_http_version(tokens[2])) - return -1; - if (!url.parse(tokens[1])) - return -1; - /* all ok */ - method = tokens[0]; - uri = tokens[1]; - version = tokens[2]; - expect = HEADER_LINE; - } - else - { - std::string line = str.substr(pos, eol - pos); - auto p = parse_header_line(line); - if (p.first.length () > 0) - headers.push_back (p); - else - return -1; - } - pos = eol + strlen(CRLF); - if (pos >= eoh) - break; - } - return eoh + strlen(HTTP_EOH); - } + while ((eol = str.find(CRLF, pos)) != std::string::npos) { + if (expect == REQ_LINE) { + std::string line = str.substr(pos, eol - pos); + std::vector tokens; + strsplit(line, tokens, ' '); + if (tokens.size() != 3) + return -1; + if (!is_http_method(tokens[0])) + return -1; + if (!is_http_version(tokens[2])) + return -1; + if (!url.parse(tokens[1])) + return -1; + /* all ok */ + method = tokens[0]; + uri = tokens[1]; + version = tokens[2]; + expect = HEADER_LINE; + } + else + { + std::string line = str.substr(pos, eol - pos); + auto p = parse_header_line(line); + if (p.first.length () > 0) + headers.push_back (p); + else + return -1; + } + pos = eol + strlen(CRLF); + if (pos >= eoh) + break; + } + return eoh + strlen(HTTP_EOH); + } - void HTTPReq::write(std::ostream & o) - { - o << method << " " << uri << " " << version << CRLF; - for (auto & h : headers) - o << h.first << ": " << h.second << CRLF; - o << CRLF; - } + void HTTPReq::write(std::ostream & o) + { + o << method << " " << uri << " " << version << CRLF; + for (auto & h : headers) + o << h.first << ": " << h.second << CRLF; + o << CRLF; + } std::string HTTPReq::to_string() { @@ -306,7 +307,7 @@ namespace http { void HTTPReq::UpdateHeader (const std::string& name, const std::string& value) { - for (auto& it : headers) + for (auto& it : headers) if (it.first == name) { it.second = value; @@ -327,177 +328,176 @@ namespace http { std::string HTTPReq::GetHeader (const std::string& name) const { - for (auto& it : headers) + for (auto& it : headers) if (it.first == name) return it.second; return ""; } - bool HTTPRes::is_chunked() const - { - auto it = headers.find("Transfer-Encoding"); - if (it == headers.end()) - return false; - if (it->second.find("chunked") == std::string::npos) - return true; - return false; - } + bool HTTPRes::is_chunked() const + { + auto it = headers.find("Transfer-Encoding"); + if (it == headers.end()) + return false; + if (it->second.find("chunked") == std::string::npos) + return true; + return false; + } - bool HTTPRes::is_gzipped(bool includingI2PGzip) const - { - auto it = headers.find("Content-Encoding"); - if (it == headers.end()) - return false; /* no header */ - if (it->second.find("gzip") != std::string::npos) - return true; /* gotcha! */ - if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos) - return true; - return false; - } + bool HTTPRes::is_gzipped(bool includingI2PGzip) const + { + auto it = headers.find("Content-Encoding"); + if (it == headers.end()) + return false; /* no header */ + if (it->second.find("gzip") != std::string::npos) + return true; /* gotcha! */ + if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos) + return true; + return false; + } - long int HTTPMsg::content_length() const - { - unsigned long int length = 0; - auto it = headers.find("Content-Length"); - if (it == headers.end()) - return -1; - errno = 0; - length = std::strtoul(it->second.c_str(), (char **) NULL, 10); - if (errno != 0) - return -1; - return length; - } + long int HTTPMsg::content_length() const + { + unsigned long int length = 0; + auto it = headers.find("Content-Length"); + if (it == headers.end()) + return -1; + errno = 0; + length = std::strtoul(it->second.c_str(), (char **) NULL, 10); + if (errno != 0) + return -1; + return length; + } - int HTTPRes::parse(const char *buf, size_t len) { - std::string str(buf, len); - return parse(str); - } + int HTTPRes::parse(const char *buf, size_t len) { + std::string str(buf, len); + return parse(str); + } - int HTTPRes::parse(const std::string& str) { - enum { RES_LINE, HEADER_LINE } expect = RES_LINE; - std::size_t eoh = str.find(HTTP_EOH); /* request head size */ - std::size_t eol = 0, pos = 0; + int HTTPRes::parse(const std::string& str) { + enum { RES_LINE, HEADER_LINE } expect = RES_LINE; + std::size_t eoh = str.find(HTTP_EOH); /* request head size */ + std::size_t eol = 0, pos = 0; - if (eoh == std::string::npos) - return 0; /* str not contains complete request */ + if (eoh == std::string::npos) + return 0; /* str not contains complete request */ - while ((eol = str.find(CRLF, pos)) != std::string::npos) { - if (expect == RES_LINE) { - std::string line = str.substr(pos, eol - pos); - std::vector tokens; - strsplit(line, tokens, ' ', 3); - if (tokens.size() != 3) - return -1; - if (!is_http_version(tokens[0])) - return -1; - code = atoi(tokens[1].c_str()); - if (code < 100 || code >= 600) - return -1; - /* all ok */ - version = tokens[0]; - status = tokens[2]; - expect = HEADER_LINE; - } else { - std::string line = str.substr(pos, eol - pos); - auto p = parse_header_line(line); - if (p.first.length () > 0) - headers.insert (p); - else - return -1; - } - pos = eol + strlen(CRLF); - if (pos >= eoh) - break; - } + while ((eol = str.find(CRLF, pos)) != std::string::npos) { + if (expect == RES_LINE) { + std::string line = str.substr(pos, eol - pos); + std::vector tokens; + strsplit(line, tokens, ' ', 3); + if (tokens.size() != 3) + return -1; + if (!is_http_version(tokens[0])) + return -1; + code = atoi(tokens[1].c_str()); + if (code < 100 || code >= 600) + return -1; + /* all ok */ + version = tokens[0]; + status = tokens[2]; + expect = HEADER_LINE; + } else { + std::string line = str.substr(pos, eol - pos); + auto p = parse_header_line(line); + if (p.first.length () > 0) + headers.insert (p); + else + return -1; + } + pos = eol + strlen(CRLF); + if (pos >= eoh) + break; + } + return eoh + strlen(HTTP_EOH); + } - return eoh + strlen(HTTP_EOH); - } + std::string HTTPRes::to_string() { + if (version == "HTTP/1.1" && headers.count("Date") == 0) { + std::string date; + gen_rfc7231_date(date); + add_header("Date", date.c_str()); + } + if (status == "OK" && code != 200) + status = HTTPCodeToStatus(code); // update + if (body.length() > 0 && headers.count("Content-Length") == 0) + add_header("Content-Length", std::to_string(body.length()).c_str()); + /* build response */ + std::stringstream ss; + ss << version << " " << code << " " << status << CRLF; + for (auto & h : headers) { + ss << h.first << ": " << h.second << CRLF; + } + ss << CRLF; + if (body.length() > 0) + ss << body; + return ss.str(); + } - std::string HTTPRes::to_string() { - if (version == "HTTP/1.1" && headers.count("Date") == 0) { - std::string date; - gen_rfc7231_date(date); - add_header("Date", date.c_str()); - } - if (status == "OK" && code != 200) - status = HTTPCodeToStatus(code); // update - if (body.length() > 0 && headers.count("Content-Length") == 0) - add_header("Content-Length", std::to_string(body.length()).c_str()); - /* build response */ - std::stringstream ss; - ss << version << " " << code << " " << status << CRLF; - for (auto & h : headers) { - ss << h.first << ": " << h.second << CRLF; - } - ss << CRLF; - if (body.length() > 0) - ss << body; - return ss.str(); - } + const char * HTTPCodeToStatus(int code) { + const char *ptr; + switch (code) { + case 105: ptr = "Name Not Resolved"; break; + /* success */ + case 200: ptr = "OK"; break; + case 206: ptr = "Partial Content"; break; + /* redirect */ + case 301: ptr = "Moved Permanently"; break; + case 302: ptr = "Found"; break; + case 304: ptr = "Not Modified"; break; + case 307: ptr = "Temporary Redirect"; break; + /* client error */ + case 400: ptr = "Bad Request"; break; + case 401: ptr = "Unauthorized"; break; + case 403: ptr = "Forbidden"; break; + case 404: ptr = "Not Found"; break; + case 407: ptr = "Proxy Authentication Required"; break; + case 408: ptr = "Request Timeout"; break; + /* server error */ + case 500: ptr = "Internal Server Error"; break; + case 502: ptr = "Bad Gateway"; break; + case 503: ptr = "Not Implemented"; break; + case 504: ptr = "Gateway Timeout"; break; + default: ptr = "Unknown Status"; break; + } + return ptr; + } - const char * HTTPCodeToStatus(int code) { - const char *ptr; - switch (code) { - case 105: ptr = "Name Not Resolved"; break; - /* success */ - case 200: ptr = "OK"; break; - case 206: ptr = "Partial Content"; break; - /* redirect */ - case 301: ptr = "Moved Permanently"; break; - case 302: ptr = "Found"; break; - case 304: ptr = "Not Modified"; break; - case 307: ptr = "Temporary Redirect"; break; - /* client error */ - case 400: ptr = "Bad Request"; break; - case 401: ptr = "Unauthorized"; break; - case 403: ptr = "Forbidden"; break; - case 404: ptr = "Not Found"; break; - case 407: ptr = "Proxy Authentication Required"; break; - case 408: ptr = "Request Timeout"; break; - /* server error */ - case 500: ptr = "Internal Server Error"; break; - case 502: ptr = "Bad Gateway"; break; - case 503: ptr = "Not Implemented"; break; - case 504: ptr = "Gateway Timeout"; break; - default: ptr = "Unknown Status"; break; - } - return ptr; - } - - std::string UrlDecode(const std::string& data, bool allow_null) { + std::string UrlDecode(const std::string& data, bool allow_null) { std::string decoded(data); - size_t pos = 0; - while ((pos = decoded.find('%', pos)) != std::string::npos) { - char c = strtol(decoded.substr(pos + 1, 2).c_str(), NULL, 16); - if (c == '\0' && !allow_null) { - pos += 3; - continue; - } - decoded.replace(pos, 3, 1, c); - pos++; - } - return decoded; - } + size_t pos = 0; + while ((pos = decoded.find('%', pos)) != std::string::npos) { + char c = strtol(decoded.substr(pos + 1, 2).c_str(), NULL, 16); + if (c == '\0' && !allow_null) { + pos += 3; + continue; + } + decoded.replace(pos, 3, 1, c); + pos++; + } + return decoded; + } - bool MergeChunkedResponse (std::istream& in, std::ostream& out) { - std::string hexLen; - while (!in.eof ()) { - std::getline (in, hexLen); - errno = 0; - long int len = strtoul(hexLen.c_str(), (char **) NULL, 16); - if (errno != 0) - return false; /* conversion error */ - if (len == 0) - return true; /* end of stream */ - if (len < 0 || len > 10 * 1024 * 1024) /* < 10Mb */ - return false; /* too large chunk */ - char * buf = new char[len]; - in.read (buf, len); - out.write (buf, len); - delete[] buf; - std::getline (in, hexLen); // read \r\n after chunk - } - return true; - } + bool MergeChunkedResponse (std::istream& in, std::ostream& out) { + std::string hexLen; + while (!in.eof ()) { + std::getline (in, hexLen); + errno = 0; + long int len = strtoul(hexLen.c_str(), (char **) NULL, 16); + if (errno != 0) + return false; /* conversion error */ + if (len == 0) + return true; /* end of stream */ + if (len < 0 || len > 10 * 1024 * 1024) /* < 10Mb */ + return false; /* too large chunk */ + char * buf = new char[len]; + in.read (buf, len); + out.write (buf, len); + delete[] buf; + std::getline (in, hexLen); // read \r\n after chunk + } + return true; + } } // http } // i2p diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index 837faf01..f156fef0 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2019, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -20,152 +20,152 @@ namespace i2p { namespace http { - const char CRLF[] = "\r\n"; /**< HTTP line terminator */ - const char HTTP_EOH[] = "\r\n\r\n"; /**< HTTP end-of-headers mark */ - extern const std::vector HTTP_METHODS; /**< list of valid HTTP methods */ - extern const std::vector HTTP_VERSIONS; /**< list of valid HTTP versions */ + const char CRLF[] = "\r\n"; /**< HTTP line terminator */ + const char HTTP_EOH[] = "\r\n\r\n"; /**< HTTP end-of-headers mark */ + extern const std::vector HTTP_METHODS; /**< list of valid HTTP methods */ + extern const std::vector HTTP_VERSIONS; /**< list of valid HTTP versions */ - struct URL - { - std::string schema; - std::string user; - std::string pass; - std::string host; - unsigned short int port; - std::string path; - std::string query; - std::string frag; + struct URL + { + std::string schema; + std::string user; + std::string pass; + std::string host; + unsigned short int port; + std::string path; + std::string query; + std::string frag; - URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), query(""), frag("") {}; + URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), query(""), frag("") {}; - /** - * @brief Tries to parse url from string - * @return true on success, false on invalid url - */ - bool parse (const char *str, std::size_t len = 0); - bool parse (const std::string& url); + /** + * @brief Tries to parse url from string + * @return true on success, false on invalid url + */ + bool parse (const char *str, std::size_t len = 0); + bool parse (const std::string& url); - /** - * @brief Parse query part of url to key/value map - * @note Honestly, this should be implemented with std::multimap - */ - bool parse_query(std::map & params); + /** + * @brief Parse query part of url to key/value map + * @note Honestly, this should be implemented with std::multimap + */ + bool parse_query(std::map & params); - /** - * @brief Serialize URL structure to url - * @note Returns relative url if schema if empty, absolute url otherwise - */ - std::string to_string (); + /** + * @brief Serialize URL structure to url + * @note Returns relative url if schema if empty, absolute url otherwise + */ + std::string to_string (); - /** - * @brief return true if the host is inside i2p - */ - bool is_i2p() const; - }; + /** + * @brief return true if the host is inside i2p + */ + bool is_i2p() const; + }; - struct HTTPMsg - { - std::map headers; + struct HTTPMsg + { + std::map headers; - void add_header(const char *name, std::string & value, bool replace = false); - void add_header(const char *name, const char *value, bool replace = false); - void del_header(const char *name); + void add_header(const char *name, std::string & value, bool replace = false); + void add_header(const char *name, const char *value, bool replace = false); + void del_header(const char *name); - /** @brief Returns declared message length or -1 if unknown */ - long int content_length() const; - }; + /** @brief Returns declared message length or -1 if unknown */ + long int content_length() const; + }; - struct HTTPReq - { - std::list > headers; - std::string version; - std::string method; - std::string uri; + struct HTTPReq + { + std::list > headers; + std::string version; + std::string method; + std::string uri; - HTTPReq (): version("HTTP/1.0"), method("GET"), uri("/") {}; + HTTPReq (): version("HTTP/1.0"), method("GET"), uri("/") {}; - /** - * @brief Tries to parse HTTP request from string - * @return -1 on error, 0 on incomplete query, >0 on success - * @note Positive return value is a size of header - */ - int parse(const char *buf, size_t len); - int parse(const std::string& buf); + /** + * @brief Tries to parse HTTP request from string + * @return -1 on error, 0 on incomplete query, >0 on success + * @note Positive return value is a size of header + */ + int parse(const char *buf, size_t len); + int parse(const std::string& buf); - /** @brief Serialize HTTP request to string */ - std::string to_string(); + /** @brief Serialize HTTP request to string */ + std::string to_string(); void write(std::ostream & o); - void AddHeader (const std::string& name, const std::string& value); - void UpdateHeader (const std::string& name, const std::string& value); - void RemoveHeader (const std::string& name, const std::string& exempt); // remove all headers starting with name, but exempt - void RemoveHeader (const std::string& name) { RemoveHeader (name, ""); }; - std::string GetHeader (const std::string& name) const; - }; + void AddHeader (const std::string& name, const std::string& value); + void UpdateHeader (const std::string& name, const std::string& value); + void RemoveHeader (const std::string& name, const std::string& exempt); // remove all headers starting with name, but exempt + void RemoveHeader (const std::string& name) { RemoveHeader (name, ""); }; + std::string GetHeader (const std::string& name) const; + }; - struct HTTPRes : HTTPMsg { - std::string version; - std::string status; - unsigned short int code; - /** - * @brief Simplifies response generation - * - * If this variable is set, on @a to_string() call: - * * Content-Length header will be added if missing, - * * contents of @a body will be included in generated response - */ - std::string body; + struct HTTPRes : HTTPMsg { + std::string version; + std::string status; + unsigned short int code; + /** + * @brief Simplifies response generation + * + * If this variable is set, on @a to_string() call: + * * Content-Length header will be added if missing, + * * contents of @a body will be included in generated response + */ + std::string body; - HTTPRes (): version("HTTP/1.1"), status("OK"), code(200) {} + HTTPRes (): version("HTTP/1.1"), status("OK"), code(200) {} - /** - * @brief Tries to parse HTTP response from string - * @return -1 on error, 0 on incomplete query, >0 on success - * @note Positive return value is a size of header - */ - int parse(const char *buf, size_t len); - int parse(const std::string& buf); + /** + * @brief Tries to parse HTTP response from string + * @return -1 on error, 0 on incomplete query, >0 on success + * @note Positive return value is a size of header + */ + int parse(const char *buf, size_t len); + int parse(const std::string& buf); - /** - * @brief Serialize HTTP response to string - * @note If @a version is set to HTTP/1.1, and Date header is missing, - * it will be generated based on current time and added to headers - * @note If @a body is set and Content-Length header is missing, - * this header will be added, based on body's length - */ - std::string to_string(); + /** + * @brief Serialize HTTP response to string + * @note If @a version is set to HTTP/1.1, and Date header is missing, + * it will be generated based on current time and added to headers + * @note If @a body is set and Content-Length header is missing, + * this header will be added, based on body's length + */ + std::string to_string(); void write(std::ostream & o); - /** @brief Checks that response declared as chunked data */ - bool is_chunked() const ; + /** @brief Checks that response declared as chunked data */ + bool is_chunked() const ; - /** @brief Checks that response contains compressed data */ - bool is_gzipped(bool includingI2PGzip = true) const; - }; + /** @brief Checks that response contains compressed data */ + bool is_gzipped(bool includingI2PGzip = true) const; + }; - /** - * @brief returns HTTP status string by integer code - * @param code HTTP code [100, 599] - * @return Immutable string with status - */ - const char * HTTPCodeToStatus(int code); + /** + * @brief returns HTTP status string by integer code + * @param code HTTP code [100, 599] + * @return Immutable string with status + */ + const char * HTTPCodeToStatus(int code); - /** - * @brief Replaces %-encoded characters in string with their values - * @param data Source string - * @param null If set to true - decode also %00 sequence, otherwise - skip - * @return Decoded string - */ - std::string UrlDecode(const std::string& data, bool null = false); + /** + * @brief Replaces %-encoded characters in string with their values + * @param data Source string + * @param null If set to true - decode also %00 sequence, otherwise - skip + * @return Decoded string + */ + std::string UrlDecode(const std::string& data, bool null = false); - /** - * @brief Merge HTTP response content with Transfer-Encoding: chunked - * @param in Input stream - * @param out Output stream - * @return true on success, false otherwise - */ - bool MergeChunkedResponse (std::istream& in, std::ostream& out); + /** + * @brief Merge HTTP response content with Transfer-Encoding: chunked + * @param in Input stream + * @param out Output stream + * @return true on success, false otherwise + */ + bool MergeChunkedResponse (std::istream& in, std::ostream& out); } // http } // i2p diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index df4895a4..af4d2913 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2019, 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 @@ -5,6 +13,7 @@ #include #include #include +#include #include #include "I2PService.h" @@ -211,16 +220,28 @@ namespace proxy { void HTTPReqHandler::SanitizeHTTPRequest(i2p::http::HTTPReq & req) { /* drop common headers */ - req.RemoveHeader("Referrer"); req.RemoveHeader("Via"); req.RemoveHeader("From"); req.RemoveHeader("Forwarded"); req.RemoveHeader("Accept", "Accept-Encoding"); // Accept*, but Accept-Encoding /* drop proxy-disclosing headers */ req.RemoveHeader("X-Forwarded"); - req.RemoveHeader("Proxy-"); // Proxy-* + req.RemoveHeader("Proxy-"); // Proxy-* /* replace headers */ req.UpdateHeader("User-Agent", "MYOB/6.66 (AN/ON)"); + + /** + * according to i2p ticket #1862: + * leave Referrer if requested URL with same schema, host and port, + * otherwise, drop it. + */ + if(req.GetHeader("Referrer") != "") { + i2p::http::URL reqURL; reqURL.parse(req.uri); + i2p::http::URL refURL; refURL.parse(req.GetHeader("Referrer")); + if(!boost::iequals(reqURL.schema, refURL.schema) || !boost::iequals(reqURL.host, refURL.host) || reqURL.port != refURL.port) + req.RemoveHeader("Referrer"); + } + /* add headers */ /* close connection, if not Connection: (U|u)pgrade (for websocket) */ auto h = req.GetHeader ("Connection"); From 60ec03237e61d0cec24feacb68abacdf872cbb27 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 May 2019 15:49:07 -0400 Subject: [PATCH 0009/2950] blidning for ECDSA --- libi2pd/Blinding.cpp | 64 +++++++++++++++++++++++++++++++++++++++++--- libi2pd/Blinding.h | 2 +- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 4469123e..f4d6040e 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -1,6 +1,8 @@ #include // for crc32 #include #include +#include +#include #include "Base.h" #include "Crypto.h" #include "Log.h" @@ -13,14 +15,70 @@ namespace i2p { namespace data { - BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType): - m_BlindedSigType (blindedKeyType) + const EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order (group, q, ctx); + // calculate alpha = seed mod q + BIGNUM * alpha = BN_CTX_get (ctx); + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_mod (alpha, alpha, q, ctx); // % q + // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha) + auto p = EC_POINT_new (group); + EC_POINT_mul (group, p, alpha, nullptr, nullptr, ctx); // B*alpha + EC_POINT_add (group, p, pub, p, ctx); // pub + B*alpha + BN_CTX_end (ctx); + BN_CTX_free (ctx); + return p; + } + + static void BlindPrivateKeyECDSA (const EC_GROUP * group, const BIGNUM * priv, const uint8_t * seed, BIGNUM * blindedPriv) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order (group, q, ctx); + // calculate alpha = seed mod q + BIGNUM * alpha = BN_CTX_get (ctx); + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_mod (alpha, alpha, q, ctx); // % q + BN_add (alpha, alpha, priv); // alpha = alpha + priv + // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod q + BN_mod (blindedPriv, alpha, q, ctx); // % q + BN_CTX_end (ctx); + BN_CTX_free (ctx); + } + + void BlindPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) + { + BIGNUM * a = BN_bin2bn (priv, publicKeyLen/2, NULL); + BIGNUM * a1 = BN_new (); + BlindPrivateKeyECDSA (group, a, seed, a1); + BN_free (a); + i2p::crypto::bn2buf (a1, blindedPriv, publicKeyLen/2); + auto p = EC_POINT_new (group); + BN_CTX * ctx = BN_CTX_new (); + EC_POINT_mul (group, p, a1, nullptr, nullptr, ctx); // B*a1 + BN_CTX_free (ctx); + BN_free (a1); + BIGNUM * x = BN_new(), * y = BN_new(); + EC_POINT_get_affine_coordinates_GFp (group, p, x, y, NULL); + EC_POINT_free (p); + i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); + i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); + BN_free (x); BN_free (y); + } + + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity) { if (!identity) return; auto len = identity->GetSigningPublicKeyLen (); m_PublicKey.resize (len); memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); m_SigType = identity->GetSigningKeyType (); + m_BlindedSigType = m_SigType; } BlindedPublicKey::BlindedPublicKey (const std::string& b33) @@ -129,7 +187,7 @@ namespace data { i2p::data::IdentHash hash; if (m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || - m_BlindedSigType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) + m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) { uint8_t blinded[32]; if (date) diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 6c3671c6..56e0d4cd 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -14,7 +14,7 @@ namespace data { public: - BlindedPublicKey (std::shared_ptr identity, SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + BlindedPublicKey (std::shared_ptr identity); BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p std::string ToB33 () const; From edf4f7695d690e06e19df19a3d6dfdc22dba98a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 May 2019 12:45:50 -0400 Subject: [PATCH 0010/2950] fix #1352. correct response for 'list' command --- libi2pd_client/BOB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 94d74726..e60dd5ca 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -593,7 +593,7 @@ namespace client LogPrint (eLogDebug, "BOB: list"); const auto& destinations = m_Owner.GetDestinations (); for (const auto& it: destinations) - SendData (it.first.c_str ()); + SendData (("DATA NICKNAME: " + it.first).c_str ()); SendReplyOK ("Listing done"); } From e40c139ff19fa0053058fe1aefc0c88afb98a480 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 May 2019 16:15:11 -0400 Subject: [PATCH 0011/2950] blind ECDSA private key --- libi2pd/Blinding.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- libi2pd/Blinding.h | 2 +- libi2pd/LeaseSet.cpp | 6 +++--- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index f4d6040e..334d5f2b 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -9,6 +9,7 @@ #include "Timestamp.h" #include "I2PEndian.h" #include "Ed25519.h" +#include "Signature.h" #include "Blinding.h" namespace i2p @@ -51,7 +52,7 @@ namespace data BN_CTX_free (ctx); } - void BlindPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) + static void BlindPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) { BIGNUM * a = BN_bin2bn (priv, publicKeyLen/2, NULL); BIGNUM * a1 = BN_new (); @@ -166,11 +167,47 @@ namespace data i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); } - void BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const + size_t BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const { uint8_t seed[64]; GenerateAlpha (date, seed); - i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub); + size_t publicKeyLength = 0; + switch (m_SigType) + { + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: + { + publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; + EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); + BlindPrivateKeyECDSA (publicKeyLength, group, priv, seed, blindedPriv, blindedPub); + EC_GROUP_free (group); + break; + } + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: + { + publicKeyLength = i2p::crypto::ECDSAP384_KEY_LENGTH; + EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp384r1); + BlindPrivateKeyECDSA (publicKeyLength, group, priv, seed, blindedPriv, blindedPub); + EC_GROUP_free (group); + break; + } + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: + { + publicKeyLength = i2p::crypto::ECDSAP521_KEY_LENGTH; + EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp521r1); + BlindPrivateKeyECDSA (publicKeyLength, group, priv, seed, blindedPriv, blindedPub); + EC_GROUP_free (group); + 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; + } + default: + LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); + } + return publicKeyLength; } void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 56e0d4cd..f0387063 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -25,7 +25,7 @@ namespace data void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes void GetBlindedKey (const char * date, uint8_t * blindedKey) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" - void BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" + size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null private: diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index ad09ab2a..5e2b859e 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -727,12 +727,12 @@ namespace data auto timestamp = i2p::util::GetSecondsSinceEpoch (); char date[9]; i2p::util::GetDateString (timestamp, date); - uint8_t blindedPriv[32], blindedPub[32]; - blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub); + 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 (blindedKeyType, blindedPriv)); auto offset = 1; htobe16buf (m_Buffer + offset, blindedKeyType); offset += 2; // Blinded Public Key Sig Type - memcpy (m_Buffer + offset, blindedPub, 32); offset += 32; // Blinded Public Key + memcpy (m_Buffer + offset, blindedPub, publicKeyLen); offset += publicKeyLen; // Blinded Public Key htobe32buf (m_Buffer + offset, timestamp); offset += 4; // published timestamp (seconds) auto nextMidnight = (timestamp/86400LL + 1)*86400LL; // 86400 = 24*3600 seconds auto expirationTime = ls->GetExpirationTime ()/1000LL; From f784cfad468df6091ec9d6e43296e4f6325b3d94 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 May 2019 06:56:41 -0400 Subject: [PATCH 0012/2950] correct RouterInfo buffer size --- libi2pd/RouterInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index ee46a5b0..d1ed3ff8 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -38,7 +38,7 @@ namespace data m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) { m_Addresses = boost::make_shared(); // create empty list - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; + m_Buffer = new uint8_t[len]; memcpy (m_Buffer, buf, len); m_BufferLen = len; ReadFromBuffer (true); @@ -101,7 +101,7 @@ namespace data } s.seekg(0, std::ios::beg); if (!m_Buffer) - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; + m_Buffer = new uint8_t[m_BufferLen]; s.read((char *)m_Buffer, m_BufferLen); } else From 7b9033d678604b7b128eb915eb45132a5557262d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 May 2019 09:32:07 -0400 Subject: [PATCH 0013/2950] allocate actual RouterInfo's buffer size --- libi2pd/NetDb.cpp | 8 +++---- libi2pd/RouterInfo.cpp | 47 ++++++++++++++++++++++++++++++------------ libi2pd/RouterInfo.h | 4 ++-- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 02ae2ae8..328f8550 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -698,14 +698,14 @@ namespace data LogPrint (eLogDebug, "NetDb: store request: RouterInfo"); size_t size = bufbe16toh (buf + offset); offset += 2; - if (size > 2048 || size > len - offset) + if (size > MAX_RI_BUFFER_SIZE || size > len - offset) { LogPrint (eLogError, "NetDb: invalid RouterInfo length ", (int)size); return; } - uint8_t uncompressed[2048]; - size_t uncompressedSize = m_Inflator.Inflate (buf + offset, size, uncompressed, 2048); - if (uncompressedSize && uncompressedSize < 2048) + uint8_t uncompressed[MAX_RI_BUFFER_SIZE]; + size_t uncompressedSize = m_Inflator.Inflate (buf + offset, size, uncompressed, MAX_RI_BUFFER_SIZE); + if (uncompressedSize && uncompressedSize < MAX_RI_BUFFER_SIZE) updated = AddRouterInfo (ident, uncompressed, uncompressedSize); else { diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index d1ed3ff8..9366cabf 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -26,7 +26,7 @@ namespace data } RouterInfo::RouterInfo (const std::string& fullPath): - m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), + m_FullPath (fullPath), m_Buffer (nullptr), m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) { m_Addresses = boost::make_shared(); // create empty list @@ -38,10 +38,19 @@ namespace data m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) { m_Addresses = boost::make_shared(); // create empty list - m_Buffer = new uint8_t[len]; - memcpy (m_Buffer, buf, len); - m_BufferLen = len; - ReadFromBuffer (true); + if (len <= MAX_RI_BUFFER_SIZE) + { + m_Buffer = new uint8_t[len]; + memcpy (m_Buffer, buf, len); + m_BufferLen = len; + ReadFromBuffer (true); + } + else + { + LogPrint (eLogError, "RouterInfo: Buffer is too long ", len, ". Ignored"); + m_Buffer = nullptr; + m_IsUnreachable = true; + } } RouterInfo::~RouterInfo () @@ -49,7 +58,7 @@ namespace data delete[] m_Buffer; } - void RouterInfo::Update (const uint8_t * buf, int len) + void RouterInfo::Update (const uint8_t * buf, size_t len) { // verify signature since we have identity already int l = len - m_RouterIdentity->GetSignatureLen (); @@ -62,9 +71,15 @@ namespace data m_Caps = 0; // don't clean up m_Addresses, it will be replaced in ReadFromStream m_Properties.clear (); + // check if existing buffer long enough + if (m_Buffer && len > m_BufferLen) + { + delete[] m_Buffer; + m_Buffer = nullptr; + } // copy buffer if (!m_Buffer) - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; + m_Buffer = new uint8_t[len]; memcpy (m_Buffer, buf, len); m_BufferLen = len; // skip identity @@ -100,8 +115,8 @@ namespace data return false; } s.seekg(0, std::ios::beg); - if (!m_Buffer) - m_Buffer = new uint8_t[m_BufferLen]; + if (m_Buffer) delete[] m_Buffer; + m_Buffer = new uint8_t[m_BufferLen]; s.read((char *)m_Buffer, m_BufferLen); } else @@ -607,15 +622,21 @@ namespace data std::stringstream s; uint8_t ident[1024]; auto identLen = privateKeys.GetPublic ()->ToBuffer (ident, 1024); + auto signatureLen = privateKeys.GetPublic ()->GetSignatureLen (); s.write ((char *)ident, identLen); WriteToStream (s); m_BufferLen = s.str ().size (); if (!m_Buffer) m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; - memcpy (m_Buffer, s.str ().c_str (), m_BufferLen); - // signature - privateKeys.Sign ((uint8_t *)m_Buffer, m_BufferLen, (uint8_t *)m_Buffer + m_BufferLen); - m_BufferLen += privateKeys.GetPublic ()->GetSignatureLen (); + if (m_BufferLen + signatureLen < MAX_RI_BUFFER_SIZE) + { + memcpy (m_Buffer, s.str ().c_str (), m_BufferLen); + // signature + privateKeys.Sign ((uint8_t *)m_Buffer, m_BufferLen, (uint8_t *)m_Buffer + m_BufferLen); + m_BufferLen += signatureLen; + } + else + LogPrint (eLogError, "RouterInfo: Our RouterInfo is too long ", m_BufferLen + signatureLen); } bool RouterInfo::SaveToFile (const std::string& fullPath) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 084ad8a7..64aaed37 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -38,7 +38,7 @@ namespace data const char CAPS_FLAG_SSU_TESTING = 'B'; const char CAPS_FLAG_SSU_INTRODUCER = 'C'; - const int MAX_RI_BUFFER_SIZE = 2048; + const int MAX_RI_BUFFER_SIZE = 2048; // if RouterInfo exceeds 2048 we consider it as malformed, might be changed later class RouterInfo: public RoutingDestination { public: @@ -196,7 +196,7 @@ namespace data std::shared_ptr GetProfile () const; void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); }; - void Update (const uint8_t * buf, int len); + void Update (const uint8_t * buf, size_t len); void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; bool IsNewer (const uint8_t * buf, size_t len) const; From 78bfde237f51647235260a87cfa8baa5af905fc2 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 May 2019 09:34:04 -0400 Subject: [PATCH 0014/2950] allocate actual RouterInfo's buffer size --- libi2pd/RouterInfo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9366cabf..45f4cb7b 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -30,7 +30,6 @@ namespace data m_SupportedTransports (0), m_Caps (0) { m_Addresses = boost::make_shared(); // create empty list - m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; ReadFromFile (); } From af33df30043e1a738250b9767ac325a93562f619 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 May 2019 11:49:54 -0400 Subject: [PATCH 0015/2950] common buffer size --- libi2pd/RouterInfo.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 45f4cb7b..4760ffa9 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -26,10 +26,11 @@ namespace data } RouterInfo::RouterInfo (const std::string& fullPath): - m_FullPath (fullPath), m_Buffer (nullptr), m_IsUpdated (false), m_IsUnreachable (false), + m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) { m_Addresses = boost::make_shared(); // create empty list + m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; ReadFromFile (); } @@ -39,7 +40,7 @@ namespace data m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) { - m_Buffer = new uint8_t[len]; + m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; memcpy (m_Buffer, buf, len); m_BufferLen = len; ReadFromBuffer (true); @@ -59,6 +60,12 @@ namespace data void RouterInfo::Update (const uint8_t * buf, size_t len) { + if (len > MAX_RI_BUFFER_SIZE) + { + LogPrint (eLogError, "RouterInfo: Buffer is too long ", len); + m_IsUnreachable = true; + return; + } // verify signature since we have identity already int l = len - m_RouterIdentity->GetSignatureLen (); if (m_RouterIdentity->Verify (buf, l, buf + l)) @@ -70,15 +77,9 @@ namespace data m_Caps = 0; // don't clean up m_Addresses, it will be replaced in ReadFromStream m_Properties.clear (); - // check if existing buffer long enough - if (m_Buffer && len > m_BufferLen) - { - delete[] m_Buffer; - m_Buffer = nullptr; - } // copy buffer if (!m_Buffer) - m_Buffer = new uint8_t[len]; + m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; memcpy (m_Buffer, buf, len); m_BufferLen = len; // skip identity @@ -114,8 +115,6 @@ namespace data return false; } s.seekg(0, std::ios::beg); - if (m_Buffer) delete[] m_Buffer; - m_Buffer = new uint8_t[m_BufferLen]; s.read((char *)m_Buffer, m_BufferLen); } else From 354c9187db403e38a4c78cf224d387009b770c10 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 May 2019 15:59:44 -0400 Subject: [PATCH 0016/2950] detect our ipv6 address --- libi2pd/NetDb.cpp | 9 +++++++++ libi2pd/NetDb.hpp | 1 + libi2pd/RouterInfo.cpp | 5 +++++ libi2pd/RouterInfo.h | 1 + libi2pd/Transports.cpp | 14 ++++++++++++++ 5 files changed, 30 insertions(+) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 328f8550..952c8017 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1076,6 +1076,15 @@ namespace data }); } + std::shared_ptr NetDb::GetRandomSSUV6Router () const + { + return GetRandomRouter ( + [](std::shared_ptr router)->bool + { + return !router->IsHidden () && router->IsSSUV6 (); + }); + } + std::shared_ptr NetDb::GetRandomIntroducer () const { return GetRandomRouter ( diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 93e9e48f..d9e10504 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -72,6 +72,7 @@ namespace data std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith) const; std::shared_ptr GetRandomPeerTestRouter (bool v4only = true) 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; std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 4760ffa9..39aa70e1 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -808,6 +808,11 @@ namespace data return m_SupportedTransports & (eSSUV4 | eSSUV6); } + bool RouterInfo::IsSSUV6 () const + { + return m_SupportedTransports & eSSUV6; + } + bool RouterInfo::IsNTCP2 (bool v4only) const { if (v4only) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 64aaed37..b23625e0 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -161,6 +161,7 @@ namespace data bool IsReachable () const { return m_Caps & Caps::eReachable; }; bool IsNTCP (bool v4only = true) const; bool IsSSU (bool v4only = true) const; + bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; bool IsV6 () const; bool IsV4 () const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c00e5d52..b76d9312 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -552,6 +552,20 @@ namespace transport 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->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); + } + } + } } else LogPrint (eLogError, "Transports: Can't detect external IP. SSU is not available"); From 07405e57b97865e2b68f6411b27ffb67e7079149 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 25 May 2019 14:58:10 -0400 Subject: [PATCH 0017/2950] fixed typo --- libi2pd/RouterInfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 39aa70e1..b58678a8 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -115,6 +115,7 @@ namespace data return false; } s.seekg(0, std::ios::beg); + if (!m_Buffer) m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; s.read((char *)m_Buffer, m_BufferLen); } else From 8e3d16e9fbb46cde463dbe558dbdb1d5d18216a1 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 May 2019 11:36:58 -0400 Subject: [PATCH 0018/2950] update ipv6 addresses from SSU rather than NTCP or NTCP2 --- libi2pd/NTCP2.cpp | 2 - libi2pd/NTCPSession.cpp | 2 - libi2pd/RouterContext.cpp | 143 ++++++++++++++++++++------------------ libi2pd/RouterContext.h | 3 +- libi2pd/RouterInfo.cpp | 2 +- 5 files changed, 76 insertions(+), 76 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 0976720e..5b5073f9 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1304,8 +1304,6 @@ namespace transport else { LogPrint (eLogDebug, "NTCP2: Connected to ", conn->GetSocket ().remote_endpoint ()); - if (conn->GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6 - context.UpdateNTCP2V6Address (conn->GetSocket ().local_endpoint ().address ()); conn->ClientLogin (); } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 68a4133f..7e8ecd15 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -1079,8 +1079,6 @@ namespace transport else { LogPrint (eLogDebug, "NTCP: Connected to ", conn->GetSocket ().remote_endpoint ()); - if (conn->GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6 - context.UpdateNTCPV6Address (conn->GetSocket ().local_endpoint ().address ()); conn->ClientLogin (); } } diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 8293f1fd..213adf72 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -238,6 +238,20 @@ namespace i2p if (address->host != host && address->IsCompatible (host)) { address->host = host; + if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU) + { + // update MTU + auto mtu = i2p::util::net::GetMTU (host); + if (mtu) + { + LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); + if (mtu > 1472) { // TODO: magic constant + mtu = 1472; + LogPrint(eLogWarning, "Router: MTU dropped to upper limit of 1472 bytes"); + } + if (address->ssu) address->ssu->mtu = mtu; + } + } updated = true; } } @@ -444,7 +458,66 @@ namespace i2p void RouterContext::SetSupportsV6 (bool supportsV6) { if (supportsV6) + { m_RouterInfo.EnableV6 (); + // insert v6 addresses if necessary + bool foundSSU = false, foundNTCP = false, foundNTCP2 = false; + uint16_t port = 0; + auto& addresses = m_RouterInfo.GetAddresses (); + for (auto& addr: addresses) + { + if (addr->host.is_v6 ()) + { + if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) + foundSSU = true; + else if (addr->IsNTCP2 ()) + { + if (addr->IsPublishedNTCP2 ()) foundNTCP2 = true; + } + else + foundNTCP = true; + } + port = addr->port; + } + if (!port) i2p::config::GetOption("port", port); + // SSU + if (!foundSSU) + { + bool ssu; i2p::config::GetOption("ssu", ssu); + if (ssu) + { + std::string host = "::1"; // TODO: read host + m_RouterInfo.AddSSUAddress (host.c_str (), port, GetIdentHash ()); + } + } + // NTCP2 + if (!foundNTCP2) + { + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); + if (ntcp2 && 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); + } + } + // NTCP + if (!foundNTCP) + { + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + if (ntcp) + { + std::string host = "::1"; + m_RouterInfo.AddNTCPAddress (host.c_str (), port); + } + } + } else m_RouterInfo.DisableV6 (); UpdateRouterInfo (); @@ -459,50 +532,9 @@ namespace i2p UpdateRouterInfo (); } - - void RouterContext::UpdateNTCPV6Address (const boost::asio::ip::address& host) - { - bool updated = false, found = false; - int port = 0; - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) - { - if (addr->host.is_v6 () && addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP) - { - if (addr->host != host) - { - addr->host = host; - updated = true; - } - found = true; - } - else - port = addr->port; - } - if (!found) - { - // create new address - m_RouterInfo.AddNTCPAddress (host.to_string ().c_str (), port); - auto mtu = i2p::util::net::GetMTU (host); - if (mtu) - { - LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); - if (mtu > 1472) { // TODO: magic constant - mtu = 1472; - LogPrint(eLogWarning, "Router: MTU dropped to upper limit of 1472 bytes"); - } - } - m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), mtu ? mtu : 1472); // TODO - updated = true; - } - if (updated) - UpdateRouterInfo (); - } - void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) { - bool updated = false, found = false; - int port = 0; + bool updated = false; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) { @@ -515,38 +547,11 @@ namespace i2p addr->host = host; updated = true; } - found = true; break; } - else - port = addr->port; // NTCP2 v4 } } - if (!found && port) // we have found NTCP2 v4 but not v6 - { - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - bool ssu; i2p::config::GetOption("ssu", ssu); - if (!ntcp && ssu) - { - // we must publish SSU address - auto mtu = i2p::util::net::GetMTU (host); - if (mtu) - { - LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); - if (mtu > 1472) // TODO: magic constant - { - mtu = 1472; - LogPrint(eLogWarning, "Router: MTU dropped to upper limit of 1472 bytes"); - } - } - else - mtu = 1472; - m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), mtu); - } - updated = true; - } if (updated) UpdateRouterInfo (); } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 19fe08b2..ed9c41b0 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -101,8 +101,7 @@ namespace i2p void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); - void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session - void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from NTCP2 session + 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 diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index b58678a8..37c2af7e 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -824,7 +824,7 @@ namespace data bool RouterInfo::IsV6 () const { - return m_SupportedTransports & (eNTCPV6 | eSSUV6); + return m_SupportedTransports & (eNTCPV6 | eSSUV6 | eNTCP2V6); } bool RouterInfo::IsV4 () const From 93d4dc70cfb75aab7040e959f6eeb34b334c57fd Mon Sep 17 00:00:00 2001 From: rszibele Date: Wed, 29 May 2019 18:05:03 +0200 Subject: [PATCH 0019/2950] BOB fixes. --- libi2pd_client/BOB.cpp | 327 +++++++++++++++++++++++++++-------------- libi2pd_client/BOB.h | 66 +++++++-- 2 files changed, 271 insertions(+), 122 deletions(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index e60dd5ca..62ab41f6 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -50,7 +50,7 @@ namespace client void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr receiver) { receiver->socket->async_read_some (boost::asio::buffer( - receiver->buffer + receiver->bufferOffset, + receiver->buffer + receiver->bufferOffset, BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset), std::bind(&BOBI2PInboundTunnel::HandleReceivedAddress, this, std::placeholders::_1, std::placeholders::_2, receiver)); @@ -119,9 +119,9 @@ namespace client connection->I2PConnect (receiver->data, receiver->dataLen); } - BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& address, int port, + BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet): BOBI2PTunnel (localDestination), - m_Endpoint (boost::asio::ip::address::from_string (address), port), m_IsQuiet (quiet) + m_Endpoint (boost::asio::ip::address::from_string (outhost), port), m_IsQuiet (quiet) { } @@ -154,9 +154,13 @@ namespace client } } - BOBDestination::BOBDestination (std::shared_ptr localDestination): + BOBDestination::BOBDestination (std::shared_ptr localDestination, + const std::string &nickname, const std::string &inhost, const std::string &outhost, + const int inport, const int outport, const bool quiet): m_LocalDestination (localDestination), - m_OutboundTunnel (nullptr), m_InboundTunnel (nullptr) + m_OutboundTunnel (nullptr), m_InboundTunnel (nullptr), + m_Nickname(nickname), m_InHost(inhost), m_OutHost(outhost), + m_InPort(inport), m_OutPort(outport), m_Quiet(quiet) { } @@ -195,15 +199,18 @@ namespace client } } - void BOBDestination::CreateInboundTunnel (int port, const std::string& address) + void BOBDestination::CreateInboundTunnel (int port, const std::string& inhost) { if (!m_InboundTunnel) { + // update inport and inhost (user can stop tunnel and change) + m_InPort = port; + m_InHost = inhost; boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), port); - if (!address.empty ()) + if (!inhost.empty ()) { boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string (address, ec); + auto addr = boost::asio::ip::address::from_string (inhost, ec); if (!ec) ep.address (addr); else @@ -213,15 +220,21 @@ namespace client } } - void BOBDestination::CreateOutboundTunnel (const std::string& address, int port, bool quiet) + void BOBDestination::CreateOutboundTunnel (const std::string& outhost, int port, bool quiet) { if (!m_OutboundTunnel) - m_OutboundTunnel = new BOBI2POutboundTunnel (address, port, m_LocalDestination, quiet); + { + // update outport and outhost (user can stop tunnel and change) + m_OutPort = port; + m_OutHost = outhost; + m_OutboundTunnel = new BOBI2POutboundTunnel (outhost, port, m_LocalDestination, quiet); + } } BOBCommandSession::BOBCommandSession (BOBCommandChannel& owner): m_Owner (owner), m_Socket (m_Owner.GetService ()), - m_ReceiveBufferOffset (0), m_IsOpen (true), m_IsQuiet (false), m_IsActive (false), + m_ReceiveBuffer(BOB_COMMAND_BUFFER_SIZE + 1), m_SendBuffer(BOB_COMMAND_BUFFER_SIZE + 1), + m_IsOpen (true), m_IsQuiet (false), m_IsActive (false), m_InPort (0), m_OutPort (0), m_CurrentDestination (nullptr) { } @@ -238,65 +251,48 @@ namespace client void BOBCommandSession::Receive () { - m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, BOB_COMMAND_BUFFER_SIZE - m_ReceiveBufferOffset), - std::bind(&BOBCommandSession::HandleReceived, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); + boost::asio::async_read_until(m_Socket, m_ReceiveBuffer, '\n', + std::bind(&BOBCommandSession::HandleReceivedLine, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } - - void BOBCommandSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) + + void BOBCommandSession::HandleReceivedLine(const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (ecode) + if(ecode) { - LogPrint (eLogError, "BOB: command channel read error: ", ecode.message ()); + LogPrint (eLogError, "BOB: command channel read error: ", ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate (); } else { - size_t size = m_ReceiveBufferOffset + bytes_transferred; - m_ReceiveBuffer[size] = 0; - char * eol = strchr (m_ReceiveBuffer, '\n'); - if (eol) + std::string line; + + std::istream is(&m_ReceiveBuffer); + std::getline(is, line); + + std::string command, operand; + std::istringstream iss(line); + iss >> command >> operand; + + // process command + auto& handlers = m_Owner.GetCommandHandlers(); + auto it = handlers.find(command); + if(it != handlers.end()) { - *eol = 0; - char * operand = strchr (m_ReceiveBuffer, ' '); - if (operand) - { - *operand = 0; - operand++; - } - else - operand = eol; - // process command - auto& handlers = m_Owner.GetCommandHandlers (); - auto it = handlers.find (m_ReceiveBuffer); - if (it != handlers.end ()) - (this->*(it->second))(operand, eol - operand); - else - { - LogPrint (eLogError, "BOB: unknown command ", m_ReceiveBuffer); - SendReplyError ("unknown command"); - } - - m_ReceiveBufferOffset = size - (eol - m_ReceiveBuffer) - 1; - memmove (m_ReceiveBuffer, eol + 1, m_ReceiveBufferOffset); + (this->*(it->second))(operand.c_str(), operand.length()); } else { - if (size < BOB_COMMAND_BUFFER_SIZE) - m_ReceiveBufferOffset = size; - else - { - LogPrint (eLogError, "BOB: Malformed input of the command channel"); - Terminate (); - } + LogPrint (eLogError, "BOB: unknown command ", command.c_str()); + SendReplyError ("unknown command"); } } } - void BOBCommandSession::Send (size_t len) + void BOBCommandSession::Send () { - boost::asio::async_write (m_Socket, boost::asio::buffer (m_SendBuffer, len), + boost::asio::async_write (m_Socket, m_SendBuffer, boost::asio::transfer_all (), std::bind(&BOBCommandSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -305,7 +301,7 @@ namespace client void BOBCommandSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) - { + { LogPrint (eLogError, "BOB: command channel send error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) Terminate (); @@ -321,39 +317,65 @@ namespace client void BOBCommandSession::SendReplyOK (const char * msg) { -#ifdef _MSC_VER - size_t len = sprintf_s (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_OK, msg); -#else - size_t len = snprintf (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_OK, msg); -#endif - Send (len); + std::ostream os(&m_SendBuffer); + os << "OK"; + if(msg) + { + os << " " << msg; + } + os << std::endl; + Send (); } void BOBCommandSession::SendReplyError (const char * msg) { -#ifdef _MSC_VER - size_t len = sprintf_s (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_ERROR, msg); -#else - size_t len = snprintf (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_REPLY_ERROR, msg); -#endif - Send (len); + std::ostream os(&m_SendBuffer); + os << "ERROR " << msg << std::endl; + Send (); } void BOBCommandSession::SendVersion () { - size_t len = strlen (BOB_VERSION); - memcpy (m_SendBuffer, BOB_VERSION, len); - Send (len); + std::ostream os(&m_SendBuffer); + os << "BOB 00.00.10" << std::endl; + SendReplyOK(); } - void BOBCommandSession::SendData (const char * nickname) + void BOBCommandSession::SendData (const char * data) { -#ifdef _MSC_VER - size_t len = sprintf_s (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_DATA, nickname); -#else - size_t len = snprintf (m_SendBuffer, BOB_COMMAND_BUFFER_SIZE, BOB_DATA, nickname); -#endif - Send (len); + std::ostream os(&m_SendBuffer); + os << "DATA " << data << std::endl; + } + + void BOBCommandSession::BuildStatusLine(bool currentTunnel, BOBDestination *dest, std::string &out) + { + // helper lambdas + const auto isset = [](const std::string &str) { return str.empty() ? "not_set" : str; }; // for inhost, outhost + const auto issetNum = [&isset](const int p) { return isset(p == 0 ? "" : std::to_string(p)); }; // for inport, outport + const auto destExists = [](const BOBDestination * const dest) { return dest != nullptr; }; + const auto destReady = [](const BOBDestination * const dest) { return dest->GetLocalDestination()->IsReady(); }; + const auto bool_str = [](const bool v) { return v ? "true" : "false"; }; // bool -> str + + // tunnel info + const std::string nickname = currentTunnel ? m_Nickname : dest->GetNickname(); + const bool quiet = currentTunnel ? m_IsQuiet : dest->GetQuiet(); + const std::string inhost = isset(currentTunnel ? m_InHost : dest->GetInHost()); + const std::string outhost = isset(currentTunnel ? m_OutHost : dest->GetOutHost()); + const std::string inport = issetNum(currentTunnel ? m_InPort : dest->GetInPort()); + const std::string outport = issetNum(currentTunnel ? m_OutPort : dest->GetOutPort()); + const bool keys = destExists(dest); // key must exist when destination is created + const bool starting = destExists(dest) && !destReady(dest); + const bool running = destExists(dest) && destReady(dest); + const bool stopping = false; + + // build line + std::stringstream ss; + ss << "NICKNAME: " << nickname << " " << "STARTING: " << bool_str(starting) << " " + << "RUNNING: " << bool_str(running) << " " << "STOPPING: " << bool_str(stopping) << " " + << "KEYS: " << bool_str(keys) << " " << "QUIET: " << bool_str(quiet) << " " + << "INPORT: " << inport << " " << "INHOST: " << inhost << " " + << "OUTPORT: " << outport << " " << "OUTHOST: " << outhost; + out = ss.str(); } void BOBCommandSession::ZapCommandHandler (const char * operand, size_t len) @@ -377,15 +399,50 @@ namespace client SendReplyError ("tunnel is active"); return; } + if (!m_Keys.GetPublic ()) // keys are set ? + { + SendReplyError("Keys must be set."); + return; + } + if (m_InPort == 0 + && m_OutHost.empty() && m_OutPort == 0) + { + SendReplyError("(inhost):inport or outhost:outport must be set."); + return; + } + if(!m_InHost.empty()) + { + // TODO: FIXME: temporary validation, until hostname support is added + boost::system::error_code ec; + boost::asio::ip::address::from_string(m_InHost, ec); + if (ec) + { + SendReplyError("inhost must be a valid IPv4 address."); + return; + } + } + if(!m_OutHost.empty()) + { + // TODO: FIXME: temporary validation, until hostname support is added + boost::system::error_code ec; + boost::asio::ip::address::from_string(m_OutHost, ec); + if (ec) + { + SendReplyError("outhost must be a IPv4 address."); + return; + } + } + if (!m_CurrentDestination) { - m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options)); + m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command + m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet); m_Owner.AddDestination (m_Nickname, m_CurrentDestination); } if (m_InPort) - m_CurrentDestination->CreateInboundTunnel (m_InPort, m_Address); - if (m_OutPort && !m_Address.empty ()) - m_CurrentDestination->CreateOutboundTunnel (m_Address, m_OutPort, m_IsQuiet); + m_CurrentDestination->CreateInboundTunnel (m_InPort, m_InHost); + if (m_OutPort && !m_OutHost.empty ()) + m_CurrentDestination->CreateOutboundTunnel (m_OutHost, m_OutPort, m_IsQuiet); m_CurrentDestination->Start (); SendReplyOK ("Tunnel starting"); m_IsActive = true; @@ -496,7 +553,7 @@ namespace client void BOBCommandSession::OuthostCommandHandler (const char * operand, size_t len) { LogPrint (eLogDebug, "BOB: outhost ", operand); - m_Address = operand; + m_OutHost = operand; SendReplyOK ("outhost set"); } @@ -513,7 +570,7 @@ namespace client void BOBCommandSession::InhostCommandHandler (const char * operand, size_t len) { LogPrint (eLogDebug, "BOB: inhost ", operand); - m_Address = operand; + m_InHost = operand; SendReplyOK ("inhost set"); } @@ -591,9 +648,23 @@ namespace client void BOBCommandSession::ListCommandHandler (const char * operand, size_t len) { LogPrint (eLogDebug, "BOB: list"); + std::string statusLine; + bool sentCurrent = false; const auto& destinations = m_Owner.GetDestinations (); for (const auto& it: destinations) - SendData (("DATA NICKNAME: " + it.first).c_str ()); + { + BuildStatusLine(false, it.second, statusLine); + SendData (statusLine.c_str()); + if(m_Nickname.compare(it.second->GetNickname()) == 0) + sentCurrent = true; + } + if(!sentCurrent && !m_Nickname.empty()) + { + // add the current tunnel to the list + BuildStatusLine(true, nullptr, statusLine); + LogPrint(eLogError, statusLine); + SendData(statusLine.c_str()); + } SendReplyOK ("Listing done"); } @@ -619,34 +690,53 @@ namespace client void BOBCommandSession::StatusCommandHandler (const char * operand, size_t len) { LogPrint (eLogDebug, "BOB: status ", operand); + std::string statusLine; if (m_Nickname == operand) { - std::stringstream s; - s << "DATA"; s << " NICKNAME: "; s << m_Nickname; - if (m_CurrentDestination) - { - if (m_CurrentDestination->GetLocalDestination ()->IsReady ()) - s << " STARTING: false RUNNING: true STOPPING: false"; - else - s << " STARTING: true RUNNING: false STOPPING: false"; - } - else - s << " STARTING: false RUNNING: false STOPPING: false"; - s << " KEYS: true"; s << " QUIET: "; s << (m_IsQuiet ? "true":"false"); - if (m_InPort) - { - s << " INPORT: " << m_InPort; - s << " INHOST: " << (m_Address.length () > 0 ? m_Address : "127.0.0.1"); - } - if (m_OutPort) - { - s << " OUTPORT: " << m_OutPort; - s << " OUTHOST: " << (m_Address.length () > 0 ? m_Address : "127.0.0.1"); - } - SendReplyOK (s.str().c_str()); + // check current tunnel + BuildStatusLine(true, nullptr, statusLine); + SendReplyOK(statusLine.c_str()); } else - SendReplyError ("no nickname has been set"); + { + // check other + std::string name = operand; + auto ptr = m_Owner.FindDestination(name); + if(ptr != nullptr) + { + BuildStatusLine(false, ptr, statusLine); + SendReplyOK(statusLine.c_str()); + } + else + { + SendReplyError("no nickname has been set"); + } + } + } + void BOBCommandSession::HelpCommandHandler (const char * operand, size_t len) + { + auto helpStrings = m_Owner.GetHelpStrings(); + if(len == 0) + { + std::stringstream ss; + ss << "COMMANDS:"; + for (auto const& x : helpStrings) + { + ss << " " << x.first; + } + const std::string &str = ss.str(); + SendReplyOK(str.c_str()); + } + else + { + auto it = helpStrings.find(operand); + if (it != helpStrings.end ()) + { + SendReplyOK(it->second.c_str()); + return; + } + SendReplyError("No such command"); + } } BOBCommandChannel::BOBCommandChannel (const std::string& address, int port): @@ -674,6 +764,29 @@ namespace client m_CommandHandlers[BOB_COMMAND_LIST] = &BOBCommandSession::ListCommandHandler; m_CommandHandlers[BOB_COMMAND_OPTION] = &BOBCommandSession::OptionCommandHandler; m_CommandHandlers[BOB_COMMAND_STATUS] = &BOBCommandSession::StatusCommandHandler; + m_CommandHandlers[BOB_COMMAND_HELP] = &BOBCommandSession::HelpCommandHandler; + // command -> help string + m_HelpStrings[BOB_COMMAND_ZAP] = BOB_HELP_ZAP; + m_HelpStrings[BOB_COMMAND_QUIT] = BOB_HELP_QUIT; + m_HelpStrings[BOB_COMMAND_START] = BOB_HELP_START; + m_HelpStrings[BOB_COMMAND_STOP] = BOB_HELP_STOP; + m_HelpStrings[BOB_COMMAND_SETNICK] = BOB_HELP_SETNICK; + m_HelpStrings[BOB_COMMAND_GETNICK] = BOB_HELP_GETNICK; + m_HelpStrings[BOB_COMMAND_NEWKEYS] = BOB_HELP_NEWKEYS; + m_HelpStrings[BOB_COMMAND_GETKEYS] = BOB_HELP_GETKEYS; + m_HelpStrings[BOB_COMMAND_SETKEYS] = BOB_HELP_SETKEYS; + m_HelpStrings[BOB_COMMAND_GETDEST] = BOB_HELP_GETDEST; + m_HelpStrings[BOB_COMMAND_OUTHOST] = BOB_HELP_OUTHOST; + m_HelpStrings[BOB_COMMAND_OUTPORT] = BOB_HELP_OUTPORT; + m_HelpStrings[BOB_COMMAND_INHOST] = BOB_HELP_INHOST; + m_HelpStrings[BOB_COMMAND_INPORT] = BOB_HELP_INPORT; + m_HelpStrings[BOB_COMMAND_QUIET] = BOB_HELP_QUIET; + m_HelpStrings[BOB_COMMAND_LOOKUP] = BOB_HELP_LOOKUP; + m_HelpStrings[BOB_COMMAND_CLEAR] = BOB_HELP_CLEAR; + m_HelpStrings[BOB_COMMAND_LIST] = BOB_HELP_LIST; + m_HelpStrings[BOB_COMMAND_OPTION] = BOB_HELP_OPTION; + m_HelpStrings[BOB_COMMAND_STATUS] = BOB_HELP_STATUS; + m_HelpStrings[BOB_COMMAND_HELP] = BOB_HELP_HELP; } BOBCommandChannel::~BOBCommandChannel () diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index a2a24164..d531a13d 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -37,11 +37,29 @@ namespace client const char BOB_COMMAND_LIST[] = "list"; const char BOB_COMMAND_OPTION[] = "option"; const char BOB_COMMAND_STATUS[] = "status"; - - const char BOB_VERSION[] = "BOB 00.00.10\nOK\n"; - const char BOB_REPLY_OK[] = "OK %s\n"; - const char BOB_REPLY_ERROR[] = "ERROR %s\n"; - const char BOB_DATA[] = "NICKNAME %s\n"; + const char BOB_COMMAND_HELP[] = "help"; + + const char BOB_HELP_ZAP[] = "zap - Shuts down BOB."; + const char BOB_HELP_QUIT[] = "quit - Quits this session with BOB."; + const char BOB_HELP_START[] = "start - Starts the current nicknamed tunnel."; + const char BOB_HELP_STOP[] = "stop - Stops the current nicknamed tunnel."; + const char BOB_HELP_SETNICK[] = "setnick - Creates a new nickname."; + const char BOB_HELP_GETNICK[] = "getnick - Sets the nickname from the database."; + const char BOB_HELP_NEWKEYS[] = "newkeys - Generate a new keypair for the current nickname."; + const char BOB_HELP_GETKEYS[] = "getkeys - Return the keypair for the current nickname."; + const char BOB_HELP_SETKEYS[] = "setkeys - Sets the keypair for the current nickname."; + const char BOB_HELP_GETDEST[] = "getdest - Return the destination for the current nickname."; + const char BOB_HELP_OUTHOST[] = "outhost - Set the outhound hostname or IP."; + const char BOB_HELP_OUTPORT[] = "outport - Set the outbound port that nickname contacts."; + const char BOB_HELP_INHOST[] = "inhost - Set the inbound hostname or IP."; + const char BOB_HELP_INPORT[] = "inport - Set the inbound port number nickname listens on."; + const char BOB_HELP_QUIET[] = "quiet - Wether to send the incoming destination."; + const char BOB_HELP_LOOKUP[] = "lookup - Look up an I2P hostname."; + const char BOB_HELP_CLEAR[] = "clear - Clear the current nickname out of the list."; + const char BOB_HELP_LIST[] = "list - List all tunnels."; + const char BOB_HELP_OPTION[] = "option = - Set an option. NOTE: Don't use any spaces."; + const char BOB_HELP_STATUS[] = "status - Display status of a nicknamed tunnel."; + const char BOB_HELP_HELP [] = "help - Get help on a command."; class BOBI2PTunnel: public I2PService { @@ -96,7 +114,7 @@ namespace client { public: - BOBI2POutboundTunnel (const std::string& address, int port, std::shared_ptr localDestination, bool quiet); + BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet); void Start (); void Stop (); @@ -119,14 +137,22 @@ namespace client { public: - BOBDestination (std::shared_ptr localDestination); + BOBDestination (std::shared_ptr localDestination, + const std::string &nickname, const std::string &inhost, const std::string &outhost, + const int inport, const int outport, const bool quiet); ~BOBDestination (); void Start (); void Stop (); void StopTunnels (); - void CreateInboundTunnel (int port, const std::string& address); - void CreateOutboundTunnel (const std::string& address, int port, bool quiet); + void CreateInboundTunnel (int port, const std::string& inhost); + void CreateOutboundTunnel (const std::string& outhost, int port, bool quiet); + const std::string& GetNickname() const { return m_Nickname; } + const std::string& GetInHost() const { return m_InHost; } + const std::string& GetOutHost() const { return m_OutHost; } + int GetInPort() const { return m_InPort; } + int GetOutPort() const { return m_OutPort; } + bool GetQuiet() const { return m_Quiet; } const i2p::data::PrivateKeys& GetKeys () const { return m_LocalDestination->GetPrivateKeys (); }; std::shared_ptr GetLocalDestination () const { return m_LocalDestination; }; @@ -135,6 +161,11 @@ namespace client std::shared_ptr m_LocalDestination; BOBI2POutboundTunnel * m_OutboundTunnel; BOBI2PInboundTunnel * m_InboundTunnel; + + std::string m_Nickname; + std::string m_InHost, m_OutHost; + int m_InPort, m_OutPort; + bool m_Quiet; }; class BOBCommandChannel; @@ -170,26 +201,29 @@ namespace client void ListCommandHandler (const char * operand, size_t len); void OptionCommandHandler (const char * operand, size_t len); void StatusCommandHandler (const char * operand, size_t len); + void HelpCommandHandler (const char * operand, size_t len); private: void Receive (); + void HandleReceivedLine(const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void Send (size_t len); + void Send (); void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void SendReplyOK (const char * msg); + void SendReplyOK (const char * msg = nullptr); void SendReplyError (const char * msg); - void SendData (const char * nickname); + void SendData (const char * data); + + void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out); private: BOBCommandChannel& m_Owner; boost::asio::ip::tcp::socket m_Socket; - char m_ReceiveBuffer[BOB_COMMAND_BUFFER_SIZE + 1], m_SendBuffer[BOB_COMMAND_BUFFER_SIZE + 1]; - size_t m_ReceiveBufferOffset; + boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer; bool m_IsOpen, m_IsQuiet, m_IsActive; - std::string m_Nickname, m_Address; + std::string m_Nickname, m_InHost, m_OutHost; int m_InPort, m_OutPort; i2p::data::PrivateKeys m_Keys; std::map m_Options; @@ -226,10 +260,12 @@ namespace client boost::asio::ip::tcp::acceptor m_Acceptor; std::map m_Destinations; std::map m_CommandHandlers; + std::map m_HelpStrings; public: const decltype(m_CommandHandlers)& GetCommandHandlers () const { return m_CommandHandlers; }; + const decltype(m_HelpStrings)& GetHelpStrings () const { return m_HelpStrings; }; const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; }; }; } From a03e828317c54b5b665974e36ba2ddf29726b2af Mon Sep 17 00:00:00 2001 From: rszibele Date: Wed, 29 May 2019 18:47:35 +0200 Subject: [PATCH 0020/2950] BOB: status: forgot to pass destination for current tunnel. --- libi2pd_client/BOB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 62ab41f6..023be3b4 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -661,7 +661,7 @@ namespace client if(!sentCurrent && !m_Nickname.empty()) { // add the current tunnel to the list - BuildStatusLine(true, nullptr, statusLine); + BuildStatusLine(true, m_CurrentDestination, statusLine); LogPrint(eLogError, statusLine); SendData(statusLine.c_str()); } From e8cac91bb76a80076831b621f6d2a4f902bfab25 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 May 2019 15:48:35 -0400 Subject: [PATCH 0021/2950] blind ECDSA public key --- libi2pd/Blinding.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 334d5f2b..2a57efe0 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -16,7 +16,7 @@ namespace i2p { namespace data { - const EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) + static EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -52,6 +52,21 @@ namespace data BN_CTX_free (ctx); } + static void BlindPublicKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * pub, const uint8_t * seed, uint8_t * blindedPub) + { + BIGNUM * x = BN_bin2bn (pub, publicKeyLen/2, NULL); + BIGNUM * y = BN_bin2bn (pub + publicKeyLen/2, publicKeyLen/2, NULL); + EC_POINT * p = EC_POINT_new (group); + EC_POINT_set_affine_coordinates_GFp (group, p, x, y, NULL); + EC_POINT * p1 = BlindPublicKeyECDSA (group, p, seed); + EC_POINT_free (p); + EC_POINT_get_affine_coordinates_GFp (group, p1, x, y, NULL); + EC_POINT_free (p1); + i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); + i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); + BN_free (x); BN_free (y); + } + static void BlindPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) { BIGNUM * a = BN_bin2bn (priv, publicKeyLen/2, NULL); @@ -164,7 +179,36 @@ namespace data { uint8_t seed[64]; GenerateAlpha (date, seed); - i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); + switch (m_SigType) + { + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: + { + EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); + BlindPublicKeyECDSA (i2p::crypto::ECDSAP256_KEY_LENGTH, group, GetPublicKey (), seed, blindedKey); + EC_GROUP_free (group); + break; + } + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: + { + EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp384r1); + BlindPublicKeyECDSA (i2p::crypto::ECDSAP384_KEY_LENGTH, group, GetPublicKey (), seed, blindedKey); + EC_GROUP_free (group); + break; + } + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: + { + EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp521r1); + BlindPublicKeyECDSA (i2p::crypto::ECDSAP521_KEY_LENGTH, group, GetPublicKey (), seed, blindedKey); + EC_GROUP_free (group); + break; + } + case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: + case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: + i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); + break; + default: + LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); + } } size_t BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const From fbb8903774aea5df4f71a111e92c940376af963b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 May 2019 13:57:43 -0400 Subject: [PATCH 0022/2950] correct buffer size for ECDSA blinding --- libi2pd/LeaseSet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 5e2b859e..c109dee8 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -468,9 +468,9 @@ namespace data // verify blinding char date[9]; i2p::util::GetDateString (m_PublishedTimestamp, date); - uint8_t blinded[32]; - key->GetBlindedKey (date, blinded); - if (memcmp (blindedPublicKey, blinded, 32)) + std::vector blinded (blindedKeyLen); + key->GetBlindedKey (date, blinded.data ()); + if (memcmp (blindedPublicKey, blinded.data (), blindedKeyLen)) { LogPrint (eLogError, "LeaseSet2: blinded public key doesn't match"); return; From 4d10593bb1b5d678c0e55720aab72c481e8ebd37 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 May 2019 16:11:35 -0400 Subject: [PATCH 0023/2950] publish/unpublish NTCP2 address depending on network status --- libi2pd/RouterContext.cpp | 43 +++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 213adf72..47567a7b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -421,13 +421,25 @@ namespace i2p caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer m_RouterInfo.SetCaps (caps); - // remove NTCP v4 address - PublishNTCPAddress (false); + uint16_t port = 0; // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr : addresses) if (addr->ssu) + { addr->ssu->introducers.clear (); + port = addr->port; + } + // remove NTCP or NTCP2 v4 address + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + if (ntcp) + PublishNTCPAddress (false); + else + { + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) + PublishNTCP2Address (port, false); + } // update UpdateRouterInfo (); } @@ -442,15 +454,34 @@ namespace i2p if (m_IsFloodfill) caps |= i2p::data::RouterInfo::eFloodfill; m_RouterInfo.SetCaps (caps); - // insert NTCP back - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - PublishNTCPAddress (true); + uint16_t port = 0; // delete previous introducers auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr : addresses) if (addr->ssu) + { addr->ssu->introducers.clear (); + port = addr->port; + } + // insert NTCP or NTCP2 back + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + if (ntcp) + PublishNTCPAddress (true); + else + { + // ntcp2 + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) + { + bool published; i2p::config::GetOption ("ntcp2.published", published); + if (published) + { + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + PublishNTCP2Address (ntcp2Port, true); + } + } + } // update UpdateRouterInfo (); } From 61d84dd4c10469a557475ad08a953e37728abb12 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 May 2019 17:48:49 -0400 Subject: [PATCH 0024/2950] publish/unpublish NTCP2 address depending on network status --- libi2pd/RouterContext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ed9c41b0..e680eff8 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -79,7 +79,7 @@ namespace i2p 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); + void PublishNTCP2Address (int port, bool publish = true, bool v4only = false); void UpdateNTCP2Address (bool enable); void PublishNTCPAddress (bool publish, bool v4only = true); bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); From 685f45bd760c56b084bb0891b1d66d7607a5637a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 May 2019 17:52:44 -0400 Subject: [PATCH 0025/2950] publish/unpublish NTCP2 address depending on network status --- libi2pd/RouterContext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 47567a7b..d228b626 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -180,7 +180,7 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::PublishNTCP2Address (int port, bool publish) + void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4only) { if (!m_NTCP2Keys) return; if (!port) @@ -191,7 +191,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->ntcp2->isPublished != publish) && (!v4only || address->host.is_v4 ())) { address->port = port; address->cost = publish ? 3 : 14; @@ -438,7 +438,7 @@ namespace i2p { bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) - PublishNTCP2Address (port, false); + PublishNTCP2Address (port, false, true); } // update UpdateRouterInfo (); @@ -478,7 +478,7 @@ namespace i2p { uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); if (!ntcp2Port) ntcp2Port = port; - PublishNTCP2Address (ntcp2Port, true); + PublishNTCP2Address (ntcp2Port, true, true); } } } From 5e1054954343775ea768511621b40aedd0829cc4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 May 2019 19:18:56 -0400 Subject: [PATCH 0026/2950] disable NTCP by default --- libi2pd/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 52f40089..0f6460a0 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -58,7 +58,7 @@ 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", value()->default_value(true), "Enable NTCP transport (default: enabled)") + ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 @@ -237,7 +237,7 @@ namespace config { options_description ntcp2("NTCP2 Options"); ntcp2.add_options() ("ntcp2.enabled", value()->default_value(true), "Enable NTCP2 (default: enabled)") - ("ntcp2.published", value()->default_value(false), "Publish NTCP2 (default: disabled)") + ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ("ntcp2.addressv6", value()->default_value("::"), "Address to bind NTCP2 on") ; From 554e8eeef3cb58dbb302b8232b86415c7672d4fd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 31 May 2019 16:32:32 +0300 Subject: [PATCH 0027/2950] [appveyor] remove gcc-ada and gcc-objc packages https://github.com/msys2/MINGW-packages/issues/5434#issuecomment-496706950 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a7cf22c3..eecffff8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ environment: - MSYSTEM: MINGW32 install: -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc" +- 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" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force" - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force" From 64707dbb22c712e3c3ae526553cbf5b03b50fbbb Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 31 May 2019 11:57:16 -0400 Subject: [PATCH 0028/2950] key blinding test --- tests/Makefile | 5 ++++- tests/test-blinding.cpp | 43 +++++++++++++++++++++++++++++++++++++++++ tests/test-gost-sig.cpp | 6 ++++-- 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 tests/test-blinding.cpp diff --git a/tests/Makefile b/tests/Makefile index 498cff17..2a12472a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread -Wl,--unresolved-symbols=ignore-in-object-files -TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 +TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding all: $(TESTS) run @@ -22,6 +22,9 @@ 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 + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system + run: $(TESTS) @for TEST in $(TESTS); do ./$$TEST ; done diff --git a/tests/test-blinding.cpp b/tests/test-blinding.cpp new file mode 100644 index 00000000..5490acd4 --- /dev/null +++ b/tests/test-blinding.cpp @@ -0,0 +1,43 @@ +#include +#include +#include +#include "Blinding.h" +#include "Identity.h" +#include "Timestamp.h" + +using namespace i2p::data; +using namespace i2p::util; +using namespace i2p::crypto; + +void BlindTest (SigningKeyType sigType) +{ + auto keys = PrivateKeys::CreateRandomKeys (sigType); + BlindedPublicKey blindedKey (keys.GetPublic ()); + auto timestamp = GetSecondsSinceEpoch (); + char date[9]; + GetDateString (timestamp, date); + uint8_t blindedPriv[64], blindedPub[128]; + auto publicKeyLen = blindedKey.BlindPrivateKey (keys.GetSigningPrivateKey (), date, blindedPriv, blindedPub); + uint8_t blindedPub1[128]; + blindedKey.GetBlindedKey (date, blindedPub1); + // check if public key produced from private blinded key matches blided public key + assert (!memcmp (blindedPub, blindedPub1, publicKeyLen)); + // try to sign and verify + std::unique_ptr blindedSigner (PrivateKeys::CreateSigner (sigType, blindedPriv)); + uint8_t buf[100], signature[128]; + memset (buf, 1, 100); + blindedSigner->Sign (buf, 100, signature); + std::unique_ptr blindedVerifier (IdentityEx::CreateVerifier (sigType)); + blindedVerifier->SetPublicKey (blindedPub1); + assert (blindedVerifier->Verify (buf, 100, signature)); +} + +int main () +{ + // RedDSA test + BlindTest (SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + // P256 test + BlindTest (SIGNING_KEY_TYPE_ECDSA_SHA256_P256); + // P384 test + BlindTest (SIGNING_KEY_TYPE_ECDSA_SHA384_P384); +} diff --git a/tests/test-gost-sig.cpp b/tests/test-gost-sig.cpp index 55cc2d1b..1348af54 100644 --- a/tests/test-gost-sig.cpp +++ b/tests/test-gost-sig.cpp @@ -21,12 +21,14 @@ int main () i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410TC26A512, priv, pub); i2p::crypto::GOSTR3410_512_Signer signer (i2p::crypto::eGOSTR3410TC26A512, priv); signer.Sign (example2, 72, signature); - i2p::crypto::GOSTR3410_512_Verifier verifier (i2p::crypto::eGOSTR3410TC26A512, pub); + i2p::crypto::GOSTR3410_512_Verifier verifier (i2p::crypto::eGOSTR3410TC26A512); + verifier.SetPublicKey (pub); assert (verifier.Verify (example2, 72, signature)); i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410CryptoProA, priv, pub); i2p::crypto::GOSTR3410_256_Signer signer1 (i2p::crypto::eGOSTR3410CryptoProA, priv); signer1.Sign (example2, 72, signature); - i2p::crypto::GOSTR3410_256_Verifier verifier1 (i2p::crypto::eGOSTR3410CryptoProA, pub); + i2p::crypto::GOSTR3410_256_Verifier verifier1 (i2p::crypto::eGOSTR3410CryptoProA); + verifier1.SetPublicKey (pub); assert (verifier1.Verify (example2, 72, signature)); } From 7147a3694cebfae597ceecea7c630857e984440a Mon Sep 17 00:00:00 2001 From: Alexey Korepanov Date: Sat, 1 Jun 2019 12:57:09 +0100 Subject: [PATCH 0029/2950] link libi2pd to boost and zlib --- build/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index e50bbc86..949f6a46 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -470,6 +470,7 @@ if (WITH_BINARY) if (WITH_STATIC) set(DL_LIB ${CMAKE_DL_LIBS}) endif() + target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY}) target_link_libraries( "${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) From c4dffa4dc8e8243a82a401c7a8a1f707a40cb40f Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 1 Jun 2019 09:37:02 -0400 Subject: [PATCH 0030/2950] remove obsolete reseeds --- .../reseed/atomike_at_mail.i2p.crt | 34 ------------------- libi2pd/Config.cpp | 2 -- 2 files changed, 36 deletions(-) delete mode 100644 contrib/certificates/reseed/atomike_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/atomike_at_mail.i2p.crt b/contrib/certificates/reseed/atomike_at_mail.i2p.crt deleted file mode 100644 index 1e724f00..00000000 --- a/contrib/certificates/reseed/atomike_at_mail.i2p.crt +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF5TCCA82gAwIBAgIRANFIiHpTaRY2Z30TQOiuqFcwDQYJKoZIhvcNAQELBQAw -cDELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE -ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGTAXBgNVBAMM -EGF0b21pa2VAbWFpbC5pMnAwHhcNMTYwODAyMTQyNDEyWhcNMjYwODAyMTQyNDEy -WjBwMQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYD -VQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UE -AwwQYXRvbWlrZUBtYWlsLmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBAMLRmxclaAvm405JLHNNiniUi0aZaBoLJ+afwn2LGfTDUhTD5Y8lW6V9o90n -eTNOCaiid7bWpVBkA1M4gZ9TdUnP0POa99jXZbj4PHFRl1l8k4Ap12PUO3hgwtH7 -7j7j+UPaIuE2y+U7hJbmyQ0v7r8yjGWSTtSqs+exNhyr4Mh7DvacZySZ+oqQdXYA -vnfDpBX1dKlN1Nb4XloG0uE1OK1YfJoC+p+v8qXjKagIdZgThdmsWcQ82EGI+Q9u -VfrE4m3CNwJy0X86wMNYqHej88wBHnJMmTm+cZtFLVmZsRqnuLAQL1wrfCbGSltR -zhVQHTysLwMz9+llTXtzMf+R2kcEAYWiPc5IRVU+LvkN/610r5fuHW+OcQ9ZgRVn -PMqlv5PDG2ZxdIOAQQsOd7fH0r5q3MhqlVstVE45Rl33uA+M7wjJK2cvnOoSioxp -szn2GIZliXQXo4dJczgfN2U4PLBGRBGmrB1R2S1YsG6CrSJuMCX14VKJP69Nfm8a -EDA5GKNke+ZpXCszPLaNMB70LVFQc9FmMhsOgLIIoJBgd61uMgokMJJMLaWN0RaK -w1ZduxYGUmg2T2pi/clIkVzZmlcHKViUn0sMcKD+ibEPOvQIB/3HPEEt6iIkanc/ -da5IFzikkaykt/Tu6o8rreeEu65HkIxFaCHegSXLHSyxj00BAgMBAAGjejB4MA4G -A1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYD -VR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQYXRvbWlrZUBtYWlsLmkycDAbBgNVHSME -FDASgBBhdG9taWtlQG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQAA0MdWfN/N -1q5CdJqDyw4JQwzdYkA27Wr02qIcmwnqjcCEDPl4uDTyqN9gbEpJ48AcsdXRa6GE -lLh/qJ67I6YDe63LuhndzRULNgxGHVMGS8kBJIssQehb2rOFnbUTp0gMR+0QpXXe -omase4kL90c9uuYX1vXaO/ADssY2/QX49prwJO+UY/jGhcX4YheFI/teA85u6Qko -ero437Shqhl0kbdK+eBkOFf9a7mGxpMT73KE1jFS6433W4fFOkybQ1dcS0qStaUM -3qKC0EQCbAl1seAp3AGuG46swHZB0rZ1WCKVAr5yqCWSWMYO+fL6FosNg9z/VDVh -g6FFfoGrv19yaVFa9AvQsk1ATZ+bwtHProNx2Xet9pnAI30dT16+C5wCctoR6RVf -iOHl6CGqadjOycbMDVvOfJhypNDgWW3gBaCfXiAocJTLpR7hKNZ2bnvcP2xyXH1j -Qz/kiMJoZ3+TV1yC/x/maAHsUIQHqqd6ZRj7x5MgJq0UBdITo2ZQVfXYI0ZGIeNm -fMu+P5448+NdpASa9QoqS8kPFeUaHJMzMFHBKhrr8lTJeZ82hKBXt5jD3Tbef5Ck -n5auKu2D0IjvrzsdIpNMQAhuBPT06TW/LzN/MvardZcaLcBmcutefw6Z7RsedHvj -cGpnw4a2u9sHZIUNHzoGq32+7UWXsBI5Ow== ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 0f6460a0..e6007d5f 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -195,10 +195,8 @@ namespace config { "https://reseed.i2p.net.in/," "https://download.xxlspeed.com/," "https://reseed-fr.i2pd.xyz/," - "https://reseed.atomike.ninja/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," - "https://itoopie.atomike.ninja/," "https://i2pseed.creativecowpat.net:8443/," "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") From 828862ea49082e3c64da7adec745609bb15898b4 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Jun 2019 12:51:57 -0400 Subject: [PATCH 0031/2950] store hash for ECDSA blidning --- libi2pd/Blinding.cpp | 42 +++++++++++++++++++++++++----------------- libi2pd/Blinding.h | 2 +- libi2pd/LeaseSet.cpp | 7 ++++++- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 2a57efe0..362823b7 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -175,40 +175,48 @@ namespace data i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); } - void BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const + size_t BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const { uint8_t seed[64]; GenerateAlpha (date, seed); + size_t publicKeyLength = 0; switch (m_SigType) { case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: { + publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); - BlindPublicKeyECDSA (i2p::crypto::ECDSAP256_KEY_LENGTH, group, GetPublicKey (), seed, blindedKey); + BlindPublicKeyECDSA (publicKeyLength, group, GetPublicKey (), seed, blindedKey); EC_GROUP_free (group); break; } case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: { + publicKeyLength = i2p::crypto::ECDSAP384_KEY_LENGTH; EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp384r1); - BlindPublicKeyECDSA (i2p::crypto::ECDSAP384_KEY_LENGTH, group, GetPublicKey (), seed, blindedKey); + BlindPublicKeyECDSA (publicKeyLength, group, GetPublicKey (), seed, blindedKey); EC_GROUP_free (group); break; } case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: { + publicKeyLength = i2p::crypto::ECDSAP521_KEY_LENGTH; EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp521r1); - BlindPublicKeyECDSA (i2p::crypto::ECDSAP521_KEY_LENGTH, group, GetPublicKey (), seed, blindedKey); + BlindPublicKeyECDSA (publicKeyLength, group, GetPublicKey (), seed, blindedKey); EC_GROUP_free (group); break; } case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: + { i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); - break; + publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; + break; + } default: LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); } + return publicKeyLength; } size_t BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const @@ -267,23 +275,23 @@ namespace data i2p::data::IdentHash BlindedPublicKey::GetStoreHash (const char * date) const { i2p::data::IdentHash hash; - if (m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || - m_BlindedSigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) + uint8_t blinded[128]; + size_t publicKeyLength = 0; + if (date) + publicKeyLength = GetBlindedKey (date, blinded); + else + { + char currentDate[9]; + i2p::util::GetCurrentDate (currentDate); + publicKeyLength = GetBlindedKey (currentDate, blinded); + } + if (publicKeyLength) { - uint8_t blinded[32]; - if (date) - GetBlindedKey (date, blinded); - else - { - char currentDate[9]; - i2p::util::GetCurrentDate (currentDate); - GetBlindedKey (currentDate, blinded); - } auto stA1 = htobe16 (m_BlindedSigType); SHA256_CTX ctx; SHA256_Init (&ctx); SHA256_Update (&ctx, (const uint8_t *)&stA1, 2); - SHA256_Update (&ctx, blinded, 32); + SHA256_Update (&ctx, blinded, publicKeyLength); SHA256_Final ((uint8_t *)hash, &ctx); } else diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index f0387063..9a3fe633 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -24,7 +24,7 @@ namespace data SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes - void GetBlindedKey (const char * date, uint8_t * blindedKey) const; // blinded key 32 bytes, date is 8 chars "YYYYMMDD" + size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index c109dee8..60d47b6f 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -463,7 +463,7 @@ namespace data if (verified && key && lenOuterCiphertext >= 32) { SetIsValid (false); // we must verify it again in Layer 2 - if (blindedKeyType == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519) + if (blindedKeyType == key->GetBlindedSigType ()) { // verify blinding char date[9]; @@ -476,6 +476,11 @@ namespace data return; } } + else + { + LogPrint (eLogError, "LeaseSet2: Unexpected blinded key type ", blindedKeyType, " instread ", key->GetBlindedSigType ()); + return; + } // outer key // outerInput = subcredential || publishedTimestamp uint8_t subcredential[36]; From 686c0b776fb6255c84bb06d4a70c5a2d76279d32 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Jun 2019 14:47:40 -0400 Subject: [PATCH 0032/2950] common blinding code for public and private keys --- libi2pd/Blinding.cpp | 99 +++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 362823b7..b2ba5faa 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -52,7 +52,7 @@ namespace data BN_CTX_free (ctx); } - static void BlindPublicKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * pub, const uint8_t * seed, uint8_t * blindedPub) + static void BlindEncodedPublicKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * pub, const uint8_t * seed, uint8_t * blindedPub) { BIGNUM * x = BN_bin2bn (pub, publicKeyLen/2, NULL); BIGNUM * y = BN_bin2bn (pub + publicKeyLen/2, publicKeyLen/2, NULL); @@ -67,7 +67,7 @@ namespace data BN_free (x); BN_free (y); } - static void BlindPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) + static void BlindEncodedPrivateKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub) { BIGNUM * a = BN_bin2bn (priv, publicKeyLen/2, NULL); BIGNUM * a1 = BN_new (); @@ -85,7 +85,45 @@ namespace data i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); BN_free (x); BN_free (y); - } + } + + template + static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args) + // blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA + { + size_t publicKeyLength = 0; + EC_GROUP * group = nullptr; + switch (sigType) + { + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: + { + publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; + group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); + break; + } + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: + { + publicKeyLength = i2p::crypto::ECDSAP384_KEY_LENGTH; + group = EC_GROUP_new_by_curve_name (NID_secp384r1); + break; + } + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: + { + publicKeyLength = i2p::crypto::ECDSAP521_KEY_LENGTH; + group = EC_GROUP_new_by_curve_name (NID_secp521r1); + break; + } + default: + LogPrint (eLogError, "Blinding: signature type ", (int)sigType, " is not ECDSA"); + } + if (group) + { + blind (publicKeyLength, group, key, seed, std::forward(args)...); + EC_GROUP_free (group); + } + return publicKeyLength; + } + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity) { @@ -179,40 +217,20 @@ namespace data { uint8_t seed[64]; GenerateAlpha (date, seed); + size_t publicKeyLength = 0; switch (m_SigType) { case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: - { - publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; - EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); - BlindPublicKeyECDSA (publicKeyLength, group, GetPublicKey (), seed, blindedKey); - EC_GROUP_free (group); - break; - } case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: - { - publicKeyLength = i2p::crypto::ECDSAP384_KEY_LENGTH; - EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp384r1); - BlindPublicKeyECDSA (publicKeyLength, group, GetPublicKey (), seed, blindedKey); - EC_GROUP_free (group); - break; - } case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: - { - publicKeyLength = i2p::crypto::ECDSAP521_KEY_LENGTH; - EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp521r1); - BlindPublicKeyECDSA (publicKeyLength, group, GetPublicKey (), seed, blindedKey); - EC_GROUP_free (group); - break; - } + publicKeyLength = BlindECDSA (m_SigType, GetPublicKey (), seed, BlindEncodedPublicKeyECDSA, blindedKey); + break; case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: - { i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; - break; - } + break; default: LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); } @@ -227,35 +245,14 @@ namespace data switch (m_SigType) { case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: - { - publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; - EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); - BlindPrivateKeyECDSA (publicKeyLength, group, priv, seed, blindedPriv, blindedPub); - EC_GROUP_free (group); - break; - } case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: - { - publicKeyLength = i2p::crypto::ECDSAP384_KEY_LENGTH; - EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp384r1); - BlindPrivateKeyECDSA (publicKeyLength, group, priv, seed, blindedPriv, blindedPub); - EC_GROUP_free (group); - break; - } case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: - { - publicKeyLength = i2p::crypto::ECDSAP521_KEY_LENGTH; - EC_GROUP * group = EC_GROUP_new_by_curve_name (NID_secp521r1); - BlindPrivateKeyECDSA (publicKeyLength, group, priv, seed, blindedPriv, blindedPub); - EC_GROUP_free (group); - break; - } + publicKeyLength = BlindECDSA (m_SigType, GetPublicKey (), seed, BlindEncodedPrivateKeyECDSA, blindedPriv, blindedPub); + 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; - } + break; default: LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); } From 485f105555d324c8af93896c0dbd7be25610d8ae Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Jun 2019 15:12:19 -0400 Subject: [PATCH 0033/2950] fixed typo --- libi2pd/Blinding.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index b2ba5faa..14852340 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -247,7 +247,7 @@ namespace data case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: - publicKeyLength = BlindECDSA (m_SigType, GetPublicKey (), seed, BlindEncodedPrivateKeyECDSA, blindedPriv, blindedPub); + publicKeyLength = BlindECDSA (m_SigType, priv, seed, BlindEncodedPrivateKeyECDSA, blindedPriv, blindedPub); break; case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub); From 14f0d6d26bc90a59f031ab2d2838c09931ab8bd6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 5 Jun 2019 15:57:20 -0400 Subject: [PATCH 0034/2950] extract client auth data --- libi2pd/LeaseSet.cpp | 64 ++++++++++++++++++++++++++++++++++++++++---- libi2pd/LeaseSet.h | 1 + 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 60d47b6f..a2b67a42 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,7 +1,9 @@ #include +#include #include "I2PEndian.h" #include "Crypto.h" #include "Log.h" +#include "Tag.h" #include "Timestamp.h" #include "NetDb.hpp" #include "Tunnel.h" @@ -497,17 +499,26 @@ namespace data std::vector outerPlainText (lenOuterPlaintext); i2p::crypto::ChaCha20 (outerCiphertext + 32, lenOuterPlaintext, keys, keys + 32, outerPlainText.data ()); // inner key - // innerInput = authCookie || subcredential || publishedTimestamp, TODO: non-empty authCookie + // innerInput = authCookie || subcredential || publishedTimestamp // innerSalt = innerCiphertext[0:32] // keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44) - // skip 1 byte flags - i2p::crypto::HKDF (outerPlainText.data () + 1, subcredential, 36, "ELS2_L2K", keys); // no authCookie + uint8_t innerInput[68]; + size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, nullptr /*TODO*/, subcredential, innerInput); + if (authDataLen > 0) + { + memcpy (innerInput + 32, subcredential, 36); + i2p::crypto::HKDF (outerPlainText.data () + 1, innerInput, 68, "ELS2_L2K", keys); + } + else + // no authData presented, innerInput = subcredential || publishedTimestamp + // skip 1 byte flags + i2p::crypto::HKDF (outerPlainText.data () + 1, subcredential, 36, "ELS2_L2K", keys); // no authCookie // decrypt Layer 2 // innerKey = keys[0:31] // innerIV = keys[32:43] - size_t lenInnerPlaintext = lenOuterPlaintext - 32 - 1; + size_t lenInnerPlaintext = lenOuterPlaintext - 32 - 1 - authDataLen; std::vector innerPlainText (lenInnerPlaintext); - i2p::crypto::ChaCha20 (outerPlainText.data () + 32 + 1, lenInnerPlaintext, keys, keys + 32, innerPlainText.data ()); + i2p::crypto::ChaCha20 (outerPlainText.data () + 32 + 1 + authDataLen, lenInnerPlaintext, keys, keys + 32, innerPlainText.data ()); if (innerPlainText[0] == NETDB_STORE_TYPE_STANDARD_LEASESET2 || innerPlainText[0] == NETDB_STORE_TYPE_META_LEASESET2) { // override store type and buffer @@ -521,6 +532,49 @@ namespace data } } + size_t LeaseSet2::ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const + { + size_t offset = 0; + uint8_t flag = buf[offset]; offset++; // flag + if (flag & 0x01) // client auth + { + if (flag & 0x0E) // PSK, bits 3-1 are set to 1 + { + const uint8_t * authSalt = buf + offset; authSalt += 32; // authSalt + uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients + std::unordered_map > authClients; + for (int i = 0; i < numClients; i++) + { + uint64_t clientID = buf64toh (buf + offset); offset += 8; // clientID_i, don't care about endianess + authClients.emplace (clientID, buf + offset); + offset += 32; // clientCookie_i + } + // calculate authCookie + if (secret) + { + uint8_t authInput[68]; + memcpy (authInput, secret, 32); + memcpy (authInput, subcredential, 36); + uint8_t okm[64]; // 52 actual data + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + uint64_t clientID = buf64toh (okm + 44); // clientID_i = okm[44:51] + auto it = authClients.find (clientID); + if (it != authClients.end ()) + // clientKey_i = okm[0:31] + // clientIV_i = okm[32:43] + i2p::crypto::ChaCha20 (it->second, 32, okm, okm + 32, authCookie); + else + LogPrint (eLogError, "LeaseSet2: Client cookie for clientID_i ", clientID, " not found"); + } + else + LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); + } + else + LogPrint (eLogError, "LeaseSet2: unknown client auth type ", (int)flag); + } + return offset - 1; + } + void LeaseSet2::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const { auto encryptor = m_Encryptor; // TODO: atomic diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 8324a58d..f76c7720 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -156,6 +156,7 @@ namespace data bool VerifySignature (Verifier& verifier, const uint8_t * buf, size_t len, size_t signatureOffset); uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; + size_t ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const; // subcredential is subcredential + timestamp, return length of autData without flag private: From c6a903572c6b4d0475116624e4658c83424790eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 6 Jun 2019 18:07:17 +0300 Subject: [PATCH 0035/2950] [HTTP] add PROFIND support --- libi2pd/HTTP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index aaba3abc..64acb6ea 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -17,7 +17,7 @@ namespace i2p { namespace http { const std::vector HTTP_METHODS = { "GET", "HEAD", "POST", "PUT", "PATCH", - "DELETE", "OPTIONS", "CONNECT" + "DELETE", "OPTIONS", "CONNECT", "PROPFIND" }; const std::vector HTTP_VERSIONS = { "HTTP/1.0", "HTTP/1.1" From 347a5f7346df6e22f7c745c3a31ff61a502d2b8a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Jun 2019 12:33:33 -0400 Subject: [PATCH 0036/2950] pass secret to encrypted LeaseSet2 --- libi2pd/LeaseSet.cpp | 46 ++++++++++++++++++++++---------------------- libi2pd/LeaseSet.h | 4 ++-- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index a2b67a42..efb6e482 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,5 +1,4 @@ #include -#include #include "I2PEndian.h" #include "Crypto.h" #include "Log.h" @@ -257,15 +256,15 @@ namespace data { SetBuffer (buf, len); if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) - ReadFromBufferEncrypted (buf, len, nullptr); + ReadFromBufferEncrypted (buf, len, nullptr, nullptr); else ReadFromBuffer (buf, len); } - LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key): + LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret): LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_OrigStoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { - ReadFromBufferEncrypted (buf, len, key); + ReadFromBufferEncrypted (buf, len, key, secret); } void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature) @@ -422,7 +421,7 @@ namespace data return offset; } - void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key) + void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret) { size_t offset = 0; // blinded key @@ -503,7 +502,7 @@ namespace data // innerSalt = innerCiphertext[0:32] // keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44) uint8_t innerInput[68]; - size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, nullptr /*TODO*/, subcredential, innerInput); + size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, secret, subcredential, innerInput); if (authDataLen > 0) { memcpy (innerInput + 32, subcredential, 36); @@ -538,17 +537,11 @@ namespace data uint8_t flag = buf[offset]; offset++; // flag if (flag & 0x01) // client auth { - if (flag & 0x0E) // PSK, bits 3-1 are set to 1 + if ((flag & 0x0E) == 0x0E) // PSK, bits 3-1 are set to 1 { const uint8_t * authSalt = buf + offset; authSalt += 32; // authSalt uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients - std::unordered_map > authClients; - for (int i = 0; i < numClients; i++) - { - uint64_t clientID = buf64toh (buf + offset); offset += 8; // clientID_i, don't care about endianess - authClients.emplace (clientID, buf + offset); - offset += 32; // clientCookie_i - } + const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients // calculate authCookie if (secret) { @@ -556,15 +549,22 @@ namespace data memcpy (authInput, secret, 32); memcpy (authInput, subcredential, 36); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); - uint64_t clientID = buf64toh (okm + 44); // clientID_i = okm[44:51] - auto it = authClients.find (clientID); - if (it != authClients.end ()) - // clientKey_i = okm[0:31] - // clientIV_i = okm[32:43] - i2p::crypto::ChaCha20 (it->second, 32, okm, okm + 32, authCookie); - else - LogPrint (eLogError, "LeaseSet2: Client cookie for clientID_i ", clientID, " not found"); + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + // try to find clientCookie_i for clientID_i = okm[44:51] + bool found = false; + for (int i = 0; i < numClients; i++) + { + if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i + { + // clientKey_i = okm[0:31] + // clientIV_i = okm[32:43] + i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i + found = true; + break; + } + } + if (!found) + LogPrint (eLogError, "LeaseSet2: Client cookie not found"); } else LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index f76c7720..a2ed6fba 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -135,7 +135,7 @@ namespace data public: LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true); - LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key); // store type 5, called from local netdb only + LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr); // store type 5, called from local netdb only uint8_t GetStoreType () const { return m_StoreType; }; uint8_t GetOrigStoreType () const { return m_OrigStoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; @@ -148,7 +148,7 @@ namespace data private: void ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity = true, bool verifySignature = true); - void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key); + void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret); size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len); size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len); From 0a299284f8ac98d31e5977c1aaafa48250fb394b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Jun 2019 13:58:31 -0400 Subject: [PATCH 0037/2950] correct check for PSK auth --- libi2pd/LeaseSet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index efb6e482..101f17d9 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -537,9 +537,9 @@ namespace data uint8_t flag = buf[offset]; offset++; // flag if (flag & 0x01) // client auth { - if ((flag & 0x0E) == 0x0E) // PSK, bits 3-1 are set to 1 + if (flag & 0x02) // PSK, bit 1 is set to 1 { - const uint8_t * authSalt = buf + offset; authSalt += 32; // authSalt + const uint8_t * authSalt = buf + offset; offset += 32; // authSalt uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients // calculate authCookie From 1c9e46dbb33b9b125dec7fb3b064d0c3fc0b7987 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 7 Jun 2019 10:04:57 -0400 Subject: [PATCH 0038/2950] 2.26.0 --- ChangeLog | 15 +++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 35 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08f78224..a8a382ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,21 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.26.0] - 2019-06-07 +### Added +- HTTP method "PROFIND" +- Detection of external ipv6 address through the SSU +- NTCP2 publishing depends on network status +### Changed +- ntcp is disabled by default, ntcp2 is published by default +- Response to BOB's "list" command +- ipv6 address is not longer NTCP's local endpoint's address +- Reseeds list +### Fixed +- Check and handle incorrect BOB input +- Ignore introducers for NTCP or NTCP2 addresses +- RouterInfo check from NTCP2 + ## [2.25.0] - 2019-05-09 ### Added - Create, publish and handle encrypted LeaseSet2 diff --git a/Win32/installer.iss b/Win32/installer.iss index b215b91c..28df9ea8 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.25.0" +#define I2Pd_ver "2.26.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index e68c160f..327d3ec1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -29,8 +29,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 28 minSdkVersion 14 - versionCode 2250 - versionName "2.25.0" + versionCode 2260 + versionName "2.26.0" ndk { abiFilters 'armeabi-v7a' abiFilters 'x86' diff --git a/appveyor.yml b/appveyor.yml index eecffff8..ddcd651a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.25.0.{build} +version: 2.26.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 ffc87519..098084d7 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.25.0 +Version: 2.26.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -110,6 +110,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Jun 7 2019 orignal - 2.26.0 +- update to 2.26.0 + * Thu May 9 2019 orignal - 2.25.0 - update to 2.25.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 7932629f..84fad674 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.25.0 +Version: 2.26.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -108,6 +108,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Jun 7 2019 orignal - 2.26.0 +- update to 2.26.0 + * Thu May 9 2019 orignal - 2.25.0 - update to 2.25.0 diff --git a/debian/changelog b/debian/changelog index a0ad2cd5..1bd32f03 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.26.0-1) unstable; urgency=medium + + * updated to version 2.26.0 + + -- orignal Fri, 7 Jun 2019 16:00:00 +0000 + i2pd (2.25.0-1) unstable; urgency=medium * updated to version 2.25.0/0.9.40 diff --git a/libi2pd/version.h b/libi2pd/version.h index 4fdb5f27..4ac7a7b0 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 25 +#define I2PD_VERSION_MINOR 26 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index e9f35676..efb8a4d6 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 79630e844b44083022a9dcd2ae0cf7b943012828 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 7 Jun 2019 17:25:55 +0300 Subject: [PATCH 0039/2950] 2.26.0 --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a8a382ca..f06a51b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ ## [2.26.0] - 2019-06-07 ### Added -- HTTP method "PROFIND" +- HTTP method "PROPFIND" - Detection of external ipv6 address through the SSU - NTCP2 publishing depends on network status ### Changed @@ -11,6 +11,7 @@ - Response to BOB's "list" command - ipv6 address is not longer NTCP's local endpoint's address - Reseeds list +- HTTP_REFERER stripping in httpproxy (#823) ### Fixed - Check and handle incorrect BOB input - Ignore introducers for NTCP or NTCP2 addresses From 213a292fd5432f671e75c24229ed82edd737ce59 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 7 Jun 2019 11:59:48 -0400 Subject: [PATCH 0040/2950] correct offsets for auth data --- libi2pd/LeaseSet.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 101f17d9..daacc7f1 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -479,7 +479,7 @@ namespace data } else { - LogPrint (eLogError, "LeaseSet2: Unexpected blinded key type ", blindedKeyType, " instread ", key->GetBlindedSigType ()); + LogPrint (eLogError, "LeaseSet2: Unexpected blinded key type ", blindedKeyType, " instead ", key->GetBlindedSigType ()); return; } // outer key @@ -506,7 +506,7 @@ namespace data if (authDataLen > 0) { memcpy (innerInput + 32, subcredential, 36); - i2p::crypto::HKDF (outerPlainText.data () + 1, innerInput, 68, "ELS2_L2K", keys); + i2p::crypto::HKDF (outerPlainText.data () + 1 + authDataLen, innerInput, 68, "ELS2_L2K", keys); } else // no authData presented, innerInput = subcredential || publishedTimestamp @@ -542,12 +542,17 @@ namespace data const uint8_t * authSalt = buf + offset; offset += 32; // authSalt uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients + if (offset > len) + { + LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in auth data"); + return 0; + } // calculate authCookie if (secret) { uint8_t authInput[68]; memcpy (authInput, secret, 32); - memcpy (authInput, subcredential, 36); + memcpy (authInput + 32, subcredential, 36); uint8_t okm[64]; // 52 actual data i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); // try to find clientCookie_i for clientID_i = okm[44:51] From 41f4f4713e21e1fc5400d56a744d26a077928fce Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 7 Jun 2019 14:51:08 -0400 Subject: [PATCH 0041/2950] handle i2cp.leaseSetPrivKey --- libi2pd/Destination.cpp | 12 +++++++++++- libi2pd/Destination.h | 2 ++ libi2pd/Tag.h | 8 ++++---- libi2pd_client/ClientContext.cpp | 2 ++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ba90342c..5187fedc 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -70,6 +70,16 @@ namespace client it = params->find (I2CP_PARAM_LEASESET_TYPE); if (it != params->end ()) m_LeaseSetType = std::stoi(it->second); + it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY); + if (it != params->end ()) + { + m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>()); + if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32) + { + LogPrint(eLogError, "Destination: invalid value i2cp.leaseSetPrivKey ", it->second); + m_LeaseSetPrivKey.reset (nullptr); + } + } } } catch (std::exception & ex) @@ -422,7 +432,7 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey); + auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 64dd0b58..35a9dbae 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -55,6 +55,7 @@ namespace client const char I2CP_PARAM_LEASESET_TYPE[] = "i2cp.leaseSetType"; const int DEFAULT_LEASESET_TYPE = 1; const char I2CP_PARAM_LEASESET_ENCRYPTION_TYPE[] = "i2cp.leaseSetEncType"; + const char I2CP_PARAM_LEASESET_PRIV_KEY[] = "i2cp.leaseSetPrivKey"; // PSK decryption key, base64 // latency const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; @@ -175,6 +176,7 @@ namespace client m_PublishDelayTimer, m_CleanupTimer; std::string m_Nickname; int m_LeaseSetType; + std::unique_ptr > m_LeaseSetPrivKey; // non-null if presented public: diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index 03e3bc06..8af82241 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -71,14 +71,14 @@ public: return std::string (str, str + l); } - void FromBase32 (const std::string& s) + size_t FromBase32 (const std::string& s) { - i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); + return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); } - void FromBase64 (const std::string& s) + size_t FromBase64 (const std::string& s) { - i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); + return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); } private: diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 3292419a..c286007c 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -395,6 +395,8 @@ namespace client options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, ""); 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; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const From e60549f8df64a105c9fc3bb03c1df299c98c7849 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 8 Jun 2019 21:15:59 +0300 Subject: [PATCH 0042/2950] [qt] fix build --- qt/i2pd_qt/i2pd_qt.pro | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index e24a3963..84acaea5 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -4,19 +4,22 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app -QMAKE_CXXFLAGS *= -std=c++11 -ggdb +QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized DEFINES += USE_UPNP SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/api.cpp \ ../../libi2pd/Base.cpp \ + ../../libi2pd/Blinding.cpp \ ../../libi2pd/BloomFilter.cpp \ + ../../libi2pd/Chacha20.cpp \ ../../libi2pd/Config.cpp \ ../../libi2pd/CPU.cpp \ ../../libi2pd/Crypto.cpp \ - ../../libi2pd/CryptoKey.cpp \ + ../../libi2pd/CryptoKey.cpp \ ../../libi2pd/Datagram.cpp \ ../../libi2pd/Destination.cpp \ + ../../libi2pd/Ed25519.cpp \ ../../libi2pd/Event.cpp \ ../../libi2pd/Family.cpp \ ../../libi2pd/FS.cpp \ @@ -31,7 +34,9 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/Log.cpp \ ../../libi2pd/NetDb.cpp \ ../../libi2pd/NetDbRequests.cpp \ + ../../libi2pd/NTCP2.cpp \ ../../libi2pd/NTCPSession.cpp \ + ../../libi2pd/Poly1305.cpp \ ../../libi2pd/Profiling.cpp \ ../../libi2pd/Reseed.cpp \ ../../libi2pd/RouterContext.cpp \ @@ -49,9 +54,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/TunnelGateway.cpp \ ../../libi2pd/TunnelPool.cpp \ ../../libi2pd/util.cpp \ - ../../libi2pd/Ed25519.cpp \ - ../../libi2pd/Chacha20.cpp \ - ../../libi2pd/Poly1305.cpp \ ../../libi2pd_client/AddressBook.cpp \ ../../libi2pd_client/BOB.cpp \ ../../libi2pd_client/ClientContext.cpp \ @@ -64,24 +66,23 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd_client/SOCKS.cpp \ ../../libi2pd_client/Websocket.cpp \ ../../libi2pd_client/WebSocks.cpp \ + ../../daemon/Daemon.cpp \ + ../../daemon/HTTPServer.cpp \ + ../../daemon/I2PControl.cpp \ + ../../daemon/i2pd.cpp \ + ../../daemon/UnixDaemon.cpp \ + ../../daemon/UPnP.cpp \ ClientTunnelPane.cpp \ MainWindowItems.cpp \ ServerTunnelPane.cpp \ SignatureTypeComboboxFactory.cpp \ TunnelConfig.cpp \ TunnelPane.cpp \ - ../../daemon/Daemon.cpp \ - ../../daemon/HTTPServer.cpp \ - ../../daemon/i2pd.cpp \ - ../../daemon/I2PControl.cpp \ - ../../daemon/UnixDaemon.cpp \ - ../../daemon/UPnP.cpp \ textbrowsertweaked1.cpp \ pagewithbackbutton.cpp \ widgetlock.cpp \ widgetlockregistry.cpp \ logviewermanager.cpp \ - ../../libi2pd/NTCP2.cpp #qt creator does not handle this well #SOURCES += $$files(../../libi2pd/*.cpp) From 48d02f7e0910329e1dc92fdc1b8ab6aefd00ccef Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 8 Jun 2019 22:24:11 +0300 Subject: [PATCH 0043/2950] [qt] update headers, fix ChaCha source name, remove duplicates --- qt/i2pd_qt/i2pd_qt.pro | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 84acaea5..46dd4a1b 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -12,7 +12,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/Base.cpp \ ../../libi2pd/Blinding.cpp \ ../../libi2pd/BloomFilter.cpp \ - ../../libi2pd/Chacha20.cpp \ + ../../libi2pd/ChaCha20.cpp \ ../../libi2pd/Config.cpp \ ../../libi2pd/CPU.cpp \ ../../libi2pd/Crypto.cpp \ @@ -90,17 +90,22 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ #SOURCES += $$files(../../daemon/*.cpp) #SOURCES += $$files(./*.cpp) -SOURCES -= ../../daemon/UnixDaemon.cpp +#SOURCES -= ../../daemon/UnixDaemon.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/api.h \ ../../libi2pd/Base.h \ + ../../libi2pd/Blinding.h \ ../../libi2pd/BloomFilter.h \ + ../../libi2pd/ChaCha20.h \ ../../libi2pd/Config.h \ + ../../libi2pd/CPU.h \ ../../libi2pd/Crypto.h \ - ../../libi2pd/CryptoKey.h \ + ../../libi2pd/CryptoKey.h \ + ../../libi2pd/CryptoWorker.h \ ../../libi2pd/Datagram.h \ ../../libi2pd/Destination.h \ + ../../libi2pd/Ed25519.h \ ../../libi2pd/Event.h \ ../../libi2pd/Family.h \ ../../libi2pd/FS.h \ @@ -116,13 +121,16 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/Log.h \ ../../libi2pd/NetDb.hpp \ ../../libi2pd/NetDbRequests.h \ + ../../libi2pd/NTCP2.h \ ../../libi2pd/NTCPSession.h \ + ../../libi2pd/Poly1305.h \ ../../libi2pd/Profiling.h \ ../../libi2pd/Queue.h \ ../../libi2pd/Reseed.h \ ../../libi2pd/RouterContext.h \ ../../libi2pd/RouterInfo.h \ ../../libi2pd/Signature.h \ + ../../libi2pd/Siphash.h \ ../../libi2pd/SSU.h \ ../../libi2pd/SSUData.h \ ../../libi2pd/SSUSession.h \ @@ -152,6 +160,10 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd_client/SOCKS.h \ ../../libi2pd_client/Websocket.h \ ../../libi2pd_client/WebSocks.h \ + ../../daemon/Daemon.h \ + ../../daemon/HTTPServer.h \ + ../../daemon/I2PControl.h \ + ../../daemon/UPnP.h \ ClientTunnelPane.h \ MainWindowItems.h \ ServerTunnelPane.h \ @@ -159,16 +171,11 @@ HEADERS += DaemonQT.h mainwindow.h \ TunnelConfig.h \ TunnelPane.h \ TunnelsPageUpdateListener.h \ - ../../daemon/Daemon.h \ - ../../daemon/HTTPServer.h \ - ../../daemon/I2PControl.h \ - ../../daemon/UPnP.h \ textbrowsertweaked1.h \ pagewithbackbutton.h \ widgetlock.h \ widgetlockregistry.h \ i2pd.rc \ - i2pd.rc \ logviewermanager.h INCLUDEPATH += ../../libi2pd From a74065f7758b3105afb043b81f1eefb92eaae6d5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 9 Jun 2019 01:04:43 +0300 Subject: [PATCH 0044/2950] [qt] dont build UnixDaemon.cpp --- qt/i2pd_qt/i2pd_qt.pro | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 46dd4a1b..9a978731 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -70,7 +70,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../daemon/HTTPServer.cpp \ ../../daemon/I2PControl.cpp \ ../../daemon/i2pd.cpp \ - ../../daemon/UnixDaemon.cpp \ ../../daemon/UPnP.cpp \ ClientTunnelPane.cpp \ MainWindowItems.cpp \ @@ -82,15 +81,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ pagewithbackbutton.cpp \ widgetlock.cpp \ widgetlockregistry.cpp \ - logviewermanager.cpp \ - -#qt creator does not handle this well -#SOURCES += $$files(../../libi2pd/*.cpp) -#SOURCES += $$files(../../libi2pd_client/*.cpp) -#SOURCES += $$files(../../daemon/*.cpp) -#SOURCES += $$files(./*.cpp) - -#SOURCES -= ../../daemon/UnixDaemon.cpp + logviewermanager.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/api.h \ From f6f45eab3946d772d48c58c42a828485fd7044d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Jun 2019 21:23:25 -0400 Subject: [PATCH 0045/2950] flood encrypted LeaseSet2 with store hash --- libi2pd/I2NPProtocol.cpp | 4 ++-- libi2pd/I2NPProtocol.h | 2 +- libi2pd/NetDb.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 9f6c609b..afdd8dc5 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -258,12 +258,12 @@ namespace i2p return m; } - std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet) + std::shared_ptr CreateDatabaseStoreMsg (const i2p::data::IdentHash& storeHash, std::shared_ptr leaseSet) { if (!leaseSet) return nullptr; auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); - memcpy (payload + DATABASE_STORE_KEY_OFFSET, leaseSet->GetIdentHash (), 32); + memcpy (payload + DATABASE_STORE_KEY_OFFSET, storeHash, 32); payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); size_t size = DATABASE_STORE_HEADER_SIZE; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 5160acec..ca074aed 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -247,7 +247,7 @@ namespace tunnel std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector routers); std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router = nullptr, uint32_t replyToken = 0); - std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet); // for floodfill only + std::shared_ptr CreateDatabaseStoreMsg (const i2p::data::IdentHash& storeHash, std::shared_ptr leaseSet); // for floodfill only std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken = 0, std::shared_ptr replyTunnel = nullptr); bool IsRouterInfoMsg (std::shared_ptr msg); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 952c8017..07272a83 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -909,7 +909,7 @@ namespace data else if (!leaseSet->IsExpired ()) // we don't send back our LeaseSets { LogPrint (eLogDebug, "NetDb: requested LeaseSet ", key, " found"); - replyMsg = CreateDatabaseStoreMsg (leaseSet); + replyMsg = CreateDatabaseStoreMsg (ident, leaseSet); } } From c8eeefe19474c6447451b74f9e4205165b13d43a Mon Sep 17 00:00:00 2001 From: rszibele Date: Mon, 10 Jun 2019 23:04:59 +0200 Subject: [PATCH 0046/2950] fix build on BSDs, as "isset" is a defined macro. --- libi2pd_client/BOB.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 023be3b4..c329d86b 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -350,8 +350,8 @@ namespace client void BOBCommandSession::BuildStatusLine(bool currentTunnel, BOBDestination *dest, std::string &out) { // helper lambdas - const auto isset = [](const std::string &str) { return str.empty() ? "not_set" : str; }; // for inhost, outhost - const auto issetNum = [&isset](const int p) { return isset(p == 0 ? "" : std::to_string(p)); }; // for inport, outport + const auto issetStr = [](const std::string &str) { return str.empty() ? "not_set" : str; }; // for inhost, outhost + const auto issetNum = [&issetStr](const int p) { return issetStr(p == 0 ? "" : std::to_string(p)); }; // for inport, outport const auto destExists = [](const BOBDestination * const dest) { return dest != nullptr; }; const auto destReady = [](const BOBDestination * const dest) { return dest->GetLocalDestination()->IsReady(); }; const auto bool_str = [](const bool v) { return v ? "true" : "false"; }; // bool -> str @@ -359,8 +359,8 @@ namespace client // tunnel info const std::string nickname = currentTunnel ? m_Nickname : dest->GetNickname(); const bool quiet = currentTunnel ? m_IsQuiet : dest->GetQuiet(); - const std::string inhost = isset(currentTunnel ? m_InHost : dest->GetInHost()); - const std::string outhost = isset(currentTunnel ? m_OutHost : dest->GetOutHost()); + const std::string inhost = issetStr(currentTunnel ? m_InHost : dest->GetInHost()); + const std::string outhost = issetStr(currentTunnel ? m_OutHost : dest->GetOutHost()); const std::string inport = issetNum(currentTunnel ? m_InPort : dest->GetInPort()); const std::string outport = issetNum(currentTunnel ? m_OutPort : dest->GetOutPort()); const bool keys = destExists(dest); // key must exist when destination is created From 74e8610ec93522eee466688fec1e44eaa27adfa5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 11 Jun 2019 10:40:53 -0400 Subject: [PATCH 0047/2950] DH auth for encrypted LeaseSet2 --- libi2pd/Crypto.cpp | 15 ++++++++--- libi2pd/Crypto.h | 2 +- libi2pd/LeaseSet.cpp | 64 ++++++++++++++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index cd6d5b8e..3c51a033 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -296,11 +296,20 @@ namespace crypto #if OPENSSL_X25519 m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); - memcpy (m_PublicKey, pub, 32); // TODO: verify against m_Pkey + if (pub) + memcpy (m_PublicKey, pub, 32); // TODO: verify against m_Pkey + else + { + size_t len = 32; + EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); + } #else + m_Ctx = BN_CTX_new (); memcpy (m_PrivateKey, priv, 32); - memcpy (m_PublicKey, pub, 32); - m_Ctx = BN_CTX_new (); + if (pub) + memcpy (m_PublicKey, pub, 32); + else + GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); #endif } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 5afc4c52..a4b6c2de 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -74,7 +74,7 @@ namespace crypto public: X25519Keys (); - X25519Keys (const uint8_t * priv, const uint8_t * pub); // for RouterContext + X25519Keys (const uint8_t * priv, const uint8_t * pub); // if pub is null, derive from priv ~X25519Keys (); void GenerateKeys (); diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index daacc7f1..1d555ac4 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -531,20 +531,63 @@ namespace data } } + // helper for ExtractClientAuthData + static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie) + { + // try to find clientCookie_i for clientID_i = okm[44:51] + for (int i = 0; i < numClients; i++) + { + if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i + { + // clientKey_i = okm[0:31] + // clientIV_i = okm[32:43] + i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i + return true; + } + } + return false; + } + size_t LeaseSet2::ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const { size_t offset = 0; uint8_t flag = buf[offset]; offset++; // flag if (flag & 0x01) // client auth { - if (flag & 0x02) // PSK, bit 1 is set to 1 + if (!(flag & 0x0E)) // DH, bit 1-3 all zeroes + { + const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey + uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients + const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients + if (offset > len) + { + LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data"); + return 0; + } + // calculate authCookie + if (secret) + { + i2p::crypto::X25519Keys ck (secret, nullptr); // derive cpk_i from csk_i + uint8_t authInput[100]; + ck.Agree (ephemeralPublicKey, authInput); // sharedSecret is first 32 bytes of authInput + memcpy (authInput + 32, ck.GetPublicKey (), 32); // cpk_i + memcpy (authInput + 32, subcredential, 36); + uint8_t okm[64]; // 52 actual data + i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); + if (!GetAuthCookie (authClients, numClients, okm, authCookie)) + LogPrint (eLogError, "LeaseSet2: Client cookie DH not found"); + } + else + LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: csk_i is not provided"); + } + else if (flag & 0x02) // PSK, bit 1 is set to 1 { const uint8_t * authSalt = buf + offset; offset += 32; // authSalt uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients if (offset > len) { - LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in auth data"); + LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data"); return 0; } // calculate authCookie @@ -555,21 +598,8 @@ namespace data memcpy (authInput + 32, subcredential, 36); uint8_t okm[64]; // 52 actual data i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); - // try to find clientCookie_i for clientID_i = okm[44:51] - bool found = false; - for (int i = 0; i < numClients; i++) - { - if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i - { - // clientKey_i = okm[0:31] - // clientIV_i = okm[32:43] - i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i - found = true; - break; - } - } - if (!found) - LogPrint (eLogError, "LeaseSet2: Client cookie not found"); + if (!GetAuthCookie (authClients, numClients, okm, authCookie)) + LogPrint (eLogError, "LeaseSet2: Client cookie PSK not found"); } else LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); From 3e932a55f4050e4f26c667b38a5670bdcc797a8f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 11 Jun 2019 15:09:10 -0400 Subject: [PATCH 0048/2950] fixed typo --- libi2pd/LeaseSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 1d555ac4..69a29377 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -571,7 +571,7 @@ namespace data uint8_t authInput[100]; ck.Agree (ephemeralPublicKey, authInput); // sharedSecret is first 32 bytes of authInput memcpy (authInput + 32, ck.GetPublicKey (), 32); // cpk_i - memcpy (authInput + 32, subcredential, 36); + memcpy (authInput + 64, subcredential, 36); uint8_t okm[64]; // 52 actual data i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); if (!GetAuthCookie (authClients, numClients, okm, authCookie)) From 13732ac33369df365132eb43ed9146221c69ec50 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 14 Jun 2019 15:43:03 -0400 Subject: [PATCH 0049/2950] fix #1363 try connect in SSU's thread --- libi2pd/Transports.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b76d9312..a2783f6c 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -562,7 +562,10 @@ namespace transport { auto addr = router->GetSSUV6Address (); if (addr) - m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); + m_SSUServer->GetServiceV6 ().post ([this, router, addr] + { + m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); + }); } } } From 832a9ab6b5d2af3cc64723090de15181783bc162 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Jun 2019 15:47:58 -0400 Subject: [PATCH 0050/2950] don't set random NTCP2 port if already set --- libi2pd/RouterContext.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index d228b626..46681f77 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -183,17 +183,18 @@ namespace i2p void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4only) { if (!m_NTCP2Keys) return; - if (!port) - { - port = rand () % (30777 - 9111) + 9111; // I2P network ports range - if (port == 9150) port = 9151; // Tor browser - } bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish) && (!v4only || address->host.is_v4 ())) { - address->port = port; + 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 ? 3 : 14; address->ntcp2->isPublished = publish; address->ntcp2->iv = m_NTCP2Keys->iv; From 8e919ddc8e20eb31cd9acfd56b93fca9df094492 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Jun 2019 11:43:04 -0400 Subject: [PATCH 0051/2950] use monotonic clock for uptime --- libi2pd/NetDb.cpp | 5 +++-- libi2pd/RouterContext.cpp | 6 +++--- libi2pd/RouterContext.h | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 07272a83..b7479744 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -523,9 +523,10 @@ namespace data auto total = m_RouterInfos.size (); uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); + auto uptime = i2p::context.GetUptime (); // routers don't expire if less than 90 or uptime is less than 1 hour - bool checkForExpiration = total > NETDB_MIN_ROUTERS && ts > (i2p::context.GetStartupTime () + 600)*1000LL; // 10 minutes - if (checkForExpiration && ts > (i2p::context.GetStartupTime () + 3600)*1000LL) // 1 hour + bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes + if (checkForExpiration && uptime > 3600) // 1 hour 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; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 46681f77..5ac26f7c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -19,7 +19,7 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_StartupTime (0), m_ShareRatio (100), m_Status (eRouterStatusOK), + m_ShareRatio (100), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -27,7 +27,7 @@ namespace i2p void RouterContext::Init () { srand (i2p::util::GetMillisecondsSinceEpoch () % 1000); - m_StartupTime = i2p::util::GetSecondsSinceEpoch (); + m_StartupTime = std::chrono::steady_clock::now(); if (!Load ()) CreateNewRouter (); m_Decryptor = m_Keys.CreateDecryptor (nullptr); @@ -716,7 +716,7 @@ namespace i2p uint32_t RouterContext::GetUptime () const { - return i2p::util::GetSecondsSinceEpoch () - m_StartupTime; + 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) const diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index e680eff8..fc4b90dc 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "Identity.h" #include "RouterInfo.h" @@ -64,8 +65,7 @@ namespace i2p const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; i2p::crypto::X25519Keys& GetStaticKeys (); - uint32_t GetUptime () const; - uint32_t GetStartupTime () const { return m_StartupTime; }; + uint32_t GetUptime () const; // in seconds uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; uint64_t GetTransitBandwidthLimit () const { return (m_BandwidthLimit*m_ShareRatio)/100LL; }; @@ -137,7 +137,7 @@ namespace i2p std::shared_ptr m_Decryptor; uint64_t m_LastUpdateTime; // in seconds bool m_AcceptsTunnels, m_IsFloodfill; - uint64_t m_StartupTime; // in seconds since epoch + std::chrono::time_point m_StartupTime; uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; RouterStatus m_Status; From cb8373e48710f922aaf764daab23e16e1e83c3eb Mon Sep 17 00:00:00 2001 From: rszibele Date: Tue, 25 Jun 2019 17:59:44 +0200 Subject: [PATCH 0052/2950] BOB: status response now correctly starts with "OK DATA". --- libi2pd_client/BOB.cpp | 11 ++++++----- libi2pd_client/BOB.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index c329d86b..828b8e8a 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -341,10 +341,10 @@ namespace client SendReplyOK(); } - void BOBCommandSession::SendData (const char * data) + void BOBCommandSession::SendRaw (const char * data) { std::ostream os(&m_SendBuffer); - os << "DATA " << data << std::endl; + os << data << std::endl; } void BOBCommandSession::BuildStatusLine(bool currentTunnel, BOBDestination *dest, std::string &out) @@ -370,7 +370,8 @@ namespace client // build line std::stringstream ss; - ss << "NICKNAME: " << nickname << " " << "STARTING: " << bool_str(starting) << " " + ss << "DATA " + << "NICKNAME: " << nickname << " " << "STARTING: " << bool_str(starting) << " " << "RUNNING: " << bool_str(running) << " " << "STOPPING: " << bool_str(stopping) << " " << "KEYS: " << bool_str(keys) << " " << "QUIET: " << bool_str(quiet) << " " << "INPORT: " << inport << " " << "INHOST: " << inhost << " " @@ -654,7 +655,7 @@ namespace client for (const auto& it: destinations) { BuildStatusLine(false, it.second, statusLine); - SendData (statusLine.c_str()); + SendRaw(statusLine.c_str()); if(m_Nickname.compare(it.second->GetNickname()) == 0) sentCurrent = true; } @@ -663,7 +664,7 @@ namespace client // add the current tunnel to the list BuildStatusLine(true, m_CurrentDestination, statusLine); LogPrint(eLogError, statusLine); - SendData(statusLine.c_str()); + SendRaw(statusLine.c_str()); } SendReplyOK ("Listing done"); } diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index d531a13d..8f1af185 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -213,7 +213,7 @@ namespace client void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void SendReplyOK (const char * msg = nullptr); void SendReplyError (const char * msg); - void SendData (const char * data); + void SendRaw (const char * data); void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out); From a23e845c03275a77f57e81b5af989806dcd5ebf8 Mon Sep 17 00:00:00 2001 From: rszibele Date: Tue, 25 Jun 2019 19:04:27 +0200 Subject: [PATCH 0053/2950] BOB: improve comment and remove error log in list command --- libi2pd_client/BOB.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 828b8e8a..b88eea81 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -661,9 +661,9 @@ namespace client } if(!sentCurrent && !m_Nickname.empty()) { - // add the current tunnel to the list + // add the current tunnel to the list. + // this is for the incomplete tunnel which has not been started yet. BuildStatusLine(true, m_CurrentDestination, statusLine); - LogPrint(eLogError, statusLine); SendRaw(statusLine.c_str()); } SendReplyOK ("Listing done"); From b75929497551b9186f207f90913612c19f4ee909 Mon Sep 17 00:00:00 2001 From: rszibele Date: Tue, 25 Jun 2019 19:18:40 +0200 Subject: [PATCH 0054/2950] BOB: fix status command. --- libi2pd_client/BOB.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index b88eea81..aba090dc 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -691,21 +691,23 @@ namespace client void BOBCommandSession::StatusCommandHandler (const char * operand, size_t len) { LogPrint (eLogDebug, "BOB: status ", operand); + const std::string name = operand; std::string statusLine; - if (m_Nickname == operand) + + // always prefer destination + auto ptr = m_Owner.FindDestination(name); + if(ptr != nullptr) { - // check current tunnel - BuildStatusLine(true, nullptr, statusLine); + // tunnel destination exists + BuildStatusLine(false, ptr, statusLine); SendReplyOK(statusLine.c_str()); } else { - // check other - std::string name = operand; - auto ptr = m_Owner.FindDestination(name); - if(ptr != nullptr) + if(m_Nickname == name && !name.empty()) { - BuildStatusLine(false, ptr, statusLine); + // tunnel is incomplete / has not been started yet + BuildStatusLine(true, nullptr, statusLine); SendReplyOK(statusLine.c_str()); } else From fecc0c464070133bfb71b4fe794f4edb5e952e00 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 25 Jun 2019 16:37:06 -0400 Subject: [PATCH 0055/2950] don't call destructor twice --- libi2pd/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.h b/libi2pd/util.h index 6da20ad6..eccdadf7 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -46,7 +46,7 @@ namespace util { auto tmp = m_Head; m_Head = static_cast(*(void * *)m_Head); // next - delete tmp; + ::operator delete ((void *)tmp); } } From 6ccef669203707e0b22544cf1e6a04490cf73230 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 26 Jun 2019 10:47:16 -0400 Subject: [PATCH 0056/2950] call shutdown before close --- libi2pd/NTCP2.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 5b5073f9..368f1b3e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -396,6 +396,10 @@ namespace transport { m_IsTerminated = true; m_IsEstablished = false; + boost::system::error_code ec; + m_Socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); + if (ec) + LogPrint (eLogDebug, "NTCP2: Couldn't shutdown socket: ", ec.message ()); m_Socket.close (); transports.PeerDisconnected (shared_from_this ()); m_Server.RemoveNTCP2Session (shared_from_this ()); From 3acfb129cd1171fbdbec758a21d2294119c68917 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Jul 2019 12:38:55 -0400 Subject: [PATCH 0057/2950] 2.27.0 --- ChangeLog | 10 ++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f06a51b6..d52260ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.27.0] - 2019-07-03 +### Added +- Support of PSK and DH authentication for encrypted LeaseSet2 +### Changed +- Uptime is based on monotonic timer +### Fixed +- BOB status command response +- Correct NTCP2 port if NTCP is disabled +- Flood encrypted LeaseSet2 with store hash + ## [2.26.0] - 2019-06-07 ### Added - HTTP method "PROPFIND" diff --git a/Win32/installer.iss b/Win32/installer.iss index 28df9ea8..b00523da 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.26.0" +#define I2Pd_ver "2.27.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 327d3ec1..b2a83710 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -29,8 +29,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 28 minSdkVersion 14 - versionCode 2260 - versionName "2.26.0" + versionCode 2270 + versionName "2.27.0" ndk { abiFilters 'armeabi-v7a' abiFilters 'x86' diff --git a/appveyor.yml b/appveyor.yml index ddcd651a..dfbc656c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.26.0.{build} +version: 2.27.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 098084d7..1dda44b1 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.26.0 +Version: 2.27.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -110,6 +110,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Wed Jul 3 2019 orignal - 2.27.0 +- update to 2.27.0 + * Fri Jun 7 2019 orignal - 2.26.0 - update to 2.26.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 84fad674..67c7f4bf 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.26.0 +Version: 2.27.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -108,6 +108,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Wed Jul 3 2019 orignal - 2.27.0 +- update to 2.27.0 + * Fri Jun 7 2019 orignal - 2.26.0 - update to 2.26.0 diff --git a/debian/changelog b/debian/changelog index 1bd32f03..0f30a066 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.27.0-1) unstable; urgency=medium + + * updated to version 2.27.0/0.9.41 + + -- orignal Wed, 3 Jul 2019 16:00:00 +0000 + i2pd (2.26.0-1) unstable; urgency=medium * updated to version 2.26.0 diff --git a/libi2pd/version.h b/libi2pd/version.h index 4ac7a7b0..cd96c677 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 26 +#define I2PD_VERSION_MINOR 27 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 40 +#define I2P_VERSION_MICRO 41 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index efb8a4d6..b16d0d5c 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 3f0534134dc30c878b2e15279d2bc1d52bbfda18 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Jul 2019 13:05:39 -0400 Subject: [PATCH 0058/2950] check for malformed b33 --- libi2pd/Blinding.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 14852340..e51c0fcc 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -139,6 +139,11 @@ namespace data { uint8_t addr[40]; // TODO: define length from b33 size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40); + if (l < 32) + { + LogPrint (eLogError, "Blinding: malformed b33 ", b33); + return; + } uint32_t checksum = crc32 (0, addr + 3, l - 3); // checksum is Little Endian addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); From a605e4bab6206c1d710aa1a2c58dcb69a100c2f2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jul 2019 21:33:55 -0400 Subject: [PATCH 0059/2950] send and recieve raw datagrams --- libi2pd/Datagram.cpp | 43 +++++++++++++++++++++++++++++------------ libi2pd/Datagram.h | 26 ++++++++++++++++--------- libi2pd/Destination.cpp | 7 +++++++ 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index ed87a054..d971a83b 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -12,10 +12,8 @@ namespace i2p namespace datagram { DatagramDestination::DatagramDestination (std::shared_ptr owner): - m_Owner (owner.get()), - m_Receiver (nullptr) + m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr) { - m_Identity.FromBase64 (owner->GetIdentity()->ToBase64()); } DatagramDestination::~DatagramDestination () @@ -28,14 +26,15 @@ namespace datagram auto owner = m_Owner; std::vector v(MAX_DATAGRAM_SIZE); uint8_t * buf = v.data(); - auto identityLen = m_Identity.ToBuffer (buf, MAX_DATAGRAM_SIZE); + auto localIdentity = m_Owner->GetIdentity (); + auto identityLen = localIdentity->ToBuffer (buf, MAX_DATAGRAM_SIZE); uint8_t * signature = buf + identityLen; - auto signatureLen = m_Identity.GetSignatureLen (); + auto signatureLen = localIdentity->GetSignatureLen (); uint8_t * buf1 = signature + signatureLen; size_t headerLen = identityLen + signatureLen; memcpy (buf1, payload, len); - if (m_Identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) { uint8_t hash[32]; SHA256(buf1, len, hash); @@ -49,7 +48,13 @@ namespace datagram session->SendMsg(msg); } - + void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) + { + auto msg = CreateDataMessage (payload, len, fromPort, toPort, true); // raw + auto session = ObtainSession(identity); + session->SendMsg(msg); + } + void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) { i2p::data::IdentityEx identity; @@ -82,6 +87,14 @@ namespace datagram LogPrint (eLogWarning, "Datagram signature verification failed"); } + void DatagramDestination::HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) + { + if (m_RawReceiver) + m_RawReceiver (fromPort, toPort, buf, len); + else + LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram"); + } + DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port) { std::lock_guard lock(m_ReceiversMutex); @@ -92,18 +105,24 @@ namespace datagram return r; } - void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) + void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw) { // unzip it uint8_t uncompressed[MAX_DATAGRAM_SIZE]; size_t uncompressedLen = m_Inflator.Inflate (buf, len, uncompressed, MAX_DATAGRAM_SIZE); if (uncompressedLen) - HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen); + { + if (isRaw) + HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen); + else + HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen); + } else LogPrint (eLogWarning, "Datagram: decompression failed"); } - std::shared_ptr DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) + + std::shared_ptr DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw) { auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); @@ -114,7 +133,7 @@ namespace datagram htobe32buf (msg->GetPayload (), size); // length htobe16buf (buf + 4, fromPort); // source port htobe16buf (buf + 6, toPort); // destination port - buf[9] = i2p::client::PROTOCOL_TYPE_DATAGRAM; // datagram protocol + buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_DATAGRAM : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol msg->len += size + 4; msg->FillI2NPMessageHeader (eI2NPData); } @@ -170,7 +189,7 @@ namespace datagram return nullptr; } - DatagramSession::DatagramSession(i2p::client::ClientDestination * localDestination, + DatagramSession::DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent) : m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent), diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 039417ea..0cfec838 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -37,7 +37,7 @@ namespace datagram class DatagramSession : public std::enable_shared_from_this { public: - DatagramSession(i2p::client::ClientDestination * localDestination, const i2p::data::IdentHash & remoteIdent); + DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent); void Start (); void Stop (); @@ -81,7 +81,7 @@ namespace datagram void HandleLeaseSetUpdated(std::shared_ptr ls); private: - i2p::client::ClientDestination * m_LocalDestination; + std::shared_ptr m_LocalDestination; i2p::data::IdentHash m_RemoteIdent; std::shared_ptr m_RemoteLeaseSet; std::shared_ptr m_RoutingSession; @@ -99,22 +99,28 @@ namespace datagram class DatagramDestination { typedef std::function Receiver; + typedef std::function RawReceiver; + public: DatagramDestination (std::shared_ptr owner); ~DatagramDestination (); - void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); - void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); - + void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); + void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); + void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); + void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; void ResetReceiver () { m_Receiver = nullptr; }; void SetReceiver (const Receiver& receiver, uint16_t port) { std::lock_guard lock(m_ReceiversMutex); m_ReceiversByPorts[port] = receiver; }; void ResetReceiver (uint16_t port) { std::lock_guard lock(m_ReceiversMutex); m_ReceiversByPorts.erase (port); }; + void SetRawReceiver (const RawReceiver& receiver) { m_RawReceiver = receiver; }; + void ResetRawReceiver () { m_RawReceiver = nullptr; }; + std::shared_ptr GetInfoForRemote(const i2p::data::IdentHash & remote); // clean up stale sessions @@ -124,17 +130,19 @@ namespace datagram std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); - std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); + std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw = false); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); - + void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + /** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */ Receiver FindReceiver(uint16_t port); private: - i2p::client::ClientDestination * m_Owner; - i2p::data::IdentityEx m_Identity; + + std::shared_ptr m_Owner; Receiver m_Receiver; // default + RawReceiver m_RawReceiver; // default std::mutex m_SessionsMutex; std::map m_Sessions; std::mutex m_ReceiversMutex; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 5187fedc..ef7c7d21 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -977,6 +977,13 @@ namespace client else LogPrint (eLogError, "Destination: Missing datagram destination"); break; + case PROTOCOL_TYPE_RAW: + // raw datagram + if (m_DatagramDestination) + m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, true); + else + LogPrint (eLogError, "Destination: Missing raw datagram destination"); + break; default: LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]); } From cc451809cca87842a8431eafe8bee601fa0bb5a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jul 2019 11:32:56 -0400 Subject: [PATCH 0060/2950] send/receive raw datagrams through the SAM --- libi2pd_client/SAM.cpp | 77 +++++++++++++++++++++++++++++++++++------- libi2pd_client/SAM.h | 15 ++++++-- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index acb9ea80..24e28c73 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -337,8 +337,20 @@ namespace client return; } + SAMSessionType type = eSAMSessionTypeUnknown; + if (style == SAM_VALUE_STREAM) type = eSAMSessionTypeStream; + else if (style == SAM_VALUE_DATAGRAM) type = eSAMSessionTypeDatagram; + else if (style == SAM_VALUE_RAW) type = eSAMSessionTypeRaw; + if (type == eSAMSessionTypeUnknown) + { + // unknown style + SendI2PError("Unknown STYLE"); + return; + } + std::shared_ptr forward = nullptr; - if (style == SAM_VALUE_DATAGRAM && params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end()) + if ((type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) && + params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end()) { // udp forward selected boost::system::error_code e; @@ -379,16 +391,20 @@ namespace client } // create destination - auto session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, ¶ms); + auto session = m_Owner.CreateSession (id, type, destination == SAM_VALUE_TRANSIENT ? "" : destination, ¶ms); if (session) { m_SocketType = eSAMSocketTypeSession; - if (style == SAM_VALUE_DATAGRAM) + if (type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) { session->UDPEndpoint = forward; auto dest = session->localDestination->CreateDatagramDestination (); - dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + 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)); + else // raw + dest->SetRawReceiver (std::bind (&SAMSocket::HandleI2PRawDatagramReceive, shared_from_this (), + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } if (session->localDestination->IsReady ()) @@ -550,7 +566,10 @@ namespace client { i2p::data::IdentityEx dest; dest.FromBase64 (params[SAM_PARAM_DESTINATION]); - d->SendDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); + if (session->Type == eSAMSessionTypeDatagram) + d->SendDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); + else // raw + d->SendRawDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); } else LogPrint (eLogError, "SAM: missing datagram destination"); @@ -926,16 +945,44 @@ namespace client } } + void SAMSocket::HandleI2PRawDatagramReceive (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) + { + LogPrint (eLogDebug, "SAM: raw datagram received ", len); + auto session = m_Owner.FindSession(m_ID); + if(session) + { + auto ep = session->UDPEndpoint; + if (ep) + // udp forward enabled + m_Owner.SendTo(buf, len, ep); + else + { +#ifdef _MSC_VER + size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_RAW_RECEIVED, (long unsigned int)len); +#else + size_t l = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_RAW_RECEIVED, (long unsigned int)len); +#endif + if (len < SAM_SOCKET_BUFFER_SIZE - l) + { + memcpy (m_StreamBuffer + l, buf, len); + WriteI2PData(len + l); + } + else + LogPrint (eLogWarning, "SAM: received raw datagram size ", len," exceeds buffer"); + } + } + } + void SAMSocket::HandleStreamSend(const boost::system::error_code & ec) { m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); } - SAMSession::SAMSession (SAMBridge & parent, const std::string & id, std::shared_ptr dest): + SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type, std::shared_ptr dest): m_Bridge(parent), localDestination (dest), UDPEndpoint(nullptr), - Name(id) + Name(id), Type (type) { } @@ -1061,8 +1108,8 @@ namespace client Accept (); } - std::shared_ptr SAMBridge::CreateSession (const std::string& id, const std::string& destination, - const std::map * params) + std::shared_ptr SAMBridge::CreateSession (const std::string& id, SAMSessionType type, + const std::string& destination, const std::map * params) { std::shared_ptr localDestination = nullptr; if (destination != "") @@ -1102,7 +1149,7 @@ namespace client if (localDestination) { localDestination->Acquire (); - auto session = std::make_shared(*this, id, localDestination); + auto session = 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) @@ -1193,8 +1240,12 @@ namespace client { i2p::data::IdentityEx dest; dest.FromBase64 (destination); - session->localDestination->GetDatagramDestination ()-> - SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); + if (session->Type == eSAMSessionTypeDatagram) + session->localDestination->GetDatagramDestination ()-> + SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); + else // raw + session->localDestination->GetDatagramDestination ()-> + SendRawDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); } else LogPrint (eLogError, "SAM: Session ", sessionID, " not found"); diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 7cd3fd4c..44ad752d 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -46,6 +46,7 @@ namespace client const char SAM_NAMING_LOOKUP[] = "NAMING LOOKUP"; const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n"; + const char SAM_RAW_RECEIVED[] = "RAW RECEIVED SIZE=%lu\n"; const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=KEY_NOT_FOUND NAME=%s\n"; const char SAM_PARAM_MIN[] = "MIN"; @@ -111,6 +112,7 @@ namespace client void HandleI2PAccept (std::shared_ptr stream); void HandleWriteI2PData (const boost::system::error_code& ecode, size_t sz); void HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + void HandleI2PRawDatagramReceive (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void ProcessSessionCreate (char * buf, size_t len); void ProcessStreamConnect (char * buf, size_t len, size_t rem); @@ -149,14 +151,23 @@ namespace client std::shared_ptr m_Stream; }; + enum SAMSessionType + { + eSAMSessionTypeUnknown, + eSAMSessionTypeStream, + eSAMSessionTypeDatagram, + eSAMSessionTypeRaw + }; + 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, std::shared_ptr dest); + SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest); ~SAMSession (); void CloseStreams (); @@ -173,7 +184,7 @@ namespace client void Stop (); boost::asio::io_service& GetService () { return m_Service; }; - std::shared_ptr CreateSession (const std::string& id, const std::string& destination, // empty string means transient + std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); std::shared_ptr FindSession (const std::string& id) const; From a204841abbe5f2c2c73bfdf9787d800dd974a060 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jul 2019 13:30:31 -0400 Subject: [PATCH 0061/2950] handle RAW SEND --- libi2pd_client/SAM.cpp | 2 +- libi2pd_client/SAM.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 24e28c73..224d84e8 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -259,7 +259,7 @@ 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_DATAGRAM_SEND)) + else if (!strcmp (m_Buffer, SAM_DATAGRAM_SEND) || !strcmp (m_Buffer, SAM_RAW_SEND)) { size_t len = bytes_transferred - (separator - m_Buffer) - 1; size_t processed = ProcessDatagramSend (separator + 1, len, eol + 1); diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 44ad752d..aebdccb6 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -40,6 +40,7 @@ namespace client const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR\n"; const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT"; const char SAM_DATAGRAM_SEND[] = "DATAGRAM SEND"; + const char SAM_RAW_SEND[] = "RAW SEND"; const char SAM_DEST_GENERATE[] = "DEST GENERATE"; const char SAM_DEST_REPLY[] = "DEST REPLY PUB=%s PRIV=%s\n"; const char SAM_DEST_REPLY_I2P_ERROR[] = "DEST REPLY RESULT=I2P_ERROR\n"; From a090114066e94a3686f465ad94b89928315f7f56 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jul 2019 13:31:49 -0400 Subject: [PATCH 0062/2950] send data message wih raw type fpr raw datagrams --- libi2pd/Datagram.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index d971a83b..7e04fce8 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -133,7 +133,7 @@ namespace datagram htobe32buf (msg->GetPayload (), size); // length htobe16buf (buf + 4, fromPort); // source port htobe16buf (buf + 6, toPort); // destination port - buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_DATAGRAM : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol + buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol msg->len += size + 4; msg->FillI2NPMessageHeader (eI2NPData); } From 7d68ccca53edf5213e469dc8861f77f2a598ee3d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jul 2019 15:37:32 -0400 Subject: [PATCH 0063/2950] create encrypted LeaseSet2 with authentication --- libi2pd/LeaseSet.cpp | 69 ++++++++++++++++++++++++++++++++++++++++---- libi2pd/LeaseSet.h | 17 ++++++++++- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 69a29377..46629d37 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -809,12 +809,20 @@ namespace data m_Buffer[0] = storeType; } - LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, i2p::data::SigningKeyType blindedKeyType): + LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, + LeaseSetAuthType authType, std::shared_ptr > authKeys): LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { size_t lenInnerPlaintext = ls->GetBufferLen () + 1, lenOuterPlaintext = lenInnerPlaintext + 32 + 1, lenOuterCiphertext = lenOuterPlaintext + 32; m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; + uint8_t layer1Flags = 0; + if (authKeys) + { + if (authType == eLeaseSetAuthTypeDH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 + else if (authType == eLeaseSetAuthTypePSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 + m_BufferLen += authKeys->size ()*40 + 2; // auth data len + } m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; BlindedPublicKey blindedKey (ls->GetIdentity ()); @@ -823,9 +831,9 @@ namespace data i2p::util::GetDateString (timestamp, date); 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 (blindedKeyType, blindedPriv)); + std::unique_ptr blindedSigner (i2p::data::PrivateKeys::CreateSigner (blindedKey.GetBlindedSigType (), blindedPriv)); auto offset = 1; - htobe16buf (m_Buffer + offset, blindedKeyType); offset += 2; // Blinded Public Key Sig Type + htobe16buf (m_Buffer + offset, blindedKey.GetBlindedSigType ()); offset += 2; // Blinded Public Key Sig Type memcpy (m_Buffer + offset, blindedPub, publicKeyLen); offset += publicKeyLen; // Blinded Public Key htobe32buf (m_Buffer + offset, timestamp); offset += 4; // published timestamp (seconds) auto nextMidnight = (timestamp/86400LL + 1)*86400LL; // 86400 = 24*3600 seconds @@ -847,12 +855,27 @@ namespace data i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L1K", keys1); offset += 32; // outerSalt uint8_t * outerPlainText = m_Buffer + offset; - m_Buffer[offset] = 0; offset++; // flag + m_Buffer[offset] = layer1Flags; offset++; // layer 1 flags + // auth data + uint8_t innerInput[68]; // authCookie || subcredential || publishedTimestamp + if (layer1Flags) + { + RAND_bytes (innerInput, 32); // authCookie + htobe16buf (m_Buffer + offset, authKeys->size ()); offset += 2; // num clients + CreateClientAuthData (subcredential, authType, authKeys, innerInput, m_Buffer); + offset += authKeys->size ()*40; // auth clients + } // Layer 2 // keys = HKDF(outerSalt, outerInput, "ELS2_L2K", 44) uint8_t keys2[64]; // 44 bytes actual data RAND_bytes (m_Buffer + offset, 32); // innerSalt = CSRNG(32) - i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L2K", keys2); + if (layer1Flags) + { + memcpy (innerInput + 32, subcredential, 36); // + subcredential || publishedTimestamp + i2p::crypto::HKDF (m_Buffer + offset, innerInput, 68, "ELS2_L2K", keys2); + } + else + i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L2K", keys2); // no authCookie offset += 32; // innerSalt m_Buffer[offset] = ls->GetStoreType (); memcpy (m_Buffer + offset + 1, ls->GetBuffer (), ls->GetBufferLen ()); @@ -879,6 +902,40 @@ namespace data else LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); } - + + void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, LeaseSetAuthType authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const + { + if (authType == eLeaseSetAuthTypeDH) + { + i2p::crypto::X25519Keys ek; + ek.GenerateKeys (); // esk and epk + uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp + memcpy (authInput + 64, subcredential, 36); + for (auto& it: *authKeys) + { + ek.Agree (it, authInput); // sharedSecret = DH(esk, cpk_i) + memcpy (authInput + 32, it, 32); + uint8_t okm[64]; // 52 actual data + i2p::crypto::HKDF (ek.GetPublicKey (), authInput, 100, "ELS2_XCA", okm); + memcpy (authClients, okm + 44, 8); authClients += 8; // clientID_i + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authClients); authClients += 32; // clientCookie_i + } + } + else // assume PSK + { + uint8_t authSalt[32]; + RAND_bytes (authSalt, 32); + uint8_t authInput[68]; // authInput = psk_i || subcredential || publishedTimestamp + memcpy (authInput + 32, subcredential, 36); + for (auto& it: *authKeys) + { + memcpy (authInput, it, 32); + uint8_t okm[64]; // 52 actual data + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + memcpy (authClients, okm + 44, 8); authClients += 8; // clientID_i + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authClients); authClients += 32; // clientCookie_i + } + } + } } } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index a2ed6fba..c2b88da6 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -247,17 +247,32 @@ namespace data size_t m_BufferLen; }; + class LocalEncryptedLeaseSet2: public LocalLeaseSet2 { public: - LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, i2p::data::SigningKeyType blindedKeyType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); + enum LeaseSetAuthType + { + eLeaseSetAuthTypeNone = 0, + eLeaseSetAuthTypeDH = 1, + eLeaseSetAuthTypePSK = 2 + }; + typedef i2p::data::Tag<32> AuthPublicKey; + + public: + + LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, LeaseSetAuthType authType = eLeaseSetAuthTypeNone, std::shared_ptr > authKeys = nullptr); LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP const IdentHash& GetStoreHash () const { return m_StoreHash; }; std::shared_ptr GetInnerLeaseSet () const { return m_InnerLeaseSet; }; + private: + + void CreateClientAuthData (const uint8_t * subcredential, LeaseSetAuthType authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const; + private: IdentHash m_StoreHash; From 99e1b740236ee64d166b0e4c7fdd50d25ea76913 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jul 2019 15:40:59 -0400 Subject: [PATCH 0064/2950] create encrypted LeaseSet2 with authentication --- libi2pd/LeaseSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 46629d37..d0eafd1d 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -821,7 +821,7 @@ namespace data { if (authType == eLeaseSetAuthTypeDH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 else if (authType == eLeaseSetAuthTypePSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 - m_BufferLen += authKeys->size ()*40 + 2; // auth data len + if (layer1Flags) m_BufferLen += authKeys->size ()*40 + 2; // auth data len } m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; From 925e8316c782485601417a273239b5f3d969cd30 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jul 2019 20:58:17 -0400 Subject: [PATCH 0065/2950] read i2cp.leaseSetAuthType, i2cp.leaseSetClient.dh.nnn and i2cp.leaseSetClient.psk.nnn from tunnel config --- libi2pd/Destination.h | 5 ++++- libi2pd_client/ClientContext.cpp | 19 +++++++++++++++++++ libi2pd_client/ClientContext.h | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 35a9dbae..25f2f1c1 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -56,7 +56,10 @@ namespace client const int DEFAULT_LEASESET_TYPE = 1; 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 + // latency const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; const int DEFAULT_MIN_TUNNEL_LATENCY = 0; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c286007c..e10c1e07 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -381,6 +381,16 @@ namespace client return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); } + template + void ClientContext::ReadI2CPOptionsGroup (const Section& section, const std::string& group, std::map& options) const + { + for (auto it: section.second) + { + if (it.first.length () >= group.length () && !it.first.compare (0, group.length (), group)) + options[it.first] = it.second.get_value (""); + } + } + template void ClientContext::ReadI2CPOptions (const Section& section, std::map& options) const { @@ -397,6 +407,15 @@ namespace client 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; + auto authType = GetI2CPOption(section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0); + if (authType != "0") // auth is set + { + options[I2CP_PARAM_LEASESET_TYPE] = authType; + if (authType == "1") // DH + ReadI2CPOptionsGroup (section, I2CP_PARAM_LEASESET_CLIENT_DH, options); + else if (authType == "2") // PSK + ReadI2CPOptionsGroup (section, I2CP_PARAM_LEASESET_CLIENT_PSK, options); + } } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 71e052c3..94aa8594 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -95,6 +95,8 @@ namespace client template std::string GetI2CPStringOption (const Section& section, const std::string& name, const std::string& value) const; // GetI2CPOption with string default value template + void ReadI2CPOptionsGroup (const Section& section, const std::string& group, std::map& options) const; + template void ReadI2CPOptions (const Section& section, std::map& options) const; // for tunnels void ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const; // for HTTP and SOCKS proxy From 54071b0e5dbc3b3296f64a6ed98f372945db477f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Jul 2019 11:48:30 -0400 Subject: [PATCH 0066/2950] set and handle unpublished LeaseSet flag --- libi2pd/Destination.cpp | 2 +- libi2pd/Destination.h | 1 + libi2pd/LeaseSet.cpp | 4 +++- libi2pd/LeaseSet.h | 7 +++++-- libi2pd/NetDb.cpp | 16 ++++++++++++---- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ef7c7d21..ea884aa4 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1147,7 +1147,7 @@ namespace client // standard LS2 (type 3) first auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, - m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels); + m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic ()); if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) // encrypt if type 5 ls2 = std::make_shared (ls2, m_Keys); leaseSet = ls2; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 25f2f1c1..dcbe9768 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -134,6 +134,7 @@ namespace client void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; }; + bool IsPublic () const { return m_IsPublic; }; virtual void CleanupDestination () {}; // additional clean up in derived classes // I2CP virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index d0eafd1d..bd2fca75 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -302,6 +302,7 @@ namespace data return; } } + if (flags & LEASESET2_FLAG_UNPUBLISHED_LEASESET) m_IsPublic = false; // type specific part size_t s = 0; switch (m_StoreType) @@ -741,7 +742,7 @@ namespace data LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, - std::vector > tunnels): + std::vector > tunnels, bool isPublic): LocalLeaseSet (keys.GetPublic (), nullptr, 0) { auto identity = keys.GetPublic (); @@ -756,6 +757,7 @@ namespace data flags |= LEASESET2_FLAG_OFFLINE_KEYS; m_BufferLen += keys.GetOfflineSignature ().size (); } + if (!isPublic) flags |= LEASESET2_FLAG_UNPUBLISHED_LEASESET; m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = storeType; diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index c2b88da6..03e0e543 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -129,7 +129,8 @@ namespace data const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7; const uint16_t LEASESET2_FLAG_OFFLINE_KEYS = 0x0001; - + const uint16_t LEASESET2_FLAG_UNPUBLISHED_LEASESET = 0x0002; + class LeaseSet2: public LeaseSet { public: @@ -139,6 +140,7 @@ namespace data uint8_t GetStoreType () const { return m_StoreType; }; uint8_t GetOrigStoreType () const { return m_OrigStoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; + bool IsPublic () const { return m_IsPublic; }; std::shared_ptr GetTransientVerifier () const { return m_TransientVerifier; }; void Update (const uint8_t * buf, size_t len, bool verifySignature); @@ -162,6 +164,7 @@ namespace data uint8_t m_StoreType, m_OrigStoreType; uint32_t m_PublishedTimestamp = 0; + bool m_IsPublic = true; std::shared_ptr m_TransientVerifier; std::shared_ptr m_Encryptor; // for standardLS2 }; @@ -227,7 +230,7 @@ namespace data LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, - std::vector > tunnels); + std::vector > tunnels, bool isPublic); LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP virtual ~LocalLeaseSet2 () { delete[] m_Buffer; }; diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index b7479744..4461c094 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -307,10 +307,18 @@ namespace data if (it == m_LeaseSets.end () || it->second->GetStoreType () != storeType || leaseSet->GetPublishedTimestamp () > it->second->GetPublishedTimestamp ()) { - // TODO: implement actual update - LogPrint (eLogInfo, "NetDb: LeaseSet2 updated: ", ident.ToBase32()); - m_LeaseSets[ident] = leaseSet; - return true; + if (leaseSet->IsPublic ()) + { + // TODO: implement actual update + LogPrint (eLogInfo, "NetDb: LeaseSet2 updated: ", ident.ToBase32()); + m_LeaseSets[ident] = leaseSet; + return true; + } + else + { + LogPrint (eLogWarning, "NetDb: Unpublished LeaseSet2 received: ", ident.ToBase32()); + m_LeaseSets.erase (ident); + } } } else From 97d9795fc9a2c672e2e97a31b3da9141364f1814 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 16 Jul 2019 16:31:17 -0400 Subject: [PATCH 0067/2950] pass encrepted LeaseSet auth keys --- libi2pd/Destination.cpp | 65 ++++++++++++++++++++++++++++++++++++----- libi2pd/Destination.h | 6 ++++ libi2pd/LeaseSet.cpp | 10 +++---- libi2pd/LeaseSet.h | 20 +++++-------- 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ea884aa4..9355e75d 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -846,7 +846,7 @@ namespace client ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), - m_ReadyChecker(GetService()) + m_ReadyChecker(GetService()), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) { if (keys.IsOfflineSignature () && GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // offline keys can be published with LS2 only @@ -868,12 +868,46 @@ namespace client if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); - // extract streaming params - if (params) + try + { + if (params) + { + // extract streaming params + auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY); + if (it != params->end ()) + m_StreamingAckDelay = std::stoi(it->second); + + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + { + // authentication for encrypted LeaseSet + it = params->find (I2CP_PARAM_LEASESET_AUTH_TYPE); + m_AuthType = std::stoi (it->second); + if (m_AuthType > 0) + { + m_AuthKeys = std::make_shared >(); + if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); + else if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); + else + { + LogPrint (eLogError, "Destination: Unexpected auth type ", m_AuthType); + m_AuthType = 0; + } + if (m_AuthKeys->size ()) + LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read"); + else + { + LogPrint (eLogError, "Destination: No auth keys read for auth type ", m_AuthType); + m_AuthKeys = nullptr; + } + } + } + } + } + catch (std::exception & ex) { - auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY); - if (it != params->end ()) - m_StreamingAckDelay = std::stoi(it->second); + LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what()); } } @@ -1149,7 +1183,7 @@ namespace client auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic ()); if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) // encrypt if type 5 - ls2 = std::make_shared (ls2, m_Keys); + ls2 = std::make_shared (ls2, m_Keys, m_AuthType, m_AuthKeys); leaseSet = ls2; } SetLeaseSet (leaseSet); @@ -1168,5 +1202,22 @@ namespace client LogPrint (eLogError, "Destinations: decryptor is not set"); return false; } + + void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) + { + for (auto it: *params) + if (it.first.length () >= group.length () && !it.first.compare (0, group.length (), group)) + { + auto pos = it.second.find (':'); + if (pos != std::string::npos) + { + i2p::data::AuthPublicKey pubKey; + if (pubKey.FromBase64 (it.second.substr (pos+1))) + m_AuthKeys->push_back (pubKey); + else + LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1)); + } + } + } } } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index dcbe9768..148a6101 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -252,6 +252,9 @@ namespace client void ScheduleCheckForReady(ReadyPromise * p); void HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p); #endif + + void ReadAuthKey (const std::string& group, const std::map * params); + private: i2p::data::PrivateKeys m_Keys; @@ -267,6 +270,9 @@ namespace client boost::asio::deadline_timer m_ReadyChecker; + int m_AuthType; + std::shared_ptr > m_AuthKeys; + public: // for HTTP only diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index bd2fca75..bc50e013 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -812,7 +812,7 @@ namespace data } LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, - LeaseSetAuthType authType, std::shared_ptr > authKeys): + int authType, std::shared_ptr > authKeys): LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { size_t lenInnerPlaintext = ls->GetBufferLen () + 1, lenOuterPlaintext = lenInnerPlaintext + 32 + 1, @@ -821,8 +821,8 @@ namespace data uint8_t layer1Flags = 0; if (authKeys) { - if (authType == eLeaseSetAuthTypeDH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 - else if (authType == eLeaseSetAuthTypePSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 + if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 + else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 if (layer1Flags) m_BufferLen += authKeys->size ()*40 + 2; // auth data len } m_Buffer = new uint8_t[m_BufferLen + 1]; @@ -905,9 +905,9 @@ namespace data LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); } - void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, LeaseSetAuthType authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const + void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const { - if (authType == eLeaseSetAuthTypeDH) + if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) { i2p::crypto::X25519Keys ek; ek.GenerateKeys (); // esk and epk diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 03e0e543..b9979e00 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -251,21 +251,17 @@ namespace data }; + const int ENCRYPTED_LEASESET_AUTH_TYPE_NONE = 0; + const int ENCRYPTED_LEASESET_AUTH_TYPE_DH = 1; + const int ENCRYPTED_LEASESET_AUTH_TYPE_PSK = 2; + + typedef i2p::data::Tag<32> AuthPublicKey; + class LocalEncryptedLeaseSet2: public LocalLeaseSet2 { public: - enum LeaseSetAuthType - { - eLeaseSetAuthTypeNone = 0, - eLeaseSetAuthTypeDH = 1, - eLeaseSetAuthTypePSK = 2 - }; - typedef i2p::data::Tag<32> AuthPublicKey; - - public: - - LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, LeaseSetAuthType authType = eLeaseSetAuthTypeNone, std::shared_ptr > authKeys = nullptr); + LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType = ENCRYPTED_LEASESET_AUTH_TYPE_NONE, std::shared_ptr > authKeys = nullptr); LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP @@ -274,7 +270,7 @@ namespace data private: - void CreateClientAuthData (const uint8_t * subcredential, LeaseSetAuthType authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const; + void CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const; private: From 2c9fa2f738a87ba2dd4e0355805e27232e596d8d Mon Sep 17 00:00:00 2001 From: Zetok Zalbavar Date: Wed, 24 Jul 2019 11:15:31 +0100 Subject: [PATCH 0068/2950] Fix and update i2pd.service - /var/run on distros with systemd is a symlink to /run , hence the path changes. - Remove unnecessary runtime dependency on `/bin/kill` which is provided by `procps` and might not be available on minimal installs (e.g. containers). Instead use `/bin/sh` which has a built-in `kill`. - `PrivateDevices=yes` causes i2pd to fail to start on latest Debian unstable. Service exits with the following: ``` i2pd.service: Failed to execute command: Operation not permitted i2pd.service: Failed at step EXEC spawning /usr/sbin/i2pd: Operation not permitted i2pd.service: Control process exited, code=exited, status=203/EXEC i2pd.service: Failed with result 'exit-code'. Failed to start I2P Router written in C++. ``` According to `man systemd.exec` exit code 203 corresponds to the `execve(2)` system call failing. So it looks like i2pd tries to do something it shouldn't be doing. The proper fix would be in i2pd, but who knows how long that would actually take, so to allow people to actually launch i2pd in meanwhile the line has been removed from the service file. Also, surprisingly, right after installing i2pd it started without any problems, and only after restarting the box i2pd started to fail for no apparent reason. --- contrib/i2pd.service | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/contrib/i2pd.service b/contrib/i2pd.service index a8eeb8d3..8ce851b0 100644 --- a/contrib/i2pd.service +++ b/contrib/i2pd.service @@ -11,9 +11,9 @@ RuntimeDirectoryMode=0700 LogsDirectory=i2pd LogsDirectoryMode=0700 Type=forking -ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service -ExecReload=/bin/kill -HUP $MAINPID -PIDFile=/var/run/i2pd/i2pd.pid +ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service +ExecReload=/bin/sh -c "kill -HUP $MAINPID" +PIDFile=/run/i2pd/i2pd.pid ### Uncomment, if auto restart needed #Restart=on-failure @@ -27,7 +27,6 @@ KillSignal=SIGQUIT LimitNOFILE=4096 # To enable write of coredump uncomment this #LimitCORE=infinity -PrivateDevices=yes [Install] WantedBy=multi-user.target From 254d2b82b3e9613514c21eaaac97a3c39f550620 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 26 Jul 2019 14:23:21 -0400 Subject: [PATCH 0069/2950] fixed #1393. store streams by recvStreamID --- libi2pd/Streaming.cpp | 30 ++++++++++++++---------------- libi2pd/Streaming.h | 6 ++++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 7b1f187b..b8ce8167 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -964,7 +964,6 @@ namespace stream StreamingDestination::StreamingDestination (std::shared_ptr owner, uint16_t localPort, bool gzip): m_Owner (owner), m_LocalPort (localPort), m_Gzip (gzip), - m_LastIncomingReceiveStreamID (0), m_PendingIncomingTimer (m_Owner->GetService ()) { } @@ -1013,18 +1012,17 @@ namespace stream if (packet->IsSYN () && !packet->GetSeqn ()) // new incoming stream { uint32_t receiveStreamID = packet->GetReceiveStreamID (); - if (receiveStreamID == m_LastIncomingReceiveStreamID) + auto it1 = m_IncomingStreams.find (receiveStreamID); + if (it1 != m_IncomingStreams.end ()) { // already pending LogPrint(eLogWarning, "Streaming: Incoming streaming with rSID=", receiveStreamID, " already exists"); DeletePacket (packet); // drop it, because previous should be connected return; } - auto incomingStream = CreateNewIncomingStream (); + auto incomingStream = CreateNewIncomingStream (receiveStreamID); incomingStream->HandleNextPacket (packet); // SYN auto ident = incomingStream->GetRemoteIdentity(); - - m_LastIncomingReceiveStreamID = receiveStreamID; // handle saved packets if any { @@ -1062,13 +1060,13 @@ namespace stream else // follow on packet without SYN { uint32_t receiveStreamID = packet->GetReceiveStreamID (); - for (auto& it: m_Streams) - if (it.second->GetSendStreamID () == receiveStreamID) - { - // found - it.second->HandleNextPacket (packet); - return; - } + auto it1 = m_IncomingStreams.find (receiveStreamID); + if (it1 != m_IncomingStreams.end ()) + { + // found + it1->second->HandleNextPacket (packet); + return; + } // save follow on packet auto it = m_SavedPackets.find (receiveStreamID); if (it != m_SavedPackets.end ()) @@ -1105,11 +1103,12 @@ namespace stream return s; } - std::shared_ptr StreamingDestination::CreateNewIncomingStream () + std::shared_ptr StreamingDestination::CreateNewIncomingStream (uint32_t receiveStreamID) { auto s = std::make_shared (m_Owner->GetService (), *this); std::unique_lock l(m_StreamsMutex); m_Streams[s->GetRecvStreamID ()] = s; + m_IncomingStreams[receiveStreamID] = s; return s; } @@ -1118,9 +1117,8 @@ namespace stream if (stream) { std::unique_lock l(m_StreamsMutex); - auto it = m_Streams.find (stream->GetRecvStreamID ()); - if (it != m_Streams.end ()) - m_Streams.erase (it); + m_Streams.erase (stream->GetRecvStreamID ()); + m_IncomingStreams.erase (stream->GetSendStreamID ()); } } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index ba52464f..49962507 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -269,8 +269,10 @@ namespace stream void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); + private: + void HandleNextPacket (Packet * packet); - std::shared_ptr CreateNewIncomingStream (); + std::shared_ptr CreateNewIncomingStream (uint32_t receiveStreamID); void HandlePendingIncomingTimer (const boost::system::error_code& ecode); private: @@ -280,8 +282,8 @@ namespace stream bool m_Gzip; // gzip compression of data messages std::mutex m_StreamsMutex; std::map > m_Streams; // sendStreamID->stream + std::map > m_IncomingStreams; // receiveStreamID->stream Acceptor m_Acceptor; - uint32_t m_LastIncomingReceiveStreamID; std::list > m_PendingIncomingStreams; boost::asio::deadline_timer m_PendingIncomingTimer; std::map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN From a6558a61a7d36809a0943713e0ed07ad26c3cfcd Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Aug 2019 12:54:24 -0400 Subject: [PATCH 0070/2950] Recognize RedDSA_SHA512_Ed25519 signature type --- libi2pd_client/SAM.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 224d84e8..dda566c9 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1011,7 +1011,8 @@ namespace client {"ECDSA_SHA256_P521", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521}, {"EdDSA_SHA512_Ed25519", i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519}, {"GOST_GOSTR3411256_GOSTR3410CRYPTOPROA", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256}, - {"GOST_GOSTR3411512_GOSTR3410TC26A512", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512} + {"GOST_GOSTR3411512_GOSTR3410TC26A512", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512}, + {"RedDSA_SHA512_Ed25519", i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519}, } { } From db107602bdc3913efdfd14b409e62ac0468fcf8c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Aug 2019 13:48:39 -0400 Subject: [PATCH 0071/2950] handle messages with \r\n --- libi2pd_client/SAM.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index dda566c9..766a1940 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -239,6 +239,7 @@ namespace client char * eol = (char *)memchr (m_Buffer, '\n', bytes_transferred); if (eol) { + if (eol > m_Buffer && eol[-1] == '\r') eol--; *eol = 0; char * separator = strchr (m_Buffer, ' '); if (separator) From e6a09b49c936180e6bd7ad9add6be658a21eb02e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Aug 2019 15:43:03 -0400 Subject: [PATCH 0072/2950] published encrypted flag --- libi2pd/Destination.cpp | 5 +++-- libi2pd/LeaseSet.cpp | 13 ++++++++++++- libi2pd/LeaseSet.h | 8 ++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 9355e75d..34ff374f 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1180,9 +1180,10 @@ namespace client { // standard LS2 (type 3) first auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; + bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, - m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic ()); - if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) // encrypt if type 5 + m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic (), isPublishedEncrypted); + if (isPublishedEncrypted) // encrypt if type 5 ls2 = std::make_shared (ls2, m_Keys, m_AuthType, m_AuthKeys); leaseSet = ls2; } diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index bc50e013..8cbb3341 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -303,6 +303,11 @@ namespace data } } if (flags & LEASESET2_FLAG_UNPUBLISHED_LEASESET) m_IsPublic = false; + if (flags & LEASESET2_FLAG_PUBLISHED_ENCRYPTED) + { + m_IsPublishedEncrypted = true; + m_IsPublic = true; + } // type specific part size_t s = 0; switch (m_StoreType) @@ -742,7 +747,8 @@ namespace data LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, - std::vector > tunnels, bool isPublic): + std::vector > tunnels, + bool isPublic, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) { auto identity = keys.GetPublic (); @@ -757,6 +763,11 @@ namespace data flags |= LEASESET2_FLAG_OFFLINE_KEYS; m_BufferLen += keys.GetOfflineSignature ().size (); } + if (isPublishedEncrypted) + { + flags |= LEASESET2_FLAG_PUBLISHED_ENCRYPTED; + isPublic = true; + } if (!isPublic) flags |= LEASESET2_FLAG_UNPUBLISHED_LEASESET; m_Buffer = new uint8_t[m_BufferLen + 1]; diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index b9979e00..2199ac32 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -82,6 +82,7 @@ namespace data virtual uint8_t GetOrigStoreType () const { return NETDB_STORE_TYPE_LEASESET; }; virtual uint32_t GetPublishedTimestamp () const { return 0; }; // should be set for LeaseSet2 only virtual std::shared_ptr GetTransientVerifier () const { return nullptr; }; + virtual bool IsPublishedEncrypted () const { return false; }; // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_Identity; }; @@ -130,6 +131,7 @@ namespace data const uint16_t LEASESET2_FLAG_OFFLINE_KEYS = 0x0001; const uint16_t LEASESET2_FLAG_UNPUBLISHED_LEASESET = 0x0002; + const uint16_t LEASESET2_FLAG_PUBLISHED_ENCRYPTED = 0x0004; class LeaseSet2: public LeaseSet { @@ -141,6 +143,7 @@ namespace data uint8_t GetOrigStoreType () const { return m_OrigStoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; bool IsPublic () const { return m_IsPublic; }; + bool IsPublishedEncrypted () const { return m_IsPublishedEncrypted; }; std::shared_ptr GetTransientVerifier () const { return m_TransientVerifier; }; void Update (const uint8_t * buf, size_t len, bool verifySignature); @@ -164,7 +167,7 @@ namespace data uint8_t m_StoreType, m_OrigStoreType; uint32_t m_PublishedTimestamp = 0; - bool m_IsPublic = true; + bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; std::shared_ptr m_Encryptor; // for standardLS2 }; @@ -230,7 +233,8 @@ namespace data LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, - std::vector > tunnels, bool isPublic); + 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 virtual ~LocalLeaseSet2 () { delete[] m_Buffer; }; From 3872c2a3f55f634971b51f6a0edbb7002e746488 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Aug 2019 16:18:00 -0400 Subject: [PATCH 0073/2950] use published encrypted instead orig type --- libi2pd/LeaseSet.cpp | 4 ++-- libi2pd/LeaseSet.h | 4 +--- libi2pd/Streaming.cpp | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 8cbb3341..008a4594 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -252,7 +252,7 @@ namespace data } LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases): - LeaseSet (storeLeases), m_StoreType (storeType), m_OrigStoreType (storeType) + LeaseSet (storeLeases), m_StoreType (storeType) { SetBuffer (buf, len); if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) @@ -262,7 +262,7 @@ namespace data } LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret): - LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_OrigStoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { ReadFromBufferEncrypted (buf, len, key, secret); } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 2199ac32..935aca37 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -79,7 +79,6 @@ namespace data bool operator== (const LeaseSet& other) const { return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); }; virtual uint8_t GetStoreType () const { return NETDB_STORE_TYPE_LEASESET; }; - virtual uint8_t GetOrigStoreType () const { return NETDB_STORE_TYPE_LEASESET; }; virtual uint32_t GetPublishedTimestamp () const { return 0; }; // should be set for LeaseSet2 only virtual std::shared_ptr GetTransientVerifier () const { return nullptr; }; virtual bool IsPublishedEncrypted () const { return false; }; @@ -140,7 +139,6 @@ namespace data LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true); LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr); // store type 5, called from local netdb only uint8_t GetStoreType () const { return m_StoreType; }; - uint8_t GetOrigStoreType () const { return m_OrigStoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; bool IsPublic () const { return m_IsPublic; }; bool IsPublishedEncrypted () const { return m_IsPublishedEncrypted; }; @@ -165,7 +163,7 @@ namespace data private: - uint8_t m_StoreType, m_OrigStoreType; + uint8_t m_StoreType; uint32_t m_PublishedTimestamp = 0; bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index b8ce8167..c8ccdcdb 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -918,7 +918,7 @@ namespace stream { expired = false; // time to request - if (m_RemoteLeaseSet->GetOrigStoreType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + if (m_RemoteLeaseSet->IsPublishedEncrypted ()) m_LocalDestination.GetOwner ()->RequestDestinationWithEncryptedLeaseSet ( std::make_shared(m_RemoteIdentity)); else From ad9c11cd9242272c1629bf494bae6bfe89902c78 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Aug 2019 22:16:26 -0400 Subject: [PATCH 0074/2950] correct parsing of addreses containing # --- libi2pd_client/AddressBook.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 75d95da1..14ed89a7 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -422,9 +422,9 @@ namespace client std::string name = s.substr(0, pos++); std::string addr = s.substr(pos); - size_t pos = s.find('#'); + size_t pos = addr.find('#'); if (pos != std::string::npos) - addr = addr.substr(pos); // remove comments + addr = addr.substr(0, pos); // remove comments auto ident = std::make_shared (); if (!ident->FromBase64(addr)) { From c8cbf425ac5d52304ce5f268639c65e4def7ee30 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 13 Aug 2019 14:55:18 -0400 Subject: [PATCH 0075/2950] check and send netid for NTCP2 and SSU --- libi2pd/NTCP2.cpp | 6 ++++++ libi2pd/SSUSession.cpp | 10 +++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 368f1b3e..6d235abe 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -161,6 +161,7 @@ namespace transport // fill options uint8_t options[32]; // actual options size is 16 bytes memset (options, 0, 16); + options[0] = i2p::context.GetNetID (); // network ID options[1] = 2; // ver htobe16buf (options + 2, paddingLength); // padLen // m3p2Len @@ -248,6 +249,11 @@ namespace transport if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionRequestBuffer + 32, 16, m_H, 32, m_K, nonce, options, 16, false)) // decrypt { // options + if (options[0] && options[0] != i2p::context.GetNetID ()) + { + LogPrint (eLogWarning, "NTCP2: SessionRequest networkID ", (int)options[0], " mismatch. Expected ", i2p::context.GetNetID ()); + return false; + } if (options[1] == 2) // ver is always 2 { paddingLen = bufbe16toh (options + 2); diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index a7497fd1..88dbcf04 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1,4 +1,5 @@ #include +#include "version.h" #include "Crypto.h" #include "Log.h" #include "Timestamp.h" @@ -729,7 +730,8 @@ namespace transport encryption.Encrypt (encrypted, encryptedLen, encrypted); // assume actual buffer size is 18 (16 + 2) bytes more memcpy (buf + len, iv, 16); - htobe16buf (buf + len + 16, encryptedLen); + uint16_t netid = i2p::context.GetNetID (); + htobe16buf (buf + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, macKey, header->mac); } @@ -750,7 +752,8 @@ namespace transport m_SessionKeyEncryption.Encrypt (encrypted, encryptedLen, encrypted); // assume actual buffer size is 18 (16 + 2) bytes more memcpy (buf + len, header->iv, 16); - htobe16buf (buf + len + 16, encryptedLen); + uint16_t netid = i2p::context.GetNetID (); + htobe16buf (buf + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, m_MacKey, header->mac); } @@ -799,7 +802,8 @@ namespace transport uint16_t encryptedLen = len - (encrypted - buf); // assume actual buffer size is 18 (16 + 2) bytes more memcpy (buf + len, header->iv, 16); - htobe16buf (buf + len + 16, encryptedLen); + uint16_t netid = i2p::context.GetNetID (); + htobe16buf (buf + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); uint8_t digest[16]; i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, macKey, digest); return !memcmp (header->mac, digest, 16); From 099adab9ed64f3b428ad30671942c0cb7b26741a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 16 Aug 2019 21:45:44 +0300 Subject: [PATCH 0076/2950] Update README.md update head badges links, add snapcraft badge --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 540e3bed..b5fb8f7e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -![GitHub release](https://img.shields.io/github/release/PurpleI2P/i2pd.svg?label=latest%20release) -![GitHub](https://img.shields.io/github/license/PurpleI2P/i2pd.svg) +[![GitHub release](https://img.shields.io/github/release/PurpleI2P/i2pd.svg?label=latest%20release)](https://github.com/PurpleI2P/i2pd/releases/latest) +[![Snapcraft release](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) +[![License](https://img.shields.io/github/license/PurpleI2P/i2pd.svg)](https://github.com/PurpleI2P/i2pd/blob/openssl/LICENSE) i2pd ==== @@ -66,6 +67,7 @@ Build instructions: * Mac OS X - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) * 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/) * Docker image - [![Build Status](https://dockerbuildbadges.quelltext.eu/status.svg?organization=meeh&repository=i2pd)](https://hub.docker.com/r/meeh/i2pd/builds/) +* Snap - [![Snap Status](https://build.snapcraft.io/badge/PurpleI2P/i2pd-snap.svg)](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap) * FreeBSD * Android * iOS From 9bbce5dba6980cb87859e1128406f66c8f8bddc8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Aug 2019 20:26:19 -0400 Subject: [PATCH 0077/2950] fixed typo --- libi2pd_client/ClientContext.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e10c1e07..d14491b2 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -410,7 +410,7 @@ namespace client auto authType = GetI2CPOption(section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0); if (authType != "0") // auth is set { - options[I2CP_PARAM_LEASESET_TYPE] = authType; + options[I2CP_PARAM_LEASESET_AUTH_TYPE] = authType; if (authType == "1") // DH ReadI2CPOptionsGroup (section, I2CP_PARAM_LEASESET_CLIENT_DH, options); else if (authType == "2") // PSK @@ -629,8 +629,8 @@ namespace client // I2CP std::map options; - ReadI2CPOptions (section, options); - + ReadI2CPOptions (section, options); + std::shared_ptr localDestination = nullptr; i2p::data::PrivateKeys k; if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) From 8f82d563c1115a819ca982b428b1dece029a5a69 Mon Sep 17 00:00:00 2001 From: kote Date: Thu, 22 Aug 2019 10:00:50 +0800 Subject: [PATCH 0078/2950] various Android stuff. Fixed #1400 --- android/.gitignore | 3 +- android/AndroidManifest.xml | 1 + android/build.gradle | 13 +- android/gradle.properties | 2 + .../gradle/wrapper/gradle-wrapper.properties | 4 +- android/res/values/strings.xml | 5 + .../org/purplei2p/i2pd/ForegroundService.java | 22 +- .../src/org/purplei2p/i2pd/I2PDActivity.java | 334 +++++++++++------- 8 files changed, 245 insertions(+), 139 deletions(-) diff --git a/android/.gitignore b/android/.gitignore index 297d122f..c1f63742 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -12,5 +12,4 @@ local.properties build.sh android.iml build - - +*.iml diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 2ae14711..757b35bb 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -9,6 +9,7 @@ + remaining Prompt SD card write permission denied, you need to allow this to continue + Battery optimizations enabled + Your device is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to disable those battery optimizations. + Your device is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to disable those. + Next + Your device does not support opting out of battery optimizations diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index 5c10e138..c1b1cc26 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -1,6 +1,5 @@ package org.purplei2p.i2pd; -import android.annotation.TargetApi; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -11,10 +10,9 @@ import android.content.Intent; import android.os.Binder; import android.os.Build; import android.os.IBinder; -import android.support.annotation.RequiresApi; -import android.support.v4.app.NotificationCompat; +import androidx.annotation.RequiresApi; +import androidx.core.app.NotificationCompat; import android.util.Log; -import android.widget.Toast; public class ForegroundService extends Service { private static final String TAG="FgService"; @@ -112,14 +110,15 @@ public class ForegroundService extends Service { // If earlier version channel ID is not used // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) - String channelId = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? createNotificationChannel() : ""; + String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : ""; // Set the info for the views that show in the notification panel. - Notification notification = new NotificationCompat.Builder(this, channelId) + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) .setOngoing(true) - .setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon - .setPriority(Notification.PRIORITY_DEFAULT) - .setCategory(Notification.CATEGORY_SERVICE) + .setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon + if(Build.VERSION.SDK_INT >= 16) builder = builder.setPriority(Notification.PRIORITY_DEFAULT); + if(Build.VERSION.SDK_INT >= 21) builder = builder.setCategory(Notification.CATEGORY_SERVICE); + Notification notification = builder .setTicker(text) // the status text .setWhen(System.currentTimeMillis()) // the time stamp .setContentTitle(getText(R.string.app_name)) // the label of the entry @@ -141,9 +140,10 @@ public class ForegroundService extends Service { //chan.setLightColor(Color.PURPLE); chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); NotificationManager service = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); - service.createNotificationChannel(chan); + if(service!=null)service.createNotificationChannel(chan); + else Log.e(TAG, "error: NOTIFICATION_SERVICE is null"); return channelId; } - private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); + private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); } diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index b5f85c5b..d97df833 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -14,24 +14,34 @@ import java.util.Timer; import java.util.TimerTask; import android.Manifest; +import android.annotation.SuppressLint; import android.app.Activity; +import android.app.AlertDialog; +import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.SharedPreferences; import android.content.res.AssetManager; import android.content.pm.PackageManager; +import android.net.Uri; import android.os.Bundle; import android.os.Build; import android.os.Environment; import android.os.IBinder; +import android.os.PowerManager; +import android.preference.PreferenceManager; +import android.provider.Settings; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; import android.widget.Toast; -import android.support.v4.app.ActivityCompat; -import android.support.v4.content.ContextCompat; + +import androidx.annotation.NonNull; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; // For future package update checking import org.purplei2p.i2pd.BuildConfig; @@ -40,6 +50,7 @@ public class I2PDActivity extends Activity { private static final String TAG = "i2pdActvt"; private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1; public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; + public static final String PACKAGE_URI_SCHEME = "package:"; private TextView textView; private boolean assetsCopied; @@ -53,28 +64,22 @@ public class I2PDActivity extends Activity { public void daemonStateUpdate() { processAssets(); - runOnUiThread(new Runnable(){ - - @Override - public void run() { - try { - if(textView==null) return; - Throwable tr = daemon.getLastThrowable(); - if(tr!=null) { - textView.setText(throwableToString(tr)); - return; - } - DaemonSingleton.State state = daemon.getState(); - textView.setText( - String.valueOf(getText(state.getStatusStringResourceId()))+ - (DaemonSingleton.State.startFailed.equals(state) ? ": "+daemon.getDaemonStartResult() : "")+ - (DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? ": "+formatGraceTimeRemaining()+" "+getText(R.string.remaining) : "") - ); - } catch (Throwable tr) { - Log.e(TAG,"error ignored",tr); - } - } - }); + runOnUiThread(() -> { + try { + if(textView==null) return; + Throwable tr = daemon.getLastThrowable(); + if(tr!=null) { + textView.setText(throwableToString(tr)); + return; + } + DaemonSingleton.State state = daemon.getState(); + String startResultStr = DaemonSingleton.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : ""; + String graceStr = DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : ""; + textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr)); + } catch (Throwable tr) { + Log.e(TAG,"error ignored",tr); + } + }); } }; private static volatile long graceStartedMillis; @@ -92,6 +97,7 @@ public class I2PDActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { + Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); textView = new TextView(this); @@ -121,6 +127,8 @@ public class I2PDActivity extends Activity { } rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis); } + + openBatteryOptimizationDialogIfNeeded(); } @Override @@ -137,21 +145,17 @@ public class I2PDActivity extends Activity { } @Override - public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - switch (requestCode) - { - case MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE: - { - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) - Log.e(TAG, "Memory permission granted"); - else - Log.e(TAG, "Memory permission declined"); - // TODO: terminate - return; - } - default: ; - } + if (requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) { + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) + Log.e(TAG, "WR_EXT_STORAGE perm granted"); + else { + Log.e(TAG, "WR_EXT_STORAGE perm declined, stopping i2pd"); + i2pdStop(); + //TODO must work w/o this perm, ask orignal + } + } } private static void cancelGracefulStop() { @@ -229,7 +233,7 @@ public class I2PDActivity extends Activity { } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(@NonNull MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. @@ -258,19 +262,15 @@ public class I2PDActivity extends Activity { private void i2pdStop() { cancelGracefulStop(); - new Thread(new Runnable(){ - - @Override - public void run() { - Log.d(TAG, "stopping"); - try{ - daemon.stopDaemon(); - }catch (Throwable tr) { - Log.e(TAG, "", tr); - } - } - - },"stop").start(); + new Thread(() -> { + Log.d(TAG, "stopping"); + try { + daemon.stopDaemon(); + } catch (Throwable tr) { + Log.e(TAG, "", tr); + } + quit(); //TODO make menu items for starting i2pd. On my Android, I need to reboot the OS to restart i2pd. + },"stop").start(); } private static volatile Timer gracefulQuitTimer; @@ -288,55 +288,44 @@ public class I2PDActivity extends Activity { } Toast.makeText(this, R.string.graceful_stop_is_in_progress, Toast.LENGTH_SHORT).show(); - new Thread(new Runnable(){ - - @Override - public void run() { - try { - Log.d(TAG, "grac stopping"); - if(daemon.isStartedOkay()) { - daemon.stopAcceptingTunnels(); - long gracefulStopAtMillis; - synchronized (graceStartedMillis_LOCK) { - graceStartedMillis = System.currentTimeMillis(); - gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; - } - rescheduleGraceStop(null,gracefulStopAtMillis); - } else { - i2pdStop(); - } - } catch(Throwable tr) { - Log.e(TAG,"",tr); - } - } - - },"gracInit").start(); + new Thread(() -> { + try { + Log.d(TAG, "grac stopping"); + if(daemon.isStartedOkay()) { + daemon.stopAcceptingTunnels(); + long gracefulStopAtMillis; + synchronized (graceStartedMillis_LOCK) { + graceStartedMillis = System.currentTimeMillis(); + gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; + } + rescheduleGraceStop(null,gracefulStopAtMillis); + } else { + i2pdStop(); + } + } catch(Throwable tr) { + Log.e(TAG,"",tr); + } + },"gracInit").start(); } private void i2pdCancelGracefulStop() { cancelGracefulStop(); Toast.makeText(this, R.string.startedOkay, Toast.LENGTH_SHORT).show(); - new Thread(new Runnable() - { - @Override - public void run() - { - try - { - Log.d(TAG, "grac stopping cancel"); - if(daemon.isStartedOkay()) - daemon.startAcceptingTunnels(); - else - i2pdStop(); - } - catch(Throwable tr) - { - Log.e(TAG,"",tr); - } - } - - },"gracCancel").start(); + new Thread(() -> { + try + { + Log.d(TAG, "grac stopping cancel"); + if(daemon.isStartedOkay()) + daemon.startAcceptingTunnels(); + else + i2pdStop(); + } + catch(Throwable tr) + { + Log.e(TAG,"",tr); + } + },"gracCancel").start(); } private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) { @@ -393,7 +382,7 @@ public class I2PDActivity extends Activity { // Make the directory. File dir = new File(i2pdpath, path); - dir.mkdirs(); + Log.d(TAG, "dir.mkdirs() returned "+dir.mkdirs()); // Recurse on the contents. for (String entry : contents) { @@ -431,45 +420,69 @@ public class I2PDActivity extends Activity { private void deleteRecursive(File fileOrDirectory) { if (fileOrDirectory.isDirectory()) { - for (File child : fileOrDirectory.listFiles()) { - deleteRecursive(child); + File[] files = fileOrDirectory.listFiles(); + if(files!=null) { + for (File child : files) { + deleteRecursive(child); + } } } - fileOrDirectory.delete(); + boolean deleteResult = fileOrDirectory.delete(); + if(!deleteResult)Log.e(TAG, "fileOrDirectory.delete() returned "+deleteResult+", absolute path='"+fileOrDirectory.getAbsolutePath()+"'"); } private void processAssets() { if (!assetsCopied) try { assetsCopied = true; // prevent from running on every state update - File holderfile = new File(i2pdpath, "assets.ready"); + File holderFile = new File(i2pdpath, "assets.ready"); String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX StringBuilder text = new StringBuilder(); - if (holderfile.exists()) try { // if holder file exists, read assets version string - BufferedReader br = new BufferedReader(new FileReader(holderfile)); - String line; + if (holderFile.exists()) { + try { // if holder file exists, read assets version string + FileReader fileReader = new FileReader(holderFile); - while ((line = br.readLine()) != null) { - text.append(line); - } - br.close(); - } - catch (IOException e) { - Log.e(TAG, "", e); - } + try { + BufferedReader br = new BufferedReader(fileReader); + + try { + String line; + + while ((line = br.readLine()) != null) { + text.append(line); + } + }finally { + try{ + br.close(); + } catch (IOException e) { + Log.e(TAG, "", e); + } + } + } finally { + try{ + fileReader.close(); + } catch (IOException e) { + Log.e(TAG, "", e); + } + } + } catch (IOException e) { + Log.e(TAG, "", e); + } + } // if version differs from current app version or null, try to delete certificates folder if (!text.toString().contains(versionName)) try { - holderfile.delete(); - File certpath = new File(i2pdpath, "certificates"); - deleteRecursive(certpath); + boolean deleteResult = holderFile.delete(); + if(!deleteResult)Log.e(TAG, "holderFile.delete() returned "+deleteResult+", absolute path='"+holderFile.getAbsolutePath()+"'"); + File certPath = new File(i2pdpath, "certificates"); + deleteRecursive(certPath); } catch (Throwable tr) { Log.e(TAG, "", tr); } - // copy assets. If processed file exists, it won't be overwrited + // copy assets. If processed file exists, it won't be overwritten copyAsset("addressbook"); copyAsset("certificates"); copyAsset("tunnels.d"); @@ -478,14 +491,95 @@ public class I2PDActivity extends Activity { copyAsset("tunnels.conf"); // update holder file about successful copying - FileWriter writer = new FileWriter(holderfile); - writer.append(versionName); - writer.flush(); - writer.close(); + FileWriter writer = new FileWriter(holderFile); + try { + writer.append(versionName); + } finally { + try{ + writer.close(); + }catch (IOException e){ + Log.e(TAG,"on writer close", e); + } + } } catch (Throwable tr) { - Log.e(TAG,"copy assets",tr); + Log.e(TAG,"on assets copying", tr); } } + + @SuppressLint("BatteryLife") + private void openBatteryOptimizationDialogIfNeeded() { + boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true); + Log.i(TAG,"BATT_OPTIM_questionEnabled=="+questionEnabled); + if (!isKnownIgnoringBatteryOptimizations() + && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M + && questionEnabled) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.battery_optimizations_enabled); + builder.setMessage(R.string.battery_optimizations_enabled_dialog); + builder.setPositiveButton(R.string.next, (dialog, which) -> { + try { + startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName()))); + } catch (ActivityNotFoundException e) { + Log.e(TAG,"BATT_OPTIM_ActvtNotFound", e); + Toast.makeText(this, R.string.device_does_not_support_disabling_battery_optimizations, Toast.LENGTH_SHORT).show(); + } + }); + builder.setOnDismissListener(dialog -> setNeverAskForBatteryOptimizationsAgain()); + final AlertDialog dialog = builder.create(); + dialog.setCanceledOnTouchOutside(false); + dialog.show(); + } + } + + private void setNeverAskForBatteryOptimizationsAgain() { + getPreferences().edit().putBoolean(getBatteryOptimizationPreferenceKey(), false).apply(); + } + + protected boolean isKnownIgnoringBatteryOptimizations() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); + if (pm == null) { + Log.i(TAG, "BATT_OPTIM: POWER_SERVICE==null"); + return false; + } + boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName()); + Log.i(TAG, "BATT_OPTIM: ignoring==" + ignoring); + return ignoring; + } else { + Log.i(TAG, "BATT_OPTIM: old sdk version=="+Build.VERSION.SDK_INT); + return false; + } + } + + protected SharedPreferences getPreferences() { + return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + } + + private String getBatteryOptimizationPreferenceKey() { + @SuppressLint("HardwareIds") String device = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); + return "show_battery_optimization" + (device == null ? "" : device); + } + + private void quit() { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + finishAndRemoveTask(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + finishAffinity(); + } else { + //moveTaskToBack(true); + finish(); + } + }catch (Throwable tr) { + Log.e(TAG, "", tr); + } + try{ + daemon.stopDaemon(); + }catch (Throwable tr) { + Log.e(TAG, "", tr); + } + System.exit(0); + } } From 488c2f6d05993ecc676996bfe113a3fe59c6444b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Aug 2019 09:45:49 -0400 Subject: [PATCH 0079/2950] bump SDK version --- android/project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/project.properties b/android/project.properties index 919ca9c3..82181932 100644 --- a/android/project.properties +++ b/android/project.properties @@ -11,4 +11,4 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-28 +target=android-29 From fe45d431d78a3787239227516f8d9caa146decd8 Mon Sep 17 00:00:00 2001 From: Grigory Kotov Date: Fri, 23 Aug 2019 15:40:17 +0300 Subject: [PATCH 0080/2950] fix dockerfile: remove unmet dependencies --- contrib/docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index e0c4d26e..322261b8 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -36,8 +36,8 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib && 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 boost-python linux-headers boost-prg_exec_monitor \ - boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \ + 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 pcre \ libtool g++ gcc pkgconfig # 2. Adding required libraries to run i2pd to ensure it will run. From 351c89980746e509fedb49595b61bce3387eb4dd Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Aug 2019 10:00:49 -0400 Subject: [PATCH 0081/2950] cleanup incoming streams on stop --- libi2pd/Streaming.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index c8ccdcdb..4f943912 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -990,6 +990,7 @@ namespace stream { std::unique_lock l(m_StreamsMutex); m_Streams.clear (); + m_IncomingStreams.clear (); } } From 6e4f18543dd48b5723c775ef5b9930fc260dab06 Mon Sep 17 00:00:00 2001 From: kote Date: Thu, 22 Aug 2019 22:09:22 +0800 Subject: [PATCH 0082/2950] added *.local to android/.gitignore --- android/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/android/.gitignore b/android/.gitignore index c1f63742..666c6694 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -13,3 +13,4 @@ build.sh android.iml build *.iml +*.local From 80f632c19a8c80e9b2fb8c62b90952ef14f7d5c9 Mon Sep 17 00:00:00 2001 From: kote Date: Sat, 24 Aug 2019 17:50:30 +0800 Subject: [PATCH 0083/2950] show battery optimiz. menu item added; translated all battery stuff into Russian --- android/res/menu/options_main.xml | 25 +++++++++++------- android/res/values-ru/strings.xml | 7 +++++ android/res/values/strings.xml | 10 ++++--- .../src/org/purplei2p/i2pd/I2PDActivity.java | 26 +++++++++++++++++-- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/android/res/menu/options_main.xml b/android/res/menu/options_main.xml index aef67c51..089c2700 100644 --- a/android/res/menu/options_main.xml +++ b/android/res/menu/options_main.xml @@ -3,14 +3,19 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".I2PDActivity"> - - + + + + + + + diff --git a/android/res/values-ru/strings.xml b/android/res/values-ru/strings.xml index d5dc58e8..318e2180 100755 --- a/android/res/values-ru/strings.xml +++ b/android/res/values-ru/strings.xml @@ -17,4 +17,11 @@ осталось Запрос Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения + Оптимизации аккумулятора + Оптимизации аккумулятора включены + Ваша версия Андроид не поддерживает отключение оптимизаций аккумулятора + Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\nРекомендуется отключить эти оптимизации. + Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций. + Продолжить + Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений. diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 430663d1..43065b77 100755 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -18,8 +18,10 @@ Prompt SD card write permission denied, you need to allow this to continue Battery optimizations enabled - Your device is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to disable those battery optimizations. - Your device is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to disable those. - Next - Your device does not support opting out of battery optimizations + Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to allow disabling those battery optimizations. + Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to allow to disable those. + Continue + Your Android version does not support opting out of battery optimizations + Battery Optimizations + Your Android OS version does not support showing the dialog for battery optimizations for applications. diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index d97df833..13db09fc 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -46,6 +46,8 @@ import androidx.core.content.ContextCompat; // For future package update checking import org.purplei2p.i2pd.BuildConfig; +import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS; + public class I2PDActivity extends Activity { private static final String TAG = "i2pdActvt"; private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1; @@ -229,9 +231,14 @@ public class I2PDActivity extends Activity { public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.options_main, menu); + menu.findItem(R.id.action_battery_otimizations).setEnabled(isBatteryOptimizationsOpenOsDialogApiAvailable()); return true; } + private boolean isBatteryOptimizationsOpenOsDialogApiAvailable() { + return android.os.Build.VERSION.SDK_INT >= 23; + } + @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { // Handle action bar item clicks here. The action bar will @@ -254,12 +261,26 @@ public class I2PDActivity extends Activity { item.setTitle(R.string.action_cancel_graceful_stop); i2pdGracefulStop(); } - return true; + return true; + case R.id.action_battery_otimizations: + onActionBatteryOptimizations(); + return true; } return super.onOptionsItemSelected(item); } + private void onActionBatteryOptimizations() { + if (isBatteryOptimizationsOpenOsDialogApiAvailable()) { + try { + startActivity(new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)); + } catch (ActivityNotFoundException e) { + Log.e(TAG,"BATT_OPTIM_DIALOG_ActvtNotFound", e); + Toast.makeText(this, R.string.os_version_does_not_support_battery_optimizations_show_os_dialog_api, Toast.LENGTH_SHORT).show(); + } + } + } + private void i2pdStop() { cancelGracefulStop(); new Thread(() -> { @@ -389,6 +410,7 @@ public class I2PDActivity extends Activity { copyAsset(path + "/" + entry); } } catch (IOException e) { + Log.e(TAG,"ex ignored", e); copyFileAsset(path); } } @@ -518,7 +540,7 @@ public class I2PDActivity extends Activity { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.battery_optimizations_enabled); builder.setMessage(R.string.battery_optimizations_enabled_dialog); - builder.setPositiveButton(R.string.next, (dialog, which) -> { + builder.setPositiveButton(R.string.continue_str, (dialog, which) -> { try { startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName()))); } catch (ActivityNotFoundException e) { From 5eab5f2437009029c24181fc855f4e5ea4e33599 Mon Sep 17 00:00:00 2001 From: kote Date: Sat, 24 Aug 2019 18:00:11 +0800 Subject: [PATCH 0084/2950] show battery optimiz. menu item now hidden if not supported by os --- android/src/org/purplei2p/i2pd/I2PDActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 13db09fc..ed0ae908 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -231,7 +231,7 @@ public class I2PDActivity extends Activity { public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.options_main, menu); - menu.findItem(R.id.action_battery_otimizations).setEnabled(isBatteryOptimizationsOpenOsDialogApiAvailable()); + menu.findItem(R.id.action_battery_otimizations).setVisible(isBatteryOptimizationsOpenOsDialogApiAvailable()); return true; } From 9d3b38141aea2f5c397efe53bf2d37c0b4cf9827 Mon Sep 17 00:00:00 2001 From: kote Date: Sat, 24 Aug 2019 19:12:11 +0800 Subject: [PATCH 0085/2950] android various fixes and improv --- android/res/values-ru/strings.xml | 1 + android/res/values/strings.xml | 1 + .../src/org/purplei2p/i2pd/I2PDActivity.java | 89 +++++++++++-------- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/android/res/values-ru/strings.xml b/android/res/values-ru/strings.xml index 318e2180..1b0b2113 100755 --- a/android/res/values-ru/strings.xml +++ b/android/res/values-ru/strings.xml @@ -24,4 +24,5 @@ Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций. Продолжить Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений. + Плановая остановка отменена diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 43065b77..e08c1c46 100755 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -24,4 +24,5 @@ Your Android version does not support opting out of battery optimizations Battery Optimizations Your Android OS version does not support showing the dialog for battery optimizations for applications. + Planned shutdown canceled diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index ed0ae908..89881b42 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -44,7 +44,6 @@ import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; // For future package update checking -import org.purplei2p.i2pd.BuildConfig; import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS; @@ -86,6 +85,7 @@ public class I2PDActivity extends Activity { }; private static volatile long graceStartedMillis; private static final Object graceStartedMillis_LOCK=new Object(); + private Menu optionsMenu; private static String formatGraceTimeRemaining() { long remainingSeconds; @@ -138,7 +138,7 @@ public class I2PDActivity extends Activity { super.onDestroy(); textView = null; daemon.removeStateChangeListener(daemonStateUpdatedListener); - //cancelGracefulStop(); + //cancelGracefulStop0(); try{ doUnbindService(); }catch(Throwable tr){ @@ -160,7 +160,7 @@ public class I2PDActivity extends Activity { } } - private static void cancelGracefulStop() { + private void cancelGracefulStop0() { Timer gracefulQuitTimer = getGracefulQuitTimer(); if(gracefulQuitTimer!=null) { gracefulQuitTimer.cancel(); @@ -232,6 +232,7 @@ public class I2PDActivity extends Activity { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.options_main, menu); menu.findItem(R.id.action_battery_otimizations).setVisible(isBatteryOptimizationsOpenOsDialogApiAvailable()); + this.optionsMenu = menu; return true; } @@ -251,15 +252,11 @@ public class I2PDActivity extends Activity { i2pdStop(); return true; case R.id.action_graceful_stop: - if (getGracefulQuitTimer()!= null) - { - item.setTitle(R.string.action_graceful_stop); - i2pdCancelGracefulStop (); - } - else - { - item.setTitle(R.string.action_cancel_graceful_stop); - i2pdGracefulStop(); + synchronized (graceStartedMillis_LOCK) { + if (getGracefulQuitTimer() != null) + cancelGracefulStop(); + else + i2pdGracefulStop(); } return true; case R.id.action_battery_otimizations: @@ -282,7 +279,7 @@ public class I2PDActivity extends Activity { } private void i2pdStop() { - cancelGracefulStop(); + cancelGracefulStop0(); new Thread(() -> { Log.d(TAG, "stopping"); try { @@ -329,16 +326,17 @@ public class I2PDActivity extends Activity { },"gracInit").start(); } - private void i2pdCancelGracefulStop() + private void cancelGracefulStop() { - cancelGracefulStop(); - Toast.makeText(this, R.string.startedOkay, Toast.LENGTH_SHORT).show(); + cancelGracefulStop0(); new Thread(() -> { try { - Log.d(TAG, "grac stopping cancel"); - if(daemon.isStartedOkay()) - daemon.startAcceptingTunnels(); + Log.d(TAG, "canceling grac stop"); + if(daemon.isStartedOkay()) { + daemon.startAcceptingTunnels(); + runOnUiThread(() -> Toast.makeText(this, R.string.shutdown_canceled, Toast.LENGTH_SHORT).show()); + } else i2pdStop(); } @@ -374,8 +372,19 @@ public class I2PDActivity extends Activity { return gracefulQuitTimer; } - private static void setGracefulQuitTimer(Timer gracefulQuitTimer) { + private void setGracefulQuitTimer(Timer gracefulQuitTimer) { I2PDActivity.gracefulQuitTimer = gracefulQuitTimer; + runOnUiThread(()-> { + Menu menu = optionsMenu; + if (menu != null) { + MenuItem item = menu.findItem(R.id.action_graceful_stop); + if (item != null) { + synchronized (graceStartedMillis_LOCK) { + item.setTitle(getGracefulQuitTimer() != null ? R.string.action_cancel_graceful_stop : R.string.action_graceful_stop); + } + } + } + }); } /** @@ -398,20 +407,22 @@ public class I2PDActivity extends Activity { // to a file. That doesn't appear to be the case. If the returned array is // null or has 0 length, we assume the path is to a file. This means empty // directories will get turned into files. - if (contents == null || contents.length == 0) - throw new IOException(); + if (contents == null || contents.length == 0) { + copyFileAsset(path); + return; + } // Make the directory. File dir = new File(i2pdpath, path); - Log.d(TAG, "dir.mkdirs() returned "+dir.mkdirs()); + boolean result = dir.mkdirs(); + Log.d(TAG, "dir.mkdirs() returned " + result); // Recurse on the contents. for (String entry : contents) { - copyAsset(path + "/" + entry); + copyAsset(path + '/' + entry); } } catch (IOException e) { - Log.e(TAG,"ex ignored", e); - copyFileAsset(path); + Log.e(TAG, "ex ignored for path='" + path + "'", e); } } @@ -424,19 +435,21 @@ public class I2PDActivity extends Activity { */ private void copyFileAsset(String path) { File file = new File(i2pdpath, path); - if(!file.exists()) try { - InputStream in = getAssets().open(path); - OutputStream out = new FileOutputStream(file); - byte[] buffer = new byte[1024]; - int read = in.read(buffer); - while (read != -1) { - out.write(buffer, 0, read); - read = in.read(buffer); + if(!file.exists()) { + try { + try (InputStream in = getAssets().open(path) ) { + try (OutputStream out = new FileOutputStream(file)) { + byte[] buffer = new byte[1024]; + int read = in.read(buffer); + while (read != -1) { + out.write(buffer, 0, read); + read = in.read(buffer); + } + } + } + } catch (IOException e) { + Log.e(TAG, "", e); } - out.close(); - in.close(); - } catch (IOException e) { - Log.e(TAG, "", e); } } From 0b5509a1edbb033578b7971f55dca941ef183fde Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Aug 2019 14:54:43 -0400 Subject: [PATCH 0086/2950] correct authClients offset --- libi2pd/LeaseSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 008a4594..c44a2f6f 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -875,7 +875,7 @@ namespace data { RAND_bytes (innerInput, 32); // authCookie htobe16buf (m_Buffer + offset, authKeys->size ()); offset += 2; // num clients - CreateClientAuthData (subcredential, authType, authKeys, innerInput, m_Buffer); + CreateClientAuthData (subcredential, authType, authKeys, innerInput, m_Buffer + offset); offset += authKeys->size ()*40; // auth clients } // Layer 2 From 80765a797b4174fc05541ef84c2fb7f3261d40ff Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Aug 2019 19:14:53 -0400 Subject: [PATCH 0087/2950] correct outer cipher text len --- libi2pd/LeaseSet.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index c44a2f6f..3a4ddd1f 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -834,7 +834,11 @@ namespace data { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 - if (layer1Flags) m_BufferLen += authKeys->size ()*40 + 2; // auth data len + if (layer1Flags) + { + m_BufferLen += authKeys->size ()*40 + 2; // auth data len + lenOuterCiphertext += authKeys->size ()*40 + 2; + } } m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; From 9d06aa2f6aa7bc76d7fbf4de41b6a624c1ab13e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Aug 2019 20:51:15 -0400 Subject: [PATCH 0088/2950] pass authSalt or epk --- libi2pd/LeaseSet.cpp | 21 ++++++++++++--------- libi2pd/LeaseSet.h | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 3a4ddd1f..5dacb6d5 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -836,8 +836,8 @@ namespace data else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 if (layer1Flags) { - m_BufferLen += authKeys->size ()*40 + 2; // auth data len - lenOuterCiphertext += authKeys->size ()*40 + 2; + m_BufferLen += 32 + 2 + authKeys->size ()*40; // auth data len + lenOuterCiphertext += 32 + 2 + authKeys->size ()*40; } } m_Buffer = new uint8_t[m_BufferLen + 1]; @@ -878,9 +878,8 @@ namespace data if (layer1Flags) { RAND_bytes (innerInput, 32); // authCookie - htobe16buf (m_Buffer + offset, authKeys->size ()); offset += 2; // num clients CreateClientAuthData (subcredential, authType, authKeys, innerInput, m_Buffer + offset); - offset += authKeys->size ()*40; // auth clients + offset += 32 + 2 + authKeys->size ()*40; // auth clients } // Layer 2 // keys = HKDF(outerSalt, outerInput, "ELS2_L2K", 44) @@ -920,12 +919,14 @@ namespace data LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); } - void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const + void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authData) const { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) { i2p::crypto::X25519Keys ek; ek.GenerateKeys (); // esk and epk + memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk + htobe16buf (authData, authKeys->size ()); authData += 2; // num clients uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp memcpy (authInput + 64, subcredential, 36); for (auto& it: *authKeys) @@ -934,14 +935,16 @@ namespace data memcpy (authInput + 32, it, 32); uint8_t okm[64]; // 52 actual data i2p::crypto::HKDF (ek.GetPublicKey (), authInput, 100, "ELS2_XCA", okm); - memcpy (authClients, okm + 44, 8); authClients += 8; // clientID_i - i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authClients); authClients += 32; // clientCookie_i + memcpy (authData, okm + 44, 8); authData += 8; // clientID_i + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i } } else // assume PSK { uint8_t authSalt[32]; RAND_bytes (authSalt, 32); + memcpy (authData, authSalt, 32); authData += 32; // authSalt + htobe16buf (authData, authKeys->size ()); authData += 2; // num clients uint8_t authInput[68]; // authInput = psk_i || subcredential || publishedTimestamp memcpy (authInput + 32, subcredential, 36); for (auto& it: *authKeys) @@ -949,8 +952,8 @@ namespace data memcpy (authInput, it, 32); uint8_t okm[64]; // 52 actual data i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); - memcpy (authClients, okm + 44, 8); authClients += 8; // clientID_i - i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authClients); authClients += 32; // clientCookie_i + memcpy (authData, okm + 44, 8); authData += 8; // clientID_i + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i } } } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 935aca37..70aa7110 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -272,7 +272,7 @@ namespace data private: - void CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authClients) const; + void CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authData) const; private: From e42efec220808f4aa04d2e726fd6c80d6404b830 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Aug 2019 07:35:11 -0400 Subject: [PATCH 0089/2950] correct outet plain text length in case of authKeys --- libi2pd/LeaseSet.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 5dacb6d5..b516f010 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -826,20 +826,18 @@ namespace data int authType, std::shared_ptr > authKeys): LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { - size_t lenInnerPlaintext = ls->GetBufferLen () + 1, lenOuterPlaintext = lenInnerPlaintext + 32 + 1, - lenOuterCiphertext = lenOuterPlaintext + 32; - m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; + size_t lenInnerPlaintext = ls->GetBufferLen () + 1, lenOuterPlaintext = lenInnerPlaintext + 32 + 1; uint8_t layer1Flags = 0; if (authKeys) { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 if (layer1Flags) - { - m_BufferLen += 32 + 2 + authKeys->size ()*40; // auth data len - lenOuterCiphertext += 32 + 2 + authKeys->size ()*40; - } - } + lenOuterPlaintext += 32 + 2 + authKeys->size ()*40; // auth data len + } + size_t lenOuterCiphertext = lenOuterPlaintext + 32; + + m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; BlindedPublicKey blindedKey (ls->GetIdentity ()); From b5aa67b491ab3d283165dc3e64dee71e1cf99bb0 Mon Sep 17 00:00:00 2001 From: kote Date: Tue, 27 Aug 2019 17:10:53 +0800 Subject: [PATCH 0090/2950] tweaked debug logging in i2pd_qt --- qt/i2pd_qt/DaemonQT.cpp | 12 ++++++++++-- qt/i2pd_qt/logviewermanager.cpp | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/qt/i2pd_qt/DaemonQT.cpp b/qt/i2pd_qt/DaemonQT.cpp index f5e6d62b..1e45c583 100644 --- a/qt/i2pd_qt/DaemonQT.cpp +++ b/qt/i2pd_qt/DaemonQT.cpp @@ -11,6 +11,8 @@ #include #include +//#define DEBUG_WITH_DEFAULT_LOGGING (1) + namespace i2p { namespace qt @@ -151,10 +153,16 @@ namespace qt int result; { - std::shared_ptr logstreamptr=std::make_shared(); + std::shared_ptr logstreamptr= +#ifdef DEBUG_WITH_DEFAULT_LOGGING + nullptr +#else + std::make_shared() +#endif + ; //TODO move daemon init deinit to a bg thread DaemonQTImpl daemon; - (*logstreamptr) << "Initialising the daemon..." << std::endl; + if(logstreamptr) (*logstreamptr) << "Initialising the daemon..." << std::endl; bool daemonInitSuccess = daemon.init(argc, argv, logstreamptr); if(!daemonInitSuccess) { diff --git a/qt/i2pd_qt/logviewermanager.cpp b/qt/i2pd_qt/logviewermanager.cpp index 30fc904a..823956b2 100644 --- a/qt/i2pd_qt/logviewermanager.cpp +++ b/qt/i2pd_qt/logviewermanager.cpp @@ -18,7 +18,7 @@ namespace logviewer { QString Worker::pollAndShootATimerForInfiniteRetries() { std::shared_ptr logStream=logViewerManager.getLogStream(); - assert(logStream!=nullptr); + if(!logStream)return ""; std::streamsize MAX_SZ=64*1024; char*buf=(char*)malloc(MAX_SZ*sizeof(char)); if(buf==nullptr)return ""; From 3939ca9eb48e34a82e72f30ee5162df3874dc57c Mon Sep 17 00:00:00 2001 From: kote Date: Tue, 27 Aug 2019 17:51:55 +0800 Subject: [PATCH 0091/2950] enabled default logging debug option for qt debug builds --- qt/i2pd_qt/i2pd_qt.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 9a978731..deb1c805 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -7,6 +7,8 @@ TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized DEFINES += USE_UPNP +debug: DEFINES += DEBUG_WITH_DEFAULT_LOGGING + SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/api.cpp \ ../../libi2pd/Base.cpp \ From 99116ff097a87dcc32ecb978953dc807c2677f66 Mon Sep 17 00:00:00 2001 From: kote Date: Tue, 27 Aug 2019 19:31:28 +0800 Subject: [PATCH 0092/2950] qt: disabled upnp for now - until upnp fixed --- qt/i2pd_qt/i2pd_qt.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index deb1c805..51aa4246 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -5,7 +5,10 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized -DEFINES += USE_UPNP + +# For now, disable UPnP which currently crashes on Stop() -- https://github.com/PurpleI2P/i2pd/issues/1387 +#DEFINES += USE_UPNP +DEFINES -= USE_UPNP debug: DEFINES += DEBUG_WITH_DEFAULT_LOGGING From d523f0caddd3b743da91d19638564e2843935c93 Mon Sep 17 00:00:00 2001 From: kote Date: Tue, 27 Aug 2019 19:31:57 +0800 Subject: [PATCH 0093/2950] gitignored autosave files by qtcreator --- qt/i2pd_qt/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qt/i2pd_qt/.gitignore b/qt/i2pd_qt/.gitignore index 3abca1bd..f1d57c58 100644 --- a/qt/i2pd_qt/.gitignore +++ b/qt/i2pd_qt/.gitignore @@ -6,4 +6,6 @@ i2pd_qt Makefile* *.stash object_script.* -i2pd_qt_plugin_import.cpp \ No newline at end of file +i2pd_qt_plugin_import.cpp +i2pd_qt.pro.autosave* + From 44a2549b8199eb392047ff1a79107d0630961546 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Aug 2019 09:46:54 -0400 Subject: [PATCH 0094/2950] 2.28.0 --- ChangeLog | 12 ++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 33 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index d52260ab..89253f5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,18 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.28.0] - 2019-08-27 +### Added +- RAW datagrams in SAM +- Publishing encrypted LeaseSet2 with DH or PSH authentication +- Ability to disable battery optimization for Android +- Transport Network ID Check +### Changed +- Set and handle published encrypted flag for LeaseSet2 +### Fixed +- ReceiveID changes in the same stream +- "\r\n" command terminator in SAM + ## [2.27.0] - 2019-07-03 ### Added - Support of PSK and DH authentication for encrypted LeaseSet2 diff --git a/Win32/installer.iss b/Win32/installer.iss index b00523da..4c78bb6a 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.27.0" +#define I2Pd_ver "2.28.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 12e4b20c..441f6be8 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2270 - versionName "2.27.0" + versionCode 2280 + versionName "2.28.0" ndk { abiFilters 'armeabi-v7a' abiFilters 'x86' diff --git a/appveyor.yml b/appveyor.yml index dfbc656c..67693ac3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.27.0.{build} +version: 2.28.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 1dda44b1..ed4bad86 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.27.0 +Version: 2.28.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -110,6 +110,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Aug 27 2019 orignal - 2.28.0 +- update to 2.28.0 + * Wed Jul 3 2019 orignal - 2.27.0 - update to 2.27.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 67c7f4bf..61271680 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.27.0 +Version: 2.28.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -108,6 +108,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Aug 27 2019 orignal - 2.28.0 +- update to 2.28.0 + * Wed Jul 3 2019 orignal - 2.27.0 - update to 2.27.0 diff --git a/debian/changelog b/debian/changelog index 0f30a066..4a6fbfd8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.28.0-1) unstable; urgency=medium + + * updated to version 2.28.0/0.9.42 + + -- orignal Tue, 27 Aug 2019 16:00:00 +0000 + i2pd (2.27.0-1) unstable; urgency=medium * updated to version 2.27.0/0.9.41 diff --git a/libi2pd/version.h b/libi2pd/version.h index cd96c677..1c08a362 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 27 +#define I2PD_VERSION_MINOR 28 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 41 +#define I2P_VERSION_MICRO 42 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index b16d0d5c..65683584 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 81d9626da9f7de4a1d195f279f7f079560799685 Mon Sep 17 00:00:00 2001 From: kote Date: Tue, 27 Aug 2019 21:56:07 +0800 Subject: [PATCH 0095/2950] qt: fixed logging to window in release builds --- qt/i2pd_qt/i2pd_qt.pro | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 51aa4246..e6349855 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -6,11 +6,16 @@ TARGET = i2pd_qt TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized -# For now, disable UPnP which currently crashes on Stop() -- https://github.com/PurpleI2P/i2pd/issues/1387 +# For now, disable UPnP which currently crashes in UPnP::Stop() -- https://github.com/PurpleI2P/i2pd/issues/1387 #DEFINES += USE_UPNP DEFINES -= USE_UPNP -debug: DEFINES += DEBUG_WITH_DEFAULT_LOGGING +CONFIG(debug, debug|release) { + message(Debug build) + DEFINES += DEBUG_WITH_DEFAULT_LOGGING +} else { + message(Release build) +} SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/api.cpp \ From 90a5d02bf6118c53dd97f2e03775dc6be81fb891 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Aug 2019 10:17:32 -0400 Subject: [PATCH 0096/2950] 2.28.0 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 89253f5b..980ae537 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ ### Fixed - ReceiveID changes in the same stream - "\r\n" command terminator in SAM +- Addressbook lines with signatures ## [2.27.0] - 2019-07-03 ### Added From 2900bc26a5056705c50273f5c0bd17d38bfb4054 Mon Sep 17 00:00:00 2001 From: kote Date: Fri, 6 Sep 2019 02:58:28 +0800 Subject: [PATCH 0097/2950] fixed #1388 : took code from https://github.com/PurpleI2P/i2pd/commit/736c95a870814f00031c75b2d4ad7af64a65918d and fixed it as https://github.com/PurpleI2P/i2pd/issues/1388#issuecomment-528495918 tells --- daemon/UPnP.cpp | 136 ++++++++++++++++++++++++++++++++---------------- daemon/UPnP.h | 56 ++++++++++++-------- 2 files changed, 124 insertions(+), 68 deletions(-) diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 3aad19c6..d112c7d2 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -79,43 +79,58 @@ namespace transport void UPnP::Discover () { -#if MINIUPNPC_API_VERSION >= 14 - int nerror = 0; - m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror); -#elif ( MINIUPNPC_API_VERSION >= 8 || defined(UPNPDISCOVER_SUCCESS) ) - int nerror = 0; - m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror); + bool isError; + int err; + +#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) + err = UPNPDISCOVER_SUCCESS; + +#if (MINIUPNPC_API_VERSION >= 14) + m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err); #else - m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0); + m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, &err); #endif + + isError = err != UPNPDISCOVER_SUCCESS; +#else // MINIUPNPC_API_VERSION >= 8 + err = 0; + m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); + isError = m_Devlist == NULL; +#endif // MINIUPNPC_API_VERSION >= 8 { - // notify satrting thread + // notify starting thread std::unique_lock l(m_StartedMutex); m_Started.notify_all (); } - int r; - r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); - if (r == 1) + if (isError) { - r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) + LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); + return; + } + + err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); + if (err == UPNP_IGD_VALID_CONNECTED) + { + err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + if(err != UPNPCOMMAND_SUCCESS) { - LogPrint (eLogError, "UPnP: UPNP_GetExternalIPAddress() returned ", r); + LogPrint (eLogError, "UPnP: unable to get external address: error ", err); return; } else { + LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL); if (!m_externalIPAddress[0]) { - LogPrint (eLogError, "UPnP: GetExternalIPAddress() failed."); + LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); return; } } } else { - LogPrint (eLogError, "UPnP: GetValidIGD() failed."); + LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); return; } @@ -126,6 +141,20 @@ namespace transport PortMapping (); } + int UPnP::CheckMapping (const char* port, const char* type) + { + int err = UPNPCOMMAND_SUCCESS; + +#if (MINIUPNPC_API_VERSION >= 10) + err = UPNP_GetSpecificPortMappingEntry(m_upnpUrls.controlURL, m_upnpData.first.servicetype, port, type, NULL, NULL, NULL, NULL, NULL, NULL); +#elif ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) + err = UPNP_GetSpecificPortMappingEntry(m_upnpUrls.controlURL, m_upnpData.first.servicetype, port, type, NULL, NULL, NULL, NULL, NULL); +#else + err = UPNP_GetSpecificPortMappingEntry(m_upnpUrls.controlURL, m_upnpData.first.servicetype, port, type, NULL, NULL); +#endif + return err; + } + void UPnP::PortMapping () { const auto& a = context.GetRouterInfo().GetAddresses(); @@ -134,13 +163,47 @@ namespace transport if (!address->host.is_v6 () && address->port) TryPortMapping (address); } - m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes + m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes m_Timer.async_wait ([this](const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) PortMapping (); }); + } + void UPnP::TryPortMapping (std::shared_ptr address) + { + std::string strType (GetProto (address)), strPort (std::to_string (address->port)); + std::string strDesc; i2p::config::GetOption("upnp.name", strDesc); + int err = UPNPCOMMAND_SUCCESS; + + // check for existing mapping + err = CheckMapping (strPort.c_str (), strType.c_str ()); + if (err != UPNPCOMMAND_SUCCESS) // if mapping not found + { + LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); + +#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) + err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL); +#else + err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL); +#endif + if (err != UPNPCOMMAND_SUCCESS) + { + LogPrint (eLogError, "UPnP: port forwarding to ", m_NetworkAddr, ":", strPort, " failed: return code ", err); + return; + } + else + { + LogPrint (eLogInfo, "UPnP: port successfully forwarded (", m_externalIPAddress ,":", strPort, " type ", strType, " -> ", m_NetworkAddr ,":", strPort ,")"); + return; + } + } + else + { + LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); + return; + } } void UPnP::CloseMapping () @@ -153,34 +216,17 @@ namespace transport } } - void UPnP::TryPortMapping (std::shared_ptr address) - { - std::string strType (GetProto (address)), strPort (std::to_string (address->port)); - int r; - std::string strDesc; i2p::config::GetOption("upnp.name", strDesc); -#ifdef UPNPDISCOVER_SUCCESS - r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0"); -#else - r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0); -#endif - if (r!=UPNPCOMMAND_SUCCESS) - { - LogPrint (eLogError, "UPnP: AddPortMapping (", m_NetworkAddr, ":", strPort, ") failed with code ", r); - return; - } - else - { - LogPrint (eLogDebug, "UPnP: Port Mapping successful. (", m_NetworkAddr ,":", strPort, " type ", strType, " -> ", m_externalIPAddress ,":", strPort ,")"); - return; - } - } - void UPnP::CloseMapping (std::shared_ptr address) { std::string strType (GetProto (address)), strPort (std::to_string (address->port)); - int r = 0; - r = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0); - LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", r); + int err = UPNPCOMMAND_SUCCESS; + + err = CheckMapping (strPort.c_str (), strType.c_str ()); + if (err == UPNPCOMMAND_SUCCESS) + { + err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL); + LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err); + } } void UPnP::Close () @@ -195,11 +241,11 @@ namespace transport switch (address->transportStyle) { case i2p::data::RouterInfo::eTransportNTCP: - return "TCP"; - break; + return "TCP"; + break; case i2p::data::RouterInfo::eTransportSSU: default: - return "UDP"; + return "UDP"; } } } diff --git a/daemon/UPnP.h b/daemon/UPnP.h index 5313a1c4..48855f0c 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -19,20 +19,31 @@ namespace i2p { namespace transport { + const int UPNP_RESPONSE_TIMEOUT = 2000; // in milliseconds + + enum + { + UPNP_IGD_NONE = 0, + UPNP_IGD_VALID_CONNECTED = 1, + UPNP_IGD_VALID_NOT_CONNECTED = 2, + UPNP_IGD_INVALID = 3 + }; + class UPnP { - public: + public: UPnP (); ~UPnP (); - void Close (); + void Close (); - void Start (); - void Stop (); + void Start (); + void Stop (); - private: + private: void Discover (); + int CheckMapping (const char* port, const char* type); void PortMapping (); void TryPortMapping (std::shared_ptr address); void CloseMapping (); @@ -41,23 +52,21 @@ namespace transport void Run (); std::string GetProto (std::shared_ptr address); - private: + private: bool m_IsRunning; - std::unique_ptr m_Thread; + std::unique_ptr m_Thread; std::condition_variable m_Started; std::mutex m_StartedMutex; boost::asio::io_service m_Service; boost::asio::deadline_timer m_Timer; - struct UPNPUrls m_upnpUrls; - struct IGDdatas m_upnpData; + struct UPNPUrls m_upnpUrls; + struct IGDdatas m_upnpData; - // For miniupnpc - char * m_MulticastIf = 0; - char * m_Minissdpdpath = 0; - struct UPNPDev * m_Devlist = 0; - char m_NetworkAddr[64]; - char m_externalIPAddress[40]; + // For miniupnpc + struct UPNPDev * m_Devlist = 0; + char m_NetworkAddr[64]; + char m_externalIPAddress[40]; }; } } @@ -65,14 +74,15 @@ namespace transport #else // USE_UPNP namespace i2p { namespace transport { - /* class stub */ - class UPnP { - public: - UPnP () {}; - ~UPnP () {}; - void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); } - void Stop () {}; - }; + /* class stub */ + class UPnP { + public: + + UPnP () {}; + ~UPnP () {}; + void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); } + void Stop () {}; + }; } } #endif // USE_UPNP From f7a084969a5d501fcd489a5bcde6236f67273d8e Mon Sep 17 00:00:00 2001 From: kote Date: Fri, 6 Sep 2019 03:21:26 +0800 Subject: [PATCH 0098/2950] fixed #1387 --- daemon/UPnP.cpp | 15 +++++++++++---- daemon/UPnP.h | 1 + qt/i2pd_qt/i2pd_qt.pro | 4 +--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index d112c7d2..b2ebb005 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -110,9 +110,10 @@ namespace transport } err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); + m_upnpUrlsInitialized=err!=0; if (err == UPNP_IGD_VALID_CONNECTED) { - err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(err != UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: unable to get external address: error ", err); @@ -218,11 +219,14 @@ namespace transport void UPnP::CloseMapping (std::shared_ptr address) { + if(!m_upnpUrlsInitialized) { + return; + } std::string strType (GetProto (address)), strPort (std::to_string (address->port)); int err = UPNPCOMMAND_SUCCESS; err = CheckMapping (strPort.c_str (), strType.c_str ()); - if (err == UPNPCOMMAND_SUCCESS) + if (err == UPNPCOMMAND_SUCCESS) { err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL); LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err); @@ -233,8 +237,11 @@ namespace transport { freeUPNPDevlist (m_Devlist); m_Devlist = 0; - FreeUPNPUrls (&m_upnpUrls); - } + if(m_upnpUrlsInitialized){ + FreeUPNPUrls (&m_upnpUrls); + m_upnpUrlsInitialized=false; + } + } std::string UPnP::GetProto (std::shared_ptr address) { diff --git a/daemon/UPnP.h b/daemon/UPnP.h index 48855f0c..e66f0aff 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -60,6 +60,7 @@ namespace transport std::mutex m_StartedMutex; boost::asio::io_service m_Service; boost::asio::deadline_timer m_Timer; + bool m_upnpUrlsInitialized=false; struct UPNPUrls m_upnpUrls; struct IGDdatas m_upnpData; diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index e6349855..15565c5c 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -6,9 +6,7 @@ TARGET = i2pd_qt TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized -# For now, disable UPnP which currently crashes in UPnP::Stop() -- https://github.com/PurpleI2P/i2pd/issues/1387 -#DEFINES += USE_UPNP -DEFINES -= USE_UPNP +DEFINES += USE_UPNP CONFIG(debug, debug|release) { message(Debug build) From b7f17d4cb1567286452baa62a25533d37a8eb7ae Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Sep 2019 11:02:19 -0400 Subject: [PATCH 0099/2950] client auth flag for B33 address --- daemon/HTTPServer.cpp | 2 +- libi2pd/Blinding.cpp | 18 ++++++++++++++---- libi2pd/Blinding.h | 3 ++- libi2pd/Destination.cpp | 35 ++++++++++++++++++++++------------- libi2pd/Destination.h | 7 ++++--- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 38b53ff3..7dc6a9d2 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -356,7 +356,7 @@ namespace http { s << dest->GetIdentity ()->ToBase64 () << "
\r\n
\r\n"; if (dest->IsEncryptedLeaseSet ()) { - i2p::data::BlindedPublicKey blinded (dest->GetIdentity ()); + i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ()); s << "
\r\n\r\n

\r\n"; s << blinded.ToB33 () << ".b32.i2p
\r\n"; s << "

\r\n
\r\n"; diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index e51c0fcc..6bf11c9e 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -124,8 +124,14 @@ namespace data return publicKeyLength; } +//---------------------------------------------------------- - BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity) + const uint8_t B33_TWO_BYTES_SIGTYPE_FLAG = 0x01; + const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now + const uint8_t B33_PER_CLIENT_AUTH_FLAG = 0x04; + + BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, bool clientAuth): + m_IsClientAuth (clientAuth) { if (!identity) return; auto len = identity->GetSigningPublicKeyLen (); @@ -147,9 +153,9 @@ namespace data uint32_t checksum = crc32 (0, addr + 3, l - 3); // checksum is Little Endian addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); - uint8_t flag = addr[0]; + uint8_t flags = addr[0]; size_t offset = 1; - if (flag & 0x01) // two bytes signatures + if (flags & B33_TWO_BYTES_SIGTYPE_FLAG) // two bytes signatures { m_SigType = bufbe16toh (addr + offset); offset += 2; m_BlindedSigType = bufbe16toh (addr + offset); offset += 2; @@ -159,6 +165,8 @@ namespace data m_SigType = addr[offset]; offset++; m_BlindedSigType = addr[offset]; offset++; } + m_IsClientAuth = flags & B33_PER_CLIENT_AUTH_FLAG; + std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (m_SigType)); if (blindedVerifier) { @@ -179,7 +187,9 @@ namespace data { if (m_PublicKey.size () > 32) return ""; // assume 25519 uint8_t addr[35]; char str[60]; // TODO: define actual length - addr[0] = 0; // flags + uint8_t flags = 0; + if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG; + addr[0] = flags; // flags addr[1] = m_SigType; // sig type addr[2] = m_BlindedSigType; // blinded sig type memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 9a3fe633..9d274fd0 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -14,7 +14,7 @@ namespace data { public: - BlindedPublicKey (std::shared_ptr identity); + BlindedPublicKey (std::shared_ptr identity, bool clientAuth = false); BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p std::string ToB33 () const; @@ -38,6 +38,7 @@ namespace data std::vector m_PublicKey; i2p::data::SigningKeyType m_SigType, m_BlindedSigType; + bool m_IsClientAuth = false; }; } } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 34ff374f..ca60f0fb 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -17,7 +17,7 @@ namespace client m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), - m_LeaseSetType (DEFAULT_LEASESET_TYPE) + m_LeaseSetType (DEFAULT_LEASESET_TYPE), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) { int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH; int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY; @@ -70,6 +70,19 @@ namespace client it = params->find (I2CP_PARAM_LEASESET_TYPE); if (it != params->end ()) m_LeaseSetType = std::stoi(it->second); + if (m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + { + // authentication for encrypted LeaseSet + it = params->find (I2CP_PARAM_LEASESET_AUTH_TYPE); + if (it != params->end ()) + { + auto authType = std::stoi (it->second); + if (authType >= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE && authType <= i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) + m_AuthType = authType; + else + LogPrint (eLogError, "Destination: Unknown auth type ", authType); + } + } it = params->find (I2CP_PARAM_LEASESET_PRIV_KEY); if (it != params->end ()) { @@ -846,7 +859,7 @@ namespace client ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), - m_ReadyChecker(GetService()), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) + m_ReadyChecker(GetService()) { if (keys.IsOfflineSignature () && GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // offline keys can be published with LS2 only @@ -880,25 +893,21 @@ namespace client if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { // authentication for encrypted LeaseSet - it = params->find (I2CP_PARAM_LEASESET_AUTH_TYPE); - m_AuthType = std::stoi (it->second); - if (m_AuthType > 0) + auto authType = GetAuthType (); + if (authType > 0) { m_AuthKeys = std::make_shared >(); - if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) + if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); - else if (m_AuthType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) + else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); else - { - LogPrint (eLogError, "Destination: Unexpected auth type ", m_AuthType); - m_AuthType = 0; - } + LogPrint (eLogError, "Destination: Unexpected auth type ", authType); if (m_AuthKeys->size ()) LogPrint (eLogInfo, "Destination: ", m_AuthKeys->size (), " auth keys read"); else { - LogPrint (eLogError, "Destination: No auth keys read for auth type ", m_AuthType); + LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType); m_AuthKeys = nullptr; } } @@ -1184,7 +1193,7 @@ namespace client auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic (), isPublishedEncrypted); if (isPublishedEncrypted) // encrypt if type 5 - ls2 = std::make_shared (ls2, m_Keys, m_AuthType, m_AuthKeys); + ls2 = std::make_shared (ls2, m_Keys, GetAuthType (), m_AuthKeys); leaseSet = ls2; } SetLeaseSet (leaseSet); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 148a6101..a32d3ed1 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -134,6 +134,7 @@ namespace client void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; }; + int GetAuthType () const { return m_AuthType; }; bool IsPublic () const { return m_IsPublic; }; virtual void CleanupDestination () {}; // additional clean up in derived classes // I2CP @@ -179,7 +180,7 @@ namespace client boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, m_PublishDelayTimer, m_CleanupTimer; std::string m_Nickname; - int m_LeaseSetType; + int m_LeaseSetType, m_AuthType; std::unique_ptr > m_LeaseSetPrivKey; // non-null if presented public: @@ -188,6 +189,7 @@ namespace client int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; }; bool IsEncryptedLeaseSet () const { return m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; }; + bool IsPerClientAuth () const { return m_AuthType > 0; }; }; class ClientDestination: public LeaseSetDestination @@ -270,8 +272,7 @@ namespace client boost::asio::deadline_timer m_ReadyChecker; - int m_AuthType; - std::shared_ptr > m_AuthKeys; + std::shared_ptr > m_AuthKeys; // we don't need them for I2CP public: From 9a7aed20e947f7c9836e0deea47c6362f2d35368 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Sep 2019 16:54:23 -0400 Subject: [PATCH 0100/2950] handle error for SessionConfrimed send --- libi2pd/NTCP2.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 6d235abe..12b4605f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -602,20 +602,29 @@ namespace transport void NTCP2Session::HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent"); - KeyDerivationFunctionDataPhase (); - // Alice data phase keys - m_SendKey = m_Kab; - m_ReceiveKey = m_Kba; - SetSipKeys (m_Sipkeysab, m_Sipkeysba); - memcpy (m_ReceiveIV.buf, m_Sipkeysba + 16, 8); - memcpy (m_SendIV.buf, m_Sipkeysab + 16, 8); - Established (); - ReceiveLength (); + (void) bytes_transferred; + if (ecode) + { + LogPrint (eLogWarning, "NTCP2: couldn't send SessionConfirmed message: ", ecode.message ()); + Terminate (); + } + else + { + LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent"); + KeyDerivationFunctionDataPhase (); + // Alice data phase keys + m_SendKey = m_Kab; + m_ReceiveKey = m_Kba; + SetSipKeys (m_Sipkeysab, m_Sipkeysba); + memcpy (m_ReceiveIV.buf, m_Sipkeysba + 16, 8); + memcpy (m_SendIV.buf, m_Sipkeysab + 16, 8); + Established (); + ReceiveLength (); - // TODO: remove - // m_SendQueue.push_back (CreateDeliveryStatusMsg (1)); - // SendQueue (); + // TODO: remove + // m_SendQueue.push_back (CreateDeliveryStatusMsg (1)); + // SendQueue (); + } } void NTCP2Session::HandleSessionCreatedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) From 03a861745ba35cab857b04a036add9a651501360 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 20 Sep 2019 20:09:25 -0400 Subject: [PATCH 0101/2950] removed CloseSession --- libi2pd/Transports.cpp | 22 ---------------------- libi2pd/Transports.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index a2783f6c..93db02d8 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -503,28 +503,6 @@ namespace transport } } } - - void Transports::CloseSession (std::shared_ptr router) - { - if (!router) return; - m_Service->post (std::bind (&Transports::PostCloseSession, this, router)); - } - - void Transports::PostCloseSession (std::shared_ptr router) - { - auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (router) : nullptr; - if (ssuSession) // try SSU first - { - m_SSUServer->DeleteSession (ssuSession); - LogPrint (eLogDebug, "Transports: SSU session closed"); - } - auto ntcpSession = m_NTCPServer ? m_NTCPServer->FindNTCPSession(router->GetIdentHash()) : nullptr; - if (ntcpSession) // try deleting ntcp session too - { - ntcpSession->Terminate (); - LogPrint(eLogDebug, "Transports: NTCP session closed"); - } - } void Transports::DetectExternalIP () { diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 798c90a9..117092ad 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -92,7 +92,6 @@ namespace transport void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); void SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs); - void CloseSession (std::shared_ptr router); void PeerConnected (std::shared_ptr session); void PeerDisconnected (std::shared_ptr session); @@ -131,7 +130,6 @@ namespace transport void RequestComplete (std::shared_ptr r, const i2p::data::IdentHash& ident); void HandleRequestComplete (std::shared_ptr r, i2p::data::IdentHash ident); void PostMessages (i2p::data::IdentHash ident, std::vector > msgs); - void PostCloseSession (std::shared_ptr router); bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer); void HandlePeerCleanupTimer (const boost::system::error_code& ecode); void HandlePeerTestTimer (const boost::system::error_code& ecode); From d6b1d0d4fb12440c4ba02939e588090cc88b634c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Sep 2019 21:01:34 -0400 Subject: [PATCH 0102/2950] remove incoming session from pending list when established --- libi2pd/NTCP2.cpp | 6 ++++-- libi2pd/NTCP2.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 12b4605f..9918efbc 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -719,7 +719,7 @@ namespace transport // ready to communicate auto existing = i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : ri.GetRouterIdentity ()); - m_Server.AddNTCP2Session (shared_from_this ()); + m_Server.AddNTCP2Session (shared_from_this (), true); Established (); ReceiveLength (); } @@ -1258,7 +1258,7 @@ namespace transport } } - bool NTCP2Server::AddNTCP2Session (std::shared_ptr session) + bool NTCP2Server::AddNTCP2Session (std::shared_ptr session, bool incoming) { if (!session || !session->GetRemoteIdentity ()) return false; auto& ident = session->GetRemoteIdentity ()->GetIdentHash (); @@ -1270,6 +1270,8 @@ namespace transport return false; } m_NTCP2Sessions.insert (std::make_pair (ident, session)); + if (incoming) + m_PendingIncomingSessions.remove (session); return true; } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 2bfc72b9..10f4f483 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -227,7 +227,7 @@ namespace transport void Start (); void Stop (); - bool AddNTCP2Session (std::shared_ptr session); + bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); void RemoveNTCP2Session (std::shared_ptr session); std::shared_ptr FindNTCP2Session (const i2p::data::IdentHash& ident); From c2f47119ceb4eadc11d3f91959ab4f25c27dbd6c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Sep 2019 13:42:15 -0400 Subject: [PATCH 0103/2950] fixed #1424. Check if .b32.i2p address string is valid --- libi2pd/Blinding.cpp | 3 ++- libi2pd/Blinding.h | 1 + libi2pd_client/AddressBook.cpp | 15 ++++++++++----- libi2pd_client/AddressBook.h | 3 ++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 6bf11c9e..8d3f4b40 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -141,7 +141,8 @@ namespace data m_BlindedSigType = m_SigType; } - BlindedPublicKey::BlindedPublicKey (const std::string& b33) + BlindedPublicKey::BlindedPublicKey (const std::string& b33): + m_SigType (0) // 0 means invalid, we can't blind DSA, set it later { uint8_t addr[40]; // TODO: define length from b33 size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40); diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 9d274fd0..65b8c0f8 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -22,6 +22,7 @@ namespace data size_t GetPublicKeyLen () const { return m_PublicKey.size (); }; SigningKeyType GetSigType () const { return m_SigType; }; SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; + bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 14ed89a7..0e40c76e 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -237,17 +237,19 @@ namespace client //--------------------------------------------------------------------- - Address::Address (const std::string& b32) + Address::Address (const std::string& b32): + addressType (eAddressInvalid) { if (b32.length () <= B33_ADDRESS_THRESHOLD) { - addressType = eAddressIndentHash; - identHash.FromBase32 (b32); + if (identHash.FromBase32 (b32) > 0) + addressType = eAddressIndentHash; } else { - addressType = eAddressBlindedPublicKey; blindedPublicKey = std::make_shared(b32); + if (blindedPublicKey->IsValid ()) + addressType = eAddressBlindedPublicKey; } } @@ -320,7 +322,10 @@ namespace client { auto pos = address.find(".b32.i2p"); if (pos != std::string::npos) - return std::make_shared(address.substr (0, pos)); + { + auto addr = std::make_shared(address.substr (0, pos)); + return addr->IsValid () ? addr : nullptr; + } else { pos = address.find (".i2p"); diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h index 47ad9993..82ba167b 100644 --- a/libi2pd_client/AddressBook.h +++ b/libi2pd_client/AddressBook.h @@ -33,13 +33,14 @@ namespace client struct Address { - enum { eAddressIndentHash, eAddressBlindedPublicKey } addressType; + enum { eAddressIndentHash, eAddressBlindedPublicKey, eAddressInvalid } addressType; i2p::data::IdentHash identHash; std::shared_ptr blindedPublicKey; Address (const std::string& b32); Address (const i2p::data::IdentHash& hash); bool IsIdentHash () const { return addressType == eAddressIndentHash; }; + bool IsValid () const { return addressType != eAddressInvalid; }; }; inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); } From 28aac6f93bf5d5299ebae9b39fbb34a747f4802b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 7 Oct 2019 21:18:46 +0300 Subject: [PATCH 0104/2950] fix bogus date in changelogs Signed-off-by: R4SAS --- contrib/rpm/i2pd.spec | 2 +- debian/changelog | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 44 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 61271680..e18d1427 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -130,7 +130,7 @@ getent passwd i2pd >/dev/null || \ - update to 2.22.0 - add support of tunnelsdir option -* Thu Oct 22 2018 orignal - 2.21.1 +* Mon Oct 22 2018 orignal - 2.21.1 - update to 2.21.1 * Thu Oct 4 2018 orignal - 2.21.0 diff --git a/debian/changelog b/debian/changelog index 4a6fbfd8..2e88d9e3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -48,7 +48,7 @@ i2pd (2.21.1-1) unstable; urgency=medium * updated to version 2.21.1 - -- orignal Thu, 22 Oct 2018 16:00:00 +0000 + -- orignal Mon, 22 Oct 2018 16:00:00 +0000 i2pd (2.21.0-1) unstable; urgency=medium diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 65683584..5227655e 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -8,19 +8,19 @@ i2pd Invisible Internet -

i2pd (I2P Daemon) is a 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.

-

I2P allows people from all around the world to communicate and share information - without restrictions.

-

Features:

-
    -
  • Distributed anonymous networking framework
  • -
  • End-to-end encrypted communications
  • -
  • Small footprint, simple dependencies, fast performance
  • -
  • Rich set of APIs for developers of secure applications
  • -
+

i2pd (I2P Daemon) is a 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.

+

I2P allows people from all around the world to communicate and share information + without restrictions.

+

Features:

+
    +
  • Distributed anonymous networking framework
  • +
  • End-to-end encrypted communications
  • +
  • Small footprint, simple dependencies, fast performance
  • +
  • Rich set of APIs for developers of secure applications
  • +
@@ -35,15 +35,15 @@ - - - - - - - - - + + + + + + + + + From dfdd76a1bb0fa5b616f116f428e1e72cb9ed1818 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Oct 2019 10:32:29 -0400 Subject: [PATCH 0105/2950] fixed #1429. Don't use monotonic timer for Win32 --- libi2pd/RouterContext.cpp | 10 ++++++++++ libi2pd/RouterContext.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 5ac26f7c..3323de87 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -27,7 +27,12 @@ namespace i2p void RouterContext::Init () { srand (i2p::util::GetMillisecondsSinceEpoch () % 1000); +#ifdef WIN32 + // for compatibility with WinXP + m_StartupTime = i2p::util::GetSecondsSinceEpoch (); +#else m_StartupTime = std::chrono::steady_clock::now(); +#endif if (!Load ()) CreateNewRouter (); m_Decryptor = m_Keys.CreateDecryptor (nullptr); @@ -716,7 +721,12 @@ namespace i2p uint32_t RouterContext::GetUptime () const { +#ifdef WIN32 + // for compatibility with WinXP + return i2p::util::GetSecondsSinceEpoch () - m_StartupTime; +#else return std::chrono::duration_cast (std::chrono::steady_clock::now() - m_StartupTime).count (); +#endif } bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index fc4b90dc..9385e11f 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -137,7 +137,11 @@ namespace i2p std::shared_ptr m_Decryptor; uint64_t m_LastUpdateTime; // in seconds bool m_AcceptsTunnels, m_IsFloodfill; +#ifdef WIN32 + uint64_t m_StartupTime = 0; // in seconds since epoch +#else std::chrono::time_point m_StartupTime; +#endif uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; RouterStatus m_Status; From a7e8dd04feb00d9ede8010f4bcba0e289a5b3469 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 21 Oct 2019 11:50:59 -0400 Subject: [PATCH 0106/2950] 2.29.0 --- ChangeLog | 10 ++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 980ae537..0afe2316 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.29.0] - 2019-10-21 +### Added +- Client auth flag for b33 address +### Changed +- Remove incoming NTCP2 session from pending list when established +- Handle errors for NTCP2 SessionConfrimed send +### Fixed +- Failure to start on Windows XP +- SAM crash if invalid lookup address + ## [2.28.0] - 2019-08-27 ### Added - RAW datagrams in SAM diff --git a/Win32/installer.iss b/Win32/installer.iss index 4c78bb6a..736c7038 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.28.0" +#define I2Pd_ver "2.29.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 441f6be8..291d90ea 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2280 - versionName "2.28.0" + versionCode 2290 + versionName "2.29.0" ndk { abiFilters 'armeabi-v7a' abiFilters 'x86' diff --git a/appveyor.yml b/appveyor.yml index 67693ac3..fe827ec5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.28.0.{build} +version: 2.29.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 ed4bad86..31b8d4a5 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.28.0 +Version: 2.29.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -110,6 +110,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Oct 21 2019 orignal - 2.29.0 +- update to 2.29.0 + * Tue Aug 27 2019 orignal - 2.28.0 - update to 2.28.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index e18d1427..3db99af0 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.28.0 +Version: 2.29.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -108,6 +108,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Oct 21 2019 orignal - 2.29.0 +- update to 2.29.0 + * Tue Aug 27 2019 orignal - 2.28.0 - update to 2.28.0 diff --git a/debian/changelog b/debian/changelog index 2e88d9e3..f5f98680 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.29.0-1) unstable; urgency=medium + + * updated to version 2.29.0/0.9.43 + + -- orignal Mon, 21 Oct 2019 16:00:00 +0000 + i2pd (2.28.0-1) unstable; urgency=medium * updated to version 2.28.0/0.9.42 diff --git a/libi2pd/version.h b/libi2pd/version.h index 1c08a362..3b69a658 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 28 +#define I2PD_VERSION_MINOR 29 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 42 +#define I2P_VERSION_MICRO 43 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 5227655e..2c30a2d6 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 569088eaca25e63ac9c396df6b8c0451f5201a8f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 21 Oct 2019 12:02:43 -0400 Subject: [PATCH 0107/2950] 2.29.0 --- ChangeLog | 1 + qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0afe2316..07110fe2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ ### Fixed - Failure to start on Windows XP - SAM crash if invalid lookup address +- Possible crash when UPnP enabled on shutdown ## [2.28.0] - 2019-08-27 ### Added diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 2c30a2d6..e6cc81d3 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,7 +35,7 @@ - + From c66f9c8d6ddf43fbc1946f061a822d3c2c11a354 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 06:46:08 -0500 Subject: [PATCH 0108/2950] reset connection attempts before reconnect --- libi2pd/Transports.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 93db02d8..7e4ab797 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -651,7 +651,10 @@ namespace transport if (it->second.sessions.empty ()) // TODO: why? { if (it->second.delayedMessages.size () > 0) + { + it->second.numAttempts = 0; ConnectToPeer (ident, it->second); + } else { std::unique_lock l(m_PeersMutex); From 60fd3a45428392e75a4f79cd00df91e510409df4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 07:17:57 -0500 Subject: [PATCH 0109/2950] fixed #1434 use memset inster bzero --- libi2pd/Transports.cpp | 2 +- libi2pd/util.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 7e4ab797..b081439b 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -652,7 +652,7 @@ namespace transport { if (it->second.delayedMessages.size () > 0) { - it->second.numAttempts = 0; + // it->second.numAttempts = 0; // TODO: recognize if connect failed ConnectToPeer (ident, it->second); } else diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 96e8ad4c..76fe6d43 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -312,15 +312,14 @@ namespace net if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af) { // match - char * addr = new char[INET6_ADDRSTRLEN]; - bzero(addr, INET6_ADDRSTRLEN); + char addr[INET6_ADDRSTRLEN]; + memset (addr, 0, INET6_ADDRSTRLEN); if(af == AF_INET) inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN); else inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN); freeifaddrs(addrs); std::string cur_ifaddr(addr); - delete[] addr; return boost::asio::ip::address::from_string(cur_ifaddr); } cur = cur->ifa_next; From 77189bf8e963e6e72b482fcb2e234ebb964244f9 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 09:38:22 -0500 Subject: [PATCH 0110/2950] start over if an active session got disconnected --- libi2pd/Transports.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b081439b..34a28fb8 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -647,12 +647,14 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { + auto before = it->second.sessions.size (); it->second.sessions.remove (session); - if (it->second.sessions.empty ()) // TODO: why? + if (it->second.sessions.empty ()) { if (it->second.delayedMessages.size () > 0) { - // it->second.numAttempts = 0; // TODO: recognize if connect failed + if (before > 0) // we had an active session before + it->second.numAttempts = 0; // start over ConnectToPeer (ident, it->second); } else From 651240113c6dc1a133c034c861efb303daefba07 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 10:03:33 -0500 Subject: [PATCH 0111/2950] mark RI as unreachable if all connections failed --- libi2pd/Transports.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 34a28fb8..42a605a4 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -465,6 +465,7 @@ namespace transport } } LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available"); + i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed peer.Done (); std::unique_lock l(m_PeersMutex); m_Peers.erase (ident); From c3e3c091cc667e6fead61e6ada75795461b8a34b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 11:35:59 -0500 Subject: [PATCH 0112/2950] correct implementation of GetMTUWindows for WindowsXP --- libi2pd/util.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 76fe6d43..ebf977e2 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -61,17 +61,22 @@ namespace net { #ifdef WIN32 bool IsWindowsXPorLater() - { - OSVERSIONINFO osvi; + { + static bool isRequested = false; + static bool isXP = false; + if (!isRequested) + { + // request + OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); - if (osvi.dwMajorVersion <= 5) - return true; - else - return false; + isXP = osvi.dwMajorVersion <= 5; + isRequested = true; + } + return isXP; } int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback) @@ -202,7 +207,7 @@ namespace net std::string localAddressUniversal = localAddress.to_string(); #endif - if (IsWindowsXPorLater()) + bool isXP = IsWindowsXPorLater(); { #define inet_pton inet_pton_xp } @@ -210,13 +215,19 @@ namespace net if(localAddress.is_v4()) { sockaddr_in inputAddress; - inet_pton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); + if (isXP) + inet_pton_xp(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); + else + inet_pton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); return GetMTUWindowsIpv4(inputAddress, fallback); } else if(localAddress.is_v6()) { - sockaddr_in6 inputAddress; - inet_pton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); + sockaddr_in6 inputAddress; + if (isXP) + inet_pton_xp(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); + else + inet_pton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); return GetMTUWindowsIpv6(inputAddress, fallback); } else { LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported"); From a104c9881e2867102e3025c6c6252a5ae97f5696 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 11:57:34 -0500 Subject: [PATCH 0113/2950] some cleanup --- libi2pd/RouterContext.cpp | 5 ----- libi2pd/RouterContext.h | 6 +----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 3323de87..baa5a3d0 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -721,12 +721,7 @@ namespace i2p uint32_t RouterContext::GetUptime () const { -#ifdef WIN32 - // for compatibility with WinXP - return i2p::util::GetSecondsSinceEpoch () - m_StartupTime; -#else return std::chrono::duration_cast (std::chrono::steady_clock::now() - m_StartupTime).count (); -#endif } bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 9385e11f..f6aa281f 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -136,12 +136,8 @@ namespace i2p i2p::data::PrivateKeys m_Keys; std::shared_ptr m_Decryptor; uint64_t m_LastUpdateTime; // in seconds - bool m_AcceptsTunnels, m_IsFloodfill; -#ifdef WIN32 - uint64_t m_StartupTime = 0; // in seconds since epoch -#else + bool m_AcceptsTunnels, m_IsFloodfill; std::chrono::time_point m_StartupTime; -#endif uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; RouterStatus m_Status; From 34ce06ac17aeb592b85ec3669951c48c69725110 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 14:19:14 -0500 Subject: [PATCH 0114/2950] some cleanup --- libi2pd/util.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index ebf977e2..8f870ec4 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -61,11 +61,11 @@ namespace net { #ifdef WIN32 bool IsWindowsXPorLater() - { - static bool isRequested = false; - static bool isXP = false; - if (!isRequested) - { + { + static bool isRequested = false; + static bool isXP = false; + if (!isRequested) + { // request OSVERSIONINFO osvi; @@ -73,8 +73,8 @@ namespace net osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); - isXP = osvi.dwMajorVersion <= 5; - isRequested = true; + isXP = osvi.dwMajorVersion <= 5; + isRequested = true; } return isXP; } @@ -208,24 +208,21 @@ namespace net #endif bool isXP = IsWindowsXPorLater(); - { - #define inet_pton inet_pton_xp - } if(localAddress.is_v4()) { sockaddr_in inputAddress; - if (isXP) - inet_pton_xp(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); - else + if (isXP) + inet_pton_xp(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); + else inet_pton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); return GetMTUWindowsIpv4(inputAddress, fallback); } else if(localAddress.is_v6()) { - sockaddr_in6 inputAddress; - if (isXP) - inet_pton_xp(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); + sockaddr_in6 inputAddress; + if (isXP) + inet_pton_xp(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); else inet_pton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); return GetMTUWindowsIpv6(inputAddress, fallback); From 515c0860990c52b185a3fa36ebcad4bcfcf83a74 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Nov 2019 15:06:04 -0500 Subject: [PATCH 0115/2950] Use GetProcAddress for inet_pton. Fixed build error --- libi2pd/RouterContext.cpp | 30 +++++++++++++----------------- libi2pd/util.cpp | 18 +++++++----------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index baa5a3d0..bf3459d8 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -27,12 +27,8 @@ namespace i2p void RouterContext::Init () { srand (i2p::util::GetMillisecondsSinceEpoch () % 1000); -#ifdef WIN32 - // for compatibility with WinXP - m_StartupTime = i2p::util::GetSecondsSinceEpoch (); -#else - m_StartupTime = std::chrono::steady_clock::now(); -#endif + m_StartupTime = std::chrono::steady_clock::now(); + if (!Load ()) CreateNewRouter (); m_Decryptor = m_Keys.CreateDecryptor (nullptr); @@ -194,11 +190,11 @@ namespace i2p if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish) && (!v4only || address->host.is_v4 ())) { 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 ? 3 : 14; address->ntcp2->isPublished = publish; @@ -438,14 +434,14 @@ namespace i2p } // remove NTCP or NTCP2 v4 address bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) + if (ntcp) PublishNTCPAddress (false); else { bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) PublishNTCP2Address (port, false, true); - } + } // update UpdateRouterInfo (); } @@ -495,7 +491,7 @@ namespace i2p void RouterContext::SetSupportsV6 (bool supportsV6) { if (supportsV6) - { + { m_RouterInfo.EnableV6 (); // insert v6 addresses if necessary bool foundSSU = false, foundNTCP = false, foundNTCP2 = false; @@ -513,7 +509,7 @@ namespace i2p } else foundNTCP = true; - } + } port = addr->port; } if (!port) i2p::config::GetOption("port", port); @@ -525,7 +521,7 @@ namespace i2p { std::string host = "::1"; // TODO: read host m_RouterInfo.AddSSUAddress (host.c_str (), port, GetIdentHash ()); - } + } } // NTCP2 if (!foundNTCP2) @@ -534,11 +530,11 @@ namespace i2p bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); if (ntcp2 && ntcp2Published) { - std::string ntcp2Host; + std::string ntcp2Host; if (!i2p::config::IsDefault ("ntcp2.addressv6")) i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); else - ntcp2Host = "::1"; + 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); @@ -550,10 +546,10 @@ namespace i2p bool ntcp; i2p::config::GetOption("ntcp", ntcp); if (ntcp) { - std::string host = "::1"; + std::string host = "::1"; m_RouterInfo.AddNTCPAddress (host.c_str (), port); } - } + } } else m_RouterInfo.DisableV6 (); diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 8f870ec4..448d1307 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -22,7 +22,7 @@ #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) -// inet_pton exists Windows since Vista, but XP haven't that function! +// inet_pton exists Windows since Vista, but XP doesn't have that function! // This function was written by Petar Korponai?. See http://stackoverflow.com/questions/15660203/inet-pton-identifier-not-found int inet_pton_xp(int af, const char *src, void *dst) { @@ -206,25 +206,21 @@ namespace net #else std::string localAddressUniversal = localAddress.to_string(); #endif - - bool isXP = IsWindowsXPorLater(); + + typedef int (* IPN)(int af, const char *src, void *dst); + IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); + if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found if(localAddress.is_v4()) { sockaddr_in inputAddress; - if (isXP) - inet_pton_xp(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); - else - inet_pton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); + inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); return GetMTUWindowsIpv4(inputAddress, fallback); } else if(localAddress.is_v6()) { sockaddr_in6 inputAddress; - if (isXP) - inet_pton_xp(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); - else - inet_pton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); + inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); return GetMTUWindowsIpv6(inputAddress, fallback); } else { LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported"); From 6cfe4fa580a235920597d09da0392a854d2d2a47 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Nov 2019 14:13:31 -0500 Subject: [PATCH 0116/2950] handle sending errors --- libi2pd/NTCP2.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 9918efbc..5183bbe6 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1035,7 +1035,9 @@ namespace transport if (ecode) { - LogPrint (eLogWarning, "NTCP2: Couldn't send frame ", ecode.message ()); + if (ecode != boost::asio::error::operation_aborted) + LogPrint (eLogWarning, "NTCP2: Couldn't send frame ", ecode.message ()); + Terminate (); } else { @@ -1260,7 +1262,10 @@ namespace transport bool NTCP2Server::AddNTCP2Session (std::shared_ptr session, bool incoming) { - if (!session || !session->GetRemoteIdentity ()) return false; + if (!session) return false; + if (incoming) + m_PendingIncomingSessions.remove (session); + if (!session->GetRemoteIdentity ()) return false; auto& ident = session->GetRemoteIdentity ()->GetIdentHash (); auto it = m_NTCP2Sessions.find (ident); if (it != m_NTCP2Sessions.end ()) @@ -1270,8 +1275,6 @@ namespace transport return false; } m_NTCP2Sessions.insert (std::make_pair (ident, session)); - if (incoming) - m_PendingIncomingSessions.remove (session); return true; } From dd94b77b2ab05743495c13a8e20b840bb3690540 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 19 Nov 2019 13:50:16 +0300 Subject: [PATCH 0117/2950] use GetTickCount dll pointer, add USE_WINXP to makefile Signed-off-by: R4SAS --- Makefile.mingw | 4 ++++ Win32/Win32App.cpp | 13 ++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Makefile.mingw b/Makefile.mingw index e2f9e857..17be71eb 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -37,6 +37,10 @@ ifeq ($(USE_WIN32_APP), yes) DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) endif +ifeq ($(USE_WINXP_FLAGS), yes) + CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 +endif + # don't change following line to ifeq ($(USE_AESNI),yes) !!! ifeq ($(USE_AESNI),1) CPU_FLAGS += -maes diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 4bf4ab56..df87da3a 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -13,10 +13,6 @@ #include "Win32App.h" #include -#if defined(_MSC_VER) && _MSC_VER < 1900 -#define snprintf _snprintf -#endif - #define ID_ABOUT 2000 #define ID_EXIT 2001 #define ID_CONSOLE 2002 @@ -39,6 +35,9 @@ namespace i2p namespace win32 { static DWORD GracefulShutdownEndtime = 0; + + typedef DWORD (* IPN)(); + IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) { @@ -53,7 +52,7 @@ namespace win32 ID_ACCEPT_TRANSIT, "Accept &transit"); else InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config"); if (!i2p::util::DaemonWin32::Instance ().isGraceful) InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); else @@ -161,7 +160,7 @@ namespace win32 s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); if (GracefulShutdownEndtime != 0) { - DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCount()) / 1000; + DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000; s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft); } else @@ -239,7 +238,7 @@ namespace win32 i2p::context.SetAcceptsTunnels (false); SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second - GracefulShutdownEndtime = GetTickCount() + 10*60*1000; + GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000; i2p::util::DaemonWin32::Instance ().isGraceful = true; return 0; } From 95debf8c8079cc270dc698b0e00d3c17a9d865a5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 19 Nov 2019 14:29:55 +0300 Subject: [PATCH 0118/2950] update mingw build script Signed-off-by: R4SAS --- build/build_mingw.cmd | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index d7fe363d..ec861bb2 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -54,6 +54,14 @@ set bitness=64 call :BUILDING echo. +REM building for WinXP +set "WD=C:\msys64-xp\usr\bin\" +set MSYSTEM=MINGW32 +set bitness=32 +set "xSH=%WD%bash -lc" +call :BUILDING_XP +echo. + del README.txt >> nul echo Build complete... @@ -71,5 +79,11 @@ echo Build AESNI... %xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_aesni_%tag%.log 2>&1 echo Build without extensions... %xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && 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... +%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && 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 704fca969f82ff81d0002c1122fa0921a3037e3d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Nov 2019 12:05:32 -0500 Subject: [PATCH 0119/2950] handle accept errors --- libi2pd/NTCP2.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 5183bbe6..fd20d35c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1345,15 +1345,19 @@ namespace transport { conn->ServerLogin (); m_PendingIncomingSessions.push_back (conn); + conn = nullptr; } } else LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ()); } + else + LogPrint (eLogError, "NTCP2: Accept error ", error.message ()); if (error != boost::asio::error::operation_aborted) { - conn = std::make_shared (*this); + if (!conn) // connection is used + conn = std::make_shared (*this); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } @@ -1409,13 +1413,13 @@ namespace transport // pending for (auto it = m_PendingIncomingSessions.begin (); it != m_PendingIncomingSessions.end ();) { - if ((*it)->IsEstablished () || (*it)->IsTerminated ()) - it = m_PendingIncomingSessions.erase (it); // established or terminated - else if ((*it)->IsTerminationTimeoutExpired (ts)) + if ((*it)->IsEstablished () || (*it)->IsTerminationTimeoutExpired (ts)) { (*it)->Terminate (); - it = m_PendingIncomingSessions.erase (it); // expired + it = m_PendingIncomingSessions.erase (it); // etsablished of expired } + else if ((*it)->IsTerminated ()) + it = m_PendingIncomingSessions.erase (it); // already terminated else it++; } From 0abb871f3ffe013110920adf70c8e2f9ee17caeb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Nov 2019 13:00:50 -0500 Subject: [PATCH 0120/2950] close socket after if accept failed --- libi2pd/NTCP2.cpp | 4 +++- libi2pd/NTCP2.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index fd20d35c..c12c5804 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1356,8 +1356,10 @@ namespace transport if (error != boost::asio::error::operation_aborted) { - if (!conn) // connection is used + if (!conn) // connection is used, create new one conn = std::make_shared (*this); + else // reuse failed + conn->Close (); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 10f4f483..d2f1f88d 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -133,6 +133,7 @@ namespace transport void Terminate (); void TerminateByTimeout (); void Done (); + void Close () { m_Socket.close (); }; // for accept boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; From 35d62686754a2d959964cf4c52f6fe3689eb6bbb Mon Sep 17 00:00:00 2001 From: Alexandre ZANNI <16578570+noraj@users.noreply.github.com> Date: Sat, 23 Nov 2019 22:52:31 +0100 Subject: [PATCH 0121/2950] README: explicit linux distro supported close #1440 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b5fb8f7e..25e6c3e5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![GitHub release](https://img.shields.io/github/release/PurpleI2P/i2pd.svg?label=latest%20release)](https://github.com/PurpleI2P/i2pd/releases/latest) [![Snapcraft release](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![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) i2pd ==== @@ -63,9 +64,10 @@ Build instructions: **Supported systems:** * GNU/Linux - [![Build Status](https://travis-ci.org/PurpleI2P/i2pd.svg?branch=openssl)](https://travis-ci.org/PurpleI2P/i2pd) + * 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) -* 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/) * Docker image - [![Build Status](https://dockerbuildbadges.quelltext.eu/status.svg?organization=meeh&repository=i2pd)](https://hub.docker.com/r/meeh/i2pd/builds/) * Snap - [![Snap Status](https://build.snapcraft.io/badge/PurpleI2P/i2pd-snap.svg)](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap) * FreeBSD From 39300a5bbf7ca4b761292438455bb4005dee7922 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Nov 2019 17:49:36 -0500 Subject: [PATCH 0122/2950] removed reseed.i2p.net.in --- .../reseed/reseedi2pnetin_at_mail.i2p.crt | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 contrib/certificates/reseed/reseedi2pnetin_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/reseedi2pnetin_at_mail.i2p.crt b/contrib/certificates/reseed/reseedi2pnetin_at_mail.i2p.crt deleted file mode 100644 index b71696a3..00000000 --- a/contrib/certificates/reseed/reseedi2pnetin_at_mail.i2p.crt +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIF3DCCA8SgAwIBAgIQPxUlcrbHX/xdyJ09E36rJzANBgkqhkiG9w0BAQsFADB3 -MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK -ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEgMB4GA1UEAwwX -cmVzZWVkaTJwbmV0aW5AbWFpbC5pMnAwHhcNMTgxMjA3MTYzNDIxWhcNMjgxMjA3 -MTYzNDIxWjB3MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhY -MR4wHAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEg -MB4GA1UEAwwXcmVzZWVkaTJwbmV0aW5AbWFpbC5pMnAwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQC912NDk6x85uqB4gyQQcded0RVrbWehWOanDRv7kC3 -92jeziPbeMtqrLsfU1MdDtQiGijpNkQ/IIitPw+6vJAIh82gyOUZvsn2XOyb/Fz0 -Fu8OrDghwl39yK8kwtqCFw3VAgafgKxz2oRge9mxFBECi50vYEPIBwNhr4yc/opu -wWUmzmRyX4gD7vKmRU6ZTwX4LXnwdl+5VbW3updcZKsDuTnKvC9FGhDRR9kIk2G9 -43sLN263nCYPykP7DaB1cUdi1vDEMw5dot+eu16qTIbuypEvYNvbB/9FyCQllm1h -vBbSku3IYpcnRPmoeyhoR/MmCySRbK5R4SrSsVD1YBpwxgn0Q4+fzEgFzT9P4oez -HkDGKVP2HdgmXx9j36fEqqvjqzRleWDwEWwIZVRLCFO+hhhT3JAjnNGJTWv1SQGB -8tz9nyYTJuhvyHE/CO5owFeCdeOGMq2KPge9w34T+mvewTEEhGU8yRAt8Xp8s5Y9 -RCUGvuQ79+edRtj7FJg7yVB8pAQ+VB9msNQvzrTnPYC9Wo7chJhBiraMiIabzIhC -f34Gg9lkX1N0dVND5rnZWwzBM6JhNG1iZZCRHVPnXdZRixUlqmFpCP/eekshksj/ -6UP/WeGA6X4HyEsC6QEf7eMhcHYjyyTzYagKrwCHg77fmIjF8rmpP2LqWSQW8bDD -uQIDAQABo2QwYjAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIG -CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wIAYDVR0OBBkEF3Jlc2VlZGkycG5l -dGluQG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQCWpXs6iuTy/w2R7q7Ua6vl -JYZwbQ+czk5ydzkBgcNkMMMNRT7sZR9xYvV+ftiL4bFQP/3ZJyo7cYz2Q6+M3oAm -YDcZWBkLUVihSlMxhWwmeFTKV2EL+bzwY1V/cy7wgukKnFIes75dLP/v25jgjdlw -Xe6R+fQM0EoHeVzzrWk/qYp6oEwtQXfZnUu/Bf45hRnnHBzzh1wCql41vbEs3Niq -+SVwY1wLT0yC1L8HqjCLX1/L5PAXxbvEGzwnXSkLKK4bPxdmVDZvS9uzXrWmTbNi -HpKIFnOif16zSgyeaOM7HETIJuVzgooUMtt+Vsr1VGdtm6K7I9J5C+rX/ckU8oaX -UjmzhWXudN0VTslogsKUCV6xG2CskeE3wnuT8HYXz9NMw6c/kIGH4hY7LcfU8Teu -QjSy2RRvy6InmZNV5sY9lzzO6romEycSoUlpCa3Ltb/5KKoYZFTsXr8suqJk89lC -e+TVMHqOZdLK/usqQDcafLypHpw9SH2Tg4jrzV/zLqacbjx6bZD5IrpY0Gf7BXg/ -pikwyA9c490G6ZcWrSEP8bzh6LL2rA2AwxaeJJNVyLHCSLrn/7DezM5J/qhd90Qg -kcZGJrUOCSWl6mDvUZn5XiQ955XwOnZQ+wsM85B3CVX22x5bp0SYWHCQBPnthPwP -Q5DD3jExbpwG5n35HEcHYw== ------END CERTIFICATE----- From 29f0e10411aba79d68fdf80fb0fd67b8b101cfa1 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Dec 2019 15:37:24 -0500 Subject: [PATCH 0123/2950] Elligator added --- build/CMakeLists.txt | 1 + libi2pd/Elligator.cpp | 30 ++++++++++++++++++++++++++++++ libi2pd/Elligator.h | 25 +++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 libi2pd/Elligator.cpp create mode 100644 libi2pd/Elligator.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 949f6a46..a9cf3a83 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -82,6 +82,7 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/Ed25519.cpp" "${LIBI2PD_SRC_DIR}/NTCP2.cpp" "${LIBI2PD_SRC_DIR}/Blinding.cpp" + "${LIBI2PD_SRC_DIR}/Elligator.cpp" ) if (WITH_WEBSOCKETS) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp new file mode 100644 index 00000000..cc49adbf --- /dev/null +++ b/libi2pd/Elligator.cpp @@ -0,0 +1,30 @@ +#include "Elligator.h" + +namespace i2p +{ +namespace crypto +{ + Elligator2::Elligator2 () + { + } + + Elligator2::~Elligator2 () + { + } + + static std::unique_ptr g_Elligator; + std::unique_ptr& GetElligator () + { + if (!g_Elligator) + { + auto el = new Elligator2(); + if (!g_Elligator) // make sure it was not created already + g_Elligator.reset (el); + else + delete el; + } + return g_Elligator; + } +} +} + diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h new file mode 100644 index 00000000..7993ccb9 --- /dev/null +++ b/libi2pd/Elligator.h @@ -0,0 +1,25 @@ +#ifndef ELLIGATOR_H__ +#define ELLIGATOR_H__ + +#include + +namespace i2p +{ +namespace crypto +{ + + class Elligator2 + { + public: + + Elligator2 (); + ~Elligator2 (); + }; + + std::unique_ptr& GetElligator (); +} +} + +#endif + + From 5fa2485a7dc03b856b1dd942bd4a6757b5237901 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Dec 2019 17:27:16 -0500 Subject: [PATCH 0124/2950] removed reseed.i2p.net.in --- libi2pd/Config.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index e6007d5f..e2f4bdd0 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -192,7 +192,6 @@ namespace config { "https://netdb.i2p2.no/," // "https://us.reseed.i2p2.no:444/," // mamoth's shit // "https://uk.reseed.i2p2.no:444/," // mamoth's shit - "https://reseed.i2p.net.in/," "https://download.xxlspeed.com/," "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," From df1aa52e087135a25602ed2935fe8a785ff7cd21 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Dec 2019 16:03:11 -0500 Subject: [PATCH 0125/2950] Elligator's encode --- libi2pd/Elligator.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++ libi2pd/Elligator.h | 8 +++++ 2 files changed, 76 insertions(+) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index cc49adbf..cc38672a 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -1,15 +1,83 @@ +#include "Crypto.h" #include "Elligator.h" namespace i2p { namespace crypto { + static const uint8_t p_[32]= + { + 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f + }; + + static const uint8_t n1_[32] = + { + 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f + }; + + static const uint8_t n2_[32] = + { + 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f + }; + + static const uint8_t A_[32] = + { + 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + static const uint8_t u_[32] = + { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + #define decode_bytes(x) { x = BN_new (); BN_bin2bn (x##_, 32, x); } Elligator2::Elligator2 () { + decode_bytes (p); + decode_bytes (n1); + decode_bytes (n2); + decode_bytes (A); + decode_bytes (u); + + BN_CTX * ctx = BN_CTX_new (); + BN_mod_inverse (iu, u, p, ctx); + BN_CTX_free (ctx); } Elligator2::~Elligator2 () { + BN_free (p); + BN_free (n1); + BN_free (n2); + BN_free (A); + } + + void Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + + BIGNUM * a = BN_CTX_get (ctx); BN_bin2bn (key, 32, a); + BIGNUM * b = BN_CTX_get (ctx); + BN_add (a, A, b); + BIGNUM * c = BN_CTX_get (ctx); + BN_mod_exp (c, b, n2, p, ctx); + BN_mod_mul (b, c, a, p, ctx); + BN_sub (b, p, b); + + //BN_mod_exp (c, b, n2, p, ctx); + + BN_mod_mul (c, b, iu, p, ctx); + // TODO: + bn2buf (b, encoded, 32); + + BN_CTX_end (ctx); + BN_CTX_free (ctx); } static std::unique_ptr g_Elligator; diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 7993ccb9..09f46888 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -1,7 +1,9 @@ #ifndef ELLIGATOR_H__ #define ELLIGATOR_H__ +#include #include +#include namespace i2p { @@ -14,6 +16,12 @@ namespace crypto Elligator2 (); ~Elligator2 (); + + void Encode (const uint8_t * key, uint8_t * encoded) const; + + private: + + BIGNUM * p, * n1, * n2, * A, * u, * iu; }; std::unique_ptr& GetElligator (); From 28779002335b9758ef9a3bf23706f1b96c65f32d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Dec 2019 16:13:59 -0500 Subject: [PATCH 0126/2950] use 486662 for A --- libi2pd/Elligator.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index cc38672a..213345b9 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -23,11 +23,6 @@ namespace crypto 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }; - static const uint8_t A_[32] = - { - 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; static const uint8_t u_[32] = { @@ -35,17 +30,18 @@ namespace crypto 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - #define decode_bytes(x) { x = BN_new (); BN_bin2bn (x##_, 32, x); } + #define decode_bytes(x) { x = BN_new (); BN_bin2bn (x##_, 32, x); } // TODO: endianess Elligator2::Elligator2 () { decode_bytes (p); decode_bytes (n1); - decode_bytes (n2); - decode_bytes (A); + decode_bytes (n2); decode_bytes (u); + A = BN_new (); BN_set_word (A, 486662); + BN_CTX * ctx = BN_CTX_new (); - BN_mod_inverse (iu, u, p, ctx); + iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); BN_CTX_free (ctx); } From e6956d9bb044e92dfcd0a1b59e79353d8db09985 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Dec 2019 14:54:15 -0500 Subject: [PATCH 0127/2950] calculate constants --- libi2pd/Elligator.cpp | 70 ++++++++++++++++++++++++------------------- libi2pd/Elligator.h | 2 +- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 213345b9..1ca48ca6 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -5,52 +5,60 @@ namespace i2p { namespace crypto { - static const uint8_t p_[32]= - { - 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f - }; - - static const uint8_t n1_[32] = - { - 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f - }; - - static const uint8_t n2_[32] = - { - 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f - }; - - static const uint8_t u_[32] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - #define decode_bytes(x) { x = BN_new (); BN_bin2bn (x##_, 32, x); } // TODO: endianess + Elligator2::Elligator2 () { - decode_bytes (p); - decode_bytes (n1); - decode_bytes (n2); - decode_bytes (u); - - A = BN_new (); BN_set_word (A, 486662); + // TODO: share with Ed22519 + p = BN_new (); + // 2^255-19 + BN_set_bit (p, 255); // 2^255 + BN_sub_word (p, 19); + p38 = BN_dup (p); BN_add_word (p38, 3); BN_div_word (p38, 8); // (p+3)/8 + p12 = BN_dup (p); BN_sub_word (p12, 1); BN_div_word (p12, 2); // (p-1)/2 + n1 = BN_dup (p); BN_sub_word (n1, 1); // p-1 + n2 = BN_dup (p); BN_sub_word (n2, 2); // p-2 - BN_CTX * ctx = BN_CTX_new (); + A = BN_new (); BN_set_word (A, 486662); + nA = BN_new (); BN_sub (nA, p, A); + + BN_CTX * ctx = BN_CTX_new (); + // calculate sqrt(-1) + sqrtn1 = BN_new (); + BN_mod_exp (sqrtn1, n1, p38, p, ctx); // (-1)^((p+3)/8) + auto p14 = BN_dup (p); BN_sub_word (p14, 1); BN_div_word (p14, 4); // (p-1)/4 + auto tmp = BN_new (); BN_set_word (tmp, 2); + BN_mod_exp (tmp, tmp, p14, p, ctx); // 2^((p-1)/4 + BN_mod_mul (sqrtn1, tmp, sqrtn1, p, ctx); // 2^((p-1)/4 * (-1)^((p+3)/8) + BN_free (p14); + + u = BN_new (); BN_bin2bn (u_, 32, u); // TODO: endianess iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); + + // calculate d = -121665*inv(121666) + d = BN_new (); + BN_set_word (tmp, 121666); + BN_mod_inverse (tmp, tmp, p, ctx); + BN_set_word (d, 121665); + BN_set_negative (d, 1); + BN_mod_mul (d, d, tmp, p, ctx); + BN_free (tmp); + //printf ("%s\n", BN_bn2hex (d)); + BN_CTX_free (ctx); } Elligator2::~Elligator2 () { - BN_free (p); - BN_free (n1); - BN_free (n2); - BN_free (A); + BN_free (p); BN_free (p38); BN_free (p12); + BN_free (n1);BN_free (n2); BN_free (sqrtn1); + BN_free (A); BN_free (nA); + BN_free (u); BN_free (iu); BN_free (d); } void Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 09f46888..da1c2f83 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -21,7 +21,7 @@ namespace crypto private: - BIGNUM * p, * n1, * n2, * A, * u, * iu; + BIGNUM * p, * n1, * n2, * p38, * p12, * sqrtn1, * A, * nA, * u, * iu, * d; }; std::unique_ptr& GetElligator (); From 934f1269f53ac6a12a56d54e49e9695f088eb5c5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Dec 2019 00:59:33 +0000 Subject: [PATCH 0128/2950] appveyor: replace deprecated --force in msys2 --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index fe827ec5..5f314fa6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,9 +18,9 @@ environment: install: - 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" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --overwrite" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --overwrite" - if "%MSYSTEM%" == "MINGW64" ( c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" From 72492e33a04f462af5b29402537584655729a6df Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 7 Dec 2019 01:02:23 +0000 Subject: [PATCH 0129/2950] appveyor: drop msys2 overwrite --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5f314fa6..f6eee9ab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,9 +18,9 @@ environment: install: - 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" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --overwrite" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --overwrite" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" - if "%MSYSTEM%" == "MINGW64" ( c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" From 95df3e4b399fd939304c29f0cb3bdc934068c123 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 6 Dec 2019 20:29:03 -0500 Subject: [PATCH 0130/2950] encode key --- libi2pd/Elligator.cpp | 73 +++++++++++++++++++------------------------ libi2pd/Elligator.h | 6 +++- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 1ca48ca6..e0f12a85 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -5,12 +5,6 @@ namespace i2p { namespace crypto { - static const uint8_t u_[32] = - { - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Elligator2::Elligator2 () { @@ -21,44 +15,29 @@ namespace crypto BN_sub_word (p, 19); p38 = BN_dup (p); BN_add_word (p38, 3); BN_div_word (p38, 8); // (p+3)/8 p12 = BN_dup (p); BN_sub_word (p12, 1); BN_div_word (p12, 2); // (p-1)/2 - n1 = BN_dup (p); BN_sub_word (n1, 1); // p-1 - n2 = BN_dup (p); BN_sub_word (n2, 2); // p-2 + p14 = BN_dup (p); BN_sub_word (p14, 1); BN_div_word (p14, 4); // (p-1)/4 - A = BN_new (); BN_set_word (A, 486662); + auto A = BN_new (); BN_set_word (A, 486662); nA = BN_new (); BN_sub (nA, p, A); BN_CTX * ctx = BN_CTX_new (); // calculate sqrt(-1) sqrtn1 = BN_new (); - BN_mod_exp (sqrtn1, n1, p38, p, ctx); // (-1)^((p+3)/8) - auto p14 = BN_dup (p); BN_sub_word (p14, 1); BN_div_word (p14, 4); // (p-1)/4 - auto tmp = BN_new (); BN_set_word (tmp, 2); - BN_mod_exp (tmp, tmp, p14, p, ctx); // 2^((p-1)/4 - BN_mod_mul (sqrtn1, tmp, sqrtn1, p, ctx); // 2^((p-1)/4 * (-1)^((p+3)/8) - BN_free (p14); + BN_set_word (sqrtn1, 2); + BN_mod_exp (sqrtn1, sqrtn1, p14, p, ctx); // 2^((p-1)/4 - u = BN_new (); BN_bin2bn (u_, 32, u); // TODO: endianess + u = BN_new (); BN_set_word (u, 2); iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); - - // calculate d = -121665*inv(121666) - d = BN_new (); - BN_set_word (tmp, 121666); - BN_mod_inverse (tmp, tmp, p, ctx); - BN_set_word (d, 121665); - BN_set_negative (d, 1); - BN_mod_mul (d, d, tmp, p, ctx); - BN_free (tmp); - //printf ("%s\n", BN_bn2hex (d)); + //printf ("%s\n", BN_bn2hex (iu)); BN_CTX_free (ctx); } Elligator2::~Elligator2 () { - BN_free (p); BN_free (p38); BN_free (p12); - BN_free (n1);BN_free (n2); BN_free (sqrtn1); - BN_free (A); BN_free (nA); - BN_free (u); BN_free (iu); BN_free (d); + BN_free (p); BN_free (p38); BN_free (p12); BN_free (p14); + BN_free (sqrtn1); BN_free (A); BN_free (nA); + BN_free (u); BN_free (iu); } void Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const @@ -66,24 +45,36 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - BIGNUM * a = BN_CTX_get (ctx); BN_bin2bn (key, 32, a); - BIGNUM * b = BN_CTX_get (ctx); - BN_add (a, A, b); - BIGNUM * c = BN_CTX_get (ctx); - BN_mod_exp (c, b, n2, p, ctx); - BN_mod_mul (b, c, a, p, ctx); - BN_sub (b, p, b); + BIGNUM * x = BN_CTX_get (ctx); BN_bin2bn (key, 32, x); + BIGNUM * xA = BN_CTX_get (ctx); BN_add (xA, x, A); // x + A + BN_sub (xA, p, xA); // p - (x + A) - //BN_mod_exp (c, b, n2, p, ctx); + BIGNUM * r = BN_CTX_get (ctx); + BN_mod_inverse (r, xA, p, ctx); + BN_mod_mul (r, r, x, p, ctx); + BN_mod_mul (r, r, iu, p, ctx); - BN_mod_mul (c, b, iu, p, ctx); - // TODO: - bn2buf (b, encoded, 32); + SquareRoot (r, r, ctx); + bn2buf (r, encoded, 32); BN_CTX_end (ctx); BN_CTX_free (ctx); } + void Elligator2::SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const + { + BIGNUM * t = BN_CTX_get (ctx); + BN_mod_exp (t, x, p14, p, ctx); // t = x^((p-1)/4) + BN_mod_exp (r, x, p38, p, ctx); // r = x^((p+3)/8) + BN_add_word (t, 1); + + if (!BN_cmp (t, p)) + BN_mod_mul (r, r, sqrtn1, p, ctx); + + if (BN_cmp (r, p12) > 0) // r > (p-1)/2 + BN_sub (r, p, r); + } + static std::unique_ptr g_Elligator; std::unique_ptr& GetElligator () { diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index da1c2f83..7d2d2f15 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -19,9 +19,13 @@ namespace crypto void Encode (const uint8_t * key, uint8_t * encoded) const; + private: + + void SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const; + private: - BIGNUM * p, * n1, * n2, * p38, * p12, * sqrtn1, * A, * nA, * u, * iu, * d; + BIGNUM * p, * p38, * p12, * p14, * sqrtn1, * A, * nA, * u, * iu; }; std::unique_ptr& GetElligator (); From 3100d587d1100a97a0145f8293f5d5393029e089 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 9 Dec 2019 13:23:17 -0500 Subject: [PATCH 0131/2950] use d%q --- libi2pd/Ed25519.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 1096b3b7..69fec4e8 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -31,7 +31,7 @@ namespace crypto BN_mod_inverse (tmp, tmp, q, ctx); BN_set_word (d, 121665); BN_set_negative (d, 1); - BN_mul (d, d, tmp, ctx); + BN_mod_mul (d, d, tmp, q, ctx); // 2^((q-1)/4) I = BN_new (); From c38298c06e42ae955d893f55cfa7ffe25c605eeb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 9 Dec 2019 16:11:46 -0500 Subject: [PATCH 0132/2950] Elligator decode --- libi2pd/Elligator.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++- libi2pd/Elligator.h | 1 + 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index e0f12a85..1f67d641 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -45,7 +45,14 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - BIGNUM * x = BN_CTX_get (ctx); BN_bin2bn (key, 32, x); + uint8_t key1[32]; + for (size_t i = 0; i < 16; i++) // from Little Endian + { + key1[i] = key[15 - i]; + key1[15 - i] = key[i]; + } + + BIGNUM * x = BN_CTX_get (ctx); BN_bin2bn (key1, 32, x); BIGNUM * xA = BN_CTX_get (ctx); BN_add (xA, x, A); // x + A BN_sub (xA, p, xA); // p - (x + A) @@ -56,6 +63,64 @@ namespace crypto SquareRoot (r, r, ctx); bn2buf (r, encoded, 32); + + for (size_t i = 0; i < 16; i++) // To Little Endian + { + uint8_t tmp = encoded[i]; + encoded[i] = encoded[15 - i]; + encoded[15 - i] = tmp; + } + + BN_CTX_end (ctx); + BN_CTX_free (ctx); + } + + void Elligator2::Decode (const uint8_t * encoded, uint8_t * key) const + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + + uint8_t encoded1[32]; + for (size_t i = 0; i < 16; i++) // from Little Endian + { + encoded1[i] = encoded[15 - i]; + encoded1[15 - i] = encoded[i]; + } + + BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); + + // v=-A/(1+u*r^2) + BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); + BN_mod_mul (v, v, u, p, ctx); + BN_add_word (v, 1); + BN_mod_inverse (v, v, p, ctx); + BN_mod_mul (v, v, nA, p, ctx); + + BIGNUM * vpA = BN_CTX_get (ctx); + BN_add (vpA, v, A); // v + A + // t = v^3+A*v^2+v = v^2*(v+A)+v + BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); + BN_mod_mul (t, t, vpA, p, ctx); + BN_mod_add (t, t, v, p, ctx); + + int legendre = 0; // TODO: + BIGNUM * x = BN_CTX_get (ctx); + if (legendre == 1) + BN_copy (x, v); + else + { + BN_sub (x, p, v); + BN_mod_sub (x, x, A, p, ctx); + } + + bn2buf (x, key, 32); + for (size_t i = 0; i < 16; i++) // To Little Endian + { + uint8_t tmp = key[i]; + key[i] = key[15 - i]; + key[15 - i] = tmp; + } + BN_CTX_end (ctx); BN_CTX_free (ctx); diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 7d2d2f15..f2a1c805 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -18,6 +18,7 @@ namespace crypto ~Elligator2 (); void Encode (const uint8_t * key, uint8_t * encoded) const; + void Decode (const uint8_t * encoded, uint8_t * key) const; private: From 8d7490525716809c30c2a433dd2e6cfd44f079bc Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 10:44:19 -0500 Subject: [PATCH 0133/2950] 0.9.44 --- libi2pd/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/version.h b/libi2pd/version.h index 3b69a658..2e876fdb 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 43 +#define I2P_VERSION_MICRO 44 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) From 7417867d0f974594ebbd56071a914ec46cfb1bbf Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 10:45:08 -0500 Subject: [PATCH 0134/2950] implemented Legendre --- libi2pd/Elligator.cpp | 114 ++++++++++++++++++++++++++---------------- libi2pd/Elligator.h | 5 +- 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 1f67d641..07711ae0 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -40,8 +40,9 @@ namespace crypto BN_free (u); BN_free (iu); } - void Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const + bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const { + bool ret = true; BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -56,27 +57,38 @@ namespace crypto BIGNUM * xA = BN_CTX_get (ctx); BN_add (xA, x, A); // x + A BN_sub (xA, p, xA); // p - (x + A) - BIGNUM * r = BN_CTX_get (ctx); - BN_mod_inverse (r, xA, p, ctx); - BN_mod_mul (r, r, x, p, ctx); - BN_mod_mul (r, r, iu, p, ctx); + BIGNUM * uxxA = BN_CTX_get (ctx); // u*x*xA + BN_mod_mul (uxxA, u, x, p, ctx); + BN_mod_mul (uxxA, uxxA, xA, p, ctx); - SquareRoot (r, r, ctx); - bn2buf (r, encoded, 32); - - for (size_t i = 0; i < 16; i++) // To Little Endian + if (Legendre (uxxA, ctx) != -1) { - uint8_t tmp = encoded[i]; - encoded[i] = encoded[15 - i]; - encoded[15 - i] = tmp; + BIGNUM * r = BN_CTX_get (ctx); + BN_mod_inverse (r, xA, p, ctx); + BN_mod_mul (r, r, x, p, ctx); + BN_mod_mul (r, r, iu, p, ctx); + + SquareRoot (r, r, ctx); + bn2buf (r, encoded, 32); + + for (size_t i = 0; i < 16; i++) // To Little Endian + { + uint8_t tmp = encoded[i]; + encoded[i] = encoded[15 - i]; + encoded[15 - i] = tmp; + } } + else + ret = false; BN_CTX_end (ctx); BN_CTX_free (ctx); + return ret; } - void Elligator2::Decode (const uint8_t * encoded, uint8_t * key) const + bool Elligator2::Decode (const uint8_t * encoded, uint8_t * key) const { + bool ret = true; BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -89,41 +101,47 @@ namespace crypto BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); - // v=-A/(1+u*r^2) - BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); - BN_mod_mul (v, v, u, p, ctx); - BN_add_word (v, 1); - BN_mod_inverse (v, v, p, ctx); - BN_mod_mul (v, v, nA, p, ctx); - - BIGNUM * vpA = BN_CTX_get (ctx); - BN_add (vpA, v, A); // v + A - // t = v^3+A*v^2+v = v^2*(v+A)+v - BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); - BN_mod_mul (t, t, vpA, p, ctx); - BN_mod_add (t, t, v, p, ctx); - - int legendre = 0; // TODO: - BIGNUM * x = BN_CTX_get (ctx); - if (legendre == 1) - BN_copy (x, v); - else + if (BN_cmp (r, p12) < 0) // r < (p-1)/2 { - BN_sub (x, p, v); - BN_mod_sub (x, x, A, p, ctx); - } + // v = -A/(1+u*r^2) + BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); + BN_mod_mul (v, v, u, p, ctx); + BN_add_word (v, 1); + BN_mod_inverse (v, v, p, ctx); + BN_mod_mul (v, v, nA, p, ctx); + + BIGNUM * vpA = BN_CTX_get (ctx); + BN_add (vpA, v, A); // v + A + // t = v^3+A*v^2+v = v^2*(v+A)+v + BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); + BN_mod_mul (t, t, vpA, p, ctx); + BN_mod_add (t, t, v, p, ctx); + + int legendre = Legendre (t, ctx); + BIGNUM * x = BN_CTX_get (ctx); + if (legendre == 1) + BN_copy (x, v); + else + { + BN_sub (x, p, v); + BN_mod_sub (x, x, A, p, ctx); + } - bn2buf (x, key, 32); - for (size_t i = 0; i < 16; i++) // To Little Endian - { - uint8_t tmp = key[i]; - key[i] = key[15 - i]; - key[15 - i] = tmp; + bn2buf (x, key, 32); + for (size_t i = 0; i < 16; i++) // To Little Endian + { + uint8_t tmp = key[i]; + key[i] = key[15 - i]; + key[15 - i] = tmp; + } } - + else + ret = false; BN_CTX_end (ctx); BN_CTX_free (ctx); + + return ret; } void Elligator2::SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const @@ -140,6 +158,18 @@ namespace crypto BN_sub (r, p, r); } + int Elligator2::Legendre (const BIGNUM * a, BN_CTX * ctx) const + { + // assume a < p, so don't check for a % p = 0 + BIGNUM * r = BN_CTX_get (ctx); + BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p + if (BN_is_word(r, 1)) + return 1; + else if (BN_is_zero(r)) + return 0; + return -1; + } + static std::unique_ptr g_Elligator; std::unique_ptr& GetElligator () { diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index f2a1c805..6f9eaf2a 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -17,12 +17,13 @@ namespace crypto Elligator2 (); ~Elligator2 (); - void Encode (const uint8_t * key, uint8_t * encoded) const; - void Decode (const uint8_t * encoded, uint8_t * key) const; + bool Encode (const uint8_t * key, uint8_t * encoded) const; + bool Decode (const uint8_t * encoded, uint8_t * key) const; private: void SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const; + int Legendre (const BIGNUM * a, BN_CTX * ctx) const; // a/p private: From d7b819267fccc817ff0005790aed04f75162f1f4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 10:53:39 -0500 Subject: [PATCH 0135/2950] check a for 0 in Legendre --- libi2pd/Elligator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 07711ae0..febece03 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -160,7 +160,8 @@ namespace crypto int Elligator2::Legendre (const BIGNUM * a, BN_CTX * ctx) const { - // assume a < p, so don't check for a % p = 0 + // assume a < p, so don't check for a % p = 0, but a = 0 only + if (BN_is_zero(a)) return 0; BIGNUM * r = BN_CTX_get (ctx); BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p if (BN_is_word(r, 1)) From 5faf84c73206be3e9f2609dc6f381aac3be3c2e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 12:51:39 -0500 Subject: [PATCH 0136/2950] correct conversion from Little Endian --- libi2pd/Elligator.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index febece03..9be0a610 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -17,8 +17,8 @@ namespace crypto p12 = BN_dup (p); BN_sub_word (p12, 1); BN_div_word (p12, 2); // (p-1)/2 p14 = BN_dup (p); BN_sub_word (p14, 1); BN_div_word (p14, 4); // (p-1)/4 - auto A = BN_new (); BN_set_word (A, 486662); - nA = BN_new (); BN_sub (nA, p, A); + A = BN_new (); BN_set_word (A, 486662); + nA = BN_new (); BN_sub (nA, p, A); BN_CTX * ctx = BN_CTX_new (); // calculate sqrt(-1) @@ -28,8 +28,7 @@ namespace crypto u = BN_new (); BN_set_word (u, 2); iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); - //printf ("%s\n", BN_bn2hex (iu)); - + BN_CTX_free (ctx); } @@ -49,8 +48,8 @@ namespace crypto uint8_t key1[32]; for (size_t i = 0; i < 16; i++) // from Little Endian { - key1[i] = key[15 - i]; - key1[15 - i] = key[i]; + key1[i] = key[31 - i]; + key1[31 - i] = key[i]; } BIGNUM * x = BN_CTX_get (ctx); BN_bin2bn (key1, 32, x); @@ -62,7 +61,7 @@ namespace crypto BN_mod_mul (uxxA, uxxA, xA, p, ctx); if (Legendre (uxxA, ctx) != -1) - { + { BIGNUM * r = BN_CTX_get (ctx); BN_mod_inverse (r, xA, p, ctx); BN_mod_mul (r, r, x, p, ctx); @@ -74,8 +73,8 @@ namespace crypto for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = encoded[i]; - encoded[i] = encoded[15 - i]; - encoded[15 - i] = tmp; + encoded[i] = encoded[31 - i]; + encoded[31 - i] = tmp; } } else @@ -95,8 +94,8 @@ namespace crypto uint8_t encoded1[32]; for (size_t i = 0; i < 16; i++) // from Little Endian { - encoded1[i] = encoded[15 - i]; - encoded1[15 - i] = encoded[i]; + encoded1[i] = encoded[31 - i]; + encoded1[31 - i] = encoded[i]; } BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); @@ -131,8 +130,8 @@ namespace crypto for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = key[i]; - key[i] = key[15 - i]; - key[15 - i] = tmp; + key[i] = key[31 - i]; + key[31 - i] = tmp; } } else From 4d7b86ca266df7166e0cf9d496e58f5028b6db5d Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 13:20:23 -0500 Subject: [PATCH 0137/2950] elligator test added --- tests/Makefile | 5 +++- tests/test-elligator.cpp | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/test-elligator.cpp diff --git a/tests/Makefile b/tests/Makefile index 2a12472a..4c80c37c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -I../libi2pd/ -pthread -Wl,--unresolved-symbols=ignore-in-object-files -TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding +TESTS = test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding test-elligator all: $(TESTS) run @@ -25,6 +25,9 @@ test-aeadchacha20poly1305: ../libi2pd/Crypto.cpp ../libi2pd/ChaCha20.cpp ../libi 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 + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system + run: $(TESTS) @for TEST in $(TESTS); do ./$$TEST ; done diff --git a/tests/test-elligator.cpp b/tests/test-elligator.cpp new file mode 100644 index 00000000..ec9ccdbc --- /dev/null +++ b/tests/test-elligator.cpp @@ -0,0 +1,56 @@ +#include +#include +#include + +#include "Elligator.h" + +const uint8_t key[32] = +{ + 0x33, 0x95, 0x19, 0x64, 0x00, 0x3c, 0x94, 0x08, 0x78, 0x06, 0x3c, 0xcf, 0xd0, 0x34, 0x8a, 0xf4, + 0x21, 0x50, 0xca, 0x16, 0xd2, 0x64, 0x6f, 0x2c, 0x58, 0x56, 0xe8, 0x33, 0x83, 0x77, 0xd8, 0x80 +}; + +const uint8_t encoded_key[32] = +{ + 0x28, 0x20, 0xb6, 0xb2, 0x41, 0xe0, 0xf6, 0x8a, 0x6c, 0x4a, 0x7f, 0xee, 0x3d, 0x97, 0x82, 0x28, + 0xef, 0x3a, 0xe4, 0x55, 0x33, 0xcd, 0x41, 0x0a, 0xa9, 0x1a, 0x41, 0x53, 0x31, 0xd8, 0x61, 0x2d +}; + +const uint8_t encoded1[32] = +{ + 0xe7, 0x35, 0x07, 0xd3, 0x8b, 0xae, 0x63, 0x99, 0x2b, 0x3f, 0x57, 0xaa, 0xc4, 0x8c, 0x0a, 0xbc, + 0x14, 0x50, 0x95, 0x89, 0x28, 0x84, 0x57, 0x99, 0x5a, 0x2b, 0x4c, 0xa3, 0x49, 0x0a, 0xa2, 0x07 +}; + +const uint8_t key1[32] = +{ + 0x1e, 0x8a, 0xff, 0xfe, 0xd6, 0xbf, 0x53, 0xfe, 0x27, 0x1a, 0xd5, 0x72, 0x47, 0x32, 0x62, 0xde, + 0xd8, 0xfa, 0xec, 0x68, 0xe5, 0xe6, 0x7e, 0xf4, 0x5e, 0xbb, 0x82, 0xee, 0xba, 0x52, 0x60, 0x4f +}; + +const uint8_t encoded2[32] = +{ + 0x95, 0xa1, 0x60, 0x19, 0x04, 0x1d, 0xbe, 0xfe, 0xd9, 0x83, 0x20, 0x48, 0xed, 0xe1, 0x19, 0x28, + 0xd9, 0x03, 0x65, 0xf2, 0x4a, 0x38, 0xaa, 0x7a, 0xef, 0x1b, 0x97, 0xe2, 0x39, 0x54, 0x10, 0x1b +}; + +const uint8_t key2[32] = +{ + 0x79, 0x4f, 0x05, 0xba, 0x3e, 0x3a, 0x72, 0x95, 0x80, 0x22, 0x46, 0x8c, 0x88, 0x98, 0x1e, 0x0b, + 0xe5, 0x78, 0x2b, 0xe1, 0xe1, 0x14, 0x5c, 0xe2, 0xc3, 0xc6, 0xfd, 0xe1, 0x6d, 0xed, 0x53, 0x63 +}; + + +int main () +{ + uint8_t buf[32]; + i2p::crypto::Elligator2 el; + // encoding test + el.Encode (key, buf); + assert(memcmp (buf, encoded_key, 32) == 0); + // decoding test + el.Decode (encoded1, buf); + assert(memcmp (buf, key1, 32) == 0); + el.Decode (encoded2, buf); + assert(memcmp (buf, key2, 32) == 0); +} From 36eaaa748c02e43bc2692cbe95aa5e62e4d3b4c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 13:40:04 -0500 Subject: [PATCH 0138/2950] handle case when encoded key is (p-1)/2 --- libi2pd/Elligator.cpp | 2 +- tests/test-elligator.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 9be0a610..9821afa1 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -100,7 +100,7 @@ namespace crypto BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); - if (BN_cmp (r, p12) < 0) // r < (p-1)/2 + if (BN_cmp (r, p12) <= 0) // r < (p-1)/2 { // v = -A/(1+u*r^2) BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); diff --git a/tests/test-elligator.cpp b/tests/test-elligator.cpp index ec9ccdbc..1647c349 100644 --- a/tests/test-elligator.cpp +++ b/tests/test-elligator.cpp @@ -40,6 +40,17 @@ const uint8_t key2[32] = 0xe5, 0x78, 0x2b, 0xe1, 0xe1, 0x14, 0x5c, 0xe2, 0xc3, 0xc6, 0xfd, 0xe1, 0x6d, 0xed, 0x53, 0x63 }; +const uint8_t encoded3[32] = +{ + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f +}; + +const uint8_t key3[32] = +{ + 0x9c, 0xdb, 0x52, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 +}; int main () { @@ -53,4 +64,6 @@ int main () assert(memcmp (buf, key1, 32) == 0); el.Decode (encoded2, buf); assert(memcmp (buf, key2, 32) == 0); + el.Decode (encoded3, buf); + assert(memcmp (buf, key3, 32) == 0); } From 9ed58e5186f7bef037cf535f16fe0a1c8f48c260 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 Dec 2019 14:10:12 -0500 Subject: [PATCH 0139/2950] encode with highY --- libi2pd/Elligator.cpp | 14 +++++++++++--- libi2pd/Elligator.h | 2 +- tests/test-elligator.cpp | 12 ++++++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 9821afa1..b9471512 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -39,7 +39,7 @@ namespace crypto BN_free (u); BN_free (iu); } - bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const + bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY) const { bool ret = true; BN_CTX * ctx = BN_CTX_new (); @@ -63,8 +63,16 @@ namespace crypto if (Legendre (uxxA, ctx) != -1) { BIGNUM * r = BN_CTX_get (ctx); - BN_mod_inverse (r, xA, p, ctx); - BN_mod_mul (r, r, x, p, ctx); + if (highY) + { + BN_mod_inverse (r, x, p, ctx); + BN_mod_mul (r, r, xA, p, ctx); + } + else + { + BN_mod_inverse (r, xA, p, ctx); + BN_mod_mul (r, r, x, p, ctx); + } BN_mod_mul (r, r, iu, p, ctx); SquareRoot (r, r, ctx); diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 6f9eaf2a..ca463568 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -17,7 +17,7 @@ namespace crypto Elligator2 (); ~Elligator2 (); - bool Encode (const uint8_t * key, uint8_t * encoded) const; + bool Encode (const uint8_t * key, uint8_t * encoded, bool highY = false) const; bool Decode (const uint8_t * encoded, uint8_t * key) const; private: diff --git a/tests/test-elligator.cpp b/tests/test-elligator.cpp index 1647c349..94798e80 100644 --- a/tests/test-elligator.cpp +++ b/tests/test-elligator.cpp @@ -16,6 +16,12 @@ const uint8_t encoded_key[32] = 0xef, 0x3a, 0xe4, 0x55, 0x33, 0xcd, 0x41, 0x0a, 0xa9, 0x1a, 0x41, 0x53, 0x31, 0xd8, 0x61, 0x2d }; +const uint8_t encoded_key_high_y[32] = +{ + 0x3c, 0xfb, 0x87, 0xc4, 0x6c, 0x0b, 0x45, 0x75, 0xca, 0x81, 0x75, 0xe0, 0xed, 0x1c, 0x0a, 0xe9, + 0xda, 0xe7, 0x9d, 0xb7, 0x8d, 0xf8, 0x69, 0x97, 0xc4, 0x84, 0x7b, 0x9f, 0x20, 0xb2, 0x77, 0x18 +}; + const uint8_t encoded1[32] = { 0xe7, 0x35, 0x07, 0xd3, 0x8b, 0xae, 0x63, 0x99, 0x2b, 0x3f, 0x57, 0xaa, 0xc4, 0x8c, 0x0a, 0xbc, @@ -56,10 +62,12 @@ int main () { uint8_t buf[32]; i2p::crypto::Elligator2 el; - // encoding test + // encoding tests el.Encode (key, buf); assert(memcmp (buf, encoded_key, 32) == 0); - // decoding test + el.Encode (key, buf, true); // with highY + assert(memcmp (buf, encoded_key_high_y, 32) == 0); + // decoding tests el.Decode (encoded1, buf); assert(memcmp (buf, key1, 32) == 0); el.Decode (encoded2, buf); From 553d59c32b037cb0d9561100be57c0dde05f6cef Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 Dec 2019 13:38:36 -0500 Subject: [PATCH 0140/2950] decryptor for ECIES-X25519-AEAD-Ratchet --- libi2pd/CryptoKey.cpp | 17 +++++++++++++++++ libi2pd/CryptoKey.h | 19 +++++++++++++++++++ libi2pd/Identity.cpp | 6 ++++++ libi2pd/Identity.h | 1 + 4 files changed, 43 insertions(+) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 711d4ce6..1c362c3b 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,6 +1,7 @@ #include #include "Log.h" #include "Gost.h" +#include "Elligator.h" #include "CryptoKey.h" namespace i2p @@ -146,6 +147,22 @@ namespace crypto BN_free (x); BN_free (y); } + + bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * keyMaterial, BN_CTX * ctx, bool zeroPadding) + { + uint8_t key[32]; + if (!GetElligator ()->Decode (epub, key)) return false; + m_StaticKeys.Agree (key, keyMaterial); + return true; + } + + void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub) + { + X25519Keys k; + k.GenerateKeys (); + k.GetPrivateKey (priv); + memcpy (pub, k.GetPublicKey (), 32); + } } } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 5584b687..c4788959 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -116,6 +116,25 @@ namespace crypto }; void CreateECIESGOSTR3410RandomKeys (uint8_t * priv, uint8_t * pub); + +// ECIES-X25519-AEAD-Ratchet + + class ECIESX25519AEADRatchetDecryptor: public CryptoKeyDecryptor + { + public: + + ECIESX25519AEADRatchetDecryptor (const uint8_t * priv): m_StaticKeys (priv, nullptr) {}; + ~ECIESX25519AEADRatchetDecryptor () {}; + bool Decrypt (const uint8_t * epub, uint8_t * keyMaterial, BN_CTX * ctx, bool zeroPadding); + // take elligator encoded ephemeral pub (32 bytes), agree with static and return in keyMaterial (32 bytes) + size_t GetPublicKeyLen () const { return 32; }; + + private: + + X25519Keys m_StaticKeys; + }; + + void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub); } } diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index f088d3f2..d217f41d 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -674,6 +674,9 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC: return std::make_shared(key); break; + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + return std::make_shared(key); + break; default: LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)cryptoType); }; @@ -750,6 +753,9 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC: i2p::crypto::CreateECIESGOSTR3410RandomKeys (priv, pub); break; + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); + break; default: LogPrint (eLogError, "Identity: Crypto key type ", (int)type, " is not supported"); } diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 72fd14c5..2fecc28a 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -55,6 +55,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; + const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET = 4; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES From 521fb83e382d0aedd2b3f2db1320ff1016ebbe7b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 17 Dec 2019 16:18:40 -0500 Subject: [PATCH 0141/2950] initial code for ECIES-X25519-AEAD-Ratchet KDF --- libi2pd/CryptoKey.cpp | 7 ++----- libi2pd/CryptoKey.h | 4 ++-- libi2pd/Destination.h | 2 ++ libi2pd/Garlic.cpp | 36 ++++++++++++++++++++++++++++++++++++ libi2pd/Garlic.h | 3 +++ libi2pd/Identity.h | 2 ++ 6 files changed, 47 insertions(+), 7 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 1c362c3b..f247f37e 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,7 +1,6 @@ #include #include "Log.h" #include "Gost.h" -#include "Elligator.h" #include "CryptoKey.h" namespace i2p @@ -148,11 +147,9 @@ namespace crypto } - bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * keyMaterial, BN_CTX * ctx, bool zeroPadding) + bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) { - uint8_t key[32]; - if (!GetElligator ()->Decode (epub, key)) return false; - m_StaticKeys.Agree (key, keyMaterial); + m_StaticKeys.Agree (epub, sharedSecret); return true; } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index c4788959..e7cde780 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -125,8 +125,8 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv): m_StaticKeys (priv, nullptr) {}; ~ECIESX25519AEADRatchetDecryptor () {}; - bool Decrypt (const uint8_t * epub, uint8_t * keyMaterial, BN_CTX * ctx, bool zeroPadding); - // take elligator encoded ephemeral pub (32 bytes), agree with static and return in keyMaterial (32 bytes) + bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); + // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const { return 32; }; private: diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index a32d3ed1..e4489fe0 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -237,6 +237,8 @@ namespace client // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; + i2p::data::CryptoKeyType GetEncryptionType () const { return m_EncryptionKeyType; }; + const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; }; protected: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 888e988c..823f61ea 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,8 +1,10 @@ #include +#include #include "I2PEndian.h" #include #include #include "Crypto.h" +#include "Elligator.h" #include "RouterContext.h" #include "I2NPProtocol.h" #include "Tunnel.h" @@ -433,6 +435,12 @@ namespace garlic return; } buf += 4; // length + if (GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + { + HandleECIESx25519 (buf, length - 4); + return; + } + // otherwise assume ElGamal/AES auto it = m_Tags.find (SessionTag(buf)); if (it != m_Tags.end ()) { @@ -821,5 +829,33 @@ namespace garlic if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT) i2p::fs::Remove (it); } + + void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) + { + // KDF + // TODO : use precalculated hashes + static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes + uint8_t h[64], ck[32]; + SHA256 ((const uint8_t *)protocolName, 40, h); + memcpy (ck, h, 32); + SHA256 (h, 32, h); + // we are Bob + memcpy (h + 32, GetEncryptionPublicKey (), 32); + SHA256 (h, 64, h); // h = SHA256(h || bpk) + + uint8_t aepk[32]; + if (!i2p::crypto::GetElligator ()->Decode (buf, aepk)) + { + LogPrint (eLogError, "Garlic: Can't decode elligator"); + return; + } + memcpy (h + 32, aepk, 32); + SHA256 (h, 64, h); // h = SHA256(h || aepk) + + uint8_t sharedSecret[32], keyData[64]; + Decrypt (aepk, sharedSecret, m_Ctx); // x25519 + i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) + memcpy (ck, keyData, 32); // chainKey = keydata[0:31] + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index c5236c90..b34fc00f 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -206,6 +206,9 @@ namespace garlic std::shared_ptr from); void HandleGarlicPayload (uint8_t * buf, size_t len, std::shared_ptr from); + // ECIES-X25519-AEAD-Ratchet + void HandleECIESx25519 (const uint8_t * buf, size_t len); + private: BN_CTX * m_Ctx; // incoming diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 2fecc28a..3bacf5da 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -227,6 +227,8 @@ namespace data virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; + virtual CryptoKeyType GetEncryptionType () const { return GetIdentity ()->GetCryptoKeyType (); }; // override for LeaseSet + virtual const uint8_t * GetEncryptionPublicKey () const { return GetIdentity ()->GetEncryptionPublicKey (); }; // override for LeaseSet }; } } From b5d55e1ffbff37f3ff8c3427b69655054149fcd2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 17 Dec 2019 16:34:47 -0500 Subject: [PATCH 0142/2950] decrypt flags/static section --- libi2pd/Garlic.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 823f61ea..371aabff 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -849,6 +849,7 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't decode elligator"); return; } + buf += 32; memcpy (h + 32, aepk, 32); SHA256 (h, 64, h); // h = SHA256(h || aepk) @@ -856,6 +857,16 @@ namespace garlic Decrypt (aepk, sharedSecret, m_Ctx); // x25519 i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (ck, keyData, 32); // chainKey = keydata[0:31] + + // decrypt flags/static + uint8_t nonce[12], fs[32]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, h, 32, keyData + 32, nonce, fs, 32, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); + return; + } + buf += 48; // 32 data + 16 poly } } } From 19a88300c6d80a573c2a16fd7abf9b6d24f36b46 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Dec 2019 14:44:02 -0500 Subject: [PATCH 0143/2950] decrypt payload section --- libi2pd/Garlic.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++-- libi2pd/Garlic.h | 12 ++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 371aabff..3c255d0d 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -832,7 +832,7 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - // KDF + // KDF1 // TODO : use precalculated hashes static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes uint8_t h[64], ck[32]; @@ -849,7 +849,7 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't decode elligator"); return; } - buf += 32; + buf += 32; len -= 32; memcpy (h + 32, aepk, 32); SHA256 (h, 64, h); // h = SHA256(h || aepk) @@ -866,7 +866,69 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); return; } - buf += 48; // 32 data + 16 poly + memcpy (h + 32, buf, 32); + SHA256 (h, 64, h); // h = SHA256(h || ciphertext) + buf += 48; len -= 48; // 32 data + 16 poly + // decrypt payload + std::vector payload (len + 32); uint8_t h1[32]; + // KDF2 for payload + bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); + if (isStatic) + { + // static key, fs is apk + Decrypt (fs, sharedSecret, m_Ctx); // DH(bsk, apk) + i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) + memcpy (ck, keyData, 32); // chainKey = keydata[0:31] + memcpy (payload.data (), h, 32); + memcpy (payload.data () + 32, buf, len); // h || ciphertext + SHA256 (payload.data (), len + 32, h1); + } + else // all zeros flags + htole64buf (nonce + 4, 1); // n = 1 + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, h, 32, keyData + 32, nonce, payload.data () + 32, len - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); + return; + } + if (isStatic) memcpy (h, h1, 32); // h = SHA256(h || ciphertext) + HandleECIESx25519Payload (payload.data () + 32, len - 16); } + + void GarlicDestination::HandleECIESx25519Payload (const uint8_t * buf, size_t len) + { + size_t offset = 0; + while (offset < len) + { + uint8_t blk = buf[offset]; + offset++; + auto size = bufbe16toh (buf + offset); + offset += 2; + LogPrint (eLogDebug, "Garlic: Block type ", (int)blk, " of size ", size); + if (size > len) + { + LogPrint (eLogError, "Garlic: Unexpected block length ", size); + break; + } + switch (blk) + { + case eECIESx25519BlkGalicClove: + // TODO: + break; + case eECIESx25519BlkDateTime: + LogPrint (eLogDebug, "Garlic: datetime"); + break; + case eECIESx25519BlkOptions: + LogPrint (eLogDebug, "Garlic: options"); + break; + case eECIESx25519BlkPadding: + LogPrint (eLogDebug, "NTCP2: padding"); + break; + default: + LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); + } + offset += size; + } + } + } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index b34fc00f..4054d88c 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -165,6 +165,17 @@ namespace garlic //using GarlicRoutingSessionPtr = std::shared_ptr; typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 + enum ECIESx25519BlockType + { + eECIESx25519BlkDateTime = 0, + eECIESx25519BlkSessionID = 1, + eECIESx25519BlkTermination = 4, + eECIESx25519BlkOptions = 5, + eECIESx25519BlkNextSessionKey = 7, + eECIESx25519BlkGalicClove = 11, + eECIESx25519BlkPadding = 254 + }; + class GarlicDestination: public i2p::data::LocalDestination { public: @@ -208,6 +219,7 @@ namespace garlic // ECIES-X25519-AEAD-Ratchet void HandleECIESx25519 (const uint8_t * buf, size_t len); + void HandleECIESx25519Payload (const uint8_t * buf, size_t len); private: From 599ec62bb0b7aca3cc99ddd95edcc35e43d808d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Dec 2019 20:45:47 -0500 Subject: [PATCH 0144/2950] use HKDF for NTCP2 key derivation data phase --- libi2pd/Crypto.cpp | 30 ++++++++++++++++++++++-------- libi2pd/Crypto.h | 2 +- libi2pd/NTCP2.cpp | 22 ++++++++-------------- libi2pd/NTCP2.h | 2 +- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 3c51a033..1c3f0b7b 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1259,18 +1259,29 @@ namespace crypto #endif } - void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out) + void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, + uint8_t * out, size_t outLen) { #if OPENSSL_HKDF - EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, NULL); + EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, nullptr); EVP_PKEY_derive_init (pctx); EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256()); - EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32); - EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen); + if (key && keyLen) + { + EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32); + EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen); + } + else + { + // zerolen + EVP_PKEY_CTX_hkdf_mode (pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY); + uint8_t tempKey[32]; unsigned int len; + HMAC(EVP_sha256(), salt, 32, nullptr, 0, tempKey, &len); + 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 ()); - size_t outlen = 64; - EVP_PKEY_derive (pctx, out, &outlen); + EVP_PKEY_derive (pctx, out, &outLen); EVP_PKEY_CTX_free (pctx); #else uint8_t prk[32]; unsigned int len; @@ -1278,8 +1289,11 @@ namespace crypto auto l = info.length (); memcpy (out, info.c_str (), l); out[l] = 0x01; HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len); - memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02; - HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); + if (outLen > 32) // 64 + { + memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02; + HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); + } #endif } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index a4b6c2de..785c0b9d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -296,7 +296,7 @@ namespace crypto // HKDF - void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out); // salt - 32, out - 64, info <= 32 + void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 // init and terminate void InitCrypto (bool precomputation); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index c12c5804..ce26794c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -441,23 +441,17 @@ namespace transport void NTCP2Session::KeyDerivationFunctionDataPhase () { - uint8_t tempKey[32]; unsigned int len; - HMAC(EVP_sha256(), m_Establisher->GetCK (), 32, nullptr, 0, tempKey, &len); // temp_key = HMAC-SHA256(ck, zerolen) - static uint8_t one[1] = { 1 }; - HMAC(EVP_sha256(), tempKey, 32, one, 1, m_Kab, &len); // k_ab = HMAC-SHA256(temp_key, byte(0x01)). - m_Kab[32] = 2; - HMAC(EVP_sha256(), tempKey, 32, m_Kab, 33, m_Kba, &len); // k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)) - static uint8_t ask[4] = { 'a', 's', 'k', 1 }, master[32]; - HMAC(EVP_sha256(), tempKey, 32, ask, 4, master, &len); // ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01)) + uint8_t k[64]; + i2p::crypto::HKDF (m_Establisher->GetCK (), nullptr, 0, "", k); // k_ab, k_ba = HKDF(ck, zerolen) + memcpy (m_Kab, k, 32); memcpy (m_Kba, k + 32, 32); + uint8_t master[32]; + i2p::crypto::HKDF (m_Establisher->GetCK (), nullptr, 0, "ask", master, 32); // ask_master = HKDF(ck, zerolen, info="ask") uint8_t h[39]; memcpy (h, m_Establisher->GetH (), 32); memcpy (h + 32, "siphash", 7); - HMAC(EVP_sha256(), master, 32, h, 39, tempKey, &len); // temp_key = HMAC-SHA256(ask_master, h || "siphash") - HMAC(EVP_sha256(), tempKey, 32, one, 1, master, &len); // sip_master = HMAC-SHA256(temp_key, byte(0x01)) - HMAC(EVP_sha256(), master, 32, nullptr, 0, tempKey, &len); // temp_key = HMAC-SHA256(sip_master, zerolen) - HMAC(EVP_sha256(), tempKey, 32, one, 1, m_Sipkeysab, &len); // sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)). - m_Sipkeysab[32] = 2; - HMAC(EVP_sha256(), tempKey, 32, m_Sipkeysab, 33, m_Sipkeysba, &len); // sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02)) + i2p::crypto::HKDF (master, h, 39, "", master, 32); // sip_master = HKDF(ask_master, h || "siphash") + i2p::crypto::HKDF (master, nullptr, 0, "", k, 64); // sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen) + memcpy (m_Sipkeysab, k, 32); memcpy (m_Sipkeysba, k + 32, 32); } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index d2f1f88d..c66ff697 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -195,7 +195,7 @@ namespace transport std::unique_ptr m_Establisher; // data phase - uint8_t m_Kab[33], m_Kba[32], m_Sipkeysab[33], m_Sipkeysba[32]; + 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; From db84be248835aff65aa84e98979e14fdcbe1985a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Dec 2019 20:48:30 -0500 Subject: [PATCH 0145/2950] use HKDF for NTCP2 key derivation data phase --- libi2pd/NTCP2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ce26794c..e2c4ae43 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -450,7 +450,7 @@ namespace transport memcpy (h, m_Establisher->GetH (), 32); memcpy (h + 32, "siphash", 7); i2p::crypto::HKDF (master, h, 39, "", master, 32); // sip_master = HKDF(ask_master, h || "siphash") - i2p::crypto::HKDF (master, nullptr, 0, "", k, 64); // sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen) + i2p::crypto::HKDF (master, nullptr, 0, "", k); // sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen) memcpy (m_Sipkeysab, k, 32); memcpy (m_Sipkeysba, k + 32, 32); } From 9f79bdae9bf8a9eaba52f6f61ba31157cc996fb5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Dec 2019 15:59:15 -0500 Subject: [PATCH 0146/2950] encryptor for ECIES-X25519-AEAD-Ratchet --- libi2pd/Crypto.cpp | 12 ++++++++++++ libi2pd/Crypto.h | 1 + libi2pd/CryptoKey.cpp | 16 ++++++++++++++++ libi2pd/CryptoKey.h | 16 +++++++++++++++- libi2pd/Identity.cpp | 3 +++ libi2pd/Identity.h | 1 + libi2pd/LeaseSet.cpp | 5 ++--- libi2pd/LeaseSet.h | 2 ++ 8 files changed, 52 insertions(+), 4 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 1c3f0b7b..567ae574 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -367,6 +367,18 @@ namespace crypto #endif } + void X25519Keys::SetPrivateKey (const uint8_t * priv) + { +#if OPENSSL_X25519 + if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); + if (m_Pkey) EVP_PKEY_free (m_Pkey); + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); + m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); +#else + memcpy (m_PrivateKey, priv, 32); +#endif + } + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 785c0b9d..33490c8a 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -80,6 +80,7 @@ namespace crypto void GenerateKeys (); const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; + void SetPrivateKey (const uint8_t * priv); // wihout calculating public void Agree (const uint8_t * pub, uint8_t * shared); private: diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index f247f37e..df5dd38f 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -146,6 +146,22 @@ namespace crypto BN_free (x); BN_free (y); } + ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor (const uint8_t * pub) + { + memcpy (m_PublicKey, pub, 32); + } + + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) + { + X25519Keys ep; + ep.SetPrivateKey (epriv); + ep.Agree (m_PublicKey, sharedSecret); + } + + ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) + { + m_StaticKeys.SetPrivateKey (priv); + } bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index e7cde780..6412f4d3 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -119,11 +119,25 @@ namespace crypto // ECIES-X25519-AEAD-Ratchet + class ECIESX25519AEADRatchetEncryptor: public CryptoKeyEncryptor + { + public: + + ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); + ~ECIESX25519AEADRatchetEncryptor () {}; + void Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); + // agree with ephemeral priv and return in sharedSecret (32 bytes) + + private: + + uint8_t m_PublicKey[32]; + }; + class ECIESX25519AEADRatchetDecryptor: public CryptoKeyDecryptor { public: - ECIESX25519AEADRatchetDecryptor (const uint8_t * priv): m_StaticKeys (priv, nullptr) {}; + ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); ~ECIESX25519AEADRatchetDecryptor () {}; bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); // agree with static and return in sharedSecret (32 bytes) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index d217f41d..de94732f 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -417,6 +417,9 @@ namespace data case CRYPTO_KEY_TYPE_ELGAMAL: return std::make_shared(key); break; + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET: + return std::make_shared(key); + break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST: return std::make_shared(key); diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 3bacf5da..f217f3c5 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -216,6 +216,7 @@ namespace data virtual bool IsDestination () const = 0; // for garlic const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; + virtual CryptoKeyType GetEncryptionType () const { return GetIdentity ()->GetCryptoKeyType (); }; // override in LeaseSet2 }; class LocalDestination diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index b516f010..e6373dd9 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -355,7 +355,6 @@ namespace data offset += propertiesLen; // skip for now. TODO: implement properties if (offset + 1 >= len) return 0; // key sections - uint16_t currentKeyType = 0; int numKeySections = buf[offset]; offset++; for (int i = 0; i < numKeySections; i++) { @@ -368,10 +367,10 @@ namespace data // we pick first valid key, higher key type has higher priority 4-1-0 // if two keys with of the same type, pick first auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); - if (encryptor && (!m_Encryptor || keyType > currentKeyType)) + if (encryptor && (!m_Encryptor || keyType > m_EncryptionType)) { m_Encryptor = encryptor; // TODO: atomic - currentKeyType = keyType; + m_EncryptionType = keyType; } } offset += encryptionKeyLen; diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 70aa7110..84d87e17 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -147,6 +147,7 @@ namespace data // implements RoutingDestination void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const; + CryptoKeyType GetEncryptionType () const { return m_EncryptionType; }; private: @@ -167,6 +168,7 @@ namespace data uint32_t m_PublishedTimestamp = 0; bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; + CryptoKeyType m_EncryptionType = CRYPTO_KEY_TYPE_ELGAMAL; std::shared_ptr m_Encryptor; // for standardLS2 }; From 5337aa10f762c98535d2170f367aa8cece7910b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Jan 2020 13:30:54 -0500 Subject: [PATCH 0147/2950] check AES tag first --- libi2pd/Garlic.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 3c255d0d..1ee69df5 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -435,13 +435,8 @@ namespace garlic return; } buf += 4; // length - if (GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) - { - HandleECIESx25519 (buf, length - 4); - return; - } - // otherwise assume ElGamal/AES auto it = m_Tags.find (SessionTag(buf)); + // AES tag might be used even if encryption type is not ElGamal/AES if (it != m_Tags.end ()) { // tag found. Use AES @@ -460,7 +455,13 @@ namespace garlic } else { - // tag not found. Use ElGamal + // tag not found. Handle depending on encryption type + if (GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + { + HandleECIESx25519 (buf, length - 4); + return; + } + // otherwise assume ElGamal/AES ElGamalBlock elGamal; if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx)) { From 26ad793d82bb0b1df23613ed77bcd6364a1b8b55 Mon Sep 17 00:00:00 2001 From: r4sas Date: Sun, 5 Jan 2020 23:04:08 +0000 Subject: [PATCH 0148/2950] use unscoped storage (fixes usage on android 10) Signed-off-by: r4sas --- android/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 757b35bb..71526701 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -16,6 +16,7 @@ android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar" + android:requestLegacyExternalStorage="true" > From a33584150930335bbb75f6f53aa940717b8e9d8f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Jan 2020 14:37:40 -0500 Subject: [PATCH 0149/2950] pass msgID to HandleDeliveryStatus --- libi2pd/Destination.cpp | 10 +++++----- libi2pd/Destination.h | 2 +- libi2pd/Garlic.cpp | 6 +++--- libi2pd/Garlic.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ca60f0fb..cbbee03a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -353,7 +353,8 @@ namespace client void LeaseSetDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); + uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); + m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msgID)); } void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) @@ -366,7 +367,7 @@ namespace client break; case eI2NPDeliveryStatus: // we assume tunnel tests non-encrypted - HandleDeliveryStatusMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len), from)); + HandleDeliveryStatusMessage (bufbe32toh (buf + I2NP_HEADER_SIZE + DELIVERY_STATUS_MSGID_OFFSET)); break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); @@ -511,9 +512,8 @@ namespace client LogPrint (eLogWarning, "Destination: Request for ", key.ToBase64 (), " not found"); } - void LeaseSetDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) + void LeaseSetDestination::HandleDeliveryStatusMessage (uint32_t msgID) { - uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); if (msgID == m_PublishReplyToken) { LogPrint (eLogDebug, "Destination: Publishing LeaseSet confirmed for ", GetIdentHash().ToBase32()); @@ -525,7 +525,7 @@ namespace client shared_from_this (), std::placeholders::_1)); } else - i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msg); + i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msgID); } void LeaseSetDestination::SetLeaseSetUpdated () diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index e4489fe0..a6e6fe2d 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -152,7 +152,7 @@ namespace client void HandlePublishDelayTimer (const boost::system::error_code& ecode); void HandleDatabaseStoreMessage (const uint8_t * buf, size_t len); void HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len); - void HandleDeliveryStatusMessage (std::shared_ptr msg); + void HandleDeliveryStatusMessage (uint32_t msgID); void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedBlindedKey = nullptr); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 1ee69df5..8cd12464 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -723,9 +723,8 @@ namespace garlic m_DeliveryStatusSessions[msgID] = session; } - void GarlicDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) + void GarlicDestination::HandleDeliveryStatusMessage (uint32_t msgID) { - uint32_t msgID = bufbe32toh (msg->GetPayload ()); GarlicRoutingSessionPtr session; { std::unique_lock l(m_DeliveryStatusSessionsMutex); @@ -757,7 +756,8 @@ namespace garlic void GarlicDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - HandleDeliveryStatusMessage (msg); + uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); + HandleDeliveryStatusMessage (msgID); } void GarlicDestination::SaveTags () diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 4054d88c..bc999df5 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -206,7 +206,7 @@ namespace garlic protected: void HandleGarlicMessage (std::shared_ptr msg); - void HandleDeliveryStatusMessage (std::shared_ptr msg); + void HandleDeliveryStatusMessage (uint32_t msgID); void SaveTags (); void LoadTags (); From 815b6db0bfb811afd996a694736677ff0a63a817 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Jan 2020 15:31:20 -0500 Subject: [PATCH 0150/2950] HandleCloveI2NPMessage --- libi2pd/Destination.cpp | 17 ++++++++++++----- libi2pd/Destination.h | 5 ++++- libi2pd/Garlic.h | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index cbbee03a..f6855844 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -360,24 +360,31 @@ namespace client void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; + if (!HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE)) + i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len), from)); + } + + bool LeaseSetDestination::HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) + { switch (typeID) { case eI2NPData: - HandleDataMessage (buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); + HandleDataMessage (payload, len); break; case eI2NPDeliveryStatus: // we assume tunnel tests non-encrypted - HandleDeliveryStatusMessage (bufbe32toh (buf + I2NP_HEADER_SIZE + DELIVERY_STATUS_MSGID_OFFSET)); + HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET)); break; case eI2NPDatabaseStore: - HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); + HandleDatabaseStoreMessage (payload, len); break; case eI2NPDatabaseSearchReply: - HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); + HandleDatabaseSearchReplyMessage (payload, len); break; default: - i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len), from)); + return false; } + return true; } void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index a6e6fe2d..bf08c80c 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -121,7 +121,6 @@ namespace client // implements GarlicDestination std::shared_ptr GetLeaseSet (); std::shared_ptr GetTunnelPool () const { return m_Pool; } - void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); // override GarlicDestination bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); @@ -131,6 +130,10 @@ namespace client protected: + // implements GarlicDestination + void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); + bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len); + void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; }; diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index bc999df5..fea2c935 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -201,10 +201,10 @@ namespace garlic virtual std::shared_ptr GetLeaseSet () = 0; // TODO virtual std::shared_ptr GetTunnelPool () const = 0; - virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) = 0; protected: + virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) = 0; // called from clove only void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); From 4afef91359cc59a14d13987c26bf4a0094b94a1e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Jan 2020 16:14:41 -0500 Subject: [PATCH 0151/2950] invoke HandleCloveI2NPMessage --- libi2pd/Garlic.cpp | 28 +++++++++++++++++++++++++++- libi2pd/Garlic.h | 2 ++ libi2pd/RouterContext.h | 7 ++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 8cd12464..82778ddc 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -913,7 +913,7 @@ namespace garlic switch (blk) { case eECIESx25519BlkGalicClove: - // TODO: + HandleECIESx25519GarlicClove (buf + offset, size); break; case eECIESx25519BlkDateTime: LogPrint (eLogDebug, "Garlic: datetime"); @@ -931,5 +931,31 @@ namespace garlic } } + void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) + { + const uint8_t * buf1 = buf; + uint8_t flag = buf[0]; buf++; // flag + GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); + switch (deliveryType) + { + case eGarlicDeliveryTypeDestination: + buf += 32; // TODO: check destination + // no break here + case eGarlicDeliveryTypeLocal: + { + uint8_t typeID = buf[0]; buf++; // typeid + buf += (4 + 4); // msgID + expiration + ptrdiff_t offset = buf - buf1; + if (offset <= (int)len) + HandleCloveI2NPMessage (typeID, buf, len - offset); + else + LogPrint (eLogError, "Garlic: clove is too long"); + break; + } + // TODO: tunnel + default: + LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index fea2c935..5ef77638 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -205,6 +205,7 @@ namespace garlic protected: virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) = 0; // called from clove only + virtual bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); @@ -220,6 +221,7 @@ namespace garlic // ECIES-X25519-AEAD-Ratchet void HandleECIESx25519 (const uint8_t * buf, size_t len); void HandleECIESx25519Payload (const uint8_t * buf, size_t len); + void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); private: diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index f6aa281f..47a6f4fa 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -115,12 +115,17 @@ namespace i2p // implements GarlicDestination std::shared_ptr GetLeaseSet () { return nullptr; }; std::shared_ptr GetTunnelPool () const; - void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); // override GarlicDestination void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatusMessage (std::shared_ptr msg); + protected: + + // implements GarlicDestination + void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); + bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented + private: void CreateNewRouter (); From 0007f304d00157ac28ecdac2d970641adf79bec9 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Jan 2020 15:20:55 -0500 Subject: [PATCH 0152/2950] don't pass from to HandleI2NPMessage --- libi2pd/Destination.cpp | 6 +++--- libi2pd/Destination.h | 2 +- libi2pd/Garlic.cpp | 4 ++-- libi2pd/Garlic.h | 2 +- libi2pd/RouterContext.cpp | 6 +++--- libi2pd/RouterContext.h | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f6855844..c3f63ffc 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -357,11 +357,10 @@ namespace client m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msgID)); } - void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) + void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len) { uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; - if (!HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE)) - i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len), from)); + LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); } bool LeaseSetDestination::HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) @@ -382,6 +381,7 @@ namespace client HandleDatabaseSearchReplyMessage (payload, len); break; default: + LogPrint (eLogWarning, "Destination: Unexpected I2NP message type ", typeID); return false; } return true; diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index bf08c80c..2b7f7bb8 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -131,7 +131,7 @@ namespace client protected: // implements GarlicDestination - void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); + void HandleI2NPMessage (const uint8_t * buf, size_t len); bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len); void SetLeaseSet (std::shared_ptr newLeaseSet); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 82778ddc..e87aae05 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -552,7 +552,7 @@ namespace garlic LogPrint (eLogError, "Garlic: message is too short"); break; } - HandleI2NPMessage (buf, len - offset, from); + HandleI2NPMessage (buf, len - offset); break; case eGarlicDeliveryTypeDestination: LogPrint (eLogDebug, "Garlic: type destination"); @@ -563,7 +563,7 @@ namespace garlic LogPrint (eLogError, "Garlic: message is too short"); break; } - HandleI2NPMessage (buf, len - offset, from); + HandleI2NPMessage (buf, len - offset); break; case eGarlicDeliveryTypeTunnel: { diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 5ef77638..6acfce95 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -204,7 +204,7 @@ namespace garlic protected: - virtual void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) = 0; // called from clove only + virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only virtual bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index bf3459d8..2c07c21b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -27,7 +27,7 @@ namespace i2p void RouterContext::Init () { srand (i2p::util::GetMillisecondsSinceEpoch () % 1000); - m_StartupTime = std::chrono::steady_clock::now(); + m_StartupTime = std::chrono::steady_clock::now(); if (!Load ()) CreateNewRouter (); @@ -692,9 +692,9 @@ namespace i2p return i2p::tunnel::tunnels.GetExploratoryPool (); } - void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) + void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len) { - i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len), from)); + i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); } void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 47a6f4fa..1524270d 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -123,7 +123,7 @@ namespace i2p protected: // implements GarlicDestination - void HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from); + void HandleI2NPMessage (const uint8_t * buf, size_t len); bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented private: From 4f70822b13a1fee29f175fac2d7ca17d56d5b831 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Jan 2020 10:03:30 -0500 Subject: [PATCH 0153/2950] always persist crypto keys for public destinations --- libi2pd/Destination.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index c3f63ffc..71a5c329 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -879,11 +879,14 @@ namespace client if (it != params->end ()) m_EncryptionKeyType = std::stoi(it->second); } - - if (isPublic && m_EncryptionKeyType == GetIdentity ()->GetCryptoKeyType ()) // TODO: presist key type + + memset (m_EncryptionPrivateKey, 0, 256); + memset (m_EncryptionPublicKey, 0, 256); + if (isPublic) PersistTemporaryKeys (); else i2p::data::PrivateKeys::GenerateCryptoKeyPair (m_EncryptionKeyType, m_EncryptionPrivateKey, m_EncryptionPublicKey); + m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_EncryptionKeyType, m_EncryptionPrivateKey); if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); @@ -1172,8 +1175,8 @@ namespace client LogPrint (eLogInfo, "Destination: Creating new temporary keys of type for address ", ident, ".b32.i2p"); memset (m_EncryptionPrivateKey, 0, 256); memset (m_EncryptionPublicKey, 0, 256); - i2p::data::PrivateKeys::GenerateCryptoKeyPair (GetIdentity ()->GetCryptoKeyType (), m_EncryptionPrivateKey, m_EncryptionPublicKey); - + i2p::data::PrivateKeys::GenerateCryptoKeyPair (m_EncryptionKeyType, m_EncryptionPrivateKey, m_EncryptionPublicKey); + // TODO:: persist crypto key type std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out); if (f1) { f1.write ((char *)m_EncryptionPublicKey, 256); From 5cfc574f9adeaa78fde582ea2706b1bad08275d8 Mon Sep 17 00:00:00 2001 From: donarrock <35000066+donarrock@users.noreply.github.com> Date: Sun, 12 Jan 2020 16:24:21 +0100 Subject: [PATCH 0154/2950] Update Dockerfile Fixes dependencies, re-adds `boost-python` as `boost-python2` which was removed in #1408 . --- contrib/docker/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 322261b8..6b6250d0 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -36,9 +36,9 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib && 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 \ - boost-serialization boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \ - libtool g++ gcc pkgconfig + boost-python3 python3 gdbm boost-unit_test_framework boost-python2 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++ From 7ac05f848737ffd6b4ccea05f86aecdd07313ef2 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Mon, 13 Jan 2020 14:47:15 +0200 Subject: [PATCH 0155/2950] Pass -dead_strip -dead_strip_dylibs -bind_at_load on macOS --- Makefile.osx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.osx b/Makefile.osx index d673d3ef..c6af4fc2 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -2,6 +2,9 @@ CXX = clang++ CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX INCFLAGS = -I/usr/local/include LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib +LDFLAGS += -Wl,-dead_strip +LDFLAGS += -Wl,-dead_strip_dylibs +LDFLAGS += -Wl,-bind_at_load ifeq ($(USE_STATIC),yes) LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread From 61752e2aaba77428de3014e97be864ca2f4f6673 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Jan 2020 22:37:31 -0500 Subject: [PATCH 0156/2950] correct ciphertext length --- libi2pd/Garlic.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index e87aae05..740b213b 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -836,7 +836,7 @@ namespace garlic // KDF1 // TODO : use precalculated hashes static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes - uint8_t h[64], ck[32]; + uint8_t h[80], ck[32]; SHA256 ((const uint8_t *)protocolName, 40, h); memcpy (ck, h, 32); SHA256 (h, 32, h); @@ -855,7 +855,7 @@ namespace garlic SHA256 (h, 64, h); // h = SHA256(h || aepk) uint8_t sharedSecret[32], keyData[64]; - Decrypt (aepk, sharedSecret, m_Ctx); // x25519 + Decrypt (aepk, sharedSecret, m_Ctx); // x25519(bsk, aepk) i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (ck, keyData, 32); // chainKey = keydata[0:31] @@ -867,8 +867,8 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); return; } - memcpy (h + 32, buf, 32); - SHA256 (h, 64, h); // h = SHA256(h || ciphertext) + memcpy (h + 32, buf, 48); + SHA256 (h, 80, h); // h = SHA256(h || ciphertext) buf += 48; len -= 48; // 32 data + 16 poly // decrypt payload std::vector payload (len + 32); uint8_t h1[32]; @@ -877,7 +877,7 @@ namespace garlic if (isStatic) { // static key, fs is apk - Decrypt (fs, sharedSecret, m_Ctx); // DH(bsk, apk) + Decrypt (fs, sharedSecret, m_Ctx); // x25519(bsk, apk) i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (ck, keyData, 32); // chainKey = keydata[0:31] memcpy (payload.data (), h, 32); From f651baab25ab6fbcf53e89ac89a13d424f708360 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 15 Jan 2020 15:13:43 -0500 Subject: [PATCH 0157/2950] ECIESX25519AEADRatchetSession added --- build/CMakeLists.txt | 1 + libi2pd/ECIESX25519AEADRatchetSession.cpp | 160 ++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 49 +++++++ libi2pd/Garlic.cpp | 132 +----------------- libi2pd/Garlic.h | 13 -- 5 files changed, 217 insertions(+), 138 deletions(-) create mode 100644 libi2pd/ECIESX25519AEADRatchetSession.cpp create mode 100644 libi2pd/ECIESX25519AEADRatchetSession.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index a9cf3a83..2577fb1b 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -83,6 +83,7 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/NTCP2.cpp" "${LIBI2PD_SRC_DIR}/Blinding.cpp" "${LIBI2PD_SRC_DIR}/Elligator.cpp" + "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp" ) if (WITH_WEBSOCKETS) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp new file mode 100644 index 00000000..a258e8f7 --- /dev/null +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -0,0 +1,160 @@ +#include +#include +#include "Log.h" +#include "Crypto.h" +#include "Elligator.h" +#include "Tag.h" +#include "I2PEndian.h" +#include "Garlic.h" +#include "ECIESX25519AEADRatchetSession.h" + +namespace i2p +{ +namespace garlic +{ + + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession () + { + // TODO : use precalculated hashes + static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes + SHA256 ((const uint8_t *)protocolName, 40, m_H); + memcpy (m_CK, m_H, 32); + SHA256 (m_H, 32, m_H); + } + + ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () + { + } + + void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, m_H, 32); + SHA256_Update (&ctx, buf, len); + SHA256_Final (m_H, &ctx); + } + + bool ECIESX25519AEADRatchetSession::NewIncomingSession (const i2p::data::LocalDestination& dest, + const uint8_t * buf, size_t len, CloveI2NPMsgHandler handleCloveI2NPMsg) + { + // we are Bob + // KDF1 + MixHash (dest.GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk) + + uint8_t aepk[32]; // Alice's ephemeral key + if (!i2p::crypto::GetElligator ()->Decode (buf, aepk)) + { + LogPrint (eLogError, "Garlic: Can't decode elligator"); + return false; + } + buf += 32; len -= 32; + MixHash (aepk, 32); // h = SHA256(h || aepk) + + uint8_t sharedSecret[32], keyData[64]; + dest.Decrypt (aepk, sharedSecret, nullptr); // x25519(bsk, aepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) + memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] + + // decrypt flags/static + uint8_t nonce[12], fs[32]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, keyData + 32, nonce, fs, 32, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); + return false; + } + MixHash (buf, 48); // h = SHA256(h || ciphertext) + buf += 48; len -= 48; // 32 data + 16 poly + + // decrypt payload + std::vector payload (len - 16); + // KDF2 for payload + bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); + if (isStatic) + { + // static key, fs is apk + dest.Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) + memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] + } + else // all zeros flags + htole64buf (nonce + 4, 1); // n = 1 + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keyData + 32, nonce, payload.data (), len - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); + return false; + } + if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) + + HandlePayload (payload.data (), len - 16, handleCloveI2NPMsg); + + return true; + } + + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg) + { + size_t offset = 0; + while (offset < len) + { + uint8_t blk = buf[offset]; + offset++; + auto size = bufbe16toh (buf + offset); + offset += 2; + LogPrint (eLogDebug, "Garlic: Block type ", (int)blk, " of size ", size); + if (size > len) + { + LogPrint (eLogError, "Garlic: Unexpected block length ", size); + break; + } + switch (blk) + { + case eECIESx25519BlkGalicClove: + HandleClove (buf + offset, size, handleCloveI2NPMsg); + break; + case eECIESx25519BlkDateTime: + LogPrint (eLogDebug, "Garlic: datetime"); + break; + case eECIESx25519BlkOptions: + LogPrint (eLogDebug, "Garlic: options"); + break; + case eECIESx25519BlkPadding: + LogPrint (eLogDebug, "NTCP2: padding"); + break; + default: + LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); + } + offset += size; + } + } + + void ECIESX25519AEADRatchetSession::HandleClove (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg) + { + const uint8_t * buf1 = buf; + uint8_t flag = buf[0]; buf++; // flag + GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); + switch (deliveryType) + { + case eGarlicDeliveryTypeDestination: + buf += 32; // TODO: check destination + // no break here + case eGarlicDeliveryTypeLocal: + { + uint8_t typeID = buf[0]; buf++; // typeid + buf += (4 + 4); // msgID + expiration + ptrdiff_t offset = buf - buf1; + if (offset <= (int)len) + handleCloveI2NPMsg (typeID, buf, len - offset); + else + LogPrint (eLogError, "Garlic: clove is too long"); + break; + } + // TODO: tunnel + default: + LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); + } + } +} +} + + diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h new file mode 100644 index 00000000..dd28c669 --- /dev/null +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -0,0 +1,49 @@ +#ifndef ECIES_X25519_AEAD_RATCHET_SESSION_H__ +#define ECIES_X25519_AEAD_RATCHET_SESSION_H__ + +#include +#include +#include "Identity.h" + +namespace i2p +{ +namespace garlic +{ + enum ECIESx25519BlockType + { + eECIESx25519BlkDateTime = 0, + eECIESx25519BlkSessionID = 1, + eECIESx25519BlkTermination = 4, + eECIESx25519BlkOptions = 5, + eECIESx25519BlkNextSessionKey = 7, + eECIESx25519BlkGalicClove = 11, + eECIESx25519BlkPadding = 254 + }; + + class ECIESX25519AEADRatchetSession + { + public: + + typedef std::function CloveI2NPMsgHandler; + + ECIESX25519AEADRatchetSession (); + ~ECIESX25519AEADRatchetSession (); + + bool NewIncomingSession (const i2p::data::LocalDestination& dest, const uint8_t * buf, size_t len, + CloveI2NPMsgHandler handleCloveI2NPMsg); + + private: + + void MixHash (const uint8_t * buf, size_t len); + + void HandlePayload (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg); + void HandleClove (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg); + + private: + + uint8_t m_H[32], m_CK[32]; + }; +} +} + +#endif diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 740b213b..de8d6944 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,10 +1,8 @@ #include -#include #include "I2PEndian.h" #include #include #include "Crypto.h" -#include "Elligator.h" #include "RouterContext.h" #include "I2NPProtocol.h" #include "Tunnel.h" @@ -13,6 +11,7 @@ #include "Timestamp.h" #include "Log.h" #include "FS.h" +#include "ECIESX25519AEADRatchetSession.h" #include "Garlic.h" namespace i2p @@ -833,129 +832,12 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - // KDF1 - // TODO : use precalculated hashes - static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes - uint8_t h[80], ck[32]; - SHA256 ((const uint8_t *)protocolName, 40, h); - memcpy (ck, h, 32); - SHA256 (h, 32, h); - // we are Bob - memcpy (h + 32, GetEncryptionPublicKey (), 32); - SHA256 (h, 64, h); // h = SHA256(h || bpk) - - uint8_t aepk[32]; - if (!i2p::crypto::GetElligator ()->Decode (buf, aepk)) - { - LogPrint (eLogError, "Garlic: Can't decode elligator"); - return; - } - buf += 32; len -= 32; - memcpy (h + 32, aepk, 32); - SHA256 (h, 64, h); // h = SHA256(h || aepk) - - uint8_t sharedSecret[32], keyData[64]; - Decrypt (aepk, sharedSecret, m_Ctx); // x25519(bsk, aepk) - i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) - memcpy (ck, keyData, 32); // chainKey = keydata[0:31] - - // decrypt flags/static - uint8_t nonce[12], fs[32]; - memset (nonce, 0, 12); // n = 0 - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, h, 32, keyData + 32, nonce, fs, 32, false)) // decrypt - { - LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); - return; - } - memcpy (h + 32, buf, 48); - SHA256 (h, 80, h); // h = SHA256(h || ciphertext) - buf += 48; len -= 48; // 32 data + 16 poly - // decrypt payload - std::vector payload (len + 32); uint8_t h1[32]; - // KDF2 for payload - bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); - if (isStatic) - { - // static key, fs is apk - Decrypt (fs, sharedSecret, m_Ctx); // x25519(bsk, apk) - i2p::crypto::HKDF (ck, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) - memcpy (ck, keyData, 32); // chainKey = keydata[0:31] - memcpy (payload.data (), h, 32); - memcpy (payload.data () + 32, buf, len); // h || ciphertext - SHA256 (payload.data (), len + 32, h1); - } - else // all zeros flags - htole64buf (nonce + 4, 1); // n = 1 - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, h, 32, keyData + 32, nonce, payload.data () + 32, len - 16, false)) // decrypt - { - LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); - return; - } - if (isStatic) memcpy (h, h1, 32); // h = SHA256(h || ciphertext) - HandleECIESx25519Payload (payload.data () + 32, len - 16); - } - - void GarlicDestination::HandleECIESx25519Payload (const uint8_t * buf, size_t len) - { - size_t offset = 0; - while (offset < len) - { - uint8_t blk = buf[offset]; - offset++; - auto size = bufbe16toh (buf + offset); - offset += 2; - LogPrint (eLogDebug, "Garlic: Block type ", (int)blk, " of size ", size); - if (size > len) - { - LogPrint (eLogError, "Garlic: Unexpected block length ", size); - break; - } - switch (blk) - { - case eECIESx25519BlkGalicClove: - HandleECIESx25519GarlicClove (buf + offset, size); - break; - case eECIESx25519BlkDateTime: - LogPrint (eLogDebug, "Garlic: datetime"); - break; - case eECIESx25519BlkOptions: - LogPrint (eLogDebug, "Garlic: options"); - break; - case eECIESx25519BlkPadding: - LogPrint (eLogDebug, "NTCP2: padding"); - break; - default: - LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); - } - offset += size; - } - } - - void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) - { - const uint8_t * buf1 = buf; - uint8_t flag = buf[0]; buf++; // flag - GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); - switch (deliveryType) - { - case eGarlicDeliveryTypeDestination: - buf += 32; // TODO: check destination - // no break here - case eGarlicDeliveryTypeLocal: - { - uint8_t typeID = buf[0]; buf++; // typeid - buf += (4 + 4); // msgID + expiration - ptrdiff_t offset = buf - buf1; - if (offset <= (int)len) - HandleCloveI2NPMessage (typeID, buf, len - offset); - else - LogPrint (eLogError, "Garlic: clove is too long"); - break; - } - // TODO: tunnel - default: - LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); - } + ECIESX25519AEADRatchetSession session; + session.NewIncomingSession (*this, buf, len, + [this](uint8_t typeID, const uint8_t * payload, size_t len) + { + HandleCloveI2NPMessage (typeID, payload,len); + }); } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6acfce95..44ab2e82 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -165,17 +165,6 @@ namespace garlic //using GarlicRoutingSessionPtr = std::shared_ptr; typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 - enum ECIESx25519BlockType - { - eECIESx25519BlkDateTime = 0, - eECIESx25519BlkSessionID = 1, - eECIESx25519BlkTermination = 4, - eECIESx25519BlkOptions = 5, - eECIESx25519BlkNextSessionKey = 7, - eECIESx25519BlkGalicClove = 11, - eECIESx25519BlkPadding = 254 - }; - class GarlicDestination: public i2p::data::LocalDestination { public: @@ -220,8 +209,6 @@ namespace garlic // ECIES-X25519-AEAD-Ratchet void HandleECIESx25519 (const uint8_t * buf, size_t len); - void HandleECIESx25519Payload (const uint8_t * buf, size_t len); - void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); private: From 376bf6ba72af16d4d5ef2e75dfc1277176806c42 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 15 Jan 2020 19:22:42 -0500 Subject: [PATCH 0158/2950] correct message size for ECIESx25519 --- libi2pd/Garlic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index de8d6944..5dfdfe79 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -457,7 +457,7 @@ namespace garlic // tag not found. Handle depending on encryption type if (GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) { - HandleECIESx25519 (buf, length - 4); + HandleECIESx25519 (buf, length); return; } // otherwise assume ElGamal/AES From bcfe44db54a83f3f3206bb97e9c7b921a2e86da0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 12:47:08 -0500 Subject: [PATCH 0159/2950] handle tunnel delivery instructioin for ECIESx25519 --- libi2pd/Destination.cpp | 4 +- libi2pd/Destination.h | 2 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 38 ++------------ libi2pd/ECIESX25519AEADRatchetSession.h | 7 ++- libi2pd/Garlic.cpp | 63 +++++++++++++++++++++-- libi2pd/Garlic.h | 3 +- libi2pd/RouterContext.h | 2 +- 7 files changed, 72 insertions(+), 47 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 71a5c329..ba74f61f 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -359,11 +359,11 @@ namespace client void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len) { - uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; + I2NPMessageType typeID = (I2NPMessageType)(buf[I2NP_HEADER_TYPEID_OFFSET]); LeaseSetDestination::HandleCloveI2NPMessage (typeID, buf + I2NP_HEADER_SIZE, GetI2NPMessageLength(buf, len) - I2NP_HEADER_SIZE); } - bool LeaseSetDestination::HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) + bool LeaseSetDestination::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { switch (typeID) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 2b7f7bb8..f4483032 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -132,7 +132,7 @@ namespace client // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len); + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); void SetLeaseSet (std::shared_ptr newLeaseSet); int GetLeaseSetType () const { return m_LeaseSetType; }; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a258e8f7..96efe5e6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -5,7 +5,6 @@ #include "Elligator.h" #include "Tag.h" #include "I2PEndian.h" -#include "Garlic.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -36,7 +35,7 @@ namespace garlic } bool ECIESX25519AEADRatchetSession::NewIncomingSession (const i2p::data::LocalDestination& dest, - const uint8_t * buf, size_t len, CloveI2NPMsgHandler handleCloveI2NPMsg) + const uint8_t * buf, size_t len, CloveHandler handleClove) { // we are Bob // KDF1 @@ -87,12 +86,12 @@ namespace garlic } if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) - HandlePayload (payload.data (), len - 16, handleCloveI2NPMsg); + HandlePayload (payload.data (), len - 16, handleClove); return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove) { size_t offset = 0; while (offset < len) @@ -110,7 +109,7 @@ namespace garlic switch (blk) { case eECIESx25519BlkGalicClove: - HandleClove (buf + offset, size, handleCloveI2NPMsg); + handleClove (buf + offset, size); break; case eECIESx25519BlkDateTime: LogPrint (eLogDebug, "Garlic: datetime"); @@ -119,7 +118,7 @@ namespace garlic LogPrint (eLogDebug, "Garlic: options"); break; case eECIESx25519BlkPadding: - LogPrint (eLogDebug, "NTCP2: padding"); + LogPrint (eLogDebug, "Garlic: padding"); break; default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); @@ -127,33 +126,6 @@ namespace garlic offset += size; } } - - void ECIESX25519AEADRatchetSession::HandleClove (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg) - { - const uint8_t * buf1 = buf; - uint8_t flag = buf[0]; buf++; // flag - GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); - switch (deliveryType) - { - case eGarlicDeliveryTypeDestination: - buf += 32; // TODO: check destination - // no break here - case eGarlicDeliveryTypeLocal: - { - uint8_t typeID = buf[0]; buf++; // typeid - buf += (4 + 4); // msgID + expiration - ptrdiff_t offset = buf - buf1; - if (offset <= (int)len) - handleCloveI2NPMsg (typeID, buf, len - offset); - else - LogPrint (eLogError, "Garlic: clove is too long"); - break; - } - // TODO: tunnel - default: - LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); - } - } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index dd28c669..aa482d54 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -24,20 +24,19 @@ namespace garlic { public: - typedef std::function CloveI2NPMsgHandler; + typedef std::function CloveHandler; ECIESX25519AEADRatchetSession (); ~ECIESX25519AEADRatchetSession (); bool NewIncomingSession (const i2p::data::LocalDestination& dest, const uint8_t * buf, size_t len, - CloveI2NPMsgHandler handleCloveI2NPMsg); + CloveHandler handleClove); private: void MixHash (const uint8_t * buf, size_t len); - void HandlePayload (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg); - void HandleClove (const uint8_t * buf, size_t len, CloveI2NPMsgHandler& handleCloveI2NPMsg); + void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 5dfdfe79..aa715e0c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -833,11 +833,64 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { ECIESX25519AEADRatchetSession session; - session.NewIncomingSession (*this, buf, len, - [this](uint8_t typeID, const uint8_t * payload, size_t len) - { - HandleCloveI2NPMessage (typeID, payload,len); - }); + session.NewIncomingSession (*this, buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2)); } + + void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) + { + const uint8_t * buf1 = buf; + uint8_t flag = buf[0]; buf++; // flag + GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); + switch (deliveryType) + { + case eGarlicDeliveryTypeDestination: + LogPrint (eLogDebug, "Garlic: type destination"); + buf += 32; // TODO: check destination + // no break here + case eGarlicDeliveryTypeLocal: + { + LogPrint (eLogDebug, "Garlic: type local"); + I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid + buf += (4 + 4); // msgID + expiration + ptrdiff_t offset = buf - buf1; + if (offset <= (int)len) + HandleCloveI2NPMessage (typeID, buf, len - offset); + else + LogPrint (eLogError, "Garlic: clove is too long"); + break; + } + case eGarlicDeliveryTypeTunnel: + { + LogPrint (eLogDebug, "Garlic: type tunnel"); + // gwHash and gwTunnel sequence is reverted + const uint8_t * gwHash = buf; + buf += 32; + ptrdiff_t offset = buf - buf1; + if (offset + 13 > (int)len) + { + LogPrint (eLogError, "Garlic: message is too short"); + break; + } + uint32_t gwTunnel = bufbe32toh (buf); buf += 4; + I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid + buf += (4 + 4); // msgID + expiration + offset += 13; + if (GetTunnelPool ()) + { + auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); + if (tunnel) + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); + else + LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); + } + else + LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel"); + break; + } + default: + LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 44ab2e82..30e6ff4b 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -194,7 +194,7 @@ namespace garlic protected: virtual void HandleI2NPMessage (const uint8_t * buf, size_t len) = 0; // called from clove only - virtual bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) = 0; + virtual bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) = 0; void HandleGarlicMessage (std::shared_ptr msg); void HandleDeliveryStatusMessage (uint32_t msgID); @@ -209,6 +209,7 @@ namespace garlic // ECIES-X25519-AEAD-Ratchet void HandleECIESx25519 (const uint8_t * buf, size_t len); + void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); private: diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 1524270d..dfc05fe7 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -124,7 +124,7 @@ namespace i2p // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (uint8_t typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented private: From d7d964bf57fe1cc42b142c53cd6b3593178a734d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 14:31:01 -0500 Subject: [PATCH 0160/2950] GarlicRoutingSession/ElGamalAESSession split --- libi2pd/Garlic.cpp | 242 +++++++++++++++++++++++---------------------- libi2pd/Garlic.h | 115 +++++++++++++-------- libi2pd/NetDb.cpp | 2 +- 3 files changed, 201 insertions(+), 158 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index aa715e0c..aac4c06c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -19,23 +19,16 @@ namespace i2p namespace garlic { GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner, - std::shared_ptr destination, int numTags, bool attachLeaseSet): - m_Owner (owner), m_Destination (destination), m_NumTags (numTags), + std::shared_ptr destination, bool attachLeaseSet): + m_Owner (owner), m_Destination (destination), m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0) { - // create new session tags and session key - RAND_bytes (m_SessionKey, 32); - m_Encryption.SetKey (m_SessionKey); } - GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag): - m_Owner (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0) + GarlicRoutingSession::GarlicRoutingSession (): + m_Owner (nullptr), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0) { - memcpy (m_SessionKey, sessionKey, 32); - m_Encryption.SetKey (m_SessionKey); - m_SessionTags.push_back (sessionTag); - m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch (); } GarlicRoutingSession::~GarlicRoutingSession () @@ -67,88 +60,24 @@ namespace garlic m_SharedRoutingPath = path; } - GarlicRoutingSession::UnconfirmedTags * GarlicRoutingSession::GenerateSessionTags () + ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, + std::shared_ptr destination, int numTags, bool attachLeaseSet): + GarlicRoutingSession (owner, destination, attachLeaseSet), m_NumTags (numTags) { - auto tags = new UnconfirmedTags (m_NumTags); - tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch (); - for (int i = 0; i < m_NumTags; i++) - { - RAND_bytes (tags->sessionTags[i], 32); - tags->sessionTags[i].creationTime = tags->tagsCreationTime; - } - return tags; + // create new session tags and session key + RAND_bytes (m_SessionKey, 32); + m_Encryption.SetKey (m_SessionKey); } - void GarlicRoutingSession::MessageConfirmed (uint32_t msgID) + ElGamalAESSession::ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag) { - TagsConfirmed (msgID); - if (msgID == m_LeaseSetUpdateMsgID) - { - m_LeaseSetUpdateStatus = eLeaseSetUpToDate; - m_LeaseSetUpdateMsgID = 0; - LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); - } - else - CleanupExpiredTags (); + memcpy (m_SessionKey, sessionKey, 32); + m_Encryption.SetKey (m_SessionKey); + m_SessionTags.push_back (sessionTag); + m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch (); } - void GarlicRoutingSession::TagsConfirmed (uint32_t msgID) - { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - auto it = m_UnconfirmedTagsMsgs.find (msgID); - if (it != m_UnconfirmedTagsMsgs.end ()) - { - auto& tags = it->second; - if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) - { - for (int i = 0; i < tags->numTags; i++) - m_SessionTags.push_back (tags->sessionTags[i]); - } - m_UnconfirmedTagsMsgs.erase (it); - } - } - - bool GarlicRoutingSession::CleanupExpiredTags () - { - auto ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_SessionTags.begin (); it != m_SessionTags.end ();) - { - if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) - it = m_SessionTags.erase (it); - else - ++it; - } - CleanupUnconfirmedTags (); - if (m_LeaseSetUpdateMsgID && ts*1000LL > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT) - { - if (m_Owner) - m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); - m_LeaseSetUpdateMsgID = 0; - } - return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); - } - - bool GarlicRoutingSession::CleanupUnconfirmedTags () - { - bool ret = false; - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - // delete expired unconfirmed tags - for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();) - { - if (ts >= it->second->tagsCreationTime + OUTGOING_TAGS_CONFIRMATION_TIMEOUT) - { - if (m_Owner) - m_Owner->RemoveDeliveryStatusSession (it->first); - it = m_UnconfirmedTagsMsgs.erase (it); - ret = true; - } - else - ++it; - } - return ret; - } - - std::shared_ptr GarlicRoutingSession::WrapSingleMessage (std::shared_ptr msg) + std::shared_ptr ElGamalAESSession::WrapSingleMessage (std::shared_ptr msg) { auto m = NewI2NPMessage (); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -178,7 +107,7 @@ namespace garlic if (!tagFound) // new session { LogPrint (eLogInfo, "Garlic: No tags available, will use ElGamal"); - if (!m_Destination) + if (!GetDestination ()) { LogPrint (eLogError, "Garlic: Can't use ElGamal for unknown destination"); return nullptr; @@ -190,7 +119,7 @@ namespace garlic 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); + GetDestination ()->Encrypt ((uint8_t *)&elGamal, buf, ctx); BN_CTX_free (ctx); m_Encryption.SetIV (iv); buf += 514; @@ -214,10 +143,10 @@ namespace garlic return m; } - size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, std::shared_ptr msg) + size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr msg) { size_t blockSize = 0; - bool createNewTags = m_Owner && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3); + bool createNewTags = GetOwner () && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3); UnconfirmedTags * newTags = createNewTags ? GenerateSessionTags () : nullptr; htobuf16 (buf, newTags ? htobe16 (newTags->numTags) : 0); // tag count blockSize += 2; @@ -246,7 +175,7 @@ namespace garlic return blockSize; } - size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, std::shared_ptr msg, UnconfirmedTags * newTags) + size_t ElGamalAESSession::CreateGarlicPayload (uint8_t * payload, std::shared_ptr msg, UnconfirmedTags * newTags) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); uint32_t msgID; @@ -256,17 +185,17 @@ namespace garlic *numCloves = 0; size++; - if (m_Owner) + if (GetOwner ()) { // resubmit non-confirmed LeaseSet - if (m_LeaseSetUpdateStatus == eLeaseSetSubmitted && ts > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT) + if (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT) { - m_LeaseSetUpdateStatus = eLeaseSetUpdated; + SetLeaseSetUpdateStatus (eLeaseSetUpdated); SetSharedRoutingPath (nullptr); // invalidate path since leaseset was not confirmed } // attach DeviveryStatus if necessary - if (newTags || m_LeaseSetUpdateStatus == eLeaseSetUpdated) // new tags created or leaseset updated + if (newTags || GetLeaseSetUpdateStatus () == eLeaseSetUpdated) // new tags created or leaseset updated { // clove is DeliveryStatus auto cloveSize = CreateDeliveryStatusClove (payload + size, msgID); @@ -280,27 +209,27 @@ namespace garlic m_UnconfirmedTagsMsgs.insert (std::make_pair(msgID, std::unique_ptr(newTags))); newTags = nullptr; // got acquired } - m_Owner->DeliveryStatusSent (shared_from_this (), msgID); + GetOwner ()->DeliveryStatusSent (shared_from_this (), msgID); } else LogPrint (eLogWarning, "Garlic: DeliveryStatus clove was not created"); } // attach LeaseSet - if (m_LeaseSetUpdateStatus == eLeaseSetUpdated) + if (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) { - if (m_LeaseSetUpdateMsgID) m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); // remove previous - m_LeaseSetUpdateStatus = eLeaseSetSubmitted; - m_LeaseSetUpdateMsgID = msgID; - m_LeaseSetSubmissionTime = ts; + if (GetLeaseSetUpdateMsgID ()) GetOwner ()->RemoveDeliveryStatusSession (GetLeaseSetUpdateMsgID ()); // remove previous + SetLeaseSetUpdateStatus (eLeaseSetSubmitted); + SetLeaseSetUpdateMsgID (msgID); + SetLeaseSetSubmissionTime (ts); // clove if our leaseSet must be attached - auto leaseSet = CreateDatabaseStoreMsg (m_Owner->GetLeaseSet ()); + auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); size += CreateGarlicClove (payload + size, leaseSet, false); (*numCloves)++; } } if (msg) // clove message ifself if presented { - size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false); + size += CreateGarlicClove (payload + size, msg, IsDestination ()); (*numCloves)++; } memset (payload + size, 0, 3); // certificate of message @@ -314,7 +243,7 @@ namespace garlic return size; } - size_t GarlicRoutingSession::CreateGarlicClove (uint8_t * buf, std::shared_ptr msg, bool isDestination) + size_t ElGamalAESSession::CreateGarlicClove (uint8_t * buf, std::shared_ptr msg, bool isDestination) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 8000; // 8 sec size_t size = 0; @@ -322,7 +251,7 @@ namespace garlic { buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination size++; - memcpy (buf + size, m_Destination->GetIdentHash (), 32); + memcpy (buf + size, GetDestination ()->GetIdentHash (), 32); size += 32; } else @@ -344,12 +273,12 @@ namespace garlic return size; } - size_t GarlicRoutingSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID) + size_t ElGamalAESSession::CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID) { size_t size = 0; - if (m_Owner) + if (GetOwner ()) { - auto inboundTunnel = m_Owner->GetTunnelPool ()->GetNextInboundTunnel (); + auto inboundTunnel = GetOwner ()->GetTunnelPool ()->GetNextInboundTunnel (); if (inboundTunnel) { buf[size] = eGarlicDeliveryTypeTunnel << 5; // delivery instructions flag tunnel @@ -361,14 +290,14 @@ namespace garlic size += 4; // create msg auto msg = CreateDeliveryStatusMsg (msgID); - if (m_Owner) + if (GetOwner ()) { //encrypt uint8_t key[32], tag[32]; RAND_bytes (key, 32); // random session key RAND_bytes (tag, 32); // random session tag - m_Owner->SubmitSessionKey (key, tag); - GarlicRoutingSession garlic (key, tag); + GetOwner ()->SubmitSessionKey (key, tag); + ElGamalAESSession garlic (key, tag); msg = garlic.WrapSingleMessage (msg); } memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); @@ -393,6 +322,87 @@ namespace garlic return size; } + ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags () + { + auto tags = new UnconfirmedTags (m_NumTags); + tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch (); + for (int i = 0; i < m_NumTags; i++) + { + RAND_bytes (tags->sessionTags[i], 32); + tags->sessionTags[i].creationTime = tags->tagsCreationTime; + } + return tags; + } + + void ElGamalAESSession::MessageConfirmed (uint32_t msgID) + { + TagsConfirmed (msgID); + if (msgID == GetLeaseSetUpdateMsgID ()) + { + SetLeaseSetUpdateStatus (eLeaseSetUpToDate); + SetLeaseSetUpdateMsgID (0); + LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); + } + else + CleanupExpiredTags (); + } + + void ElGamalAESSession::TagsConfirmed (uint32_t msgID) + { + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + auto it = m_UnconfirmedTagsMsgs.find (msgID); + if (it != m_UnconfirmedTagsMsgs.end ()) + { + auto& tags = it->second; + if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) + { + for (int i = 0; i < tags->numTags; i++) + m_SessionTags.push_back (tags->sessionTags[i]); + } + m_UnconfirmedTagsMsgs.erase (it); + } + } + + bool ElGamalAESSession::CleanupExpiredTags () + { + auto ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_SessionTags.begin (); it != m_SessionTags.end ();) + { + if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) + it = m_SessionTags.erase (it); + else + ++it; + } + CleanupUnconfirmedTags (); + if (GetLeaseSetUpdateMsgID () && ts*1000LL > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT) + { + if (GetOwner ()) + GetOwner ()->RemoveDeliveryStatusSession (GetLeaseSetUpdateMsgID ()); + SetLeaseSetUpdateMsgID (0); + } + return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); + } + + bool ElGamalAESSession::CleanupUnconfirmedTags () + { + bool ret = false; + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + // delete expired unconfirmed tags + for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();) + { + if (ts >= it->second->tagsCreationTime + OUTGOING_TAGS_CONFIRMATION_TIMEOUT) + { + if (GetOwner ()) + GetOwner ()->RemoveDeliveryStatusSession (it->first); + it = m_UnconfirmedTagsMsgs.erase (it); + ret = true; + } + else + ++it; + } + return ret; + } + GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default { m_Ctx = BN_CTX_new (); @@ -646,7 +656,7 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - GarlicRoutingSessionPtr session; + ElGamalAESSessionPtr session; { std::unique_lock l(m_SessionsMutex); auto it = m_Sessions.find (destination->GetIdentHash ()); @@ -655,7 +665,7 @@ namespace garlic } if (!session) { - session = std::make_shared (this, destination, + session = std::make_shared (this, destination, attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests std::unique_lock l(m_SessionsMutex); m_Sessions[destination->GetIdentHash ()] = session; @@ -716,7 +726,7 @@ namespace garlic m_DeliveryStatusSessions.erase (msgID); } - void GarlicDestination::DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID) + void GarlicDestination::DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID) { std::unique_lock l(m_DeliveryStatusSessionsMutex); m_DeliveryStatusSessions[msgID] = session; @@ -724,7 +734,7 @@ namespace garlic void GarlicDestination::HandleDeliveryStatusMessage (uint32_t msgID) { - GarlicRoutingSessionPtr session; + ElGamalAESSessionPtr session; { std::unique_lock l(m_DeliveryStatusSessionsMutex); auto it = m_DeliveryStatusSessions.find (msgID); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 30e6ff4b..296ef9a3 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -85,8 +85,10 @@ namespace garlic }; class GarlicDestination; - class GarlicRoutingSession: public std::enable_shared_from_this + class GarlicRoutingSession { + protected: + enum LeaseSetUpdateStatus { eLeaseSetUpToDate = 0, @@ -95,26 +97,13 @@ namespace garlic eLeaseSetDoNotSend }; - struct UnconfirmedTags - { - UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; - ~UnconfirmedTags () { delete[] sessionTags; }; - uint32_t msgID; - int numTags; - SessionTag * sessionTags; - uint32_t tagsCreationTime; - }; - public: - GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr destination, - int numTags, bool attachLeaseSet); - GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption - ~GarlicRoutingSession (); - std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - void MessageConfirmed (uint32_t msgID); - bool CleanupExpiredTags (); // returns true if something left - bool CleanupUnconfirmedTags (); // returns true if something has been deleted + GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr destination, bool attachLeaseSet); + GarlicRoutingSession (); + virtual ~GarlicRoutingSession (); + virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; + virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession void SetLeaseSetUpdated () { @@ -127,11 +116,65 @@ namespace garlic std::shared_ptr GetSharedRoutingPath (); void SetSharedRoutingPath (std::shared_ptr path); - const GarlicDestination * GetOwner () const { return m_Owner; } + GarlicDestination * GetOwner () const { return m_Owner; } void SetOwner (GarlicDestination * owner) { m_Owner = owner; } + protected: + + LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } + void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; } + uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; } + void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } + + void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } + bool IsDestination () const { return m_Destination ? m_Destination->IsDestination () : false; } + const std::shared_ptr& GetDestination () const { return m_Destination; } + private: + GarlicDestination * m_Owner; + std::shared_ptr m_Destination; + + LeaseSetUpdateStatus m_LeaseSetUpdateStatus; + uint32_t m_LeaseSetUpdateMsgID; + uint64_t m_LeaseSetSubmissionTime; // in milliseconds + + std::shared_ptr m_SharedRoutingPath; + + public: + // for HTTP only + virtual size_t GetNumOutgoingTags () const { return 0; }; + }; + //using GarlicRoutingSessionPtr = std::shared_ptr; + typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 + + class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this + { + struct UnconfirmedTags + { + UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; + ~UnconfirmedTags () { delete[] sessionTags; }; + uint32_t msgID; + int numTags; + SessionTag * sessionTags; + uint32_t tagsCreationTime; + }; + + public: + + ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, + int numTags, bool attachLeaseSet); + ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption + ~ElGamalAESSession () {}; + + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); + + void MessageConfirmed (uint32_t msgID); + bool CleanupExpiredTags (); // returns true if something left + bool CleanupUnconfirmedTags (); // returns true if something has been deleted + + private: + size_t CreateAESBlock (uint8_t * buf, std::shared_ptr msg); size_t CreateGarlicPayload (uint8_t * payload, std::shared_ptr msg, UnconfirmedTags * newTags); size_t CreateGarlicClove (uint8_t * buf, std::shared_ptr msg, bool isDestination); @@ -139,31 +182,21 @@ namespace garlic void TagsConfirmed (uint32_t msgID); UnconfirmedTags * GenerateSessionTags (); + + private: - private: - - GarlicDestination * m_Owner; - std::shared_ptr m_Destination; - - i2p::crypto::AESKey m_SessionKey; + i2p::crypto::AESKey m_SessionKey; std::list m_SessionTags; int m_NumTags; std::map > m_UnconfirmedTagsMsgs; // msgID->tags - LeaseSetUpdateStatus m_LeaseSetUpdateStatus; - uint32_t m_LeaseSetUpdateMsgID; - uint64_t m_LeaseSetSubmissionTime; // in milliseconds + i2p::crypto::CBCEncryption m_Encryption; - i2p::crypto::CBCEncryption m_Encryption; - - std::shared_ptr m_SharedRoutingPath; - - public: + public: // for HTTP only - size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; - }; - //using GarlicRoutingSessionPtr = std::shared_ptr; - typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 + size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; + }; + typedef std::shared_ptr ElGamalAESSessionPtr; class GarlicDestination: public i2p::data::LocalDestination { @@ -182,7 +215,7 @@ namespace garlic void AddSessionKey (const uint8_t * key, const uint8_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); + void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); virtual void ProcessGarlicMessage (std::shared_ptr msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); @@ -217,12 +250,12 @@ namespace garlic // outgoing sessions int m_NumTags; std::mutex m_SessionsMutex; - std::map m_Sessions; + std::map m_Sessions; // incoming std::map > m_Tags; // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; - std::map m_DeliveryStatusSessions; // msgID -> session + std::map m_DeliveryStatusSessions; // msgID -> session public: diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4461c094..6d69f131 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -950,7 +950,7 @@ namespace data if (numTags) { const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag - i2p::garlic::GarlicRoutingSession garlic (sessionKey, sessionTag); + i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); replyMsg = garlic.WrapSingleMessage (replyMsg); if(replyMsg == nullptr) LogPrint(eLogError, "NetDb: failed to wrap message"); } From dc9da6950953b6491385257de29dc5061545bbb4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 14:59:19 -0500 Subject: [PATCH 0161/2950] derive ECIESX25519AEADRatchetSession from GarlicRoutingSession --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 19 +++++++++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 10 ++++++---- libi2pd/Garlic.cpp | 21 ++++++++++----------- libi2pd/Garlic.h | 10 ++++------ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 96efe5e6..56b97635 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -12,7 +12,8 @@ namespace i2p namespace garlic { - ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession () + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): + GarlicRoutingSession (owner, true) { // TODO : use precalculated hashes static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes @@ -34,12 +35,12 @@ namespace garlic SHA256_Final (m_H, &ctx); } - bool ECIESX25519AEADRatchetSession::NewIncomingSession (const i2p::data::LocalDestination& dest, - const uint8_t * buf, size_t len, CloveHandler handleClove) + bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { + if (!GetOwner ()) return false; // we are Bob // KDF1 - MixHash (dest.GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk) + MixHash (GetOwner ()->GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk) uint8_t aepk[32]; // Alice's ephemeral key if (!i2p::crypto::GetElligator ()->Decode (buf, aepk)) @@ -51,7 +52,7 @@ namespace garlic MixHash (aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32], keyData[64]; - dest.Decrypt (aepk, sharedSecret, nullptr); // x25519(bsk, aepk) + GetOwner ()->Decrypt (aepk, sharedSecret, nullptr); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] @@ -73,7 +74,7 @@ namespace garlic if (isStatic) { // static key, fs is apk - dest.Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) + GetOwner ()->Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] } @@ -126,6 +127,12 @@ namespace garlic offset += size; } } + + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) + { + // TODO: + return nullptr; + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index aa482d54..fa9a960e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -4,6 +4,7 @@ #include #include #include "Identity.h" +#include "Garlic.h" namespace i2p { @@ -20,17 +21,18 @@ namespace garlic eECIESx25519BlkPadding = 254 }; - class ECIESX25519AEADRatchetSession + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession { public: typedef std::function CloveHandler; - ECIESX25519AEADRatchetSession (); + ECIESX25519AEADRatchetSession (GarlicDestination * owner); ~ECIESX25519AEADRatchetSession (); - bool NewIncomingSession (const i2p::data::LocalDestination& dest, const uint8_t * buf, size_t len, - CloveHandler handleClove); + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); + + bool NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index aac4c06c..965ccdb4 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -18,10 +18,8 @@ namespace i2p { namespace garlic { - GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner, - std::shared_ptr destination, bool attachLeaseSet): - m_Owner (owner), m_Destination (destination), - m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend), + GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner, bool attachLeaseSet): + m_Owner (owner), m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0) { } @@ -62,7 +60,8 @@ namespace garlic ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, int numTags, bool attachLeaseSet): - GarlicRoutingSession (owner, destination, attachLeaseSet), m_NumTags (numTags) + GarlicRoutingSession (owner, attachLeaseSet), + m_Destination (destination), m_NumTags (numTags) { // create new session tags and session key RAND_bytes (m_SessionKey, 32); @@ -107,7 +106,7 @@ namespace garlic if (!tagFound) // new session { LogPrint (eLogInfo, "Garlic: No tags available, will use ElGamal"); - if (!GetDestination ()) + if (!m_Destination) { LogPrint (eLogError, "Garlic: Can't use ElGamal for unknown destination"); return nullptr; @@ -119,7 +118,7 @@ namespace garlic uint8_t iv[32]; // IV is first 16 bytes SHA256(elGamal.preIV, 32, iv); BN_CTX * ctx = BN_CTX_new (); - GetDestination ()->Encrypt ((uint8_t *)&elGamal, buf, ctx); + m_Destination->Encrypt ((uint8_t *)&elGamal, buf, ctx); BN_CTX_free (ctx); m_Encryption.SetIV (iv); buf += 514; @@ -229,7 +228,7 @@ namespace garlic } if (msg) // clove message ifself if presented { - size += CreateGarlicClove (payload + size, msg, IsDestination ()); + size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false); (*numCloves)++; } memset (payload + size, 0, 3); // certificate of message @@ -251,7 +250,7 @@ namespace garlic { buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination size++; - memcpy (buf + size, GetDestination ()->GetIdentHash (), 32); + memcpy (buf + size, m_Destination->GetIdentHash (), 32); size += 32; } else @@ -842,8 +841,8 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - ECIESX25519AEADRatchetSession session; - session.NewIncomingSession (*this, buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + ECIESX25519AEADRatchetSession session (this); + session.NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, this, std::placeholders::_1, std::placeholders::_2)); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 296ef9a3..cd8c48ed 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -99,7 +99,7 @@ namespace garlic public: - GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr destination, bool attachLeaseSet); + GarlicRoutingSession (GarlicDestination * owner, bool attachLeaseSet); GarlicRoutingSession (); virtual ~GarlicRoutingSession (); virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; @@ -125,15 +125,11 @@ namespace garlic void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; } uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; } void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } - - void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } - bool IsDestination () const { return m_Destination ? m_Destination->IsDestination () : false; } - const std::shared_ptr& GetDestination () const { return m_Destination; } + void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } private: GarlicDestination * m_Owner; - std::shared_ptr m_Destination; LeaseSetUpdateStatus m_LeaseSetUpdateStatus; uint32_t m_LeaseSetUpdateMsgID; @@ -184,6 +180,8 @@ namespace garlic UnconfirmedTags * GenerateSessionTags (); private: + + std::shared_ptr m_Destination; i2p::crypto::AESKey m_SessionKey; std::list m_SessionTags; From b6800dd125544d9823f75b488949366789d6df33 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 15:45:22 -0500 Subject: [PATCH 0162/2950] lookup ECIESX25519AEADRatchet session by static key --- libi2pd/CryptoKey.cpp | 6 +-- libi2pd/CryptoKey.h | 4 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 1 + libi2pd/ECIESX25519AEADRatchetSession.h | 3 +- libi2pd/Garlic.cpp | 55 +++++++++++++++-------- libi2pd/Garlic.h | 4 ++ 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index df5dd38f..9881ebef 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -151,11 +151,9 @@ namespace crypto memcpy (m_PublicKey, pub, 32); } - void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) + void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) { - X25519Keys ep; - ep.SetPrivateKey (epriv); - ep.Agree (m_PublicKey, sharedSecret); + memcpy (pub, m_PublicKey, 32); } ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 6412f4d3..701e9482 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -125,8 +125,8 @@ namespace crypto ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; - void Encrypt (const uint8_t * epriv, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); - // agree with ephemeral priv and return in sharedSecret (32 bytes) + void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool); + // copies m_PublicKey to pub private: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 56b97635..2f18ada2 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -74,6 +74,7 @@ namespace garlic if (isStatic) { // static key, fs is apk + memcpy (m_StaticKey, fs, 32); GetOwner ()->Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index fa9a960e..b273f2fd 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -33,6 +33,7 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); bool NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); + const uint8_t * GetStaticKey () const { return m_StaticKey; }; private: @@ -42,7 +43,7 @@ namespace garlic private: - uint8_t m_H[32], m_CK[32]; + uint8_t m_H[32], m_CK[32], m_StaticKey[32]; }; } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 965ccdb4..f865d8f9 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -655,21 +655,35 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - ElGamalAESSessionPtr session; - { - std::unique_lock l(m_SessionsMutex); - auto it = m_Sessions.find (destination->GetIdentHash ()); - if (it != m_Sessions.end ()) - session = it->second; - } - if (!session) - { - session = std::make_shared (this, destination, - attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests - std::unique_lock l(m_SessionsMutex); - m_Sessions[destination->GetIdentHash ()] = session; - } - return session; + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + { + ECIESX25519AEADRatchetSessionPtr session; + uint8_t staticKey[32]; + destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key + auto it = m_ECIESx25519Sessions.find (staticKey); + if (it != m_ECIESx25519Sessions.end ()) + session = it->second; + // TODO: Alice + return session; + } + else + { + ElGamalAESSessionPtr session; + { + std::unique_lock l(m_SessionsMutex); + auto it = m_Sessions.find (destination->GetIdentHash ()); + if (it != m_Sessions.end ()) + session = it->second; + } + if (!session) + { + session = std::make_shared (this, destination, + attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests + std::unique_lock l(m_SessionsMutex); + m_Sessions[destination->GetIdentHash ()] = session; + } + return session; + } } void GarlicDestination::CleanupExpiredTags () @@ -841,9 +855,14 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - ECIESX25519AEADRatchetSession session (this); - session.NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, - this, std::placeholders::_1, std::placeholders::_2)); + auto session = std::make_shared (this); + if (session->NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2))) + { + m_ECIESx25519Sessions.emplace (session->GetStaticKey (), session); + } + else + LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); } void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index cd8c48ed..727b4a8d 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -196,6 +196,9 @@ namespace garlic }; typedef std::shared_ptr ElGamalAESSessionPtr; + class ECIESX25519AEADRatchetSession; + typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; + class GarlicDestination: public i2p::data::LocalDestination { public: @@ -249,6 +252,7 @@ namespace garlic int m_NumTags; std::mutex m_SessionsMutex; std::map m_Sessions; + std::map, ECIESX25519AEADRatchetSessionPtr > m_ECIESx25519Sessions; // static key -> session // incoming std::map > m_Tags; // DeliveryStatus From 67dd59125ed6f9c065cb43b98b459fc08543c4cb Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 16:34:13 -0500 Subject: [PATCH 0163/2950] new outgoing ECIESX25519AEADRatchet session --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 36 +++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 4 +++ 2 files changed, 40 insertions(+) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2f18ada2..22458a5e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -15,6 +15,7 @@ namespace garlic ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): GarlicRoutingSession (owner, true) { + m_EphemeralKeys.GenerateKeys (); // TODO : use precalculated hashes static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes SHA256 ((const uint8_t *)protocolName, 40, m_H); @@ -129,6 +130,41 @@ namespace garlic } } + bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Alice, bpk is m_StaticKey + size_t offset = 0; + if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) + { + LogPrint (eLogError, "Garlic: Can't encode elligator"); + return false; + } + offset += 32; + + // KDF1 + MixHash (m_StaticKey, 32); // h = SHA256(h || bpk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) + uint8_t sharedSecret[32], keyData[64]; + m_EphemeralKeys.Agree (m_StaticKey, nullptr); // x25519(aesk, bpk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) + memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] + // encrypt static key section + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (), 32, m_H, 32, keyData + 32, nonce, out + offset, 48, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); + return false; + } + MixHash (out + offset, 48); // h = SHA256(h || ciphertext) + offset += 48; + + // KDF2 + // TODO: // x25519 (ask, bpk) + + return true; + } + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { // TODO: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index b273f2fd..8cfd18b9 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -4,6 +4,7 @@ #include #include #include "Identity.h" +#include "Crypto.h" #include "Garlic.h" namespace i2p @@ -41,9 +42,12 @@ namespace garlic void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); + bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + private: uint8_t m_H[32], m_CK[32], m_StaticKey[32]; + i2p::crypto::X25519Keys m_EphemeralKeys; }; } } From 00cb15d9b4e8bddd5e99c0563b4662a0f2450385 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 18:03:51 -0500 Subject: [PATCH 0164/2950] fixed tyypo --- libi2pd/Garlic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index f865d8f9..a4cbeb01 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -68,7 +68,8 @@ namespace garlic m_Encryption.SetKey (m_SessionKey); } - ElGamalAESSession::ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag) + ElGamalAESSession::ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag): + m_NumTags(1) { memcpy (m_SessionKey, sessionKey, 32); m_Encryption.SetKey (m_SessionKey); From 451c3945f051a843c56a326891c053f826a30d53 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 16 Jan 2020 19:33:00 -0500 Subject: [PATCH 0165/2950] create new ECIESX25519AEADRatchet session if not found --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 44 ++++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 6 ++-- libi2pd/Garlic.cpp | 9 +++-- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 22458a5e..ff40bef1 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -35,7 +35,7 @@ namespace garlic SHA256_Update (&ctx, buf, len); SHA256_Final (m_H, &ctx); } - + bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { if (!GetOwner ()) return false; @@ -52,15 +52,14 @@ namespace garlic buf += 32; len -= 32; MixHash (aepk, 32); // h = SHA256(h || aepk) - uint8_t sharedSecret[32], keyData[64]; + uint8_t sharedSecret[32]; GetOwner ()->Decrypt (aepk, sharedSecret, nullptr); // x25519(bsk, aepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) - memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] - + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + // decrypt flags/static uint8_t nonce[12], fs[32]; memset (nonce, 0, 12); // n = 0 - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, keyData + 32, nonce, fs, 32, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); return false; @@ -75,14 +74,13 @@ namespace garlic if (isStatic) { // static key, fs is apk - memcpy (m_StaticKey, fs, 32); + memcpy (m_RemoteStaticKey, fs, 32); GetOwner ()->Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) - memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags htole64buf (nonce + 4, 1); // n = 1 - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keyData + 32, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); return false; @@ -132,7 +130,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { - // we are Alice, bpk is m_StaticKey + // we are Alice, bpk is m_RemoteStaticKey size_t offset = 0; if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) { @@ -142,26 +140,32 @@ namespace garlic offset += 32; // KDF1 - MixHash (m_StaticKey, 32); // h = SHA256(h || bpk) + MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) - uint8_t sharedSecret[32], keyData[64]; - m_EphemeralKeys.Agree (m_StaticKey, nullptr); // x25519(aesk, bpk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", keyData); // keydata = HKDF(chainKey, sharedSecret, "", 64) - memcpy (m_CK, keyData, 32); // chainKey = keydata[0:31] + uint8_t sharedSecret[32]; + m_EphemeralKeys.Agree (m_RemoteStaticKey, nullptr); // x25519(aesk, bpk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt static key section uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 - if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (), 32, m_H, 32, keyData + 32, nonce, out + offset, 48, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); return false; } MixHash (out + offset, 48); // h = SHA256(h || ciphertext) offset += 48; - // KDF2 - // TODO: // x25519 (ask, bpk) - + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr); // x25519 (ask, bpk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + // 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 section AEAD encryption failed"); + return false; + } + MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) + return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 8cfd18b9..fd0658a5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,6 +1,7 @@ #ifndef ECIES_X25519_AEAD_RATCHET_SESSION_H__ #define ECIES_X25519_AEAD_RATCHET_SESSION_H__ +#include #include #include #include "Identity.h" @@ -34,7 +35,8 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); bool NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); - const uint8_t * GetStaticKey () const { return m_StaticKey; }; + const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } + void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } private: @@ -46,7 +48,7 @@ namespace garlic private: - uint8_t m_H[32], m_CK[32], m_StaticKey[32]; + uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; i2p::crypto::X25519Keys m_EphemeralKeys; }; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index a4cbeb01..fc8a4f01 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -664,7 +664,12 @@ namespace garlic auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) session = it->second; - // TODO: Alice + if (!session) + { + session = std::make_shared (this); + session->SetRemoteStaticKey (staticKey); + m_ECIESx25519Sessions.emplace (staticKey, session); + } return session; } else @@ -860,7 +865,7 @@ namespace garlic if (session->NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, this, std::placeholders::_1, std::placeholders::_2))) { - m_ECIESx25519Sessions.emplace (session->GetStaticKey (), session); + m_ECIESx25519Sessions.emplace (session->GetRemoteStaticKey (), session); } else LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); From 80373623cdd325a52c79b1528a2375752cbf25e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Jan 2020 11:21:41 -0500 Subject: [PATCH 0166/2950] create payload --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 45 ++++++++++++++++++++--- libi2pd/ECIESX25519AEADRatchetSession.h | 9 +++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index ff40bef1..49077ef7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -15,7 +15,6 @@ namespace garlic ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): GarlicRoutingSession (owner, true) { - m_EphemeralKeys.GenerateKeys (); // TODO : use precalculated hashes static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes SHA256 ((const uint8_t *)protocolName, 40, m_H); @@ -86,7 +85,8 @@ namespace garlic return false; } if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) - + m_State = eSessionStateNewSessionReceived; + HandlePayload (payload.data (), len - 16, handleClove); return true; @@ -130,6 +130,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { + m_EphemeralKeys.GenerateKeys (); // we are Alice, bpk is m_RemoteStaticKey size_t offset = 0; if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) @@ -170,10 +171,44 @@ namespace garlic } std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) - { - // TODO: - return nullptr; + { + 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 + auto payload = CreatePayload (msg); + size_t len = payload.size (); + + switch (m_State) + { + case eSessionStateNew: + if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 96; + break; + default: + return nullptr; + } + + htobe32buf (m->GetPayload (), len); + m->len += len + 4; + m->FillI2NPMessageHeader (eI2NPGarlic); + return m; } + + std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) + { + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + std::vector v(cloveSize + 3); + uint8_t * payload = v.data (); + payload[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (payload + 1, cloveSize); // size + payload[3] = 0; // flag and delivery instructions + payload[4] = msg->GetTypeID (); // I2NP msg type + htobe32buf (payload + 5, msg->GetMsgID ()); // msgID + htobe32buf (payload + 9, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (payload + 13, msg->GetPayload (), msg->GetPayloadLength ()); + return v; + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index fd0658a5..0689ed5b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "Identity.h" #include "Crypto.h" #include "Garlic.h" @@ -25,6 +26,12 @@ namespace garlic class ECIESX25519AEADRatchetSession: public GarlicRoutingSession { + enum SessionState + { + eSessionStateNew =0, + eSessionStateNewSessionReceived + }; + public: typedef std::function CloveHandler; @@ -45,11 +52,13 @@ namespace garlic void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + std::vector CreatePayload (std::shared_ptr msg); private: uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; i2p::crypto::X25519Keys m_EphemeralKeys; + SessionState m_State = eSessionStateNew; }; } } From 62e39ddfbdbcb8c1f3d1cabbf416f0e0e978ac57 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 17 Jan 2020 14:11:15 -0500 Subject: [PATCH 0167/2950] new session reply --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 73 ++++++++++++++++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 2 + 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 49077ef7..36d8af43 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -34,7 +34,16 @@ namespace garlic SHA256_Update (&ctx, buf, len); SHA256_Final (m_H, &ctx); } - + + void ECIESX25519AEADRatchetSession::DHInitialize (const uint8_t * rootKey, const uint8_t * k, uint8_t * nextRootKey, uint8_t * ck) + { + uint8_t keydata[64]; + i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) + memcpy (nextRootKey, keydata, 32); // nextRootKey = keydata[0:31] + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", ck); + // ck = [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + } + bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { if (!GetOwner ()) return false; @@ -165,11 +174,66 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; } - MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) + MixHash (out + offset, 16); // h = SHA256(h || ciphertext) return true; } + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + m_EphemeralKeys.GenerateKeys (); + // we are Bob + uint8_t tagsetKey[32], ck[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) + DHInitialize (m_CK, tagsetKey, tagsetKey, ck); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey), nextRootKey? + // Session Tag Ratchet + uint8_t keydata[64]; + i2p::crypto::HKDF (ck, nullptr, 0, "STInitialization", keydata); // keydata = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) + // sessTag_chainKey = keydata[0:31], SESSTAG_CONSTANT = keydata[32:63] + i2p::crypto::HKDF (keydata, keydata + 32, 32, "SessionTagKeyGen", keydata); // keydata_0 = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + // tag_0 = keydata_0[32:39] + uint8_t * tag = keydata + 32; + + size_t offset = 0; + memcpy (out + offset, tag, 8); + offset += 8; + if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) // bepk + { + LogPrint (eLogError, "Garlic: Can't encode elligator"); + return false; + } + offset += 32; + // KDF for Reply Key Section + MixHash (tag, 8); // h = SHA256(h || tag) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + uint8_t sharedSecret[32]; + m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, aepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + // calulate hash for zero length + if (!i2p::crypto::AEADChaCha20Poly1305 (sharedSecret /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + { + LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); + return false; + } + MixHash (out + offset, 16); // h = SHA256(h || ciphertext) + out += 16; + // KDF for payload + i2p::crypto::HKDF (m_CK, nullptr, 0, "STInitialization", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + // k_ab = keydata[0:31], k_ba = keydata[32:63] + // tagset_ab = DH_INITIALIZE(chainKey, k_ab), tagset_ba = DH_INITIALIZE(chainKey, k_ba) + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); + return false; + } + + return true; + } + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { auto m = NewI2NPMessage (); @@ -185,6 +249,11 @@ namespace garlic return nullptr; len += 96; break; + case eSessionStateNewSessionReceived: + if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 72; + break; default: return nullptr; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 0689ed5b..4ff6623f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -48,10 +48,12 @@ namespace garlic private: void MixHash (const uint8_t * buf, size_t len); + void DHInitialize (const uint8_t * rootKey, const uint8_t * k, uint8_t * nextRootKey, uint8_t * ck); // ck is 64 buytes void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); std::vector CreatePayload (std::shared_ptr msg); private: From 6cc388c1bc5f2fdb0c5880b72b616a0206eec98c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 18 Jan 2020 14:43:36 -0500 Subject: [PATCH 0168/2950] use HKDF for MixKey --- libi2pd/NTCP2.cpp | 27 ++++++++++----------------- libi2pd/NTCP2.h | 4 ++-- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e2c4ae43..664b917b 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -41,15 +41,8 @@ namespace transport void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial) { - // temp_key = HMAC-SHA256(ck, input_key_material) - uint8_t tempKey[32]; unsigned int len; - HMAC(EVP_sha256(), m_CK, 32, inputKeyMaterial, 32, tempKey, &len); - // ck = HMAC-SHA256(temp_key, byte(0x01)) - static uint8_t one[1] = { 1 }; - HMAC(EVP_sha256(), tempKey, 32, one, 1, m_CK, &len); - // derived = HMAC-SHA256(temp_key, ck || byte(0x02)) - m_CK[32] = 2; - HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, m_K, &len); + i2p::crypto::HKDF (m_CK, inputKeyMaterial, 32, "", m_CK); + // ck is m_CK[0:31], k is m_CK[32:63] } void NTCP2Establisher::MixHash (const uint8_t * buf, size_t len) @@ -181,7 +174,7 @@ namespace transport // sign and encrypt options, use m_H as AD uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero - i2p::crypto::AEADChaCha20Poly1305 (options, 16, m_H, 32, m_K, nonce, m_SessionRequestBuffer + 32, 32, true); // encrypt + i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionRequestBuffer + 32, 32, true); // encrypt } void NTCP2Establisher::CreateSessionCreatedMessage () @@ -204,7 +197,7 @@ namespace transport // sign and encrypt options, use m_H as AD uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero - i2p::crypto::AEADChaCha20Poly1305 (options, 16, m_H, 32, m_K, nonce, m_SessionCreatedBuffer + 32, 32, true); // encrypt + i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionCreatedBuffer + 32, 32, true); // encrypt } @@ -217,7 +210,7 @@ namespace transport MixHash (m_SessionCreatedBuffer + 64, paddingLength); // part1 48 bytes - i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, m_H, 32, m_K, nonce, m_SessionConfirmedBuffer, 48, true); // encrypt + i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, GetH (), 32, GetK (), nonce, m_SessionConfirmedBuffer, 48, true); // encrypt } void NTCP2Establisher::CreateSessionConfirmedMessagePart2 (const uint8_t * nonce) @@ -228,7 +221,7 @@ namespace transport // encrypt m3p2, it must be filled in SessionRequest KDF3Alice (); uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; - i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2, m3p2Len, true); // encrypt + i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2, m3p2Len, true); // encrypt // update h again MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext) } @@ -246,7 +239,7 @@ namespace transport // verify MAC and decrypt options block (32 bytes), use m_H as AD uint8_t nonce[12], options[16]; memset (nonce, 0, 12); // set nonce to zero - if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionRequestBuffer + 32, 16, m_H, 32, m_K, nonce, options, 16, false)) // decrypt + if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionRequestBuffer + 32, 16, GetH (), 32, GetK (), nonce, options, 16, false)) // decrypt { // options if (options[0] && options[0] != i2p::context.GetNetID ()) @@ -301,7 +294,7 @@ namespace transport uint8_t payload[16]; uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero - if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionCreatedBuffer + 32, 16, m_H, 32, m_K, nonce, payload, 16, false)) // decrypt + if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionCreatedBuffer + 32, 16, GetH (), 32, GetK (), nonce, payload, 16, false)) // decrypt { // options paddingLen = bufbe16toh(payload + 2); @@ -330,7 +323,7 @@ namespace transport if (paddingLength > 0) MixHash (m_SessionCreatedBuffer + 64, paddingLength); - if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, m_H, 32, m_K, nonce, m_RemoteStaticKey, 32, false)) // decrypt S + if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, GetH (), 32, GetK (), nonce, m_RemoteStaticKey, 32, false)) // decrypt S { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed "); return false; @@ -344,7 +337,7 @@ namespace transport MixHash (m_SessionConfirmedBuffer, 48); KDF3Bob (); - if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt + if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt { // caclulate new h again for KDF data memcpy (m_SessionConfirmedBuffer + 16, m_H, 32); // h || ciphertext diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index c66ff697..93f6a1cc 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -85,7 +85,7 @@ namespace transport const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set - const uint8_t * GetK () const { return m_K; }; + const uint8_t * GetK () const { return m_CK + 32; }; const uint8_t * GetCK () const { return m_CK; }; const uint8_t * GetH () const { return m_H; }; @@ -114,7 +114,7 @@ namespace transport i2p::crypto::X25519Keys m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 - uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/; + uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/; i2p::data::IdentHash m_RemoteIdentHash; uint16_t m3p2Len; From eabcafa516a6e03d7480f2b4ff7e8870a4372818 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Thu, 16 Jan 2020 22:10:15 -0800 Subject: [PATCH 0169/2950] replace random_shuffle with shuffle random_shuffle is gone with C++17. Found and fixed with clang-tidy. --- libi2pd/Tunnel.cpp | 3 ++- libi2pd/TunnelPool.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 66620717..00b0a12c 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,5 +1,6 @@ #include #include "I2PEndian.h" +#include #include #include #include @@ -45,7 +46,7 @@ namespace tunnel // shuffle records std::vector recordIndicies; for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i); - std::random_shuffle (recordIndicies.begin(), recordIndicies.end()); + std::shuffle (recordIndicies.begin(), recordIndicies.end(), std::mt19937(std::random_device()())); // create real records uint8_t * records = msg->GetPayload () + 1; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 4f740a09..7a1325fe 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -1,4 +1,5 @@ #include +#include #include "I2PEndian.h" #include "Crypto.h" #include "Tunnel.h" @@ -441,7 +442,7 @@ namespace tunnel int size = m_ExplicitPeers->size (); std::vector peerIndicies; for (int i = 0; i < size; i++) peerIndicies.push_back(i); - std::random_shuffle (peerIndicies.begin(), peerIndicies.end()); + std::shuffle (peerIndicies.begin(), peerIndicies.end(), std::mt19937(std::random_device()())); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; for (int i = 0; i < numHops; i++) From 8b49a5544284562a2a1082ae332ecb58578182c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 20 Jan 2020 15:17:38 -0500 Subject: [PATCH 0170/2950] ratchet tagsets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 52 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 15 ++++++- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 36d8af43..7548603c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -12,6 +12,29 @@ namespace i2p namespace garlic { + void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k) + { + // DH_INITIALIZE(rootKey, k) + uint8_t keydata[64]; + i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) + // nextRootKey = keydata[0:31] + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_CK); + // ck = [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + } + + void RatchetTagSet::NextSessionTagRatchet () + { + i2p::crypto::HKDF (m_CK, nullptr, 0, "STInitialization", m_CK); // [ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) + memcpy (m_SessTagConstant, m_CK + 32, 32); + } + + const uint8_t * RatchetTagSet::GetNextSessionTag () + { + i2p::crypto::HKDF (m_CK, m_SessTagConstant, 32, "SessionTagKeyGen", m_CK); // [ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + return m_CK + 32; + } + + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): GarlicRoutingSession (owner, true) { @@ -35,15 +58,6 @@ namespace garlic SHA256_Final (m_H, &ctx); } - void ECIESX25519AEADRatchetSession::DHInitialize (const uint8_t * rootKey, const uint8_t * k, uint8_t * nextRootKey, uint8_t * ck) - { - uint8_t keydata[64]; - i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) - memcpy (nextRootKey, keydata, 32); // nextRootKey = keydata[0:31] - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", ck); - // ck = [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) - } - bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { if (!GetOwner ()) return false; @@ -183,16 +197,14 @@ namespace garlic { m_EphemeralKeys.GenerateKeys (); // we are Bob - uint8_t tagsetKey[32], ck[64]; + uint8_t tagsetKey[32]; i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) - DHInitialize (m_CK, tagsetKey, tagsetKey, ck); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey), nextRootKey? + // Session Tag Ratchet - uint8_t keydata[64]; - i2p::crypto::HKDF (ck, nullptr, 0, "STInitialization", keydata); // keydata = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) - // sessTag_chainKey = keydata[0:31], SESSTAG_CONSTANT = keydata[32:63] - i2p::crypto::HKDF (keydata, keydata + 32, 32, "SessionTagKeyGen", keydata); // keydata_0 = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) - // tag_0 = keydata_0[32:39] - uint8_t * tag = keydata + 32; + RatchetTagSet tagsetNsr; + tagsetNsr.DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) + tagsetNsr.NextSessionTagRatchet (); + auto tag = tagsetNsr.GetNextSessionTag (); size_t offset = 0; memcpy (out + offset, tag, 8); @@ -220,9 +232,11 @@ namespace garlic MixHash (out + offset, 16); // h = SHA256(h || ciphertext) out += 16; // KDF for payload - i2p::crypto::HKDF (m_CK, nullptr, 0, "STInitialization", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) // k_ab = keydata[0:31], k_ba = keydata[32:63] - // tagset_ab = DH_INITIALIZE(chainKey, k_ab), tagset_ba = DH_INITIALIZE(chainKey, k_ba) + m_TagsetAB.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_TagsetBA.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 4ff6623f..b449c0e5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -13,6 +13,19 @@ namespace i2p { namespace garlic { + class RatchetTagSet + { + public: + + void DHInitialize (const uint8_t * rootKey, const uint8_t * k); + void NextSessionTagRatchet (); + const uint8_t * GetNextSessionTag (); + + private: + + uint8_t m_CK[64], m_SessTagConstant[32]; + }; + enum ECIESx25519BlockType { eECIESx25519BlkDateTime = 0, @@ -48,7 +61,6 @@ namespace garlic private: void MixHash (const uint8_t * buf, size_t len); - void DHInitialize (const uint8_t * rootKey, const uint8_t * k, uint8_t * nextRootKey, uint8_t * ck); // ck is 64 buytes void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); @@ -61,6 +73,7 @@ namespace garlic uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; + RatchetTagSet m_TagsetAB, m_TagsetBA; }; } } From f498fabd27dd805d1d52640d472e5cdb05406043 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 10:52:51 -0500 Subject: [PATCH 0171/2950] fix for openssl 1.1 --- tests/test-x25519.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test-x25519.cpp b/tests/test-x25519.cpp index 9f249dbd..2ab8ad6a 100644 --- a/tests/test-x25519.cpp +++ b/tests/test-x25519.cpp @@ -27,10 +27,13 @@ uint8_t p[32] = int main () { +#if !OPENSSL_X25519 +// we test it for openssl < 1.1.0 uint8_t buf[32]; BN_CTX * ctx = BN_CTX_new (); i2p::crypto::GetEd25519 ()->ScalarMul (u, k, buf, ctx); BN_CTX_free (ctx); assert(memcmp (buf, p, 32) == 0); +#endif } From 0e666e7d6a65d4b51bf64876e38dc02d2b36b4cc Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 10:53:11 -0500 Subject: [PATCH 0172/2950] encoding fail test --- tests/test-elligator.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test-elligator.cpp b/tests/test-elligator.cpp index 94798e80..e73eb8ab 100644 --- a/tests/test-elligator.cpp +++ b/tests/test-elligator.cpp @@ -58,6 +58,12 @@ const uint8_t key3[32] = 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }; +const uint8_t failed_key[32] = +{ + 0xe6, 0xf6, 0x6f, 0xdf, 0x6e, 0x23, 0x0c, 0x60, 0x3c, 0x5e, 0x6e, 0x59, 0xa2, 0x54, 0xea, 0x14, + 0x76, 0xa1, 0x3e, 0xb9, 0x51, 0x1b, 0x95, 0x49, 0x84, 0x67, 0x81, 0xe1, 0x2e, 0x52, 0x23, 0x0a +}; + int main () { uint8_t buf[32]; @@ -74,4 +80,6 @@ int main () assert(memcmp (buf, key2, 32) == 0); el.Decode (encoded3, buf); assert(memcmp (buf, key3, 32) == 0); + // encoding fails + assert (!el.Encode (failed_key, buf)); } From f497a74ec4a0321d5b4e51b87d808923174f67b1 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 12:18:31 -0500 Subject: [PATCH 0173/2950] set random two highest bits --- libi2pd/Elligator.cpp | 13 ++++++++++--- libi2pd/Elligator.h | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index b9471512..bd9c382f 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -1,3 +1,4 @@ +#include #include "Crypto.h" #include "Elligator.h" @@ -39,8 +40,8 @@ namespace crypto BN_free (u); BN_free (iu); } - bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY) const - { + bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const + { bool ret = true; BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); @@ -61,7 +62,11 @@ namespace crypto BN_mod_mul (uxxA, uxxA, xA, p, ctx); if (Legendre (uxxA, ctx) != -1) - { + { + uint8_t randByte; // random highest bits and high y + RAND_bytes (&randByte, 1); + bool highY = randByte & 0x01; + BIGNUM * r = BN_CTX_get (ctx); if (highY) { @@ -78,6 +83,7 @@ namespace crypto SquareRoot (r, r, ctx); bn2buf (r, encoded, 32); + encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = encoded[i]; @@ -105,6 +111,7 @@ namespace crypto encoded1[i] = encoded[31 - i]; encoded1[31 - i] = encoded[i]; } + encoded1[0] &= 0x3F; // drop two highest bits BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index ca463568..6f9eaf2a 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -17,7 +17,7 @@ namespace crypto Elligator2 (); ~Elligator2 (); - bool Encode (const uint8_t * key, uint8_t * encoded, bool highY = false) const; + bool Encode (const uint8_t * key, uint8_t * encoded) const; bool Decode (const uint8_t * encoded, uint8_t * key) const; private: From ccec3376ba0be9621306593c90986a546d14104e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 12:19:20 -0500 Subject: [PATCH 0174/2950] try another ephemeral keys if elligator encoding failes --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 19 ++++++++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7548603c..1dacdfcc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -58,6 +58,17 @@ namespace garlic SHA256_Final (m_H, &ctx); } + bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) + { + for (int i = 0; i < 5; i++) + { + m_EphemeralKeys.GenerateKeys (); + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) + return true; // success + } + return false; + } + bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { if (!GetOwner ()) return false; @@ -152,11 +163,10 @@ namespace garlic } bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - m_EphemeralKeys.GenerateKeys (); + { // we are Alice, bpk is m_RemoteStaticKey size_t offset = 0; - if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) + if (!GenerateEphemeralKeysAndEncode (out + offset)) { LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; @@ -195,7 +205,6 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { - m_EphemeralKeys.GenerateKeys (); // we are Bob uint8_t tagsetKey[32]; i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) @@ -209,7 +218,7 @@ namespace garlic size_t offset = 0; memcpy (out + offset, tag, 8); offset += 8; - if (!i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), out + offset)) // bepk + if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk { LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index b449c0e5..32a9a89f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -61,6 +61,7 @@ namespace garlic private: void MixHash (const uint8_t * buf, size_t len); + bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); From 6142e9325293f60614511d6886c65f8ebc13a805 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 14:40:23 -0500 Subject: [PATCH 0175/2950] session tag for ECIESx25519 sessions --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 51 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 19 +++++++-- libi2pd/Garlic.cpp | 33 ++++++++++++--- libi2pd/Garlic.h | 4 +- 4 files changed, 79 insertions(+), 28 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 1dacdfcc..e3f3d974 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -18,20 +18,20 @@ namespace garlic uint8_t keydata[64]; i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64) // nextRootKey = keydata[0:31] - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_CK); - // ck = [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf); + // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) } void RatchetTagSet::NextSessionTagRatchet () { - i2p::crypto::HKDF (m_CK, nullptr, 0, "STInitialization", m_CK); // [ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64) - memcpy (m_SessTagConstant, m_CK + 32, 32); + 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); } - const uint8_t * RatchetTagSet::GetNextSessionTag () + uint64_t RatchetTagSet::GetNextSessionTag () { - i2p::crypto::HKDF (m_CK, m_SessTagConstant, 32, "SessionTagKeyGen", m_CK); // [ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) - return m_CK + 32; + 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 (); } @@ -60,7 +60,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) { - for (int i = 0; i < 5; i++) + for (int i = 0; i < 10; i++) { m_EphemeralKeys.GenerateKeys (); if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) @@ -69,6 +69,17 @@ namespace garlic return false; } + uint64_t ECIESX25519AEADRatchetSession::CreateNewSessionTag () const + { + uint8_t tagsetKey[32]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) + // Session Tag Ratchet + RatchetTagSet tagsetNsr; + tagsetNsr.DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) + tagsetNsr.NextSessionTagRatchet (); + return tagsetNsr.GetNextSessionTag (); + } + bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { if (!GetOwner ()) return false; @@ -199,24 +210,20 @@ namespace garlic return false; } MixHash (out + offset, 16); // h = SHA256(h || ciphertext) - + + if (GetOwner ()) + GetOwner ()->AddECIESx25519SessionTag (CreateNewSessionTag (), shared_from_this ()); + return true; } bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob - uint8_t tagsetKey[32]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) - - // Session Tag Ratchet - RatchetTagSet tagsetNsr; - tagsetNsr.DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) - tagsetNsr.NextSessionTagRatchet (); - auto tag = tagsetNsr.GetNextSessionTag (); + uint64_t tag = CreateNewSessionTag (); size_t offset = 0; - memcpy (out + offset, tag, 8); + memcpy (out + offset, &tag, 8); offset += 8; if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk { @@ -225,7 +232,7 @@ namespace garlic } offset += 32; // KDF for Reply Key Section - MixHash (tag, 8); // h = SHA256(h || tag) + MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, aepk) @@ -257,6 +264,12 @@ namespace garlic return true; } + bool ECIESX25519AEADRatchetSession::NewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove) + { + // TODO + return true; + } + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { auto m = NewI2NPMessage (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 32a9a89f..829f0517 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "Identity.h" #include "Crypto.h" @@ -19,11 +20,21 @@ namespace garlic void DHInitialize (const uint8_t * rootKey, const uint8_t * k); void NextSessionTagRatchet (); - const uint8_t * GetNextSessionTag (); + uint64_t GetNextSessionTag (); private: + + union + { + uint64_t ll[8]; + uint8_t buf[64]; - uint8_t m_CK[64], m_SessTagConstant[32]; + 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; + uint8_t m_SessTagConstant[32]; }; enum ECIESx25519BlockType @@ -37,7 +48,7 @@ namespace garlic eECIESx25519BlkPadding = 254 }; - class ECIESX25519AEADRatchetSession: public GarlicRoutingSession + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { enum SessionState { @@ -55,6 +66,7 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); bool NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); + bool NewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -62,6 +74,7 @@ namespace garlic void MixHash (const uint8_t * buf, size_t len); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes + uint64_t CreateNewSessionTag () const; void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index fc8a4f01..4e9f3d2c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -861,14 +861,32 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - auto session = std::make_shared (this); - if (session->NewIncomingSession (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, - this, std::placeholders::_1, std::placeholders::_2))) + auto handleClove = std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2); + uint64_t tag; + memcpy (&tag, buf, 8); + auto it = m_ECIESx25519Tags.find (tag); + if (it != m_ECIESx25519Tags.end ()) { - m_ECIESx25519Sessions.emplace (session->GetRemoteStaticKey (), session); + // TODO + auto session = it->second; + if (!session->NewOutgoingSessionReply (buf, len, handleClove)) + { + LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session reply"); + m_ECIESx25519Tags.erase (tag); + m_ECIESx25519Sessions.erase (session->GetRemoteStaticKey ()); + } } else - LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); + { + auto session = std::make_shared (this); + if (session->NewIncomingSession (buf, len, handleClove)) + { + m_ECIESx25519Sessions.emplace (session->GetRemoteStaticKey (), session); + } + else + LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); + } } void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) @@ -926,5 +944,10 @@ namespace garlic LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); } } + + void GarlicDestination::AddECIESx25519SessionTag (uint64_t tag, ECIESX25519AEADRatchetSessionPtr session) + { + m_ECIESx25519Tags.emplace (tag, session); + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 727b4a8d..fa37bf66 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -217,6 +217,7 @@ namespace garlic void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); + void AddECIESx25519SessionTag (uint64_t tag, ECIESX25519AEADRatchetSessionPtr session); virtual void ProcessGarlicMessage (std::shared_ptr msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); @@ -252,9 +253,10 @@ namespace garlic int m_NumTags; std::mutex m_SessionsMutex; std::map m_Sessions; - std::map, ECIESX25519AEADRatchetSessionPtr > m_ECIESx25519Sessions; // static key -> session + std::map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming std::map > m_Tags; + std::map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::map m_DeliveryStatusSessions; // msgID -> session From 0d2d7e5e716ab0a1a9da1b1595890a43444b561b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 17:53:48 -0500 Subject: [PATCH 0176/2950] fixed Elligator tests --- libi2pd/Elligator.cpp | 18 +++++++++++------- libi2pd/Elligator.h | 2 +- tests/test-elligator.cpp | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index bd9c382f..48a5a7ac 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -40,7 +40,7 @@ namespace crypto BN_free (u); BN_free (iu); } - bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded) const + bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY, bool random) const { bool ret = true; BN_CTX * ctx = BN_CTX_new (); @@ -63,10 +63,13 @@ namespace crypto if (Legendre (uxxA, ctx) != -1) { - uint8_t randByte; // random highest bits and high y - RAND_bytes (&randByte, 1); - bool highY = randByte & 0x01; - + uint8_t randByte = 0; // random highest bits and high y + if (random) + { + RAND_bytes (&randByte, 1); + highY = randByte & 0x01; + } + BIGNUM * r = BN_CTX_get (ctx); if (highY) { @@ -82,8 +85,9 @@ namespace crypto SquareRoot (r, r, ctx); bn2buf (r, encoded, 32); - - encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte + + if (random) + encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = encoded[i]; diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 6f9eaf2a..7cdcbbfe 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -17,7 +17,7 @@ namespace crypto Elligator2 (); ~Elligator2 (); - bool Encode (const uint8_t * key, uint8_t * encoded) const; + bool Encode (const uint8_t * key, uint8_t * encoded, bool highY = false, bool random = true) const; bool Decode (const uint8_t * encoded, uint8_t * key) const; private: diff --git a/tests/test-elligator.cpp b/tests/test-elligator.cpp index e73eb8ab..48c9e31a 100644 --- a/tests/test-elligator.cpp +++ b/tests/test-elligator.cpp @@ -69,9 +69,9 @@ int main () uint8_t buf[32]; i2p::crypto::Elligator2 el; // encoding tests - el.Encode (key, buf); + el.Encode (key, buf, false, false); assert(memcmp (buf, encoded_key, 32) == 0); - el.Encode (key, buf, true); // with highY + el.Encode (key, buf, true, false); // with highY assert(memcmp (buf, encoded_key_high_y, 32) == 0); // decoding tests el.Decode (encoded1, buf); From 2b2bd733e9c9e63cd649324b358ca88c93ebad5e Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 19:13:23 -0500 Subject: [PATCH 0177/2950] correct sharedkey for new outgoing session --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index e3f3d974..ece3ec1e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -188,7 +188,7 @@ namespace garlic MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, nullptr); // x25519(aesk, bpk) + m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt static key section uint8_t nonce[12]; From 09c6c2a4f36dbdbc2b77400b404819780587091f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Jan 2020 21:09:19 -0500 Subject: [PATCH 0178/2950] decode aepk and bepk back --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index ece3ec1e..624a2f7f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -181,12 +181,14 @@ namespace garlic { LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; - } + } + uint8_t aepk[32]; + i2p::crypto::GetElligator ()->Decode (out + offset, aepk); // decode back for h offset += 32; // KDF1 MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) + MixHash (aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) @@ -229,11 +231,13 @@ namespace garlic { LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; - } + } + uint8_t bepk[32]; + i2p::crypto::GetElligator ()->Decode (out + offset, bepk); // decode back for h offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (bepk, 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) From 928b90d5bc104ae56136962f7f2dbbd99c202385 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jan 2020 09:50:50 -0500 Subject: [PATCH 0179/2950] fixed #1461. Use openssl's HKDF for 1.1.1 anf higher --- libi2pd/Crypto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 33490c8a..2a0a8427 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -27,8 +27,8 @@ # define X509_getm_notAfter X509_get_notAfter #else # define LEGACY_OPENSSL 0 -# define OPENSSL_HKDF 1 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 +# define OPENSSL_HKDF 1 # define OPENSSL_EDDSA 1 # define OPENSSL_X25519 1 # define OPENSSL_SIPHASH 1 From 76f95644b7985c11f713cb48482aee32008887de Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jan 2020 09:59:08 -0500 Subject: [PATCH 0180/2950] fixed #1461. Use openssl's HKDF for 1.1.1 anf higher --- libi2pd/Crypto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 2a0a8427..32410daf 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -28,7 +28,7 @@ #else # define LEGACY_OPENSSL 0 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 -# define OPENSSL_HKDF 1 +# define OPENSSL_HKDF 1 # define OPENSSL_EDDSA 1 # define OPENSSL_X25519 1 # define OPENSSL_SIPHASH 1 From 7c212bef63358cb3780ee16b38526b009011c86d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jan 2020 11:27:47 -0500 Subject: [PATCH 0181/2950] add new session to the list after reply received --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++-------- libi2pd/Garlic.cpp | 5 +++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 624a2f7f..74443e5e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -181,14 +181,12 @@ namespace garlic { LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; - } - uint8_t aepk[32]; - i2p::crypto::GetElligator ()->Decode (out + offset, aepk); // decode back for h + } offset += 32; // KDF1 MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) - MixHash (aepk, 32); // h = SHA256(h || aepk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) @@ -231,13 +229,11 @@ namespace garlic { LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; - } - uint8_t bepk[32]; - i2p::crypto::GetElligator ()->Decode (out + offset, bepk); // decode back for h + } offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (bepk, 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 4e9f3d2c..833817f7 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -668,7 +668,6 @@ namespace garlic { session = std::make_shared (this); session->SetRemoteStaticKey (staticKey); - m_ECIESx25519Sessions.emplace (staticKey, session); } return session; } @@ -870,7 +869,9 @@ namespace garlic { // TODO auto session = it->second; - if (!session->NewOutgoingSessionReply (buf, len, handleClove)) + if (session->NewOutgoingSessionReply (buf, len, handleClove)) + m_ECIESx25519Sessions.emplace (session->GetRemoteStaticKey (), session); + else { LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session reply"); m_ECIESx25519Tags.erase (tag); From 34295adb05f10386fad0f72ab4b925091c314533 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jan 2020 14:26:47 -0500 Subject: [PATCH 0182/2950] attach LeaseSet clove --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 40 ++++++++++++++++------- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 74443e5e..285eaa7e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -302,18 +302,36 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - std::vector v(cloveSize + 3); - uint8_t * payload = v.data (); - payload[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (payload + 1, cloveSize); // size - payload[3] = 0; // flag and delivery instructions - payload[4] = msg->GetTypeID (); // I2NP msg type - htobe32buf (payload + 5, msg->GetMsgID ()); // msgID - htobe32buf (payload + 9, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (payload + 13, msg->GetPayload (), msg->GetPayloadLength ()); + size_t payloadLen = 0; + if (payloadLen) + payloadLen += msg->GetPayloadLength () + 13; + auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); + if (leaseSet) + payloadLen += leaseSet->GetPayloadLength () + 13; + std::vector v(payloadLen); + size_t offset = 0; + if (leaseSet) + offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); + if (msg) + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); return v; - } + } + + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) + { + if (!msg) return 0; + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + if ((int)len < cloveSize + 3) return 0; + buf[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (buf + 1, cloveSize); // size + buf[3] = 0; // flag and delivery instructions + buf[4] = msg->GetTypeID (); // I2NP msg type + htobe32buf (buf + 5, msg->GetMsgID ()); // msgID + htobe32buf (buf + 9, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (buf + 13, msg->GetPayload (), msg->GetPayloadLength ()); + return cloveSize + 3; + } + } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 829f0517..05dfc961 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -81,6 +81,7 @@ namespace garlic bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); std::vector CreatePayload (std::shared_ptr msg); + size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); private: From 205e807b6645466018d13b769e5f7604784daf4e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jan 2020 21:42:30 -0500 Subject: [PATCH 0183/2950] reset keys --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 ++++++++++++++------- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 285eaa7e..1276ef3e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -38,17 +38,22 @@ namespace garlic ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): GarlicRoutingSession (owner, true) { - // TODO : use precalculated hashes - static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes - SHA256 ((const uint8_t *)protocolName, 40, m_H); - memcpy (m_CK, m_H, 32); - SHA256 (m_H, 32, m_H); + ResetKeys (); } ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () { } + void ECIESX25519AEADRatchetSession::ResetKeys () + { + // TODO : use precalculated hashes + static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes + SHA256 ((const uint8_t *)protocolName, 40, m_H); + memcpy (m_CK, m_H, 32); + SHA256 (m_H, 32, m_H); + } + void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) { SHA256_CTX ctx; @@ -175,6 +180,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { + ResetKeys (); // we are Alice, bpk is m_RemoteStaticKey size_t offset = 0; if (!GenerateEphemeralKeysAndEncode (out + offset)) @@ -266,7 +272,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove) { - // TODO + // TODO + LogPrint (eLogDebug, "Garlic: reply received"); return true; } @@ -303,7 +310,7 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { size_t payloadLen = 0; - if (payloadLen) + if (msg) payloadLen += msg->GetPayloadLength () + 13; auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); if (leaseSet) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 05dfc961..5777885b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -72,6 +72,7 @@ namespace garlic private: + void ResetKeys (); void MixHash (const uint8_t * buf, size_t len); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes uint64_t CreateNewSessionTag () const; From fd1ee48dbe7e41ab15448f1369d2f9802a5a0778 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Jan 2020 14:26:40 -0500 Subject: [PATCH 0184/2950] datetime and padding blocks --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 1276ef3e..29171584 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -5,6 +5,7 @@ #include "Elligator.h" #include "Tag.h" #include "I2PEndian.h" +#include "Timestamp.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -309,18 +310,32 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { - size_t payloadLen = 0; + size_t payloadLen = 7; // datatime if (msg) payloadLen += msg->GetPayloadLength () + 13; auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); if (leaseSet) - payloadLen += leaseSet->GetPayloadLength () + 13; + payloadLen += leaseSet->GetPayloadLength () + 13; + uint8_t paddingSize; + RAND_bytes (&paddingSize, 1); + paddingSize &= 0x0F; paddingSize++; // 1 - 16 + payloadLen += paddingSize; std::vector v(payloadLen); size_t offset = 0; + // DateTime + v[offset] = eECIESx25519BlkDateTime; offset++; + htobe16buf (v.data () + offset, 4); offset += 2; + htobe32buf (v.data () + offset, i2p::util::GetSecondsSinceEpoch ()); offset += 4; + // LeaseSet if (leaseSet) offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); + // msg if (msg) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); + // padding + v[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (v.data () + offset, paddingSize); offset += 2; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; return v; } From 77440c235d24988720009c1bf1d30462ccae5900 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Jan 2020 10:03:51 -0500 Subject: [PATCH 0185/2950] replaced map by unordered_map --- libi2pd/Garlic.h | 12 ++++++------ libi2pd/Tag.h | 12 ++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index fa37bf66..e3b090cb 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -2,7 +2,7 @@ #define GARLIC_H__ #include -#include +#include #include #include #include @@ -252,14 +252,14 @@ namespace garlic // outgoing sessions int m_NumTags; std::mutex m_SessionsMutex; - std::map m_Sessions; - std::map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session + std::unordered_map m_Sessions; + std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming - std::map > m_Tags; - std::map m_ECIESx25519Tags; // session tag -> session + std::unordered_map > m_Tags; + std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; - std::map m_DeliveryStatusSessions; // msgID -> session + std::unordered_map m_DeliveryStatusSessions; // msgID -> session public: diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index 8af82241..010b160f 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -93,4 +93,16 @@ private: } // data } // i2p +namespace std +{ + // hash for std::unordered_map + template struct hash > + { + size_t operator()(const i2p::data::Tag& s) const + { + return s.GetLL ()[0]; + } + }; +} + #endif /* TAG_H__ */ From abe668f1c32d76fce2bb59e52dde52996e283f81 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Jan 2020 10:31:35 -0500 Subject: [PATCH 0186/2950] fixed build error --- libi2pd/Garlic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index e3b090cb..08bbfc5b 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -255,7 +255,7 @@ namespace garlic std::unordered_map m_Sessions; std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming - std::unordered_map > m_Tags; + std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; From a1dbec0fcbea8dafb9e7b4e123b028f3cc5d4f6e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jan 2020 12:54:26 -0500 Subject: [PATCH 0187/2950] handle new session reply --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 47 ++++++++++++++++++++++- libi2pd/Garlic.cpp | 21 +++++----- libi2pd/Garlic.h | 1 + 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 29171584..3a732876 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -137,6 +137,7 @@ namespace garlic } if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) m_State = eSessionStateNewSessionReceived; + GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); HandlePayload (payload.data (), len - 16, handleClove); @@ -273,8 +274,52 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove) { - // TODO + // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); + const uint8_t * tag = buf; + buf += 8; len -= 8; // tag + uint8_t bepk[32]; // Bob's ephemeral key + if (!i2p::crypto::GetElligator ()->Decode (buf, bepk)) + { + LogPrint (eLogError, "Garlic: Can't decode elligator"); + return false; + } + buf += 32; len -= 32; + // KDF for Reply Key Section + MixHash (tag, 8); // h = SHA256(h || tag) + MixHash (bepk, 32); // h = SHA256(h || bepk) + uint8_t sharedSecret[32]; + m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + // calulate hash for zero length + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anyting */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only + { + LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed"); + return false; + } + MixHash (buf, 16); // h = SHA256(h || ciphertext) + buf += 16; len -= 16; + // KDF for payload + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + // k_ab = keydata[0:31], k_ba = keydata[32:63] + m_TagsetAB.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_TagsetBA.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + // decrypt payload + std::vector payload (len - 16); + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, payload.data (), len - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); + return false; + } + + // TODO: change state + GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); + HandlePayload (payload.data (), len - 16, handleClove); + return true; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 833817f7..b6a870f0 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -869,23 +869,14 @@ namespace garlic { // TODO auto session = it->second; - if (session->NewOutgoingSessionReply (buf, len, handleClove)) - m_ECIESx25519Sessions.emplace (session->GetRemoteStaticKey (), session); - else - { + if (!session->NewOutgoingSessionReply (buf, len, handleClove)) LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session reply"); - m_ECIESx25519Tags.erase (tag); - m_ECIESx25519Sessions.erase (session->GetRemoteStaticKey ()); - } + m_ECIESx25519Tags.erase (tag); } else { auto session = std::make_shared (this); - if (session->NewIncomingSession (buf, len, handleClove)) - { - m_ECIESx25519Sessions.emplace (session->GetRemoteStaticKey (), session); - } - else + if (!session->NewIncomingSession (buf, len, handleClove)) LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); } } @@ -950,5 +941,11 @@ namespace garlic { m_ECIESx25519Tags.emplace (tag, session); } + + void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) + { + m_ECIESx25519Sessions.emplace (staticKey, session); + } + } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 08bbfc5b..4e66f75f 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -218,6 +218,7 @@ namespace garlic virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); void AddECIESx25519SessionTag (uint64_t tag, ECIESX25519AEADRatchetSessionPtr session); + void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); virtual void ProcessGarlicMessage (std::shared_ptr msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); From 48fa10b080168d1a8f6cdde05fdfa628b1f418c0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jan 2020 15:54:11 -0500 Subject: [PATCH 0188/2950] incoming ECIESX25519AEADRatchet messages hanler --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 19 +++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 8 +++++--- libi2pd/Garlic.cpp | 23 ++++++++++------------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 3a732876..ffda9191 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -86,7 +86,7 @@ namespace garlic return tagsetNsr.GetNextSessionTag (); } - bool ECIESX25519AEADRatchetSession::NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) + bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) { if (!GetOwner ()) return false; // we are Bob @@ -219,6 +219,7 @@ namespace garlic } MixHash (out + offset, 16); // h = SHA256(h || ciphertext) + m_State = eSessionStateNewSessionSent; if (GetOwner ()) GetOwner ()->AddECIESx25519SessionTag (CreateNewSessionTag (), shared_from_this ()); @@ -272,7 +273,7 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::NewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove) + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove) { // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); @@ -323,6 +324,20 @@ namespace garlic return true; } + bool ECIESX25519AEADRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len, CloveHandler handleClove) + { + switch (m_State) + { + case eSessionStateNew: + return HandleNewIncomingSession (buf, len, handleClove); + case eSessionStateNewSessionSent: + return HandleNewOutgoingSessionReply (buf, len, handleClove); + default: + return false; + } + return true; + } + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { auto m = NewI2NPMessage (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 5777885b..b8988f6e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -53,7 +53,8 @@ namespace garlic enum SessionState { eSessionStateNew =0, - eSessionStateNewSessionReceived + eSessionStateNewSessionReceived, + eSessionStateNewSessionSent }; public: @@ -63,10 +64,9 @@ namespace garlic ECIESX25519AEADRatchetSession (GarlicDestination * owner); ~ECIESX25519AEADRatchetSession (); + bool HandleNextMessage (const uint8_t * buf, size_t len, CloveHandler handleClove); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - bool NewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); - bool NewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -77,6 +77,8 @@ namespace garlic bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes uint64_t CreateNewSessionTag () const; + bool HandleNewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); + bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove); void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index b6a870f0..69ca0335 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -864,21 +864,18 @@ namespace garlic this, std::placeholders::_1, std::placeholders::_2); uint64_t tag; memcpy (&tag, buf, 8); + ECIESX25519AEADRatchetSessionPtr session; auto it = m_ECIESx25519Tags.find (tag); if (it != m_ECIESx25519Tags.end ()) - { - // TODO - auto session = it->second; - if (!session->NewOutgoingSessionReply (buf, len, handleClove)) - LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session reply"); - m_ECIESx25519Tags.erase (tag); - } - else - { - auto session = std::make_shared (this); - if (!session->NewIncomingSession (buf, len, handleClove)) - LogPrint (eLogError, "Garlic: can't decrypt ECIES-X25519-AEAD-Ratchet new session"); - } + { + session = it->second; + m_ECIESx25519Tags.erase (tag); + } + else + session = std::make_shared (this); // incoming + + if (!session->HandleNextMessage (buf, len, handleClove)) + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); } void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) From cdd068d99aef58a32c155597218d54ba77e84cdf Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jan 2020 19:27:38 -0500 Subject: [PATCH 0189/2950] correct message size --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index ffda9191..b6820482 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -379,7 +379,7 @@ namespace garlic uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize; + payloadLen += paddingSize + 3; std::vector v(payloadLen); size_t offset = 0; // DateTime @@ -395,7 +395,7 @@ namespace garlic // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; return v; } From 8c800dc178109807863a0751ef6f012a8c658002 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jan 2020 21:57:10 -0500 Subject: [PATCH 0190/2950] save aepk from new session message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 13 ++++++------- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b6820482..154bec98 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -92,18 +92,17 @@ namespace garlic // we are Bob // KDF1 MixHash (GetOwner ()->GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk) - - uint8_t aepk[32]; // Alice's ephemeral key - if (!i2p::crypto::GetElligator ()->Decode (buf, aepk)) + + if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { LogPrint (eLogError, "Garlic: Can't decode elligator"); return false; } buf += 32; len -= 32; - MixHash (aepk, 32); // h = SHA256(h || aepk) + MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (aepk, sharedSecret, nullptr); // x25519(bsk, aepk) + GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // decrypt flags/static @@ -217,7 +216,7 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; } - MixHash (out + offset, 16); // h = SHA256(h || ciphertext) + MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) m_State = eSessionStateNewSessionSent; if (GetOwner ()) @@ -244,7 +243,7 @@ namespace garlic MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, aepk) + m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index b8988f6e..f5cef114 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -89,6 +89,7 @@ namespace garlic private: uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; + uint8_t m_Aepk[32]; // Alice's ephemeral keys TODO: for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; RatchetTagSet m_TagsetAB, m_TagsetBA; From 239c8b51720fc1a108b9dd2273c22bc465c0bd8a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Jan 2020 11:48:32 -0500 Subject: [PATCH 0191/2950] destination delivery instructions --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 31 +++++++++++++++-------- libi2pd/ECIESX25519AEADRatchetSession.h | 8 +++++- libi2pd/Garlic.cpp | 6 ++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 154bec98..b8ddf577 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -370,8 +370,8 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { size_t payloadLen = 7; // datatime - if (msg) - payloadLen += msg->GetPayloadLength () + 13; + if (msg && m_Destination) + payloadLen += msg->GetPayloadLength () + 13 + 32; auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); if (leaseSet) payloadLen += leaseSet->GetPayloadLength () + 13; @@ -389,8 +389,8 @@ namespace garlic if (leaseSet) offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); // msg - if (msg) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); + if (msg && m_Destination) + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; @@ -398,18 +398,27 @@ namespace garlic return v; } - size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) { if (!msg) return 0; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + if (isDestination) cloveSize += 32; if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (buf + 1, cloveSize); // size - buf[3] = 0; // flag and delivery instructions - buf[4] = msg->GetTypeID (); // I2NP msg type - htobe32buf (buf + 5, msg->GetMsgID ()); // msgID - htobe32buf (buf + 9, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (buf + 13, msg->GetPayload (), msg->GetPayloadLength ()); + htobe16buf (buf + 1, cloveSize); // size + buf += 3; + if (isDestination) + { + *buf = (eGarlicDeliveryTypeDestination << 5); + memcpy (buf + 1, *m_Destination, 32); buf += 32; + } + else + *buf = 0; + buf++; // flag and delivery instructions + *buf = msg->GetTypeID (); // I2NP msg type + htobe32buf (buf + 1, msg->GetMsgID ()); // msgID + htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); return cloveSize + 3; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index f5cef114..ebe8cf13 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -70,6 +70,11 @@ namespace garlic const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } + void SetDestination (const i2p::data::IdentHash& dest) // TODO: + { + if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); + } + private: void ResetKeys (); @@ -84,7 +89,7 @@ namespace garlic bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); std::vector CreatePayload (std::shared_ptr msg); - size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len); + size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); private: @@ -93,6 +98,7 @@ namespace garlic i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; RatchetTagSet m_TagsetAB, m_TagsetBA; + std::unique_ptr m_Destination;// TODO: might not need it }; } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 69ca0335..1b34f99c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -669,6 +669,7 @@ namespace garlic session = std::make_shared (this); session->SetRemoteStaticKey (staticKey); } + session->SetDestination (destination->GetIdentHash ()); // TODO: remove return session; } else @@ -860,8 +861,6 @@ namespace garlic void GarlicDestination::HandleECIESx25519 (const uint8_t * buf, size_t len) { - auto handleClove = std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, - this, std::placeholders::_1, std::placeholders::_2); uint64_t tag; memcpy (&tag, buf, 8); ECIESX25519AEADRatchetSessionPtr session; @@ -874,7 +873,8 @@ namespace garlic else session = std::make_shared (this); // incoming - if (!session->HandleNextMessage (buf, len, handleClove)) + if (!session->HandleNextMessage (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, + this, std::placeholders::_1, std::placeholders::_2))) LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); } From 85b88b874915dc97bca2470c9dd032276d4b72c4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Jan 2020 19:30:30 -0500 Subject: [PATCH 0192/2950] second x25519 for new session reply --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b8ddf577..11e7edad 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -244,8 +244,10 @@ namespace garlic MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - uint8_t nonce[12]; + uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 // calulate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (sharedSecret /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) @@ -290,8 +292,10 @@ namespace garlic MixHash (bepk, 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - uint8_t nonce[12]; + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr); // x25519 (ask, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + uint8_t nonce[12]; memset (nonce, 0, 12); // n = 0 // calulate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anyting */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only From 49810eb15351d11d3f2a20d47c32d4a78cbbcb8a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 2 Feb 2020 17:05:30 -0500 Subject: [PATCH 0193/2950] common RunnableService --- libi2pd/NTCP2.cpp | 49 +++++++++++------------------------------------ libi2pd/NTCP2.h | 13 ++----------- libi2pd/util.cpp | 39 +++++++++++++++++++++++++++++++++++++ libi2pd/util.h | 38 ++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 49 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 664b917b..e79be97a 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1,12 +1,10 @@ /* -* Copyright (c) 2013-2018, The PurpleI2P Project +* 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 * -* Kovri go write your own code -* */ #include @@ -1143,8 +1141,8 @@ namespace transport } NTCP2Server::NTCP2Server (): - m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), - m_TerminationTimer (m_Service) + RunnableServiceWithWork ("NTCP2"), + m_TerminationTimer (GetService ()) { } @@ -1155,10 +1153,9 @@ namespace transport void NTCP2Server::Start () { - if (!m_IsRunning) + if (!IsRunning ()) { - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&NTCP2Server::Run, this)); + StartService (); auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address: addresses) { @@ -1169,7 +1166,7 @@ namespace transport { try { - m_NTCP2Acceptor.reset (new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port))); + m_NTCP2Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port))); } catch ( std::exception & ex ) { @@ -1183,7 +1180,7 @@ namespace transport } else if (address->host.is_v6() && context.SupportsV6 ()) { - m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (m_Service)); + m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ())); try { m_NTCP2V6Acceptor->open (boost::asio::ip::tcp::v6()); @@ -1218,33 +1215,9 @@ namespace transport } m_NTCP2Sessions.clear (); - if (m_IsRunning) - { - m_IsRunning = false; + if (IsRunning ()) m_TerminationTimer.cancel (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - } - - void NTCP2Server::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "NTCP2: runtime exception: ", ex.what ()); - } - } + StopService (); } bool NTCP2Server::AddNTCP2Session (std::shared_ptr session, bool incoming) @@ -1282,11 +1255,11 @@ namespace transport void NTCP2Server::Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn) { LogPrint (eLogDebug, "NTCP2: Connecting to ", address ,":", port); - m_Service.post([this, address, port, conn]() + GetService ().post([this, address, port, conn]() { if (this->AddNTCP2Session (conn)) { - auto timer = std::make_shared(m_Service); + auto timer = std::make_shared(GetService ()); auto timeout = NTCP2_CONNECT_TIMEOUT * 5; conn->SetTerminationTimeout(timeout * 2); timer->expires_from_now (boost::posix_time::seconds(timeout)); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 93f6a1cc..a63b86b8 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -1,12 +1,10 @@ /* -* Copyright (c) 2013-2018, The PurpleI2P Project +* 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 * -* Kovri go write your own code -* */ #ifndef NTCP2_H__ #define NTCP2_H__ @@ -218,7 +216,7 @@ namespace transport std::list > m_SendQueue; }; - class NTCP2Server + class NTCP2Server: public i2p::util::RunnableServiceWithWork { public: @@ -231,14 +229,11 @@ namespace transport bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); void RemoveNTCP2Session (std::shared_ptr session); std::shared_ptr FindNTCP2Session (const i2p::data::IdentHash& ident); - - boost::asio::io_service& GetService () { return m_Service; }; void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn); private: - void Run (); void HandleAccept (std::shared_ptr conn, const boost::system::error_code& error); void HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error); @@ -250,10 +245,6 @@ namespace transport private: - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; - boost::asio::io_service::work m_Work; boost::asio::deadline_timer m_TerminationTimer; std::unique_ptr m_NTCP2Acceptor, m_NTCP2V6Acceptor; std::map > m_NTCP2Sessions; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 448d1307..6ae9fa6b 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -57,6 +57,45 @@ namespace i2p { namespace util { + + void RunnableService::StartService () + { + if (!m_IsRunning) + { + m_IsRunning = true; + m_Thread.reset (new std::thread (std::bind (& RunnableService::Run, this))); + } + } + + void RunnableService::StopService () + { + if (m_IsRunning) + { + m_IsRunning = false; + m_Service.stop (); + if (m_Thread) + { + m_Thread->join (); + m_Thread = nullptr; + } + } + } + + void RunnableService::Run () + { + while (m_IsRunning) + { + try + { + m_Service.run (); + } + catch (std::exception& ex) + { + LogPrint (eLogError, m_Name, ": runtime exception: ", ex.what ()); + } + } + } + namespace net { #ifdef WIN32 diff --git a/libi2pd/util.h b/libi2pd/util.h index eccdadf7..830a984d 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -122,6 +123,43 @@ namespace util std::mutex m_Mutex; }; + class RunnableService + { + public: + + RunnableService (const std::string& name): m_Name (name), m_IsRunning (false) {} + virtual ~RunnableService () {} + + boost::asio::io_service& GetService () { return m_Service; } + bool IsRunning () const { return m_IsRunning; }; + + void StartService (); + void StopService (); + + private: + + void Run (); + + private: + + std::string m_Name; + bool m_IsRunning; + std::unique_ptr m_Thread; + boost::asio::io_service m_Service; + }; + + class RunnableServiceWithWork: public RunnableService + { + public: + + RunnableServiceWithWork (const std::string& name): + RunnableService (name), m_Work (GetService ()) {} + + private: + + boost::asio::io_service::work m_Work; + }; + namespace net { int GetMTU (const boost::asio::ip::address& localAddress); From 2d154ee640fa4028e669a031c312d362ab2e5c78 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 2 Feb 2020 18:58:58 -0500 Subject: [PATCH 0194/2950] move RunnableService away from LeaseSetDestination --- libi2pd/Destination.cpp | 108 ++++++++------------------ libi2pd/Destination.h | 20 ++--- libi2pd/util.h | 2 +- libi2pd_client/I2CP.cpp | 27 ++++++- libi2pd_client/I2CP.h | 9 ++- libi2pd_client/MatchedDestination.cpp | 28 +++---- libi2pd_client/MatchedDestination.h | 4 +- 7 files changed, 87 insertions(+), 111 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ba74f61f..835c8e52 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -7,15 +7,15 @@ #include "Timestamp.h" #include "NetDb.hpp" #include "Destination.h" -#include "util.h" namespace i2p { namespace client { - LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map * params): - m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), - m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), + LeaseSetDestination::LeaseSetDestination (boost::asio::io_service& service, + bool isPublic, const std::map * params): + m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0), + m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), m_LeaseSetType (DEFAULT_LEASESET_TYPE), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) { @@ -123,77 +123,36 @@ namespace client LeaseSetDestination::~LeaseSetDestination () { - if (m_IsRunning) - Stop (); if (m_Pool) i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); for (auto& it: m_LeaseSetRequests) it.second->Complete (nullptr); } - void LeaseSetDestination::Run () + void LeaseSetDestination::Start () { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "Destination: runtime exception: ", ex.what ()); - } - } + if (m_Nickname.empty ()) + m_Nickname = i2p::data::GetIdentHashAbbreviation (GetIdentHash ()); // set default nickname + LoadTags (); + m_Pool->SetLocalDestination (shared_from_this ()); + m_Pool->SetActive (true); + m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT)); + m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, + shared_from_this (), std::placeholders::_1)); } - bool LeaseSetDestination::Start () + void LeaseSetDestination::Stop () { - if (!m_IsRunning) + m_CleanupTimer.cancel (); + m_PublishConfirmationTimer.cancel (); + m_PublishVerificationTimer.cancel (); + if (m_Pool) { - if (m_Nickname.empty ()) - m_Nickname = i2p::data::GetIdentHashAbbreviation (GetIdentHash ()); // set default nickname - LoadTags (); - m_IsRunning = true; - m_Pool->SetLocalDestination (shared_from_this ()); - m_Pool->SetActive (true); - m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT)); - m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, - shared_from_this (), std::placeholders::_1)); - m_Thread = new std::thread (std::bind (&LeaseSetDestination::Run, shared_from_this ())); - - return true; + m_Pool->SetLocalDestination (nullptr); + i2p::tunnel::tunnels.StopTunnelPool (m_Pool); } - else - return false; - } - - bool LeaseSetDestination::Stop () - { - if (m_IsRunning) - { - m_CleanupTimer.cancel (); - m_PublishConfirmationTimer.cancel (); - m_PublishVerificationTimer.cancel (); - - m_IsRunning = false; - if (m_Pool) - { - m_Pool->SetLocalDestination (nullptr); - i2p::tunnel::tunnels.StopTunnelPool (m_Pool); - } - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = 0; - } - SaveTags (); - CleanUp (); // GarlicDestination - return true; - } - else - return false; + SaveTags (); + CleanUp (); // GarlicDestination } bool LeaseSetDestination::Reconfigure(std::map params) @@ -864,7 +823,8 @@ namespace client } ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - LeaseSetDestination (isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + RunnableService ("Destination"), LeaseSetDestination (GetService (), isPublic, params), + m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) { @@ -932,26 +892,28 @@ namespace client ClientDestination::~ClientDestination () { + if (IsRunning ()) + Stop (); } - bool ClientDestination::Start () + void ClientDestination::Start () { - if (LeaseSetDestination::Start ()) + if (!IsRunning ()) { + LeaseSetDestination::Start (); m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: m_StreamingDestination->Start (); for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); - return true; + StartService (); } - else - return false; } - bool ClientDestination::Stop () + void ClientDestination::Stop () { - if (LeaseSetDestination::Stop ()) + if (IsRunning ()) { + LeaseSetDestination::Stop (); m_ReadyChecker.cancel(); m_StreamingDestination->Stop (); //m_StreamingDestination->SetOwner (nullptr); @@ -967,10 +929,8 @@ namespace client delete m_DatagramDestination; m_DatagramDestination = nullptr; } - return true; + StopService (); } - else - return false; } #ifdef I2LUA diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f4483032..5b411c14 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -20,6 +20,7 @@ #include "NetDb.hpp" #include "Streaming.h" #include "Datagram.h" +#include "util.h" namespace i2p { @@ -98,18 +99,16 @@ namespace client public: - LeaseSetDestination (bool isPublic, const std::map * params = nullptr); + LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map * params = nullptr); ~LeaseSetDestination (); const std::string& GetNickname () const { return m_Nickname; }; - virtual bool Start (); - virtual bool Stop (); + virtual void Start (); + virtual void Stop (); /** i2cp reconfigure */ virtual bool Reconfigure(std::map i2cpOpts); - bool IsRunning () const { return m_IsRunning; }; - boost::asio::io_service& GetService () { return m_Service; }; std::shared_ptr GetTunnelPool () { return m_Pool; }; bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; }; std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); @@ -146,7 +145,6 @@ namespace client private: - void Run (); void UpdateLeaseSet (); std::shared_ptr GetLeaseSetMt (); void Publish (); @@ -165,9 +163,7 @@ namespace client private: - volatile bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; + boost::asio::io_service& m_Service; mutable std::mutex m_RemoteLeaseSetsMutex; std::map > m_RemoteLeaseSets; std::map > m_LeaseSetRequests; @@ -195,7 +191,7 @@ namespace client bool IsPerClientAuth () const { return m_AuthType > 0; }; }; - class ClientDestination: public LeaseSetDestination + class ClientDestination: public i2p::util::RunnableService, public LeaseSetDestination { public: #ifdef I2LUA @@ -209,8 +205,8 @@ namespace client ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); ~ClientDestination (); - virtual bool Start (); - virtual bool Stop (); + virtual void Start (); + virtual void Stop (); const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; diff --git a/libi2pd/util.h b/libi2pd/util.h index 830a984d..febb98b0 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -143,7 +143,7 @@ namespace util private: std::string m_Name; - bool m_IsRunning; + volatile bool m_IsRunning; std::unique_ptr m_Thread; boost::asio::io_service m_Service; }; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 78190c89..e06b2db4 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -24,10 +24,35 @@ namespace client { I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - LeaseSetDestination (isPublic, ¶ms), m_Owner (owner), m_Identity (identity) + RunnableService ("I2CP"), LeaseSetDestination (GetService (), isPublic, ¶ms), + m_Owner (owner), m_Identity (identity) { } + I2CPDestination::~I2CPDestination () + { + if (IsRunning ()) + Stop (); + } + + void I2CPDestination::Start () + { + if (!IsRunning ()) + { + LeaseSetDestination::Start (); + StartService (); + } + } + + void I2CPDestination::Stop () + { + if (IsRunning ()) + { + LeaseSetDestination::Stop (); + StopService (); + } + } + void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { memcpy (m_EncryptionPrivateKey, key, 256); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 0d235161..a51597af 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -15,6 +15,7 @@ #include #include #include +#include "util.h" #include "Destination.h" namespace i2p @@ -61,12 +62,16 @@ namespace client const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; class I2CPSession; - class I2CPDestination: public LeaseSetDestination + class I2CPDestination: public i2p::util::RunnableService, public LeaseSetDestination { public: I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params); - + ~I2CPDestination (); + + void Start (); + void Stop (); + void SetEncryptionPrivateKey (const uint8_t * key); void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index fa08ec51..48d09b79 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -45,29 +45,19 @@ namespace client } - bool MatchedTunnelDestination::Start() + void MatchedTunnelDestination::Start() { - if(ClientDestination::Start()) - { - m_ResolveTimer = std::make_shared(GetService()); - GetTunnelPool()->SetCustomPeerSelector(this); - ResolveCurrentLeaseSet(); - return true; - } - else - return false; + ClientDestination::Start(); + m_ResolveTimer = std::make_shared(GetService()); + GetTunnelPool()->SetCustomPeerSelector(this); + ResolveCurrentLeaseSet(); } - bool MatchedTunnelDestination::Stop() + void MatchedTunnelDestination::Stop() { - if(ClientDestination::Stop()) - { - if(m_ResolveTimer) - m_ResolveTimer->cancel(); - return true; - } - else - return false; + ClientDestination::Stop(); + if(m_ResolveTimer) + m_ResolveTimer->cancel(); } diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index bbeeb503..1d7abf7d 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -14,8 +14,8 @@ namespace client { public: MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName, const std::map * params = nullptr); - bool Start(); - bool Stop(); + void Start(); + void Stop(); bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); bool OnBuildResult(const i2p::tunnel::Path & peers, bool inbound, i2p::tunnel::TunnelBuildResult result); From b982be5ff58295436d4942f67cbb3411d8031f51 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Feb 2020 16:21:07 -0500 Subject: [PATCH 0195/2950] handle existing session message --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 64 ++++++++++++++++------- libi2pd/ECIESX25519AEADRatchetSession.h | 17 +++--- libi2pd/Garlic.cpp | 11 ++-- libi2pd/Garlic.h | 11 ++-- 4 files changed, 68 insertions(+), 35 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 11e7edad..96c917cd 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -86,7 +86,7 @@ namespace garlic return tagsetNsr.GetNextSessionTag (); } - bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove) + bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) { if (!GetOwner ()) return false; // we are Bob @@ -138,12 +138,12 @@ namespace garlic m_State = eSessionStateNewSessionReceived; GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); - HandlePayload (payload.data (), len - 16, handleClove); + HandlePayload (payload.data (), len - 16); return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len) { size_t offset = 0; while (offset < len) @@ -161,7 +161,7 @@ namespace garlic switch (blk) { case eECIESx25519BlkGalicClove: - handleClove (buf + offset, size); + GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); break; case eECIESx25519BlkDateTime: LogPrint (eLogDebug, "Garlic: datetime"); @@ -220,7 +220,7 @@ namespace garlic m_State = eSessionStateNewSessionSent; if (GetOwner ()) - GetOwner ()->AddECIESx25519SessionTag (CreateNewSessionTag (), shared_from_this ()); + GetOwner ()->AddECIESx25519SessionTag (CreateNewSessionTag (), 0, shared_from_this ()); return true; } @@ -260,9 +260,12 @@ namespace garlic // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) - // k_ab = keydata[0:31], k_ba = keydata[32:63] - m_TagsetAB.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) - m_TagsetBA.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + memcpy (m_ReceiveKey, keydata, 32); // k_ab = keydata[0:31] + memcpy (m_SendKey, keydata + 32, 32);// k_ba = keydata[32:63] + m_ReceiveTagset.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_ReceiveTagset.NextSessionTagRatchet (); + m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + m_SendTagset.NextSessionTagRatchet (); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt @@ -270,11 +273,12 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; } + m_State = eSessionStateEstablished; return true; } - bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove) + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len) { // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); @@ -308,9 +312,12 @@ namespace garlic // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) - // k_ab = keydata[0:31], k_ba = keydata[32:63] - m_TagsetAB.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) - m_TagsetBA.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + memcpy (m_SendKey, keydata, 32); // k_ab = keydata[0:31] + memcpy (m_ReceiveKey, keydata + 32, 32);// k_ba = keydata[32:63] + m_SendTagset.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_SendTagset.NextSessionTagRatchet (); + m_ReceiveTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + m_ReceiveTagset.NextSessionTagRatchet (); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -320,21 +327,41 @@ namespace garlic return false; } - // TODO: change state + m_State = eSessionStateEstablished; GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); - HandlePayload (payload.data (), len - 16, handleClove); + HandlePayload (payload.data (), len - 16); return true; } - bool ECIESX25519AEADRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len, CloveHandler handleClove) + bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (const uint8_t * buf, size_t len, int index) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + htole64buf (nonce + 4, index); // tag's index + // ad = The session tag, 8 bytes + // ciphertext = ENCRYPT(k, n, payload, ad) + len -= 8; // tag + std::vector payload (len - 16); + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, m_ReceiveKey, nonce, payload.data (), len - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); + return false; + } + HandlePayload (payload.data (), len - 16); + return true; + } + + bool ECIESX25519AEADRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len, int index) { switch (m_State) { + case eSessionStateEstablished: + return HandleExistingSessionMessage (buf, len, index); case eSessionStateNew: - return HandleNewIncomingSession (buf, len, handleClove); + return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: - return HandleNewOutgoingSessionReply (buf, len, handleClove); + return HandleNewOutgoingSessionReply (buf, len); default: return false; } @@ -424,8 +451,7 @@ namespace garlic htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); return cloveSize + 3; - } - + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index ebe8cf13..f9b2de25 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -54,17 +54,16 @@ namespace garlic { eSessionStateNew =0, eSessionStateNewSessionReceived, - eSessionStateNewSessionSent + eSessionStateNewSessionSent, + eSessionStateEstablished }; public: - typedef std::function CloveHandler; - ECIESX25519AEADRatchetSession (GarlicDestination * owner); ~ECIESX25519AEADRatchetSession (); - bool HandleNextMessage (const uint8_t * buf, size_t len, CloveHandler handleClove); + bool HandleNextMessage (const uint8_t * buf, size_t len, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } @@ -82,9 +81,10 @@ namespace garlic bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes uint64_t CreateNewSessionTag () const; - bool HandleNewIncomingSession (const uint8_t * buf, size_t len, CloveHandler handleClove); - bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len, CloveHandler handleClove); - void HandlePayload (const uint8_t * buf, size_t len, CloveHandler& handleClove); + bool HandleNewIncomingSession (const uint8_t * buf, size_t len); + bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len); + bool HandleExistingSessionMessage (const uint8_t * buf, size_t len, int index); + void HandlePayload (const uint8_t * buf, size_t len); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); @@ -97,7 +97,8 @@ namespace garlic uint8_t m_Aepk[32]; // Alice's ephemeral keys TODO: for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; - RatchetTagSet m_TagsetAB, m_TagsetBA; + RatchetTagSet m_SendTagset, m_ReceiveTagset; + uint8_t m_SendKey[32], m_ReceiveKey[32]; std::unique_ptr m_Destination;// TODO: might not need it }; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 1b34f99c..7307b9c1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -864,17 +864,18 @@ namespace garlic uint64_t tag; memcpy (&tag, buf, 8); ECIESX25519AEADRatchetSessionPtr session; + int index = 0; auto it = m_ECIESx25519Tags.find (tag); if (it != m_ECIESx25519Tags.end ()) { - session = it->second; + session = it->second.session; + index = it->second.index; m_ECIESx25519Tags.erase (tag); } else session = std::make_shared (this); // incoming - if (!session->HandleNextMessage (buf, len, std::bind (&GarlicDestination::HandleECIESx25519GarlicClove, - this, std::placeholders::_1, std::placeholders::_2))) + if (!session->HandleNextMessage (buf, len, index)) LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); } @@ -934,9 +935,9 @@ namespace garlic } } - void GarlicDestination::AddECIESx25519SessionTag (uint64_t tag, ECIESX25519AEADRatchetSessionPtr session) + void GarlicDestination::AddECIESx25519SessionTag (uint64_t tag, int index, ECIESX25519AEADRatchetSessionPtr session) { - m_ECIESx25519Tags.emplace (tag, session); + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexSession{index, session}); } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 4e66f75f..d12d0fa7 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -198,6 +198,11 @@ namespace garlic class ECIESX25519AEADRatchetSession; typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; + struct ECIESX25519AEADRatchetIndexSession + { + int index; + ECIESX25519AEADRatchetSessionPtr session; + }; class GarlicDestination: public i2p::data::LocalDestination { @@ -217,8 +222,9 @@ namespace garlic void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); - void AddECIESx25519SessionTag (uint64_t tag, ECIESX25519AEADRatchetSessionPtr session); + void AddECIESx25519SessionTag (uint64_t tag, int index, ECIESX25519AEADRatchetSessionPtr session); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); + void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); virtual void ProcessGarlicMessage (std::shared_ptr msg); virtual void ProcessDeliveryStatusMessage (std::shared_ptr msg); @@ -245,7 +251,6 @@ namespace garlic // ECIES-X25519-AEAD-Ratchet void HandleECIESx25519 (const uint8_t * buf, size_t len); - void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); private: @@ -257,7 +262,7 @@ namespace garlic std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming std::unordered_map, std::hash > > m_Tags; - std::unordered_map m_ECIESx25519Tags; // session tag -> session + std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session From 969f9aa4364d39efcec625882eb95ee86dc43485 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Feb 2020 11:48:56 -0500 Subject: [PATCH 0196/2950] common RuunableBase with private inheritance --- libi2pd/Destination.cpp | 6 +++--- libi2pd/Destination.h | 3 ++- libi2pd/NTCP2.cpp | 4 ++-- libi2pd/NTCP2.h | 3 ++- libi2pd/util.cpp | 10 ++++----- libi2pd/util.h | 12 +++++------ libi2pd_client/BOB.cpp | 34 ++++++------------------------ libi2pd_client/BOB.h | 9 +++----- libi2pd_client/ClientContext.cpp | 3 +-- libi2pd_client/I2CP.cpp | 6 +++--- libi2pd_client/I2CP.h | 2 +- libi2pd_client/SAM.cpp | 36 ++++++-------------------------- libi2pd_client/SAM.h | 10 +++------ 13 files changed, 43 insertions(+), 95 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 835c8e52..5240cb05 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -823,7 +823,7 @@ namespace client } ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - RunnableService ("Destination"), LeaseSetDestination (GetService (), isPublic, params), + RunnableService ("Destination"), LeaseSetDestination (GetIOService (), isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) @@ -905,7 +905,7 @@ namespace client m_StreamingDestination->Start (); for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); - StartService (); + StartIOService (); } } @@ -929,7 +929,7 @@ namespace client delete m_DatagramDestination; m_DatagramDestination = nullptr; } - StopService (); + StopIOService (); } } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 5b411c14..529a9adb 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -102,6 +102,7 @@ namespace client LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map * params = nullptr); ~LeaseSetDestination (); const std::string& GetNickname () const { return m_Nickname; }; + boost::asio::io_service& GetService () { return m_Service; }; virtual void Start (); virtual void Stop (); @@ -191,7 +192,7 @@ namespace client bool IsPerClientAuth () const { return m_AuthType > 0; }; }; - class ClientDestination: public i2p::util::RunnableService, public LeaseSetDestination + class ClientDestination: private i2p::util::RunnableService, public LeaseSetDestination { public: #ifdef I2LUA diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e79be97a..034f7e21 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1155,7 +1155,7 @@ namespace transport { if (!IsRunning ()) { - StartService (); + StartIOService (); auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address: addresses) { @@ -1217,7 +1217,7 @@ namespace transport if (IsRunning ()) m_TerminationTimer.cancel (); - StopService (); + StopIOService (); } bool NTCP2Server::AddNTCP2Session (std::shared_ptr session, bool incoming) diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index a63b86b8..7e3c53e8 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -216,7 +216,7 @@ namespace transport std::list > m_SendQueue; }; - class NTCP2Server: public i2p::util::RunnableServiceWithWork + class NTCP2Server: private i2p::util::RunnableServiceWithWork { public: @@ -225,6 +225,7 @@ namespace transport void Start (); void Stop (); + boost::asio::io_service& GetService () { return GetIOService (); }; bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); void RemoveNTCP2Session (std::shared_ptr session); diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 6ae9fa6b..051eea5d 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -58,7 +58,7 @@ namespace i2p namespace util { - void RunnableService::StartService () + void RunnableService::StartIOService () { if (!m_IsRunning) { @@ -67,7 +67,7 @@ namespace util } } - void RunnableService::StopService () + void RunnableService::StopIOService () { if (m_IsRunning) { @@ -245,10 +245,10 @@ namespace net #else std::string localAddressUniversal = localAddress.to_string(); #endif - - typedef int (* IPN)(int af, const char *src, void *dst); + + typedef int (* IPN)(int af, const char *src, void *dst); IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); - if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found + if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found if(localAddress.is_v4()) { diff --git a/libi2pd/util.h b/libi2pd/util.h index febb98b0..2202ccd9 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -125,16 +125,16 @@ namespace util class RunnableService { - public: + protected: RunnableService (const std::string& name): m_Name (name), m_IsRunning (false) {} virtual ~RunnableService () {} - boost::asio::io_service& GetService () { return m_Service; } + boost::asio::io_service& GetIOService () { return m_Service; } bool IsRunning () const { return m_IsRunning; }; - void StartService (); - void StopService (); + void StartIOService (); + void StopIOService (); private: @@ -150,10 +150,10 @@ namespace util class RunnableServiceWithWork: public RunnableService { - public: + protected: RunnableServiceWithWork (const std::string& name): - RunnableService (name), m_Work (GetService ()) {} + RunnableService (name), m_Work (GetIOService ()) {} private: diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index aba090dc..c7bbdb46 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -743,8 +743,8 @@ namespace client } BOBCommandChannel::BOBCommandChannel (const std::string& address, int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)) + RunnableService ("BOB"), + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)) { // command -> handler m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler; @@ -794,7 +794,8 @@ namespace client BOBCommandChannel::~BOBCommandChannel () { - Stop (); + if (IsRunning ()) + Stop (); for (const auto& it: m_Destinations) delete it.second; } @@ -802,38 +803,15 @@ namespace client void BOBCommandChannel::Start () { Accept (); - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&BOBCommandChannel::Run, this)); + StartIOService (); } void BOBCommandChannel::Stop () { - m_IsRunning = false; for (auto& it: m_Destinations) it.second->Stop (); m_Acceptor.cancel (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - - void BOBCommandChannel::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "BOB: runtime exception: ", ex.what ()); - } - } + StopIOService (); } void BOBCommandChannel::AddDestination (const std::string& name, BOBDestination * dest) diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 8f1af185..15a0afaf 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -7,6 +7,7 @@ #include #include #include +#include "util.h" #include "I2PTunnel.h" #include "I2PService.h" #include "Identity.h" @@ -231,7 +232,7 @@ namespace client }; typedef void (BOBCommandSession::*BOBCommandHandler)(const char * operand, size_t len); - class BOBCommandChannel + class BOBCommandChannel: private i2p::util::RunnableService { public: @@ -241,22 +242,18 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; + boost::asio::io_service& GetService () { return GetIOService (); }; void AddDestination (const std::string& name, BOBDestination * dest); void DeleteDestination (const std::string& name); BOBDestination * FindDestination (const std::string& name); private: - void Run (); void Accept (); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr session); private: - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; std::map m_Destinations; std::map m_CommandHandlers; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index d14491b2..53e740b3 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -344,8 +344,7 @@ namespace client if (it != m_Destinations.end ()) { LogPrint (eLogWarning, "Clients: Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " exists"); - if (!it->second->IsRunning ()) - it->second->Start (); + it->second->Start (); // make sure to start return it->second; } auto localDestination = std::make_shared (keys, isPublic, params); diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index e06b2db4..69b26cab 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -24,7 +24,7 @@ namespace client { I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - RunnableService ("I2CP"), LeaseSetDestination (GetService (), isPublic, ¶ms), + RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), m_Owner (owner), m_Identity (identity) { } @@ -40,7 +40,7 @@ namespace client if (!IsRunning ()) { LeaseSetDestination::Start (); - StartService (); + StartIOService (); } } @@ -49,7 +49,7 @@ namespace client if (IsRunning ()) { LeaseSetDestination::Stop (); - StopService (); + StopIOService (); } } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index a51597af..d4e05b51 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -62,7 +62,7 @@ namespace client const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; class I2CPSession; - class I2CPDestination: public i2p::util::RunnableService, public LeaseSetDestination + class I2CPDestination: private i2p::util::RunnableService, public LeaseSetDestination { public: diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 766a1940..3ddfc940 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1001,9 +1001,9 @@ namespace client } SAMBridge::SAMBridge (const std::string& address, int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), - m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint), + RunnableService ("SAM"), + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), + m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, @@ -1020,7 +1020,7 @@ namespace client SAMBridge::~SAMBridge () { - if (m_IsRunning) + if (IsRunning ()) Stop (); } @@ -1028,14 +1028,11 @@ namespace client { Accept (); ReceiveDatagram (); - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&SAMBridge::Run, this)); + StartIOService (); } void SAMBridge::Stop () { - m_IsRunning = false; - try { m_Acceptor.cancel (); @@ -1048,28 +1045,7 @@ namespace client for (auto& it: m_Sessions) it.second->CloseStreams (); m_Sessions.clear (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - - void SAMBridge::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "SAM: runtime exception: ", ex.what ()); - } - } + StopIOService (); } void SAMBridge::Accept () diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index aebdccb6..029f3524 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -9,6 +9,7 @@ #include #include #include +#include "util.h" #include "Identity.h" #include "LeaseSet.h" #include "Streaming.h" @@ -174,7 +175,7 @@ namespace client void CloseStreams (); }; - class SAMBridge + class SAMBridge: private i2p::util::RunnableService { public: @@ -184,7 +185,7 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; + 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); void CloseSession (const std::string& id); @@ -201,8 +202,6 @@ namespace client private: - void Run (); - void Accept (); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); @@ -211,9 +210,6 @@ namespace client private: - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::socket m_DatagramSocket; From cbedebc9dd72623f5aa10ea67474f5e4066c7290 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Feb 2020 13:32:16 -0500 Subject: [PATCH 0197/2950] change minimal MTU size --- libi2pd/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 051eea5d..c1b741fc 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -324,7 +324,7 @@ namespace net int GetMTU(const boost::asio::ip::address& localAddress) { - const int fallback = 576; // fallback MTU + int fallback = localAddress.is_v6 () ? 1280 : 620; // fallback MTU #ifdef WIN32 return GetMTUWindows(localAddress, fallback); From d0e78be8676c514e1c6a785befc69b3acdb4e5ed Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Feb 2020 14:17:23 -0500 Subject: [PATCH 0198/2950] moved io_service away from ClientDestination --- libi2pd/Destination.cpp | 86 +++++++++++++++++---------- libi2pd/Destination.h | 21 +++++-- libi2pd/api.cpp | 4 +- libi2pd_client/ClientContext.cpp | 4 +- libi2pd_client/MatchedDestination.cpp | 2 +- libi2pd_client/MatchedDestination.h | 2 +- 6 files changed, 77 insertions(+), 42 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 5240cb05..4f6b43ae 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -822,11 +822,12 @@ namespace client } } - ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - RunnableService ("Destination"), LeaseSetDestination (GetIOService (), isPublic, params), + ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + bool isPublic, const std::map * params): + LeaseSetDestination (service, isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), - m_ReadyChecker(GetService()) + m_ReadyChecker(service) { if (keys.IsOfflineSignature () && GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // offline keys can be published with LS2 only @@ -892,44 +893,34 @@ namespace client ClientDestination::~ClientDestination () { - if (IsRunning ()) - Stop (); } void ClientDestination::Start () { - if (!IsRunning ()) - { - LeaseSetDestination::Start (); - m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: - m_StreamingDestination->Start (); - for (auto& it: m_StreamingDestinationsByPorts) - it.second->Start (); - StartIOService (); - } + LeaseSetDestination::Start (); + m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: + m_StreamingDestination->Start (); + for (auto& it: m_StreamingDestinationsByPorts) + it.second->Start (); } void ClientDestination::Stop () { - if (IsRunning ()) + LeaseSetDestination::Stop (); + m_ReadyChecker.cancel(); + m_StreamingDestination->Stop (); + //m_StreamingDestination->SetOwner (nullptr); + m_StreamingDestination = nullptr; + for (auto& it: m_StreamingDestinationsByPorts) { - LeaseSetDestination::Stop (); - m_ReadyChecker.cancel(); - m_StreamingDestination->Stop (); - //m_StreamingDestination->SetOwner (nullptr); - m_StreamingDestination = nullptr; - for (auto& it: m_StreamingDestinationsByPorts) - { - it.second->Stop (); - //it.second->SetOwner (nullptr); - } - m_StreamingDestinationsByPorts.clear (); - if (m_DatagramDestination) - { - delete m_DatagramDestination; - m_DatagramDestination = nullptr; - } - StopIOService (); + it.second->Stop (); + //it.second->SetOwner (nullptr); + } + m_StreamingDestinationsByPorts.clear (); + if (m_DatagramDestination) + { + delete m_DatagramDestination; + m_DatagramDestination = nullptr; } } @@ -1199,5 +1190,36 @@ namespace client } } } + + RunnableClientDestination::RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): + RunnableService ("Destination"), + ClientDestination (GetIOService (), keys, isPublic, params) + { + } + + RunnableClientDestination::~RunnableClientDestination () + { + if (IsRunning ()) + Stop (); + } + + void RunnableClientDestination::Start () + { + if (!IsRunning ()) + { + ClientDestination::Start (); + StartIOService (); + } + } + + void RunnableClientDestination::Stop () + { + if (IsRunning ()) + { + ClientDestination::Stop (); + StopIOService (); + } + } + } } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 529a9adb..ed3abdfb 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -192,7 +192,7 @@ namespace client bool IsPerClientAuth () const { return m_AuthType > 0; }; }; - class ClientDestination: private i2p::util::RunnableService, public LeaseSetDestination + class ClientDestination: public LeaseSetDestination { public: #ifdef I2LUA @@ -203,11 +203,12 @@ namespace client void Ready(ReadyPromise & p); #endif - ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); + ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + bool isPublic, const std::map * params = nullptr); ~ClientDestination (); - virtual void Start (); - virtual void Stop (); + void Start (); + void Stop (); const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; }; void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; @@ -281,6 +282,18 @@ namespace client // for HTTP only std::vector > GetAllStreams () const; }; + + class RunnableClientDestination: private i2p::util::RunnableService, public ClientDestination + { + public: + + RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); + ~RunnableClientDestination (); + + void Start (); + void Stop (); + }; + } } diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index ca72ae49..0a76bda7 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -77,7 +77,7 @@ namespace api std::shared_ptr CreateLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params) { - auto localDestination = std::make_shared (keys, isPublic, params); + auto localDestination = std::make_shared (keys, isPublic, params); localDestination->Start (); return localDestination; } @@ -86,7 +86,7 @@ namespace api const std::map * params) { i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType); - auto localDestination = std::make_shared (keys, isPublic, params); + auto localDestination = std::make_shared (keys, isPublic, params); localDestination->Start (); return localDestination; } diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 53e740b3..37fad236 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -305,7 +305,7 @@ namespace client const std::map * params) { i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); - auto localDestination = std::make_shared (keys, isPublic, params); + auto localDestination = std::make_shared (keys, isPublic, params); std::unique_lock l(m_DestinationsMutex); m_Destinations[localDestination->GetIdentHash ()] = localDestination; localDestination->Start (); @@ -347,7 +347,7 @@ namespace client it->second->Start (); // make sure to start return it->second; } - auto localDestination = std::make_shared (keys, isPublic, params); + auto localDestination = std::make_shared (keys, isPublic, params); std::unique_lock l(m_DestinationsMutex); m_Destinations[keys.GetPublic ()->GetIdentHash ()] = localDestination; localDestination->Start (); diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index 48d09b79..3d75a3ca 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -8,7 +8,7 @@ namespace i2p namespace client { MatchedTunnelDestination::MatchedTunnelDestination(const i2p::data::PrivateKeys & keys, const std::string & remoteName, const std::map * params) - : ClientDestination(keys, false, params), + : RunnableClientDestination(keys, false, params), m_RemoteName(remoteName) {} diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 1d7abf7d..67b874e6 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -10,7 +10,7 @@ namespace client /** client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination */ - class MatchedTunnelDestination : public ClientDestination, public i2p::tunnel::ITunnelPeerSelector + class MatchedTunnelDestination : public RunnableClientDestination, public i2p::tunnel::ITunnelPeerSelector { public: MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName, const std::map * params = nullptr); From 9d891ab5dd6def8f9380af254a77a0a8a6db48ab Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 4 Feb 2020 15:31:04 -0500 Subject: [PATCH 0199/2950] single thread mode for SAM --- libi2pd/Config.cpp | 1 + libi2pd_client/ClientContext.cpp | 59 ++++++++++++++++++++++++-------- libi2pd_client/ClientContext.h | 8 +++++ libi2pd_client/SAM.cpp | 12 ++++--- libi2pd_client/SAM.h | 3 +- 5 files changed, 64 insertions(+), 19 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index e2f4bdd0..9d32cc72 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -131,6 +131,7 @@ namespace config { ("sam.enabled", value()->default_value(true), "Enable or disable SAM Application bridge") ("sam.address", value()->default_value("127.0.0.1"), "SAM listen address") ("sam.port", value()->default_value(7656), "SAM listen port") + ("sam.singlethread", value()->default_value(false), "Sessions run in the SAM bridge's thread") ; options_description bob("BOB options"); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 37fad236..d72f40a8 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -53,14 +53,19 @@ namespace client // SAM bool sam; i2p::config::GetOption("sam.enabled", sam); - if (sam) { + if (sam) + { std::string samAddr; i2p::config::GetOption("sam.address", samAddr); uint16_t samPort; i2p::config::GetOption("sam.port", samPort); + bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try { - m_SamBridge = new SAMBridge (samAddr, samPort); - m_SamBridge->Start (); - } catch (std::exception& e) { + try + { + m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); + m_SamBridge->Start (); + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); } } @@ -306,20 +311,33 @@ namespace client { i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); auto localDestination = std::make_shared (keys, isPublic, params); - std::unique_lock l(m_DestinationsMutex); - m_Destinations[localDestination->GetIdentHash ()] = localDestination; - localDestination->Start (); + AddLocalDestination (localDestination); + return localDestination; + } + + std::shared_ptr ClientContext::CreateNewLocalDestination ( + boost::asio::io_service& service, bool isPublic, + i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType, + const std::map * params) + { + i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); + auto localDestination = std::make_shared (service, keys, isPublic, params); + AddLocalDestination (localDestination); return localDestination; } std::shared_ptr ClientContext::CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map * params) { - MatchedTunnelDestination * cl = new MatchedTunnelDestination(keys, name, params); - auto localDestination = std::shared_ptr(cl); + auto localDestination = std::make_shared(keys, name, params); + AddLocalDestination (localDestination); + return localDestination; + } + + void ClientContext::AddLocalDestination (std::shared_ptr localDestination) + { std::unique_lock l(m_DestinationsMutex); m_Destinations[localDestination->GetIdentHash ()] = localDestination; localDestination->Start (); - return localDestination; } void ClientContext::DeleteLocalDestination (std::shared_ptr destination) @@ -348,9 +366,22 @@ namespace client return it->second; } auto localDestination = std::make_shared (keys, isPublic, params); - std::unique_lock l(m_DestinationsMutex); - m_Destinations[keys.GetPublic ()->GetIdentHash ()] = localDestination; - localDestination->Start (); + AddLocalDestination (localDestination); + return localDestination; + } + + std::shared_ptr ClientContext::CreateNewLocalDestination (boost::asio::io_service& service, + const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params) + { + auto it = m_Destinations.find (keys.GetPublic ()->GetIdentHash ()); + if (it != m_Destinations.end ()) + { + LogPrint (eLogWarning, "Clients: Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " exists"); + it->second->Start (); // make sure to start + return it->second; + } + auto localDestination = std::make_shared (service, keys, isPublic, params); + AddLocalDestination (localDestination); return localDestination; } diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 94aa8594..a239035f 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -68,8 +68,15 @@ namespace client i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, const std::map * params = nullptr); // used by SAM only + std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, + bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, + i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, + const std::map * params = nullptr); // same as previous but on external io_service std::shared_ptr CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); + std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, + const i2p::data::PrivateKeys& keys, bool isPublic = true, + const std::map * params = nullptr); // same as previous but on external io_service std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map * params = nullptr); void DeleteLocalDestination (std::shared_ptr destination); std::shared_ptr FindLocalDestination (const i2p::data::IdentHash& destination) const; @@ -107,6 +114,7 @@ namespace client void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain void CreateNewSharedLocalDestination (); + void AddLocalDestination (std::shared_ptr localDestination); private: diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 3ddfc940..bc4812bb 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1000,8 +1000,8 @@ namespace client } } - SAMBridge::SAMBridge (const std::string& address, int port): - RunnableService ("SAM"), + 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)), m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes @@ -1094,7 +1094,9 @@ namespace client { i2p::data::PrivateKeys keys; if (!keys.FromBase64 (destination)) return nullptr; - localDestination = i2p::client::context.CreateNewLocalDestination (keys, true, params); + localDestination = m_IsSingleThread ? + i2p::client::context.CreateNewLocalDestination (GetIOService (), keys, true, params) : + i2p::client::context.CreateNewLocalDestination (keys, true, params); } else // transient { @@ -1122,7 +1124,9 @@ namespace client } } } - localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); + localDestination = m_IsSingleThread ? + i2p::client::context.CreateNewLocalDestination (GetIOService (), true, signatureType, cryptoType, params) : + i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); } if (localDestination) { diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 029f3524..5a447c06 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -179,7 +179,7 @@ namespace client { public: - SAMBridge (const std::string& address, int port); + SAMBridge (const std::string& address, int port, bool singleThread); ~SAMBridge (); void Start (); @@ -210,6 +210,7 @@ namespace client private: + bool m_IsSingleThread; boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::socket m_DatagramSocket; From 012f22cc477158c8d7bfb684cd5101c6fbe7b05e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 5 Feb 2020 15:48:51 -0500 Subject: [PATCH 0200/2950] create session tags for ECIESX25519 --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 52 ++++++++++++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 5 +++ libi2pd/Garlic.cpp | 5 ++- libi2pd/Garlic.h | 3 +- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 96c917cd..94ccbce5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -27,11 +27,13 @@ namespace garlic { 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); + m_NextIndex = 0; } uint64_t RatchetTagSet::GetNextSessionTag () { i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + m_NextIndex++; return m_KeyData.GetTag (); } @@ -64,6 +66,12 @@ namespace garlic SHA256_Final (m_H, &ctx); } + void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) + { + memset (nonce, 0, 4); + htole64buf (nonce + 4, seqn); + } + bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) { for (int i = 0; i < 10; i++) @@ -107,7 +115,7 @@ namespace garlic // decrypt flags/static uint8_t nonce[12], fs[32]; - memset (nonce, 0, 12); // n = 0 + CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Flags/static section AEAD verification failed "); @@ -128,7 +136,7 @@ namespace garlic i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags - htole64buf (nonce + 4, 1); // n = 1 + CreateNonce (1, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); @@ -199,7 +207,7 @@ namespace garlic i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt static key section uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 + CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); @@ -220,7 +228,7 @@ namespace garlic m_State = eSessionStateNewSessionSent; if (GetOwner ()) - GetOwner ()->AddECIESx25519SessionTag (CreateNewSessionTag (), 0, shared_from_this ()); + GetOwner ()->AddECIESx25519SessionTag (0, CreateNewSessionTag (), shared_from_this ()); return true; } @@ -248,7 +256,7 @@ namespace garlic m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 + CreateNonce (0, nonce); // calulate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (sharedSecret /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { @@ -266,6 +274,9 @@ namespace garlic m_ReceiveTagset.NextSessionTagRatchet (); m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset.NextSessionTagRatchet (); + auto numTags = GetOwner ()->GetNumTags (); + for (int i = 0; i < numTags; i++) + GetOwner ()->AddECIESx25519SessionTag (m_ReceiveTagset.GetNextIndex (), m_ReceiveTagset.GetNextSessionTag (), shared_from_this ()); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt @@ -300,7 +311,7 @@ namespace garlic GetOwner ()->Decrypt (bepk, sharedSecret, nullptr); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; - memset (nonce, 0, 12); // n = 0 + CreateNonce (0, nonce); // calulate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anyting */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only { @@ -318,6 +329,9 @@ namespace garlic m_SendTagset.NextSessionTagRatchet (); m_ReceiveTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_ReceiveTagset.NextSessionTagRatchet (); + auto numTags = GetOwner ()->GetNumTags (); + for (int i = 0; i < numTags; i++) + GetOwner ()->AddECIESx25519SessionTag (m_ReceiveTagset.GetNextIndex (), m_ReceiveTagset.GetNextSessionTag (), shared_from_this ()); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -334,13 +348,26 @@ namespace garlic return true; } + bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + uint8_t nonce[12]; + CreateNonce (m_SendTagset.GetNextIndex (), nonce); // tag's index + uint64_t tag = m_SendTagset.GetNextSessionTag (); + memcpy (out, &tag, 8); + // ad = The session tag, 8 bytes + // ciphertext = ENCRYPT(k, n, payload, ad) + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, m_SendKey, nonce, out + 8, outLen - 8, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); + return false; + } + return true; + } + bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (const uint8_t * buf, size_t len, int index) { uint8_t nonce[12]; - memset (nonce, 0, 12); - htole64buf (nonce + 4, index); // tag's index - // ad = The session tag, 8 bytes - // ciphertext = ENCRYPT(k, n, payload, ad) + CreateNonce (index, nonce); // tag's index len -= 8; // tag std::vector payload (len - 16); if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, m_ReceiveKey, nonce, payload.data (), len - 16, false)) // decrypt @@ -378,6 +405,11 @@ namespace garlic switch (m_State) { + case eSessionStateEstablished: + if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 24; + break; case eSessionStateNew: if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) return nullptr; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index f9b2de25..acc90e96 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -21,6 +21,7 @@ namespace garlic void DHInitialize (const uint8_t * rootKey, const uint8_t * k); void NextSessionTagRatchet (); uint64_t GetNextSessionTag (); + int GetNextIndex () const { return m_NextIndex; }; private: @@ -35,6 +36,7 @@ namespace garlic } m_KeyData; uint8_t m_SessTagConstant[32]; + int m_NextIndex; }; enum ECIESx25519BlockType @@ -78,6 +80,7 @@ namespace garlic void ResetKeys (); void MixHash (const uint8_t * buf, size_t len); + void CreateNonce (uint64_t seqn, uint8_t * nonce); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes uint64_t CreateNewSessionTag () const; @@ -88,6 +91,8 @@ namespace garlic bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (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); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 7307b9c1..14154eaf 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -418,6 +418,8 @@ namespace garlic m_Sessions.clear (); m_DeliveryStatusSessions.clear (); m_Tags.clear (); + m_ECIESx25519Sessions.clear (); + m_ECIESx25519Tags.clear (); } void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag) { @@ -737,6 +739,7 @@ namespace garlic ++it; } } + // TODO: cleanup ECIESx25519 } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) @@ -935,7 +938,7 @@ namespace garlic } } - void GarlicDestination::AddECIESx25519SessionTag (uint64_t tag, int index, ECIESX25519AEADRatchetSessionPtr session) + void GarlicDestination::AddECIESx25519SessionTag (int index, uint64_t tag, ECIESX25519AEADRatchetSessionPtr session) { m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexSession{index, session}); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index d12d0fa7..4fdb299e 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -213,6 +213,7 @@ namespace garlic void CleanUp (); void SetNumTags (int numTags) { m_NumTags = numTags; }; + int GetNumTags () const { return m_NumTags; }; std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); @@ -222,7 +223,7 @@ namespace garlic void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); - void AddECIESx25519SessionTag (uint64_t tag, int index, ECIESX25519AEADRatchetSessionPtr session); + void AddECIESx25519SessionTag (int index, uint64_t tag, ECIESX25519AEADRatchetSessionPtr session); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); From 63e807b0b4eb2a781f5800b508c74b1415aba87b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 6 Feb 2020 10:53:45 -0500 Subject: [PATCH 0201/2950] fixed crash on stop --- libi2pd_client/SAM.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index bc4812bb..138e39cf 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1042,9 +1042,12 @@ namespace client LogPrint (eLogError, "SAM: runtime exception: ", ex.what ()); } - for (auto& it: m_Sessions) - it.second->CloseStreams (); - m_Sessions.clear (); + { + std::unique_lock l(m_SessionsMutex); + for (auto& it: m_Sessions) + it.second->CloseStreams (); + m_Sessions.clear (); + } StopIOService (); } From 8e53c30a000882568811b40d3047894c1bfc43f2 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 7 Feb 2020 22:08:55 -0500 Subject: [PATCH 0202/2950] correct calls sequence for tag and index --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 94ccbce5..3b604445 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -276,7 +276,11 @@ namespace garlic m_SendTagset.NextSessionTagRatchet (); auto numTags = GetOwner ()->GetNumTags (); for (int i = 0; i < numTags; i++) - GetOwner ()->AddECIESx25519SessionTag (m_ReceiveTagset.GetNextIndex (), m_ReceiveTagset.GetNextSessionTag (), shared_from_this ()); + { + auto index = m_ReceiveTagset.GetNextIndex (); + uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); + GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); + } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt @@ -331,7 +335,11 @@ namespace garlic m_ReceiveTagset.NextSessionTagRatchet (); auto numTags = GetOwner ()->GetNumTags (); for (int i = 0; i < numTags; i++) - GetOwner ()->AddECIESx25519SessionTag (m_ReceiveTagset.GetNextIndex (), m_ReceiveTagset.GetNextSessionTag (), shared_from_this ()); + { + auto index = m_ReceiveTagset.GetNextIndex (); + uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); + GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); + } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); From 694d851cdb59ee0f54e36be1ee7794750425a775 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Feb 2020 21:51:02 -0500 Subject: [PATCH 0203/2950] Symmetric Key Ratchet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 37 ++++++++++++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 12 +++++--- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 3b604445..b29c27ed 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -21,6 +21,8 @@ namespace garlic // nextRootKey = keydata[0:31] i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf); // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32); + m_NextSymmKeyIndex = 0; } void RatchetTagSet::NextSessionTagRatchet () @@ -32,12 +34,32 @@ namespace garlic uint64_t RatchetTagSet::GetNextSessionTag () { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; return m_KeyData.GetTag (); } + const uint8_t * RatchetTagSet::GetSymmKey (int index) + { + // TODO: store intermediate keys + if (m_NextSymmKeyIndex > 0 && index == m_NextSymmKeyIndex) + { + i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); + m_NextSymmKeyIndex++; + } + else + CalculateSymmKeyCK (index); + return m_CurrentSymmKeyCK + 32; + } + void RatchetTagSet::CalculateSymmKeyCK (int index) + { + i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) + for (int i = 0; i < index; i++) + i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_n = HKDF(symmKey_chainKey_(n-1), SYMMKEY_CONSTANT, "SymmetricRatchet", 64) + m_NextSymmKeyIndex = index + 1; + } + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): GarlicRoutingSession (owner, true) { @@ -268,8 +290,7 @@ namespace garlic // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) - memcpy (m_ReceiveKey, keydata, 32); // k_ab = keydata[0:31] - memcpy (m_SendKey, keydata + 32, 32);// k_ba = keydata[32:63] + // k_ab = keydata[0:31], k_ba = keydata[32:63] m_ReceiveTagset.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) m_ReceiveTagset.NextSessionTagRatchet (); m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) @@ -327,8 +348,7 @@ namespace garlic // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) - memcpy (m_SendKey, keydata, 32); // k_ab = keydata[0:31] - memcpy (m_ReceiveKey, keydata + 32, 32);// k_ba = keydata[32:63] + // k_ab = keydata[0:31], k_ba = keydata[32:63] m_SendTagset.DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) m_SendTagset.NextSessionTagRatchet (); m_ReceiveTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) @@ -359,12 +379,13 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { uint8_t nonce[12]; - CreateNonce (m_SendTagset.GetNextIndex (), nonce); // tag's index + auto index = m_SendTagset.GetNextIndex (); + CreateNonce (index, nonce); // tag's index uint64_t tag = m_SendTagset.GetNextSessionTag (); memcpy (out, &tag, 8); // ad = The session tag, 8 bytes // ciphertext = ENCRYPT(k, n, payload, ad) - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, m_SendKey, nonce, out + 8, outLen - 8, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, m_SendTagset.GetSymmKey (index), nonce, out + 8, outLen - 8, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; @@ -378,7 +399,7 @@ namespace garlic CreateNonce (index, nonce); // tag's index len -= 8; // tag std::vector payload (len - 16); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, m_ReceiveKey, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, m_ReceiveTagset.GetSymmKey (index), nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index acc90e96..214e47f6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -22,9 +22,14 @@ namespace garlic void NextSessionTagRatchet (); uint64_t GetNextSessionTag (); int GetNextIndex () const { return m_NextIndex; }; + const uint8_t * GetSymmKey (int index); private: - + + void CalculateSymmKeyCK (int index); + + private: + union { uint64_t ll[8]; @@ -35,8 +40,8 @@ namespace garlic uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39] } m_KeyData; - uint8_t m_SessTagConstant[32]; - int m_NextIndex; + uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64]; + int m_NextIndex, m_NextSymmKeyIndex; }; enum ECIESx25519BlockType @@ -103,7 +108,6 @@ namespace garlic i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; RatchetTagSet m_SendTagset, m_ReceiveTagset; - uint8_t m_SendKey[32], m_ReceiveKey[32]; std::unique_ptr m_Destination;// TODO: might not need it }; } From 53a6162b0c3c434823ce6b1ce21ef7971b3d2845 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 9 Feb 2020 17:19:42 -0500 Subject: [PATCH 0204/2950] generate more receive tags when needed --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 32 ++++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 5 +++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b29c27ed..7f17130c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -295,13 +295,7 @@ namespace garlic m_ReceiveTagset.NextSessionTagRatchet (); m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset.NextSessionTagRatchet (); - auto numTags = GetOwner ()->GetNumTags (); - for (int i = 0; i < numTags; i++) - { - auto index = m_ReceiveTagset.GetNextIndex (); - uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); - GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); - } + GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt @@ -310,7 +304,7 @@ namespace garlic return false; } m_State = eSessionStateEstablished; - + return true; } @@ -353,13 +347,7 @@ namespace garlic m_SendTagset.NextSessionTagRatchet (); m_ReceiveTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_ReceiveTagset.NextSessionTagRatchet (); - auto numTags = GetOwner ()->GetNumTags (); - for (int i = 0; i < numTags; i++) - { - auto index = m_ReceiveTagset.GetNextIndex (); - uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); - GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); - } + GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -405,6 +393,9 @@ namespace garlic return false; } HandlePayload (payload.data (), len - 16); + if (m_NumReceiveTags > 0)m_NumReceiveTags--; + if (m_NumReceiveTags <= GetOwner ()->GetNumTags ()*2/3) + GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); return true; } @@ -513,6 +504,17 @@ namespace garlic memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); return cloveSize + 3; } + + void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (int numTags) + { + for (int i = 0; i < numTags; i++) + { + auto index = m_ReceiveTagset.GetNextIndex (); + uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); + GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); + } + m_NumReceiveTags += numTags; + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 214e47f6..90e21e8a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -80,7 +80,7 @@ namespace garlic { if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } - + private: void ResetKeys (); @@ -101,6 +101,8 @@ namespace garlic std::vector CreatePayload (std::shared_ptr msg); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + void GenerateMoreReceiveTags (int numTags); + private: uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; @@ -108,6 +110,7 @@ namespace garlic i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; RatchetTagSet m_SendTagset, m_ReceiveTagset; + int m_NumReceiveTags = 0; std::unique_ptr m_Destination;// TODO: might not need it }; } From 09ed57ad425110b87ad64b14ec7147a67a16acd3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 12 Feb 2020 11:09:20 -0500 Subject: [PATCH 0205/2950] select preferred crypto from LeaseSet2 --- libi2pd/Destination.cpp | 4 ++-- libi2pd/LeaseSet.cpp | 21 ++++++++++++--------- libi2pd/LeaseSet.h | 6 +++--- libi2pd_client/I2CP.cpp | 5 ++++- libi2pd_client/I2CP.h | 3 +++ 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 4f6b43ae..6544d120 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -388,7 +388,7 @@ namespace client if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET) leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else - leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset); // LeaseSet2 + leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetEncryptionType ()); // LeaseSet2 if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) { if (leaseSet->GetIdentHash () != GetIdentHash ()) @@ -412,7 +412,7 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr); + auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetEncryptionType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index e6373dd9..8d1b9524 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -251,18 +251,19 @@ namespace data memcpy (m_Buffer, buf, len); } - LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases): - LeaseSet (storeLeases), m_StoreType (storeType) + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto): + LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto) { - SetBuffer (buf, len); + SetBuffer (buf, len); if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) ReadFromBufferEncrypted (buf, len, nullptr, nullptr); else ReadFromBuffer (buf, len); } - LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret): - LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) + LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, + const uint8_t * secret, CryptoKeyType preferredCrypto): + LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_EncryptionType (preferredCrypto) { ReadFromBufferEncrypted (buf, len, key, secret); } @@ -355,6 +356,8 @@ namespace data offset += propertiesLen; // skip for now. TODO: implement properties if (offset + 1 >= len) return 0; // key sections + CryptoKeyType preferredKeyType = m_EncryptionType; + bool preferredKeyFound = false; int numKeySections = buf[offset]; offset++; for (int i = 0; i < numKeySections; i++) { @@ -362,15 +365,15 @@ namespace data if (offset + 2 >= len) return 0; uint16_t encryptionKeyLen = bufbe16toh (buf + offset); offset += 2; if (offset + encryptionKeyLen >= len) return 0; - if (IsStoreLeases ()) // create encryptor with leases only + if (IsStoreLeases () && !preferredKeyFound) // create encryptor with leases only { - // we pick first valid key, higher key type has higher priority 4-1-0 - // if two keys with of the same type, pick first + // we pick first valid key if preferred not found auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset); - if (encryptor && (!m_Encryptor || keyType > m_EncryptionType)) + if (encryptor && (!m_Encryptor || keyType == preferredKeyType)) { m_Encryptor = encryptor; // TODO: atomic m_EncryptionType = keyType; + if (keyType == preferredKeyType) preferredKeyFound = true; } } offset += encryptionKeyLen; diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 84d87e17..a51570f7 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -136,8 +136,8 @@ namespace data { public: - LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true); - LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr); // store type 5, called from local netdb only + LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); + LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL); // store type 5, called from local netdb only uint8_t GetStoreType () const { return m_StoreType; }; uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; }; bool IsPublic () const { return m_IsPublic; }; @@ -168,7 +168,7 @@ namespace data uint32_t m_PublishedTimestamp = 0; bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; - CryptoKeyType m_EncryptionType = CRYPTO_KEY_TYPE_ELGAMAL; + CryptoKeyType m_EncryptionType; std::shared_ptr m_Encryptor; // for standardLS2 }; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 69b26cab..a14588a8 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -25,7 +25,7 @@ namespace client I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), - m_Owner (owner), m_Identity (identity) + m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()) { } @@ -581,7 +581,10 @@ namespace client } // TODO: support multiple keys if (currentKey) + { m_Destination->SetEncryptionPrivateKey (currentKey); + m_Destination->SetEncryptionType (currentKeyType); + } m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index d4e05b51..68b4415a 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -73,12 +73,14 @@ namespace client void Stop (); void SetEncryptionPrivateKey (const uint8_t * key); + void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession 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) const; + i2p::data::CryptoKeyType GetEncryptionType () const { return m_EncryptionKeyType; }; std::shared_ptr GetIdentity () const { return m_Identity; }; protected: @@ -98,6 +100,7 @@ namespace client std::shared_ptr m_Owner; std::shared_ptr m_Identity; uint8_t m_EncryptionPrivateKey[256]; + i2p::data::CryptoKeyType m_EncryptionKeyType; std::shared_ptr m_Decryptor; uint64_t m_LeaseSetExpirationTime; }; From 32e2f0b1faf4897db307873bcb2f7ea29c2c54f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 15 Feb 2020 16:30:10 -0500 Subject: [PATCH 0206/2950] correct termination of streaming destination --- libi2pd/Streaming.cpp | 6 ++++-- libi2pd/Streaming.h | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 4f943912..d666d786 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -86,13 +86,13 @@ namespace stream LogPrint (eLogDebug, "Streaming: Stream deleted"); } - void Stream::Terminate () + void Stream::Terminate () // shoudl be called from StreamingDestination::Stop only { m_AckSendTimer.cancel (); m_ReceiveTimer.cancel (); m_ResendTimer.cancel (); //CleanUp (); /* Need to recheck - broke working on windows */ - m_LocalDestination.DeleteStream (shared_from_this ()); + //m_LocalDestination.DeleteStream (shared_from_this ()); } void Stream::CleanUp () @@ -989,6 +989,8 @@ namespace stream m_PendingIncomingStreams.clear (); { std::unique_lock l(m_StreamsMutex); + for (auto it: m_Streams) + it.second->Terminate (); m_Streams.clear (); m_IncomingStreams.clear (); } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 49962507..3424bb2d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -180,7 +180,6 @@ namespace stream int GetWindowSize () const { return m_WindowSize; }; int GetRTT () const { return m_RTT; }; - /** don't call me */ void Terminate (); private: From 88594887f9545459cc286b15456ac01b74a5061e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 16 Feb 2020 17:44:36 -0500 Subject: [PATCH 0207/2950] fixed qt build --- qt/i2pd_qt/i2pd_qt.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 15565c5c..adc2297d 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -62,6 +62,8 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/TunnelGateway.cpp \ ../../libi2pd/TunnelPool.cpp \ ../../libi2pd/util.cpp \ + ../../libi2pd/Elligator.cpp \ + ../../libi2pd/ECIESX25519AEADRatchetSession.cpp \ ../../libi2pd_client/AddressBook.cpp \ ../../libi2pd_client/BOB.cpp \ ../../libi2pd_client/ClientContext.cpp \ @@ -147,6 +149,8 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/TunnelPool.h \ ../../libi2pd/util.h \ ../../libi2pd/version.h \ + ../../libi2pd/Elligator.h \ + ../../libi2pd/ECIESX25519AEADRatchetSession.h \ ../../libi2pd_client/AddressBook.h \ ../../libi2pd_client/BOB.h \ ../../libi2pd_client/ClientContext.h \ From 47f384a0e093fb3e9b090b137bc0604565fdf412 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 17 Feb 2020 15:14:35 -0500 Subject: [PATCH 0208/2950] postpone SAM destination termination --- libi2pd_client/SAM.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 138e39cf..d0942221 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1161,6 +1161,15 @@ namespace client session->localDestination->Release (); session->localDestination->StopAcceptingStreams (); session->CloseStreams (); + if (m_IsSingleThread) + { + auto timer = std::make_shared(GetService ()); + timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds + timer->async_wait ([timer, session](const boost::system::error_code& ecode) + { + // session's destructor is called here + }); + } } } From 24b48e5d50d2a7aabe68c6ef5e2ef2df069153fd Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 18 Feb 2020 17:45:04 -0500 Subject: [PATCH 0209/2950] reseeds update --- .../reseed/backup_at_mail.i2p.crt | 32 ------------------- libi2pd/Config.cpp | 3 +- 2 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 contrib/certificates/reseed/backup_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/backup_at_mail.i2p.crt b/contrib/certificates/reseed/backup_at_mail.i2p.crt deleted file mode 100644 index 73b08eaa..00000000 --- a/contrib/certificates/reseed/backup_at_mail.i2p.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFfTCCA2WgAwIBAgIEOprmhjANBgkqhkiG9w0BAQ0FADBvMQswCQYDVQQGEwJY -WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt -b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEYMBYGA1UEAwwPYmFja3VwQG1haWwu -aTJwMB4XDTEzMTAxMzEzNDQ1NVoXDTIzMTAxMzEzNDQ1NVowbzELMAkGA1UEBhMC -WFgxCzAJBgNVBAgTAlhYMQswCQYDVQQHEwJYWDEeMBwGA1UEChMVSTJQIEFub255 -bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGDAWBgNVBAMMD2JhY2t1cEBtYWls -LmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIoAkobXwk/Enf1d -roHyqCyvcJfZJVTwb/LgYWAvCBMCr+RGqlSgtk3g69Y3I0xU08fD2kGt3r5Pwsbr -omXIbJAcccyLqmQ5QX6QgL+X9VpMDp9C4h2RogCrqLBAWw4cuZ4RS9VCpP1Yis7H -uejYqENP86p7BsRnuW/4cYnfunAdMpss4LpRGQXt1nTX+kfgCYgnKFbFqwAHt7yV -Ds+Pe6FuBHPlp+sc1amKRcUnSvhXLsv43VicnT7xYL/kUsN83wrtHA3B4aGDx3aA -3/EzuRmIXQB0BlTZILMEyYwG/nc4OsW82QYrvEZ9BIg9A4lF/wS/KZCICPxLF2zo -dGjnmlgkiA4s8eO+va/ElHyELjckVXqmG1eXHhSkEsDvOQJy01IUuwLinvq7cUbJ -HfJBZJllEg+sLDCv3FkEqN+XjBNFfQN4oNew4w6IPY6YH1INVB9LL0Cmdu4DudLv -TY8OcI8eSfez3hmm+pYQ23PJRYYnvRDnRECyIWBegkckWRh8U/WvZUYUvETK6EDl -/0KpTtfzX6MqHA5D6bTAB8Y3ijGMLrZ/B5vj5yCoZbLiGme9X2moR2k1LEhdhtzV -exsqezCpg6dn48FTX7mHjvR5/r4kz2jqBGmdPUWIIxnjFUzDUK3llVQiHihleHpe -jL4LqnhBGKWFRTaVwaIkBG4zAfIzAgMBAAGjITAfMB0GA1UdDgQWBBQNkfW7bSMl -1/4KDbgwrkf9x1Zu/TANBgkqhkiG9w0BAQ0FAAOCAgEAGg3a3rTf0EznQocmio0T -5gCoL0n8h6yKW/PyPAIELrd9wiYjhJFcWvMTcJJJnVqmAL5vpvhaAFVtAfx70MGa -0DZ7FvytK5hEfF4IqOFDyEEVGJR5rIpVK4MeI1nmwEsxdbW+FhODjtRzgYO8XBME -Xj4aY1FWg9vxc3reUj6PSFsZtsB0aLiRgL9JDovJIiRw0Uqr1v2wXBte5yVCxDge -vTREZtpK4cKetoOa68pwSXI32JwKE18j6bfdKVBCcYQKlKP/3gHGduaDrQv3w32S -DRym5s6MREeTUOtAw4wq46KpdOX8yyAqJPrCfMwS6ORd3t+egqOw0PUnsqb97w4O -lUtrRYvb2cOj60SmRx4vJvItyuHbKqIK7o2e1RcUZPXYoAVx2ww4XB2Wk4D7LSAs -cS7nLj8yAqzJ2qqtBzxu+zILJtkVa12dKF0xmS0BxBp4sCYiBtmAVE8AWQqEuSHA -FrMWqoXcjcfdvvyX487FFWWUE7ZBIn0hee2sK9J9+SPtqczJaN7TF3K3nzo65WJG -1epltmq2Ugjb67Gz7v4y7H23DJ/qhm8yLtCHTj69HTta5I08j6Kut924WLZaiMO/ -4YoEL5AE63X0sxYibKFQiq7FW5nUJA280GRlY3xSMFzlB2ggazrUV3YAWVDhfdnI -flpzWXkFM2D36OUaubfe9YY= ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 9d32cc72..4ce51954 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -191,9 +191,10 @@ namespace config { "https://reseed.i2p-projekt.de/," "https://i2p.mooo.com/netDb/," "https://netdb.i2p2.no/," + "https://reseed.i2p2.no/," + "https://reseed2.i2p2.no/," // "https://us.reseed.i2p2.no:444/," // mamoth's shit // "https://uk.reseed.i2p2.no:444/," // mamoth's shit - "https://download.xxlspeed.com/," "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," From f392edd66cafc374a40fed98bcea6c8d58bb88c8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Feb 2020 13:27:28 -0500 Subject: [PATCH 0210/2950] single thread SAM by default --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 4ce51954..b0f7572d 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -131,7 +131,7 @@ namespace config { ("sam.enabled", value()->default_value(true), "Enable or disable SAM Application bridge") ("sam.address", value()->default_value("127.0.0.1"), "SAM listen address") ("sam.port", value()->default_value(7656), "SAM listen port") - ("sam.singlethread", value()->default_value(false), "Sessions run in the SAM bridge's thread") + ("sam.singlethread", value()->default_value(true), "Sessions run in the SAM bridge's thread") ; options_description bob("BOB options"); From 50450923dfabdfac612210a2f0fa3badcaf213ca Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 19 Feb 2020 20:51:32 -0500 Subject: [PATCH 0211/2950] don't add extra , to result string --- daemon/I2PControl.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 572292ee..acf054f1 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -394,13 +394,15 @@ namespace client void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) { + bool first = true; for (auto it = params.begin (); it != params.end (); it++) { LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first); auto it1 = m_RouterInfoHandlers.find (it->first); if (it1 != m_RouterInfoHandlers.end ()) { - if (it != params.begin ()) results << ","; + if (!first) results << ","; + else first = false; (this->*(it1->second))(results); } else From 9c9b723cf5b5f4e8a1cc1bea3cc2d505a796f7af Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Feb 2020 15:44:09 -0500 Subject: [PATCH 0212/2950] delete expired ECIESX25519AEADRatchet sessions and tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 1 + libi2pd/ECIESX25519AEADRatchetSession.h | 8 +++++ libi2pd/Garlic.cpp | 36 +++++++++++++++++++++-- libi2pd/Garlic.h | 1 + 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7f17130c..d2d07343 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -401,6 +401,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len, int index) { + m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); switch (m_State) { case eSessionStateEstablished: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 90e21e8a..e5836cd4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -55,6 +55,10 @@ namespace garlic eECIESx25519BlkPadding = 254 }; + + const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after + const int ECIESX25519_EXPIRATION_TIMEOUT = 600; // in seconds + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { enum SessionState @@ -81,6 +85,9 @@ namespace garlic if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } + bool IsExpired (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } + bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } + private: void ResetKeys (); @@ -109,6 +116,7 @@ namespace garlic uint8_t m_Aepk[32]; // Alice's ephemeral keys TODO: for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; + uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; int m_NumReceiveTags = 0; std::unique_ptr m_Destination;// TODO: might not need it diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 14154eaf..4828ad67 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -739,7 +739,25 @@ namespace garlic ++it; } } - // TODO: cleanup ECIESx25519 + // ECIESx25519 + for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) + { + if (ts > it->second.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT) + it = m_ECIESx25519Tags.erase (it); + else + ++it; + } + + for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) + { + if (it->second->IsExpired (ts)) + { + it->second->SetOwner (nullptr); + it = m_ECIESx25519Sessions.erase (it); + } + else + ++it; + } } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) @@ -940,12 +958,24 @@ namespace garlic void GarlicDestination::AddECIESx25519SessionTag (int index, uint64_t tag, ECIESX25519AEADRatchetSessionPtr session) { - m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexSession{index, session}); + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexSession{index, session, i2p::util::GetSecondsSinceEpoch ()}); } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) { - m_ECIESx25519Sessions.emplace (staticKey, session); + i2p::data::Tag<32> staticKeyTag (staticKey); + auto it = m_ECIESx25519Sessions.find (staticKeyTag); + if (it != m_ECIESx25519Sessions.end ()) + { + if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ())) + m_ECIESx25519Sessions.erase (it); + else + { + LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); + return; + } + } + m_ECIESx25519Sessions.emplace (staticKeyTag, session); } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 4fdb299e..9c256b48 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -202,6 +202,7 @@ namespace garlic { int index; ECIESX25519AEADRatchetSessionPtr session; + uint64_t creationTime; // seconds since epoch }; class GarlicDestination: public i2p::data::LocalDestination From 7168738835012d109a67bf9796880fa201a5072d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Feb 2020 21:05:07 -0500 Subject: [PATCH 0213/2950] check ctx for null --- libi2pd/CryptoKey.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 9881ebef..878e984a 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -14,6 +14,7 @@ namespace crypto void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { + if (!ctx) return; ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding); } @@ -24,6 +25,7 @@ namespace crypto bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding) { + if (!ctx) return false; return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding); } From 91919c6d64ad9ab70329404441820fcdf2795d03 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 20 Feb 2020 21:07:45 -0500 Subject: [PATCH 0214/2950] check if both sides are ECIESx25519 --- libi2pd/Garlic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 4828ad67..c7d0e21d 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -658,7 +658,8 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET && + GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; From 5c308026ac280f699a01e0944deaac3b7698cf30 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Fri, 21 Feb 2020 09:12:57 +0200 Subject: [PATCH 0215/2950] Pass -dead_strip -dead_strip_dylibs -bind_at_load on macOS --- qt/i2pd_qt/i2pd_qt.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index adc2297d..caa0bd50 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -210,6 +210,9 @@ macx { LIBS += $$BOOSTROOT/lib/libboost_filesystem.a LIBS += $$BOOSTROOT/lib/libboost_program_options.a LIBS += $$UPNPROOT/lib/libminiupnpc.a + LIBS += -Wl,-dead_strip + LIBS += -Wl,-dead_strip_dylibs + LIBS += -Wl,-bind_at_load } linux:!android { From 5115c27e72e85ebf07e146957a3e1fbeca4f70a9 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 25 Feb 2020 11:15:30 -0500 Subject: [PATCH 0216/2950] 2.30.0 --- ChangeLog | 16 ++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 37 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07110fe2..293764a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,22 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.30.0] - 2020-02-25 +### Added +- Single threaded SAM +- Experimental support of ECIES-X25519-AEAD-Ratchet crypto type +### Changed +- Minimal MTU size is 1280 for ipv6 +- Use unordered_map instead map for destination's sessions and tags list +- Use std::shuffle instead std::random_shuffle +- SAM is single threaded by default +- Reseeds list +### Fixed +- Correct termination of streaming destination +- Extra ',' in RouterInfo response in I2PControl +- SAM crash on session termination +- Storage for Android 10 + ## [2.29.0] - 2019-10-21 ### Added - Client auth flag for b33 address diff --git a/Win32/installer.iss b/Win32/installer.iss index 736c7038..d4f6f247 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.29.0" +#define I2Pd_ver "2.30.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 291d90ea..844615f8 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2290 - versionName "2.29.0" + versionCode 2300 + versionName "2.30.0" ndk { abiFilters 'armeabi-v7a' abiFilters 'x86' diff --git a/appveyor.yml b/appveyor.yml index f6eee9ab..8c4a1a9d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.29.0.{build} +version: 2.30.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 31b8d4a5..89e3cee9 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.29.0 +Version: 2.30.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -110,6 +110,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Feb 25 2020 orignal - 2.30.0 +- update to 2.30.0 + * Mon Oct 21 2019 orignal - 2.29.0 - update to 2.29.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 3db99af0..0f91c03b 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.29.0 +Version: 2.30.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -108,6 +108,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Feb 25 2020 orignal - 2.30.0 +- update to 2.30.0 + * Mon Oct 21 2019 orignal - 2.29.0 - update to 2.29.0 diff --git a/debian/changelog b/debian/changelog index f5f98680..da177cbd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.30.0-1) unstable; urgency=medium + + * updated to version 2.30.0/0.9.45 + + -- orignal Tue, 25 Feb 2020 16:00:00 +0000 + i2pd (2.29.0-1) unstable; urgency=medium * updated to version 2.29.0/0.9.43 diff --git a/libi2pd/version.h b/libi2pd/version.h index 2e876fdb..36fbe2ca 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 29 +#define I2PD_VERSION_MINOR 30 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 44 +#define I2P_VERSION_MICRO 45 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index e6cc81d3..09bcf9ac 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From a0d6c654cc86faa2a045f60c03be0ef7c3950237 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 25 Feb 2020 20:08:50 +0300 Subject: [PATCH 0217/2950] 2.30.0 Signed-off-by: R4SAS --- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 09bcf9ac..00b6974a 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,7 +35,7 @@ - + From 2c6e041ae2f1f930fd953013506151c829ee61ce Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 26 Feb 2020 13:41:35 +0000 Subject: [PATCH 0218/2950] rpm: make package buildable on mageia cauldron (#1476) --- contrib/rpm/i2pd-git.spec | 12 ++++++++++-- contrib/rpm/i2pd.spec | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 89e3cee9..f9571ca0 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -55,14 +55,22 @@ cd build %endif %endif +%if 0%{?mageia} > 7 +pushd build make %{?_smp_mflags} +popd +%else +make %{?_smp_mflags} +%endif %install -cd build +pushd build + %if 0%{?mageia} -cd build +pushd build %endif + chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 0f91c03b..b3cca8ab 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -53,14 +53,22 @@ cd build %endif %endif +%if 0%{?mageia} > 7 +pushd build make %{?_smp_mflags} +popd +%else +make %{?_smp_mflags} +%endif %install -cd build +pushd build + %if 0%{?mageia} -cd build +pushd build %endif + chrpath -d i2pd install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf From 00db527377cfbbee1767766828daf46b81593ae0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 27 Feb 2020 14:58:06 +0300 Subject: [PATCH 0219/2950] drop websockets support Signed-off-by: R4SAS --- Makefile | 4 - build/CMakeLists.txt | 11 - daemon/Daemon.cpp | 87 ++--- libi2pd/Config.cpp | 8 - libi2pd/Event.cpp | 19 -- libi2pd/Event.h | 33 +- libi2pd/NTCPSession.cpp | 6 - libi2pd/SSUData.cpp | 6 - libi2pd/Transports.cpp | 16 - libi2pd/Tunnel.cpp | 21 -- libi2pd/Tunnel.h | 38 +-- libi2pd/TunnelPool.cpp | 15 - libi2pd_client/ClientContext.h | 2 +- libi2pd_client/WebSocks.cpp | 488 +--------------------------- libi2pd_client/Websocket.cpp | 195 ----------- libi2pd_client/Websocket.h | 28 -- qt/i2pd_qt/generalsettingswidget.ui | 115 ------- qt/i2pd_qt/i2pd_qt.pro | 2 - qt/i2pd_qt/mainwindow.cpp | 4 - 19 files changed, 57 insertions(+), 1041 deletions(-) delete mode 100644 libi2pd_client/Websocket.cpp delete mode 100644 libi2pd_client/Websocket.h diff --git a/Makefile b/Makefile index 3dfaaade..a814aecf 100644 --- a/Makefile +++ b/Makefile @@ -27,10 +27,6 @@ else LD_DEBUG = -s endif -ifeq ($(WEBSOCKETS),1) - NEEDED_CXXFLAGS += -DWITH_EVENTS -endif - ifneq (, $(findstring darwin, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp ifeq ($(HOMEBREW),1) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2577fb1b..324ac468 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -20,7 +20,6 @@ option(WITH_MESHNET "Build for cjdns test network" OFF) option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) option(WITH_I2LUA "Build for i2lua" OFF) -option(WITH_WEBSOCKETS "Build with websocket ui" OFF) # paths set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) @@ -86,11 +85,6 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp" ) -if (WITH_WEBSOCKETS) - add_definitions(-DWITH_EVENTS) - find_package(websocketpp REQUIRED) -endif () - if (WIN32 OR MSYS) list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") endif () @@ -127,10 +121,6 @@ set (CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp" ) -if(WITH_WEBSOCKETS) - list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp") -endif () - add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") @@ -427,7 +417,6 @@ message(STATUS " MESHNET : ${WITH_MESHNET}") message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS " I2LUA : ${WITH_I2LUA}") -message(STATUS " WEBSOCKETS : ${WITH_WEBSOCKETS}") message(STATUS "---------------------------------------") #Handle paths nicely diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 0ea45bb7..2c6b34d7 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -26,9 +26,6 @@ #include "Timestamp.h" #include "util.h" -#include "Event.h" -#include "Websocket.h" - namespace i2p { namespace util @@ -43,9 +40,6 @@ namespace i2p std::unique_ptr m_I2PControlService; std::unique_ptr UPnP; std::unique_ptr m_NTPSync; -#ifdef WITH_EVENTS - std::unique_ptr m_WebsocketServer; -#endif }; Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {} @@ -62,12 +56,12 @@ namespace i2p return service; } - bool Daemon_Singleton::init(int argc, char* argv[]) { - return init(argc, argv, nullptr); - } + bool Daemon_Singleton::init(int argc, char* argv[]) { + return init(argc, argv, nullptr); + } - bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr logstream) - { + bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr logstream) + { i2p::config::Init(); i2p::config::ParseCmdline(argc, argv); @@ -110,10 +104,10 @@ namespace i2p logs = "file"; i2p::log::Logger().SetLogLevel(loglevel); - if (logstream) { - LogPrint(eLogInfo, "Log: will send messages to std::ostream"); - i2p::log::Logger().SendTo (logstream); - } else if (logs == "file") { + if (logstream) { + LogPrint(eLogInfo, "Log: will send messages to std::ostream"); + i2p::log::Logger().SendTo (logstream); + } else if (logs == "file") { if (logfile == "") logfile = i2p::fs::DataDirPath("i2pd.log"); LogPrint(eLogInfo, "Log: will send messages to ", logfile); @@ -127,7 +121,7 @@ namespace i2p // use stdout -- default } - LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); + LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); @@ -151,8 +145,8 @@ namespace i2p LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port); i2p::context.UpdatePort (port); } - i2p::context.SetSupportsV6 (ipv6); - i2p::context.SetSupportsV4 (ipv4); + i2p::context.SetSupportsV6 (ipv6); + i2p::context.SetSupportsV4 (ipv4); bool ntcp; i2p::config::GetOption("ntcp", ntcp); i2p::context.PublishNTCPAddress (ntcp, !ipv6); @@ -233,15 +227,15 @@ namespace i2p if (family.length () > 0) LogPrint(eLogInfo, "Daemon: family set to ", family); - bool trust; i2p::config::GetOption("trust.enabled", trust); - if (trust) - { - LogPrint(eLogInfo, "Daemon: explicit trust enabled"); - std::string fam; i2p::config::GetOption("trust.family", fam); + bool trust; i2p::config::GetOption("trust.enabled", trust); + if (trust) + { + LogPrint(eLogInfo, "Daemon: explicit trust enabled"); + std::string fam; i2p::config::GetOption("trust.family", fam); std::string routers; i2p::config::GetOption("trust.routers", routers); bool restricted = false; - if (fam.length() > 0) - { + if (fam.length() > 0) + { std::set fams; size_t pos = 0, comma; do @@ -253,7 +247,7 @@ namespace i2p while (comma != std::string::npos); i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; - } + } if (routers.length() > 0) { std::set idents; size_t pos = 0, comma; @@ -272,14 +266,15 @@ namespace i2p } if(!restricted) LogPrint(eLogError, "Daemon: no trusted routers of families specififed"); - } - bool hidden; i2p::config::GetOption("trust.hidden", hidden); - if (hidden) - { - LogPrint(eLogInfo, "Daemon: using hidden mode"); - i2p::data::netdb.SetHidden(true); - } - return true; + } + + bool hidden; i2p::config::GetOption("trust.hidden", hidden); + if (hidden) + { + LogPrint(eLogInfo, "Daemon: using hidden mode"); + i2p::data::netdb.SetHidden(true); + } + return true; } bool Daemon_Singleton::start() @@ -322,7 +317,7 @@ namespace i2p bool http; i2p::config::GetOption("http.enabled", http); if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort); d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); @@ -344,26 +339,11 @@ namespace i2p d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); } -#ifdef WITH_EVENTS - - bool websocket; i2p::config::GetOption("websockets.enabled", websocket); - if(websocket) { - std::string websocketAddr; i2p::config::GetOption("websockets.address", websocketAddr); - uint16_t websocketPort; i2p::config::GetOption("websockets.port", websocketPort); - LogPrint(eLogInfo, "Daemon: starting Websocket server at ", websocketAddr, ":", websocketPort); - d.m_WebsocketServer = std::unique_ptr(new i2p::event::WebsocketServer (websocketAddr, websocketPort)); - d.m_WebsocketServer->Start(); - i2p::event::core.SetListener(d.m_WebsocketServer->ToListener()); - } -#endif return true; } bool Daemon_Singleton::stop() { -#ifdef WITH_EVENTS - i2p::event::core.SetListener(nullptr); -#endif LogPrint(eLogInfo, "Daemon: shutting down"); LogPrint(eLogInfo, "Daemon: stopping Client"); i2p::client::context.Stop(); @@ -397,13 +377,6 @@ namespace i2p d.m_I2PControlService->Stop (); d.m_I2PControlService = nullptr; } -#ifdef WITH_EVENTS - if (d.m_WebsocketServer) { - LogPrint(eLogInfo, "Daemon: stopping Websocket server"); - d.m_WebsocketServer->Stop(); - d.m_WebsocketServer = nullptr; - } -#endif i2p::crypto::TerminateCrypto (); i2p::log::Logger().Stop(); diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b0f7572d..13cd772d 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -218,13 +218,6 @@ namespace config { ("trust.hidden", value()->default_value(false), "Should we hide our router from other routers?") ; - options_description websocket("Websocket Options"); - websocket.add_options() - ("websockets.enabled", value()->default_value(false), "Enable websocket server") - ("websockets.address", value()->default_value("127.0.0.1"), "Address to bind websocket server on") - ("websockets.port", value()->default_value(7666), "Port to bind websocket server on") - ; - options_description exploratory("Exploratory Options"); exploratory.add_options() ("exploratory.inbound.length", value()->default_value(2), "Exploratory inbound tunnel length") @@ -274,7 +267,6 @@ namespace config { .add(reseed) .add(addressbook) .add(trust) - .add(websocket) .add(exploratory) .add(ntcp2) .add(nettime) diff --git a/libi2pd/Event.cpp b/libi2pd/Event.cpp index 9c75f95b..90c5ed97 100644 --- a/libi2pd/Event.cpp +++ b/libi2pd/Event.cpp @@ -5,10 +5,6 @@ namespace i2p { namespace event { -#ifdef WITH_EVENTS - EventCore core; -#endif - void EventCore::SetListener(EventListener * l) { m_listener = l; @@ -44,18 +40,3 @@ namespace i2p } } } - -void QueueIntEvent(const std::string & type, const std::string & ident, uint64_t val) -{ -#ifdef WITH_EVENTS - i2p::event::core.CollectEvent(type, ident, val); -#endif -} - -void EmitEvent(const EventType & e) -{ -#if WITH_EVENTS - i2p::event::core.QueueEvent(e); -#endif -} - diff --git a/libi2pd/Event.h b/libi2pd/Event.h index a8b46a4b..74eed1db 100644 --- a/libi2pd/Event.h +++ b/libi2pd/Event.h @@ -14,40 +14,33 @@ namespace i2p { namespace event { - class EventListener { + class EventListener { public: virtual ~EventListener() {}; virtual void HandleEvent(const EventType & ev) = 0; - /** @brief handle collected event when pumped */ - virtual void HandlePumpEvent(const EventType & ev, const uint64_t & val) = 0; + /** @brief handle collected event when pumped */ + virtual void HandlePumpEvent(const EventType & ev, const uint64_t & val) = 0; }; class EventCore { public: void QueueEvent(const EventType & ev); - void CollectEvent(const std::string & type, const std::string & ident, uint64_t val); + void CollectEvent(const std::string & type, const std::string & ident, uint64_t val); void SetListener(EventListener * l); - void PumpCollected(EventListener * l); + void PumpCollected(EventListener * l); private: - std::mutex m_collect_mutex; - struct CollectedEvent - { - std::string Key; - std::string Ident; - uint64_t Val; - }; - std::map m_collected; + std::mutex m_collect_mutex; + struct CollectedEvent + { + std::string Key; + std::string Ident; + uint64_t Val; + }; + std::map m_collected; EventListener * m_listener = nullptr; }; -#ifdef WITH_EVENTS - extern EventCore core; -#endif } } - -void QueueIntEvent(const std::string & type, const std::string & ident, uint64_t val); -void EmitEvent(const EventType & ev); - #endif diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 7e8ecd15..9711ffb0 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -14,9 +14,6 @@ #include "NTCPSession.h" #include "HTTP.h" #include "util.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif using namespace i2p::crypto; @@ -649,9 +646,6 @@ namespace transport { if (!m_NextMessage->IsExpired ()) { -#ifdef WITH_EVENTS - QueueIntEvent("transport.recvmsg", GetIdentHashBase64(), 1); -#endif m_Handler.PutNextMessage (m_NextMessage); } else diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 3ad5e769..add58739 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -5,9 +5,6 @@ #include "NetDb.hpp" #include "SSU.h" #include "SSUData.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif namespace i2p { @@ -241,9 +238,6 @@ namespace transport m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch (); if (!msg->IsExpired ()) { -#ifdef WITH_EVENTS - QueueIntEvent("transport.recvmsg", m_Session.GetIdentHashBase64(), 1); -#endif m_Handler.PutNextMessage (msg); } else diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 42a605a4..ee99acf7 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -6,10 +6,6 @@ #include "Transports.h" #include "Config.h" #include "HTTP.h" -#ifdef WITH_EVENTS -#include "Event.h" -#include "util.h" -#endif using namespace i2p::data; @@ -346,9 +342,6 @@ namespace transport void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) { -#ifdef WITH_EVENTS - QueueIntEvent("transport.send", ident.ToBase64(), msgs.size()); -#endif m_Service->post (std::bind (&Transports::PostMessages, this, ident, msgs)); } @@ -597,9 +590,6 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { -#ifdef WITH_EVENTS - EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "false"}}); -#endif bool sendDatabaseStore = true; if (it->second.delayedMessages.size () > 0) { @@ -625,9 +615,6 @@ namespace transport session->Done(); return; } -#ifdef WITH_EVENTS - EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "true"}}); -#endif session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore std::unique_lock l(m_PeersMutex); m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} })); @@ -642,9 +629,6 @@ namespace transport auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; auto ident = remoteIdentity->GetIdentHash (); -#ifdef WITH_EVENTS - EmitEvent({{"type" , "transport.disconnected"}, {"ident", ident.ToBase64()}}); -#endif auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 00b0a12c..9dacddac 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -14,9 +14,6 @@ #include "Config.h" #include "Tunnel.h" #include "TunnelPool.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif namespace i2p { @@ -35,9 +32,6 @@ namespace tunnel void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr outboundTunnel) { -#ifdef WITH_EVENTS - std::string peers = i2p::context.GetIdentity()->GetIdentHash().ToBase64(); -#endif auto numHops = m_Config->GetNumHops (); int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops; auto msg = NewI2NPShortMessage (); @@ -64,15 +58,9 @@ namespace tunnel hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx); hop->recordIndex = idx; i++; -#ifdef WITH_EVENTS - peers += ":" + hop->ident->GetIdentHash().ToBase64(); -#endif hop = hop->next; } BN_CTX_free (ctx); -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.build", this, peers); -#endif // fill up fake records with random data for (int i = numHops; i < numRecords; i++) { @@ -207,9 +195,6 @@ namespace tunnel void Tunnel::SetState(TunnelState state) { m_State = state; -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.state", this, state); -#endif } @@ -614,9 +599,6 @@ namespace tunnel hop = hop->next; } } -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed); -#endif // for i2lua if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout); // delete @@ -628,9 +610,6 @@ namespace tunnel break; case eTunnelStateBuildFailed: LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted"); -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed); -#endif // for i2lua if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected); diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 3244faad..66b620b8 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -25,42 +25,28 @@ namespace i2p { namespace tunnel { - - template - static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) - { -#ifdef WITH_EVENTS - EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}}); -#else + template + static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) + { (void) ev; (void) t; -#endif - } + } - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) - { -#ifdef WITH_EVENTS - EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", std::to_string(val)}, {"inbound", std::to_string(t->IsInbound())}}); -#else + template + static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) + { (void) ev; (void) t; (void) val; -#endif - } + } - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) - { -#ifdef WITH_EVENTS - EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", val}, {"inbound", std::to_string(t->IsInbound())}}); -#else + template + static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) + { (void) ev; (void) t; (void) val; -#endif - } - + } const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7a1325fe..b3e3c7d2 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -11,9 +11,6 @@ #include "Tunnel.h" #include "TunnelPool.h" #include "Destination.h" -#ifdef WITH_EVENTS -#include "Event.h" -#endif namespace i2p { @@ -86,9 +83,6 @@ namespace tunnel { if (!m_IsActive) return; { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.created", createdTunnel); -#endif std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.insert (createdTunnel); } @@ -102,9 +96,6 @@ namespace tunnel { if (expiredTunnel) { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.expired", expiredTunnel); -#endif expiredTunnel->SetTunnelPool (nullptr); for (auto& it: m_Tests) if (it.second.second == expiredTunnel) it.second.second = nullptr; @@ -118,9 +109,6 @@ namespace tunnel { if (!m_IsActive) return; { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.created", createdTunnel); -#endif std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } @@ -133,9 +121,6 @@ namespace tunnel { if (expiredTunnel) { -#ifdef WITH_EVENTS - EmitTunnelEvent("tunnels.expired", expiredTunnel); -#endif expiredTunnel->SetTunnelPool (nullptr); for (auto& it: m_Tests) if (it.second.first == expiredTunnel) it.second.first = nullptr; diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index a239035f..610914bf 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -37,7 +37,7 @@ namespace client const char I2P_CLIENT_TUNNEL_CRYPTO_TYPE[] = "cryptotype"; 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_CONNECT_TIMEOUT[] = "connecttimeout"; 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/WebSocks.cpp b/libi2pd_client/WebSocks.cpp index c80feac8..95abf455 100644 --- a/libi2pd_client/WebSocks.cpp +++ b/libi2pd_client/WebSocks.cpp @@ -2,491 +2,6 @@ #include "Log.h" #include -#ifdef WITH_EVENTS -#include "ClientContext.h" -#include "Identity.h" -#include "Destination.h" -#include "Streaming.h" -#include - -#include -#include - -#include -#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -#if !GCC47_BOOST149 -#include -#endif - -namespace i2p -{ -namespace client -{ - typedef websocketpp::server WebSocksServerImpl; - - typedef std::function)> StreamConnectFunc; - - - struct IWebSocksConn : public I2PServiceHandler - { - IWebSocksConn(I2PService * parent) : I2PServiceHandler(parent) {} - virtual void Close() = 0; - virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) = 0; - }; - - typedef std::shared_ptr WebSocksConn_ptr; - - WebSocksConn_ptr CreateWebSocksConn(const websocketpp::connection_hdl & conn, WebSocksImpl * parent); - - class WebSocksImpl - { - - typedef std::mutex mutex_t; - typedef std::unique_lock lock_t; - - typedef std::shared_ptr Destination_t; - public: - - typedef WebSocksServerImpl ServerImpl; - typedef ServerImpl::message_ptr MessagePtr; - - WebSocksImpl(const std::string & addr, int port) : - Parent(nullptr), - m_Run(false), - m_Addr(addr), - m_Port(port), - m_Thread(nullptr) - { - m_Server.init_asio(); - m_Server.set_open_handler(std::bind(&WebSocksImpl::ConnOpened, this, std::placeholders::_1)); - } - - void InitializeDestination(WebSocks * parent) - { - Parent = parent; - m_Dest = Parent->GetLocalDestination(); - } - - ServerImpl::connection_ptr GetConn(const websocketpp::connection_hdl & conn) - { - return m_Server.get_con_from_hdl(conn); - } - - void CloseConn(const websocketpp::connection_hdl & conn) - { - auto c = GetConn(conn); - if(c) c->close(websocketpp::close::status::normal, "closed"); - } - - void CreateStreamTo(const std::string & addr, int port, StreamConnectFunc complete) - { - auto & addressbook = i2p::client::context.GetAddressBook(); - auto a = addressbook.GetAddress (addr); - if (a && a->IsIdentHash ()) - { - // address found - m_Dest->CreateStream(complete, a->identHash, port); - } - else - { - // not found - complete(nullptr); - } - } - - void ConnOpened(websocketpp::connection_hdl conn) - { - auto ptr = CreateWebSocksConn(conn, this); - Parent->AddHandler(ptr); - m_Conns.push_back(ptr); - } - - void Start() - { - if(m_Run) return; // already started - m_Server.listen(boost::asio::ip::address::from_string(m_Addr), m_Port); - m_Server.start_accept(); - m_Run = true; - m_Thread = new std::thread([&] (){ - while(m_Run) { - try { - m_Server.run(); - } catch( std::exception & ex) { - LogPrint(eLogError, "Websocks runtime exception: ", ex.what()); - } - } - }); - m_Dest->Start(); - } - - void Stop() - { - for(const auto & conn : m_Conns) - conn->Close(); - - m_Dest->Stop(); - m_Run = false; - m_Server.stop(); - if(m_Thread) { - m_Thread->join(); - delete m_Thread; - } - m_Thread = nullptr; - } - - boost::asio::ip::tcp::endpoint GetLocalEndpoint() - { - return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(m_Addr), m_Port); - } - - i2p::datagram::DatagramDestination * GetDatagramDest() const - { - auto dgram = m_Dest->GetDatagramDestination(); - if(!dgram) dgram = m_Dest->CreateDatagramDestination(); - return dgram; - } - - WebSocks * Parent; - - private: - std::vector m_Conns; - bool m_Run; - ServerImpl m_Server; - std::string m_Addr; - int m_Port; - std::thread * m_Thread; - Destination_t m_Dest; - }; - - struct WebSocksConn : public IWebSocksConn , public std::enable_shared_from_this - { - enum ConnState - { - eWSCInitial, - eWSCTryConnect, - eWSCFailConnect, - eWSCOkayConnect, - eWSCDatagram, - eWSCClose, - eWSCEnd - }; - - typedef WebSocksServerImpl ServerImpl; - typedef ServerImpl::message_ptr Message_t; - typedef websocketpp::connection_hdl ServerConn; - typedef std::shared_ptr Destination_t; - typedef std::shared_ptr StreamDest_t; - typedef std::shared_ptr Stream_t; - - ServerConn m_Conn; - Stream_t m_Stream; - ConnState m_State; - WebSocksImpl * m_Parent; - std::string m_RemoteAddr; - int m_RemotePort; - uint8_t m_RecvBuf[2048]; - bool m_IsDatagram; - i2p::datagram::DatagramDestination * m_Datagram; - - WebSocksConn(const ServerConn & conn, WebSocksImpl * parent) : - IWebSocksConn(parent->Parent), - m_Conn(conn), - m_Stream(nullptr), - m_State(eWSCInitial), - m_Parent(parent), - m_IsDatagram(false), - m_Datagram(nullptr) - { - - } - - ~WebSocksConn() - { - Close(); - } - - void HandleDatagram(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) - { - auto conn = m_Parent->GetConn(m_Conn); - if(conn) - { - std::stringstream ss; - ss << from.GetIdentHash().ToBase32(); - ss << ".b32.i2p:"; - ss << std::to_string(fromPort); - ss << "\n"; - ss.write((char *)buf, len); - conn->send(ss.str()); - } - } - - void BeginDatagram() - { - m_Datagram = m_Parent->GetDatagramDest(); - m_Datagram->SetReceiver( - std::bind( - &WebSocksConn::HandleDatagram, - this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3, - std::placeholders::_4, - std::placeholders::_5), m_RemotePort); - } - - void EnterState(ConnState state) - { - LogPrint(eLogDebug, "websocks: state ", m_State, " -> ", state); - switch(m_State) - { - case eWSCInitial: - if (state == eWSCClose) { - m_State = eWSCClose; - // connection was opened but never used - LogPrint(eLogInfo, "websocks: connection closed but never used"); - Close(); - return; - } else if (state == eWSCTryConnect) { - // we will try to connect - m_State = eWSCTryConnect; - m_Parent->CreateStreamTo(m_RemoteAddr, m_RemotePort, std::bind(&WebSocksConn::ConnectResult, this, std::placeholders::_1)); - } else if (state == eWSCDatagram) { - if (m_RemotePort >= 0 && m_RemotePort <= 65535) - { - LogPrint(eLogDebug, "websocks: datagram mode initiated"); - m_State = eWSCDatagram; - BeginDatagram(); - SendResponse(""); - } - else - SendResponse("invalid port"); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCTryConnect: - if(state == eWSCOkayConnect) { - // we connected okay - LogPrint(eLogDebug, "websocks: connected to ", m_RemoteAddr, ":", m_RemotePort); - SendResponse(""); - m_State = eWSCOkayConnect; - } else if(state == eWSCFailConnect) { - // we did not connect okay - LogPrint(eLogDebug, "websocks: failed to connect to ", m_RemoteAddr, ":", m_RemotePort); - SendResponse("failed to connect"); - m_State = eWSCFailConnect; - EnterState(eWSCInitial); - } else if(state == eWSCClose) { - // premature close - LogPrint(eLogWarning, "websocks: websocket connection closed prematurely"); - m_State = eWSCClose; - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCFailConnect: - if (state == eWSCInitial) { - // reset to initial state so we can try connecting again - m_RemoteAddr = ""; - m_RemotePort = 0; - LogPrint(eLogDebug, "websocks: reset websocket conn to initial state"); - m_State = eWSCInitial; - } else if (state == eWSCClose) { - // we are going to close the connection - m_State = eWSCClose; - Close(); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCDatagram: - if(state != eWSCClose) { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - m_State = eWSCClose; - Close(); - return; - case eWSCOkayConnect: - if(state == eWSCClose) { - // graceful close - m_State = eWSCClose; - Close(); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - case eWSCClose: - if(state == eWSCEnd) { - LogPrint(eLogDebug, "websocks: socket ended"); - Kill(); - auto me = shared_from_this(); - Done(me); - } else { - LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state); - } - return; - default: - LogPrint(eLogError, "websocks: bad state ", m_State); - } - } - - void StartForwarding() - { - LogPrint(eLogDebug, "websocks: begin forwarding data"); - uint8_t b[1]; - m_Stream->Send(b, 0); - AsyncRecv(); - } - - void HandleAsyncRecv(const boost::system::error_code &ec, std::size_t n) - { - if(ec) { - // error - LogPrint(eLogWarning, "websocks: connection error ", ec.message()); - EnterState(eWSCClose); - } else { - // forward data - LogPrint(eLogDebug, "websocks recv ", n); - - std::string str((char*)m_RecvBuf, n); - auto conn = m_Parent->GetConn(m_Conn); - if(!conn) { - LogPrint(eLogWarning, "websocks: connection is gone"); - EnterState(eWSCClose); - return; - } - conn->send(str); - AsyncRecv(); - - } - } - - void AsyncRecv() - { - m_Stream->AsyncReceive( - boost::asio::buffer(m_RecvBuf, sizeof(m_RecvBuf)), - std::bind(&WebSocksConn::HandleAsyncRecv, this, std::placeholders::_1, std::placeholders::_2), 60); - } - - /** @brief send error message or empty string for success */ - void SendResponse(const std::string & errormsg) - { - boost::property_tree::ptree resp; - if(errormsg.size()) { - resp.put("error", errormsg); - resp.put("success", 0); - } else { - resp.put("success", 1); - } - std::ostringstream ss; - write_json(ss, resp); - auto conn = m_Parent->GetConn(m_Conn); - if(conn) conn->send(ss.str()); - } - - void ConnectResult(Stream_t stream) - { - m_Stream = stream; - if(m_State == eWSCClose) { - // premature close of websocket - Close(); - return; - } - if(m_Stream) { - // connect good - EnterState(eWSCOkayConnect); - StartForwarding(); - } else { - // connect failed - EnterState(eWSCFailConnect); - } - } - - virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) - { - (void) conn; - std::string payload = msg->get_payload(); - if(m_State == eWSCOkayConnect) - { - // forward to server - LogPrint(eLogDebug, "websocks: forward ", payload.size()); - m_Stream->Send((uint8_t*)payload.c_str(), payload.size()); - } else if (m_State == eWSCInitial) { - // recv connect request - auto itr = payload.find(":"); - if(itr == std::string::npos) { - // no port - m_RemotePort = 0; - m_RemoteAddr = payload; - } else { - // includes port - m_RemotePort = std::stoi(payload.substr(itr+1)); - m_RemoteAddr = payload.substr(0, itr); - } - m_IsDatagram = m_RemoteAddr == "DATAGRAM"; - if(m_IsDatagram) - EnterState(eWSCDatagram); - else - EnterState(eWSCTryConnect); - } else if (m_State == eWSCDatagram) { - // send datagram - // format is "host:port\npayload" - auto idx = payload.find("\n"); - std::string line = payload.substr(0, idx); - auto itr = line.find(":"); - auto & addressbook = i2p::client::context.GetAddressBook(); - std::string addr; - int port = 0; - if (itr == std::string::npos) - { - addr = line; - } - else - { - addr = line.substr(0, itr); - port = std::atoi(line.substr(itr+1).c_str()); - } - auto a = addressbook.GetAddress (addr); - if (a && a->IsIdentHash ()) - { - const char * data = payload.c_str() + idx + 1; - size_t len = payload.size() - (1 + line.size()); - m_Datagram->SendDatagramTo((const uint8_t*)data, len, a->identHash, m_RemotePort, port); - } - } else { - // wtf? - LogPrint(eLogWarning, "websocks: got message in invalid state ", m_State); - } - } - - virtual void Close() - { - if(m_State == eWSCClose) { - LogPrint(eLogDebug, "websocks: closing connection"); - if(m_Stream) m_Stream->Close(); - if(m_Datagram) m_Datagram->ResetReceiver(m_RemotePort); - m_Parent->CloseConn(m_Conn); - EnterState(eWSCEnd); - } else { - EnterState(eWSCClose); - } - } - }; - - WebSocksConn_ptr CreateWebSocksConn(const websocketpp::connection_hdl & conn, WebSocksImpl * parent) - { - auto ptr = std::make_shared(conn, parent); - auto c = parent->GetConn(conn); - c->set_message_handler(std::bind(&WebSocksConn::GotMessage, ptr.get(), std::placeholders::_1, std::placeholders::_2)); - return ptr; - } - -} -} -#else - -// no websocket support - namespace i2p { namespace client @@ -504,7 +19,7 @@ namespace client void Start() { - LogPrint(eLogInfo, "WebSockets not enabled on compile time"); + LogPrint(eLogInfo, "[Tunnels] starting websocks tunnel at %s:%d is rejected: WebSockets is deprecated", m_Addr, m_Port); } void Stop() @@ -527,7 +42,6 @@ namespace client } } -#endif namespace i2p { namespace client diff --git a/libi2pd_client/Websocket.cpp b/libi2pd_client/Websocket.cpp deleted file mode 100644 index 3d456655..00000000 --- a/libi2pd_client/Websocket.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#ifdef WITH_EVENTS -#include "Websocket.h" -#include "Log.h" - -#include -#include - -#include -#include -#include -#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -#if !GCC47_BOOST149 -#include -#endif - -#include - -namespace i2p -{ - namespace event - { - - typedef websocketpp::server ServerImpl; - typedef websocketpp::connection_hdl ServerConn; - - class WebsocketServerImpl : public EventListener - { - private: - typedef ServerImpl::message_ptr MessagePtr; - public: - - WebsocketServerImpl(const std::string & addr, int port) : - m_run(false), - m_ws_thread(nullptr), - m_ev_thread(nullptr), - m_WebsocketTicker(m_Service) - { - m_server.init_asio(); - m_server.set_open_handler(std::bind(&WebsocketServerImpl::ConnOpened, this, std::placeholders::_1)); - m_server.set_close_handler(std::bind(&WebsocketServerImpl::ConnClosed, this, std::placeholders::_1)); - m_server.set_message_handler(std::bind(&WebsocketServerImpl::OnConnMessage, this, std::placeholders::_1, std::placeholders::_2)); - - m_server.listen(boost::asio::ip::address::from_string(addr), port); - } - - ~WebsocketServerImpl() - { - } - - void Start() { - m_run = true; - m_server.start_accept(); - m_ws_thread = new std::thread([&] () { - while(m_run) { - try { - m_server.run(); - } catch (std::exception & e ) { - LogPrint(eLogError, "Websocket server: ", e.what()); - } - } - }); - m_ev_thread = new std::thread([&] () { - while(m_run) { - try { - m_Service.run(); - break; - } catch (std::exception & e ) { - LogPrint(eLogError, "Websocket service: ", e.what()); - } - } - }); - ScheduleTick(); - } - - void Stop() { - m_run = false; - m_Service.stop(); - m_server.stop(); - - if(m_ev_thread) { - m_ev_thread->join(); - delete m_ev_thread; - } - m_ev_thread = nullptr; - - if(m_ws_thread) { - m_ws_thread->join(); - delete m_ws_thread; - } - m_ws_thread = nullptr; - } - - void ConnOpened(ServerConn c) - { - std::lock_guard lock(m_connsMutex); - m_conns.insert(c); - } - - void ConnClosed(ServerConn c) - { - std::lock_guard lock(m_connsMutex); - m_conns.erase(c); - } - - void OnConnMessage(ServerConn conn, ServerImpl::message_ptr msg) - { - (void) conn; - (void) msg; - } - - void HandleTick(const boost::system::error_code & ec) - { - - if(ec != boost::asio::error::operation_aborted) - LogPrint(eLogError, "Websocket ticker: ", ec.message()); - // pump collected events to us - i2p::event::core.PumpCollected(this); - ScheduleTick(); - } - - void ScheduleTick() - { - LogPrint(eLogDebug, "Websocket schedule tick"); - boost::posix_time::seconds dlt(1); - m_WebsocketTicker.expires_from_now(dlt); - m_WebsocketTicker.async_wait(std::bind(&WebsocketServerImpl::HandleTick, this, std::placeholders::_1)); - } - - /** @brief called from m_ev_thread */ - void HandlePumpEvent(const EventType & ev, const uint64_t & val) - { - EventType e; - for (const auto & i : ev) - e[i.first] = i.second; - - e["number"] = std::to_string(val); - HandleEvent(e); - } - - /** @brief called from m_ws_thread */ - void HandleEvent(const EventType & ev) - { - std::lock_guard lock(m_connsMutex); - boost::property_tree::ptree event; - for (const auto & item : ev) { - event.put(item.first, item.second); - } - std::ostringstream ss; - write_json(ss, event); - std::string s = ss.str(); - - ConnList::iterator it; - for (it = m_conns.begin(); it != m_conns.end(); ++it) { - ServerImpl::connection_ptr con = m_server.get_con_from_hdl(*it); - con->send(s); - } - } - - private: - typedef std::set > ConnList; - bool m_run; - std::thread * m_ws_thread; - std::thread * m_ev_thread; - std::mutex m_connsMutex; - ConnList m_conns; - ServerImpl m_server; - boost::asio::io_service m_Service; - boost::asio::deadline_timer m_WebsocketTicker; - }; - - - WebsocketServer::WebsocketServer(const std::string & addr, int port) : m_impl(new WebsocketServerImpl(addr, port)) {} - WebsocketServer::~WebsocketServer() - { - delete m_impl; - } - - - void WebsocketServer::Start() - { - m_impl->Start(); - } - - void WebsocketServer::Stop() - { - m_impl->Stop(); - } - - EventListener * WebsocketServer::ToListener() - { - return m_impl; - } - } -} -#endif diff --git a/libi2pd_client/Websocket.h b/libi2pd_client/Websocket.h deleted file mode 100644 index 3a754e49..00000000 --- a/libi2pd_client/Websocket.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef WEBSOCKET_H__ -#define WEBSOCKET_H__ -#include "Event.h" -namespace i2p -{ - namespace event - { - - class WebsocketServerImpl; - - class WebsocketServer - { - public: - WebsocketServer(const std::string & addr, int port); - ~WebsocketServer(); - - void Start(); - void Stop(); - - EventListener * ToListener(); - - private: - WebsocketServerImpl * m_impl; - }; - - } -} -#endif diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index a7f07e5d..9e59132f 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -2135,121 +2135,6 @@ Comma separated list of base64 identities:
- - - - - 0 - 0 - - - - - 0 - 105 - - - - - 16777215 - 105 - - - - Websockets server - - - - - 0 - 20 - 85 - 21 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Address to bind websocket server on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to bind websocket server on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index caa0bd50..1f01cb4b 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -74,7 +74,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd_client/MatchedDestination.cpp \ ../../libi2pd_client/SAM.cpp \ ../../libi2pd_client/SOCKS.cpp \ - ../../libi2pd_client/Websocket.cpp \ ../../libi2pd_client/WebSocks.cpp \ ../../daemon/Daemon.cpp \ ../../daemon/HTTPServer.cpp \ @@ -161,7 +160,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd_client/MatchedDestination.h \ ../../libi2pd_client/SAM.h \ ../../libi2pd_client/SOCKS.h \ - ../../libi2pd_client/Websocket.h \ ../../libi2pd_client/WebSocks.h \ ../../daemon/Daemon.h \ ../../daemon/HTTPServer.h \ diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index e4c9f2a7..76a6fda8 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -258,10 +258,6 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters); initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden); - initCheckBox( OPTION("websockets","enabled",[]{return "false";}), uiSettings->checkBoxWebsocketsEnable); - initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), uiSettings->lineEdit_webSock_addr, tr("Websocket server -> IP address")); - initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), uiSettings->lineEdit_webSock_port, tr("Websocket server -> Port")); - # undef OPTION //widgetlocks.add(new widgetlock(widget,lockbtn)); From bca0809918a2843b3d5b853a129a3068b0d9882a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 28 Feb 2020 18:48:43 +0300 Subject: [PATCH 0220/2950] cleanup removed websockets funtions Signed-off-by: R4SAS --- build/CMakeLists.txt | 1 - filelist.mk | 2 +- libi2pd/Event.cpp | 42 --------------------------------- libi2pd/Event.h | 46 ------------------------------------- libi2pd/Tunnel.h | 24 ------------------- libi2pd_client/WebSocks.cpp | 1 - qt/i2pd_qt/i2pd_qt.pro | 2 -- 7 files changed, 1 insertion(+), 117 deletions(-) delete mode 100644 libi2pd/Event.cpp delete mode 100644 libi2pd/Event.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 324ac468..d39dd113 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -74,7 +74,6 @@ set (LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/Signature.cpp" "${LIBI2PD_SRC_DIR}/Timestamp.cpp" "${LIBI2PD_SRC_DIR}/api.cpp" - "${LIBI2PD_SRC_DIR}/Event.cpp" "${LIBI2PD_SRC_DIR}/Gost.cpp" "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" "${LIBI2PD_SRC_DIR}/Poly1305.cpp" diff --git a/filelist.mk b/filelist.mk index 8d451dc9..72773975 100644 --- a/filelist.mk +++ b/filelist.mk @@ -5,7 +5,7 @@ # SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ # Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \ # Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \ -# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp Gost.cpp +# Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Gost.cpp LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp) diff --git a/libi2pd/Event.cpp b/libi2pd/Event.cpp deleted file mode 100644 index 90c5ed97..00000000 --- a/libi2pd/Event.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "Event.h" -#include "Log.h" - -namespace i2p -{ - namespace event - { - void EventCore::SetListener(EventListener * l) - { - m_listener = l; - LogPrint(eLogInfo, "Event: listener set"); - } - - void EventCore::QueueEvent(const EventType & ev) - { - if(m_listener) m_listener->HandleEvent(ev); - } - - void EventCore::CollectEvent(const std::string & type, const std::string & ident, uint64_t val) - { - std::unique_lock lock(m_collect_mutex); - std::string key = type + "." + ident; - if (m_collected.find(key) == m_collected.end()) - { - m_collected[key] = {type, key, 0}; - } - m_collected[key].Val += val; - } - - void EventCore::PumpCollected(EventListener * listener) - { - std::unique_lock lock(m_collect_mutex); - if(listener) - { - for(const auto & ev : m_collected) { - listener->HandlePumpEvent({{"type", ev.second.Key}, {"ident", ev.second.Ident}}, ev.second.Val); - } - } - m_collected.clear(); - } - } -} diff --git a/libi2pd/Event.h b/libi2pd/Event.h deleted file mode 100644 index 74eed1db..00000000 --- a/libi2pd/Event.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef EVENT_H__ -#define EVENT_H__ -#include -#include -#include -#include -#include - -#include - -typedef std::map EventType; - -namespace i2p -{ - namespace event - { - class EventListener { - public: - virtual ~EventListener() {}; - virtual void HandleEvent(const EventType & ev) = 0; - /** @brief handle collected event when pumped */ - virtual void HandlePumpEvent(const EventType & ev, const uint64_t & val) = 0; - }; - - class EventCore - { - public: - void QueueEvent(const EventType & ev); - void CollectEvent(const std::string & type, const std::string & ident, uint64_t val); - void SetListener(EventListener * l); - void PumpCollected(EventListener * l); - - private: - std::mutex m_collect_mutex; - struct CollectedEvent - { - std::string Key; - std::string Ident; - uint64_t Val; - }; - std::map m_collected; - EventListener * m_listener = nullptr; - }; - } -} -#endif diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 66b620b8..f97bcc63 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -19,35 +19,11 @@ #include "TunnelGateway.h" #include "TunnelBase.h" #include "I2NPProtocol.h" -#include "Event.h" namespace i2p { namespace tunnel { - template - static void EmitTunnelEvent(const std::string & ev, const TunnelT & t) - { - (void) ev; - (void) t; - } - - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val) - { - (void) ev; - (void) t; - (void) val; - } - - template - static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val) - { - (void) ev; - (void) t; - (void) val; - } - const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes diff --git a/libi2pd_client/WebSocks.cpp b/libi2pd_client/WebSocks.cpp index 95abf455..a3e8c1bf 100644 --- a/libi2pd_client/WebSocks.cpp +++ b/libi2pd_client/WebSocks.cpp @@ -70,4 +70,3 @@ namespace client } } } - diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 1f01cb4b..ce3ec1ca 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -28,7 +28,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/Datagram.cpp \ ../../libi2pd/Destination.cpp \ ../../libi2pd/Ed25519.cpp \ - ../../libi2pd/Event.cpp \ ../../libi2pd/Family.cpp \ ../../libi2pd/FS.cpp \ ../../libi2pd/Garlic.cpp \ @@ -106,7 +105,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/Datagram.h \ ../../libi2pd/Destination.h \ ../../libi2pd/Ed25519.h \ - ../../libi2pd/Event.h \ ../../libi2pd/Family.h \ ../../libi2pd/FS.h \ ../../libi2pd/Garlic.h \ From b02c9fb118be455c73873d7ec291b089323da4e3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 Feb 2020 14:03:08 -0500 Subject: [PATCH 0221/2950] enable C++17 for gcc --- Makefile.linux | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index d1ccf143..9db660c2 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -15,13 +15,14 @@ ifeq ($(shell expr match $(CXX) 'clang'),5) NEEDED_CXXFLAGS += -std=c++11 else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10 NEEDED_CXXFLAGS += -std=c++11 -else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7 +else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6 - NEEDED_CXXFLAGS += -std=c++0x -else ifeq ($(shell expr match ${CXXVER} "[5-9]"),1) # gcc >= 5 +else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic +else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc >= 7 + NEEDED_CXXFLAGS += -std=c++17 + LDLIBS = -latomic else # not supported $(error Compiler too old) endif From 1893127e8468e67e0cc5ccd7ffcda8686d441490 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 Feb 2020 14:05:51 -0500 Subject: [PATCH 0222/2950] use fold expression if C++17 --- libi2pd/Log.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index b11c6763..ba10b5e9 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -161,6 +161,7 @@ void LogPrint (std::stringstream& s, TValue&& arg) noexcept s << std::forward(arg); } +#if (__cplusplus < 201703L) // below C++ 17 /** internal usage only -- folding args array to single string */ template void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept @@ -168,6 +169,7 @@ void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept LogPrint (s, std::forward(arg)); LogPrint (s, std::forward(args)...); } +#endif /** * @brief Create log message and send it to queue @@ -184,7 +186,11 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept // fold message to single string std::stringstream ss(""); +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else LogPrint (ss, std::forward(args)...); +#endif auto msg = std::make_shared(level, std::time(nullptr), ss.str()); msg->tid = std::this_thread::get_id(); From e0cb26bd9e247c982219e639bc9b05cfacf46f11 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 28 Feb 2020 14:15:41 -0500 Subject: [PATCH 0223/2950] fixed fallthough warning for C++17 --- libi2pd/Garlic.cpp | 2 +- libi2pd/Identity.cpp | 2 +- libi2pd/RouterContext.cpp | 2 +- libi2pd/Streaming.cpp | 2 +- libi2pd_client/SOCKS.cpp | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index c7d0e21d..597602fb 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -911,7 +911,7 @@ namespace garlic case eGarlicDeliveryTypeDestination: LogPrint (eLogDebug, "Garlic: type destination"); buf += 32; // TODO: check destination - // no break here + [[fallthrough]]; // no break here case eGarlicDeliveryTypeLocal: { LogPrint (eLogDebug, "Garlic: type local"); diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index de94732f..5116ecd8 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -723,7 +723,7 @@ namespace data case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA512_4096: LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Creating EdDSA"); - // no break here + [[fallthrough]]; // no break here case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: i2p::crypto::CreateEDDSA25519RandomKeys (priv, pub); break; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 2c07c21b..c282f095 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -338,7 +338,7 @@ namespace i2p { case low : /* not set */; break; case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P' - case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; // no break here, extra + high means 'X' + case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; [[fallthrough]]; // no break here, extra + high means 'X' case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; } m_RouterInfo.SetCaps (caps); diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index d666d786..e486fa79 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -847,7 +847,7 @@ namespace stream break; case 2: m_RTO = INITIAL_RTO; // drop RTO to initial upon tunnels pair change first time - // no break here + [[fallthrough]]; // no break here case 4: if (m_RoutingSession) m_RoutingSession->SetSharedRoutingPath (nullptr); UpdateCurrentRemoteLease (); // pick another lease diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 8a67901c..c01aa212 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -433,6 +433,7 @@ namespace proxy break; case CMD_UDP: if (m_socksv == SOCKS5) break; + [[fallthrough]]; default: LogPrint(eLogError, "SOCKS: invalid command: ", ((int)*sock_buff)); SocksRequestFailed(SOCKS5_GEN_FAIL); From ed574f9d792dd0d390d631a006b85055eea9b5bc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 28 Feb 2020 23:05:26 +0300 Subject: [PATCH 0224/2950] use C++17 if available when configuring with cmake --- build/CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2577fb1b..3a723c45 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -184,16 +184,16 @@ else() set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections" ) # -flto is added from above endif () -# check for c++11 support +# check for c++17 & c++11 support include(CheckCXXCompilerFlag) +CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED) CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED) -CHECK_CXX_COMPILER_FLAG("-std=c++0x" CXX0X_SUPPORTED) -if (CXX11_SUPPORTED) +if (CXX17_SUPPORTED) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" ) +elseif (CXX11_SUPPORTED) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" ) -elseif (CXX0X_SUPPORTED) # gcc 4.6 - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x" ) -elseif (NOT MSVC) - message(SEND_ERROR "C++11 standard not seems to be supported by compiler. Too old version?") +else + message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?") endif () if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") From 2ac2da41cfa673b0ec001b700e310d63332fcc39 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 28 Feb 2020 23:28:41 +0300 Subject: [PATCH 0225/2950] cmake: fix else statement --- build/CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 3a723c45..f5c1280e 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -188,13 +188,13 @@ endif () include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++17" CXX17_SUPPORTED) CHECK_CXX_COMPILER_FLAG("-std=c++11" CXX11_SUPPORTED) -if (CXX17_SUPPORTED) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" ) -elseif (CXX11_SUPPORTED) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" ) -else +if(CXX17_SUPPORTED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") +elseif(CXX11_SUPPORTED) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +else() message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?") -endif () +endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe") From fe1724e7e694ab3c05492cb2dbfdae454fcf18a0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 28 Feb 2020 23:41:42 +0300 Subject: [PATCH 0226/2950] switch travis-ci to xenial --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c55f1885..af47f458 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ cache: os: - linux #- osx -dist: trusty +dist: xenial sudo: required compiler: - g++ From 2ffe62ba41bffb03e2042bf4d7cc7188a2a2393d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 29 Feb 2020 09:21:50 -0500 Subject: [PATCH 0227/2950] [[fallthrough]] if C++17 only --- libi2pd/Garlic.cpp | 5 ++++- libi2pd/Identity.cpp | 5 ++++- libi2pd/RouterContext.cpp | 6 +++++- libi2pd/Streaming.cpp | 5 ++++- libi2pd_client/SOCKS.cpp | 2 ++ 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 597602fb..45c97172 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -911,7 +911,10 @@ namespace garlic case eGarlicDeliveryTypeDestination: LogPrint (eLogDebug, "Garlic: type destination"); buf += 32; // TODO: check destination - [[fallthrough]]; // no break here +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif + // no break here case eGarlicDeliveryTypeLocal: { LogPrint (eLogDebug, "Garlic: type local"); diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 5116ecd8..3f9633ed 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -723,7 +723,10 @@ namespace data case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA512_4096: LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Creating EdDSA"); - [[fallthrough]]; // no break here +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif + // no break here case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: i2p::crypto::CreateEDDSA25519RandomKeys (priv, pub); break; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index c282f095..6c63ef79 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -338,7 +338,11 @@ namespace i2p { case low : /* not set */; break; case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P' - case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; [[fallthrough]]; // no break here, extra + high means 'X' + case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; + #if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; + #endif + // no break here, extra + high means 'X' case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; } m_RouterInfo.SetCaps (caps); diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index e486fa79..b5f935fe 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -847,7 +847,10 @@ namespace stream break; case 2: m_RTO = INITIAL_RTO; // drop RTO to initial upon tunnels pair change first time - [[fallthrough]]; // no break here +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif + // no break here case 4: if (m_RoutingSession) m_RoutingSession->SetSharedRoutingPath (nullptr); UpdateCurrentRemoteLease (); // pick another lease diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index c01aa212..8742d4c5 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -433,7 +433,9 @@ namespace proxy break; case CMD_UDP: if (m_socksv == SOCKS5) break; +#if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; +#endif default: LogPrint(eLogError, "SOCKS: invalid command: ", ((int)*sock_buff)); SocksRequestFailed(SOCKS5_GEN_FAIL); From 97f0347715920c2e628c7ac40c9a065cfe94b5ef Mon Sep 17 00:00:00 2001 From: r4sas Date: Sat, 29 Feb 2020 23:08:43 +0000 Subject: [PATCH 0228/2950] Update android stuff: * switch to c++17 * use boost 1.72.0 * disable minify in release * enable apk splitting (separate apk for every ABI) * add version to output apk name Signed-off-by: r4sas --- android/build.gradle | 21 ++++++++++++++++++--- android/jni/Android.mk | 16 ++++++++-------- android/jni/Application.mk | 6 +++--- android_binary_only/jni/Android.mk | 16 ++++++++-------- android_binary_only/jni/Application.mk | 6 +++--- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 844615f8..6fcb4521 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -32,6 +32,7 @@ android { minSdkVersion 14 versionCode 2300 versionName "2.30.0" + setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' abiFilters 'x86' @@ -56,9 +57,10 @@ android { splits { abi { // change that to true if you need splitted apk - enable false + enable true reset() - include "armeabi-v7a", "arm64-v8a", "x86", "x86_64" + //include "armeabi-v7a", "arm64-v8a", "x86", "x86_64" + include "armeabi-v7a", "x86" universalApk true } } @@ -72,7 +74,7 @@ android { } buildTypes { release { - minifyEnabled true + minifyEnabled false signingConfig signingConfigs.orignal proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' } @@ -87,3 +89,16 @@ android { targetCompatibility = '1.8' } } + +ext.abiCodes = ['armeabi-v7a':1, 'x86':2, 'arm64-v8a':3, 'x86_64':4] +import com.android.build.OutputFile + +android.applicationVariants.all { variant -> + variant.outputs.each { output -> + def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) + + if (baseAbiVersionCode != null) { + output.versionCodeOverride = baseAbiVersionCode + variant.versionCode + } + } +} diff --git a/android/jni/Android.mk b/android/jni/Android.mk index d44fcc5a..2376509e 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -25,29 +25,29 @@ include $(BUILD_SHARED_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_system -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_system.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_date_time -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_filesystem -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_program_options -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) diff --git a/android/jni/Application.mk b/android/jni/Application.mk index 6d51ac1a..0c291661 100755 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -9,15 +9,15 @@ NDK_TOOLCHAIN_VERSION := clang #APP_STL := c++_shared APP_STL := c++_static -# Enable c++11 extensions in source code -APP_CPPFLAGS += -std=c++11 -fexceptions -frtti +# Enable c++17 extensions in source code +APP_CPPFLAGS += -std=c++17 -fexceptions -frtti APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) APP_CPPFLAGS += -DANDROID_ARM7A endif -# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0 # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git diff --git a/android_binary_only/jni/Android.mk b/android_binary_only/jni/Android.mk index 7e73b23d..a59e32e5 100755 --- a/android_binary_only/jni/Android.mk +++ b/android_binary_only/jni/Android.mk @@ -26,29 +26,29 @@ include $(BUILD_EXECUTABLE) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_system -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_system.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_date_time -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_filesystem -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_program_options -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_68_0-clang/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_68_0-clang/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) diff --git a/android_binary_only/jni/Application.mk b/android_binary_only/jni/Application.mk index 655bf430..bb4afac3 100755 --- a/android_binary_only/jni/Application.mk +++ b/android_binary_only/jni/Application.mk @@ -9,8 +9,8 @@ APP_PLATFORM := android-14 NDK_TOOLCHAIN_VERSION := clang APP_STL := c++_static -# Enable c++11 extensions in source code -APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE +# Enable c++17 extensions in source code +APP_CPPFLAGS += -std=c++17 -fvisibility=default -fPIE APP_CPPFLAGS += -DANDROID_BINARY -DANDROID -D__ANDROID__ -DUSE_UPNP APP_LDFLAGS += -rdynamic -fPIE -pie @@ -21,7 +21,7 @@ endif # Forcing debug optimization. Use `ndk-build NDK_DEBUG=1` instead. #APP_OPTIM := debug -# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0 # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git From 4f0da87a7a11e399aedb6fedb67c037de5a6aaa0 Mon Sep 17 00:00:00 2001 From: unlnown542a Date: Sun, 1 Mar 2020 14:35:24 +0000 Subject: [PATCH 0229/2950] add ntcp2proxy support --- libi2pd/Config.cpp | 7 +- libi2pd/NTCP2.cpp | 597 +++++++++++++++++++++++++++++------------ libi2pd/NTCP2.h | 67 +++-- libi2pd/Transports.cpp | 80 ++++-- 4 files changed, 533 insertions(+), 218 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b0f7572d..4050f769 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -61,6 +61,7 @@ namespace config { ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") + ("ntcp2proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") @@ -305,16 +306,16 @@ namespace config { std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl; std::cout << m_OptionsDesc; exit(EXIT_SUCCESS); - } + } else if (m_Options.count("version")) { std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl; - std::cout << "Boost version " + std::cout << "Boost version " << BOOST_VERSION / 100000 << "." // maj. version << BOOST_VERSION / 100 % 1000 << "." // min. version << BOOST_VERSION % 100 // patch version << std::endl; -#if defined(OPENSSL_VERSION_TEXT) +#if defined(OPENSSL_VERSION_TEXT) std::cout << OPENSSL_VERSION_TEXT << std::endl; #endif #if defined(LIBRESSL_VERSION_TEXT) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 034f7e21..a3c42790 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -20,19 +20,21 @@ #include "Transports.h" #include "NetDb.hpp" #include "NTCP2.h" +#include "HTTP.h" +#include "util.h" namespace i2p { namespace transport { NTCP2Establisher::NTCP2Establisher (): - m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) - { + m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) + { } - NTCP2Establisher::~NTCP2Establisher () - { - delete[] m_SessionRequestBuffer; + NTCP2Establisher::~NTCP2Establisher () + { + delete[] m_SessionRequestBuffer; delete[] m_SessionCreatedBuffer; delete[] m_SessionConfirmedBuffer; } @@ -54,22 +56,22 @@ namespace transport void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { - static const uint8_t protocolNameHash[] = - { - 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, - 0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71 + static const uint8_t protocolNameHash[] = + { + 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, + 0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71 }; // SHA256 ("Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256") - static const uint8_t hh[32] = - { - 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, - 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e + static const uint8_t hh[32] = + { + 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, + 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e }; // SHA256 (protocolNameHash) - memcpy (m_CK, protocolNameHash, 32); + memcpy (m_CK, protocolNameHash, 32); // h = SHA256(hh || rs) SHA256_CTX ctx; SHA256_Init (&ctx); - SHA256_Update (&ctx, hh, 32); - SHA256_Update (&ctx, rs, 32); + SHA256_Update (&ctx, hh, 32); + SHA256_Update (&ctx, rs, 32); SHA256_Final (m_H, &ctx); // h = SHA256(h || epub) MixHash (epub, 32); @@ -83,25 +85,25 @@ namespace transport { KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); } - + void NTCP2Establisher::KDF1Bob () { - KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetStaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); + KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetStaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); } void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) - { - MixHash (sessionRequest + 32, 32); // encrypted payload + { + MixHash (sessionRequest + 32, 32); // encrypted payload int paddingLength = sessionRequestLen - 64; if (paddingLength > 0) MixHash (sessionRequest + 64, paddingLength); - MixHash (epub, 32); + MixHash (epub, 32); // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); - + MixKey (inputKeyMaterial); } @@ -109,7 +111,7 @@ namespace transport { KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetRemotePub ()); } - + void NTCP2Establisher::KDF2Bob () { KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); @@ -118,14 +120,14 @@ namespace transport void NTCP2Establisher::KDF3Alice () { uint8_t inputKeyMaterial[32]; - i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); + i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); MixKey (inputKeyMaterial); } void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); + m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); MixKey (inputKeyMaterial); } @@ -146,30 +148,30 @@ namespace transport encryption.SetKey (m_RemoteIdentHash); encryption.SetIV (m_IV); encryption.Encrypt (GetPub (), 32, m_SessionRequestBuffer); // X - encryption.GetIV (m_IV); // save IV for SessionCreated + encryption.GetIV (m_IV); // save IV for SessionCreated // encryption key for next block KDF1Alice (); // fill options uint8_t options[32]; // actual options size is 16 bytes memset (options, 0, 16); options[0] = i2p::context.GetNetID (); // network ID - options[1] = 2; // ver + options[1] = 2; // ver htobe16buf (options + 2, paddingLength); // padLen - // m3p2Len + // m3p2Len auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen (); - m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options + m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options htobe16buf (options + 4, m3p2Len); - // fill m3p2 payload (RouterInfo block) + // fill m3p2 payload (RouterInfo block) m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; m3p2[0] = eNTCP2BlkRouterInfo; // block htobe16buf (m3p2 + 1, bufLen + 1); // flag + RI - m3p2[3] = 0; // flag + m3p2[3] = 0; // flag memcpy (m3p2 + 4, i2p::context.GetRouterInfo ().GetBuffer (), bufLen); // TODO: own RI should be protected by mutex // 2 bytes reserved htobe32buf (options + 8, i2p::util::GetSecondsSinceEpoch ()); // tsA // 4 bytes reserved - // sign and encrypt options, use m_H as AD + // sign and encrypt options, use m_H as AD uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionRequestBuffer + 32, 32, true); // encrypt @@ -179,7 +181,7 @@ namespace transport { auto paddingLen = rand () % (287 - 64); m_SessionCreatedBufferLen = paddingLen + 64; - m_SessionCreatedBuffer = new uint8_t[m_SessionCreatedBufferLen]; + m_SessionCreatedBuffer = new uint8_t[m_SessionCreatedBufferLen]; RAND_bytes (m_SessionCreatedBuffer + 64, paddingLen); // encrypt Y i2p::crypto::CBCEncryption encryption; @@ -187,12 +189,12 @@ namespace transport encryption.SetIV (m_IV); encryption.Encrypt (GetPub (), 32, m_SessionCreatedBuffer); // Y // encryption key for next block (m_K) - KDF2Bob (); + KDF2Bob (); uint8_t options[16]; memset (options, 0, 16); htobe16buf (options + 2, paddingLen); // padLen htobe32buf (options + 8, i2p::util::GetSecondsSinceEpoch ()); // tsB - // sign and encrypt options, use m_H as AD + // sign and encrypt options, use m_H as AD uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionCreatedBuffer + 32, 32, true); // encrypt @@ -205,9 +207,9 @@ namespace transport MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload int paddingLength = m_SessionCreatedBufferLen - 64; if (paddingLength > 0) - MixHash (m_SessionCreatedBuffer + 64, paddingLength); + MixHash (m_SessionCreatedBuffer + 64, paddingLength); - // part1 48 bytes + // part1 48 bytes i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, GetH (), 32, GetK (), nonce, m_SessionConfirmedBuffer, 48, true); // encrypt } @@ -215,14 +217,14 @@ namespace transport { // part 2 // update AD again - MixHash (m_SessionConfirmedBuffer, 48); + MixHash (m_SessionConfirmedBuffer, 48); // encrypt m3p2, it must be filled in SessionRequest - KDF3Alice (); + KDF3Alice (); uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; - i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2, m3p2Len, true); // encrypt + i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2, m3p2Len, true); // encrypt // update h again MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext) - } + } bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen) { @@ -231,7 +233,7 @@ namespace transport decryption.SetKey (i2p::context.GetIdentHash ()); decryption.SetIV (i2p::context.GetNTCP2IV ()); decryption.Decrypt (m_SessionRequestBuffer, 32, GetRemotePub ()); - decryption.GetIV (m_IV); // save IV for SessionCreated + decryption.GetIV (m_IV); // save IV for SessionCreated // decryption key for next block KDF1Bob (); // verify MAC and decrypt options block (32 bytes), use m_H as AD @@ -245,7 +247,7 @@ namespace transport LogPrint (eLogWarning, "NTCP2: SessionRequest networkID ", (int)options[0], " mismatch. Expected ", i2p::context.GetNetID ()); return false; } - if (options[1] == 2) // ver is always 2 + if (options[1] == 2) // ver is always 2 { paddingLen = bufbe16toh (options + 2); m_SessionRequestBufferLen = paddingLen + 64; @@ -253,11 +255,11 @@ namespace transport if (m3p2Len < 16) { LogPrint (eLogWarning, "NTCP2: SessionRequest m3p2len=", m3p2Len, " is too short"); - return false; - } + return false; + } // check timestamp auto ts = i2p::util::GetSecondsSinceEpoch (); - uint32_t tsA = bufbe32toh (options + 8); + uint32_t tsA = bufbe32toh (options + 8); if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW) { LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew"); @@ -274,8 +276,8 @@ namespace transport { LogPrint (eLogWarning, "NTCP2: SessionRequest AEAD verification failed "); return false; - } - return true; + } + return true; } bool NTCP2Establisher::ProcessSessionCreatedMessage (uint16_t& paddingLen) @@ -294,11 +296,11 @@ namespace transport memset (nonce, 0, 12); // set nonce to zero if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionCreatedBuffer + 32, 16, GetH (), 32, GetK (), nonce, payload, 16, false)) // decrypt { - // options + // options paddingLen = bufbe16toh(payload + 2); // check timestamp auto ts = i2p::util::GetSecondsSinceEpoch (); - uint32_t tsB = bufbe32toh (payload + 8); + uint32_t tsB = bufbe32toh (payload + 8); if (tsB < ts - NTCP2_CLOCK_SKEW || tsB > ts + NTCP2_CLOCK_SKEW) { LogPrint (eLogWarning, "NTCP2: SessionCreated time difference ", (int)(ts - tsB), " exceeds clock skew"); @@ -306,10 +308,10 @@ namespace transport } } else - { + { LogPrint (eLogWarning, "NTCP2: SessionCreated AEAD verification failed "); return false; - } + } return true; } @@ -320,7 +322,7 @@ namespace transport int paddingLength = m_SessionCreatedBufferLen - 64; if (paddingLength > 0) MixHash (m_SessionCreatedBuffer + 64, paddingLength); - + if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, GetH (), 32, GetK (), nonce, m_RemoteStaticKey, 32, false)) // decrypt S { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed "); @@ -332,9 +334,9 @@ namespace transport bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf) { // update AD again - MixHash (m_SessionConfirmedBuffer, 48); + MixHash (m_SessionConfirmedBuffer, 48); - KDF3Bob (); + KDF3Bob (); if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt { // caclulate new h again for KDF data @@ -350,8 +352,8 @@ namespace transport } NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter): - TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT), - m_Server (server), m_Socket (m_Server.GetService ()), + TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT), + m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_Establisher (new NTCP2Establisher), m_SendSipKey (nullptr), m_ReceiveSipKey (nullptr), @@ -371,10 +373,82 @@ namespace transport memcpy (m_Establisher->m_IV, addr->ntcp2->iv, 16); } else - LogPrint (eLogWarning, "NTCP2: Missing NTCP2 parameters"); + LogPrint (eLogWarning, "NTCP2: Missing NTCP2 parameters"); } } + void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + + // build request + size_t sz = 0; + uint8_t buff[256]; + uint8_t readbuff[256]; + buff[0] = 0x05; + buff[1] = 0x01; + buff[2] = 0x00; + + if(addrtype == eIP4Address) + { + buff[3] = 0x01; + auto addr = boost::asio::ip::address::from_string(host).to_v4(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff+4, addrbytes.data(), addrsize); + } + else if (addrtype == eIP6Address) + { + buff[3] = 0x04; + auto addr = boost::asio::ip::address::from_string(host).to_v6(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff+4, addrbytes.data(), addrsize); + } + else if (addrtype == eHostname) + { + buff[3] = 0x03; + size_t addrsize = host.size(); + sz = addrsize + 1 + 4; + if (2 + sz > sizeof(buff)) + { + // too big + return; + } + buff[4] = (uint8_t) addrsize; + memcpy(buff+5, host.c_str(), addrsize); + } + htobe16buf(buff+sz, port); + sz += 2; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, sz), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t written) { + if(ec) + { + LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); + return; + } + }); + + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) { + if(e) + { + LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); + } + else if(transferred == sz) + { + if( readbuff[1] == 0x00) + { + timer->cancel(); + conn->ClientLogin(); + return; + } + } + if(!e) + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + timer->cancel(); + conn->Terminate(); + }); + } + + NTCP2Session::~NTCP2Session () { delete[] m_NextReceivedBuffer; @@ -425,8 +499,8 @@ namespace transport void NTCP2Session::CreateNonce (uint64_t seqn, uint8_t * nonce) { - memset (nonce, 0, 4); - htole64buf (nonce + 4, seqn); + memset (nonce, 0, 4); + htole64buf (nonce + 4, seqn); } @@ -442,7 +516,7 @@ namespace transport memcpy (h + 32, "siphash", 7); i2p::crypto::HKDF (master, h, 39, "", master, 32); // sip_master = HKDF(ask_master, h || "siphash") i2p::crypto::HKDF (master, nullptr, 0, "", k); // sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen) - memcpy (m_Sipkeysab, k, 32); memcpy (m_Sipkeysba, k + 32, 32); + memcpy (m_Sipkeysab, k, 32); memcpy (m_Sipkeysba, k + 32, 32); } @@ -451,8 +525,8 @@ namespace transport m_Establisher->CreateSessionRequestMessage (); // send message boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionRequestBuffer, m_Establisher->m_SessionRequestBufferLen), boost::asio::transfer_all (), - std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } + std::bind(&NTCP2Session::HandleSessionRequestSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } void NTCP2Session::HandleSessionRequestSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { @@ -500,7 +574,7 @@ namespace transport } else SendSessionCreated (); - } + } else Terminate (); } @@ -520,9 +594,9 @@ namespace transport void NTCP2Session::SendSessionCreated () { m_Establisher->CreateSessionCreatedMessage (); - // send message + // send message boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionCreatedBuffer, m_Establisher->m_SessionCreatedBufferLen), boost::asio::transfer_all (), - std::bind(&NTCP2Session::HandleSessionCreatedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + std::bind(&NTCP2Session::HandleSessionCreatedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } void NTCP2Session::HandleSessionCreatedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -577,9 +651,9 @@ namespace transport { uint8_t nonce[12]; CreateNonce (1, nonce); // set nonce to 1 - m_Establisher->CreateSessionConfirmedMessagePart1 (nonce); + m_Establisher->CreateSessionConfirmedMessagePart1 (nonce); memset (nonce, 0, 12); // set nonce back to 0 - m_Establisher->CreateSessionConfirmedMessagePart2 (nonce); + m_Establisher->CreateSessionConfirmedMessagePart2 (nonce); // send message boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionConfirmedBuffer, m_Establisher->m3p2Len + 48), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionConfirmedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -594,12 +668,12 @@ namespace transport Terminate (); } else - { + { LogPrint (eLogDebug, "NTCP2: SessionConfirmed sent"); KeyDerivationFunctionDataPhase (); // Alice data phase keys m_SendKey = m_Kab; - m_ReceiveKey = m_Kba; + m_ReceiveKey = m_Kba; SetSipKeys (m_Sipkeysab, m_Sipkeysba); memcpy (m_ReceiveIV.buf, m_Sipkeysba + 16, 8); memcpy (m_SendIV.buf, m_Sipkeysab + 16, 8); @@ -609,7 +683,7 @@ namespace transport // TODO: remove // m_SendQueue.push_back (CreateDeliveryStatusMsg (1)); // SendQueue (); - } + } } void NTCP2Session::HandleSessionCreatedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -623,7 +697,7 @@ namespace transport else { LogPrint (eLogDebug, "NTCP2: SessionCreated sent"); - m_Establisher->m_SessionConfirmedBuffer = new uint8_t[m_Establisher->m3p2Len + 48]; + m_Establisher->m_SessionConfirmedBuffer = new uint8_t[m_Establisher->m3p2Len + 48]; boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionConfirmedBuffer, m_Establisher->m3p2Len + 48), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionConfirmedReceived , shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -652,7 +726,7 @@ namespace transport KeyDerivationFunctionDataPhase (); // Bob data phase keys m_SendKey = m_Kba; - m_ReceiveKey = m_Kab; + m_ReceiveKey = m_Kab; SetSipKeys (m_Sipkeysba, m_Sipkeysab); memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); @@ -660,8 +734,8 @@ namespace transport // process RI if (buf[0] != eNTCP2BlkRouterInfo) { - LogPrint (eLogWarning, "NTCP2: unexpected block ", (int)buf[0], " in SessionConfirmed"); - Terminate (); + LogPrint (eLogWarning, "NTCP2: unexpected block ", (int)buf[0], " in SessionConfirmed"); + Terminate (); return; } auto size = bufbe16toh (buf.data () + 1); @@ -675,33 +749,33 @@ namespace transport i2p::data::RouterInfo ri (buf.data () + 4, size - 1); // 1 byte block type + 2 bytes size + 1 byte flag if (ri.IsUnreachable ()) { - LogPrint (eLogError, "NTCP2: Signature verification failed in SessionConfirmed"); - SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); + LogPrint (eLogError, "NTCP2: Signature verification failed in SessionConfirmed"); + SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); return; } if (i2p::util::GetMillisecondsSinceEpoch () > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes { - LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed"); - SendTerminationAndTerminate (eNTCP2Message3Error); + LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed"); + SendTerminationAndTerminate (eNTCP2Message3Error); return; } auto addr = ri.GetNTCP2Address (false); // any NTCP2 address if (!addr) { - LogPrint (eLogError, "NTCP2: No NTCP2 address found in SessionConfirmed"); + LogPrint (eLogError, "NTCP2: No NTCP2 address found in SessionConfirmed"); Terminate (); return; } if (memcmp (addr->ntcp2->staticKey, m_Establisher->m_RemoteStaticKey, 32)) { - LogPrint (eLogError, "NTCP2: Static key mismatch in SessionConfirmed"); - SendTerminationAndTerminate (eNTCP2IncorrectSParameter); + LogPrint (eLogError, "NTCP2: Static key mismatch in SessionConfirmed"); + SendTerminationAndTerminate (eNTCP2IncorrectSParameter); return; } i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice // TODO: process options - - // ready to communicate + + // ready to communicate auto existing = i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : ri.GetRouterIdentity ()); m_Server.AddNTCP2Session (shared_from_this (), true); @@ -720,13 +794,13 @@ namespace transport { #if OPENSSL_SIPHASH m_SendSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, sendSipKey, 16); - m_SendMDCtx = EVP_MD_CTX_create (); + m_SendMDCtx = EVP_MD_CTX_create (); EVP_PKEY_CTX *ctx = nullptr; EVP_DigestSignInit (m_SendMDCtx, &ctx, nullptr, nullptr, m_SendSipKey); - EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); + 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); - m_ReceiveMDCtx = EVP_MD_CTX_create (); + m_ReceiveMDCtx = EVP_MD_CTX_create (); ctx = nullptr; EVP_DigestSignInit (m_ReceiveMDCtx, &ctx, NULL, NULL, m_ReceiveSipKey); EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); @@ -770,9 +844,9 @@ namespace transport { #if OPENSSL_SIPHASH EVP_DigestSignInit (m_ReceiveMDCtx, nullptr, nullptr, nullptr, nullptr); - EVP_DigestSignUpdate (m_ReceiveMDCtx, m_ReceiveIV.buf, 8); - size_t l = 8; - EVP_DigestSignFinal (m_ReceiveMDCtx, m_ReceiveIV.buf, &l); + EVP_DigestSignUpdate (m_ReceiveMDCtx, m_ReceiveIV.buf, 8); + size_t l = 8; + EVP_DigestSignFinal (m_ReceiveMDCtx, m_ReceiveIV.buf, &l); #else i2p::crypto::Siphash<8> (m_ReceiveIV.buf, m_ReceiveIV.buf, 8, m_ReceiveSipKey); #endif @@ -780,7 +854,7 @@ namespace transport m_NextReceivedLen = be16toh (m_NextReceivedLen) ^ le16toh (m_ReceiveIV.key); LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen); if (m_NextReceivedLen >= 16) - { + { if (m_NextReceivedBuffer) delete[] m_NextReceivedBuffer; m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen]; boost::system::error_code ec; @@ -798,7 +872,7 @@ namespace transport { LogPrint (eLogError, "NTCP2: received length ", m_NextReceivedLen, " is too short"); Terminate (); - } + } } } @@ -825,7 +899,7 @@ namespace transport uint8_t nonce[12]; CreateNonce (m_ReceiveSequenceNumber, nonce); m_ReceiveSequenceNumber++; if (i2p::crypto::AEADChaCha20Poly1305 (m_NextReceivedBuffer, m_NextReceivedLen-16, nullptr, 0, m_ReceiveKey, nonce, m_NextReceivedBuffer, m_NextReceivedLen, false)) - { + { 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 @@ -835,7 +909,7 @@ namespace transport { LogPrint (eLogWarning, "NTCP2: Received AEAD verification failed "); SendTerminationAndTerminate (eNTCP2DataPhaseAEADFailure); - } + } } } @@ -858,7 +932,7 @@ namespace transport { case eNTCP2BlkDateTime: LogPrint (eLogDebug, "NTCP2: datetime"); - break; + break; case eNTCP2BlkOptions: LogPrint (eLogDebug, "NTCP2: options"); break; @@ -881,11 +955,11 @@ namespace transport 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 (nextMsg); break; } case eNTCP2BlkTermination: - if (size >= 9) + if (size >= 9) { LogPrint (eLogDebug, "NTCP2: termination. reason=", (int)(frame[offset + 8])); Terminate (); @@ -908,46 +982,46 @@ namespace transport { #if OPENSSL_SIPHASH 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_DigestSignUpdate (m_SendMDCtx, m_SendIV.buf, 8); + size_t l = 8; + EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); #else i2p::crypto::Siphash<8> (m_SendIV.buf, m_SendIV.buf, 8, m_SendSipKey); #endif // length must be in BigEndian htobe16buf (lengthBuf, frameLen ^ le16toh (m_SendIV.key)); LogPrint (eLogDebug, "NTCP2: sent length ", frameLen); - } + } void NTCP2Session::SendI2NPMsgs (std::vector >& msgs) { if (msgs.empty () || IsTerminated ()) return; - + size_t totalLen = 0; std::vector > encryptBufs; - std::vector bufs; + std::vector bufs; std::shared_ptr first; uint8_t * macBuf = nullptr; - for (auto& it: msgs) - { + for (auto& it: msgs) + { it->ToNTCP2 (); auto buf = it->GetNTCP2Header (); auto len = it->GetNTCP2Length (); // block header - buf -= 3; + buf -= 3; buf[0] = eNTCP2BlkI2NPMessage; // blk htobe16buf (buf + 1, len); // size - len += 3; - totalLen += len; + len += 3; + totalLen += len; encryptBufs.push_back ( {buf, len} ); if (&it == &msgs.front ()) // first message { // allocate two bytes for length buf -= 2; len += 2; first = it; - } + } if (&it == &msgs.back () && it->len + 16 < it->maxLen) // last message - { + { // if it's long enough we add padding and MAC to it // create padding block auto paddingLen = CreatePaddingBlock (totalLen, buf + len, it->maxLen - it->len - 16); @@ -960,8 +1034,8 @@ namespace transport macBuf = buf + len; // allocate 16 bytes for MAC len += 16; - } - + } + bufs.push_back (boost::asio::buffer (buf, len)); } @@ -973,42 +1047,42 @@ namespace transport auto paddingLen = CreatePaddingBlock (totalLen, m_NextSendBuffer, 287 - 16); // and padding block to encrypt and send if (paddingLen) - encryptBufs.push_back ( {m_NextSendBuffer, paddingLen} ); + encryptBufs.push_back ( {m_NextSendBuffer, paddingLen} ); bufs.push_back (boost::asio::buffer (m_NextSendBuffer, paddingLen + 16)); macBuf = m_NextSendBuffer + paddingLen; - totalLen += paddingLen; + totalLen += paddingLen; } uint8_t nonce[12]; CreateNonce (m_SendSequenceNumber, nonce); m_SendSequenceNumber++; i2p::crypto::AEADChaCha20Poly1305Encrypt (encryptBufs, m_SendKey, nonce, macBuf); // encrypt buffers SetNextSentFrameLength (totalLen + 16, first->GetNTCP2Header () - 5); // frame length right before first block - + // send buffers - m_IsSending = true; + m_IsSending = true; boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleI2NPMsgsSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); - } + } void NTCP2Session::HandleI2NPMsgsSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs) { HandleNextFrameSent (ecode, bytes_transferred); // msgs get destroyed here } - + void NTCP2Session::EncryptAndSendNextBuffer (size_t payloadLen) { - if (IsTerminated ()) + if (IsTerminated ()) { delete[] m_NextSendBuffer; m_NextSendBuffer = nullptr; - return; + return; } // encrypt uint8_t nonce[12]; CreateNonce (m_SendSequenceNumber, nonce); m_SendSequenceNumber++; - i2p::crypto::AEADChaCha20Poly1305Encrypt ({ {m_NextSendBuffer + 2, payloadLen} }, m_SendKey, nonce, m_NextSendBuffer + payloadLen + 2); + i2p::crypto::AEADChaCha20Poly1305Encrypt ({ {m_NextSendBuffer + 2, payloadLen} }, m_SendKey, nonce, m_NextSendBuffer + payloadLen + 2); SetNextSentFrameLength (payloadLen + 16, m_NextSendBuffer); // send - m_IsSending = true; + m_IsSending = true; boost::asio::async_write (m_Socket, boost::asio::buffer (m_NextSendBuffer, payloadLen + 16 + 2), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleNextFrameSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } @@ -1017,23 +1091,23 @@ namespace transport { m_IsSending = false; delete[] m_NextSendBuffer; m_NextSendBuffer = nullptr; - + if (ecode) { if (ecode != boost::asio::error::operation_aborted) LogPrint (eLogWarning, "NTCP2: Couldn't send frame ", ecode.message ()); Terminate (); - } + } else - { + { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); m_NumSentBytes += bytes_transferred; i2p::transport::transports.UpdateSentBytes (bytes_transferred); LogPrint (eLogDebug, "NTCP2: Next frame sent ", bytes_transferred); SendQueue (); - } + } } - + void NTCP2Session::SendQueue () { if (!m_SendQueue.empty ()) @@ -1043,7 +1117,7 @@ namespace transport while (!m_SendQueue.empty ()) { auto msg = m_SendQueue.front (); - size_t len = msg->GetNTCP2Length (); + size_t len = msg->GetNTCP2Length (); if (s + len + 3 <= NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) // 3 bytes block header { msgs.push_back (msg); @@ -1059,12 +1133,12 @@ namespace transport break; } SendI2NPMsgs (msgs); - } + } } size_t NTCP2Session::CreatePaddingBlock (size_t msgLen, uint8_t * buf, size_t len) { - if (len < 3) return 0; + if (len < 3) return 0; len -= 3; if (msgLen < 256) msgLen = 256; // for short message padding should not be always zero size_t paddingSize = (msgLen*NTCP2_MAX_PADDING_RATIO)/100; @@ -1073,10 +1147,10 @@ namespace transport if (paddingSize) paddingSize = rand () % paddingSize; buf[0] = eNTCP2BlkPadding; // blk htobe16buf (buf + 1, paddingSize); // size - memset (buf + 3, 0, paddingSize); + memset (buf + 3, 0, paddingSize); return paddingSize + 3; - } - + } + void NTCP2Session::SendRouterInfo () { if (!IsEstablished ()) return; @@ -1094,14 +1168,158 @@ namespace transport EncryptAndSendNextBuffer (payloadLen); } + void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) + { + m_ProxyType = proxytype; + m_ProxyAddress = addr; + m_ProxyPort = port; + } + + void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + if(ecode) + { + LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); + timer->cancel(); + conn->Terminate(); + return; + } + if(m_ProxyType == eSocksProxy) + { + // TODO: support username/password auth etc + uint8_t buff[3] = {0x05, 0x01, 0x00}; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), [=] (const boost::system::error_code & ec, std::size_t transferred) { + (void) transferred; + if(ec) + { + LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); + } + }); + uint8_t readbuff[2]; + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), [=](const boost::system::error_code & ec, std::size_t transferred) + { + LogPrint(eLogError, "NTCP2: ", transferred); + if(ec) + { + LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + return; + } + else if(transferred == 2) + { + if(readbuff[1] == 0xba) + { + AfterSocksHandshake(conn, timer, host, port, addrtype); + return; + } + else if (readbuff[1] == 0xff) + { + LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + timer->cancel(); + conn->Terminate(); + return; + } + LogPrint(eLogError, "NTCP2:", readbuff[1]); + } + LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); + timer->cancel(); + conn->Terminate(); + }); + } + else if(m_ProxyType == eHTTPProxy) + { + i2p::http::HTTPReq req; + req.method = "CONNECT"; + req.version ="HTTP/1.1"; + if(addrtype == eIP6Address) + req.uri = "[" + host + "]:" + std::to_string(port); + else + req.uri = host + ":" + std::to_string(port); + + boost::asio::streambuf writebuff; + std::ostream out(&writebuff); + out << req.to_string(); + + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); + }); + + boost::asio::streambuf * readbuff = new boost::asio::streambuf; + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", [=] (const boost::system::error_code & ec, std::size_t transferred) { + if(ec) + { + LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + } + else + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + { + LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); + } + } + else + LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); + } + else + LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); + } + + void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) + { + if(m_ProxyEndpoint == nullptr) + { + return; + } + GetService().post([=]() { + if (this->AddNTCP2Session (conn)) + { + + auto timer = std::make_shared(GetService()); + auto timeout = NTCP_CONNECT_TIMEOUT * 5; + conn->SetTerminationTimeout(timeout * 2); + timer->expires_from_now (boost::posix_time::seconds(timeout)); + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); + } + }); + } + void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { if (!m_SendKey || !m_SendSipKey) return; - m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block + 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; m_NextSendBuffer[3] = 0; m_NextSendBuffer[4] = 9; // 9 bytes block size - htobe64buf (m_NextSendBuffer + 5, m_ReceiveSequenceNumber); + htobe64buf (m_NextSendBuffer + 5, m_ReceiveSequenceNumber); m_NextSendBuffer[13] = (uint8_t)reason; // padding block auto paddingSize = CreatePaddingBlock (12, m_NextSendBuffer + 14, 19); @@ -1125,13 +1343,13 @@ namespace transport if (m_IsTerminated) return; for (auto it: msgs) m_SendQueue.push_back (it); - if (!m_IsSending) - SendQueue (); + if (!m_IsSending) + SendQueue (); else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) { LogPrint (eLogWarning, "NTCP2: outgoing messages queue size exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); Terminate (); - } + } } void NTCP2Session::SendLocalRouterInfo () @@ -1142,6 +1360,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), + m_ProxyType(eNoProxy), m_Resolver(GetService ()), m_ProxyEndpoint(nullptr), m_TerminationTimer (GetService ()) { } @@ -1156,45 +1375,69 @@ namespace transport if (!IsRunning ()) { StartIOService (); - auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (const auto& address: addresses) + if(UsingProxy()) { - if (!address) continue; - if (address->IsPublishedNTCP2 ()) + LogPrint(eLogError, "NTCP2: USING PROXY "); + // TODO: resolve proxy until it is resolved + boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); + boost::system::error_code e; + auto itr = m_Resolver.resolve(q, e); + if(e) { - if (address->host.is_v4()) + LogPrint(eLogError, "NTCP2: Failed to resolve proxy ", e.message()); + } + else + { + m_ProxyEndpoint = new boost::asio::ip::tcp::endpoint(*itr); + if (m_ProxyEndpoint) { - try - { - m_NTCP2Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port))); - } - catch ( std::exception & ex ) - { - LogPrint(eLogError, "NTCP2: Failed to bind to ip4 port ",address->port, ex.what()); - continue; - } - - LogPrint (eLogInfo, "NTCP2: Start listening TCP port ", address->port); - auto conn = std::make_shared(*this); - m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); + LogPrint(eLogError, "NTCP2: m_ProxyEndpoint %s", m_ProxyEndpoint); } - else if (address->host.is_v6() && context.SupportsV6 ()) + } + } + else + { + LogPrint(eLogError, "NTCP2: NOTUSING PROXY "); + auto& addresses = context.GetRouterInfo ().GetAddresses (); + for (const auto& address: addresses) + { + if (!address) continue; + if (address->IsPublishedNTCP2 ()) { - m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ())); - try + if (address->host.is_v4()) { - 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)); - m_NTCP2V6Acceptor->listen (); + try + { + m_NTCP2Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port))); + } + catch ( std::exception & ex ) + { + LogPrint(eLogError, "NTCP2: Failed to bind to ip4 port ",address->port, ex.what()); + continue; + } - LogPrint (eLogInfo, "NTCP2: Start listening V6 TCP port ", address->port); - auto conn = std::make_shared (*this); - m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); - } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: failed to bind to ip6 port ", address->port); - continue; + LogPrint (eLogInfo, "NTCP2: Start listening TCP port ", address->port); + 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 ()) + { + m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ())); + try + { + 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)); + m_NTCP2V6Acceptor->listen (); + + LogPrint (eLogInfo, "NTCP2: Start listening V6 TCP port ", address->port); + auto conn = std::make_shared (*this); + m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); + } catch ( std::exception & ex ) { + LogPrint(eLogError, "NTCP2: failed to bind to ip6 port ", address->port); + continue; + } } } } @@ -1216,14 +1459,21 @@ namespace transport m_NTCP2Sessions.clear (); if (IsRunning ()) + { m_TerminationTimer.cancel (); + if(m_ProxyEndpoint) + { + delete m_ProxyEndpoint; + m_ProxyEndpoint = nullptr; + } + } StopIOService (); } bool NTCP2Server::AddNTCP2Session (std::shared_ptr session, bool incoming) { if (!session) return false; - if (incoming) + if (incoming) m_PendingIncomingSessions.remove (session); if (!session->GetRemoteIdentity ()) return false; auto& ident = session->GetRemoteIdentity ()->GetIdentHash (); @@ -1255,7 +1505,7 @@ namespace transport void NTCP2Server::Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn) { LogPrint (eLogDebug, "NTCP2: Connecting to ", address ,":", port); - GetService ().post([this, address, port, conn]() + GetService ().post([this, address, port, conn]() { if (this->AddNTCP2Session (conn)) { @@ -1263,7 +1513,7 @@ namespace transport auto timeout = NTCP2_CONNECT_TIMEOUT * 5; conn->SetTerminationTimeout(timeout * 2); timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) { @@ -1391,4 +1641,3 @@ namespace transport } } } - diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 7e3c53e8..9e784c88 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -28,7 +28,7 @@ namespace i2p namespace transport { - const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519; + const size_t NTCP2_UNENCRYPTED_FRAME_MAX_SIZE = 65519; const int NTCP2_MAX_PADDING_RATIO = 6; // in % const int NTCP2_CONNECT_TIMEOUT = 5; // 5 seconds @@ -36,7 +36,7 @@ namespace transport const int NTCP2_TERMINATION_TIMEOUT = 120; // 2 minutes const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds - const int NTCP2_CLOCK_SKEW = 60; // in seconds + 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 @@ -46,8 +46,8 @@ namespace transport eNTCP2BlkRouterInfo, // 2 eNTCP2BlkI2NPMessage, // 3 eNTCP2BlkTermination, // 4 - eNTCP2BlkPadding = 254 - }; + eNTCP2BlkPadding = 254 + }; enum NTCP2TerminationReason { @@ -69,16 +69,16 @@ namespace transport eNTCP2RouterInfoSignatureVerificationFail, // 15 eNTCP2IncorrectSParameter, // 16 eNTCP2Banned, // 17 - }; - + }; + // RouterInfo flags - const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01; + const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01; struct NTCP2Establisher { NTCP2Establisher (); ~NTCP2Establisher (); - + const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); }; const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set @@ -114,19 +114,20 @@ namespace transport uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/; i2p::data::IdentHash m_RemoteIdentHash; - uint16_t m3p2Len; + uint16_t m3p2Len; uint8_t * m_SessionRequestBuffer, * m_SessionCreatedBuffer, * m_SessionConfirmedBuffer; size_t m_SessionRequestBufferLen, m_SessionCreatedBufferLen; - }; + }; class NTCP2Server; class NTCP2Session: public TransportSession, public std::enable_shared_from_this { public: - NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter = nullptr); + + NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter = nullptr); ~NTCP2Session (); void Terminate (); void TerminateByTimeout (); @@ -138,9 +139,9 @@ namespace transport bool IsEstablished () const { return m_IsEstablished; }; bool IsTerminated () const { return m_IsTerminated; }; - void ClientLogin (); // Alice + void ClientLogin (); // Alice void ServerLogin (); // Bob - + void SendLocalRouterInfo (); // after handshake void SendI2NPMessages (const std::vector >& msgs); @@ -193,15 +194,15 @@ namespace transport std::unique_ptr m_Establisher; // data phase - uint8_t m_Kab[32], m_Kba[32], m_Sipkeysab[32], m_Sipkeysba[32]; + uint8_t m_Kab[32], m_Kba[32], m_Sipkeysab[32], m_Sipkeysba[32]; const uint8_t * m_SendKey, * m_ReceiveKey; -#if OPENSSL_SIPHASH +#if OPENSSL_SIPHASH EVP_PKEY * m_SendSipKey, * m_ReceiveSipKey; EVP_MD_CTX * m_SendMDCtx, * m_ReceiveMDCtx; #else const uint8_t * m_SendSipKey, * m_ReceiveSipKey; #endif - uint16_t m_NextReceivedLen; + uint16_t m_NextReceivedLen; uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer; union { @@ -220,6 +221,20 @@ namespace transport { public: + enum RemoteAddressType + { + eIP4Address, + eIP6Address, + eHostname + }; + + enum ProxyType + { + eNoProxy, + eSocksProxy, + eHTTPProxy + }; + NTCP2Server (); ~NTCP2Server (); @@ -230,15 +245,23 @@ namespace transport bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); void RemoveNTCP2Session (std::shared_ptr session); std::shared_ptr FindNTCP2Session (const i2p::data::IdentHash& ident); - + + void ConnectWithProxy (const std::string& addr, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn); void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn); + void AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype); + + + bool UsingProxy() const { return m_ProxyType != eNoProxy; }; + void UseProxy(ProxyType proxy, const std::string & address, uint16_t port); + private: void HandleAccept (std::shared_ptr conn, const boost::system::error_code& error); void HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error); - void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); + void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); + void HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); // timer void ScheduleTermination (); @@ -248,9 +271,15 @@ namespace transport boost::asio::deadline_timer m_TerminationTimer; std::unique_ptr m_NTCP2Acceptor, m_NTCP2V6Acceptor; - std::map > m_NTCP2Sessions; + std::map > m_NTCP2Sessions; std::list > m_PendingIncomingSessions; + ProxyType m_ProxyType; + std::string m_ProxyAddress; + uint16_t m_ProxyPort; + boost::asio::ip::tcp::resolver m_Resolver; + boost::asio::ip::tcp::endpoint * m_ProxyEndpoint; + public: // for HTTP/I2PControl diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 42a605a4..34ec25f4 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -157,6 +157,7 @@ namespace transport m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); + std::string ntcp2proxy; i2p::config::GetOption("ntcp2proxy", ntcp2proxy); i2p::http::URL proxyurl; uint16_t softLimit, hardLimit, threads; i2p::config::GetOption("limits.ntcpsoft", softLimit); @@ -196,13 +197,36 @@ namespace transport LogPrint(eLogError, "Transports: invalid NTCP proxy url ", ntcpproxy); return; } - // create NTCP2. TODO: move to acceptor + // create NTCP2. TODO: move to acceptor bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { - m_NTCP2Server = new NTCP2Server (); - m_NTCP2Server->Start (); - } + if(ntcp2proxy.size()) + { + if(proxyurl.parse(ntcp2proxy)) + { + if(proxyurl.schema == "socks" || proxyurl.schema == "http") + { + m_NTCP2Server = new NTCP2Server (); + NTCP2Server::ProxyType proxytype = NTCP2Server::eSocksProxy; + + if (proxyurl.schema == "http") + proxytype = NTCP2Server::eHTTPProxy; + + m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; + m_NTCP2Server->Start(); + } + else + LogPrint(eLogError, "Transports: unsupported NTCP2 proxy URL ", ntcp2proxy); + } + else + LogPrint(eLogError, "Transports: invalid NTCP2 proxy url ", ntcp2proxy); + return; + } + + // m_NTCP2Server = new NTCP2Server (); + // m_NTCP2Server->Start (); + } // create acceptors auto& addresses = context.GetRouterInfo ().GetAddresses (); @@ -405,24 +429,36 @@ namespace transport { if (peer.router) // we have RI already { - if (!peer.numAttempts) // NTCP2 - { - peer.numAttempts++; - if (m_NTCP2Server) // we support NTCP2 - { - // NTCP2 have priority over NTCP - auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address) - { - auto s = std::make_shared (*m_NTCP2Server, peer.router); - m_NTCP2Server->Connect (address->host, address->port, s); - return true; - } - } - } + if (!peer.numAttempts) // NTCP2 + { + peer.numAttempts++; + if (m_NTCP2Server) // we support NTCP2 + { + // NTCP2 have priority over NTCP + auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only + if (address) + { + auto s = std::make_shared (*m_NTCP2Server, peer.router); + + if(m_NTCP2Server->UsingProxy()) + { + NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address; + std::string addr = address->host.to_string(); + + if(address->host.is_v6()) + remote = NTCP2Server::eIP6Address; + + m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s); + } + else + m_NTCP2Server->Connect (address->host, address->port, s); + return true; + } + } + } if (peer.numAttempts == 1) // NTCP1 { - peer.numAttempts++; + peer.numAttempts++; auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); if (address && m_NTCPServer) { @@ -650,14 +686,14 @@ namespace transport { auto before = it->second.sessions.size (); it->second.sessions.remove (session); - if (it->second.sessions.empty ()) + if (it->second.sessions.empty ()) { if (it->second.delayedMessages.size () > 0) { if (before > 0) // we had an active session before it->second.numAttempts = 0; // start over ConnectToPeer (ident, it->second); - } + } else { std::unique_lock l(m_PeersMutex); From ae20e3aa953fb9926b9ca14838df578d9dcefe40 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 1 Mar 2020 11:24:18 -0500 Subject: [PATCH 0230/2950] NTCP2 proxy --- libi2pd/NTCP2.cpp | 152 +++++++++++++++++++++++----------------------- libi2pd/NTCP2.h | 4 +- 2 files changed, 77 insertions(+), 79 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index a3c42790..10cc3d89 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1175,16 +1175,18 @@ namespace transport m_ProxyPort = port; } - void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + if (ecode) { - if(ecode) - { - LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); - timer->cancel(); - conn->Terminate(); - return; - } - if(m_ProxyType == eSocksProxy) + LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); + timer->cancel(); + conn->Terminate(); + return; + } + switch (m_ProxyType) + { + case eSocksProxy: { // TODO: support username/password auth etc uint8_t buff[3] = {0x05, 0x01, 0x00}; @@ -1196,7 +1198,8 @@ namespace transport } }); uint8_t readbuff[2]; - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), [=](const boost::system::error_code & ec, std::size_t transferred) + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), + [=](const boost::system::error_code & ec, std::size_t transferred) { LogPrint(eLogError, "NTCP2: ", transferred); if(ec) @@ -1226,71 +1229,73 @@ namespace transport timer->cancel(); conn->Terminate(); }); + break; } - else if(m_ProxyType == eHTTPProxy) - { - i2p::http::HTTPReq req; - req.method = "CONNECT"; - req.version ="HTTP/1.1"; - if(addrtype == eIP6Address) - req.uri = "[" + host + "]:" + std::to_string(port); - else - req.uri = host + ":" + std::to_string(port); - - boost::asio::streambuf writebuff; - std::ostream out(&writebuff); - out << req.to_string(); - - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); - }); - - boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", [=] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) - { - LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } + case eHTTPProxy: + { + i2p::http::HTTPReq req; + req.method = "CONNECT"; + req.version ="HTTP/1.1"; + if(addrtype == eIP6Address) + req.uri = "[" + host + "]:" + std::to_string(port); else + req.uri = host + ":" + std::to_string(port); + + boost::asio::streambuf writebuff; + std::ostream out(&writebuff); + out << req.to_string(); + + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); + }); + + boost::asio::streambuf * readbuff = new boost::asio::streambuf; + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", + [=] (const boost::system::error_code & ec, std::size_t transferred) { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + if(ec) { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - { - LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); - } + LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); } else - LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); - } - else - LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + { + LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); + } + } + else + LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); + break; + } + default: + LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); + } } void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) { - if(m_ProxyEndpoint == nullptr) - { - return; - } + if(!m_ProxyEndpoint) return GetService().post([=]() { if (this->AddNTCP2Session (conn)) { @@ -1359,9 +1364,8 @@ namespace transport } NTCP2Server::NTCP2Server (): - RunnableServiceWithWork ("NTCP2"), - m_ProxyType(eNoProxy), m_Resolver(GetService ()), m_ProxyEndpoint(nullptr), - m_TerminationTimer (GetService ()) + RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), + m_Resolver(GetService ()) { } @@ -1388,11 +1392,9 @@ namespace transport } else { - m_ProxyEndpoint = new boost::asio::ip::tcp::endpoint(*itr); + m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr)); if (m_ProxyEndpoint) - { - LogPrint(eLogError, "NTCP2: m_ProxyEndpoint %s", m_ProxyEndpoint); - } + LogPrint(eLogError, "NTCP2: m_ProxyEndpoint ", *m_ProxyEndpoint); } } else @@ -1461,11 +1463,7 @@ namespace transport if (IsRunning ()) { m_TerminationTimer.cancel (); - if(m_ProxyEndpoint) - { - delete m_ProxyEndpoint; - m_ProxyEndpoint = nullptr; - } + m_ProxyEndpoint = nullptr; } StopIOService (); } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 9e784c88..11ae5995 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -274,11 +274,11 @@ namespace transport std::map > m_NTCP2Sessions; std::list > m_PendingIncomingSessions; - ProxyType m_ProxyType; + ProxyType m_ProxyType =eNoProxy; std::string m_ProxyAddress; uint16_t m_ProxyPort; boost::asio::ip::tcp::resolver m_Resolver; - boost::asio::ip::tcp::endpoint * m_ProxyEndpoint; + std::unique_ptr m_ProxyEndpoint; public: From e969d58689a6a5f57e896ef6b8e0dab649904c8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 1 Mar 2020 15:11:54 -0500 Subject: [PATCH 0231/2950] handle ntcp2.proxy parameter --- libi2pd/Config.cpp | 4 +- libi2pd/NTCP2.cpp | 139 +++++++++++++++++++++-------------------- libi2pd/Transports.cpp | 12 ++-- 3 files changed, 80 insertions(+), 75 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 4050f769..521ebf65 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -60,8 +60,7 @@ namespace config { ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") - ("ntcp2proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") + ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") @@ -240,6 +239,7 @@ namespace config { ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ("ntcp2.addressv6", value()->default_value("::"), "Address to bind NTCP2 on") + ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") ; options_description nettime("Time sync options"); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 10cc3d89..c46dbd81 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1189,46 +1189,48 @@ namespace transport case eSocksProxy: { // TODO: support username/password auth etc - uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), [=] (const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); - } - }); - uint8_t readbuff[2]; - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), - [=](const boost::system::error_code & ec, std::size_t transferred) - { - LogPrint(eLogError, "NTCP2: ", transferred); - if(ec) - { - LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if(readbuff[1] == 0xba) + static const uint8_t buff[3] = {0x05, 0x01, 0x00}; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), + [] (const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) { - AfterSocksHandshake(conn, timer, host, port, addrtype); - return; + LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); } - else if (readbuff[1] == 0xff) + }); + auto readbuff = std::make_shared >(); + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(*readbuff, 2), + [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) + { + LogPrint(eLogError, "NTCP2: ", transferred); + if(ec) { - LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); timer->cancel(); conn->Terminate(); return; } - LogPrint(eLogError, "NTCP2:", readbuff[1]); - } - LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); - timer->cancel(); - conn->Terminate(); - }); + else if(transferred == 2) + { + if((*readbuff)[1] == 0xba) + { + AfterSocksHandshake(conn, timer, host, port, addrtype); + return; + } + else if ((*readbuff)[1] == 0xff) + { + LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + timer->cancel(); + conn->Terminate(); + return; + } + LogPrint(eLogError, "NTCP2:", (*readbuff)[1]); + } + LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); + timer->cancel(); + conn->Terminate(); + }); break; } case eHTTPProxy: @@ -1245,47 +1247,47 @@ namespace transport std::ostream out(&writebuff); out << req.to_string(); - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); - }); + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); + }); boost::asio::streambuf * readbuff = new boost::asio::streambuf; boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [=] (const boost::system::error_code & ec, std::size_t transferred) - { - if(ec) + [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) { - LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } - else - { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + if(ec) { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - { - LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); - } + LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); } else - LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); + } + else + LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); break; } default: @@ -1304,7 +1306,8 @@ namespace transport auto timeout = NTCP_CONNECT_TIMEOUT * 5; conn->SetTerminationTimeout(timeout * 2); timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + { if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 34ec25f4..8a36c5aa 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -157,7 +157,7 @@ namespace transport m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); - std::string ntcp2proxy; i2p::config::GetOption("ntcp2proxy", ntcp2proxy); + std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); i2p::http::URL proxyurl; uint16_t softLimit, hardLimit, threads; i2p::config::GetOption("limits.ntcpsoft", softLimit); @@ -201,7 +201,7 @@ namespace transport bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { - if(ntcp2proxy.size()) + if(!ntcp2proxy.empty()) { if(proxyurl.parse(ntcp2proxy)) { @@ -223,9 +223,11 @@ namespace transport LogPrint(eLogError, "Transports: invalid NTCP2 proxy url ", ntcp2proxy); return; } - - // m_NTCP2Server = new NTCP2Server (); - // m_NTCP2Server->Start (); + else + { + m_NTCP2Server = new NTCP2Server (); + m_NTCP2Server->Start (); + } } // create acceptors From 35e8424293e62be087e4a0b5daac11153e46169a Mon Sep 17 00:00:00 2001 From: potatowipedlifereverse Date: Mon, 2 Mar 2020 01:47:48 +0300 Subject: [PATCH 0232/2950] preinit webview+configparser+README.md tabulation fixes configparser to comments dont need pre init webview readme changes delete submodules webview in main menu webview pre init delete modules delete submodules --- .gitmodules | 0 android/AndroidManifest.xml | 1 + android/README.md | 19 ++++++++++++++++ android/res/layout/webview.xml | 13 +++++++++++ android/res/menu/options_main.xml | 4 ++++ android/res/values/strings.xml | 1 + .../src/org/purplei2p/i2pd/I2PDActivity.java | 22 +++++++++++++++++++ 7 files changed, 60 insertions(+) create mode 100644 .gitmodules create mode 100644 android/README.md create mode 100644 android/res/layout/webview.xml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e69de29b diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 71526701..a95e3773 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -17,6 +17,7 @@ android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar" android:requestLegacyExternalStorage="true" + android:usesCleartextTraffic="true" > diff --git a/android/README.md b/android/README.md new file mode 100644 index 00000000..de6a16c3 --- /dev/null +++ b/android/README.md @@ -0,0 +1,19 @@ +# how to compile? +## Install the gradle + NDK or use android-studio +[![https://gradle.org/install/]](https://gradle.org/install/) + +## Install the depencies +``` +git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0 +git clone https://github.com/PurpleI2P/android-ifaddrs.git +git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git +git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git +``` +## Set libs in jni/Application.mk on 24 line: +``` +# change to your own +I2PD_LIBS_PATH = /home/user/i2pd/android/ +``` + +## compile apk file +gradle clean assembleRelease diff --git a/android/res/layout/webview.xml b/android/res/layout/webview.xml new file mode 100644 index 00000000..d13be23e --- /dev/null +++ b/android/res/layout/webview.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/android/res/menu/options_main.xml b/android/res/menu/options_main.xml index 089c2700..b0f23bd2 100644 --- a/android/res/menu/options_main.xml +++ b/android/res/menu/options_main.xml @@ -12,6 +12,10 @@ android:id="@+id/action_graceful_stop" android:orderInCategory="98" android:title="@string/action_graceful_stop" /> + Battery Optimizations Your Android OS version does not support showing the dialog for battery optimizations for applications. Planned shutdown canceled + Start webview diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 89881b42..7949e8d0 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -39,15 +39,23 @@ import android.view.MenuItem; import android.widget.TextView; import android.widget.Toast; + import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; // For future package update checking +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; + + import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS; public class I2PDActivity extends Activity { + private WebView webView; + private static final String TAG = "i2pdActvt"; private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1; public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; @@ -56,6 +64,7 @@ public class I2PDActivity extends Activity { private TextView textView; private boolean assetsCopied; private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/"; + //private ConfigParser parser = new ConfigParser(i2pdpath); // TODO: private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); @@ -262,6 +271,16 @@ public class I2PDActivity extends Activity { case R.id.action_battery_otimizations: onActionBatteryOptimizations(); return true; + case R.id.action_start_webview: + setContentView(R.layout.webview); + this.webView = (WebView) findViewById(R.id.webview1); + this.webView.setWebViewClient(new WebViewClient()); + + WebSettings webSettings = this.webView.getSettings(); + webSettings.setBuiltInZoomControls(true); + webSettings.setJavaScriptEnabled(false); + this.webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort + break; } return super.onOptionsItemSelected(item); @@ -617,4 +636,7 @@ public class I2PDActivity extends Activity { } System.exit(0); } + public String getI2pdpath(){ + return this.i2pdpath; + } } From b6368170ed4049859f8c3e22e11a3a1def7ce159 Mon Sep 17 00:00:00 2001 From: wipedlifepotato <60944239+wipedlifepotato@users.noreply.github.com> Date: Mon, 2 Mar 2020 04:00:28 +0300 Subject: [PATCH 0233/2950] Update README.md --- android/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/README.md b/android/README.md index de6a16c3..e0850b15 100644 --- a/android/README.md +++ b/android/README.md @@ -1,6 +1,6 @@ # how to compile? ## Install the gradle + NDK or use android-studio -[![https://gradle.org/install/]](https://gradle.org/install/) +[https://gradle.org/install/](https://gradle.org/install/) ## Install the depencies ``` From c6ccb373a22ed6df9f5c13f7ca20a77a9ecaf339 Mon Sep 17 00:00:00 2001 From: potatowipedlifereverse Date: Mon, 2 Mar 2020 05:04:37 +0300 Subject: [PATCH 0234/2950] del geti2pdpath --- android/src/org/purplei2p/i2pd/I2PDActivity.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 7949e8d0..258bafe2 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -636,7 +636,4 @@ public class I2PDActivity extends Activity { } System.exit(0); } - public String getI2pdpath(){ - return this.i2pdpath; - } } From 2d3fad2cdbf01f2fa19e4a9fb708db80ca432902 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 2 Mar 2020 16:24:00 -0500 Subject: [PATCH 0235/2950] correct proxy buffers --- libi2pd/NTCP2.cpp | 450 +++++++++++++++++++++++----------------------- 1 file changed, 226 insertions(+), 224 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index c46dbd81..3dfd6250 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -377,78 +377,6 @@ namespace transport } } - void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - - // build request - size_t sz = 0; - uint8_t buff[256]; - uint8_t readbuff[256]; - buff[0] = 0x05; - buff[1] = 0x01; - buff[2] = 0x00; - - if(addrtype == eIP4Address) - { - buff[3] = 0x01; - auto addr = boost::asio::ip::address::from_string(host).to_v4(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eIP6Address) - { - buff[3] = 0x04; - auto addr = boost::asio::ip::address::from_string(host).to_v6(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eHostname) - { - buff[3] = 0x03; - size_t addrsize = host.size(); - sz = addrsize + 1 + 4; - if (2 + sz > sizeof(buff)) - { - // too big - return; - } - buff[4] = (uint8_t) addrsize; - memcpy(buff+5, host.c_str(), addrsize); - } - htobe16buf(buff+sz, port); - sz += 2; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, sz), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t written) { - if(ec) - { - LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); - return; - } - }); - - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) { - if(e) - { - LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); - } - else if(transferred == sz) - { - if( readbuff[1] == 0x00) - { - timer->cancel(); - conn->ClientLogin(); - return; - } - } - if(!e) - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - timer->cancel(); - conn->Terminate(); - }); - } - - NTCP2Session::~NTCP2Session () { delete[] m_NextReceivedBuffer; @@ -1168,158 +1096,6 @@ namespace transport EncryptAndSendNextBuffer (payloadLen); } - void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) - { - m_ProxyType = proxytype; - m_ProxyAddress = addr; - m_ProxyPort = port; - } - - void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - if (ecode) - { - LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); - timer->cancel(); - conn->Terminate(); - return; - } - switch (m_ProxyType) - { - case eSocksProxy: - { - // TODO: support username/password auth etc - static const uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), - [] (const boost::system::error_code & ec, std::size_t transferred) - { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); - } - }); - auto readbuff = std::make_shared >(); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(*readbuff, 2), - [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) - { - LogPrint(eLogError, "NTCP2: ", transferred); - if(ec) - { - LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if((*readbuff)[1] == 0xba) - { - AfterSocksHandshake(conn, timer, host, port, addrtype); - return; - } - else if ((*readbuff)[1] == 0xff) - { - LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); - timer->cancel(); - conn->Terminate(); - return; - } - LogPrint(eLogError, "NTCP2:", (*readbuff)[1]); - } - LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); - timer->cancel(); - conn->Terminate(); - }); - break; - } - case eHTTPProxy: - { - i2p::http::HTTPReq req; - req.method = "CONNECT"; - req.version ="HTTP/1.1"; - if(addrtype == eIP6Address) - req.uri = "[" + host + "]:" + std::to_string(port); - else - req.uri = host + ":" + std::to_string(port); - - boost::asio::streambuf writebuff; - std::ostream out(&writebuff); - out << req.to_string(); - - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t transferred) - { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); - }); - - boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) - { - if(ec) - { - LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } - else - { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) - { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); - } - else - LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); - break; - } - default: - LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); - } - } - - void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) - { - if(!m_ProxyEndpoint) return - GetService().post([=]() { - if (this->AddNTCP2Session (conn)) - { - - auto timer = std::make_shared(GetService()); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; - conn->SetTerminationTimeout(timeout * 2); - timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); - } - }); - } - void NTCP2Session::SendTermination (NTCP2TerminationReason reason) { if (!m_SendKey || !m_SendSipKey) return; @@ -1640,5 +1416,231 @@ namespace transport ScheduleTermination (); } } + + void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) + { + m_ProxyType = proxytype; + m_ProxyAddress = addr; + m_ProxyPort = port; + } + + void NTCP2Server::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + if (ecode) + { + LogPrint(eLogWarning, "NTCP2: failed to connect to proxy ", ecode.message()); + timer->cancel(); + conn->Terminate(); + return; + } + switch (m_ProxyType) + { + case eSocksProxy: + { + // TODO: support username/password auth etc + static const uint8_t buff[3] = {0x05, 0x01, 0x00}; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), + [] (const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) + { + LogPrint(eLogWarning, "NTCP2: socks5 write error ", ec.message()); + } + }); + auto readbuff = std::make_shared >(2); + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), + [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) + { + if(ec) + { + LogPrint(eLogError, "NTCP2: socks5 read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + return; + } + else if(transferred == 2) + { + if((*readbuff)[1] == 0x00) + { + AfterSocksHandshake(conn, timer, host, port, addrtype); + return; + } + else if ((*readbuff)[1] == 0xff) + { + LogPrint(eLogError, "NTCP2: socks5 proxy rejected authentication"); + timer->cancel(); + conn->Terminate(); + return; + } + LogPrint(eLogError, "NTCP2:", (int)(*readbuff)[1]); + } + LogPrint(eLogError, "NTCP2: socks5 server gave invalid response"); + timer->cancel(); + conn->Terminate(); + }); + break; + } + case eHTTPProxy: + { + i2p::http::HTTPReq req; + req.method = "CONNECT"; + req.version ="HTTP/1.1"; + if(addrtype == eIP6Address) + req.uri = "[" + host + "]:" + std::to_string(port); + else + req.uri = host + ":" + std::to_string(port); + + boost::asio::streambuf writebuff; + std::ostream out(&writebuff); + out << req.to_string(); + + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t transferred) + { + (void) transferred; + if(ec) + LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); + }); + + boost::asio::streambuf * readbuff = new boost::asio::streambuf; + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", + [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) + { + if(ec) + { + LogPrint(eLogError, "NTCP2: http proxy read error ", ec.message()); + timer->cancel(); + conn->Terminate(); + } + else + { + readbuff->commit(transferred); + i2p::http::HTTPRes res; + if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + { + if(res.code == 200) + { + timer->cancel(); + conn->ClientLogin(); + delete readbuff; + return; + } + else + LogPrint(eLogError, "NTCP2: http proxy rejected request ", res.code); + } + else + LogPrint(eLogError, "NTCP2: http proxy gave malformed response"); + timer->cancel(); + conn->Terminate(); + delete readbuff; + } + }); + break; + } + default: + LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); + } + } + + void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) + { + if(!m_ProxyEndpoint) return; + GetService().post([this, host, port, addrtype, conn]() { + if (this->AddNTCP2Session (conn)) + { + + auto timer = std::make_shared(GetService()); + auto timeout = NTCP_CONNECT_TIMEOUT * 5; + conn->SetTerminationTimeout(timeout * 2); + timer->expires_from_now (boost::posix_time::seconds(timeout)); + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); + } + }); + } + + void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) + { + // build request + size_t sz = 0; + auto buff = std::make_shared >(256); + auto readbuff = std::make_shared >(256); + (*buff)[0] = 0x05; + (*buff)[1] = 0x01; + (*buff)[2] = 0x00; + + if(addrtype == eIP4Address) + { + (*buff)[3] = 0x01; + auto addr = boost::asio::ip::address::from_string(host).to_v4(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff->data () + 4, addrbytes.data(), addrsize); + } + else if (addrtype == eIP6Address) + { + (*buff)[3] = 0x04; + auto addr = boost::asio::ip::address::from_string(host).to_v6(); + auto addrbytes = addr.to_bytes(); + auto addrsize = addrbytes.size(); + memcpy(buff->data () + 4, addrbytes.data(), addrsize); + } + else if (addrtype == eHostname) + { + (*buff)[3] = 0x03; + size_t addrsize = host.size(); + sz = addrsize + 1 + 4; + if (2 + sz > buff->size ()) + { + // too big + return; + } + (*buff)[4] = (uint8_t) addrsize; + memcpy(buff->data() + 5, host.c_str(), addrsize); + } + htobe16buf(buff->data () + sz, port); + sz += 2; + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t written) + { + if(ec) + { + LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); + return; + } + }); + + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 10), + [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) + { + if(e) + { + LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); + } + else if(transferred == sz) + { + if((*readbuff)[1] == 0x00) + { + timer->cancel(); + conn->ClientLogin(); + return; + } + } + if(!e) + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + timer->cancel(); + conn->Terminate(); + }); + } + } } From 1e9a53da3fead5b1caaea7145ef90eb411bc2ff7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Mar 2020 15:54:09 -0500 Subject: [PATCH 0236/2950] delete stream by id for HTTP interface --- libi2pd/Destination.cpp | 10 ++++++++++ libi2pd/Destination.h | 1 + libi2pd/Streaming.cpp | 9 +++++++++ libi2pd/Streaming.h | 1 + 4 files changed, 21 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6544d120..d4620ed9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1191,6 +1191,16 @@ namespace client } } + bool ClientDestination::DeleteStream (uint32_t recvStreamID) + { + if (m_StreamingDestination->DeleteStream (recvStreamID)) + return true; + for (auto it: m_StreamingDestinationsByPorts) + if (it.second->DeleteStream (recvStreamID)) + return true; + return false; + } + RunnableClientDestination::RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): RunnableService ("Destination"), ClientDestination (GetIOService (), keys, isPublic, params) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index ed3abdfb..23ed5188 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -281,6 +281,7 @@ namespace client // for HTTP only std::vector > GetAllStreams () const; + bool DeleteStream (uint32_t recvStreamID); }; class RunnableClientDestination: private i2p::util::RunnableService, public ClientDestination diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index b5f935fe..97a653f5 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1128,6 +1128,15 @@ namespace stream } } + bool StreamingDestination::DeleteStream (uint32_t recvStreamID) + { + auto it = m_Streams.find (recvStreamID); + if (it == m_Streams.end ()) + return false; + DeleteStream (it->second); + return true; + } + void StreamingDestination::SetAcceptor (const Acceptor& acceptor) { m_Acceptor = acceptor; // we must set it immediately for IsAcceptorSet diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 3424bb2d..9962ad8d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -250,6 +250,7 @@ namespace stream std::shared_ptr CreateNewOutgoingStream (std::shared_ptr remote, int port = 0); void DeleteStream (std::shared_ptr stream); + bool DeleteStream (uint32_t recvStreamID); void SetAcceptor (const Acceptor& acceptor); void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; From 5eec580727df7d2865f6478ccb21498fafa2556f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Mar 2020 18:31:22 -0500 Subject: [PATCH 0237/2950] delete strem from destination upon termination --- libi2pd/Streaming.cpp | 7 ++++--- libi2pd/Streaming.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 97a653f5..3efcfb99 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -86,13 +86,14 @@ namespace stream LogPrint (eLogDebug, "Streaming: Stream deleted"); } - void Stream::Terminate () // shoudl be called from StreamingDestination::Stop only + void Stream::Terminate (bool deleteFromDestination) // shoudl be called from StreamingDestination::Stop only { m_AckSendTimer.cancel (); m_ReceiveTimer.cancel (); m_ResendTimer.cancel (); //CleanUp (); /* Need to recheck - broke working on windows */ - //m_LocalDestination.DeleteStream (shared_from_this ()); + if (deleteFromDestination) + m_LocalDestination.DeleteStream (shared_from_this ()); } void Stream::CleanUp () @@ -993,7 +994,7 @@ namespace stream { std::unique_lock l(m_StreamsMutex); for (auto it: m_Streams) - it.second->Terminate (); + it.second->Terminate (false); // we delete here m_Streams.clear (); m_IncomingStreams.clear (); } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 9962ad8d..985a7eca 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -180,7 +180,7 @@ namespace stream int GetWindowSize () const { return m_WindowSize; }; int GetRTT () const { return m_RTT; }; - void Terminate (); + void Terminate (bool deleteFromDestination = true); private: From 51d018acc61c84aca55d669a2157fdcf3e8cd4c3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 5 Mar 2020 04:14:39 +0300 Subject: [PATCH 0238/2950] webconsole: add stream closing Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 180 ++++++++++++++++++++++++++++-------------- daemon/HTTPServer.h | 1 + 2 files changed, 121 insertions(+), 60 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7dc6a9d2..36e26785 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -54,6 +54,7 @@ namespace http { " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " 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; color: initial;}\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" " .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n" " .left { float: left; position: absolute; }\r\n" @@ -64,10 +65,11 @@ namespace http { " .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" - " .slide p, .slide [type='checkbox']{ display:none; }\r\n" - " .slide [type='checkbox']:checked ~ p { display:block; margin-top: 0; padding: 0; }\r\n" + " .slide p, .slide [type='checkbox'] { display: none; }\r\n" + " .slide [type='checkbox']:checked ~ p { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" + " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -89,10 +91,12 @@ namespace http { const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; const char HTTP_COMMAND_RELOAD_CONFIG[] = "reload_config"; const char HTTP_COMMAND_LOGLEVEL[] = "set_loglevel"; + const char HTTP_COMMAND_KILLSTREAM[] = "closestream"; 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 void ShowUptime (std::stringstream& s, int seconds) { @@ -203,10 +207,7 @@ namespace http { s << "ERROR: " << string << "
\r\n"; } - void ShowStatus ( - std::stringstream& s, - bool includeHiddenContent, - i2p::http::OutputFormatEnum outputFormat) + void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat) { s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); @@ -253,12 +254,12 @@ namespace http { 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 << "
"; - if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n

\r\n"; - } - if(includeHiddenContent) { - s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; + s << "

"; + if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { + s << "\r\n\r\n

\r\n"; + } + if(includeHiddenContent) { + s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; s << "Our external address:" << "
\r\n" ; @@ -292,12 +293,12 @@ namespace http { } s << address->host.to_string() << ":" << address->port << "
\r\n"; } - } + } s << "

\r\n
\r\n"; - if(outputFormat==OutputFormatEnum::forQtUi) { - s << "
"; - } - s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; + 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"; @@ -308,17 +309,17 @@ namespace http { s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; - if(outputFormat==OutputFormatEnum::forWebConsole) { - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); - s << "\r\n"; - s << "
Services
ServiceState
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; - } + if(outputFormat==OutputFormatEnum::forWebConsole) { + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); + s << "\r\n"; + s << "
Services
ServiceState
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; + } } void ShowLocalDestinations (std::stringstream& s) @@ -352,7 +353,7 @@ namespace http { static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr dest) { - s << "Base64:
\r\n
\r\n
\r\n"; if (dest->IsEncryptedLeaseSet ()) { @@ -403,19 +404,21 @@ namespace http { s << "
\r\n"; } - void ShowLocalDestination (std::stringstream& s, const std::string& b32) + void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token) { s << "Local Destination:
\r\n
\r\n"; i2p::data::IdentHash ident; ident.FromBase32 (b32); auto dest = i2p::client::context.FindLocalDestination (ident); + if (dest) { ShowLeaseSetDestination (s, dest); // show streams - s << "\r\n"; - s << ""; - s << ""; + s << "
Streams
StreamIDDestination
\r\n\r\n\r\n"; + s << ""; + s << ""; s << ""; s << ""; s << ""; @@ -424,13 +427,20 @@ namespace http { s << ""; s << ""; s << ""; - s << "\r\n"; + s << "\r\n\r\n\r\n"; for (const auto& it: dest->GetAllStreams ()) { + auto streamDest = i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()); s << ""; - s << ""; - s << ""; + s << ""; + if (it->GetRecvStreamID ()) { + s << ""; + } else { + s << ""; s << ""; s << ""; s << ""; @@ -441,7 +451,7 @@ namespace http { s << ""; s << "\r\n"; } - s << "
Streams
StreamID"; // Stream closing button column + s << "DestinationSentReceivedOutRTTWindowStatus
" << it->GetSendStreamID () << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << "" << it->GetRecvStreamID () << ""; + } + s << "" << streamDest << "" << it->GetNumSentBytes () << "" << it->GetNumReceivedBytes () << "" << it->GetSendQueueSize () << "" << (int)it->GetStatus () << "
"; + s << "\r\n"; } } @@ -858,7 +868,8 @@ namespace http { m_Socket->close (); } - bool HTTPConnection::CheckAuth (const HTTPReq & req) { + bool HTTPConnection::CheckAuth (const HTTPReq & req) + { /* method #1: http://user:pass@127.0.0.1:7070/ */ if (req.uri.find('@') != std::string::npos) { URL url; @@ -920,7 +931,7 @@ namespace http { } else if (req.uri.find("cmd=") != std::string::npos) { HandleCommand (req, res, s); } else { - ShowStatus (s, true, i2p::http::OutputFormatEnum::forWebConsole); + ShowStatus (s, true, i2p::http::OutputFormatEnum::forWebConsole); res.add_header("Refresh", "10"); } ShowPageTail (s); @@ -930,7 +941,23 @@ namespace http { SendReply (res, content); } - std::map HTTPConnection::m_Tokens; + uint32_t HTTPConnection::CreateToken () + { + uint32_t token; + RAND_bytes ((uint8_t *)&token, 4); + token &= 0x7FFFFFFF; // clear first bit + auto ts = i2p::util::GetSecondsSinceEpoch (); + for (auto it = m_Tokens.begin (); it != m_Tokens.end (); ) + { + if (ts > it->second + TOKEN_EXPIRATION_TIMEOUT) + it = m_Tokens.erase (it); + else + ++it; + } + m_Tokens[token] = ts; + return token; + } + void HTTPConnection::HandlePage (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { std::map params; @@ -947,18 +974,7 @@ namespace http { ShowTunnels (s); else if (page == HTTP_PAGE_COMMANDS) { - uint32_t token; - RAND_bytes ((uint8_t *)&token, 4); - token &= 0x7FFFFFFF; // clear first bit - auto ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_Tokens.begin (); it != m_Tokens.end (); ) - { - if (ts > it->second + TOKEN_EXPIRATION_TIMEOUT) - it = m_Tokens.erase (it); - else - ++it; - } - m_Tokens[token] = ts; + uint32_t token = CreateToken (); ShowCommands (s, token); } else if (page == HTTP_PAGE_TRANSIT_TUNNELS) @@ -966,7 +982,10 @@ namespace http { else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) ShowLocalDestinations (s); else if (page == HTTP_PAGE_LOCAL_DESTINATION) - ShowLocalDestination (s, params["b32"]); + { + uint32_t token = CreateToken (); + ShowLocalDestination (s, params["b32"], token); + } else if (page == HTTP_PAGE_I2CP_LOCAL_DESTINATION) ShowI2CPLocalDestination (s, params["i2cp_id"]); else if (page == HTTP_PAGE_SAM_SESSIONS) @@ -992,7 +1011,10 @@ namespace http { url.parse(req.uri); url.parse_query(params); + std::string webroot; i2p::config::GetOption("http.webroot", webroot); + std::string redirect = "5; url=" + webroot + "?page=commands"; std::string token = params["token"]; + if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ()) { ShowError(s, "Invalid token"); @@ -1008,36 +1030,74 @@ namespace http { i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_DISABLE_TRANSIT) i2p::context.SetAcceptsTunnels (false); - else if (cmd == HTTP_COMMAND_SHUTDOWN_START) { + else if (cmd == HTTP_COMMAND_SHUTDOWN_START) + { i2p::context.SetAcceptsTunnels (false); #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) Daemon.gracefulShutdownInterval = 10*60; #elif defined(WIN32_APP) i2p::win32::GracefulShutdown (); #endif - } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { + } + else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) + { i2p::context.SetAcceptsTunnels (true); #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) Daemon.gracefulShutdownInterval = 0; #elif defined(WIN32_APP) i2p::win32::StopGracefulShutdown (); #endif - } else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) { + } + else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) + { #ifndef WIN32_APP Daemon.running = false; #else i2p::win32::StopWin32App (); #endif - } else if (cmd == HTTP_COMMAND_LOGLEVEL){ + } + else if (cmd == HTTP_COMMAND_LOGLEVEL) + { std::string level = params["level"]; SetLogLevel (level); - } else { + } + else if (cmd == HTTP_COMMAND_KILLSTREAM) + { + std::string b32 = params["b32"]; + uint32_t streamID = std::stoul(params["streamID"], nullptr); + + i2p::data::IdentHash ident; + ident.FromBase32 (b32); + auto dest = i2p::client::context.FindLocalDestination (ident); + + if (streamID) + { + if (dest) + { + if(dest->DeleteStream (streamID)) + s << "SUCCESS: Stream closed

\r\n"; + else + s << "ERROR: Stream not found or already was closed

\r\n"; + } + else + s << "ERROR: Destination not found

\r\n"; + } + else + s << "ERROR: StreamID can be null

\r\n"; + + s << "Return to destination page
\r\n"; + s << "

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; + } + else + { res.code = 400; ShowError(s, "Unknown command: " + cmd); return; } - std::string webroot; i2p::config::GetOption("http.webroot", webroot); - std::string redirect = "5; url=" + webroot + "?page=commands"; + s << "SUCCESS: Command accepted

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

You will be redirected in 5 seconds"; diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index 3d32ed2b..f5ac95fc 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -35,6 +35,7 @@ namespace http void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void SendReply (HTTPRes & res, std::string & content); + uint32_t CreateToken (); private: From dd9b5faa5c072c24aadf4ca6c31d6ac00be992e1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Mar 2020 18:44:15 -0500 Subject: [PATCH 0239/2950] fixed crash on termination --- libi2pd_client/I2CP.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index a14588a8..c09b7f4d 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -814,8 +814,11 @@ namespace client { m_IsRunning = false; m_Acceptor.cancel (); - for (auto& it: m_Sessions) - it.second->Stop (); + { + auto sessions = m_Sessions; + for (auto& it: sessions) + it.second->Stop (); + } m_Sessions.clear (); m_Service.stop (); if (m_Thread) From 64da62dbe69be040215babad89fc481f0e429c00 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Mar 2020 18:46:40 -0500 Subject: [PATCH 0240/2950] alsways store latest symmkey --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 33 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 4 +-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index d2d07343..a066dc17 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -39,25 +39,28 @@ namespace garlic return m_KeyData.GetTag (); } - const uint8_t * RatchetTagSet::GetSymmKey (int index) + void RatchetTagSet::GetSymmKey (int index, uint8_t * key) { - // TODO: store intermediate keys - if (m_NextSymmKeyIndex > 0 && index == m_NextSymmKeyIndex) + if (m_NextSymmKeyIndex > 0 && index >= m_NextSymmKeyIndex) { - i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); - m_NextSymmKeyIndex++; + auto num = index + 1 - m_NextSymmKeyIndex; + for (int i = 0; i < num; i++) + i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); + m_NextSymmKeyIndex += num; + memcpy (key, m_CurrentSymmKeyCK + 32, 32); } else - CalculateSymmKeyCK (index); - return m_CurrentSymmKeyCK + 32; + CalculateSymmKeyCK (index, key); } - void RatchetTagSet::CalculateSymmKeyCK (int index) + void RatchetTagSet::CalculateSymmKeyCK (int index, uint8_t * key) { - i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) + // TODO: store intermediate keys + uint8_t currentSymmKeyCK[64]; + i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", currentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) for (int i = 0; i < index; i++) - i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_n = HKDF(symmKey_chainKey_(n-1), SYMMKEY_CONSTANT, "SymmetricRatchet", 64) - m_NextSymmKeyIndex = index + 1; + i2p::crypto::HKDF (currentSymmKeyCK, nullptr, 0, "SymmetricRatchet", currentSymmKeyCK); // keydata_n = HKDF(symmKey_chainKey_(n-1), SYMMKEY_CONSTANT, "SymmetricRatchet", 64) + memcpy (key, currentSymmKeyCK + 32, 32); } ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner): @@ -373,7 +376,9 @@ namespace garlic memcpy (out, &tag, 8); // ad = The session tag, 8 bytes // ciphertext = ENCRYPT(k, n, payload, ad) - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, m_SendTagset.GetSymmKey (index), nonce, out + 8, outLen - 8, true)) // encrypt + uint8_t key[32]; + m_SendTagset.GetSymmKey (index, key); + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, out, 8, key, nonce, out + 8, outLen - 8, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; @@ -387,7 +392,9 @@ namespace garlic CreateNonce (index, nonce); // tag's index len -= 8; // tag std::vector payload (len - 16); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, m_ReceiveTagset.GetSymmKey (index), nonce, payload.data (), len - 16, false)) // decrypt + uint8_t key[32]; + m_ReceiveTagset.GetSymmKey (index, key); + if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, key, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index e5836cd4..f23c569c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -22,11 +22,11 @@ namespace garlic void NextSessionTagRatchet (); uint64_t GetNextSessionTag (); int GetNextIndex () const { return m_NextIndex; }; - const uint8_t * GetSymmKey (int index); + void GetSymmKey (int index, uint8_t * key); private: - void CalculateSymmKeyCK (int index); + void CalculateSymmKeyCK (int index, uint8_t * key); private: From 4adc741de319ee2afc6f51f180fff33db63869b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 8 Mar 2020 18:13:41 -0400 Subject: [PATCH 0241/2950] send DeliveryStatusMsg for LeaseSet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 53 ++++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + libi2pd/Garlic.cpp | 60 ++++++++++++++--------- libi2pd/Garlic.h | 11 +++-- 4 files changed, 96 insertions(+), 29 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a066dc17..5f2eb5c8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -6,6 +6,8 @@ #include "Tag.h" #include "I2PEndian.h" #include "Timestamp.h" +#include "Tunnel.h" +#include "TunnelPool.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -460,12 +462,22 @@ namespace garlic std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg) { + uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); size_t payloadLen = 7; // datatime if (msg && m_Destination) payloadLen += msg->GetPayloadLength () + 13 + 32; - auto leaseSet = CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()); - if (leaseSet) + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()) : nullptr; + std::shared_ptr deliveryStatus; + if (leaseSet) + { payloadLen += leaseSet->GetPayloadLength () + 13; + deliveryStatus = CreateEncryptedDeliveryStatusMsg (leaseSet->GetMsgID ()); + payloadLen += deliveryStatus->GetPayloadLength () + 49; + if (GetLeaseSetUpdateMsgID ()) GetOwner ()->RemoveDeliveryStatusSession (GetLeaseSetUpdateMsgID ()); // remove previous + SetLeaseSetUpdateStatus (eLeaseSetSubmitted); + SetLeaseSetUpdateMsgID (leaseSet->GetMsgID ()); + SetLeaseSetSubmissionTime (ts); + } uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -475,10 +487,13 @@ namespace garlic // DateTime v[offset] = eECIESx25519BlkDateTime; offset++; htobe16buf (v.data () + offset, 4); offset += 2; - htobe32buf (v.data () + offset, i2p::util::GetSecondsSinceEpoch ()); offset += 4; + htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds // LeaseSet if (leaseSet) offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); + // DeliveryStatus + if (deliveryStatus) + offset += CreateDeliveryStatusClove (deliveryStatus, v.data () + offset, payloadLen - offset); // msg if (msg && m_Destination) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); @@ -513,6 +528,38 @@ namespace garlic return cloveSize + 3; } + size_t ECIESX25519AEADRatchetSession::CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len) + { + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 37 /* delivery instruction */; + if ((int)len < cloveSize + 3) return 0; + buf[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (buf + 1, cloveSize); // size + buf += 3; + if (GetOwner ()) + { + auto inboundTunnel = GetOwner ()->GetTunnelPool ()->GetNextInboundTunnel (); + if (inboundTunnel) + { + // delivery instructions + *buf = eGarlicDeliveryTypeTunnel << 5; buf++; // delivery instructions flag tunnel + // hash and tunnelID sequence is reversed for Garlic + memcpy (buf, inboundTunnel->GetNextIdentHash (), 32); buf += 32;// To Hash + htobe32buf (buf, inboundTunnel->GetNextTunnelID ()); buf += 4;// tunnelID + } + else + { + LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus"); + return 0; + } + htobe32buf (buf + 1, msg->GetMsgID ()); // msgID + htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds + memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); + } + else + return 0; + return cloveSize + 3; + } + void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (int numTags) { for (int i = 0; i < numTags; i++) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index f23c569c..4d273c13 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -107,6 +107,7 @@ namespace garlic std::vector CreatePayload (std::shared_ptr msg); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + size_t CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len); void GenerateMoreReceiveTags (int numTags); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 45c97172..dd63572c 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -58,6 +58,34 @@ namespace garlic m_SharedRoutingPath = path; } + bool GarlicRoutingSession::MessageConfirmed (uint32_t msgID) + { + if (msgID == GetLeaseSetUpdateMsgID ()) + { + SetLeaseSetUpdateStatus (eLeaseSetUpToDate); + SetLeaseSetUpdateMsgID (0); + LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); + return true; + } + return false; + } + + std::shared_ptr GarlicRoutingSession::CreateEncryptedDeliveryStatusMsg (uint32_t msgID) + { + auto msg = CreateDeliveryStatusMsg (msgID); + if (GetOwner ()) + { + //encrypt + uint8_t key[32], tag[32]; + RAND_bytes (key, 32); // random session key + RAND_bytes (tag, 32); // random session tag + GetOwner ()->SubmitSessionKey (key, tag); + ElGamalAESSession garlic (key, tag); + msg = garlic.WrapSingleMessage (msg); + } + return msg; + } + ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, int numTags, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet), @@ -289,19 +317,12 @@ namespace garlic htobe32buf (buf + size, inboundTunnel->GetNextTunnelID ()); // tunnelID size += 4; // create msg - auto msg = CreateDeliveryStatusMsg (msgID); - if (GetOwner ()) - { - //encrypt - uint8_t key[32], tag[32]; - RAND_bytes (key, 32); // random session key - RAND_bytes (tag, 32); // random session tag - GetOwner ()->SubmitSessionKey (key, tag); - ElGamalAESSession garlic (key, tag); - msg = garlic.WrapSingleMessage (msg); - } - memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); - size += msg->GetLength (); + auto msg = CreateEncryptedDeliveryStatusMsg (msgID); + if (msg) + { + memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); + size += msg->GetLength (); + } // fill clove uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 8000; // 8 sec uint32_t cloveID; @@ -334,17 +355,12 @@ namespace garlic return tags; } - void ElGamalAESSession::MessageConfirmed (uint32_t msgID) + bool ElGamalAESSession::MessageConfirmed (uint32_t msgID) { TagsConfirmed (msgID); - if (msgID == GetLeaseSetUpdateMsgID ()) - { - SetLeaseSetUpdateStatus (eLeaseSetUpToDate); - SetLeaseSetUpdateMsgID (0); - LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); - } - else + if (!GarlicRoutingSession::MessageConfirmed (msgID)) CleanupExpiredTags (); + return true; } void ElGamalAESSession::TagsConfirmed (uint32_t msgID) @@ -775,7 +791,7 @@ namespace garlic void GarlicDestination::HandleDeliveryStatusMessage (uint32_t msgID) { - ElGamalAESSessionPtr session; + GarlicRoutingSessionPtr session; { std::unique_lock l(m_DeliveryStatusSessionsMutex); auto it = m_DeliveryStatusSessions.find (msgID); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 9c256b48..be0ac117 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -104,7 +104,8 @@ namespace garlic virtual ~GarlicRoutingSession (); virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession - + virtual bool MessageConfirmed (uint32_t msgID); + void SetLeaseSetUpdated () { if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated; @@ -118,7 +119,7 @@ namespace garlic GarlicDestination * GetOwner () const { return m_Owner; } void SetOwner (GarlicDestination * owner) { m_Owner = owner; } - + protected: LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } @@ -127,6 +128,8 @@ namespace garlic void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } + std::shared_ptr CreateEncryptedDeliveryStatusMsg (uint32_t msgID); + private: GarlicDestination * m_Owner; @@ -165,7 +168,7 @@ namespace garlic std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - void MessageConfirmed (uint32_t msgID); + bool MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left bool CleanupUnconfirmedTags (); // returns true if something has been deleted @@ -267,7 +270,7 @@ namespace garlic std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; - std::unordered_map m_DeliveryStatusSessions; // msgID -> session + std::unordered_map m_DeliveryStatusSessions; // msgID -> session public: From 3c534798643d9b0e7f7a529b24beacd679732281 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 8 Mar 2020 20:58:59 -0400 Subject: [PATCH 0242/2950] update LeaseSet for ECIESX25519AEADRatchet sessions --- libi2pd/Garlic.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index dd63572c..9ac5540f 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -810,8 +810,12 @@ namespace garlic void GarlicDestination::SetLeaseSetUpdated () { - std::unique_lock l(m_SessionsMutex); - for (auto& it: m_Sessions) + { + std::unique_lock l(m_SessionsMutex); + for (auto& it: m_Sessions) + it.second->SetLeaseSetUpdated (); + } + for (auto& it: m_ECIESx25519Sessions) it.second->SetLeaseSetUpdated (); } From ee73ee365f5d02a4fc29832745f70a381b085aa1 Mon Sep 17 00:00:00 2001 From: user Date: Tue, 10 Mar 2020 21:49:04 +0800 Subject: [PATCH 0243/2950] some work on qt --- .gitignore | 4 + qt/i2pd_qt/DelayedSaveManager.cpp | 3 + qt/i2pd_qt/DelayedSaveManager.h | 24 +++++ qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 140 ++++++++++++++++++++++++++ qt/i2pd_qt/DelayedSaveManagerImpl.h | 82 +++++++++++++++ qt/i2pd_qt/Saver.cpp | 6 ++ qt/i2pd_qt/Saver.h | 22 ++++ qt/i2pd_qt/SaverImpl.cpp | 79 +++++++++++++++ qt/i2pd_qt/SaverImpl.h | 33 ++++++ qt/i2pd_qt/TunnelPane.cpp | 2 +- qt/i2pd_qt/i2pd_qt.pro | 14 ++- qt/i2pd_qt/mainwindow.cpp | 103 ++++++++----------- qt/i2pd_qt/mainwindow.h | 29 ++++-- 13 files changed, 466 insertions(+), 75 deletions(-) create mode 100644 qt/i2pd_qt/DelayedSaveManager.cpp create mode 100644 qt/i2pd_qt/DelayedSaveManager.h create mode 100644 qt/i2pd_qt/DelayedSaveManagerImpl.cpp create mode 100644 qt/i2pd_qt/DelayedSaveManagerImpl.h create mode 100644 qt/i2pd_qt/Saver.cpp create mode 100644 qt/i2pd_qt/Saver.h create mode 100644 qt/i2pd_qt/SaverImpl.cpp create mode 100644 qt/i2pd_qt/SaverImpl.h diff --git a/.gitignore b/.gitignore index c2db70e0..68aea504 100644 --- a/.gitignore +++ b/.gitignore @@ -264,3 +264,7 @@ qt/i2pd_qt/*.ui_* #unknown android stuff android/libs/ + +#various logs +*LOGS/ + diff --git a/qt/i2pd_qt/DelayedSaveManager.cpp b/qt/i2pd_qt/DelayedSaveManager.cpp new file mode 100644 index 00000000..8e17d111 --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManager.cpp @@ -0,0 +1,3 @@ +#include "DelayedSaveManager.h" + +DelayedSaveManager::DelayedSaveManager(){} diff --git a/qt/i2pd_qt/DelayedSaveManager.h b/qt/i2pd_qt/DelayedSaveManager.h new file mode 100644 index 00000000..9a9a997b --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManager.h @@ -0,0 +1,24 @@ +#ifndef DELAYEDSAVEMANAGER_H +#define DELAYEDSAVEMANAGER_H + +#include "Saver.h" + +class DelayedSaveManager +{ +public: + DelayedSaveManager(); + + virtual void setSaver(Saver* saver)=0; + + typedef unsigned int DATA_SERIAL_TYPE; + + virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool needsTunnelFocus, std::string tunnelNameToFocus)=0; + + //returns false iff save failed + virtual bool appExiting()=0; + + virtual bool needsFocusOnTunnel()=0; + virtual std::string getTunnelNameToFocus()=0; +}; + +#endif // DELAYEDSAVEMANAGER_H diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp new file mode 100644 index 00000000..5588d7e9 --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp @@ -0,0 +1,140 @@ +#include "DelayedSaveManagerImpl.h" + +DelayedSaveManagerImpl::DelayedSaveManagerImpl() : + saver(nullptr), + lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL), + lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP), + exiting(false), + thread(new DelayedSaveThread(this)) +{ +} + +void DelayedSaveManagerImpl::setSaver(Saver* saver) { + this->saver = saver; +} + +void DelayedSaveManagerImpl::start() { + thread->start(); +} + +bool DelayedSaveManagerImpl::isSaverValid() { + return saver != nullptr; +} + +void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus) { + if(lastDataSerialSeen==dataSerial)return; + this->focusOnTunnel = focusOnTunnel; + this->tunnelNameToFocus = tunnelNameToFocus; + lastDataSerialSeen=dataSerial; + assert(isSaverValid()); + TIMESTAMP_TYPE now = getTime(); + TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS; + if(now < wakeTime) { + //defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS + thread->deferSaveUntil(wakeTime); + return; + } + lastSaveStartedTimestamp = now; + thread->startSavingNow(); +} + +bool DelayedSaveManagerImpl::appExiting() { + exiting=true; + thread->wakeThreadAndJoinThread(); + assert(isSaverValid()); + saver->save(false, ""); + return true; +} + +DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_): + delayedSaveManagerImpl(delayedSaveManagerImpl_), + mutex(new QMutex()), + waitCondition(new QWaitCondition()), + saveNow(false), + defer(false) +{ + mutex->lock(); +} + +DelayedSaveThread::~DelayedSaveThread(){ + mutex->unlock(); + delete mutex; + delete waitCondition; +} + +void DelayedSaveThread::run() { + forever { + if(delayedSaveManagerImpl->isExiting())return; + waitCondition->wait(mutex, WAIT_TIME_MILLIS); + if(delayedSaveManagerImpl->isExiting())return; + Saver* saver = delayedSaveManagerImpl->getSaver(); + assert(saver!=nullptr); + if(saveNow) { + saveNow = false; + const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel(); + const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); + saver->save(focusOnTunnel, tunnelNameToFocus); + continue; + } + if(defer) { + defer=false; +#define max(a,b) (((a)>(b))?(a):(b)) + forever { + TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime(); + TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0); + if(millisToWait>0) { + waitCondition->wait(mutex, millisToWait); + if(delayedSaveManagerImpl->isExiting())return; + continue; + } + const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel(); + const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); + saver->save(focusOnTunnel, tunnelNameToFocus); + break; //break inner loop + } + } + } +} + +void DelayedSaveThread::wakeThreadAndJoinThread() { + waitCondition->wakeAll(); + quit(); + wait();//join //"similar to the POSIX pthread_join()" +} + +DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() { + return QDateTime::currentMSecsSinceEpoch(); +} + +void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) { + wakeTime = wakeTime_; + defer = true; + waitCondition->wakeAll(); +} + +void DelayedSaveThread::startSavingNow() { + //mutex->lock(); + saveNow=true; + waitCondition->wakeAll(); + //mutex->unlock(); +} + +DelayedSaveManagerImpl::~DelayedSaveManagerImpl() { + thread->wakeThreadAndJoinThread(); + delete thread; +} + +bool DelayedSaveManagerImpl::isExiting() { + return exiting; +} +Saver* DelayedSaveManagerImpl::getSaver() { + return saver; +} + +bool DelayedSaveManagerImpl::needsFocusOnTunnel() { + return focusOnTunnel; +} + +std::string DelayedSaveManagerImpl::getTunnelNameToFocus() { + return tunnelNameToFocus; +} diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.h b/qt/i2pd_qt/DelayedSaveManagerImpl.h new file mode 100644 index 00000000..0d8c7592 --- /dev/null +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.h @@ -0,0 +1,82 @@ +#ifndef DELAYEDSAVEMANAGERIMPL_H +#define DELAYEDSAVEMANAGERIMPL_H + +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "DelayedSaveManager.h" +#include "Saver.h" + +class DelayedSaveManagerImpl; + +class DelayedSaveThread : public QThread +{ + Q_OBJECT + +public: + static constexpr unsigned long WAIT_TIME_MILLIS = 1000L; + + typedef qint64 TIMESTAMP_TYPE; + static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0; + + DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl); + virtual ~DelayedSaveThread(); + + void run() override; + + void deferSaveUntil(TIMESTAMP_TYPE wakeTime); + void startSavingNow(); + + void wakeThreadAndJoinThread(); + +private: + DelayedSaveManagerImpl* delayedSaveManagerImpl; + QMutex* mutex; + QWaitCondition* waitCondition; + volatile bool saveNow; + volatile bool defer; + volatile TIMESTAMP_TYPE wakeTime; +}; + +class DelayedSaveManagerImpl : public DelayedSaveManager +{ +public: + DelayedSaveManagerImpl(); + virtual ~DelayedSaveManagerImpl(); + virtual void setSaver(Saver* saver); + virtual void start(); + virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus); + virtual bool appExiting(); + + typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE; + + static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0; + bool isExiting(); + Saver* getSaver(); + static TIMESTAMP_TYPE getTime(); + + bool needsFocusOnTunnel(); + std::string getTunnelNameToFocus(); + +private: + Saver* saver; + bool isSaverValid(); + + volatile DATA_SERIAL_TYPE lastDataSerialSeen; + + static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP; + TIMESTAMP_TYPE lastSaveStartedTimestamp; + + volatile bool exiting; + DelayedSaveThread* thread; + void wakeThreadAndJoinThread(); + + volatile bool focusOnTunnel; + std::string tunnelNameToFocus; +}; + +#endif // DELAYEDSAVEMANAGERIMPL_H diff --git a/qt/i2pd_qt/Saver.cpp b/qt/i2pd_qt/Saver.cpp new file mode 100644 index 00000000..4841acb0 --- /dev/null +++ b/qt/i2pd_qt/Saver.cpp @@ -0,0 +1,6 @@ +#include "Saver.h" + +Saver::Saver() +{ + +} diff --git a/qt/i2pd_qt/Saver.h b/qt/i2pd_qt/Saver.h new file mode 100644 index 00000000..cefe0220 --- /dev/null +++ b/qt/i2pd_qt/Saver.h @@ -0,0 +1,22 @@ +#ifndef SAVER_H +#define SAVER_H + +#include +#include +#include + +class Saver : public QObject +{ + Q_OBJECT + +public: + Saver(); + //false iff failures + virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus)=0; + +signals: + void reloadTunnelsConfigAndUISignal(const QString); + +}; + +#endif // SAVER_H diff --git a/qt/i2pd_qt/SaverImpl.cpp b/qt/i2pd_qt/SaverImpl.cpp new file mode 100644 index 00000000..f35ef5b7 --- /dev/null +++ b/qt/i2pd_qt/SaverImpl.cpp @@ -0,0 +1,79 @@ +#include "SaverImpl.h" + +#include +#include +#include + +#include "QList" +#include "QString" + +#include "mainwindow.h" + +SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList * configItems_, std::map* tunnelConfigs_) : + configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_) +{} + +SaverImpl::~SaverImpl() {} + +bool SaverImpl::save(const bool focusOnTunnel, const std::string& tunnelNameToFocus) { + //save main config + { + std::stringstream out; + for(QList::iterator it = configItems->begin(); it!= configItems->end(); ++it) { + MainWindowItem* item = *it; + item->saveToStringStream(out); + } + + using namespace std; + + + QString backup=confpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(confpath.toStdString());//TODO handle errors + outfile << out.str().c_str(); + outfile.close(); + } + + //save tunnels config + { + std::stringstream out; + + for (std::map::iterator it=tunnelConfigs->begin(); it!=tunnelConfigs->end(); ++it) { + //const std::string& name = it->first; + TunnelConfig* tunconf = it->second; + tunconf->saveHeaderToStringStream(out); + tunconf->saveToStringStream(out); + tunconf->saveI2CPParametersToStringStream(out); + } + + using namespace std; + + QString backup=tunconfpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(tunconfpath.toStdString());//TODO handle errors + outfile << out.str().c_str(); + outfile.close(); + } + + //reload saved configs +#if 0 + i2p::client::context.ReloadConfig(); +#endif + + if(focusOnTunnel) emit reloadTunnelsConfigAndUISignal(QString::fromStdString(tunnelNameToFocus)); + + return true; +} + +void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; } + +void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; } + +/*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) { + this->focusOnTunnel=focusOnTunnel; + this->tunnelNameToFocus=tunnelNameToFocus; +}*/ diff --git a/qt/i2pd_qt/SaverImpl.h b/qt/i2pd_qt/SaverImpl.h new file mode 100644 index 00000000..c44877a2 --- /dev/null +++ b/qt/i2pd_qt/SaverImpl.h @@ -0,0 +1,33 @@ +#ifndef SAVERIMPL_H +#define SAVERIMPL_H + +#include +#include + +#include +#include "QList" + +#include "mainwindow.h" +#include "TunnelConfig.h" +#include "Saver.h" + +class MainWindowItem; +class TunnelConfig; + +class SaverImpl : public Saver +{ +public: + SaverImpl(MainWindow *mainWindowPtr_, QList * configItems_, std::map* tunnelConfigs_); + virtual ~SaverImpl(); + virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus); + void setConfPath(QString& confpath_); + void setTunnelsConfPath(QString& tunconfpath_); +private: + QList * configItems; + std::map* tunnelConfigs; + QString confpath; + QString tunconfpath; + MainWindow* mainWindowPtr; +}; + +#endif // SAVERIMPL_H diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index fb840276..3813eafc 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -64,7 +64,7 @@ void TunnelPane::setupTunnelPane( //type { - const QString& type = tunnelConfig->getType(); + //const QString& type = tunnelConfig->getType(); QHBoxLayout * horizontalLayout_ = new QHBoxLayout(); horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_")); typeLabel = new QLabel(gridLayoutWidget_2); diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 15565c5c..0cb73a2f 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -62,6 +62,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/TunnelGateway.cpp \ ../../libi2pd/TunnelPool.cpp \ ../../libi2pd/util.cpp \ + ../../libi2pd/Elligator.cpp \ ../../libi2pd_client/AddressBook.cpp \ ../../libi2pd_client/BOB.cpp \ ../../libi2pd_client/ClientContext.cpp \ @@ -89,7 +90,11 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ pagewithbackbutton.cpp \ widgetlock.cpp \ widgetlockregistry.cpp \ - logviewermanager.cpp + logviewermanager.cpp \ + DelayedSaveManager.cpp \ + Saver.cpp \ + DelayedSaveManagerImpl.cpp \ + SaverImpl.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/api.h \ @@ -147,6 +152,7 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/TunnelPool.h \ ../../libi2pd/util.h \ ../../libi2pd/version.h \ + ../../libi2pd/Elligator.h \ ../../libi2pd_client/AddressBook.h \ ../../libi2pd_client/BOB.h \ ../../libi2pd_client/ClientContext.h \ @@ -175,7 +181,11 @@ HEADERS += DaemonQT.h mainwindow.h \ widgetlock.h \ widgetlockregistry.h \ i2pd.rc \ - logviewermanager.h + logviewermanager.h \ + DelayedSaveManager.h \ + Saver.h \ + DelayedSaveManagerImpl.h \ + SaverImpl.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index e4c9f2a7..3b1890c4 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,11 +1,8 @@ -#include -#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" #include "ui_routercommandswidget.h" #include "ui_generalsettingswidget.h" -#include #include #include #include @@ -29,17 +26,22 @@ #include "logviewermanager.h" +#include "DelayedSaveManagerImpl.h" +#include "SaverImpl.h" + std::string programOptionsWriterCurrentSection; MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *parent) : QMainWindow(parent) ,logStream(logStream_) -#ifndef ANDROID - ,quitting(false) -#endif + ,delayedSaveManagerPtr(new DelayedSaveManagerImpl()) + ,dataSerial(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL) ,wasSelectingAtStatusMainPage(false) ,showHiddenInfoStatusMainPage(false) ,logViewerManagerPtr(nullptr) +#ifndef ANDROID + ,quitting(false) +#endif ,ui(new Ui::MainWindow) ,statusButtonsUI(new Ui::StatusButtonsForm) ,routerCommandsUI(new Ui::routerCommandsWidget) @@ -51,9 +53,14 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ,datadir() ,confpath() ,tunconfpath() + ,tunnelConfigs() ,tunnelsPageUpdateListener(this) + ,saverPtr(new SaverImpl(this, &configItems, &tunnelConfigs)) { + assert(delayedSaveManagerPtr!=nullptr); + assert(saverPtr!=nullptr); + ui->setupUi(this); statusButtonsUI->setupUi(ui->statusButtonsPane); routerCommandsUI->setupUi(routerCommandsParent); @@ -75,7 +82,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ui->stackedWidget->setCurrentIndex(0); ui->settingsScrollArea->resize(uiSettings->settingsContentsGridLayout->sizeHint().width()+10,380); - QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); + //QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); int w = 683; int h = 3060; ui->settingsContents->setFixedSize(w, h); @@ -270,7 +277,13 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren widgetlocks.add(new widgetlock(uiSettings->comboBox_httpPorxySignatureType,uiSettings->httpProxySignTypeComboEditPushButton)); widgetlocks.add(new widgetlock(uiSettings->comboBox_socksProxySignatureType,uiSettings->socksProxySignTypeComboEditPushButton)); - loadAllConfigs(); + loadAllConfigs(saverPtr); + + QObject::connect(saverPtr, SIGNAL(reloadTunnelsConfigAndUISignal(const QString)), + this, SLOT(reloadTunnelsConfigAndUI_QString(const QString))); + + delayedSaveManagerPtr->setSaver(saverPtr); + delayedSaveManagerPtr->start(); QObject::connect(uiSettings->logDestinationComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(logDestinationComboBoxValueChanged(const QString &))); @@ -292,7 +305,6 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren QObject::connect(uiSettings->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(reloadTunnelsConfigAndUI())); - QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased())); QObject::connect(ui->addClientTunnelPushButton, SIGNAL(released()), this, SLOT(addClientTunnelPushButtonReleased())); @@ -307,7 +319,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren logViewerManagerPtr=new LogViewerManager(logStream_,ui->logViewerTextEdit,this); assert(logViewerManagerPtr!=nullptr); - onLoggingOptionsChange(); + //onLoggingOptionsChange(); //QMetaObject::connectSlotsByName(this); } @@ -500,6 +512,8 @@ void MainWindow::handleQuitButton() { quitting=true; #endif close(); + delayedSaveManagerPtr->appExiting(); + qDebug("Performing quit"); QApplication::instance()->quit(); } @@ -526,6 +540,7 @@ void MainWindow::handleGracefulQuitTimerEvent() { quitting=true; #endif close(); + delayedSaveManagerPtr->appExiting(); qDebug("Performing quit"); QApplication::instance()->quit(); } @@ -534,6 +549,8 @@ MainWindow::~MainWindow() { qDebug("Destroying main window"); delete statusPageUpdateTimer; + delete delayedSaveManagerPtr; + delete saverPtr; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->deleteLater(); @@ -594,7 +611,7 @@ NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) { return retValue; } -void MainWindow::loadAllConfigs(){ +void MainWindow::loadAllConfigs(SaverImpl* saverPtr){ //BORROWED FROM ??? //TODO move this code into single location std::string config; i2p::config::GetOption("conf", config); @@ -635,6 +652,9 @@ void MainWindow::loadAllConfigs(){ this->datadir = datadir.c_str(); this->tunconfpath = tunConf.c_str(); + saverPtr->setConfPath(this->confpath); + saverPtr->setTunnelsConfPath(this->tunconfpath); + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->loadFromConfigOption(); @@ -642,10 +662,10 @@ void MainWindow::loadAllConfigs(){ ReadTunnelsConfig(); - onLoggingOptionsChange(); + //onLoggingOptionsChange(); } /** returns false iff not valid items present and save was aborted */ -bool MainWindow::saveAllConfigs(){ +bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); programOptionsWriterCurrentSection=""; /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); @@ -653,7 +673,6 @@ bool MainWindow::saveAllConfigs(){ daemonOption->optionValue=boost::any(false); serviceOption->optionValue=boost::any(false); - std::stringstream out; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; if(!item->isValid()){ @@ -661,27 +680,8 @@ bool MainWindow::saveAllConfigs(){ return false; } } - - for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { - MainWindowItem* item = *it; - item->saveToStringStream(out); - } - - using namespace std; - - - QString backup=confpath+"~"; - if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors - if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors - ofstream outfile; - outfile.open(confpath.toStdString());//TODO handle errors - outfile << out.str().c_str(); - outfile.close(); - - SaveTunnelsConfig(); - - onLoggingOptionsChange(); - + delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus); + //onLoggingOptionsChange(); return true; } @@ -711,7 +711,7 @@ void MainWindow::updated() { adjustSizesAccordingToWrongLabel(); applyTunnelsUiToConfigs(); - saveAllConfigs(); + saveAllConfigs(false); } void MainWindowItem::installListeners(MainWindow *mainWindow) {} @@ -784,6 +784,10 @@ bool MainWindow::applyTunnelsUiToConfigs() { return true; } +void MainWindow::reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus) { + reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString()); +} + void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { deleteTunnelForms(); for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { @@ -795,31 +799,6 @@ void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { appendTunnelForms(tunnelNameToFocus); } -void MainWindow::SaveTunnelsConfig() { - std::stringstream out; - - for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { - const std::string& name = it->first; - TunnelConfig* tunconf = it->second; - tunconf->saveHeaderToStringStream(out); - tunconf->saveToStringStream(out); - tunconf->saveI2CPParametersToStringStream(out); - } - - using namespace std; - - QString backup=tunconfpath+"~"; - if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors - if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors - ofstream outfile; - outfile.open(tunconfpath.toStdString());//TODO handle errors - outfile << out.str().c_str(); - outfile.close(); - - i2p::client::context.ReloadConfig(); - -} - void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) { if(oldName!=tunConf->getName()) { //name has changed @@ -827,7 +806,7 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; } - mainWindow->saveAllConfigs(); + mainWindow->saveAllConfigs(true, tunConf->getName()); } void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 048f44af..bfbc527f 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -62,6 +62,12 @@ #include "widgetlockregistry.h" #include "widgetlock.h" +#include "DelayedSaveManager.h" +#include "DelayedSaveManagerImpl.h" +#include "SaverImpl.h" + +class SaverImpl; + class LogViewerManager; template @@ -373,10 +379,14 @@ using namespace i2p::qt; class Controller; +class DelayedSaveManagerImpl; + class MainWindow : public QMainWindow { Q_OBJECT private: std::shared_ptr logStream; + DelayedSaveManagerImpl* delayedSaveManagerPtr; + DelayedSaveManager::DATA_SERIAL_TYPE dataSerial; public: explicit MainWindow(std::shared_ptr logStream_, QWidget *parent=nullptr); ~MainWindow(); @@ -502,16 +512,16 @@ protected: void initStringBox(ConfigOption option, QLineEdit* lineEdit); NonGUIOptionItem* initNonGUIOption(ConfigOption option); - void loadAllConfigs(); + void loadAllConfigs(SaverImpl* saverPtr); public slots: /** returns false iff not valid items present and save was aborted */ - bool saveAllConfigs(); - void SaveTunnelsConfig(); + bool saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus=""); void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus); //focus none void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); } + void reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus); void addServerTunnelPushButtonReleased(); void addClientTunnelPushButtonReleased(); @@ -578,8 +588,7 @@ private: tunnelConfigs.erase(it); delete tc; } - saveAllConfigs(); - reloadTunnelsConfigAndUI(""); + saveAllConfigs(false); } std::string GenerateNewTunnelName() { @@ -614,8 +623,7 @@ private: destinationPort, sigType); - saveAllConfigs(); - reloadTunnelsConfigAndUI(name); + saveAllConfigs(true, name); } void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () @@ -651,8 +659,7 @@ private: isUniqueLocal); - saveAllConfigs(); - reloadTunnelsConfigAndUI(name); + saveAllConfigs(true, name); } void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels () @@ -793,7 +800,9 @@ private: TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener; - void onLoggingOptionsChange() {} + //void onLoggingOptionsChange() {} + + SaverImpl* saverPtr; }; #endif // MAINWINDOW_H From 0e38e43315836d1797caba87e82d5fc0340bf090 Mon Sep 17 00:00:00 2001 From: user Date: Tue, 10 Mar 2020 23:22:49 +0800 Subject: [PATCH 0244/2950] some qt work. fixed on slow computers; now faster as delayed save is implemented --- .gitignore | 4 ++- daemon/HTTPServer.h | 2 +- qt/i2pd_qt/DelayedSaveManager.h | 2 +- qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 6 ++--- qt/i2pd_qt/DelayedSaveManagerImpl.h | 8 +++--- qt/i2pd_qt/TunnelConfig.h | 7 +++++- qt/i2pd_qt/TunnelPane.cpp | 5 ++++ qt/i2pd_qt/TunnelPane.h | 2 ++ qt/i2pd_qt/mainwindow.cpp | 36 ++++++++++++++++++++++++++- qt/i2pd_qt/mainwindow.h | 3 +++ 10 files changed, 63 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 68aea504..3319fa10 100644 --- a/.gitignore +++ b/.gitignore @@ -258,7 +258,7 @@ build/Makefile # qt -qt/i2pd_qt/*.ui.autosave +qt/i2pd_qt/*.autosave qt/i2pd_qt/*.ui.bk* qt/i2pd_qt/*.ui_* @@ -268,3 +268,5 @@ android/libs/ #various logs *LOGS/ +qt/build-*.sh* + diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index f5ac95fc..abc4fea5 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -89,7 +89,7 @@ namespace http void ShowTransports (std::stringstream& s); void ShowSAMSessions (std::stringstream& s); void ShowI2PTunnels (std::stringstream& s); - void ShowLocalDestination (std::stringstream& s, const std::string& b32); + void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); } // http } // i2p diff --git a/qt/i2pd_qt/DelayedSaveManager.h b/qt/i2pd_qt/DelayedSaveManager.h index 9a9a997b..b09aa28f 100644 --- a/qt/i2pd_qt/DelayedSaveManager.h +++ b/qt/i2pd_qt/DelayedSaveManager.h @@ -18,7 +18,7 @@ public: virtual bool appExiting()=0; virtual bool needsFocusOnTunnel()=0; - virtual std::string getTunnelNameToFocus()=0; + virtual std::string& getTunnelNameToFocus()=0; }; #endif // DELAYEDSAVEMANAGER_H diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp index 5588d7e9..f6704c17 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp @@ -21,10 +21,10 @@ bool DelayedSaveManagerImpl::isSaverValid() { return saver != nullptr; } -void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus) { +void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus_) { if(lastDataSerialSeen==dataSerial)return; this->focusOnTunnel = focusOnTunnel; - this->tunnelNameToFocus = tunnelNameToFocus; + tunnelNameToFocus = tunnelNameToFocus_; lastDataSerialSeen=dataSerial; assert(isSaverValid()); TIMESTAMP_TYPE now = getTime(); @@ -135,6 +135,6 @@ bool DelayedSaveManagerImpl::needsFocusOnTunnel() { return focusOnTunnel; } -std::string DelayedSaveManagerImpl::getTunnelNameToFocus() { +std::string& DelayedSaveManagerImpl::getTunnelNameToFocus() { return tunnelNameToFocus; } diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.h b/qt/i2pd_qt/DelayedSaveManagerImpl.h index 0d8c7592..cb1f7568 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.h +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.h @@ -60,22 +60,22 @@ public: static TIMESTAMP_TYPE getTime(); bool needsFocusOnTunnel(); - std::string getTunnelNameToFocus(); + std::string& getTunnelNameToFocus(); private: Saver* saver; bool isSaverValid(); - volatile DATA_SERIAL_TYPE lastDataSerialSeen; + DATA_SERIAL_TYPE lastDataSerialSeen; static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP; TIMESTAMP_TYPE lastSaveStartedTimestamp; - volatile bool exiting; + bool exiting; DelayedSaveThread* thread; void wakeThreadAndJoinThread(); - volatile bool focusOnTunnel; + bool focusOnTunnel; std::string tunnelNameToFocus; }; diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 58a1fa0b..059d48b5 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -40,6 +40,9 @@ public: class ClientTunnelConfig; class ServerTunnelConfig; + +class TunnelPane; + class TunnelConfig { /* const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; @@ -54,6 +57,7 @@ class TunnelConfig { */ QString type; std::string name; + TunnelPane* tunnelPane; public: TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): type(type_), name(name_), i2cpParameters(i2cpParameters_) {} @@ -68,7 +72,8 @@ public: virtual void saveToStringStream(std::stringstream& out)=0; virtual ClientTunnelConfig* asClientTunnelConfig()=0; virtual ServerTunnelConfig* asServerTunnelConfig()=0; - + void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;} + TunnelPane* getTunnelPane() {return tunnelPane;} private: I2CPParameters i2cpParameters; }; diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 3813eafc..c64b37ab 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -83,6 +83,11 @@ void TunnelPane::setupTunnelPane( retranslateTunnelForm(*this); } +void TunnelPane::deleteWidget() { + //gridLayoutWidget_2->deleteLater(); + tunnelGroupBox->deleteLater(); +} + void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) { { //number of hops of an inbound tunnel diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index a7012810..71331b4e 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -41,6 +41,8 @@ public: virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; + void deleteWidget(); + protected: MainWindow* mainWindow; QWidget * wrongInputPane; diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 3b1890c4..97a4ee69 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -664,6 +664,36 @@ void MainWindow::loadAllConfigs(SaverImpl* saverPtr){ //onLoggingOptionsChange(); } + +void MainWindow::layoutTunnels() { + + int height=0; + ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0); + for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { + const std::string& name=it->first; + TunnelConfig* tunconf = it->second; + TunnelPane * tunnelPane=tunconf->getTunnelPane(); + if(!tunnelPane)continue; + int h=tunnelPane->height(); + height+=h; + //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); + //int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); + } + //qDebug() << "tun.setting height:" << height; + ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); + /*QList childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren(); + foreach(QWidget* widget, childWidgets) + widget->show();*/ +} + +void MainWindow::deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf) { + TunnelPane* tp = cnf->getTunnelPane(); + if(!tp)return; + tunnelPanes.remove(tp); + tp->deleteWidget(); + layoutTunnels(); +} + /** returns false iff not valid items present and save was aborted */ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); @@ -681,6 +711,7 @@ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocu } } delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus); + //onLoggingOptionsChange(); return true; } @@ -725,6 +756,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel, this); + tunconf->setTunnelPane(tunnelPane); int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); @@ -738,6 +770,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel, this); + tunconf->setTunnelPane(tunnelPane); int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); @@ -854,7 +887,8 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { pageWithBackButton->show(); textBrowser->hide(); std::stringstream s; - i2p::http::ShowLocalDestination(s,str.toStdString()); + std::string strstd = str.toStdString(); + i2p::http::ShowLocalDestination(s,strstd,0); childTextBrowser->setHtml(QString::fromStdString(s.str())); } } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index bfbc527f..91c99122 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -513,6 +513,7 @@ protected: NonGUIOptionItem* initNonGUIOption(ConfigOption option); void loadAllConfigs(SaverImpl* saverPtr); + void layoutTunnels(); public slots: /** returns false iff not valid items present and save was aborted */ @@ -540,6 +541,7 @@ private: void appendTunnelForms(std::string tunnelNameToFocus); void deleteTunnelForms(); + void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf); template std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const @@ -585,6 +587,7 @@ private: std::map::const_iterator it=tunnelConfigs.find(name); if(it!=tunnelConfigs.end()){ TunnelConfig* tc=it->second; + deleteTunnelFromUI(name, tc); tunnelConfigs.erase(it); delete tc; } From dd8200e8b0a9f2f7bf56a95db2ccacace81eb572 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 12 Mar 2020 03:50:21 +0300 Subject: [PATCH 0245/2950] cleanup websocks Signed-off-by: R4SAS --- build/CMakeLists.txt | 1 - filelist.mk | 2 +- libi2pd_client/ClientContext.cpp | 7 +--- libi2pd_client/WebSocks.cpp | 72 -------------------------------- libi2pd_client/WebSocks.h | 34 --------------- qt/i2pd_qt/i2pd_qt.pro | 2 - 6 files changed, 3 insertions(+), 115 deletions(-) delete mode 100644 libi2pd_client/WebSocks.cpp delete mode 100644 libi2pd_client/WebSocks.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 8b3553d2..2bdfb396 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -117,7 +117,6 @@ set (CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/SOCKS.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/HTTPProxy.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/I2CP.cpp" - "${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp" ) add_library(libi2pdclient ${CLIENT_SRC}) diff --git a/filelist.mk b/filelist.mk index 72773975..7d13fb2f 100644 --- a/filelist.mk +++ b/filelist.mk @@ -11,7 +11,7 @@ LIB_SRC = $(wildcard $(LIB_SRC_DIR)/*.cpp) #LIB_CLIENT_SRC = \ # AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp MatchedDestination.cpp \ -# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp WebSocks.cpp +# SAM.cpp SOCKS.cpp HTTPProxy.cpp I2CP.cpp LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index d72f40a8..722fb242 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -9,7 +9,6 @@ #include "util.h" #include "ClientContext.h" #include "SOCKS.h" -#include "WebSocks.h" #include "MatchedDestination.h" namespace i2p @@ -598,10 +597,8 @@ namespace client } else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) { - // websocks proxy - auto tun = std::make_shared(address, port, localDestination); - clientTunnel = tun; - clientEndpoint = tun->GetLocalEndpoint(); + LogPrint(eLogError, "Clients: I2P Client tunnel websocks is deprecated"); + continue; } else { diff --git a/libi2pd_client/WebSocks.cpp b/libi2pd_client/WebSocks.cpp deleted file mode 100644 index a3e8c1bf..00000000 --- a/libi2pd_client/WebSocks.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "WebSocks.h" -#include "Log.h" -#include - -namespace i2p -{ -namespace client -{ - class WebSocksImpl - { - public: - WebSocksImpl(const std::string & addr, int port) : m_Addr(addr), m_Port(port) - { - } - - ~WebSocksImpl() - { - } - - void Start() - { - LogPrint(eLogInfo, "[Tunnels] starting websocks tunnel at %s:%d is rejected: WebSockets is deprecated", m_Addr, m_Port); - } - - void Stop() - { - } - - void InitializeDestination(WebSocks * parent) - { - } - - boost::asio::ip::tcp::endpoint GetLocalEndpoint() - { - return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(m_Addr), m_Port); - } - - std::string m_Addr; - int m_Port; - - }; -} -} - -namespace i2p -{ -namespace client -{ - WebSocks::WebSocks(const std::string & addr, int port, std::shared_ptr localDestination) : m_Impl(new WebSocksImpl(addr, port)) - { - m_Impl->InitializeDestination(this); - } - WebSocks::~WebSocks() { delete m_Impl; } - - void WebSocks::Start() - { - m_Impl->Start(); - GetLocalDestination()->Start(); - } - - boost::asio::ip::tcp::endpoint WebSocks::GetLocalEndpoint() const - { - return m_Impl->GetLocalEndpoint(); - } - - void WebSocks::Stop() - { - m_Impl->Stop(); - GetLocalDestination()->Stop(); - } -} -} diff --git a/libi2pd_client/WebSocks.h b/libi2pd_client/WebSocks.h deleted file mode 100644 index 2314659f..00000000 --- a/libi2pd_client/WebSocks.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef WEBSOCKS_H_ -#define WEBSOCKS_H_ -#include -#include -#include "I2PService.h" -#include "Destination.h" - -namespace i2p -{ -namespace client -{ - - class WebSocksImpl; - - /** @brief websocket socks proxy server */ - class WebSocks : public i2p::client::I2PService - { - public: - WebSocks(const std::string & addr, int port, std::shared_ptr localDestination); - ~WebSocks(); - - void Start(); - void Stop(); - - boost::asio::ip::tcp::endpoint GetLocalEndpoint() const; - - const char * GetName() { return "WebSOCKS Proxy"; } - - private: - WebSocksImpl * m_Impl; - }; -} -} -#endif diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index aa87a765..6eec3a16 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -73,7 +73,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd_client/MatchedDestination.cpp \ ../../libi2pd_client/SAM.cpp \ ../../libi2pd_client/SOCKS.cpp \ - ../../libi2pd_client/WebSocks.cpp \ ../../daemon/Daemon.cpp \ ../../daemon/HTTPServer.cpp \ ../../daemon/I2PControl.cpp \ @@ -162,7 +161,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd_client/MatchedDestination.h \ ../../libi2pd_client/SAM.h \ ../../libi2pd_client/SOCKS.h \ - ../../libi2pd_client/WebSocks.h \ ../../daemon/Daemon.h \ ../../daemon/HTTPServer.h \ ../../daemon/I2PControl.h \ From 45145fa50af40a5270223930cd92d33df452db82 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 14 Mar 2020 09:33:48 -0400 Subject: [PATCH 0246/2950] add ECIESX25519AEADRatchet session to delivery status --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 1 + libi2pd/Garlic.cpp | 2 +- libi2pd/Garlic.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5f2eb5c8..4705c708 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -477,6 +477,7 @@ namespace garlic SetLeaseSetUpdateStatus (eLeaseSetSubmitted); SetLeaseSetUpdateMsgID (leaseSet->GetMsgID ()); SetLeaseSetSubmissionTime (ts); + GetOwner ()->DeliveryStatusSent (shared_from_this (), leaseSet->GetMsgID ()); } uint8_t paddingSize; RAND_bytes (&paddingSize, 1); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 9ac5540f..99b737b1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -783,7 +783,7 @@ namespace garlic m_DeliveryStatusSessions.erase (msgID); } - void GarlicDestination::DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID) + void GarlicDestination::DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID) { std::unique_lock l(m_DeliveryStatusSessionsMutex); m_DeliveryStatusSessions[msgID] = session; diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index be0ac117..396a38fe 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -226,7 +226,7 @@ namespace garlic void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread - void DeliveryStatusSent (ElGamalAESSessionPtr session, uint32_t msgID); + void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); void AddECIESx25519SessionTag (int index, uint64_t tag, ECIESX25519AEADRatchetSessionPtr session); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); From b5bc05ac2b2ed9375d689207190af89b5344c37d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 14 Mar 2020 16:35:34 -0400 Subject: [PATCH 0247/2950] delete unconfirmed LeaseSet and DeliveryStatus --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 6 ++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 19 ++++++++++++------- libi2pd/Garlic.h | 3 ++- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4705c708..8c293f15 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -571,6 +571,12 @@ namespace garlic } m_NumReceiveTags += numTags; } + + bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) + { + CleanupUnconfirmedLeaseSet (ts); + return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; + } } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 4d273c13..db9807a5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -85,7 +85,7 @@ namespace garlic if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } - bool IsExpired (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } + bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 99b737b1..97f80b41 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -70,6 +70,16 @@ namespace garlic return false; } + void GarlicRoutingSession::CleanupUnconfirmedLeaseSet (uint64_t ts) + { + if (m_LeaseSetUpdateMsgID && ts*1000LL > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT) + { + if (GetOwner ()) + GetOwner ()->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); + m_LeaseSetUpdateMsgID = 0; + } + } + std::shared_ptr GarlicRoutingSession::CreateEncryptedDeliveryStatusMsg (uint32_t msgID) { auto msg = CreateDeliveryStatusMsg (msgID); @@ -390,12 +400,7 @@ namespace garlic ++it; } CleanupUnconfirmedTags (); - if (GetLeaseSetUpdateMsgID () && ts*1000LL > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT) - { - if (GetOwner ()) - GetOwner ()->RemoveDeliveryStatusSession (GetLeaseSetUpdateMsgID ()); - SetLeaseSetUpdateMsgID (0); - } + CleanupUnconfirmedLeaseSet (ts); return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); } @@ -767,7 +772,7 @@ namespace garlic for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) { - if (it->second->IsExpired (ts)) + if (it->second->CheckExpired (ts)) { it->second->SetOwner (nullptr); it = m_ECIESx25519Sessions.erase (it); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 396a38fe..06da679d 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -113,7 +113,8 @@ namespace garlic bool IsLeaseSetNonConfirmed () const { return m_LeaseSetUpdateStatus == eLeaseSetSubmitted; }; bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; }; uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; } - + void CleanupUnconfirmedLeaseSet (uint64_t ts); + std::shared_ptr GetSharedRoutingPath (); void SetSharedRoutingPath (std::shared_ptr path); From 5da92437a136cf5938062c5ec4ceaf28832c5aff Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 16 Mar 2020 16:41:07 -0400 Subject: [PATCH 0248/2950] set msg type for deliverystatus --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8c293f15..8d300a16 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -552,6 +552,7 @@ namespace garlic LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus"); return 0; } + *buf = msg->GetTypeID (); // I2NP msg type htobe32buf (buf + 1, msg->GetMsgID ()); // msgID htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); From f3b0e57a5440586c3f7de2ed97b5b742f52c995c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Mar 2020 18:03:03 -0400 Subject: [PATCH 0249/2950] publish multiple encryption keys --- libi2pd/Destination.cpp | 5 +++-- libi2pd/LeaseSet.cpp | 18 ++++++++++++------ libi2pd/LeaseSet.h | 9 ++++++++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d4620ed9..60f5062c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1149,10 +1149,11 @@ namespace client else { // standard LS2 (type 3) first - auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; + uint16_t keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, - m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels, IsPublic (), isPublishedEncrypted); + m_Keys, i2p::data::LocalLeaseSet2::KeySections { {m_EncryptionKeyType, keyLen, m_EncryptionPublicKey} }, + tunnels, IsPublic (), isPublishedEncrypted); if (isPublishedEncrypted) // encrypt if type 5 ls2 = std::make_shared (ls2, m_Keys, GetAuthType (), m_AuthKeys); leaseSet = ls2; diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 8d1b9524..e2da1d21 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -748,7 +748,7 @@ namespace data } LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, + const KeySections& encryptionKeys, std::vector > tunnels, bool isPublic, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) @@ -757,8 +757,11 @@ namespace data // assume standard LS2 int num = tunnels.size (); if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES; + size_t keySectionsLen = 0; + for (const auto& it: encryptionKeys) + keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; m_BufferLen = identity->GetFullLen () + 4/*published*/ + 2/*expires*/ + 2/*flag*/ + 2/*properties len*/ + - 1/*num keys*/ + 2/*key type*/ + 2/*key len*/ + keyLen/*key*/ + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); + 1/*num keys*/ + keySectionsLen + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); uint16_t flags = 0; if (keys.IsOfflineSignature ()) { @@ -789,10 +792,13 @@ namespace data } htobe16buf (m_Buffer + offset, 0); offset += 2; // properties len // keys - m_Buffer[offset] = 1; offset++; // 1 key - htobe16buf (m_Buffer + offset, keyType); offset += 2; // key type - htobe16buf (m_Buffer + offset, keyLen); offset += 2; // key len - memcpy (m_Buffer + offset, encryptionPublicKey, keyLen); offset += keyLen; // key + m_Buffer[offset] = encryptionKeys.size (); offset++; // 1 key + for (const auto& it: encryptionKeys) + { + htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type + htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len + memcpy (m_Buffer + offset, it.encryptionPublicKey, it.keyLen); offset += it.keyLen; // key + } // leases uint32_t expirationTime = 0; // in seconds m_Buffer[offset] = num; offset++; // num leases diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index a51570f7..791d77e3 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -231,8 +231,15 @@ namespace data { public: + struct KeySection + { + uint16_t keyType, keyLen; + const uint8_t * encryptionPublicKey; + }; + typedef std::vector KeySections; + LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - uint16_t keyType, uint16_t keyLen, const uint8_t * encryptionPublicKey, + const KeySections& encryptionKeys, 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 From 2fcaa7d260fa9b657e9e1e24f00a03f964c7febf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Mar 2020 02:26:55 +0300 Subject: [PATCH 0250/2950] [webconsole] rework spoilers; print tags, leases, router info in table Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 240 ++++++++++++++++++++++++------------------ 1 file changed, 137 insertions(+), 103 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 36e26785..a7bd693f 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -54,7 +54,7 @@ namespace http { " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " 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; color: initial;}\r\n" + " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial; width: 1.5em;}\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" " .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n" " .left { float: left; position: absolute; }\r\n" @@ -64,12 +64,13 @@ namespace http { " .tunnel.failed { color: #D33F3F; }\r\n" " .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" - " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" - " .slide p, .slide [type='checkbox'] { display: none; }\r\n" - " .slide [type='checkbox']:checked ~ p { display: block; margin-top: 0; padding: 0; }\r\n" + " table { display: table; border-collapse: collapse; text-align: center; }\r\n" + " table.extaddr { text-align: left; }\r\n table.services { width: 100%; }" + " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" + " .slide div.content, .slide [type='checkbox'] { display: none; }\r\n" + " .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" - " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -181,8 +182,10 @@ namespace http { "

\r\n" " Main page
\r\n
\r\n" " Router commands
\r\n" - " Local destinations
\r\n" - " LeaseSets
\r\n" + " Local destinations
\r\n"; + if (i2p::context.IsFloodfill ()) + s << " LeaseSets
\r\n"; + s << " Tunnels
\r\n" " Transit tunnels
\r\n" " Transports
\r\n" @@ -234,11 +237,8 @@ namespace http { } s << "
\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) - if (auto remains = Daemon.gracefulShutdownInterval) { - s << "Stopping in: "; - s << remains << " seconds"; - s << "
\r\n"; - } + if (auto remains = Daemon.gracefulShutdownInterval) + s << "Stopping in: " << remains << " seconds
\r\n"; #endif auto family = i2p::context.GetFamily (); if (family.length () > 0) @@ -256,45 +256,50 @@ namespace http { s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
"; if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n

\r\n"; + s << "\r\n\r\n

\r\n"; } if(includeHiddenContent) { s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; - s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\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 << "Our external address:" << "
\r\n" ; + s << "Our external address:" << "
\r\n\r\n"; for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) { + s << "\r\n"; if (address->IsNTCP2 () && !address->IsPublishedNTCP2 ()) { - s << "NTCP2"; + s << "\r\n\r\n"; continue; } switch (address->transportStyle) { case i2p::data::RouterInfo::eTransportNTCP: { - s << "NTCP"; + s << "\r\n"; break; } case i2p::data::RouterInfo::eTransportSSU: + { + s << "\r\n"; + break; + } default: - s << "Unknown  "; + s << "\r\n"; } - s << address->host.to_string() << ":" << address->port << "
\r\n"; + s << "\r\n\r\n"; } + s << "
NTCP2"; if (address->host.is_v6 ()) s << "v6"; - s << "   supported
\r\n"; + s << "
supported
NTCP"; if (address->IsPublishedNTCP2 ()) s << "2"; if (address->host.is_v6 ()) s << "v6"; - s << "  "; + s << "SSU"; if (address->host.is_v6 ()) - s << "SSUv6     "; - else - s << "SSU     "; - break; + s << "v6"; + s << "Unknown" << address->host.to_string() << ":" << address->port << "
\r\n"; } - s << "

\r\n
\r\n"; + s << "\r\n
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forQtUi) { s << "
"; } @@ -310,15 +315,15 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n
\r\n"; if(outputFormat==OutputFormatEnum::forWebConsole) { - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; - s << "\r\n"; bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); - s << "\r\n"; - s << "
Services
ServiceState
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "\r\n"; + s << "
Services
" << "HTTP Proxy" << "
" << "SOCKS Proxy" << "
" << "BOB" << "
" << "SAM" << "
" << "I2CP" << "
" << "I2PControl" << "
\r\n"; } } @@ -358,19 +363,20 @@ 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"; + s << "
\r\n
\r\n"; } if(dest->GetNumRemoteLeaseSets()) { - s << "
\r\n\r\n

\r\n"; + s << "

\r\n\r\n
\r\n"; for(auto& it: dest->GetLeaseSets ()) - s << it.first.ToBase32 () << " " << (int)it.second->GetStoreType () << "
\r\n"; - s << "

\r\n\r\n"; + s << "\r\n"; + s << "
AddressTypeEncType
" << 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"; + s << "LeaseSets: 0
\r\n
\r\n"; auto pool = dest->GetTunnelPool (); if (pool) { @@ -395,10 +401,11 @@ namespace http { 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"; + tmp_s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "" << it.second->GetNumOutgoingTags () << "\r\n"; out_tags = out_tags + it.second->GetNumOutgoingTags (); } - s << "
\r\n\r\n

\r\n" << tmp_s.str () << "

\r\n
\r\n"; + s << "
\r\n\r\n" + << "
\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -473,46 +480,57 @@ namespace http { void ShowLeasesSets(std::stringstream& s) { - s << "LeaseSets:
\r\n
\r\n"; - int counter = 1; - // for each lease set - i2p::data::netdb.VisitLeaseSets( - [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) - { - // create copy of lease set so we extract leases - auto storeType = leaseSet->GetStoreType (); - std::unique_ptr ls; - if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) - ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); - else - ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); - if (!ls) return; - s << "
\r\n"; - if (!ls->IsValid()) - s << "
!! 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"; - 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"; - for ( auto & l : leases ) + if (i2p::data::netdb.GetNumLeaseSets ()) + { + s << "LeaseSets:
\r\n
\r\n"; + int counter = 1; + // for each lease set + i2p::data::netdb.VisitLeaseSets( + [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) + { + // create copy of lease set so we extract leases + auto storeType = leaseSet->GetStoreType (); + std::unique_ptr ls; + if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET) + ls.reset (new i2p::data::LeaseSet (leaseSet->GetBuffer(), leaseSet->GetBufferLen())); + else + ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); + if (!ls) return; + s << "

\r\n"; + if (!ls->IsValid()) + s << "
!! 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"; + if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) { - s << "Gateway: " << l->tunnelGateway.ToBase64() << "
\r\n"; - s << "TunnelID: " << l->tunnelID << "
\r\n"; - s << "EndDate: " << ConvertTime(l->endDate) << "
\r\n"; + // leases information is available + auto leases = ls->GetNonExpiredLeases(); + s << "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 << "

\r\n
\r\n
\r\n"; - } - ); - // end for each lease set + s << "
\r\n
\r\n
\r\n"; + } + ); + // end for each lease set + } + else if (!i2p::context.IsFloodfill ()) + { + s << "LeaseSets: not floodfill.
\r\n"; + } + else + { + s << "LeaseSets: 0
\r\n"; + } } void ShowTunnels (std::stringstream& s) @@ -574,16 +592,23 @@ namespace http { void ShowTransitTunnels (std::stringstream& s) { - s << "Transit tunnels:
\r\n
\r\n"; - for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) + if(i2p::tunnel::tunnels.CountTransitTunnels()) { - if (std::dynamic_pointer_cast(it)) - s << it->GetTunnelID () << " ⇒ "; - else if (std::dynamic_pointer_cast(it)) - s << " ⇒ " << it->GetTunnelID (); - else - s << " ⇒ " << it->GetTunnelID () << " ⇒ "; - s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + s << "Transit tunnels:
\r\n
\r\n"; + for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) + { + if (std::dynamic_pointer_cast(it)) + s << it->GetTunnelID () << " ⇒ "; + else if (std::dynamic_pointer_cast(it)) + s << " ⇒ " << it->GetTunnelID (); + else + s << " ⇒ " << it->GetTunnelID () << " ⇒ "; + s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + } + } + else + { + s << "Transit tunnels: no transit tunnels currently built.
\r\n"; } } @@ -617,13 +642,15 @@ namespace http { } if (!tmp_s.str ().empty ()) { - s << "
\r\n\r\n

"; - s << tmp_s.str () << "

\r\n
\r\n"; + s << "
\r\n\r\n
" + << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { - s << "
\r\n\r\n

"; - s << tmp_s6.str () << "

\r\n
\r\n"; + s << "
\r\n\r\n
" + << tmp_s6.str () << "
\r\n
\r\n"; } } @@ -650,7 +677,7 @@ namespace http { auto sessions = ssuServer->GetSessions (); if (!sessions.empty ()) { - s << "
\r\n\r\n

"; + s << "

\r\n\r\n
"; for (const auto& it: sessions) { auto endpoint = it.second->GetRemoteEndpoint (); @@ -662,12 +689,12 @@ namespace http { s << " [itag:" << it.second->GetRelayTag () << "]"; s << "
\r\n" << std::endl; } - s << "

\r\n
\r\n"; + s << "
\r\n
\r\n"; } auto sessions6 = ssuServer->GetSessionsV6 (); if (!sessions6.empty ()) { - s << "
\r\n\r\n

"; + s << "

\r\n\r\n
"; for (const auto& it: sessions6) { auto endpoint = it.second->GetRemoteEndpoint (); @@ -679,7 +706,7 @@ namespace http { s << " [itag:" << it.second->GetRelayTag () << "]"; s << "
\r\n" << std::endl; } - s << "

\r\n
\r\n"; + s << "
\r\n
\r\n"; } } } @@ -688,17 +715,24 @@ namespace http { { std::string webroot; i2p::config::GetOption("http.webroot", webroot); auto sam = i2p::client::context.GetSAMBridge (); - if (!sam) { + if (!sam) + { ShowError(s, "SAM disabled"); return; } - s << "SAM Sessions:
\r\n
\r\n"; - for (auto& it: sam->GetSessions ()) + + if(sam->GetSessions ().size ()) { - auto& name = it.second->localDestination->GetNickname (); - s << ""; - s << name << " (" << it.first << ")
\r\n" << std::endl; + s << "SAM Sessions:
\r\n
\r\n"; + for (auto& it: sam->GetSessions ()) + { + auto& name = it.second->localDestination->GetNickname (); + s << ""; + s << name << " (" << it.first << ")
\r\n" << std::endl; + } } + else + s << "SAM Sessions: no sessions currently running.
\r\n"; } static void ShowSAMSession (std::stringstream& s, const std::string& id) From 22497080973e25e8b9b5fd93b86af44f795a18e3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 19 Mar 2020 02:34:45 +0300 Subject: [PATCH 0251/2950] [webconsole] remove excess tag 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 a7bd693f..5eac08a9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -299,7 +299,7 @@ namespace http { } s << "\r\n"; } - s << "\r\n
\r\n
\r\n"; + s << "
\r\n\r\n"; if(outputFormat==OutputFormatEnum::forQtUi) { s << "
"; } From 3ca17fdc039f46996038d5bb501539a728e06f8a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Mar 2020 18:33:42 -0400 Subject: [PATCH 0252/2950] support multiple encryption keys --- libi2pd/Destination.cpp | 11 +++++++++-- libi2pd/Destination.h | 9 +++++---- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 ++-- libi2pd/Garlic.cpp | 4 ++-- libi2pd/Identity.h | 4 ++-- libi2pd_client/I2CP.h | 3 ++- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 60f5062c..46d3fc57 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -388,7 +388,7 @@ namespace client if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET) leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else - leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetEncryptionType ()); // LeaseSet2 + leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET], buf + offset, len - offset, true, GetPreferredCryptoType () ); // LeaseSet2 if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) { if (leaseSet->GetIdentHash () != GetIdentHash ()) @@ -412,7 +412,7 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetEncryptionType ()); + auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetPreferredCryptoType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key @@ -822,6 +822,13 @@ namespace client } } + i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const + { + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET; + return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; + } + ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (service, isPublic, params), diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 23ed5188..f26200a0 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -161,6 +161,7 @@ namespace client void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); + i2p::data::CryptoKeyType GetPreferredCryptoType () const; private: @@ -232,14 +233,14 @@ namespace client int GetStreamingAckDelay () const { return m_StreamingAckDelay; } // datagram - i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; - i2p::datagram::DatagramDestination * CreateDatagramDestination (); + i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; + i2p::datagram::DatagramDestination * CreateDatagramDestination (); // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - i2p::data::CryptoKeyType GetEncryptionType () const { return m_EncryptionKeyType; }; - const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; }; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; + const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { return m_EncryptionPublicKey; }; protected: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8d300a16..2cea2172 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -126,7 +126,7 @@ namespace garlic if (!GetOwner ()) return false; // we are Bob // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (), 32); // h = SHA256(h || bpk) + MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32); // h = SHA256(h || bpk) if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { @@ -235,7 +235,7 @@ namespace garlic // encrypt static key section uint8_t nonce[12]; CreateNonce (0, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); return false; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 97f80b41..629e0d76 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -488,7 +488,7 @@ namespace garlic else { // tag not found. Handle depending on encryption type - if (GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) { HandleECIESx25519 (buf, length); return; @@ -680,7 +680,7 @@ namespace garlic std::shared_ptr destination, bool attachLeaseSet) { if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET && - GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET) + SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET)) { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index f217f3c5..9c78f552 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -228,8 +228,8 @@ namespace data virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; - virtual CryptoKeyType GetEncryptionType () const { return GetIdentity ()->GetCryptoKeyType (); }; // override for LeaseSet - virtual const uint8_t * GetEncryptionPublicKey () const { return GetIdentity ()->GetEncryptionPublicKey (); }; // override for LeaseSet + virtual bool SupportsEncryptionType (CryptoKeyType keyType) const { return GetIdentity ()->GetCryptoKeyType () == keyType; }; // override for LeaseSet + virtual const uint8_t * GetEncryptionPublicKey (CryptoKeyType keyType) const { return GetIdentity ()->GetEncryptionPublicKey (); }; // override for LeaseSet }; } } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 68b4415a..848378e0 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -80,7 +80,8 @@ namespace client // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; - i2p::data::CryptoKeyType GetEncryptionType () const { return m_EncryptionKeyType; }; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; + // TODO: implement GetEncryptionPublicKey std::shared_ptr GetIdentity () const { return m_Identity; }; protected: From b6b25dc9f3c6d57c11f8fd8c2980e64133f4a682 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 20 Mar 2020 17:44:53 +0300 Subject: [PATCH 0253/2950] update log messages Signed-off-by: R4SAS --- libi2pd/Garlic.cpp | 2 +- libi2pd/LeaseSet.cpp | 2 +- libi2pd/SSUData.cpp | 6 +++--- libi2pd/Transports.cpp | 13 +++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 629e0d76..02d1cd83 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -890,7 +890,7 @@ namespace garlic m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption)); } if (!m_Tags.empty ()) - LogPrint (eLogInfo, m_Tags.size (), " loaded for ", ident); + LogPrint (eLogInfo, "Garlic: " m_Tags.size (), " tags loaded for ", ident); } } i2p::fs::Remove (path); diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index e2da1d21..bcfede33 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -159,7 +159,7 @@ namespace data } } else - LogPrint (eLogWarning, "LeaseSet: Lease is expired already "); + LogPrint (eLogWarning, "LeaseSet: Lease is expired already"); } uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index add58739..866da277 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -442,7 +442,7 @@ namespace transport } catch (boost::system::system_error& ec) { - LogPrint (eLogWarning, "SSU: Can't resend data fragment ", ec.what ()); + LogPrint (eLogWarning, "SSU: Can't resend message ", it->first, " data fragment: ", ec.what ()); } } @@ -452,7 +452,7 @@ namespace transport } else { - LogPrint (eLogInfo, "SSU: message has not been ACKed after ", MAX_NUM_RESENDS, " attempts, deleted"); + LogPrint (eLogInfo, "SSU: message ", it->first, " has not been ACKed after ", MAX_NUM_RESENDS, " attempts, deleted"); it = m_SentMessages.erase (it); } } @@ -488,7 +488,7 @@ namespace transport { 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"); + LogPrint (eLogWarning, "SSU: message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds, deleted"); it = m_IncompleteMessages.erase (it); } else diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 97c29c70..804f26cb 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -271,11 +271,11 @@ namespace transport m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); - if (m_IsNAT) - { - m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); - m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); - } + if (m_IsNAT) + { + m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); + m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); + } } void Transports::Stop () @@ -589,6 +589,7 @@ namespace transport if (RoutesRestricted() || !i2p::context.SupportsV4 ()) return; if (m_SSUServer) { + LogPrint (eLogInfo, "Transports: Started peer test"); bool statusChanged = false; for (int i = 0; i < 5; i++) { @@ -604,7 +605,7 @@ namespace transport } } if (!statusChanged) - LogPrint (eLogWarning, "Can't find routers for peer test"); + LogPrint (eLogWarning, "Transports: Can't find routers for peer test"); } } From 168da33d8bc5689ee0ecb01e4c05ca785e3662ba Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 20 Mar 2020 18:43:54 +0300 Subject: [PATCH 0254/2950] add comma Signed-off-by: R4SAS --- libi2pd/Garlic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 02d1cd83..ae6599fc 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -890,7 +890,7 @@ namespace garlic m_Tags.insert (std::make_pair (SessionTag (tag, ts), decryption)); } if (!m_Tags.empty ()) - LogPrint (eLogInfo, "Garlic: " m_Tags.size (), " tags loaded for ", ident); + LogPrint (eLogInfo, "Garlic: ", m_Tags.size (), " tags loaded for ", ident); } } i2p::fs::Remove (path); From 962c2160c77cce4460950fb6a231725235daf89d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 20 Mar 2020 17:43:37 -0400 Subject: [PATCH 0255/2950] set actual LeaseSet2 buffer size --- libi2pd/LeaseSet.cpp | 15 +++++++++++++++ libi2pd/LeaseSet.h | 1 + 2 files changed, 16 insertions(+) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index bcfede33..b411ca0e 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -251,6 +251,13 @@ namespace data memcpy (m_Buffer, buf, len); } + void LeaseSet::SetBufferLen (size_t len) + { + if (len <= m_BufferLen) m_BufferLen = len; + else + LogPrint (eLogError, "LeaseSet2: actual buffer size ", len , " exceeds full buffer size ", m_BufferLen); + } + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto): LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto) { @@ -331,6 +338,8 @@ namespace data VerifySignature (identity, buf, len, offset); SetIsValid (verified); } + offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : identity->GetSignatureLen (); + SetBufferLen (offset); } template @@ -537,6 +546,12 @@ namespace data else LogPrint (eLogError, "LeaseSet2: unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet"); } + else + { + // we set actual length of encrypted buffer + offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : blindedVerifier->GetSignatureLen (); + SetBufferLen (offset); + } } // helper for ExtractClientAuthData diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 791d77e3..0d255644 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -97,6 +97,7 @@ namespace data // called from LeaseSet2 LeaseSet (bool storeLeases); void SetBuffer (const uint8_t * buf, size_t len); + void SetBufferLen (size_t len); void SetIdentity (std::shared_ptr identity) { m_Identity = identity; }; void SetExpirationTime (uint64_t t) { m_ExpirationTime = t; }; void SetIsValid (bool isValid) { m_IsValid = isValid; }; From ff19bab80087947c7f364d60edfd8af63478b9c7 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 21 Mar 2020 16:21:51 -0400 Subject: [PATCH 0256/2950] set only key correctly --- libi2pd_client/I2CP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index c09b7f4d..ccd94e46 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -572,7 +572,7 @@ namespace client uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length if (offset + keyLen > len) return; - if (keyType > currentKeyType) + if (!currentKey || keyType > currentKeyType) { currentKeyType = keyType; currentKey = buf + offset; From 6fb80f226acd76c50e4f615111a8ba01e279c4d5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Mar 2020 08:14:20 -0400 Subject: [PATCH 0257/2950] reopen socked and restart receiver on exception --- libi2pd/SSU.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index daf7e1e9..4eb958de 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -160,6 +160,13 @@ namespace transport catch (std::exception& ex) { LogPrint (eLogError, "SSU: receivers runtime exception: ", ex.what ()); + if (m_IsRunning) + { + // restart socket + m_Socket.close (); + OpenSocket (); + Receive (); + } } } } @@ -175,6 +182,12 @@ namespace transport catch (std::exception& ex) { LogPrint (eLogError, "SSU: v6 receivers runtime exception: ", ex.what ()); + if (m_IsRunning) + { + m_SocketV6.close (); + OpenSocketV6 (); + ReceiveV6 (); + } } } } From fe9ac10f02da049c7966c0ecb2cd84c8e94698c8 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Mar 2020 21:21:12 -0400 Subject: [PATCH 0258/2950] generate new tags based on last received index --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 +--- libi2pd/ECIESX25519AEADRatchetSession.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2cea2172..5dd78747 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -402,8 +402,7 @@ namespace garlic return false; } HandlePayload (payload.data (), len - 16); - if (m_NumReceiveTags > 0)m_NumReceiveTags--; - if (m_NumReceiveTags <= GetOwner ()->GetNumTags ()*2/3) + if (m_ReceiveTagset.GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); return true; } @@ -570,7 +569,6 @@ namespace garlic uint64_t tag = m_ReceiveTagset.GetNextSessionTag (); GetOwner ()->AddECIESx25519SessionTag (index, tag, shared_from_this ()); } - m_NumReceiveTags += numTags; } bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index db9807a5..95875013 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -119,7 +119,6 @@ namespace garlic SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; - int m_NumReceiveTags = 0; std::unique_ptr m_Destination;// TODO: might not need it }; } From 744e893dcef13db3d47aea1d877cf97032fa0c03 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Mar 2020 18:09:57 -0400 Subject: [PATCH 0259/2950] check message length --- libi2pd_client/I2CP.cpp | 12 ++++++++++-- libi2pd_client/I2CP.h | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index ccd94e46..eec21f06 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -246,8 +246,16 @@ namespace client m_PayloadLen = bufbe32toh (m_Header + I2CP_HEADER_LENGTH_OFFSET); if (m_PayloadLen > 0) { - m_Payload = new uint8_t[m_PayloadLen]; - ReceivePayload (); + if (m_PayloadLen <= I2CP_MAX_MESSAGE_LENGTH) + { + m_Payload = new uint8_t[m_PayloadLen]; + ReceivePayload (); + } + else + { + LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); + Terminate (); + } } else // no following payload { diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 848378e0..f675318f 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -24,7 +24,8 @@ namespace client { const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; - + const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; + const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1; From 869d0156ce38de301e32c5a35a698059c4a0d5d9 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Mar 2020 19:03:38 -0400 Subject: [PATCH 0260/2950] handle Ack request --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 25 +++++++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 6 +++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 5dd78747..c57553d4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -38,6 +38,7 @@ namespace garlic { i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; + if (m_NextIndex >= 65535) m_NextIndex = 0; // TODO: dirty hack, should create new tagset return m_KeyData.GetTag (); } @@ -178,7 +179,7 @@ namespace garlic return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, int index) { size_t offset = 0; while (offset < len) @@ -207,6 +208,12 @@ namespace garlic case eECIESx25519BlkPadding: LogPrint (eLogDebug, "Garlic: padding"); break; + case eECIESx25519BlkAckRequest: + { + LogPrint (eLogDebug, "Garlic: ack request"); + m_AckRequests.push_back ( {bufbe16toh (buf + offset), index}); + break; + } default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } @@ -401,7 +408,7 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - HandlePayload (payload.data (), len - 16); + HandlePayload (payload.data (), len - 16, index); if (m_ReceiveTagset.GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); return true; @@ -478,6 +485,8 @@ namespace garlic SetLeaseSetSubmissionTime (ts); GetOwner ()->DeliveryStatusSent (shared_from_this (), leaseSet->GetMsgID ()); } + if (m_AckRequests.size () > 0) + payloadLen += m_AckRequests.size ()*4 + 3; uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -497,6 +506,18 @@ namespace garlic // msg if (msg && m_Destination) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + // ack + if (m_AckRequests.size () > 0) + { + v[offset] = eECIESx25519BlkAck; offset++; + htobe16buf (v.data () + 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; + } + m_AckRequests.clear (); + } // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 95875013..56fb48cf 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "Identity.h" #include "Crypto.h" #include "Garlic.h" @@ -51,6 +52,8 @@ namespace garlic eECIESx25519BlkTermination = 4, eECIESx25519BlkOptions = 5, eECIESx25519BlkNextSessionKey = 7, + eECIESx25519BlkAck = 8, + eECIESx25519BlkAckRequest = 9, eECIESx25519BlkGalicClove = 11, eECIESx25519BlkPadding = 254 }; @@ -99,7 +102,7 @@ namespace garlic bool HandleNewIncomingSession (const uint8_t * buf, size_t len); bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len); bool HandleExistingSessionMessage (const uint8_t * buf, size_t len, int index); - void HandlePayload (const uint8_t * buf, size_t len); + void HandlePayload (const uint8_t * buf, size_t len, int index = 0); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); @@ -120,6 +123,7 @@ namespace garlic uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; std::unique_ptr m_Destination;// TODO: might not need it + std::list > m_AckRequests; // (key_id, indeX) }; } } From f4ca6bbb52d8d2029662be8e72305fb21c29acba Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Mar 2020 19:27:10 -0400 Subject: [PATCH 0261/2950] fixed race with identity verifier --- libi2pd/Identity.cpp | 49 ++++++++++++++++++++------------------------ libi2pd/Identity.h | 5 +++-- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 3f9633ed..1026eb02 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -34,12 +34,11 @@ namespace data } IdentityEx::IdentityEx (): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { } - IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType): - m_IsVerifierCreated (false) + IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType) { memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of if (type != SIGNING_KEY_TYPE_DSA_SHA1) @@ -141,19 +140,19 @@ namespace data } IdentityEx::IdentityEx (const uint8_t * buf, size_t len): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { FromBuffer (buf, len); } IdentityEx::IdentityEx (const IdentityEx& other): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { *this = other; } IdentityEx::IdentityEx (const Identity& standard): - m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + m_ExtendedLen (0), m_ExtendedBuffer (nullptr) { *this = standard; } @@ -161,6 +160,7 @@ namespace data IdentityEx::~IdentityEx () { delete[] m_ExtendedBuffer; + delete m_Verifier; } IdentityEx& IdentityEx::operator=(const IdentityEx& other) @@ -178,8 +178,8 @@ namespace data else m_ExtendedBuffer = nullptr; + delete m_Verifier; m_Verifier = nullptr; - m_IsVerifierCreated = false; return *this; } @@ -193,8 +193,8 @@ namespace data m_ExtendedBuffer = nullptr; m_ExtendedLen = 0; + delete m_Verifier; m_Verifier = nullptr; - m_IsVerifierCreated = false; return *this; } @@ -233,6 +233,7 @@ namespace data } SHA256(buf, GetFullLen (), m_IdentHash); + delete m_Verifier; m_Verifier = nullptr; return GetFullLen (); @@ -381,33 +382,27 @@ namespace data void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const { - if (!m_Verifier) + bool del = false; { - auto created = m_IsVerifierCreated.exchange (true); - if (!created) - m_Verifier.reset (verifier); + std::lock_guard l(m_VerifierMutex); + if (!m_Verifier) + m_Verifier = verifier; else - { - delete verifier; - int count = 0; - while (!m_Verifier && count < 500) // 5 seconds - { - std::this_thread::sleep_for (std::chrono::milliseconds(10)); - count++; - } - if (!m_Verifier) - LogPrint (eLogError, "Identity: couldn't get verifier in 5 seconds"); - } + del = true; } - else + if (del) delete verifier; } void IdentityEx::DropVerifier () const { - // TODO: potential race condition with Verify - m_IsVerifierCreated = false; - m_Verifier = nullptr; + i2p::crypto::Verifier * verifier; + { + std::lock_guard l(m_VerifierMutex); + verifier = m_Verifier; + m_Verifier = nullptr; + } + delete verifier; } std::shared_ptr IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key) diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 9c78f552..0ee87beb 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "Base.h" #include "Signature.h" #include "CryptoKey.h" @@ -125,8 +126,8 @@ namespace data Identity m_StandardIdentity; IdentHash m_IdentHash; - mutable std::unique_ptr m_Verifier; - mutable std::atomic_bool m_IsVerifierCreated; // make sure we don't create twice + mutable i2p::crypto::Verifier * m_Verifier = nullptr; + mutable std::mutex m_VerifierMutex; size_t m_ExtendedLen; uint8_t * m_ExtendedBuffer; }; From f21af4068fd1c9890eb467d94af718e717bd8b21 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Mar 2020 17:35:51 -0400 Subject: [PATCH 0262/2950] preferred crypto type for Decrypt --- libi2pd/Destination.cpp | 2 +- libi2pd/Destination.h | 2 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 2 +- libi2pd/Identity.h | 2 +- libi2pd/RouterContext.cpp | 2 +- libi2pd/RouterContext.h | 2 +- libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 46d3fc57..fb0add02 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1173,7 +1173,7 @@ namespace client if (m_DatagramDestination) m_DatagramDestination->CleanUp (); } - bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const + bool ClientDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index f26200a0..c5c2c16f 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -237,7 +237,7 @@ namespace client i2p::datagram::DatagramDestination * CreateDatagramDestination (); // implements LocalDestination - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { return m_EncryptionPublicKey; }; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index c57553d4..1523d775 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -138,7 +138,7 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr); // x25519(bsk, aepk) + GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // decrypt flags/static @@ -160,7 +160,7 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - GetOwner ()->Decrypt (fs, sharedSecret, nullptr); // x25519(bsk, apk) + GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags @@ -211,7 +211,7 @@ namespace garlic case eECIESx25519BlkAckRequest: { LogPrint (eLogDebug, "Garlic: ack request"); - m_AckRequests.push_back ( {bufbe16toh (buf + offset), index}); + m_AckRequests.push_back ({0, index}); // TODO: use actual tagsetid break; } default: @@ -250,7 +250,7 @@ namespace garlic MixHash (out + offset, 48); // h = SHA256(h || ciphertext) offset += 48; // KDF2 - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt @@ -339,7 +339,7 @@ namespace garlic uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RARCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 56fb48cf..ed1fa17d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -123,7 +123,7 @@ namespace garlic uint64_t m_LastActivityTimestamp = 0; // incoming RatchetTagSet m_SendTagset, m_ReceiveTagset; std::unique_ptr m_Destination;// TODO: might not need it - std::list > m_AckRequests; // (key_id, indeX) + std::list > m_AckRequests; // (tagsetid, index) }; } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index ae6599fc..fd6e8fee 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -495,7 +495,7 @@ namespace garlic } // otherwise assume ElGamal/AES ElGamalBlock elGamal; - if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx)) + if (length >= 514 && Decrypt (buf, (uint8_t *)&elGamal, m_Ctx, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)) { auto decryption = std::make_shared(elGamal.sessionKey); uint8_t iv[32]; // IV is first 16 bytes diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 0ee87beb..663f46b5 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -225,7 +225,7 @@ namespace data public: virtual ~LocalDestination() {}; - virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const = 0; + virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, 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/RouterContext.cpp b/libi2pd/RouterContext.cpp index 6c63ef79..b86ed8f2 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -724,7 +724,7 @@ 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) const + 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; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index dfc05fe7..28c324c4 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -108,7 +108,7 @@ namespace i2p // implements LocalDestination std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, 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_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index eec21f06..f4c8a91e 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -59,7 +59,7 @@ namespace client m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), m_EncryptionPrivateKey); } - bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const + bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const { if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index f675318f..7f590555 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -80,7 +80,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) const; + bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; // TODO: implement GetEncryptionPublicKey std::shared_ptr GetIdentity () const { return m_Identity; }; From 8872d1f389a63cf2823d9562396eb34b01bd3e63 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Apr 2020 09:54:10 -0400 Subject: [PATCH 0263/2950] mutex for m_RemoteIdentity --- libi2pd/TransportSession.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 49067ce2..55c39c7a 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "Identity.h" #include "Crypto.h" #include "RouterInfo.h" @@ -67,8 +68,16 @@ namespace transport std::string GetIdentHashBase64() const { return m_RemoteIdentity ? m_RemoteIdentity->GetIdentHash().ToBase64() : ""; } - std::shared_ptr GetRemoteIdentity () { return m_RemoteIdentity; }; - void SetRemoteIdentity (std::shared_ptr ident) { m_RemoteIdentity = ident; }; + std::shared_ptr GetRemoteIdentity () + { + std::lock_guard l(m_RemoteIdentityMutex); + return m_RemoteIdentity; + } + void SetRemoteIdentity (std::shared_ptr ident) + { + std::lock_guard l(m_RemoteIdentityMutex); + m_RemoteIdentity = ident; + } size_t GetNumSentBytes () const { return m_NumSentBytes; }; size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; @@ -85,6 +94,7 @@ namespace transport protected: std::shared_ptr m_RemoteIdentity; + mutable std::mutex m_RemoteIdentityMutex; std::shared_ptr m_DHKeysPair; // X - for client and Y - for server size_t m_NumSentBytes, m_NumReceivedBytes; bool m_IsOutgoing; From aa7750bfd345aa04aefa4b08e4fedf97d6997c04 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Apr 2020 21:48:39 -0400 Subject: [PATCH 0264/2950] keep sending new session reply until first established session message received --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 36 +++++++++++++++++++---- libi2pd/ECIESX25519AEADRatchetSession.h | 5 +++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 1523d775..c3f7320d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -298,7 +298,8 @@ namespace garlic return false; } MixHash (out + offset, 16); // h = SHA256(h || ciphertext) - out += 16; + offset += 16; + memcpy (m_NSRHeader, out, 56); // for possible next NSR // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) @@ -308,18 +309,33 @@ namespace garlic m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset.NextSessionTagRatchet (); GenerateMoreReceiveTags (GetOwner ()->GetNumTags ()); - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt { - LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); + LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed"); return false; } - m_State = eSessionStateEstablished; + m_State = eSessionStateNewSessionReplySent; return true; } + bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Bob and sent NSR already + memcpy (out, m_NSRHeader, 56); + uint8_t nonce[12]; + CreateNonce (0, nonce); + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed"); + return false; + } + return true; + } + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len) { // we are Alice @@ -419,6 +435,11 @@ namespace garlic m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); switch (m_State) { + case eSessionStateNewSessionReplySent: + m_State = eSessionStateEstablished; +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif case eSessionStateEstablished: return HandleExistingSessionMessage (buf, len, index); case eSessionStateNew: @@ -456,6 +477,11 @@ namespace garlic return nullptr; len += 72; break; + case eSessionStateNewSessionReplySent: + if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 72; + break; default: return nullptr; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index ed1fa17d..82675331 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -69,6 +69,7 @@ namespace garlic eSessionStateNew =0, eSessionStateNewSessionReceived, eSessionStateNewSessionSent, + eSessionStateNewSessionReplySent, eSessionStateEstablished }; @@ -106,6 +107,7 @@ namespace garlic bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); 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); std::vector CreatePayload (std::shared_ptr msg); @@ -117,7 +119,8 @@ namespace garlic private: uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; - uint8_t m_Aepk[32]; // Alice's ephemeral keys TODO: for incoming only + uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only + uint8_t m_NSRHeader[56], m_NSRKey[32]; // new session reply, for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming From d503f0756470ec1d27228295fd906cf47f97fe3e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 26 Mar 2020 09:54:51 +0300 Subject: [PATCH 0265/2950] suppress GCC 7 (bug 77728) psabi note Suppresses messages like that: note: parameter passing for argument of type <...> will change in GCC 7.1 Signed-off-by: R4SAS --- Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index 9db660c2..fa2f2fdf 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -1,5 +1,5 @@ # set defaults instead redefine -CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation +CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation -Wno-psabi LDFLAGS ?= ${LD_DEBUG} ## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time From a9436aa9af5a97daef899f352c9b774d4ce40e6d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 3 Apr 2020 14:31:18 +0300 Subject: [PATCH 0266/2950] drop i2lua Signed-off-by: R4SAS --- build/CMakeLists.txt | 6 ------ libi2pd/Destination.cpp | 26 -------------------------- libi2pd/Destination.h | 20 +++----------------- libi2pd/Tunnel.cpp | 6 ------ libi2pd/TunnelPool.cpp | 10 ---------- libi2pd/TunnelPool.h | 10 ---------- libi2pd_client/MatchedDestination.cpp | 5 ----- libi2pd_client/MatchedDestination.h | 1 - 8 files changed, 3 insertions(+), 81 deletions(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 2bdfb396..1a459bf8 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -19,7 +19,6 @@ option(WITH_GUI "Include GUI (currently MS Windows only)" ON) option(WITH_MESHNET "Build for cjdns test network" OFF) option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) -option(WITH_I2LUA "Build for i2lua" OFF) # paths set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) @@ -88,10 +87,6 @@ if (WIN32 OR MSYS) list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") endif () -if (WITH_I2LUA) - add_definitions(-DI2LUA) -endif() - add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") @@ -414,7 +409,6 @@ message(STATUS " PCH : ${WITH_PCH}") message(STATUS " MESHNET : ${WITH_MESHNET}") message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") -message(STATUS " I2LUA : ${WITH_I2LUA}") message(STATUS "---------------------------------------") #Handle paths nicely diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index fb0add02..98c4b323 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -931,32 +931,6 @@ namespace client } } -#ifdef I2LUA - void ClientDestination::Ready(ReadyPromise & p) - { - ScheduleCheckForReady(&p); - } - - void ClientDestination::ScheduleCheckForReady(ReadyPromise * p) - { - // tick every 100ms - m_ReadyChecker.expires_from_now(boost::posix_time::milliseconds(100)); - m_ReadyChecker.async_wait([&, p] (const boost::system::error_code & ecode) { - HandleCheckForReady(ecode, p); - }); - } - - void ClientDestination::HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p) - { - if(ecode) // error happened - p->set_value(nullptr); - else if(IsReady()) // we are ready - p->set_value(std::shared_ptr(this)); - else // we are not ready - ScheduleCheckForReady(p); - } -#endif - void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index c5c2c16f..83a38816 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -8,9 +8,6 @@ #include #include #include -#ifdef I2LUA -#include -#endif #include #include "Identity.h" #include "TunnelPool.h" @@ -196,13 +193,6 @@ namespace client class ClientDestination: public LeaseSetDestination { public: -#ifdef I2LUA - // type for informing that a client destination is ready - typedef std::promise > ReadyPromise; - // informs promise with shared_from_this() when this destination is ready to use - // if cancelled before ready, informs promise with nullptr - void Ready(ReadyPromise & p); -#endif ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); @@ -251,14 +241,10 @@ namespace client private: - std::shared_ptr GetSharedFromThis () - { return std::static_pointer_cast(shared_from_this ()); } + std::shared_ptr GetSharedFromThis () { + return std::static_pointer_cast(shared_from_this ()); + } void PersistTemporaryKeys (); -#ifdef I2LUA - void ScheduleCheckForReady(ReadyPromise * p); - void HandleCheckForReady(const boost::system::error_code & ecode, ReadyPromise * p); -#endif - void ReadAuthKey (const std::string& group, const std::map * params); private: diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 9dacddac..879ee2d3 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -576,7 +576,6 @@ namespace tunnel for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();) { auto tunnel = it->second; - auto pool = tunnel->GetTunnelPool(); switch (tunnel->GetState ()) { case eTunnelStatePending: @@ -599,8 +598,6 @@ namespace tunnel hop = hop->next; } } - // for i2lua - if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout); // delete it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; @@ -610,9 +607,6 @@ namespace tunnel break; case eTunnelStateBuildFailed: LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted"); - // for i2lua - if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected); - it = pendingTunnels.erase (it); m_NumFailedTunnelCreations++; break; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index b3e3c7d2..7256b2db 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -88,8 +88,6 @@ namespace tunnel } if (m_LocalDestination) m_LocalDestination->SetLeaseSetUpdated (); - - OnTunnelBuildResult(createdTunnel, eBuildResultOkay); } void TunnelPool::TunnelExpired (std::shared_ptr expiredTunnel) @@ -112,8 +110,6 @@ namespace tunnel std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } - OnTunnelBuildResult(createdTunnel, eBuildResultOkay); - //CreatePairedInboundTunnel (createdTunnel); } @@ -596,11 +592,5 @@ namespace tunnel } return tun; } - - void TunnelPool::OnTunnelBuildResult(std::shared_ptr tunnel, TunnelBuildResult result) - { - auto peers = tunnel->GetPeers(); - if(m_CustomPeerSelector) m_CustomPeerSelector->OnBuildResult(peers, tunnel->IsInbound(), result); - } } } diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index fc46930c..d6fb91cc 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -23,13 +23,6 @@ namespace tunnel class InboundTunnel; class OutboundTunnel; - - enum TunnelBuildResult { - eBuildResultOkay, // tunnel was built okay - eBuildResultRejected, // tunnel build was explicitly rejected - eBuildResultTimeout // tunnel build timed out - }; - typedef std::shared_ptr Peer; typedef std::vector Path; @@ -38,7 +31,6 @@ namespace tunnel { virtual ~ITunnelPeerSelector() {}; virtual bool SelectPeers(Path & peers, int hops, bool isInbound) = 0; - virtual bool OnBuildResult(const Path & peers, bool isInbound, TunnelBuildResult result) = 0; }; @@ -98,8 +90,6 @@ namespace tunnel std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude=nullptr) const; std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude=nullptr) const; - void OnTunnelBuildResult(std::shared_ptr tunnel, TunnelBuildResult result); - // for overriding tunnel peer selection std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index 3d75a3ca..5cec178f 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -94,10 +94,5 @@ namespace client } return true; } - - bool MatchedTunnelDestination::OnBuildResult(const i2p::tunnel::Path & path, bool inbound, i2p::tunnel::TunnelBuildResult result) - { - return true; - } } } diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 67b874e6..9d61799a 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -18,7 +18,6 @@ namespace client void Stop(); bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); - bool OnBuildResult(const i2p::tunnel::Path & peers, bool inbound, i2p::tunnel::TunnelBuildResult result); private: void ResolveCurrentLeaseSet(); From 4e1319d874ca788672dba47a942efa8f849dc675 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Apr 2020 11:40:18 -0400 Subject: [PATCH 0267/2950] handle ECIESFlag in DatabaseLookup at floodfill --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 35 +++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 2 ++ libi2pd/I2NPProtocol.h | 1 + libi2pd/NetDb.cpp | 21 ++++++++++---- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index c3f7320d..4371124e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -623,6 +623,41 @@ namespace garlic CleanupUnconfirmedLeaseSet (ts); return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } + + std::shared_ptr WrapECIESX25519AEADRatchetMessage (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; + *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 ()); + + 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); + return m; + } + } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 82675331..3185a7fc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -128,6 +128,8 @@ namespace garlic std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) }; + + std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); } } diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index ca074aed..5714afce 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -95,6 +95,7 @@ namespace i2p // DatabaseLookup flags const uint8_t DATABASE_LOOKUP_DELIVERY_FLAG = 0x01; const uint8_t DATABASE_LOOKUP_ENCRYPTION_FLAG = 0x02; + const uint8_t DATABASE_LOOKUP_ECIES_FLAG = 0x10; const uint8_t DATABASE_LOOKUP_TYPE_FLAGS_MASK = 0x0C; const uint8_t DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP = 0; const uint8_t DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP = 0x04; // 0100 diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 6d69f131..5d452d1d 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -15,8 +15,9 @@ #include "NTCP2.h" #include "RouterContext.h" #include "Garlic.h" -#include "NetDb.hpp" +#include "ECIESX25519AEADRatchetSession.h" #include "Config.h" +#include "NetDb.hpp" using namespace i2p::transport; @@ -949,10 +950,20 @@ namespace data const uint8_t numTags = excluded[32]; if (numTags) { - const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag - i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); - replyMsg = garlic.WrapSingleMessage (replyMsg); - if(replyMsg == nullptr) LogPrint(eLogError, "NetDb: failed to wrap message"); + if (flag & DATABASE_LOOKUP_ECIES_FLAG) + { + uint64_t tag; + memcpy (&tag, excluded + 33, 8); + replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag); + } + else + { + const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag + i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); + replyMsg = garlic.WrapSingleMessage (replyMsg); + } + if (!replyMsg) + LogPrint (eLogError, "NetDb: failed to wrap message"); } else LogPrint(eLogWarning, "NetDb: encrypted reply requested but no tags provided"); From 49c1e477369cc08a94ea6eb57d19b4e91f81fc42 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 8 Apr 2020 18:02:12 -0400 Subject: [PATCH 0268/2950] correct termination if session already exists --- libi2pd/NTCP2.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 3dfd6250..a92c77ce 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -706,9 +706,13 @@ namespace transport // ready to communicate auto existing = i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : ri.GetRouterIdentity ()); - m_Server.AddNTCP2Session (shared_from_this (), true); - Established (); - ReceiveLength (); + if (m_Server.AddNTCP2Session (shared_from_this (), true)) + { + Established (); + ReceiveLength (); + } + else + Terminate (); } else Terminate (); @@ -1258,7 +1262,6 @@ namespace transport if (it != m_NTCP2Sessions.end ()) { LogPrint (eLogWarning, "NTCP2: session to ", ident.ToBase64 (), " already exists"); - session->Terminate(); return false; } m_NTCP2Sessions.insert (std::make_pair (ident, session)); @@ -1301,6 +1304,8 @@ namespace transport }); conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port), std::bind (&NTCP2Server::HandleConnect, this, std::placeholders::_1, conn, timer)); } + else + conn->Terminate (); }); } From b7c206c44bacaf611b06855f9d6292d88b196978 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 9 Apr 2020 15:00:38 -0400 Subject: [PATCH 0269/2950] replace by new incoming session --- libi2pd/NTCP2.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index a92c77ce..85d83bf0 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1262,7 +1262,11 @@ namespace transport if (it != m_NTCP2Sessions.end ()) { LogPrint (eLogWarning, "NTCP2: session to ", ident.ToBase64 (), " already exists"); - return false; + if (incoming) + // replace by new session + it->second->Terminate (); + else + return false; } m_NTCP2Sessions.insert (std::make_pair (ident, session)); return true; From b3974cb52a2eb5bf2201af6b5e82410024b643e9 Mon Sep 17 00:00:00 2001 From: r4sas Date: Fri, 10 Apr 2020 02:34:47 +0000 Subject: [PATCH 0270/2950] [webconsole] security hardening headers (closes #1464) Signed-off-by: r4sas --- daemon/HTTPServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 5eac08a9..f93c3531 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1141,6 +1141,8 @@ namespace http { void HTTPConnection::SendReply (HTTPRes& reply, std::string& content) { reply.add_header("X-Frame-Options", "SAMEORIGIN"); + reply.add_header("X-Content-Type-Options", "nosniff"); + reply.add_header("X-XSS-Protection", "1; mode=block"); reply.add_header("Content-Type", "text/html"); reply.body = content; From 5e606573b1b0ea640a6ed21fd9a0707541587854 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Apr 2020 12:57:47 -0400 Subject: [PATCH 0271/2950] 2.31.0 --- ChangeLog | 19 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 39 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 293764a6..39d62f21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,25 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.31.0] - 2020-04-10 +### Added +- NTCP2 HTTP proxy +- Publish LeaseSet2 for I2CP destinations +- Show status page on main activity for android +- Handle ECIESFlag in DatabaseLookup at floodfill +- C++17 features for eligible compilers +### Changed +- Droped Websockets and Lua support +- Send DeliveryStatusMsg for LeaseSet for ECIES-X25519-AEAD-Ratchet +- Keep sending new session reply until established for ECIES-X25519-AEAD-Ratchet +- Updated SSU log messages +- Security hardening headers in web console +- Various QT changes +### Fixed +- NTCP2 socket descriptors leak +- Race condition with router's identity in transport sessions +- Not terminated streams remain forever + ## [2.30.0] - 2020-02-25 ### Added - Single threaded SAM diff --git a/Win32/installer.iss b/Win32/installer.iss index d4f6f247..8e66c17a 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.30.0" +#define I2Pd_ver "2.31.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 6fcb4521..d3c5c16b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2300 - versionName "2.30.0" + versionCode 2310 + versionName "2.31.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index 8c4a1a9d..d6dcf060 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.30.0.{build} +version: 2.31.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 f9571ca0..b182dca4 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.30.0 +Version: 2.31.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -118,6 +118,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Apr 10 2020 orignal - 2.31.0 +- update to 2.31.0 + * Tue Feb 25 2020 orignal - 2.30.0 - update to 2.30.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index b3cca8ab..5ece769c 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.30.0 +Version: 2.31.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -116,6 +116,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Fri Apr 10 2020 orignal - 2.31.0 +- update to 2.31.0 + * Tue Feb 25 2020 orignal - 2.30.0 - update to 2.30.0 diff --git a/debian/changelog b/debian/changelog index da177cbd..3824d4f8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.31.0-1) unstable; urgency=medium + + * updated to version 2.31.0 + + -- orignal Fri, 10 Apr 2020 16:00:00 +0000 + i2pd (2.30.0-1) unstable; urgency=medium * updated to version 2.30.0/0.9.45 diff --git a/libi2pd/version.h b/libi2pd/version.h index 36fbe2ca..4ad1a546 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 30 +#define I2PD_VERSION_MINOR 31 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 00b6974a..4c027bc0 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 4e37df26a3ba285ebd9c1918472d59dfb530f2cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 10 Apr 2020 20:33:54 +0300 Subject: [PATCH 0272/2950] 2.31.0 Signed-off-by: R4SAS --- ChangeLog | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 39d62f21..930be261 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,7 +3,7 @@ ## [2.31.0] - 2020-04-10 ### Added -- NTCP2 HTTP proxy +- NTCP2 through HTTP proxy - Publish LeaseSet2 for I2CP destinations - Show status page on main activity for android - Handle ECIESFlag in DatabaseLookup at floodfill @@ -13,7 +13,9 @@ - Send DeliveryStatusMsg for LeaseSet for ECIES-X25519-AEAD-Ratchet - Keep sending new session reply until established for ECIES-X25519-AEAD-Ratchet - Updated SSU log messages +- Reopen SSU socket on exception - Security hardening headers in web console +- Various web console changes - Various QT changes ### Fixed - NTCP2 socket descriptors leak From 95fa835191d052feee915cfa047230a05176e646 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 11 Apr 2020 23:28:45 +0300 Subject: [PATCH 0273/2950] [android] update strings, menus, add reloading tunnels item Signed-off-by: R4SAS --- android/.gitignore | 2 + android/AndroidManifest.xml | 5 +- android/jni/i2pd_android.cpp | 6 + android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 3 + android/res/layout/activity_perms_asker.xml | 7 +- .../res/layout/activity_perms_explanation.xml | 6 +- android/res/layout/webview.xml | 11 +- android/res/menu/options_main.xml | 30 +- android/res/values-ru/strings.xml | 18 +- android/res/values/strings.xml | 20 +- .../org/purplei2p/i2pd/DaemonSingleton.java | 76 +++- .../src/org/purplei2p/i2pd/I2PDActivity.java | 382 +++++++++--------- android/src/org/purplei2p/i2pd/I2PD_JNI.java | 2 + 13 files changed, 326 insertions(+), 242 deletions(-) diff --git a/android/.gitignore b/android/.gitignore index 666c6694..57a0a6cd 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -4,6 +4,7 @@ bin libs log* obj +.cxx .gradle .idea .externalNativeBuild @@ -14,3 +15,4 @@ android.iml build *.iml *.local +*.jks diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index a95e3773..88985138 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -17,8 +17,9 @@ android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar" android:requestLegacyExternalStorage="true" - android:usesCleartextTraffic="true" + android:usesCleartextTraffic="true" > + @@ -30,10 +31,10 @@ android:label="@string/app_name"> - + diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index da908648..bb058b5d 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -2,6 +2,7 @@ #include "org_purplei2p_i2pd_I2PD_JNI.h" #include "DaemonAndroid.h" #include "RouterContext.h" +#include "ClientContext.h" #include "Transports.h" JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith @@ -61,6 +62,11 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels i2p::context.SetAcceptsTunnels (true); } +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs + (JNIEnv *env, jclass clazz) { + i2p::client::context.ReloadConfig(); +} + JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged (JNIEnv *env, jclass clazz, jboolean isConnected) { bool isConnectedBool = (bool) isConnected; diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index 6939a153..6d809e63 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -27,6 +27,9 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels (JNIEnv *, jclass); +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs + (JNIEnv *, jclass); + JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged (JNIEnv * env, jclass clazz, jboolean isConnected); diff --git a/android/res/layout/activity_perms_asker.xml b/android/res/layout/activity_perms_asker.xml index d2d12cb6..778c9ef5 100644 --- a/android/res/layout/activity_perms_asker.xml +++ b/android/res/layout/activity_perms_asker.xml @@ -15,13 +15,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/horizontal_page_margin" - android:visibility="gone" - /> + android:visibility="gone" /> \r\n"; + s << "\r\n
\r\n"; } void ShowTransitTunnels (std::stringstream& s) @@ -1125,6 +1137,19 @@ namespace http { res.add_header("Refresh", redirect.c_str()); return; } + else if (cmd == HTTP_COMMAND_LIMITTRANSIT) + { + uint32_t limit = std::stoul(params["limit"], nullptr); + if (limit > 0 && limit <= 65535) + SetMaxNumTransitTunnels (limit); + else { + s << "ERROR: Transit tunnels count must not exceed 65535

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

You will be redirected back in 5 seconds"; + res.add_header("Refresh", redirect.c_str()); + return; + } + } else { res.code = 400; diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index b0233901..275aa69d 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -316,13 +316,23 @@ namespace i2p static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO: void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) { - if (maxNumTransitTunnels > 0 && maxNumTransitTunnels <= 10000 && g_MaxNumTransitTunnels != maxNumTransitTunnels) + if (maxNumTransitTunnels > 0 && g_MaxNumTransitTunnels != maxNumTransitTunnels) { - LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); + if (maxNumTransitTunnels <= 65535) { + LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); + } else { + LogPrint (eLogWarning, "I2NP: Requested number of transit tunnels exceeds 65535, limited"); + maxNumTransitTunnels = 65535; + } g_MaxNumTransitTunnels = maxNumTransitTunnels; } } + uint16_t GetMaxNumTransitTunnels () + { + return g_MaxNumTransitTunnels; + } + bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 5714afce..2fca1538 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -285,6 +285,7 @@ namespace tunnel const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 2500; void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); + uint16_t GetMaxNumTransitTunnels (); } #endif From 51e3d5f7bc122d81eb0c0466e3fb3b7511ea4ecd Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Apr 2020 19:27:31 -0400 Subject: [PATCH 0290/2950] create next tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 70 ++++++++++++++++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 9 +-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2a30713e..8d820eb6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -38,7 +38,11 @@ namespace garlic { i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; - if (m_NextIndex >= 65535) m_NextIndex = 0; // TODO: dirty hack, should create new tagset + if (m_NextIndex >= 65535) + { + LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty"); + return 0; + } return m_KeyData.GetTag (); } @@ -251,7 +255,26 @@ namespace garlic uint8_t flag = buf[0]; buf++; // flag if (flag & ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG) { - // TODO: implement + if (!m_NextSendRatchet) return; + uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID + if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) || + (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) + { + if (flag & ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG) + memcpy (m_NextSendRatchet->remote, buf, 32); + uint8_t sharedSecret[32], tagsetKey[32]; + m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret); + i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) + auto newTagset = std::make_shared (shared_from_this ()); + newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); + newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); + newTagset->NextSessionTagRatchet (); + m_SendTagset = newTagset; + m_SendForwardKey = false; + LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created"); + } + else + LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID); } else { @@ -292,6 +315,26 @@ namespace garlic LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } } + + void ECIESX25519AEADRatchetSession::NewNextSendRatchet () + { + auto newTagset = new DHRatchet (); + if (m_NextSendRatchet) + { + newTagset->keyID = m_NextSendRatchet->keyID; + if (!newTagset->newKey || !newTagset->keyID) + { + newTagset->keyID++; + newTagset->newKey = true; + } + else + newTagset->newKey = false; + } + if (newTagset->newKey) + newTagset->key.GenerateKeys (); + m_NextSendRatchet.reset (newTagset); + m_SendForwardKey = true; + } bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { @@ -487,7 +530,9 @@ namespace garlic { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; - } + } + if (index >= ECIESX25519_TAGSET_MAX_NUM_TAGS && !m_SendForwardKey) + NewNextSendRatchet (); return true; } @@ -601,6 +646,11 @@ namespace garlic payloadLen += 6; if (m_NextReceiveRatchet->newKey) payloadLen += 32; } + if (m_SendForwardKey) + { + payloadLen += 6; + if (m_NextSendRatchet->newKey) payloadLen += 32; + } uint8_t paddingSize; RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; paddingSize++; // 1 - 16 @@ -662,6 +712,20 @@ namespace garlic } 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 + offset++; // flag + htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid + if (m_NextSendRatchet->newKey) + { + memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); + offset += 32; // public key + } + } // padding v[offset] = eECIESx25519BlkPadding; offset++; htobe16buf (v.data () + offset, paddingSize); offset += 2; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 963429ed..0a051810 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -73,6 +73,7 @@ namespace garlic const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after const int ECIESX25519_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 60000; // number of tags we request new tagset after class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { @@ -90,7 +91,7 @@ namespace garlic int keyID = 0; i2p::crypto::X25519Keys key; uint8_t remote[32]; // last remote public key - bool newKey; + bool newKey = true; }; public: @@ -136,6 +137,7 @@ namespace garlic size_t CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len); void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); + void NewNextSendRatchet (); private: @@ -148,9 +150,8 @@ namespace garlic std::shared_ptr m_SendTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) - int m_SendKeyID = 0, m_ReceiveKeyID = 0; - bool m_SendReverseKey = false; - std::unique_ptr m_NextReceiveRatchet; + bool m_SendReverseKey = false, m_SendForwardKey = false; + std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); From 50a77fedca2c6d9119b8a10237e3bcc54367f8c1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Apr 2020 19:37:00 -0400 Subject: [PATCH 0291/2950] removed trivial check --- libi2pd/I2NPProtocol.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 275aa69d..0e7c245e 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -318,12 +318,7 @@ namespace i2p { if (maxNumTransitTunnels > 0 && g_MaxNumTransitTunnels != maxNumTransitTunnels) { - if (maxNumTransitTunnels <= 65535) { - LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); - } else { - LogPrint (eLogWarning, "I2NP: Requested number of transit tunnels exceeds 65535, limited"); - maxNumTransitTunnels = 65535; - } + LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); g_MaxNumTransitTunnels = maxNumTransitTunnels; } } From 5700e18257993a7f18e69629f92a53d111292c5e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 27 Apr 2020 13:23:29 +0300 Subject: [PATCH 0292/2950] [FS] read tunnels configs which ends with .conf only Signed-off-by: R4SAS --- libi2pd_client/ClientContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 722fb242..fa0532c3 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -490,6 +490,7 @@ namespace client { for (auto& it: files) { + if (it.substr(it.size() - 5) != ".conf") continue; // skip files which not ends with ".conf" LogPrint(eLogDebug, "Clients: tunnels extra config file: ", it); ReadTunnels (it, numClientTunnels, numServerTunnels); } From e6fdf5ad8da59072f431268e27cb9b736441fd15 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 27 Apr 2020 13:59:00 +0300 Subject: [PATCH 0293/2950] [Log] create logfile even if loglevel is "none" Signed-off-by: R4SAS --- libi2pd/Log.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 79b4a511..7d77aaf8 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -199,7 +199,6 @@ namespace log { void Log::SendTo (const std::string& path) { if (m_LogStream) m_LogStream = nullptr; // close previous - if (m_MinLevel == eLogNone) return; auto flags = std::ofstream::out | std::ofstream::app; auto os = std::make_shared (path, flags); if (os->is_open ()) From 142a138cfceb96c35d05217606525a8f21255018 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Apr 2020 09:35:02 -0400 Subject: [PATCH 0294/2950] store previous reverse key --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8d820eb6..b02e49f8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -255,12 +255,12 @@ namespace garlic uint8_t flag = buf[0]; buf++; // flag if (flag & ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG) { - if (!m_NextSendRatchet) return; + if (!m_SendForwardKey || !m_NextSendRatchet) return; uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) || (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) { - if (flag & ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG) + if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextSendRatchet->remote, buf, 32); uint8_t sharedSecret[32], tagsetKey[32]; m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret); @@ -318,22 +318,23 @@ namespace garlic void ECIESX25519AEADRatchetSession::NewNextSendRatchet () { - auto newTagset = new DHRatchet (); if (m_NextSendRatchet) { - newTagset->keyID = m_NextSendRatchet->keyID; - if (!newTagset->newKey || !newTagset->keyID) + if (!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) { - newTagset->keyID++; - newTagset->newKey = true; + m_NextSendRatchet->keyID++; + m_NextSendRatchet->newKey = true; } else - newTagset->newKey = false; + m_NextSendRatchet->newKey = false; } - if (newTagset->newKey) - newTagset->key.GenerateKeys (); - m_NextSendRatchet.reset (newTagset); + else + m_NextSendRatchet.reset (new DHRatchet ()); + if (m_NextSendRatchet->newKey) + m_NextSendRatchet->key.GenerateKeys (); + m_SendForwardKey = true; + LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); } bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) From f77a58b2dc03ef3478d8b8a13da3b13ea315109a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 27 Apr 2020 18:53:02 -0400 Subject: [PATCH 0295/2950] set some ECIESx25519 params --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 13 ++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 9 ++++++--- libi2pd/Garlic.cpp | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b02e49f8..4dba003d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -311,7 +311,7 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, GetOwner ()->GetNumTags ()); + GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } } @@ -426,7 +426,7 @@ namespace garlic m_SendTagset = std::make_shared(shared_from_this ()); m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, GetOwner ()->GetNumTags ()); + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt @@ -495,7 +495,7 @@ namespace garlic auto receiveTagset = std::make_shared(shared_from_this ()); receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, GetOwner ()->GetNumTags ()); + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -552,8 +552,11 @@ namespace garlic return false; } HandlePayload (payload.data (), len - 16, receiveTagset, index); - if (receiveTagset->GetNextIndex () - index <= GetOwner ()->GetNumTags ()*2/3) - GenerateMoreReceiveTags (receiveTagset, GetOwner ()->GetNumTags ()); + int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 + if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; + moreTags -= (receiveTagset->GetNextIndex () - index); + if (moreTags > 0) + GenerateMoreReceiveTags (receiveTagset, moreTags); return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 0a051810..5cba8868 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -72,9 +72,12 @@ namespace garlic const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after - const int ECIESX25519_EXPIRATION_TIMEOUT = 600; // in seconds - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 60000; // number of tags we request new tagset after - + const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after + const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; + const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { enum SessionState diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index f0e3c10e..fe5e8d69 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -788,7 +788,7 @@ namespace garlic // ECIESx25519 for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { - if (ts > it->second.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT) + if (ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) it = m_ECIESx25519Tags.erase (it); else ++it; From 7b22ef4270de78e2bd013edff6fd9795bb5b6c2c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Apr 2020 14:47:53 -0400 Subject: [PATCH 0296/2950] create incoming NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4dba003d..06f6c84e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -378,7 +378,7 @@ namespace garlic m_State = eSessionStateNewSessionSent; if (GetOwner ()) - GetOwner ()->AddECIESx25519SessionNextTag (CreateNewSessionTagset ()); + GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 5cba8868..20676405 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -77,6 +77,7 @@ namespace garlic const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { From 0a431594f89a2e57f12f5bc9c29fd5905b44a726 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 29 Apr 2020 00:56:43 +0300 Subject: [PATCH 0297/2950] [Log] Change default loglevel (closes #1230) Signed-off-by: R4SAS --- contrib/i2pd.conf | 10 +++++----- libi2pd/Config.cpp | 30 +++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 1ef725bb..f8786a33 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -13,10 +13,10 @@ ## Tunnels config files path ## Use that path to store separated tunnels in different config files. ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d -# tunnelsdir = /var/lib/i2pd/tunnels.conf.d +# tunnelsdir = /var/lib/i2pd/tunnels.d ## Where to write pidfile (don't write by default) -# pidfile = /var/run/i2pd.pid +# pidfile = /run/i2pd.pid ## Logging configuration section ## By default logs go to stdout with level 'info' and higher @@ -27,10 +27,10 @@ ## * syslog - use syslog, see man 3 syslog # log = file ## Path to logfile (default - autodetect) -# logfile = /var/log/i2pd.log -## Log messages above this level (debug, *info, warn, error, none) +# logfile = /var/log/i2pd/i2pd.log +## Log messages above this level (debug, info, *warn, error, none) ## If you set it to none, logging will be disabled -# loglevel = info +# loglevel = warn ## Write full CLF-formatted date and time to log (default: write only time) # logclftime = true diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 975a027e..cd17660a 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -35,11 +35,11 @@ namespace config { ("version", "Show i2pd version") ("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") + ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") ("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)") - ("loglevel", value()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error, none)") + ("loglevel", value()->default_value("warn"), "Set the minimal level of log messages (debug, info, warn, error, none)") ("logclftime", bool_switch()->default_value(false), "Write full CLF-formatted date and time to log (default: disabled, write only time)") ("family", value()->default_value(""), "Specify a family, router belongs to") ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") @@ -88,7 +88,7 @@ namespace config { ("http.pass", value()->default_value(""), "Password for basic auth (default: random, see logs)") ("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.webroot", value()->default_value("/"), "WebUI root path (default: / )") ; options_description httpproxy("HTTP Proxy options"); @@ -131,7 +131,7 @@ namespace config { ("sam.enabled", value()->default_value(true), "Enable or disable SAM Application bridge") ("sam.address", value()->default_value("127.0.0.1"), "SAM listen address") ("sam.port", value()->default_value(7656), "SAM listen port") - ("sam.singlethread", value()->default_value(true), "Sessions run in the SAM bridge's thread") + ("sam.singlethread", value()->default_value(true), "Sessions run in the SAM bridge's thread") ; options_description bob("BOB options"); @@ -191,15 +191,15 @@ namespace config { "https://reseed.i2p-projekt.de/," "https://i2p.mooo.com/netDb/," "https://netdb.i2p2.no/," - "https://reseed.i2p2.no/," - "https://reseed2.i2p2.no/," + "https://reseed.i2p2.no/," + "https://reseed2.i2p2.no/," // "https://us.reseed.i2p2.no:444/," // mamoth's shit // "https://uk.reseed.i2p2.no:444/," // mamoth's shit "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," - "https://i2p.novg.net/" + "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ; @@ -228,29 +228,29 @@ namespace config { options_description ntcp2("NTCP2 Options"); ntcp2.add_options() - ("ntcp2.enabled", value()->default_value(true), "Enable NTCP2 (default: enabled)") - ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") - ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") + ("ntcp2.enabled", value()->default_value(true), "Enable NTCP2 (default: enabled)") + ("ntcp2.published", value()->default_value(true), "Publish NTCP2 (default: enabled)") + ("ntcp2.port", value()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)") ("ntcp2.addressv6", value()->default_value("::"), "Address to bind NTCP2 on") - ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") + ("ntcp2.proxy", value()->default_value(""), "Proxy URL for NTCP2 transport") ; options_description nettime("Time sync options"); nettime.add_options() - ("nettime.enabled", value()->default_value(false), "Disable time sync (default: disabled)") + ("nettime.enabled", value()->default_value(false), "Disable time sync (default: disabled)") ("nettime.ntpservers", value()->default_value( "0.pool.ntp.org," "1.pool.ntp.org," "2.pool.ntp.org," "3.pool.ntp.org" ), "Comma separated list of NTCP servers") - ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") + ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") ; options_description persist("Network information persisting options"); persist.add_options() - ("persist.profiles", value()->default_value(true), "Persist peer profiles (default: true)") - ("persist.addressbook", value()->default_value(true), "Persist full addresses (default: true)") + ("persist.profiles", value()->default_value(true), "Persist peer profiles (default: true)") + ("persist.addressbook", value()->default_value(true), "Persist full addresses (default: true)") ; m_OptionsDesc From 65e1871cd73adc07f9c0fb6180b63764c7bbf781 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Apr 2020 18:23:13 -0400 Subject: [PATCH 0298/2950] new tag for each NSR --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 25 ++++++++++++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 06f6c84e..43049d56 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -386,7 +386,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob - uint64_t tag = CreateNewSessionTagset ()->GetNextSessionTag (); + m_NSRTagset = CreateNewSessionTagset (); + uint64_t tag = m_NSRTagset->GetNextSessionTag (); size_t offset = 0; memcpy (out + offset, &tag, 8); @@ -396,6 +397,8 @@ namespace garlic LogPrint (eLogError, "Garlic: Can't encode elligator"); return false; } + memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR + memcpy (m_NSRH, m_H, 32); offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) @@ -408,14 +411,13 @@ namespace garlic uint8_t nonce[12]; CreateNonce (0, nonce); // calulate hash for zero length - if (!i2p::crypto::AEADChaCha20Poly1305 (sharedSecret /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } MixHash (out + offset, 16); // h = SHA256(h || ciphertext) offset += 16; - memcpy (m_NSRHeader, out, 56); // for possible next NSR // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) @@ -442,9 +444,21 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob and sent NSR already - memcpy (out, m_NSRHeader, 56); + uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag + memcpy (out, &tag, 8); + memcpy (out + 8, m_NSREncodedKey, 32); + // recalculte h with new tag + memcpy (m_H, m_NSRH, 32); + MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t nonce[12]; - CreateNonce (0, nonce); + CreateNonce (0, nonce); + if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) + { + LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); + return false; + } + MixHash (out + 40, 16); // h = SHA256(h || ciphertext) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt { @@ -568,6 +582,7 @@ namespace garlic { case eSessionStateNewSessionReplySent: m_State = eSessionStateEstablished; + m_NSRTagset = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 20676405..995bbe4a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -147,11 +147,11 @@ namespace garlic uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only - uint8_t m_NSRHeader[56], m_NSRKey[32]; // new session reply, for incoming only + uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming - std::shared_ptr m_SendTagset; + std::shared_ptr m_SendTagset, m_NSRTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; From c0de9455bbda0d18e7db75aa382a9bfa166a36a8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 29 Apr 2020 02:11:35 +0300 Subject: [PATCH 0299/2950] [android] stop immediatly if no transit tunnels available while graceful shutdown Signed-off-by: R4SAS --- android/jni/i2pd_android.cpp | 6 ++++++ android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 3 +++ android/src/org/purplei2p/i2pd/DaemonSingleton.java | 4 ++++ android/src/org/purplei2p/i2pd/I2PDActivity.java | 11 ++++++++--- android/src/org/purplei2p/i2pd/I2PD_JNI.java | 2 ++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index bb058b5d..177bfd7c 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -4,6 +4,7 @@ #include "RouterContext.h" #include "ClientContext.h" #include "Transports.h" +#include "Tunnel.h" JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith (JNIEnv *env, jclass clazz) { @@ -98,3 +99,8 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir // Set DataDir i2p::android::SetDataDir(dataDir); } + +JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount + (JNIEnv *env, jclass clazz) { + return i2p::tunnel::tunnels.CountTransitTunnels(); +} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index 6d809e63..d5c2f15f 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -36,6 +36,9 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir (JNIEnv *env, jclass clazz, jstring jdataDir); +JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount + (JNIEnv *, jclass); + #ifdef __cplusplus } #endif diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java index 49a323ae..e9e4fc06 100644 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java @@ -65,6 +65,10 @@ public class DaemonSingleton { } } + public synchronized int GetTransitTunnelsCount() { + return I2PD_JNI.GetTransitTunnelsCount(); + } + private volatile boolean startedOkay; public enum State { diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 5303a4da..8295e9f1 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -74,7 +74,7 @@ public class I2PDActivity extends Activity { processAssets(); runOnUiThread(() -> { try { - if (textView==null) + if (textView == null) return; Throwable tr = daemon.getLastThrowable(); if (tr!=null) { @@ -128,7 +128,7 @@ public class I2PDActivity extends Activity { doBindService(); final Timer gracefulQuitTimer = getGracefulQuitTimer(); - if (gracefulQuitTimer!=null) { + if (gracefulQuitTimer != null) { long gracefulStopAtMillis; synchronized (graceStartedMillis_LOCK) { gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; @@ -373,6 +373,11 @@ public class I2PDActivity extends Activity { if (gracefulQuitTimerOld != null) gracefulQuitTimerOld.cancel(); + if(daemon.GetTransitTunnelsCount() <= 0) { // no tunnels left + Log.d(TAG, "no transit tunnels left, stopping"); + i2pdStop(); + } + final Timer gracefulQuitTimer = new Timer(true); setGracefulQuitTimer(gracefulQuitTimer); gracefulQuitTimer.schedule(new TimerTask() { @@ -480,7 +485,7 @@ public class I2PDActivity extends Activity { private void deleteRecursive(File fileOrDirectory) { if (fileOrDirectory.isDirectory()) { File[] files = fileOrDirectory.listFiles(); - if (files!=null) { + if (files != null) { for (File child : files) { deleteRecursive(child); } diff --git a/android/src/org/purplei2p/i2pd/I2PD_JNI.java b/android/src/org/purplei2p/i2pd/I2PD_JNI.java index deb7d6b9..582b102b 100644 --- a/android/src/org/purplei2p/i2pd/I2PD_JNI.java +++ b/android/src/org/purplei2p/i2pd/I2PD_JNI.java @@ -22,6 +22,8 @@ public class I2PD_JNI { public static native void setDataDir(String jdataDir); + public static native int GetTransitTunnelsCount(); + public static void loadLibraries() { //System.loadLibrary("c++_shared"); System.loadLibrary("i2pd"); From 3d9c844dca41d464920077cd73d46a374175f0b5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Apr 2020 22:03:13 -0400 Subject: [PATCH 0300/2950] handle out of order NSR --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 52 ++++++++++++++++------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 43049d56..025340c8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -482,13 +482,18 @@ namespace garlic } buf += 32; len -= 32; // KDF for Reply Key Section + uint8_t h[32]; memcpy (h, m_H, 32); // save m_H MixHash (tag, 8); // h = SHA256(h || tag) MixHash (bepk, 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + if (m_State == eSessionStateNewSessionSent) + { + // only fist time, we assume ephemeral keys the same + m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + } uint8_t nonce[12]; CreateNonce (0, nonce); // calulate hash for zero length @@ -502,14 +507,17 @@ namespace garlic // KDF for payload uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) - // k_ab = keydata[0:31], k_ba = keydata[32:63] - m_SendTagset = std::make_shared(shared_from_this ()); - m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) - m_SendTagset->NextSessionTagRatchet (); - auto receiveTagset = std::make_shared(shared_from_this ()); - receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) - receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + if (m_State == eSessionStateNewSessionSent) + { + // k_ab = keydata[0:31], k_ba = keydata[32:63] + m_SendTagset = std::make_shared(shared_from_this ()); + m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_SendTagset->NextSessionTagRatchet (); + auto receiveTagset = std::make_shared(shared_from_this ()); + receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + receiveTagset->NextSessionTagRatchet (); + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload std::vector payload (len - 16); @@ -518,9 +526,13 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - - m_State = eSessionStateEstablished; - GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); + + if (m_State == eSessionStateNewSessionSent) + { + m_State = eSessionStateEstablished; + GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); + } + memcpy (m_H, h, 32); // restore m_H HandlePayload (payload.data (), len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it @@ -587,7 +599,15 @@ namespace garlic [[fallthrough]]; #endif case eSessionStateEstablished: - return HandleExistingSessionMessage (buf, len, receiveTagset, index); + if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; + if (index < ECIESX25519_NSR_NUM_GENERATED_TAGS) + { + // check NSR just in case + LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); + return HandleNewOutgoingSessionReply (buf, len); + } + else + return false; case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: From 16b992d7055fdd1258572674cc8b5f9391af9867 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 29 Apr 2020 16:55:25 +0300 Subject: [PATCH 0301/2950] update info about pidfile defaults (closes #1136) Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- daemon/UnixDaemon.cpp | 3 +-- daemon/i2pd.cpp | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index f8786a33..2174abe8 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -15,7 +15,7 @@ ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d # tunnelsdir = /var/lib/i2pd/tunnels.d -## Where to write pidfile (don't write by default) +## Where to write pidfile (default: i2pd.pid, not used in Windows) # pidfile = /run/i2pd.pid ## Logging configuration section diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index 3dd38fba..b7af779c 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -167,7 +167,7 @@ namespace i2p sigaction(SIGABRT, &sa, 0); sigaction(SIGTERM, &sa, 0); sigaction(SIGINT, &sa, 0); - sigaction(SIGPIPE, &sa, 0); + sigaction(SIGPIPE, &sa, 0); return Daemon_Singleton::start(); } @@ -175,7 +175,6 @@ namespace i2p bool DaemonLinux::stop() { i2p::fs::Remove(pidfile); - return Daemon_Singleton::stop(); } diff --git a/daemon/i2pd.cpp b/daemon/i2pd.cpp index 8718ad0c..425c2560 100644 --- a/daemon/i2pd.cpp +++ b/daemon/i2pd.cpp @@ -7,18 +7,18 @@ namespace i2p { namespace qt { - int RunQT (int argc, char* argv[]); + int RunQT (int argc, char* argv[]); } } int main( int argc, char* argv[] ) { - return i2p::qt::RunQT (argc, argv); + return i2p::qt::RunQT (argc, argv); } #else int main( int argc, char* argv[] ) { - if (Daemon.init(argc, argv)) + if (Daemon.init(argc, argv)) { if (Daemon.start()) Daemon.run (); From 627d8cfe6965c26b0907a7b8574ada7bcf1a73a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Apr 2020 17:11:48 -0400 Subject: [PATCH 0302/2950] correct timestamp check for LeaseSet2 --- libi2pd/LeaseSet.cpp | 36 ++++++++++++++++++++++-------------- libi2pd/LeaseSet.h | 10 ++++++---- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index b411ca0e..6ce77792 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -149,20 +149,13 @@ namespace data auto ret = m_Leases.insert (std::make_shared(lease)); if (!ret.second) (*ret.first)->endDate = lease.endDate; // update existing (*ret.first)->isUpdated = true; - // check if lease's gateway is in our netDb - if (!netdb.FindRouter (lease.tunnelGateway)) - { - // if not found request it - LogPrint (eLogInfo, "LeaseSet: Lease's tunnel gateway not found, requesting"); - netdb.RequestDestination (lease.tunnelGateway); - } } } else LogPrint (eLogWarning, "LeaseSet: Lease is expired already"); } - uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const + uint64_t LeaseSet::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const { if (!m_Identity) return 0; size_t size = m_Identity->GetFullLen (); @@ -187,7 +180,7 @@ namespace data bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const { - return ExtractTimestamp (buf, len) > ExtractTimestamp (m_Buffer, m_BufferLen); + return ExtractExpirationTimestamp (buf, len) > (m_ExpirationTime ? m_ExpirationTime : ExtractExpirationTimestamp (m_Buffer, m_BufferLen)); } bool LeaseSet::ExpiresSoon(const uint64_t dlt, const uint64_t fudge) const @@ -282,6 +275,12 @@ namespace data ReadFromBuffer (buf, len, false, verifySignature); // TODO: implement encrypted } + + bool LeaseSet2::IsNewer (const uint8_t * buf, size_t len) const + { + uint64_t expiration; + return ExtractPublishedTimestamp (buf, len, expiration) > m_PublishedTimestamp; + } void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity, bool verifySignature) { @@ -640,7 +639,14 @@ namespace data encryptor->Encrypt (data, encrypted, ctx, true); } - uint64_t LeaseSet2::ExtractTimestamp (const uint8_t * buf, size_t len) const + uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const + { + uint64_t expiration = 0; + ExtractPublishedTimestamp (buf, len, expiration); + return expiration; + } + + uint64_t LeaseSet2::ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const { if (len < 8) return 0; if (m_StoreType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) @@ -655,7 +661,8 @@ namespace data offset += blindedKeyLen; uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; uint16_t expires = bufbe16toh (buf + offset); offset += 2; - return (timestamp + expires)* 1000LL; + expiration = (timestamp + expires)* 1000LL; + return timestamp; } else { @@ -665,10 +672,11 @@ namespace data if (offset + 6 >= len) return 0; uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; uint16_t expires = bufbe16toh (buf + offset); offset += 2; - return (timestamp + expires)* 1000LL; + expiration = (timestamp + expires)* 1000LL; + return timestamp; } - } - + } + LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels): m_ExpirationTime (0), m_Identity (identity) { diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 0d255644..4d084da3 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -63,14 +63,14 @@ namespace data LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true); virtual ~LeaseSet () { delete[] m_EncryptionKey; delete[] m_Buffer; }; virtual void Update (const uint8_t * buf, size_t len, bool verifySignature = true); - bool IsNewer (const uint8_t * buf, size_t len) const; + virtual bool IsNewer (const uint8_t * buf, size_t len) const; void PopulateLeases (); // from buffer const uint8_t * GetBuffer () const { return m_Buffer; }; size_t GetBufferLen () const { return m_BufferLen; }; bool IsValid () const { return m_IsValid; }; const std::vector > GetNonExpiredLeases (bool withThreshold = true) const; - const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; + const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; bool HasExpiredLeases () const; bool IsExpired () const; bool IsEmpty () const { return m_Leases.empty (); }; @@ -106,7 +106,7 @@ namespace data private: void ReadFromBuffer (bool readIdentity = true, bool verifySignature = true); - virtual uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // returns max expiration time + virtual uint64_t ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const; // returns max expiration time private: @@ -145,6 +145,7 @@ namespace data bool IsPublishedEncrypted () const { return m_IsPublishedEncrypted; }; std::shared_ptr GetTransientVerifier () const { return m_TransientVerifier; }; void Update (const uint8_t * buf, size_t len, bool verifySignature); + 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; @@ -160,7 +161,8 @@ namespace data template bool VerifySignature (Verifier& verifier, const uint8_t * buf, size_t len, size_t signatureOffset); - uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; + uint64_t ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const; + uint64_t ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const; size_t ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const; // subcredential is subcredential + timestamp, return length of autData without flag private: From 7133a07f389de35e273d65e24b066ec1396f2d26 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 01:52:44 +0300 Subject: [PATCH 0303/2950] [SOCKS] wrap DNS type requests response as IPv4 (fixes netcat usage, closes #1336) Signed-off-by: R4SAS --- libi2pd_client/SOCKS.cpp | 69 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 8742d4c5..9cb69590 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -135,9 +135,9 @@ namespace proxy void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamConnected(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::iterator itr); void HandleUpstreamResolved(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::iterator itr); boost::asio::ip::tcp::resolver m_proxy_resolver; uint8_t m_sock_buff[socks_buffer_size]; @@ -184,8 +184,8 @@ namespace proxy LogPrint(eLogDebug, "SOCKS: async sock read"); if (m_sock) { m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size), - std::bind(&SOCKSHandler::HandleSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&SOCKSHandler::HandleSockRecv, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError,"SOCKS: no socket for read"); } @@ -219,8 +219,8 @@ namespace proxy assert(error >= SOCKS4_OK); m_response[0] = '\x00'; //Version m_response[1] = error; //Response code - htobe16buf(m_response+2,port); //Port - htobe32buf(m_response+4,ip); //IP + htobe16buf(m_response + 2, port); //Port + htobe32buf(m_response + 4, ip); //IP return boost::asio::const_buffers_1(m_response,8); } @@ -236,20 +236,23 @@ namespace proxy { case ADDR_IPV4: size = 10; - htobe32buf(m_response+4,addr.ip); + htobe32buf(m_response + 4, addr.ip); break; case ADDR_IPV6: size = 22; - memcpy(m_response+4,addr.ipv6, 16); + memcpy(m_response + 4, addr.ipv6, 16); break; case ADDR_DNS: - size = 7+addr.dns.size; + size = 7 + addr.dns.size; m_response[4] = addr.dns.size; - memcpy(m_response+5,addr.dns.value, addr.dns.size); + memcpy(m_response + 5, addr.dns.value, addr.dns.size); + // replace type to IPv4 for support socks5 clients + // without domain name resolving support (like netcat) + m_response[3] = ADDR_IPV4; break; } - htobe16buf(m_response+size-2,port); //Port - return boost::asio::const_buffers_1(m_response,size); + htobe16buf(m_response + size - 2, port); //Port + return boost::asio::const_buffers_1(m_response, size); } boost::asio::const_buffers_1 SOCKSHandler::GenerateUpstreamRequest() @@ -259,7 +262,7 @@ namespace proxy // SOCKS 4a m_upstream_request[0] = '\x04'; //version m_upstream_request[1] = m_cmd; - htobe16buf(m_upstream_request+2, m_port); + htobe16buf(m_upstream_request + 2, m_port); m_upstream_request[4] = 0; m_upstream_request[5] = 0; m_upstream_request[6] = 0; @@ -270,7 +273,7 @@ namespace proxy m_upstream_request[10] = 'p'; m_upstream_request[11] = 'd'; m_upstream_request[12] = 0; - upstreamRequestSize += 13; + upstreamRequestSize += 13; if (m_address.dns.size <= max_socks_hostname_size - ( upstreamRequestSize + 1) ) { // bounds check okay memcpy(m_upstream_request + upstreamRequestSize, m_address.dns.value, m_address.dns.size); @@ -285,21 +288,19 @@ namespace proxy bool SOCKSHandler::Socks5ChooseAuth() { - m_response[0] = '\x05'; //Version - m_response[1] = m_authchosen; //Response code - boost::asio::const_buffers_1 response(m_response,2); + m_response[0] = '\x05'; // Version + m_response[1] = m_authchosen; // Response code + boost::asio::const_buffers_1 response(m_response, 2); if (m_authchosen == AUTH_UNACCEPTABLE) { LogPrint(eLogWarning, "SOCKS: v5 authentication negotiation failed"); - boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, - shared_from_this(), std::placeholders::_1)); + boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, shared_from_this(), std::placeholders::_1)); return false; } else { LogPrint(eLogDebug, "SOCKS: v5 choosing authentication method: ", m_authchosen); - boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse, - shared_from_this(), std::placeholders::_1)); + boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse, shared_from_this(), std::placeholders::_1)); return true; } } @@ -313,7 +314,7 @@ namespace proxy { case SOCKS4: LogPrint(eLogWarning, "SOCKS: v4 request failed: ", error); - if (error < SOCKS4_OK) error = SOCKS4_FAIL; //Transparently map SOCKS5 errors + if (error < SOCKS4_OK) error = SOCKS4_FAIL; // Transparently map SOCKS5 errors response = GenerateSOCKS4Response(error, m_4aip, m_port); break; case SOCKS5: @@ -322,13 +323,13 @@ namespace proxy break; } boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, - shared_from_this(), std::placeholders::_1)); + shared_from_this(), std::placeholders::_1)); } void SOCKSHandler::SocksRequestSuccess() { boost::asio::const_buffers_1 response(nullptr,0); - //TODO: this should depend on things like the command type and callbacks may change + // TODO: this should depend on things like the command type and callbacks may change switch (m_socksv) { case SOCKS4: @@ -339,12 +340,11 @@ namespace proxy LogPrint(eLogInfo, "SOCKS: v5 connection success"); auto s = i2p::client::context.GetAddressBook().ToAddress(GetOwner()->GetLocalDestination()->GetIdentHash()); address ad; ad.dns.FromString(s); - //HACK only 16 bits passed in port as SOCKS5 doesn't allow for more + // HACK only 16 bits passed in port as SOCKS5 doesn't allow for more response = GenerateSOCKS5Response(SOCKS5_OK, ADDR_DNS, ad, m_stream->GetRecvStreamID()); break; } - boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone, - shared_from_this(), std::placeholders::_1)); + boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone, shared_from_this(), std::placeholders::_1)); } void SOCKSHandler::EnterState(SOCKSHandler::state nstate, uint8_t parseleft) { @@ -366,12 +366,12 @@ namespace proxy { if ( m_cmd != CMD_CONNECT ) { - //TODO: we need to support binds and other shit! + // TODO: we need to support binds and other shit! LogPrint(eLogError, "SOCKS: unsupported command: ", m_cmd); SocksRequestFailed(SOCKS5_CMD_UNSUP); return false; } - //TODO: we may want to support other address types! + // TODO: we may want to support other address types! if ( m_addrtype != ADDR_DNS ) { switch (m_socksv) @@ -433,9 +433,9 @@ namespace proxy break; case CMD_UDP: if (m_socksv == SOCKS5) break; -#if (__cplusplus >= 201703L) // C++ 17 or higher +#if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; -#endif +#endif default: LogPrint(eLogError, "SOCKS: invalid command: ", ((int)*sock_buff)); SocksRequestFailed(SOCKS5_GEN_FAIL); @@ -652,8 +652,8 @@ namespace proxy LogPrint(eLogDebug, "SOCKS: async upstream sock read"); if (m_upstreamSock) { m_upstreamSock->async_read_some(boost::asio::buffer(m_upstream_response, SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE), - std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError, "SOCKS: no upstream socket for read"); SocksRequestFailed(SOCKS5_GEN_FAIL); @@ -735,8 +735,7 @@ namespace proxy LogPrint(eLogInfo, "SOCKS: negotiating with upstream proxy"); EnterState(UPSTREAM_HANDSHAKE); if (m_upstreamSock) { - boost::asio::write(*m_upstreamSock, - GenerateUpstreamRequest()); + boost::asio::write(*m_upstreamSock, GenerateUpstreamRequest()); AsyncUpstreamSockRead(); } else { LogPrint(eLogError, "SOCKS: no upstream socket to send handshake to"); From 27d69894d474092f97990b726d787cd5245ddda5 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Apr 2020 20:50:31 -0400 Subject: [PATCH 0304/2950] show ECIESx25519 session and tag on the web console --- daemon/HTTPServer.cpp | 11 +++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 9 +++++++++ libi2pd/Garlic.h | 2 ++ 3 files changed, 22 insertions(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ef1e0716..bc1eccd5 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -22,6 +22,7 @@ #include "HTTPServer.h" #include "Daemon.h" #include "util.h" +#include "ECIESX25519AEADRatchetSession.h" #ifdef WIN32_APP #include "Win32/Win32App.h" #endif @@ -409,6 +410,16 @@ namespace http { << "

\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n\r\n"; } else s << "Outgoing: 0
\r\n"; + auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); + if (numECIESx25519Tags > 0) + s << "Incoming ECIESx25519: " << numECIESx25519Tags << "
"; + if (!dest->GetECIESx25519Sessions ().empty ()) + { + s << "
\r\nECIESx25519Tags sessions
"; + for (const auto& it: dest->GetECIESx25519Sessions ()) + s << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) + << " " << it.second->GetState () << "
\r\n"; + } s << "
\r\n"; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 995bbe4a..6dd842e4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -156,6 +156,15 @@ namespace garlic std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; + + public: + + // for HTTP only + int GetState () const { return (int)m_State; } + i2p::data::IdentHash GetDestination () const + { + return m_Destination ? *m_Destination : i2p::data::IdentHash (); + } }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index ffb66245..2c71abe8 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -276,7 +276,9 @@ namespace garlic // for HTTP only size_t GetNumIncomingTags () const { return m_Tags.size (); } + size_t GetNumIncomingECIESx25519Tags () const { return m_ECIESx25519Tags.size (); } const decltype(m_Sessions)& GetSessions () const { return m_Sessions; }; + const decltype(m_ECIESx25519Sessions)& GetECIESx25519Sessions () const { return m_ECIESx25519Sessions; } }; void CleanUpTagsFiles (); From 1aa0da33820eb091c76e7b95553cace3416245eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 04:44:13 +0300 Subject: [PATCH 0305/2950] [NTCP2] fix socks proxy support Signed-off-by: R4SAS --- libi2pd/Config.cpp | 10 ++-- libi2pd/NTCP2.cpp | 119 +++++++++++++++++---------------------- libi2pd/NTCP2.h | 2 +- libi2pd/NTCPSession.cpp | 1 - libi2pd/Transports.cpp | 56 +++++++++--------- libi2pd_client/SOCKS.cpp | 42 +++++++------- 6 files changed, 109 insertions(+), 121 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index cd17660a..580e9156 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -58,9 +58,9 @@ 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", value()->default_value(false), "Enable NTCP transport (default: disabled)") + ("ntcp", value()->default_value(false), "Enable NTCP transport (default: disabled)") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") + ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") @@ -97,7 +97,8 @@ namespace config { ("httpproxy.address", value()->default_value("127.0.0.1"), "HTTP Proxy listen address") ("httpproxy.port", value()->default_value(4444), "HTTP Proxy listen port") ("httpproxy.keys", value()->default_value(""), "File to persist HTTP Proxy keys") - ("httpproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") + ("httpproxy.signaturetype", value()-> + default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("httpproxy.inbound.length", value()->default_value("3"), "HTTP proxy inbound tunnel length") ("httpproxy.outbound.length", value()->default_value("3"), "HTTP proxy outbound tunnel length") ("httpproxy.inbound.quantity", value()->default_value("5"), "HTTP proxy inbound tunnels quantity") @@ -114,7 +115,8 @@ namespace config { ("socksproxy.address", value()->default_value("127.0.0.1"), "SOCKS Proxy listen address") ("socksproxy.port", value()->default_value(4447), "SOCKS Proxy listen port") ("socksproxy.keys", value()->default_value(""), "File to persist SOCKS Proxy keys") - ("socksproxy.signaturetype", value()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") + ("socksproxy.signaturetype", value()-> + default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("socksproxy.inbound.length", value()->default_value("3"), "SOCKS proxy inbound tunnel length") ("socksproxy.outbound.length", value()->default_value("3"), "SOCKS proxy outbound tunnel length") ("socksproxy.inbound.quantity", value()->default_value("5"), "SOCKS proxy inbound tunnels quantity") diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 85d83bf0..e7c37fdd 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1148,7 +1148,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), - m_Resolver(GetService ()) + m_Resolver(GetService ()), m_ProxyType(eNoProxy), m_ProxyEndpoint(nullptr) { } @@ -1164,25 +1164,23 @@ namespace transport StartIOService (); if(UsingProxy()) { - LogPrint(eLogError, "NTCP2: USING PROXY "); + LogPrint(eLogInfo, "NTCP2: Using proxy to connect to peers"); // TODO: resolve proxy until it is resolved boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); boost::system::error_code e; auto itr = m_Resolver.resolve(q, e); if(e) - { LogPrint(eLogError, "NTCP2: Failed to resolve proxy ", e.message()); - } else { m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr)); if (m_ProxyEndpoint) - LogPrint(eLogError, "NTCP2: m_ProxyEndpoint ", *m_ProxyEndpoint); + LogPrint(eLogDebug, "NTCP2: m_ProxyEndpoint ", *m_ProxyEndpoint); } } else { - LogPrint(eLogError, "NTCP2: NOTUSING PROXY "); + LogPrint(eLogInfo, "NTCP2: Proxy is not used"); auto& addresses = context.GetRouterInfo ().GetAddresses (); for (const auto& address: addresses) { @@ -1426,6 +1424,31 @@ namespace transport } } + void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) + { + if(!m_ProxyEndpoint) return; + GetService().post([this, host, port, addrtype, conn]() { + if (this->AddNTCP2Session (conn)) + { + + auto timer = std::make_shared(GetService()); + auto timeout = NTCP_CONNECT_TIMEOUT * 5; + conn->SetTerminationTimeout(timeout * 2); + timer->expires_from_now (boost::posix_time::seconds(timeout)); + timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + conn->Terminate (); + } + }); + conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); + } + }); + } + void NTCP2Server::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) { m_ProxyType = proxytype; @@ -1443,14 +1466,14 @@ namespace transport return; } switch (m_ProxyType) - { + { case eSocksProxy: { // TODO: support username/password auth etc static const uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), - [] (const boost::system::error_code & ec, std::size_t transferred) - { + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), + [] (const boost::system::error_code & ec, std::size_t transferred) + { (void) transferred; if(ec) { @@ -1505,8 +1528,8 @@ namespace transport out << req.to_string(); boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t transferred) - { + [](const boost::system::error_code & ec, std::size_t transferred) + { (void) transferred; if(ec) LogPrint(eLogError, "NTCP2: http proxy write error ", ec.message()); @@ -1549,38 +1572,13 @@ namespace transport } default: LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); - } + } } - void NTCP2Server::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) - { - if(!m_ProxyEndpoint) return; - GetService().post([this, host, port, addrtype, conn]() { - if (this->AddNTCP2Session (conn)) - { - - auto timer = std::make_shared(GetService()); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; - conn->SetTerminationTimeout(timeout * 2); - timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCP2Server::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); - } - }); - } - void NTCP2Server::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) { // build request - size_t sz = 0; + size_t sz = 6; // header + port auto buff = std::make_shared >(256); auto readbuff = std::make_shared >(256); (*buff)[0] = 0x05; @@ -1590,37 +1588,27 @@ namespace transport if(addrtype == eIP4Address) { (*buff)[3] = 0x01; - auto addr = boost::asio::ip::address::from_string(host).to_v4(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff->data () + 4, addrbytes.data(), addrsize); + auto addrbytes = boost::asio::ip::address::from_string(host).to_v4().to_bytes(); + sz += 4; + memcpy(buff->data () + 4, addrbytes.data(), 4); } else if (addrtype == eIP6Address) { (*buff)[3] = 0x04; - auto addr = boost::asio::ip::address::from_string(host).to_v6(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff->data () + 4, addrbytes.data(), addrsize); + auto addrbytes = boost::asio::ip::address::from_string(host).to_v6().to_bytes(); + sz += 16; + memcpy(buff->data () + 4, addrbytes.data(), 16); } else if (addrtype == eHostname) { - (*buff)[3] = 0x03; - size_t addrsize = host.size(); - sz = addrsize + 1 + 4; - if (2 + sz > buff->size ()) - { - // too big - return; - } - (*buff)[4] = (uint8_t) addrsize; - memcpy(buff->data() + 5, host.c_str(), addrsize); + // We mustn't really fall here because all connections are made to IP addresses + LogPrint(eLogError, "NTCP2: Tried to connect to domain name via socks proxy"); + return; } - htobe16buf(buff->data () + sz, port); - sz += 2; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t written) - { + htobe16buf(buff->data () + sz - 2, port); + boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff->data (), sz), boost::asio::transfer_all(), + [buff](const boost::system::error_code & ec, std::size_t written) + { if(ec) { LogPrint(eLogError, "NTCP2: failed to write handshake to socks proxy ", ec.message()); @@ -1628,9 +1616,9 @@ namespace transport } }); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 10), - [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) - { + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 10), + [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) + { if(e) { LogPrint(eLogError, "NTCP2: socks proxy read error ", e.message()); @@ -1650,6 +1638,5 @@ namespace transport conn->Terminate(); }); } - } } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 11ae5995..10170fda 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -274,7 +274,7 @@ namespace transport std::map > m_NTCP2Sessions; std::list > m_PendingIncomingSessions; - ProxyType m_ProxyType =eNoProxy; + ProxyType m_ProxyType; std::string m_ProxyAddress; uint16_t m_ProxyPort; boost::asio::ip::tcp::resolver m_Resolver; diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 9711ffb0..ae94553c 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -1193,7 +1193,6 @@ namespace transport void NTCPServer::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) { - // build request size_t sz = 0; uint8_t buff[256]; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 804f26cb..bb74e2ad 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -176,7 +176,7 @@ namespace transport if (proxyurl.schema == "http") proxytype = NTCPServer::eHTTPProxy; - m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; + m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port); m_NTCPServer->Start(); if(!m_NTCPServer->NetworkIsReady()) { @@ -194,7 +194,7 @@ namespace transport return; } // create NTCP2. TODO: move to acceptor - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { if(!ntcp2proxy.empty()) @@ -209,7 +209,7 @@ namespace transport if (proxyurl.schema == "http") proxytype = NTCP2Server::eHTTPProxy; - m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; + m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port); m_NTCP2Server->Start(); } else @@ -424,36 +424,36 @@ namespace transport { if (peer.router) // we have RI already { - if (!peer.numAttempts) // NTCP2 - { - peer.numAttempts++; - if (m_NTCP2Server) // we support NTCP2 - { - // NTCP2 have priority over NTCP - auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address) - { - auto s = std::make_shared (*m_NTCP2Server, peer.router); + if (!peer.numAttempts) // NTCP2 + { + peer.numAttempts++; + if (m_NTCP2Server) // we support NTCP2 + { + // NTCP2 have priority over NTCP + auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only + if (address) + { + auto s = std::make_shared (*m_NTCP2Server, peer.router); - if(m_NTCP2Server->UsingProxy()) - { - NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address; - std::string addr = address->host.to_string(); + if(m_NTCP2Server->UsingProxy()) + { + NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address; + std::string addr = address->host.to_string(); - if(address->host.is_v6()) - remote = NTCP2Server::eIP6Address; + if(address->host.is_v6()) + remote = NTCP2Server::eIP6Address; - m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s); - } - else - m_NTCP2Server->Connect (address->host, address->port, s); - return true; - } - } - } + m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s); + } + else + m_NTCP2Server->Connect (address->host, address->port, s); + return true; + } + } + } if (peer.numAttempts == 1) // NTCP1 { - peer.numAttempts++; + peer.numAttempts++; auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); if (address && m_NTCPServer) { diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 9cb69590..a70ac2b7 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -118,7 +118,7 @@ namespace proxy boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method); boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); - boost::asio::const_buffers_1 GenerateUpstreamRequest(); + boost::asio::const_buffers_1 GenerateUpstreamRequest(); bool Socks5ChooseAuth(); void SocksRequestFailed(errTypes error); void SocksRequestSuccess(); @@ -128,27 +128,27 @@ namespace proxy void HandleStreamRequestComplete (std::shared_ptr stream); void ForwardSOCKS(); - void SocksUpstreamSuccess(); - void AsyncUpstreamSockRead(); - void SendUpstreamRequest(); + void SocksUpstreamSuccess(); + void AsyncUpstreamSockRead(); + void SendUpstreamRequest(); void HandleUpstreamData(uint8_t * buff, std::size_t len); - void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); - void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); - void HandleUpstreamConnected(const boost::system::error_code & ecode, + void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); + void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); + void HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); - void HandleUpstreamResolved(const boost::system::error_code & ecode, + void HandleUpstreamResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); - boost::asio::ip::tcp::resolver m_proxy_resolver; - uint8_t m_sock_buff[socks_buffer_size]; - std::shared_ptr m_sock, m_upstreamSock; + boost::asio::ip::tcp::resolver m_proxy_resolver; + uint8_t m_sock_buff[socks_buffer_size]; + std::shared_ptr m_sock, m_upstreamSock; std::shared_ptr m_stream; uint8_t *m_remaining_data; //Data left to be sent uint8_t *m_remaining_upstream_data; //upstream data left to be forwarded uint8_t m_response[7+max_socks_hostname_size]; - uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE]; - uint8_t m_upstream_request[14+max_socks_hostname_size]; - std::size_t m_upstream_response_len; + uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE]; + uint8_t m_upstream_request[14+max_socks_hostname_size]; + std::size_t m_upstream_response_len; address m_address; //Address std::size_t m_remaining_data_len; //Size of the data left to be sent uint32_t m_4aip; //Used in 4a requests @@ -161,11 +161,11 @@ namespace proxy cmdTypes m_cmd; // Command requested state m_state; const bool m_UseUpstreamProxy; // do we want to use the upstream proxy for non i2p addresses? - const std::string m_UpstreamProxyAddress; - const uint16_t m_UpstreamProxyPort; + const std::string m_UpstreamProxyAddress; + const uint16_t m_UpstreamProxyPort; public: - SOCKSHandler(SOCKSServer * parent, std::shared_ptr sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : + SOCKSHandler(SOCKSServer * parent, std::shared_ptr sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : I2PServiceHandler(parent), m_proxy_resolver(parent->GetService()), m_sock(sock), m_stream(nullptr), @@ -226,7 +226,7 @@ namespace proxy boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) { - size_t size = 6; + size_t size = 6; // header + port assert(error <= SOCKS5_ADDR_UNSUP); m_response[0] = '\x05'; //Version m_response[1] = error; //Response code @@ -235,15 +235,15 @@ namespace proxy switch (type) { case ADDR_IPV4: - size = 10; + size += 4; htobe32buf(m_response + 4, addr.ip); break; case ADDR_IPV6: - size = 22; + size += 16; memcpy(m_response + 4, addr.ipv6, 16); break; case ADDR_DNS: - size = 7 + addr.dns.size; + size += (1 + addr.dns.size); /* name length + domain name */ m_response[4] = addr.dns.size; memcpy(m_response + 5, addr.dns.value, addr.dns.size); // replace type to IPv4 for support socks5 clients From f5712c419848bd9c4ea27dfe66253ad8a6c61a1f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 04:59:05 +0300 Subject: [PATCH 0306/2950] remove not needed initialization for pointer Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e7c37fdd..4efcc92f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1148,7 +1148,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), - m_Resolver(GetService ()), m_ProxyType(eNoProxy), m_ProxyEndpoint(nullptr) + m_Resolver(GetService ()), m_ProxyType(eNoProxy) { } @@ -1412,7 +1412,7 @@ namespace transport if ((*it)->IsEstablished () || (*it)->IsTerminationTimeoutExpired (ts)) { (*it)->Terminate (); - it = m_PendingIncomingSessions.erase (it); // etsablished of expired + it = m_PendingIncomingSessions.erase (it); // established of expired } else if ((*it)->IsTerminated ()) it = m_PendingIncomingSessions.erase (it); // already terminated From c36747603681f3919a7ee26a2cb68a2adecbd968 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 30 Apr 2020 16:21:49 +0300 Subject: [PATCH 0307/2950] [webconsole] fix printing information about ECIESx25519 tags/sessions Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index bc1eccd5..8b0323ce 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -399,28 +399,36 @@ namespace http { } } s << "
\r\n"; - s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
"; + + s << "Tags
\r\nIncoming: " << 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 = out_tags + it.second->GetNumOutgoingTags (); + out_tags += it.second->GetNumOutgoingTags (); } s << "
\r\n\r\n" << "
\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; - auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); - if (numECIESx25519Tags > 0) - s << "Incoming ECIESx25519: " << numECIESx25519Tags << "
"; - if (!dest->GetECIESx25519Sessions ().empty ()) - { - s << "
\r\nECIESx25519Tags sessions
"; - for (const auto& it: dest->GetECIESx25519Sessions ()) - s << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) - << " " << it.second->GetState () << "
\r\n"; - } s << "
\r\n"; + + auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); + if (numECIESx25519Tags > 0) { + s << "ECIESx25519
\r\nIncoming Tags: " << numECIESx25519Tags << "
\r\n"; + if (!dest->GetECIESx25519Sessions ().empty ()) + { + std::stringstream tmp_s; uint32_t ecies_sessions = 0; + for (const auto& it: dest->GetECIESx25519Sessions ()) { + 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" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + } else + s << "Tags sessions: 0
\r\n"; + s << "
\r\n"; + } } void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token) From c4f9f7da06123b678b40271d528697a78baf1e23 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Apr 2020 13:45:26 -0400 Subject: [PATCH 0308/2950] fixed warning --- libi2pd/NTCP2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 4efcc92f..2091b373 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1148,7 +1148,7 @@ namespace transport NTCP2Server::NTCP2Server (): RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), - m_Resolver(GetService ()), m_ProxyType(eNoProxy) + m_ProxyType(eNoProxy), m_Resolver(GetService ()) { } From 17e69e67b1391705e44348599524632ba44cf4d9 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Apr 2020 15:38:15 -0400 Subject: [PATCH 0309/2950] create additional tags for NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 025340c8..56fc5948 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -600,14 +600,11 @@ namespace garlic #endif case eSessionStateEstablished: if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; - if (index < ECIESX25519_NSR_NUM_GENERATED_TAGS) - { - // check NSR just in case - LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); - return HandleNewOutgoingSessionReply (buf, len); - } - else - return false; + // check NSR just in case + LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); + if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2) + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS); + return HandleNewOutgoingSessionReply (buf, len); case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: @@ -620,12 +617,12 @@ namespace garlic std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { - 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 auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); size_t len = payload.size (); - + auto m = NewI2NPMessage (len + 100); // 96 + 4 + m->Align (12); // in order to get buf aligned to 16 (12 + 4) + uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length + switch (m_State) { case eSessionStateEstablished: From ec4e17f75c0109bcb3a0d70ff67b98e10ef2368f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Apr 2020 21:27:35 -0400 Subject: [PATCH 0310/2950] cleanup previous tagsets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 21 +++++++++++++-------- libi2pd/Garlic.cpp | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 56fc5948..788d4d6d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -78,6 +78,12 @@ namespace garlic LogPrint (eLogError, "Garlic: Missing symmetric key for index ", index); } } + + void RatchetTagSet::Expire () + { + if (!m_ExpirationTimestamp) + m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; + } ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) @@ -311,7 +317,8 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } } @@ -608,6 +615,7 @@ namespace garlic case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: + receiveTagset->Expire (); // NSR tagset return HandleNewOutgoingSessionReply (buf, len); default: return false; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 6dd842e4..cf4eb3d7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -17,6 +17,15 @@ namespace i2p { namespace garlic { + const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after + const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after + const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; + const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; + class ECIESX25519AEADRatchetSession; class RatchetTagSet { @@ -34,6 +43,9 @@ namespace garlic std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; + + void Expire (); + bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; private: @@ -52,6 +64,7 @@ namespace garlic std::unordered_map > m_ItermediateSymmKeys; std::weak_ptr m_Session; int m_TagSetID = 0; + uint64_t m_ExpirationTimestamp = 0; }; enum ECIESx25519BlockType @@ -71,14 +84,6 @@ namespace garlic const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02; const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; - const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after - const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds - const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after - const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; - const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; - const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; - class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this { enum SessionState diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index fe5e8d69..fb3451d0 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -788,7 +788,7 @@ namespace garlic // ECIESx25519 for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { - if (ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) + if (it->second.tagset->IsExpired (ts) || ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) it = m_ECIESx25519Tags.erase (it); else ++it; From d48db501e03a81685e3419186f7831107df8e716 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 May 2020 07:33:05 -0400 Subject: [PATCH 0311/2950] max payload is always 1730 --- libi2pd/Streaming.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3efcfb99..3214e81b 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -505,7 +505,7 @@ namespace stream memset (signature, 0, signatureLen); // zeroes for now size += signatureLen; // signature htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size - size += m_SendBuffer.Get (packet + size, STREAMING_MTU - size); // payload + size += m_SendBuffer.Get (packet + size, STREAMING_MTU); // payload m_LocalDestination.GetOwner ()->Sign (packet, size, signature); } else @@ -515,7 +515,7 @@ namespace stream size += 2; // flags htobuf16 (packet + size, 0); // no options size += 2; // options size - size += m_SendBuffer.Get(packet + size, STREAMING_MTU - size); // payload + size += m_SendBuffer.Get(packet + size, STREAMING_MTU); // payload } p->len = size; packets.push_back (p); From c49e544781fc615879fd51d68bb338e9ec6afcab Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 May 2020 14:30:56 -0400 Subject: [PATCH 0312/2950] allow longer families --- libi2pd/Family.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index b7cbf7d4..bc99bb52 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -113,9 +113,9 @@ namespace data bool Families::VerifyFamily (const std::string& family, const IdentHash& ident, const char * signature, const char * key) { - uint8_t buf[50], signatureBuf[64]; + uint8_t buf[100], signatureBuf[64]; size_t len = family.length (), signatureLen = strlen (signature); - if (len + 32 > 50) + if (len + 32 > 100) { LogPrint (eLogError, "Family: ", family, " is too long"); return false; From e301387896cec0f8a30753adc7ab86d248879f79 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 May 2020 11:13:40 -0400 Subject: [PATCH 0313/2950] don't calculate checsum for Data message send through ECIESX25519AEADRatchet session --- libi2pd/ECIESX25519AEADRatchetSession.h | 2 ++ libi2pd/Garlic.h | 1 + libi2pd/I2NPProtocol.cpp | 4 ++-- libi2pd/I2NPProtocol.h | 2 +- libi2pd/Streaming.cpp | 10 ++++++---- libi2pd/Streaming.h | 7 +++---- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cf4eb3d7..79e920b5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -122,6 +122,8 @@ namespace garlic bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } + bool IsRatchets () const { return true; }; + private: void ResetKeys (); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 2c71abe8..6c81dabf 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -105,6 +105,7 @@ namespace garlic virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); + virtual bool IsRatchets () const { return false; }; void SetLeaseSetUpdated () { diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 0e7c245e..933fa707 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -39,14 +39,14 @@ namespace i2p return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); } - void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) + void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum) { SetTypeID (msgType); if (!replyMsgID) RAND_bytes ((uint8_t *)&replyMsgID, 4); SetMsgID (replyMsgID); SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT); UpdateSize (); - UpdateChks (); + if (checksum) UpdateChks (); } void I2NPMessage::RenewI2NPMessageHeader () diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 2fca1538..c8957b5f 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -218,7 +218,7 @@ namespace tunnel memcpy (ntcp2 + I2NP_HEADER_TYPEID_OFFSET, GetHeader () + I2NP_HEADER_TYPEID_OFFSET, 5); // typeid + msgid } - void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0); + void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0, bool checksum = true); void RenewI2NPMessageHeader (); bool IsExpired () const; }; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3214e81b..6b547170 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -756,7 +756,8 @@ namespace stream std::vector msgs; for (auto it: packets) { - auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage (it->GetBuffer (), it->GetLength (), m_Port)); + auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage ( + it->GetBuffer (), it->GetLength (), m_Port, !m_RoutingSession->IsRatchets ())); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, @@ -1207,9 +1208,10 @@ namespace stream DeletePacket (uncompressed); } - std::shared_ptr StreamingDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort) + std::shared_ptr StreamingDestination::CreateDataMessage ( + const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { - auto msg = NewI2NPShortMessage (); + auto msg = m_I2NPMsgsPool.AcquireShared (); if (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE) m_Deflator.SetCompressionLevel (Z_NO_COMPRESSION); else @@ -1225,7 +1227,7 @@ namespace stream htobe16buf (buf + 6, toPort); // destination port buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol msg->len += size; - msg->FillI2NPMessageHeader (eI2NPData); + msg->FillI2NPMessageHeader (eI2NPData, 0, checksum); } else msg = nullptr; diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 985a7eca..64e4c18d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -255,20 +255,18 @@ namespace stream void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; void AcceptOnce (const Acceptor& acceptor); + void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); std::shared_ptr GetOwner () const { return m_Owner; }; void SetOwner (std::shared_ptr owner) { m_Owner = owner; }; uint16_t GetLocalPort () const { return m_LocalPort; }; void HandleDataMessagePayload (const uint8_t * buf, size_t len); - std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort); + std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort, bool checksum = true); Packet * NewPacket () { return m_PacketsPool.Acquire(); } void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); } - - void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); - private: void HandleNextPacket (Packet * packet); @@ -289,6 +287,7 @@ namespace stream std::map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN i2p::util::MemoryPool m_PacketsPool; + i2p::util::MemoryPool > m_I2NPMsgsPool; public: From 1eead0e885d2fbeaa4f60aea1682eab895c85dff Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 May 2020 21:18:44 -0400 Subject: [PATCH 0314/2950] GzipNoCompression witout zlib calls --- libi2pd/Gzip.cpp | 15 +++++++++++++++ libi2pd/Gzip.h | 9 +++++++-- libi2pd/Streaming.cpp | 8 +++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 1c06e941..a03640a7 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -10,6 +10,7 @@ #include /* memset */ #include #include "Log.h" +#include "I2PEndian.h" #include "Gzip.h" namespace i2p @@ -111,5 +112,19 @@ namespace data LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; } + + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) + { + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x01 }; + if (outLen < (size_t)inLen + 23) return 0; + memcpy (out, gzipHeader, 11); + htole16buf (out + 11, inLen); + htole16buf (out + 13, 0xffff - inLen); + memcpy (out + 15, in, inLen); + htole32buf (out + inLen + 15, crc32 (0, in, inLen)); + htole32buf (out + inLen + 19, inLen); + return inLen + 23; + } + } // data } // i2p diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index 35661abe..cf08d920 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -3,8 +3,10 @@ #include -namespace i2p { -namespace data { +namespace i2p +{ +namespace data +{ class GzipInflator { public: @@ -38,6 +40,9 @@ namespace data { z_stream m_Deflator; bool m_IsDirty; }; + + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K + } // data } // i2p diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 6b547170..2a4175f4 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1212,14 +1212,12 @@ namespace stream const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { auto msg = m_I2NPMsgsPool.AcquireShared (); - if (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE) - m_Deflator.SetCompressionLevel (Z_NO_COMPRESSION); - else - m_Deflator.SetCompressionLevel (Z_DEFAULT_COMPRESSION); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for lengthlength msg->len += 4; - size_t size = m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); + 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 (size) { htobe32buf (msg->GetPayload (), size); // length From dff510c181469f4bd6d4d0063ea3f3cc376d8cf2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 3 May 2020 09:27:17 -0400 Subject: [PATCH 0315/2950] set best compression for RouterInfo --- libi2pd/Gzip.cpp | 5 ++++- libi2pd/I2NPProtocol.cpp | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index a03640a7..2ca711b0 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -107,7 +107,10 @@ namespace data m_Deflator.avail_out = outLen; int err; if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) + { + out[9] = 0xff; // OS is always unknown return outLen - m_Deflator.avail_out; + } // else LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; @@ -115,7 +118,7 @@ namespace data size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { - static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x01 }; + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 }; if (outLen < (size_t)inLen + 23) return 0; memcpy (out, gzipHeader, 11); htole16buf (out + 11, inLen); diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 933fa707..a16ce580 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -250,6 +250,7 @@ namespace i2p buf += 2; m->len += (buf - payload); // payload size i2p::data::GzipDeflator deflator; + deflator.SetCompressionLevel (Z_BEST_COMPRESSION); size_t size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); if (size) { From b7ba8f8e93a58dadf9eadfba3824149e5435bc82 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 3 May 2020 13:23:08 -0400 Subject: [PATCH 0316/2950] precalculate initial h and ck --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 788d4d6d..7fdf351e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -97,11 +97,18 @@ namespace garlic void ECIESX25519AEADRatchetSession::ResetKeys () { - // TODO : use precalculated hashes - static const char protocolName[41] = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"; // 40 bytes - SHA256 ((const uint8_t *)protocolName, 40, m_H); - memcpy (m_CK, m_H, 32); - SHA256 (m_H, 32, m_H); + static const uint8_t protocolNameHash[32] = + { + 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, + 0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c + }; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes + static const uint8_t hh[32] = + { + 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, + 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c + }; // SHA256 (protocolNameHash) + memcpy (m_CK, protocolNameHash, 32); + memcpy (m_H, hh, 32); } void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) From 4d48d35ad7901346a3a2936d3d6f5294bb69995f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 17 May 2019 10:28:58 +0300 Subject: [PATCH 0317/2950] [SSU] handle socket binding errors Signed-off-by: R4SAS --- libi2pd/NTCP2.cpp | 8 ++++---- libi2pd/NTCPSession.cpp | 7 ++++--- libi2pd/SSU.cpp | 28 +++++++++++++++++++--------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 2091b373..195f664f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1195,11 +1195,11 @@ namespace transport } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: Failed to bind to ip4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ",address->port, ex.what()); continue; } - LogPrint (eLogInfo, "NTCP2: Start listening TCP port ", address->port); + LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared(*this); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } @@ -1214,11 +1214,11 @@ namespace transport m_NTCP2V6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); m_NTCP2V6Acceptor->listen (); - LogPrint (eLogInfo, "NTCP2: Start listening V6 TCP port ", address->port); + LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: failed to bind to ip6 port ", address->port); + LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port); continue; } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index ae94553c..9fe5d415 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -820,9 +820,10 @@ namespace transport try { m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); + LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); } catch ( std::exception & ex ) { /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to ip4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP: Failed to bind to v4 port ",address->port, ex.what()); continue; } @@ -841,11 +842,11 @@ namespace transport m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); m_NTCPV6Acceptor->listen (); - LogPrint (eLogInfo, "NTCP: Start listening V6 TCP port ", address->port); + LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to ip6 port ", address->port); + LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port); continue; } } diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 4eb958de..f101443f 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -45,19 +45,29 @@ namespace transport void SSUServer::OpenSocket () { - m_Socket.open (boost::asio::ip::udp::v4()); - m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); - m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); - m_Socket.bind (m_Endpoint); + try { + m_Socket.open (boost::asio::ip::udp::v4()); + m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); + m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); + m_Socket.bind (m_Endpoint); + LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); + } catch ( std::exception & ex ) { + LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); + } } void SSUServer::OpenSocketV6 () { - m_SocketV6.open (boost::asio::ip::udp::v6()); - 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)); - m_SocketV6.bind (m_EndpointV6); + try { + m_SocketV6.open (boost::asio::ip::udp::v6()); + 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)); + m_SocketV6.bind (m_EndpointV6); + LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); + } catch ( std::exception & ex ) { + LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); + } } void SSUServer::Start () From d991cc3b96b2560bacaa27f6c55b8db17057a85c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 17 May 2019 11:04:44 +0300 Subject: [PATCH 0318/2950] [services] handle binding errors in tunnels, webconsole Signed-off-by: R4SAS --- daemon/Daemon.cpp | 2 +- daemon/HTTPServer.cpp | 13 +++++++++---- libi2pd_client/I2PService.cpp | 10 +++++++--- libi2pd_client/I2PTunnel.cpp | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 2c6b34d7..b0596634 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -317,7 +317,7 @@ namespace i2p bool http; i2p::config::GetOption("http.enabled", http); if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort); d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 8b0323ce..3104dba8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1226,10 +1226,15 @@ namespace http { i2p::config::SetOption("http.pass", pass); LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - m_IsRunning = true; - m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); - m_Acceptor.listen (); - Accept (); + + try { + m_IsRunning = true; + m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); + m_Acceptor.listen (); + Accept (); + } catch (std::exception& ex) { + LogPrint (eLogError, "HTTPServer: failed to start webconsole: ", ex.what ()); + } } void HTTPServer::Stop () diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 7157020f..c795fc5f 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -283,10 +283,14 @@ namespace client void TCPIPAcceptor::Start () { m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); - //update the local end point in case port has been set zero and got updated now + // update the local end point in case port has been set zero and got updated now m_LocalEndpoint = m_Acceptor->local_endpoint(); - m_Acceptor->listen (); - Accept (); + try { + m_Acceptor->listen (); + Accept (); + } catch (std::exception& ex) { + LogPrint (eLogError, "I2PService: failed to start ", GetName(), " acceptor: ", ex.what ()); + } } void TCPIPAcceptor::Stop () diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 290ce11e..b7487441 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -389,7 +389,7 @@ namespace client } - /* This handler tries to stablish a connection with the desired server and dies if it fails to do so */ + /* This handler tries to establish a connection with the desired server and dies if it fails to do so */ class I2PClientTunnelHandler: public I2PServiceHandler, public std::enable_shared_from_this { public: From 42d4781a9685266f489c6e509d614caf5352db77 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 5 May 2020 02:36:34 +0300 Subject: [PATCH 0319/2950] [windows] add binding exceptions messagebox notifications, update exceptions handling code Signed-off-by: R4SAS --- Win32/Win32App.cpp | 3 +- daemon/Daemon.cpp | 41 +++++++----- daemon/HTTPServer.cpp | 12 ++-- libi2pd/Log.h | 43 ++++++++++++ libi2pd/NTCP2.cpp | 10 ++- libi2pd/NTCPSession.cpp | 10 ++- libi2pd/SSU.cpp | 14 ++-- libi2pd_client/ClientContext.cpp | 108 ++++++++++++++++--------------- libi2pd_client/I2PService.cpp | 16 ++--- 9 files changed, 160 insertions(+), 97 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index dd614df2..7ae4e419 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -432,7 +432,7 @@ namespace win32 HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); if (hWnd) PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); - UnSubscribeFromEvents(); + // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); } @@ -451,6 +451,5 @@ namespace win32 PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); return hWnd; } - } } diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index b0596634..75829ef6 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -71,18 +71,13 @@ namespace i2p i2p::fs::Init(); datadir = i2p::fs::GetDataDir(); - // TODO: drop old name detection in v2.8.0 + if (config == "") { - config = i2p::fs::DataDirPath("i2p.conf"); - if (i2p::fs::Exists (config)) { - LogPrint(eLogWarning, "Daemon: please rename i2p.conf to i2pd.conf here: ", config); - } else { - config = i2p::fs::DataDirPath("i2pd.conf"); - if (!i2p::fs::Exists (config)) { - // use i2pd.conf only if exists - config = ""; /* reset */ - } + config = i2p::fs::DataDirPath("i2pd.conf"); + if (!i2p::fs::Exists (config)) { + // use i2pd.conf only if exists + config = ""; /* reset */ } } @@ -265,7 +260,7 @@ namespace i2p restricted = idents.size() > 0; } if(!restricted) - LogPrint(eLogError, "Daemon: no trusted routers of families specififed"); + LogPrint(eLogError, "Daemon: no trusted routers of families specified"); } bool hidden; i2p::config::GetOption("trust.hidden", hidden); @@ -318,9 +313,16 @@ namespace i2p if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - LogPrint(eLogInfo, "Daemon: starting HTTP Server at ", httpAddr, ":", httpPort); - d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); - d.httpServer->Start(); + LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); + try { + d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); + d.httpServer->Start(); + } catch (std::exception& ex) { + LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); +#endif + } } @@ -336,8 +338,15 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); - d.m_I2PControlService->Start (); + try { + d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); + d.m_I2PControlService->Start (); + } catch (std::exception& ex) { + LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); +#endif + } } return true; } diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 3104dba8..a1cba3ce 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1227,14 +1227,10 @@ namespace http { LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - try { - m_IsRunning = true; - m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); - m_Acceptor.listen (); - Accept (); - } catch (std::exception& ex) { - LogPrint (eLogError, "HTTPServer: failed to start webconsole: ", ex.what ()); - } + m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); + m_Acceptor.listen (); + Accept (); + m_IsRunning = true; } void HTTPServer::Stop () diff --git a/libi2pd/Log.h b/libi2pd/Log.h index ba10b5e9..8343e3b3 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -23,6 +23,11 @@ #include #endif +#ifdef WIN32_APP +#include +#include "Win32/Win32App.h" +#endif + enum LogLevel { eLogNone = 0, @@ -197,4 +202,42 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept log.Append(msg); } +#ifdef WIN32_APP +/** + * @brief Show message box for user with message in it + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +{ + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (!hWnd) hWnd = NULL; + + UINT uType; + switch (level) { + case eLogError : + case eLogWarning : + uType = MB_ICONWARNING; + break; + case eLogNone : + case eLogInfo : + case eLogDebug : + default : + uType = MB_ICONINFORMATION; + break; + } + MessageBox( hWnd, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +} +#endif // WIN32_APP + #endif // LOG_H__ diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 195f664f..dba73e50 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1195,7 +1195,10 @@ namespace transport } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ", address->port, ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); +#endif continue; } @@ -1218,7 +1221,10 @@ namespace transport auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port); + LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port, ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); +#endif continue; } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 9fe5d415..fe420ac6 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -823,7 +823,10 @@ namespace transport LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); } catch ( std::exception & ex ) { /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to v4 port ",address->port, ex.what()); + LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); +#endif continue; } @@ -846,7 +849,10 @@ namespace transport auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port); + LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); +#endif continue; } } diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f101443f..ae2caf62 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -53,6 +53,9 @@ namespace transport LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); } catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); +#endif } } @@ -67,6 +70,9 @@ namespace transport LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); } catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); +#endif } } @@ -197,7 +203,7 @@ namespace transport m_SocketV6.close (); OpenSocketV6 (); ReceiveV6 (); - } + } } } } @@ -580,7 +586,7 @@ namespace transport { return session->GetState () == eSessionStateEstablished && session != excluded; } - ); + ); } template @@ -604,7 +610,7 @@ namespace transport { return session->GetState () == eSessionStateEstablished && session != excluded; } - ); + ); } std::set SSUServer::FindIntroducers (int maxNumIntroducers) @@ -620,7 +626,7 @@ namespace transport session->GetState () == eSessionStateEstablished && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION; } - ); + ); if (session) { ret.insert (session.get ()); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index fa0532c3..1e8b23cb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -58,14 +58,14 @@ namespace client uint16_t samPort; i2p::config::GetOption("sam.port", samPort); bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try - { + try { m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); - m_SamBridge->Start (); - } - catch (std::exception& e) - { - LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); + m_SamBridge->Start (); + } catch (std::exception& e) { + LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); +#endif } } @@ -76,10 +76,13 @@ namespace client uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort); LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort); try { - m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); - m_BOBCommandChannel->Start (); + m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); + m_BOBCommandChannel->Start (); } catch (std::exception& e) { - LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); + LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); +#endif } } @@ -90,14 +93,14 @@ namespace client std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); - try - { + try { m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer->Start (); - } - catch (std::exception& e) - { + } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); +#endif } } @@ -501,16 +504,12 @@ namespace client LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); } - void ClientContext::ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels) { boost::property_tree::ptree pt; - try - { + try { boost::property_tree::read_ini (tunConf, pt); - } - catch (std::exception& ex) - { + } catch (std::exception& ex) { LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ()); return; } @@ -565,14 +564,11 @@ namespace client // TODO: hostnames boost::asio::ip::udp::endpoint end(boost::asio::ip::address::from_string(address), port); if (!localDestination) - { localDestination = m_SharedLocalDestination; - } + auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort); if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second) - { clientTunnel->Start(); - } else LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists"); @@ -598,7 +594,10 @@ namespace client } else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) { - LogPrint(eLogError, "Clients: I2P Client tunnel websocks is deprecated"); + LogPrint(eLogWarning, "Clients: I2P Client tunnel websocks is deprecated, not starting ", name, " tunnel"); +#ifdef WIN32_APP + ShowMessageBox (eLogWarning, "Skipped websocks tunnel ", name, " because it's support is discontinued."); +#endif continue; } else @@ -608,6 +607,7 @@ namespace client clientTunnel = tun; clientEndpoint = tun->GetLocalEndpoint (); } + uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); if(timeout) { @@ -657,8 +657,8 @@ namespace client // I2CP std::map options; - ReadI2CPOptions (section, options); - + ReadI2CPOptions (section, options); + std::shared_ptr localDestination = nullptr; i2p::data::PrivateKeys k; if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) @@ -745,12 +745,14 @@ namespace client } else - LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf); - + LogPrint (eLogWarning, "Clients: Unknown section type = ", type, " of ", name, " in ", tunConf); } catch (std::exception& ex) { LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start tunnel ", name, ": ", ex.what ()); +#endif } } } @@ -761,12 +763,12 @@ namespace client bool httproxy; i2p::config::GetOption("httpproxy.enabled", httproxy); if (httproxy) { - std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); - std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); - uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); - i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); - std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); - bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); + std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); + std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); + uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); + i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); + std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); + bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort); if (httpProxyKeys.length () > 0) { @@ -781,14 +783,14 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try - { + try { m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); - } - catch (std::exception& e) - { + } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); +#endif } } } @@ -799,13 +801,13 @@ namespace client bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy); if (socksproxy) { - std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); - std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); - uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort); - bool socksOutProxy; i2p::config::GetOption("socksproxy.outproxy.enabled", socksOutProxy); - std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr); - uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort); - i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType); + std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); + std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); + uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort); + bool socksOutProxy; i2p::config::GetOption("socksproxy.outproxy.enabled", socksOutProxy); + std::string socksOutProxyAddr; i2p::config::GetOption("socksproxy.outproxy", socksOutProxyAddr); + uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort); + i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType); LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort); if (socksProxyKeys.length () > 0) { @@ -820,15 +822,15 @@ namespace client else LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key"); } - try - { + try { m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination); m_SocksProxy->Start(); - } - catch (std::exception& e) - { + } catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); +#ifdef WIN32_APP + ShowMessageBox (eLogError, "Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); +#endif } } } diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index c795fc5f..31f34710 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -84,7 +84,7 @@ namespace client auto itr = m_ReadyCallbacks.begin(); while(itr != m_ReadyCallbacks.end()) { - if(itr->second != NEVER_TIMES_OUT && now >= itr->second) + if(itr->second != NEVER_TIMES_OUT && now >= itr->second) { itr->first(boost::asio::error::timed_out); itr = m_ReadyCallbacks.erase(itr); @@ -94,9 +94,9 @@ namespace client } } if(!ec && m_ReadyCallbacks.size()) - TriggerReadyCheckTimer(); + TriggerReadyCheckTimer(); else - m_ReadyTimerTriggered = false; + m_ReadyTimerTriggered = false; } void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) { @@ -118,7 +118,7 @@ namespace client AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) { if(ec) { - LogPrint(eLogWarning, "I2PService::CeateStream() ", ec.message()); + LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message()); streamRequestComplete(nullptr); } else @@ -285,12 +285,8 @@ namespace client m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); // update the local end point in case port has been set zero and got updated now m_LocalEndpoint = m_Acceptor->local_endpoint(); - try { - m_Acceptor->listen (); - Accept (); - } catch (std::exception& ex) { - LogPrint (eLogError, "I2PService: failed to start ", GetName(), " acceptor: ", ex.what ()); - } + m_Acceptor->listen (); + Accept (); } void TCPIPAcceptor::Stop () From b19755644764d6016893363e3bce11cd1e5eef98 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 08:11:01 -0400 Subject: [PATCH 0320/2950] remove dependency from Win32App --- libi2pd/Log.h | 479 +++++++++++++++++++++++++------------------------- 1 file changed, 236 insertions(+), 243 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 8343e3b3..2737d5ed 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,243 +1,236 @@ -/* -* Copyright (c) 2013-2016, 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 LOG_H__ -#define LOG_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Queue.h" - -#ifndef _WIN32 -#include -#endif - -#ifdef WIN32_APP -#include -#include "Win32/Win32App.h" -#endif - -enum LogLevel -{ - eLogNone = 0, - eLogError, - eLogWarning, - eLogInfo, - eLogDebug, - eNumLogLevels -}; - -enum LogType { - eLogStdout = 0, - eLogStream, - eLogFile, -#ifndef _WIN32 - eLogSyslog, -#endif -}; - -namespace i2p { -namespace log { - - struct LogMsg; /* forward declaration */ - - class Log - { - private: - - enum LogType m_Destination; - enum LogLevel m_MinLevel; - std::shared_ptr m_LogStream; - std::string m_Logfile; - std::time_t m_LastTimestamp; - char m_LastDateTime[64]; - i2p::util::Queue > m_Queue; - bool m_HasColors; - std::string m_TimeFormat; - volatile bool m_IsRunning; - std::thread * m_Thread; - - private: - - /** prevent making copies */ - Log (const Log &); - const Log& operator=(const Log&); - - void Run (); - void Process (std::shared_ptr msg); - - /** - * @brief Makes formatted string from unix timestamp - * @param ts Second since epoch - * - * This function internally caches the result for last provided value - */ - const char * TimeAsString(std::time_t ts); - - public: - - Log (); - ~Log (); - - LogType GetLogType () { return m_Destination; }; - LogLevel GetLogLevel () { return m_MinLevel; }; - - void Start (); - void Stop (); - - /** - * @brief Sets minimal allowed level for log messages - * @param level String with wanted minimal msg level - */ - void SetLogLevel (const std::string& level); - - /** - * @brief Sets log destination to logfile - * @param path Path to logfile - */ - void SendTo (const std::string &path); - - /** - * @brief Sets log destination to given output stream - * @param os Output stream - */ - void SendTo (std::shared_ptr os); - - /** - * @brief Sets format for timestamps in log - * @param format String with timestamp format - */ - void SetTimeFormat (std::string format) { m_TimeFormat = format; }; - - #ifndef _WIN32 - /** - * @brief Sets log destination to syslog - * @param name Wanted program name - * @param facility Wanted log category - */ - void SendTo (const char *name, int facility); - #endif - - /** - * @brief Format log message and write to output stream/syslog - * @param msg Pointer to processed message - */ - void Append(std::shared_ptr &); - - /** @brief Reopen log file */ - void Reopen(); - }; - - /** - * @struct LogMsg - * @brief Log message container - * - * We creating it somewhere with LogPrint(), - * then put in MsgQueue for later processing. - */ - struct LogMsg { - std::time_t timestamp; - std::string text; /**< message text as single string */ - LogLevel level; /**< message level */ - std::thread::id tid; /**< id of thread that generated message */ - - LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; - }; - - Log & Logger(); -} // log -} - -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg) noexcept -{ - s << std::forward(arg); -} - -#if (__cplusplus < 201703L) // below C++ 17 -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept -{ - LogPrint (s, std::forward(arg)); - LogPrint (s, std::forward(args)...); -} -#endif - -/** - * @brief Create log message and send it to queue - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void LogPrint (LogLevel level, TArgs&&... args) noexcept -{ - i2p::log::Log &log = i2p::log::Logger(); - if (level > log.GetLogLevel ()) - return; - - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - auto msg = std::make_shared(level, std::time(nullptr), ss.str()); - msg->tid = std::this_thread::get_id(); - log.Append(msg); -} - -#ifdef WIN32_APP -/** - * @brief Show message box for user with message in it - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept -{ - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (!hWnd) hWnd = NULL; - - UINT uType; - switch (level) { - case eLogError : - case eLogWarning : - uType = MB_ICONWARNING; - break; - case eLogNone : - case eLogInfo : - case eLogDebug : - default : - uType = MB_ICONINFORMATION; - break; - } - MessageBox( hWnd, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); -} -#endif // WIN32_APP - -#endif // LOG_H__ +/* +* Copyright (c) 2013-2016, 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 LOG_H__ +#define LOG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Queue.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef WIN32_APP +#include // TODO: move away to win32app +#endif + +enum LogLevel +{ + eLogNone = 0, + eLogError, + eLogWarning, + eLogInfo, + eLogDebug, + eNumLogLevels +}; + +enum LogType { + eLogStdout = 0, + eLogStream, + eLogFile, +#ifndef _WIN32 + eLogSyslog, +#endif +}; + +namespace i2p { +namespace log { + + struct LogMsg; /* forward declaration */ + + class Log + { + private: + + enum LogType m_Destination; + enum LogLevel m_MinLevel; + std::shared_ptr m_LogStream; + std::string m_Logfile; + std::time_t m_LastTimestamp; + char m_LastDateTime[64]; + i2p::util::Queue > m_Queue; + bool m_HasColors; + std::string m_TimeFormat; + volatile bool m_IsRunning; + std::thread * m_Thread; + + private: + + /** prevent making copies */ + Log (const Log &); + const Log& operator=(const Log&); + + void Run (); + void Process (std::shared_ptr msg); + + /** + * @brief Makes formatted string from unix timestamp + * @param ts Second since epoch + * + * This function internally caches the result for last provided value + */ + const char * TimeAsString(std::time_t ts); + + public: + + Log (); + ~Log (); + + LogType GetLogType () { return m_Destination; }; + LogLevel GetLogLevel () { return m_MinLevel; }; + + void Start (); + void Stop (); + + /** + * @brief Sets minimal allowed level for log messages + * @param level String with wanted minimal msg level + */ + void SetLogLevel (const std::string& level); + + /** + * @brief Sets log destination to logfile + * @param path Path to logfile + */ + void SendTo (const std::string &path); + + /** + * @brief Sets log destination to given output stream + * @param os Output stream + */ + void SendTo (std::shared_ptr os); + + /** + * @brief Sets format for timestamps in log + * @param format String with timestamp format + */ + void SetTimeFormat (std::string format) { m_TimeFormat = format; }; + + #ifndef _WIN32 + /** + * @brief Sets log destination to syslog + * @param name Wanted program name + * @param facility Wanted log category + */ + void SendTo (const char *name, int facility); + #endif + + /** + * @brief Format log message and write to output stream/syslog + * @param msg Pointer to processed message + */ + void Append(std::shared_ptr &); + + /** @brief Reopen log file */ + void Reopen(); + }; + + /** + * @struct LogMsg + * @brief Log message container + * + * We creating it somewhere with LogPrint(), + * then put in MsgQueue for later processing. + */ + struct LogMsg { + std::time_t timestamp; + std::string text; /**< message text as single string */ + LogLevel level; /**< message level */ + std::thread::id tid; /**< id of thread that generated message */ + + LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; + }; + + Log & Logger(); +} // log +} + +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg) noexcept +{ + s << std::forward(arg); +} + +#if (__cplusplus < 201703L) // below C++ 17 +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept +{ + LogPrint (s, std::forward(arg)); + LogPrint (s, std::forward(args)...); +} +#endif + +/** + * @brief Create log message and send it to queue + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void LogPrint (LogLevel level, TArgs&&... args) noexcept +{ + i2p::log::Log &log = i2p::log::Logger(); + if (level > log.GetLogLevel ()) + return; + + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + auto msg = std::make_shared(level, std::time(nullptr), ss.str()); + msg->tid = std::this_thread::get_id(); + log.Append(msg); +} + +#ifdef WIN32_APP +/** + * @brief Show message box for user with message in it + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +{ + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + UINT uType; + switch (level) + { + case eLogError : + case eLogWarning : + uType = MB_ICONWARNING; + break; + default : + uType = MB_ICONINFORMATION; + } + MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +} +#endif // WIN32_APP + +#endif // LOG_H__ From 53b43353eb121e5d4a091d7501ef905d7205269a Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 08:27:56 -0400 Subject: [PATCH 0321/2950] fixed formatting --- libi2pd/Log.h | 472 +++++++++++++++++++++++++------------------------- 1 file changed, 236 insertions(+), 236 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 2737d5ed..eb3ce327 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,236 +1,236 @@ -/* -* Copyright (c) 2013-2016, 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 LOG_H__ -#define LOG_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Queue.h" - -#ifndef _WIN32 -#include -#endif - -#ifdef WIN32_APP -#include // TODO: move away to win32app -#endif - -enum LogLevel -{ - eLogNone = 0, - eLogError, - eLogWarning, - eLogInfo, - eLogDebug, - eNumLogLevels -}; - -enum LogType { - eLogStdout = 0, - eLogStream, - eLogFile, -#ifndef _WIN32 - eLogSyslog, -#endif -}; - -namespace i2p { -namespace log { - - struct LogMsg; /* forward declaration */ - - class Log - { - private: - - enum LogType m_Destination; - enum LogLevel m_MinLevel; - std::shared_ptr m_LogStream; - std::string m_Logfile; - std::time_t m_LastTimestamp; - char m_LastDateTime[64]; - i2p::util::Queue > m_Queue; - bool m_HasColors; - std::string m_TimeFormat; - volatile bool m_IsRunning; - std::thread * m_Thread; - - private: - - /** prevent making copies */ - Log (const Log &); - const Log& operator=(const Log&); - - void Run (); - void Process (std::shared_ptr msg); - - /** - * @brief Makes formatted string from unix timestamp - * @param ts Second since epoch - * - * This function internally caches the result for last provided value - */ - const char * TimeAsString(std::time_t ts); - - public: - - Log (); - ~Log (); - - LogType GetLogType () { return m_Destination; }; - LogLevel GetLogLevel () { return m_MinLevel; }; - - void Start (); - void Stop (); - - /** - * @brief Sets minimal allowed level for log messages - * @param level String with wanted minimal msg level - */ - void SetLogLevel (const std::string& level); - - /** - * @brief Sets log destination to logfile - * @param path Path to logfile - */ - void SendTo (const std::string &path); - - /** - * @brief Sets log destination to given output stream - * @param os Output stream - */ - void SendTo (std::shared_ptr os); - - /** - * @brief Sets format for timestamps in log - * @param format String with timestamp format - */ - void SetTimeFormat (std::string format) { m_TimeFormat = format; }; - - #ifndef _WIN32 - /** - * @brief Sets log destination to syslog - * @param name Wanted program name - * @param facility Wanted log category - */ - void SendTo (const char *name, int facility); - #endif - - /** - * @brief Format log message and write to output stream/syslog - * @param msg Pointer to processed message - */ - void Append(std::shared_ptr &); - - /** @brief Reopen log file */ - void Reopen(); - }; - - /** - * @struct LogMsg - * @brief Log message container - * - * We creating it somewhere with LogPrint(), - * then put in MsgQueue for later processing. - */ - struct LogMsg { - std::time_t timestamp; - std::string text; /**< message text as single string */ - LogLevel level; /**< message level */ - std::thread::id tid; /**< id of thread that generated message */ - - LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; - }; - - Log & Logger(); -} // log -} - -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg) noexcept -{ - s << std::forward(arg); -} - -#if (__cplusplus < 201703L) // below C++ 17 -/** internal usage only -- folding args array to single string */ -template -void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept -{ - LogPrint (s, std::forward(arg)); - LogPrint (s, std::forward(args)...); -} -#endif - -/** - * @brief Create log message and send it to queue - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void LogPrint (LogLevel level, TArgs&&... args) noexcept -{ - i2p::log::Log &log = i2p::log::Logger(); - if (level > log.GetLogLevel ()) - return; - - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - auto msg = std::make_shared(level, std::time(nullptr), ss.str()); - msg->tid = std::this_thread::get_id(); - log.Append(msg); -} - -#ifdef WIN32_APP -/** - * @brief Show message box for user with message in it - * @param level Message level (eLogError, eLogInfo, ...) - * @param args Array of message parts - */ -template -void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept -{ - // fold message to single string - std::stringstream ss(""); - -#if (__cplusplus >= 201703L) // C++ 17 or higher - (LogPrint (ss, std::forward(args)), ...); -#else - LogPrint (ss, std::forward(args)...); -#endif - - UINT uType; - switch (level) - { - case eLogError : - case eLogWarning : - uType = MB_ICONWARNING; - break; - default : - uType = MB_ICONINFORMATION; - } - MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); -} -#endif // WIN32_APP - -#endif // LOG_H__ +/* +* Copyright (c) 2013-2016, 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 LOG_H__ +#define LOG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Queue.h" + +#ifndef _WIN32 +#include +#endif + +#ifdef WIN32_APP +#include // TODO: move away to win32app +#endif + +enum LogLevel +{ + eLogNone = 0, + eLogError, + eLogWarning, + eLogInfo, + eLogDebug, + eNumLogLevels +}; + +enum LogType { + eLogStdout = 0, + eLogStream, + eLogFile, +#ifndef _WIN32 + eLogSyslog, +#endif +}; + +namespace i2p { +namespace log { + + struct LogMsg; /* forward declaration */ + + class Log + { + private: + + enum LogType m_Destination; + enum LogLevel m_MinLevel; + std::shared_ptr m_LogStream; + std::string m_Logfile; + std::time_t m_LastTimestamp; + char m_LastDateTime[64]; + i2p::util::Queue > m_Queue; + bool m_HasColors; + std::string m_TimeFormat; + volatile bool m_IsRunning; + std::thread * m_Thread; + + private: + + /** prevent making copies */ + Log (const Log &); + const Log& operator=(const Log&); + + void Run (); + void Process (std::shared_ptr msg); + + /** + * @brief Makes formatted string from unix timestamp + * @param ts Second since epoch + * + * This function internally caches the result for last provided value + */ + const char * TimeAsString(std::time_t ts); + + public: + + Log (); + ~Log (); + + LogType GetLogType () { return m_Destination; }; + LogLevel GetLogLevel () { return m_MinLevel; }; + + void Start (); + void Stop (); + + /** + * @brief Sets minimal allowed level for log messages + * @param level String with wanted minimal msg level + */ + void SetLogLevel (const std::string& level); + + /** + * @brief Sets log destination to logfile + * @param path Path to logfile + */ + void SendTo (const std::string &path); + + /** + * @brief Sets log destination to given output stream + * @param os Output stream + */ + void SendTo (std::shared_ptr os); + + /** + * @brief Sets format for timestamps in log + * @param format String with timestamp format + */ + void SetTimeFormat (std::string format) { m_TimeFormat = format; }; + + #ifndef _WIN32 + /** + * @brief Sets log destination to syslog + * @param name Wanted program name + * @param facility Wanted log category + */ + void SendTo (const char *name, int facility); + #endif + + /** + * @brief Format log message and write to output stream/syslog + * @param msg Pointer to processed message + */ + void Append(std::shared_ptr &); + + /** @brief Reopen log file */ + void Reopen(); + }; + + /** + * @struct LogMsg + * @brief Log message container + * + * We creating it somewhere with LogPrint(), + * then put in MsgQueue for later processing. + */ + struct LogMsg { + std::time_t timestamp; + std::string text; /**< message text as single string */ + LogLevel level; /**< message level */ + std::thread::id tid; /**< id of thread that generated message */ + + LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; + }; + + Log & Logger(); +} // log +} + +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg) noexcept +{ + s << std::forward(arg); +} + +#if (__cplusplus < 201703L) // below C++ 17 +/** internal usage only -- folding args array to single string */ +template +void LogPrint (std::stringstream& s, TValue&& arg, TArgs&&... args) noexcept +{ + LogPrint (s, std::forward(arg)); + LogPrint (s, std::forward(args)...); +} +#endif + +/** + * @brief Create log message and send it to queue + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void LogPrint (LogLevel level, TArgs&&... args) noexcept +{ + i2p::log::Log &log = i2p::log::Logger(); + if (level > log.GetLogLevel ()) + return; + + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + auto msg = std::make_shared(level, std::time(nullptr), ss.str()); + msg->tid = std::this_thread::get_id(); + log.Append(msg); +} + +#ifdef WIN32_APP +/** + * @brief Show message box for user with message in it + * @param level Message level (eLogError, eLogInfo, ...) + * @param args Array of message parts + */ +template +void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +{ + // fold message to single string + std::stringstream ss(""); + +#if (__cplusplus >= 201703L) // C++ 17 or higher + (LogPrint (ss, std::forward(args)), ...); +#else + LogPrint (ss, std::forward(args)...); +#endif + + UINT uType; + switch (level) + { + case eLogError : + case eLogWarning : + uType = MB_ICONWARNING; + break; + default : + uType = MB_ICONINFORMATION; + } + MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +} +#endif // WIN32_APP + +#endif // LOG_H__ From bb7f03857c3b3c9d95f2a3a374d3d6e90167d138 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 09:35:41 -0400 Subject: [PATCH 0322/2950] ThrowFatal function --- libi2pd/Log.h | 25 +++++-------- libi2pd/NTCP2.cpp | 12 +++---- libi2pd/NTCPSession.cpp | 16 ++++----- libi2pd/SSU.cpp | 22 ++++++------ libi2pd_client/ClientContext.cpp | 62 ++++++++++++++++---------------- 5 files changed, 64 insertions(+), 73 deletions(-) diff --git a/libi2pd/Log.h b/libi2pd/Log.h index eb3ce327..88d5c4db 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -201,36 +201,27 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept log.Append(msg); } -#ifdef WIN32_APP + /** - * @brief Show message box for user with message in it - * @param level Message level (eLogError, eLogInfo, ...) + * @brief Throw fatal error message with the list of arguments * @param args Array of message parts */ template -void ShowMessageBox (LogLevel level, TArgs&&... args) noexcept +void ThrowFatal (TArgs&&... args) noexcept { // fold message to single string std::stringstream ss(""); - #if (__cplusplus >= 201703L) // C++ 17 or higher (LogPrint (ss, std::forward(args)), ...); #else LogPrint (ss, std::forward(args)...); #endif - UINT uType; - switch (level) - { - case eLogError : - case eLogWarning : - uType = MB_ICONWARNING; - break; - default : - uType = MB_ICONINFORMATION; - } - MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), uType | MB_TASKMODAL | MB_OK ); +#ifdef WIN32_APP + MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); +#else + std::cout << ss.str (); +#endif } -#endif // WIN32_APP #endif // LOG_H__ diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index dba73e50..e52f0111 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1196,9 +1196,7 @@ namespace transport catch ( std::exception & ex ) { LogPrint(eLogError, "NTCP2: Failed to bind to v4 port ", address->port, ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv4 NTCP2 transport at port ", address->port, ": ", ex.what ()); continue; } @@ -1220,11 +1218,11 @@ namespace transport LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port, ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); continue; } } diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index fe420ac6..4ab3c5d0 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -821,12 +821,12 @@ namespace transport { m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { /** fail to bind ip4 */ LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); continue; } @@ -848,11 +848,11 @@ namespace transport LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); -#endif + ThrowFatal (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); continue; } } diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index ae2caf62..74cbe39b 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -45,34 +45,36 @@ namespace transport void SSUServer::OpenSocket () { - try { + try + { m_Socket.open (boost::asio::ip::udp::v4()); m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_Socket.bind (m_Endpoint); LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); } } void SSUServer::OpenSocketV6 () { - try { + try + { m_SocketV6.open (boost::asio::ip::udp::v6()); 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)); m_SocketV6.bind (m_EndpointV6); LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); - } catch ( std::exception & ex ) { + } + catch ( std::exception & ex ) + { LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); } } diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 1e8b23cb..c8a9ddfe 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -58,14 +58,15 @@ namespace client uint16_t samPort; i2p::config::GetOption("sam.port", samPort); bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try { + try + { m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); m_SamBridge->Start (); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); } } @@ -75,14 +76,15 @@ namespace client std::string bobAddr; i2p::config::GetOption("bob.address", bobAddr); uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort); LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort); - try { + try + { m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); m_BOBCommandChannel->Start (); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); } } @@ -93,14 +95,15 @@ namespace client std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); - try { + try + { m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer->Start (); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); } } @@ -595,9 +598,6 @@ namespace client else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) { LogPrint(eLogWarning, "Clients: I2P Client tunnel websocks is deprecated, not starting ", name, " tunnel"); -#ifdef WIN32_APP - ShowMessageBox (eLogWarning, "Skipped websocks tunnel ", name, " because it's support is discontinued."); -#endif continue; } else @@ -750,9 +750,7 @@ namespace client catch (std::exception& ex) { LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start tunnel ", name, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start tunnel ", name, ": ", ex.what ()); } } } @@ -783,14 +781,15 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try { + try + { m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); } } } @@ -822,15 +821,16 @@ namespace client else LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key"); } - try { + try + { m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination); m_SocksProxy->Start(); - } catch (std::exception& e) { + } + catch (std::exception& e) + { LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); -#endif + ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); } } } From dbe1e3f577c05d3fe0c6a50ceacc26d2b8e9daff Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 10:16:16 -0400 Subject: [PATCH 0323/2950] ThrowFatal function --- daemon/Daemon.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 75829ef6..fc71123f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -314,14 +314,15 @@ namespace i2p std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try { + try + { d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); - } catch (std::exception& ex) { + } + catch (std::exception& ex) + { LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } @@ -338,14 +339,15 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try { + try + { d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); - } catch (std::exception& ex) { + } + catch (std::exception& ex) + { LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); -#ifdef WIN32_APP - ShowMessageBox (eLogError, "Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); -#endif + ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); } } return true; From d7d70b707ffe0435c80b1d908a51b4047d94e741 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 11:13:59 -0400 Subject: [PATCH 0324/2950] configurable throw function --- Win32/DaemonWin32.cpp | 6 ++++++ libi2pd/Log.cpp | 6 ++++++ libi2pd/Log.h | 19 ++++++++----------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 9fffe7fb..5524aff3 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -8,6 +8,7 @@ #ifdef _WIN32 #include "Win32/Win32Service.h" #ifdef WIN32_APP +#include #include "Win32/Win32App.h" #endif @@ -23,6 +24,11 @@ namespace util setlocale(LC_ALL, "Russian"); setlocale(LC_TIME, "C"); + i2p::log::SetThrowFunction ([](const std::string& s) + { + MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); + }); + if (!Daemon_Singleton::init(argc, argv)) return false; diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 7d77aaf8..65602674 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -236,5 +236,11 @@ namespace log { Log & Logger() { return logger; } + + static ThrowFunction g_ThrowFunction; + ThrowFunction GetThrowFunction () { return g_ThrowFunction; } + void SetThrowFunction (ThrowFunction f) { g_ThrowFunction = f; } + } // log } // i2p + diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 88d5c4db..556654e2 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -17,16 +17,13 @@ #include #include #include +#include #include "Queue.h" #ifndef _WIN32 #include #endif -#ifdef WIN32_APP -#include // TODO: move away to win32app -#endif - enum LogLevel { eLogNone = 0, @@ -155,6 +152,10 @@ namespace log { }; Log & Logger(); + + typedef std::function ThrowFunction; + ThrowFunction GetThrowFunction (); + void SetThrowFunction (ThrowFunction f); } // log } @@ -201,7 +202,6 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept log.Append(msg); } - /** * @brief Throw fatal error message with the list of arguments * @param args Array of message parts @@ -209,6 +209,8 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept template void ThrowFatal (TArgs&&... args) noexcept { + auto f = i2p::log::GetThrowFunction (); + if (!f) return; // fold message to single string std::stringstream ss(""); #if (__cplusplus >= 201703L) // C++ 17 or higher @@ -216,12 +218,7 @@ void ThrowFatal (TArgs&&... args) noexcept #else LogPrint (ss, std::forward(args)...); #endif - -#ifdef WIN32_APP - MessageBox(0, TEXT(ss.str ().c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); -#else - std::cout << ss.str (); -#endif + f (ss.str ()); } #endif // LOG_H__ From c4d9c039300d94bb91279396dd4ccca363a481a6 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 May 2020 13:01:23 -0400 Subject: [PATCH 0325/2950] handle termination block --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 29 ++++++++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- libi2pd/Garlic.cpp | 9 +++++++ libi2pd/Garlic.h | 1 + 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7fdf351e..4c7d15ef 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -223,16 +223,8 @@ namespace garlic switch (blk) { case eECIESx25519BlkGalicClove: - GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); - break; - case eECIESx25519BlkDateTime: - LogPrint (eLogDebug, "Garlic: datetime"); - break; - case eECIESx25519BlkOptions: - LogPrint (eLogDebug, "Garlic: options"); - break; - case eECIESx25519BlkPadding: - LogPrint (eLogDebug, "Garlic: padding"); + if (GetOwner ()) + GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); break; case eECIESx25519BlkNextKey: LogPrint (eLogDebug, "Garlic: next key"); @@ -256,6 +248,21 @@ namespace garlic m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); break; } + case eECIESx25519BlkTermination: + LogPrint (eLogDebug, "Garlic: termination"); + if (GetOwner ()) + GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey); + if (receiveTagset) receiveTagset->Expire (); + break; + case eECIESx25519BlkDateTime: + LogPrint (eLogDebug, "Garlic: datetime"); + break; + case eECIESx25519BlkOptions: + LogPrint (eLogDebug, "Garlic: options"); + break; + case eECIESx25519BlkPadding: + LogPrint (eLogDebug, "Garlic: padding"); + break; default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } @@ -852,7 +859,7 @@ namespace garlic CleanupUnconfirmedLeaseSet (ts); return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; } - + std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) { auto m = NewI2NPMessage (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 79e920b5..29d75a6b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -21,7 +21,7 @@ namespace garlic const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 1024; // number of tags we request new tagset after + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 4096; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; @@ -110,7 +110,7 @@ namespace garlic bool HandleNextMessage (const uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - + const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index fb3451d0..8ba4a8a1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1013,5 +1013,14 @@ namespace garlic m_ECIESx25519Sessions.emplace (staticKeyTag, session); } + void GarlicDestination::RemoveECIESx25519Session (const uint8_t * staticKey) + { + auto it = m_ECIESx25519Sessions.find (staticKey); + if (it != m_ECIESx25519Sessions.end ()) + { + it->second->SetOwner (nullptr); + m_ECIESx25519Sessions.erase (it); + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6c81dabf..86c9e432 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -233,6 +233,7 @@ namespace garlic void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID); void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); + void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); virtual void ProcessGarlicMessage (std::shared_ptr msg); From d50319064794c011b3045bf586d513a08aeb09e2 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 May 2020 10:08:01 -0400 Subject: [PATCH 0326/2950] fixed crash of encrypted leaseset without authentication --- libi2pd/Destination.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 1473d41f..650ab04b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -415,7 +415,10 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - auto ls2 = std::make_shared (buf + offset, len - offset, it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? *m_LeaseSetPrivKey : nullptr, GetPreferredCryptoType ()); + const uint8_t * secret = nullptr; + if (m_LeaseSetPrivKey) secret = *m_LeaseSetPrivKey; // m_LeaseSetPrivKey ? *m_LeaseSetPrivKey: nullptr invokes copy contructor + auto ls2 = std::make_shared (buf + offset, len - offset, + it2->second->requestedBlindedKey, secret, GetPreferredCryptoType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key From 9b6facf3b01a1377577a959a5b3eab0895834911 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 May 2020 14:08:54 -0400 Subject: [PATCH 0327/2950] fixed crash of encrypted leaseset without authentication --- libi2pd/Destination.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 650ab04b..736390a2 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -415,10 +415,8 @@ namespace client auto it2 = m_LeaseSetRequests.find (key); if (it2 != m_LeaseSetRequests.end () && it2->second->requestedBlindedKey) { - const uint8_t * secret = nullptr; - if (m_LeaseSetPrivKey) secret = *m_LeaseSetPrivKey; // m_LeaseSetPrivKey ? *m_LeaseSetPrivKey: nullptr invokes copy contructor auto ls2 = std::make_shared (buf + offset, len - offset, - it2->second->requestedBlindedKey, secret, GetPreferredCryptoType ()); + it2->second->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr , GetPreferredCryptoType ()); if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key From 789ff702ac5eca7901c3a96a3d58e0af002b9f77 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 May 2020 14:54:41 -0400 Subject: [PATCH 0328/2950] fixed sudden webconsole hangs --- daemon/HTTPServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a1cba3ce..de052a2b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1227,10 +1227,10 @@ namespace http { LogPrint(eLogInfo, "HTTPServer: password set to ", pass); } - m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); + m_IsRunning = true; + m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); Accept (); - m_IsRunning = true; } void HTTPServer::Stop () From 24c5f07153216f14d7b57cd67b7984eed40e1f76 Mon Sep 17 00:00:00 2001 From: Anatolii Vorona Date: Thu, 7 May 2020 12:11:30 +0200 Subject: [PATCH 0329/2950] added logrotate config --- contrib/rpm/i2pd-git.spec | 16 +++++++++++----- contrib/rpm/i2pd.logrotate | 9 +++++++++ contrib/rpm/i2pd.spec | 14 ++++++++++---- 3 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 contrib/rpm/i2pd.logrotate diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index b182dca4..6844a25f 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -24,6 +24,7 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units +Requires: logrotate Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd @@ -73,10 +74,11 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -%{__install} -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd @@ -108,16 +110,20 @@ getent passwd i2pd >/dev/null || \ %files %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd -%config(noreplace) %{_sysconfdir}/i2pd/* +%config(noreplace) %{_sysconfdir}/i2pd/*.conf %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %{_datadir}/%{name}/certificates %{_sharedstatedir}/i2pd/certificates +%{_sysconfdir}/logrotate.d/i2pd %changelog +* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +- added RPM logrotate config + * Fri Apr 10 2020 orignal - 2.31.0 - update to 2.31.0 diff --git a/contrib/rpm/i2pd.logrotate b/contrib/rpm/i2pd.logrotate new file mode 100644 index 00000000..795280d4 --- /dev/null +++ b/contrib/rpm/i2pd.logrotate @@ -0,0 +1,9 @@ +"/var/log/i2pd/*.log" { + copytruncate + daily + rotate 5 + compress + delaycompress + missingok + notifempty +} diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5ece769c..bcbade2f 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.31.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -22,6 +22,7 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units +Requires: logrotate Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd @@ -71,8 +72,9 @@ pushd build chrpath -d i2pd install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd -install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf -install -D -m 755 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates @@ -107,15 +109,19 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md %{_sbindir}/i2pd %{_datadir}/i2pd/certificates -%config(noreplace) %{_sysconfdir}/i2pd/* +%config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* /%{_unitdir}/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %{_sharedstatedir}/i2pd/certificates +%{_sysconfdir}/logrotate.d/i2pd %changelog +* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +- added RPM logrotate config + * Fri Apr 10 2020 orignal - 2.31.0 - update to 2.31.0 From 9274881c183f689364fc8b9c0c3279aeb5d09398 Mon Sep 17 00:00:00 2001 From: Anatolii Vorona Date: Fri, 8 May 2020 18:45:28 +0200 Subject: [PATCH 0330/2950] update logrotate config for reusing in debian --- contrib/{rpm => }/i2pd.logrotate | 0 contrib/rpm/i2pd-git.spec | 6 +++--- contrib/rpm/i2pd.service | 1 - contrib/rpm/i2pd.spec | 8 ++++---- 4 files changed, 7 insertions(+), 8 deletions(-) rename contrib/{rpm => }/i2pd.logrotate (100%) delete mode 120000 contrib/rpm/i2pd.service diff --git a/contrib/rpm/i2pd.logrotate b/contrib/i2pd.logrotate similarity index 100% rename from contrib/rpm/i2pd.logrotate rename to contrib/i2pd.logrotate diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 6844a25f..6967f949 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -78,8 +78,8 @@ chrpath -d i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README -%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd -%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd @@ -121,7 +121,7 @@ getent passwd i2pd >/dev/null || \ %changelog -* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +* Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config * Fri Apr 10 2020 orignal - 2.31.0 diff --git a/contrib/rpm/i2pd.service b/contrib/rpm/i2pd.service deleted file mode 120000 index ca477e3b..00000000 --- a/contrib/rpm/i2pd.service +++ /dev/null @@ -1 +0,0 @@ -../i2pd.service \ No newline at end of file diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index bcbade2f..49a5e666 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.31.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -74,12 +74,12 @@ chrpath -d i2pd install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/rpm/i2pd.service %{buildroot}%{_unitdir}/i2pd.service +install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates @@ -119,7 +119,7 @@ getent passwd i2pd >/dev/null || \ %changelog -* Thu May 7 2020 Anatolii Vorona - 2.31.0-2 +* Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config * Fri Apr 10 2020 orignal - 2.31.0 From a96c205830734dfa80986ad4a50e17f09a5c549b Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 8 May 2020 14:20:13 -0400 Subject: [PATCH 0331/2950] allow encryption type param for encrypted LeaseSet --- libi2pd/Destination.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 736390a2..105cd2e6 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -845,7 +845,8 @@ namespace client // extract encryption type params for LS2 std::set encryptionKeyTypes; - if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 && params) + if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 || + GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) { auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE); if (it != params->end ()) From 86782f347986fba71321e68f41f37b67b91b9677 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 May 2020 18:30:04 -0400 Subject: [PATCH 0332/2950] eliminate extra buffer allocation for incoming packets --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 22 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4c7d15ef..bccf56f6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -178,8 +178,6 @@ namespace garlic MixHash (buf, 48); // h = SHA256(h || ciphertext) buf += 48; len -= 48; // 32 data + 16 poly - // decrypt payload - std::vector payload (len - 16); // KDF2 for payload bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); if (isStatic) @@ -191,6 +189,9 @@ namespace garlic } else // all zeros flags CreateNonce (1, nonce); + + // decrypt payload + std::vector payload (len - 16); // we must save original ciphertext if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); @@ -489,7 +490,7 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len) + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len) { // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); @@ -541,8 +542,7 @@ namespace garlic } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload - std::vector payload (len - 16); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; @@ -554,7 +554,7 @@ namespace garlic GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } memcpy (m_H, h, 32); // restore m_H - HandlePayload (payload.data (), len - 16, nullptr, 0); + HandlePayload (buf, len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it SetLeaseSetUpdateStatus (eLeaseSetUpToDate); @@ -584,21 +584,21 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (const uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { uint8_t nonce[12]; CreateNonce (index, nonce); // tag's index len -= 8; // tag - std::vector payload (len - 16); + uint8_t * payload = buf + 8; uint8_t key[32]; receiveTagset->GetSymmKey (index, key); - if (!i2p::crypto::AEADChaCha20Poly1305 (buf + 8, len - 16, buf, 8, key, nonce, payload.data (), len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len - 16, buf, 8, key, nonce, payload, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } - HandlePayload (payload.data (), len - 16, receiveTagset, index); + HandlePayload (payload, len - 16, receiveTagset, index); int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; moreTags -= (receiveTagset->GetNextIndex () - index); @@ -607,7 +607,7 @@ namespace garlic return true; } - bool ECIESX25519AEADRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 29d75a6b..001f5e51 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -108,7 +108,7 @@ namespace garlic ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); ~ECIESX25519AEADRatchetSession (); - bool HandleNextMessage (const uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); + bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } @@ -133,8 +133,8 @@ namespace garlic std::shared_ptr CreateNewSessionTagset (); bool HandleNewIncomingSession (const uint8_t * buf, size_t len); - bool HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len); - bool HandleExistingSessionMessage (const uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); + bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); + bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); From 23be4c01dfcc32d5d747e5ccce9a00526170ae3b Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 13 May 2020 18:09:26 -0400 Subject: [PATCH 0333/2950] CreateLeaseSetClove --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 51 ++++++++++------------- libi2pd/ECIESX25519AEADRatchetSession.h | 4 +- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index bccf56f6..4f4f56ce 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -684,10 +684,10 @@ namespace garlic if (first) payloadLen += 7;// datatime if (msg && m_Destination) payloadLen += msg->GetPayloadLength () + 13 + 32; - auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? CreateDatabaseStoreMsg (GetOwner ()->GetLeaseSet ()) : nullptr; + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) { - payloadLen += leaseSet->GetPayloadLength () + 13; + payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; if (!first) { // ack request @@ -725,7 +725,7 @@ namespace garlic // LeaseSet if (leaseSet) { - offset += CreateGarlicClove (leaseSet, v.data () + offset, payloadLen - offset); + offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); if (!first) { // ack request @@ -815,38 +815,31 @@ namespace garlic return cloveSize + 3; } - size_t ECIESX25519AEADRatchetSession::CreateDeliveryStatusClove (std::shared_ptr msg, uint8_t * buf, size_t len) + size_t ECIESX25519AEADRatchetSession::CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len) { - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 37 /* delivery instruction */; + if (!ls || ls->GetStoreType () != i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) + { + LogPrint (eLogError, "Garlic: Incorrect LeasetSet type to send"); + return 0; + } + uint16_t cloveSize = 1 + 9 + DATABASE_STORE_HEADER_SIZE + ls->GetBufferLen (); // to local if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (buf + 1, cloveSize); // size buf += 3; - if (GetOwner ()) - { - auto inboundTunnel = GetOwner ()->GetTunnelPool ()->GetNextInboundTunnel (); - if (inboundTunnel) - { - // delivery instructions - *buf = eGarlicDeliveryTypeTunnel << 5; buf++; // delivery instructions flag tunnel - // hash and tunnelID sequence is reversed for Garlic - memcpy (buf, inboundTunnel->GetNextIdentHash (), 32); buf += 32;// To Hash - htobe32buf (buf, inboundTunnel->GetNextTunnelID ()); buf += 4;// tunnelID - } - else - { - LogPrint (eLogError, "Garlic: No inbound tunnels in the pool for DeliveryStatus"); - return 0; - } - *buf = msg->GetTypeID (); // I2NP msg type - htobe32buf (buf + 1, msg->GetMsgID ()); // msgID - htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); - } - else - return 0; + *buf = 0; buf++; // flag and delivery instructions + *buf = eI2NPDatabaseStore; buf++; // I2NP msg type + RAND_bytes (buf, 4); buf += 4; // msgID + htobe32buf (buf, (ts + I2NP_MESSAGE_EXPIRATION_TIMEOUT)/1000); buf += 4; // expiration + // payload + memcpy (buf + DATABASE_STORE_KEY_OFFSET, ls->GetStoreHash (), 32); + buf[DATABASE_STORE_TYPE_OFFSET] = i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2; + memset (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // replyToken = 0 + buf += DATABASE_STORE_HEADER_SIZE; + memcpy (buf, ls->GetBuffer (), ls->GetBufferLen ()); + return cloveSize + 3; - } + } void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 001f5e51..ce5e2eb4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -145,8 +145,8 @@ namespace garlic std::vector CreatePayload (std::shared_ptr msg, bool first); size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); - size_t CreateDeliveryStatusClove (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); + void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); void NewNextSendRatchet (); From b5b195e6283b916592df2c192374d70049e84f3d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 14 May 2020 20:59:52 +0300 Subject: [PATCH 0334/2950] [windows] fix msys build Signed-off-by: R4SAS --- Win32/Win32Service.cpp | 2 +- libi2pd_client/I2PTunnel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index 717bc887..9d1dedb4 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -4,7 +4,7 @@ #include "Win32Service.h" #include -#include +//#include #include #include "Daemon.h" diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index b7487441..78bc8018 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -69,15 +69,15 @@ namespace client return ourIP; } +#ifdef __linux__ static void MapToLoopback(const std::shared_ptr & sock, const i2p::data::IdentHash & addr) { - // 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)); - } +#endif void I2PTunnelConnection::Connect (bool isUniqueLocal) { From 716378bd6bb2e8417fd208fabcda9c80d7593b64 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 14 May 2020 21:52:33 +0300 Subject: [PATCH 0335/2950] [makefile] fix build with g++ 10 Signed-off-by: R4SAS --- Makefile.linux | 2 +- Makefile.mingw | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index fa2f2fdf..305978dd 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -20,7 +20,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic else # not supported diff --git a/Makefile.mingw b/Makefile.mingw index 1b1b4b25..251e2e90 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -2,10 +2,19 @@ USE_WIN32_APP=yes CXX = g++ WINDRES = windres CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -NEEDED_CXXFLAGS = -std=c++11 INCFLAGS = -Idaemon -I. LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ +# detect proper flag for c++11 support by compilers +CXXVER := $(shell $(CXX) -dumpversion) +ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6 + NEEDED_CXXFLAGS += -std=c++11 +else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 + NEEDED_CXXFLAGS += -std=c++17 +else # not supported +$(error Compiler too old) +endif + # Boost libraries suffix BOOST_SUFFIX = -mt From 1e4d2fd05380c9702ed6cfb4d83b9fc30c51e14f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 14 May 2020 15:45:25 -0400 Subject: [PATCH 0336/2950] fixed for g++10 --- Makefile.linux | 2 +- Makefile.mingw | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index 305978dd..1cdf0a48 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -20,7 +20,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 LDLIBS = -latomic -else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7 NEEDED_CXXFLAGS += -std=c++17 LDLIBS = -latomic else # not supported diff --git a/Makefile.mingw b/Makefile.mingw index 251e2e90..2782b715 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -9,7 +9,7 @@ LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ CXXVER := $(shell $(CXX) -dumpversion) ifeq ($(shell expr match ${CXXVER} "[4]\.[7-9]\|4\.1[0-9]\|[5-6]"),4) # gcc 4.7 - 6 NEEDED_CXXFLAGS += -std=c++11 -else ifeq ($(shell expr match ${CXXVER} "[7-9]\|1[0-9]"),2) # gcc >= 7 +else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7 NEEDED_CXXFLAGS += -std=c++17 else # not supported $(error Compiler too old) From 0b1cfb2102dfde98617e643dcc36e1ca35c93b9e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 16 May 2020 19:10:17 -0400 Subject: [PATCH 0337/2950] send response to recived datagram from ECIESX25519AEADRatchet session --- libi2pd/Datagram.cpp | 9 ++++++--- libi2pd/ECIESX25519AEADRatchetSession.cpp | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 7e04fce8..a69c86b0 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -247,6 +247,8 @@ namespace datagram auto path = GetSharedRoutingPath(); if(path) path->updateTime = i2p::util::GetSecondsSinceEpoch (); + if (m_RoutingSession && m_RoutingSession->IsRatchets ()) + SendMsg (nullptr); // send empty message in case if we have some data to send } std::shared_ptr DatagramSession::GetSharedRoutingPath () @@ -352,14 +354,14 @@ namespace datagram void DatagramSession::HandleSend(std::shared_ptr msg) { - m_SendQueue.push_back(msg); + if (msg || m_SendQueue.empty ()) + m_SendQueue.push_back(msg); // flush queue right away if full if(m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); } void DatagramSession::FlushSendQueue () { - std::vector send; auto routingPath = GetSharedRoutingPath(); // if we don't have a routing path we will drop all queued messages @@ -368,7 +370,8 @@ namespace datagram for (const auto & msg : m_SendQueue) { auto m = m_RoutingSession->WrapSingleMessage(msg); - send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m}); + if (m) + send.push_back(i2p::tunnel::TunnelMessageBlock{i2p::tunnel::eDeliveryTypeTunnel,routingPath->remoteLease->tunnelGateway, routingPath->remoteLease->tunnelID, m}); } routingPath->outboundTunnel->SendTunnelDataMsg(send); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 4f4f56ce..513ac626 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -641,6 +641,7 @@ namespace garlic { auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); size_t len = payload.size (); + if (!len) return nullptr; auto m = NewI2NPMessage (len + 100); // 96 + 4 m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length @@ -708,11 +709,14 @@ namespace garlic { payloadLen += 6; if (m_NextSendRatchet->newKey) payloadLen += 32; + } + uint8_t paddingSize = 0; + if (payloadLen) + { + RAND_bytes (&paddingSize, 1); + paddingSize &= 0x0F; paddingSize++; // 1 - 16 + payloadLen += paddingSize + 3; } - uint8_t paddingSize; - RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize + 3; std::vector v(payloadLen); size_t offset = 0; // DateTime @@ -785,9 +789,12 @@ namespace garlic } } // padding - v[offset] = eECIESx25519BlkPadding; offset++; - htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + if (paddingSize) + { + v[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (v.data () + offset, paddingSize); offset += 2; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + } return v; } From 329439d0ae472c9d700a38ff6f6c1494ae429f51 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 May 2020 16:49:31 -0400 Subject: [PATCH 0338/2950] don't copy datagram payload --- libi2pd/Datagram.cpp | 32 ++++++++++++++++---------------- libi2pd/Datagram.h | 5 ++++- libi2pd/Gzip.cpp | 30 ++++++++++++++++++++++++++++++ libi2pd/Gzip.h | 2 ++ 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index a69c86b0..04e01796 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -24,34 +24,32 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { auto owner = m_Owner; - std::vector v(MAX_DATAGRAM_SIZE); - uint8_t * buf = v.data(); - auto localIdentity = m_Owner->GetIdentity (); - auto identityLen = localIdentity->ToBuffer (buf, MAX_DATAGRAM_SIZE); - uint8_t * signature = buf + identityLen; + auto localIdentity = m_Owner->GetIdentity (); + auto identityLen = localIdentity->GetFullLen (); auto signatureLen = localIdentity->GetSignatureLen (); - uint8_t * buf1 = signature + signatureLen; size_t headerLen = identityLen + signatureLen; - - memcpy (buf1, payload, len); + + std::vector header(headerLen); + localIdentity->ToBuffer (header.data (), identityLen); + uint8_t * signature = header.data () + identityLen; if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) { uint8_t hash[32]; - SHA256(buf1, len, hash); + SHA256(payload, len, hash); owner->Sign (hash, 32, signature); } else - owner->Sign (buf1, len, signature); + owner->Sign (payload, len, signature); - auto msg = CreateDataMessage (buf, len + headerLen, fromPort, toPort); auto session = ObtainSession(identity); + auto msg = CreateDataMessage ({{header.data (), headerLen}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); } void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - auto msg = CreateDataMessage (payload, len, fromPort, toPort, true); // raw auto session = ObtainSession(identity); + auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw session->SendMsg(msg); } @@ -122,12 +120,14 @@ namespace datagram } - std::shared_ptr DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw) + std::shared_ptr DatagramDestination::CreateDataMessage ( + const std::vector >& payloads, + uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length - size_t size = m_Deflator.Deflate (payload, len, buf, msg->maxLen - msg->len); + size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length @@ -135,7 +135,7 @@ namespace datagram htobe16buf (buf + 6, toPort); // destination port buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol msg->len += size + 4; - msg->FillI2NPMessageHeader (eI2NPData); + msg->FillI2NPMessageHeader (eI2NPData, 0, checksum); } else msg = nullptr; @@ -247,7 +247,7 @@ namespace datagram auto path = GetSharedRoutingPath(); if(path) path->updateTime = i2p::util::GetSecondsSinceEpoch (); - if (m_RoutingSession && m_RoutingSession->IsRatchets ()) + if (IsRatchets ()) SendMsg (nullptr); // send empty message in case if we have some data to send } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 0cfec838..87f3a7a8 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -51,6 +51,8 @@ namespace datagram /** get the last time in milliseconds for when we used this datagram session */ uint64_t LastActivity() const { return m_LastUse; } + bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } + struct Info { std::shared_ptr IBGW; @@ -130,7 +132,8 @@ namespace datagram std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); - std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort, bool isRaw = false); + std::shared_ptr CreateDataMessage (const std::vector >& payloads, + uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 2ca711b0..cb6a79af 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -116,6 +116,36 @@ namespace data return 0; } + size_t GzipDeflator::Deflate (const std::vector >& bufs, uint8_t * out, size_t outLen) + { + if (m_IsDirty) deflateReset (&m_Deflator); + m_IsDirty = true; + size_t offset = 0; + int err; + for (const auto& it: bufs) + { + m_Deflator.next_in = const_cast(it.first); + m_Deflator.avail_in = it.second; + m_Deflator.next_out = out + offset; + m_Deflator.avail_out = outLen - offset; + auto flush = (it == bufs.back ()) ? Z_FINISH : Z_NO_FLUSH; + err = deflate (&m_Deflator, flush); + if (err) + { + if (flush && err == Z_STREAM_END) + { + out[9] = 0xff; // OS is always unknown + return outLen - m_Deflator.avail_out; + } + break; + } + offset = outLen - m_Deflator.avail_out; + } + // else + LogPrint (eLogError, "Gzip: Deflate error ", err); + return 0; + } + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 }; diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index cf08d920..e5b8775e 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -2,6 +2,7 @@ #define GZIP_H__ #include +#include namespace i2p { @@ -34,6 +35,7 @@ namespace data void SetCompressionLevel (int level); size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); + size_t Deflate (const std::vector >& bufs, uint8_t * out, size_t outLen); private: From e1b1032df9501b3962067305ed346dc9e33725e7 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 08:29:09 -0400 Subject: [PATCH 0339/2950] reseeds update --- .../reseed/hankhill19580_at_gmail.com.crt | 34 +++++++++++++++++++ libi2pd/Config.cpp | 5 +-- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 contrib/certificates/reseed/hankhill19580_at_gmail.com.crt diff --git a/contrib/certificates/reseed/hankhill19580_at_gmail.com.crt b/contrib/certificates/reseed/hankhill19580_at_gmail.com.crt new file mode 100644 index 00000000..2f177ee1 --- /dev/null +++ b/contrib/certificates/reseed/hankhill19580_at_gmail.com.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIRAKye34BRrKyQN6kMVPHddykwDQYJKoZIhvcNAQELBQAw +dzELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE +ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxIDAeBgNVBAMM +F2hhbmtoaWxsMTk1ODBAZ21haWwuY29tMB4XDTIwMDUwNzA1MDkxMFoXDTMwMDUw +NzA1MDkxMFowdzELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJY +WDEeMBwGA1UEChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAx +IDAeBgNVBAMMF2hhbmtoaWxsMTk1ODBAZ21haWwuY29tMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA5Vt7c0SeUdVkcXXEYe3M9LmCTUyiCv/PHF2Puys6 +8luLH8lO0U/pQ4j703kFKK7s4rV65jVpGNncjHWbfSCNevvs6VcbAFoo7oJX7Yjt +5+Z4oU1g7JG86feTwU6pzfFjAs0RO2lNq2L8AyLYKWOnPsVrmuGYl2c6N5WDzTxA +Et66IudfGsppTv7oZkgX6VNUMioV8tCjBTLaPCkSfyYKBX7r6ByHY86PflhFgYES +zIB92Ma75YFtCB0ktCM+o6d7wmnt10Iy4I6craZ+z7szCDRF73jhf3Vk7vGzb2cN +aCfr2riwlRJBaKrLJP5m0dGf5RdhviMgxc6JAgkN7Ius5lkxO/p3OSy5co0DrMJ7 +lvwdZ2hu0dnO75unTt6ImR4RQ90Sqj7MUdorKR/8FcYEo+twBV8cV3s9kjuO5jxV +g976Q+GD3zDoixiege3W5UT4ff/Anm4mJpE5PKbNuO+KUjk6WA4B1PeudkEcxkO4 +tQYy0aBzfjeyENee9otd4TgN1epY4wlHIORCa3HUFmFZd9VZMQcxwv7c47wl2kc9 +Cv1L6Nae78wRzRu2CHD8zWhq+tv5q7Md2eRd3mFPI09ljsOgG2TQv6300WvHvI5M +enNdjYjLqOTRCzUJ2Jst4BZsvDxjWYkHsSZc1UORzm2LQmh2bJvbhC3m81qANGw6 +ZhcCAwEAAaNkMGIwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMC +BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCAGA1UdDgQZBBdoYW5raGlsbDE5 +NTgwQGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAgEAVtMF7lrgkDLTNXlavI7h +HJqFxFHjmxPk3iu2Qrgwk302Gowqg5NjVVamT20cXeuJaUa6maTTHzDyyCai3+3e +roaosGxZQRpRf5/RBz2yhdEPLZBV9IqxGgIxvCWNqNIYB1SNk00rwC4q5heW1me0 +EsOK4Mw5IbS2jUjbi9E5th781QDj91elwltghxwtDvpE2vzAJwmxwwBhjySGsKfq +w8SBZOxN+Ih5/IIpDnYGNoN1LSkJnBVGSkjY6OpstuJRIPYWl5zX5tJtYdaxiD+8 +qNbFHBIZ5WrktMopJ3QJJxHdERyK6BFYYSzX/a1gO7woOFCkx8qMCsVzfcE/z1pp +JxJvshT32hnrKZ6MbZMd9JpTFclQ62RV5tNs3FPP3sbDsFtKBUtj87SW7XsimHbZ +OrWlPacSnQDbOoV5TfDDCqWi4PW2EqzDsDcg+Lc8EnBRIquWcAox2+4zmcQI29wO +C1TUpMT5o/wGyL/i9pf6GuTbH0D+aYukULropgSrK57EALbuvqnN3vh5l2QlX/rM ++7lCKsGCNLiJFXb0m6l/B9CC1947XVEbpMEAC/80Shwxl/UB+mKFpJxcNLFtPXzv +FYv2ixarBPbJx/FclOO8G91QC4ZhAKbsVZn5HPMSgtZe+xWM1r0/UJVChsMTafpd +CCOJyu3XtyzFf+tAeixOnuQ= +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 580e9156..b741b118 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -192,15 +192,12 @@ namespace config { ("reseed.urls", value()->default_value( "https://reseed.i2p-projekt.de/," "https://i2p.mooo.com/netDb/," - "https://netdb.i2p2.no/," "https://reseed.i2p2.no/," - "https://reseed2.i2p2.no/," - // "https://us.reseed.i2p2.no:444/," // mamoth's shit - // "https://uk.reseed.i2p2.no:444/," // mamoth's shit "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," + "https://reseed.i2pgit.org/," "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ; From d4bfeab36ce06f1eba42cfeda0bbfcec068dbea4 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 12:01:13 -0400 Subject: [PATCH 0340/2950] pass gzip parameter to UDP tunnels --- libi2pd/Datagram.cpp | 5 +++-- libi2pd/Datagram.h | 3 ++- libi2pd/Destination.cpp | 4 ++-- libi2pd/Destination.h | 2 +- libi2pd_client/ClientContext.cpp | 5 +++-- libi2pd_client/ClientContext.h | 1 + libi2pd_client/I2PTunnel.cpp | 8 ++++---- libi2pd_client/I2PTunnel.h | 4 ++-- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 04e01796..7eb20460 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -11,8 +11,8 @@ namespace i2p { namespace datagram { - DatagramDestination::DatagramDestination (std::shared_ptr owner): - m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr) + DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): + m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { } @@ -127,6 +127,7 @@ namespace datagram auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length + m_Deflator.SetCompressionLevel (m_Gzip ? Z_DEFAULT_COMPRESSION : Z_NO_COMPRESSION); size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len); if (size) { diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 87f3a7a8..5fcaec3a 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -107,7 +107,7 @@ namespace datagram public: - DatagramDestination (std::shared_ptr owner); + DatagramDestination (std::shared_ptr owner, bool gzip); ~DatagramDestination (); void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); @@ -146,6 +146,7 @@ namespace datagram std::shared_ptr m_Owner; Receiver m_Receiver; // default RawReceiver m_RawReceiver; // default + bool m_Gzip; // gzip compression of data messages std::mutex m_SessionsMutex; std::map m_Sessions; std::mutex m_ReceiversMutex; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 105cd2e6..782e2841 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1105,10 +1105,10 @@ namespace client return dest; } - i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination () + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) { if (m_DatagramDestination == nullptr) - m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis ()); + m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip); return m_DatagramDestination; } diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 8c423d77..04cf05f4 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -236,7 +236,7 @@ namespace client // datagram i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; - i2p::datagram::DatagramDestination * CreateDatagramDestination (); + 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; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c8a9ddfe..765d3dec 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -569,7 +569,8 @@ namespace client if (!localDestination) localDestination = m_SharedLocalDestination; - auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort); + 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) clientTunnel->Start(); else @@ -672,7 +673,7 @@ namespace client // TODO: hostnames auto localAddress = boost::asio::ip::address::from_string(address); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); - auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port); + auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port, gzip); if(!isUniqueLocal) { LogPrint(eLogInfo, "Clients: disabling loopback address mapping"); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 610914bf..1a56575f 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -33,6 +33,7 @@ namespace client const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address"; const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination"; const char I2P_CLIENT_TUNNEL_KEYS[] = "keys"; + const char I2P_CLIENT_TUNNEL_GZIP[] = "gzip"; const char I2P_CLIENT_TUNNEL_SIGNATURE_TYPE[] = "signaturetype"; const char I2P_CLIENT_TUNNEL_CRYPTO_TYPE[] = "cryptotype"; const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 78bc8018..dc2a8811 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -696,7 +696,7 @@ namespace client } I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, - boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) : + boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip) : m_IsUniqueLocal(true), m_Name(name), m_LocalAddress(localAddress), @@ -704,7 +704,7 @@ namespace client { m_LocalDest = localDestination; m_LocalDest->Start(); - auto dgram = m_LocalDest->CreateDatagramDestination(); + auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); } @@ -745,7 +745,7 @@ namespace client I2PUDPClientTunnel::I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, - uint16_t remotePort) : + uint16_t remotePort, bool gzip) : m_Name(name), m_RemoteDest(remoteDest), m_LocalDest(localDestination), @@ -756,7 +756,7 @@ namespace client RemotePort(remotePort), m_cancel_resolve(false) { - auto dgram = m_LocalDest->CreateDatagramDestination(); + auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 0d1ac9a8..fbe2f7bb 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -198,7 +198,7 @@ namespace client I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, boost::asio::ip::address localAddress, - boost::asio::ip::udp::endpoint forwardTo, uint16_t port); + boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip); ~I2PUDPServerTunnel(); /** expire stale udp conversations */ void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT); @@ -228,7 +228,7 @@ namespace client public: I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, - uint16_t remotePort); + uint16_t remotePort, bool gzip); ~I2PUDPClientTunnel(); void Start(); const char * GetName() const { return m_Name.c_str(); } From 1c8d662e30f591bb27ac58cc39e4341eaad57bcb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 16:42:06 -0400 Subject: [PATCH 0341/2950] don't add padding for optimal packet size --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 10 +++++++--- libi2pd/ECIESX25519AEADRatchetSession.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 513ac626..18e1c7b6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -713,9 +713,13 @@ namespace garlic uint8_t paddingSize = 0; if (payloadLen) { - RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize + 3; + // don't create padding if we are close to optimal size + if (first || payloadLen + 19 <= ECIESX25519_OPTIMAL_PAYLOAD_SIZE || payloadLen > ECIESX25519_OPTIMAL_PAYLOAD_SIZE) + { + RAND_bytes (&paddingSize, 1); + paddingSize &= 0x0F; paddingSize++; // 1 - 16 + payloadLen += paddingSize + 3; + } } std::vector v(payloadLen); size_t offset = 0; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index ce5e2eb4..14f97ce9 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -26,6 +26,9 @@ namespace garlic const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; + const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ + // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ + class ECIESX25519AEADRatchetSession; class RatchetTagSet { From 7b418b3adfe1ef59922aa65658a8603243bc9c34 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 17:51:45 -0400 Subject: [PATCH 0342/2950] insert whole message to queue --- libi2pd/Streaming.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 2a4175f4..3355d99a 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -423,15 +423,8 @@ namespace stream size_t Stream::Send (const uint8_t * buf, size_t len) { - size_t sent = len; - while(len > MAX_PACKET_SIZE) - { - AsyncSend (buf, MAX_PACKET_SIZE, nullptr); - buf += MAX_PACKET_SIZE; - len -= MAX_PACKET_SIZE; - } AsyncSend (buf, len, nullptr); - return sent; + return len; } void Stream::AsyncSend (const uint8_t * buf, size_t len, SendHandler handler) From c7c6e5917a49f234e190fa16cd29a687ececc1d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 20:45:25 -0400 Subject: [PATCH 0343/2950] Streaming MTU size 1812 for ECIESX25519AEADRatchet --- libi2pd/Streaming.cpp | 16 +++++++++++----- libi2pd/Streaming.h | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3355d99a..ad3f6209 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -63,7 +63,7 @@ namespace stream m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), - m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0) + m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) { RAND_bytes ((uint8_t *)&m_RecvStreamID, 4); m_RemoteIdentity = remote->GetIdentity (); @@ -75,7 +75,7 @@ namespace stream m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), - m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0) + m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) { RAND_bytes ((uint8_t *)&m_RecvStreamID, 4); } @@ -473,6 +473,12 @@ namespace stream { // initial packet m_Status = eStreamStatusOpen; + if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; + if (m_RemoteLeaseSet) + { + m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); + m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; + } uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; if (isNoAck) flags |= PACKET_FLAG_NO_ACK; @@ -486,7 +492,7 @@ namespace stream size += 2; // options size m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); size += identityLen; // from - htobe16buf (packet + size, STREAMING_MTU); + htobe16buf (packet + size, m_MTU); size += 2; // max packet size if (isOfflineSignature) { @@ -498,7 +504,7 @@ namespace stream memset (signature, 0, signatureLen); // zeroes for now size += signatureLen; // signature htobe16buf (optionsSize, packet + size - 2 - optionsSize); // actual options size - size += m_SendBuffer.Get (packet + size, STREAMING_MTU); // payload + size += m_SendBuffer.Get (packet + size, m_MTU); // payload m_LocalDestination.GetOwner ()->Sign (packet, size, signature); } else @@ -508,7 +514,7 @@ namespace stream size += 2; // flags htobuf16 (packet + size, 0); // no options size += 2; // options size - size += m_SendBuffer.Get(packet + size, STREAMING_MTU); // payload + size += m_SendBuffer.Get(packet + size, m_MTU); // payload } p->len = size; packets.push_back (p); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 64e4c18d..d3d47794 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -41,6 +41,7 @@ namespace stream const uint16_t PACKET_FLAG_OFFLINE_SIGNATURE = 0x0800; const size_t STREAMING_MTU = 1730; + const size_t STREAMING_MTU_RATCHETS = 1812; const size_t MAX_PACKET_SIZE = 4096; const size_t COMPRESSION_THRESHOLD_SIZE = 66; const int MAX_NUM_RESEND_ATTEMPTS = 6; @@ -234,6 +235,7 @@ namespace stream int m_WindowSize, m_RTT, m_RTO, m_AckDelay; uint64_t m_LastWindowSizeIncreaseTime; int m_NumResendAttempts; + size_t m_MTU; }; class StreamingDestination: public std::enable_shared_from_this From 9fb59e128b601513086f0d30e2cce10d49c56efb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 May 2020 22:31:36 -0400 Subject: [PATCH 0344/2950] resubmit updated LeaseSet if not confirmed --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 18e1c7b6..9781a70a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -685,7 +685,10 @@ namespace garlic if (first) payloadLen += 7;// datatime if (msg && m_Destination) payloadLen += msg->GetPayloadLength () + 13 + 32; - auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? GetOwner ()->GetLeaseSet () : nullptr; + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || + (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && + ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? + GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) { payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; From 3db4421aa7f808924cb7b0317665f9e03631f0b2 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 May 2020 10:48:23 -0400 Subject: [PATCH 0345/2950] don't invoke gzip for decompression if no compression --- libi2pd/Gzip.cpp | 42 +++++++++++++++++++++++++++++------------- libi2pd/I2PEndian.h | 15 +++++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index cb6a79af..f098987a 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -32,18 +32,34 @@ namespace data size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) { - if (m_IsDirty) inflateReset (&m_Inflator); - m_IsDirty = true; - m_Inflator.next_in = const_cast(in); - m_Inflator.avail_in = inLen; - m_Inflator.next_out = out; - m_Inflator.avail_out = outLen; - int err; - if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) - return outLen - m_Inflator.avail_out; - // else - LogPrint (eLogError, "Gzip: Inflate error ", err); - return 0; + if (inLen < 23) return 0; + if (in[10] == 0x01) // non compressed + { + size_t len = bufle16toh (in + 11); + if (len + 23 < inLen) + { + LogPrint (eLogError, "Gzip: Incorrect length"); + return 0; + } + if (len > outLen) len = outLen; + memcpy (out, in + 15, len); + return len; + } + else + { + if (m_IsDirty) inflateReset (&m_Inflator); + m_IsDirty = true; + m_Inflator.next_in = const_cast(in); + m_Inflator.avail_in = inLen; + m_Inflator.next_out = out; + m_Inflator.avail_out = outLen; + int err; + if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) + return outLen - m_Inflator.avail_out; + // else + LogPrint (eLogError, "Gzip: Inflate error ", err); + return 0; + } } void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os) @@ -148,7 +164,7 @@ namespace data size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { - static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0x01 }; + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; if (outLen < (size_t)inLen + 23) return 0; memcpy (out, gzipHeader, 11); htole16buf (out + 11, inLen); diff --git a/libi2pd/I2PEndian.h b/libi2pd/I2PEndian.h index 0798f688..04a9480e 100644 --- a/libi2pd/I2PEndian.h +++ b/libi2pd/I2PEndian.h @@ -128,5 +128,20 @@ inline void htole64buf(void *buf, uint64_t big64) htobuf64(buf, htole64(big64)); } +inline uint16_t bufle16toh(const void *buf) +{ + return le16toh(buf16toh(buf)); +} + +inline uint32_t bufle32toh(const void *buf) +{ + return le32toh(buf32toh(buf)); +} + +inline uint64_t bufle64toh(const void *buf) +{ + return le64toh(buf64toh(buf)); +} + #endif // I2PENDIAN_H__ From 7ebf2f010c463bcb3ccf30b3efa4d0846eead255 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 May 2020 19:03:12 -0400 Subject: [PATCH 0346/2950] shorter padding for optimal packet length --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 9781a70a..7b386d92 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -716,12 +716,18 @@ namespace garlic uint8_t paddingSize = 0; if (payloadLen) { - // don't create padding if we are close to optimal size - if (first || payloadLen + 19 <= ECIESX25519_OPTIMAL_PAYLOAD_SIZE || payloadLen > ECIESX25519_OPTIMAL_PAYLOAD_SIZE) - { + int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; + if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size + { RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; paddingSize++; // 1 - 16 - payloadLen += paddingSize + 3; + paddingSize &= 0x0F; // 0 - 15 + if (delta > 3) + { + delta -= 3; + if (paddingSize >= delta) paddingSize %= delta; + } + paddingSize++; + payloadLen += paddingSize + 3; } } std::vector v(payloadLen); From 648d035a0fe6cd44fab7108f09314b9d75965231 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 May 2020 21:02:32 -0400 Subject: [PATCH 0347/2950] GzipNoCompression for datagrams --- libi2pd/Datagram.cpp | 4 ++-- libi2pd/Gzip.cpp | 22 ++++++++++++++++++++++ libi2pd/Gzip.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 7eb20460..08cd86bf 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -127,8 +127,8 @@ namespace datagram auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); buf += 4; // reserve for length - m_Deflator.SetCompressionLevel (m_Gzip ? Z_DEFAULT_COMPRESSION : Z_NO_COMPRESSION); - size_t size = m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len); + size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) : + i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index f098987a..f36620ae 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -174,6 +174,28 @@ namespace data htole32buf (out + inLen + 19, inLen); return inLen + 23; } + + size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen) + { + static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; + memcpy (out, gzipHeader, 11); + uint32_t crc = 0; + size_t len = 0, len1; + for (const auto& it: bufs) + { + len1 = len; + len += it.second; + if (outLen < len + 23) return 0; + memcpy (out + 15 + len1, it.first, it.second); + crc = crc32 (crc, it.first, it.second); + } + if (len > 0xffff) return 0; + htole32buf (out + len + 15, crc); + htole32buf (out + len + 19, len); + htole16buf (out + 11, len); + htole16buf (out + 13, 0xffff - len); + return len + 23; + } } // data } // i2p diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index e5b8775e..16776d35 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -44,6 +44,7 @@ namespace data }; size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K + size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen); // for total size < 64K } // data } // i2p From db6a0e6ad9124ef9b6217af487b3c844234ba5e1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 20 May 2020 09:17:54 +0000 Subject: [PATCH 0348/2950] [cmake] remove windows build support (#1517) Removes support for MSVC, MSYS, MinGW and included NSIS installer in cmake --- build/CMakeLists.txt | 527 ++++++++++------------------------ build/cmake-zlib-amd64.patch | 10 - build/cmake-zlib-static.patch | 28 -- 3 files changed, 158 insertions(+), 407 deletions(-) delete mode 100644 build/cmake-zlib-amd64.patch delete mode 100644 build/cmake-zlib-static.patch diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 1a459bf8..8271ce3a 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -1,28 +1,32 @@ -cmake_minimum_required ( VERSION 2.8.12 ) +cmake_minimum_required(VERSION 2.8.12) # this addresses CMP0059 with CMake > 3.3 for PCH flags -cmake_policy( VERSION 2.8.12 ) -project ( "i2pd" ) +cmake_policy(VERSION 2.8.12) +project("i2pd") # for debugging #set(CMAKE_VERBOSE_MAKEFILE on) +# Win32 build with cmake is not supported +if(WIN32 OR MSVC OR MSYS OR MINGW) + message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.") +endif() + # configurale options -option(WITH_AESNI "Use AES-NI instructions set" OFF) -option(WITH_AVX "Use AVX instructions" OFF) -option(WITH_HARDENING "Use hardening compiler flags" OFF) -option(WITH_LIBRARY "Build library" ON) -option(WITH_BINARY "Build binary" ON) -option(WITH_STATIC "Static build" OFF) -option(WITH_UPNP "Include support for UPnP client" OFF) -option(WITH_PCH "Use precompiled header" OFF) -option(WITH_GUI "Include GUI (currently MS Windows only)" ON) -option(WITH_MESHNET "Build for cjdns test network" OFF) -option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) -option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) +option(WITH_AESNI "Use AES-NI instructions set" OFF) +option(WITH_AVX "Use AVX instructions" OFF) +option(WITH_HARDENING "Use hardening compiler flags" OFF) +option(WITH_LIBRARY "Build library" ON) +option(WITH_BINARY "Build binary" ON) +option(WITH_STATIC "Static build" OFF) +option(WITH_UPNP "Include support for UPnP client" OFF) +option(WITH_PCH "Use precompiled header" OFF) +option(WITH_MESHNET "Build for cjdns test network" OFF) +option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF) +option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF) # paths -set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) -set ( CMAKE_SOURCE_DIR ".." ) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") +set(CMAKE_SOURCE_DIR "..") # architecture include(TargetArch) @@ -30,67 +34,65 @@ target_architecture(ARCHITECTURE) set(LIBI2PD_SRC_DIR ../libi2pd) set(LIBI2PD_CLIENT_SRC_DIR ../libi2pd_client) +set(DAEMON_SRC_DIR ../daemon) include_directories(${LIBI2PD_SRC_DIR}) include_directories(${LIBI2PD_CLIENT_SRC_DIR}) +include_directories(${DAEMON_SRC_DIR}) -set (LIBI2PD_SRC +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}/FS.cpp" "${LIBI2PD_SRC_DIR}/Log.cpp" - "${LIBI2PD_SRC_DIR}/NTCPSession.cpp" - "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" "${LIBI2PD_SRC_DIR}/NetDb.cpp" + "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" + "${LIBI2PD_SRC_DIR}/NTCP2.cpp" + "${LIBI2PD_SRC_DIR}/NTCPSession.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}/Destination.cpp" - "${LIBI2PD_SRC_DIR}/TransitTunnel.cpp" - "${LIBI2PD_SRC_DIR}/Tunnel.cpp" - "${LIBI2PD_SRC_DIR}/TunnelGateway.cpp" - "${LIBI2PD_SRC_DIR}/Transports.cpp" - "${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp" - "${LIBI2PD_SRC_DIR}/TunnelPool.cpp" - "${LIBI2PD_SRC_DIR}/Base.cpp" - "${LIBI2PD_SRC_DIR}/util.cpp" - "${LIBI2PD_SRC_DIR}/Datagram.cpp" - "${LIBI2PD_SRC_DIR}/Family.cpp" - "${LIBI2PD_SRC_DIR}/Signature.cpp" "${LIBI2PD_SRC_DIR}/Timestamp.cpp" - "${LIBI2PD_SRC_DIR}/api.cpp" - "${LIBI2PD_SRC_DIR}/Gost.cpp" - "${LIBI2PD_SRC_DIR}/ChaCha20.cpp" - "${LIBI2PD_SRC_DIR}/Poly1305.cpp" - "${LIBI2PD_SRC_DIR}/Ed25519.cpp" - "${LIBI2PD_SRC_DIR}/NTCP2.cpp" - "${LIBI2PD_SRC_DIR}/Blinding.cpp" - "${LIBI2PD_SRC_DIR}/Elligator.cpp" - "${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.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}/util.cpp" ) -if (WIN32 OR MSYS) - list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp") -endif () - add_library(libi2pd ${LIBI2PD_SRC}) set_target_properties(libi2pd PROPERTIES PREFIX "") -if (WITH_LIBRARY) +if(WITH_LIBRARY) install(TARGETS libi2pd EXPORT libi2pd ARCHIVE DESTINATION lib @@ -101,7 +103,7 @@ if (WITH_LIBRARY) # install(EXPORT libi2pd DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() -set (CLIENT_SRC +set(CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/AddressBook.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/BOB.cpp" "${LIBI2PD_CLIENT_SRC_DIR}/ClientContext.cpp" @@ -117,7 +119,7 @@ set (CLIENT_SRC add_library(libi2pdclient ${CLIENT_SRC}) set_target_properties(libi2pdclient PROPERTIES PREFIX "") -if (WITH_LIBRARY) +if(WITH_LIBRARY) install(TARGETS libi2pdclient EXPORT libi2pdclient ARCHIVE DESTINATION lib @@ -125,9 +127,7 @@ if (WITH_LIBRARY) COMPONENT Libraries) endif() -set(DAEMON_SRC_DIR ../daemon) - -set (DAEMON_SRC +set(DAEMON_SRC "${DAEMON_SRC_DIR}/Daemon.cpp" "${DAEMON_SRC_DIR}/HTTPServer.cpp" "${DAEMON_SRC_DIR}/I2PControl.cpp" @@ -135,37 +135,20 @@ set (DAEMON_SRC "${DAEMON_SRC_DIR}/UPnP.cpp" ) -if (WITH_MESHNET) +if(WITH_MESHNET) add_definitions(-DMESHNET) -endif () +endif() -if (WITH_UPNP) +if(WITH_UPNP) add_definitions(-DUSE_UPNP) - if (NOT MSVC AND NOT MSYS) - set(DL_LIB ${CMAKE_DL_LIBS}) - endif () -endif () +endif() -# compiler flags customization (by vendor) -if (MSVC) - add_definitions( -DWIN32_LEAN_AND_MEAN -DNOMINMAX ) - # TODO Check & report to Boost dev, there should be no need for these two - add_definitions( -DBOOST_THREAD_NO_LIB -DBOOST_CHRONO_NO_LIB ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL" ) - set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /INCREMENTAL:NO /LTCG" ) - set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /GL" ) - set( CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO /LTCG" ) -else() - if (MSYS OR MINGW) - add_definitions( -DWIN32_LEAN_AND_MEAN ) - endif () - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic" ) - # TODO: The following is incompatible with static build and enabled hardening for OpenWRT. - # Multiple definitions of __stack_chk_fail (libssp & libc) - set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections" ) - set( CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections" ) # -flto is added from above -endif () +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic") +# TODO: The following is incompatible with static build and enabled hardening for OpenWRT. +# Multiple definitions of __stack_chk_fail(libssp & libc) +set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -flto -s -ffunction-sections -fdata-sections") +set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-Wl,--gc-sections") # -flto is added from above # check for c++17 & c++11 support include(CheckCXXCompilerFlag) @@ -179,72 +162,53 @@ else() message(SEND_ERROR "C++17 nor C++11 standard not seems to be supported by compiler. Too old version?") endif() -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe") - if (WITH_HARDENING) - add_definitions( "-D_FORTIFY_SOURCE=2" ) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security -Werror=format-security" ) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param ssp-buffer-size=4" ) - endif () -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe") + if(WITH_HARDENING) + add_definitions("-D_FORTIFY_SOURCE=2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security -Werror=format-security") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector --param ssp-buffer-size=4") + endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # more tweaks - if (LINUX) - set (CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libstdc++" ) # required for + if(LINUX) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -stdlib=libstdc++") # required for list(APPEND CMAKE_REQUIRED_LIBRARIES "stdc++") # required to link with -stdlib=libstdc++ endif() - if (NOT (MSVC OR MSYS OR APPLE)) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions" ) + if(NOT APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions") endif() -endif () +endif() -if (WITH_HARDENING AND MSVC) - # Most security options like dynamic base, buffer & stack checks are ON by default - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /guard:cf" ) -endif () - -# compiler flags customization (by system) -if (UNIX) - list (APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp") - if (NOT (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE)) +# compiler flags customization(by system) +if(UNIX) + list(APPEND DAEMON_SRC "${DAEMON_SRC_DIR}/UnixDaemon.cpp") + if(NOT(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR APPLE)) # "'sleep_for' is not a member of 'std::this_thread'" in gcc 4.7/4.8 - add_definitions( "-D_GLIBCXX_USE_NANOSLEEP=1" ) - endif () -elseif (WIN32 OR MSYS) - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp") - if (WITH_GUI) - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp") - set_source_files_properties("${CMAKE_SOURCE_DIR}/Win32/DaemonWin32.cpp" - PROPERTIES COMPILE_DEFINITIONS WIN32_APP) - endif () - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp") - list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Resource.rc") -endif () - -if (WITH_AESNI) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes" ) -endif() - -if (WITH_AVX) - set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx" ) -endif() - -if (WITH_ADDRSANITIZER) - if (NOT MSVC) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer" ) - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" ) - else () - message( SEND_ERROR "MSVC does not support address sanitizer option") + add_definitions("-D_GLIBCXX_USE_NANOSLEEP=1") endif() endif() -if (WITH_THREADSANITIZER) - if (WITH_ADDRSANITIZER) - message( FATAL_ERROR "thread sanitizer option cannot be combined with address sanitizer") - elseif (NOT MSVC) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread" ) - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread" ) - else () - message( SEND_ERROR "MSVC does not support address sanitizer option") +if(WITH_AESNI) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") + add_definitions(-DAESNI) +endif() + +if(WITH_AVX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx") +endif() + +if(WITH_ADDRSANITIZER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") +endif() + +if(WITH_THREADSANITIZER) + if(WITH_ADDRSANITIZER) + message(FATAL_ERROR "thread sanitizer option cannot be combined with address sanitizer") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread") endif() endif() @@ -253,141 +217,87 @@ endif() # TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826 # use imported Threads::Threads instead set(THREADS_PREFER_PTHREAD_FLAG ON) -if (IOS) +if(IOS) set(CMAKE_THREAD_LIBS_INIT "-lpthread") set(CMAKE_HAVE_THREADS_LIBRARY 1) set(CMAKE_USE_WIN32_THREADS_INIT 0) set(CMAKE_USE_PTHREADS_INIT 1) else() - find_package ( Threads REQUIRED ) + find_package(Threads REQUIRED) endif() if(THREADS_HAVE_PTHREAD_ARG) # compile time flag set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() -if (WITH_STATIC) +if(WITH_STATIC) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_RUNTIME ON) - if (WIN32 AND NOT MSYS AND NOT MINGW) - # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace - foreach(flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif(${flag_var} MATCHES "/MD") - endforeach(flag_var) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - endif () set(BUILD_SHARED_LIBS OFF) - if (${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread" ) - # set( CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive" ) - set( CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,-u,pthread_create,-u,pthread_once,-u,pthread_mutex_lock,-u,pthread_mutex_unlock,-u,pthread_join,-u,pthread_equal,-u,pthread_detach,-u,pthread_cond_wait,-u,pthread_cond_signal,-u,pthread_cond_destroy,-u,pthread_cond_broadcast,-u,pthread_cancel" ) - endif () + if(${CMAKE_CXX_COMPILER} MATCHES ".*-openwrt-.*") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + # set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,--whole-archive -lpthread -Wl,--no-whole-archive") + set(CMAKE_THREAD_LIBS_INIT "gcc_eh -Wl,-u,pthread_create,-u,pthread_once,-u,pthread_mutex_lock,-u,pthread_mutex_unlock,-u,pthread_join,-u,pthread_equal,-u,pthread_detach,-u,pthread_cond_wait,-u,pthread_cond_signal,-u,pthread_cond_destroy,-u,pthread_cond_broadcast,-u,pthread_cancel") + endif() else() - if (NOT WIN32 AND NOT MSYS) - # TODO: Consider separate compilation for LIBI2PD_SRC for library. - # No need in -fPIC overhead for binary if not interested in library - # HINT: revert c266cff CMakeLists.txt: compilation speed up - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) - endif () + # TODO: Consider separate compilation for LIBI2PD_SRC for library. + # No need in -fPIC overhead for binary if not interested in library + # HINT: revert c266cff CMakeLists.txt: compilation speed up + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") add_definitions(-DBOOST_SYSTEM_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_PROGRAM_OPTIONS_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_REGEX_DYN_LINK) -endif () +endif() -if (WITH_PCH) +if(WITH_PCH) include_directories(BEFORE ${CMAKE_BINARY_DIR}) add_library(stdafx STATIC "${LIBI2PD_SRC_DIR}/stdafx.cpp") - if(MSVC) - target_compile_options(stdafx PRIVATE /Ycstdafx.h /Zm155) - add_custom_command(TARGET stdafx POST_BUILD - COMMAND xcopy /y stdafx.dir\\$\\*.pdb libi2pd.dir\\$\\ - COMMAND xcopy /y stdafx.dir\\$\\*.pdb i2pdclient.dir\\$\\ - COMMAND xcopy /y stdafx.dir\\$\\*.pdb i2pd.dir\\$\\ - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - ) - target_compile_options(libi2pd PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - target_compile_options(libi2pdclient PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - else() - string(TOUPPER ${CMAKE_BUILD_TYPE} BTU) - get_directory_property(DEFS DEFINITIONS) - string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}") - add_custom_command(TARGET stdafx PRE_BUILD - COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch - ) - target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) - target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) - endif() + string(TOUPPER ${CMAKE_BUILD_TYPE} BTU) + get_directory_property(DEFS DEFINITIONS) + string(REPLACE " " ";" FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTU}} ${DEFS}") + add_custom_command(TARGET stdafx PRE_BUILD + COMMAND ${CMAKE_CXX_COMPILER} ${FLAGS} -c ${CMAKE_CURRENT_SOURCE_DIR}/../libi2pd/stdafx.h -o ${CMAKE_BINARY_DIR}/stdafx.h.gch + ) + target_compile_options(libi2pd PRIVATE -include libi2pd/stdafx.h) + target_compile_options(libi2pdclient PRIVATE -include libi2pd/stdafx.h) target_link_libraries(libi2pd stdafx) endif() target_link_libraries(libi2pdclient libi2pd) -find_package ( Boost COMPONENTS system filesystem program_options date_time REQUIRED ) +find_package(Boost COMPONENTS system filesystem program_options date_time REQUIRED) if(NOT DEFINED Boost_INCLUDE_DIRS) message(SEND_ERROR "Boost is not found, or your boost version was below 1.46. Please download Boost!") endif() -find_package ( OpenSSL REQUIRED ) +find_package(OpenSSL REQUIRED) if(NOT DEFINED OPENSSL_INCLUDE_DIR) message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!") endif() -if (WITH_UPNP) - find_package ( MiniUPnPc REQUIRED ) - include_directories( SYSTEM ${MINIUPNPC_INCLUDE_DIR} ) +if(WITH_UPNP) + find_package(MiniUPnPc REQUIRED) + if(NOT MINIUPNPC_FOUND) + message(SEND_ERROR "Could not find MiniUPnPc. Please download and install it first!") + else() + include_directories(SYSTEM ${MINIUPNPC_INCLUDE_DIR}) + endif() endif() -find_package ( ZLIB ) -if (NOT ZLIB_FOUND ) - # We are probably on Windows - find_program( PATCH patch C:/Program Files/Git/usr/bin C:/msys64/usr/bin C:/msys32/usr/bin C:/Strawberry/c/bin ) - include( ExternalProject ) - if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - set( ZLIB_EXTRA -DAMD64=ON ) - else() - set( ZLIB_EXTRA -DASM686=ON "-DCMAKE_ASM_MASM_FLAGS=/W0 /safeseh" ) - endif() - ExternalProject_Add(zlib-project - URL https://zlib.net/zlib-1.2.11.tar.gz - URL_HASH SHA256=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 - PREFIX ${CMAKE_CURRENT_BINARY_DIR}/zlib - PATCH_COMMAND "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-static.patch - && "${PATCH}" -p0 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake-zlib-amd64.patch - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= - -DWITH_STATIC=${WITH_STATIC} ${ZLIB_EXTRA} - ) - if (WITH_PCH) - add_dependencies( stdafx zlib-project ) - else () - add_dependencies( libi2pd zlib-project ) - endif () - # ExternalProject_Get_Property(zlib-project install_dir) - set ( ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/zlib/include" CACHE FILEPATH "zlib include dir" FORCE) - if (NOT WITH_STATIC) - set ( ZLIB_LIBRARY debug zlibd optimized zlib CACHE STRING "zlib libraries" FORCE) - endif () - link_directories(${CMAKE_CURRENT_BINARY_DIR}/zlib/lib) -else() +find_package(ZLIB) +if(ZLIB_FOUND) link_directories(${ZLIB_ROOT}/lib) -endif () -if (WITH_STATIC AND (MSVC OR MSYS)) - set ( ZLIB_LIBRARY debug zlibstaticd optimized zlibstatic CACHE STRING "zlib libraries" FORCE) -endif () +endif() # load includes -include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ) - +include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}) # warn if for meshnet -if (WITH_MESHNET) +if(WITH_MESHNET) message(STATUS "Building for testnet") message(WARNING "This build will NOT work on mainline i2p") endif() -include(CheckAtomic) - +if(NOT MSYS) + include(CheckAtomic) +endif() # show summary message(STATUS "---------------------------------------") @@ -414,32 +324,24 @@ message(STATUS "---------------------------------------") #Handle paths nicely include(GNUInstallDirs) -if (WITH_BINARY) - add_executable ( "${PROJECT_NAME}" ${DAEMON_SRC} ) - if (WIN32 AND WITH_GUI) - set_target_properties("${PROJECT_NAME}" PROPERTIES WIN32_EXECUTABLE TRUE ) - endif() - if(NOT MSVC) - if (WITH_STATIC) - set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static" ) - endif () +if(WITH_BINARY) + add_executable("${PROJECT_NAME}" ${DAEMON_SRC}) + + if(WITH_STATIC) + set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static") endif() - if (WITH_PCH) - if (MSVC) - target_compile_options("${PROJECT_NAME}" PRIVATE /FIstdafx.h /Yustdafx.h /Zm155 "/Fp${CMAKE_BINARY_DIR}/stdafx.dir/$/stdafx.pch") - else() - target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h) - endif() + if(WITH_PCH) + target_compile_options("${PROJECT_NAME}" PRIVATE -include libi2pd/stdafx.h) endif() - if (WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT MSYS AND NOT MINGW) - set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now" ) - endif () + if(WITH_HARDENING AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now") + endif() - if (WITH_UPNP) - target_link_libraries("${PROJECT_NAME}" "${MINIUPNPC_LIBRARY}") - endif () + if(WITH_UPNP) + set(UPNP_LIB ${MINIUPNPC_LIBRARY}) + endif() # FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04 list(GET Boost_LIBRARIES -1 LAST_Boost_LIBRARIES) @@ -447,128 +349,15 @@ if (WITH_BINARY) list(REMOVE_AT Boost_LIBRARIES -1) endif() - if (MSYS OR MINGW) - set (MINGW_EXTRA -lws2_32 -lmswsock -liphlpapi ) - endif () - if (WITH_STATIC) + + if(WITH_STATIC) set(DL_LIB ${CMAKE_DL_LIBS}) endif() + target_link_libraries(libi2pd ${Boost_LIBRARIES} ${ZLIB_LIBRARY}) - target_link_libraries( "${PROJECT_NAME}" libi2pd libi2pdclient ${DL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_EXTRA} ${DL_LIB} ${CMAKE_REQUIRED_LIBRARIES}) + 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}) install(TARGETS "${PROJECT_NAME}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime) - set (APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") - set (DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin") - if (MSVC) - install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} CONFIGURATIONS DEBUG RELWITHDEBINFO COMPONENT Symbols) - # TODO Somehow this picks lots of unrelevant stuff with MSYS. OS X testing needed. - INSTALL(CODE " - include(BundleUtilities) - fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\") - " COMPONENT Runtime) - endif () -endif () - -install(FILES ../LICENSE - DESTINATION . - COMPONENT Runtime - ) -# Take a copy on Appveyor -install(FILES "C:/projects/openssl-$ENV{OPENSSL}/LICENSE" - DESTINATION . - COMPONENT Runtime - RENAME LICENSE_OPENSSL - OPTIONAL # for local builds only! - ) - -file(GLOB_RECURSE I2PD_SOURCES "../libi2pd/*.cpp" "../libi2pd_client/*.cpp" "../daemon/*.cpp" "../build" "../Win32" "../Makefile*") -install(FILES ${I2PD_SOURCES} DESTINATION src/ COMPONENT Source) -# install(DIRECTORY ../ DESTINATION src/ -# # OPTIONAL -# COMPONENT Source FILES_MATCHING -# PATTERN .git EXCLUDE -# PATTERN "*.cpp" -# ) - -file(GLOB I2PD_HEADERS "../libi2pd/*.h" "../libi2pd_client/*.h" "../daemon/*.h") -install(FILES ${I2PD_HEADERS} DESTINATION src/ COMPONENT Headers) -# install(DIRECTORY ../ DESTINATION src/ -# # OPTIONAL -# COMPONENT Headers FILES_MATCHING -# PATTERN .git EXCLUDE -# PATTERN "*.h" -# ) - -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Purple I2P, a C++ I2P daemon") -set(CPACK_PACKAGE_VENDOR "Purple I2P") -set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/../README.md") -set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE") -file(READ ../libi2pd/version.h version_h) -string(REGEX REPLACE ".*I2PD_VERSION_MAJOR ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${version_h}") -string(REGEX REPLACE ".*I2PD_VERSION_MINOR ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MINOR "${version_h}") -string(REGEX REPLACE ".*I2PD_VERSION_MICRO ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_MICRO "${version_h}") -string(REGEX REPLACE ".*I2PD_VERSION_PATCH ([0-9]+).*" "\\1" CPACK_PACKAGE_VERSION_PATCH "${version_h}") -set(CPACK_PACKAGE_INSTALL_DIRECTORY "Purple I2P")# ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}") -include(CPackComponent) -cpack_add_component(Runtime - DESCRIPTION "Main files" - REQUIRED INSTALL_TYPES minimal) -cpack_add_component(Symbols - DISPLAY_NAME "Debug symbols" - DESCRIPTION "Debug symbols for use with WinDbg or Visual Studio" - INSTALL_TYPES recommended full - ) -cpack_add_component(Libraries - DESCRIPTION "Binary libraries for development" - INSTALL_TYPES full dev3rd - ) -cpack_add_component(Source - DISPLAY_NAME "Source code" - DESCRIPTION "I2pd source code" - INSTALL_TYPES full - ) -cpack_add_component(Headers - DISPLAY_NAME "Header files" - DESCRIPTION "I2pd header files for development" - INSTALL_TYPES full dev3rd - ) -install(FILES ${MINIUPNPC_INCLUDE_DIR}/miniupnpc/miniupnpc.dll - DESTINATION bin - COMPONENT MiniUPnPc - OPTIONAL - ) -install(FILES ${MINIUPNPC_INCLUDE_DIR}/miniupnpc/LICENSE - DESTINATION . - COMPONENT MiniUPnPc - RENAME LICENSE_MINIUPNPC - OPTIONAL - ) -cpack_add_component(MiniUPnPc - INSTALL_TYPES full recommended - # DOWNLOADED - # ARCHIVE_FILE miniupnpc-win32.zip - ) -cpack_add_install_type(recommended DISPLAY_NAME Recommended) -cpack_add_install_type(dev3rd DISPLAY_NAME "Third party development") -cpack_add_install_type(full DISPLAY_NAME Full) -cpack_add_install_type(minimal DISPLAY_NAME Minimal) -if((WIN32 OR MSYS) AND NOT UNIX) - # There is a bug in NSI that does not handle full unix paths properly. Make - # sure there is at least one set of four (4) backlasshes. - set(CPACK_NSIS_DEFINES "RequestExecutionLevel user") - set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/../Win32\\\\mask.bmp") - set(CPACK_NSIS_INSTALLED_ICON_NAME "bin/i2pd.exe") - SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}") - set(CPACK_NSIS_HELP_LINK "https:\\\\\\\\github.com\\\\PurpleI2P\\\\i2pd\\\\issues") - set(CPACK_NSIS_URL_INFO_ABOUT "https:\\\\\\\\github.com\\\\PurpleI2P\\\\i2pd") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Install i2pd as windows service.lnk' '$INSTDIR\\\\bin\\\\i2pd.exe' '--service=install' -CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Remove i2pd windows service.lnk' '$INSTDIR\\\\bin\\\\i2pd.exe' '--service=remove'") - set(CPACK_NSIS_DELETE_ICONS_EXTRA "Delete '$SMPROGRAMS\\\\$START_MENU\\\\Install i2pd as windows service.lnk' -Delete '$SMPROGRAMS\\\\$START_MENU\\\\Remove i2pd windows service.lnk'") -else() - set(CPACK_STRIP_FILES "bin/i2pd") - set(CPACK_SOURCE_STRIP_FILES "") + set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") + set(DIRS "${Boost_LIBRARY_DIR};${OPENSSL_INCLUDE_DIR}/../bin;${ZLIB_INCLUDE_DIR}/../bin;/mingw32/bin") endif() -set(CPACK_PACKAGE_EXECUTABLES "i2pd" "C++ I2P daemon") -set(CPACK_SOURCE_GENERATOR "TGZ") -include(CPack) diff --git a/build/cmake-zlib-amd64.patch b/build/cmake-zlib-amd64.patch deleted file mode 100644 index 7ea1d9fe..00000000 --- a/build/cmake-zlib-amd64.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- CMakeLists.txt.orig 2015-12-07 14:19:36.447689600 -0600 -+++ CMakeLists.txt 2015-12-07 14:18:23.004419900 -0600 -@@ -165,6 +165,7 @@ - ENABLE_LANGUAGE(ASM_MASM) - set(ZLIB_ASMS - contrib/masmx64/gvmat64.asm -+ contrib/masmx64/inffas8664.c - contrib/masmx64/inffasx64.asm - ) - endif() diff --git a/build/cmake-zlib-static.patch b/build/cmake-zlib-static.patch deleted file mode 100644 index 68f1400e..00000000 --- a/build/cmake-zlib-static.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- CMakeLists.txt.orig 2013-04-28 17:57:10.000000000 -0500 -+++ CMakeLists.txt 2015-12-03 12:53:52.371087900 -0600 -@@ -7,6 +7,7 @@ - - option(ASM686 "Enable building i686 assembly implementation") - option(AMD64 "Enable building amd64 assembly implementation") -+option(WITH_STATIC "Static runtime on Windows" OFF) - - set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") - set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -@@ -66,6 +67,17 @@ - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - endif() - -+if(WITH_STATIC AND (MSVC OR MSYS)) -+ # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace -+ foreach(flag_var -+ CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE -+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) -+ if(${flag_var} MATCHES "/MD") -+ string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") -+ endif(${flag_var} MATCHES "/MD") -+ endforeach(flag_var) -+endif() -+ - if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... From bdd75e11714d0d15f2d261f86b62e50558073dc7 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 May 2020 14:59:18 -0400 Subject: [PATCH 0349/2950] build client tunnels through router with version >= 0.9.36 --- libi2pd/NetDb.cpp | 3 ++- libi2pd/NetDb.hpp | 2 ++ libi2pd/RouterInfo.cpp | 20 ++++++++++++++++++-- libi2pd/RouterInfo.h | 3 +++ libi2pd/version.h | 2 ++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 3466cf2b..86bf160e 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1121,7 +1121,8 @@ namespace data { return !router->IsHidden () && router != compatibleWith && router->IsCompatible (*compatibleWith) && - (router->GetCaps () & RouterInfo::eHighBandwidth); + (router->GetCaps () & RouterInfo::eHighBandwidth) && + router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION; }); } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index d9e10504..6e251ecb 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -21,6 +21,7 @@ #include "Reseed.h" #include "NetDbRequests.h" #include "Family.h" +#include "version.h" namespace i2p { @@ -32,6 +33,7 @@ namespace data const int NETDB_MIN_EXPIRATION_TIMEOUT = 90*60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27*60*60; // 27 hours const int NETDB_PUBLISH_INTERVAL = 60*40; + const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0,9,36); // 0.9.36 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 37c2af7e..9b3b7e89 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -27,7 +27,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_SupportedTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; @@ -35,7 +35,8 @@ namespace data } RouterInfo::RouterInfo (const uint8_t * buf, int len): - m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0) + m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), + m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) @@ -340,6 +341,21 @@ namespace data // extract caps if (!strcmp (key, "caps")) ExtractCaps (value); + // extract version + else if (!strcmp (key, ROUTER_INFO_PROPERTY_VERSION)) + { + m_Version = 0; + char * ch = value; + while (*ch) + { + if (*ch >= '0' && *ch <= '9') + { + m_Version *= 10; + m_Version += (*ch - '0'); + } + ch++; + } + } // check netId else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != i2p::context.GetNetID ()) { diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index b23625e0..f8598b1e 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -19,6 +19,7 @@ namespace data const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets"; const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters"; const char ROUTER_INFO_PROPERTY_NETID[] = "netId"; + const char ROUTER_INFO_PROPERTY_VERSION[] = "router.version"; const char ROUTER_INFO_PROPERTY_FAMILY[] = "family"; const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig"; @@ -142,6 +143,7 @@ namespace data void SetRouterIdentity (std::shared_ptr identity); std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); }; uint64_t GetTimestamp () const { return m_Timestamp; }; + int GetVersion () const { return m_Version; }; Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr std::shared_ptr GetNTCPAddress (bool v4only = true) const; std::shared_ptr GetNTCP2Address (bool publishedOnly, bool v4only = true) const; @@ -235,6 +237,7 @@ namespace data std::map m_Properties; bool m_IsUpdated, m_IsUnreachable; uint8_t m_SupportedTransports, m_Caps; + int m_Version; mutable std::shared_ptr m_Profile; }; } diff --git a/libi2pd/version.h b/libi2pd/version.h index 4ad1a546..fa8f9a0f 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -5,6 +5,7 @@ #define STRINGIZE(x) #x #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) +#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 31 @@ -24,5 +25,6 @@ #define I2P_VERSION_MICRO 45 #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) #endif From 9318388007cff0495b4b360d0480f4fc1219a9dc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 20 May 2020 22:30:02 +0300 Subject: [PATCH 0350/2950] [apparmor] add one more resolv.conf path (reported by user with ubuntu 18.04) Signed-off-by: R4SAS --- contrib/apparmor/usr.sbin.i2pd | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/apparmor/usr.sbin.i2pd b/contrib/apparmor/usr.sbin.i2pd index afa59563..6cc80609 100644 --- a/contrib/apparmor/usr.sbin.i2pd +++ b/contrib/apparmor/usr.sbin.i2pd @@ -19,6 +19,7 @@ /etc/nsswitch.conf r, /etc/resolv.conf r, /run/resolvconf/resolv.conf r, + /run/systemd/resolve/resolv.conf r, /run/systemd/resolve/stub-resolv.conf r, # path specific (feel free to modify if you have another paths) From e5901dad9177dc1740149d164143b1230fe78854 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 14:52:44 -0400 Subject: [PATCH 0351/2950] resend not more than half of window --- libi2pd/Streaming.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ad3f6209..e2047b0d 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -824,6 +824,8 @@ namespace stream } // collect packets to resend + int maxNumPackets = (m_WindowSize >> 1); // /2 + if (maxNumPackets < WINDOW_SIZE) maxNumPackets = WINDOW_SIZE; auto ts = i2p::util::GetMillisecondsSinceEpoch (); std::vector packets; for (auto it : m_SentPackets) @@ -832,6 +834,8 @@ namespace stream { it->sendTime = ts; packets.push_back (it); + maxNumPackets--; + if (maxNumPackets <= 0) break; } } @@ -843,7 +847,7 @@ namespace stream switch (m_NumResendAttempts) { case 1: // congesion avoidance - m_WindowSize /= 2; + m_WindowSize >>= 1; // /2 if (m_WindowSize < MIN_WINDOW_SIZE) m_WindowSize = MIN_WINDOW_SIZE; break; case 2: From 153aaa6d21459d50fbab54c9c553e6322a489ad1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 15:33:12 -0400 Subject: [PATCH 0352/2950] no compression for RouterInfo gzip --- libi2pd/I2NPProtocol.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index a16ce580..3a139792 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -249,9 +249,7 @@ namespace i2p uint8_t * sizePtr = buf; buf += 2; m->len += (buf - payload); // payload size - i2p::data::GzipDeflator deflator; - deflator.SetCompressionLevel (Z_BEST_COMPRESSION); - size_t size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + size_t size = i2p::data::GzipNoCompression (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); if (size) { htobe16buf (sizePtr, size); // size From a6c9ee446a3a89a45f741037256c88e56613f378 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 15:36:16 -0400 Subject: [PATCH 0353/2950] LeaseSet and encryption type for http and socks proxy --- libi2pd_client/ClientContext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 765d3dec..51f10f5e 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -468,6 +468,10 @@ namespace client options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = value; if (i2p::config::GetOption(prefix + I2CP_PARAM_MAX_TUNNEL_LATENCY, value)) options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = value; + if (i2p::config::GetOption(prefix + I2CP_PARAM_LEASESET_TYPE, value)) + options[I2CP_PARAM_LEASESET_TYPE] = value; + if (i2p::config::GetOption(prefix + I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, value)) + options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = value; } void ClientContext::ReadTunnels () From f133a7f9fd3b70a9d23c6fc83cda772d11d5702a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 18:58:28 -0400 Subject: [PATCH 0354/2950] resend outstading packets again --- libi2pd/Streaming.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index e2047b0d..0af7d902 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -408,11 +408,14 @@ namespace stream else break; } - if (m_SentPackets.empty ()) - m_ResendTimer.cancel (); if (acknowledged) { + bool isPreviousResend = m_NumResendAttempts > 0; m_NumResendAttempts = 0; + if (m_SentPackets.empty ()) + m_ResendTimer.cancel (); + else if (isPreviousResend) // resend outstanding + HandleResendTimer (boost::system::error_code ()); // no error SendBuffer (); } if (m_Status == eStreamStatusClosed) From 0c2b0081b5cc4ffbedd09bed70a7141f43ca6312 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 19:38:25 -0400 Subject: [PATCH 0355/2950] rollback --- libi2pd/Streaming.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 0af7d902..00ee35b0 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -408,14 +408,11 @@ namespace stream else break; } + if (m_SentPackets.empty ()) + m_ResendTimer.cancel (); if (acknowledged) { - bool isPreviousResend = m_NumResendAttempts > 0; m_NumResendAttempts = 0; - if (m_SentPackets.empty ()) - m_ResendTimer.cancel (); - else if (isPreviousResend) // resend outstanding - HandleResendTimer (boost::system::error_code ()); // no error SendBuffer (); } if (m_Status == eStreamStatusClosed) @@ -827,8 +824,6 @@ namespace stream } // collect packets to resend - int maxNumPackets = (m_WindowSize >> 1); // /2 - if (maxNumPackets < WINDOW_SIZE) maxNumPackets = WINDOW_SIZE; auto ts = i2p::util::GetMillisecondsSinceEpoch (); std::vector packets; for (auto it : m_SentPackets) @@ -837,8 +832,6 @@ namespace stream { it->sendTime = ts; packets.push_back (it); - maxNumPackets--; - if (maxNumPackets <= 0) break; } } From 46ee427ee33c8a727a9bb838b5d5961145d917c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 May 2020 21:54:00 -0400 Subject: [PATCH 0356/2950] common header for repliable datagrams --- libi2pd/Datagram.cpp | 23 +++++++++-------------- libi2pd/Datagram.h | 2 ++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 08cd86bf..6441b5e2 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,5 +1,4 @@ #include -#include #include "Crypto.h" #include "Log.h" #include "TunnelBase.h" @@ -14,6 +13,10 @@ namespace datagram DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { + auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); + m_From.resize (identityLen); + m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); + m_Signature.resize (m_Owner->GetIdentity ()->GetSignatureLen ()); } DatagramDestination::~DatagramDestination () @@ -23,26 +26,18 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - auto owner = m_Owner; - auto localIdentity = m_Owner->GetIdentity (); - auto identityLen = localIdentity->GetFullLen (); - auto signatureLen = localIdentity->GetSignatureLen (); - size_t headerLen = identityLen + signatureLen; - - std::vector header(headerLen); - localIdentity->ToBuffer (header.data (), identityLen); - uint8_t * signature = header.data () + identityLen; - if (localIdentity->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) { uint8_t hash[32]; SHA256(payload, len, hash); - owner->Sign (hash, 32, signature); + m_Owner->Sign (hash, 32, m_Signature.data ()); } else - owner->Sign (payload, len, signature); + m_Owner->Sign (payload, len, m_Signature.data ()); auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{header.data (), headerLen}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 5fcaec3a..ea2a4e13 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "Base.h" #include "Identity.h" #include "LeaseSet.h" @@ -154,6 +155,7 @@ namespace datagram i2p::data::GzipInflator m_Inflator; i2p::data::GzipDeflator m_Deflator; + std::vector m_From, m_Signature; }; } } From 78640532e1c0e50b122df45702e9861e6402d2af Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 May 2020 13:01:25 +0000 Subject: [PATCH 0357/2950] [appveyor] add build fix (#1520) Add fix due to msys2/MSYS2-packages#1967 --- appveyor.yml | 33 +++++++++++-------------------- build/appveyor-msys2-upgrade.bash | 10 ++++++++++ 2 files changed, 22 insertions(+), 21 deletions(-) create mode 100644 build/appveyor-msys2-upgrade.bash diff --git a/appveyor.yml b/appveyor.yml index d6dcf060..45a16dd8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,34 +14,25 @@ environment: CHERE_INVOKING: enabled_from_arguments matrix: - MSYSTEM: MINGW64 + MSYS_PACKAGES: mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc + MSYS_BITNESS: 64 - MSYSTEM: MINGW32 + MSYS_PACKAGES: mingw-w64-i686-boost mingw-w64-i686-miniupnpc + MSYS_BITNESS: 32 install: - 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" +# TODO: revert that change when appveyor's images will be updated +- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" +# update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" - -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" - -- if "%MSYSTEM%" == "MINGW64" ( - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" - ) else ( - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-boost mingw-w64-i686-miniupnpc" - ) - -- if "%MSYSTEM%" == "MINGW64" ( - set "bitness=64" - ) else ( - set "bitness=32" - ) +# update packages and install required +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" build_script: -- cmd: >- - cd \projects\i2pd - - echo MSYSTEM = %MSYSTEM%, bitness = %bitness% - -- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j2" -- 7z a -tzip -mx9 -mmt i2pd-mingw-win%bitness%.zip i2pd.exe +- echo MSYSTEM = %MSYSTEM%, bitness = %MSYS_BITNESS% +- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j3" +- 7z a -tzip -mx9 -mmt i2pd-mingw-win%MSYS_BITNESS%.zip i2pd.exe test: off diff --git a/build/appveyor-msys2-upgrade.bash b/build/appveyor-msys2-upgrade.bash new file mode 100644 index 00000000..20c6af69 --- /dev/null +++ b/build/appveyor-msys2-upgrade.bash @@ -0,0 +1,10 @@ +set -e -x + +base_url='http://repo.msys2.org/msys/x86_64/' +packages="libzstd-1.4.4-2-x86_64.pkg.tar.xz pacman-5.2.1-6-x86_64.pkg.tar.xz zstd-1.4.4-2-x86_64.pkg.tar.xz" +for p in $packages +do + curl "${base_url}$p" -o "$p" +done +pacman -U --noconfirm $packages +rm -f $packages From 9633c247f0ebf4c0613fea92b4a1b59795f6f2c4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 May 2020 19:34:42 +0300 Subject: [PATCH 0358/2950] [readme] update docker badges --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 25e6c3e5..ec7548f0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Snapcraft release](https://snapcraft.io/i2pd/badge.svg)](https://snapcraft.io/i2pd) [![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) i2pd ==== @@ -68,7 +69,7 @@ Build instructions: * 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) -* Docker image - [![Build Status](https://dockerbuildbadges.quelltext.eu/status.svg?organization=meeh&repository=i2pd)](https://hub.docker.com/r/meeh/i2pd/builds/) +* Docker image - [![Build Status](https://img.shields.io/docker/cloud/build/purplei2p/i2pd)](https://hub.docker.com/r/purplei2p/i2pd/builds/) * Snap - [![Snap Status](https://build.snapcraft.io/badge/PurpleI2P/i2pd-snap.svg)](https://build.snapcraft.io/user/PurpleI2P/i2pd-snap) * FreeBSD * Android From 7a5146ea7455136d507843c2180a3761ab401bc7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 1 Mar 2020 13:25:50 +0300 Subject: [PATCH 0359/2950] fix code syle(spaces->tabs, tabulations) Signed-off-by: R4SAS --- Win32/DaemonWin32.cpp | 4 +- Win32/Win32App.cpp | 910 +++++++++++----------- Win32/Win32App.h | 34 +- Win32/Win32Service.h | 70 +- Win32/resource.h | 22 +- daemon/Daemon.cpp | 45 +- daemon/Daemon.h | 14 +- daemon/HTTPServer.cpp | 4 +- daemon/HTTPServer.h | 22 +- daemon/I2PControl.cpp | 49 +- daemon/I2PControl.h | 1 + daemon/UPnP.cpp | 44 +- daemon/UPnP.h | 60 +- daemon/UnixDaemon.cpp | 1 - daemon/i2pd.cpp | 3 +- libi2pd/Base.cpp | 214 ++--- libi2pd/Base.h | 12 +- libi2pd/Blinding.cpp | 79 +- libi2pd/Blinding.h | 8 +- libi2pd/CPU.h | 6 +- libi2pd/ChaCha20.cpp | 115 ++- libi2pd/ChaCha20.h | 30 +- libi2pd/Config.cpp | 2 +- libi2pd/Config.h | 169 ++-- libi2pd/Crypto.cpp | 118 ++- libi2pd/Crypto.h | 30 +- libi2pd/CryptoKey.cpp | 7 +- libi2pd/CryptoKey.h | 13 +- libi2pd/CryptoWorker.h | 1 - libi2pd/Datagram.cpp | 32 +- libi2pd/Datagram.h | 97 +-- libi2pd/Destination.cpp | 119 ++- libi2pd/Destination.h | 31 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 752 +++++++++--------- libi2pd/ECIESX25519AEADRatchetSession.h | 164 ++-- libi2pd/Ed25519.cpp | 43 +- libi2pd/Ed25519.h | 14 +- libi2pd/Elligator.cpp | 87 +-- libi2pd/Elligator.h | 6 +- libi2pd/FS.h | 221 +++--- libi2pd/Family.cpp | 1 - libi2pd/Garlic.cpp | 188 ++--- libi2pd/Garlic.h | 106 +-- libi2pd/Gost.h | 8 +- libi2pd/Gzip.cpp | 26 +- libi2pd/Gzip.h | 5 +- libi2pd/I2NPProtocol.cpp | 28 +- libi2pd/I2NPProtocol.h | 6 +- libi2pd/Identity.cpp | 50 +- libi2pd/Identity.h | 13 +- libi2pd/LeaseSet.cpp | 224 +++--- libi2pd/LeaseSet.h | 39 +- libi2pd/LittleBigEndian.h | 324 ++++---- libi2pd/Log.cpp | 24 +- libi2pd/Log.h | 6 +- libi2pd/NTCP2.cpp | 20 +- libi2pd/NTCP2.h | 1 - libi2pd/NTCPSession.cpp | 15 +- libi2pd/NetDb.cpp | 28 +- libi2pd/NetDb.hpp | 37 +- libi2pd/NetDbRequests.cpp | 5 +- libi2pd/NetDbRequests.h | 1 - libi2pd/Poly1305.cpp | 3 +- libi2pd/Poly1305.h | 15 +- libi2pd/Reseed.cpp | 120 +-- libi2pd/Reseed.h | 2 +- libi2pd/RouterContext.cpp | 8 +- libi2pd/RouterContext.h | 14 +- libi2pd/RouterInfo.cpp | 54 +- libi2pd/RouterInfo.h | 4 +- libi2pd/SSU.cpp | 23 +- libi2pd/SSU.h | 3 +- libi2pd/SSUData.cpp | 3 +- libi2pd/SSUData.h | 1 - libi2pd/SSUSession.cpp | 5 +- libi2pd/SSUSession.h | 9 +- libi2pd/Signature.cpp | 52 +- libi2pd/Signature.h | 61 +- libi2pd/Siphash.h | 238 +++--- libi2pd/Streaming.cpp | 54 +- libi2pd/Tag.h | 142 ++-- libi2pd/Timestamp.cpp | 13 +- libi2pd/Timestamp.h | 13 +- libi2pd/TransitTunnel.cpp | 4 +- libi2pd/TransportSession.h | 8 +- libi2pd/Transports.cpp | 14 +- libi2pd/Transports.h | 20 +- libi2pd/TunnelEndpoint.cpp | 3 +- libi2pd/TunnelGateway.cpp | 5 +- libi2pd/TunnelPool.cpp | 12 +- libi2pd/TunnelPool.h | 24 +- libi2pd/api.cpp | 5 +- libi2pd/api.h | 1 - libi2pd/util.cpp | 51 +- libi2pd/util.h | 16 +- libi2pd_client/AddressBook.cpp | 62 +- libi2pd_client/AddressBook.h | 6 +- libi2pd_client/BOB.cpp | 50 +- libi2pd_client/BOB.h | 27 +- libi2pd_client/ClientContext.cpp | 64 +- libi2pd_client/ClientContext.h | 10 +- libi2pd_client/HTTPProxy.cpp | 12 +- libi2pd_client/HTTPProxy.h | 3 + libi2pd_client/I2CP.cpp | 53 +- libi2pd_client/I2CP.h | 9 +- libi2pd_client/I2PService.cpp | 22 +- libi2pd_client/I2PService.h | 26 +- libi2pd_client/I2PTunnel.cpp | 12 +- libi2pd_client/I2PTunnel.h | 36 +- libi2pd_client/MatchedDestination.cpp | 8 +- libi2pd_client/MatchedDestination.h | 32 +- libi2pd_client/SAM.cpp | 99 ++- libi2pd_client/SAM.h | 17 +- libi2pd_client/SOCKS.cpp | 9 +- libi2pd_client/SOCKS.h | 2 + 115 files changed, 3206 insertions(+), 3161 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 5524aff3..7ba3ffc3 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -27,8 +27,8 @@ namespace util i2p::log::SetThrowFunction ([](const std::string& s) { MessageBox(0, TEXT(s.c_str ()), TEXT("i2pd"), MB_ICONERROR | MB_TASKMODAL | MB_OK ); - }); - + }); + if (!Daemon_Singleton::init(argc, argv)) return false; diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 7ae4e419..3bcb24b3 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -1,455 +1,455 @@ -#include -#include -#include -#include -#include "ClientContext.h" -#include "Config.h" -#include "NetDb.hpp" -#include "RouterContext.h" -#include "Transports.h" -#include "Tunnel.h" -#include "version.h" -#include "resource.h" -#include "Daemon.h" -#include "Win32App.h" -#include "Win32NetState.h" - -#define ID_ABOUT 2000 -#define ID_EXIT 2001 -#define ID_CONSOLE 2002 -#define ID_APP 2003 -#define ID_GRACEFUL_SHUTDOWN 2004 -#define ID_STOP_GRACEFUL_SHUTDOWN 2005 -#define ID_RELOAD 2006 -#define ID_ACCEPT_TRANSIT 2007 -#define ID_DECLINE_TRANSIT 2008 - -#define ID_TRAY_ICON 2050 -#define WM_TRAYICON (WM_USER + 1) - -#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100 -#define FRAME_UPDATE_TIMER 2101 -#define IDT_GRACEFUL_TUNNELCHECK_TIMER 2102 - -namespace i2p -{ -namespace win32 -{ - static DWORD GracefulShutdownEndtime = 0; - - typedef DWORD (* IPN)(); - IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); - - static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) - { - 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_ABOUT, "&About..."); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); - if(!i2p::context.AcceptsTunnels()) - InsertMenu (hPopup, -1, - i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING, - ID_ACCEPT_TRANSIT, "Accept &transit"); - else - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config"); - if (!i2p::util::DaemonWin32::Instance ().isGraceful) - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); - else - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown"); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); - SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); - SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); - - POINT p; - if (!curpos) - { - GetCursorPos (&p); - curpos = &p; - } - - WORD cmd = TrackPopupMenu (hPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, curpos->x, curpos->y, 0, hWnd, NULL); - SendMessage (hWnd, WM_COMMAND, cmd, 0); - - DestroyMenu(hPopup); - } - - static void AddTrayIcon (HWND hWnd) - { - NOTIFYICONDATA nid; - memset(&nid, 0, sizeof(nid)); - nid.cbSize = sizeof(nid); - nid.hWnd = hWnd; - nid.uID = ID_TRAY_ICON; - nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; - nid.uCallbackMessage = WM_TRAYICON; - nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON)); - strcpy (nid.szTip, "i2pd"); - strcpy (nid.szInfo, "i2pd is starting"); - Shell_NotifyIcon(NIM_ADD, &nid ); - } - - static void RemoveTrayIcon (HWND hWnd) - { - NOTIFYICONDATA nid; - nid.hWnd = hWnd; - nid.uID = ID_TRAY_ICON; - Shell_NotifyIcon (NIM_DELETE, &nid); - } - - static void ShowUptime (std::stringstream& s, int seconds) - { - int num; - - if ((num = seconds / 86400) > 0) { - s << num << " days, "; - seconds -= num * 86400; - } - if ((num = seconds / 3600) > 0) { - s << num << " hours, "; - seconds -= num * 3600; - } - if ((num = seconds / 60) > 0) { - s << num << " min, "; - seconds -= num * 60; - } - s << seconds << " seconds\n"; - } - - template static void ShowTransfered (std::stringstream& s, size transfer) - { - auto bytes = transfer & 0x03ff; - transfer >>= 10; - auto kbytes = transfer & 0x03ff; - transfer >>= 10; - auto mbytes = transfer & 0x03ff; - transfer >>= 10; - auto gbytes = transfer & 0x03ff; - - if (gbytes) - s << gbytes << " GB, "; - if (mbytes) - s << mbytes << " MB, "; - if (kbytes) - s << kbytes << " KB, "; - s << bytes << " Bytes\n"; - } - - static void PrintMainWindowText (std::stringstream& s) - { - s << "\n"; - s << "Status: "; - switch (i2p::context.GetStatus()) - { - 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 << "; "; - s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; - s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); - if (GracefulShutdownEndtime != 0) - { - DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000; - s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft); - } - else - s << "\n"; - s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; "; - s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n"; - s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes()); - s << "Sent: "; ShowTransfered (s, i2p::transport::transports.GetTotalSentBytes()); - s << "\n"; - s << "Routers: " << i2p::data::netdb.GetNumRouters () << "; "; - s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << "; "; - s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "\n"; - s << "Tunnels: "; - s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; "; - s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; "; - s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n"; - s << "\n"; - } - - static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - static UINT s_uTaskbarRestart; - - switch (uMsg) - { - case WM_CREATE: - { - s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); - AddTrayIcon (hWnd); - break; - } - case WM_CLOSE: - { - RemoveTrayIcon (hWnd); - KillTimer (hWnd, FRAME_UPDATE_TIMER); - KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); - KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); - PostQuitMessage (0); - break; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case ID_ABOUT: - { - std::stringstream text; - text << "Version: " << I2PD_VERSION << " " << CODENAME; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_EXIT: - { - PostMessage (hWnd, WM_CLOSE, 0, 0); - return 0; - } - case ID_ACCEPT_TRANSIT: - { - i2p::context.SetAcceptsTunnels (true); - std::stringstream text; - text << "I2Pd now accept transit tunnels"; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_DECLINE_TRANSIT: - { - i2p::context.SetAcceptsTunnels (false); - std::stringstream text; - text << "I2Pd now decline new transit tunnels"; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_GRACEFUL_SHUTDOWN: - { - i2p::context.SetAcceptsTunnels (false); - SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes - SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second - GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000; - i2p::util::DaemonWin32::Instance ().isGraceful = true; - return 0; - } - case ID_STOP_GRACEFUL_SHUTDOWN: - { - i2p::context.SetAcceptsTunnels (true); - KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); - KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); - GracefulShutdownEndtime = 0; - i2p::util::DaemonWin32::Instance ().isGraceful = false; - return 0; - } - case ID_RELOAD: - { - i2p::client::context.ReloadConfig(); - std::stringstream text; - text << "I2Pd reloading configs..."; - MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); - return 0; - } - case ID_CONSOLE: - { - char buf[30]; - std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort); - ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL); - return 0; - } - case ID_APP: - { - ShowWindow(hWnd, SW_SHOW); - SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL); - return 0; - } - } - break; - } - case WM_SYSCOMMAND: - { - switch (wParam) - { - case SC_MINIMIZE: - { - ShowWindow(hWnd, SW_HIDE); - KillTimer (hWnd, FRAME_UPDATE_TIMER); - return 0; - } - case SC_CLOSE: - { - std::string close; i2p::config::GetOption("close", close); - if (0 == close.compare("ask")) - switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?" - " You can add 'close' configuration option. Valid values are: ask, minimize, exit.", - "Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1)) - { - case IDYES: close = "minimize"; break; - case IDNO: close = "exit"; break; - default: return 0; - } - if (0 == close.compare("minimize")) - { - ShowWindow(hWnd, SW_HIDE); - KillTimer (hWnd, FRAME_UPDATE_TIMER); - return 0; - } - if (0 != close.compare("exit")) - { - ::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING); - return 0; - } - } - } - } - case WM_TRAYICON: - { - switch (lParam) - { - case WM_LBUTTONUP: - case WM_RBUTTONUP: - { - SetForegroundWindow (hWnd); - ShowPopupMenu(hWnd, NULL, -1); - PostMessage (hWnd, WM_APP + 1, 0, 0); - break; - } - } - break; - } - case WM_TIMER: - { - switch(wParam) - { - case IDT_GRACEFUL_SHUTDOWN_TIMER: - { - GracefulShutdownEndtime = 0; - PostMessage (hWnd, WM_CLOSE, 0, 0); // exit - return 0; - } - case IDT_GRACEFUL_TUNNELCHECK_TIMER: - { - if (i2p::tunnel::tunnels.CountTransitTunnels() == 0) - PostMessage (hWnd, WM_CLOSE, 0, 0); - else - SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); - return 0; - } - case FRAME_UPDATE_TIMER: - { - InvalidateRect(hWnd, NULL, TRUE); - return 0; - } - } - break; - } - case WM_PAINT: - { - HDC hDC; - PAINTSTRUCT ps; - RECT rp; - HFONT hFont; - std::stringstream s; PrintMainWindowText (s); - hDC = BeginPaint (hWnd, &ps); - GetClientRect(hWnd, &rp); - SetTextColor(hDC, 0x00D43B69); - hFont = CreateFont(18,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0,TEXT("Times New Roman")); - SelectObject(hDC,hFont); - DrawText(hDC, TEXT(s.str().c_str()), s.str().length(), &rp, DT_CENTER|DT_VCENTER); - DeleteObject(hFont); - EndPaint(hWnd, &ps); - break; - } - default: - { - if (uMsg == s_uTaskbarRestart) - AddTrayIcon (hWnd); - break; - } - } - return DefWindowProc( hWnd, uMsg, wParam, lParam); - } - - bool StartWin32App () - { - if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"))) - { - MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK); - return false; - } - // register main window - auto hInst = GetModuleHandle(NULL); - WNDCLASSEX wclx; - memset (&wclx, 0, sizeof(wclx)); - wclx.cbSize = sizeof(wclx); - wclx.style = 0; - wclx.lpfnWndProc = WndProc; - //wclx.cbClsExtra = 0; - //wclx.cbWndExtra = 0; - wclx.hInstance = hInst; - wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON)); - wclx.hCursor = LoadCursor (NULL, IDC_ARROW); - //wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wclx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wclx.lpszMenuName = NULL; - wclx.lpszClassName = I2PD_WIN32_CLASSNAME; - RegisterClassEx (&wclx); - // create new window - if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL)) - { - MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); - return false; - } - SubscribeToEvents(); - return true; - } - - int RunWin32App () - { - MSG msg; - while (GetMessage (&msg, NULL, 0, 0 )) - { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - return msg.wParam; - } - - void StopWin32App () - { - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (hWnd) - PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); - // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app - UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); - } - - bool GracefulShutdown () - { - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (hWnd) - PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0); - return hWnd; - } - - bool StopGracefulShutdown () - { - HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); - if (hWnd) - PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); - return hWnd; - } -} -} +#include +#include +#include +#include +#include "ClientContext.h" +#include "Config.h" +#include "NetDb.hpp" +#include "RouterContext.h" +#include "Transports.h" +#include "Tunnel.h" +#include "version.h" +#include "resource.h" +#include "Daemon.h" +#include "Win32App.h" +#include "Win32NetState.h" + +#define ID_ABOUT 2000 +#define ID_EXIT 2001 +#define ID_CONSOLE 2002 +#define ID_APP 2003 +#define ID_GRACEFUL_SHUTDOWN 2004 +#define ID_STOP_GRACEFUL_SHUTDOWN 2005 +#define ID_RELOAD 2006 +#define ID_ACCEPT_TRANSIT 2007 +#define ID_DECLINE_TRANSIT 2008 + +#define ID_TRAY_ICON 2050 +#define WM_TRAYICON (WM_USER + 1) + +#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100 +#define FRAME_UPDATE_TIMER 2101 +#define IDT_GRACEFUL_TUNNELCHECK_TIMER 2102 + +namespace i2p +{ +namespace win32 +{ + static DWORD GracefulShutdownEndtime = 0; + + typedef DWORD (* IPN)(); + IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); + + static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) + { + 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_ABOUT, "&About..."); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); + if(!i2p::context.AcceptsTunnels()) + InsertMenu (hPopup, -1, + i2p::util::DaemonWin32::Instance ().isGraceful ? MF_BYPOSITION | MF_STRING | MF_GRAYED : MF_BYPOSITION | MF_STRING, + ID_ACCEPT_TRANSIT, "Accept &transit"); + else + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_DECLINE_TRANSIT, "Decline &transit"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload tunnels config"); + if (!i2p::util::DaemonWin32::Instance ().isGraceful) + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); + else + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "Stop &graceful shutdown"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); + SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); + SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); + + POINT p; + if (!curpos) + { + GetCursorPos (&p); + curpos = &p; + } + + WORD cmd = TrackPopupMenu (hPopup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, curpos->x, curpos->y, 0, hWnd, NULL); + SendMessage (hWnd, WM_COMMAND, cmd, 0); + + DestroyMenu(hPopup); + } + + static void AddTrayIcon (HWND hWnd) + { + NOTIFYICONDATA nid; + memset(&nid, 0, sizeof(nid)); + nid.cbSize = sizeof(nid); + nid.hWnd = hWnd; + nid.uID = ID_TRAY_ICON; + nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON)); + strcpy (nid.szTip, "i2pd"); + strcpy (nid.szInfo, "i2pd is starting"); + Shell_NotifyIcon(NIM_ADD, &nid ); + } + + static void RemoveTrayIcon (HWND hWnd) + { + NOTIFYICONDATA nid; + nid.hWnd = hWnd; + nid.uID = ID_TRAY_ICON; + Shell_NotifyIcon (NIM_DELETE, &nid); + } + + static void ShowUptime (std::stringstream& s, int seconds) + { + int num; + + if ((num = seconds / 86400) > 0) { + s << num << " days, "; + seconds -= num * 86400; + } + if ((num = seconds / 3600) > 0) { + s << num << " hours, "; + seconds -= num * 3600; + } + if ((num = seconds / 60) > 0) { + s << num << " min, "; + seconds -= num * 60; + } + s << seconds << " seconds\n"; + } + + template static void ShowTransfered (std::stringstream& s, size transfer) + { + auto bytes = transfer & 0x03ff; + transfer >>= 10; + auto kbytes = transfer & 0x03ff; + transfer >>= 10; + auto mbytes = transfer & 0x03ff; + transfer >>= 10; + auto gbytes = transfer & 0x03ff; + + if (gbytes) + s << gbytes << " GB, "; + if (mbytes) + s << mbytes << " MB, "; + if (kbytes) + s << kbytes << " KB, "; + s << bytes << " Bytes\n"; + } + + static void PrintMainWindowText (std::stringstream& s) + { + s << "\n"; + s << "Status: "; + switch (i2p::context.GetStatus()) + { + 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 << "; "; + s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; + s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); + if (GracefulShutdownEndtime != 0) + { + DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000; + s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft); + } + else + s << "\n"; + s << "Inbound: " << i2p::transport::transports.GetInBandwidth() / 1024 << " KiB/s; "; + s << "Outbound: " << i2p::transport::transports.GetOutBandwidth() / 1024 << " KiB/s\n"; + s << "Received: "; ShowTransfered (s, i2p::transport::transports.GetTotalReceivedBytes()); + s << "Sent: "; ShowTransfered (s, i2p::transport::transports.GetTotalSentBytes()); + s << "\n"; + s << "Routers: " << i2p::data::netdb.GetNumRouters () << "; "; + s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << "; "; + s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "\n"; + s << "Tunnels: "; + s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; "; + s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; "; + s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n"; + s << "\n"; + } + + static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + static UINT s_uTaskbarRestart; + + switch (uMsg) + { + case WM_CREATE: + { + s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); + AddTrayIcon (hWnd); + break; + } + case WM_CLOSE: + { + RemoveTrayIcon (hWnd); + KillTimer (hWnd, FRAME_UPDATE_TIMER); + KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); + KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); + PostQuitMessage (0); + break; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_ABOUT: + { + std::stringstream text; + text << "Version: " << I2PD_VERSION << " " << CODENAME; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_EXIT: + { + PostMessage (hWnd, WM_CLOSE, 0, 0); + return 0; + } + case ID_ACCEPT_TRANSIT: + { + i2p::context.SetAcceptsTunnels (true); + std::stringstream text; + text << "I2Pd now accept transit tunnels"; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_DECLINE_TRANSIT: + { + i2p::context.SetAcceptsTunnels (false); + std::stringstream text; + text << "I2Pd now decline new transit tunnels"; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_GRACEFUL_SHUTDOWN: + { + i2p::context.SetAcceptsTunnels (false); + SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes + SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second + GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000; + i2p::util::DaemonWin32::Instance ().isGraceful = true; + return 0; + } + case ID_STOP_GRACEFUL_SHUTDOWN: + { + i2p::context.SetAcceptsTunnels (true); + KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); + KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); + GracefulShutdownEndtime = 0; + i2p::util::DaemonWin32::Instance ().isGraceful = false; + return 0; + } + case ID_RELOAD: + { + i2p::client::context.ReloadConfig(); + std::stringstream text; + text << "I2Pd reloading configs..."; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); + return 0; + } + case ID_CONSOLE: + { + char buf[30]; + std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort); + ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL); + return 0; + } + case ID_APP: + { + ShowWindow(hWnd, SW_SHOW); + SetTimer(hWnd, FRAME_UPDATE_TIMER, 3000, NULL); + return 0; + } + } + break; + } + case WM_SYSCOMMAND: + { + switch (wParam) + { + case SC_MINIMIZE: + { + ShowWindow(hWnd, SW_HIDE); + KillTimer (hWnd, FRAME_UPDATE_TIMER); + return 0; + } + case SC_CLOSE: + { + std::string close; i2p::config::GetOption("close", close); + if (0 == close.compare("ask")) + switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?" + " You can add 'close' configuration option. Valid values are: ask, minimize, exit.", + "Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1)) + { + case IDYES: close = "minimize"; break; + case IDNO: close = "exit"; break; + default: return 0; + } + if (0 == close.compare("minimize")) + { + ShowWindow(hWnd, SW_HIDE); + KillTimer (hWnd, FRAME_UPDATE_TIMER); + return 0; + } + if (0 != close.compare("exit")) + { + ::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING); + return 0; + } + } + } + } + case WM_TRAYICON: + { + switch (lParam) + { + case WM_LBUTTONUP: + case WM_RBUTTONUP: + { + SetForegroundWindow (hWnd); + ShowPopupMenu(hWnd, NULL, -1); + PostMessage (hWnd, WM_APP + 1, 0, 0); + break; + } + } + break; + } + case WM_TIMER: + { + switch(wParam) + { + case IDT_GRACEFUL_SHUTDOWN_TIMER: + { + GracefulShutdownEndtime = 0; + PostMessage (hWnd, WM_CLOSE, 0, 0); // exit + return 0; + } + case IDT_GRACEFUL_TUNNELCHECK_TIMER: + { + if (i2p::tunnel::tunnels.CountTransitTunnels() == 0) + PostMessage (hWnd, WM_CLOSE, 0, 0); + else + SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); + return 0; + } + case FRAME_UPDATE_TIMER: + { + InvalidateRect(hWnd, NULL, TRUE); + return 0; + } + } + break; + } + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + RECT rp; + HFONT hFont; + std::stringstream s; PrintMainWindowText (s); + hDC = BeginPaint (hWnd, &ps); + GetClientRect(hWnd, &rp); + SetTextColor(hDC, 0x00D43B69); + hFont = CreateFont(18,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0,TEXT("Times New Roman")); + SelectObject(hDC,hFont); + DrawText(hDC, TEXT(s.str().c_str()), s.str().length(), &rp, DT_CENTER|DT_VCENTER); + DeleteObject(hFont); + EndPaint(hWnd, &ps); + break; + } + default: + { + if (uMsg == s_uTaskbarRestart) + AddTrayIcon (hWnd); + break; + } + } + return DefWindowProc( hWnd, uMsg, wParam, lParam); + } + + bool StartWin32App () + { + if (FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"))) + { + MessageBox(NULL, TEXT("I2Pd is running already"), TEXT("Warning"), MB_OK); + return false; + } + // register main window + auto hInst = GetModuleHandle(NULL); + WNDCLASSEX wclx; + memset (&wclx, 0, sizeof(wclx)); + wclx.cbSize = sizeof(wclx); + wclx.style = 0; + wclx.lpfnWndProc = WndProc; + //wclx.cbClsExtra = 0; + //wclx.cbWndExtra = 0; + wclx.hInstance = hInst; + wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON)); + wclx.hCursor = LoadCursor (NULL, IDC_ARROW); + //wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wclx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wclx.lpszMenuName = NULL; + wclx.lpszClassName = I2PD_WIN32_CLASSNAME; + RegisterClassEx (&wclx); + // create new window + if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL)) + { + MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); + return false; + } + SubscribeToEvents(); + return true; + } + + int RunWin32App () + { + MSG msg; + while (GetMessage (&msg, NULL, 0, 0 )) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + return msg.wParam; + } + + void StopWin32App () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); + // UnSubscribeFromEvents(); // TODO: understand why unsubscribing crashes app + UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); + } + + bool GracefulShutdown () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0); + return hWnd; + } + + bool StopGracefulShutdown () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); + return hWnd; + } +} +} diff --git a/Win32/Win32App.h b/Win32/Win32App.h index b230eb06..23082842 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -1,17 +1,17 @@ -#ifndef WIN32APP_H__ -#define WIN32APP_H__ - -#define I2PD_WIN32_CLASSNAME "i2pd main window" - -namespace i2p -{ -namespace win32 -{ - bool StartWin32App (); - void StopWin32App (); - int RunWin32App (); - bool GracefulShutdown (); - bool StopGracefulShutdown (); -} -} -#endif // WIN32APP_H__ +#ifndef WIN32APP_H__ +#define WIN32APP_H__ + +#define I2PD_WIN32_CLASSNAME "i2pd main window" + +namespace i2p +{ +namespace win32 +{ + bool StartWin32App (); + void StopWin32App (); + int RunWin32App (); + bool GracefulShutdown (); + bool StopGracefulShutdown (); +} +} +#endif // WIN32APP_H__ diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h index 2830d237..05a6b9f9 100644 --- a/Win32/Win32Service.h +++ b/Win32/Win32Service.h @@ -26,48 +26,48 @@ class I2PService { -public: + public: - I2PService(PSTR pszServiceName, - BOOL fCanStop = TRUE, - BOOL fCanShutdown = TRUE, - BOOL fCanPauseContinue = FALSE); + I2PService(PSTR pszServiceName, + BOOL fCanStop = TRUE, + BOOL fCanShutdown = TRUE, + BOOL fCanPauseContinue = FALSE); - virtual ~I2PService(void); + virtual ~I2PService(void); - static BOOL isService(); - static BOOL Run(I2PService &service); - void Stop(); + static BOOL isService(); + static BOOL Run(I2PService &service); + void Stop(); -protected: + protected: - virtual void OnStart(DWORD dwArgc, PSTR *pszArgv); - virtual void OnStop(); - virtual void OnPause(); - virtual void OnContinue(); - virtual void OnShutdown(); - void SetServiceStatus(DWORD dwCurrentState, - DWORD dwWin32ExitCode = NO_ERROR, - DWORD dwWaitHint = 0); + virtual void OnStart(DWORD dwArgc, PSTR *pszArgv); + virtual void OnStop(); + virtual void OnPause(); + virtual void OnContinue(); + virtual void OnShutdown(); + void SetServiceStatus(DWORD dwCurrentState, + DWORD dwWin32ExitCode = NO_ERROR, + DWORD dwWaitHint = 0); -private: + private: - static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv); - static void WINAPI ServiceCtrlHandler(DWORD dwCtrl); - void WorkerThread(); - void Start(DWORD dwArgc, PSTR *pszArgv); - void Pause(); - void Continue(); - void Shutdown(); - static I2PService* s_service; - PSTR m_name; - SERVICE_STATUS m_status; - SERVICE_STATUS_HANDLE m_statusHandle; + static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv); + static void WINAPI ServiceCtrlHandler(DWORD dwCtrl); + void WorkerThread(); + void Start(DWORD dwArgc, PSTR *pszArgv); + void Pause(); + void Continue(); + void Shutdown(); + static I2PService* s_service; + PSTR m_name; + SERVICE_STATUS m_status; + SERVICE_STATUS_HANDLE m_statusHandle; - BOOL m_fStopping; - HANDLE m_hStoppedEvent; + BOOL m_fStopping; + HANDLE m_hStoppedEvent; - std::thread* _worker; + std::thread* _worker; }; void InstallService( @@ -77,8 +77,8 @@ void InstallService( PCSTR pszDependencies, PCSTR pszAccount, PCSTR pszPassword - ); +); void UninstallService(PCSTR pszServiceName); -#endif // WIN_32_SERVICE_H__ \ No newline at end of file +#endif // WIN_32_SERVICE_H__ diff --git a/Win32/resource.h b/Win32/resource.h index 3b188481..daa1ddcb 100644 --- a/Win32/resource.h +++ b/Win32/resource.h @@ -1,11 +1,11 @@ -//{{NO_DEPENDENCIES}} -#define MAINICON 101 - -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +#define MAINICON 101 + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index fc71123f..dd302fce 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -127,8 +127,8 @@ namespace i2p 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; @@ -143,8 +143,8 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - i2p::context.PublishNTCPAddress (ntcp, !ipv6); + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + i2p::context.PublishNTCPAddress (ntcp, !ipv6); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -172,10 +172,13 @@ namespace i2p SetMaxNumTransitTunnels (transitTunnels); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - if (isFloodfill) { + if (isFloodfill) + { LogPrint(eLogInfo, "Daemon: router will be floodfill"); i2p::context.SetFloodfill (true); - } else { + } + else + { i2p::context.SetFloodfill (false); } @@ -243,7 +246,8 @@ namespace i2p i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; } - if (routers.length() > 0) { + if (routers.length() > 0) + { std::set idents; size_t pos = 0, comma; do @@ -279,7 +283,8 @@ namespace i2p i2p::data::netdb.Start(); bool upnp; i2p::config::GetOption("upnp.enabled", upnp); - if (upnp) { + if (upnp) + { d.UPnP = std::unique_ptr(new i2p::transport::UPnP); d.UPnP->Start (); } @@ -292,15 +297,15 @@ namespace i2p } bool ntcp; i2p::config::GetOption("ntcp", ntcp); - bool ssu; i2p::config::GetOption("ssu", ssu); + bool ssu; i2p::config::GetOption("ssu", ssu); LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled"); i2p::transport::transports.Start(ntcp, ssu); - if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); - else + else { LogPrint(eLogError, "Daemon: failed to start Transports"); /** shut down netdb right away */ @@ -310,23 +315,23 @@ namespace i2p } bool http; i2p::config::GetOption("http.enabled", http); - if (http) { + if (http) + { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try + try { d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } - LogPrint(eLogInfo, "Daemon: starting Tunnels"); i2p::tunnel::tunnels.Start(); @@ -339,12 +344,12 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try + try { d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); @@ -361,7 +366,7 @@ namespace i2p LogPrint(eLogInfo, "Daemon: stopping Tunnels"); i2p::tunnel::tunnels.Stop(); - if (d.UPnP) + if (d.UPnP) { d.UPnP->Stop (); d.UPnP = nullptr; diff --git a/daemon/Daemon.h b/daemon/Daemon.h index 1745b980..050cc7e8 100644 --- a/daemon/Daemon.h +++ b/daemon/Daemon.h @@ -13,9 +13,10 @@ namespace util class Daemon_Singleton { public: - virtual bool init(int argc, char* argv[], std::shared_ptr logstream); - virtual bool init(int argc, char* argv[]); - virtual bool start(); + + virtual bool init(int argc, char* argv[], std::shared_ptr logstream); + virtual bool init(int argc, char* argv[]); + virtual bool start(); virtual bool stop(); virtual void run () {}; @@ -23,6 +24,7 @@ namespace util bool running; protected: + Daemon_Singleton(); virtual ~Daemon_Singleton(); @@ -39,6 +41,7 @@ namespace util class DaemonQT: public i2p::util::Daemon_Singleton { public: + static DaemonQT& Instance() { static DaemonQT instance; @@ -51,6 +54,7 @@ namespace util class DaemonWin32 : public Daemon_Singleton { public: + static DaemonWin32& Instance() { static DaemonWin32 instance; @@ -72,6 +76,7 @@ namespace util class DaemonAndroid: public i2p::util::Daemon_Singleton { public: + static DaemonAndroid& Instance() { static DaemonAndroid instance; @@ -83,6 +88,7 @@ namespace util class DaemonLinux : public Daemon_Singleton { public: + static DaemonLinux& Instance() { static DaemonLinux instance; @@ -94,10 +100,12 @@ namespace util void run (); private: + std::string pidfile; int pidFH; public: + int gracefulShutdownInterval; // in seconds }; #endif diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index de052a2b..6f903e7e 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -892,8 +892,8 @@ namespace http { void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), - std::bind(&HTTPConnection::HandleReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&HTTPConnection::HandleReceive, shared_from_this (), + std::placeholders::_1, std::placeholders::_2)); } void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index abc4fea5..fe62c271 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -79,17 +79,17 @@ namespace http std::string m_Hostname; }; - //all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml - enum OutputFormatEnum { forWebConsole, forQtUi }; - void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat); - void ShowLocalDestinations (std::stringstream& s); - void ShowLeasesSets(std::stringstream& s); - void ShowTunnels (std::stringstream& s); - void ShowTransitTunnels (std::stringstream& s); - void ShowTransports (std::stringstream& s); - void ShowSAMSessions (std::stringstream& s); - void ShowI2PTunnels (std::stringstream& s); - void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); + //all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml + enum OutputFormatEnum { forWebConsole, forQtUi }; + void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat); + void ShowLocalDestinations (std::stringstream& s); + void ShowLeasesSets(std::stringstream& s); + void ShowTunnels (std::stringstream& s); + void ShowTransitTunnels (std::stringstream& s); + void ShowTransports (std::stringstream& s); + void ShowSAMSessions (std::stringstream& s); + void ShowI2PTunnels (std::stringstream& s); + void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); } // http } // i2p diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index acf054f1..fb00dc29 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -59,29 +59,28 @@ namespace client m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem); // handlers - m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; - m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; - m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; - m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; - m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; - m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; - m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; + m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; + m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; + m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; + m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; + m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; + m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; + m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; // I2PControl m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler; // RouterInfo - m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; - m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; - m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; - m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; - m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; - m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; + m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; + m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; + m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; + m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; + m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; + m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler; - m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = -&I2PControlService::TunnelsSuccessRateHandler; + m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler; m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes; m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes; @@ -97,10 +96,10 @@ namespace client // ClientServicesInfo m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler; m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler; - m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; - m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; - m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; - m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; + m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; + m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; + m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; + m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; } I2PControlService::~I2PControlService () @@ -401,8 +400,8 @@ namespace client auto it1 = m_RouterInfoHandlers.find (it->first); if (it1 != m_RouterInfoHandlers.end ()) { - if (!first) results << ","; - else first = false; + if (!first) results << ","; + else first = false; (this->*(it1->second))(results); } else @@ -500,7 +499,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } @@ -514,7 +513,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } diff --git a/daemon/I2PControl.h b/daemon/I2PControl.h index 3233ad12..eb28af76 100644 --- a/daemon/I2PControl.h +++ b/daemon/I2PControl.h @@ -27,6 +27,7 @@ namespace client class I2PControlService { typedef boost::asio::ssl::stream ssl_socket; + public: I2PControlService (const std::string& address, int port); diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index b2ebb005..92e79c11 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -80,10 +80,10 @@ namespace transport void UPnP::Discover () { bool isError; - int err; + int err; #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) - err = UPNPDISCOVER_SUCCESS; + err = UPNPDISCOVER_SUCCESS; #if (MINIUPNPC_API_VERSION >= 14) m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err); @@ -92,9 +92,9 @@ namespace transport #endif isError = err != UPNPDISCOVER_SUCCESS; -#else // MINIUPNPC_API_VERSION >= 8 - err = 0; - m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); +#else // MINIUPNPC_API_VERSION >= 8 + err = 0; + m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); isError = m_Devlist == NULL; #endif // MINIUPNPC_API_VERSION >= 8 { @@ -105,15 +105,15 @@ namespace transport if (isError) { - LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); + LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); return; } err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); - m_upnpUrlsInitialized=err!=0; + m_upnpUrlsInitialized = err != 0; if (err == UPNP_IGD_VALID_CONNECTED) { - err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(err != UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: unable to get external address: error ", err); @@ -124,14 +124,14 @@ namespace transport LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL); if (!m_externalIPAddress[0]) { - LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); + LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); return; } } } else { - LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); + LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); return; } @@ -182,7 +182,7 @@ namespace transport err = CheckMapping (strPort.c_str (), strType.c_str ()); if (err != UPNPCOMMAND_SUCCESS) // if mapping not found { - LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); + LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL); @@ -202,7 +202,7 @@ namespace transport } else { - LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); + LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); return; } } @@ -219,14 +219,14 @@ namespace transport void UPnP::CloseMapping (std::shared_ptr address) { - if(!m_upnpUrlsInitialized) { - return; - } + if(!m_upnpUrlsInitialized) { + return; + } std::string strType (GetProto (address)), strPort (std::to_string (address->port)); int err = UPNPCOMMAND_SUCCESS; - + err = CheckMapping (strPort.c_str (), strType.c_str ()); - if (err == UPNPCOMMAND_SUCCESS) + if (err == UPNPCOMMAND_SUCCESS) { err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL); LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err); @@ -237,11 +237,11 @@ namespace transport { freeUPNPDevlist (m_Devlist); m_Devlist = 0; - if(m_upnpUrlsInitialized){ - FreeUPNPUrls (&m_upnpUrls); - m_upnpUrlsInitialized=false; - } - } + if(m_upnpUrlsInitialized){ + FreeUPNPUrls (&m_upnpUrls); + m_upnpUrlsInitialized=false; + } + } std::string UPnP::GetProto (std::shared_ptr address) { diff --git a/daemon/UPnP.h b/daemon/UPnP.h index e66f0aff..29f9e3e6 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -33,41 +33,41 @@ namespace transport { public: - UPnP (); - ~UPnP (); - void Close (); + UPnP (); + ~UPnP (); + void Close (); - void Start (); - void Stop (); + void Start (); + void Stop (); private: - void Discover (); - int CheckMapping (const char* port, const char* type); - void PortMapping (); - void TryPortMapping (std::shared_ptr address); - void CloseMapping (); - void CloseMapping (std::shared_ptr address); + void Discover (); + int CheckMapping (const char* port, const char* type); + void PortMapping (); + void TryPortMapping (std::shared_ptr address); + void CloseMapping (); + void CloseMapping (std::shared_ptr address); - void Run (); - std::string GetProto (std::shared_ptr address); + void Run (); + std::string GetProto (std::shared_ptr address); private: - bool m_IsRunning; - std::unique_ptr m_Thread; - std::condition_variable m_Started; - std::mutex m_StartedMutex; - boost::asio::io_service m_Service; - boost::asio::deadline_timer m_Timer; - bool m_upnpUrlsInitialized=false; - struct UPNPUrls m_upnpUrls; - struct IGDdatas m_upnpData; + bool m_IsRunning; + std::unique_ptr m_Thread; + std::condition_variable m_Started; + std::mutex m_StartedMutex; + boost::asio::io_service m_Service; + boost::asio::deadline_timer m_Timer; + bool m_upnpUrlsInitialized = false; + struct UPNPUrls m_upnpUrls; + struct IGDdatas m_upnpData; - // For miniupnpc - struct UPNPDev * m_Devlist = 0; - char m_NetworkAddr[64]; - char m_externalIPAddress[40]; + // For miniupnpc + struct UPNPDev * m_Devlist = 0; + char m_NetworkAddr[64]; + char m_externalIPAddress[40]; }; } } @@ -79,10 +79,10 @@ namespace transport { class UPnP { public: - UPnP () {}; - ~UPnP () {}; - void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); } - void Stop () {}; + UPnP () {}; + ~UPnP () {}; + void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); } + void Stop () {}; }; } } diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index b7af779c..a59fc693 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -196,5 +196,4 @@ namespace i2p } } } - #endif diff --git a/daemon/i2pd.cpp b/daemon/i2pd.cpp index 425c2560..7b68c073 100644 --- a/daemon/i2pd.cpp +++ b/daemon/i2pd.cpp @@ -2,7 +2,6 @@ #include "Daemon.h" #if defined(QT_GUI_LIB) - namespace i2p { namespace qt @@ -10,11 +9,11 @@ namespace qt int RunQT (int argc, char* argv[]); } } + int main( int argc, char* argv[] ) { return i2p::qt::RunQT (argc, argv); } - #else int main( int argc, char* argv[] ) { diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index f80f2751..51f5f225 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -7,7 +7,8 @@ namespace i2p { namespace data { - static const char T32[32] = { + static const char T32[32] = + { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', @@ -29,15 +30,16 @@ namespace data * Direct Substitution Table */ - static const char T64[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '-', '~' + static const char T64[64] = + { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '~' }; const char * GetBase64SubstitutionTable () @@ -67,14 +69,12 @@ namespace data * */ - size_t /* Number of bytes in the encoded buffer */ - ByteStreamToBase64 ( - const uint8_t * InBuffer, /* Input buffer, binary data */ - size_t InCount, /* Number of bytes in the input buffer */ - char * OutBuffer, /* output buffer */ - size_t len /* length of output buffer */ + size_t ByteStreamToBase64 ( /* Number of bytes in the encoded buffer */ + const uint8_t * InBuffer, /* Input buffer, binary data */ + size_t InCount, /* Number of bytes in the input buffer */ + char * OutBuffer, /* output buffer */ + size_t len /* length of output buffer */ ) - { unsigned char * ps; unsigned char * pd; @@ -83,55 +83,60 @@ namespace data int i; int n; int m; - size_t outCount; + size_t outCount; ps = (unsigned char *)InBuffer; - n = InCount/3; - m = InCount%3; + n = InCount / 3; + m = InCount % 3; if (!m) - outCount = 4*n; + outCount = 4 * n; else - outCount = 4*(n+1); + outCount = 4 * (n + 1); + if (outCount > len) return 0; + pd = (unsigned char *)OutBuffer; - for ( i = 0; i>= 2; /* base64 digit #1 */ - *pd++ = T64[acc_1]; - acc_1 = *ps++; - acc_2 |= acc_1 >> 4; /* base64 digit #2 */ - *pd++ = T64[acc_2]; - acc_1 &= 0x0f; - acc_1 <<=2; - acc_2 = *ps++; - acc_1 |= acc_2>>6; /* base64 digit #3 */ - *pd++ = T64[acc_1]; - acc_2 &= 0x3f; /* base64 digit #4 */ - *pd++ = T64[acc_2]; + for ( i = 0; i < n; i++ ) + { + acc_1 = *ps++; + acc_2 = (acc_1 << 4) & 0x30; + acc_1 >>= 2; /* base64 digit #1 */ + *pd++ = T64[acc_1]; + acc_1 = *ps++; + acc_2 |= acc_1 >> 4; /* base64 digit #2 */ + *pd++ = T64[acc_2]; + acc_1 &= 0x0f; + acc_1 <<= 2; + acc_2 = *ps++; + acc_1 |= acc_2 >> 6; /* base64 digit #3 */ + *pd++ = T64[acc_1]; + acc_2 &= 0x3f; /* base64 digit #4 */ + *pd++ = T64[acc_2]; } - if ( m == 1 ){ - acc_1 = *ps++; - acc_2 = (acc_1<<4)&0x3f; /* base64 digit #2 */ - acc_1 >>= 2; /* base64 digit #1 */ - *pd++ = T64[acc_1]; - *pd++ = T64[acc_2]; - *pd++ = P64; - *pd++ = P64; + if ( m == 1 ) + { + acc_1 = *ps++; + acc_2 = (acc_1 << 4) & 0x3f; /* base64 digit #2 */ + acc_1 >>= 2; /* base64 digit #1 */ + *pd++ = T64[acc_1]; + *pd++ = T64[acc_2]; + *pd++ = P64; + *pd++ = P64; } - else if ( m == 2 ){ - acc_1 = *ps++; - acc_2 = (acc_1<<4)&0x3f; - acc_1 >>= 2; /* base64 digit #1 */ - *pd++ = T64[acc_1]; - acc_1 = *ps++; - acc_2 |= acc_1 >> 4; /* base64 digit #2 */ - *pd++ = T64[acc_2]; - acc_1 &= 0x0f; - acc_1 <<=2; /* base64 digit #3 */ - *pd++ = T64[acc_1]; - *pd++ = P64; + else if ( m == 2 ) + { + acc_1 = *ps++; + acc_2 = (acc_1 << 4) & 0x3f; + acc_1 >>= 2; /* base64 digit #1 */ + *pd++ = T64[acc_1]; + acc_1 = *ps++; + acc_2 |= acc_1 >> 4; /* base64 digit #2 */ + *pd++ = T64[acc_2]; + acc_1 &= 0x0f; + acc_1 <<= 2; /* base64 digit #3 */ + *pd++ = T64[acc_1]; + *pd++ = P64; } return outCount; @@ -147,12 +152,11 @@ namespace data * */ - size_t /* Number of output bytes */ - Base64ToByteStream ( - const char * InBuffer, /* BASE64 encoded buffer */ - size_t InCount, /* Number of input bytes */ - uint8_t * OutBuffer, /* output buffer length */ - size_t len /* length of output buffer */ + size_t Base64ToByteStream ( /* Number of output bytes */ + const char * InBuffer, /* BASE64 encoded buffer */ + size_t InCount, /* Number of input bytes */ + uint8_t * OutBuffer, /* output buffer length */ + size_t len /* length of output buffer */ ) { unsigned char * ps; @@ -162,42 +166,52 @@ namespace data int i; int n; int m; - size_t outCount; + size_t outCount; + + if (isFirstTime) + iT64Build(); + + n = InCount / 4; + m = InCount % 4; - if (isFirstTime) iT64Build(); - n = InCount/4; - m = InCount%4; if (InCount && !m) - outCount = 3*n; - else { - outCount = 0; - return 0; + outCount = 3 * n; + else + { + outCount = 0; + return 0; } ps = (unsigned char *)(InBuffer + InCount - 1); - while ( *ps-- == P64 ) outCount--; + while ( *ps-- == P64 ) + outCount--; ps = (unsigned char *)InBuffer; - if (outCount > len) return -1; + if (outCount > len) + return -1; + pd = OutBuffer; auto endOfOutBuffer = OutBuffer + outCount; - for ( i = 0; i < n; i++ ){ - acc_1 = iT64[*ps++]; - acc_2 = iT64[*ps++]; - acc_1 <<= 2; - acc_1 |= acc_2>>4; - *pd++ = acc_1; - if (pd >= endOfOutBuffer) break; + for ( i = 0; i < n; i++ ) + { + acc_1 = iT64[*ps++]; + acc_2 = iT64[*ps++]; + acc_1 <<= 2; + acc_1 |= acc_2 >> 4; + *pd++ = acc_1; + if (pd >= endOfOutBuffer) + break; - acc_2 <<= 4; - acc_1 = iT64[*ps++]; - acc_2 |= acc_1 >> 2; - *pd++ = acc_2; - if (pd >= endOfOutBuffer) break; + acc_2 <<= 4; + acc_1 = iT64[*ps++]; + acc_2 |= acc_1 >> 2; + *pd++ = acc_2; + if (pd >= endOfOutBuffer) + break; - acc_2 = iT64[*ps++]; - acc_2 |= acc_1 << 6; - *pd++ = acc_2; + acc_2 = iT64[*ps++]; + acc_2 |= acc_1 << 6; + *pd++ = acc_2; } return outCount; @@ -206,20 +220,25 @@ namespace data size_t Base64EncodingBufferSize (const size_t input_size) { auto d = div (input_size, 3); - if (d.rem) d.quot++; - return 4*d.quot; + if (d.rem) + d.quot++; + + return 4 * d.quot; } std::string ToBase64Standard (const std::string& in) { - auto len = Base64EncodingBufferSize (in.length ()); - char * str = new char[len+1]; + auto len = Base64EncodingBufferSize (in.length ()); + char * str = new char[len + 1]; auto l = ByteStreamToBase64 ((const uint8_t *)in.c_str (), in.length (), str, len); str[l] = 0; // replace '-' by '+' and '~' by '/' for (size_t i = 0; i < l; i++) - if (str[i] == '-') str[i] = '+'; - else if (str[i] == '~') str[i] = '/'; + if (str[i] == '-') + str[i] = '+'; + else if (str[i] == '~') + str[i] = '/'; + std::string s(str); delete[] str; return s; @@ -236,10 +255,10 @@ namespace data static void iT64Build() { - int i; + int i; isFirstTime = 0; - for ( i=0; i<256; i++ ) iT64[i] = -1; - for ( i=0; i<64; i++ ) iT64[(int)T64[i]] = i; + for ( i = 0; i < 256; i++ ) iT64[i] = -1; + for ( i = 0; i < 64; i++ ) iT64[(int)T64[i]] = i; iT64[(int)P64] = 0; } @@ -302,4 +321,3 @@ namespace data } } } - diff --git a/libi2pd/Base.h b/libi2pd/Base.h index a273f468..5d550092 100644 --- a/libi2pd/Base.h +++ b/libi2pd/Base.h @@ -15,13 +15,13 @@ namespace data { size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen); size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen); - /** - Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes - */ + /** + Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes + */ size_t Base64EncodingBufferSize(const size_t input_size); - - std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization - + + std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization + } // data } // i2p diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 8d3f4b40..287d3648 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -17,21 +17,21 @@ namespace i2p namespace data { static EC_POINT * BlindPublicKeyECDSA (const EC_GROUP * group, const EC_POINT * pub, const uint8_t * seed) - { + { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - BIGNUM * q = BN_CTX_get (ctx); + BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order (group, q, ctx); // calculate alpha = seed mod q BIGNUM * alpha = BN_CTX_get (ctx); - BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian BN_mod (alpha, alpha, q, ctx); // % q // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha) auto p = EC_POINT_new (group); EC_POINT_mul (group, p, alpha, nullptr, nullptr, ctx); // B*alpha EC_POINT_add (group, p, pub, p, ctx); // pub + B*alpha BN_CTX_end (ctx); - BN_CTX_free (ctx); + BN_CTX_free (ctx); return p; } @@ -39,18 +39,18 @@ namespace data { BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - BIGNUM * q = BN_CTX_get (ctx); + BIGNUM * q = BN_CTX_get (ctx); EC_GROUP_get_order (group, q, ctx); // calculate alpha = seed mod q BIGNUM * alpha = BN_CTX_get (ctx); - BN_bin2bn (seed, 64, alpha); // seed is in BigEndian - BN_mod (alpha, alpha, q, ctx); // % q + BN_bin2bn (seed, 64, alpha); // seed is in BigEndian + BN_mod (alpha, alpha, q, ctx); // % q BN_add (alpha, alpha, priv); // alpha = alpha + priv - // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod q + // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod q BN_mod (blindedPriv, alpha, q, ctx); // % q BN_CTX_end (ctx); BN_CTX_free (ctx); - } + } static void BlindEncodedPublicKeyECDSA (size_t publicKeyLen, const EC_GROUP * group, const uint8_t * pub, const uint8_t * seed, uint8_t * blindedPub) { @@ -63,7 +63,7 @@ namespace data EC_POINT_get_affine_coordinates_GFp (group, p1, x, y, NULL); EC_POINT_free (p1); i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); - i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); + i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); BN_free (x); BN_free (y); } @@ -85,7 +85,7 @@ namespace data i2p::crypto::bn2buf (x, blindedPub, publicKeyLen/2); i2p::crypto::bn2buf (y, blindedPub + publicKeyLen/2, publicKeyLen/2); BN_free (x); BN_free (y); - } + } template static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args) @@ -97,7 +97,7 @@ namespace data { case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: { - publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; + publicKeyLength = i2p::crypto::ECDSAP256_KEY_LENGTH; group = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1); break; } @@ -116,18 +116,18 @@ namespace data default: LogPrint (eLogError, "Blinding: signature type ", (int)sigType, " is not ECDSA"); } - if (group) + if (group) { blind (publicKeyLength, group, key, seed, std::forward(args)...); EC_GROUP_free (group); - } + } return publicKeyLength; } //---------------------------------------------------------- const uint8_t B33_TWO_BYTES_SIGTYPE_FLAG = 0x01; - const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now + const uint8_t B33_PER_SECRET_FLAG = 0x02; // not used for now const uint8_t B33_PER_CLIENT_AUTH_FLAG = 0x04; BlindedPublicKey::BlindedPublicKey (std::shared_ptr identity, bool clientAuth): @@ -138,7 +138,7 @@ namespace data m_PublicKey.resize (len); memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); m_SigType = identity->GetSigningKeyType (); - m_BlindedSigType = m_SigType; + m_BlindedSigType = m_SigType; } BlindedPublicKey::BlindedPublicKey (const std::string& b33): @@ -150,12 +150,12 @@ namespace data { LogPrint (eLogError, "Blinding: malformed b33 ", b33); return; - } - uint32_t checksum = crc32 (0, addr + 3, l - 3); + } + uint32_t checksum = crc32 (0, addr + 3, l - 3); // checksum is Little Endian - addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); + addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); uint8_t flags = addr[0]; - size_t offset = 1; + size_t offset = 1; if (flags & B33_TWO_BYTES_SIGTYPE_FLAG) // two bytes signatures { m_SigType = bufbe16toh (addr + offset); offset += 2; @@ -178,7 +178,7 @@ namespace data memcpy (m_PublicKey.data (), addr + offset, len); } else - LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType); + LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType); } else LogPrint (eLogError, "Blinding: unknown signature type ", (int)m_SigType, " in b33"); @@ -189,25 +189,25 @@ namespace data if (m_PublicKey.size () > 32) return ""; // assume 25519 uint8_t addr[35]; char str[60]; // TODO: define actual length uint8_t flags = 0; - if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG; + if (m_IsClientAuth) flags |= B33_PER_CLIENT_AUTH_FLAG; addr[0] = flags; // flags addr[1] = m_SigType; // sig type addr[2] = m_BlindedSigType; // blinded sig type memcpy (addr + 3, m_PublicKey.data (), m_PublicKey.size ()); - uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); + uint32_t checksum = crc32 (0, addr + 3, m_PublicKey.size ()); // checksum is Little Endian - addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); + addr[0] ^= checksum; addr[1] ^= (checksum >> 8); addr[2] ^= (checksum >> 16); auto l = ByteStreamToBase32 (addr, m_PublicKey.size () + 3, str, 60); return std::string (str, str + l); } void BlindedPublicKey::GetCredential (uint8_t * credential) const { - // A = destination's signing public key + // A = destination's signing public key // stA = signature type of A, 2 bytes big endian uint16_t stA = htobe16 (GetSigType ()); // stA1 = signature type of blinded A, 2 bytes big endian - uint16_t stA1 = htobe16 (GetBlindedSigType ()); + uint16_t stA1 = htobe16 (GetBlindedSigType ()); // credential = H("credential", A || stA || stA1) H ("credential", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, credential); } @@ -224,15 +224,15 @@ namespace data { uint16_t stA = htobe16 (GetSigType ()), stA1 = htobe16 (GetBlindedSigType ()); uint8_t salt[32]; - //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) + //seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64) H ("I2PGenerateAlpha", { {GetPublicKey (), GetPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt); i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed); } size_t BlindedPublicKey::GetBlindedKey (const char * date, uint8_t * blindedKey) const { - uint8_t seed[64]; - GenerateAlpha (date, seed); + uint8_t seed[64]; + GenerateAlpha (date, seed); size_t publicKeyLength = 0; switch (m_SigType) @@ -244,7 +244,7 @@ namespace data break; case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: - i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); + i2p::crypto::GetEd25519 ()->BlindPublicKey (GetPublicKey (), seed, blindedKey); publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; break; default: @@ -255,8 +255,8 @@ namespace data size_t BlindedPublicKey::BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const { - uint8_t seed[64]; - GenerateAlpha (date, seed); + uint8_t seed[64]; + GenerateAlpha (date, seed); size_t publicKeyLength = 0; switch (m_SigType) { @@ -272,15 +272,15 @@ namespace data default: LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType); } - return publicKeyLength; + return publicKeyLength; } - void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const + void BlindedPublicKey::H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const { SHA256_CTX ctx; SHA256_Init (&ctx); SHA256_Update (&ctx, p.c_str (), p.length ()); - for (const auto& it: bufs) + for (const auto& it: bufs) SHA256_Update (&ctx, it.first, it.second); SHA256_Final (hash, &ctx); } @@ -289,15 +289,15 @@ namespace data { i2p::data::IdentHash hash; uint8_t blinded[128]; - size_t publicKeyLength = 0; + size_t publicKeyLength = 0; if (date) publicKeyLength = GetBlindedKey (date, blinded); else { char currentDate[9]; i2p::util::GetCurrentDate (currentDate); - publicKeyLength = GetBlindedKey (currentDate, blinded); - } + publicKeyLength = GetBlindedKey (currentDate, blinded); + } if (publicKeyLength) { auto stA1 = htobe16 (m_BlindedSigType); @@ -308,10 +308,9 @@ namespace data SHA256_Final ((uint8_t *)hash, &ctx); } else - LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported"); + LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported"); return hash; } } } - diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 65b8c0f8..3e0ad3fc 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -15,7 +15,7 @@ namespace data public: BlindedPublicKey (std::shared_ptr identity, bool clientAuth = false); - BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p + BlindedPublicKey (const std::string& b33); // from b33 without .b32.i2p std::string ToB33 () const; const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; @@ -25,14 +25,14 @@ namespace data bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes - size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length - size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length + size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length + size_t BlindPrivateKey (const uint8_t * priv, const char * date, uint8_t * blindedPriv, uint8_t * blindedPub) const; // date is 8 chars "YYYYMMDD", return public key length i2p::data::IdentHash GetStoreHash (const char * date = nullptr) const; // date is 8 chars "YYYYMMDD", use current if null private: void GetCredential (uint8_t * credential) const; // 32 bytes - void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD" + void GenerateAlpha (const char * date, uint8_t * seed) const; // 64 bytes, date is 8 chars "YYYYMMDD" void H (const std::string& p, const std::vector >& bufs, uint8_t * hash) const; private: diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index b4c19607..e1fd450c 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -5,10 +5,10 @@ namespace i2p { namespace cpu { - extern bool aesni; - extern bool avx; + extern bool aesni; + extern bool avx; - void Detect(); + void Detect(); } } diff --git a/libi2pd/ChaCha20.cpp b/libi2pd/ChaCha20.cpp index 222111b7..1d1e9bc6 100644 --- a/libi2pd/ChaCha20.cpp +++ b/libi2pd/ChaCha20.cpp @@ -12,73 +12,72 @@ #include "I2PEndian.h" #include "ChaCha20.h" -#if !OPENSSL_AEAD_CHACHA20_POLY1305 +#if !OPENSSL_AEAD_CHACHA20_POLY1305 namespace i2p { namespace crypto { namespace chacha { -void u32t8le(uint32_t v, uint8_t * p) +void u32t8le(uint32_t v, uint8_t * p) { - p[0] = v & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; + p[0] = v & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; } -uint32_t u8t32le(const uint8_t * p) +uint32_t u8t32le(const uint8_t * p) { - uint32_t value = p[3]; + uint32_t value = p[3]; - value = (value << 8) | p[2]; - value = (value << 8) | p[1]; - value = (value << 8) | p[0]; + value = (value << 8) | p[2]; + value = (value << 8) | p[1]; + value = (value << 8) | p[0]; - return value; + return value; } -uint32_t rotl32(uint32_t x, int n) +uint32_t rotl32(uint32_t x, int n) { - return x << n | (x >> (-n & 31)); + return x << n | (x >> (-n & 31)); } -void quarterround(uint32_t *x, int a, int b, int c, int d) +void quarterround(uint32_t *x, int a, int b, int c, int d) { - x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16); - x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12); - x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8); - x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7); + x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16); + x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12); + x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8); + x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7); } void Chacha20Block::operator << (const Chacha20State & st) { int i; - for (i = 0; i < 16; i++) + for (i = 0; i < 16; i++) u32t8le(st.data[i], data + (i << 2)); } void block (Chacha20State &input, int rounds) { - int i; - Chacha20State x; - x.Copy(input); - - for (i = rounds; i > 0; i -= 2) - { - quarterround(x.data, 0, 4, 8, 12); - quarterround(x.data, 1, 5, 9, 13); - quarterround(x.data, 2, 6, 10, 14); - quarterround(x.data, 3, 7, 11, 15); - quarterround(x.data, 0, 5, 10, 15); - quarterround(x.data, 1, 6, 11, 12); - quarterround(x.data, 2, 7, 8, 13); - quarterround(x.data, 3, 4, 9, 14); - } - x += input; - input.block << x; + int i; + Chacha20State x; + x.Copy(input); + for (i = rounds; i > 0; i -= 2) + { + quarterround(x.data, 0, 4, 8, 12); + quarterround(x.data, 1, 5, 9, 13); + quarterround(x.data, 2, 6, 10, 14); + quarterround(x.data, 3, 7, 11, 15); + quarterround(x.data, 0, 5, 10, 15); + quarterround(x.data, 1, 6, 11, 12); + quarterround(x.data, 2, 7, 8, 13); + quarterround(x.data, 3, 4, 9, 14); + } + x += input; + input.block << x; } void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter) @@ -87,52 +86,52 @@ void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * state.data[1] = 0x3320646e; state.data[2] = 0x79622d32; state.data[3] = 0x6b206574; - for (size_t i = 0; i < 8; i++) - state.data[4 + i] = chacha::u8t32le(key + i * 4); - + for (size_t i = 0; i < 8; i++) + state.data[4 + i] = chacha::u8t32le(key + i * 4); + state.data[12] = htole32 (counter); - for (size_t i = 0; i < 3; i++) - state.data[13 + i] = chacha::u8t32le(nonce + i * 4); + for (size_t i = 0; i < 3; i++) + state.data[13 + i] = chacha::u8t32le(nonce + i * 4); } void Chacha20SetCounter (Chacha20State& state, uint32_t counter) { state.data[12] = htole32 (counter); state.offset = 0; -} +} void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz) -{ +{ if (state.offset > 0) { - // previous block if any - auto s = chacha::blocksize - state.offset; + // previous block if any + auto s = chacha::blocksize - state.offset; if (sz < s) s = sz; for (size_t i = 0; i < s; i++) buf[i] ^= state.block.data[state.offset + i]; buf += s; sz -= s; state.offset += s; - if (state.offset >= chacha::blocksize) state.offset = 0; + if (state.offset >= chacha::blocksize) state.offset = 0; } - for (size_t i = 0; i < sz; i += chacha::blocksize) + for (size_t i = 0; i < sz; i += chacha::blocksize) { - chacha::block(state, chacha::rounds); - state.data[12]++; - for (size_t j = i; j < i + chacha::blocksize; j++) - { - if (j >= sz) + chacha::block(state, chacha::rounds); + state.data[12]++; + for (size_t j = i; j < i + chacha::blocksize; j++) + { + if (j >= sz) { state.offset = j & 0x3F; // % 64 break; } - buf[j] ^= state.block.data[j - i]; - } + buf[j] ^= state.block.data[j - i]; + } } } + } // namespace chacha +} // namespace crypto +} // namespace i2p -} -} #endif - diff --git a/libi2pd/ChaCha20.h b/libi2pd/ChaCha20.h index b2eec320..a8bb1d56 100644 --- a/libi2pd/ChaCha20.h +++ b/libi2pd/ChaCha20.h @@ -21,23 +21,23 @@ namespace i2p { namespace crypto { - const std::size_t CHACHA20_KEY_BYTES = 32; - const std::size_t CHACHA20_NOUNCE_BYTES = 12; - + const std::size_t CHACHA20_KEY_BYTES = 32; + const std::size_t CHACHA20_NOUNCE_BYTES = 12; + namespace chacha { - constexpr std::size_t blocksize = 64; + constexpr std::size_t blocksize = 64; constexpr int rounds = 20; struct Chacha20State; struct Chacha20Block { - Chacha20Block () {}; - Chacha20Block (Chacha20Block &&) = delete; + Chacha20Block () {}; + Chacha20Block (Chacha20Block &&) = delete; - uint8_t data[blocksize]; + uint8_t data[blocksize]; - void operator << (const Chacha20State & st); + void operator << (const Chacha20State & st); }; struct Chacha20State @@ -54,19 +54,19 @@ namespace chacha void Copy(const Chacha20State & other) { - memcpy(data, other.data, sizeof(uint32_t) * 16); + memcpy(data, other.data, sizeof(uint32_t) * 16); } uint32_t data[16]; Chacha20Block block; - size_t offset; + size_t offset; }; void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter); void Chacha20SetCounter (Chacha20State& state, uint32_t counter); - void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place -} -} -} -#endif + void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place +} // namespace chacha +} // namespace crypto +} // namespace i2p #endif +#endif diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b741b118..59b51c00 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -242,7 +242,7 @@ namespace config { "1.pool.ntp.org," "2.pool.ntp.org," "3.pool.ntp.org" - ), "Comma separated list of NTCP servers") + ), "Comma separated list of NTCP servers") ("nettime.ntpsyncinterval", value()->default_value(72), "NTP sync interval in hours (default: 72)") ; diff --git a/libi2pd/Config.h b/libi2pd/Config.h index 679ae3bb..679795b1 100644 --- a/libi2pd/Config.h +++ b/libi2pd/Config.h @@ -18,98 +18,101 @@ namespace i2p { namespace config { - extern boost::program_options::variables_map m_Options; + extern boost::program_options::variables_map m_Options; - /** - * @brief Initialize list of acceptable parameters - * - * Should be called before any Parse* functions. - */ - void Init(); + /** + * @brief Initialize list of acceptable parameters + * + * Should be called before any Parse* functions. + */ + void Init(); - /** - * @brief Parse cmdline parameters, and show help if requested - * @param argc Cmdline arguments count, should be passed from main(). - * @param argv Cmdline parameters array, should be passed from main() - * - * If --help is given in parameters, shows its list with description - * and terminates the program with exitcode 0. - * - * In case of parameter misuse boost throws an exception. - * We internally handle type boost::program_options::unknown_option, - * and then terminate the program with exitcode 1. - * - * Other exceptions will be passed to higher level. - */ - void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false); + /** + * @brief Parse cmdline parameters, and show help if requested + * @param argc Cmdline arguments count, should be passed from main(). + * @param argv Cmdline parameters array, should be passed from main() + * + * If --help is given in parameters, shows its list with description + * and terminates the program with exitcode 0. + * + * In case of parameter misuse boost throws an exception. + * We internally handle type boost::program_options::unknown_option, + * and then terminate the program with exitcode 1. + * + * Other exceptions will be passed to higher level. + */ + void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false); - /** - * @brief Load and parse given config file - * @param path Path to config file - * - * If error occurred when opening file path is points to, - * we show the error message and terminate program. - * - * In case of parameter misuse boost throws an exception. - * We internally handle type boost::program_options::unknown_option, - * and then terminate program with exitcode 1. - * - * Other exceptions will be passed to higher level. - */ - void ParseConfig(const std::string& path); + /** + * @brief Load and parse given config file + * @param path Path to config file + * + * If error occurred when opening file path is points to, + * we show the error message and terminate program. + * + * In case of parameter misuse boost throws an exception. + * We internally handle type boost::program_options::unknown_option, + * and then terminate program with exitcode 1. + * + * Other exceptions will be passed to higher level. + */ + void ParseConfig(const std::string& path); - /** - * @brief Used to combine options from cmdline, config and default values - */ - void Finalize(); + /** + * @brief Used to combine options from cmdline, config and default values + */ + void Finalize(); - /* @brief Accessor to parameters by name - * @param name Name of the requested parameter - * @param value Variable where to store option - * @return this function returns false if parameter not found - * - * Example: uint16_t port; GetOption("sam.port", port); - */ - template - bool GetOption(const char *name, T& value) { - if (!m_Options.count(name)) - return false; - value = m_Options[name].as(); - return true; - } + /** + * @brief Accessor to parameters by name + * @param name Name of the requested parameter + * @param value Variable where to store option + * @return this function returns false if parameter not found + * + * Example: uint16_t port; GetOption("sam.port", port); + */ + template + bool GetOption(const char *name, T& value) + { + if (!m_Options.count(name)) + return false; + value = m_Options[name].as(); + return true; + } - template - bool GetOption(const std::string& name, T& value) - { - return GetOption (name.c_str (), value); - } + template + bool GetOption(const std::string& name, T& value) + { + return GetOption (name.c_str (), value); + } - bool GetOptionAsAny(const char *name, boost::any& value); - bool GetOptionAsAny(const std::string& name, boost::any& value); + bool GetOptionAsAny(const char *name, boost::any& value); + bool GetOptionAsAny(const std::string& name, boost::any& value); - /** - * @brief Set value of given parameter - * @param name Name of settable parameter - * @param value New parameter value - * @return true if value set up successful, false otherwise - * - * Example: uint16_t port = 2827; SetOption("bob.port", port); - */ - template - bool SetOption(const char *name, const T& value) { - if (!m_Options.count(name)) - return false; - m_Options.at(name).value() = value; - notify(m_Options); - return true; - } + /** + * @brief Set value of given parameter + * @param name Name of settable parameter + * @param value New parameter value + * @return true if value set up successful, false otherwise + * + * Example: uint16_t port = 2827; SetOption("bob.port", port); + */ + template + bool SetOption(const char *name, const T& value) + { + if (!m_Options.count(name)) + return false; + m_Options.at(name).value() = value; + notify(m_Options); + return true; + } - /** - * @brief Check is value explicitly given or default - * @param name Name of checked parameter - * @return true if value set to default, false otherwise - */ - bool IsDefault(const char *name); + /** + * @brief Check is value explicitly given or default + * @param name Name of checked parameter + * @return true if value set to default, false otherwise + */ + bool IsDefault(const char *name); } } diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 567ae574..d4d3519e 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -286,14 +286,14 @@ namespace crypto #if OPENSSL_X25519 m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); m_Pkey = nullptr; -#else +#else m_Ctx = BN_CTX_new (); -#endif - } +#endif + } X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub) { -#if OPENSSL_X25519 +#if OPENSSL_X25519 m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); if (pub) @@ -302,33 +302,33 @@ namespace crypto { size_t len = 32; EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); - } + } #else - m_Ctx = BN_CTX_new (); + m_Ctx = BN_CTX_new (); memcpy (m_PrivateKey, priv, 32); if (pub) memcpy (m_PublicKey, pub, 32); else GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); -#endif - } - +#endif + } + X25519Keys::~X25519Keys () { #if OPENSSL_X25519 EVP_PKEY_CTX_free (m_Ctx); - if (m_Pkey) EVP_PKEY_free (m_Pkey); -#else + if (m_Pkey) EVP_PKEY_free (m_Pkey); +#else BN_CTX_free (m_Ctx); -#endif - } +#endif + } void X25519Keys::GenerateKeys () { #if OPENSSL_X25519 if (m_Pkey) - { - EVP_PKEY_free (m_Pkey); + { + EVP_PKEY_free (m_Pkey); m_Pkey = nullptr; } EVP_PKEY_keygen_init (m_Ctx); @@ -337,26 +337,26 @@ namespace crypto m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx? size_t len = 32; EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); -#else +#else RAND_bytes (m_PrivateKey, 32); GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); -#endif - } +#endif + } void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) { -#if OPENSSL_X25519 +#if OPENSSL_X25519 EVP_PKEY_derive_init (m_Ctx); auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); EVP_PKEY_derive_set_peer (m_Ctx, pkey); size_t len = 32; EVP_PKEY_derive (m_Ctx, shared, &len); EVP_PKEY_free (pkey); -#else +#else GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx); -#endif - } - +#endif + } + void X25519Keys::GetPrivateKey (uint8_t * priv) const { #if OPENSSL_X25519 @@ -369,14 +369,14 @@ namespace crypto void X25519Keys::SetPrivateKey (const uint8_t * priv) { -#if OPENSSL_X25519 - if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); +#if OPENSSL_X25519 + if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); if (m_Pkey) EVP_PKEY_free (m_Pkey); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); #else memcpy (m_PrivateKey, priv, 32); -#endif +#endif } // ElGamal @@ -681,12 +681,12 @@ namespace crypto // AES #ifdef __AES__ - #ifdef ARM64AES - void init_aesenc(void){ + #ifdef ARM64AES + void init_aesenc(void){ // TODO: Implementation - } + } - #endif + #endif #define KeyExpansion256(round0,round1) \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \ @@ -884,7 +884,6 @@ namespace crypto } } - void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out) { #ifdef __AES__ @@ -1139,10 +1138,10 @@ namespace crypto } EVP_CIPHER_CTX_free (ctx); -#else +#else chacha::Chacha20State state; // generate one time poly key - chacha::Chacha20Init (state, nonce, key, 0); + chacha::Chacha20Init (state, nonce, key, 0); uint64_t polyKey[8]; memset(polyKey, 0, sizeof(polyKey)); chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); @@ -1158,7 +1157,7 @@ namespace crypto { // padding1 rem = 16 - rem; - polyHash.Update (padding, rem); + polyHash.Update (padding, rem); } } // encrypt/decrypt data and add to hash @@ -1174,20 +1173,20 @@ namespace crypto { polyHash.Update (buf, msgLen); // before decryption chacha::Chacha20Encrypt (state, buf, msgLen); // decrypt - } + } auto rem = msgLen & 0x0F; // %16 if (rem) { // padding2 rem = 16 - rem; - polyHash.Update (padding, rem); + polyHash.Update (padding, rem); } // adLen and msgLen htole64buf (padding, adLen); htole64buf (padding + 8, msgLen); - polyHash.Update (padding, 16); - + polyHash.Update (padding, 16); + if (encrypt) // calculate Poly1305 tag and write in after encrypted data polyHash.Finish ((uint64_t *)(buf + msgLen)); @@ -1195,7 +1194,7 @@ namespace crypto { uint64_t tag[4]; // calculate Poly1305 tag - polyHash.Finish (tag); + polyHash.Finish (tag); if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided } #endif @@ -1211,20 +1210,20 @@ namespace crypto EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, 0); EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce); - for (const auto& it: bufs) + for (const auto& it: bufs) EVP_EncryptUpdate(ctx, it.first, &outlen, it.first, it.second); EVP_EncryptFinal_ex(ctx, NULL, &outlen); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac); EVP_CIPHER_CTX_free (ctx); -#else +#else chacha::Chacha20State state; // generate one time poly key - chacha::Chacha20Init (state, nonce, key, 0); + chacha::Chacha20Init (state, nonce, key, 0); uint64_t polyKey[8]; memset(polyKey, 0, sizeof(polyKey)); chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); Poly1305 polyHash (polyKey); - // encrypt buffers + // encrypt buffers Chacha20SetCounter (state, 1); size_t size = 0; for (const auto& it: bufs) @@ -1234,22 +1233,22 @@ namespace crypto size += it.second; } // padding - uint8_t padding[16]; + uint8_t padding[16]; memset (padding, 0, 16); auto rem = size & 0x0F; // %16 if (rem) { // padding2 rem = 16 - rem; - polyHash.Update (padding, rem); + polyHash.Update (padding, rem); } // adLen and msgLen // adLen is always zero htole64buf (padding + 8, size); - polyHash.Update (padding, 16); + polyHash.Update (padding, 16); // MAC - polyHash.Finish ((uint64_t *)mac); -#endif + polyHash.Finish ((uint64_t *)mac); +#endif } void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out) @@ -1265,13 +1264,13 @@ namespace crypto EVP_CIPHER_CTX_free (ctx); #else chacha::Chacha20State state; - chacha::Chacha20Init (state, nonce, key, 1); + chacha::Chacha20Init (state, nonce, key, 1); if (out != msg) memcpy (out, msg, msgLen); chacha::Chacha20Encrypt (state, out, msgLen); #endif } - void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, + void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen) { #if OPENSSL_HKDF @@ -1279,10 +1278,10 @@ namespace crypto EVP_PKEY_derive_init (pctx); EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256()); if (key && keyLen) - { + { EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32); EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen); - } + } else { // zerolen @@ -1290,22 +1289,22 @@ namespace crypto uint8_t tempKey[32]; unsigned int len; HMAC(EVP_sha256(), salt, 32, nullptr, 0, tempKey, &len); 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_derive (pctx, out, &outLen); EVP_PKEY_CTX_free (pctx); #else uint8_t prk[32]; unsigned int len; - HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len); + HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len); auto l = info.length (); memcpy (out, info.c_str (), l); out[l] = 0x01; HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len); if (outLen > 32) // 64 - { + { memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02; - HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); - } + HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len); + } #endif } @@ -1323,10 +1322,10 @@ namespace crypto } }*/ - + void InitCrypto (bool precomputation) { - i2p::cpu::Detect (); + i2p::cpu::Detect (); #if LEGACY_OPENSSL SSL_library_init (); #endif @@ -1364,4 +1363,3 @@ namespace crypto } } } - diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 32410daf..2dfd6d0e 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -28,13 +28,13 @@ #else # define LEGACY_OPENSSL 0 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 -# define OPENSSL_HKDF 1 -# define OPENSSL_EDDSA 1 -# define OPENSSL_X25519 1 -# define OPENSSL_SIPHASH 1 +# define OPENSSL_HKDF 1 +# define OPENSSL_EDDSA 1 +# define OPENSSL_X25519 1 +# define OPENSSL_SIPHASH 1 # endif # if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them -# define OPENSSL_AEAD_CHACHA20_POLY1305 1 +# define OPENSSL_AEAD_CHACHA20_POLY1305 1 # endif #endif @@ -81,20 +81,20 @@ namespace crypto const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; void SetPrivateKey (const uint8_t * priv); // wihout calculating public - void Agree (const uint8_t * pub, uint8_t * shared); + void Agree (const uint8_t * pub, uint8_t * shared); private: - uint8_t m_PublicKey[32]; + uint8_t m_PublicKey[32]; #if OPENSSL_X25519 EVP_PKEY_CTX * m_Ctx; EVP_PKEY * m_Pkey; -#else +#else BN_CTX * m_Ctx; uint8_t m_PrivateKey[32]; -#endif +#endif }; - + // 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); @@ -117,15 +117,15 @@ namespace crypto void operator^=(const ChipherBlock& other) // XOR { if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ? - { + { for (int i = 0; i < 4; i++) reinterpret_cast(buf)[i] ^= reinterpret_cast(other.buf)[i]; - } + } else - { + { for (int i = 0; i < 16; i++) buf[i] ^= other.buf[i]; - } + } } }; @@ -297,7 +297,7 @@ namespace crypto // HKDF - void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 + void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 // init and terminate void InitCrypto (bool precomputation); diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 878e984a..2abcb111 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -151,7 +151,7 @@ namespace crypto ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor (const uint8_t * pub) { memcpy (m_PublicKey, pub, 32); - } + } void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool) { @@ -166,16 +166,15 @@ namespace crypto bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) { m_StaticKeys.Agree (epub, sharedSecret); - return true; + return true; } void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub) { X25519Keys k; - k.GenerateKeys (); + k.GenerateKeys (); k.GetPrivateKey (priv); memcpy (pub, k.GetPublicKey (), 32); } } } - diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 701e9482..43bd3aaa 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -45,7 +45,7 @@ namespace crypto 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; }; - + private: uint8_t m_PrivateKey[256]; @@ -76,7 +76,7 @@ namespace crypto ~ECIESP256Decryptor (); bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); size_t GetPublicKeyLen () const { return 64; }; - + private: EC_GROUP * m_Curve; @@ -109,7 +109,7 @@ namespace crypto ~ECIESGOSTR3410Decryptor (); bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding); size_t GetPublicKeyLen () const { return 64; }; - + private: BIGNUM * m_PrivateKey; @@ -119,14 +119,14 @@ namespace crypto // ECIES-X25519-AEAD-Ratchet - class ECIESX25519AEADRatchetEncryptor: public CryptoKeyEncryptor + class ECIESX25519AEADRatchetEncryptor: public CryptoKeyEncryptor { public: ECIESX25519AEADRatchetEncryptor (const uint8_t * pub); ~ECIESX25519AEADRatchetEncryptor () {}; void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool); - // copies m_PublicKey to pub + // copies m_PublicKey to pub private: @@ -139,7 +139,7 @@ namespace crypto ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); ~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, bool zeroPadding); // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const { return 32; }; @@ -153,4 +153,3 @@ namespace crypto } #endif - diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h index d43e356c..baeb7f14 100644 --- a/libi2pd/CryptoWorker.h +++ b/libi2pd/CryptoWorker.h @@ -77,5 +77,4 @@ namespace worker } } - #endif diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 6441b5e2..2da73649 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -13,10 +13,10 @@ namespace datagram DatagramDestination::DatagramDestination (std::shared_ptr owner, bool gzip): m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip) { - auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); - m_From.resize (identityLen); - m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); - m_Signature.resize (m_Owner->GetIdentity ()->GetSignatureLen ()); + auto identityLen = m_Owner->GetIdentity ()->GetFullLen (); + m_From.resize (identityLen); + m_Owner->GetIdentity ()->ToBuffer (m_From.data (), identityLen); + m_Signature.resize (m_Owner->GetIdentity ()->GetSignatureLen ()); } DatagramDestination::~DatagramDestination () @@ -36,7 +36,7 @@ namespace datagram m_Owner->Sign (payload, len, m_Signature.data ()); auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); } @@ -46,8 +46,8 @@ namespace datagram auto session = ObtainSession(identity); auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw session->SendMsg(msg); - } - + } + void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) { i2p::data::IdentityEx identity; @@ -86,8 +86,8 @@ namespace datagram m_RawReceiver (fromPort, toPort, buf, len); else LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram"); - } - + } + DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port) { std::lock_guard lock(m_ReceiversMutex); @@ -107,23 +107,22 @@ namespace datagram { if (isRaw) HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen); - else + else HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen); - } + } else LogPrint (eLogWarning, "Datagram: decompression failed"); } - std::shared_ptr DatagramDestination::CreateDataMessage ( - const std::vector >& payloads, - uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) + const std::vector >& payloads, + uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { auto msg = NewI2NPMessage (); 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); + i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len); if (size) { htobe32buf (msg->GetPayload (), size); // length @@ -186,7 +185,7 @@ namespace datagram } DatagramSession::DatagramSession(std::shared_ptr localDestination, - const i2p::data::IdentHash & remoteIdent) : + const i2p::data::IdentHash & remoteIdent) : m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent), m_SendQueueTimer(localDestination->GetService()), @@ -384,4 +383,3 @@ namespace datagram } } } - diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index ea2a4e13..72e7340c 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -32,68 +32,71 @@ namespace datagram const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000; // milliseconds minimum time between path switches const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000; - // max 64 messages buffered in send queue for each datagram session - const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64; + // max 64 messages buffered in send queue for each datagram session + const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64; class DatagramSession : public std::enable_shared_from_this { - public: - DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent); - void Start (); - void Stop (); + public: + + DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent); + + void Start (); + void Stop (); - /** @brief ack the garlic routing path */ - void Ack(); + /** @brief ack the garlic routing path */ + void Ack(); - /** send an i2np message to remote endpoint for this session */ - void SendMsg(std::shared_ptr msg); - /** get the last time in milliseconds for when we used this datagram session */ - uint64_t LastActivity() const { return m_LastUse; } + /** send an i2np message to remote endpoint for this session */ + void SendMsg(std::shared_ptr msg); + /** get the last time in milliseconds for when we used this datagram session */ + uint64_t LastActivity() const { return m_LastUse; } bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } - + struct Info { std::shared_ptr IBGW; std::shared_ptr OBEP; const uint64_t activity; - Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {} - Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) : - activity(a) { - if(ibgw) IBGW = std::make_shared(ibgw); - else IBGW = nullptr; - if(obep) OBEP = std::make_shared(obep); - else OBEP = nullptr; - } - }; + Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {} + Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) : + activity(a) { + if(ibgw) IBGW = std::make_shared(ibgw); + else IBGW = nullptr; + if(obep) OBEP = std::make_shared(obep); + else OBEP = nullptr; + } + }; - Info GetSessionInfo() const; + Info GetSessionInfo() const; - private: + private: - void FlushSendQueue(); - void ScheduleFlushSendQueue(); + void FlushSendQueue(); + void ScheduleFlushSendQueue(); - void HandleSend(std::shared_ptr msg); + void HandleSend(std::shared_ptr msg); - std::shared_ptr GetSharedRoutingPath(); + std::shared_ptr GetSharedRoutingPath(); - void HandleLeaseSetUpdated(std::shared_ptr ls); + void HandleLeaseSetUpdated(std::shared_ptr ls); - private: - std::shared_ptr m_LocalDestination; - i2p::data::IdentHash m_RemoteIdent; - std::shared_ptr m_RemoteLeaseSet; - std::shared_ptr m_RoutingSession; - std::shared_ptr m_CurrentRemoteLease; - std::shared_ptr m_CurrentOutboundTunnel; - boost::asio::deadline_timer m_SendQueueTimer; - std::vector > m_SendQueue; - uint64_t m_LastUse; - bool m_RequestingLS; + private: + + std::shared_ptr m_LocalDestination; + i2p::data::IdentHash m_RemoteIdent; + std::shared_ptr m_RemoteLeaseSet; + std::shared_ptr m_RoutingSession; + std::shared_ptr m_CurrentRemoteLease; + std::shared_ptr m_CurrentOutboundTunnel; + boost::asio::deadline_timer m_SendQueueTimer; + std::vector > m_SendQueue; + uint64_t m_LastUse; + bool m_RequestingLS; }; typedef std::shared_ptr DatagramSession_ptr; @@ -104,17 +107,15 @@ namespace datagram typedef std::function Receiver; typedef std::function RawReceiver; - public: - - DatagramDestination (std::shared_ptr owner, bool gzip); + DatagramDestination (std::shared_ptr owner, bool gzip); ~DatagramDestination (); void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); - + void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; void ResetReceiver () { m_Receiver = nullptr; }; @@ -123,7 +124,7 @@ namespace datagram void SetRawReceiver (const RawReceiver& receiver) { m_RawReceiver = receiver; }; void ResetRawReceiver () { m_RawReceiver = nullptr; }; - + std::shared_ptr GetInfoForRemote(const i2p::data::IdentHash & remote); // clean up stale sessions @@ -131,14 +132,14 @@ namespace datagram private: - std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); + std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); - std::shared_ptr CreateDataMessage (const std::vector >& payloads, + std::shared_ptr CreateDataMessage (const std::vector >& payloads, uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); - + /** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */ Receiver FindReceiver(uint16_t port); diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 782e2841..921e55f0 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -16,8 +16,8 @@ namespace i2p namespace client { LeaseSetDestination::LeaseSetDestination (boost::asio::io_service& service, - bool isPublic, const std::map * params): - m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0), + bool isPublic, const std::map * params): + m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), m_LeaseSetType (DEFAULT_LEASESET_TYPE), m_AuthType (i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_NONE) @@ -160,13 +160,12 @@ namespace client bool LeaseSetDestination::Reconfigure(std::map params) { - auto itr = params.find("i2cp.dontPublishLeaseSet"); if (itr != params.end()) { m_IsPublic = itr->second != "true"; } - + int inLen, outLen, inQuant, outQuant, numTags, minLatency, maxLatency; std::map intOpts = { {I2CP_PARAM_INBOUND_TUNNEL_LENGTH, inLen}, @@ -185,7 +184,7 @@ namespace client outQuant = pool->GetNumOutboundTunnels(); minLatency = 0; maxLatency = 0; - + for (auto & opt : intOpts) { itr = params.find(opt.first); @@ -197,7 +196,7 @@ namespace client pool->RequireLatency(minLatency, maxLatency); return pool->Reconfigure(inLen, outLen, inQuant, outQuant); } - + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; @@ -266,7 +265,7 @@ namespace client std::lock_guard l(m_LeaseSetMutex); return m_LeaseSet; } - + void LeaseSetDestination::SetLeaseSet (std::shared_ptr newLeaseSet) { { @@ -281,7 +280,7 @@ namespace client { s->m_PublishVerificationTimer.cancel (); s->Publish (); - }); + }); } } @@ -565,12 +564,12 @@ namespace client m_PublishReplyToken = 0; if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) { - LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); + LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); Publish (); } else { - LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ()); + LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ()); // Java floodfill never sends confirmation back for unknown crypto type // assume it successive and try to verify m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); @@ -591,7 +590,7 @@ namespace client { LogPrint (eLogWarning, "Destination: couldn't verify LeaseSet for ", GetIdentHash().ToBase32()); return; - } + } auto s = shared_from_this (); // we must capture this for gcc 4.7 due the bug RequestLeaseSet (ls->GetStoreHash (), @@ -643,9 +642,9 @@ namespace client if (requestComplete) m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; - } + } auto storeHash = dest->GetStoreHash (); - auto leaseSet = FindLeaseSet (storeHash); + auto leaseSet = FindLeaseSet (storeHash); if (leaseSet) { if (requestComplete) @@ -720,7 +719,7 @@ namespace client } bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, - std::shared_ptr nextFloodfill, std::shared_ptr request) + std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) request->replyTunnel = m_Pool->GetNextInboundTunnel (); @@ -783,7 +782,7 @@ namespace client } else { - LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); + LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); done = true; } @@ -829,13 +828,13 @@ namespace client i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const { if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; - return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; - } - - ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; + return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; + } + + ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - LeaseSetDestination (service, isPublic, params), + LeaseSetDestination (service, isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(service) @@ -846,7 +845,7 @@ namespace client // extract encryption type params for LS2 std::set encryptionKeyTypes; if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 || - GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) + GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) { auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE); if (it != params->end ()) @@ -864,37 +863,37 @@ namespace client { LogPrint (eLogInfo, "Destination: Unexpected crypto type ", it1, ". ", ex.what ()); continue; - } - } - } - } - // if no param or valid crypto type use from identity - bool isSingleKey = false; - if (encryptionKeyTypes.empty ()) + } + } + } + } + // if no param or valid crypto type use from identity + bool isSingleKey = false; + if (encryptionKeyTypes.empty ()) { isSingleKey = true; encryptionKeyTypes.insert (GetIdentity ()->GetCryptoKeyType ()); - } + } for (auto& it: encryptionKeyTypes) - { + { auto encryptionKey = new EncryptionKey (it); - if (isPublic) + if (isPublic) PersistTemporaryKeys (encryptionKey, isSingleKey); else encryptionKey->GenerateKeys (); - encryptionKey->CreateDecryptor (); + encryptionKey->CreateDecryptor (); if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) m_ECIESx25519EncryptionKey.reset (encryptionKey); else - m_StandardEncryptionKey.reset (encryptionKey); - } - + m_StandardEncryptionKey.reset (encryptionKey); + } + if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); try - { + { if (params) { // extract streaming params @@ -910,9 +909,9 @@ namespace client { m_AuthKeys = std::make_shared >(); if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_DH) - ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_DH, params); else if (authType == i2p::data::ENCRYPTED_LEASESET_AUTH_TYPE_PSK) - ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); + ReadAuthKey (I2CP_PARAM_LEASESET_CLIENT_PSK, params); else LogPrint (eLogError, "Destination: Unexpected auth type ", authType); if (m_AuthKeys->size ()) @@ -920,7 +919,7 @@ namespace client else { LogPrint (eLogError, "Destination: No auth keys read for auth type ", authType); - m_AuthKeys = nullptr; + m_AuthKeys = nullptr; } } } @@ -1002,7 +1001,7 @@ namespace client m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, true); else LogPrint (eLogError, "Destination: Missing raw datagram destination"); - break; + break; default: LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]); } @@ -1105,7 +1104,7 @@ namespace client return dest; } - i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip) { if (m_DatagramDestination == nullptr) m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip); @@ -1130,7 +1129,7 @@ namespace client { if (!keys) return; std::string ident = GetIdentHash().ToBase32(); - std::string path = i2p::fs::DataDirPath("destinations", + std::string path = i2p::fs::DataDirPath("destinations", isSingleKey ? (ident + ".dat") : (ident + "." + std::to_string (keys->keyType) + ".dat")); std::ifstream f(path, std::ifstream::binary); @@ -1142,12 +1141,12 @@ namespace client LogPrint (eLogInfo, "Destination: Creating new temporary keys of type for address ", ident, ".b32.i2p"); memset (keys->priv, 0, 256); - memset (keys->pub, 0, 256); + memset (keys->pub, 0, 256); keys->GenerateKeys (); // TODO:: persist crypto key type std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out); if (f1) { - f1.write ((char *)keys->pub, 256); + f1.write ((char *)keys->pub, 256); f1.write ((char *)keys->priv, 256); return; } @@ -1160,11 +1159,11 @@ namespace client if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) { if (m_StandardEncryptionKey) - { + { leaseSet = std::make_shared (GetIdentity (), m_StandardEncryptionKey->pub, tunnels); // sign - Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); - } + Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); + } else LogPrint (eLogError, "Destinations: Wrong encryption key type for LeaseSet type 1"); } @@ -1175,9 +1174,9 @@ namespace client if (m_ECIESx25519EncryptionKey) keySections.push_back ({m_ECIESx25519EncryptionKey->keyType, 32, m_ECIESx25519EncryptionKey->pub} ); if (m_StandardEncryptionKey) - keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub} ); + keySections.push_back ({m_StandardEncryptionKey->keyType, (uint16_t)m_StandardEncryptionKey->decryptor->GetPublicKeyLen (), m_StandardEncryptionKey->pub} ); - bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; + bool isPublishedEncrypted = GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; auto ls2 = std::make_shared (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, m_Keys, keySections, tunnels, IsPublic (), isPublishedEncrypted); if (isPublishedEncrypted) // encrypt if type 5 @@ -1204,18 +1203,18 @@ namespace client return false; } - bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const - { + bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const + { return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519EncryptionKey : (bool)m_StandardEncryptionKey; } - const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const - { + const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const + { if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub : nullptr; return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub : nullptr; } - + void ClientDestination::ReadAuthKey (const std::string& group, const std::map * params) { for (auto it: *params) @@ -1229,7 +1228,7 @@ namespace client m_AuthKeys->push_back (pubKey); else LogPrint (eLogError, "Destination: Unexpected auth key ", it.second.substr (pos+1)); - } + } } } @@ -1241,10 +1240,10 @@ namespace client if (it.second->DeleteStream (recvStreamID)) return true; return false; - } - + } + RunnableClientDestination::RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - RunnableService ("Destination"), + RunnableService ("Destination"), ClientDestination (GetIOService (), keys, isPublic, params) { } @@ -1253,7 +1252,7 @@ namespace client { if (IsRunning ()) Stop (); - } + } void RunnableClientDestination::Start () { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 04cf05f4..dbdc3704 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -52,13 +52,13 @@ 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 = 1; 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 - + // latency const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; const int DEFAULT_MIN_TUNNEL_LATENCY = 0; @@ -94,7 +94,6 @@ namespace client } }; - public: LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map * params = nullptr); @@ -107,12 +106,12 @@ namespace client /** i2cp reconfigure */ virtual bool Reconfigure(std::map i2cpOpts); - + std::shared_ptr GetTunnelPool () { return m_Pool; }; bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; }; std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr); - bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete = nullptr); + bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete = nullptr); void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true); void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify = true); @@ -155,7 +154,7 @@ namespace client void HandleDeliveryStatusMessage (uint32_t msgID); void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr requestedBlindedKey = nullptr); - bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); + bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); @@ -202,11 +201,11 @@ namespace client EncryptionKey (i2p::data::CryptoKeyType t):keyType(t) { memset (pub, 0, 256); memset (priv, 0, 256); }; void GenerateKeys () { i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv, pub); }; void CreateDecryptor () { decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv); }; - }; - + }; + public: - ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); ~ClientDestination (); @@ -235,13 +234,13 @@ namespace client int GetStreamingAckDelay () const { return m_StreamingAckDelay; } // datagram - i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; - i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); + i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; + 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; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; - bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; + bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const; const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; protected: @@ -259,8 +258,8 @@ namespace client void PersistTemporaryKeys (EncryptionKey * keys, bool isSingleKey); void ReadAuthKey (const std::string& group, const std::map * params); - private: - + private: + i2p::data::PrivateKeys m_Keys; std::unique_ptr m_StandardEncryptionKey; std::unique_ptr m_ECIESx25519EncryptionKey; @@ -273,7 +272,7 @@ namespace client boost::asio::deadline_timer m_ReadyChecker; - std::shared_ptr > m_AuthKeys; // we don't need them for I2CP + std::shared_ptr > m_AuthKeys; // we don't need them for I2CP public: @@ -287,7 +286,7 @@ namespace client public: RunnableClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); - ~RunnableClientDestination (); + ~RunnableClientDestination (); void Start (); void Stop (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 7b386d92..f3b1a685 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -15,54 +15,54 @@ namespace i2p namespace garlic { - void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k) - { - // DH_INITIALIZE(rootKey, k) - 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); - // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) + void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k) + { + // DH_INITIALIZE(rootKey, k) + 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); + // [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64) memcpy (m_SymmKeyCK, m_KeyData.buf + 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); + 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); m_NextIndex = 0; - } + } - uint64_t RatchetTagSet::GetNextSessionTag () - { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) - m_NextIndex++; - if (m_NextIndex >= 65535) + uint64_t RatchetTagSet::GetNextSessionTag () + { + i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) + m_NextIndex++; + if (m_NextIndex >= 65535) { LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty"); return 0; - } - return m_KeyData.GetTag (); - } + } + return m_KeyData.GetTag (); + } void RatchetTagSet::GetSymmKey (int index, uint8_t * key) { if (index >= m_NextSymmKeyIndex) - { + { auto num = index + 1 - m_NextSymmKeyIndex; if (!m_NextSymmKeyIndex) { i2p::crypto::HKDF (m_SymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); // keydata_0 = HKDF(symmKey_ck, SYMMKEY_CONSTANT, "SymmetricRatchet", 64) m_NextSymmKeyIndex = 1; num--; - } + } for (int i = 0; i < num; i++) - { + { i2p::crypto::HKDF (m_CurrentSymmKeyCK, nullptr, 0, "SymmetricRatchet", m_CurrentSymmKeyCK); if (i < num - 1) m_ItermediateSymmKeys.emplace (m_NextSymmKeyIndex + i, m_CurrentSymmKeyCK + 32); - } + } m_NextSymmKeyIndex += num; memcpy (key, m_CurrentSymmKeyCK + 32, 32); } @@ -70,30 +70,30 @@ namespace garlic { auto it = m_ItermediateSymmKeys.find (index); if (it != m_ItermediateSymmKeys.end ()) - { + { memcpy (key, it->second, 32); m_ItermediateSymmKeys.erase (it); - } + } else LogPrint (eLogError, "Garlic: Missing symmetric key for index ", index); - } - } + } + } void RatchetTagSet::Expire () { if (!m_ExpirationTimestamp) m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; - } - - ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): - GarlicRoutingSession (owner, attachLeaseSet) - { - ResetKeys (); - } + } - ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () - { - } + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): + GarlicRoutingSession (owner, attachLeaseSet) + { + ResetKeys (); + } + + ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () + { + } void ECIESX25519AEADRatchetSession::ResetKeys () { @@ -109,65 +109,65 @@ namespace garlic }; // SHA256 (protocolNameHash) memcpy (m_CK, protocolNameHash, 32); memcpy (m_H, hh, 32); - } - - void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; + } + + void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; SHA256_Init (&ctx); SHA256_Update (&ctx, m_H, 32); SHA256_Update (&ctx, buf, len); SHA256_Final (m_H, &ctx); - } - - void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) - { - memset (nonce, 0, 4); - htole64buf (nonce + 4, seqn); } - bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) - { - for (int i = 0; i < 10; i++) - { - m_EphemeralKeys.GenerateKeys (); - if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) - return true; // success - } - return false; - } + void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) + { + memset (nonce, 0, 4); + htole64buf (nonce + 4, seqn); + } - std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () - { - uint8_t tagsetKey[32]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) - // Session Tag Ratchet - auto tagsetNsr = std::make_shared(shared_from_this ()); - tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) - tagsetNsr->NextSessionTagRatchet (); - return tagsetNsr; - } - - bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) - { - if (!GetOwner ()) return false; - // we are Bob - // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk) - - if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) - { - LogPrint (eLogError, "Garlic: Can't decode elligator"); - return false; + bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) + { + for (int i = 0; i < 10; i++) + { + m_EphemeralKeys.GenerateKeys (); + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) + return true; // success } - buf += 32; len -= 32; - MixHash (m_Aepk, 32); // h = SHA256(h || aepk) - - uint8_t sharedSecret[32]; + return false; + } + + std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () + { + uint8_t tagsetKey[32]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) + // Session Tag Ratchet + auto tagsetNsr = std::make_shared(shared_from_this ()); + tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) + tagsetNsr->NextSessionTagRatchet (); + return tagsetNsr; + } + + bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) + { + if (!GetOwner ()) return false; + // we are Bob + // KDF1 + MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk) + + if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) + { + LogPrint (eLogError, "Garlic: Can't decode elligator"); + return false; + } + buf += 32; len -= 32; + MixHash (m_Aepk, 32); // h = SHA256(h || aepk) + + uint8_t sharedSecret[32]; GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - - // decrypt flags/static + + // decrypt flags/static uint8_t nonce[12], fs[32]; CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt @@ -179,17 +179,17 @@ namespace garlic buf += 48; len -= 48; // 32 data + 16 poly // KDF2 for payload - bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); + bool isStatic = !i2p::data::Tag<32> (fs).IsZero (); if (isStatic) { // static key, fs is apk - memcpy (m_RemoteStaticKey, fs, 32); + memcpy (m_RemoteStaticKey, fs, 32); GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) } else // all zeros flags CreateNonce (1, nonce); - + // decrypt payload std::vector payload (len - 16); // we must save original ciphertext if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt @@ -198,17 +198,17 @@ namespace garlic return false; } if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) - m_State = eSessionStateNewSessionReceived; + m_State = eSessionStateNewSessionReceived; GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); - HandlePayload (payload.data (), len - 16, nullptr, 0); + HandlePayload (payload.data (), len - 16, nullptr, 0); - return true; - } + return true; + } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index) - { - size_t offset = 0; + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index) + { + size_t offset = 0; while (offset < len) { uint8_t blk = buf[offset]; @@ -228,48 +228,48 @@ namespace garlic GetOwner ()->HandleECIESx25519GarlicClove (buf + offset, size); break; case eECIESx25519BlkNextKey: - LogPrint (eLogDebug, "Garlic: next key"); + LogPrint (eLogDebug, "Garlic: next key"); HandleNextKey (buf + offset, size, receiveTagset); break; case eECIESx25519BlkAck: - { + { LogPrint (eLogDebug, "Garlic: ack"); int numAcks = size >> 2; // /4 - auto offset1 = offset; + auto offset1 = offset; for (auto i = 0; i < numAcks; i++) - { + { offset1 += 2; // tagsetid MessageConfirmed (bufbe16toh (buf + offset1)); offset1 += 2; // N } break; - } + } case eECIESx25519BlkAckRequest: - { + { LogPrint (eLogDebug, "Garlic: ack request"); - m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); - break; - } + m_AckRequests.push_back ({receiveTagset->GetTagSetID (), index}); + break; + } case eECIESx25519BlkTermination: LogPrint (eLogDebug, "Garlic: termination"); if (GetOwner ()) GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey); if (receiveTagset) receiveTagset->Expire (); - break; + break; case eECIESx25519BlkDateTime: LogPrint (eLogDebug, "Garlic: datetime"); - break; + break; case eECIESx25519BlkOptions: LogPrint (eLogDebug, "Garlic: options"); break; case eECIESx25519BlkPadding: LogPrint (eLogDebug, "Garlic: padding"); - break; + break; default: LogPrint (eLogWarning, "Garlic: Unknown block type ", (int)blk); } offset += size; } - } + } void ECIESX25519AEADRatchetSession::HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset) { @@ -279,7 +279,7 @@ namespace garlic if (!m_SendForwardKey || !m_NextSendRatchet) return; uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) || - (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) + (m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1)) { if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextSendRatchet->remote, buf, 32); @@ -288,15 +288,15 @@ namespace garlic i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared (shared_from_this ()); newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); - newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); + newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - m_SendTagset = newTagset; + m_SendTagset = newTagset; m_SendForwardKey = false; LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created"); } else LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID); - } + } else { uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID @@ -305,38 +305,38 @@ namespace garlic if (!m_NextReceiveRatchet) m_NextReceiveRatchet.reset (new DHRatchet ()); else - { - if (keyID == m_NextReceiveRatchet->keyID && newKey == m_NextReceiveRatchet->newKey) + { + if (keyID == m_NextReceiveRatchet->keyID && newKey == m_NextReceiveRatchet->newKey) { LogPrint (eLogDebug, "Garlic: Duplicate ", newKey ? "new" : "old", " key ", keyID, " received"); return; - } + } m_NextReceiveRatchet->keyID = keyID; } int tagsetID = 2*keyID; if (newKey) - { + { m_NextReceiveRatchet->key.GenerateKeys (); m_NextReceiveRatchet->newKey = true; tagsetID++; - } + } else m_NextReceiveRatchet->newKey = false; if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextReceiveRatchet->remote, buf, 32); - + uint8_t sharedSecret[32], tagsetKey[32]; m_NextReceiveRatchet->key.Agree (m_NextReceiveRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) - auto newTagset = std::make_shared(shared_from_this ()); - newTagset->SetTagSetID (tagsetID); - newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); + auto newTagset = std::make_shared(shared_from_this ()); + newTagset->SetTagSetID (tagsetID); + newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); - } - } + } + } void ECIESX25519AEADRatchetSession::NewNextSendRatchet () { @@ -346,49 +346,49 @@ namespace garlic { m_NextSendRatchet->keyID++; m_NextSendRatchet->newKey = true; - } + } else m_NextSendRatchet->newKey = false; - } + } else m_NextSendRatchet.reset (new DHRatchet ()); if (m_NextSendRatchet->newKey) m_NextSendRatchet->key.GenerateKeys (); - + m_SendForwardKey = true; LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); - } - - bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - ResetKeys (); - // we are Alice, bpk is m_RemoteStaticKey - size_t offset = 0; - if (!GenerateEphemeralKeysAndEncode (out + offset)) - { - LogPrint (eLogError, "Garlic: Can't encode elligator"); - return false; - } - offset += 32; + } - // KDF1 - MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) - uint8_t sharedSecret[32]; + bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + ResetKeys (); + // we are Alice, bpk is m_RemoteStaticKey + size_t offset = 0; + if (!GenerateEphemeralKeysAndEncode (out + offset)) + { + LogPrint (eLogError, "Garlic: Can't encode elligator"); + return false; + } + offset += 32; + + // KDF1 + MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) + uint8_t sharedSecret[32]; m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - // encrypt static key section - uint8_t nonce[12]; + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + // encrypt static key section + uint8_t nonce[12]; CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); return false; } - MixHash (out + offset, 48); // h = SHA256(h || ciphertext) - offset += 48; - // KDF2 - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) + MixHash (out + offset, 48); // h = SHA256(h || ciphertext) + offset += 48; + // KDF2 + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt @@ -399,169 +399,169 @@ namespace garlic MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) m_State = eSessionStateNewSessionSent; - if (GetOwner ()) + if (GetOwner ()) GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); - return true; - } + return true; + } - bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Bob + bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + { + // we are Bob m_NSRTagset = CreateNewSessionTagset (); - uint64_t tag = m_NSRTagset->GetNextSessionTag (); - - size_t offset = 0; - memcpy (out + offset, &tag, 8); - offset += 8; - if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk - { + uint64_t tag = m_NSRTagset->GetNextSessionTag (); + + size_t offset = 0; + memcpy (out + offset, &tag, 8); + offset += 8; + if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk + { LogPrint (eLogError, "Garlic: Can't encode elligator"); - return false; + return false; } memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR memcpy (m_NSRH, m_H, 32); - offset += 32; - // KDF for Reply Key Section - MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) - uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + offset += 32; + // KDF for Reply Key Section + MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + uint8_t sharedSecret[32]; + m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); - // calulate hash for zero length + // calculate hash for zero length if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } - MixHash (out + offset, 16); // h = SHA256(h || ciphertext) - offset += 16; - // KDF for payload - uint8_t keydata[64]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + MixHash (out + offset, 16); // h = SHA256(h || ciphertext) + offset += 16; + // KDF for payload + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) // k_ab = keydata[0:31], k_ba = keydata[32:63] auto receiveTagset = std::make_shared(shared_from_this ()); - receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) receiveTagset->NextSessionTagRatchet (); m_SendTagset = std::make_shared(shared_from_this ()); - m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) - m_SendTagset->NextSessionTagRatchet (); + m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + m_SendTagset->NextSessionTagRatchet (); GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) - // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + // encrypt payload + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed"); return false; } m_State = eSessionStateNewSessionReplySent; - - return true; - } + + return true; + } bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) - { - // we are Bob and sent NSR already - uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag - memcpy (out, &tag, 8); + { + // we are Bob and sent NSR already + uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag + memcpy (out, &tag, 8); memcpy (out + 8, m_NSREncodedKey, 32); - // recalculte h with new tag + // recalculate h with new tag memcpy (m_H, m_NSRH, 32); MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t nonce[12]; - CreateNonce (0, nonce); + CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) { LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); return false; } - MixHash (out + 40, 16); // h = SHA256(h || ciphertext) + MixHash (out + 40, 16); // h = SHA256(h || ciphertext) // encrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt { LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed"); return false; } return true; - } - - bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len) - { + } + + bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len) + { // we are Alice LogPrint (eLogDebug, "Garlic: reply received"); const uint8_t * tag = buf; buf += 8; len -= 8; // tag - uint8_t bepk[32]; // Bob's ephemeral key + uint8_t bepk[32]; // Bob's ephemeral key if (!i2p::crypto::GetElligator ()->Decode (buf, bepk)) - { + { LogPrint (eLogError, "Garlic: Can't decode elligator"); - return false; - } + return false; + } buf += 32; len -= 32; - // KDF for Reply Key Section + // KDF for Reply Key Section uint8_t h[32]; memcpy (h, m_H, 32); // save m_H - MixHash (tag, 8); // h = SHA256(h || tag) - MixHash (bepk, 32); // h = SHA256(h || bepk) - uint8_t sharedSecret[32]; + MixHash (tag, 8); // h = SHA256(h || tag) + MixHash (bepk, 32); // h = SHA256(h || bepk) + uint8_t sharedSecret[32]; if (m_State == eSessionStateNewSessionSent) - { + { // only fist time, we assume ephemeral keys the same - m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) - } + } uint8_t nonce[12]; CreateNonce (0, nonce); - // calulate hash for zero length - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anyting */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only + // calculate hash for zero length + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anything */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only { LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed"); return false; } - MixHash (buf, 16); // h = SHA256(h || ciphertext) + MixHash (buf, 16); // h = SHA256(h || ciphertext) buf += 16; len -= 16; // KDF for payload - uint8_t keydata[64]; - i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) + uint8_t keydata[64]; + i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) if (m_State == eSessionStateNewSessionSent) - { - // k_ab = keydata[0:31], k_ba = keydata[32:63] + { + // k_ab = keydata[0:31], k_ba = keydata[32:63] m_SendTagset = std::make_shared(shared_from_this ()); - m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) + m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) m_SendTagset->NextSessionTagRatchet (); auto receiveTagset = std::make_shared(shared_from_this ()); - receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) + receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); - } - i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) + } + i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload - if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt + if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; } if (m_State == eSessionStateNewSessionSent) - { + { m_State = eSessionStateEstablished; GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } - memcpy (m_H, h, 32); // restore m_H - HandlePayload (buf, len - 16, nullptr, 0); + memcpy (m_H, h, 32); // restore m_H + HandlePayload (buf, len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it SetLeaseSetUpdateStatus (eLeaseSetUpToDate); SetLeaseSetUpdateMsgID (0); - - return true; - } + + return true; + } bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { @@ -578,18 +578,18 @@ namespace garlic { LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); return false; - } + } if (index >= ECIESX25519_TAGSET_MAX_NUM_TAGS && !m_SendForwardKey) - NewNextSendRatchet (); + NewNextSendRatchet (); return true; } - bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { uint8_t nonce[12]; CreateNonce (index, nonce); // tag's index - len -= 8; // tag + len -= 8; // tag uint8_t * payload = buf + 8; uint8_t key[32]; receiveTagset->GetSymmKey (index, key); @@ -597,17 +597,17 @@ namespace garlic { LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); return false; - } - HandlePayload (payload, len - 16, receiveTagset, index); + } + HandlePayload (payload, len - 16, receiveTagset, index); int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; - moreTags -= (receiveTagset->GetNextIndex () - index); + moreTags -= (receiveTagset->GetNextIndex () - index); if (moreTags > 0) - GenerateMoreReceiveTags (receiveTagset, moreTags); + GenerateMoreReceiveTags (receiveTagset, moreTags); return true; } - bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, + bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index) { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); @@ -617,8 +617,8 @@ namespace garlic m_State = eSessionStateEstablished; m_NSRTagset = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif + [[fallthrough]]; +#endif case eSessionStateEstablished: if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; // check NSR just in case @@ -637,77 +637,77 @@ namespace garlic return true; } - std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) - { - auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); - size_t len = payload.size (); + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) + { + auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); + size_t len = payload.size (); if (!len) return nullptr; auto m = NewI2NPMessage (len + 100); // 96 + 4 m->Align (12); // in order to get buf aligned to 16 (12 + 4) uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length - - switch (m_State) - { + + switch (m_State) + { case eSessionStateEstablished: if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) return nullptr; len += 24; - break; - case eSessionStateNew: - if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 96; - break; - case eSessionStateNewSessionReceived: - if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 72; - break; + break; + case eSessionStateNew: + if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 96; + break; + case eSessionStateNewSessionReceived: + if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) + return nullptr; + len += 72; + break; case eSessionStateNewSessionReplySent: if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen)) - return nullptr; - len += 72; - break; - default: - return nullptr; - } - - htobe32buf (m->GetPayload (), len); + return nullptr; + len += 72; + break; + default: + return nullptr; + } + + htobe32buf (m->GetPayload (), len); m->len += len + 4; m->FillI2NPMessageHeader (eI2NPGarlic); return m; - } + } - std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) - { + std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) + { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); - size_t payloadLen = 0; - if (first) payloadLen += 7;// datatime - if (msg && m_Destination) - payloadLen += msg->GetPayloadLength () + 13 + 32; + size_t payloadLen = 0; + if (first) payloadLen += 7;// datatime + if (msg && m_Destination) + payloadLen += msg->GetPayloadLength () + 13 + 32; auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || - (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && - ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? + (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && + ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) - { - payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; - if (!first) + { + payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; + if (!first) { // ack request SetLeaseSetUpdateStatus (eLeaseSetSubmitted); SetLeaseSetUpdateMsgID (m_SendTagset->GetNextIndex ()); SetLeaseSetSubmissionTime (ts); - payloadLen += 4; - } - } + payloadLen += 4; + } + } if (m_AckRequests.size () > 0) payloadLen += m_AckRequests.size ()*4 + 3; if (m_SendReverseKey) - { + { payloadLen += 6; if (m_NextReceiveRatchet->newKey) payloadLen += 32; - } + } if (m_SendForwardKey) { payloadLen += 6; @@ -715,110 +715,110 @@ namespace garlic } uint8_t paddingSize = 0; if (payloadLen) - { + { int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size { RAND_bytes (&paddingSize, 1); paddingSize &= 0x0F; // 0 - 15 if (delta > 3) - { + { delta -= 3; - if (paddingSize >= delta) paddingSize %= delta; - } + if (paddingSize >= delta) paddingSize %= delta; + } paddingSize++; - payloadLen += paddingSize + 3; - } - } - std::vector v(payloadLen); - size_t offset = 0; - // DateTime + payloadLen += paddingSize + 3; + } + } + std::vector v(payloadLen); + 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 - } - // LeaseSet - if (leaseSet) - { - offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); + { + v[offset] = eECIESx25519BlkDateTime; offset++; + htobe16buf (v.data () + offset, 4); offset += 2; + htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds + } + // LeaseSet + if (leaseSet) + { + offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); if (!first) - { + { // ack request v[offset] = eECIESx25519BlkAckRequest; offset++; htobe16buf (v.data () + offset, 1); offset += 2; v[offset] = 0; offset++; // flags - } - } - // msg - if (msg && m_Destination) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + } + } + // msg + if (msg && m_Destination) + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); // ack if (m_AckRequests.size () > 0) { v[offset] = eECIESx25519BlkAck; offset++; - htobe16buf (v.data () + offset, m_AckRequests.size ()*4); offset += 2; + htobe16buf (v.data () + 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; - } + } 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; + v[offset] = ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG; int keyID = m_NextReceiveRatchet->keyID - 1; - if (m_NextReceiveRatchet->newKey) - { + if (m_NextReceiveRatchet->newKey) + { v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; keyID++; - } + } offset++; // flag htobe16buf (v.data () + offset, keyID); offset += 2; // keyid if (m_NextReceiveRatchet->newKey) - { - memcpy (v.data () + offset, m_NextReceiveRatchet->key.GetPublicKey (), 32); + { + memcpy (v.data () + 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; + 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 offset++; // flag htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid if (m_NextSendRatchet->newKey) - { - memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); + { + memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); offset += 32; // public key - } - } - // padding + } + } + // padding if (paddingSize) - { - v[offset] = eECIESx25519BlkPadding; offset++; - htobe16buf (v.data () + offset, paddingSize); offset += 2; - memset (v.data () + offset, 0, paddingSize); offset += paddingSize; - } - return v; - } + { + v[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (v.data () + offset, paddingSize); offset += 2; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + } + return v; + } - size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) - { - if (!msg) return 0; - uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) + { + if (!msg) return 0; + uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; if (isDestination) cloveSize += 32; - if ((int)len < cloveSize + 3) return 0; - buf[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (buf + 1, cloveSize); // size + if ((int)len < cloveSize + 3) return 0; + buf[0] = eECIESx25519BlkGalicClove; // clove type + htobe16buf (buf + 1, cloveSize); // size buf += 3; if (isDestination) { @@ -826,88 +826,86 @@ namespace garlic memcpy (buf + 1, *m_Destination, 32); buf += 32; } else - *buf = 0; + *buf = 0; buf++; // flag and delivery instructions - *buf = msg->GetTypeID (); // I2NP msg type - htobe32buf (buf + 1, msg->GetMsgID ()); // msgID - htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds - memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); - return cloveSize + 3; - } + *buf = msg->GetTypeID (); // I2NP msg type + htobe32buf (buf + 1, msg->GetMsgID ()); // msgID + htobe32buf (buf + 5, msg->GetExpiration () / 1000); // expiration in seconds + memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ()); + return cloveSize + 3; + } size_t ECIESX25519AEADRatchetSession::CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len) - { + { if (!ls || ls->GetStoreType () != i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) { LogPrint (eLogError, "Garlic: Incorrect LeasetSet type to send"); return 0; - } + } uint16_t cloveSize = 1 + 9 + DATABASE_STORE_HEADER_SIZE + ls->GetBufferLen (); // to local if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type - htobe16buf (buf + 1, cloveSize); // size + htobe16buf (buf + 1, cloveSize); // size buf += 3; *buf = 0; buf++; // flag and delivery instructions *buf = eI2NPDatabaseStore; buf++; // I2NP msg type RAND_bytes (buf, 4); buf += 4; // msgID - htobe32buf (buf, (ts + I2NP_MESSAGE_EXPIRATION_TIMEOUT)/1000); buf += 4; // expiration + htobe32buf (buf, (ts + I2NP_MESSAGE_EXPIRATION_TIMEOUT)/1000); buf += 4; // expiration // payload memcpy (buf + DATABASE_STORE_KEY_OFFSET, ls->GetStoreHash (), 32); buf[DATABASE_STORE_TYPE_OFFSET] = i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2; - memset (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // replyToken = 0 + memset (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0, 4); // replyToken = 0 buf += DATABASE_STORE_HEADER_SIZE; memcpy (buf, ls->GetBuffer (), ls->GetBufferLen ()); return cloveSize + 3; } - + void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) { for (int i = 0; i < numTags; i++) GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset); - } + } bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) - { + { CleanupUnconfirmedLeaseSet (ts); - return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; - } - + return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; + } + std::shared_ptr WrapECIESX25519AEADRatchetMessage (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 + 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[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; 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 ()); 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); return m; } - + } } - - diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 14f97ce9..d5a83f89 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -25,22 +25,22 @@ namespace garlic const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; - - const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ - // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ - - class ECIESX25519AEADRatchetSession; - class RatchetTagSet - { - public: - RatchetTagSet (std::shared_ptr session): m_Session (session) {}; - - void DHInitialize (const uint8_t * rootKey, const uint8_t * k); - void NextSessionTagRatchet (); - uint64_t GetNextSessionTag (); + const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ + // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ + + class ECIESX25519AEADRatchetSession; + class RatchetTagSet + { + public: + + RatchetTagSet (std::shared_ptr session): m_Session (session) {}; + + void DHInitialize (const uint8_t * rootKey, const uint8_t * k); + void NextSessionTagRatchet (); + uint64_t GetNextSessionTag (); const uint8_t * GetNextRootKey () const { return m_NextRootKey; }; - int GetNextIndex () const { return m_NextIndex; }; + int GetNextIndex () const { return m_NextIndex; }; void GetSymmKey (int index, uint8_t * key); std::shared_ptr GetSession () { return m_Session.lock (); }; @@ -49,54 +49,54 @@ namespace garlic void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - + 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; - uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; - int m_NextIndex, m_NextSymmKeyIndex; - std::unordered_map > m_ItermediateSymmKeys; - std::weak_ptr m_Session; - int m_TagSetID = 0; - uint64_t m_ExpirationTimestamp = 0; - }; + union + { + uint64_t ll[8]; + uint8_t buf[64]; - enum ECIESx25519BlockType + 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; + uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; + int m_NextIndex, m_NextSymmKeyIndex; + std::unordered_map > m_ItermediateSymmKeys; + std::weak_ptr m_Session; + int m_TagSetID = 0; + uint64_t m_ExpirationTimestamp = 0; + }; + + enum ECIESx25519BlockType { - eECIESx25519BlkDateTime = 0, - eECIESx25519BlkSessionID = 1, + eECIESx25519BlkDateTime = 0, + eECIESx25519BlkSessionID = 1, eECIESx25519BlkTermination = 4, - eECIESx25519BlkOptions = 5, - eECIESx25519BlkNextKey = 7, - eECIESx25519BlkAck = 8, - eECIESx25519BlkAckRequest = 9, - eECIESx25519BlkGalicClove = 11, - eECIESx25519BlkPadding = 254 - }; + eECIESx25519BlkOptions = 5, + eECIESx25519BlkNextKey = 7, + eECIESx25519BlkAck = 8, + eECIESx25519BlkAckRequest = 9, + eECIESx25519BlkGalicClove = 11, + eECIESx25519BlkPadding = 254 + }; const uint8_t ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG = 0x01; const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02; const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; - - class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this - { - enum SessionState - { - eSessionStateNew =0, - eSessionStateNewSessionReceived, + + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this + { + enum SessionState + { + eSessionStateNew = 0, + eSessionStateNewSessionReceived, eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, - eSessionStateEstablished - }; + eSessionStateEstablished + }; struct DHRatchet { @@ -104,65 +104,65 @@ namespace garlic i2p::crypto::X25519Keys key; uint8_t remote[32]; // last remote public key bool newKey = true; - }; - - public: + }; - ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); - ~ECIESX25519AEADRatchetSession (); + public: + + ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); + ~ECIESX25519AEADRatchetSession (); bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); - std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - - const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); + + const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } void SetDestination (const i2p::data::IdentHash& dest) // TODO: { if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); } - + bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } bool IsRatchets () const { return true; }; - - private: + + private: void ResetKeys (); - void MixHash (const uint8_t * buf, size_t len); + void MixHash (const uint8_t * buf, size_t len); void CreateNonce (uint64_t seqn, uint8_t * nonce); - bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes + bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes std::shared_ptr CreateNewSessionTagset (); bool HandleNewIncomingSession (const uint8_t * buf, size_t len); - bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); + bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); - void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); + void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); - - bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); - bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + + bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + 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); - - std::vector CreatePayload (std::shared_ptr msg, bool first); - size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + + std::vector CreatePayload (std::shared_ptr msg, bool first); + size_t CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); size_t CreateLeaseSetClove (std::shared_ptr ls, uint64_t ts, uint8_t * buf, size_t len); - + void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); void NewNextSendRatchet (); - - private: - uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; + private: + + uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only - i2p::crypto::X25519Keys m_EphemeralKeys; - SessionState m_State = eSessionStateNew; + i2p::crypto::X25519Keys m_EphemeralKeys; + SessionState m_State = eSessionStateNew; uint64_t m_LastActivityTimestamp = 0; // incoming - std::shared_ptr m_SendTagset, m_NSRTagset; - std::unique_ptr m_Destination;// TODO: might not need it + std::shared_ptr m_SendTagset, m_NSRTagset; + std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; @@ -174,8 +174,8 @@ namespace garlic i2p::data::IdentHash GetDestination () const { return m_Destination ? *m_Destination : i2p::data::IdentHash (); - } - }; + } + }; std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag); } diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 69fec4e8..8de5e3a1 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -121,7 +121,7 @@ namespace crypto return passed; } - void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, + void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const { BN_CTX * bnCtx = BN_CTX_new (); @@ -153,7 +153,7 @@ namespace crypto BN_CTX_free (bnCtx); } - void Ed25519::SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, + void Ed25519::SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const { BN_CTX * bnCtx = BN_CTX_new (); @@ -164,16 +164,16 @@ namespace crypto SHA512_CTX ctx; SHA512_Init (&ctx); SHA512_Update (&ctx, T, 80); - SHA512_Update (&ctx, publicKeyEncoded, 32); + SHA512_Update (&ctx, publicKeyEncoded, 32); SHA512_Update (&ctx, buf, len); // data uint8_t digest[64]; SHA512_Final (digest, &ctx); - BIGNUM * r = DecodeBN<64> (digest); - BN_mod (r, r, l, bnCtx); // % l + BIGNUM * r = DecodeBN<64> (digest); + BN_mod (r, r, l, bnCtx); // % l EncodeBN (r, digest, 32); // calculate R uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf - EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); + EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); // calculate S SHA512_Init (&ctx); SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R @@ -182,7 +182,7 @@ namespace crypto SHA512_Final (digest, &ctx); BIGNUM * h = DecodeBN<64> (digest); // S = (r + h*a) % l - BIGNUM * a = DecodeBN (privateKey); + BIGNUM * a = DecodeBN (privateKey); BN_mod_mul (h, h, a, l, bnCtx); // %l BN_mod_add (h, h, r, l, bnCtx); // %l memcpy (signature, R, EDDSA25519_SIGNATURE_LENGTH/2); @@ -190,7 +190,7 @@ namespace crypto BN_free (r); BN_free (h); BN_free (a); BN_CTX_free (bnCtx); } - + EDDSAPoint Ed25519::Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const { // x3 = (x1*y2+y1*x2)*(z1*z2-d*t1*t2) @@ -467,7 +467,7 @@ namespace crypto --bits; auto k_t = BN_is_bit_set(k, bits) ? 1 : 0; swap ^= k_t; - if (swap) + if (swap) { std::swap (x2, x3); std::swap (z2, z3); @@ -492,7 +492,7 @@ namespace crypto BN_mod_mul(z3, x1, z2, q, ctx); BN_mod_mul(z2, tmp1, tmp0, q, ctx); } - if (swap) + if (swap) { std::swap (x2, x3); std::swap (z2, z3); @@ -533,9 +533,9 @@ namespace crypto { BN_CTX * ctx = BN_CTX_new (); // calculate alpha = seed mod l - BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian + BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian BN_mod (alpha, alpha, l, ctx); // % l - uint8_t priv[32]; + uint8_t priv[32]; EncodeBN (alpha, priv, 32); // back to Little Endian BN_free (alpha); // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha) @@ -548,16 +548,16 @@ namespace crypto { BN_CTX * ctx = BN_CTX_new (); // calculate alpha = seed mod l - BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian + BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian BN_mod (alpha, alpha, l, ctx); // % l - BIGNUM * p = DecodeBN<32> (priv); // priv is in Little Endian + BIGNUM * p = DecodeBN<32> (priv); // priv is in Little Endian BN_add (alpha, alpha, p); // alpha = alpha + priv - // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L + // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L BN_mod (alpha, alpha, l, ctx); // % l EncodeBN (alpha, blindedPriv, 32); - // A' = DERIVE_PUBLIC(a') + // A' = DERIVE_PUBLIC(a') auto A1 = MulB (blindedPriv, ctx); - EncodePublicKey (A1, blindedPub, ctx); + EncodePublicKey (A1, blindedPub, ctx); BN_free (alpha); BN_free (p); BN_CTX_free (ctx); } @@ -574,14 +574,14 @@ namespace crypto { uint8_t seed[32]; RAND_bytes (seed, 32); - BIGNUM * p = DecodeBN<32> (seed); + BIGNUM * p = DecodeBN<32> (seed); BN_CTX * ctx = BN_CTX_new (); BN_mod (p, p, l, ctx); // % l - EncodeBN (p, priv, 32); + EncodeBN (p, priv, 32); BN_CTX_free (ctx); BN_free (p); - } - + } + static std::unique_ptr g_Ed25519; std::unique_ptr& GetEd25519 () { @@ -597,4 +597,3 @@ namespace crypto } } } - diff --git a/libi2pd/Ed25519.h b/libi2pd/Ed25519.h index 84501b03..10061ad0 100644 --- a/libi2pd/Ed25519.h +++ b/libi2pd/Ed25519.h @@ -86,10 +86,10 @@ namespace crypto bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const; void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const; void SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const; - + static void ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey); // key - 32 bytes, expandedKey - 64 bytes void CreateRedDSAPrivateKey (uint8_t * priv); // priv is 32 bytes - + private: EDDSAPoint Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const; @@ -97,8 +97,8 @@ namespace crypto EDDSAPoint Mul (const EDDSAPoint& p, const BIGNUM * e, BN_CTX * ctx) const; EDDSAPoint MulB (const uint8_t * e, BN_CTX * ctx) const; // B*e, e is 32 bytes Little Endian EDDSAPoint Normalize (const EDDSAPoint& p, BN_CTX * ctx) const; - - bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const; + + bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const; BIGNUM * RecoverX (const BIGNUM * y, BN_CTX * ctx) const; EDDSAPoint DecodePoint (const uint8_t * buf, BN_CTX * ctx) const; void EncodePoint (const EDDSAPoint& p, uint8_t * buf) const; @@ -109,7 +109,7 @@ namespace crypto #if !OPENSSL_X25519 // for x25519 - BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const; + BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const; #endif private: @@ -121,13 +121,11 @@ namespace crypto // if j > 128 we use 256 - j and carry 1 to next byte // Bi256[0][0] = B, base point EDDSAPoint Bi256Carry; // Bi256[32][0] - }; + }; std::unique_ptr& GetEd25519 (); } } - #endif - diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 48a5a7ac..8fefb2ae 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -6,7 +6,7 @@ namespace i2p { namespace crypto { - + Elligator2::Elligator2 () { // TODO: share with Ed22519 @@ -21,32 +21,32 @@ namespace crypto A = BN_new (); BN_set_word (A, 486662); nA = BN_new (); BN_sub (nA, p, A); - BN_CTX * ctx = BN_CTX_new (); - // calculate sqrt(-1) + BN_CTX * ctx = BN_CTX_new (); + // calculate sqrt(-1) sqrtn1 = BN_new (); - BN_set_word (sqrtn1, 2); + BN_set_word (sqrtn1, 2); BN_mod_exp (sqrtn1, sqrtn1, p14, p, ctx); // 2^((p-1)/4 - + u = BN_new (); BN_set_word (u, 2); - iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); - + iu = BN_new (); BN_mod_inverse (iu, u, p, ctx); + BN_CTX_free (ctx); } Elligator2::~Elligator2 () { BN_free (p); BN_free (p38); BN_free (p12); BN_free (p14); - BN_free (sqrtn1); BN_free (A); BN_free (nA); - BN_free (u); BN_free (iu); + BN_free (sqrtn1); BN_free (A); BN_free (nA); + BN_free (u); BN_free (iu); } bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY, bool random) const - { + { bool ret = true; BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - uint8_t key1[32]; + uint8_t key1[32]; for (size_t i = 0; i < 16; i++) // from Little Endian { key1[i] = key[31 - i]; @@ -59,35 +59,35 @@ namespace crypto BIGNUM * uxxA = BN_CTX_get (ctx); // u*x*xA BN_mod_mul (uxxA, u, x, p, ctx); - BN_mod_mul (uxxA, uxxA, xA, p, ctx); - + BN_mod_mul (uxxA, uxxA, xA, p, ctx); + if (Legendre (uxxA, ctx) != -1) - { - uint8_t randByte = 0; // random highest bits and high y + { + uint8_t randByte = 0; // random highest bits and high y if (random) - { - RAND_bytes (&randByte, 1); - highY = randByte & 0x01; + { + RAND_bytes (&randByte, 1); + highY = randByte & 0x01; } - + BIGNUM * r = BN_CTX_get (ctx); if (highY) { BN_mod_inverse (r, x, p, ctx); - BN_mod_mul (r, r, xA, p, ctx); + BN_mod_mul (r, r, xA, p, ctx); } else { - BN_mod_inverse (r, xA, p, ctx); + BN_mod_inverse (r, xA, p, ctx); BN_mod_mul (r, r, x, p, ctx); - } - BN_mod_mul (r, r, iu, p, ctx); - + } + BN_mod_mul (r, r, iu, p, ctx); + SquareRoot (r, r, ctx); bn2buf (r, encoded, 32); if (random) - encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte + encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = encoded[i]; @@ -98,7 +98,7 @@ namespace crypto else ret = false; - BN_CTX_end (ctx); + BN_CTX_end (ctx); BN_CTX_free (ctx); return ret; } @@ -109,31 +109,31 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); BN_CTX_start (ctx); - uint8_t encoded1[32]; + uint8_t encoded1[32]; for (size_t i = 0; i < 16; i++) // from Little Endian { encoded1[i] = encoded[31 - i]; encoded1[31 - i] = encoded[i]; } - encoded1[0] &= 0x3F; // drop two highest bits + encoded1[0] &= 0x3F; // drop two highest bits BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r); if (BN_cmp (r, p12) <= 0) // r < (p-1)/2 { // v = -A/(1+u*r^2) - BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); + BIGNUM * v = BN_CTX_get (ctx); BN_mod_sqr (v, r, p, ctx); BN_mod_mul (v, v, u, p, ctx); BN_add_word (v, 1); - BN_mod_inverse (v, v, p, ctx); + BN_mod_inverse (v, v, p, ctx); BN_mod_mul (v, v, nA, p, ctx); BIGNUM * vpA = BN_CTX_get (ctx); BN_add (vpA, v, A); // v + A // t = v^3+A*v^2+v = v^2*(v+A)+v - BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); - BN_mod_mul (t, t, vpA, p, ctx); - BN_mod_add (t, t, v, p, ctx); + BIGNUM * t = BN_CTX_get (ctx); BN_mod_sqr (t, v, p, ctx); + BN_mod_mul (t, t, vpA, p, ctx); + BN_mod_add (t, t, v, p, ctx); int legendre = Legendre (t, ctx); BIGNUM * x = BN_CTX_get (ctx); @@ -143,9 +143,9 @@ namespace crypto { BN_sub (x, p, v); BN_mod_sub (x, x, A, p, ctx); - } - - bn2buf (x, key, 32); + } + + bn2buf (x, key, 32); for (size_t i = 0; i < 16; i++) // To Little Endian { uint8_t tmp = key[i]; @@ -156,7 +156,7 @@ namespace crypto else ret = false; - BN_CTX_end (ctx); + BN_CTX_end (ctx); BN_CTX_free (ctx); return ret; @@ -170,21 +170,21 @@ namespace crypto BN_add_word (t, 1); if (!BN_cmp (t, p)) - BN_mod_mul (r, r, sqrtn1, p, ctx); + BN_mod_mul (r, r, sqrtn1, p, ctx); if (BN_cmp (r, p12) > 0) // r > (p-1)/2 BN_sub (r, p, r); - } - + } + int Elligator2::Legendre (const BIGNUM * a, BN_CTX * ctx) const { // assume a < p, so don't check for a % p = 0, but a = 0 only - if (BN_is_zero(a)) return 0; + if (BN_is_zero(a)) return 0; BIGNUM * r = BN_CTX_get (ctx); BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p - if (BN_is_word(r, 1)) + if (BN_is_word(r, 1)) return 1; - else if (BN_is_zero(r)) + else if (BN_is_zero(r)) return 0; return -1; } @@ -204,4 +204,3 @@ namespace crypto } } } - diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 7cdcbbfe..56fbc2eb 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -20,11 +20,11 @@ namespace crypto bool Encode (const uint8_t * key, uint8_t * encoded, bool highY = false, bool random = true) const; bool Decode (const uint8_t * encoded, uint8_t * key) const; - private: + private: void SquareRoot (const BIGNUM * x, BIGNUM * r, BN_CTX * ctx) const; int Legendre (const BIGNUM * a, BN_CTX * ctx) const; // a/p - + private: BIGNUM * p, * p38, * p12, * p14, * sqrtn1, * A, * nA, * u, * iu; @@ -35,5 +35,3 @@ namespace crypto } #endif - - diff --git a/libi2pd/FS.h b/libi2pd/FS.h index 6f112218..054ac2a3 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -17,133 +17,136 @@ namespace i2p { namespace fs { - extern std::string dirSep; + extern std::string dirSep; - /** - * @brief Class to work with NetDb & Router profiles - * - * Usage: - * - * const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; - * auto h = HashedStorage("name", "y", "z-", ".txt"); - * h.SetPlace("/tmp/hs-test"); - * h.GetName() -> gives "name" - * h.GetRoot() -> gives "/tmp/hs-test/name" - * h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet - * h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt - * h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists - * std::vector files; - * h.Traverse(files); <- finds all files in storage and saves in given vector - */ - class HashedStorage { - protected: - std::string root; /**< path to storage with it's name included */ - std::string name; /**< name of the storage */ - std::string prefix1; /**< hashed directory prefix */ - std::string prefix2; /**< prefix of file in storage */ - std::string suffix; /**< suffix of file in storage (extension) */ + /** + * @brief Class to work with NetDb & Router profiles + * + * Usage: + * + * const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; + * auto h = HashedStorage("name", "y", "z-", ".txt"); + * h.SetPlace("/tmp/hs-test"); + * h.GetName() -> gives "name" + * h.GetRoot() -> gives "/tmp/hs-test/name" + * h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet + * h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt + * h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists + * std::vector files; + * h.Traverse(files); <- finds all files in storage and saves in given vector + */ + class HashedStorage + { + protected: - public: - typedef std::function FilenameVisitor; - HashedStorage(const char *n, const char *p1, const char *p2, const char *s): - name(n), prefix1(p1), prefix2(p2), suffix(s) {}; + std::string root; /**< path to storage with it's name included */ + std::string name; /**< name of the storage */ + std::string prefix1; /**< hashed directory prefix */ + std::string prefix2; /**< prefix of file in storage */ + std::string suffix; /**< suffix of file in storage (extension) */ - /** create subdirs in storage */ - bool Init(const char* chars, size_t cnt); - const std::string & GetRoot() const { return root; } - const std::string & GetName() const { return name; } - /** set directory where to place storage directory */ - void SetPlace(const std::string & path); - /** path to file with given ident */ - std::string Path(const std::string & ident) const; - /** remove file by ident */ - void Remove(const std::string & ident); - /** find all files in storage and store list in provided vector */ - void Traverse(std::vector & files); - /** visit every file in this storage with a visitor */ - void Iterate(FilenameVisitor v); - }; + public: - /** @brief Returns current application name, default 'i2pd' */ + typedef std::function FilenameVisitor; + HashedStorage(const char *n, const char *p1, const char *p2, const char *s): + name(n), prefix1(p1), prefix2(p2), suffix(s) {}; + + /** create subdirs in storage */ + bool Init(const char* chars, size_t cnt); + const std::string & GetRoot() const { return root; } + const std::string & GetName() const { return name; } + /** set directory where to place storage directory */ + void SetPlace(const std::string & path); + /** path to file with given ident */ + std::string Path(const std::string & ident) const; + /** remove file by ident */ + void Remove(const std::string & ident); + /** find all files in storage and store list in provided vector */ + void Traverse(std::vector & files); + /** visit every file in this storage with a visitor */ + void Iterate(FilenameVisitor v); + }; + + /** @brief Returns current application name, default 'i2pd' */ const std::string & GetAppName (); - /** @brief Set application name, affects autodetection of datadir */ + /** @brief Set application name, affects autodetection of datadir */ void SetAppName (const std::string& name); - /** @brief Returns datadir path */ - const std::string & GetDataDir(); + /** @brief Returns datadir path */ + const std::string & GetDataDir(); - /** - * @brief Set datadir either from cmdline option or using autodetection - * @param cmdline_param Value of cmdline parameter --datadir= - * @param isService Value of cmdline parameter --service - * - * Examples of autodetected paths: - * - * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\ - * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\ - * 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); + /** + * @brief Set datadir either from cmdline option or using autodetection + * @param cmdline_param Value of cmdline parameter --datadir= + * @param isService Value of cmdline parameter --service + * + * Examples of autodetected paths: + * + * Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\ + * Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\ + * 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); - /** - * @brief Create subdirectories inside datadir - */ - bool Init(); + /** + * @brief Create subdirectories inside datadir + */ + bool Init(); - /** - * @brief Get list of files in directory - * @param path Path to directory - * @param files Vector to store found files - * @return true on success and false if directory not exists - */ - bool ReadDir(const std::string & path, std::vector & files); + /** + * @brief Get list of files in directory + * @param path Path to directory + * @param files Vector to store found files + * @return true on success and false if directory not exists + */ + bool ReadDir(const std::string & path, std::vector & files); - /** - * @brief Remove file with given path - * @param path Absolute path to file - * @return true on success, false if file not exists, throws exception on error - */ - bool Remove(const std::string & path); + /** + * @brief Remove file with given path + * @param path Absolute path to file + * @return true on success, false if file not exists, throws exception on error + */ + bool Remove(const std::string & path); - /** - * @brief Check existence of file - * @param path Absolute path to file - * @return true if file exists, false otherwise - */ - bool Exists(const std::string & path); + /** + * @brief Check existence of file + * @param path Absolute path to file + * @return true if file exists, false otherwise + */ + bool Exists(const std::string & path); - uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch + uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch - bool CreateDirectory (const std::string& path); + bool CreateDirectory (const std::string& path); - template - void _ExpandPath(std::stringstream & path, T c) { - path << i2p::fs::dirSep << c; - } + template + void _ExpandPath(std::stringstream & path, T c) { + path << i2p::fs::dirSep << c; + } - template - void _ExpandPath(std::stringstream & path, T c, Other ... other) { - _ExpandPath(path, c); - _ExpandPath(path, other ...); - } + template + void _ExpandPath(std::stringstream & path, T c, Other ... other) { + _ExpandPath(path, c); + _ExpandPath(path, other ...); + } - /** - * @brief Get path relative to datadir - * - * Examples (with datadir = "/tmp/i2pd"): - * - * i2p::fs::Path("test") -> '/tmp/i2pd/test' - * i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt' - */ - template - std::string DataDirPath(Other ... components) { - std::stringstream s(""); - s << i2p::fs::GetDataDir(); - _ExpandPath(s, components ...); + /** + * @brief Get path relative to datadir + * + * Examples (with datadir = "/tmp/i2pd"): + * + * i2p::fs::Path("test") -> '/tmp/i2pd/test' + * i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt' + */ + template + std::string DataDirPath(Other ... components) { + std::stringstream s(""); + s << i2p::fs::GetDataDir(); + _ExpandPath(s, components ...); - return s.str(); - } + return s.str(); + } template std::string StorageRootPath (const Storage& storage, Filename... filenames) diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index bc99bb52..e5ac9990 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -179,4 +179,3 @@ namespace data } } } - diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 8ba4a8a1..5d07155e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -38,9 +38,9 @@ namespace garlic if (!m_SharedRoutingPath) return nullptr; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); if (m_SharedRoutingPath->numTimesUsed >= ROUTING_PATH_MAX_NUM_TIMES_USED || - !m_SharedRoutingPath->outboundTunnel->IsEstablished () || + !m_SharedRoutingPath->outboundTunnel->IsEstablished () || ts*1000LL > m_SharedRoutingPath->remoteLease->endDate || - ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT) + ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT) m_SharedRoutingPath = nullptr; if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++; return m_SharedRoutingPath; @@ -68,7 +68,7 @@ namespace garlic return true; } return false; - } + } void GarlicRoutingSession::CleanupUnconfirmedLeaseSet (uint64_t ts) { @@ -78,8 +78,8 @@ namespace garlic GetOwner ()->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); m_LeaseSetUpdateMsgID = 0; } - } - + } + std::shared_ptr GarlicRoutingSession::CreateEncryptedDeliveryStatusMsg (uint32_t msgID) { auto msg = CreateDeliveryStatusMsg (msgID); @@ -94,12 +94,12 @@ namespace garlic msg = garlic.WrapSingleMessage (msg); } return msg; - } - - ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, - std::shared_ptr destination, int numTags, bool attachLeaseSet): - GarlicRoutingSession (owner, attachLeaseSet), - m_Destination (destination), m_NumTags (numTags) + } + + ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner, + std::shared_ptr destination, int numTags, bool attachLeaseSet): + GarlicRoutingSession (owner, attachLeaseSet), + m_Destination (destination), m_NumTags (numTags) { // create new session tags and session key RAND_bytes (m_SessionKey, 32); @@ -115,7 +115,7 @@ namespace garlic m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch (); } - std::shared_ptr ElGamalAESSession::WrapSingleMessage (std::shared_ptr msg) + std::shared_ptr ElGamalAESSession::WrapSingleMessage (std::shared_ptr msg) { auto m = NewI2NPMessage (); m->Align (12); // in order to get buf aligned to 16 (12 + 4) @@ -181,7 +181,7 @@ namespace garlic return m; } - size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr msg) + size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr msg) { size_t blockSize = 0; bool createNewTags = GetOwner () && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3); @@ -329,10 +329,10 @@ namespace garlic // create msg auto msg = CreateEncryptedDeliveryStatusMsg (msgID); if (msg) - { + { memcpy (buf + size, msg->GetBuffer (), msg->GetLength ()); size += msg->GetLength (); - } + } // fill clove uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 8000; // 8 sec uint32_t cloveID; @@ -353,7 +353,7 @@ namespace garlic return size; } - ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags () + ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags () { auto tags = new UnconfirmedTags (m_NumTags); tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch (); @@ -487,7 +487,7 @@ namespace garlic LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes"); } else - { + { bool found = false; if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) { @@ -500,15 +500,15 @@ namespace garlic found = true; auto session = it1->second.tagset->GetSession (); if (!session || !session->HandleNextMessage (buf, length, it1->second.tagset, it1->second.index)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it1); } - } - - if (!found) // assume new session + } + + if (!found) // assume new session { - // AES tag not found. Handle depending on encryption type - // try ElGamal/AES first if leading block is 514 + // AES tag not found. Handle depending on encryption type + // 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)) @@ -521,16 +521,16 @@ namespace garlic HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - { - // otherwise ECIESx25519 + { + // otherwise ECIESx25519 auto session = std::make_shared (this, false); // incoming if (!session->HandleNextMessage (buf, length, nullptr, 0)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); - } + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + } else - LogPrint (eLogError, "Garlic: Failed to decrypt message"); + LogPrint (eLogError, "Garlic: Failed to decrypt message"); } - } + } } void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr decryption, @@ -703,41 +703,41 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && - SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - { - ECIESX25519AEADRatchetSessionPtr session; - uint8_t staticKey[32]; - destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key - auto it = m_ECIESx25519Sessions.find (staticKey); + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && + SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + { + ECIESX25519AEADRatchetSessionPtr session; + uint8_t staticKey[32]; + destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key + auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) - session = it->second; - if (!session) + session = it->second; + if (!session) { session = std::make_shared (this, true); session->SetRemoteStaticKey (staticKey); - } + } session->SetDestination (destination->GetIdentHash ()); // TODO: remove - return session; - } - else - { - ElGamalAESSessionPtr session; - { - std::unique_lock l(m_SessionsMutex); - auto it = m_Sessions.find (destination->GetIdentHash ()); - if (it != m_Sessions.end ()) - session = it->second; - } - if (!session) - { - session = std::make_shared (this, destination, - attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests - std::unique_lock l(m_SessionsMutex); - m_Sessions[destination->GetIdentHash ()] = session; - } - return session; - } + return session; + } + else + { + ElGamalAESSessionPtr session; + { + std::unique_lock l(m_SessionsMutex); + auto it = m_Sessions.find (destination->GetIdentHash ()); + if (it != m_Sessions.end ()) + session = it->second; + } + if (!session) + { + session = std::make_shared (this, destination, + attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests + std::unique_lock l(m_SessionsMutex); + m_Sessions[destination->GetIdentHash ()] = session; + } + return session; + } } void GarlicDestination::CleanupExpiredTags () @@ -791,7 +791,7 @@ namespace garlic if (it->second.tagset->IsExpired (ts) || ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) it = m_ECIESx25519Tags.erase (it); else - ++it; + ++it; } for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) @@ -800,7 +800,7 @@ namespace garlic { it->second->SetOwner (nullptr); it = m_ECIESx25519Sessions.erase (it); - } + } else ++it; } @@ -925,28 +925,28 @@ namespace garlic std::vector files; i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files); uint32_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it: files) + for (auto it: files) if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT) i2p::fs::Remove (it); } - void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) - { - const uint8_t * buf1 = buf; + void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len) + { + const uint8_t * buf1 = buf; uint8_t flag = buf[0]; buf++; // flag GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03); switch (deliveryType) { case eGarlicDeliveryTypeDestination: - LogPrint (eLogDebug, "Garlic: type destination"); + LogPrint (eLogDebug, "Garlic: type destination"); buf += 32; // TODO: check destination -#if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif // no break here case eGarlicDeliveryTypeLocal: { - LogPrint (eLogDebug, "Garlic: type local"); + LogPrint (eLogDebug, "Garlic: type local"); I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid buf += (4 + 4); // msgID + expiration ptrdiff_t offset = buf - buf1; @@ -957,8 +957,8 @@ namespace garlic break; } case eGarlicDeliveryTypeTunnel: - { - LogPrint (eLogDebug, "Garlic: type tunnel"); + { + LogPrint (eLogDebug, "Garlic: type tunnel"); // gwHash and gwTunnel sequence is reverted const uint8_t * gwHash = buf; buf += 32; @@ -968,47 +968,47 @@ namespace garlic LogPrint (eLogError, "Garlic: message is too short"); break; } - uint32_t gwTunnel = bufbe32toh (buf); buf += 4; - I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid + uint32_t gwTunnel = bufbe32toh (buf); buf += 4; + I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid buf += (4 + 4); // msgID + expiration - offset += 13; + offset += 13; if (GetTunnelPool ()) - { - auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); - if (tunnel) - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); + { + auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel (); + if (tunnel) + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset)); else - LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); - } + LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); + } else LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel"); - break; - } + break; + } default: LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType); - } - } + } + } - void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) - { + void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) + { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); - m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()}); - } + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()}); + } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) { i2p::data::Tag<32> staticKeyTag (staticKey); auto it = m_ECIESx25519Sessions.find (staticKeyTag); if (it != m_ECIESx25519Sessions.end ()) - { + { if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ())) m_ECIESx25519Sessions.erase (it); else { - LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); + LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); return; - } + } } m_ECIESx25519Sessions.emplace (staticKeyTag, session); } @@ -1020,7 +1020,7 @@ namespace garlic { it->second->SetOwner (nullptr); m_ECIESx25519Sessions.erase (it); - } - } + } + } } } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 86c9e432..55ebe795 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -87,8 +87,8 @@ namespace garlic class GarlicDestination; class GarlicRoutingSession { - protected: - + protected: + enum LeaseSetUpdateStatus { eLeaseSetUpToDate = 0, @@ -103,10 +103,10 @@ namespace garlic GarlicRoutingSession (); virtual ~GarlicRoutingSession (); virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; - virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession + virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); virtual bool IsRatchets () const { return false; }; - + void SetLeaseSetUpdated () { if (m_LeaseSetUpdateStatus != eLeaseSetDoNotSend) m_LeaseSetUpdateStatus = eLeaseSetUpdated; @@ -115,23 +115,23 @@ namespace garlic bool IsLeaseSetUpdated () const { return m_LeaseSetUpdateStatus == eLeaseSetUpdated; }; uint64_t GetLeaseSetSubmissionTime () const { return m_LeaseSetSubmissionTime; } void CleanupUnconfirmedLeaseSet (uint64_t ts); - + std::shared_ptr GetSharedRoutingPath (); void SetSharedRoutingPath (std::shared_ptr path); GarlicDestination * GetOwner () const { return m_Owner; } void SetOwner (GarlicDestination * owner) { m_Owner = owner; } - - protected: - - LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } - void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; } - uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; } - void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } - void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } + + protected: + + LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; } + void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; } + uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; } + void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; } + void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; } std::shared_ptr CreateEncryptedDeliveryStatusMsg (uint32_t msgID); - + private: GarlicDestination * m_Owner; @@ -143,38 +143,39 @@ namespace garlic std::shared_ptr m_SharedRoutingPath; public: + // for HTTP only virtual size_t GetNumOutgoingTags () const { return 0; }; }; - //using GarlicRoutingSessionPtr = std::shared_ptr; - typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 + //using GarlicRoutingSessionPtr = std::shared_ptr; + typedef std::shared_ptr GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8 - class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this - { - struct UnconfirmedTags - { - UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; - ~UnconfirmedTags () { delete[] sessionTags; }; - uint32_t msgID; - int numTags; - SessionTag * sessionTags; - uint32_t tagsCreationTime; - }; + class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this + { + struct UnconfirmedTags + { + UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; + ~UnconfirmedTags () { delete[] sessionTags; }; + uint32_t msgID; + int numTags; + SessionTag * sessionTags; + uint32_t tagsCreationTime; + }; - public: + public: - ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, + ElGamalAESSession (GarlicDestination * owner, std::shared_ptr destination, int numTags, bool attachLeaseSet); ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption ~ElGamalAESSession () {}; - std::shared_ptr WrapSingleMessage (std::shared_ptr msg); - - bool MessageConfirmed (uint32_t msgID); + std::shared_ptr WrapSingleMessage (std::shared_ptr msg); + + bool MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left bool CleanupUnconfirmedTags (); // returns true if something has been deleted - private: + private: size_t CreateAESBlock (uint8_t * buf, std::shared_ptr msg); size_t CreateGarlicPayload (uint8_t * payload, std::shared_ptr msg, UnconfirmedTags * newTags); @@ -183,32 +184,33 @@ namespace garlic void TagsConfirmed (uint32_t msgID); UnconfirmedTags * GenerateSessionTags (); - - private: - - std::shared_ptr m_Destination; - i2p::crypto::AESKey m_SessionKey; + private: + + std::shared_ptr m_Destination; + + i2p::crypto::AESKey m_SessionKey; std::list m_SessionTags; int m_NumTags; std::map > m_UnconfirmedTagsMsgs; // msgID->tags - i2p::crypto::CBCEncryption m_Encryption; + i2p::crypto::CBCEncryption m_Encryption; + + public: - public: // for HTTP only - size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; - }; - typedef std::shared_ptr ElGamalAESSessionPtr; + size_t GetNumOutgoingTags () const { return m_SessionTags.size (); }; + }; + typedef std::shared_ptr ElGamalAESSessionPtr; - class ECIESX25519AEADRatchetSession; - typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; + class ECIESX25519AEADRatchetSession; + typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; class RatchetTagSet; typedef std::shared_ptr RatchetTagSetPtr; struct ECIESX25519AEADRatchetIndexTagset - { - int index; - RatchetTagSetPtr tagset; + { + int index; + RatchetTagSetPtr tagset; uint64_t creationTime; // seconds since epoch }; @@ -226,12 +228,12 @@ namespace garlic void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); std::shared_ptr WrapMessage (std::shared_ptr destination, - std::shared_ptr msg, bool attachLeaseSet = false); + std::shared_ptr msg, bool attachLeaseSet = false); void AddSessionKey (const uint8_t * key, const uint8_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); - void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); + void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); @@ -266,10 +268,10 @@ namespace garlic int m_NumTags; std::mutex m_SessionsMutex; std::unordered_map m_Sessions; - std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session + std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming std::unordered_map, std::hash > > m_Tags; - std::unordered_map m_ECIESx25519Tags; // session tag -> session + std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session diff --git a/libi2pd/Gost.h b/libi2pd/Gost.h index 30386104..a4cc9741 100644 --- a/libi2pd/Gost.h +++ b/libi2pd/Gost.h @@ -13,11 +13,11 @@ namespace crypto enum GOSTR3410ParamSet { - eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 + eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 // XchA = A, XchB = C - //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 - //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 - eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1 + //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 + //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 + eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1 eGOSTR3410NumParamSets }; diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index f36620ae..5709719b 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -40,13 +40,13 @@ namespace data { LogPrint (eLogError, "Gzip: Incorrect length"); return 0; - } + } if (len > outLen) len = outLen; memcpy (out, in + 15, len); return len; } else - { + { if (m_IsDirty) inflateReset (&m_Inflator); m_IsDirty = true; m_Inflator.next_in = const_cast(in); @@ -59,7 +59,7 @@ namespace data // else LogPrint (eLogError, "Gzip: Inflate error ", err); return 0; - } + } } void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os) @@ -126,7 +126,7 @@ namespace data { out[9] = 0xff; // OS is always unknown return outLen - m_Deflator.avail_out; - } + } // else LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; @@ -147,21 +147,21 @@ namespace data auto flush = (it == bufs.back ()) ? Z_FINISH : Z_NO_FLUSH; err = deflate (&m_Deflator, flush); if (err) - { + { if (flush && err == Z_STREAM_END) { out[9] = 0xff; // OS is always unknown return outLen - m_Deflator.avail_out; - } + } break; } offset = outLen - m_Deflator.avail_out; - } + } // else LogPrint (eLogError, "Gzip: Deflate error ", err); return 0; - } - + } + size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen) { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; @@ -176,7 +176,7 @@ namespace data } size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen) - { + { static const uint8_t gzipHeader[11] = { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x01 }; memcpy (out, gzipHeader, 11); uint32_t crc = 0; @@ -186,9 +186,9 @@ namespace data len1 = len; len += it.second; if (outLen < len + 23) return 0; - memcpy (out + 15 + len1, it.first, it.second); + memcpy (out + 15 + len1, it.first, it.second); crc = crc32 (crc, it.first, it.second); - } + } if (len > 0xffff) return 0; htole32buf (out + len + 15, crc); htole32buf (out + len + 19, len); @@ -196,6 +196,6 @@ namespace data htole16buf (out + 13, 0xffff - len); return len + 23; } - + } // data } // i2p diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index 16776d35..6489b79b 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -4,9 +4,9 @@ #include #include -namespace i2p +namespace i2p { -namespace data +namespace data { class GzipInflator { @@ -45,7 +45,6 @@ namespace data size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K size_t GzipNoCompression (const std::vector >& bufs, uint8_t * out, size_t outLen); // for total size < 64K - } // data } // i2p diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 3a139792..170bb864 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -180,9 +180,9 @@ namespace i2p // excluded if (cnt > 512) { - LogPrint (eLogWarning, "I2NP: Too many peers to exclude ", cnt, " for DatabaseLookup"); + LogPrint (eLogWarning, "I2NP: Too many peers to exclude ", cnt, " for DatabaseLookup"); cnt = 0; - } + } htobe16buf (buf, cnt); buf += 2; if (cnt > 0) @@ -205,7 +205,7 @@ namespace i2p } std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, - std::vector routers) + std::vector routers) { auto m = NewI2NPShortMessage (); uint8_t * buf = m->GetPayload (); @@ -268,7 +268,7 @@ namespace i2p auto m = NewI2NPShortMessage (); uint8_t * payload = m->GetPayload (); memcpy (payload + DATABASE_STORE_KEY_OFFSET, storeHash, 32); - payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet + payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0); size_t size = DATABASE_STORE_HEADER_SIZE; memcpy (payload + size, leaseSet->GetBuffer (), leaseSet->GetBufferLen ()); @@ -278,7 +278,7 @@ namespace i2p return m; } - std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken, std::shared_ptr replyTunnel) + std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken, std::shared_ptr replyTunnel) { if (!leaseSet) return nullptr; auto m = NewI2NPShortMessage (); @@ -347,11 +347,11 @@ namespace i2p auto transitTunnel = 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), + 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_IV_KEY_OFFSET, clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80, - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40); + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0; } @@ -386,7 +386,7 @@ namespace i2p return; } - auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); + auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); if (tunnel) { // endpoint of inbound tunnel @@ -414,7 +414,7 @@ namespace i2p 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))); + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -440,7 +440,7 @@ namespace i2p 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))); + bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET))); } else transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, @@ -592,13 +592,13 @@ namespace i2p switch (typeID) { case eI2NPVariableTunnelBuild: - HandleVariableTunnelBuildMsg (msgID, buf, size); + HandleVariableTunnelBuildMsg (msgID, buf, size); break; case eI2NPVariableTunnelBuildReply: HandleVariableTunnelBuildReplyMsg (msgID, buf, size); break; case eI2NPTunnelBuild: - HandleTunnelBuildMsg (buf, size); + HandleTunnelBuildMsg (buf, size); break; case eI2NPTunnelBuildReply: // TODO: @@ -667,7 +667,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 c8957b5f..4ecba2eb 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -27,7 +27,7 @@ namespace i2p const size_t I2NP_SHORT_HEADER_SIZE = I2NP_SHORT_HEADER_EXPIRATION_OFFSET + 4; // I2NP NTCP2 header - const size_t I2NP_NTCP2_HEADER_SIZE = I2NP_HEADER_EXPIRATION_OFFSET + 4; + const size_t I2NP_NTCP2_HEADER_SIZE = I2NP_HEADER_EXPIRATION_OFFSET + 4; // Tunnel Gateway header const size_t TUNNEL_GATEWAY_HEADER_TUNNELID_OFFSET = 0; @@ -75,7 +75,7 @@ namespace i2p enum I2NPMessageType { - eI2NPDummyMsg = 0, + eI2NPDummyMsg = 0, eI2NPDatabaseStore = 1, eI2NPDatabaseLookup = 2, eI2NPDatabaseSearchReply = 3, @@ -209,7 +209,7 @@ namespace tunnel SetExpiration (bufbe32toh (ntcp2 + I2NP_HEADER_EXPIRATION_OFFSET)*1000LL); SetSize (len - offset - I2NP_HEADER_SIZE); SetChks (0); - } + } void ToNTCP2 () { diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 0c2dc50e..77a1f7e2 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -356,7 +356,7 @@ namespace data } return nullptr; } - + void IdentityEx::CreateVerifier () const { if (m_Verifier) return; // don't create again @@ -369,15 +369,15 @@ namespace data else { // for P521 - uint8_t * signingKey = new uint8_t[keyLen]; + uint8_t * signingKey = new uint8_t[keyLen]; memcpy (signingKey, m_StandardIdentity.signingKey, 128); - size_t excessLen = keyLen - 128; + size_t excessLen = keyLen - 128; memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types verifier->SetPublicKey (signingKey); - delete[] signingKey; - } - } - UpdateVerifier (verifier); + delete[] signingKey; + } + } + UpdateVerifier (verifier); } void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const @@ -390,7 +390,7 @@ namespace data else del = true; } - if (del) + if (del) delete verifier; } @@ -426,7 +426,7 @@ namespace data LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)keyType); }; return nullptr; - } + } std::shared_ptr IdentityEx::CreateEncryptor (const uint8_t * key) const { @@ -460,9 +460,9 @@ namespace data return *this; } - size_t PrivateKeys::GetFullLen () const - { - size_t ret = m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); + size_t PrivateKeys::GetFullLen () const + { + size_t ret = m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); if (IsOfflineSignature ()) ret += m_OfflineSignature.size () + m_TransientSigningPrivateKeyLen; return ret; @@ -483,7 +483,7 @@ namespace data // check if signing private key is all zeros bool allzeros = true; for (size_t i = 0; i < signingPrivateKeySize; i++) - if (m_SigningPrivateKey[i]) + if (m_SigningPrivateKey[i]) { allzeros = false; break; @@ -500,7 +500,7 @@ namespace data if (keyLen + ret > len) return 0; transientVerifier->SetPublicKey (buf + ret); ret += keyLen; if (m_Public->GetSignatureLen () + ret > len) return 0; - if (!m_Public->Verify (offlineInfo, keyLen + 6, buf + ret)) + if (!m_Public->Verify (offlineInfo, keyLen + 6, buf + ret)) { LogPrint (eLogError, "Identity: offline signature verification failed"); return 0; @@ -511,7 +511,7 @@ namespace data size_t offlineInfoLen = buf + ret - offlineInfo; m_OfflineSignature.resize (offlineInfoLen); memcpy (m_OfflineSignature.data (), offlineInfo, offlineInfoLen); - // override signing private key + // override signing private key m_TransientSigningPrivateKeyLen = transientVerifier->GetPrivateKeyLen (); if (m_TransientSigningPrivateKeyLen + ret > len || m_TransientSigningPrivateKeyLen > 128) return 0; memcpy (m_SigningPrivateKey, buf + ret, m_TransientSigningPrivateKeyLen); @@ -586,10 +586,10 @@ namespace data else CreateSigner (m_Public->GetSigningKeyType ()); } - + void PrivateKeys::CreateSigner (SigningKeyType keyType) const { - if (m_Signer) return; + if (m_Signer) return; if (keyType == SIGNING_KEY_TYPE_DSA_SHA1) m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey)); else if (keyType == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 && !IsOfflineSignature ()) @@ -599,7 +599,7 @@ namespace data // public key is not required auto signer = CreateSigner (keyType, m_SigningPrivateKey); if (signer) m_Signer.reset (signer); - } + } } i2p::crypto::Signer * PrivateKeys::CreateSigner (SigningKeyType keyType, const uint8_t * priv) @@ -630,8 +630,8 @@ namespace data return new i2p::crypto::GOSTR3410_512_Signer (i2p::crypto::eGOSTR3410TC26A512, priv); break; case SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: - return new i2p::crypto::RedDSA25519Signer (priv); - break; + return new i2p::crypto::RedDSA25519Signer (priv); + break; default: LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported"); } @@ -719,8 +719,8 @@ namespace data case SIGNING_KEY_TYPE_RSA_SHA512_4096: LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Creating EdDSA"); #if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif + [[fallthrough]]; +#endif // no break here case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: i2p::crypto::CreateEDDSA25519RandomKeys (priv, pub); @@ -733,7 +733,7 @@ namespace data break; case SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519: i2p::crypto::CreateRedDSA25519RandomKeys (priv, pub); - break; + break; default: LogPrint (eLogWarning, "Identity: Signing key type ", (int)type, " is not supported. Create DSA-SHA1"); i2p::crypto::CreateDSARandomKeys (priv, pub); // DSA-SHA1 @@ -765,7 +765,7 @@ namespace data PrivateKeys PrivateKeys::CreateOfflineKeys (SigningKeyType type, uint32_t expires) const { PrivateKeys keys (*this); - std::unique_ptr verifier (IdentityEx::CreateVerifier (type)); + std::unique_ptr verifier (IdentityEx::CreateVerifier (type)); if (verifier) { size_t pubKeyLen = verifier->GetPublicKeyLen (); @@ -775,7 +775,7 @@ namespace data htobe32buf (keys.m_OfflineSignature.data (), expires); // expires htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key - Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature + Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature // recreate signer keys.m_Signer = nullptr; keys.CreateSigner (type); diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index da14e141..08baba01 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -56,7 +56,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; - const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; + const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES @@ -115,7 +115,7 @@ namespace data void RecalculateIdentHash(uint8_t * buff=nullptr); static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType); - static std::shared_ptr CreateEncryptor (CryptoKeyType keyType, const uint8_t * key); + static std::shared_ptr CreateEncryptor (CryptoKeyType keyType, const uint8_t * key); private: @@ -148,7 +148,7 @@ namespace data const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; size_t GetSignatureLen () const; // might not match identity bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; }; - uint8_t * GetPadding(); + uint8_t * GetPadding(); void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } void Sign (const uint8_t * buf, int len, uint8_t * signature) const; @@ -163,12 +163,12 @@ namespace data static std::shared_ptr CreateDecryptor (CryptoKeyType cryptoType, const uint8_t * key); static PrivateKeys CreateRandomKeys (SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1, CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL); - static void GenerateSigningKeyPair (SigningKeyType type, uint8_t * priv, uint8_t * pub); + static void GenerateSigningKeyPair (SigningKeyType type, uint8_t * priv, uint8_t * pub); static void GenerateCryptoKeyPair (CryptoKeyType type, uint8_t * priv, uint8_t * pub); // priv and pub are 256 bytes long static i2p::crypto::Signer * CreateSigner (SigningKeyType keyType, const uint8_t * priv); // offline keys - PrivateKeys CreateOfflineKeys (SigningKeyType type, uint32_t expires) const; + PrivateKeys CreateOfflineKeys (SigningKeyType type, uint32_t expires) const; const std::vector& GetOfflineSignature () const { return m_OfflineSignature; }; private: @@ -204,7 +204,7 @@ namespace data IdentHash CreateRoutingKey (const IdentHash& ident); XORMetric operator^(const IdentHash& key1, const IdentHash& key2); - // destination for delivery instuctions + // destination for delivery instructions class RoutingDestination { public: @@ -235,5 +235,4 @@ namespace data } } - #endif diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 6ce77792..1aa7fa6d 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -12,9 +12,8 @@ namespace i2p { namespace data { - LeaseSet::LeaseSet (bool storeLeases): - m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr), + m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr), m_Buffer (nullptr), m_BufferLen (0) { } @@ -62,7 +61,7 @@ namespace data { if (!m_EncryptionKey) m_EncryptionKey = new uint8_t[256]; memcpy (m_EncryptionKey, m_Buffer + size, 256); - } + } size += 256; // encryption key size += m_Identity->GetSigningPublicKeyLen (); // unused signing key uint8_t num = m_Buffer[size]; @@ -191,10 +190,10 @@ namespace data return m_ExpirationTime - now <= dlt; } - const std::vector > LeaseSet::GetNonExpiredLeases (bool withThreshold) const - { - return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold); - } + const std::vector > LeaseSet::GetNonExpiredLeases (bool withThreshold) const + { + return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold); + } const std::vector > LeaseSet::GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold) const { @@ -249,19 +248,19 @@ namespace data if (len <= m_BufferLen) m_BufferLen = len; else LogPrint (eLogError, "LeaseSet2: actual buffer size ", len , " exceeds full buffer size ", m_BufferLen); - } - + } + LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto): LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto) - { - SetBuffer (buf, len); + { + SetBuffer (buf, len); if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) ReadFromBufferEncrypted (buf, len, nullptr, nullptr); else ReadFromBuffer (buf, len); } - LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, + LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret, CryptoKeyType preferredCrypto): LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_EncryptionType (preferredCrypto) { @@ -269,10 +268,10 @@ namespace data } void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature) - { + { SetBuffer (buf, len); if (GetStoreType () != NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) - ReadFromBuffer (buf, len, false, verifySignature); + ReadFromBuffer (buf, len, false, verifySignature); // TODO: implement encrypted } @@ -281,13 +280,13 @@ namespace data uint64_t expiration; return ExtractPublishedTimestamp (buf, len, expiration) > m_PublishedTimestamp; } - + void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity, bool verifySignature) { // standard LS2 header std::shared_ptr identity; if (readIdentity) - { + { identity = std::make_shared(buf, len); SetIdentity (identity); } @@ -304,7 +303,7 @@ namespace data // transient key m_TransientVerifier = ProcessOfflineSignature (identity, buf, len, offset); if (!m_TransientVerifier) - { + { LogPrint (eLogError, "LeaseSet2: offline signature failed"); return; } @@ -314,7 +313,7 @@ namespace data { m_IsPublishedEncrypted = true; m_IsPublic = true; - } + } // type specific part size_t s = 0; switch (m_StoreType) @@ -331,11 +330,11 @@ namespace data if (!s) return; offset += s; if (verifySignature || m_TransientVerifier) - { + { // verify signature bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) : - VerifySignature (identity, buf, len, offset); - SetIsValid (verified); + VerifySignature (identity, buf, len, offset); + SetIsValid (verified); } offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : identity->GetSignatureLen (); SetBufferLen (offset); @@ -346,10 +345,10 @@ namespace data { if (signatureOffset + verifier->GetSignatureLen () > len) return false; // we assume buf inside DatabaseStore message, so buf[-1] is valid memory - // change it for signature verification, and restore back + // change it for signature verification, and restore back uint8_t c = buf[-1]; const_cast(buf)[-1] = m_StoreType; - bool verified = verifier->Verify (buf - 1, signatureOffset + 1, buf + signatureOffset); + bool verified = verifier->Verify (buf - 1, signatureOffset + 1, buf + signatureOffset); const_cast(buf)[-1] = c; if (!verified) LogPrint (eLogWarning, "LeaseSet2: verification failed"); @@ -360,7 +359,7 @@ namespace data { size_t offset = 0; // properties - uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; + uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; offset += propertiesLen; // skip for now. TODO: implement properties if (offset + 1 >= len) return 0; // key sections @@ -371,7 +370,7 @@ namespace data { uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption key type if (offset + 2 >= len) return 0; - uint16_t encryptionKeyLen = bufbe16toh (buf + offset); offset += 2; + uint16_t encryptionKeyLen = bufbe16toh (buf + offset); offset += 2; if (offset + encryptionKeyLen >= len) return 0; if (IsStoreLeases () && !preferredKeyFound) // create encryptor with leases only { @@ -384,10 +383,10 @@ namespace data if (keyType == preferredKeyType) preferredKeyFound = true; } } - offset += encryptionKeyLen; - } + offset += encryptionKeyLen; + } // leases - if (offset + 1 >= len) return 0; + if (offset + 1 >= len) return 0; int numLeases = buf[offset]; offset++; auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (IsStoreLeases ()) @@ -413,9 +412,9 @@ namespace data { size_t offset = 0; // properties - uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; + uint16_t propertiesLen = bufbe16toh (buf + offset); offset += 2; offset += propertiesLen; // skip for now. TODO: implement properties - // entries + // entries if (offset + 1 >= len) return 0; int numEntries = buf[offset]; offset++; for (int i = 0; i < numEntries; i++) @@ -423,12 +422,12 @@ namespace data if (offset + 40 >= len) return 0; offset += 32; // hash offset += 3; // flags - offset += 1; // cost + offset += 1; // cost offset += 4; // expires } // revocations if (offset + 1 >= len) return 0; - int numRevocations = buf[offset]; offset++; + int numRevocations = buf[offset]; offset++; for (int i = 0; i < numRevocations; i++) { if (offset + 32 > len) return 0; @@ -446,7 +445,7 @@ namespace data uint16_t blindedKeyType = bufbe16toh (stA1); offset += 2; std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (blindedKeyType)); if (!blindedVerifier) return; - auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); + auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); if (offset + blindedKeyLen >= len) return; const uint8_t * blindedPublicKey = buf + offset; blindedVerifier->SetPublicKey (blindedPublicKey); offset += blindedKeyLen; @@ -461,7 +460,7 @@ namespace data { // transient key m_TransientVerifier = ProcessOfflineSignature (blindedVerifier, buf, len, offset); - if (!m_TransientVerifier) + if (!m_TransientVerifier) { LogPrint (eLogError, "LeaseSet2: offline signature failed"); return; @@ -470,16 +469,16 @@ namespace data // outer ciphertext if (offset + 2 > len) return; uint16_t lenOuterCiphertext = bufbe16toh (buf + offset); offset += 2; - const uint8_t * outerCiphertext = buf + offset; - offset += lenOuterCiphertext; + const uint8_t * outerCiphertext = buf + offset; + offset += lenOuterCiphertext; // verify signature bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) : - VerifySignature (blindedVerifier, buf, len, offset); + VerifySignature (blindedVerifier, buf, len, offset); SetIsValid (verified); // handle ciphertext if (verified && key && lenOuterCiphertext >= 32) { - SetIsValid (false); // we must verify it again in Layer 2 + SetIsValid (false); // we must verify it again in Layer 2 if (blindedKeyType == key->GetBlindedSigType ()) { // verify blinding @@ -491,13 +490,13 @@ namespace data { LogPrint (eLogError, "LeaseSet2: blinded public key doesn't match"); return; - } - } + } + } else { LogPrint (eLogError, "LeaseSet2: Unexpected blinded key type ", blindedKeyType, " instead ", key->GetBlindedSigType ()); return; - } + } // outer key // outerInput = subcredential || publishedTimestamp uint8_t subcredential[36]; @@ -518,10 +517,10 @@ namespace data // innerSalt = innerCiphertext[0:32] // keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44) uint8_t innerInput[68]; - size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, secret, subcredential, innerInput); + size_t authDataLen = ExtractClientAuthData (outerPlainText.data (), lenOuterPlaintext, secret, subcredential, innerInput); if (authDataLen > 0) { - memcpy (innerInput + 32, subcredential, 36); + memcpy (innerInput + 32, subcredential, 36); i2p::crypto::HKDF (outerPlainText.data () + 1 + authDataLen, innerInput, 68, "ELS2_L2K", keys); } else @@ -537,20 +536,20 @@ namespace data if (innerPlainText[0] == NETDB_STORE_TYPE_STANDARD_LEASESET2 || innerPlainText[0] == NETDB_STORE_TYPE_META_LEASESET2) { // override store type and buffer - m_StoreType = innerPlainText[0]; + m_StoreType = innerPlainText[0]; SetBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1); // parse and verify Layer 2 ReadFromBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1); } else LogPrint (eLogError, "LeaseSet2: unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet"); - } + } else { // we set actual length of encrypted buffer offset += m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : blindedVerifier->GetSignatureLen (); SetBufferLen (offset); - } + } } // helper for ExtractClientAuthData @@ -563,12 +562,12 @@ namespace data { // clientKey_i = okm[0:31] // clientIV_i = okm[32:43] - i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i + i2p::crypto::ChaCha20 (authClients + i*40 + 8, 32, okm, okm + 32, authCookie); // clientCookie_i return true; - } + } } - return false; - } + return false; + } size_t LeaseSet2::ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const { @@ -581,7 +580,7 @@ namespace data const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients - if (offset > len) + if (offset > len) { LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data"); return 0; @@ -595,19 +594,19 @@ namespace data memcpy (authInput + 32, ck.GetPublicKey (), 32); // cpk_i memcpy (authInput + 64, subcredential, 36); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); + i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); if (!GetAuthCookie (authClients, numClients, okm, authCookie)) - LogPrint (eLogError, "LeaseSet2: Client cookie DH not found"); + LogPrint (eLogError, "LeaseSet2: Client cookie DH not found"); } else - LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: csk_i is not provided"); + LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: csk_i is not provided"); } else if (flag & 0x02) // PSK, bit 1 is set to 1 { const uint8_t * authSalt = buf + offset; offset += 32; // authSalt uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients - if (offset > len) + if (offset > len) { LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data"); return 0; @@ -619,7 +618,7 @@ namespace data memcpy (authInput, secret, 32); memcpy (authInput + 32, subcredential, 36); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); if (!GetAuthCookie (authClients, numClients, okm, authCookie)) LogPrint (eLogError, "LeaseSet2: Client cookie PSK not found"); } @@ -627,7 +626,7 @@ namespace data LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); } else - LogPrint (eLogError, "LeaseSet2: unknown client auth type ", (int)flag); + LogPrint (eLogError, "LeaseSet2: unknown client auth type ", (int)flag); } return offset - 1; } @@ -636,7 +635,7 @@ namespace data { auto encryptor = m_Encryptor; // TODO: atomic if (encryptor) - encryptor->Encrypt (data, encrypted, ctx, true); + encryptor->Encrypt (data, encrypted, ctx, true); } uint64_t LeaseSet2::ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const @@ -648,7 +647,7 @@ namespace data uint64_t LeaseSet2::ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const { - if (len < 8) return 0; + if (len < 8) return 0; if (m_StoreType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { // encrypted LS2 @@ -656,11 +655,11 @@ namespace data uint16_t blindedKeyType = bufbe16toh (buf + offset); offset += 2; std::unique_ptr blindedVerifier (i2p::data::IdentityEx::CreateVerifier (blindedKeyType)); if (!blindedVerifier) return 0 ; - auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); + auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); if (offset + blindedKeyLen + 6 >= len) return 0; offset += blindedKeyLen; - uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; - uint16_t expires = bufbe16toh (buf + offset); offset += 2; + uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; + uint16_t expires = bufbe16toh (buf + offset); offset += 2; expiration = (timestamp + expires)* 1000LL; return timestamp; } @@ -670,13 +669,13 @@ namespace data if (!identity) return 0; size_t offset = identity->GetFullLen (); if (offset + 6 >= len) return 0; - uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; - uint16_t expires = bufbe16toh (buf + offset); offset += 2; + uint32_t timestamp = bufbe32toh (buf + offset); offset += 4; + uint16_t expires = bufbe16toh (buf + offset); offset += 2; expiration = (timestamp + expires)* 1000LL; return timestamp; } - } - + } + LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels): m_ExpirationTime (0), m_Identity (identity) { @@ -770,36 +769,35 @@ namespace data return ident.Verify(ptr, leases - ptr, leases); } - LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, - std::vector > tunnels, + LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, + const KeySections& encryptionKeys, std::vector > tunnels, bool isPublic, bool isPublishedEncrypted): LocalLeaseSet (keys.GetPublic (), nullptr, 0) { auto identity = keys.GetPublic (); - // assume standard LS2 + // assume standard LS2 int num = tunnels.size (); if (num > MAX_NUM_LEASES) num = MAX_NUM_LEASES; size_t keySectionsLen = 0; for (const auto& it: encryptionKeys) - keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; + keySectionsLen += 2/*key type*/ + 2/*key len*/ + it.keyLen/*key*/; m_BufferLen = identity->GetFullLen () + 4/*published*/ + 2/*expires*/ + 2/*flag*/ + 2/*properties len*/ + 1/*num keys*/ + keySectionsLen + 1/*num leases*/ + num*LEASE2_SIZE + keys.GetSignatureLen (); uint16_t flags = 0; - if (keys.IsOfflineSignature ()) + if (keys.IsOfflineSignature ()) { flags |= LEASESET2_FLAG_OFFLINE_KEYS; - m_BufferLen += keys.GetOfflineSignature ().size (); + m_BufferLen += keys.GetOfflineSignature ().size (); } - if (isPublishedEncrypted) + if (isPublishedEncrypted) { flags |= LEASESET2_FLAG_PUBLISHED_ENCRYPTED; - isPublic = true; + isPublic = true; } if (!isPublic) flags |= LEASESET2_FLAG_UNPUBLISHED_LEASESET; m_Buffer = new uint8_t[m_BufferLen + 1]; - m_Buffer[0] = storeType; + m_Buffer[0] = storeType; // LS2 header auto offset = identity->ToBuffer (m_Buffer + 1, m_BufferLen) + 1; auto timestamp = i2p::util::GetSecondsSinceEpoch (); @@ -814,14 +812,14 @@ namespace data offset += offlineSignature.size (); } htobe16buf (m_Buffer + offset, 0); offset += 2; // properties len - // keys + // keys m_Buffer[offset] = encryptionKeys.size (); offset++; // 1 key for (const auto& it: encryptionKeys) - { - htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type - htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len + { + htobe16buf (m_Buffer + offset, it.keyType); offset += 2; // key type + htobe16buf (m_Buffer + offset, it.keyLen); offset += 2; // key len memcpy (m_Buffer + offset, it.encryptionPublicKey, it.keyLen); offset += it.keyLen; // key - } + } // leases uint32_t expirationTime = 0; // in seconds m_Buffer[offset] = num; offset++; // num leases @@ -835,11 +833,11 @@ namespace data if (ts > expirationTime) expirationTime = ts; htobe32buf (m_Buffer + offset, ts); offset += 4; // end date - } + } // update expiration - SetExpirationTime (expirationTime*1000LL); + SetExpirationTime (expirationTime*1000LL); auto expires = expirationTime - timestamp; - htobe16buf (expiresBuf, expires > 0 ? expires : 0); + htobe16buf (expiresBuf, expires > 0 ? expires : 0); // sign keys.Sign (m_Buffer, offset, m_Buffer + offset); // LS + leading store type } @@ -853,7 +851,7 @@ namespace data m_Buffer[0] = storeType; } - LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, + LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType, std::shared_ptr > authKeys): LocalLeaseSet2 (ls->GetIdentity ()), m_InnerLeaseSet (ls) { @@ -863,16 +861,16 @@ namespace data { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) layer1Flags |= 0x01; // DH, authentication scheme 0, auth bit 1 else if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_PSK) layer1Flags |= 0x03; // PSK, authentication scheme 1, auth bit 1 - if (layer1Flags) + if (layer1Flags) lenOuterPlaintext += 32 + 2 + authKeys->size ()*40; // auth data len - } + } size_t lenOuterCiphertext = lenOuterPlaintext + 32; - - m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; - m_Buffer = new uint8_t[m_BufferLen + 1]; + + m_BufferLen = 2/*blinded sig type*/ + 32/*blinded pub key*/ + 4/*published*/ + 2/*expires*/ + 2/*flags*/ + 2/*lenOuterCiphertext*/ + lenOuterCiphertext + 64/*signature*/; + m_Buffer = new uint8_t[m_BufferLen + 1]; m_Buffer[0] = NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; BlindedPublicKey blindedKey (ls->GetIdentity ()); - auto timestamp = i2p::util::GetSecondsSinceEpoch (); + auto timestamp = i2p::util::GetSecondsSinceEpoch (); char date[9]; i2p::util::GetDateString (timestamp, date); uint8_t blindedPriv[64], blindedPub[128]; // 64 and 128 max @@ -883,25 +881,25 @@ namespace data memcpy (m_Buffer + offset, blindedPub, publicKeyLen); offset += publicKeyLen; // Blinded Public Key htobe32buf (m_Buffer + offset, timestamp); offset += 4; // published timestamp (seconds) auto nextMidnight = (timestamp/86400LL + 1)*86400LL; // 86400 = 24*3600 seconds - auto expirationTime = ls->GetExpirationTime ()/1000LL; + auto expirationTime = ls->GetExpirationTime ()/1000LL; if (expirationTime > nextMidnight) expirationTime = nextMidnight; SetExpirationTime (expirationTime*1000LL); htobe16buf (m_Buffer + offset, expirationTime > timestamp ? expirationTime - timestamp : 0); offset += 2; // expires uint16_t flags = 0; - htobe16buf (m_Buffer + offset, flags); offset += 2; // flags + htobe16buf (m_Buffer + offset, flags); offset += 2; // flags htobe16buf (m_Buffer + offset, lenOuterCiphertext); offset += 2; // lenOuterCiphertext // outerChipherText - // Layer 1 + // Layer 1 uint8_t subcredential[36]; blindedKey.GetSubcredential (blindedPub, 32, subcredential); htobe32buf (subcredential + 32, timestamp); // outerInput = subcredential || publishedTimestamp // keys = HKDF(outerSalt, outerInput, "ELS2_L1K", 44) uint8_t keys1[64]; // 44 bytes actual data - RAND_bytes (m_Buffer + offset, 32); // outerSalt = CSRNG(32) + RAND_bytes (m_Buffer + offset, 32); // outerSalt = CSRNG(32) i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L1K", keys1); offset += 32; // outerSalt - uint8_t * outerPlainText = m_Buffer + offset; - m_Buffer[offset] = layer1Flags; offset++; // layer 1 flags + uint8_t * outerPlainText = m_Buffer + offset; + m_Buffer[offset] = layer1Flags; offset++; // layer 1 flags // auth data uint8_t innerInput[68]; // authCookie || subcredential || publishedTimestamp if (layer1Flags) @@ -909,20 +907,20 @@ namespace data RAND_bytes (innerInput, 32); // authCookie CreateClientAuthData (subcredential, authType, authKeys, innerInput, m_Buffer + offset); offset += 32 + 2 + authKeys->size ()*40; // auth clients - } + } // Layer 2 // keys = HKDF(outerSalt, outerInput, "ELS2_L2K", 44) uint8_t keys2[64]; // 44 bytes actual data - RAND_bytes (m_Buffer + offset, 32); // innerSalt = CSRNG(32) + RAND_bytes (m_Buffer + offset, 32); // innerSalt = CSRNG(32) if (layer1Flags) { memcpy (innerInput + 32, subcredential, 36); // + subcredential || publishedTimestamp - i2p::crypto::HKDF (m_Buffer + offset, innerInput, 68, "ELS2_L2K", keys2); + i2p::crypto::HKDF (m_Buffer + offset, innerInput, 68, "ELS2_L2K", keys2); } else i2p::crypto::HKDF (m_Buffer + offset, subcredential, 36, "ELS2_L2K", keys2); // no authCookie - offset += 32; // innerSalt - m_Buffer[offset] = ls->GetStoreType (); + offset += 32; // innerSalt + m_Buffer[offset] = ls->GetStoreType (); memcpy (m_Buffer + offset + 1, ls->GetBuffer (), ls->GetBufferLen ()); i2p::crypto::ChaCha20 (m_Buffer + offset, lenInnerPlaintext, keys2, keys2 + 32, m_Buffer + offset); // encrypt Layer 2 offset += lenInnerPlaintext; @@ -930,14 +928,14 @@ namespace data // signature blindedSigner->Sign (m_Buffer, offset, m_Buffer + offset); // store hash - m_StoreHash = blindedKey.GetStoreHash (date); + m_StoreHash = blindedKey.GetStoreHash (date); } LocalEncryptedLeaseSet2::LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len): - LocalLeaseSet2 (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2, identity, buf, len) + LocalLeaseSet2 (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2, identity, buf, len) { - // fill inner LeaseSet2 - auto blindedKey = std::make_shared(identity); + // fill inner LeaseSet2 + auto blindedKey = std::make_shared(identity); i2p::data::LeaseSet2 ls (buf, len, blindedKey); // inner layer if (ls.IsValid ()) { @@ -945,10 +943,10 @@ namespace data m_StoreHash = blindedKey->GetStoreHash (); } else - LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); + LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer"); } - void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authData) const + void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr > authKeys, const uint8_t * authCookie, uint8_t * authData) const { if (authType == ENCRYPTED_LEASESET_AUTH_TYPE_DH) { @@ -963,9 +961,9 @@ namespace data ek.Agree (it, authInput); // sharedSecret = DH(esk, cpk_i) memcpy (authInput + 32, it, 32); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (ek.GetPublicKey (), authInput, 100, "ELS2_XCA", okm); + i2p::crypto::HKDF (ek.GetPublicKey (), authInput, 100, "ELS2_XCA", okm); memcpy (authData, okm + 44, 8); authData += 8; // clientID_i - i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i } } else // assume PSK @@ -980,10 +978,10 @@ namespace data { memcpy (authInput, it, 32); uint8_t okm[64]; // 52 actual data - i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); + i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); memcpy (authData, okm + 44, 8); authData += 8; // clientID_i - i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i - } + i2p::crypto::ChaCha20 (authCookie, 32, okm, okm + 32, authData); authData += 32; // clientCookie_i + } } } } diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 4d084da3..479594e1 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -48,11 +48,11 @@ namespace data }; }; - typedef std::function LeaseInspectFunc; + typedef std::function LeaseInspectFunc; const size_t MAX_LS_BUFFER_SIZE = 3072; const size_t LEASE_SIZE = 44; // 32 + 4 + 8 - const size_t LEASE2_SIZE = 40; // 32 + 4 + 4 + const size_t LEASE2_SIZE = 40; // 32 + 4 + 4 const uint8_t MAX_NUM_LEASES = 16; const uint8_t NETDB_STORE_TYPE_LEASESET = 1; @@ -70,7 +70,7 @@ namespace data size_t GetBufferLen () const { return m_BufferLen; }; bool IsValid () const { return m_IsValid; }; const std::vector > GetNonExpiredLeases (bool withThreshold = true) const; - const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; + const std::vector > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const; bool HasExpiredLeases () const; bool IsExpired () const; bool IsEmpty () const { return m_Leases.empty (); }; @@ -80,7 +80,7 @@ namespace data { return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); }; virtual uint8_t GetStoreType () const { return NETDB_STORE_TYPE_LEASESET; }; virtual uint32_t GetPublishedTimestamp () const { return 0; }; // should be set for LeaseSet2 only - virtual std::shared_ptr GetTransientVerifier () const { return nullptr; }; + virtual std::shared_ptr GetTransientVerifier () const { return nullptr; }; virtual bool IsPublishedEncrypted () const { return false; }; // implements RoutingDestination @@ -97,7 +97,7 @@ namespace data // called from LeaseSet2 LeaseSet (bool storeLeases); void SetBuffer (const uint8_t * buf, size_t len); - void SetBufferLen (size_t len); + void SetBufferLen (size_t len); void SetIdentity (std::shared_ptr identity) { m_Identity = identity; }; void SetExpirationTime (uint64_t t) { m_ExpirationTime = t; }; void SetIsValid (bool isValid) { m_IsValid = isValid; }; @@ -130,7 +130,7 @@ namespace data const uint8_t NETDB_STORE_TYPE_META_LEASESET2 = 7; const uint16_t LEASESET2_FLAG_OFFLINE_KEYS = 0x0001; - const uint16_t LEASESET2_FLAG_UNPUBLISHED_LEASESET = 0x0002; + const uint16_t LEASESET2_FLAG_UNPUBLISHED_LEASESET = 0x0002; const uint16_t LEASESET2_FLAG_PUBLISHED_ENCRYPTED = 0x0004; class LeaseSet2: public LeaseSet @@ -167,7 +167,7 @@ namespace data private: - uint8_t m_StoreType; + uint8_t m_StoreType; uint32_t m_PublishedTimestamp = 0; bool m_IsPublic = true, m_IsPublishedEncrypted = false; std::shared_ptr m_TransientVerifier; @@ -175,7 +175,7 @@ namespace data std::shared_ptr m_Encryptor; // for standardLS2 }; - // also called from Streaming.cpp + // also called from Streaming.cpp template std::shared_ptr ProcessOfflineSignature (const Verifier& verifier, const uint8_t * buf, size_t len, size_t& offset) { @@ -191,7 +191,7 @@ namespace data transientVerifier->SetPublicKey (buf + offset); offset += keyLen; if (offset + verifier->GetSignatureLen () >= len) return nullptr; if (!verifier->Verify (signedData, keyLen + 6, buf + offset)) return nullptr; - offset += verifier->GetSignatureLen (); + offset += verifier->GetSignatureLen (); return transientVerifier; } @@ -238,17 +238,18 @@ namespace data { uint16_t keyType, keyLen; const uint8_t * encryptionPublicKey; - }; + }; typedef std::vector KeySections; - - LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, - const KeySections& encryptionKeys, - std::vector > tunnels, + + LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys, + const KeySections& encryptionKeys, + 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 - + + LocalLeaseSet2 (uint8_t storeType, std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP + virtual ~LocalLeaseSet2 () { delete[] m_Buffer; }; - + uint8_t * GetBuffer () const { return m_Buffer + 1; }; size_t GetBufferLen () const { return m_BufferLen; }; @@ -269,13 +270,13 @@ namespace data const int ENCRYPTED_LEASESET_AUTH_TYPE_DH = 1; const int ENCRYPTED_LEASESET_AUTH_TYPE_PSK = 2; - typedef i2p::data::Tag<32> AuthPublicKey; + typedef i2p::data::Tag<32> AuthPublicKey; class LocalEncryptedLeaseSet2: public LocalLeaseSet2 { public: - LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType = ENCRYPTED_LEASESET_AUTH_TYPE_NONE, std::shared_ptr > authKeys = nullptr); + LocalEncryptedLeaseSet2 (std::shared_ptr ls, const i2p::data::PrivateKeys& keys, int authType = ENCRYPTED_LEASESET_AUTH_TYPE_NONE, std::shared_ptr > authKeys = nullptr); LocalEncryptedLeaseSet2 (std::shared_ptr identity, const uint8_t * buf, size_t len); // from I2CP diff --git a/libi2pd/LittleBigEndian.h b/libi2pd/LittleBigEndian.h index 69f10ee9..55039fb6 100644 --- a/libi2pd/LittleBigEndian.h +++ b/libi2pd/LittleBigEndian.h @@ -29,35 +29,35 @@ struct BigEndian; template struct LittleEndian { - union - { - unsigned char bytes[sizeof(T)]; - T raw_value; - }; + union + { + unsigned char bytes[sizeof(T)]; + T raw_value; + }; - LittleEndian(T t = T()) - { - operator =(t); - } + LittleEndian(T t = T()) + { + operator =(t); + } - LittleEndian(const LittleEndian & t) - { - raw_value = t.raw_value; - } + LittleEndian(const LittleEndian & t) + { + raw_value = t.raw_value; + } - LittleEndian(const BigEndian & t) - { - for (unsigned i = 0; i < sizeof(T); i++) - bytes[i] = t.bytes[sizeof(T)-1-i]; - } + LittleEndian(const BigEndian & t) + { + for (unsigned i = 0; i < sizeof(T); i++) + bytes[i] = t.bytes[sizeof(T)-1-i]; + } - operator const T() const - { - T t = T(); - for (unsigned i = 0; i < sizeof(T); i++) - t |= T(bytes[i]) << (i << 3); - return t; - } + operator const T() const + { + T t = T(); + for (unsigned i = 0; i < sizeof(T); i++) + t |= T(bytes[i]) << (i << 3); + return t; + } const T operator = (const T t) { @@ -66,68 +66,68 @@ struct LittleEndian return t; } - // operators + // operators - const T operator += (const T t) - { - return (*this = *this + t); - } + const T operator += (const T t) + { + return (*this = *this + t); + } - const T operator -= (const T t) - { - return (*this = *this - t); - } + const T operator -= (const T t) + { + return (*this = *this - t); + } - const T operator *= (const T t) - { - return (*this = *this * t); - } + const T operator *= (const T t) + { + return (*this = *this * t); + } - const T operator /= (const T t) - { - return (*this = *this / t); - } + const T operator /= (const T t) + { + return (*this = *this / t); + } - const T operator %= (const T t) - { - return (*this = *this % t); - } + const T operator %= (const T t) + { + return (*this = *this % t); + } - LittleEndian operator ++ (int) - { - LittleEndian tmp(*this); - operator ++ (); - return tmp; - } + LittleEndian operator ++ (int) + { + LittleEndian tmp(*this); + operator ++ (); + return tmp; + } - LittleEndian & operator ++ () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - ++bytes[i]; - if (bytes[i] != 0) - break; - } - return (*this); - } + LittleEndian & operator ++ () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + ++bytes[i]; + if (bytes[i] != 0) + break; + } + return (*this); + } - LittleEndian operator -- (int) - { - LittleEndian tmp(*this); - operator -- (); - return tmp; - } + LittleEndian operator -- (int) + { + LittleEndian tmp(*this); + operator -- (); + return tmp; + } - LittleEndian & operator -- () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - --bytes[i]; - if (bytes[i] != (T)(-1)) - break; - } - return (*this); - } + LittleEndian & operator -- () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + --bytes[i]; + if (bytes[i] != (T)(-1)) + break; + } + return (*this); + } }; #pragma pack(pop) @@ -137,105 +137,105 @@ struct LittleEndian template struct BigEndian { - union - { - unsigned char bytes[sizeof(T)]; - T raw_value; - }; + union + { + unsigned char bytes[sizeof(T)]; + T raw_value; + }; - BigEndian(T t = T()) - { - operator =(t); - } + BigEndian(T t = T()) + { + operator =(t); + } - BigEndian(const BigEndian & t) - { - raw_value = t.raw_value; - } + BigEndian(const BigEndian & t) + { + raw_value = t.raw_value; + } - BigEndian(const LittleEndian & t) - { - for (unsigned i = 0; i < sizeof(T); i++) - bytes[i] = t.bytes[sizeof(T)-1-i]; - } + BigEndian(const LittleEndian & t) + { + for (unsigned i = 0; i < sizeof(T); i++) + bytes[i] = t.bytes[sizeof(T)-1-i]; + } - operator const T() const - { - T t = T(); - for (unsigned i = 0; i < sizeof(T); i++) - t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3); - return t; - } + operator const T() const + { + T t = T(); + for (unsigned i = 0; i < sizeof(T); i++) + t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3); + return t; + } - const T operator = (const T t) - { - for (unsigned i = 0; i < sizeof(T); i++) - bytes[sizeof(T) - 1 - i] = t >> (i << 3); - return t; - } + const T operator = (const T t) + { + for (unsigned i = 0; i < sizeof(T); i++) + bytes[sizeof(T) - 1 - i] = t >> (i << 3); + return t; + } - // operators + // operators - const T operator += (const T t) - { - return (*this = *this + t); - } + const T operator += (const T t) + { + return (*this = *this + t); + } - const T operator -= (const T t) - { - return (*this = *this - t); - } + const T operator -= (const T t) + { + return (*this = *this - t); + } - const T operator *= (const T t) - { - return (*this = *this * t); - } + const T operator *= (const T t) + { + return (*this = *this * t); + } - const T operator /= (const T t) - { - return (*this = *this / t); - } + const T operator /= (const T t) + { + return (*this = *this / t); + } - const T operator %= (const T t) - { - return (*this = *this % t); - } + const T operator %= (const T t) + { + return (*this = *this % t); + } - BigEndian operator ++ (int) - { - BigEndian tmp(*this); - operator ++ (); - return tmp; - } + BigEndian operator ++ (int) + { + BigEndian tmp(*this); + operator ++ (); + return tmp; + } - BigEndian & operator ++ () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - ++bytes[sizeof(T) - 1 - i]; - if (bytes[sizeof(T) - 1 - i] != 0) - break; - } - return (*this); - } + BigEndian & operator ++ () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + ++bytes[sizeof(T) - 1 - i]; + if (bytes[sizeof(T) - 1 - i] != 0) + break; + } + return (*this); + } - BigEndian operator -- (int) - { - BigEndian tmp(*this); - operator -- (); - return tmp; - } + BigEndian operator -- (int) + { + BigEndian tmp(*this); + operator -- (); + return tmp; + } - BigEndian & operator -- () - { - for (unsigned i = 0; i < sizeof(T); i++) - { - --bytes[sizeof(T) - 1 - i]; - if (bytes[sizeof(T) - 1 - i] != (T)(-1)) - break; - } - return (*this); - } + BigEndian & operator -- () + { + for (unsigned i = 0; i < sizeof(T); i++) + { + --bytes[sizeof(T) - 1 - i]; + if (bytes[sizeof(T) - 1 - i] != (T)(-1)) + break; + } + return (*this); + } }; #pragma pack(pop) diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 65602674..6f2eb5bd 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -110,18 +110,18 @@ namespace log { } } - std::string str_tolower(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - // static_cast(std::tolower) // wrong - // [](int c){ return std::tolower(c); } // wrong - // [](char c){ return std::tolower(c); } // wrong - [](unsigned char c){ return std::tolower(c); } // correct - ); - return s; - } + std::string str_tolower(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), + // static_cast(std::tolower) // wrong + // [](int c){ return std::tolower(c); } // wrong + // [](char c){ return std::tolower(c); } // wrong + [](unsigned char c){ return std::tolower(c); } // correct + ); + return s; + } - void Log::SetLogLevel (const std::string& level_) { - std::string level=str_tolower(level_); + void Log::SetLogLevel (const std::string& level_) { + std::string level=str_tolower(level_); if (level == "none") { m_MinLevel = eLogNone; } else if (level == "error") { m_MinLevel = eLogError; } else if (level == "warn") { m_MinLevel = eLogWarning; } @@ -240,7 +240,7 @@ namespace log { static ThrowFunction g_ThrowFunction; ThrowFunction GetThrowFunction () { return g_ThrowFunction; } void SetThrowFunction (ThrowFunction f) { g_ThrowFunction = f; } - + } // log } // i2p diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 556654e2..fbd122a8 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -155,9 +155,9 @@ namespace log { typedef std::function ThrowFunction; ThrowFunction GetThrowFunction (); - void SetThrowFunction (ThrowFunction f); + void SetThrowFunction (ThrowFunction f); } // log -} +} // i2p /** internal usage only -- folding args array to single string */ template @@ -203,7 +203,7 @@ void LogPrint (LogLevel level, TArgs&&... args) noexcept } /** - * @brief Throw fatal error message with the list of arguments + * @brief Throw fatal error message with the list of arguments * @param args Array of message parts */ template diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index e52f0111..eec3a5a5 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -114,7 +114,7 @@ namespace transport void NTCP2Establisher::KDF2Bob () { - KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); + KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); } void NTCP2Establisher::KDF3Alice () @@ -707,7 +707,7 @@ namespace transport auto existing = i2p::data::netdb.FindRouter (ri.GetRouterIdentity ()->GetIdentHash ()); // check if exists already SetRemoteIdentity (existing ? existing->GetRouterIdentity () : ri.GetRouterIdentity ()); if (m_Server.AddNTCP2Session (shared_from_this (), true)) - { + { Established (); ReceiveLength (); } @@ -1200,7 +1200,7 @@ namespace transport continue; } - LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); + LogPrint (eLogInfo, "NTCP2: Start listening v4 TCP port ", address->port); auto conn = std::make_shared(*this); m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1)); } @@ -1218,8 +1218,8 @@ namespace transport LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint(eLogError, "NTCP2: failed to bind to v6 port ", address->port, ": ", ex.what()); ThrowFatal ("Unable to start IPv6 NTCP2 transport at port ", address->port, ": ", ex.what ()); @@ -1485,7 +1485,7 @@ namespace transport } }); auto readbuff = std::make_shared >(2); - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), + boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), 2), [this, readbuff, timer, conn, host, port, addrtype](const boost::system::error_code & ec, std::size_t transferred) { if(ec) @@ -1531,8 +1531,8 @@ namespace transport std::ostream out(&writebuff); out << req.to_string(); - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), - [](const boost::system::error_code & ec, std::size_t transferred) + boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), + [](const boost::system::error_code & ec, std::size_t transferred) { (void) transferred; if(ec) @@ -1540,8 +1540,8 @@ namespace transport }); boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) + boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", + [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) { if(ec) { diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 10170fda..8b8c6acb 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -126,7 +126,6 @@ namespace transport { public: - NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter = nullptr); ~NTCP2Session (); void Terminate (); diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 4ab3c5d0..56c69e05 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -26,7 +26,7 @@ namespace transport { std::shared_ptr session; }; - + NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), m_Server (server), m_Socket (m_Server.GetService ()), @@ -468,7 +468,7 @@ namespace transport LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock"); if (ecode != boost::asio::error::operation_aborted) { - // this router doesn't like us + // this router doesn't like us i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); Terminate (); } @@ -736,13 +736,11 @@ namespace transport } } - void NTCPSession::SendTimeSyncMessage () { Send (nullptr); } - void NTCPSession::SendI2NPMessages (const std::vector >& msgs) { m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); @@ -821,8 +819,8 @@ namespace transport { m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { /** fail to bind ip4 */ LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); @@ -848,8 +846,8 @@ namespace transport LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); auto conn = std::make_shared (*this); m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); ThrowFatal (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); @@ -904,7 +902,6 @@ namespace transport } } - void NTCPServer::Run () { while (m_IsRunning) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 86bf160e..30916f1a 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -216,10 +216,10 @@ namespace data LogPrint (eLogDebug, "NetDb: RouterInfo floodfill status updated: ", ident.ToBase64()); std::unique_lock l(m_FloodfillsMutex); if (wasFloodfill) - m_Floodfills.remove (r); - else + m_Floodfills.remove (r); + else m_Floodfills.push_back (r); - } + } } else { @@ -390,7 +390,7 @@ namespace data } } - m_Reseeder->Bootstrap (); + m_Reseeder->Bootstrap (); } void NetDb::ReseedFromFloodfill(const RouterInfo & ri, int numRouters, int numFloodfills) @@ -532,12 +532,12 @@ namespace data auto total = m_RouterInfos.size (); uint64_t expirationTimeout = NETDB_MAX_EXPIRATION_TIMEOUT*1000LL; uint64_t ts = i2p::util::GetMillisecondsSinceEpoch(); - auto uptime = i2p::context.GetUptime (); + auto uptime = i2p::context.GetUptime (); // routers don't expire if less than 90 or uptime is less than 1 hour bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes if (checkForExpiration && uptime > 3600) // 1 hour 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; + NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total; for (auto& it: m_RouterInfos) { @@ -555,7 +555,7 @@ namespace data // find & mark expired routers if (it.second->UsesIntroducer ()) { - if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) + if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL) // RouterInfo expires after 1 hour if uses introducer it.second->SetUnreachable (true); } @@ -873,7 +873,7 @@ namespace data std::shared_ptr replyMsg; if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP) { - LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded"); + LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded"); std::set excludedRouters; for (int i = 0; i < numExcluded; i++) { @@ -894,7 +894,7 @@ namespace data } else { - if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP || + if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP || lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP) { auto router = FindRouter (ident); @@ -907,7 +907,7 @@ namespace data } } - if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP || + if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP || lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)) { auto leaseSet = FindLeaseSet (ident); @@ -957,12 +957,12 @@ namespace data replyMsg = i2p::garlic::WrapECIESX25519AEADRatchetMessage (replyMsg, sessionKey, tag); } else - { + { const i2p::garlic::SessionTag sessionTag(excluded + 33); // take first tag i2p::garlic::ElGamalAESSession garlic (sessionKey, sessionTag); replyMsg = garlic.WrapSingleMessage (replyMsg); - } - if (!replyMsg) + } + if (!replyMsg) LogPrint (eLogError, "NetDb: failed to wrap message"); } else @@ -1103,7 +1103,7 @@ namespace data { return !router->IsHidden () && router->IsSSUV6 (); }); - } + } std::shared_ptr NetDb::GetRandomIntroducer () const { diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 6e251ecb..47a6fab5 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -28,12 +28,12 @@ namespace i2p namespace data { const int NETDB_MIN_ROUTERS = 90; - 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 - const int NETDB_MAX_EXPIRATION_TIMEOUT = 27*60*60; // 27 hours - const int NETDB_PUBLISH_INTERVAL = 60*40; - const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0,9,36); // 0.9.36 + 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 + const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours + const int NETDB_PUBLISH_INTERVAL = 60 * 40; + const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; @@ -63,13 +63,13 @@ namespace data std::shared_ptr FindRouterProfile (const IdentHash& ident) const; void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr); - void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); + void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); void HandleDatabaseStoreMsg (std::shared_ptr msg); void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void HandleDatabaseLookupMsg (std::shared_ptr msg); void HandleNTCP2RouterInfoMsg (std::shared_ptr m); - + std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith) const; @@ -80,13 +80,13 @@ namespace data std::vector GetClosestFloodfills (const IdentHash& destination, size_t num, std::set& excluded, bool closeThanUsOnly = false) const; std::shared_ptr GetClosestNonFloodfill (const IdentHash& destination, const std::set& excluded) const; - std::shared_ptr GetRandomRouterInFamily(const std::string & fam) const; + std::shared_ptr GetRandomRouterInFamily(const std::string & fam) const; void SetUnreachable (const IdentHash& ident, bool unreachable); void PostI2NPMsg (std::shared_ptr msg); - /** set hidden mode, aka don't publish our RI to netdb and don't explore */ - void SetHidden(bool hide); + /** set hidden mode, aka don't publish our RI to netdb and don't explore */ + void SetHidden(bool hide); void Reseed (); Families& GetFamilies () { return m_Families; }; @@ -119,12 +119,13 @@ namespace data void ManageLeaseSets (); void ManageRequests (); - void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20); + void ReseedFromFloodfill(const RouterInfo & ri, int numRouters = 40, int numFloodfills = 20); std::shared_ptr AddRouterInfo (const uint8_t * buf, int len, bool& updated); std::shared_ptr AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len, bool& updated); - template - std::shared_ptr GetRandomRouter (Filter filter) const; + + template + std::shared_ptr GetRandomRouter (Filter filter) const; private: @@ -150,12 +151,12 @@ namespace data bool m_PersistProfiles; - /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ - std::shared_ptr m_FloodfillBootstrap; + /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ + std::shared_ptr m_FloodfillBootstrap; - /** true if in hidden mode */ - bool m_HiddenMode; + /** true if in hidden mode */ + bool m_HiddenMode; }; extern NetDb netdb; diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index f1853124..b1eb9380 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -14,8 +14,8 @@ namespace data std::shared_ptr msg; if(replyTunnel) msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, - replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory, - &m_ExcludedPeers); + replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory, + &m_ExcludedPeers); else msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers); if(router) @@ -158,4 +158,3 @@ namespace data } } } - diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index 7a7a55ab..c5e077bf 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -66,4 +66,3 @@ namespace data } #endif - diff --git a/libi2pd/Poly1305.cpp b/libi2pd/Poly1305.cpp index bf94c9a9..23098d74 100644 --- a/libi2pd/Poly1305.cpp +++ b/libi2pd/Poly1305.cpp @@ -7,12 +7,11 @@ */ -#if !OPENSSL_AEAD_CHACHA20_POLY1305 +#if !OPENSSL_AEAD_CHACHA20_POLY1305 namespace i2p { namespace crypto { - void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz) { Poly1305 p(key); diff --git a/libi2pd/Poly1305.h b/libi2pd/Poly1305.h index 800fbfd9..f91a037e 100644 --- a/libi2pd/Poly1305.h +++ b/libi2pd/Poly1305.h @@ -1,9 +1,9 @@ /** - This code is licensed under the MCGSI Public License - Copyright 2018 Jeff Becker - - Kovri go write your own code - + * This code is licensed under the MCGSI Public License + * Copyright 2018 Jeff Becker + * + * Kovri go write your own code + * */ #ifndef LIBI2PD_POLY1305_H #define LIBI2PD_POLY1305_H @@ -11,7 +11,7 @@ #include #include "Crypto.h" -#if !OPENSSL_AEAD_CHACHA20_POLY1305 +#if !OPENSSL_AEAD_CHACHA20_POLY1305 namespace i2p { namespace crypto @@ -24,7 +24,6 @@ namespace crypto namespace poly1305 { - struct LongBlock { unsigned long data[17]; @@ -252,8 +251,8 @@ namespace crypto poly1305::LongBlock m_HR; uint8_t m_Final; }; + void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz); - } } #endif diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 98f95dc3..4f26e520 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -32,73 +32,76 @@ namespace data { } - /** @brief tries to bootstrap into I2P network (from local files and servers, with respect of options) - */ - void Reseeder::Bootstrap () - { - std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName); - std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName); + /** + @brief tries to bootstrap into I2P network (from local files and servers, with respect of options) + */ + void Reseeder::Bootstrap () + { + std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName); + std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName); - if (su3FileName.length() > 0) // bootstrap from SU3 file or URL - { - int num; - if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://") - { - num = ReseedFromSU3Url (su3FileName); // from https URL - } - else - { - num = ProcessSU3File (su3FileName.c_str ()); - } - if (num == 0) - LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName); - } - else if (zipFileName.length() > 0) // bootstrap from ZIP file - { - int num = ProcessZIPFile (zipFileName.c_str ()); - if (num == 0) - LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName); - } - else // bootstrap from reseed servers - { - int num = ReseedFromServers (); - if (num == 0) - LogPrint (eLogWarning, "Reseed: failed to reseed from servers"); - } - } + if (su3FileName.length() > 0) // bootstrap from SU3 file or URL + { + int num; + if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://") + { + num = ReseedFromSU3Url (su3FileName); // from https URL + } + else + { + num = ProcessSU3File (su3FileName.c_str ()); + } + if (num == 0) + LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName); + } + else if (zipFileName.length() > 0) // bootstrap from ZIP file + { + int num = ProcessZIPFile (zipFileName.c_str ()); + if (num == 0) + LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName); + } + else // bootstrap from reseed servers + { + int num = ReseedFromServers (); + if (num == 0) + LogPrint (eLogWarning, "Reseed: failed to reseed from servers"); + } + } - /** @brief bootstrap from random server, retry 10 times - * @return number of entries added to netDb - */ + /** + * @brief bootstrap from random server, retry 10 times + * @return number of entries added to netDb + */ int Reseeder::ReseedFromServers () { std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs); - std::vector httpsReseedHostList; - boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); + std::vector httpsReseedHostList; + boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); - if (reseedURLs.length () == 0) - { - LogPrint (eLogWarning, "Reseed: No reseed servers specified"); - return 0; - } + if (reseedURLs.length () == 0) + { + LogPrint (eLogWarning, "Reseed: No reseed servers specified"); + return 0; + } - int reseedRetries = 0; - while (reseedRetries < 10) - { - auto ind = rand () % httpsReseedHostList.size (); - std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3"; - auto num = ReseedFromSU3Url (reseedUrl); - if (num > 0) return num; // success - reseedRetries++; - } - LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts"); - return 0; + int reseedRetries = 0; + while (reseedRetries < 10) + { + auto ind = rand () % httpsReseedHostList.size (); + std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3"; + auto num = ReseedFromSU3Url (reseedUrl); + if (num > 0) return num; // success + reseedRetries++; + } + LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts"); + return 0; } - /** @brief bootstrap from HTTPS URL with SU3 file - * @param url - * @return number of entries added to netDb - */ + /** + * @brief bootstrap from HTTPS URL with SU3 file + * @param url + * @return number of entries added to netDb + */ int Reseeder::ReseedFromSU3Url (const std::string& url) { LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url); @@ -702,4 +705,3 @@ namespace data } } } - diff --git a/libi2pd/Reseed.h b/libi2pd/Reseed.h index a69969bf..5f402988 100644 --- a/libi2pd/Reseed.h +++ b/libi2pd/Reseed.h @@ -21,7 +21,7 @@ namespace data Reseeder(); ~Reseeder(); - void Bootstrap (); + void Bootstrap (); int ReseedFromServers (); int ReseedFromSU3Url (const std::string& url); int ProcessSU3File (const char * filename); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b86ed8f2..b855fc29 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -338,10 +338,10 @@ namespace i2p { case low : /* not set */; break; case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P' - case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; - #if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; - #endif + case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif // no break here, extra + high means 'X' case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 28c324c4..6382189b 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -15,7 +15,7 @@ namespace i2p { const char ROUTER_INFO[] = "router.info"; const char ROUTER_KEYS[] = "router.keys"; - const char NTCP2_KEYS[] = "ntcp2.keys"; + const char NTCP2_KEYS[] = "ntcp2.keys"; const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes enum RouterStatus @@ -36,12 +36,12 @@ namespace i2p { private: - struct NTCP2PrivateKeys + struct NTCP2PrivateKeys { uint8_t staticPublicKey[32]; uint8_t staticPrivateKey[32]; uint8_t iv[16]; - }; + }; public: @@ -63,7 +63,7 @@ namespace i2p const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; }; const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; - i2p::crypto::X25519Keys& GetStaticKeys (); + i2p::crypto::X25519Keys& GetStaticKeys (); uint32_t GetUptime () const; // in seconds uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; @@ -77,7 +77,7 @@ namespace i2p void SetNetID (int netID) { m_NetID = netID; }; bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) const; - void UpdatePort (int port); // called from Daemon + 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 UpdateNTCP2Address (bool enable); @@ -124,7 +124,7 @@ namespace i2p // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented private: @@ -141,7 +141,7 @@ namespace i2p i2p::data::PrivateKeys m_Keys; std::shared_ptr m_Decryptor; uint64_t m_LastUpdateTime; // in seconds - bool m_AcceptsTunnels, m_IsFloodfill; + bool m_AcceptsTunnels, m_IsFloodfill; std::chrono::time_point m_StartupTime; uint64_t m_BandwidthLimit; // allowed bandwidth int m_ShareRatio; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 9b3b7e89..bf81a8af 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -35,12 +35,12 @@ namespace data } RouterInfo::RouterInfo (const uint8_t * buf, int len): - m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), + m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0), m_Version (0) { m_Addresses = boost::make_shared(); // create empty list if (len <= MAX_RI_BUFFER_SIZE) - { + { m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE]; memcpy (m_Buffer, buf, len); m_BufferLen = len; @@ -173,7 +173,6 @@ namespace data LogPrint (eLogError, "RouterInfo: malformed message"); m_IsUnreachable = true; } - } void RouterInfo::ReadFromStream (std::istream& s) @@ -192,7 +191,7 @@ namespace data s.read ((char *)&address->cost, sizeof (address->cost)); s.read ((char *)&address->date, sizeof (address->date)); bool isNTCP2Only = false; - char transportStyle[6]; + char transportStyle[6]; auto transportStyleLen = ReadString (transportStyle, 6, s) - 1; if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2 { @@ -231,13 +230,13 @@ namespace data address->host.to_string (ecode); if (!ecode) #endif - { + { // add supported protocol if (address->host.is_v4 ()) supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4; else supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6; - } + } } } else if (!strcmp (key, "port")) @@ -262,15 +261,15 @@ namespace data { if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; - Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32); - } + Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32); + } else if (!strcmp (key, "i")) // ntcp2 iv { if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; - Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); + Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); address->ntcp2->isPublished = true; // presence if "i" means "published" - } + } else if (key[0] == 'i') { // introducers @@ -278,7 +277,7 @@ namespace data { LogPrint (eLogError, "RouterInfo: Introducer is presented for non-SSU address. Skipped"); continue; - } + } introducers = true; size_t l = strlen(key); unsigned char index = key[l-1] - '0'; // TODO: @@ -309,7 +308,7 @@ namespace data } if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented if (isNTCP2Only && address->ntcp2) address->ntcp2->isNTCP2Only = true; - if (supportedTransports) + if (supportedTransports) { addresses->push_back(address); m_SupportedTransports |= supportedTransports; @@ -349,13 +348,13 @@ namespace data while (*ch) { if (*ch >= '0' && *ch <= '9') - { - m_Version *= 10; + { + m_Version *= 10; m_Version += (*ch - '0'); - } + } ch++; - } - } + } + } // check netId else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != i2p::context.GetNetID ()) { @@ -384,9 +383,10 @@ namespace data SetUnreachable (true); } - bool RouterInfo::IsFamily(const std::string & fam) const { - return m_Family == fam; - } + bool RouterInfo::IsFamily(const std::string & fam) const + { + return m_Family == fam; + } void RouterInfo::ExtractCaps (const char * value) { @@ -580,7 +580,7 @@ namespace data properties << '='; WriteString (boost::lexical_cast(address.port), properties); properties << ';'; - } + } if (address.IsNTCP2 ()) { // publish s and v for NTCP2 @@ -588,7 +588,7 @@ namespace data WriteString (address.ntcp2->staticKey.ToBase64 (), properties); properties << ';'; WriteString ("v", properties); properties << '='; WriteString ("2", properties); properties << ';'; - } + } uint16_t size = htobe16 (properties.str ().size ()); s.write ((char *)&size, sizeof (size)); @@ -742,7 +742,7 @@ namespace data addr->ntcp2->isNTCP2Only = true; // NTCP2 only address if (port) addr->ntcp2->isPublished = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); - memcpy (addr->ntcp2->iv, iv, 16); + memcpy (addr->ntcp2->iv, iv, 16); m_Addresses->push_back(std::move(addr)); } @@ -854,7 +854,7 @@ namespace data m_SupportedTransports |= eNTCPV6 | eSSUV6 | eNTCP2V6; } - void RouterInfo::EnableV4 () + void RouterInfo::EnableV4 () { if (!IsV4 ()) m_SupportedTransports |= eNTCPV4 | eSSUV4 | eNTCP2V4; @@ -877,7 +877,7 @@ namespace data } } - void RouterInfo::DisableV4 () + void RouterInfo::DisableV4 () { if (IsV4 ()) { @@ -926,7 +926,7 @@ namespace data }); } - template + template std::shared_ptr RouterInfo::GetAddress (Filter filter) const { // TODO: make it more generic using comparator @@ -937,7 +937,7 @@ namespace data #endif for (const auto& address : *addresses) if (filter (address)) return address; - + return nullptr; } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index f8598b1e..5bdb0f8f 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -203,8 +203,8 @@ namespace data void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; bool IsNewer (const uint8_t * buf, size_t len) const; - /** return true if we are in a router family and the signature is valid */ - bool IsFamily(const std::string & fam) const; + /** return true if we are in a router family and the signature is valid */ + bool IsFamily(const std::string & fam) const; // implements RoutingDestination std::shared_ptr GetIdentity () const { return m_RouterIdentity; }; diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 74cbe39b..4a33ff3a 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -45,15 +45,15 @@ namespace transport void SSUServer::OpenSocket () { - try + try { m_Socket.open (boost::asio::ip::udp::v4()); m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (SSU_SOCKET_RECEIVE_BUFFER_SIZE)); m_Socket.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_Socket.bind (m_Endpoint); LogPrint (eLogInfo, "SSU: Start listening v4 port ", m_Endpoint.port()); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what()); ThrowFatal ("Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); @@ -62,7 +62,7 @@ namespace transport void SSUServer::OpenSocketV6 () { - try + try { m_SocketV6.open (boost::asio::ip::udp::v6()); m_SocketV6.set_option (boost::asio::ip::v6_only (true)); @@ -70,8 +70,8 @@ namespace transport m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (SSU_SOCKET_SEND_BUFFER_SIZE)); m_SocketV6.bind (m_EndpointV6); LogPrint (eLogInfo, "SSU: Start listening v6 port ", m_EndpointV6.port()); - } - catch ( std::exception & ex ) + } + catch ( std::exception & ex ) { LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what()); ThrowFatal ("Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ()); @@ -184,7 +184,7 @@ namespace transport m_Socket.close (); OpenSocket (); Receive (); - } + } } } } @@ -359,10 +359,10 @@ namespace transport { if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous { - if (session) - { - session->FlushData (); - session = nullptr; + if (session) + { + session->FlushData (); + session = nullptr; } auto it = sessions->find (packet->from); if (it != sessions->end ()) @@ -826,4 +826,3 @@ namespace transport } } } - diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 10e5ec06..942d0e64 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -40,7 +40,7 @@ namespace transport public: SSUServer (int port); - SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor + SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor ~SSUServer (); void Start (); void Stop (); @@ -135,4 +135,3 @@ namespace transport } #endif - diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 866da277..4eb90522 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -496,7 +496,7 @@ namespace transport } // decay if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES || - i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) + i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL) m_ReceivedMessages.clear (); ScheduleIncompleteMessagesCleanup (); @@ -504,4 +504,3 @@ namespace transport } } } - diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index fbd167bf..98d60c41 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -128,4 +128,3 @@ namespace transport } #endif - diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 88dbcf04..e29af479 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -336,7 +336,7 @@ namespace transport 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 + paddingSize &= 0x0F; // %16 if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; // verify signature @@ -934,7 +934,7 @@ namespace transport for (const auto& it: msgs) if (it) { - if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE) + if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE) m_Data.Send (it); else LogPrint (eLogError, "SSU: I2NP message of size ", it->GetLength (), " can't be sent. Dropped"); @@ -1206,4 +1206,3 @@ namespace transport } } } - diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 8f81838a..4f73158a 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -28,7 +28,7 @@ namespace transport const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes const int SSU_CLOCK_SKEW = 60; // in seconds - const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768; + const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768; // payload types (4 bits) const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0; @@ -81,12 +81,12 @@ namespace transport void Done (); void Failed (); const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; }; - + bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); }; void SendI2NPMessages (const std::vector >& msgs); void SendPeerTest (); // Alice - SessionState GetState () const { return m_State; }; + SessionState GetState () const { return m_State; }; size_t GetNumSentBytes () const { return m_NumSentBytes; }; size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; }; @@ -158,10 +158,7 @@ namespace transport std::unique_ptr m_SignedData; // we need it for SessionConfirmed only std::map > m_RelayRequests; // nonce->Charlie }; - - } } #endif - diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 21d08f30..64aff5bc 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -6,11 +6,11 @@ namespace i2p { namespace crypto { -#if OPENSSL_EDDSA +#if OPENSSL_EDDSA EDDSA25519Verifier::EDDSA25519Verifier (): m_Pkey (nullptr) { - m_MDCtx = EVP_MD_CTX_create (); + m_MDCtx = EVP_MD_CTX_create (); } EDDSA25519Verifier::~EDDSA25519Verifier () @@ -23,21 +23,21 @@ namespace crypto { m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - } - + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len); } - -#else + +#else EDDSA25519Verifier::EDDSA25519Verifier () { } EDDSA25519Verifier::~EDDSA25519Verifier () { - } + } void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey) { @@ -45,8 +45,8 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); m_PublicKey = GetEd25519 ()->DecodePublicKey (m_PublicKeyEncoded, ctx); BN_CTX_free (ctx); - } - + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { uint8_t digest[64]; @@ -83,19 +83,19 @@ namespace crypto EDDSA25519SignerCompat::~EDDSA25519SignerCompat () { - } - + } + void EDDSA25519SignerCompat::Sign (const uint8_t * buf, int len, uint8_t * signature) const { GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); } - -#if OPENSSL_EDDSA + +#if OPENSSL_EDDSA EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): m_Fallback (nullptr) - { + { m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); - uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; + uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); if (signingPublicKey && memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) @@ -105,10 +105,10 @@ namespace crypto m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); } else - { - m_MDCtx = EVP_MD_CTX_create (); + { + m_MDCtx = EVP_MD_CTX_create (); EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); - } + } } EDDSA25519Signer::~EDDSA25519Signer () @@ -118,22 +118,20 @@ namespace crypto { EVP_MD_CTX_destroy (m_MDCtx); EVP_PKEY_free (m_Pkey); - } + } } void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const { if (m_Fallback) return m_Fallback->Sign (buf, len, signature); else - { - size_t l = 64; + { + size_t l = 64; uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232 - EVP_DigestSign (m_MDCtx, sig, &l, buf, len); + EVP_DigestSign (m_MDCtx, sig, &l, buf, len); memcpy (signature, sig, 64); - } - } -#endif + } + } +#endif } } - - diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 0c5f27d6..26184639 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -46,9 +46,9 @@ namespace crypto { m_PublicKey = CreateDSA (); } - + void SetPublicKey (const uint8_t * signingKey) - { + { DSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, DSA_PUBLIC_KEY_LENGTH, NULL), NULL); } @@ -163,9 +163,9 @@ namespace crypto { m_PublicKey = EC_KEY_new_by_curve_name (curve); } - + void SetPublicKey (const uint8_t * signingKey) - { + { BIGNUM * x = BN_bin2bn (signingKey, keyLen/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL); EC_KEY_set_public_key_affine_coordinates (m_PublicKey, x, y); @@ -287,7 +287,7 @@ namespace crypto EDDSA25519Verifier (); void SetPublicKey (const uint8_t * signingKey); ~EDDSA25519Verifier (); - + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; @@ -298,10 +298,10 @@ namespace crypto #if OPENSSL_EDDSA EVP_PKEY * m_Pkey; EVP_MD_CTX * m_MDCtx; -#else +#else EDDSAPoint m_PublicKey; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; -#endif +#endif }; class EDDSA25519SignerCompat: public Signer @@ -311,17 +311,17 @@ namespace crypto EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); // we pass signingPublicKey to check if it matches private key ~EDDSA25519SignerCompat (); - + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation private: - + uint8_t m_ExpandedPrivateKey[64]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; }; -#if OPENSSL_EDDSA +#if OPENSSL_EDDSA class EDDSA25519Signer: public Signer { public: @@ -329,23 +329,23 @@ namespace crypto EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); // we pass signingPublicKey to check if it matches private key ~EDDSA25519Signer (); - + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; private: EVP_PKEY * m_Pkey; - EVP_MD_CTX * m_MDCtx; + EVP_MD_CTX * m_MDCtx; EDDSA25519SignerCompat * m_Fallback; }; #else typedef EDDSA25519SignerCompat EDDSA25519Signer; - -#endif - + +#endif + inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { -#if OPENSSL_EDDSA +#if OPENSSL_EDDSA EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL); EVP_PKEY_keygen_init (pctx); @@ -355,12 +355,12 @@ namespace crypto EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len); len = EDDSA25519_PRIVATE_KEY_LENGTH; EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len); - EVP_PKEY_free (pkey); -#else + EVP_PKEY_free (pkey); +#else RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); EDDSA25519Signer signer (signingPrivateKey); memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); -#endif +#endif } @@ -399,18 +399,18 @@ namespace crypto GOSTR3410Verifier (GOSTR3410ParamSet paramSet): m_ParamSet (paramSet), m_PublicKey (nullptr) { - } + } - void SetPublicKey (const uint8_t * signingKey) + void SetPublicKey (const uint8_t * signingKey) { BIGNUM * x = BN_bin2bn (signingKey, GetPublicKeyLen ()/2, NULL); BIGNUM * y = BN_bin2bn (signingKey + GetPublicKeyLen ()/2, GetPublicKeyLen ()/2, NULL); m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y); BN_free (x); BN_free (y); } - ~GOSTR3410Verifier () - { - if (m_PublicKey) EC_POINT_free (m_PublicKey); + ~GOSTR3410Verifier () + { + if (m_PublicKey) EC_POINT_free (m_PublicKey); } bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const @@ -501,18 +501,18 @@ namespace crypto auto publicKey = GetEd25519 ()->GeneratePublicKey (m_PrivateKey, ctx); GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); BN_CTX_free (ctx); - } + } ~RedDSA25519Signer () {}; - + void Sign (const uint8_t * buf, int len, uint8_t * signature) const { - GetEd25519 ()->SignRedDSA (m_PrivateKey, m_PublicKeyEncoded, buf, len, signature); + GetEd25519 ()->SignRedDSA (m_PrivateKey, m_PublicKeyEncoded, buf, len, signature); } - + const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation private: - + uint8_t m_PrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; }; @@ -521,10 +521,9 @@ namespace crypto { GetEd25519 ()->CreateRedDSAPrivateKey (signingPrivateKey); RedDSA25519Signer signer (signingPrivateKey); - memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); + memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); } } } #endif - diff --git a/libi2pd/Siphash.h b/libi2pd/Siphash.h index 70822466..78b22b90 100644 --- a/libi2pd/Siphash.h +++ b/libi2pd/Siphash.h @@ -1,9 +1,9 @@ /** - This code is licensed under the MCGSI Public License - Copyright 2018 Jeff Becker - - Kovri go write your own code - + * This code is licensed under the MCGSI Public License + * Copyright 2018 Jeff Becker + * + * Kovri go write your own code + * */ #ifndef SIPHASH_H #define SIPHASH_H @@ -14,140 +14,140 @@ #if !OPENSSL_SIPHASH namespace i2p { -namespace crypto +namespace crypto { - namespace siphash - { - constexpr int crounds = 2; - constexpr int drounds = 4; + namespace siphash + { + constexpr int crounds = 2; + constexpr int drounds = 4; - inline uint64_t rotl(const uint64_t & x, int b) - { - uint64_t ret = x << b; - ret |= x >> (64 - b); - return ret; - } + inline uint64_t rotl(const uint64_t & x, int b) + { + uint64_t ret = x << b; + ret |= x >> (64 - b); + return ret; + } - inline void u32to8le(const uint32_t & v, uint8_t * p) - { - p[0] = (uint8_t) v; - p[1] = (uint8_t) (v >> 8); - p[2] = (uint8_t) (v >> 16); - p[3] = (uint8_t) (v >> 24); - } + inline void u32to8le(const uint32_t & v, uint8_t * p) + { + p[0] = (uint8_t) v; + p[1] = (uint8_t) (v >> 8); + p[2] = (uint8_t) (v >> 16); + p[3] = (uint8_t) (v >> 24); + } - inline void u64to8le(const uint64_t & v, uint8_t * p) - { - p[0] = v & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; - p[4] = (v >> 32) & 0xff; - p[5] = (v >> 40) & 0xff; - p[6] = (v >> 48) & 0xff; - p[7] = (v >> 56) & 0xff; - } + inline void u64to8le(const uint64_t & v, uint8_t * p) + { + p[0] = v & 0xff; + p[1] = (v >> 8) & 0xff; + p[2] = (v >> 16) & 0xff; + p[3] = (v >> 24) & 0xff; + p[4] = (v >> 32) & 0xff; + p[5] = (v >> 40) & 0xff; + p[6] = (v >> 48) & 0xff; + p[7] = (v >> 56) & 0xff; + } - inline uint64_t u8to64le(const uint8_t * p) - { - uint64_t i = 0; - int idx = 0; - while(idx < 8) - { - i |= ((uint64_t) p[idx]) << (idx * 8); - ++idx; - } - return i; - } - - inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3) - { - _v0 += _v1; - _v1 = rotl(_v1, 13); - _v1 ^= _v0; - _v0 = rotl(_v0, 32); - _v2 += _v3; - _v3 = rotl(_v3, 16); - _v3 ^= _v2; - _v0 += _v3; - _v3 = rotl(_v3, 21); - _v3 ^= _v0; - _v2 += _v1; - _v1 = rotl(_v1, 17); - _v1 ^= _v2; - _v2 = rotl(_v2, 32); - } - } - - /** hashsz must be 8 or 16 */ - template - inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key) - { - uint64_t v0 = 0x736f6d6570736575ULL; - uint64_t v1 = 0x646f72616e646f6dULL; - uint64_t v2 = 0x6c7967656e657261ULL; - uint64_t v3 = 0x7465646279746573ULL; - const uint64_t k0 = siphash::u8to64le(key); - const uint64_t k1 = siphash::u8to64le(key + 8); - uint64_t msg; - int i; - const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t)); - auto left = bufsz & 7; - uint64_t b = ((uint64_t)bufsz) << 56; - v3 ^= k1; - v2 ^= k0; - v1 ^= k1; - v0 ^= k0; + inline uint64_t u8to64le(const uint8_t * p) + { + uint64_t i = 0; + int idx = 0; + while(idx < 8) + { + i |= ((uint64_t) p[idx]) << (idx * 8); + ++idx; + } + return i; + } - if(hashsz == 16) v1 ^= 0xee; + inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3) + { + _v0 += _v1; + _v1 = rotl(_v1, 13); + _v1 ^= _v0; + _v0 = rotl(_v0, 32); + _v2 += _v3; + _v3 = rotl(_v3, 16); + _v3 ^= _v2; + _v0 += _v3; + _v3 = rotl(_v3, 21); + _v3 ^= _v0; + _v2 += _v1; + _v1 = rotl(_v1, 17); + _v1 ^= _v2; + _v2 = rotl(_v2, 32); + } + } - while(buf != end) - { - msg = siphash::u8to64le(buf); - v3 ^= msg; - for(i = 0; i < siphash::crounds; ++i) - siphash::round(v0, v1, v2, v3); - - v0 ^= msg; - buf += 8; - } + /** hashsz must be 8 or 16 */ + template + inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key) + { + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f6dULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + const uint64_t k0 = siphash::u8to64le(key); + const uint64_t k1 = siphash::u8to64le(key + 8); + uint64_t msg; + int i; + const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t)); + auto left = bufsz & 7; + uint64_t b = ((uint64_t)bufsz) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; - while(left) - { - --left; - b |= ((uint64_t)(buf[left])) << (left * 8); - } + if(hashsz == 16) v1 ^= 0xee; - v3 ^= b; + while(buf != end) + { + msg = siphash::u8to64le(buf); + v3 ^= msg; + for(i = 0; i < siphash::crounds; ++i) + siphash::round(v0, v1, v2, v3); - for(i = 0; i < siphash::crounds; ++i) - siphash::round(v0, v1, v2, v3); + v0 ^= msg; + buf += 8; + } - v0 ^= b; + while(left) + { + --left; + b |= ((uint64_t)(buf[left])) << (left * 8); + } + + v3 ^= b; + + for(i = 0; i < siphash::crounds; ++i) + siphash::round(v0, v1, v2, v3); + + v0 ^= b; - if(hashsz == 16) - v2 ^= 0xee; - else - v2 ^= 0xff; + if(hashsz == 16) + v2 ^= 0xee; + else + v2 ^= 0xff; - for(i = 0; i < siphash::drounds; ++i) - siphash::round(v0, v1, v2, v3); + for(i = 0; i < siphash::drounds; ++i) + siphash::round(v0, v1, v2, v3); - b = v0 ^ v1 ^ v2 ^ v3; + b = v0 ^ v1 ^ v2 ^ v3; - siphash::u64to8le(b, h); + siphash::u64to8le(b, h); - if(hashsz == 8) return; + if(hashsz == 8) return; - v1 ^= 0xdd; + v1 ^= 0xdd; - for (i = 0; i < siphash::drounds; ++i) - siphash::round(v0, v1, v2, v3); + for (i = 0; i < siphash::drounds; ++i) + siphash::round(v0, v1, v2, v3); - b = v0 ^ v1 ^ v2 ^ v3; - siphash::u64to8le(b, h + 8); - } + b = v0 ^ v1 ^ v2 ^ v3; + siphash::u64to8le(b, h + 8); + } } } #endif diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 00ee35b0..ac527cb4 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -34,7 +34,7 @@ namespace stream else { // partially - rem = len - offset; + rem = len - offset; memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset); nextBuffer->offset += (len - offset); offset = len; // break @@ -60,7 +60,7 @@ namespace stream m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local), m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), - m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), + m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) @@ -73,7 +73,7 @@ namespace stream m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), - m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE), + m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()), m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU) { @@ -228,7 +228,7 @@ namespace stream Terminate (); return; } - + packet->offset = packet->GetPayload () - packet->buf; if (packet->GetLength () > 0) { @@ -258,7 +258,7 @@ namespace stream bool Stream::ProcessOptions (uint16_t flags, Packet * packet) { const uint8_t * optionData = packet->GetOptionData (); - size_t optionSize = packet->GetOptionSize (); + size_t optionSize = packet->GetOptionSize (); if (flags & PACKET_FLAG_DELAY_REQUESTED) optionData += 2; @@ -269,7 +269,7 @@ namespace stream m_RemoteIdentity = std::make_shared(optionData, optionSize); if (m_RemoteIdentity->IsRSA ()) { - LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded"); + LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded"); return false; } optionData += m_RemoteIdentity->GetFullLen (); @@ -306,11 +306,11 @@ namespace stream size_t offset = 0; m_TransientVerifier = i2p::data::ProcessOfflineSignature (m_RemoteIdentity, optionData, optionSize - (optionData - packet->GetOptionData ()), offset); optionData += offset; - if (!m_TransientVerifier) + if (!m_TransientVerifier) { LogPrint (eLogError, "Streaming: offline signature failed"); return false; - } + } } } @@ -322,7 +322,7 @@ namespace stream { memcpy (signature, optionData, signatureLen); memset (const_cast(optionData), 0, signatureLen); - bool verified = m_TransientVerifier ? + bool verified = m_TransientVerifier ? m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature) : m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature); if (!verified) @@ -340,7 +340,7 @@ namespace stream return false; } } - return true; + return true; } void Stream::ProcessAck (Packet * packet) @@ -435,7 +435,7 @@ namespace stream m_SendBuffer.Add (buf, len, handler); } else if (handler) - handler(boost::system::error_code ()); + handler(boost::system::error_code ()); m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ())); } @@ -471,14 +471,14 @@ namespace stream size++; // resend delay if (m_Status == eStreamStatusNew) { - // initial packet + // initial packet m_Status = eStreamStatusOpen; if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());; if (m_RemoteLeaseSet) - { + { m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); m_MTU = m_RoutingSession->IsRatchets () ? STREAMING_MTU_RATCHETS : STREAMING_MTU; - } + } uint16_t flags = PACKET_FLAG_SYNCHRONIZE | PACKET_FLAG_FROM_INCLUDED | PACKET_FLAG_SIGNATURE_INCLUDED | PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED; if (isNoAck) flags |= PACKET_FLAG_NO_ACK; @@ -488,7 +488,7 @@ namespace stream 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 + uint8_t * optionsSize = packet + size; // set options size later size += 2; // options size m_LocalDestination.GetOwner ()->GetIdentity ()->ToBuffer (packet + size, identityLen); size += identityLen; // from @@ -654,7 +654,7 @@ namespace stream size += 4; // receiveStreamID htobe32buf (packet + size, m_SequenceNumber++); size += 4; // sequenceNum - htobe32buf (packet + size, m_LastReceivedSequenceNumber >= 0 ? m_LastReceivedSequenceNumber : 0); + htobe32buf (packet + size, m_LastReceivedSequenceNumber >= 0 ? m_LastReceivedSequenceNumber : 0); size += 4; // ack Through packet[size] = 0; size++; // NACK count @@ -748,7 +748,7 @@ namespace stream auto ts = i2p::util::GetMillisecondsSinceEpoch (); if (!m_CurrentRemoteLease || !m_CurrentRemoteLease->endDate || // excluded from LeaseSet - ts >= m_CurrentRemoteLease->endDate - i2p::data::LEASE_ENDDATE_THRESHOLD) + ts >= m_CurrentRemoteLease->endDate - i2p::data::LEASE_ENDDATE_THRESHOLD) UpdateCurrentRemoteLease (true); if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD) { @@ -785,7 +785,7 @@ namespace stream if (ts > m_RoutingSession->GetLeaseSetSubmissionTime () + i2p::garlic::LEASET_CONFIRMATION_TIMEOUT) { // LeaseSet was not confirmed, should try other tunnels - LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit"); + LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit"); m_RoutingSession->SetSharedRoutingPath (nullptr); m_CurrentOutboundTunnel = nullptr; m_CurrentRemoteLease = nullptr; @@ -848,9 +848,9 @@ namespace stream break; case 2: m_RTO = INITIAL_RTO; // drop RTO to initial upon tunnels pair change first time -#if (__cplusplus >= 201703L) // C++ 17 or higher - [[fallthrough]]; -#endif +#if (__cplusplus >= 201703L) // C++ 17 or higher + [[fallthrough]]; +#endif // no break here case 4: if (m_RoutingSession) m_RoutingSession->SetSharedRoutingPath (nullptr); @@ -911,7 +911,7 @@ namespace stream // LeaseSet updated m_RemoteIdentity = m_RemoteLeaseSet->GetIdentity (); m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier (); - } + } } if (m_RemoteLeaseSet) { @@ -926,7 +926,7 @@ namespace stream m_LocalDestination.GetOwner ()->RequestDestinationWithEncryptedLeaseSet ( std::make_shared(m_RemoteIdentity)); else - m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); + m_LocalDestination.GetOwner ()->RequestDestination (m_RemoteIdentity->GetIdentHash ()); leases = m_RemoteLeaseSet->GetNonExpiredLeases (true); // then with threshold } if (!leases.empty ()) @@ -994,7 +994,7 @@ namespace stream { std::unique_lock l(m_StreamsMutex); for (auto it: m_Streams) - it.second->Terminate (false); // we delete here + it.second->Terminate (false); // we delete here m_Streams.clear (); m_IncomingStreams.clear (); } @@ -1136,8 +1136,8 @@ namespace stream return false; DeleteStream (it->second); return true; - } - + } + void StreamingDestination::SetAcceptor (const Acceptor& acceptor) { m_Acceptor = acceptor; // we must set it immediately for IsAcceptorSet @@ -1164,7 +1164,7 @@ namespace stream m_Owner->GetService ().post([acceptor, this](void) { if (!m_PendingIncomingStreams.empty ()) - { + { acceptor (m_PendingIncomingStreams.front ()); m_PendingIncomingStreams.pop_front (); if (m_PendingIncomingStreams.empty ()) diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index 010b160f..eefab6de 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -16,93 +16,91 @@ namespace i2p { namespace data { - -template -class Tag -{ - BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes"); - -public: - - Tag () = default; - Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); } - - bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); } - bool operator!= (const Tag& other) const { return !(*this == other); } - bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; } - - uint8_t * operator()() { return m_Buf; } - const uint8_t * operator()() const { return m_Buf; } - - operator uint8_t * () { return m_Buf; } - operator const uint8_t * () const { return m_Buf; } - - const uint8_t * data() const { return m_Buf; } - const uint64_t * GetLL () const { return ll; } - - bool IsZero () const + template + class Tag { - for (size_t i = 0; i < sz/8; ++i) - if (ll[i]) return false; - return true; - } + BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes"); - void Fill(uint8_t c) - { - memset(m_Buf, c, sz); - } + public: - void Randomize() - { - RAND_bytes(m_Buf, sz); - } + Tag () = default; + Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); } - std::string ToBase64 () const - { - char str[sz*2]; - size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); - return std::string (str, str + l); - } + bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); } + bool operator!= (const Tag& other) const { return !(*this == other); } + bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; } - std::string ToBase32 () const - { - char str[sz*2]; - size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); - return std::string (str, str + l); - } + uint8_t * operator()() { return m_Buf; } + const uint8_t * operator()() const { return m_Buf; } - size_t FromBase32 (const std::string& s) - { - return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); - } + operator uint8_t * () { return m_Buf; } + operator const uint8_t * () const { return m_Buf; } - size_t FromBase64 (const std::string& s) - { - return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); - } + const uint8_t * data() const { return m_Buf; } + const uint64_t * GetLL () const { return ll; } -private: + bool IsZero () const + { + for (size_t i = 0; i < sz/8; ++i) + if (ll[i]) return false; + return true; + } - union // 8 bytes aligned - { - uint8_t m_Buf[sz]; - uint64_t ll[sz/8]; + void Fill(uint8_t c) + { + memset(m_Buf, c, sz); + } + + void Randomize() + { + RAND_bytes(m_Buf, sz); + } + + std::string ToBase64 () const + { + char str[sz*2]; + size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); + return std::string (str, str + l); + } + + std::string ToBase32 () const + { + char str[sz*2]; + size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); + return std::string (str, str + l); + } + + size_t FromBase32 (const std::string& s) + { + return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + + size_t FromBase64 (const std::string& s) + { + return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + + private: + + union // 8 bytes aligned + { + uint8_t m_Buf[sz]; + uint64_t ll[sz/8]; + }; }; -}; - } // data } // i2p namespace std { - // hash for std::unordered_map - template struct hash > - { - size_t operator()(const i2p::data::Tag& s) const - { - return s.GetLL ()[0]; - } - }; + // hash for std::unordered_map + template struct hash > + { + size_t operator()(const i2p::data::Tag& s) const + { + return s.GetLL ()[0]; + } + }; } #endif /* TAG_H__ */ diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index acc9cb10..9e435e21 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -24,26 +24,26 @@ namespace util static uint64_t GetLocalMillisecondsSinceEpoch () { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); + std::chrono::system_clock::now().time_since_epoch()).count (); } static uint32_t GetLocalHoursSinceEpoch () { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); + std::chrono::system_clock::now().time_since_epoch()).count (); } static uint64_t GetLocalSecondsSinceEpoch () { return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); + std::chrono::system_clock::now().time_since_epoch()).count (); } static int64_t g_TimeOffset = 0; // in seconds static void SyncTimeWithNTP (const std::string& address) { - LogPrint (eLogInfo, "Timestamp: NTP request to ", address); + 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; @@ -148,11 +148,11 @@ namespace util } void NTPTimeSync::Sync () - { + { if (m_NTPServersList.size () > 0) SyncTimeWithNTP (m_NTPServersList[rand () % m_NTPServersList.size ()]); else - m_IsRunning = false; + m_IsRunning = false; if (m_IsRunning) { @@ -200,4 +200,3 @@ namespace util } } } - diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index 31dc86aa..7d183cd3 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -15,8 +15,8 @@ namespace util uint32_t GetHoursSinceEpoch (); uint64_t GetSecondsSinceEpoch (); - void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes - void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes + void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes + void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes class NTPTimeSync { @@ -26,17 +26,17 @@ namespace util ~NTPTimeSync (); void Start (); - void Stop (); + void Stop (); private: - + void Run (); - void Sync (); + void Sync (); private: bool m_IsRunning; - std::unique_ptr m_Thread; + std::unique_ptr m_Thread; boost::asio::io_service m_Service; boost::asio::deadline_timer m_Timer; int m_SyncInterval; @@ -46,4 +46,3 @@ namespace util } #endif - diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 1adc4178..02aac23f 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -12,7 +12,7 @@ namespace i2p namespace tunnel { TransitTunnel::TransitTunnel (uint32_t receiveTunnelID, - const uint8_t * nextIdent, uint32_t nextTunnelID, + const uint8_t * nextIdent, uint32_t nextTunnelID, const uint8_t * layerKey,const uint8_t * ivKey): TunnelBase (receiveTunnelID, nextTunnelID, nextIdent) { @@ -88,7 +88,7 @@ namespace tunnel std::shared_ptr CreateTransitTunnel (uint32_t receiveTunnelID, const uint8_t * nextIdent, uint32_t nextTunnelID, - const uint8_t * layerKey,const uint8_t * ivKey, + const uint8_t * layerKey,const uint8_t * ivKey, bool isGateway, bool isEndpoint) { if (isEndpoint) diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 55c39c7a..69b772cb 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -68,15 +68,15 @@ namespace transport std::string GetIdentHashBase64() const { return m_RemoteIdentity ? m_RemoteIdentity->GetIdentHash().ToBase64() : ""; } - std::shared_ptr GetRemoteIdentity () + std::shared_ptr GetRemoteIdentity () { std::lock_guard l(m_RemoteIdentityMutex); - return m_RemoteIdentity; + return m_RemoteIdentity; } - void SetRemoteIdentity (std::shared_ptr ident) + void SetRemoteIdentity (std::shared_ptr ident) { std::lock_guard l(m_RemoteIdentityMutex); - m_RemoteIdentity = ident; + m_RemoteIdentity = ident; } size_t GetNumSentBytes () const { return m_NumSentBytes; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index bb74e2ad..15820584 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -220,10 +220,10 @@ namespace transport return; } else - { + { m_NTCP2Server = new NTCP2Server (); m_NTCP2Server->Start (); - } + } } // create acceptors @@ -390,7 +390,7 @@ namespace transport { auto r = netdb.FindRouter (ident); { - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, i2p::util::GetSecondsSinceEpoch (), {} })).first; } @@ -553,13 +553,13 @@ namespace transport { auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4 if (router) - m_SSUServer->CreateSession (router, true, isv4); // peer test + 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 + m_SSUServer->CreateSession (router); // no peer test } } if (i2p::context.SupportsV6 ()) @@ -574,7 +574,7 @@ namespace transport if (addr) m_SSUServer->GetServiceV6 ().post ([this, router, addr] { - m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); + m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); }); } } @@ -713,7 +713,7 @@ namespace transport { profile->TunnelNonReplied(); } - std::unique_lock l(m_PeersMutex); + std::unique_lock l(m_PeersMutex); it = m_Peers.erase (it); } else diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 117092ad..37cfa269 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -103,7 +103,7 @@ namespace transport uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; }; uint64_t GetTotalTransitTransmittedBytes () const { return m_TotalTransitTransmittedBytes; } void UpdateTotalTransitTransmittedBytes (uint32_t add) { m_TotalTransitTransmittedBytes += add; }; - uint32_t GetInBandwidth () const { return m_InBandwidth; }; + uint32_t GetInBandwidth () const { return m_InBandwidth; }; uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; }; bool IsBandwidthExceeded () const; @@ -111,16 +111,16 @@ namespace transport size_t GetNumPeers () const { return m_Peers.size (); }; std::shared_ptr GetRandomPeer () const; - /** get a trusted first hop for restricted routes */ - std::shared_ptr GetRestrictedPeer() const; - /** do we want to use restricted routes? */ - bool RoutesRestricted() const; - /** restrict routes to use only these router families for first hops */ - void RestrictRoutesToFamilies(std::set families); - /** restrict routes to use only these routers for first hops */ - void RestrictRoutesToRouters(std::set routers); + /** get a trusted first hop for restricted routes */ + std::shared_ptr GetRestrictedPeer() const; + /** do we want to use restricted routes? */ + bool RoutesRestricted() const; + /** restrict routes to use only these router families for first hops */ + void RestrictRoutesToFamilies(std::set families); + /** restrict routes to use only these routers for first hops */ + void RestrictRoutesToRouters(std::set routers); - bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; + bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const; void PeerTest (); diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 324d5315..6e453d91 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -64,8 +64,7 @@ namespace tunnel m.hash = i2p::data::IdentHash (fragment); fragment += 32; // to hash break; - default: - ; + default: ; } bool isFragmented = flag & 0x08; diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 7d0069a9..3f4069e1 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -51,7 +51,7 @@ namespace tunnel // create fragments const std::shared_ptr & msg = block.data; size_t fullMsgLen = diLen + msg->GetLength () + 2; // delivery instructions + payload + 2 bytes length - + if (!messageCreated && fullMsgLen > m_RemainingSize) // check if we should complete previous message { size_t numFollowOnFragments = fullMsgLen / TUNNEL_DATA_MAX_PAYLOAD_SIZE; @@ -172,7 +172,7 @@ namespace tunnel SHA256(payload, size+16, hash); memcpy (buf+20, hash, 4); // checksum payload[-1] = 0; // zero - ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1 + ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1 if (paddingSize > 0) { // non-zero padding @@ -219,4 +219,3 @@ namespace tunnel } } } - diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 7256b2db..54459960 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -16,7 +16,6 @@ namespace i2p { namespace tunnel { - TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true), @@ -67,7 +66,8 @@ namespace tunnel m_Tests.clear (); } - bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) { + bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) + { if( inHops >= 0 && outHops >= 0 && inQuant > 0 && outQuant > 0) { m_NumInboundHops = inHops; @@ -78,7 +78,7 @@ namespace tunnel } return false; } - + void TunnelPool::TunnelCreated (std::shared_ptr createdTunnel) { if (!m_IsActive) return; @@ -180,8 +180,8 @@ namespace tunnel { if (it->IsEstablished () && it != excluded) { - tunnel = it; - i++; + tunnel = it; + i++; } if (i > ind && tunnel) break; } @@ -411,7 +411,7 @@ namespace tunnel { std::lock_guard lock(m_CustomPeerSelectorMutex); if (m_CustomPeerSelector) - return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); + return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound); } // explicit peers in use if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index d6fb91cc..149a5efa 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -75,23 +75,23 @@ namespace tunnel /** i2cp reconfigure */ bool Reconfigure(int inboundHops, int outboundHops, int inboundQuant, int outboundQuant); - + void SetCustomPeerSelector(ITunnelPeerSelector * selector); void UnsetCustomPeerSelector(); bool HasCustomPeerSelector(); - /** @brief make this tunnel pool yield tunnels that fit latency range [min, max] */ - void RequireLatency(uint64_t min, uint64_t max) { m_MinLatency = min; m_MaxLatency = max; } + /** @brief make this tunnel pool yield tunnels that fit latency range [min, max] */ + void RequireLatency(uint64_t min, uint64_t max) { m_MinLatency = min; m_MaxLatency = max; } - /** @brief return true if this tunnel pool has a latency requirement */ - bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; } + /** @brief return true if this tunnel pool has a latency requirement */ + bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; } - /** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */ - std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude=nullptr) const; - std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude=nullptr) const; + /** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */ + std::shared_ptr GetLowestLatencyInboundTunnel(std::shared_ptr exclude = nullptr) const; + std::shared_ptr GetLowestLatencyOutboundTunnel(std::shared_ptr exclude = nullptr) const; - // for overriding tunnel peer selection - std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; + // for overriding tunnel peer selection + std::shared_ptr SelectNextHop (std::shared_ptr prevHop) const; private: @@ -118,8 +118,8 @@ namespace tunnel std::mutex m_CustomPeerSelectorMutex; ITunnelPeerSelector * m_CustomPeerSelector; - uint64_t m_MinLatency=0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms - uint64_t m_MaxLatency=0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms + uint64_t m_MinLatency = 0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms + uint64_t m_MaxLatency = 0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms public: diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index 0a76bda7..3bac4878 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -31,8 +31,8 @@ namespace api bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); i2p::crypto::InitCrypto (precomputation); - int netID; i2p::config::GetOption("netid", netID); - i2p::context.SetNetID (netID); + int netID; i2p::config::GetOption("netid", netID); + i2p::context.SetNetID (netID); i2p::context.Init (); } @@ -133,4 +133,3 @@ namespace api } } } - diff --git a/libi2pd/api.h b/libi2pd/api.h index f64590d1..444667f0 100644 --- a/libi2pd/api.h +++ b/libi2pd/api.h @@ -35,4 +35,3 @@ namespace api } #endif - diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index c1b741fc..37898167 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -64,9 +64,9 @@ namespace util { m_IsRunning = true; m_Thread.reset (new std::thread (std::bind (& RunnableService::Run, this))); - } + } } - + void RunnableService::StopIOService () { if (m_IsRunning) @@ -79,7 +79,7 @@ namespace util m_Thread = nullptr; } } - } + } void RunnableService::Run () { @@ -94,28 +94,28 @@ namespace util LogPrint (eLogError, m_Name, ": runtime exception: ", ex.what ()); } } - } - + } + namespace net { #ifdef WIN32 bool IsWindowsXPorLater() { - static bool isRequested = false; - static bool isXP = false; - if (!isRequested) - { - // request - OSVERSIONINFO osvi; + static bool isRequested = false; + static bool isXP = false; + if (!isRequested) + { + // request + OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); - isXP = osvi.dwMajorVersion <= 5; - isRequested = true; - } - return isXP; + isXP = osvi.dwMajorVersion <= 5; + isRequested = true; + } + return isXP; } int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback) @@ -246,22 +246,24 @@ namespace net std::string localAddressUniversal = localAddress.to_string(); #endif - typedef int (* IPN)(int af, const char *src, void *dst); + typedef int (* IPN)(int af, const char *src, void *dst); IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton"); - if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found + if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found if(localAddress.is_v4()) { sockaddr_in inputAddress; - inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); + inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr)); return GetMTUWindowsIpv4(inputAddress, fallback); } else if(localAddress.is_v6()) { sockaddr_in6 inputAddress; - inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); + inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr)); return GetMTUWindowsIpv6(inputAddress, fallback); - } else { + } + else + { LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported"); return fallback; } @@ -355,7 +357,7 @@ namespace net if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af) { // match - char addr[INET6_ADDRSTRLEN]; + char addr[INET6_ADDRSTRLEN]; memset (addr, 0, INET6_ADDRSTRLEN); if(af == AF_INET) inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN); @@ -379,7 +381,6 @@ namespace net LogPrint(eLogWarning, "NetIface: cannot find ipv4 address for interface ", ifname); } return boost::asio::ip::address::from_string(fallback); - #endif } } diff --git a/libi2pd/util.h b/libi2pd/util.h index 2202ccd9..aa83ed7b 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -132,34 +132,34 @@ namespace util boost::asio::io_service& GetIOService () { return m_Service; } bool IsRunning () const { return m_IsRunning; }; - + void StartIOService (); void StopIOService (); private: void Run (); - + private: std::string m_Name; volatile bool m_IsRunning; std::unique_ptr m_Thread; boost::asio::io_service m_Service; - }; + }; class RunnableServiceWithWork: public RunnableService { protected: - RunnableServiceWithWork (const std::string& name): - RunnableService (name), m_Work (GetIOService ()) {} - + RunnableServiceWithWork (const std::string& name): + RunnableService (name), m_Work (GetIOService ()) {} + private: boost::asio::io_service::work m_Work; - }; - + }; + namespace net { int GetMTU (const boost::asio::ip::address& localAddress); diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 0e40c76e..8e14c526 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -31,7 +31,7 @@ namespace client std::string etagsPath, indexPath, localPath; public: - AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") + AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") { i2p::config::GetOption("persist.addressbook", m_IsPersist); } @@ -77,10 +77,10 @@ namespace client std::shared_ptr AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const { - if (!m_IsPersist) + if (!m_IsPersist) { LogPrint(eLogDebug, "Addressbook: Persistence is disabled"); - return nullptr; + return nullptr; } std::string filename = storage.Path(ident.ToBase32()); std::ifstream f(filename, std::ifstream::binary); @@ -121,7 +121,7 @@ namespace client void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident) { - if (!m_IsPersist) return; + if (!m_IsPersist) return; storage.Remove( ident.ToBase32() ); } @@ -189,7 +189,7 @@ namespace client } for (const auto& it: addresses) - { + { f << it.first << ","; if (it.second->IsIdentHash ()) f << it.second->identHash.ToBase32 (); @@ -251,12 +251,12 @@ namespace client if (blindedPublicKey->IsValid ()) addressType = eAddressBlindedPublicKey; } - } + } Address::Address (const i2p::data::IdentHash& hash) { addressType = eAddressIndentHash; - identHash = hash; + identHash = hash; } AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false), @@ -322,7 +322,7 @@ namespace client { auto pos = address.find(".b32.i2p"); if (pos != std::string::npos) - { + { auto addr = std::make_shared(address.substr (0, pos)); return addr->IsValid () ? addr : nullptr; } @@ -333,10 +333,10 @@ namespace client { auto addr = FindAddress (address); if (!addr) - LookupAddress (address); // TODO: + LookupAddress (address); // TODO: return addr; - } - } + } + } // if not .b32 we assume full base64 address i2p::data::IdentityEx dest; if (!dest.FromBase64 (address)) @@ -359,10 +359,10 @@ namespace client { m_Addresses[address] = std::make_shared
(jump.substr (0, pos)); LogPrint (eLogInfo, "Addressbook: added ", address," -> ", jump); - } + } else - { - // assume base64 + { + // assume base64 auto ident = std::make_shared(); if (ident->FromBase64 (jump)) { @@ -487,18 +487,18 @@ namespace client LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead"); } else if (!i2p::config::IsDefault("addressbook.subscriptions")) - { - // using config file items - std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs); - std::vector subsList; - boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); + { + // using config file items + std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs); + std::vector subsList; + boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); - for (size_t i = 0; i < subsList.size (); i++) - { - m_Subscriptions.push_back (std::make_shared (*this, subsList[i])); - } - LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); - } + for (size_t i = 0; i < subsList.size (); i++) + { + m_Subscriptions.push_back (std::make_shared (*this, subsList[i])); + } + LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); + } } else LogPrint (eLogError, "Addressbook: subscriptions already loaded"); @@ -515,7 +515,7 @@ namespace client if (dot != std::string::npos) { auto domain = it.first.substr (dot + 1); - auto it1 = m_Addresses.find (domain); // find domain in our addressbook + auto it1 = m_Addresses.find (domain); // find domain in our addressbook if (it1 != m_Addresses.end () && it1->second->IsIdentHash ()) { auto dest = context.FindLocalDestination (it1->second->identHash); @@ -610,7 +610,7 @@ namespace client { // download it from default subscription LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription."); - std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL); + std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL); if (!m_DefaultSubscription) m_DefaultSubscription = std::make_shared(*this, defaultSubURL); m_IsDownloading = true; @@ -743,13 +743,13 @@ namespace client i2p::http::URL url; // must be run in separate thread LogPrint (eLogInfo, "Addressbook: Downloading hosts database from ", m_Link); - if (!url.parse(m_Link)) + if (!url.parse(m_Link)) { LogPrint(eLogError, "Addressbook: failed to parse url: ", m_Link); return false; } auto addr = m_Book.GetAddress (url.host); - if (!addr || !addr->IsIdentHash ()) + if (!addr || !addr->IsIdentHash ()) { LogPrint (eLogError, "Addressbook: Can't resolve ", url.host); return false; @@ -802,7 +802,7 @@ namespace client /* convert url to relative */ url.schema = ""; url.host = ""; - req.uri = url.to_string(); + req.uri = url.to_string(); auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port); std::string request = req.to_string(); stream->Send ((const uint8_t *) request.data(), request.length()); @@ -920,7 +920,7 @@ namespace client { auto datagram = m_LocalDestination->GetDatagramDestination (); if (datagram) - datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT); + datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT); } } diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h index 82ba167b..fb69dad3 100644 --- a/libi2pd_client/AddressBook.h +++ b/libi2pd_client/AddressBook.h @@ -37,8 +37,8 @@ namespace client i2p::data::IdentHash identHash; std::shared_ptr blindedPublicKey; - Address (const std::string& b32); - Address (const i2p::data::IdentHash& hash); + Address (const std::string& b32); + Address (const i2p::data::IdentHash& hash); bool IsIdentHash () const { return addressType == eAddressIndentHash; }; bool IsValid () const { return addressType != eAddressInvalid; }; }; @@ -160,5 +160,3 @@ namespace client } #endif - - diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index c7bbdb46..e5d5404b 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -50,10 +50,10 @@ namespace client void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr receiver) { receiver->socket->async_read_some (boost::asio::buffer( - receiver->buffer + receiver->bufferOffset, - BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset), + receiver->buffer + receiver->bufferOffset, + BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset), std::bind(&BOBI2PInboundTunnel::HandleReceivedAddress, this, - std::placeholders::_1, std::placeholders::_2, receiver)); + std::placeholders::_1, std::placeholders::_2, receiver)); } void BOBI2PInboundTunnel::HandleReceivedAddress (const boost::system::error_code& ecode, std::size_t bytes_transferred, @@ -255,7 +255,7 @@ namespace client std::bind(&BOBCommandSession::HandleReceivedLine, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - + void BOBCommandSession::HandleReceivedLine(const boost::system::error_code& ecode, std::size_t bytes_transferred) { if(ecode) @@ -267,14 +267,14 @@ namespace client else { std::string line; - + std::istream is(&m_ReceiveBuffer); std::getline(is, line); - + std::string command, operand; std::istringstream iss(line); iss >> command >> operand; - + // process command auto& handlers = m_Owner.GetCommandHandlers(); auto it = handlers.find(command); @@ -346,7 +346,7 @@ namespace client std::ostream os(&m_SendBuffer); os << data << std::endl; } - + void BOBCommandSession::BuildStatusLine(bool currentTunnel, BOBDestination *dest, std::string &out) { // helper lambdas @@ -355,7 +355,7 @@ namespace client const auto destExists = [](const BOBDestination * const dest) { return dest != nullptr; }; const auto destReady = [](const BOBDestination * const dest) { return dest->GetLocalDestination()->IsReady(); }; const auto bool_str = [](const bool v) { return v ? "true" : "false"; }; // bool -> str - + // tunnel info const std::string nickname = currentTunnel ? m_Nickname : dest->GetNickname(); const bool quiet = currentTunnel ? m_IsQuiet : dest->GetQuiet(); @@ -367,7 +367,7 @@ namespace client const bool starting = destExists(dest) && !destReady(dest); const bool running = destExists(dest) && destReady(dest); const bool stopping = false; - + // build line std::stringstream ss; ss << "DATA " @@ -433,11 +433,11 @@ namespace client return; } } - + if (!m_CurrentDestination) { m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command - m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet); + m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet); m_Owner.AddDestination (m_Nickname, m_CurrentDestination); } if (m_InPort) @@ -613,25 +613,24 @@ namespace client } auto localDestination = m_CurrentDestination ? m_CurrentDestination->GetLocalDestination () : i2p::client::context.GetSharedLocalDestination (); if (addr->IsIdentHash ()) - { + { // we might have leaseset already auto leaseSet = localDestination->FindLeaseSet (addr->identHash); if (leaseSet) - { + { SendReplyOK (leaseSet->GetIdentity ()->ToBase64 ().c_str ()); return; } } // trying to request - auto s = shared_from_this (); - auto requstCallback = - [s](std::shared_ptr ls) - { - if (ls) - s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ()); - else - s->SendReplyError ("LeaseSet Not found"); - }; + auto s = shared_from_this (); + auto requstCallback = [s](std::shared_ptr ls) + { + if (ls) + s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ()); + else + s->SendReplyError ("LeaseSet Not found"); + }; if (addr->IsIdentHash ()) localDestination->RequestDestination (addr->identHash, requstCallback); else @@ -794,7 +793,7 @@ namespace client BOBCommandChannel::~BOBCommandChannel () { - if (IsRunning ()) + if (IsRunning ()) Stop (); for (const auto& it: m_Destinations) delete it.second; @@ -856,8 +855,7 @@ namespace client session->SendVersion (); } else - LogPrint (eLogError, "BOB: accept error: ", ecode.message ()); + LogPrint (eLogError, "BOB: accept error: ", ecode.message ()); } } } - diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 15a0afaf..a3d58148 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -39,7 +39,7 @@ namespace client const char BOB_COMMAND_OPTION[] = "option"; const char BOB_COMMAND_STATUS[] = "status"; const char BOB_COMMAND_HELP[] = "help"; - + const char BOB_HELP_ZAP[] = "zap - Shuts down BOB."; const char BOB_HELP_QUIT[] = "quit - Quits this session with BOB."; const char BOB_HELP_START[] = "start - Starts the current nicknamed tunnel."; @@ -75,15 +75,15 @@ namespace client class BOBI2PInboundTunnel: public BOBI2PTunnel { - struct AddressReceiver - { - std::shared_ptr socket; - char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address - uint8_t * data; // pointer to buffer - size_t dataLen, bufferOffset; + struct AddressReceiver + { + std::shared_ptr socket; + char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address + uint8_t * data; // pointer to buffer + size_t dataLen, bufferOffset; - AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {}; - }; + AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {}; + }; public: @@ -115,7 +115,7 @@ namespace client { public: - BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet); + BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr localDestination, bool quiet); void Start (); void Stop (); @@ -162,7 +162,7 @@ namespace client std::shared_ptr m_LocalDestination; BOBI2POutboundTunnel * m_OutboundTunnel; BOBI2PInboundTunnel * m_InboundTunnel; - + std::string m_Nickname; std::string m_InHost, m_OutHost; int m_InPort, m_OutPort; @@ -215,14 +215,14 @@ namespace client void SendReplyOK (const char * msg = nullptr); void SendReplyError (const char * msg); void SendRaw (const char * data); - + void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out); private: BOBCommandChannel& m_Owner; boost::asio::ip::tcp::socket m_Socket; - boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer; + boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer; bool m_IsOpen, m_IsQuiet, m_IsActive; std::string m_Nickname, m_InHost, m_OutHost; int m_InPort, m_OutPort; @@ -269,4 +269,3 @@ namespace client } #endif - diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 51f10f5e..03c756a1 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -52,18 +52,18 @@ namespace client // SAM bool sam; i2p::config::GetOption("sam.enabled", sam); - if (sam) + if (sam) { std::string samAddr; i2p::config::GetOption("sam.address", samAddr); uint16_t samPort; i2p::config::GetOption("sam.port", samPort); - bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); + bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort); - try + try { m_SamBridge = new SAMBridge (samAddr, samPort, singleThread); m_SamBridge->Start (); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SAM bridge: ", e.what()); ThrowFatal ("Unable to start SAM bridge at ", samAddr, ":", samPort, ": ", e.what ()); @@ -76,12 +76,12 @@ namespace client std::string bobAddr; i2p::config::GetOption("bob.address", bobAddr); uint16_t bobPort; i2p::config::GetOption("bob.port", bobPort); LogPrint(eLogInfo, "Clients: starting BOB command channel at ", bobAddr, ":", bobPort); - try + try { m_BOBCommandChannel = new BOBCommandChannel (bobAddr, bobPort); m_BOBCommandChannel->Start (); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in BOB bridge: ", e.what()); ThrowFatal ("Unable to start BOB bridge at ", bobAddr, ":", bobPort, ": ", e.what ()); @@ -95,12 +95,12 @@ namespace client std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); - try + try { m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); m_I2CPServer->Start (); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); ThrowFatal ("Unable to start I2CP at ", i2cpAddr, ":", i2cpPort, ": ", e.what ()); @@ -407,13 +407,13 @@ namespace client template std::string ClientContext::GetI2CPOption (const Section& section, const std::string& name, const Type& value) const { - return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value)); + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value)); } template std::string ClientContext::GetI2CPStringOption (const Section& section, const std::string& name, const std::string& value) const { - return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); } template @@ -423,13 +423,13 @@ namespace client { if (it.first.length () >= group.length () && !it.first.compare (0, group.length (), group)) options[it.first] = it.second.get_value (""); - } + } } - + template void ClientContext::ReadI2CPOptions (const Section& section, std::map& options) const { - options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); + options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH); options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY); options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY); @@ -528,10 +528,10 @@ namespace client { std::string type = section.second.get (I2P_TUNNELS_SECTION_TYPE); if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT - || type == I2P_TUNNELS_SECTION_TYPE_SOCKS - || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS - || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY - || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) + || type == I2P_TUNNELS_SECTION_TYPE_SOCKS + || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS + || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY + || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { // mandatory params std::string dest; @@ -640,9 +640,9 @@ namespace client } } else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER - || type == I2P_TUNNELS_SECTION_TYPE_HTTP - || type == I2P_TUNNELS_SECTION_TYPE_IRC - || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) + || type == I2P_TUNNELS_SECTION_TYPE_HTTP + || type == I2P_TUNNELS_SECTION_TYPE_IRC + || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) { // mandatory params std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); @@ -699,7 +699,7 @@ namespace client continue; } - std::shared_ptr serverTunnel; + std::shared_ptr serverTunnel; if (type == I2P_TUNNELS_SECTION_TYPE_HTTP) serverTunnel = std::make_shared (name, host, port, localDestination, hostOverride, inPort, gzip); else if (type == I2P_TUNNELS_SECTION_TYPE_IRC) @@ -745,7 +745,7 @@ namespace client ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ()); } ins.first->second->isUpdated = true; - LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); + LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); } } @@ -769,9 +769,9 @@ namespace client std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); - i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); + i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort); if (httpProxyKeys.length () > 0) { @@ -786,12 +786,12 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try + try { m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); ThrowFatal ("Unable to start HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort, ": ", e.what ()); @@ -826,13 +826,13 @@ namespace client else LogPrint(eLogError, "Clients: failed to load SOCKS Proxy key"); } - try + try { m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination); m_SocksProxy->Start(); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in SOCKS Proxy: ", e.what()); ThrowFatal ("Unable to start SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort, ": ", e.what ()); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 1a56575f..110f0970 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -75,10 +75,11 @@ namespace client const std::map * params = nullptr); // same as previous but on external io_service std::shared_ptr CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); - std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, - const i2p::data::PrivateKeys& keys, bool isPublic = true, + std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, + const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); // same as previous but on external io_service - std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map * params = nullptr); + std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, + const std::string & name, const std::map * params = nullptr); void DeleteLocalDestination (std::shared_ptr destination); std::shared_ptr FindLocalDestination (const i2p::data::IdentHash& destination) const; bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, @@ -114,7 +115,7 @@ namespace client template void VisitTunnels (Visitor v); // Visitor: (I2PService *) -> bool, true means retain - void CreateNewSharedLocalDestination (); + void CreateNewSharedLocalDestination (); void AddLocalDestination (std::shared_ptr localDestination); private: @@ -141,6 +142,7 @@ namespace client std::unique_ptr m_CleanupUDPTimer; public: + // for HTTP const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; }; const decltype(m_ClientTunnels)& GetClientTunnels () const { return m_ClientTunnels; }; diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index af4d2913..0c915921 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -191,7 +191,7 @@ namespace proxy { res.body = ss.str(); std::string response = res.to_string(); boost::asio::async_write(*m_sock, boost::asio::buffer(response), boost::asio::transfer_all(), - std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); + std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm) @@ -406,7 +406,7 @@ namespace proxy { void HTTPReqHandler::ForwardToUpstreamProxy() { LogPrint(eLogDebug, "HTTPProxy: forward to upstream"); - // build http requset + // build http request m_ClientRequestURL = m_RequestURL; LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host); @@ -458,7 +458,7 @@ namespace proxy { if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port)); m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { - m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); + m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); })); } else @@ -562,14 +562,16 @@ namespace proxy { if(m_ClientRequest.method == "CONNECT") { m_ClientResponse.code = 200; 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) { + 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()); else HandoverToUpstreamProxy(); }); } else { m_send_buf = m_ClientRequestBuffer.str(); 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) { + 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()); else HandoverToUpstreamProxy(); }); diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 590166e3..4504eedd 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -6,6 +6,7 @@ namespace proxy { class HTTPProxy: public i2p::client::TCPIPAcceptor { public: + HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination); HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr localDestination = nullptr) : HTTPProxy(name, address, port, "", true, localDestination) {} ; @@ -15,11 +16,13 @@ namespace proxy { bool GetHelperSupport() { return m_Addresshelper; } protected: + // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); const char* GetName() { return m_Name.c_str (); } private: + std::string m_Name; std::string m_OutproxyUrl; bool m_Addresshelper; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index f4c8a91e..2cea5098 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -24,7 +24,7 @@ namespace client { I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), + RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()) { } @@ -33,26 +33,26 @@ namespace client { if (IsRunning ()) Stop (); - } - + } + void I2CPDestination::Start () { if (!IsRunning ()) - { + { LeaseSetDestination::Start (); StartIOService (); - } + } } - + void I2CPDestination::Stop () { if (IsRunning ()) - { + { LeaseSetDestination::Stop (); StopIOService (); - } - } - + } + } + void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { memcpy (m_EncryptionPrivateKey, key, 256); @@ -98,7 +98,7 @@ namespace client auto ls = (storeType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) ? std::make_shared (m_Identity, buf, len): std::make_shared (storeType, m_Identity, buf, len); - ls->SetExpirationTime (m_LeaseSetExpirationTime); + ls->SetExpirationTime (m_LeaseSetExpirationTime); SetLeaseSet (ls); } @@ -221,7 +221,7 @@ namespace client auto s = shared_from_this (); m_Socket->async_read_some (boost::asio::buffer (m_Header, 1), [s](const boost::system::error_code& ecode, std::size_t bytes_transferred) - { + { if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE) s->ReceiveHeader (); else @@ -247,15 +247,15 @@ namespace client if (m_PayloadLen > 0) { if (m_PayloadLen <= I2CP_MAX_MESSAGE_LENGTH) - { + { m_Payload = new uint8_t[m_PayloadLen]; ReceivePayload (); } else { - LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); + LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); Terminate (); - } + } } else // no following payload { @@ -323,7 +323,7 @@ namespace client memcpy (buf + I2CP_HEADER_SIZE, payload, len); boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + std::placeholders::_1, std::placeholders::_2, buf)); } else LogPrint (eLogError, "I2CP: Can't write to the socket"); @@ -510,8 +510,8 @@ namespace client } else LogPrint(eLogError, "I2CP: short message"); - SendSessionStatusMessage (status); - } + SendSessionStatusMessage (status); + } void I2CPSession::SendSessionStatusMessage (uint8_t status) { @@ -568,12 +568,12 @@ namespace client { LogPrint (eLogError, "I2CP: invalid LeaseSet2 of type ", storeType); return; - } + } offset += ls.GetBufferLen (); // private keys int numPrivateKeys = buf[offset]; offset++; uint16_t currentKeyType = 0; - const uint8_t * currentKey = nullptr; + const uint8_t * currentKey = nullptr; for (int i = 0; i < numPrivateKeys; i++) { if (offset + 4 > len) return; @@ -586,7 +586,7 @@ namespace client currentKey = buf + offset; } offset += keyLen; - } + } // TODO: support multiple keys if (currentKey) { @@ -594,7 +594,7 @@ namespace client m_Destination->SetEncryptionType (currentKeyType); } - m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); + m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); } } else @@ -779,14 +779,14 @@ namespace client memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + std::placeholders::_1, std::placeholders::_2, buf)); } I2CPServer::I2CPServer (const std::string& interface, int port): m_IsRunning (false), m_Thread (nullptr), m_Acceptor (m_Service, #ifdef ANDROID - I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address + I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address #else I2CPSession::proto::endpoint(boost::asio::ip::address::from_string(interface), port)) #endif @@ -823,10 +823,10 @@ namespace client m_IsRunning = false; m_Acceptor.cancel (); { - auto sessions = m_Sessions; + auto sessions = m_Sessions; for (auto& it: sessions) it.second->Stop (); - } + } m_Sessions.clear (); m_Service.stop (); if (m_Thread) @@ -899,4 +899,3 @@ namespace client } } } - diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 7f590555..08dbaa21 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -25,7 +25,7 @@ namespace client const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; - + const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1; @@ -69,10 +69,10 @@ namespace client I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params); ~I2CPDestination (); - + void Start (); void Stop (); - + void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession @@ -82,7 +82,7 @@ namespace client // implements LocalDestination bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const; bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; - // TODO: implement GetEncryptionPublicKey + // TODO: implement GetEncryptionPublicKey std::shared_ptr GetIdentity () const { return m_Identity; }; protected: @@ -220,4 +220,3 @@ namespace client } #endif - diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 31f34710..7a30decd 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -115,22 +115,24 @@ namespace client { if(m_ConnectTimeout && !m_LocalDestination->IsReady()) { - AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) { + AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) + { if(ec) { LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message()); streamRequestComplete(nullptr); } else - { if (address->IsIdentHash ()) + { + if (address->IsIdentHash ()) this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port); else - this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); + this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); } }); } else - { + { if (address->IsIdentHash ()) m_LocalDestination->CreateStream (streamRequestComplete, address->identHash, port); else @@ -180,7 +182,7 @@ namespace client { m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE), std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2)); } else LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket"); @@ -191,7 +193,7 @@ namespace client if (m_down) { m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE), std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2)); } else LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket"); @@ -205,8 +207,8 @@ namespace client boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len), boost::asio::transfer_all(), std::bind(&TCPIPPipe::HandleUpstreamWrite, - shared_from_this(), - std::placeholders::_1)); + shared_from_this(), + std::placeholders::_1)); } else LogPrint(eLogError, "TCPIPPipe: upstream write: no socket"); @@ -220,8 +222,8 @@ namespace client boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len), boost::asio::transfer_all(), std::bind(&TCPIPPipe::HandleDownstreamWrite, - shared_from_this(), - std::placeholders::_1)); + shared_from_this(), + std::placeholders::_1)); } else LogPrint(eLogError, "TCPIPPipe: downstream write: no socket"); diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index e0dfd2da..be935b93 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -18,10 +18,12 @@ namespace client class I2PService : public std::enable_shared_from_this { public: + typedef std::function ReadyCallback; public: - I2PService (std::shared_ptr localDestination = nullptr); + + I2PService (std::shared_ptr localDestination = nullptr); I2PService (i2p::data::SigningKeyType kt); virtual ~I2PService (); @@ -42,7 +44,7 @@ namespace client void AddReadyCallback(ReadyCallback cb); inline std::shared_ptr GetLocalDestination () { return m_LocalDestination; } - inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } + inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } inline void SetLocalDestination (std::shared_ptr dest) { if (m_LocalDestination) m_LocalDestination->Release (); @@ -59,21 +61,24 @@ namespace client virtual const char* GetName() { return "Generic I2P Service"; } private: + void TriggerReadyCheckTimer(); void HandleReadyCheckTimer(const boost::system::error_code & ec); private: + std::shared_ptr m_LocalDestination; std::unordered_set > m_Handlers; std::mutex m_HandlersMutex; std::vector > m_ReadyCallbacks; boost::asio::deadline_timer m_ReadyTimer; - bool m_ReadyTimerTriggered; + bool m_ReadyTimerTriggered; uint32_t m_ConnectTimeout; - const size_t NEVER_TIMES_OUT = 0; - + const size_t NEVER_TIMES_OUT = 0; + public: + bool isUpdated; // transient, used during reload only }; @@ -81,6 +86,7 @@ namespace client class I2PServiceHandler { public: + I2PServiceHandler(I2PService * parent) : m_Service(parent), m_Dead(false) { } virtual ~I2PServiceHandler() { } //If you override this make sure you call it from the children @@ -89,6 +95,7 @@ namespace client void Terminate () { Kill (); }; protected: + // Call when terminating or handing over to avoid race conditions inline bool Kill () { return m_Dead.exchange(true); } // Call to know if the handler is dead @@ -99,6 +106,7 @@ namespace client inline I2PService * GetOwner() { return m_Service; } private: + I2PService *m_Service; std::atomic m_Dead; //To avoid cleaning up multiple times }; @@ -109,11 +117,13 @@ namespace client class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this { public: + TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); ~TCPIPPipe(); void Start(); protected: + void Terminate(); void AsyncReceiveUpstream(); void AsyncReceiveDownstream(); @@ -125,6 +135,7 @@ namespace client void DownstreamWrite(size_t len); private: + uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE]; uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE]; std::shared_ptr m_up, m_down; @@ -135,6 +146,7 @@ namespace client class TCPIPAcceptor: public I2PService { public: + TCPIPAcceptor (const std::string& address, int port, std::shared_ptr localDestination = nullptr) : I2PService(localDestination), m_LocalEndpoint (boost::asio::ip::address::from_string(address), port), @@ -149,14 +161,16 @@ namespace client //If you override this make sure you call it from the children void Stop (); - const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; + const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } protected: + virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; private: + void Accept(); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); boost::asio::ip::tcp::endpoint m_LocalEndpoint; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index dc2a8811..b7a15c26 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -168,7 +168,7 @@ namespace client { m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE), std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2), + std::placeholders::_1, std::placeholders::_2), I2P_TUNNEL_CONNECTION_MAX_IDLE); } else // closed by peer @@ -257,7 +257,7 @@ namespace client if (!m_ConnectionSent && !line.compare(0, 10, "Connection")) { /* close connection, if not Connection: (U|u)pgrade (for websocket) */ - auto x = line.find("pgrade"); + auto x = line.find("pgrade"); if (x != std::string::npos && std::tolower(line[x - 1]) == 'u') m_OutHeader << line << "\r\n"; else @@ -281,7 +281,7 @@ namespace client if (endOfHeader) { if (!m_ConnectionSent) m_OutHeader << "Connection: close\r\n"; - if (!m_ProxyConnectionSent) m_OutHeader << "Proxy-Connection: close\r\n"; + if (!m_ProxyConnectionSent) m_OutHeader << "Proxy-Connection: close\r\n"; m_OutHeader << "\r\n"; // end of header m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header m_InHeader.str (""); @@ -462,7 +462,7 @@ namespace client } /* HACK: maybe we should create a caching IdentHash provider in AddressBook */ - std::shared_ptr I2PClientTunnel::GetAddress () + std::shared_ptr I2PClientTunnel::GetAddress () { if (!m_Address) { @@ -477,7 +477,7 @@ namespace client { auto address = GetAddress (); if (address) - return std::make_shared(this, address, m_DestinationPort, socket); + return std::make_shared(this, address, m_DestinationPort, socket); else return nullptr; } @@ -826,7 +826,7 @@ namespace client { LogPrint(eLogError, "UDP Tunnel: ", m_RemoteDest, " not found"); return; - } + } m_RemoteIdent = new i2p::data::IdentHash; *m_RemoteIdent = addr->identHash; LogPrint(eLogInfo, "UDP Tunnel: resolved ", m_RemoteDest, " to ", m_RemoteIdent->ToBase32()); diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index fbe2f7bb..94f63e48 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -30,6 +30,7 @@ namespace client class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this { public: + I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr leaseSet, int port = 0); // to I2P I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, @@ -41,6 +42,7 @@ namespace client void Connect (bool isUniqueLocal = true); protected: + void Terminate (); void Receive (); @@ -55,6 +57,7 @@ namespace client std::shared_ptr GetSocket () const { return m_Socket; }; private: + uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE]; std::shared_ptr m_Socket; std::shared_ptr m_Stream; @@ -65,15 +68,18 @@ namespace client class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection { public: + I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream): I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false), m_ConnectionSent (false), m_ProxyConnectionSent (false) {}; protected: + void Write (const uint8_t * buf, size_t len); private: + std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent; }; @@ -81,14 +87,17 @@ namespace client class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection { public: + I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host); protected: + void Write (const uint8_t * buf, size_t len); private: + std::string m_Host; std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent; @@ -98,14 +107,17 @@ namespace client class I2PTunnelConnectionIRC: public I2PTunnelConnection { public: + I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass); protected: + void Write (const uint8_t * buf, size_t len); private: + std::shared_ptr m_From; std::stringstream m_OutPacket, m_InPacket; bool m_NeedsWebIrc; @@ -116,10 +128,12 @@ namespace client class I2PClientTunnel: public TCPIPAcceptor { protected: + // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); public: + I2PClientTunnel (const std::string& name, const std::string& destination, const std::string& address, int port, std::shared_ptr localDestination, int destinationPort = 0); ~I2PClientTunnel () {} @@ -130,9 +144,11 @@ namespace client const char* GetName() { return m_Name.c_str (); } private: + std::shared_ptr GetAddress (); private: + std::string m_Name, m_Destination; std::shared_ptr m_Address; int m_DestinationPort; @@ -160,9 +176,9 @@ namespace client uint8_t m_Buffer[I2P_UDP_MAX_MTU]; UDPSession(boost::asio::ip::udp::endpoint localEndpoint, - const std::shared_ptr & localDestination, - boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident, - uint16_t ourPort, uint16_t theirPort); + const std::shared_ptr & localDestination, + boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident, + uint16_t ourPort, uint16_t theirPort); void HandleReceived(const boost::system::error_code & ecode, std::size_t len); void Receive(); }; @@ -195,6 +211,7 @@ namespace client class I2PUDPServerTunnel { public: + I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, boost::asio::ip::address localAddress, @@ -210,10 +227,12 @@ namespace client void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; } private: + void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); private: + bool m_IsUniqueLocal; const std::string m_Name; boost::asio::ip::address m_LocalAddress; @@ -226,6 +245,7 @@ namespace client class I2PUDPClientTunnel { public: + I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, uint16_t remotePort, bool gzip); @@ -240,6 +260,7 @@ namespace client void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT); private: + typedef std::pair UDPConvo; void RecvFromLocal(); void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred); @@ -263,6 +284,7 @@ namespace client class I2PServerTunnel: public I2PService { public: + I2PServerTunnel (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, int inport = 0, bool gzip = true); @@ -282,6 +304,7 @@ namespace client const char* GetName() { return m_Name.c_str (); } private: + void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, std::shared_ptr resolver); @@ -290,6 +313,7 @@ namespace client virtual std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: + bool m_IsUniqueLocal; std::string m_Name, m_Address; int m_Port; @@ -302,28 +326,34 @@ namespace client class I2PServerTunnelHTTP: public I2PServerTunnel { public: + I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, const std::string& host, int inport = 0, bool gzip = true); private: + std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: + std::string m_Host; }; class I2PServerTunnelIRC: public I2PServerTunnel { public: + I2PServerTunnelIRC (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, const std::string& webircpass, int inport = 0, bool gzip = true); private: + std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: + std::string m_WebircPass; }; } diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index 5cec178f..a4c82504 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -14,10 +14,10 @@ namespace client void MatchedTunnelDestination::ResolveCurrentLeaseSet() { - auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName); + auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName); if(addr && addr->IsIdentHash ()) { - m_RemoteIdent = addr->identHash; + m_RemoteIdent = addr->identHash; auto ls = FindLeaseSet(m_RemoteIdent); if(ls) HandleFoundCurrentLeaseSet(ls); @@ -39,7 +39,7 @@ namespace client { m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1)); m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) { - if(!ec) ResolveCurrentLeaseSet(); + if(!ec) ResolveCurrentLeaseSet(); }); } } @@ -50,7 +50,7 @@ namespace client ClientDestination::Start(); m_ResolveTimer = std::make_shared(GetService()); GetTunnelPool()->SetCustomPeerSelector(this); - ResolveCurrentLeaseSet(); + ResolveCurrentLeaseSet(); } void MatchedTunnelDestination::Stop() diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 9d61799a..53cae203 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -8,26 +8,30 @@ namespace i2p namespace client { /** - client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination + * client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination */ class MatchedTunnelDestination : public RunnableClientDestination, public i2p::tunnel::ITunnelPeerSelector { - public: - MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName, const std::map * params = nullptr); - void Start(); - void Stop(); + public: - bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); + MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName, + const std::map * params = nullptr); + void Start(); + void Stop(); - private: - void ResolveCurrentLeaseSet(); - void HandleFoundCurrentLeaseSet(std::shared_ptr ls); + bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound); - private: - std::string m_RemoteName; - i2p::data::IdentHash m_RemoteIdent; - std::shared_ptr m_RemoteLeaseSet; - std::shared_ptr m_ResolveTimer; + private: + + void ResolveCurrentLeaseSet(); + void HandleFoundCurrentLeaseSet(std::shared_ptr ls); + + private: + + std::string m_RemoteName; + i2p::data::IdentHash m_RemoteIdent; + std::shared_ptr m_RemoteLeaseSet; + std::shared_ptr m_ResolveTimer; }; } } diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index d0942221..086cbe69 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -17,7 +17,7 @@ namespace client { SAMSocket::SAMSocket (SAMBridge& owner): m_Owner (owner), m_Socket(owner.GetService()), m_Timer (m_Owner.GetService ()), - m_BufferOffset (0), + m_BufferOffset (0), m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false), m_IsAccepting (false), m_Stream (nullptr) { @@ -26,7 +26,7 @@ namespace client SAMSocket::~SAMSocket () { m_Stream = nullptr; - } + } void SAMSocket::Terminate (const char* reason) { @@ -54,8 +54,7 @@ namespace client } break; } - default: - ; + default: ; } m_SocketType = eSAMSocketTypeTerminated; if (m_Socket.is_open ()) @@ -68,7 +67,7 @@ namespace client } void SAMSocket::ReceiveHandshake () - { + { m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE), std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -152,7 +151,7 @@ namespace client size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); #endif boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (), - std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), + std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } else @@ -170,7 +169,7 @@ namespace client { return id == m_ID; } - + void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -350,7 +349,7 @@ namespace client } std::shared_ptr forward = nullptr; - if ((type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) && + if ((type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) && params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end()) { // udp forward selected @@ -372,7 +371,7 @@ namespace client } forward = std::make_shared(addr, port); } - + //ensure we actually received a destination if (destination.empty()) { @@ -381,7 +380,7 @@ namespace client } if (destination != SAM_VALUE_TRANSIENT) - { + { //ensure it's a base64 string i2p::data::PrivateKeys keys; if (!keys.FromBase64(destination)) @@ -389,7 +388,7 @@ namespace client SendMessageReply(SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), true); return; } - } + } // create destination auto session = m_Owner.CreateSession (id, type, destination == SAM_VALUE_TRANSIENT ? "" : destination, ¶ms); @@ -542,7 +541,7 @@ namespace client m_SocketType = eSAMSocketTypeAcceptor; if (!session->localDestination->IsAcceptingStreams ()) { - m_IsAccepting = true; + m_IsAccepting = true; session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); @@ -567,7 +566,7 @@ namespace client { i2p::data::IdentityEx dest; dest.FromBase64 (params[SAM_PARAM_DESTINATION]); - if (session->Type == eSAMSessionTypeDatagram) + if (session->Type == eSAMSessionTypeDatagram) d->SendDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); else // raw d->SendRawDatagramTo ((const uint8_t *)data, size, dest.GetIdentHash ()); @@ -598,20 +597,20 @@ namespace client if (it != params.end ()) { if (!m_Owner.ResolveSignatureType (it->second, signatureType)) - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); } it = params.find (SAM_PARAM_CRYPTO_TYPE); if (it != params.end ()) { try - { + { cryptoType = std::stoi(it->second); } - catch (const std::exception& ex) + catch (const std::exception& ex) { - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); - } - } + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); + } + } auto keys = i2p::data::PrivateKeys::CreateRandomKeys (signatureType, cryptoType); #ifdef _MSC_VER size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY, @@ -647,12 +646,12 @@ namespace client else dest->RequestDestination (addr->identHash, std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete, - shared_from_this (), std::placeholders::_1, name)); + shared_from_this (), std::placeholders::_1, name)); } else dest->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete, - shared_from_this (), std::placeholders::_1, name)); + shared_from_this (), std::placeholders::_1, name)); } else { @@ -762,7 +761,7 @@ namespace client if (m_Stream) { if (m_Stream->GetStatus () == i2p::stream::eStreamStatusNew || - m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular + m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular { m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE), std::bind (&SAMSocket::HandleI2PReceive, shared_from_this(), @@ -800,7 +799,7 @@ namespace client { delete [] buff; } - + void SAMSocket::WriteI2PData(size_t sz) { boost::asio::async_write ( @@ -809,7 +808,7 @@ namespace client boost::asio::transfer_all(), std::bind(&SAMSocket::HandleWriteI2PData, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - + void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -955,7 +954,7 @@ namespace client auto ep = session->UDPEndpoint; if (ep) // udp forward enabled - m_Owner.SendTo(buf, len, ep); + m_Owner.SendTo(buf, len, ep); else { #ifdef _MSC_VER @@ -978,7 +977,7 @@ 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), @@ -986,7 +985,7 @@ namespace client Name(id), Type (type) { } - + SAMSession::~SAMSession () { i2p::client::context.DeleteLocalDestination (localDestination); @@ -1001,7 +1000,7 @@ namespace client } SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): - RunnableService ("SAM"), m_IsSingleThread (singleThread), + RunnableService ("SAM"), m_IsSingleThread (singleThread), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes @@ -1063,7 +1062,7 @@ namespace client std::unique_lock lock(m_OpenSocketsMutex); m_OpenSockets.remove_if([socket](const std::shared_ptr & item) -> bool { return item == socket; }); } - + void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket) { if (!ecode) @@ -1089,7 +1088,7 @@ namespace client Accept (); } - std::shared_ptr SAMBridge::CreateSession (const std::string& id, SAMSessionType type, + std::shared_ptr SAMBridge::CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, const std::map * params) { std::shared_ptr localDestination = nullptr; @@ -1097,7 +1096,7 @@ namespace client { i2p::data::PrivateKeys keys; if (!keys.FromBase64 (destination)) return nullptr; - localDestination = m_IsSingleThread ? + localDestination = m_IsSingleThread ? i2p::client::context.CreateNewLocalDestination (GetIOService (), keys, true, params) : i2p::client::context.CreateNewLocalDestination (keys, true, params); } @@ -1110,24 +1109,24 @@ namespace client { auto it = params->find (SAM_PARAM_SIGNATURE_TYPE); if (it != params->end ()) - { + { if (!ResolveSignatureType (it->second, signatureType)) - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); - } + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); + } it = params->find (SAM_PARAM_CRYPTO_TYPE); if (it != params->end ()) - { + { try - { + { cryptoType = std::stoi(it->second); } - catch (const std::exception& ex) + catch (const std::exception& ex) { - LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); - } - } + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); + } + } } - localDestination = m_IsSingleThread ? + localDestination = m_IsSingleThread ? i2p::client::context.CreateNewLocalDestination (GetIOService (), true, signatureType, cryptoType, params) : i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); } @@ -1165,11 +1164,11 @@ namespace client { auto timer = std::make_shared(GetService ()); timer->expires_from_now (boost::posix_time::seconds(5)); // postpone destination clean for 5 seconds - timer->async_wait ([timer, session](const boost::system::error_code& ecode) + timer->async_wait ([timer, session](const boost::system::error_code& ecode) { // session's destructor is called here }); - } + } } } @@ -1193,7 +1192,7 @@ namespace client } return list; } - + void SAMBridge::SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote) { if(remote) @@ -1261,7 +1260,7 @@ namespace client bool SAMBridge::ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const { try - { + { type = std::stoi (name); } catch (const std::invalid_argument& ex) @@ -1273,12 +1272,12 @@ namespace client else return false; } - catch (const std::exception& ex) + catch (const std::exception& ex) { - return false; - } - // name has been resolved - return true; + return false; + } + // name has been resolved + return true; } } } diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 5a447c06..51a8bc57 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -87,7 +87,7 @@ namespace client typedef boost::asio::ip::tcp::socket Socket_t; SAMSocket (SAMBridge& owner); - ~SAMSocket (); + ~SAMSocket (); Socket_t& GetSocket () { return m_Socket; }; void ReceiveHandshake (); @@ -97,10 +97,11 @@ namespace client void Terminate (const char* reason); bool IsSession(const std::string & id) const; - - private: + + private: + void TerminateClose() { Terminate(nullptr); } - + void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred); @@ -137,7 +138,7 @@ namespace client void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff); void HandleStreamSend(const boost::system::error_code & ec); - + private: SAMBridge& m_Owner; @@ -186,7 +187,7 @@ namespace client void Stop (); 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 + std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); std::shared_ptr FindSession (const std::string& id) const; @@ -197,8 +198,8 @@ namespace client void SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote); void RemoveSocket(const std::shared_ptr & socket); - - bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const; + + bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const; private: diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index a70ac2b7..272ac178 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -41,6 +41,7 @@ namespace proxy class SOCKSHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this { private: + enum state { GET_SOCKSV, @@ -137,7 +138,7 @@ namespace proxy void HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr); void HandleUpstreamResolved(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::iterator itr); boost::asio::ip::tcp::resolver m_proxy_resolver; uint8_t m_sock_buff[socks_buffer_size]; @@ -165,6 +166,7 @@ namespace proxy const uint16_t m_UpstreamProxyPort; public: + SOCKSHandler(SOCKSServer * parent, std::shared_ptr sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : I2PServiceHandler(parent), m_proxy_resolver(parent->GetService()), @@ -652,8 +654,7 @@ namespace proxy LogPrint(eLogDebug, "SOCKS: async upstream sock read"); if (m_upstreamSock) { m_upstreamSock->async_read_some(boost::asio::buffer(m_upstream_response, SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE), - std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&SOCKSHandler::HandleUpstreamSockRecv, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError, "SOCKS: no upstream socket for read"); SocksRequestFailed(SOCKS5_GEN_FAIL); @@ -773,7 +774,7 @@ namespace proxy SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort, std::shared_ptr localDestination) : - TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name) + TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name) { m_UseUpstreamProxy = false; if (outAddress.length() > 0 && outEnable) diff --git a/libi2pd_client/SOCKS.h b/libi2pd_client/SOCKS.h index 87f08de4..fc43415a 100644 --- a/libi2pd_client/SOCKS.h +++ b/libi2pd_client/SOCKS.h @@ -14,6 +14,7 @@ namespace proxy class SOCKSServer: public i2p::client::TCPIPAcceptor { public: + SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort, std::shared_ptr localDestination = nullptr); ~SOCKSServer() {}; @@ -21,6 +22,7 @@ namespace proxy void SetUpstreamProxy(const std::string & addr, const uint16_t port); protected: + // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); const char* GetName() { return m_Name.c_str (); } From 8bae4975fbd923c55971278f6b389bef155b9258 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 22 May 2020 16:18:41 +0300 Subject: [PATCH 0360/2950] add copyright headers Signed-off-by: R4SAS --- Win32/DaemonWin32.cpp | 8 ++++++++ Win32/Win32App.cpp | 8 ++++++++ Win32/Win32App.h | 8 ++++++++ Win32/Win32NetState.cpp | 8 ++++++++ Win32/Win32NetState.h | 8 ++++++++ Win32/Win32Service.cpp | 8 ++++++++ Win32/Win32Service.h | 8 ++++++++ android/jni/DaemonAndroid.cpp | 8 ++++++++ android/jni/DaemonAndroid.h | 8 ++++++++ android/jni/i2pd_android.cpp | 8 ++++++++ android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 8 ++++++++ daemon/Daemon.cpp | 8 ++++++++ daemon/Daemon.h | 8 ++++++++ daemon/HTTPServer.cpp | 8 ++++++++ daemon/HTTPServer.h | 8 ++++++++ daemon/I2PControl.cpp | 8 ++++++++ daemon/I2PControl.h | 8 ++++++++ daemon/UPnP.cpp | 8 ++++++++ daemon/UPnP.h | 8 ++++++++ daemon/UnixDaemon.cpp | 8 ++++++++ daemon/i2pd.cpp | 8 ++++++++ libi2pd/Base.cpp | 8 ++++++++ libi2pd/Base.h | 8 ++++++++ libi2pd/Blinding.cpp | 8 ++++++++ libi2pd/Blinding.h | 8 ++++++++ libi2pd/BloomFilter.cpp | 8 ++++++++ libi2pd/BloomFilter.h | 8 ++++++++ libi2pd/CPU.cpp | 8 ++++++++ libi2pd/CPU.h | 8 ++++++++ libi2pd/ChaCha20.cpp | 2 +- libi2pd/ChaCha20.h | 2 +- libi2pd/Config.cpp | 2 +- libi2pd/Config.h | 8 ++++++++ libi2pd/Crypto.cpp | 8 ++++++++ libi2pd/Crypto.h | 8 ++++++++ libi2pd/CryptoKey.cpp | 8 ++++++++ libi2pd/CryptoKey.h | 8 ++++++++ libi2pd/CryptoWorker.h | 8 ++++++++ libi2pd/Datagram.cpp | 8 ++++++++ libi2pd/Datagram.h | 8 ++++++++ libi2pd/Destination.cpp | 8 ++++++++ libi2pd/Destination.h | 8 ++++++++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 8 ++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 8 ++++++++ libi2pd/Ed25519.cpp | 8 ++++++++ libi2pd/Ed25519.h | 8 ++++++++ libi2pd/Elligator.cpp | 8 ++++++++ libi2pd/Elligator.h | 8 ++++++++ libi2pd/FS.cpp | 2 +- libi2pd/FS.h | 2 +- libi2pd/Family.cpp | 8 ++++++++ libi2pd/Family.h | 8 ++++++++ libi2pd/Garlic.cpp | 8 ++++++++ libi2pd/Garlic.h | 8 ++++++++ libi2pd/Gost.cpp | 8 ++++++++ libi2pd/Gost.h | 8 ++++++++ libi2pd/Gzip.cpp | 2 +- libi2pd/Gzip.h | 8 ++++++++ libi2pd/HTTP.cpp | 2 +- libi2pd/HTTP.h | 2 +- libi2pd/I2NPProtocol.cpp | 8 ++++++++ libi2pd/I2NPProtocol.h | 8 ++++++++ libi2pd/I2PEndian.cpp | 8 ++++++++ libi2pd/I2PEndian.h | 8 ++++++++ libi2pd/Identity.cpp | 8 ++++++++ libi2pd/Identity.h | 8 ++++++++ libi2pd/LeaseSet.cpp | 8 ++++++++ libi2pd/LeaseSet.h | 8 ++++++++ libi2pd/LittleBigEndian.h | 8 ++++++++ libi2pd/Log.cpp | 2 +- libi2pd/Log.h | 2 +- libi2pd/NTCPSession.cpp | 8 ++++++++ libi2pd/NTCPSession.h | 8 ++++++++ libi2pd/NetDb.cpp | 8 ++++++++ libi2pd/NetDb.hpp | 8 ++++++++ libi2pd/NetDbRequests.cpp | 8 ++++++++ libi2pd/NetDbRequests.h | 8 ++++++++ libi2pd/Profiling.cpp | 8 ++++++++ libi2pd/Profiling.h | 8 ++++++++ libi2pd/Queue.h | 8 ++++++++ libi2pd/Reseed.cpp | 8 ++++++++ libi2pd/Reseed.h | 8 ++++++++ libi2pd/RouterContext.cpp | 8 ++++++++ libi2pd/RouterContext.h | 8 ++++++++ libi2pd/RouterInfo.cpp | 8 ++++++++ libi2pd/RouterInfo.h | 8 ++++++++ libi2pd/SSU.cpp | 8 ++++++++ libi2pd/SSU.h | 8 ++++++++ libi2pd/SSUData.cpp | 8 ++++++++ libi2pd/SSUData.h | 8 ++++++++ libi2pd/SSUSession.cpp | 8 ++++++++ libi2pd/SSUSession.h | 8 ++++++++ libi2pd/Signature.cpp | 8 ++++++++ libi2pd/Signature.h | 8 ++++++++ libi2pd/Streaming.cpp | 8 ++++++++ libi2pd/Streaming.h | 8 ++++++++ libi2pd/Tag.h | 8 ++++++++ libi2pd/Timestamp.cpp | 8 ++++++++ libi2pd/Timestamp.h | 8 ++++++++ libi2pd/TransitTunnel.cpp | 8 ++++++++ libi2pd/TransitTunnel.h | 8 ++++++++ libi2pd/TransportSession.h | 8 ++++++++ libi2pd/Transports.cpp | 8 ++++++++ libi2pd/Transports.h | 8 ++++++++ libi2pd/Tunnel.cpp | 8 ++++++++ libi2pd/Tunnel.h | 8 ++++++++ libi2pd/TunnelBase.h | 8 ++++++++ libi2pd/TunnelConfig.h | 8 ++++++++ libi2pd/TunnelEndpoint.cpp | 8 ++++++++ libi2pd/TunnelEndpoint.h | 8 ++++++++ libi2pd/TunnelGateway.cpp | 8 ++++++++ libi2pd/TunnelGateway.h | 8 ++++++++ libi2pd/TunnelPool.cpp | 8 ++++++++ libi2pd/TunnelPool.h | 8 ++++++++ libi2pd/api.cpp | 8 ++++++++ libi2pd/api.h | 8 ++++++++ libi2pd/util.cpp | 8 ++++++++ libi2pd/util.h | 8 ++++++++ libi2pd/version.h | 8 ++++++++ libi2pd_client/AddressBook.cpp | 8 ++++++++ libi2pd_client/AddressBook.h | 8 ++++++++ libi2pd_client/BOB.cpp | 8 ++++++++ libi2pd_client/BOB.h | 8 ++++++++ libi2pd_client/ClientContext.cpp | 8 ++++++++ libi2pd_client/ClientContext.h | 8 ++++++++ libi2pd_client/HTTPProxy.cpp | 2 +- libi2pd_client/HTTPProxy.h | 8 ++++++++ libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 2 +- libi2pd_client/I2PService.cpp | 8 ++++++++ libi2pd_client/I2PService.h | 8 ++++++++ libi2pd_client/I2PTunnel.cpp | 8 ++++++++ libi2pd_client/I2PTunnel.h | 8 ++++++++ libi2pd_client/MatchedDestination.cpp | 8 ++++++++ libi2pd_client/MatchedDestination.h | 8 ++++++++ libi2pd_client/SAM.cpp | 8 ++++++++ libi2pd_client/SAM.h | 8 ++++++++ libi2pd_client/SOCKS.cpp | 8 ++++++++ libi2pd_client/SOCKS.h | 8 ++++++++ 139 files changed, 1021 insertions(+), 13 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 7ba3ffc3..1214ff68 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Config.h" diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 3bcb24b3..df345b11 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/Win32/Win32App.h b/Win32/Win32App.h index 23082842..d242f7d3 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -1,3 +1,11 @@ +/* +* 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 WIN32APP_H__ #define WIN32APP_H__ diff --git a/Win32/Win32NetState.cpp b/Win32/Win32NetState.cpp index 9a650179..dd4dd08c 100644 --- a/Win32/Win32NetState.cpp +++ b/Win32/Win32NetState.cpp @@ -1,3 +1,11 @@ +/* +* 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 +*/ + #if WINVER != 0x0501 // supported since Vista #include "Win32NetState.h" #include diff --git a/Win32/Win32NetState.h b/Win32/Win32NetState.h index f043b171..bcb6c8d7 100644 --- a/Win32/Win32NetState.h +++ b/Win32/Win32NetState.h @@ -1,3 +1,11 @@ +/* +* 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 WIN_32_NETSTATE_H__ #define WIN_32_NETSTATE_H__ diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index 9d1dedb4..7a6d7abf 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -1,3 +1,11 @@ +/* +* 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 +*/ + #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS // to use freopen #endif diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h index 05a6b9f9..40fff787 100644 --- a/Win32/Win32Service.h +++ b/Win32/Win32Service.h @@ -1,3 +1,11 @@ +/* +* 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 WIN_32_SERVICE_H__ #define WIN_32_SERVICE_H__ diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index c3a1b805..39c06ea0 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h index 64bf64fd..912f6f49 100644 --- a/android/jni/DaemonAndroid.h +++ b/android/jni/DaemonAndroid.h @@ -1,3 +1,11 @@ +/* +* 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 DAEMON_ANDROID_H #define DAEMON_ANDROID_H diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index 177bfd7c..c6e309dd 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "org_purplei2p_i2pd_I2PD_JNI.h" #include "DaemonAndroid.h" diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index d5c2f15f..68935ad1 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -1,3 +1,11 @@ +/* +* 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 +*/ + /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class org_purplei2p_i2pd_I2PD_JNI */ diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index dd302fce..264013cf 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include diff --git a/daemon/Daemon.h b/daemon/Daemon.h index 050cc7e8..836c2a8e 100644 --- a/daemon/Daemon.h +++ b/daemon/Daemon.h @@ -1,3 +1,11 @@ +/* +* 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 DAEMON_H__ #define DAEMON_H__ diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 6f903e7e..7268ae01 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index fe62c271..a977e3e8 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -1,3 +1,11 @@ +/* +* 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 HTTP_SERVER_H__ #define HTTP_SERVER_H__ diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index fb00dc29..77614f2f 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/daemon/I2PControl.h b/daemon/I2PControl.h index eb28af76..d731c24e 100644 --- a/daemon/I2PControl.h +++ b/daemon/I2PControl.h @@ -1,3 +1,11 @@ +/* +* 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 I2P_CONTROL_H__ #define I2P_CONTROL_H__ diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 92e79c11..852122f2 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -1,3 +1,11 @@ +/* +* 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 +*/ + #ifdef USE_UPNP #include #include diff --git a/daemon/UPnP.h b/daemon/UPnP.h index 29f9e3e6..e8220e24 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -1,3 +1,11 @@ +/* +* 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 __UPNP_H__ #define __UPNP_H__ diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index a59fc693..ffc5f1c0 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -1,3 +1,11 @@ +/* +* 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 "Daemon.h" #ifndef _WIN32 diff --git a/daemon/i2pd.cpp b/daemon/i2pd.cpp index 7b68c073..028aa916 100644 --- a/daemon/i2pd.cpp +++ b/daemon/i2pd.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Daemon.h" diff --git a/libi2pd/Base.cpp b/libi2pd/Base.cpp index 51f5f225..921c20af 100644 --- a/libi2pd/Base.cpp +++ b/libi2pd/Base.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include diff --git a/libi2pd/Base.h b/libi2pd/Base.h index 5d550092..073d9b40 100644 --- a/libi2pd/Base.h +++ b/libi2pd/Base.h @@ -1,3 +1,11 @@ +/* +* 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 BASE_H__ #define BASE_H__ diff --git a/libi2pd/Blinding.cpp b/libi2pd/Blinding.cpp index 287d3648..6770d223 100644 --- a/libi2pd/Blinding.cpp +++ b/libi2pd/Blinding.cpp @@ -1,3 +1,11 @@ +/* +* 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 // for crc32 #include #include diff --git a/libi2pd/Blinding.h b/libi2pd/Blinding.h index 3e0ad3fc..2f670882 100644 --- a/libi2pd/Blinding.h +++ b/libi2pd/Blinding.h @@ -1,3 +1,11 @@ +/* +* 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 BLINDING_H__ #define BLINDING_H__ diff --git a/libi2pd/BloomFilter.cpp b/libi2pd/BloomFilter.cpp index b92039df..de077e60 100644 --- a/libi2pd/BloomFilter.cpp +++ b/libi2pd/BloomFilter.cpp @@ -1,3 +1,11 @@ +/* +* 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 "BloomFilter.h" #include "I2PEndian.h" #include diff --git a/libi2pd/BloomFilter.h b/libi2pd/BloomFilter.h index 2745fbf5..ade854e4 100644 --- a/libi2pd/BloomFilter.h +++ b/libi2pd/BloomFilter.h @@ -1,3 +1,11 @@ +/* +* 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 BLOOM_FILTER_H_ #define BLOOM_FILTER_H_ #include diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index a707c3dc..e7eff473 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -1,3 +1,11 @@ +/* +* 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 "CPU.h" #if defined(__x86_64__) || defined(__i386__) #include diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index e1fd450c..9677b293 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -1,3 +1,11 @@ +/* +* 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 LIBI2PD_CPU_H #define LIBI2PD_CPU_H diff --git a/libi2pd/ChaCha20.cpp b/libi2pd/ChaCha20.cpp index 1d1e9bc6..66bc135f 100644 --- a/libi2pd/ChaCha20.cpp +++ b/libi2pd/ChaCha20.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2018, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/ChaCha20.h b/libi2pd/ChaCha20.h index a8bb1d56..4364024b 100644 --- a/libi2pd/ChaCha20.h +++ b/libi2pd/ChaCha20.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2018, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 59b51c00..19d72104 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2017, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Config.h b/libi2pd/Config.h index 679795b1..dac5fc80 100644 --- a/libi2pd/Config.h +++ b/libi2pd/Config.h @@ -1,3 +1,11 @@ +/* +* 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 CONFIG_H #define CONFIG_H diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index d4d3519e..6db124c0 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 2dfd6d0e..56c8c10b 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -1,3 +1,11 @@ +/* +* 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 CRYPTO_H__ #define CRYPTO_H__ diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 2abcb111..d786e193 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Log.h" #include "Gost.h" diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 43bd3aaa..1c8b0a71 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -1,3 +1,11 @@ +/* +* 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 CRYPTO_KEY_H__ #define CRYPTO_KEY_H__ diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h index baeb7f14..27b012e7 100644 --- a/libi2pd/CryptoWorker.h +++ b/libi2pd/CryptoWorker.h @@ -1,3 +1,11 @@ +/* +* 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 CRYPTO_WORKER_H_ #define CRYPTO_WORKER_H_ diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 2da73649..85b435d1 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Crypto.h" #include "Log.h" diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 72e7340c..e81f738a 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -1,3 +1,11 @@ +/* +* 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 DATAGRAM_H__ #define DATAGRAM_H__ diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 921e55f0..cd447773 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index dbdc3704..139423c6 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -1,3 +1,11 @@ +/* +* 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 DESTINATION_H__ #define DESTINATION_H__ diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index f3b1a685..61e67339 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Log.h" diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index d5a83f89..dd958060 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -1,3 +1,11 @@ +/* +* 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 ECIES_X25519_AEAD_RATCHET_SESSION_H__ #define ECIES_X25519_AEAD_RATCHET_SESSION_H__ diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index 8de5e3a1..791bd685 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Log.h" #include "Crypto.h" diff --git a/libi2pd/Ed25519.h b/libi2pd/Ed25519.h index 10061ad0..28d4e930 100644 --- a/libi2pd/Ed25519.h +++ b/libi2pd/Ed25519.h @@ -1,3 +1,11 @@ +/* +* 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 ED25519_H__ #define ED25519_H__ diff --git a/libi2pd/Elligator.cpp b/libi2pd/Elligator.cpp index 8fefb2ae..712e514a 100644 --- a/libi2pd/Elligator.cpp +++ b/libi2pd/Elligator.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Crypto.h" #include "Elligator.h" diff --git a/libi2pd/Elligator.h b/libi2pd/Elligator.h index 56fbc2eb..eacb03cd 100644 --- a/libi2pd/Elligator.h +++ b/libi2pd/Elligator.h @@ -1,3 +1,11 @@ +/* +* 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 ELLIGATOR_H__ #define ELLIGATOR_H__ diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index f8b3ed7e..32fc3ec0 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/FS.h b/libi2pd/FS.h index 054ac2a3..698e9b6b 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp index e5ac9990..fbb7b9ee 100644 --- a/libi2pd/Family.cpp +++ b/libi2pd/Family.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Family.h b/libi2pd/Family.h index a1b5a789..2a9149ba 100644 --- a/libi2pd/Family.h +++ b/libi2pd/Family.h @@ -1,3 +1,11 @@ +/* +* 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 FAMILY_H__ #define FAMILY_H__ diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 5d07155e..7e717829 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "I2PEndian.h" #include diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 55ebe795..6b34231a 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -1,3 +1,11 @@ +/* +* 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 GARLIC_H__ #define GARLIC_H__ diff --git a/libi2pd/Gost.cpp b/libi2pd/Gost.cpp index c401f8be..5e84a95d 100644 --- a/libi2pd/Gost.cpp +++ b/libi2pd/Gost.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Gost.h b/libi2pd/Gost.h index a4cc9741..0a79c30b 100644 --- a/libi2pd/Gost.h +++ b/libi2pd/Gost.h @@ -1,3 +1,11 @@ +/* +* 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 GOST_H__ #define GOST_H__ diff --git a/libi2pd/Gzip.cpp b/libi2pd/Gzip.cpp index 5709719b..07c6a96e 100644 --- a/libi2pd/Gzip.cpp +++ b/libi2pd/Gzip.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2017, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Gzip.h b/libi2pd/Gzip.h index 6489b79b..d0bb28ed 100644 --- a/libi2pd/Gzip.h +++ b/libi2pd/Gzip.h @@ -1,3 +1,11 @@ +/* +* 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 GZIP_H__ #define GZIP_H__ diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 64acb6ea..4f7b03a1 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index f156fef0..c0cf1285 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 170bb864..a03ad7ed 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Base.h" diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 4ecba2eb..695de798 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -1,3 +1,11 @@ +/* +* 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 I2NP_PROTOCOL_H__ #define I2NP_PROTOCOL_H__ diff --git a/libi2pd/I2PEndian.cpp b/libi2pd/I2PEndian.cpp index b8a041d8..32ca4e26 100644 --- a/libi2pd/I2PEndian.cpp +++ b/libi2pd/I2PEndian.cpp @@ -1,3 +1,11 @@ +/* +* 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 "I2PEndian.h" // http://habrahabr.ru/post/121811/ diff --git a/libi2pd/I2PEndian.h b/libi2pd/I2PEndian.h index 04a9480e..9ffc28d0 100644 --- a/libi2pd/I2PEndian.h +++ b/libi2pd/I2PEndian.h @@ -1,3 +1,11 @@ +/* +* 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 I2PENDIAN_H__ #define I2PENDIAN_H__ #include diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 77a1f7e2..b2b5f2b4 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -1,3 +1,11 @@ +/* +* 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 "Crypto.h" #include "I2PEndian.h" #include "Log.h" diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 08baba01..534b8f4c 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -1,3 +1,11 @@ +/* +* 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 IDENTITY_H__ #define IDENTITY_H__ diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 1aa7fa6d..6b8b7545 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "I2PEndian.h" #include "Crypto.h" diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h index 479594e1..cd31bf30 100644 --- a/libi2pd/LeaseSet.h +++ b/libi2pd/LeaseSet.h @@ -1,3 +1,11 @@ +/* +* 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 LEASE_SET_H__ #define LEASE_SET_H__ diff --git a/libi2pd/LittleBigEndian.h b/libi2pd/LittleBigEndian.h index 55039fb6..8c081187 100644 --- a/libi2pd/LittleBigEndian.h +++ b/libi2pd/LittleBigEndian.h @@ -1,3 +1,11 @@ +/* +* 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 +*/ + // LittleBigEndian.h fixed for 64-bits added union // diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 6f2eb5bd..a0014841 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/Log.h b/libi2pd/Log.h index fbd122a8..972a00e1 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2016, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index 56c69e05..4d3f1da6 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/NTCPSession.h b/libi2pd/NTCPSession.h index e2207eb7..d3aa6f7c 100644 --- a/libi2pd/NTCPSession.h +++ b/libi2pd/NTCPSession.h @@ -1,3 +1,11 @@ +/* +* 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 NTCP_SESSION_H__ #define NTCP_SESSION_H__ diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 30916f1a..466016c5 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 47a6fab5..1c65969a 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -1,3 +1,11 @@ +/* +* 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 NETDB_H__ #define NETDB_H__ // this file is called NetDb.hpp to resolve conflict with libc's netdb.h on case insensitive fs diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index b1eb9380..e7aab34c 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -1,3 +1,11 @@ +/* +* 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 "Log.h" #include "I2NPProtocol.h" #include "Transports.h" diff --git a/libi2pd/NetDbRequests.h b/libi2pd/NetDbRequests.h index c5e077bf..16ea430d 100644 --- a/libi2pd/NetDbRequests.h +++ b/libi2pd/NetDbRequests.h @@ -1,3 +1,11 @@ +/* +* 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 NETDB_REQUESTS_H__ #define NETDB_REQUESTS_H__ diff --git a/libi2pd/Profiling.cpp b/libi2pd/Profiling.cpp index 3840eb32..850774d9 100644 --- a/libi2pd/Profiling.cpp +++ b/libi2pd/Profiling.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Profiling.h b/libi2pd/Profiling.h index 4ba6702f..dab50e6b 100644 --- a/libi2pd/Profiling.h +++ b/libi2pd/Profiling.h @@ -1,3 +1,11 @@ +/* +* 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 PROFILING_H__ #define PROFILING_H__ diff --git a/libi2pd/Queue.h b/libi2pd/Queue.h index 0438cc37..d43567a5 100644 --- a/libi2pd/Queue.h +++ b/libi2pd/Queue.h @@ -1,3 +1,11 @@ +/* +* 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 QUEUE_H__ #define QUEUE_H__ diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 4f26e520..2812f413 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Reseed.h b/libi2pd/Reseed.h index 5f402988..345b45bf 100644 --- a/libi2pd/Reseed.h +++ b/libi2pd/Reseed.h @@ -1,3 +1,11 @@ +/* +* 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 RESEED_H #define RESEED_H diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index b855fc29..cbbd961e 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Config.h" diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 6382189b..6f08a87a 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -1,3 +1,11 @@ +/* +* 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 ROUTER_CONTEXT_H__ #define ROUTER_CONTEXT_H__ diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index bf81a8af..91c12b60 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "I2PEndian.h" diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 5bdb0f8f..ef902c0e 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -1,3 +1,11 @@ +/* +* 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 ROUTER_INFO_H__ #define ROUTER_INFO_H__ diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 4a33ff3a..c435715f 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Log.h" diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 942d0e64..6a79f754 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -1,3 +1,11 @@ +/* +* 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 SSU_H__ #define SSU_H__ diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 4eb90522..5068f006 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Log.h" diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 98d60c41..f4a5ba4f 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -1,3 +1,11 @@ +/* +* 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 SSU_DATA_H__ #define SSU_DATA_H__ diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index e29af479..73699d6a 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "version.h" #include "Crypto.h" diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 4f73158a..066e01eb 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -1,3 +1,11 @@ +/* +* 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 SSU_SESSION_H__ #define SSU_SESSION_H__ diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 64aff5bc..88ee4060 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Log.h" #include "Signature.h" diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 26184639..18084603 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -1,3 +1,11 @@ +/* +* 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 SIGNATURE_H__ #define SIGNATURE_H__ diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ac527cb4..ff8915c0 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -1,3 +1,11 @@ +/* +* 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 "Crypto.h" #include "Log.h" #include "RouterInfo.h" diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index d3d47794..a56b0565 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -1,3 +1,11 @@ +/* +* 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 STREAMING_H__ #define STREAMING_H__ diff --git a/libi2pd/Tag.h b/libi2pd/Tag.h index eefab6de..3856abd9 100644 --- a/libi2pd/Tag.h +++ b/libi2pd/Tag.h @@ -1,3 +1,11 @@ +/* +* 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 TAG_H__ #define TAG_H__ diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 9e435e21..4362a878 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index 7d183cd3..91175a49 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -1,3 +1,11 @@ +/* +* 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 TIMESTAMP_H__ #define TIMESTAMP_H__ diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index 02aac23f..73ca977c 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "I2PEndian.h" #include "Log.h" diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index 5b891dc3..e71ec750 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -1,3 +1,11 @@ +/* +* 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 TRANSIT_TUNNEL_H__ #define TRANSIT_TUNNEL_H__ diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index 69b772cb..a97f246f 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -1,3 +1,11 @@ +/* +* 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 TRANSPORT_SESSION_H__ #define TRANSPORT_SESSION_H__ diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 15820584..2f5e92f5 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1,3 +1,11 @@ +/* +* 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 "Log.h" #include "Crypto.h" #include "RouterContext.h" diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 37cfa269..cdfbfccf 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -1,3 +1,11 @@ +/* +* 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 TRANSPORTS_H__ #define TRANSPORTS_H__ diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 879ee2d3..fe7e36af 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "I2PEndian.h" #include diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index f97bcc63..1fb12af9 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -1,3 +1,11 @@ +/* +* 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 TUNNEL_H__ #define TUNNEL_H__ diff --git a/libi2pd/TunnelBase.h b/libi2pd/TunnelBase.h index 53782ae3..f98066d3 100644 --- a/libi2pd/TunnelBase.h +++ b/libi2pd/TunnelBase.h @@ -1,3 +1,11 @@ +/* +* 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 TUNNEL_BASE_H__ #define TUNNEL_BASE_H__ diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 48e66f2e..0bd8a842 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -1,3 +1,11 @@ +/* +* 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 TUNNEL_CONFIG_H__ #define TUNNEL_CONFIG_H__ diff --git a/libi2pd/TunnelEndpoint.cpp b/libi2pd/TunnelEndpoint.cpp index 6e453d91..eb70bdca 100644 --- a/libi2pd/TunnelEndpoint.cpp +++ b/libi2pd/TunnelEndpoint.cpp @@ -1,3 +1,11 @@ +/* +* 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 "I2PEndian.h" #include #include "Crypto.h" diff --git a/libi2pd/TunnelEndpoint.h b/libi2pd/TunnelEndpoint.h index c2ffe53d..43b836f1 100644 --- a/libi2pd/TunnelEndpoint.h +++ b/libi2pd/TunnelEndpoint.h @@ -1,3 +1,11 @@ +/* +* 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 TUNNEL_ENDPOINT_H__ #define TUNNEL_ENDPOINT_H__ diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 3f4069e1..8f01bc4e 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Crypto.h" #include "I2PEndian.h" diff --git a/libi2pd/TunnelGateway.h b/libi2pd/TunnelGateway.h index 7959b57b..01101a36 100644 --- a/libi2pd/TunnelGateway.h +++ b/libi2pd/TunnelGateway.h @@ -1,3 +1,11 @@ +/* +* 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 TUNNEL_GATEWAY_H__ #define TUNNEL_GATEWAY_H__ diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 54459960..d0fd401f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "I2PEndian.h" diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 149a5efa..04ff4ae7 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -1,3 +1,11 @@ +/* +* 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 TUNNEL_POOL__ #define TUNNEL_POOL__ diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index 3bac4878..569fbd8c 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include "Config.h" diff --git a/libi2pd/api.h b/libi2pd/api.h index 444667f0..9b0256d8 100644 --- a/libi2pd/api.h +++ b/libi2pd/api.h @@ -1,3 +1,11 @@ +/* +* 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 API_H__ #define API_H__ diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 37898167..f5204a50 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd/util.h b/libi2pd/util.h index aa83ed7b..cb8fd8f1 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -1,3 +1,11 @@ +/* +* 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 UTIL_H #define UTIL_H diff --git a/libi2pd/version.h b/libi2pd/version.h index fa8f9a0f..d862f46e 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -1,3 +1,11 @@ +/* +* 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 _VERSION_H_ #define _VERSION_H_ diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 8e14c526..8b8e781d 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h index fb69dad3..04600792 100644 --- a/libi2pd_client/AddressBook.h +++ b/libi2pd_client/AddressBook.h @@ -1,3 +1,11 @@ +/* +* 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 ADDRESS_BOOK_H__ #define ADDRESS_BOOK_H__ diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index e5d5404b..c4447808 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Log.h" #include "ClientContext.h" diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index a3d58148..74418011 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -1,3 +1,11 @@ +/* +* 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 BOB_H__ #define BOB_H__ diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 03c756a1..6a58d63c 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 110f0970..8a4835c8 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -1,3 +1,11 @@ +/* +* 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 CLIENT_CONTEXT_H__ #define CLIENT_CONTEXT_H__ diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 0c915921..64080752 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 4504eedd..69ed4cef 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -1,3 +1,11 @@ +/* +* 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 HTTP_PROXY_H__ #define HTTP_PROXY_H__ diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 2cea5098..fef5d6b6 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 08dbaa21..f4e83f06 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2019, The PurpleI2P Project +* Copyright (c) 2013-2020, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 7a30decd..83838106 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -1,3 +1,11 @@ +/* +* 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 "Destination.h" #include "Identity.h" #include "ClientContext.h" diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index be935b93..e14f85c1 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -1,3 +1,11 @@ +/* +* 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 I2PSERVICE_H__ #define I2PSERVICE_H__ diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index b7a15c26..5b384bff 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include "Base.h" #include "Log.h" diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 94f63e48..d4db80d8 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -1,3 +1,11 @@ +/* +* 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 I2PTUNNEL_H__ #define I2PTUNNEL_H__ diff --git a/libi2pd_client/MatchedDestination.cpp b/libi2pd_client/MatchedDestination.cpp index a4c82504..4ffa7442 100644 --- a/libi2pd_client/MatchedDestination.cpp +++ b/libi2pd_client/MatchedDestination.cpp @@ -1,3 +1,11 @@ +/* +* 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 "MatchedDestination.h" #include "Log.h" #include "ClientContext.h" diff --git a/libi2pd_client/MatchedDestination.h b/libi2pd_client/MatchedDestination.h index 53cae203..30ad8942 100644 --- a/libi2pd_client/MatchedDestination.h +++ b/libi2pd_client/MatchedDestination.h @@ -1,3 +1,11 @@ +/* +* 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 MATCHED_DESTINATION_H_ #define MATCHED_DESTINATION_H_ #include "Destination.h" diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 086cbe69..2c6b711d 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #ifdef _MSC_VER diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 51a8bc57..ceda5253 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -1,3 +1,11 @@ +/* +* 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 SAM_H__ #define SAM_H__ diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 272ac178..52d7799b 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include #include diff --git a/libi2pd_client/SOCKS.h b/libi2pd_client/SOCKS.h index fc43415a..f41cfd72 100644 --- a/libi2pd_client/SOCKS.h +++ b/libi2pd_client/SOCKS.h @@ -1,3 +1,11 @@ +/* +* 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 SOCKS_H__ #define SOCKS_H__ From ead89c767ac6641c55ed70d1488ec8ee3461dea6 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 22 May 2020 18:32:44 -0400 Subject: [PATCH 0361/2950] compress longer RouterInfo --- libi2pd/I2NPProtocol.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index a03ad7ed..53afbca4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -257,7 +257,14 @@ namespace i2p uint8_t * sizePtr = buf; buf += 2; m->len += (buf - payload); // payload size - size_t size = i2p::data::GzipNoCompression (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + size_t size = 0; + if (router->GetBufferLen () + (buf - payload) <= 940) // fits one tunnel message + size = i2p::data::GzipNoCompression (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + else + { + i2p::data::GzipDeflator deflator; + size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len); + } if (size) { htobe16buf (sizePtr, size); // size From 86e8614934d0111756cc521cbaf06832b38e48fe Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 May 2020 10:20:22 -0400 Subject: [PATCH 0362/2950] allow session restart after 2 minutes from creation --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 4 +++- libi2pd/ECIESX25519AEADRatchetSession.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 61e67339..2f43b554 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -467,7 +467,8 @@ namespace garlic return false; } m_State = eSessionStateNewSessionReplySent; - + m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); + return true; } @@ -559,6 +560,7 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { m_State = eSessionStateEstablished; + m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } memcpy (m_H, h, 32); // restore m_H diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index dd958060..27ab9c71 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -131,7 +131,7 @@ namespace garlic } bool CheckExpired (uint64_t ts); // true is expired - bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } + bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; } bool IsRatchets () const { return true; }; @@ -168,7 +168,7 @@ namespace garlic uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; - uint64_t m_LastActivityTimestamp = 0; // incoming + uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming std::shared_ptr m_SendTagset, m_NSRTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) From 45aa78d953dc0a42e8f63e52914dd6953862a86a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 23 May 2020 20:40:27 +0300 Subject: [PATCH 0363/2950] revert 7133a07 - it broke usage in some SOCKS implementations Signed-off-by: R4SAS --- libi2pd_client/SOCKS.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 52d7799b..6edd5677 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -256,9 +256,6 @@ namespace proxy size += (1 + addr.dns.size); /* name length + domain name */ m_response[4] = addr.dns.size; memcpy(m_response + 5, addr.dns.value, addr.dns.size); - // replace type to IPv4 for support socks5 clients - // without domain name resolving support (like netcat) - m_response[3] = ADDR_IPV4; break; } htobe16buf(m_response + size - 2, port); //Port From 5a32082624a2956be3ef36c1ef58ea96513e585b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 May 2020 15:58:11 -0400 Subject: [PATCH 0364/2950] recreate session after 90 seconds incativity --- libi2pd/Datagram.cpp | 3 ++- libi2pd/ECIESX25519AEADRatchetSession.h | 6 ++++-- libi2pd/Garlic.cpp | 10 ++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 85b435d1..04792bc5 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -256,7 +256,8 @@ namespace datagram std::shared_ptr DatagramSession::GetSharedRoutingPath () { - if(!m_RoutingSession) { + if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) + { if(!m_RemoteLeaseSet) { m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 27ab9c71..108788d5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -25,8 +25,9 @@ namespace i2p { namespace garlic { - const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second of inactivity we should restart after + const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second since session creation we can restart session after const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_INACTIVITY_TIMEOUT = 90; // number of second we receive nothing and should restart if we can const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 4096; // number of tags we request new tagset after @@ -132,7 +133,8 @@ namespace garlic bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_SessionCreatedTimestamp + ECIESX25519_RESTART_TIMEOUT; } - + bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); } + bool IsRatchets () const { return true; }; private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 7e717829..1170634d 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -719,7 +719,14 @@ namespace garlic destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) + { session = it->second; + if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ())) + { + LogPrint (eLogDebug, "Garlic: session restarted"); + session = nullptr; + } + } if (!session) { session = std::make_shared (this, true); @@ -1011,7 +1018,10 @@ namespace garlic if (it != m_ECIESx25519Sessions.end ()) { if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ())) + { + it->second->SetOwner (nullptr); // detach m_ECIESx25519Sessions.erase (it); + } else { LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists"); From 71564f0d10132c49f29e29b17a98cd83728465f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 May 2020 10:30:00 -0400 Subject: [PATCH 0365/2950] set default i2cp.leaseSetEncType=0,4 for http and socks proxy for android --- android/assets/i2pd.conf | 2 ++ libi2pd/Config.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/android/assets/i2pd.conf b/android/assets/i2pd.conf index 312a24ea..14254248 100644 --- a/android/assets/i2pd.conf +++ b/android/assets/i2pd.conf @@ -42,6 +42,8 @@ inbound.quantity = 5 outbound.length = 1 outbound.quantity = 5 signaturetype=7 +i2cp.leaseSetType=3 +i2cp.leaseSetEncType=0,4 keys = proxy-keys.dat # addresshelper = true # outproxy = http://false.i2p diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 19d72104..0358d3e9 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -107,6 +107,8 @@ namespace config { ("httpproxy.latency.max", value()->default_value("0"), "HTTP proxy max latency for tunnels") ("httpproxy.outproxy", value()->default_value(""), "HTTP proxy upstream out proxy url") ("httpproxy.addresshelper", value()->default_value(true), "Enable or disable addresshelper") + ("httpproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type") + ("httpproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type") ; options_description socksproxy("SOCKS Proxy options"); @@ -126,6 +128,8 @@ namespace config { ("socksproxy.outproxy.enabled", value()->default_value(false), "Enable or disable SOCKS outproxy") ("socksproxy.outproxy", value()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy") ("socksproxy.outproxyport", value()->default_value(9050), "Upstream outproxy port for SOCKS Proxy") + ("socksproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type") + ("socksproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type") ; options_description sam("SAM bridge options"); From 1975adc48f8ddd6ce618ea1150078c6f0e0ea385 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 May 2020 14:14:16 -0400 Subject: [PATCH 0366/2950] print remote peer for queues --- libi2pd/NTCP2.cpp | 3 ++- libi2pd/Transports.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index eec3a5a5..8b44a795 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1135,7 +1135,8 @@ namespace transport SendQueue (); else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) { - LogPrint (eLogWarning, "NTCP2: outgoing messages queue size exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); + LogPrint (eLogWarning, "NTCP2: outgoing messages queue size to ", + GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); Terminate (); } } diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 2f5e92f5..7157306d 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -389,7 +389,7 @@ namespace transport m_LoopbackHandler.Flush (); return; } - if(RoutesRestricted() && ! IsRestrictedPeer(ident)) return; + if(RoutesRestricted() && !IsRestrictedPeer(ident)) return; auto it = m_Peers.find (ident); if (it == m_Peers.end ()) { @@ -421,7 +421,8 @@ namespace transport } else { - LogPrint (eLogWarning, "Transports: delayed messages queue size exceeds ", MAX_NUM_DELAYED_MESSAGES); + LogPrint (eLogWarning, "Transports: delayed messages queue size to ", + ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES); std::unique_lock l(m_PeersMutex); m_Peers.erase (it); } From 50c8a84037d762551e200921f41e46ccd3250357 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 03:53:54 +0300 Subject: [PATCH 0367/2950] [SOCKS] overwrite connection info after establishing connection to i2p host (closes #1336) Signed-off-by: R4SAS --- libi2pd_client/SOCKS.cpp | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 6edd5677..c5428c86 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -227,38 +227,50 @@ namespace proxy boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS4Response(SOCKSHandler::errTypes error, uint32_t ip, uint16_t port) { assert(error >= SOCKS4_OK); - m_response[0] = '\x00'; //Version - m_response[1] = error; //Response code - htobe16buf(m_response + 2, port); //Port - htobe32buf(m_response + 4, ip); //IP + m_response[0] = '\x00'; // version + m_response[1] = error; // response code + htobe16buf(m_response + 2, port); // port + htobe32buf(m_response + 4, ip); // IP return boost::asio::const_buffers_1(m_response,8); } boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) { - size_t size = 6; // header + port + size_t size = 6; // header + port assert(error <= SOCKS5_ADDR_UNSUP); - m_response[0] = '\x05'; //Version - m_response[1] = error; //Response code - m_response[2] = '\x00'; //RSV - m_response[3] = type; //Address type + m_response[0] = '\x05'; // version + m_response[1] = error; // response code + m_response[2] = '\x00'; // reserved + m_response[3] = type; // address type switch (type) { case ADDR_IPV4: size += 4; htobe32buf(m_response + 4, addr.ip); + htobe16buf(m_response + size - 2, port); break; case ADDR_IPV6: size += 16; memcpy(m_response + 4, addr.ipv6, 16); + htobe16buf(m_response + size - 2, port); break; case ADDR_DNS: - size += (1 + addr.dns.size); /* name length + domain name */ - m_response[4] = addr.dns.size; - memcpy(m_response + 5, addr.dns.value, addr.dns.size); + std::string address(addr.dns.value, addr.dns.size); + if(address.substr(addr.dns.size - 4, 4) == ".i2p") // overwrite if requested address inside I2P + { + m_response[3] = ADDR_IPV4; + size += 4; + memset(m_response + 4, 0, 6); // six HEX zeros + } + else + { + size += (1 + addr.dns.size); /* name length + resolved address */ + m_response[4] = addr.dns.size; + memcpy(m_response + 5, addr.dns.value, addr.dns.size); + htobe16buf(m_response + size - 2, port); + } break; } - htobe16buf(m_response + size - 2, port); //Port return boost::asio::const_buffers_1(m_response, size); } From 0e0169d22be7227e36875038a51a1f69104726f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 May 2020 08:37:47 -0400 Subject: [PATCH 0368/2950] 2.32.0 --- ChangeLog | 24 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 930be261..69fa58b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,30 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.32.0] - 2020-05-25 +### Added +- Multiple encryption types for local destinations +- Next key and tagset for ECIES-X25519-AEAD-Ratchet +- NTCP2 through SOCKS proxy +- Throw error message if any port to bind is occupied +- gzip parameter for UDP tunnels +- Show ECIES-X25519-AEAD-Ratchet sessions and tags on the web console +- Simplified implementation of gzip for no compression mode +- Allow ECIES-X25519-AEAD-Ratchet session restart after 2 minutes +### Changed +- Select peers for client tunnels among routers >= 0.9.36 +- Check ECIES flag for encrypted lookup reply +- Streaming MTU size 1812 for ECIES-X25519-AEAD-Ratchet +- Don't calculate checksum for Data message send through ECIES-X25519-AEAD-Ratchet +- Catch network connectivity status for Windows +- Stop as soon as no more transit tunnels during graceful shutdown for Android +- RouterInfo gzip compression level depends on size +- Send response to received datagram from ECIES-X25519-AEAD-Ratchet session +- Reseeds list +### Fixed +- Correct timestamp check for LeaseSet2 +- Encrypted leaseset without authentication + ## [2.31.0] - 2020-04-10 ### Added - NTCP2 through HTTP proxy diff --git a/Win32/installer.iss b/Win32/installer.iss index 8e66c17a..88856558 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.31.0" +#define I2Pd_ver "2.32.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index d3c5c16b..ef6bf36e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2310 - versionName "2.31.0" + versionCode 2320 + versionName "2.32.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index 45a16dd8..a5ad1bfd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.31.0.{build} +version: 2.32.0.{build} pull_requests: do_not_increment_build_number: true branches: diff --git a/libi2pd/version.h b/libi2pd/version.h index d862f46e..346cf8a7 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 31 +#define I2PD_VERSION_MINOR 32 #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 45 +#define I2P_VERSION_MICRO 46 #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) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 4c027bc0..da9627cc 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 1dcb8787963830396652c9cc56be93496d667357 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 25 May 2020 12:43:16 +0000 Subject: [PATCH 0369/2950] update debian and rpm stuff to 2.32.0 Signed-off-by: r4sas --- contrib/debian/i2pd.tmpfile | 2 +- contrib/i2pd.logrotate | 14 +++++++------- contrib/rpm/i2pd-git.spec | 4 ++++ contrib/rpm/i2pd.spec | 4 ++++ debian/changelog | 9 +++++++++ debian/copyright | 6 +++--- debian/i2pd.logrotate | 10 +--------- debian/postrm | 2 +- 8 files changed, 30 insertions(+), 21 deletions(-) mode change 100644 => 120000 debian/i2pd.logrotate diff --git a/contrib/debian/i2pd.tmpfile b/contrib/debian/i2pd.tmpfile index 6cd19112..e9bfebc6 100644 --- a/contrib/debian/i2pd.tmpfile +++ b/contrib/debian/i2pd.tmpfile @@ -1,2 +1,2 @@ -d /var/run/i2pd 0755 i2pd i2pd - - +d /run/i2pd 0755 i2pd i2pd - - d /var/log/i2pd 0755 i2pd i2pd - - diff --git a/contrib/i2pd.logrotate b/contrib/i2pd.logrotate index 795280d4..d0ca70ad 100644 --- a/contrib/i2pd.logrotate +++ b/contrib/i2pd.logrotate @@ -1,9 +1,9 @@ "/var/log/i2pd/*.log" { - copytruncate - daily - rotate 5 - compress - delaycompress - missingok - notifempty + copytruncate + daily + rotate 5 + compress + delaycompress + missingok + notifempty } diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 6967f949..22bbb505 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -121,6 +121,10 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon May 25 2020 r4sas - 2.32.0 +- update to 2.32.0 +- updated systemd service file (#1394) + * Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 49a5e666..646e4fb6 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -119,6 +119,10 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon May 25 2020 r4sas - 2.32.0 +- update to 2.32.0 +- updated systemd service file (#1394) + * Thu May 7 2020 Anatolii Vorona - 2.31.0-3 - added RPM logrotate config diff --git a/debian/changelog b/debian/changelog index 3824d4f8..43c3fc60 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +i2pd (2.32.0-1) unstable; urgency=high + + * updated to version 2.32.0/0.9.46 + * updated systemd service file (see #1394) + * updated apparmor profile (see 9318388007cff0495b4b360d0480f4fc1219a9dc) + * updated logrotate config and moved it to contrib + + -- r4sas Mon, 25 May 2020 12:45:00 +0000 + i2pd (2.31.0-1) unstable; urgency=medium * updated to version 2.31.0 diff --git a/debian/copyright b/debian/copyright index 3c513020..9f18f53a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,7 +3,7 @@ Upstream-Name: i2pd Source: https://github.com/PurpleI2P Files: * -Copyright: 2013-2017 PurpleI2P +Copyright: 2013-2020 PurpleI2P License: BSD-3-clause Files: qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl @@ -16,8 +16,8 @@ License: BSD-2-Clause Files: debian/* Copyright: 2013-2015 Kill Your TV 2014-2016 hagen - 2016-2017 R4SAS - 2017-2018 Yangfl + 2016-2020 R4SAS + 2017-2020 Yangfl License: GPL-2+ License: BSD-3-clause diff --git a/debian/i2pd.logrotate b/debian/i2pd.logrotate deleted file mode 100644 index 63c44270..00000000 --- a/debian/i2pd.logrotate +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/i2pd/i2pd.log { - rotate 6 - daily - missingok - notifempty - compress - delaycompress - copytruncate -} diff --git a/debian/i2pd.logrotate b/debian/i2pd.logrotate new file mode 120000 index 00000000..2630046a --- /dev/null +++ b/debian/i2pd.logrotate @@ -0,0 +1 @@ +/opt/build/i2pd/contrib/i2pd.logrotate \ No newline at end of file diff --git a/debian/postrm b/debian/postrm index 53ab15e7..ba69785e 100755 --- a/debian/postrm +++ b/debian/postrm @@ -6,7 +6,7 @@ if [ "$1" = "purge" ]; then rm -rf /etc/i2pd rm -rf /var/lib/i2pd rm -rf /var/log/i2pd - rm -rf /var/run/i2pd + rm -rf /run/i2pd fi #DEBHELPER# From 6bd44f0e4b6804a5feb817c7487d9bfa05ee0f72 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 25 May 2020 13:06:11 +0000 Subject: [PATCH 0370/2950] 2.32.0 Signed-off-by: r4sas --- ChangeLog | 17 +++++++++++------ qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69fa58b8..f080e1bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ - Show ECIES-X25519-AEAD-Ratchet sessions and tags on the web console - Simplified implementation of gzip for no compression mode - Allow ECIES-X25519-AEAD-Ratchet session restart after 2 minutes +- Added logrotate config for rpm package ### Changed - Select peers for client tunnels among routers >= 0.9.36 - Check ECIES flag for encrypted lookup reply @@ -20,10 +21,14 @@ - Stop as soon as no more transit tunnels during graceful shutdown for Android - RouterInfo gzip compression level depends on size - Send response to received datagram from ECIES-X25519-AEAD-Ratchet session +- Update webconsole functional +- Increased max transit tunnels limit - Reseeds list +- Dropped windows support in cmake ### Fixed -- Correct timestamp check for LeaseSet2 -- Encrypted leaseset without authentication +- Correct timestamp check for LeaseSet2 +- Encrypted leaseset without authentication +- Change SOCKS proxy connection response for clients without socks5h support (#1336) ## [2.31.0] - 2020-04-10 ### Added @@ -66,7 +71,7 @@ ### Added - Client auth flag for b33 address ### Changed -- Remove incoming NTCP2 session from pending list when established +- Remove incoming NTCP2 session from pending list when established - Handle errors for NTCP2 SessionConfrimed send ### Fixed - Failure to start on Windows XP @@ -115,7 +120,7 @@ ## [2.25.0] - 2019-05-09 ### Added - Create, publish and handle encrypted LeaseSet2 -- Support of b33 addresses +- Support of b33 addresses - RedDSA key blinding - .b32.i2p addresses in jump links - ntcp2.addressv6 parameter @@ -147,7 +152,7 @@ - Correct SAM response for invalid key - SAM crash on termination for Windows - Race condition for publishing - + ## [2.23.0] - 2019-01-21 ### Added - Standard LeaseSet2 support @@ -206,7 +211,7 @@ - NTCP2 is enabled by default - Show lease's expiration time in readable format in the web console ### Fixed -- Correct names for transports in the web console +- Correct names for transports in the web console ## [2.19.0] - 2018-06-26 ### Added diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index da9627cc..452d750f 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,7 +35,7 @@ - + From 2facf144438baa3e8822ab43bcd054372a028b93 Mon Sep 17 00:00:00 2001 From: r4sas Date: Mon, 25 May 2020 13:09:02 +0000 Subject: [PATCH 0371/2950] fix symbolic link Signed-off-by: r4sas --- debian/i2pd.logrotate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/i2pd.logrotate b/debian/i2pd.logrotate index 2630046a..40dea037 120000 --- a/debian/i2pd.logrotate +++ b/debian/i2pd.logrotate @@ -1 +1 @@ -/opt/build/i2pd/contrib/i2pd.logrotate \ No newline at end of file +../contrib/i2pd.logrotate \ No newline at end of file From d226834eef933b6b0b1ec051017463cb45bf62cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 13:33:02 +0000 Subject: [PATCH 0372/2950] update debian patch Signed-off-by: R4SAS --- debian/patches/01-tune-build-opts.patch | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/debian/patches/01-tune-build-opts.patch b/debian/patches/01-tune-build-opts.patch index dd2b4638..e06a8621 100644 --- a/debian/patches/01-tune-build-opts.patch +++ b/debian/patches/01-tune-build-opts.patch @@ -1,17 +1,15 @@ -diff --git a/Makefile b/Makefile -index bdadfe0..2f71eec 100644 ---- a/Makefile -+++ b/Makefile -@@ -9,10 +9,10 @@ DEPS := obj/make.dep - +Index: i2pd/Makefile +=================================================================== +--- i2pd.orig/Makefile ++++ i2pd/Makefile +@@ -13,8 +13,8 @@ DAEMON_SRC_DIR := daemon + include filelist.mk - + -USE_AESNI := yes -+USE_AESNI := no -USE_AVX := yes ++USE_AESNI := no +USE_AVX := no USE_STATIC := no USE_MESHNET := no USE_UPNP := no - DEBUG := yes - From dba6d681083ebe271eb5b70bae0b206f9a218f28 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 13:42:26 +0000 Subject: [PATCH 0373/2950] update debian patch Signed-off-by: R4SAS --- debian/patches/02-fix-1210.patch | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/debian/patches/02-fix-1210.patch b/debian/patches/02-fix-1210.patch index 6a4caf94..9ad9bb0f 100644 --- a/debian/patches/02-fix-1210.patch +++ b/debian/patches/02-fix-1210.patch @@ -4,10 +4,12 @@ Author: r4sas Bug: https://github.com/PurpleI2P/i2pd/issues/1210 Reviewed-By: r4sas -Last-Update: 2018-08-25 +Last-Update: 2020-05-25 ---- a/contrib/i2pd.service -+++ b/contrib/i2pd.service +Index: i2pd/contrib/i2pd.service +=================================================================== +--- i2pd.orig/contrib/i2pd.service ++++ i2pd/contrib/i2pd.service @@ -6,10 +6,10 @@ After=network.target [Service] User=i2pd @@ -21,5 +23,5 @@ Last-Update: 2018-08-25 +#LogsDirectory=i2pd +#LogsDirectoryMode=0700 Type=forking - ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service - ExecReload=/bin/kill -HUP $MAINPID + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --tunnelsdir=/etc/i2pd/tunnels.conf.d --pidfile=/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service + ExecReload=/bin/sh -c "kill -HUP $MAINPID" From 8e0f1de25a8e4aade51b8acbec0cd72622c507f1 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 20:28:52 +0300 Subject: [PATCH 0374/2950] 2.32.0 - [RPM] fix build in fedora copr Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 4 +++- contrib/rpm/i2pd.spec | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 22bbb505..6cb09f0d 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.31.0 +Version: 2.32.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -111,6 +111,8 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* +%{_sysconfdir}/i2pd/subscriptions.txt %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 646e4fb6..62ef68e7 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd -Version: 2.31.0 -Release: 3%{?dist} +Version: 2.32.0 +Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -111,6 +111,7 @@ getent passwd i2pd >/dev/null || \ %{_datadir}/i2pd/certificates %config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* +%{_sysconfdir}/i2pd/subscriptions.txt /%{_unitdir}/i2pd.service %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd From 60b1b2ca4af37fde2858d2c711269036f715a3da Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 21:22:50 +0300 Subject: [PATCH 0375/2950] [RPM] update spec files Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 19 ++++++++++--------- contrib/rpm/i2pd.spec | 38 ++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 6cb09f0d..1a557758 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -10,7 +10,7 @@ License: BSD URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz -%if 0%{?rhel} == 7 +%if 0%{?rhel} == 7 BuildRequires: cmake3 %else BuildRequires: cmake @@ -24,8 +24,8 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units -Requires: logrotate -Requires: systemd +Requires: logrotate +Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description @@ -74,17 +74,18 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d +%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd +%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.d/README %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d/README %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 -%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd -%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd -%{__install} -d -m 755 %{buildroot}%{_datadir}/%{name} -%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/%{name}/certificates +%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates +%{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates @@ -117,7 +118,7 @@ getent passwd i2pd >/dev/null || \ %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd -%{_datadir}/%{name}/certificates +%{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates %{_sysconfdir}/logrotate.d/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 62ef68e7..b11f8b67 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd Version: 2.32.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -8,7 +8,7 @@ License: BSD URL: https://github.com/PurpleI2P/i2pd Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz -%if 0%{?rhel} == 7 +%if 0%{?rhel} == 7 BuildRequires: cmake3 %else BuildRequires: cmake @@ -22,8 +22,8 @@ BuildRequires: openssl-devel BuildRequires: miniupnpc-devel BuildRequires: systemd-units -Requires: logrotate -Requires: systemd +Requires: logrotate +Requires: systemd Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description @@ -71,19 +71,20 @@ pushd build %endif chrpath -d i2pd -install -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd -install -d -m 755 %{buildroot}%{_datadir}/i2pd -install -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d +%{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd +%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d +%{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd +%{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/subscriptions.txt %{buildroot}%{_sysconfdir}/i2pd/subscriptions.txt +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/tunnels.conf %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/i2pd +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service +%{__install} -D -m 644 %{_builddir}/%{name}-%{version}/debian/i2pd.1 %{buildroot}%{_mandir}/man1/i2pd.1 %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/certificates/ %{buildroot}%{_datadir}/i2pd/certificates %{__cp} -r %{_builddir}/%{name}-%{version}/contrib/tunnels.d/ %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d -install -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.service %{buildroot}%{_unitdir}/i2pd.service -install -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd -install -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd ln -s %{_datadir}/%{name}/certificates %{buildroot}%{_sharedstatedir}/i2pd/certificates -ln -s %{_datadir}/i2pd/tunnels.conf.d %{buildroot}%{_sysconfdir}/i2pd/tunnels.conf.d %pre @@ -106,15 +107,16 @@ getent passwd i2pd >/dev/null || \ %files -%doc LICENSE README.md +%doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd -%{_datadir}/i2pd/certificates %config(noreplace) %{_sysconfdir}/i2pd/*.conf %config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* %{_sysconfdir}/i2pd/subscriptions.txt -/%{_unitdir}/i2pd.service -%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd +%{_unitdir}/i2pd.service +%{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd +%dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd +%{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates %{_sysconfdir}/logrotate.d/i2pd From a4c4bf4b584cd01633b570336adda383ce052761 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 22:30:18 +0300 Subject: [PATCH 0376/2950] [RPM] update spec files Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 46 +++++++++++++++++++-------------------- contrib/rpm/i2pd.spec | 46 +++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 1a557758..41a9dbe9 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,32 +1,32 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) -Name: i2pd-git -Version: 2.32.0 -Release: git%{git_hash}%{?dist} -Summary: I2P router written in C++ -Conflicts: i2pd +Name: i2pd-git +Version: 2.32.0 +Release: git%{git_hash}%{?dist} +Summary: I2P router written in C++ +Conflicts: i2pd -License: BSD -URL: https://github.com/PurpleI2P/i2pd -Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz +License: BSD +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 -BuildRequires: gcc-c++ -BuildRequires: zlib-devel -BuildRequires: boost-devel -BuildRequires: openssl-devel -BuildRequires: miniupnpc-devel -BuildRequires: systemd-units +BuildRequires: chrpath +BuildRequires: gcc-c++ +BuildRequires: zlib-devel +BuildRequires: boost-devel +BuildRequires: openssl-devel +BuildRequires: miniupnpc-devel +BuildRequires: systemd-units -Requires: logrotate -Requires: systemd -Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd +Requires: logrotate +Requires: systemd +Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description C++ implementation of I2P. @@ -112,15 +112,15 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf -%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* -%{_sysconfdir}/i2pd/subscriptions.txt +%config %{_sysconfdir}/i2pd/subscriptions.txt +%doc %{_sysconfdir}/i2pd/tunnels.conf.d/README +%{_sysconfdir}/logrotate.d/i2pd %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates -%{_sysconfdir}/logrotate.d/i2pd %changelog diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index b11f8b67..cd9856cb 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,30 +1,30 @@ -Name: i2pd -Version: 2.32.0 -Release: 2%{?dist} -Summary: I2P router written in C++ -Conflicts: i2pd-git +Name: i2pd +Version: 2.32.0 +Release: 2%{?dist} +Summary: I2P router written in C++ +Conflicts: i2pd-git -License: BSD -URL: https://github.com/PurpleI2P/i2pd -Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz +License: BSD +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 -BuildRequires: gcc-c++ -BuildRequires: zlib-devel -BuildRequires: boost-devel -BuildRequires: openssl-devel -BuildRequires: miniupnpc-devel -BuildRequires: systemd-units +BuildRequires: chrpath +BuildRequires: gcc-c++ +BuildRequires: zlib-devel +BuildRequires: boost-devel +BuildRequires: openssl-devel +BuildRequires: miniupnpc-devel +BuildRequires: systemd-units -Requires: logrotate -Requires: systemd -Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd +Requires: logrotate +Requires: systemd +Requires(pre): %{_sbindir}/useradd %{_sbindir}/groupadd %description C++ implementation of I2P. @@ -110,15 +110,15 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf -%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/* -%{_sysconfdir}/i2pd/subscriptions.txt +%config %{_sysconfdir}/i2pd/subscriptions.txt +%doc %{_sysconfdir}/i2pd/tunnels.conf.d/README +%{_sysconfdir}/logrotate.d/i2pd %{_unitdir}/i2pd.service %{_mandir}/man1/i2pd.1* %dir %attr(0700,i2pd,i2pd) %{_sharedstatedir}/i2pd %dir %attr(0700,i2pd,i2pd) %{_localstatedir}/log/i2pd %{_datadir}/i2pd/certificates %{_sharedstatedir}/i2pd/certificates -%{_sysconfdir}/logrotate.d/i2pd %changelog From 64c986ebbb5d11f6143ade4fbb3277f18a13c574 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 25 May 2020 23:01:02 +0300 Subject: [PATCH 0377/2950] [RPM] update spec files Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 2 +- contrib/rpm/i2pd.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 41a9dbe9..3473a9d0 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -75,7 +75,6 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd -%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf @@ -112,6 +111,7 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf %config %{_sysconfdir}/i2pd/subscriptions.txt %doc %{_sysconfdir}/i2pd/tunnels.conf.d/README %{_sysconfdir}/logrotate.d/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index cd9856cb..588a6839 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -73,7 +73,6 @@ pushd build chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd -%{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd/tunnels.conf.d %{__install} -d -m 700 %{buildroot}%{_sharedstatedir}/i2pd %{__install} -d -m 700 %{buildroot}%{_localstatedir}/log/i2pd %{__install} -D -m 644 %{_builddir}/%{name}-%{version}/contrib/i2pd.conf %{buildroot}%{_sysconfdir}/i2pd/i2pd.conf @@ -110,6 +109,7 @@ getent passwd i2pd >/dev/null || \ %doc LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf contrib/tunnels.d %{_sbindir}/i2pd %config(noreplace) %{_sysconfdir}/i2pd/*.conf +%config(noreplace) %{_sysconfdir}/i2pd/tunnels.conf.d/*.conf %config %{_sysconfdir}/i2pd/subscriptions.txt %doc %{_sysconfdir}/i2pd/tunnels.conf.d/README %{_sysconfdir}/logrotate.d/i2pd From bdb918cdb38057a1a7ce991dbbf2e7fc7e75fbdc Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 May 2020 21:40:46 -0400 Subject: [PATCH 0378/2950] honour explicitPeer param in tunnels --- libi2pd_client/ClientContext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 6a58d63c..54007c95 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -459,6 +459,8 @@ namespace client else if (authType == "2") // PSK ReadI2CPOptionsGroup (section, I2CP_PARAM_LEASESET_CLIENT_PSK, options); } + std::string explicitPeers = GetI2CPStringOption(section, I2CP_PARAM_EXPLICIT_PEERS, ""); + if (explicitPeers.length () > 0) options[I2CP_PARAM_EXPLICIT_PEERS] = explicitPeers; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const From 37ec90c436f2e34705d39ffd944cfab729028e89 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 May 2020 16:47:45 -0400 Subject: [PATCH 0379/2950] don't gererate more tags for detached session --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2f43b554..310d263e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -612,7 +612,7 @@ namespace garlic int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; moreTags -= (receiveTagset->GetNextIndex () - index); - if (moreTags > 0) + if (moreTags > 0 && GetOwner ()) GenerateMoreReceiveTags (receiveTagset, moreTags); return true; } From 45e8d5c50ecb9fdf8399d82c8f5a15d633741d77 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 27 May 2020 21:27:16 +0300 Subject: [PATCH 0380/2950] Return deprecated websocket config options for compatibility Closes #1523 Signed-off-by: R4SAS --- libi2pd/Config.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 0358d3e9..d11152dd 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -221,6 +221,14 @@ namespace config { ("trust.hidden", value()->default_value(false), "Should we hide our router from other routers?") ; + // Save deprecated websocket options for compatibility + options_description websocket("Websocket Options"); + websocket.add_options() + ("websockets.enabled", value()->default_value(false), "Deprecated option") + ("websockets.address", value()->default_value(""), "Deprecated option") + ("websockets.port", value()->default_value(0), "Deprecated option") + ; + options_description exploratory("Exploratory Options"); exploratory.add_options() ("exploratory.inbound.length", value()->default_value(2), "Exploratory inbound tunnel length") @@ -271,6 +279,7 @@ namespace config { .add(reseed) .add(addressbook) .add(trust) + .add(websocket) // deprecated .add(exploratory) .add(ntcp2) .add(nettime) From 0dc212d97c75ba1fa852af6889386f82f5ec289e Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 May 2020 13:46:02 -0400 Subject: [PATCH 0381/2950] fixed non-updating LeaseSet1 --- libi2pd/LeaseSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp index 6b8b7545..b90d6d85 100644 --- a/libi2pd/LeaseSet.cpp +++ b/libi2pd/LeaseSet.cpp @@ -187,7 +187,7 @@ namespace data bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const { - return ExtractExpirationTimestamp (buf, len) > (m_ExpirationTime ? m_ExpirationTime : ExtractExpirationTimestamp (m_Buffer, m_BufferLen)); + return ExtractExpirationTimestamp (buf, len) > ExtractExpirationTimestamp (m_Buffer, m_BufferLen); } bool LeaseSet::ExpiresSoon(const uint64_t dlt, const uint64_t fudge) const From 9135772f8959c0a965085657dd8300a928304c64 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 2 Jun 2020 19:26:36 +0300 Subject: [PATCH 0382/2950] 2.32.1 Signed-off-by: R4SAS --- ChangeLog | 8 ++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 7 +++++-- debian/changelog | 6 ++++++ libi2pd/version.h | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 29 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index f080e1bc..33792a97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.32.1] - 2020-06-02 +### Added +- Read explicit peers in tunnels config +### Fixed +- Generation of tags for detached sessions +- Non-updating LeaseSet1 +- Start when deprecated websocket options present in i2pd.conf + ## [2.32.0] - 2020-05-25 ### Added - Multiple encryption types for local destinations diff --git a/Win32/installer.iss b/Win32/installer.iss index 88856558..40724d7a 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.32.0" +#define I2Pd_ver "2.32.1" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index ef6bf36e..c9e8429c 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2320 - versionName "2.32.0" + versionCode 2321 + versionName "2.32.1" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index a5ad1bfd..0567127c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.32.0.{build} +version: 2.32.1.{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 3473a9d0..7079ec23 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.32.0 +Version: 2.32.1 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -124,6 +124,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Jun 02 2020 r4sas - 2.32.1 +- update to 2.32.1 + * Mon May 25 2020 r4sas - 2.32.0 - update to 2.32.0 - updated systemd service file (#1394) diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 588a6839..5c0b8fbd 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,6 +1,6 @@ Name: i2pd -Version: 2.32.0 -Release: 2%{?dist} +Version: 2.32.1 +Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -122,6 +122,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Jun 02 2020 r4sas - 2.32.1 +- update to 2.32.1 + * Mon May 25 2020 r4sas - 2.32.0 - update to 2.32.0 - updated systemd service file (#1394) diff --git a/debian/changelog b/debian/changelog index 43c3fc60..b01f9519 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.32.1-1) unstable; urgency=high + + * updated to version 2.32.1 + + -- r4sas Tue, 02 Jun 2020 16:30:00 +0000 + i2pd (2.32.0-1) unstable; urgency=high * updated to version 2.32.0/0.9.46 diff --git a/libi2pd/version.h b/libi2pd/version.h index 346cf8a7..c234516f 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -17,7 +17,7 @@ #define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MINOR 32 -#define I2PD_VERSION_MICRO 0 +#define I2PD_VERSION_MICRO 1 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define VERSION I2PD_VERSION diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 452d750f..75c57fb7 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From e1356965308b3554d001003b9bce737603030ffa Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Jun 2020 16:05:19 -0400 Subject: [PATCH 0383/2950] support multiple encryption keys through the I2CP --- libi2pd/Crypto.cpp | 9 ++++++++- libi2pd/Crypto.h | 2 +- libi2pd/CryptoKey.cpp | 2 +- libi2pd/CryptoKey.h | 3 ++- libi2pd_client/I2CP.cpp | 44 +++++++++++++++++++++++++++-------------- libi2pd_client/I2CP.h | 9 +++++---- 6 files changed, 46 insertions(+), 23 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 6db124c0..2f10e91d 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -375,15 +375,22 @@ namespace crypto #endif } - void X25519Keys::SetPrivateKey (const uint8_t * priv) + void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic) { #if OPENSSL_X25519 if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); if (m_Pkey) EVP_PKEY_free (m_Pkey); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); + if (calculatePublic) + { + size_t len = 32; + EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); + } #else memcpy (m_PrivateKey, priv, 32); + if (calculatePublic) + GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); #endif } diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 56c8c10b..9ca3163f 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -88,7 +88,7 @@ namespace crypto void GenerateKeys (); const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; - void SetPrivateKey (const uint8_t * priv); // wihout calculating public + void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false); void Agree (const uint8_t * pub, uint8_t * shared); private: diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index d786e193..b8f66e4d 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -166,7 +166,7 @@ namespace crypto memcpy (pub, m_PublicKey, 32); } - ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv) + ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic) { m_StaticKeys.SetPrivateKey (priv); } diff --git a/libi2pd/CryptoKey.h b/libi2pd/CryptoKey.h index 1c8b0a71..fb69558f 100644 --- a/libi2pd/CryptoKey.h +++ b/libi2pd/CryptoKey.h @@ -145,11 +145,12 @@ namespace crypto { public: - ECIESX25519AEADRatchetDecryptor (const uint8_t * priv); + ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic = false); ~ECIESX25519AEADRatchetDecryptor () {}; bool Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding); // agree with static and return in sharedSecret (32 bytes) size_t GetPublicKeyLen () const { return 32; }; + const uint8_t * GetPubicKey () const { return m_StaticKeys.GetPublicKey (); }; private: diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index fef5d6b6..5a2f0901 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -55,12 +55,18 @@ namespace client void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { - memcpy (m_EncryptionPrivateKey, key, 256); - m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), m_EncryptionPrivateKey); + m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key); } + void I2CPDestination::SetECIESx25519EncryptionPrivateKey (const uint8_t * key) + { + m_ECIESx25519Decryptor = std::make_shared(key, true); // calculate public + } + 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_RATCHET && m_ECIESx25519Decryptor) + return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true); if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); else @@ -68,6 +74,19 @@ namespace client return false; } + const uint8_t * I2CPDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const + { + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor) + return m_ECIESx25519Decryptor->GetPubicKey (); + return nullptr; + } + + bool I2CPDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const + { + return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType; + } + + void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); @@ -77,7 +96,8 @@ namespace client void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) { - i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPrivateKey, tunnels); // we don't care about encryption key + uint8_t priv[256] = {0}; + i2p::data::LocalLeaseSet ls (m_Identity, priv, tunnels); // we don't care about encryption key, we need leases only m_LeaseSetExpirationTime = ls.GetExpirationTime (); uint8_t * leases = ls.GetLeases (); leases[-1] = tunnels.size (); @@ -572,28 +592,22 @@ namespace client offset += ls.GetBufferLen (); // private keys int numPrivateKeys = buf[offset]; offset++; - uint16_t currentKeyType = 0; - const uint8_t * currentKey = nullptr; for (int i = 0; i < numPrivateKeys; i++) { if (offset + 4 > len) return; uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length if (offset + keyLen > len) return; - if (!currentKey || keyType > currentKeyType) + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset); + else { - currentKeyType = keyType; - currentKey = buf + offset; + m_Destination->SetEncryptionType (keyType); + m_Destination->SetEncryptionPrivateKey (buf + offset); } offset += keyLen; } - // TODO: support multiple keys - if (currentKey) - { - m_Destination->SetEncryptionPrivateKey (currentKey); - m_Destination->SetEncryptionType (currentKeyType); - } - + m_Destination->LeaseSet2Created (storeType, ls.GetBuffer (), ls.GetBufferLen ()); } } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index f4e83f06..db38ecdc 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -75,14 +75,15 @@ namespace client void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; + void SetECIESx25519EncryptionPrivateKey (const uint8_t * key); void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession 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 SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { return m_EncryptionKeyType == keyType; }; - // TODO: implement GetEncryptionPublicKey + 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; }; protected: @@ -101,9 +102,9 @@ namespace client std::shared_ptr m_Owner; std::shared_ptr m_Identity; - uint8_t m_EncryptionPrivateKey[256]; i2p::data::CryptoKeyType m_EncryptionKeyType; - std::shared_ptr m_Decryptor; + std::shared_ptr m_Decryptor; // standard + std::shared_ptr m_ECIESx25519Decryptor; uint64_t m_LeaseSetExpirationTime; }; From 438a225487d023f0f88905f0e1e1bbad07905801 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Jun 2020 19:58:36 -0400 Subject: [PATCH 0384/2950] pass calculatePublic --- libi2pd/CryptoKey.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index b8f66e4d..4518a347 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -168,7 +168,7 @@ namespace crypto ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic) { - m_StaticKeys.SetPrivateKey (priv); + m_StaticKeys.SetPrivateKey (priv, calculatePublic); } bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) From 4ae41513acd14a370514e029ebf9c4a8b32af3f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Jun 2020 18:19:38 -0400 Subject: [PATCH 0385/2950] save new session with NSR tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 11 ++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 14 +++++++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 310d263e..a578131d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -150,7 +150,8 @@ namespace garlic uint8_t tagsetKey[32]; i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) // Session Tag Ratchet - auto tagsetNsr = std::make_shared(shared_from_this ()); + auto tagsetNsr = (m_State == eSessionStateNewSessionReceived) ? std::make_shared(shared_from_this ()): + std::make_shared(shared_from_this ()); tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) tagsetNsr->NextSessionTagRatchet (); return tagsetNsr; @@ -416,8 +417,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob - m_NSRTagset = CreateNewSessionTagset (); - uint64_t tag = m_NSRTagset->GetNextSessionTag (); + m_NSRSendTagset = CreateNewSessionTagset (); + uint64_t tag = m_NSRSendTagset->GetNextSessionTag (); size_t offset = 0; memcpy (out + offset, &tag, 8); @@ -475,7 +476,7 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob and sent NSR already - uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag + uint64_t tag = m_NSRSendTagset->GetNextSessionTag (); // next tag memcpy (out, &tag, 8); memcpy (out + 8, m_NSREncodedKey, 32); // recalculate h with new tag @@ -625,7 +626,7 @@ namespace garlic { case eSessionStateNewSessionReplySent: m_State = eSessionStateEstablished; - m_NSRTagset = nullptr; + m_NSRSendTagset = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 108788d5..d121842d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -79,6 +79,18 @@ namespace garlic uint64_t m_ExpirationTimestamp = 0; }; + class NSRatchetTagSet: public RatchetTagSet + { + public: + + NSRatchetTagSet (std::shared_ptr session): + RatchetTagSet (session), m_DummySession (session) {}; + + private: + + std::shared_ptr m_DummySession; // we need a strong pointer for NS + }; + enum ECIESx25519BlockType { eECIESx25519BlkDateTime = 0, @@ -171,7 +183,7 @@ namespace garlic i2p::crypto::X25519Keys m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming - std::shared_ptr m_SendTagset, m_NSRTagset; + std::shared_ptr m_SendTagset, m_NSRSendTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; From 55ff6beb7d76f89c1ae7237ba6b8ab5fa5727a14 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2020 09:23:50 -0400 Subject: [PATCH 0386/2950] don't create ECIESx25519 again if key was not changed --- libi2pd_client/I2CP.cpp | 6 +++++- libi2pd_client/I2CP.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 5a2f0901..b0f334f5 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -60,7 +60,11 @@ namespace client void I2CPDestination::SetECIESx25519EncryptionPrivateKey (const uint8_t * key) { - m_ECIESx25519Decryptor = std::make_shared(key, true); // calculate public + if (!m_ECIESx25519Decryptor || memcmp (m_ECIESx25519PrivateKey, key, 32)) // new key? + { + m_ECIESx25519Decryptor = std::make_shared(key, true); // calculate public + memcpy (m_ECIESx25519PrivateKey, key, 32); + } } bool I2CPDestination::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index db38ecdc..adb648f4 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -105,6 +105,7 @@ namespace client i2p::data::CryptoKeyType m_EncryptionKeyType; std::shared_ptr m_Decryptor; // standard std::shared_ptr m_ECIESx25519Decryptor; + uint8_t m_ECIESx25519PrivateKey[32]; uint64_t m_LeaseSetExpirationTime; }; From 6735b2686b6c13a36546dd794ee49b4d583565e0 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Jun 2020 15:41:30 -0400 Subject: [PATCH 0387/2950] set LeaseSet2 for ECIESx25519 --- libi2pd/Destination.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index cd447773..6d5fb916 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -892,7 +892,11 @@ namespace client encryptionKey->GenerateKeys (); encryptionKey->CreateDecryptor (); if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + { m_ECIESx25519EncryptionKey.reset (encryptionKey); + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) + SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2 + } else m_StandardEncryptionKey.reset (encryptionKey); } From 221c14cf0e2ae481bbaa7edfd4257511e02ec9ac Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Jun 2020 16:24:11 -0400 Subject: [PATCH 0388/2950] don't lookup UDP session if port was not changed --- libi2pd_client/I2PTunnel.cpp | 28 ++++++++++++++++++---------- libi2pd_client/I2PTunnel.h | 5 +++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5b384bff..ea2517d7 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -634,7 +634,7 @@ namespace client uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); std::vector removePorts; for (const auto & s : m_Sessions) { - if (now - s.second.second >= delta) + if (now - s.second->second >= delta) removePorts.push_back(s.first); } for(auto port : removePorts) { @@ -761,7 +761,7 @@ namespace client m_RemoteIdent(nullptr), m_ResolveThread(nullptr), m_LocalSocket(localDestination->GetService(), localEndpoint), - RemotePort(remotePort), + RemotePort(remotePort), m_LastPort (0), m_cancel_resolve(false) { auto dgram = m_LocalDest->CreateDatagramDestination(gzip); @@ -796,16 +796,24 @@ namespace client return; // drop, remote not resolved } auto remotePort = m_RecvEndpoint.port(); - auto itr = m_Sessions.find(remotePort); - if (itr == m_Sessions.end()) { - // track new udp convo - m_Sessions[remotePort] = {boost::asio::ip::udp::endpoint(m_RecvEndpoint), 0}; - } + if (!m_LastPort || m_LastPort != remotePort) + { + auto itr = m_Sessions.find(remotePort); + if (itr != m_Sessions.end()) + m_LastSession = itr->second; + else + { + m_LastSession = std::make_shared(boost::asio::ip::udp::endpoint(m_RecvEndpoint), 0); + m_Sessions.emplace (remotePort, m_LastSession); + } + m_LastPort = remotePort; + } // send off to remote i2p destination LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); // mark convo as active - m_Sessions[remotePort].second = i2p::util::GetMillisecondsSinceEpoch(); + if (m_LastSession) + m_LastSession->second = i2p::util::GetMillisecondsSinceEpoch(); RecvFromLocal(); } @@ -851,9 +859,9 @@ namespace client // found convo if (len > 0) { LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32()); - m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second.first); + m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first); // mark convo as active - itr->second.second = i2p::util::GetMillisecondsSinceEpoch(); + itr->second->second = i2p::util::GetMillisecondsSinceEpoch(); } } else diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index d4db80d8..99934196 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -276,7 +276,7 @@ namespace client void TryResolving(); const std::string m_Name; std::mutex m_SessionsMutex; - std::map m_Sessions; // maps i2p port -> local udp convo + std::unordered_map > m_Sessions; // maps i2p port -> local udp convo const std::string m_RemoteDest; std::shared_ptr m_LocalDest; const boost::asio::ip::udp::endpoint m_LocalEndpoint; @@ -285,8 +285,9 @@ namespace client boost::asio::ip::udp::socket m_LocalSocket; boost::asio::ip::udp::endpoint m_RecvEndpoint; uint8_t m_RecvBuff[I2P_UDP_MAX_MTU]; - uint16_t RemotePort; + uint16_t RemotePort, m_LastPort; bool m_cancel_resolve; + std::shared_ptr m_LastSession; }; class I2PServerTunnel: public I2PService From 6d7847f2dfc2da364f5303207f3665533bfbbbbc Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2020 16:26:45 -0400 Subject: [PATCH 0389/2950] send bulk datagrams --- libi2pd/Datagram.cpp | 14 ++++++++++++-- libi2pd/Datagram.h | 3 ++- libi2pd_client/I2PTunnel.cpp | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 04792bc5..5a6b8d90 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -56,6 +56,11 @@ namespace datagram session->SendMsg(msg); } + void DatagramDestination::FlushSendQueue (const i2p::data::IdentHash & ident) + { + ObtainSession(ident)->FlushSendQueue (); + } + void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) { i2p::data::IdentityEx identity; @@ -366,6 +371,7 @@ namespace datagram void DatagramSession::FlushSendQueue () { + if (m_SendQueue.empty ()) return; std::vector send; auto routingPath = GetSharedRoutingPath(); // if we don't have a routing path we will drop all queued messages @@ -380,7 +386,6 @@ namespace datagram routingPath->outboundTunnel->SendTunnelDataMsg(send); } m_SendQueue.clear(); - ScheduleFlushSendQueue(); } void DatagramSession::ScheduleFlushSendQueue() @@ -388,7 +393,12 @@ namespace datagram boost::posix_time::milliseconds dlt(10); m_SendQueueTimer.expires_from_now(dlt); auto self = shared_from_this(); - m_SendQueueTimer.async_wait([self](const boost::system::error_code & ec) { if(ec) return; self->FlushSendQueue(); }); + m_SendQueueTimer.async_wait([self](const boost::system::error_code & ec) + { + if(ec) return; + self->FlushSendQueue(); + self->ScheduleFlushSendQueue(); + }); } } } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index e81f738a..b7abcc03 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -59,6 +59,7 @@ namespace datagram /** send an i2np message to remote endpoint for this session */ void SendMsg(std::shared_ptr msg); + void FlushSendQueue(); /** get the last time in milliseconds for when we used this datagram session */ uint64_t LastActivity() const { return m_LastUse; } @@ -84,7 +85,6 @@ namespace datagram private: - void FlushSendQueue(); void ScheduleFlushSendQueue(); void HandleSend(std::shared_ptr msg); @@ -122,6 +122,7 @@ namespace datagram void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); + void FlushSendQueue (const i2p::data::IdentHash & ident); void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index ea2517d7..048c9962 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -811,6 +811,24 @@ namespace client // send off to remote i2p destination LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + size_t numPackets = 0; + while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) + { + boost::system::error_code ec; + size_t moreBytes = m_LocalSocket.available(ec); + if (ec || !moreBytes) break; + transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec); + remotePort = m_RecvEndpoint.port(); + // TODO: check remotePort + m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + numPackets++; + } + if (numPackets) + { + LogPrint(eLogDebug, "UDP Client: sent ", numPackets, " more packets to ", m_RemoteIdent->ToBase32()); + m_LocalDest->GetDatagramDestination()->FlushSendQueue (*m_RemoteIdent); + } + // mark convo as active if (m_LastSession) m_LastSession->second = i2p::util::GetMillisecondsSinceEpoch(); From f077836bf5518d4fe19aea425dbaa7b5b12eaea1 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2020 19:20:24 -0400 Subject: [PATCH 0390/2950] store DatagramSession for bulk --- libi2pd/Datagram.cpp | 53 ++++++++++++++++++++++++------------ libi2pd/Datagram.h | 7 ++++- libi2pd_client/I2PTunnel.cpp | 9 +++--- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 5a6b8d90..c4877106 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -34,31 +34,48 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) - { - uint8_t hash[32]; - SHA256(payload, len, hash); - m_Owner->Sign (hash, 32, m_Signature.data ()); - } - else - m_Owner->Sign (payload, len, m_Signature.data ()); - - auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, - fromPort, toPort, false, !session->IsRatchets ()); // datagram - session->SendMsg(msg); + SendDatagram (ObtainSession(identity), payload, len, fromPort, toPort); } void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - auto session = ObtainSession(identity); - auto msg = CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ()); // raw - session->SendMsg(msg); + SendRawDatagram (ObtainSession(identity), payload, len, fromPort, toPort); } - void DatagramDestination::FlushSendQueue (const i2p::data::IdentHash & ident) + std::shared_ptr DatagramDestination::GetSession(const i2p::data::IdentHash & ident) { - ObtainSession(ident)->FlushSendQueue (); + return ObtainSession(ident); + } + + void DatagramDestination::SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) + { + if (session) + { + if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + { + uint8_t hash[32]; + SHA256(payload, len, hash); + m_Owner->Sign (hash, 32, m_Signature.data ()); + } + else + m_Owner->Sign (payload, len, m_Signature.data ()); + + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + fromPort, toPort, false, !session->IsRatchets ()); // datagram + session->SendMsg(msg); + } + } + + void DatagramDestination::SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) + { + if (session) + session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw + } + + void DatagramDestination::FlushSendQueue (std::shared_ptr session) + { + if (session) + session->FlushSendQueue (); } void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index b7abcc03..fa9d2371 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -122,7 +122,12 @@ namespace datagram void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); - void FlushSendQueue (const i2p::data::IdentHash & ident); + + std::shared_ptr GetSession(const i2p::data::IdentHash & ident); + void SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); + void SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); + void FlushSendQueue (std::shared_ptr session); + void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false); void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; }; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 048c9962..0b2bb7e0 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -810,7 +810,8 @@ namespace client } // send off to remote i2p destination LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); - m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent); + m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); size_t numPackets = 0; while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) { @@ -820,14 +821,12 @@ namespace client transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec); remotePort = m_RecvEndpoint.port(); // TODO: check remotePort - m_LocalDest->GetDatagramDestination()->SendDatagramTo(m_RecvBuff, transferred, *m_RemoteIdent, remotePort, RemotePort); + m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); numPackets++; } if (numPackets) - { LogPrint(eLogDebug, "UDP Client: sent ", numPackets, " more packets to ", m_RemoteIdent->ToBase32()); - m_LocalDest->GetDatagramDestination()->FlushSendQueue (*m_RemoteIdent); - } + m_LocalDest->GetDatagramDestination()->FlushSendQueue (session); // mark convo as active if (m_LastSession) From a8f227f7594ae827764d1e7445cfe1824da689bf Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 9 Jun 2020 21:48:47 -0400 Subject: [PATCH 0391/2950] send raw follow-on datagrams --- libi2pd_client/I2PTunnel.cpp | 22 +++++++++++++++++----- libi2pd_client/I2PTunnel.h | 2 ++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 0b2bb7e0..48b1e79d 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -611,12 +611,23 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { - std::lock_guard lock(m_SessionsMutex); - auto session = ObtainUDPSession(from, toPort, fromPort); - session->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); - session->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + { + std::lock_guard lock(m_SessionsMutex); + m_LastSession = ObtainUDPSession(from, toPort, fromPort); + } + m_LastSession->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); + m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); } + void I2PUDPServerTunnel::HandleRecvFromI2PRaw (uint16_t, uint16_t, const uint8_t * buf, size_t len) + { + if (m_LastSession) + { + m_LastSession->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); + m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + } + } + void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) { std::lock_guard lock(m_SessionsMutex); uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); @@ -714,6 +725,7 @@ namespace client m_LocalDest->Start(); auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + dgram->SetRawReceiver(std::bind(&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } I2PUDPServerTunnel::~I2PUDPServerTunnel() @@ -821,7 +833,7 @@ namespace client transferred = m_LocalSocket.receive_from (boost::asio::buffer (m_RecvBuff, I2P_UDP_MAX_MTU), m_RecvEndpoint, 0, ec); remotePort = m_RecvEndpoint.port(); // TODO: check remotePort - m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); + m_LocalDest->GetDatagramDestination()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); numPackets++; } if (numPackets) diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 99934196..19e44e79 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -237,6 +237,7 @@ namespace client private: void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); private: @@ -248,6 +249,7 @@ namespace client std::mutex m_SessionsMutex; std::vector m_Sessions; std::shared_ptr m_LocalDest; + UDPSessionPtr m_LastSession; }; class I2PUDPClientTunnel From 0639cce784a0506cff7be8fbc6b9edb2b9a420b7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 10 Jun 2020 05:11:26 +0300 Subject: [PATCH 0392/2950] [SAM] fix ECDSA signatures names Signed-off-by: R4SAS --- libi2pd_client/SAM.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 2c6b711d..4723d168 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1015,8 +1015,8 @@ namespace client { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, {"ECDSA_SHA256_P256", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256}, - {"ECDSA_SHA256_P384", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384}, - {"ECDSA_SHA256_P521", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521}, + {"ECDSA_SHA384_P384", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384}, + {"ECDSA_SHA512_P521", i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521}, {"EdDSA_SHA512_Ed25519", i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519}, {"GOST_GOSTR3411256_GOSTR3410CRYPTOPROA", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256}, {"GOST_GOSTR3411512_GOSTR3410TC26A512", i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512}, From a33cad4b709fe62a488cbcd7447e3f35dd8ab3bf Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jun 2020 11:57:40 -0400 Subject: [PATCH 0393/2950] eliminate datagram send timer --- libi2pd/Datagram.cpp | 26 +++++++------------------- libi2pd/Datagram.h | 3 --- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index c4877106..99318ec9 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -34,12 +34,16 @@ namespace datagram void DatagramDestination::SendDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - SendDatagram (ObtainSession(identity), payload, len, fromPort, toPort); + auto session = ObtainSession(identity); + SendDatagram (session, payload, len, fromPort, toPort); + FlushSendQueue (session); } void DatagramDestination::SendRawDatagramTo(const uint8_t * payload, size_t len, const i2p::data::IdentHash & identity, uint16_t fromPort, uint16_t toPort) { - SendRawDatagram (ObtainSession(identity), payload, len, fromPort, toPort); + auto session = ObtainSession(identity); + SendRawDatagram (session, payload, len, fromPort, toPort); + FlushSendQueue (session); } std::shared_ptr DatagramDestination::GetSession(const i2p::data::IdentHash & ident) @@ -218,7 +222,6 @@ namespace datagram const i2p::data::IdentHash & remoteIdent) : m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent), - m_SendQueueTimer(localDestination->GetService()), m_RequestingLS(false) { } @@ -226,12 +229,10 @@ namespace datagram void DatagramSession::Start () { m_LastUse = i2p::util::GetMillisecondsSinceEpoch (); - ScheduleFlushSendQueue(); } void DatagramSession::Stop () { - m_SendQueueTimer.cancel (); } void DatagramSession::SendMsg(std::shared_ptr msg) @@ -383,7 +384,7 @@ namespace datagram if (msg || m_SendQueue.empty ()) m_SendQueue.push_back(msg); // flush queue right away if full - if(m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); + if(!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); } void DatagramSession::FlushSendQueue () @@ -404,18 +405,5 @@ namespace datagram } m_SendQueue.clear(); } - - void DatagramSession::ScheduleFlushSendQueue() - { - boost::posix_time::milliseconds dlt(10); - m_SendQueueTimer.expires_from_now(dlt); - auto self = shared_from_this(); - m_SendQueueTimer.async_wait([self](const boost::system::error_code & ec) - { - if(ec) return; - self->FlushSendQueue(); - self->ScheduleFlushSendQueue(); - }); - } } } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index fa9d2371..2aabcb1f 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -85,8 +85,6 @@ namespace datagram private: - void ScheduleFlushSendQueue(); - void HandleSend(std::shared_ptr msg); std::shared_ptr GetSharedRoutingPath(); @@ -101,7 +99,6 @@ namespace datagram std::shared_ptr m_RoutingSession; std::shared_ptr m_CurrentRemoteLease; std::shared_ptr m_CurrentOutboundTunnel; - boost::asio::deadline_timer m_SendQueueTimer; std::vector > m_SendQueue; uint64_t m_LastUse; bool m_RequestingLS; From 44bb8f6f1691176978390b753a325b92b42fbf00 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 10 Jun 2020 21:19:37 -0400 Subject: [PATCH 0394/2950] allocated datagram I2NP from memory pool --- libi2pd/Datagram.cpp | 18 ++++++------------ libi2pd/Datagram.h | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 99318ec9..5a196c3a 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -152,7 +152,7 @@ namespace datagram const std::vector >& payloads, uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) { - auto msg = NewI2NPMessage (); + 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) : @@ -239,9 +239,11 @@ namespace datagram { // we used this session m_LastUse = i2p::util::GetMillisecondsSinceEpoch(); - // schedule send - auto self = shared_from_this(); - m_LocalDestination->GetService().post(std::bind(&DatagramSession::HandleSend, self, msg)); + if (msg || m_SendQueue.empty ()) + m_SendQueue.push_back(msg); + // flush queue right away if full + if (!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) + FlushSendQueue(); } DatagramSession::Info DatagramSession::GetSessionInfo() const @@ -379,14 +381,6 @@ namespace datagram if(ls && ls->GetExpirationTime() > oldExpire) m_RemoteLeaseSet = ls; } - void DatagramSession::HandleSend(std::shared_ptr msg) - { - if (msg || m_SendQueue.empty ()) - m_SendQueue.push_back(msg); - // flush queue right away if full - if(!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); - } - void DatagramSession::FlushSendQueue () { if (m_SendQueue.empty ()) return; diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 2aabcb1f..94fe422c 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -85,8 +85,6 @@ namespace datagram private: - void HandleSend(std::shared_ptr msg); - std::shared_ptr GetSharedRoutingPath(); void HandleLeaseSetUpdated(std::shared_ptr ls); @@ -119,6 +117,7 @@ namespace datagram void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); void SendRawDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0); + // TODO: implement calls from other thread from SAM std::shared_ptr GetSession(const i2p::data::IdentHash & ident); void SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort); @@ -168,6 +167,7 @@ namespace datagram i2p::data::GzipInflator m_Inflator; i2p::data::GzipDeflator m_Deflator; std::vector m_From, m_Signature; + i2p::util::MemoryPool > m_I2NPMsgsPool; }; } } From 6a0174293e0e828d52b06cb5d261cdf183a865ec Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 11 Jun 2020 22:04:32 -0400 Subject: [PATCH 0395/2950] send raw datagrams in opposite direction --- libi2pd_client/I2PTunnel.cpp | 61 ++++++++++++++++++++++++------------ libi2pd_client/I2PTunnel.h | 4 +++ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 48b1e79d..74175b14 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -611,6 +611,7 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { + if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0]) { std::lock_guard lock(m_SessionsMutex); m_LastSession = ObtainUDPSession(from, toPort, fromPort); @@ -658,7 +659,7 @@ namespace client auto ih = from.GetIdentHash(); for (auto & s : m_Sessions ) { - if ( s->Identity == ih) + if (s->Identity.GetLL()[0] == ih.GetLL()[0]) { /** found existing session */ LogPrint(eLogDebug, "UDPServer: found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); @@ -707,11 +708,25 @@ namespace client { LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint); LastActivity = i2p::util::GetMillisecondsSinceEpoch(); - m_Destination->SendDatagramTo(m_Buffer, len, Identity, LocalPort, RemotePort); + auto session = m_Destination->GetSession (Identity); + m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort); + size_t numPackets = 0; + while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) + { + boost::system::error_code ec; + size_t moreBytes = IPSocket.available(ec); + if (ec || !moreBytes) break; + len = IPSocket.receive_from (boost::asio::buffer (m_Buffer, I2P_UDP_MAX_MTU), FromEndpoint, 0, ec); + m_Destination->SendRawDatagram (session, m_Buffer, len, LocalPort, RemotePort); + numPackets++; + } + if (numPackets > 0) + LogPrint(eLogDebug, "UDPSession: forward more ", numPackets, "packets B from ", FromEndpoint); + m_Destination->FlushSendQueue (session); Receive(); - } else { + } + else LogPrint(eLogError, "UDPSession: ", ecode.message()); - } } I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, @@ -781,6 +796,8 @@ namespace client std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + dgram->SetRawReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } void I2PUDPClientTunnel::Start() { @@ -880,26 +897,30 @@ namespace client void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { if(m_RemoteIdent && from.GetIdentHash() == *m_RemoteIdent) - { - auto itr = m_Sessions.find(toPort); - // found convo ? - if(itr != m_Sessions.end()) - { - // found convo - if (len > 0) { - LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32()); - m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first); - // mark convo as active - itr->second->second = i2p::util::GetMillisecondsSinceEpoch(); - } - } - else - LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); - } + HandleRecvFromI2PRaw (fromPort, toPort, buf, len); else LogPrint(eLogWarning, "UDP Client: unwarranted traffic from ", from.GetIdentHash().ToBase32()); } + void I2PUDPClientTunnel::HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) + { + auto itr = m_Sessions.find(toPort); + // found convo ? + if(itr != m_Sessions.end()) + { + // found convo + if (len > 0) + { + LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", m_RemoteIdent ? m_RemoteIdent->ToBase32() : ""); + m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second->first); + // mark convo as active + itr->second->second = i2p::util::GetMillisecondsSinceEpoch(); + } + } + else + LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); + } + I2PUDPClientTunnel::~I2PUDPClientTunnel() { auto dgram = m_LocalDest->GetDatagramDestination(); if (dgram) dgram->ResetReceiver(); diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 19e44e79..19d553da 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -275,7 +275,11 @@ namespace client void RecvFromLocal(); void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred); void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); + void HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void TryResolving(); + + private: + const std::string m_Name; std::mutex m_SessionsMutex; std::unordered_map > m_Sessions; // maps i2p port -> local udp convo From 5993cc857a94abd10ebf05fbe7c1426719a1b9a4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 16:03:12 -0400 Subject: [PATCH 0396/2950] start new tunnel message if remining is too small --- libi2pd/TunnelGateway.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 8f01bc4e..317926ae 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -66,7 +66,7 @@ namespace tunnel // length of bytes doesn't fit full tunnel message // every follow-on fragment adds 7 bytes size_t nonFit = (fullMsgLen + numFollowOnFragments*7) % TUNNEL_DATA_MAX_PAYLOAD_SIZE; - if (!nonFit || nonFit > m_RemainingSize) + if (!nonFit || nonFit > m_RemainingSize || m_RemainingSize < fullMsgLen/5) { CompleteCurrentTunnelDataMessage (); CreateCurrentTunnelDataMessage (); From 5e0a8ed2324b4a6966fff0fe2b70a21e3c15dd14 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 16:06:07 -0400 Subject: [PATCH 0397/2950] set UDP receive buffer size --- libi2pd_client/I2PTunnel.cpp | 3 +++ libi2pd_client/I2PTunnel.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 74175b14..d05a97b7 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -692,6 +692,7 @@ namespace client LocalPort(ourPort), RemotePort(theirPort) { + IPSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU )); memcpy(Identity, to->data(), 32); Receive(); } @@ -791,6 +792,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 )); + auto dgram = m_LocalDest->CreateDatagramDestination(gzip); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 19d553da..eb1d8ed9 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -167,7 +167,7 @@ namespace client const uint64_t I2P_UDP_SESSION_TIMEOUT = 1000 * 60 * 2; /** max size for i2p udp */ - const size_t I2P_UDP_MAX_MTU = i2p::datagram::MAX_DATAGRAM_SIZE; + const size_t I2P_UDP_MAX_MTU = 64*1024; struct UDPSession { From 61897ae16c151f67e73bb3f13c3c0e513acb05e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 12 Jun 2020 20:42:54 -0400 Subject: [PATCH 0398/2950] crypto.ratchet.inboundTags --- libi2pd/Destination.cpp | 3 +++ libi2pd/Destination.h | 2 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 31 +++++++++++++++++------ libi2pd/Garlic.cpp | 3 ++- libi2pd/Garlic.h | 3 +++ libi2pd_client/ClientContext.cpp | 2 ++ 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6d5fb916..a764224c 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -56,6 +56,9 @@ namespace client if (it != params->end ()) numTags = std::stoi(it->second); LogPrint (eLogInfo, "Destination: parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags"); + it = params->find (I2CP_PARAM_RATCHET_INBOUND_TAGS); + if (it != params->end ()) + SetNumRatchetInboundTags (std::stoi(it->second)); it = params->find (I2CP_PARAM_EXPLICIT_PEERS); if (it != params->end ()) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 139423c6..1d5c0a55 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -57,6 +57,8 @@ namespace client const int STREAM_REQUEST_TIMEOUT = 60; //in seconds const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend"; const int DEFAULT_TAGS_TO_SEND = 40; + const char I2CP_PARAM_RATCHET_INBOUND_TAGS[] = "crypto.ratchet.inboundTags"; + 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_LEASESET_TYPE[] = "i2cp.leaseSetType"; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a578131d..ad91382f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -341,7 +341,8 @@ namespace garlic newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (newTagset, ECIESX25519_MAX_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (newTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MAX_NUM_GENERATED_TAGS); receiveTagset->Expire (); LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created"); } @@ -459,7 +460,8 @@ namespace garlic m_SendTagset = std::make_shared(shared_from_this ()); m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt @@ -548,7 +550,8 @@ namespace garlic auto receiveTagset = std::make_shared(shared_from_this ()); receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS); + GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? + GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); } i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) // decrypt payload @@ -610,11 +613,23 @@ namespace garlic return false; } HandlePayload (payload, len - 16, receiveTagset, index); - int moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 - if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; - moreTags -= (receiveTagset->GetNextIndex () - index); - if (moreTags > 0 && GetOwner ()) - GenerateMoreReceiveTags (receiveTagset, moreTags); + if (GetOwner ()) + { + int moreTags = 0; + if (GetOwner ()->GetNumRatchetInboundTags () > 0) // override in settings? + { + if (receiveTagset->GetNextIndex () - index < GetOwner ()->GetNumRatchetInboundTags ()/2) + moreTags = GetOwner ()->GetNumRatchetInboundTags (); + } + else + { + moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 + if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; + moreTags -= (receiveTagset->GetNextIndex () - index); + } + if (moreTags > 0) + GenerateMoreReceiveTags (receiveTagset, moreTags); + } return true; } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 1170634d..84a0519e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -432,7 +432,8 @@ namespace garlic return ret; } - GarlicDestination::GarlicDestination (): m_NumTags (32) // 32 tags by default + GarlicDestination::GarlicDestination (): m_NumTags (32), // 32 tags by default + m_NumRatchetInboundTags (0) // 0 means standard { m_Ctx = BN_CTX_new (); } diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 6b34231a..70893bec 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -232,6 +232,8 @@ namespace garlic void CleanUp (); void SetNumTags (int numTags) { m_NumTags = numTags; }; int GetNumTags () const { return m_NumTags; }; + void SetNumRatchetInboundTags (int numTags) { m_NumRatchetInboundTags = numTags; }; + int GetNumRatchetInboundTags () const { return m_NumRatchetInboundTags; }; std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); @@ -278,6 +280,7 @@ namespace garlic std::unordered_map m_Sessions; std::unordered_map, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session // incoming + int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session // DeliveryStatus diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 54007c95..0348aeeb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -461,6 +461,8 @@ namespace client } std::string explicitPeers = GetI2CPStringOption(section, I2CP_PARAM_EXPLICIT_PEERS, ""); if (explicitPeers.length () > 0) options[I2CP_PARAM_EXPLICIT_PEERS] = explicitPeers; + std::string ratchetInboundTags = GetI2CPStringOption(section, I2CP_PARAM_RATCHET_INBOUND_TAGS, ""); + if (ratchetInboundTags.length () > 0) options[I2CP_PARAM_RATCHET_INBOUND_TAGS] = ratchetInboundTags; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const From 79858d4372f1754363ce61059208f5ba4c4329d5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 13 Jun 2020 18:19:24 +0300 Subject: [PATCH 0399/2950] [webconsole] adaptive styling Signed-off-by: R4SAS --- android/assets/tunnels.conf | 2 +- daemon/HTTPServer.cpp | 60 ++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/android/assets/tunnels.conf b/android/assets/tunnels.conf index e95fdf2e..c39a0220 100644 --- a/android/assets/tunnels.conf +++ b/android/assets/tunnels.conf @@ -1,4 +1,4 @@ -[IRC-IRC2P] +#[IRC-IRC2P] #type = client #address = 127.0.0.1 #port = 6668 diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7268ae01..a9588436 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -63,23 +63,40 @@ namespace http { " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " 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; color: initial; padding: 0 5px; }\r\n" - " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" - " .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n" - " .left { float: left; position: absolute; }\r\n" - " .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\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" + " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n" + " .wrapper { margin: 0 auto; padding: 1em; max-width: 56em; }\r\n" + " .menu { float: left; } .menu a { display: block; padding: 2px; }\r\n" + " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; }\r\n" " .tunnel.expiring { color: #D3AE3F; }\r\n" " .tunnel.failed { color: #D33F3F; }\r\n" " .tunnel.building { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { display: table; border-collapse: collapse; text-align: center; }\r\n" - " table.extaddr { text-align: left; }\r\n table.services { width: 100%; }" + " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n" " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" " .slide div.content, .slide [type='checkbox'] { display: none; }\r\n" " .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" + " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ + " .menu { width: 100%; display: block; float: none; position: unset; font-size: 24px;\r\n" + " text-align: center; }\r\n" + " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%; font-size: 1.2em;\r\n" + " text-align: center; line-height: 28px; }\r\n" + " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" + " .header { margin: 0.5em 0; } 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%; height: 50px; text-align: center; /* margin-top: 15px; */ padding: 5px;\r\n" + " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 35px; }\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: 22px; }\r\n" + " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n" + " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 50px; display: -webkit-inline-box; margin-top: 25px; }\r\n" + " }\r\n" /* adaptive style */ "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -181,30 +198,31 @@ namespace http { #else " \r\n" #endif + " \r\n" " \r\n" " Purple I2P " VERSION " Webconsole\r\n" << cssStyles << "\r\n"; s << "\r\n" - "
i2pd webconsole
\r\n" - "
\r\n" - "
\r\n" - " Main page
\r\n
\r\n" - " Router commands
\r\n" - " Local destinations
\r\n"; + "
i2pd webconsole
\r\n" + "
\r\n" + "
\r\n" + " Main page
\r\n" + " Router commands\r\n" + " Local destinations\r\n"; if (i2p::context.IsFloodfill ()) - s << " LeaseSets
\r\n"; + s << " LeaseSets\r\n"; s << - " Tunnels
\r\n" - " Transit tunnels
\r\n" - " Transports
\r\n" - " I2P tunnels
\r\n"; + " Tunnels\r\n" + " Transit tunnels\r\n" + " Transports\r\n" + " I2P tunnels\r\n"; if (i2p::client::context.GetSAMBridge ()) - s << " SAM sessions
\r\n"; + s << " SAM sessions\r\n"; s << "
\r\n" - "
"; + "
"; } static void ShowPageTail (std::stringstream& s) @@ -416,7 +434,7 @@ namespace http { out_tags += it.second->GetNumOutgoingTags (); } s << "
\r\n\r\n" - << "
\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -432,7 +450,7 @@ namespace http { ecies_sessions++; } s << "
\r\n\r\n" - << "
\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; } else s << "Tags sessions: 0
\r\n"; s << "
\r\n"; From a5fed64f38c7f0b21f31297161ef15fa50f1d79e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 13 Jun 2020 18:33:39 +0300 Subject: [PATCH 0400/2950] [webconsole] update sliders html and css Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a9588436..41f198c8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -66,7 +66,7 @@ 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: 56em; }\r\n" + " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" " .menu { float: left; } .menu a { display: block; padding: 2px; }\r\n" " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; }\r\n" @@ -77,8 +77,8 @@ namespace http { " table { display: table; border-collapse: collapse; text-align: center; }\r\n" " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n" " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" - " .slide div.content, .slide [type='checkbox'] { display: none; }\r\n" - " .slide [type='checkbox']:checked ~ div.content { display: block; margin-top: 0; padding: 0; }\r\n" + " .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n" + " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ @@ -284,7 +284,7 @@ namespace http { s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
"; if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) { - s << "\r\n\r\n
\r\n"; + s << "\r\n\r\n
\r\n"; } if(includeHiddenContent) { s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; @@ -391,7 +391,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"; } @@ -399,7 +399,7 @@ namespace http { if(dest->GetNumRemoteLeaseSets()) { s << "
\r\n\r\n
\r\n"; + << "\r\n\r\n
\r\n
AddressTypeEncType
"; for(auto& it: dest->GetLeaseSets ()) s << "\r\n"; s << "
AddressTypeEncType
" << it.first.ToBase32 () << "" << (int)it.second->GetStoreType () << "" << (int)it.second->GetEncryptionType () <<"
\r\n
\r\n
\r\n
\r\n"; @@ -433,8 +433,8 @@ namespace http { 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 () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -449,8 +449,8 @@ 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 () << "
DestinationStatus
\r\n
\r\n
\r\n"; } else s << "Tags sessions: 0
\r\n"; s << "
\r\n"; @@ -549,7 +549,7 @@ namespace http { if (!ls->IsValid()) s << "
!! Invalid !!
\r\n"; s << "
\r\n"; - s << "\r\n
\r\n"; + s << "\r\n
\r\n"; s << "Store type: " << (int)storeType << "
\r\n"; s << "Expires: " << ConvertTime(ls->GetExpirationTime()) << "
\r\n"; if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2) @@ -700,13 +700,13 @@ namespace http { if (!tmp_s.str ().empty ()) { s << "
\r\n\r\n
" + << " ( " << cnt << " )\r\n\r\n
" << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { s << "
\r\n\r\n
" + << "v6 ( " << cnt6 << " )\r\n\r\n
" << tmp_s6.str () << "
\r\n
\r\n"; } } @@ -734,7 +734,7 @@ namespace http { auto sessions = ssuServer->GetSessions (); if (!sessions.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions) { auto endpoint = it.second->GetRemoteEndpoint (); @@ -751,7 +751,7 @@ namespace http { auto sessions6 = ssuServer->GetSessionsV6 (); if (!sessions6.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions6) { auto endpoint = it.second->GetRemoteEndpoint (); From 1a39f7e5c608c6dd2443aef27534f05d9e56f4f9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 13 Jun 2020 16:18:12 -0400 Subject: [PATCH 0401/2950] GarlicRoutingPath per session --- libi2pd/Datagram.cpp | 118 +++++++++++++++++++------------------------ libi2pd/Datagram.h | 2 - 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 5a196c3a..ad679cc0 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -281,94 +281,82 @@ namespace datagram std::shared_ptr DatagramSession::GetSharedRoutingPath () { - if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) + if (!m_RemoteLeaseSet || m_RemoteLeaseSet->IsExpired ()) { - if(!m_RemoteLeaseSet) { - m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - } - if(!m_RemoteLeaseSet) { - // no remote lease set - if(!m_RequestingLS) { + m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); + if (!m_RemoteLeaseSet) + { + if(!m_RequestingLS) + { m_RequestingLS = true; m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1)); } return nullptr; - } + } + } + + if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); - } + auto path = m_RoutingSession->GetSharedRoutingPath(); - if(path) { - if (m_CurrentOutboundTunnel && !m_CurrentOutboundTunnel->IsEstablished()) { + if (path) + { + if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ()) // bad outbound tunnel, switch outbound tunnel - m_CurrentOutboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(m_CurrentOutboundTunnel); - path->outboundTunnel = m_CurrentOutboundTunnel; - } - if(m_CurrentRemoteLease && m_CurrentRemoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { + path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel); + + if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) + { // bad lease, switch to next one - if(m_RemoteLeaseSet && m_RemoteLeaseSet->IsExpired()) - m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - if(m_RemoteLeaseSet) { - auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding([&](const i2p::data::Lease& l) -> bool { - return l.tunnelID == m_CurrentRemoteLease->tunnelID; - }); + if (m_RemoteLeaseSet) + { + auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding( + [&](const i2p::data::Lease& l) -> bool + { + return l.tunnelID == path->remoteLease->tunnelID; + }); auto sz = ls.size(); - if (sz) { + if (sz) + { auto idx = rand() % sz; - m_CurrentRemoteLease = ls[idx]; + path->remoteLease = ls[idx]; } - } else { + else + path->remoteLease = nullptr; + } + else // no remote lease set? LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32()); - } - path->remoteLease = m_CurrentRemoteLease; } - } else { + } + else + { // no current path, make one path = std::make_shared(); - // switch outbound tunnel if bad - if(m_CurrentOutboundTunnel == nullptr || ! m_CurrentOutboundTunnel->IsEstablished()) { - m_CurrentOutboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(m_CurrentOutboundTunnel); - } - // switch lease if bad - if(m_CurrentRemoteLease && m_CurrentRemoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { - if(!m_RemoteLeaseSet) { - m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - } - if(m_RemoteLeaseSet) { - // pick random next good lease - auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding([&] (const i2p::data::Lease & l) -> bool { - if(m_CurrentRemoteLease) - return l.tunnelGateway == m_CurrentRemoteLease->tunnelGateway; - return false; - }); - auto sz = ls.size(); - if(sz) { - auto idx = rand() % sz; - m_CurrentRemoteLease = ls[idx]; - } - } else { - // no remote lease set currently, bail - LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32()); - return nullptr; - } - } else if (!m_CurrentRemoteLease) { - if(!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); - if (m_RemoteLeaseSet) + path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(); + + if (m_RemoteLeaseSet) + { + // pick random next good lease + auto ls = m_RemoteLeaseSet->GetNonExpiredLeases(); + auto sz = ls.size(); + if (sz) { - auto ls = m_RemoteLeaseSet->GetNonExpiredLeases(); - auto sz = ls.size(); - if (sz) { - auto idx = rand() % sz; - m_CurrentRemoteLease = ls[idx]; - } + auto idx = rand() % sz; + path->remoteLease = ls[idx]; } + + + } + else + { + // no remote lease set currently, bail + LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32()); + return nullptr; } - path->outboundTunnel = m_CurrentOutboundTunnel; - path->remoteLease = m_CurrentRemoteLease; m_RoutingSession->SetSharedRoutingPath(path); } return path; - } void DatagramSession::HandleLeaseSetUpdated(std::shared_ptr ls) diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 94fe422c..66e9e909 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -95,8 +95,6 @@ namespace datagram i2p::data::IdentHash m_RemoteIdent; std::shared_ptr m_RemoteLeaseSet; std::shared_ptr m_RoutingSession; - std::shared_ptr m_CurrentRemoteLease; - std::shared_ptr m_CurrentOutboundTunnel; std::vector > m_SendQueue; uint64_t m_LastUse; bool m_RequestingLS; From 0f309377ecf57c9edc23324da8368c22624fa5b1 Mon Sep 17 00:00:00 2001 From: Anton Nesterov Date: Sat, 13 Jun 2020 20:46:17 +0000 Subject: [PATCH 0402/2950] Improve AppArmor profile - give it a name - import needed abstractions - allow local additions - cleanup --- contrib/apparmor/usr.sbin.i2pd | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/contrib/apparmor/usr.sbin.i2pd b/contrib/apparmor/usr.sbin.i2pd index 6cc80609..1e47cd74 100644 --- a/contrib/apparmor/usr.sbin.i2pd +++ b/contrib/apparmor/usr.sbin.i2pd @@ -4,34 +4,22 @@ # #include -/usr/sbin/i2pd { +profile i2pd /{usr/,}sbin/i2pd { #include - - network inet dgram, - network inet stream, - network inet6 dgram, - network inet6 stream, - network netlink raw, - - /etc/gai.conf r, - /etc/host.conf r, - /etc/hosts r, - /etc/nsswitch.conf r, - /etc/resolv.conf r, - /run/resolvconf/resolv.conf r, - /run/systemd/resolve/resolv.conf r, - /run/systemd/resolve/stub-resolv.conf r, + #include + #include # path specific (feel free to modify if you have another paths) /etc/i2pd/** r, - /run/i2pd/i2pd.pid rwk, /var/lib/i2pd/** rw, /var/log/i2pd/i2pd.log w, - /var/run/i2pd/i2pd.pid rwk, - /usr/sbin/i2pd mr, - /usr/share/i2pd/** r, + /{var/,}run/i2pd/i2pd.pid rwk, + /{usr/,}sbin/i2pd mr, + @{system_share_dirs}/i2pd/** r, # user homedir (if started not by init.d or systemd) owner @{HOME}/.i2pd/ rw, owner @{HOME}/.i2pd/** rwk, + + #include if exists } From 69194118dfe3c6e0201efc3db6671bbf1d81e32e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 13 Jun 2020 21:24:16 -0400 Subject: [PATCH 0403/2950] generate random padding length in bulk --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 +++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index ad91382f..87fd13ed 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -96,6 +96,7 @@ namespace garlic ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) { + RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0; ResetKeys (); } @@ -745,8 +746,12 @@ namespace garlic int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size { - RAND_bytes (&paddingSize, 1); - paddingSize &= 0x0F; // 0 - 15 + paddingSize = m_PaddingSizes[m_NextPaddingSize++] & 0x0F; // 0 - 15 + if (m_NextPaddingSize >= 32) + { + RAND_bytes (m_PaddingSizes, 32); + m_NextPaddingSize = 0; + } if (delta > 3) { delta -= 3; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index d121842d..727c48ac 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -188,7 +188,8 @@ namespace garlic std::list > m_AckRequests; // (tagsetid, index) bool m_SendReverseKey = false, m_SendForwardKey = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; - + uint8_t m_PaddingSizes[32], m_NextPaddingSize; + public: // for HTTP only From 1e609acb035dba27116d3f3b4f3a63740aa52e3d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 14 Jun 2020 11:16:08 -0400 Subject: [PATCH 0404/2950] keep sending through first successive routing path --- libi2pd/Datagram.cpp | 20 +++++++++++++++++--- libi2pd/Datagram.h | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index ad679cc0..844611d3 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -296,7 +296,23 @@ namespace datagram } if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) - m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); + { + bool found = false; + for (auto& it: m_PendingRoutingSessions) + if (it->GetOwner ()) // found established session + { + m_RoutingSession = it; + m_PendingRoutingSessions.clear (); + found = true; + break; + } + if (!found) + { + m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); + if (!m_RoutingSession->GetOwner ()) + m_PendingRoutingSessions.push_back (m_RoutingSession); + } + } auto path = m_RoutingSession->GetSharedRoutingPath(); if (path) @@ -345,8 +361,6 @@ namespace datagram auto idx = rand() % sz; path->remoteLease = ls[idx]; } - - } else { diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index 66e9e909..5dd6c8b6 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -95,6 +95,7 @@ namespace datagram i2p::data::IdentHash m_RemoteIdent; std::shared_ptr m_RemoteLeaseSet; std::shared_ptr m_RoutingSession; + std::vector > m_PendingRoutingSessions; std::vector > m_SendQueue; uint64_t m_LastUse; bool m_RequestingLS; From 8d903a09e2a20d790fe287ca66eb4b4c458c8efa Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 14 Jun 2020 22:18:41 +0300 Subject: [PATCH 0405/2950] [Docker] drop boost-python2 --- contrib/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index 6b6250d0..be3feea7 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -36,7 +36,7 @@ RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool zlib && 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 boost-python2 linux-headers boost-prg_exec_monitor \ + 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 From 70e4cbc0236d253b68d6747c0a3c046f9c095384 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 15 Jun 2020 20:10:47 -0400 Subject: [PATCH 0406/2950] differentiate UDP server sessions by port --- libi2pd_client/I2PTunnel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index d05a97b7..95f56873 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -611,7 +611,7 @@ namespace client void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { - if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0]) + if (!m_LastSession || m_LastSession->Identity.GetLL()[0] != from.GetIdentHash ().GetLL()[0] || fromPort != m_LastSession->RemotePort) { std::lock_guard lock(m_SessionsMutex); m_LastSession = ObtainUDPSession(from, toPort, fromPort); @@ -659,7 +659,7 @@ namespace client auto ih = from.GetIdentHash(); for (auto & s : m_Sessions ) { - if (s->Identity.GetLL()[0] == ih.GetLL()[0]) + if (s->Identity.GetLL()[0] == ih.GetLL()[0] && remotePort == s->RemotePort) { /** found existing session */ LogPrint(eLogDebug, "UDPServer: found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); From 31494267e5856b0f685f323e6cfcbbd66dde16dd Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2020 14:24:25 -0400 Subject: [PATCH 0407/2950] fixed datagram idle crash --- libi2pd/Datagram.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 844611d3..b9938043 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -318,8 +318,12 @@ namespace datagram if (path) { if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ()) + { // bad outbound tunnel, switch outbound tunnel path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel); + if (!path->outboundTunnel) + m_RoutingSession->SetSharedRoutingPath (nullptr); + } if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { @@ -338,11 +342,14 @@ namespace datagram path->remoteLease = ls[idx]; } else - path->remoteLease = nullptr; + m_RoutingSession->SetSharedRoutingPath (nullptr); } else + { // no remote lease set? LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32()); + m_RoutingSession->SetSharedRoutingPath (nullptr); + } } } else @@ -350,7 +357,8 @@ namespace datagram // no current path, make one path = std::make_shared(); path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(); - + if (!path->outboundTunnel) return nullptr; + if (m_RemoteLeaseSet) { // pick random next good lease @@ -361,6 +369,8 @@ namespace datagram auto idx = rand() % sz; path->remoteLease = ls[idx]; } + else + return nullptr; } else { From 951ec567c7769e2f4b8adf1c5876052260821e89 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 17 Jun 2020 21:06:35 -0400 Subject: [PATCH 0408/2950] don't try to connect though teminated local destination --- libi2pd_client/SAM.cpp | 23 +++++++++++++++-------- libi2pd_client/SAM.h | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 4723d168..63b9c7ed 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -494,7 +494,7 @@ namespace client context.GetAddressBook().InsertFullAddress(dest); auto leaseSet = session->localDestination->FindLeaseSet(dest->GetIdentHash()); if (leaseSet) - Connect(leaseSet); + Connect(leaseSet, session); else { session->localDestination->RequestDestination(dest->GetIdentHash(), @@ -509,18 +509,25 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } - void SAMSocket::Connect (std::shared_ptr remote) + void SAMSocket::Connect (std::shared_ptr remote, std::shared_ptr session) { - auto session = m_Owner.FindSession(m_ID); - if(session) + if (!session) session = m_Owner.FindSession(m_ID); + if (session) { m_SocketType = eSAMSocketTypeStream; m_Stream = session->localDestination->CreateStream (remote); - m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send - m_BufferOffset = 0; - I2PReceive (); - SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + if (m_Stream) + { + m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send + m_BufferOffset = 0; + I2PReceive (); + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + } + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } void SAMSocket::HandleConnectLeaseSetRequestComplete (std::shared_ptr leaseSet) diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index ceda5253..7b1702f5 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -134,7 +134,7 @@ namespace client size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 void ExtractParams (char * buf, std::map& params); - void Connect (std::shared_ptr remote); + void Connect (std::shared_ptr remote, std::shared_ptr session = nullptr); void HandleConnectLeaseSetRequestComplete (std::shared_ptr leaseSet); void SendNamingLookupReply (std::shared_ptr identity); void HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr leaseSet, std::string name); From a0b35ebd3ef68dd4d4ccacf6cef218000e618c2f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 22 Jun 2020 22:32:18 -0400 Subject: [PATCH 0409/2950] mark NTCP2 unreachable routers --- libi2pd/NTCP2.cpp | 3 ++- libi2pd/Transports.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 8b44a795..60eab17c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1305,7 +1305,8 @@ namespace transport if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogInfo, "NTCP2: Not connected in ", timeout, " seconds"); - //i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); + if (conn->GetRemoteIdentity ()) + i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); conn->Terminate (); } }); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 7157306d..6f163e5f 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -440,7 +440,7 @@ namespace transport { // NTCP2 have priority over NTCP auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address) + if (address && !peer.router->IsUnreachable ()) { auto s = std::make_shared (*m_NTCP2Server, peer.router); From 61e9c31f0dc3a3bda295fd4fdb0f80a3ac099ca9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Jun 2020 11:29:54 -0400 Subject: [PATCH 0410/2950] don't hold RouterInfo after successive connect --- libi2pd/Transports.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 6f163e5f..7da0f63b 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -431,6 +431,8 @@ namespace transport bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer) { + if (!peer.router) // reconnect + peer.router = netdb.FindRouter (ident); // try to get new one from netdb if (peer.router) // we have RI already { if (!peer.numAttempts) // NTCP2 @@ -638,6 +640,7 @@ namespace transport auto it = m_Peers.find (ident); if (it != m_Peers.end ()) { + it->second.router = nullptr; // we don't need RouterInfo after successive connect bool sendDatabaseStore = true; if (it->second.delayedMessages.size () > 0) { From df9965e1295de377516cb3a15aa68ef1a86c71f6 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jun 2020 18:19:31 -0400 Subject: [PATCH 0411/2950] use unordered_map for peers --- libi2pd/Transports.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index cdfbfccf..95c7aedb 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -157,7 +157,7 @@ namespace transport SSUServer * m_SSUServer; NTCP2Server * m_NTCP2Server; mutable std::mutex m_PeersMutex; - std::map m_Peers; + std::unordered_map m_Peers; DHKeysPairSupplier m_DHKeysPairSupplier; From 1f31fdc257ec0a0f44fd263d0fb0ed9fa14464a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 29 Jun 2020 20:02:09 -0400 Subject: [PATCH 0412/2950] pre-calculate ephemeral keys for x25519 --- libi2pd/NTCP2.cpp | 8 +++---- libi2pd/NTCP2.h | 4 ++-- libi2pd/Transports.cpp | 52 +++++++++++++++++++++++++++++------------- libi2pd/Transports.h | 23 ++++++++++++------- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 60eab17c..f1f7e59f 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -83,7 +83,7 @@ namespace transport void NTCP2Establisher::KDF1Alice () { - KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); + KeyDerivationFunction1 (m_RemoteStaticKey, *m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); } void NTCP2Establisher::KDF1Bob () @@ -102,7 +102,7 @@ namespace transport // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; - m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); + m_EphemeralKeys->Agree (GetRemotePub (), inputKeyMaterial); MixKey (inputKeyMaterial); } @@ -127,13 +127,13 @@ namespace transport void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); + m_EphemeralKeys->Agree (m_RemoteStaticKey, inputKeyMaterial); MixKey (inputKeyMaterial); } void NTCP2Establisher::CreateEphemeralKey () { - m_EphemeralKeys.GenerateKeys (); + m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); } void NTCP2Establisher::CreateSessionRequestMessage () diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 8b8c6acb..df72fed0 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -79,7 +79,7 @@ namespace transport NTCP2Establisher (); ~NTCP2Establisher (); - const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); }; + const uint8_t * GetPub () const { return m_EphemeralKeys->GetPublicKey (); }; const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set @@ -110,7 +110,7 @@ namespace transport bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce); bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); - i2p::crypto::X25519Keys m_EphemeralKeys; + std::shared_ptr m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/; i2p::data::IdentHash m_RemoteIdentHash; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 7da0f63b..edfe33fa 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -21,23 +21,27 @@ namespace i2p { namespace transport { - DHKeysPairSupplier::DHKeysPairSupplier (int size): + template + EphemeralKeysSupplier::EphemeralKeysSupplier (int size): m_QueueSize (size), m_IsRunning (false), m_Thread (nullptr) { } - DHKeysPairSupplier::~DHKeysPairSupplier () + template + EphemeralKeysSupplier::~EphemeralKeysSupplier () { Stop (); } - void DHKeysPairSupplier::Start () + template + void EphemeralKeysSupplier::Start () { m_IsRunning = true; - m_Thread = new std::thread (std::bind (&DHKeysPairSupplier::Run, this)); + m_Thread = new std::thread (std::bind (&EphemeralKeysSupplier::Run, this)); } - void DHKeysPairSupplier::Stop () + template + void EphemeralKeysSupplier::Stop () { { std::unique_lock l(m_AcquiredMutex); @@ -52,19 +56,20 @@ namespace transport } } - void DHKeysPairSupplier::Run () + template + void EphemeralKeysSupplier::Run () { while (m_IsRunning) { int num, total = 0; while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 10) { - CreateDHKeysPairs (num); + CreateEphemeralKeys (num); total += num; } if (total >= 10) { - LogPrint (eLogWarning, "Transports: ", total, " DH keys generated at the time"); + LogPrint (eLogWarning, "Transports: ", total, " ephemeral keys generated at the time"); std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break } else @@ -76,24 +81,26 @@ namespace transport } } - void DHKeysPairSupplier::CreateDHKeysPairs (int num) + template + void EphemeralKeysSupplier::CreateEphemeralKeys (int num) { if (num > 0) { for (int i = 0; i < num; i++) { - auto pair = std::make_shared (); + auto pair = std::make_shared (); pair->GenerateKeys (); - std::unique_lock l(m_AcquiredMutex); + std::unique_lock l(m_AcquiredMutex); m_Queue.push (pair); } } } - std::shared_ptr DHKeysPairSupplier::Acquire () + template + std::shared_ptr EphemeralKeysSupplier::Acquire () { { - std::unique_lock l(m_AcquiredMutex); + std::unique_lock l(m_AcquiredMutex); if (!m_Queue.empty ()) { auto pair = m_Queue.front (); @@ -103,12 +110,13 @@ namespace transport } } // queue is empty, create new - auto pair = std::make_shared (); + auto pair = std::make_shared (); pair->GenerateKeys (); return pair; } - void DHKeysPairSupplier::Return (std::shared_ptr pair) + template + void EphemeralKeysSupplier::Return (std::shared_ptr pair) { if (pair) { @@ -126,7 +134,7 @@ namespace transport m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_NTCPServer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), - m_DHKeysPairSupplier (5), // 5 pre-generated keys + m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 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), @@ -158,6 +166,7 @@ namespace transport i2p::config::GetOption("nat", m_IsNAT); m_DHKeysPairSupplier.Start (); + m_X25519KeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); @@ -312,6 +321,7 @@ namespace transport } m_DHKeysPairSupplier.Stop (); + m_X25519KeysPairSupplier.Stop (); m_IsRunning = false; if (m_Service) m_Service->stop (); if (m_Thread) @@ -630,6 +640,16 @@ namespace transport m_DHKeysPairSupplier.Return (pair); } + std::shared_ptr Transports::GetNextX25519KeysPair () + { + return m_X25519KeysPairSupplier.Acquire (); + } + + void Transports::ReuseX25519KeysPair (std::shared_ptr pair) + { + m_X25519KeysPairSupplier.Return (pair); + } + void Transports::PeerConnected (std::shared_ptr session) { m_Service->post([session, this]() diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 95c7aedb..48eee4b4 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -32,33 +32,37 @@ namespace i2p { namespace transport { - class DHKeysPairSupplier + template + class EphemeralKeysSupplier { + // called from this file only, so implementation is in Transports.cpp public: - DHKeysPairSupplier (int size); - ~DHKeysPairSupplier (); + EphemeralKeysSupplier (int size); + ~EphemeralKeysSupplier (); void Start (); void Stop (); - std::shared_ptr Acquire (); - void Return (std::shared_ptr pair); + std::shared_ptr Acquire (); + void Return (std::shared_ptr pair); private: void Run (); - void CreateDHKeysPairs (int num); + void CreateEphemeralKeys (int num); private: const int m_QueueSize; - std::queue > m_Queue; + std::queue > m_Queue; bool m_IsRunning; std::thread * m_Thread; std::condition_variable m_Acquired; std::mutex m_AcquiredMutex; }; - + typedef EphemeralKeysSupplier DHKeysPairSupplier; + typedef EphemeralKeysSupplier X25519KeysPairSupplier; + struct Peer { int numAttempts; @@ -97,6 +101,8 @@ namespace transport boost::asio::io_service& GetService () { return *m_Service; }; std::shared_ptr GetNextDHKeysPair (); void ReuseDHKeysPair (std::shared_ptr pair); + std::shared_ptr GetNextX25519KeysPair (); + void ReuseX25519KeysPair (std::shared_ptr pair); void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); void SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs); @@ -160,6 +166,7 @@ namespace transport std::unordered_map m_Peers; DHKeysPairSupplier m_DHKeysPairSupplier; + X25519KeysPairSupplier m_X25519KeysPairSupplier; std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; // bytes per second From 5f1e66d64b2c92af5082f9b29b5e6d52ad4130d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jun 2020 13:00:41 -0400 Subject: [PATCH 0413/2950] use pre-calculated x25519 ephemeral keys for ratchets --- libi2pd/Crypto.h | 4 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 59 +++++++++++++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 4 +- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 9ca3163f..ab84e56a 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -91,6 +91,9 @@ namespace crypto void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false); void Agree (const uint8_t * pub, uint8_t * shared); + bool IsElligatorIneligible () const { return m_IsElligatorIneligible; } + void SetElligatorIneligible () { m_IsElligatorIneligible = true; } + private: uint8_t m_PublicKey[32]; @@ -101,6 +104,7 @@ namespace crypto BN_CTX * m_Ctx; uint8_t m_PrivateKey[32]; #endif + bool m_IsElligatorIneligible = false; // true if definitly ineligible }; // ElGamal diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 87fd13ed..8e0e743d 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -16,6 +16,7 @@ #include "Timestamp.h" #include "Tunnel.h" #include "TunnelPool.h" +#include "Transports.h" #include "ECIESX25519AEADRatchetSession.h" namespace i2p @@ -137,12 +138,38 @@ namespace garlic bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf) { + bool ineligible = false; + while (!ineligible) + { + m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + ineligible = m_EphemeralKeys->IsElligatorIneligible (); + if (!ineligible) // we haven't tried it yet + { + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys->GetPublicKey (), buf)) + return true; // success + // otherwise return back + m_EphemeralKeys->SetElligatorIneligible (); + i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); + } + else + i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); + } + // we still didn't find elligator eligible pair for (int i = 0; i < 10; i++) { - m_EphemeralKeys.GenerateKeys (); - if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf)) + // create new + m_EphemeralKeys = std::make_shared(); + m_EphemeralKeys->GenerateKeys (); + if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys->GetPublicKey (), buf)) return true; // success + else + { + // let NTCP2 use it + m_EphemeralKeys->SetElligatorIneligible (); + i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys); + } } + LogPrint (eLogError, "Garlic: Can't generate elligator eligible x25519 keys"); return false; } @@ -294,7 +321,7 @@ namespace garlic if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG) memcpy (m_NextSendRatchet->remote, buf, 32); uint8_t sharedSecret[32], tagsetKey[32]; - m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret); + m_NextSendRatchet->key->Agree (m_NextSendRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared (shared_from_this ()); newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); @@ -326,7 +353,7 @@ namespace garlic int tagsetID = 2*keyID; if (newKey) { - m_NextReceiveRatchet->key.GenerateKeys (); + m_NextReceiveRatchet->key = i2p::transport::transports.GetNextX25519KeysPair (); m_NextReceiveRatchet->newKey = true; tagsetID++; } @@ -336,7 +363,7 @@ namespace garlic memcpy (m_NextReceiveRatchet->remote, buf, 32); uint8_t sharedSecret[32], tagsetKey[32]; - m_NextReceiveRatchet->key.Agree (m_NextReceiveRatchet->remote, sharedSecret); + m_NextReceiveRatchet->key->Agree (m_NextReceiveRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) auto newTagset = std::make_shared(shared_from_this ()); newTagset->SetTagSetID (tagsetID); @@ -364,7 +391,7 @@ namespace garlic else m_NextSendRatchet.reset (new DHRatchet ()); if (m_NextSendRatchet->newKey) - m_NextSendRatchet->key.GenerateKeys (); + m_NextSendRatchet->key->GenerateKeys (); m_SendForwardKey = true; LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); @@ -384,9 +411,9 @@ namespace garlic // KDF1 MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk) + MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) + m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) // encrypt static key section uint8_t nonce[12]; @@ -435,11 +462,11 @@ namespace garlic offset += 32; // KDF for Reply Key Section MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) + m_EphemeralKeys->Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) - m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) + m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) uint8_t nonce[12]; CreateNonce (0, nonce); @@ -485,7 +512,7 @@ namespace garlic // recalculate h with new tag memcpy (m_H, m_NSRH, 32); MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) - MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk) + MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t nonce[12]; CreateNonce (0, nonce); if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) @@ -524,7 +551,7 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { // only fist time, we assume ephemeral keys the same - m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) @@ -565,6 +592,7 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { m_State = eSessionStateEstablished; + m_EphemeralKeys = nullptr; m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } @@ -643,6 +671,7 @@ namespace garlic case eSessionStateNewSessionReplySent: m_State = eSessionStateEstablished; m_NSRSendTagset = nullptr; + m_EphemeralKeys = nullptr; #if (__cplusplus >= 201703L) // C++ 17 or higher [[fallthrough]]; #endif @@ -813,7 +842,7 @@ namespace garlic htobe16buf (v.data () + offset, keyID); offset += 2; // keyid if (m_NextReceiveRatchet->newKey) { - memcpy (v.data () + offset, m_NextReceiveRatchet->key.GetPublicKey (), 32); + memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); offset += 32; // public key } m_SendReverseKey = false; @@ -828,7 +857,7 @@ namespace garlic htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid if (m_NextSendRatchet->newKey) { - memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32); + memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32); offset += 32; // public key } } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 727c48ac..2dccd865 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -122,7 +122,7 @@ namespace garlic struct DHRatchet { int keyID = 0; - i2p::crypto::X25519Keys key; + std::shared_ptr key; uint8_t remote[32]; // last remote public key bool newKey = true; }; @@ -180,7 +180,7 @@ namespace garlic uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only - i2p::crypto::X25519Keys m_EphemeralKeys; + std::shared_ptr m_EphemeralKeys; SessionState m_State = eSessionStateNew; uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming std::shared_ptr m_SendTagset, m_NSRSendTagset; From 6f2e6ed8873d68f8bdd9e626ed7ac5912beeffd0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 30 Jun 2020 15:05:17 -0400 Subject: [PATCH 0414/2950] key for next send ratchet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8e0e743d..d403c9bd 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -391,7 +391,7 @@ namespace garlic else m_NextSendRatchet.reset (new DHRatchet ()); if (m_NextSendRatchet->newKey) - m_NextSendRatchet->key->GenerateKeys (); + m_NextSendRatchet->key = i2p::transport::transports.GetNextX25519KeysPair (); m_SendForwardKey = true; LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); From 6f17624742b4af654b1c4c604172beb7b2c48787 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 5 Jul 2020 12:53:15 +0800 Subject: [PATCH 0415/2950] Android.mk : openssl-1.1.1d-clang instead of openssl-1.1.1a-clang --- android/jni/Android.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 2376509e..07dc7080 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -53,15 +53,15 @@ include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := crypto -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ssl -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/$(TARGET_ARCH_ABI)/lib/libssl.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1a-clang/include +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libssl.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include LOCAL_STATIC_LIBRARIES := crypto include $(PREBUILT_STATIC_LIBRARY) From e15b2cc5d6531037850b855b36b025ad371b962b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 15 Jun 2020 09:01:17 +0300 Subject: [PATCH 0416/2950] [webconsole] rework lists with tunnels, transit, etc Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 166 ++++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 71 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 41f198c8..c387a402 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -67,35 +67,36 @@ namespace http { " 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 { display: block; padding: 2px; }\r\n" + " .menu { float: left; } .menu a, .commands a { display: block; }\r\n" + " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n" " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 46em; overflow: auto; }\r\n" - " .tunnel.established { color: #56B734; }\r\n" - " .tunnel.expiring { color: #D3AE3F; }\r\n" - " .tunnel.failed { color: #D33F3F; }\r\n" - " .tunnel.building { color: #434343; }\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" " table { display: table; border-collapse: collapse; text-align: center; }\r\n" " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n" + " textarea { word-break: break-all; }\r\n" " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n" " .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n" " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n" " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ - " .menu { width: 100%; display: block; float: none; position: unset; font-size: 24px;\r\n" + " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n" + " text-align: center; }\r\n" + " .menu a, .commands a { padding: 2px; }\r\n" + " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%;\r\n" " text-align: center; }\r\n" - " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%; font-size: 1.2em;\r\n" - " text-align: center; line-height: 28px; }\r\n" " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n" - " .header { margin: 0.5em 0; } small {display: block}\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%; height: 50px; text-align: center; /* margin-top: 15px; */ padding: 5px;\r\n" - " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 35px; }\r\n" + " input { width: 35%; text-align: center; padding: 5px;\r\n" + " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 24px; }\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: 22px; }\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" - " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 50px; display: -webkit-inline-box; margin-top: 25px; }\r\n" + " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n" " }\r\n" /* adaptive style */ "\r\n"; @@ -228,7 +229,7 @@ namespace http { static void ShowPageTail (std::stringstream& s) { s << - "
\r\n" + "
\r\n
\r\n" "\r\n" "\r\n"; } @@ -358,18 +359,19 @@ namespace http { void ShowLocalDestinations (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "Local Destinations:
\r\n
\r\n"; + s << "Local Destinations:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetDestinations ()) { auto ident = it.second->GetIdentHash (); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; + s << "\r\n" << std::endl; } + s << "
\r\n"; auto i2cpServer = i2p::client::context.GetI2CPServer (); if (i2cpServer && !(i2cpServer->GetSessions ().empty ())) { - s << "
I2CP Local Destinations:
\r\n
\r\n"; + s << "
I2CP Local Destinations:
\r\n
\r\n"; for (auto& it: i2cpServer->GetSessions ()) { auto dest = it.second->GetDestination (); @@ -377,10 +379,11 @@ namespace http { { auto ident = dest->GetIdentHash (); auto& name = dest->GetNickname (); - s << "[ "; - s << name << " ] ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"
\r\n" << std::endl; + s << "
[ "; + s << name << " ] ⇔ " << i2p::client::context.GetAddressBook ().ToAddress(ident) <<"
\r\n" << std::endl; } } + s << "
\r\n"; } } @@ -581,54 +584,59 @@ namespace http { void ShowTunnels (std::stringstream& s) { - s << "Tunnels:
\r\n
\r\n"; - s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; + s << "Tunnels:
\r\n"; + s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n
\r\n"; auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool (); - s << "Inbound tunnels:
\r\n"; + s << "Inbound tunnels:
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ()); + s << "
\r\n"; } - s << "
\r\n"; - s << "Outbound tunnels:
\r\n"; + s << "
\r\n
\r\n"; + s << "Outbound tunnels:
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ()); + s << "
\r\n"; } - s << "
\r\n"; + s << "
\r\n"; } static void ShowCommands (std::stringstream& s, uint32_t token) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); /* commands */ - s << "Router Commands
\r\n
\r\n"; - s << " Run peer test
\r\n"; + s << "Router Commands
\r\n
\r\n
\r\n"; + s << " Run peer test\r\n"; //s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << " Decline transit tunnels
\r\n"; + s << " Decline transit tunnels\r\n"; else - s << " Accept transit tunnels
\r\n"; + s << " Accept transit tunnels\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) if (Daemon.gracefulShutdownInterval) - s << " Cancel graceful shutdown
"; + s << " Cancel graceful shutdown\r\n"; else s << " Start graceful shutdown
\r\n"; #elif defined(WIN32_APP) if (i2p::util::DaemonWin32::Instance().isGraceful) - s << " Cancel graceful shutdown
"; + s << " Cancel graceful shutdown\r\n"; else - s << " Graceful shutdown
\r\n"; + s << " Graceful shutdown\r\n"; #endif - s << " Force shutdown
\r\n
\r\n"; + s << " Force shutdown\r\n"; + s << "
"; - s << "Note: any action done here are not persistent and not changes your config files.\r\n
\r\n"; + s << "
\r\nNote: any action done here are not persistent and not changes your config files.\r\n
\r\n"; s << "Logging level
\r\n"; s << " none \r\n"; @@ -651,17 +659,19 @@ namespace http { { if(i2p::tunnel::tunnels.CountTransitTunnels()) { - s << "Transit tunnels:
\r\n
\r\n"; + s << "Transit tunnels:
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) { + s << "
\r\n"; if (std::dynamic_pointer_cast(it)) s << it->GetTunnelID () << " ⇒ "; else if (std::dynamic_pointer_cast(it)) s << " ⇒ " << it->GetTunnelID (); else s << " ⇒ " << it->GetTunnelID () << " ⇒ "; - s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + s << " " << it->GetNumTransmittedBytes () << "
\r\n"; } + s << "
\r\n"; } else { @@ -677,43 +687,44 @@ namespace http { { if (it.second && it.second->IsEstablished () && !it.second->GetSocket ().remote_endpoint ().address ().is_v6 ()) { - // incoming connection doesn't have remote RI + tmp_s << "
\r\n"; if (it.second->IsOutgoing ()) tmp_s << " ⇒ "; tmp_s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " << it.second->GetSocket ().remote_endpoint().address ().to_string (); if (!it.second->IsOutgoing ()) tmp_s << " ⇒ "; tmp_s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - tmp_s << "
\r\n" << std::endl; + tmp_s << "
\r\n" << std::endl; cnt++; } if (it.second && it.second->IsEstablished () && it.second->GetSocket ().remote_endpoint ().address ().is_v6 ()) { + tmp_s6 << "
\r\n"; if (it.second->IsOutgoing ()) tmp_s6 << " ⇒ "; tmp_s6 << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " << "[" << it.second->GetSocket ().remote_endpoint().address ().to_string () << "]"; if (!it.second->IsOutgoing ()) tmp_s6 << " ⇒ "; tmp_s6 << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - tmp_s6 << "
\r\n" << std::endl; + tmp_s6 << "
\r\n" << std::endl; cnt6++; } } if (!tmp_s.str ().empty ()) { s << "
\r\n\r\n
" + << " ( " << cnt << " )\r\n\r\n
" << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { s << "
\r\n\r\n
" + << "v6 ( " << cnt6 << " )\r\n\r\n
" << tmp_s6.str () << "
\r\n
\r\n"; } } void ShowTransports (std::stringstream& s) { - s << "Transports:
\r\n
\r\n"; + s << "Transports:
\r\n"; auto ntcpServer = i2p::transport::transports.GetNTCPServer (); if (ntcpServer) { @@ -734,9 +745,10 @@ namespace http { auto sessions = ssuServer->GetSessions (); if (!sessions.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions) { + s << "
\r\n"; auto endpoint = it.second->GetRemoteEndpoint (); if (it.second->IsOutgoing ()) s << " ⇒ "; s << endpoint.address ().to_string () << ":" << endpoint.port (); @@ -744,16 +756,17 @@ namespace http { s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; if (it.second->GetRelayTag ()) s << " [itag:" << it.second->GetRelayTag () << "]"; - s << "
\r\n" << std::endl; + s << "
\r\n" << std::endl; } s << "
\r\n
\r\n"; } auto sessions6 = ssuServer->GetSessionsV6 (); if (!sessions6.empty ()) { - s << "
\r\n\r\n
"; + s << "
\r\n\r\n
"; for (const auto& it: sessions6) { + s << "
\r\n"; auto endpoint = it.second->GetRemoteEndpoint (); if (it.second->IsOutgoing ()) s << " ⇒ "; s << "[" << endpoint.address ().to_string () << "]:" << endpoint.port (); @@ -761,7 +774,7 @@ namespace http { s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; if (it.second->GetRelayTag ()) s << " [itag:" << it.second->GetRelayTag () << "]"; - s << "
\r\n" << std::endl; + s << "
\r\n" << std::endl; } s << "
\r\n
\r\n"; } @@ -780,13 +793,14 @@ namespace http { if(sam->GetSessions ().size ()) { - s << "SAM Sessions:
\r\n
\r\n"; + s << "SAM Sessions:
\r\n
\r\n"; for (auto& it: sam->GetSessions ()) { auto& name = it.second->localDestination->GetNickname (); - s << ""; - s << name << " (" << it.first << ")
\r\n" << std::endl; + s << "\r\n" << std::endl; } + s << "
\r\n"; } else s << "SAM Sessions: no sessions currently running.
\r\n"; @@ -794,25 +808,28 @@ namespace http { static void ShowSAMSession (std::stringstream& s, const std::string& id) { - std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "SAM Session:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { ShowError(s, "SAM disabled"); return; } + auto session = sam->FindSession (id); if (!session) { ShowError(s, "SAM session not found"); return; } + + std::string webroot; i2p::config::GetOption("http.webroot", webroot); + s << "SAM Session:
\r\n
\r\n"; auto& ident = session->localDestination->GetIdentHash(); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n"; + s << "\r\n"; s << "
\r\n"; - s << "Streams:
\r\n"; + s << "Streams:
\r\n
\r\n"; for (const auto& it: sam->ListSockets(id)) { + s << "
"; switch (it->GetSocketType ()) { case i2p::client::eSAMSocketTypeSession : s << "session"; break; @@ -821,78 +838,85 @@ namespace http { default: s << "unknown"; break; } s << " [" << it->GetSocket ().remote_endpoint() << "]"; - s << "
\r\n"; + s << "
\r\n"; } + s << "
\r\n"; } void ShowI2PTunnels (std::stringstream& s) { std::string webroot; i2p::config::GetOption("http.webroot", webroot); - s << "Client Tunnels:
\r\n
\r\n"; + s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } auto httpProxy = i2p::client::context.GetHttpProxy (); if (httpProxy) { auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << "HTTP Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } auto socksProxy = i2p::client::context.GetSocksProxy (); if (socksProxy) { auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << "SOCKS Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; + auto& serverTunnels = i2p::client::context.GetServerTunnels (); if (!serverTunnels.empty ()) { - s << "
\r\nServer Tunnels:
\r\n
\r\n"; + s << "
\r\nServer Tunnels:
\r\n
\r\n"; for (auto& it: serverTunnels) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; } + auto& clientForwards = i2p::client::context.GetClientForwards (); if (!clientForwards.empty ()) { - s << "
\r\nClient Forwards:
\r\n
\r\n"; + s << "
\r\nClient Forwards:
\r\n
\r\n"; for (auto& it: clientForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << "
"; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; } auto& serverForwards = i2p::client::context.GetServerForwards (); if (!serverForwards.empty ()) { - s << "
\r\nServer Forwards:
\r\n
\r\n"; + s << "
\r\nServer Forwards:
\r\n
\r\n"; for (auto& it: serverForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } + s << "
\r\n"; } } From 2d65402cedf9d788609b47bbeac7faaab88c8591 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 15 Jun 2020 13:05:01 +0300 Subject: [PATCH 0417/2950] [webconsole] update styles Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c387a402..416cf1e4 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -69,6 +69,7 @@ namespace http { " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n" " .menu { float: left; } .menu a, .commands a { display: block; }\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: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n" " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n" @@ -172,7 +173,7 @@ namespace http { default: state = "unknown"; break; } s << " " << state << ((explr) ? " (exploratory)" : "") << ", "; - s << " " << (int) (bytes / 1024) << " KiB
\r\n"; + s << " " << (int) (bytes / 1024) << " KiB\r\n"; } static void SetLogLevel (const std::string& level) @@ -389,7 +390,7 @@ namespace http { static void ShowLeaseSetDestination (std::stringstream& s, std::shared_ptr dest) { - s << "Base64:
\r\n
\r\n
\r\n"; if (dest->IsEncryptedLeaseSet ()) { @@ -402,29 +403,34 @@ namespace http { if(dest->GetNumRemoteLeaseSets()) { s << "
\r\n\r\n
\r\n"; + << "\r\n\r\n
\r\n
AddressTypeEncType
"; for(auto& it: dest->GetLeaseSets ()) s << "\r\n"; s << "
AddressTypeEncType
" << 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"; + auto pool = dest->GetTunnelPool (); if (pool) { - s << "Inbound tunnels:
\r\n"; + s << "Inbound tunnels:
\r\n
\r\n"; for (auto & it : pool->GetInboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); + s << "
\r\n"; } s << "
\r\n"; - s << "Outbound tunnels:
\r\n"; + s << "Outbound tunnels:
\r\n
\r\n"; for (auto & it : pool->GetOutboundTunnels ()) { + s << "
"; it->Print(s); if(it->LatencyIsKnown()) s << " ( " << it->GetMeanLatency() << "ms )"; ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); + s << "
\r\n"; } } s << "
\r\n"; @@ -437,7 +443,7 @@ namespace http { 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"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationAmount
\r\n
\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; @@ -453,7 +459,7 @@ namespace http { 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"; + << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
DestinationStatus
\r\n
\r\n
\r\n"; } else s << "Tags sessions: 0
\r\n"; s << "
\r\n"; @@ -483,11 +489,12 @@ namespace http { s << "RTT"; s << "Window"; s << "Status"; - s << "\r\n\r\n\r\n"; + s << "\r\n\r\n\r\n"; for (const auto& it: dest->GetAllStreams ()) { auto streamDest = i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()); + std::string streamDestShort = streamDest.substr(0,12) + "….b32.i2p"; s << ""; s << "" << it->GetRecvStreamID () << ""; if (it->GetRecvStreamID ()) { @@ -496,7 +503,7 @@ namespace http { } else { s << ""; } - s << "" << streamDest << ""; + s << "" << streamDestShort << ""; s << "" << it->GetNumSentBytes () << ""; s << "" << it->GetNumReceivedBytes () << ""; s << "" << it->GetSendQueueSize () << ""; @@ -531,7 +538,7 @@ namespace http { { if (i2p::data::netdb.GetNumLeaseSets ()) { - s << "LeaseSets:
\r\n
\r\n"; + s << "LeaseSets:
\r\n
\r\n"; int counter = 1; // for each lease set i2p::data::netdb.VisitLeaseSets( @@ -545,13 +552,13 @@ namespace http { else ls.reset (new i2p::data::LeaseSet2 (storeType, leaseSet->GetBuffer(), leaseSet->GetBufferLen())); if (!ls) return; - s << "
\r\n"; + s << "\">\r\n"; if (!ls->IsValid()) - s << "
!! Invalid !!
\r\n"; - s << "
\r\n"; + s << "
!! 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"; @@ -922,7 +929,7 @@ namespace http { std::string ConvertTime (uint64_t time) { - ldiv_t divTime = ldiv(time,1000); + lldiv_t divTime = lldiv(time, 1000); time_t t = divTime.quot; struct tm *tm = localtime(&t); char date[128]; From 4e4c11702371bbbcc9ee87a02448bb36f8815fb4 Mon Sep 17 00:00:00 2001 From: potatowipedlifereverse Date: Tue, 7 Jul 2020 02:01:56 +0300 Subject: [PATCH 0418/2950] whitelist synonim for accesslist --- libi2pd_client/ClientContext.cpp | 2 ++ libi2pd_client/ClientContext.h | 1 + 2 files changed, 3 insertions(+) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 0348aeeb..e8e8eb2d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -663,6 +663,8 @@ namespace client // optional params int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); + if(accessList == "") + 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); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 8a4835c8..05b754fe 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -54,6 +54,7 @@ namespace client const char I2P_SERVER_TUNNEL_SIGNATURE_TYPE[] = "signaturetype"; const char I2P_SERVER_TUNNEL_INPORT[] = "inport"; const char I2P_SERVER_TUNNEL_ACCESS_LIST[] = "accesslist"; + const char I2P_SERVER_TUNNEL_WHITE_LIST[] = "whitelist"; const char I2P_SERVER_TUNNEL_GZIP[] = "gzip"; const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword"; const char I2P_SERVER_TUNNEL_ADDRESS[] = "address"; From 67b94d3533f8e0f0eca2443344c012d06acc5ab5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 7 Jul 2020 15:38:20 -0400 Subject: [PATCH 0419/2950] unordered_map for RouterInfos and LeaseSets --- libi2pd/NetDb.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index 1c65969a..d4501ab9 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -11,7 +11,7 @@ // this file is called NetDb.hpp to resolve conflict with libc's netdb.h on case insensitive fs #include #include -#include +#include #include #include #include @@ -138,9 +138,9 @@ namespace data private: mutable std::mutex m_LeaseSetsMutex; - std::map > m_LeaseSets; + std::unordered_map > m_LeaseSets; mutable std::mutex m_RouterInfosMutex; - std::map > m_RouterInfos; + std::unordered_map > m_RouterInfos; mutable std::mutex m_FloodfillsMutex; std::list > m_Floodfills; From c41554109b76ad3ff4e9b621c86e0f91a533dc54 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 15 Jul 2020 16:20:35 -0400 Subject: [PATCH 0420/2950] change datagram routing path if nothing comes back in 10 seconds --- libi2pd/Datagram.cpp | 7 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 140 +++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 7 +- libi2pd/Garlic.h | 1 + 4 files changed, 85 insertions(+), 70 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index b9938043..559b0a8b 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -315,6 +315,13 @@ namespace datagram } auto path = m_RoutingSession->GetSharedRoutingPath(); + if (path && m_RoutingSession->IsRatchets () && + m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT) + { + m_RoutingSession->SetSharedRoutingPath (nullptr); + path = nullptr; + } + if (path) { if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ()) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index d403c9bd..dac5dbe0 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -770,7 +770,7 @@ namespace garlic if (m_NextSendRatchet->newKey) payloadLen += 32; } uint8_t paddingSize = 0; - if (payloadLen) + if (payloadLen || ts > m_LastSentTimestamp + ECIESX25519_SEND_INACTIVITY_TIMEOUT) { int delta = (int)ECIESX25519_OPTIMAL_PAYLOAD_SIZE - (int)payloadLen; if (delta < 0 || delta > 3) // don't create padding if we are close to optimal size @@ -791,83 +791,87 @@ namespace garlic } } std::vector v(payloadLen); - 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 - } - // LeaseSet - if (leaseSet) - { - offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); - if (!first) + if (payloadLen) + { + m_LastSentTimestamp = ts; + size_t offset = 0; + // DateTime + if (first) { - // ack request - v[offset] = eECIESx25519BlkAckRequest; offset++; - htobe16buf (v.data () + offset, 1); offset += 2; - v[offset] = 0; offset++; // flags + v[offset] = eECIESx25519BlkDateTime; offset++; + htobe16buf (v.data () + offset, 4); offset += 2; + htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds } - } - // msg - if (msg && m_Destination) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); - // ack - if (m_AckRequests.size () > 0) - { - v[offset] = eECIESx25519BlkAck; offset++; - htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2; - for (auto& it: m_AckRequests) + // LeaseSet + if (leaseSet) { - htobe16buf (v.data () + offset, it.first); offset += 2; - htobe16buf (v.data () + offset, it.second); offset += 2; + offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset); + if (!first) + { + // ack request + v[offset] = eECIESx25519BlkAckRequest; offset++; + htobe16buf (v.data () + offset, 1); offset += 2; + v[offset] = 0; offset++; // flags + } } - 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; - int keyID = m_NextReceiveRatchet->keyID - 1; - if (m_NextReceiveRatchet->newKey) + // msg + if (msg && m_Destination) + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + // ack + if (m_AckRequests.size () > 0) { - v[offset] |= ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG; - keyID++; + v[offset] = eECIESx25519BlkAck; offset++; + htobe16buf (v.data () + 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; + } + m_AckRequests.clear (); } - offset++; // flag - htobe16buf (v.data () + offset, keyID); offset += 2; // keyid - if (m_NextReceiveRatchet->newKey) + // next keys + if (m_SendReverseKey) { - memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); - offset += 32; // public key + v[offset] = eECIESx25519BlkNextKey; offset++; + htobe16buf (v.data () + offset, m_NextReceiveRatchet->newKey ? 35 : 3); offset += 2; + v[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; + keyID++; + } + offset++; // flag + htobe16buf (v.data () + offset, keyID); offset += 2; // keyid + if (m_NextReceiveRatchet->newKey) + { + memcpy (v.data () + offset, m_NextReceiveRatchet->key->GetPublicKey (), 32); + offset += 32; // public key + } + m_SendReverseKey = false; } - 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 - offset++; // flag - htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid - if (m_NextSendRatchet->newKey) + if (m_SendForwardKey) { - memcpy (v.data () + offset, m_NextSendRatchet->key->GetPublicKey (), 32); - offset += 32; // public key + 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 + offset++; // flag + htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid + if (m_NextSendRatchet->newKey) + { + memcpy (v.data () + 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; - } + // padding + if (paddingSize) + { + v[offset] = eECIESx25519BlkPadding; offset++; + htobe16buf (v.data () + offset, paddingSize); offset += 2; + memset (v.data () + offset, 0, paddingSize); offset += paddingSize; + } + } return v; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 2dccd865..cccb4092 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -27,7 +27,8 @@ namespace garlic { const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second since session creation we can restart session after const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds - const int ECIESX25519_INACTIVITY_TIMEOUT = 90; // number of second we receive nothing and should restart if we can + const int ECIESX25519_INACTIVITY_TIMEOUT = 90; // number of seconds we receive nothing and should restart if we can + const int ECIESX25519_SEND_INACTIVITY_TIMEOUT = 5000; // number of milliseconds we can send empty(pyaload only) packet after const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 4096; // number of tags we request new tagset after @@ -148,6 +149,7 @@ namespace garlic bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); } bool IsRatchets () const { return true; }; + uint64_t GetLastActivityTimestamp () const { return m_LastActivityTimestamp; }; private: @@ -182,7 +184,8 @@ namespace garlic uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only std::shared_ptr m_EphemeralKeys; SessionState m_State = eSessionStateNew; - uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0; // incoming + uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming + m_LastSentTimestamp = 0; // in milliseconds std::shared_ptr m_SendTagset, m_NSRSendTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 70893bec..2168ee81 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -114,6 +114,7 @@ namespace garlic virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); virtual bool IsRatchets () const { return false; }; + virtual uint64_t GetLastActivityTimestamp () const { return 0; }; // non-zero for rathets only void SetLeaseSetUpdated () { From 3ef8b3dcbb55a3b1714eb46f3cd86bec2d53000a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jul 2020 20:44:01 -0400 Subject: [PATCH 0421/2950] don't send repliable datagram after less then 100 milliseconds --- libi2pd_client/I2PTunnel.cpp | 16 ++++++++++++---- libi2pd_client/I2PTunnel.h | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 95f56873..3575e062 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -708,9 +708,12 @@ namespace client if(!ecode) { LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint); - LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + auto ts = i2p::util::GetMillisecondsSinceEpoch(); auto session = m_Destination->GetSession (Identity); - m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort); + if (ts > LastActivity + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL) + m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort); + else + m_Destination->SendRawDatagram(session, m_Buffer, len, LocalPort, RemotePort); size_t numPackets = 0; while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) { @@ -724,6 +727,7 @@ namespace client if (numPackets > 0) LogPrint(eLogDebug, "UDPSession: forward more ", numPackets, "packets B from ", FromEndpoint); m_Destination->FlushSendQueue (session); + LastActivity = ts; Receive(); } else @@ -841,9 +845,13 @@ namespace client m_LastPort = remotePort; } // send off to remote i2p destination + auto ts = i2p::util::GetMillisecondsSinceEpoch(); LogPrint(eLogDebug, "UDP Client: send ", transferred, " to ", m_RemoteIdent->ToBase32(), ":", RemotePort); auto session = m_LocalDest->GetDatagramDestination()->GetSession (*m_RemoteIdent); - m_LocalDest->GetDatagramDestination()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort); + 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); size_t numPackets = 0; while (numPackets < i2p::datagram::DATAGRAM_SEND_QUEUE_MAX_SIZE) { @@ -862,7 +870,7 @@ namespace client // mark convo as active if (m_LastSession) - m_LastSession->second = i2p::util::GetMillisecondsSinceEpoch(); + m_LastSession->second = ts; RecvFromLocal(); } diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index eb1d8ed9..b76a1027 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -165,7 +165,8 @@ namespace client /** 2 minute timeout for udp sessions */ const uint64_t I2P_UDP_SESSION_TIMEOUT = 1000 * 60 * 2; - + const uint64_t I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL = 100; // in milliseconds + /** max size for i2p udp */ const size_t I2P_UDP_MAX_MTU = 64*1024; From c3aa6b9cda922a4c76221c3383287ae60a20a038 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jul 2020 17:47:46 -0400 Subject: [PATCH 0422/2950] use delivery type local if destination is not secified --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 15 +++++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index dac5dbe0..51ca9242 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -739,8 +739,11 @@ namespace garlic uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); size_t payloadLen = 0; if (first) payloadLen += 7;// datatime - if (msg && m_Destination) - payloadLen += msg->GetPayloadLength () + 13 + 32; + if (msg) + { + payloadLen += msg->GetPayloadLength () + 13; + if (m_Destination) payloadLen += 32; + } auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? @@ -816,7 +819,7 @@ namespace garlic } // msg if (msg && m_Destination) - offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true); + offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); // ack if (m_AckRequests.size () > 0) { @@ -875,16 +878,16 @@ namespace garlic return v; } - size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination) + size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len) { if (!msg) return 0; uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1; - if (isDestination) cloveSize += 32; + if (m_Destination) cloveSize += 32; if ((int)len < cloveSize + 3) return 0; buf[0] = eECIESx25519BlkGalicClove; // clove type htobe16buf (buf + 1, cloveSize); // size buf += 3; - if (isDestination) + if (m_Destination) { *buf = (eGarlicDeliveryTypeDestination << 5); memcpy (buf + 1, *m_Destination, 32); buf += 32; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cccb4092..73e129d7 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -171,7 +171,7 @@ namespace garlic 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 CreateGarlicClove (std::shared_ptr msg, uint8_t * buf, size_t len, bool isDestination = false); + 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); void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); From 9636d82b37ff021cd7ee7a7a0d55e89624e4a183 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Aug 2020 18:31:03 -0400 Subject: [PATCH 0423/2950] MixHash for SessionConfirmed processing --- libi2pd/NTCP2.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index f1f7e59f..4e3b219c 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -338,11 +338,8 @@ namespace transport KDF3Bob (); if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt - { // caclulate new h again for KDF data - memcpy (m_SessionConfirmedBuffer + 16, m_H, 32); // h || ciphertext - SHA256 (m_SessionConfirmedBuffer + 16, m3p2Len + 32, m_H); //h = SHA256(h || ciphertext); - } + MixHash (m_SessionConfirmedBuffer + 48, m3p2Len); // h = SHA256(h || ciphertext) else { LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 AEAD verification failed "); From 8e252265744cc8fdb942b90c2b27b8968d45698c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Aug 2020 13:34:27 -0400 Subject: [PATCH 0424/2950] use unordered_map for incomplete and sent messages --- libi2pd/SSUData.cpp | 2 +- libi2pd/SSUData.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 5068f006..fde684d0 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -301,7 +301,7 @@ namespace transport void SSUData::Send (std::shared_ptr msg) { uint32_t msgID = msg->ToSSU (); - if (m_SentMessages.count (msgID) > 0) + if (m_SentMessages.find (msgID) != m_SentMessages.end()) { LogPrint (eLogWarning, "SSU: message ", msgID, " already sent"); return; diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index f4a5ba4f..2e606053 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -124,8 +124,8 @@ namespace transport private: SSUSession& m_Session; - std::map > m_IncompleteMessages; - std::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; From e50abbb250da622191cebcb2c9d9f989087bfd8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 8 Aug 2020 19:01:55 -0400 Subject: [PATCH 0425/2950] avoid replay upon SSU packet resend --- libi2pd/SSUData.cpp | 23 +++++++++++++++-------- libi2pd/SSUSession.cpp | 26 ++++++++++++++++---------- libi2pd/SSUSession.h | 1 + 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index fde684d0..bd188ab7 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -326,8 +326,7 @@ namespace transport { Fragment * fragment = new Fragment; fragment->fragmentNum = fragmentNum; - uint8_t * buf = fragment->buf; - uint8_t * payload = buf + sizeof (SSUHeader); + uint8_t * payload = fragment->buf + sizeof (SSUHeader); *payload = DATA_FLAG_WANT_REPLY; // for compatibility payload++; *payload = 1; // always 1 message fragment per message @@ -346,14 +345,20 @@ namespace transport payload += 3; memcpy (payload, msgBuf, size); - size += payload - buf; - if (size & 0x0F) // make sure 16 bytes boundary - size = ((size >> 4) + 1) << 4; // (/16 + 1)*16 + size += payload - fragment->buf; + uint8_t rem = size & 0x0F; + if (rem) // make sure 16 bytes boundary + { + auto padding = 16 - rem; + memset (fragment->buf + size, 0, padding); + size += padding; + } fragment->len = size; fragments.push_back (std::unique_ptr (fragment)); // encrypt message with session key - m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, size); + uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; + m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, fragment->buf, size, buf); try { m_Session.Send (buf, size); @@ -432,6 +437,7 @@ namespace transport { if (ecode != boost::asio::error::operation_aborted) { + uint8_t buf[SSU_V4_MAX_PACKET_SIZE + 18]; uint32_t ts = i2p::util::GetSecondsSinceEpoch (); int numResent = 0; for (auto it = m_SentMessages.begin (); it != m_SentMessages.end ();) @@ -444,8 +450,9 @@ namespace transport if (f) { try - { - m_Session.Send (f->buf, f->len); // resend + { + m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, f->buf, f->len, buf); + m_Session.Send (buf, f->len); // resend numResent++; } catch (boost::system::system_error& ec) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 73699d6a..fca074b3 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -744,27 +744,33 @@ namespace transport } void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len) + { + FillHeaderAndEncrypt (payloadType, buf, len, buf); + } + + void SSUSession::FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * in, size_t len, uint8_t * out) { if (len < sizeof (SSUHeader)) { LogPrint (eLogError, "SSU: Unexpected packet length ", len); return; } - SSUHeader * header = (SSUHeader *)buf; + SSUHeader * header = (SSUHeader *)out; RAND_bytes (header->iv, 16); // random iv m_SessionKeyEncryption.SetIV (header->iv); - header->flag = payloadType << 4; // MSB is 0 - htobe32buf (header->time, i2p::util::GetSecondsSinceEpoch ()); - uint8_t * encrypted = &header->flag; - uint16_t encryptedLen = len - (encrypted - buf); - m_SessionKeyEncryption.Encrypt (encrypted, encryptedLen, encrypted); - // assume actual buffer size is 18 (16 + 2) bytes more - memcpy (buf + len, header->iv, 16); + SSUHeader * inHeader = (SSUHeader *)in; + inHeader->flag = payloadType << 4; // MSB is 0 + htobe32buf (inHeader->time, i2p::util::GetSecondsSinceEpoch ()); + uint8_t * encrypted = &header->flag, * clear = &inHeader->flag; + uint16_t encryptedLen = len - (encrypted - out); + m_SessionKeyEncryption.Encrypt (clear, encryptedLen, encrypted); + // assume actual out buffer size is 18 (16 + 2) bytes more + memcpy (out + len, header->iv, 16); uint16_t netid = i2p::context.GetNetID (); - htobe16buf (buf + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); + htobe16buf (out + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8)); i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, m_MacKey, header->mac); } - + void SSUSession::Decrypt (uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey) { if (len < sizeof (SSUHeader)) diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 066e01eb..ea820517 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -138,6 +138,7 @@ namespace transport void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey, const uint8_t * iv, const i2p::crypto::MACKey& macKey, uint8_t flag = 0); void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len); // with session key + void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * in, size_t len, uint8_t * out); // with session key void Decrypt (uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey); void DecryptSessionKey (uint8_t * buf, size_t len); bool Validate (uint8_t * buf, size_t len, const i2p::crypto::MACKey& macKey); From 6fec92c012b8fa067284f26355c427610f8624fb Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 10 Aug 2020 17:49:46 -0400 Subject: [PATCH 0426/2950] shared transient addresses --- libi2pd_client/ClientContext.cpp | 52 +++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e8e8eb2d..fc48ddbb 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -253,7 +253,8 @@ namespace client bool ClientContext::LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType) { - if (filename == "transient") + static const std::string transient("transient"); + if (!filename.compare (0, transient.length (), transient)) // starts with transient { keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); LogPrint (eLogInfo, "Clients: New transient keys address ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " created"); @@ -533,6 +534,7 @@ namespace client return; } + std::map > destinations; // keys -> destination for (auto& section: pt) { std::string name = section.first; @@ -564,18 +566,25 @@ namespace client std::shared_ptr localDestination = nullptr; if (keys.length () > 0) { - i2p::data::PrivateKeys k; - if(LoadPrivateKeys (k, keys, sigType, cryptoType)) - { - localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); - if (!localDestination) + auto it = destinations.find (keys); + if (it != destinations.end ()) + localDestination = it->second; + else + { + i2p::data::PrivateKeys k; + if(LoadPrivateKeys (k, keys, sigType, cryptoType)) { - if(matchTunnels) - localDestination = CreateNewMatchedTunnelDestination(k, dest, &options); - else - localDestination = CreateNewLocalDestination (k, type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT, &options); + localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); + if (!localDestination) + { + if(matchTunnels) + localDestination = CreateNewMatchedTunnelDestination(k, dest, &options); + else + localDestination = CreateNewLocalDestination (k, type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT, &options); + destinations[keys] = localDestination; + } } - } + } } if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { @@ -679,12 +688,21 @@ namespace client ReadI2CPOptions (section, options); std::shared_ptr localDestination = nullptr; - i2p::data::PrivateKeys k; - if(!LoadPrivateKeys (k, keys, sigType, cryptoType)) - continue; - localDestination = FindLocalDestination (k.GetPublic ()->GetIdentHash ()); - if (!localDestination) - localDestination = CreateNewLocalDestination (k, true, &options); + auto it = destinations.find (keys); + 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 From e7ff6fbffc437adef64e198eed8ae34085741cc9 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 14 Aug 2020 09:54:31 -0400 Subject: [PATCH 0427/2950] don't save invalid addreses --- libi2pd_client/AddressBook.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 8b8e781d..7af1272d 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -198,13 +198,18 @@ namespace client for (const auto& it: addresses) { - f << it.first << ","; - if (it.second->IsIdentHash ()) - f << it.second->identHash.ToBase32 (); + if (it.second->IsValid ()) + { + f << it.first << ","; + if (it.second->IsIdentHash ()) + f << it.second->identHash.ToBase32 (); + else + f << it.second->blindedPublicKey->ToB33 (); + f << std::endl; + num++; + } else - f << it.second->blindedPublicKey->ToB33 (); - f << std::endl; - num++; + LogPrint (eLogWarning, "Addressbook: invalid address ", it.first); } LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); return num; From 3159b06988a215a745eba48c1e1c8c41fcf231c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 15 Aug 2020 13:53:49 -0400 Subject: [PATCH 0428/2950] reseeds update --- .../certificates/reseed/bugme_at_mail.i2p.crt | 32 ----------------- .../reseed/reseed_at_diva.exchange.crt | 34 +++++++++++++++++++ libi2pd/Config.cpp | 2 +- 3 files changed, 35 insertions(+), 33 deletions(-) delete mode 100644 contrib/certificates/reseed/bugme_at_mail.i2p.crt create mode 100644 contrib/certificates/reseed/reseed_at_diva.exchange.crt diff --git a/contrib/certificates/reseed/bugme_at_mail.i2p.crt b/contrib/certificates/reseed/bugme_at_mail.i2p.crt deleted file mode 100644 index 2b6acac0..00000000 --- a/contrib/certificates/reseed/bugme_at_mail.i2p.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFezCCA2OgAwIBAgIEUQYyQjANBgkqhkiG9w0BAQ0FADBuMQswCQYDVQQGEwJY -WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt -b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOYnVnbWVAbWFpbC5p -MnAwHhcNMTQxMTA2MDkxMTE0WhcNMjQxMTA1MDkxMTE0WjBuMQswCQYDVQQGEwJY -WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt -b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOYnVnbWVAbWFpbC5p -MnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCrThOH0eSDT0VnCSBC -sqYmAydWH+O8eNttDXr2mSvZLhvAW+6/xHTkKhaWvkIvvS0Vh8hujMnD90Cgp4Fk -TKCxMj9K527o5xIZwWW05OevbjlBwIpVLO1PjmsfsoD1nIX14eEzJSEoAulKsv7V -jGUC/6hC11mmVvH9buQLSRv6sCjuAcMszmw3TAD+XYBIs+z57KuwYXtX3+OA543c -l1/ZKLYkkwY8cwzZqWDVWqTKP5TfVae58t40HhJk3bOsr21FZsaOjlmao3GO+d/3 -exKuUGJRcolSqskL3sZ1ovFqko81obvvx0upI0YA0iMr/NRGl3VPuf/LJvRppYGc -LsJHgy9TIgtHvaXRi5Nt4CbKl9sZh/7WkkTTI5YGvevu00btlabAN+DSAZZqdsB3 -wY8HhM1MHiA9SWsqwU65TwErcRrjNna2FiDHEu0xk5+/iAGl6CSKHZBmNcYKXSv8 -cwShB0jjmciK0a05nC638RPgj0fng7KRrSglyzfjXRrljmZ40LSBL/GGMZMWpOM7 -mEsBH5UZJ/2BEmjc9X9257zBdx8BK8y1TXpAligpNBsERcTw1WP1PJ35einZvlXW -qI3GwMf0sl26sn+evcK0gDl27jVDZ45MtNQEq64M4NV3Tn9zq0eg/39YvjVeqrI5 -l7sxmYqYGR6BuSncwdc4x+t6swIDAQABoyEwHzAdBgNVHQ4EFgQU/REZ7NMbVZHr -Xkao6Q8Ccqv2kAMwDQYJKoZIhvcNAQENBQADggIBACc2YjLVNbl1kJUdg2klCLJt -5LjNTiIZa2Cha5GStlC/lyoRRge6+q/y9TN3tTptlzLPS9pI9EE1GfIQaE+HAk+e -/bC3KUOAHgVuETvsNAbfpaVsPCdWpFuXmp/4b9iDN7qZy4afTKUPA/Ir/cLfNp14 -JULfP4z2yFOsCQZ5viNFAs1u99FrwobV2LBzUSIJQewsksuOwj96zIyau0Y629oJ -k+og88Tifd9EH3MVZNGhdpojQDDdwHQSITnCDgfRP5yER1WIA4jg6l+mM90QkvLY -5NjWTna5kJ3X6UizvgCk365yzT2sbN3R9UGXfCJa9GBcnnviJtJF3+/gC0abwY2f -NtVYp32Xky45NY/NdRhDg0bjHP3psxmX+Sc0M9NuQcDQ+fUR+CzM0IGeiszkzXOs -RG+bOou2cZ81G4oxWdAALHIRrn7VvLGlkFMxiIZyhYcTGQZzsTPT6n18dY99+DAV -yQWZfIRdm8DOnt0G+cwfeohc/9ZwDmj4jJAAi0aeTXdY6NEGIVydk6MAycEhg2Hx -9EV96kRwZNIW0AGY8CozECFL3Eyo2ClQVV4Q35SsBibsitDjM03usc2DJ/qjynXA -C8HoOSWgbddiBvqZueqK8GdhykOy3J3ysr+MNN/lbG48LqkQr1OWxev9rGGQ6RJT -wpBgPyAFAwouPy1whmnx ------END CERTIFICATE----- diff --git a/contrib/certificates/reseed/reseed_at_diva.exchange.crt b/contrib/certificates/reseed/reseed_at_diva.exchange.crt new file mode 100644 index 00000000..04b1524b --- /dev/null +++ b/contrib/certificates/reseed/reseed_at_diva.exchange.crt @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF0zCCA7ugAwIBAgIQWjHyC+NRh3emuuAwcEnKSjANBgkqhkiG9w0BAQsFADB0 +MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK +ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEdMBsGA1UEAwwU +cmVzZWVkQGRpdmEuZXhjaGFuZ2UwHhcNMjAwNjA5MDUzNjQ1WhcNMzAwNjA5MDUz +NjQ1WjB0MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4w +HAYDVQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEdMBsG +A1UEAwwUcmVzZWVkQGRpdmEuZXhjaGFuZ2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQC6BJGeMEgoXk9dlzKVfmwHrT2VpwTT+wRJvh3eAM746u4uDT2y +NPHXhdGcQ9dRRZ63T98IshWCwOmWSlm1kdWkmKkVVb93GUoMQ3gziCi0apLJMAau +gEu/sPCbORS2dPsQeAPW2eIsJO7dSjTRiQAuquW//NcIXG4gnxDA52lgke1BvpKr +83SJlCrqECAy6OKtZ49yn75CqmPPWFn0b/E8bxruN5ffeipTTospvdEtT41gXUqk +hOz3k8ang+QTWiP//jOjk31KXZ2dbh0LOlNJOvRxCqQmBZafNxxCR4DH8RewfPlL +qOiOJVzbLSP9RjqPLwnny5BOjbLWXcaybN5Qv2Pyd4mKtN3EpqBwRu7VnzXpsuuG +gRbxNmfKJ/vBEGrZAHAxi0NkHHEEne3B7pPDc2dVZHOfTfCu31m9uDHZ4eHEsNOJ +SJRiGjq74l0chCSlBGLrD1Y9LPyqadjdwuB9bzM0tMFC1wPflanQCflhhnEzAfbN +BaU2GRXo/I1UCDW/dH1FIkqEe61eMW1Lwqr5tdlrUpdr5VIddTyNJRBJogbZ+HZE +8mcoJW2lXRAkYi7KEm4b4EQNe7sbRNTF0j+fAJ+3ZOZ3O3SMHss6ignlSa+giVim +VvL+Joc6wpSzxpeNPf6m82cEO/UvifFYeOC9TpiRriSt+vvgQVzQtfQ+fQIDAQAB +o2EwXzAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF +BwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHJlc2VlZEBkaXZhLmV4Y2hh +bmdlMA0GCSqGSIb3DQEBCwUAA4ICAQCFGOb1dHlwjmgFHEER6oMiGWl1mI3Hb7GX +NNI6QUhZQ+iEWGYtsOTk3Q8xejL8t6AG/ZLXfZviLIJXZc5XZfPXk0ezDSC2cYxQ +ZAyYPw2dRP14brI86sCSqNAFIax/U5SM3zXhCbBiTfaEoBPfDpvKjx+VliaITUnc +sHTRn+C5ID5M8cZIqUSGECPEMU/bDtuRNJLTKYaJ98yXtYuS2CWsMEM4o0GGcnYQ +5HOZT/lbbwfq1Ks7IyJpeIpRaS5qckGcfgkxFY4eGujDuaFeWC+HCIh9RzBJrqZR +73Aly4Pyu7Jjg8xCCf9MswDjtqAjEHgWCmRLWL7p3H6cPipFKNMY6yomYZl5urE7 +q6DUAZFKwPqlZpyeaY4/SVvaHTxuPp7484s3db4kPhdmuQS/DOB/7d+cn/S580Vy +ALqlFQjtjLEaT16upceAV0gYktDInE6Rtym/OsqilrtYks/Sc0GROSz8lJhDDWbr +W3t92muSXDh0rYrEUYWl+xl1gSTpbIP75zzU+cUr1E/qlRY9qZn66FsJpOuN0I0q +UXsQS/bPDcA+IW48Hd9LfO9gtTWZslwFTimjEvQ2nJAnUlUQP6OfuPUKHoYX/CwY +2LCN8+pv2bKPDVHvp0lf6xrbbZNvFtzfR0G3AprZjYpuu2XgjVB5nJnwmbH74b9w +LD8d2z2Lgg== +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index d11152dd..6ce3a714 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -195,7 +195,7 @@ namespace config { ("reseed.proxy", value()->default_value(""), "url for reseed proxy, supports http/socks") ("reseed.urls", value()->default_value( "https://reseed.i2p-projekt.de/," - "https://i2p.mooo.com/netDb/," + "https://reseed.diva.exchange/," "https://reseed.i2p2.no/," "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," From 0777bad2c3b92607825c25898383346ae877a236 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 23 Aug 2020 22:25:54 +0300 Subject: [PATCH 0429/2950] [webconsole] fix warning, mobile page width Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 416cf1e4..d6b7a2ef 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -83,17 +83,18 @@ namespace http { " .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n" " .enabled:after { color: #56B734; content: \"Enabled\" }\r\n" " @media screen and (max-width: 980px) {\r\n" /* adaptive style */ + " body { padding: 1.5em 0 0 0; }\r\n" " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n" " text-align: center; }\r\n" " .menu a, .commands a { padding: 2px; }\r\n" - " .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%;\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" - " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 24px; }\r\n" + " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\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" @@ -933,7 +934,7 @@ namespace http { time_t t = divTime.quot; struct tm *tm = localtime(&t); char date[128]; - snprintf(date, sizeof(date), "%02d/%02d/%d %02d:%02d:%02d.%03ld", tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec, divTime.rem); + 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; } From 954781262c1be24673c9c7d57527eefe921aa065 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 24 Aug 2020 12:27:39 -0400 Subject: [PATCH 0430/2950] 2.33.0 --- ChangeLog | 23 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 ++-- contrib/rpm/i2pd-git.spec | 5 +++- contrib/rpm/i2pd.spec | 5 +++- debian/changelog | 6 +++++ libi2pd/version.h | 6 ++--- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 8 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33792a97..362b28bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,29 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.33.0] - 2020-08-24 +### Added +- Shared transient addresses +- crypto.ratchet.inboundTags paramater +- Multiple encryption keys through I2CP +- Pre-calculated x25519 ephemeral keys +- Change datagram routing path if nothing comes back in 10 seconds +- Shared routing path for datagram session +### Changed +- UDP tunnels send mix of repliable and raw datagrams in bulk +- Encrypt SSU packet again upon resend +- Start new tunnel message if remaining buffer is too small +- Use LeaseSet2 for ECIES-X25519-AEAD-Ratchet automatically +- Save new ECIES-X25519-AEAD-Ratchet session with NSR tagset +- Generate random padding lengths for ECIES-X25519-AEAD-Ratchet in bulk +- Webconsole layout +- Reseed servers list +### Fixed +- Don't connect through terminated SAM destination +- Differentiate UDP server sessions by port +- ECIES-X25519-AEAD-Ratchet through I2CP +- Don't save invalid address to AddressBook + ## [2.32.1] - 2020-06-02 ### Added - Read explicit peers in tunnels config diff --git a/Win32/installer.iss b/Win32/installer.iss index 40724d7a..fbbeba53 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.32.1" +#define I2Pd_ver "2.33.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index c9e8429c..ace2047a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2321 - versionName "2.32.1" + versionCode 2330 + versionName "2.33.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 7079ec23..00bea0b0 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.32.1 +Version: 2.33.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -124,6 +124,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2020 orignal - 2.33.0 +- update to 2.33.0 + * Tue Jun 02 2020 r4sas - 2.32.1 - update to 2.32.1 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 5c0b8fbd..22287f24 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.32.1 +Version: 2.33.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -122,6 +122,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Aug 24 2020 orignal - 2.33.0 +- update to 2.33.0 + * Tue Jun 02 2020 r4sas - 2.32.1 - update to 2.32.1 diff --git a/debian/changelog b/debian/changelog index b01f9519..bac3f3b3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.33.0-1) unstable; urgency=medium + + * updated to version 2.33.0/0.9.47 + + -- orignal Mon, 24 Aug 2020 16:00:00 +0000 + i2pd (2.32.1-1) unstable; urgency=high * updated to version 2.32.1 diff --git a/libi2pd/version.h b/libi2pd/version.h index c234516f..db30eee8 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -16,8 +16,8 @@ #define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 32 -#define I2PD_VERSION_MICRO 1 +#define I2PD_VERSION_MINOR 33 +#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define VERSION I2PD_VERSION @@ -30,7 +30,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 46 +#define I2P_VERSION_MICRO 47 #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) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 75c57fb7..d3fa2e9e 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From a0685d804d158796adbdc96deb30fdadc65aa4e5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 24 Aug 2020 12:48:09 -0400 Subject: [PATCH 0431/2950] 2.33.0 --- ChangeLog | 2 ++ appveyor.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 362b28bf..beef7a5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,8 @@ - Differentiate UDP server sessions by port - ECIES-X25519-AEAD-Ratchet through I2CP - Don't save invalid address to AddressBook +- ECDSA signatures names in SAM +- AppArmor profile ## [2.32.1] - 2020-06-02 ### Added diff --git a/appveyor.yml b/appveyor.yml index 0567127c..a6278d2d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.32.1.{build} +version: 2.33.0.{build} pull_requests: do_not_increment_build_number: true branches: From a05a54b38edba546dc77f9d60037ab4dcec1129e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 7 Sep 2020 18:45:05 -0400 Subject: [PATCH 0432/2950] trim behind ECIESx25519 tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 3 +++ libi2pd/ECIESX25519AEADRatchetSession.h | 6 ++++-- libi2pd/Garlic.cpp | 21 ++++++++++++--------- libi2pd/Garlic.h | 1 - 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 51ca9242..229578a1 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -657,7 +657,10 @@ namespace garlic moreTags -= (receiveTagset->GetNextIndex () - index); } if (moreTags > 0) + { GenerateMoreReceiveTags (receiveTagset, moreTags); + receiveTagset->MoveTrimBehind (moreTags >> 1); // /2 + } } return true; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 73e129d7..c9f21463 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -56,10 +56,12 @@ namespace garlic std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; + void MoveTrimBehind (int offset) { m_TrimBehindIndex += offset; }; void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - + bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + private: union @@ -73,7 +75,7 @@ namespace garlic } m_KeyData; uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; - int m_NextIndex, m_NextSymmKeyIndex; + int m_NextIndex, m_NextSymmKeyIndex, m_TrimBehindIndex = 0; std::unordered_map > m_ItermediateSymmKeys; std::weak_ptr m_Session; int m_TagSetID = 0; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 84a0519e..6d50aa1e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -802,14 +802,6 @@ namespace garlic } } // ECIESx25519 - for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) - { - if (it->second.tagset->IsExpired (ts) || ts > it->second.creationTime + ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT) - it = m_ECIESx25519Tags.erase (it); - else - ++it; - } - for (auto it = m_ECIESx25519Sessions.begin (); it != m_ECIESx25519Sessions.end ();) { if (it->second->CheckExpired (ts)) @@ -820,6 +812,17 @@ namespace garlic else ++it; } + + numExpiredTags = 0; + for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) + { + if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) + it = m_ECIESx25519Tags.erase (it); + else + ++it; + } + if (numExpiredTags > 0) + LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ()); } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) @@ -1009,7 +1012,7 @@ namespace garlic { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); - m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()}); + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset}); } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 2168ee81..b97eaab2 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -220,7 +220,6 @@ namespace garlic { int index; RatchetTagSetPtr tagset; - uint64_t creationTime; // seconds since epoch }; class GarlicDestination: public i2p::data::LocalDestination From da1e52357f9b11dd45e240afbc8d1e6248eeb9b5 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 8 Sep 2020 07:46:55 -0400 Subject: [PATCH 0433/2950] delete symmkey on cleanup --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 ++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 3 ++- libi2pd/Garlic.cpp | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 229578a1..885dc1fc 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -88,6 +88,11 @@ namespace garlic } } + void RatchetTagSet::DeleteSymmKey (int index) + { + m_ItermediateSymmKeys.erase (index); + } + void RatchetTagSet::Expire () { if (!m_ExpirationTimestamp) @@ -659,7 +664,9 @@ namespace garlic if (moreTags > 0) { GenerateMoreReceiveTags (receiveTagset, moreTags); - receiveTagset->MoveTrimBehind (moreTags >> 1); // /2 + index -= (moreTags >> 1); // /2 + if (index > 0) + receiveTagset->SetTrimBehind (index); } } return true; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index c9f21463..c7451b98 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -52,11 +52,12 @@ namespace garlic const uint8_t * GetNextRootKey () const { return m_NextRootKey; }; int GetNextIndex () const { return m_NextIndex; }; void GetSymmKey (int index, uint8_t * key); + void DeleteSymmKey (int index); std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; - void MoveTrimBehind (int offset) { m_TrimBehindIndex += offset; }; + void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 6d50aa1e..6bdbb630 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -817,7 +817,10 @@ namespace garlic for (auto it = m_ECIESx25519Tags.begin (); it != m_ECIESx25519Tags.end ();) { if (it->second.tagset->IsExpired (ts) || it->second.tagset->IsIndexExpired (it->second.index)) + { + it->second.tagset->DeleteSymmKey (it->second.index); it = m_ECIESx25519Tags.erase (it); + } else ++it; } From d0d71c93af3859fd24491678b37d500f1e4769ef Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Sep 2020 19:27:29 -0400 Subject: [PATCH 0434/2950] set LeaseSet type to 3 for ratchets if not specified --- libi2pd/Destination.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a764224c..c8940383 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -855,8 +855,7 @@ namespace client // extract encryption type params for LS2 std::set encryptionKeyTypes; - if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 || - GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params) + if (params) { auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE); if (it != params->end ()) From 2b0d1a2190743135f3a412c0d106b2e520e304d0 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Sep 2020 19:39:18 -0400 Subject: [PATCH 0435/2950] implement DatabaseLookupTagSet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 50 +++++++++++++++++++++++ libi2pd/ECIESX25519AEADRatchetSession.h | 21 +++++++++- libi2pd/Garlic.cpp | 3 +- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 885dc1fc..aef273ed 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -99,6 +99,56 @@ namespace garlic m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; } + bool RatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + { + auto session = GetSession (); + if (!session) return false; + return session->HandleNextMessage (buf, len, shared_from_this (), index); + } + + DatabaseLookupTagSet::DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key): + RatchetTagSet (nullptr), m_Destination (destination) + { + memcpy (m_Key, key, 32); + Expire (); + } + + bool DatabaseLookupTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + { + if (len < 24) return false; + uint8_t nonce[12]; + memset (nonce, 0, 12); // n = 0 + size_t offset = 8; // first 8 bytes is reply tag used as AD + 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"); + return false; + } + // we assume 1 I2NP block with delivery type local + if (offset + 3 > len) + { + LogPrint (eLogWarning, "Garlic: Lookup reply is too short ", len); + return false; + } + if (buf[offset] != eECIESx25519BlkGalicClove) + { + LogPrint (eLogWarning, "Garlic: Lookup reply unexpected block ", (int)buf[offset]); + return false; + } + offset++; + auto size = bufbe16toh (buf + offset); + offset += 2; + if (offset + size > len) + { + LogPrint (eLogWarning, "Garlic: Lookup reply block is too long ", size); + return false; + } + if (m_Destination) + m_Destination->HandleECIESx25519GarlicClove (buf + offset, size); + return true; + } + ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet): GarlicRoutingSession (owner, attachLeaseSet) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index c7451b98..af0b5de5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -40,7 +40,7 @@ namespace garlic // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ class ECIESX25519AEADRatchetSession; - class RatchetTagSet + class RatchetTagSet: public std::enable_shared_from_this { public: @@ -61,7 +61,9 @@ namespace garlic void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + virtual bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + + virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); private: @@ -94,6 +96,21 @@ namespace garlic std::shared_ptr m_DummySession; // we need a strong pointer for NS }; + + class DatabaseLookupTagSet: public RatchetTagSet + { + public: + + DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key); + + bool IsIndexExpired (int index) const { return false; }; + bool HandleNextMessage (uint8_t * buf, size_t len, int index); + + private: + + GarlicDestination * m_Destination; + uint8_t m_Key[32]; + }; enum ECIESx25519BlockType { diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 6bdbb630..05d7fd3e 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -507,8 +507,7 @@ namespace garlic if (it1 != m_ECIESx25519Tags.end ()) { found = true; - auto session = it1->second.tagset->GetSession (); - if (!session || !session->HandleNextMessage (buf, length, it1->second.tagset, it1->second.index)) + if (!it1->second.tagset->HandleNextMessage (buf, length, it1->second.index)) LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); m_ECIESx25519Tags.erase (it1); } From 024c29b180d2ad6bfcf6179d64119a14ef94f9c4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Sep 2020 21:11:46 -0400 Subject: [PATCH 0436/2950] eliminate boost/bind --- daemon/HTTPServer.cpp | 5 ++-- daemon/UPnP.cpp | 53 ++++++++++++++++++------------------------ libi2pd/SSU.cpp | 1 - libi2pd/SSUData.cpp | 1 - libi2pd/SSUSession.cpp | 1 - 5 files changed, 24 insertions(+), 37 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d6b7a2ef..52b655b9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include "Base.h" @@ -1321,8 +1320,8 @@ namespace http { void HTTPServer::Accept () { auto newSocket = std::make_shared (m_Service); - m_Acceptor.async_accept (*newSocket, boost::bind (&HTTPServer::HandleAccept, this, - boost::asio::placeholders::error, newSocket)); + m_Acceptor.async_accept (*newSocket, std::bind (&HTTPServer::HandleAccept, this, + std::placeholders::_1, newSocket)); } void HTTPServer::HandleAccept(const boost::system::error_code& ecode, diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 852122f2..92a41011 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -1,18 +1,9 @@ -/* -* 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 -*/ - #ifdef USE_UPNP #include #include #include #include -#include #include "Log.h" @@ -88,10 +79,10 @@ namespace transport void UPnP::Discover () { bool isError; - int err; + int err; #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) - err = UPNPDISCOVER_SUCCESS; + err = UPNPDISCOVER_SUCCESS; #if (MINIUPNPC_API_VERSION >= 14) m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err); @@ -100,9 +91,9 @@ namespace transport #endif isError = err != UPNPDISCOVER_SUCCESS; -#else // MINIUPNPC_API_VERSION >= 8 - err = 0; - m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); +#else // MINIUPNPC_API_VERSION >= 8 + err = 0; + m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); isError = m_Devlist == NULL; #endif // MINIUPNPC_API_VERSION >= 8 { @@ -113,15 +104,15 @@ namespace transport if (isError) { - LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); + LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err); return; } err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); - m_upnpUrlsInitialized = err != 0; + m_upnpUrlsInitialized=err!=0; if (err == UPNP_IGD_VALID_CONNECTED) { - err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(err != UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: unable to get external address: error ", err); @@ -132,14 +123,14 @@ namespace transport LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL); if (!m_externalIPAddress[0]) { - LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); + LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address"); return; } } } else { - LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); + LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err); return; } @@ -190,7 +181,7 @@ namespace transport err = CheckMapping (strPort.c_str (), strType.c_str ()); if (err != UPNPCOMMAND_SUCCESS) // if mapping not found { - LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); + LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err); #if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS)) err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL); @@ -210,7 +201,7 @@ namespace transport } else { - LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); + LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device"); return; } } @@ -227,14 +218,14 @@ namespace transport void UPnP::CloseMapping (std::shared_ptr address) { - if(!m_upnpUrlsInitialized) { - return; - } + if(!m_upnpUrlsInitialized) { + return; + } std::string strType (GetProto (address)), strPort (std::to_string (address->port)); int err = UPNPCOMMAND_SUCCESS; - + err = CheckMapping (strPort.c_str (), strType.c_str ()); - if (err == UPNPCOMMAND_SUCCESS) + if (err == UPNPCOMMAND_SUCCESS) { err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL); LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err); @@ -245,11 +236,11 @@ namespace transport { freeUPNPDevlist (m_Devlist); m_Devlist = 0; - if(m_upnpUrlsInitialized){ - FreeUPNPUrls (&m_upnpUrls); - m_upnpUrlsInitialized=false; - } - } + if(m_upnpUrlsInitialized){ + FreeUPNPUrls (&m_upnpUrls); + m_upnpUrlsInitialized=false; + } + } std::string UPnP::GetProto (std::shared_ptr address) { diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index c435715f..0f4526bd 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -7,7 +7,6 @@ */ #include -#include #include "Log.h" #include "Timestamp.h" #include "RouterContext.h" diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index bd188ab7..4e0e712f 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -7,7 +7,6 @@ */ #include -#include #include "Log.h" #include "Timestamp.h" #include "NetDb.hpp" diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index fca074b3..399b2fc7 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -6,7 +6,6 @@ * See full license text in LICENSE file at top of project tree */ -#include #include "version.h" #include "Crypto.h" #include "Log.h" From 09fdb068d2cbf70c4c4162748bb047331de69b47 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Sep 2020 21:15:42 -0400 Subject: [PATCH 0437/2950] Database lookups from ECIES destinations --- libi2pd/Destination.cpp | 11 ++++++++--- libi2pd/Garlic.cpp | 8 ++++++++ libi2pd/Garlic.h | 1 + libi2pd/I2NPProtocol.cpp | 18 ++++++++++++++---- libi2pd/I2NPProtocol.h | 5 +++-- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index c8940383..6b51fe1a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -744,14 +744,19 @@ namespace client request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTimeoutTimer.cancel (); + bool isECIES = SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) && + nextFloodfill->GetVersion () >= MAKE_VERSION_NUMBER(0, 9, 46); // >= 0.9.46; uint8_t replyKey[32], replyTag[32]; RAND_bytes (replyKey, 32); // random session key - RAND_bytes (replyTag, 32); // random session tag - AddSessionKey (replyKey, replyTag); + RAND_bytes (replyTag, isECIES ? 8 : 32); // random session tag + if (isECIES) + AddECIESx25519Key (replyKey, replyTag); + else + AddSessionKey (replyKey, replyTag); auto msg = WrapMessage (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - request->replyTunnel, replyKey, replyTag)); + request->replyTunnel, replyKey, replyTag, isECIES)); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 05d7fd3e..429a2092 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -460,6 +460,14 @@ namespace garlic } } + void GarlicDestination::AddECIESx25519Key (const uint8_t * key, const uint8_t * tag) + { + uint64_t t; + memcpy (&t, tag, 8); + auto tagset = std::make_shared(this, key); + m_ECIESx25519Tags.emplace (t, ECIESX25519AEADRatchetIndexTagset{0, tagset}); + } + bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) { AddSessionKey (key, tag); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index b97eaab2..f1e363df 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -241,6 +241,7 @@ namespace garlic std::shared_ptr msg, bool attachLeaseSet = false); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag + void AddECIESx25519Key (const uint8_t * key, const uint8_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); void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 53afbca4..36e7a763 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -171,7 +171,8 @@ namespace i2p std::shared_ptr CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, const std::set& excludedFloodfills, - std::shared_ptr replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag) + std::shared_ptr replyTunnel, const uint8_t * replyKey, + const uint8_t * replyTag, bool replyECIES) { int cnt = excludedFloodfills.size (); auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage (); @@ -180,7 +181,8 @@ namespace i2p buf += 32; memcpy (buf, replyTunnel->GetNextIdentHash (), 32); // reply tunnel GW buf += 32; - *buf = DATABASE_LOOKUP_DELIVERY_FLAG | DATABASE_LOOKUP_ENCRYPTION_FLAG | DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP; // flags + *buf = DATABASE_LOOKUP_DELIVERY_FLAG | DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP; // flags + *buf |= (replyECIES ? DATABASE_LOOKUP_ECIES_FLAG : DATABASE_LOOKUP_ENCRYPTION_FLAG); buf ++; htobe32buf (buf, replyTunnel->GetNextTunnelID ()); // reply tunnel ID buf += 4; @@ -204,8 +206,16 @@ namespace i2p // encryption memcpy (buf, replyKey, 32); buf[32] = 1; // 1 tag - memcpy (buf + 33, replyTag, 32); - buf += 65; + if (replyECIES) + { + memcpy (buf + 33, replyTag, 8); // 8 bytes tag + buf += 41; + } + else + { + memcpy (buf + 33, replyTag, 32); // 32 bytes tag + buf += 65; + } m->len += (buf - m->GetPayload ()); m->FillI2NPMessageHeader (eI2NPDatabaseLookup); diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 695de798..fe5ca968 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -251,8 +251,9 @@ namespace tunnel std::shared_ptr CreateRouterInfoDatabaseLookupMsg (const uint8_t * key, const uint8_t * from, uint32_t replyTunnelID, bool exploratory = false, std::set * excludedPeers = nullptr); std::shared_ptr CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, - const std::set& excludedFloodfills, - std::shared_ptr replyTunnel, const uint8_t * replyKey, const uint8_t * replyTag); + const std::set& excludedFloodfills, + std::shared_ptr replyTunnel, + const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false); std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector routers); std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router = nullptr, uint32_t replyToken = 0); From f939a7b349a930f2f2da5aee654095c50fa53500 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 21 Sep 2020 19:22:53 -0400 Subject: [PATCH 0438/2950] reduce variable tunnel build length to 4 --- libi2pd/Tunnel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 1fb12af9..a50bc31a 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -36,7 +36,7 @@ namespace tunnel const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds - const int STANDARD_NUM_RECORDS = 5; // in VariableTunnelBuild message + const int STANDARD_NUM_RECORDS = 4; // in VariableTunnelBuild message enum TunnelState { From 335f9394a5727596fc9a196b4c622464721e69b9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Sep 2020 19:32:19 -0400 Subject: [PATCH 0439/2950] drop gcc 4.7 support --- Makefile.linux | 2 +- daemon/I2PControl.cpp | 69 +++++++++++++++-------------------------- libi2pd/Destination.cpp | 3 +- 3 files changed, 27 insertions(+), 47 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index 1cdf0a48..3ef4793c 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -15,7 +15,7 @@ ifeq ($(shell expr match $(CXX) 'clang'),5) NEEDED_CXXFLAGS += -std=c++11 else ifeq ($(shell expr match ${CXXVER} "4\.[0-9][0-9]"),4) # gcc >= 4.10 NEEDED_CXXFLAGS += -std=c++11 -else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # gcc 4.7 - 4.9 +else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9 NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 NEEDED_CXXFLAGS += -std=c++11 diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 77614f2f..e8c6e031 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -1,11 +1,3 @@ -/* -* 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 #include #include @@ -14,12 +6,7 @@ #include #include #include - -// There is bug in boost 1.49 with gcc 4.7 coming with Debian Wheezy -#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) -#if !GCC47_BOOST149 #include -#endif #include "Crypto.h" #include "FS.h" @@ -67,28 +54,29 @@ namespace client m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem); // handlers - m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; - m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; - m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; - m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; - m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; - m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; - m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; + m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; + m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; + m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; + m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; + m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; + m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; + m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; // I2PControl m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler; // RouterInfo - m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; - m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; - m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; - m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; - m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; - m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; - m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; + m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; + m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; + m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; + m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; + m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; + m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler; - m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler; + m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = +&I2PControlService::TunnelsSuccessRateHandler; m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes; m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes; @@ -104,10 +92,10 @@ namespace client // ClientServicesInfo m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler; m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler; - m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; - m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; - m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; - m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; + m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; + m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; + m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; + m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; } I2PControlService::~I2PControlService () @@ -242,12 +230,6 @@ namespace client } } std::ostringstream response; -#if GCC47_BOOST149 - LogPrint (eLogError, "I2PControl: json_read is not supported due bug in boost 1.49 with gcc 4.7"); - response << "{\"id\":null,\"error\":"; - response << "{\"code\":-32603,\"message\":\"JSON requests is not supported with this version of boost\"},"; - response << "\"jsonrpc\":\"2.0\"}"; -#else boost::property_tree::ptree pt; boost::property_tree::read_json (ss, pt); @@ -267,7 +249,6 @@ namespace client response << "{\"code\":-32601,\"message\":\"Method not found\"},"; response << "\"jsonrpc\":\"2.0\"}"; } -#endif SendResponse (socket, buf, response, isHtml); } catch (std::exception& ex) @@ -408,8 +389,8 @@ namespace client auto it1 = m_RouterInfoHandlers.find (it->first); if (it1 != m_RouterInfoHandlers.end ()) { - if (!first) results << ","; - else first = false; + if (!first) results << ","; + else first = false; (this->*(it1->second))(results); } else @@ -507,7 +488,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } @@ -521,7 +502,7 @@ namespace client m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second m_ShutdownTimer.async_wait ( [](const boost::system::error_code& ecode) - { + { Daemon.running = 0; }); } diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 6b51fe1a..cd0ad9ab 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -603,9 +603,8 @@ namespace client return; } auto s = shared_from_this (); - // we must capture this for gcc 4.7 due the bug RequestLeaseSet (ls->GetStoreHash (), - [s, ls, this](std::shared_ptr leaseSet) + [s, ls](std::shared_ptr leaseSet) { if (leaseSet) { From 4d850793727f067a64c12499123325a911da1a89 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 17:46:15 -0400 Subject: [PATCH 0440/2950] correct addressbook request --- libi2pd_client/AddressBook.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 7af1272d..c044a047 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -806,6 +806,7 @@ namespace client i2p::http::HTTPReq req; req.AddHeader("Host", dest_host); req.AddHeader("User-Agent", "Wget/1.11.4"); + req.AddHeader("Accept-Encoding", "gzip"); req.AddHeader("X-Accept-Encoding", "x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0"); req.AddHeader("Connection", "close"); if (!m_Etag.empty()) @@ -816,6 +817,7 @@ namespace client url.schema = ""; url.host = ""; req.uri = url.to_string(); + req.version = "HTTP/1.1"; auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port); std::string request = req.to_string(); stream->Send ((const uint8_t *) request.data(), request.length()); @@ -895,7 +897,7 @@ namespace client i2p::http::MergeChunkedResponse (in, out); response = out.str(); } - else if (res.is_gzipped()) + if (res.is_gzipped()) { std::stringstream out; i2p::data::GzipInflator inflator; From 949fc47f311bb7c33ef073fc5e05cb369214718a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 19:07:58 -0400 Subject: [PATCH 0441/2950] two tunnels for shared local destination --- libi2pd_client/ClientContext.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index fc48ddbb..b24ce3ce 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -401,7 +401,14 @@ namespace client void ClientContext::CreateNewSharedLocalDestination () { - m_SharedLocalDestination = CreateNewLocalDestination (); // non-public, EDDSA + std::map params + { + { I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, "2" }, + { I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, "2" }, + { I2CP_PARAM_LEASESET_TYPE, "3" } + }; + m_SharedLocalDestination = CreateNewLocalDestination (false, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, + i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, ¶ms); // non-public, EDDSA m_SharedLocalDestination->Acquire (); } From 489c38ec5b13c1be33b22ff887f96f925cd49866 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 19:19:48 -0400 Subject: [PATCH 0442/2950] read Last-Modified --- libi2pd_client/AddressBook.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index c044a047..5c1cffbb 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -889,7 +889,7 @@ namespace client /* assert: res.code == 200 */ auto it = res.headers.find("ETag"); if (it != res.headers.end()) m_Etag = it->second; - it = res.headers.find("If-Modified-Since"); + it = res.headers.find("Last-Modified"); if (it != res.headers.end()) m_LastModified = it->second; if (res.is_chunked()) { From 5f42888b6118277b1569551296fef3759593ff25 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 03:43:47 +0300 Subject: [PATCH 0443/2950] [appveyor] disable fix introdued in 7864053 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a6278d2d..378fadc8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,7 +23,7 @@ environment: install: - 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" # TODO: revert that change when appveyor's images will be updated -- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" +#- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # update packages and install required From dec7a9a01c30238399d5b5bb86c36d4376708d58 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Sep 2020 20:50:57 -0400 Subject: [PATCH 0444/2950] shared transient destination between proxies --- libi2pd/Config.cpp | 4 ++-- libi2pd_client/ClientContext.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 6ce3a714..7668d6a7 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -96,7 +96,7 @@ namespace config { ("httpproxy.enabled", value()->default_value(true), "Enable or disable HTTP Proxy") ("httpproxy.address", value()->default_value("127.0.0.1"), "HTTP Proxy listen address") ("httpproxy.port", value()->default_value(4444), "HTTP Proxy listen port") - ("httpproxy.keys", value()->default_value(""), "File to persist HTTP Proxy keys") + ("httpproxy.keys", value()->default_value("transient-proxy"), "File to persist HTTP Proxy keys. Transient by default") ("httpproxy.signaturetype", value()-> default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("httpproxy.inbound.length", value()->default_value("3"), "HTTP proxy inbound tunnel length") @@ -116,7 +116,7 @@ namespace config { ("socksproxy.enabled", value()->default_value(true), "Enable or disable SOCKS Proxy") ("socksproxy.address", value()->default_value("127.0.0.1"), "SOCKS Proxy listen address") ("socksproxy.port", value()->default_value(4447), "SOCKS Proxy listen port") - ("socksproxy.keys", value()->default_value(""), "File to persist SOCKS Proxy keys") + ("socksproxy.keys", value()->default_value("transient-proxy"), "File to persist SOCKS Proxy keys. Transient by default") ("socksproxy.signaturetype", value()-> default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("socksproxy.inbound.length", value()->default_value("3"), "SOCKS proxy inbound tunnel length") diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index b24ce3ce..e1316a7f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -844,6 +844,8 @@ namespace client bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy); if (socksproxy) { + std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); + // we still need httpProxyKeys to compare with sockProxyKeys std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); uint16_t socksProxyPort; i2p::config::GetOption("socksproxy.port", socksProxyPort); @@ -852,7 +854,12 @@ namespace client uint16_t socksOutProxyPort; i2p::config::GetOption("socksproxy.outproxyport", socksOutProxyPort); i2p::data::SigningKeyType sigType; i2p::config::GetOption("socksproxy.signaturetype", sigType); LogPrint(eLogInfo, "Clients: starting SOCKS Proxy at ", socksProxyAddr, ":", socksProxyPort); - if (socksProxyKeys.length () > 0) + if (httpProxyKeys == socksProxyKeys && m_HttpProxy) + { + localDestination = m_HttpProxy->GetLocalDestination (); + localDestination->Acquire (); + } + else if (socksProxyKeys.length () > 0) { i2p::data::PrivateKeys keys; if (LoadPrivateKeys (keys, socksProxyKeys, sigType)) From 730c6aff11e7617cde385e4e0e63a1644db642e0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:08:39 +0300 Subject: [PATCH 0445/2950] Update appveyor.yml --- appveyor.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 378fadc8..0e7dc3a9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,9 +21,13 @@ environment: MSYS_BITNESS: 32 install: +# install new signing keyring +- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/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 -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" -# TODO: revert that change when appveyor's images will be updated -#- c:\msys64\usr\bin\bash -l "build/appveyor-msys2-upgrade.bash" # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # update packages and install required From cb41c0455185beff299f10c46c0b8033609ae543 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:10:11 +0300 Subject: [PATCH 0446/2950] [appveyor] install keyring package without question --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0e7dc3a9..11f6c9fd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/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 -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- c:\msys64\usr\bin\bash -lc "pacman -y -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 From 208707c00b86d130ae7ddd565b03c27b0e5c1438 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:11:40 +0300 Subject: [PATCH 0447/2950] [appveyor] install keyring package without question --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 11f6c9fd..5b365634 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/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 -y -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +- 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 From 7d34f1e8831d9b3d5702281ae64e19ecf68b7664 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:20:18 +0300 Subject: [PATCH 0448/2950] [appveyor] add delay before second try --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 5b365634..c233f535 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,6 +30,8 @@ install: - 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" +# Sleep for 5 seconds before next try? +- ping -n 5 127.0.0.1 > nul # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From 221b7cbf76bf6a3244f354a0181ace6300e5d96a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:29:43 +0300 Subject: [PATCH 0449/2950] [appveyor] kill bash before second try Ok, just waiting for bash termination doesn't works, so lets kill it. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c233f535..4b6c8b9a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,8 +30,8 @@ install: - 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" -# Sleep for 5 seconds before next try? -- ping -n 5 127.0.0.1 > nul +# Kill bash before next try +- taskkill /T /F /IM bash.exe # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From beb5d26e6d1aff804438285f9918216f56e3a298 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:44:18 +0300 Subject: [PATCH 0450/2950] [appveyor] kill gpg --- appveyor.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4b6c8b9a..07308d10 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,7 +31,9 @@ install: # update runtime - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" # Kill bash before next try -- taskkill /T /F /IM bash.exe +- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe +# For debug purposes +- tasklist # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From 873b4f3178d2d6fc570d206fa11512f38394a2a6 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:48:57 +0300 Subject: [PATCH 0451/2950] [appveyor] suppress error code --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 07308d10..83dee927 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,7 +31,7 @@ install: # 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 +- taskkill /T /F /IM bash.exe /IM gpg.exe /IM gpg-agent.exe | exit /B 0 # For debug purposes - tasklist # update packages and install required From ac5a4fe70ff4d6226da8c9bac150f1f4f7e8044d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 28 Sep 2020 04:51:13 +0300 Subject: [PATCH 0452/2950] [appveyor] remove tasklist print --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 83dee927..9d035653 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -32,8 +32,6 @@ install: - 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 -# For debug purposes -- tasklist # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From fd9229c4676b158137532bb61aee0ffb84408263 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Sep 2020 17:12:28 -0400 Subject: [PATCH 0453/2950] ping/pong for streaming --- libi2pd/Destination.cpp | 10 +++++++--- libi2pd/Destination.h | 6 +++++- libi2pd/Streaming.cpp | 31 +++++++++++++++++++++++++++++++ libi2pd/Streaming.h | 2 ++ libi2pd_client/ClientContext.cpp | 1 + 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index cd0ad9ab..af3b4cbc 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -849,8 +849,9 @@ namespace client ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - LeaseSetDestination (service, isPublic, params), - m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + LeaseSetDestination (service, isPublic, params), + m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(service) { @@ -918,7 +919,10 @@ namespace client auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY); if (it != params->end ()) m_StreamingAckDelay = std::stoi(it->second); - + it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS); + if (it != params->end ()) + m_IsStreamingAnswerPings = (it->second == "true"); + if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { // authentication for encrypted LeaseSet diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 1d5c0a55..a7567534 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -78,6 +78,8 @@ namespace client // streaming const char I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY[] = "i2p.streaming.initialAckDelay"; const int DEFAULT_INITIAL_ACK_DELAY = 200; // milliseconds + const char I2CP_PARAM_STREAMING_ANSWER_PINGS[] = "i2p.streaming.answerPings"; + const int DEFAULT_ANSWER_PINGS = true; typedef std::function stream)> StreamRequestComplete; @@ -242,7 +244,8 @@ namespace client bool IsAcceptingStreams () const; void AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor); int GetStreamingAckDelay () const { return m_StreamingAckDelay; } - + bool IsStreamingAnswerPings () const { return m_IsStreamingAnswerPings; } + // datagram i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true); @@ -275,6 +278,7 @@ namespace client std::unique_ptr m_ECIESx25519EncryptionKey; int m_StreamingAckDelay; + bool m_IsStreamingAnswerPings; std::shared_ptr m_StreamingDestination; // default std::map > m_StreamingDestinationsByPorts; i2p::datagram::DatagramDestination * m_DatagramDestination; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ff8915c0..ab08f41f 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -351,6 +351,28 @@ namespace stream return true; } + void Stream::HandlePing (Packet * packet) + { + uint16_t flags = packet->GetFlags (); + if (ProcessOptions (flags, packet) && m_RemoteIdentity) + { + // send pong + Packet p; + memset (p.buf, 0, 22); // minimal header all zeroes + memcpy (p.buf + 4, packet->buf, 4); // but receiveStreamID is the sendStreamID from the ping + htobe16buf (p.buf + 18, PACKET_FLAG_ECHO); // and echo flag + ssize_t payloadLen = packet->len - (packet->GetPayload () - packet->buf); + if (payloadLen > 0) + memcpy (p.buf + 22, packet->GetPayload (), payloadLen); + else + payloadLen = 0; + p.len = payloadLen + 22; + SendPackets (std::vector { &p }); + LogPrint (eLogDebug, "Streaming: Pong of ", p.len, " bytes sent"); + } + m_LocalDestination.DeletePacket (packet); + } + void Stream::ProcessAck (Packet * packet) { bool acknowledged = false; @@ -609,6 +631,7 @@ namespace stream packet[size] = 0; size++; // NACK count } + packet[size] = 0; size++; // resend delay htobuf16 (packet + size, 0); // no flags set size += 2; // flags @@ -666,6 +689,7 @@ namespace stream size += 4; // ack Through packet[size] = 0; size++; // NACK count + packet[size] = 0; size++; // resend delay htobe16buf (packet + size, PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED); size += 2; // flags @@ -1016,6 +1040,13 @@ namespace stream auto it = m_Streams.find (sendStreamID); if (it != m_Streams.end ()) it->second->HandleNextPacket (packet); + else if (packet->IsEcho () && m_Owner->IsStreamingAnswerPings ()) + { + // ping + LogPrint (eLogInfo, "Streaming: Ping received sSID=", sendStreamID); + auto s = std::make_shared (m_Owner->GetService (), *this); + s->HandlePing (packet); + } else { LogPrint (eLogInfo, "Streaming: Unknown stream sSID=", sendStreamID); diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index a56b0565..e8b8db91 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -87,6 +87,7 @@ namespace stream bool IsSYN () const { return GetFlags () & PACKET_FLAG_SYNCHRONIZE; }; bool IsNoAck () const { return GetFlags () & PACKET_FLAG_NO_ACK; }; + bool IsEcho () const { return GetFlags () & PACKET_FLAG_ECHO; }; }; struct PacketCmp @@ -168,6 +169,7 @@ namespace stream StreamingDestination& GetLocalDestination () { return m_LocalDestination; }; void HandleNextPacket (Packet * packet); + 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); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e1316a7f..a70add7d 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -453,6 +453,7 @@ namespace client options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY); options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY); 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, DEFAULT_ANSWER_PINGS); options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, ""); if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; From ee8429199740b69a4e75cc5eb65b62857f1a306e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Sep 2020 19:06:13 -0400 Subject: [PATCH 0454/2950] handle i2p.streaming.answerPings properly --- libi2pd/Destination.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index af3b4cbc..e88ac411 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,6 +13,7 @@ #include #include #include "Crypto.h" +#include "Config.h" #include "Log.h" #include "FS.h" #include "Timestamp.h" @@ -921,7 +922,7 @@ namespace client m_StreamingAckDelay = std::stoi(it->second); it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS); if (it != params->end ()) - m_IsStreamingAnswerPings = (it->second == "true"); + i2p::config::GetOption (it->second, m_IsStreamingAnswerPings); if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) { From 3a2724ec586e9fb7ac6c61b4b4290a0a93aa28e4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Oct 2020 13:13:27 -0400 Subject: [PATCH 0455/2950] single thread for I2CP --- libi2pd/Config.cpp | 1 + libi2pd_client/ClientContext.cpp | 3 +- libi2pd_client/I2CP.cpp | 101 ++++++++++++++----------------- libi2pd_client/I2CP.h | 37 ++++++----- 4 files changed, 70 insertions(+), 72 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 7668d6a7..b8016a7c 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -152,6 +152,7 @@ namespace config { ("i2cp.enabled", value()->default_value(false), "Enable or disable I2CP") ("i2cp.address", value()->default_value("127.0.0.1"), "I2CP listen address") ("i2cp.port", value()->default_value(7654), "I2CP listen port") + ("i2cp.singlethread", value()->default_value(true), "Destinations run in the I2CP server's thread") ; options_description i2pcontrol("I2PControl options"); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index a70add7d..e83e293a 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -102,10 +102,11 @@ namespace client { std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); + bool singleThread; i2p::config::GetOption("i2cp.singlethread", singleThread); LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); try { - m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); + m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort, singleThread); m_I2CPServer->Start (); } catch (std::exception& e) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index b0f334f5..24c2496b 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -23,36 +23,13 @@ namespace i2p namespace client { - I2CPDestination::I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): - RunnableService ("I2CP"), LeaseSetDestination (GetIOService (), isPublic, ¶ms), + I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, + std::shared_ptr identity, bool isPublic, const std::map& params): + LeaseSetDestination (service, isPublic, ¶ms), m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()) { } - I2CPDestination::~I2CPDestination () - { - if (IsRunning ()) - Stop (); - } - - void I2CPDestination::Start () - { - if (!IsRunning ()) - { - LeaseSetDestination::Start (); - StartIOService (); - } - } - - void I2CPDestination::Stop () - { - if (IsRunning ()) - { - LeaseSetDestination::Stop (); - StopIOService (); - } - } - void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key); @@ -217,6 +194,37 @@ namespace client } } + RunnableI2CPDestination::RunnableI2CPDestination (std::shared_ptr owner, + std::shared_ptr identity, bool isPublic, const std::map& params): + RunnableService ("I2CP"), + I2CPDestination (GetIOService (), owner, identity, isPublic, params) + { + } + + RunnableI2CPDestination::~RunnableI2CPDestination () + { + if (IsRunning ()) + Stop (); + } + + void RunnableI2CPDestination::Start () + { + if (!IsRunning ()) + { + I2CPDestination::Start (); + StartIOService (); + } + } + + void RunnableI2CPDestination::Stop () + { + if (IsRunning ()) + { + I2CPDestination::Stop (); + StopIOService (); + } + } + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_Payload (nullptr), m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) @@ -451,7 +459,9 @@ namespace client if (params[I2CP_PARAM_DONT_PUBLISH_LEASESET] == "true") isPublic = false; if (!m_Destination) { - m_Destination = std::make_shared(shared_from_this (), identity, isPublic, params); + 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); SendSessionStatusMessage (1); // created LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " created"); m_Destination->Start (); @@ -800,9 +810,9 @@ namespace client std::placeholders::_1, std::placeholders::_2, buf)); } - I2CPServer::I2CPServer (const std::string& interface, int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, + I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread): + RunnableService ("I2CP"), m_IsSingleThread (isSingleThread), + m_Acceptor (GetIOService (), #ifdef ANDROID I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address #else @@ -825,20 +835,18 @@ namespace client I2CPServer::~I2CPServer () { - if (m_IsRunning) + if (IsRunning ()) Stop (); } void I2CPServer::Start () { Accept (); - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&I2CPServer::Run, this)); + StartIOService (); } void I2CPServer::Stop () { - m_IsRunning = false; m_Acceptor.cancel (); { auto sessions = m_Sessions; @@ -846,33 +854,12 @@ namespace client it.second->Stop (); } m_Sessions.clear (); - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - } - - void I2CPServer::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "I2CP: runtime exception: ", ex.what ()); - } - } + StopIOService (); } void I2CPServer::Accept () { - auto newSocket = std::make_shared (m_Service); + auto newSocket = std::make_shared (GetIOService ()); m_Acceptor.async_accept (*newSocket, std::bind (&I2CPServer::HandleAccept, this, std::placeholders::_1, newSocket)); } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index adb648f4..4c6b7531 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -63,16 +63,14 @@ namespace client const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; class I2CPSession; - class I2CPDestination: private i2p::util::RunnableService, public LeaseSetDestination + class I2CPDestination: public LeaseSetDestination { public: - I2CPDestination (std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params); - ~I2CPDestination (); - - void Start (); - void Stop (); - + I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, + std::shared_ptr identity, bool isPublic, const std::map& params); + ~I2CPDestination () {}; + void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; void SetECIESx25519EncryptionPrivateKey (const uint8_t * key); @@ -109,6 +107,18 @@ namespace client uint64_t m_LeaseSetExpirationTime; }; + class RunnableI2CPDestination: private i2p::util::RunnableService, public I2CPDestination + { + public: + + RunnableI2CPDestination (std::shared_ptr owner, std::shared_ptr identity, + bool isPublic, const std::map& params); + ~RunnableI2CPDestination (); + + void Start (); + void Stop (); + }; + class I2CPServer; class I2CPSession: public std::enable_shared_from_this { @@ -179,17 +189,18 @@ namespace client }; typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); - class I2CPServer + class I2CPServer: private i2p::util::RunnableService { public: - I2CPServer (const std::string& interface, int port); + I2CPServer (const std::string& interface, int port, bool isSingleThread); ~I2CPServer (); void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; - + boost::asio::io_service& GetService () { return GetIOService (); }; + bool IsSingleThread () const { return m_IsSingleThread; }; + bool InsertSession (std::shared_ptr session); void RemoveSession (uint16_t sessionID); @@ -203,12 +214,10 @@ namespace client private: + bool m_IsSingleThread; I2CPMessageHandler m_MessagesHandlers[256]; std::map > m_Sessions; - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; I2CPSession::proto::acceptor m_Acceptor; public: From 9450dc84dacfd6950bab8534160337c9c281c950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AD=D1=80=D0=B8=D0=BA=20=D0=97=D0=B0=D0=BC=D0=B0=D0=B1?= =?UTF-8?q?=D1=83=D0=B2=D0=B0=D1=80=D0=B0=D0=B5=D0=B2=E2=80=90=D0=81=D0=BC?= =?UTF-8?q?=D0=BE=D0=BB=D0=BA=D1=83=D1=83?= Date: Sun, 4 Oct 2020 03:32:02 +0700 Subject: [PATCH 0456/2950] Update Win32NetState.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QueryInterface должна увеличивать счётчик ссылок. --- Win32/Win32NetState.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Win32/Win32NetState.h b/Win32/Win32NetState.h index bcb6c8d7..c2ddaee4 100644 --- a/Win32/Win32NetState.h +++ b/Win32/Win32NetState.h @@ -31,7 +31,8 @@ public: } else { Result = E_NOINTERFACE; } - + AddRef(); + return Result; } @@ -90,4 +91,4 @@ void SubscribeToEvents() { } void UnSubscribeFromEvents() { } #endif // WINVER -#endif \ No newline at end of file +#endif From 8483464aab8763ccf141b365a878359f37bc3d80 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 17:20:04 -0400 Subject: [PATCH 0457/2950] don't attach our RouterInfo to router's request --- libi2pd/Destination.cpp | 12 ++++++------ libi2pd/NetDb.cpp | 40 ++++++++++++++++++++-------------------- libi2pd/NetDb.hpp | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index e88ac411..669fd791 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -465,14 +465,14 @@ namespace client if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) { for (int i = 0; i < num; i++) - { - i2p::data::IdentHash peerHash (buf + 33 + i*32); - if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) { - LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); // TODO: recheck this message - i2p::data::netdb.RequestDestination (peerHash); + i2p::data::IdentHash peerHash (buf + 33 + i*32); + if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash)) + { + LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); + i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory + } } - } auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); if (floodfill) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 466016c5..5930baf7 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -610,7 +610,7 @@ namespace data } } - void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete) + void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct) { auto dest = m_Requests.CreateRequest (destination, false, requestComplete); // non-exploratory if (!dest) @@ -621,7 +621,23 @@ namespace data auto floodfill = GetClosestFloodfill (destination, dest->GetExcludedPeers ()); if (floodfill) - transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); + { + if (direct) + transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); + else + { + auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); + auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; + auto inbound = pool ? pool->GetNextInboundTunnel () : nullptr; + if (outbound && inbound) + outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, dest->CreateRequestMessage (floodfill, inbound)); + else + { + LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found"); + m_Requests.RequestComplete (destination, nullptr); + } + } + } else { LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no floodfills found"); @@ -775,37 +791,21 @@ namespace data // reply to our destination. Try other floodfills if (outbound && inbound) { - std::vector msgs; auto count = dest->GetExcludedPeers ().size (); if (count < 7) { auto nextFloodfill = GetClosestFloodfill (dest->GetDestination (), dest->GetExcludedPeers ()); if (nextFloodfill) { - // tell floodfill about us - msgs.push_back (i2p::tunnel::TunnelMessageBlock - { - i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, - CreateDatabaseStoreMsg () - }); - // request destination LogPrint (eLogDebug, "NetDb: Try ", key, " at ", count, " floodfill ", nextFloodfill->GetIdentHash ().ToBase64 ()); - auto msg = dest->CreateRequestMessage (nextFloodfill, inbound); - msgs.push_back (i2p::tunnel::TunnelMessageBlock - { - i2p::tunnel::eDeliveryTypeRouter, - nextFloodfill->GetIdentHash (), 0, msg - }); + outbound->SendTunnelDataMsg (nextFloodfill->GetIdentHash (), 0, + dest->CreateRequestMessage (nextFloodfill, inbound)); deleteDest = false; } } else LogPrint (eLogWarning, "NetDb: ", key, " was not found on ", count, " floodfills"); - - if (msgs.size () > 0) - outbound->SendTunnelDataMsg (msgs); } } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index d4501ab9..f9a57ccd 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -70,7 +70,7 @@ namespace data std::shared_ptr FindLeaseSet (const IdentHash& destination) const; std::shared_ptr FindRouterProfile (const IdentHash& ident) const; - void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr); + void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr, bool direct = true); void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr); void HandleDatabaseStoreMsg (std::shared_ptr msg); From c601a2986f3febae1430baf162c09640db30038c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 00:35:12 +0300 Subject: [PATCH 0458/2950] [appveyor] test without manual keyring installation --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 9d035653..00dd8c1b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,10 +22,10 @@ environment: install: # install new signing keyring -- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/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" +#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/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 From cfda807057f361f32f3563cb40b06f14f261dfaf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 00:45:30 +0300 Subject: [PATCH 0459/2950] [appveyor] use different mirror for keyring Default repo mirror is not available, changed to other one. --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 00dd8c1b..d5f67b14 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,10 +22,10 @@ environment: install: # install new signing keyring -#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -#- c:\msys64\usr\bin\bash -lc "curl -O http://repo.msys2.org/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" +- 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 From a8d23b5439d363ae3eae3dd7989b1a9a51732a53 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 18:46:12 -0400 Subject: [PATCH 0460/2950] disable NTCP for good --- libi2pd/Config.cpp | 2 +- libi2pd/RouterContext.cpp | 83 +++++++++++---------------------------- libi2pd/RouterInfo.cpp | 26 ++++-------- libi2pd/RouterInfo.h | 2 - libi2pd/Transports.cpp | 36 +---------------- 5 files changed, 33 insertions(+), 116 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b8016a7c..e0dc66d8 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -58,7 +58,7 @@ 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", value()->default_value(false), "Enable NTCP transport (default: disabled)") + ("ntcp", value()->default_value(false), "Ignored. Always false") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") #ifdef _WIN32 diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index cbbd961e..7333e613 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -63,7 +63,6 @@ namespace i2p bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ssu; i2p::config::GetOption("ssu", ssu); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool nat; i2p::config::GetOption("nat", nat); std::string ifname; i2p::config::GetOption("ifname", ifname); @@ -83,8 +82,6 @@ namespace i2p if (ssu) routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); - if (ntcp) - routerInfo.AddNTCPAddress (host.c_str(), port); } if (ipv6) { @@ -99,8 +96,6 @@ namespace i2p if (ssu) routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); - if (ntcp) - routerInfo.AddNTCPAddress (host.c_str(), port); } routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | @@ -115,20 +110,17 @@ namespace i2p { if (!m_NTCP2Keys) NewNTCP2Keys (); UpdateNTCP2Address (true); - if (!ntcp) // NTCP2 should replace NTCP + bool published; i2p::config::GetOption("ntcp2.published", published); + if (published) { - bool published; i2p::config::GetOption("ntcp2.published", published); - if (published) + PublishNTCP2Address (port, true); + if (ipv6) { - PublishNTCP2Address (port, true); - if (ipv6) - { - // add NTCP2 ipv6 address - std::string host = "::1"; - if (!i2p::config::IsDefault ("ntcp2.addressv6")) - i2p::config::GetOption ("ntcp2.addressv6", host); - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); - } + // add NTCP2 ipv6 address + std::string host = "::1"; + if (!i2p::config::IsDefault ("ntcp2.addressv6")) + i2p::config::GetOption ("ntcp2.addressv6", host); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); } } } @@ -444,16 +436,10 @@ namespace i2p addr->ssu->introducers.clear (); port = addr->port; } - // remove NTCP or NTCP2 v4 address - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - PublishNTCPAddress (false); - else - { - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) - PublishNTCP2Address (port, false, true); - } + // remove NTCP2 v4 address + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) + PublishNTCP2Address (port, false, true); // update UpdateRouterInfo (); } @@ -477,23 +463,16 @@ namespace i2p addr->ssu->introducers.clear (); port = addr->port; } - // insert NTCP or NTCP2 back - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - PublishNTCPAddress (true); - else + // insert NTCP2 back + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) { - // ntcp2 - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) + bool published; i2p::config::GetOption ("ntcp2.published", published); + if (published) { - bool published; i2p::config::GetOption ("ntcp2.published", published); - if (published) - { - uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); - if (!ntcp2Port) ntcp2Port = port; - PublishNTCP2Address (ntcp2Port, true, true); - } + uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); + if (!ntcp2Port) ntcp2Port = port; + PublishNTCP2Address (ntcp2Port, true, true); } } // update @@ -506,7 +485,7 @@ namespace i2p { m_RouterInfo.EnableV6 (); // insert v6 addresses if necessary - bool foundSSU = false, foundNTCP = false, foundNTCP2 = false; + bool foundSSU = false, foundNTCP2 = false; uint16_t port = 0; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) @@ -515,12 +494,8 @@ namespace i2p { if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) foundSSU = true; - else if (addr->IsNTCP2 ()) - { - if (addr->IsPublishedNTCP2 ()) foundNTCP2 = true; - } - else - foundNTCP = true; + else if (addr->IsPublishedNTCP2 ()) + foundNTCP2 = true; } port = addr->port; } @@ -552,16 +527,6 @@ namespace i2p m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port); } } - // NTCP - if (!foundNTCP) - { - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - if (ntcp) - { - std::string host = "::1"; - m_RouterInfo.AddNTCPAddress (host.c_str (), port); - } - } } else m_RouterInfo.DisableV6 (); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 91c12b60..703c853f 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -316,7 +316,7 @@ namespace data } if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented if (isNTCP2Only && address->ntcp2) address->ntcp2->isNTCP2Only = true; - if (supportedTransports) + if (supportedTransports & ~(eNTCPV4 | eNTCPV6)) // exclude NTCP only { addresses->push_back(address); m_SupportedTransports |= supportedTransports; @@ -477,7 +477,12 @@ namespace data s.write ((const char *)&address.date, sizeof (address.date)); std::stringstream properties; if (address.transportStyle == eTransportNTCP) - WriteString (address.IsNTCP2 () ? "NTCP2" : "NTCP", s); + { + if (address.IsNTCP2 ()) + WriteString ("NTCP2", s); + else + continue; // don't write NTCP address + } else if (address.transportStyle == eTransportSSU) { WriteString ("SSU", s); @@ -817,14 +822,6 @@ namespace data return ""; } - bool RouterInfo::IsNTCP (bool v4only) const - { - if (v4only) - return m_SupportedTransports & eNTCPV4; - else - return m_SupportedTransports & (eNTCPV4 | eNTCPV6); - } - bool RouterInfo::IsSSU (bool v4only) const { if (v4only) @@ -907,15 +904,6 @@ namespace data return m_Caps & Caps::eUnreachable; // non-reachable } - std::shared_ptr RouterInfo::GetNTCPAddress (bool v4only) const - { - return GetAddress ( - [v4only](std::shared_ptr address)->bool - { - return (address->transportStyle == eTransportNTCP) && !address->IsNTCP2Only () && (!v4only || address->host.is_v4 ()); - }); - } - std::shared_ptr RouterInfo::GetSSUAddress (bool v4only) const { return GetAddress ( diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index ef902c0e..1c0063b0 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -153,7 +153,6 @@ namespace data uint64_t GetTimestamp () const { return m_Timestamp; }; int GetVersion () const { return m_Version; }; Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr - std::shared_ptr GetNTCPAddress (bool v4only = true) const; std::shared_ptr GetNTCP2Address (bool publishedOnly, bool v4only = true) const; std::shared_ptr GetSSUAddress (bool v4only = true) const; std::shared_ptr GetSSUV6Address () const; @@ -169,7 +168,6 @@ namespace data void ClearProperties () { m_Properties.clear (); }; bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; - bool IsNTCP (bool v4only = true) const; bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index edfe33fa..54bf3fd9 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -472,41 +472,7 @@ namespace transport } } } - if (peer.numAttempts == 1) // NTCP1 - { - peer.numAttempts++; - auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); - if (address && m_NTCPServer) - { - if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ()) - { - if(!m_NTCPServer->ShouldLimit()) - { - auto s = std::make_shared (*m_NTCPServer, peer.router); - if(m_NTCPServer->UsingProxy()) - { - NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address; - std::string addr = address->host.to_string(); - - if(address->host.is_v6()) - remote = NTCPServer::eIP6Address; - - m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s); - } - else - m_NTCPServer->Connect (address->host, address->port, s); - return true; - } - else - { - LogPrint(eLogWarning, "Transports: NTCP Limit hit falling back to SSU"); - } - } - } - else - LogPrint (eLogDebug, "Transports: NTCP address is not present for ", i2p::data::GetIdentHashAbbreviation (ident), ", trying SSU"); - } - if (peer.numAttempts == 2)// SSU + if (peer.numAttempts == 1)// SSU { peer.numAttempts++; if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) From faae2709d9e8ba7fede3ae73228dec493250cd17 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 21:58:20 -0400 Subject: [PATCH 0461/2950] removed NTCP --- build/CMakeLists.txt | 1 - daemon/Daemon.cpp | 60 +- daemon/HTTPServer.cpp | 7 - libi2pd/NTCP2.cpp | 2 +- libi2pd/NTCPSession.cpp | 1317 --------------------------------------- libi2pd/NTCPSession.h | 242 ------- libi2pd/Transports.cpp | 70 +-- libi2pd/Transports.h | 6 +- qt/i2pd_qt/i2pd_qt.pro | 2 - 9 files changed, 30 insertions(+), 1677 deletions(-) delete mode 100644 libi2pd/NTCPSession.cpp delete mode 100644 libi2pd/NTCPSession.h diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 8271ce3a..4825855b 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -68,7 +68,6 @@ set(LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/NetDb.cpp" "${LIBI2PD_SRC_DIR}/NetDbRequests.cpp" "${LIBI2PD_SRC_DIR}/NTCP2.cpp" - "${LIBI2PD_SRC_DIR}/NTCPSession.cpp" "${LIBI2PD_SRC_DIR}/Poly1305.cpp" "${LIBI2PD_SRC_DIR}/Profiling.cpp" "${LIBI2PD_SRC_DIR}/Reseed.cpp" diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 264013cf..5f98d47a 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,11 +1,3 @@ -/* -* 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 #include @@ -17,7 +9,6 @@ #include "Base.h" #include "version.h" #include "Transports.h" -#include "NTCPSession.h" #include "RouterInfo.h" #include "RouterContext.h" #include "Tunnel.h" @@ -135,8 +126,8 @@ namespace i2p 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; @@ -151,8 +142,8 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - i2p::context.PublishNTCPAddress (ntcp, !ipv6); + bool ntcp; i2p::config::GetOption("ntcp", ntcp); + i2p::context.PublishNTCPAddress (ntcp, !ipv6); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -180,13 +171,10 @@ namespace i2p SetMaxNumTransitTunnels (transitTunnels); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - if (isFloodfill) - { + if (isFloodfill) { LogPrint(eLogInfo, "Daemon: router will be floodfill"); i2p::context.SetFloodfill (true); - } - else - { + } else { i2p::context.SetFloodfill (false); } @@ -254,8 +242,7 @@ namespace i2p i2p::transport::transports.RestrictRoutesToFamilies(fams); restricted = fams.size() > 0; } - if (routers.length() > 0) - { + if (routers.length() > 0) { std::set idents; size_t pos = 0, comma; do @@ -291,8 +278,7 @@ namespace i2p i2p::data::netdb.Start(); bool upnp; i2p::config::GetOption("upnp.enabled", upnp); - if (upnp) - { + if (upnp) { d.UPnP = std::unique_ptr(new i2p::transport::UPnP); d.UPnP->Start (); } @@ -304,16 +290,16 @@ namespace i2p d.m_NTPSync->Start (); } - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - bool ssu; i2p::config::GetOption("ssu", ssu); + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ssu; i2p::config::GetOption("ssu", ssu); LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); - if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled"); + if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); - i2p::transport::transports.Start(ntcp, ssu); - if (i2p::transport::transports.IsBoundNTCP() || i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + i2p::transport::transports.Start(ntcp2, ssu); + if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); - else + else { LogPrint(eLogError, "Daemon: failed to start Transports"); /** shut down netdb right away */ @@ -323,23 +309,23 @@ namespace i2p } bool http; i2p::config::GetOption("http.enabled", http); - if (http) - { + if (http) { std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try + try { d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); d.httpServer->Start(); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); } } + LogPrint(eLogInfo, "Daemon: starting Tunnels"); i2p::tunnel::tunnels.Start(); @@ -352,12 +338,12 @@ namespace i2p std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try + try { d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); d.m_I2PControlService->Start (); - } - catch (std::exception& ex) + } + catch (std::exception& ex) { LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); @@ -374,7 +360,7 @@ namespace i2p LogPrint(eLogInfo, "Daemon: stopping Tunnels"); i2p::tunnel::tunnels.Stop(); - if (d.UPnP) + if (d.UPnP) { d.UPnP->Stop (); d.UPnP = nullptr; diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 52b655b9..19734038 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -732,13 +732,6 @@ namespace http { void ShowTransports (std::stringstream& s) { s << "Transports:
\r\n"; - auto ntcpServer = i2p::transport::transports.GetNTCPServer (); - if (ntcpServer) - { - auto sessions = ntcpServer->GetNTCPSessions (); - if (!sessions.empty ()) - ShowNTCPTransports (s, sessions, "NTCP"); - } auto ntcp2Server = i2p::transport::transports.GetNTCP2Server (); if (ntcp2Server) { diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 4e3b219c..cdf660b7 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1435,7 +1435,7 @@ namespace transport { auto timer = std::make_shared(GetService()); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; + auto timeout = NTCP2_CONNECT_TIMEOUT * 5; conn->SetTerminationTimeout(timeout * 2); timer->expires_from_now (boost::posix_time::seconds(timeout)); timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp deleted file mode 100644 index 4d3f1da6..00000000 --- a/libi2pd/NTCPSession.cpp +++ /dev/null @@ -1,1317 +0,0 @@ -/* -* 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 -#include -#include - -#include "I2PEndian.h" -#include "Base.h" -#include "Crypto.h" -#include "Log.h" -#include "Timestamp.h" -#include "I2NPProtocol.h" -#include "RouterContext.h" -#include "Transports.h" -#include "NetDb.hpp" -#include "NTCPSession.h" -#include "HTTP.h" -#include "util.h" - -using namespace i2p::crypto; - -namespace i2p -{ -namespace transport -{ - - struct NTCPWork - { - std::shared_ptr session; - }; - - NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter): - TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), - m_Server (server), m_Socket (m_Server.GetService ()), - m_IsEstablished (false), m_IsTerminated (false), - m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false) - { - m_Establisher = new Establisher; - } - - NTCPSession::~NTCPSession () - { - delete m_Establisher; - } - - void NTCPSession::CreateAESKey (uint8_t * pubKey) - { - uint8_t sharedKey[256]; - m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation - - i2p::crypto::AESKey aesKey; - if (sharedKey[0] & 0x80) - { - aesKey[0] = 0; - memcpy (aesKey + 1, sharedKey, 31); - } - else if (sharedKey[0]) - memcpy (aesKey, sharedKey, 32); - else - { - // find first non-zero byte - uint8_t * nonZero = sharedKey + 1; - while (!*nonZero) - { - nonZero++; - if (nonZero - sharedKey > 32) - { - LogPrint (eLogWarning, "NTCP: First 32 bytes of shared key is all zeros, ignored"); - return; - } - } - memcpy (aesKey, nonZero, 32); - } - - m_Decryption.SetKey (aesKey); - m_Encryption.SetKey (aesKey); - } - - void NTCPSession::Done () - { - m_Server.GetService ().post (std::bind (&NTCPSession::Terminate, shared_from_this ())); - } - - void NTCPSession::Terminate () - { - if (!m_IsTerminated) - { - m_IsTerminated = true; - m_IsEstablished = false; - m_Socket.close (); - transports.PeerDisconnected (shared_from_this ()); - m_Server.RemoveNTCPSession (shared_from_this ()); - m_SendQueue.clear (); - m_NextMessage = nullptr; - LogPrint (eLogDebug, "NTCP: session terminated"); - } - } - - void NTCPSession::Connected () - { - m_IsEstablished = true; - - delete m_Establisher; - m_Establisher = nullptr; - - m_DHKeysPair = nullptr; - - SetTerminationTimeout (NTCP_TERMINATION_TIMEOUT); - SendTimeSyncMessage (); - transports.PeerConnected (shared_from_this ()); - } - - boost::asio::io_service & NTCPSession::GetService() - { - return m_Server.GetService(); - } - - void NTCPSession::ClientLogin () - { - if (!m_DHKeysPair) - m_DHKeysPair = transports.GetNextDHKeysPair (); - // send Phase1 - const uint8_t * x = m_DHKeysPair->GetPublicKey (); - memcpy (m_Establisher->phase1.pubKey, x, 256); - SHA256(x, 256, m_Establisher->phase1.HXxorHI); - const uint8_t * ident = m_RemoteIdentity->GetIdentHash (); - for (int i = 0; i < 32; i++) - m_Establisher->phase1.HXxorHI[i] ^= ident[i]; - - boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase1Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::ServerLogin () - { - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - // receive Phase1 - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: couldn't send Phase 1 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase2Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - } - - void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: phase 1 read error: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - // verify ident - uint8_t digest[32]; - SHA256(m_Establisher->phase1.pubKey, 256, digest); - const uint8_t * ident = i2p::context.GetIdentHash (); - for (int i = 0; i < 32; i++) - { - if ((m_Establisher->phase1.HXxorHI[i] ^ ident[i]) != digest[i]) - { - LogPrint (eLogError, "NTCP: phase 1 error: ident mismatch"); - Terminate (); - return; - } - } - // TODO: check for number of pending keys - auto work = new NTCPWork{shared_from_this()}; - m_Server.Work(work->session, [work, this]() -> std::function { - if (!work->session->m_DHKeysPair) - work->session->m_DHKeysPair = transports.GetNextDHKeysPair (); - work->session->CreateAESKey (work->session->m_Establisher->phase1.pubKey); - return std::bind(&NTCPSession::SendPhase2, work->session, work); - }); - } - } - - void NTCPSession::SendPhase2 (NTCPWork * work) - { - if(work) - delete work; - const uint8_t * y = m_DHKeysPair->GetPublicKey (); - memcpy (m_Establisher->phase2.pubKey, y, 256); - uint8_t xy[512]; - memcpy (xy, m_Establisher->phase1.pubKey, 256); - memcpy (xy + 256, y, 256); - SHA256(xy, 512, m_Establisher->phase2.encrypted.hxy); - uint32_t tsB = htobe32 (i2p::util::GetSecondsSinceEpoch ()); - memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4); - RAND_bytes (m_Establisher->phase2.encrypted.filler, 12); - - m_Encryption.SetIV (y + 240); - m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - - m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); - boost::asio::async_write(m_Socket, boost::asio::buffer (&m_Establisher->phase2, sizeof (NTCPPhase2)), boost::asio::transfer_all(), - std::bind(&NTCPSession::HandlePhase2Sent, shared_from_this(), std::placeholders::_1, std::placeholders::_2, tsB)); - } - - void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Couldn't send Phase 2 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, tsB)); - } - } - - void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Phase 2 read error: ", ecode.message (), ". Wrong ident assumed"); - if (ecode != boost::asio::error::operation_aborted) - { - // this RI is not valid - i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); - transports.ReuseDHKeysPair (m_DHKeysPair); - m_DHKeysPair = nullptr; - Terminate (); - } - } - else - { - auto work = new NTCPWork{shared_from_this()}; - m_Server.Work(work->session, [work, this]() -> std::function { - work->session->CreateAESKey (work->session->m_Establisher->phase2.pubKey); - return std::bind(&NTCPSession::HandlePhase2, work->session, work); - }); - } - } - - void NTCPSession::HandlePhase2 (NTCPWork * work) - { - if(work) delete work; - m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); - m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); - - m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); - // verify - uint8_t xy[512]; - memcpy (xy, m_DHKeysPair->GetPublicKey (), 256); - memcpy (xy + 256, m_Establisher->phase2.pubKey, 256); - uint8_t digest[32]; - SHA256 (xy, 512, digest); - if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32)) - { - LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash"); - transports.ReuseDHKeysPair (m_DHKeysPair); - m_DHKeysPair = nullptr; - Terminate (); - return ; - } - SendPhase3 (); - } - - void NTCPSession::SendPhase3 () - { - auto& keys = i2p::context.GetPrivateKeys (); - uint8_t * buf = m_ReceiveBuffer; - htobe16buf (buf, keys.GetPublic ()->GetFullLen ()); - buf += 2; - buf += i2p::context.GetIdentity ()->ToBuffer (buf, NTCP_BUFFER_SIZE); - uint32_t tsA = htobe32 (i2p::util::GetSecondsSinceEpoch ()); - htobuf32(buf,tsA); - buf += 4; - size_t signatureLen = keys.GetPublic ()->GetSignatureLen (); - size_t len = (buf - m_ReceiveBuffer) + signatureLen; - size_t paddingSize = len & 0x0F; // %16 - if (paddingSize > 0) - { - paddingSize = 16 - paddingSize; - // fill padding with random data - RAND_bytes(buf, paddingSize); - buf += paddingSize; - len += paddingSize; - } - - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (m_Establisher->phase2.encrypted.timestamp, 4); // tsB - s.Sign (keys, buf); - - m_Encryption.Encrypt(m_ReceiveBuffer, len, m_ReceiveBuffer); - boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, len), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA)); - } - - void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Couldn't send Phase 3 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - // wait for phase4 - auto signatureLen = m_RemoteIdentity->GetSignatureLen (); - size_t paddingSize = signatureLen & 0x0F; // %16 - if (paddingSize > 0) signatureLen += (16 - paddingSize); - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase4Received, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, tsA)); - } - } - - void NTCPSession::HandlePhase3Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB) - { - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Phase 3 read error: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - m_Decryption.Decrypt (m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer); - uint8_t * buf = m_ReceiveBuffer; - uint16_t size = bufbe16toh (buf); - auto identity = std::make_shared (buf + 2, size); - if (m_Server.FindNTCPSession (identity->GetIdentHash ())) - { - LogPrint (eLogInfo, "NTCP: session already exists"); - Terminate (); - } - auto existing = i2p::data::netdb.FindRouter (identity->GetIdentHash ()); // check if exists already - SetRemoteIdentity (existing ? existing->GetRouterIdentity () : identity); - - size_t expectedSize = size + 2/*size*/ + 4/*timestamp*/ + m_RemoteIdentity->GetSignatureLen (); - size_t paddingLen = expectedSize & 0x0F; - if (paddingLen) paddingLen = (16 - paddingLen); - if (expectedSize > NTCP_DEFAULT_PHASE3_SIZE) - { - // we need more bytes for Phase3 - expectedSize += paddingLen; - boost::asio::async_read (m_Socket, boost::asio::buffer(m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, expectedSize - NTCP_DEFAULT_PHASE3_SIZE), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase3ExtraReceived, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, tsB, paddingLen)); - } - else - HandlePhase3 (tsB, paddingLen); - } - } - - void NTCPSession::HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen) - { - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Phase 3 extra read error: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - m_Decryption.Decrypt (m_ReceiveBuffer + NTCP_DEFAULT_PHASE3_SIZE, bytes_transferred, m_ReceiveBuffer+ NTCP_DEFAULT_PHASE3_SIZE); - HandlePhase3 (tsB, paddingLen); - } - } - - void NTCPSession::HandlePhase3 (uint32_t tsB, size_t paddingLen) - { - uint8_t * buf = m_ReceiveBuffer + m_RemoteIdentity->GetFullLen () + 2 /*size*/; - uint32_t tsA = buf32toh(buf); - buf += 4; - buf += paddingLen; - - // check timestamp - auto ts = i2p::util::GetSecondsSinceEpoch (); - uint32_t tsA1 = be32toh (tsA); - if (tsA1 < ts - NTCP_CLOCK_SKEW || tsA1 > ts + NTCP_CLOCK_SKEW) - { - LogPrint (eLogError, "NTCP: Phase3 time difference ", (int)(ts - tsA1), " exceeds clock skew"); - Terminate (); - return; - } - - // check signature - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (i2p::context.GetRouterInfo ().GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (tsB); // tsB - if (!s.Verify (m_RemoteIdentity, buf)) - { - LogPrint (eLogError, "NTCP: signature verification failed"); - Terminate (); - return; - } - - SendPhase4 (tsA, tsB); - } - - void NTCPSession::SendPhase4 (uint32_t tsA, uint32_t tsB) - { - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (m_RemoteIdentity->GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (tsB); // tsB - auto& keys = i2p::context.GetPrivateKeys (); - auto signatureLen = keys.GetPublic ()->GetSignatureLen (); - s.Sign (keys, m_ReceiveBuffer); - size_t paddingSize = signatureLen & 0x0F; // %16 - if (paddingSize > 0) signatureLen += (16 - paddingSize); - m_Encryption.Encrypt (m_ReceiveBuffer, signatureLen, m_ReceiveBuffer); - - boost::asio::async_write (m_Socket, boost::asio::buffer (m_ReceiveBuffer, signatureLen), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandlePhase4Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - (void) bytes_transferred; - if (ecode) - { - LogPrint (eLogWarning, "NTCP: Couldn't send Phase 4 message: ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - LogPrint (eLogDebug, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected"); - m_Server.AddNTCPSession (shared_from_this ()); - - Connected (); - m_ReceiveBufferOffset = 0; - m_NextMessage = nullptr; - Receive (); - } - } - - void NTCPSession::HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA) - { - if (ecode) - { - LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock"); - if (ecode != boost::asio::error::operation_aborted) - { - // this router doesn't like us - i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); - Terminate (); - } - } - else - { - m_Decryption.Decrypt(m_ReceiveBuffer, bytes_transferred, m_ReceiveBuffer); - - // check timestamp - uint32_t tsB = bufbe32toh (m_Establisher->phase2.encrypted.timestamp); - auto ts = i2p::util::GetSecondsSinceEpoch (); - if (tsB < ts - NTCP_CLOCK_SKEW || tsB > ts + NTCP_CLOCK_SKEW) - { - LogPrint (eLogError, "NTCP: Phase4 time difference ", (int)(ts - tsB), " exceeds clock skew"); - Terminate (); - return; - } - - // verify signature - SignedData s; - s.Insert (m_Establisher->phase1.pubKey, 256); // x - s.Insert (m_Establisher->phase2.pubKey, 256); // y - s.Insert (i2p::context.GetIdentHash (), 32); // ident - s.Insert (tsA); // tsA - s.Insert (m_Establisher->phase2.encrypted.timestamp, 4); // tsB - - if (!s.Verify (m_RemoteIdentity, m_ReceiveBuffer)) - { - LogPrint (eLogError, "NTCP: Phase 4 process error: signature verification failed"); - Terminate (); - return; - } - LogPrint (eLogDebug, "NTCP: session to ", m_Socket.remote_endpoint (), " connected"); - Connected (); - - m_ReceiveBufferOffset = 0; - m_NextMessage = nullptr; - Receive (); - } - } - - void NTCPSession::Receive () - { - m_Socket.async_read_some (boost::asio::buffer(m_ReceiveBuffer + m_ReceiveBufferOffset, NTCP_BUFFER_SIZE - m_ReceiveBufferOffset), - std::bind(&NTCPSession::HandleReceived, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - - void NTCPSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - if (ecode) - { - if (ecode != boost::asio::error::operation_aborted) - LogPrint (eLogDebug, "NTCP: Read error: ", ecode.message ()); - //if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else - { - m_NumReceivedBytes += bytes_transferred; - i2p::transport::transports.UpdateReceivedBytes (bytes_transferred); - m_ReceiveBufferOffset += bytes_transferred; - - if (m_ReceiveBufferOffset >= 16) - { - // process received data - uint8_t * nextBlock = m_ReceiveBuffer; - while (m_ReceiveBufferOffset >= 16) - { - if (!DecryptNextBlock (nextBlock)) // 16 bytes - { - Terminate (); - return; - } - nextBlock += 16; - m_ReceiveBufferOffset -= 16; - } - if (m_ReceiveBufferOffset > 0) - memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); - } - - // read and process more is available - boost::system::error_code ec; - size_t moreBytes = m_Socket.available(ec); - if (moreBytes && !ec) - { - uint8_t * buf = nullptr, * moreBuf = m_ReceiveBuffer; - if (moreBytes + m_ReceiveBufferOffset > NTCP_BUFFER_SIZE) - { - buf = new uint8_t[moreBytes + m_ReceiveBufferOffset + 16]; - moreBuf = buf; - uint8_t rem = ((size_t)buf) & 0x0f; - if (rem) moreBuf += (16 - rem); // align 16 - if (m_ReceiveBufferOffset) - memcpy (moreBuf, m_ReceiveBuffer, m_ReceiveBufferOffset); - } - moreBytes = m_Socket.read_some (boost::asio::buffer (moreBuf + m_ReceiveBufferOffset, moreBytes), ec); - if (ec) - { - LogPrint (eLogInfo, "NTCP: Read more bytes error: ", ec.message ()); - delete[] buf; - Terminate (); - return; - } - m_ReceiveBufferOffset += moreBytes; - m_NumReceivedBytes += moreBytes; - i2p::transport::transports.UpdateReceivedBytes (moreBytes); - // process more data - uint8_t * nextBlock = moreBuf; - while (m_ReceiveBufferOffset >= 16) - { - if (!DecryptNextBlock (nextBlock)) // 16 bytes - { - delete[] buf; - Terminate (); - return; - } - nextBlock += 16; - m_ReceiveBufferOffset -= 16; - } - if (m_ReceiveBufferOffset > 0) - memcpy (m_ReceiveBuffer, nextBlock, m_ReceiveBufferOffset); // nextBlock points to memory inside buf - delete[] buf; - } - m_Handler.Flush (); - - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - Receive (); - } - } - - bool NTCPSession::DecryptNextBlock (const uint8_t * encrypted) // 16 bytes - { - if (!m_NextMessage) // new message, header expected - { - // decrypt header and extract length - uint8_t buf[16]; - m_Decryption.Decrypt (encrypted, buf); - uint16_t dataSize = bufbe16toh (buf); - if (dataSize) - { - // new message - if (dataSize + 16U + 15U > NTCP_MAX_MESSAGE_SIZE - 2) // + 6 + padding - { - LogPrint (eLogError, "NTCP: data size ", dataSize, " exceeds max size"); - return false; - } - m_NextMessage = (dataSize + 16U + 15U) <= I2NP_MAX_SHORT_MESSAGE_SIZE - 2 ? NewI2NPShortMessage () : NewI2NPMessage (); - m_NextMessage->Align (16); - m_NextMessage->offset += 2; // size field - m_NextMessage->len = m_NextMessage->offset + dataSize; - memcpy (m_NextMessage->GetBuffer () - 2, buf, 16); - m_NextMessageOffset = 16; - } - else - { - // timestamp - int diff = (int)bufbe32toh (buf + 2) - (int)i2p::util::GetSecondsSinceEpoch (); - LogPrint (eLogInfo, "NTCP: Timestamp. Time difference ", diff, " seconds"); - return true; - } - } - else // message continues - { - m_Decryption.Decrypt (encrypted, m_NextMessage->GetBuffer () - 2 + m_NextMessageOffset); - m_NextMessageOffset += 16; - } - - if (m_NextMessageOffset >= m_NextMessage->GetLength () + 2 + 4) // +checksum - { - // we have a complete I2NP message - uint8_t checksum[4]; - htobe32buf (checksum, adler32 (adler32 (0, Z_NULL, 0), m_NextMessage->GetBuffer () - 2, m_NextMessageOffset - 4)); - if (!memcmp (m_NextMessage->GetBuffer () - 2 + m_NextMessageOffset - 4, checksum, 4)) - { - if (!m_NextMessage->IsExpired ()) - { - m_Handler.PutNextMessage (m_NextMessage); - } - else - LogPrint (eLogInfo, "NTCP: message expired"); - } - else - LogPrint (eLogWarning, "NTCP: Incorrect adler checksum of message, dropped"); - m_NextMessage = nullptr; - } - return true; - } - - void NTCPSession::Send (std::shared_ptr msg) - { - m_IsSending = true; - boost::asio::async_write (m_Socket, CreateMsgBuffer (msg), boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::vector >{ msg })); - } - - boost::asio::const_buffers_1 NTCPSession::CreateMsgBuffer (std::shared_ptr msg) - { - uint8_t * sendBuffer; - int len; - - if (msg) - { - // regular I2NP - if (msg->offset < 2) - LogPrint (eLogError, "NTCP: Malformed I2NP message"); // TODO: - sendBuffer = msg->GetBuffer () - 2; - len = msg->GetLength (); - htobe16buf (sendBuffer, len); - } - else - { - // prepare timestamp - sendBuffer = m_TimeSyncBuffer; - len = 4; - htobuf16(sendBuffer, 0); - htobe32buf (sendBuffer + 2, i2p::util::GetSecondsSinceEpoch ()); - } - int rem = (len + 6) & 0x0F; // %16 - int padding = 0; - if (rem > 0) { - padding = 16 - rem; - // fill with random padding - RAND_bytes(sendBuffer + len + 2, padding); - } - htobe32buf (sendBuffer + len + 2 + padding, adler32 (adler32 (0, Z_NULL, 0), sendBuffer, len + 2+ padding)); - - int l = len + padding + 6; - m_Encryption.Encrypt(sendBuffer, l, sendBuffer); - return boost::asio::buffer ((const uint8_t *)sendBuffer, l); - } - - - void NTCPSession::Send (const std::vector >& msgs) - { - m_IsSending = true; - std::vector bufs; - for (const auto& it: msgs) - bufs.push_back (CreateMsgBuffer (it)); - boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (), - std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs)); - } - - void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs) - { - (void) msgs; - m_IsSending = false; - if (ecode) - { - LogPrint (eLogWarning, "NTCP: Couldn't send msgs: ", ecode.message ()); - // we shouldn't call Terminate () here, because HandleReceive takes care - // TODO: 'delete this' statement in Terminate () must be eliminated later - // Terminate (); - } - else - { - m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); - m_NumSentBytes += bytes_transferred; - i2p::transport::transports.UpdateSentBytes (bytes_transferred); - if (!m_SendQueue.empty()) - { - Send (m_SendQueue); - m_SendQueue.clear (); - } - } - } - - void NTCPSession::SendTimeSyncMessage () - { - Send (nullptr); - } - - void NTCPSession::SendI2NPMessages (const std::vector >& msgs) - { - m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs)); - } - - void NTCPSession::PostI2NPMessages (std::vector > msgs) - { - if (m_IsTerminated) return; - if (m_IsSending) - { - if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE) - { - for (const auto& it: msgs) - m_SendQueue.push_back (it); - } - else - { - LogPrint (eLogWarning, "NTCP: outgoing messages queue size exceeds ", NTCP_MAX_OUTGOING_QUEUE_SIZE); - Terminate (); - } - } - else - Send (msgs); - } - -//----------------------------------------- - NTCPServer::NTCPServer (int workers): - m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), - m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr), - m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr), - m_SoftLimit(0), m_HardLimit(0) - { - if(workers <= 0) workers = 1; - m_CryptoPool = std::make_shared(workers); - } - - NTCPServer::~NTCPServer () - { - Stop (); - } - - void NTCPServer::Start () - { - if (!m_IsRunning) - { - m_IsRunning = true; - m_Thread = new std::thread (std::bind (&NTCPServer::Run, this)); - // we are using a proxy, don't create any acceptors - if(UsingProxy()) - { - // TODO: resolve proxy until it is resolved - boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); - boost::system::error_code e; - auto itr = m_Resolver.resolve(q, e); - if(e) - { - LogPrint(eLogError, "NTCP: Failed to resolve proxy ", e.message()); - } - else - { - m_ProxyEndpoint = new boost::asio::ip::tcp::endpoint(*itr); - } - } - else - { - // create acceptors - auto& addresses = context.GetRouterInfo ().GetAddresses (); - for (const auto& address: addresses) - { - if (!address) continue; - if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !address->IsNTCP2 ()) - { - if (address->host.is_v4()) - { - try - { - m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port)); - LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - } - catch ( std::exception & ex ) - { - /** fail to bind ip4 */ - LogPrint(eLogError, "NTCP: Failed to bind to v4 port ", address->port, ": ", ex.what()); - ThrowFatal ("Unable to start IPv4 NTCP transport at port ", address->port, ": ", ex.what ()); - continue; - } - - LogPrint (eLogInfo, "NTCP: Start listening TCP port ", address->port); - auto conn = std::make_shared(*this); - m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, conn, std::placeholders::_1)); - } - else if (address->host.is_v6() && context.SupportsV6 ()) - { - m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service); - try - { - m_NTCPV6Acceptor->open (boost::asio::ip::tcp::v6()); - m_NTCPV6Acceptor->set_option (boost::asio::ip::v6_only (true)); - m_NTCPV6Acceptor->set_option (boost::asio::socket_base::reuse_address (true)); - m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port)); - m_NTCPV6Acceptor->listen (); - - LogPrint (eLogInfo, "NTCP: Start listening v6 TCP port ", address->port); - auto conn = std::make_shared (*this); - m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, conn, std::placeholders::_1)); - } - catch ( std::exception & ex ) - { - LogPrint(eLogError, "NTCP: failed to bind to v6 port ", address->port, ": ", ex.what()); - ThrowFatal (eLogError, "Unable to start IPv6 NTCP transport at port ", address->port, ": ", ex.what ()); - continue; - } - } - } - } - } - ScheduleTermination (); - } - } - - void NTCPServer::Stop () - { - { - // we have to copy it because Terminate changes m_NTCPSessions - auto ntcpSessions = m_NTCPSessions; - for (auto& it: ntcpSessions) - it.second->Terminate (); - for (auto& it: m_PendingIncomingSessions) - it->Terminate (); - } - m_NTCPSessions.clear (); - - if (m_IsRunning) - { - m_IsRunning = false; - m_TerminationTimer.cancel (); - if (m_NTCPAcceptor) - { - delete m_NTCPAcceptor; - m_NTCPAcceptor = nullptr; - } - if (m_NTCPV6Acceptor) - { - delete m_NTCPV6Acceptor; - m_NTCPV6Acceptor = nullptr; - } - m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - delete m_Thread; - m_Thread = nullptr; - } - if(m_ProxyEndpoint) - { - delete m_ProxyEndpoint; - m_ProxyEndpoint = nullptr; - } - } - } - - void NTCPServer::Run () - { - while (m_IsRunning) - { - try - { - m_Service.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "NTCP: runtime exception: ", ex.what ()); - } - } - } - - bool NTCPServer::AddNTCPSession (std::shared_ptr session) - { - if (!session || !session->GetRemoteIdentity ()) return false; - auto& ident = session->GetRemoteIdentity ()->GetIdentHash (); - auto it = m_NTCPSessions.find (ident); - if (it != m_NTCPSessions.end ()) - { - LogPrint (eLogWarning, "NTCP: session to ", ident.ToBase64 (), " already exists"); - session->Terminate(); - return false; - } - m_NTCPSessions.insert (std::pair >(ident, session)); - return true; - } - - void NTCPServer::RemoveNTCPSession (std::shared_ptr session) - { - if (session && session->GetRemoteIdentity ()) - m_NTCPSessions.erase (session->GetRemoteIdentity ()->GetIdentHash ()); - } - - std::shared_ptr NTCPServer::FindNTCPSession (const i2p::data::IdentHash& ident) - { - auto it = m_NTCPSessions.find (ident); - if (it != m_NTCPSessions.end ()) - return it->second; - return nullptr; - } - - void NTCPServer::HandleAccept (std::shared_ptr conn, const boost::system::error_code& error) - { - if (!error) - { - boost::system::error_code ec; - auto ep = conn->GetSocket ().remote_endpoint(ec); - if (!ec) - { - if(ShouldLimit()) - { - // hit limit, close premature - LogPrint(eLogWarning, "NTCP: limiting with backoff session from ", ep); - conn->Terminate(); - return; - } - LogPrint (eLogDebug, "NTCP: Connected from ", ep); - if (conn) - { - conn->ServerLogin (); - m_PendingIncomingSessions.push_back (conn); - } - } - else - LogPrint (eLogError, "NTCP: Connected from error ", ec.message ()); - } - - - if (error != boost::asio::error::operation_aborted) - { - conn = std::make_shared (*this); - m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this, - conn, std::placeholders::_1)); - } - } - - void NTCPServer::HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error) - { - if (!error) - { - boost::system::error_code ec; - auto ep = conn->GetSocket ().remote_endpoint(ec); - if (!ec) - { - if(ShouldLimit()) - { - // hit limit, close premature - LogPrint(eLogWarning, "NTCP: limiting with backoff on session from ", ep); - conn->Terminate(); - return; - } - - LogPrint (eLogDebug, "NTCP: Connected from ", ep); - if (conn) - { - conn->ServerLogin (); - m_PendingIncomingSessions.push_back (conn); - } - } - else - LogPrint (eLogError, "NTCP: Connected from error ", ec.message ()); - } - - if (error != boost::asio::error::operation_aborted) - { - conn = std::make_shared (*this); - m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6, this, - conn, std::placeholders::_1)); - } - } - - void NTCPServer::Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn) - { - LogPrint (eLogDebug, "NTCP: Connecting to ", address ,":", port); - m_Service.post([=]() { - if (this->AddNTCPSession (conn)) - { - - auto timer = std::make_shared(m_Service); - timer->expires_from_now (boost::posix_time::seconds(NTCP_CONNECT_TIMEOUT)); - timer->async_wait ([conn](const boost::system::error_code& ecode) { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP: Not connected in ", NTCP_CONNECT_TIMEOUT, " seconds"); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (boost::asio::ip::tcp::endpoint (address, port), std::bind (&NTCPServer::HandleConnect, this, std::placeholders::_1, conn, timer)); - } - }); - } - - void NTCPServer::ConnectWithProxy (const std::string& host, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn) - { - if(m_ProxyEndpoint == nullptr) - { - return; - } - m_Service.post([=]() { - if (this->AddNTCPSession (conn)) - { - - auto timer = std::make_shared(m_Service); - auto timeout = NTCP_CONNECT_TIMEOUT * 5; - conn->SetTerminationTimeout(timeout * 2); - timer->expires_from_now (boost::posix_time::seconds(timeout)); - timer->async_wait ([conn, timeout](const boost::system::error_code& ecode) { - if (ecode != boost::asio::error::operation_aborted) - { - LogPrint (eLogInfo, "NTCP: Not connected in ", timeout, " seconds"); - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - }); - conn->GetSocket ().async_connect (*m_ProxyEndpoint, std::bind (&NTCPServer::HandleProxyConnect, this, std::placeholders::_1, conn, timer, host, port, addrtype)); - } - }); - } - - void NTCPServer::HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer) - { - timer->cancel (); - if (ecode) - { - LogPrint (eLogInfo, "NTCP: Connect error ", ecode.message ()); - if (ecode != boost::asio::error::operation_aborted) - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - conn->Terminate (); - } - else - { - LogPrint (eLogDebug, "NTCP: Connected to ", conn->GetSocket ().remote_endpoint ()); - conn->ClientLogin (); - } - } - - void NTCPServer::UseProxy(ProxyType proxytype, const std::string & addr, uint16_t port) - { - m_ProxyType = proxytype; - m_ProxyAddress = addr; - m_ProxyPort = port; - } - - void NTCPServer::HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - if(ecode) - { - LogPrint(eLogWarning, "NTCP: failed to connect to proxy ", ecode.message()); - timer->cancel(); - conn->Terminate(); - return; - } - if(m_ProxyType == eSocksProxy) - { - // TODO: support username/password auth etc - uint8_t buff[3] = {0x05, 0x01, 0x00}; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, 3), boost::asio::transfer_all(), [=] (const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - { - LogPrint(eLogWarning, "NTCP: socks5 write error ", ec.message()); - } - }); - uint8_t readbuff[2]; - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 2), [=](const boost::system::error_code & ec, std::size_t transferred) { - if(ec) - { - LogPrint(eLogError, "NTCP: socks5 read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - return; - } - else if(transferred == 2) - { - if(readbuff[1] == 0x00) - { - AfterSocksHandshake(conn, timer, host, port, addrtype); - return; - } - else if (readbuff[1] == 0xff) - { - LogPrint(eLogError, "NTCP: socks5 proxy rejected authentication"); - timer->cancel(); - conn->Terminate(); - return; - } - } - LogPrint(eLogError, "NTCP: socks5 server gave invalid response"); - timer->cancel(); - conn->Terminate(); - }); - } - else if(m_ProxyType == eHTTPProxy) - { - i2p::http::HTTPReq req; - req.method = "CONNECT"; - req.version ="HTTP/1.1"; - if(addrtype == eIP6Address) - req.uri = "[" + host + "]:" + std::to_string(port); - else - req.uri = host + ":" + std::to_string(port); - - boost::asio::streambuf writebuff; - std::ostream out(&writebuff); - out << req.to_string(); - - boost::asio::async_write(conn->GetSocket(), writebuff.data(), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t transferred) { - (void) transferred; - if(ec) - LogPrint(eLogError, "NTCP: http proxy write error ", ec.message()); - }); - - boost::asio::streambuf * readbuff = new boost::asio::streambuf; - boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", [=] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) - { - LogPrint(eLogError, "NTCP: http proxy read error ", ec.message()); - timer->cancel(); - conn->Terminate(); - } - else - { - readbuff->commit(transferred); - i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) - { - if(res.code == 200) - { - timer->cancel(); - conn->ClientLogin(); - delete readbuff; - return; - } - else - { - LogPrint(eLogError, "NTCP: http proxy rejected request ", res.code); - } - } - else - LogPrint(eLogError, "NTCP: http proxy gave malformed response"); - timer->cancel(); - conn->Terminate(); - delete readbuff; - } - }); - } - else - LogPrint(eLogError, "NTCP: unknown proxy type, invalid state"); - } - - void NTCPServer::AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) - { - // build request - size_t sz = 0; - uint8_t buff[256]; - uint8_t readbuff[256]; - buff[0] = 0x05; - buff[1] = 0x01; - buff[2] = 0x00; - - if(addrtype == eIP4Address) - { - buff[3] = 0x01; - auto addr = boost::asio::ip::address::from_string(host).to_v4(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eIP6Address) - { - buff[3] = 0x04; - auto addr = boost::asio::ip::address::from_string(host).to_v6(); - auto addrbytes = addr.to_bytes(); - auto addrsize = addrbytes.size(); - memcpy(buff+4, addrbytes.data(), addrsize); - } - else if (addrtype == eHostname) - { - buff[3] = 0x03; - size_t addrsize = host.size(); - sz = addrsize + 1 + 4; - if (2 + sz > sizeof(buff)) - { - // too big - return; - } - buff[4] = (uint8_t) addrsize; - memcpy(buff+5, host.c_str(), addrsize); - } - htobe16buf(buff+sz, port); - sz += 2; - boost::asio::async_write(conn->GetSocket(), boost::asio::buffer(buff, sz), boost::asio::transfer_all(), [=](const boost::system::error_code & ec, std::size_t written) { - if(ec) - { - LogPrint(eLogError, "NTCP: failed to write handshake to socks proxy ", ec.message()); - return; - } - }); - - boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) { - if(e) - { - LogPrint(eLogError, "NTCP: socks proxy read error ", e.message()); - } - else if(transferred == sz) - { - if( readbuff[1] == 0x00) - { - timer->cancel(); - conn->ClientLogin(); - return; - } - } - if(!e) - i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); - timer->cancel(); - conn->Terminate(); - }); - } - - void NTCPServer::ScheduleTermination () - { - m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_CHECK_TIMEOUT)); - m_TerminationTimer.async_wait (std::bind (&NTCPServer::HandleTerminationTimer, - this, std::placeholders::_1)); - } - - void NTCPServer::HandleTerminationTimer (const boost::system::error_code& ecode) - { - if (ecode != boost::asio::error::operation_aborted) - { - auto ts = i2p::util::GetSecondsSinceEpoch (); - // established - for (auto& it: m_NTCPSessions) - if (it.second->IsTerminationTimeoutExpired (ts)) - { - auto session = it.second; - // Terminate modifies m_NTCPSession, so we postpone it - m_Service.post ([session] { - LogPrint (eLogDebug, "NTCP: No activity for ", session->GetTerminationTimeout (), " seconds"); - session->Terminate (); - }); - } - // pending - for (auto it = m_PendingIncomingSessions.begin (); it != m_PendingIncomingSessions.end ();) - { - if ((*it)->IsEstablished () || (*it)->IsTerminated ()) - it = m_PendingIncomingSessions.erase (it); // established or terminated - else if ((*it)->IsTerminationTimeoutExpired (ts)) - { - (*it)->Terminate (); - it = m_PendingIncomingSessions.erase (it); // expired - } - else - it++; - } - - ScheduleTermination (); - } - } -} -} diff --git a/libi2pd/NTCPSession.h b/libi2pd/NTCPSession.h deleted file mode 100644 index d3aa6f7c..00000000 --- a/libi2pd/NTCPSession.h +++ /dev/null @@ -1,242 +0,0 @@ -/* -* 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 NTCP_SESSION_H__ -#define NTCP_SESSION_H__ - -#include -#include -#include -#include -#include -#include -#include "Crypto.h" -#include "Identity.h" -#include "RouterInfo.h" -#include "I2NPProtocol.h" -#include "TransportSession.h" -#include "CryptoWorker.h" - -namespace i2p -{ -namespace transport -{ - struct NTCPPhase1 - { - uint8_t pubKey[256]; - uint8_t HXxorHI[32]; - }; - - struct NTCPPhase2 - { - uint8_t pubKey[256]; - struct - { - uint8_t hxy[32]; - uint8_t timestamp[4]; - uint8_t filler[12]; - } encrypted; - }; - - struct NTCPWork; - - const size_t NTCP_MAX_MESSAGE_SIZE = 16384; - const size_t NTCP_BUFFER_SIZE = 1028; // fits 1 tunnel data message - const int NTCP_CONNECT_TIMEOUT = 5; // 5 seconds - const int NTCP_ESTABLISH_TIMEOUT = 10; // 10 seconds - const int NTCP_TERMINATION_TIMEOUT = 120; // 2 minutes - const int NTCP_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds - const size_t NTCP_DEFAULT_PHASE3_SIZE = 2/*size*/ + i2p::data::DEFAULT_IDENTITY_SIZE/*387*/ + 4/*ts*/ + 15/*padding*/ + 40/*signature*/; // 448 - const int NTCP_CLOCK_SKEW = 60; // in seconds - const int NTCP_MAX_OUTGOING_QUEUE_SIZE = 200; // how many messages we can queue up - - class NTCPServer; - class NTCPSession: public TransportSession, public std::enable_shared_from_this - { - public: - - NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter = nullptr); - ~NTCPSession (); - void Terminate (); - void Done (); - - boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; - boost::asio::io_service & GetService(); - bool IsEstablished () const { return m_IsEstablished; }; - bool IsTerminated () const { return m_IsTerminated; }; - - void ClientLogin (); - void ServerLogin (); - void SendI2NPMessages (const std::vector >& msgs); - - private: - - void PostI2NPMessages (std::vector > msgs); - void Connected (); - void SendTimeSyncMessage (); - void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; } - - void CreateAESKey (uint8_t * pubKey); - - // client - void SendPhase3 (); - void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandlePhase2 (NTCPWork * work=nullptr); - void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); - void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); - - //server - void SendPhase2 (NTCPWork * work=nullptr); - void SendPhase4 (uint32_t tsA, uint32_t tsB); - void HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB); - void HandlePhase3Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB); - void HandlePhase3ExtraReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB, size_t paddingLen); - void HandlePhase3 (uint32_t tsB, size_t paddingLen); - void HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - - // common - void Receive (); - void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); - bool DecryptNextBlock (const uint8_t * encrypted); - - void Send (std::shared_ptr msg); - boost::asio::const_buffers_1 CreateMsgBuffer (std::shared_ptr msg); - void Send (const std::vector >& msgs); - void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs); - - private: - - NTCPServer& m_Server; - boost::asio::ip::tcp::socket m_Socket; - bool m_IsEstablished, m_IsTerminated; - - i2p::crypto::CBCDecryption m_Decryption; - i2p::crypto::CBCEncryption m_Encryption; - - struct Establisher - { - NTCPPhase1 phase1; - NTCPPhase2 phase2; - } * m_Establisher; - - i2p::crypto::AESAlignedBuffer m_ReceiveBuffer; - i2p::crypto::AESAlignedBuffer<16> m_TimeSyncBuffer; - int m_ReceiveBufferOffset; - - std::shared_ptr m_NextMessage; - size_t m_NextMessageOffset; - i2p::I2NPMessagesHandler m_Handler; - - bool m_IsSending; - std::vector > m_SendQueue; - }; - - // TODO: move to NTCP.h/.cpp - class NTCPServer - { - public: - - typedef i2p::worker::ThreadPool Pool; - - enum RemoteAddressType - { - eIP4Address, - eIP6Address, - eHostname - }; - - enum ProxyType - { - eNoProxy, - eSocksProxy, - eHTTPProxy - }; - - - NTCPServer (int workers=4); - ~NTCPServer (); - - void Start (); - void Stop (); - - bool AddNTCPSession (std::shared_ptr session); - void RemoveNTCPSession (std::shared_ptr session); - std::shared_ptr FindNTCPSession (const i2p::data::IdentHash& ident); - void ConnectWithProxy (const std::string& addr, uint16_t port, RemoteAddressType addrtype, std::shared_ptr conn); - void Connect(const boost::asio::ip::address & address, uint16_t port, std::shared_ptr conn); - - bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; }; - bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; }; - bool NetworkIsReady() const { return IsBoundV4() || IsBoundV6() || UsingProxy(); }; - bool UsingProxy() const { return m_ProxyType != eNoProxy; }; - - void UseProxy(ProxyType proxy, const std::string & address, uint16_t port); - - boost::asio::io_service& GetService () { return m_Service; }; - - void SetSessionLimits(uint16_t softLimit, uint16_t hardLimit) { m_SoftLimit = softLimit; m_HardLimit = hardLimit; } - bool ShouldLimit() const { return ShouldHardLimit() || ShouldSoftLimit(); } - void Work(std::shared_ptr conn, Pool::WorkFunc work) - { - m_CryptoPool->Offer({conn, work}); - } - private: - - /** @brief return true for hard limit */ - bool ShouldHardLimit() const { return m_HardLimit && m_NTCPSessions.size() >= m_HardLimit; } - - /** @brief return true for probabalistic soft backoff */ - bool ShouldSoftLimit() const - { - auto sessions = m_NTCPSessions.size(); - return sessions && m_SoftLimit && m_SoftLimit < sessions && ( rand() % sessions ) <= m_SoftLimit; - } - void Run (); - void HandleAccept (std::shared_ptr conn, const boost::system::error_code& error); - void HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error); - - void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); - - void HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); - void AfterSocksHandshake(std::shared_ptr conn, std::shared_ptr timer, const std::string & host, uint16_t port, RemoteAddressType adddrtype); - - // timer - void ScheduleTermination (); - void HandleTerminationTimer (const boost::system::error_code& ecode); - - private: - - bool m_IsRunning; - std::thread * m_Thread; - boost::asio::io_service m_Service; - boost::asio::io_service::work m_Work; - boost::asio::deadline_timer m_TerminationTimer; - boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor; - std::map > m_NTCPSessions; // access from m_Thread only - std::list > m_PendingIncomingSessions; - - ProxyType m_ProxyType; - std::string m_ProxyAddress; - uint16_t m_ProxyPort; - boost::asio::ip::tcp::resolver m_Resolver; - boost::asio::ip::tcp::endpoint * m_ProxyEndpoint; - - std::shared_ptr m_CryptoPool; - - uint16_t m_SoftLimit, m_HardLimit; - public: - - // for HTTP/I2PControl - const decltype(m_NTCPSessions)& GetNTCPSessions () const { return m_NTCPSessions; }; - }; -} -} - -#endif diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 54bf3fd9..19e17f52 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -133,7 +133,7 @@ namespace transport Transports::Transports (): m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), - m_NTCPServer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), + m_SSUServer (nullptr), m_NTCP2Server (nullptr), m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), @@ -154,7 +154,7 @@ namespace transport } } - void Transports::Start (bool enableNTCP, bool enableSSU) + void Transports::Start (bool enableNTCP2, bool enableSSU) { if (!m_Service) { @@ -169,50 +169,10 @@ namespace transport m_X25519KeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); - std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); - i2p::http::URL proxyurl; - uint16_t softLimit, hardLimit, threads; - i2p::config::GetOption("limits.ntcpsoft", softLimit); - i2p::config::GetOption("limits.ntcphard", hardLimit); - i2p::config::GetOption("limits.ntcpthreads", threads); - if(softLimit > 0 && hardLimit > 0 && softLimit >= hardLimit) - { - LogPrint(eLogError, "ntcp soft limit must be less than ntcp hard limit"); - return; - } - if(ntcpproxy.size() && enableNTCP) - { - if(proxyurl.parse(ntcpproxy)) - { - if(proxyurl.schema == "socks" || proxyurl.schema == "http") - { - m_NTCPServer = new NTCPServer(threads); - m_NTCPServer->SetSessionLimits(softLimit, hardLimit); - NTCPServer::ProxyType proxytype = NTCPServer::eSocksProxy; - - if (proxyurl.schema == "http") - proxytype = NTCPServer::eHTTPProxy; - m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port); - m_NTCPServer->Start(); - if(!m_NTCPServer->NetworkIsReady()) - { - LogPrint(eLogError, "Transports: NTCP failed to start with proxy"); - m_NTCPServer->Stop(); - delete m_NTCPServer; - m_NTCPServer = nullptr; - } - } - else - LogPrint(eLogError, "Transports: unsupported NTCP proxy URL ", ntcpproxy); - } - else - LogPrint(eLogError, "Transports: invalid NTCP proxy url ", ntcpproxy); - return; - } + i2p::http::URL proxyurl; // create NTCP2. TODO: move to acceptor - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) + if (enableNTCP2) { if(!ntcp2proxy.empty()) { @@ -248,20 +208,6 @@ namespace transport for (const auto& address : addresses) { if (!address) continue; - if (m_NTCPServer == nullptr && enableNTCP) - { - m_NTCPServer = new NTCPServer (threads); - m_NTCPServer->SetSessionLimits(softLimit, hardLimit); - m_NTCPServer->Start (); - if (!(m_NTCPServer->IsBoundV6() || m_NTCPServer->IsBoundV4())) { - /** failed to bind to NTCP */ - LogPrint(eLogError, "Transports: failed to bind to TCP"); - m_NTCPServer->Stop(); - delete m_NTCPServer; - m_NTCPServer = nullptr; - } - } - if (address->transportStyle == RouterInfo::eTransportSSU) { if (m_SSUServer == nullptr && enableSSU) @@ -306,13 +252,7 @@ namespace transport delete m_SSUServer; m_SSUServer = nullptr; } - if (m_NTCPServer) - { - m_NTCPServer->Stop (); - delete m_NTCPServer; - m_NTCPServer = nullptr; - } - + if (m_NTCP2Server) { m_NTCP2Server->Stop (); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 48eee4b4..c3008b09 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -21,7 +21,6 @@ #include #include #include "TransportSession.h" -#include "NTCPSession.h" #include "SSU.h" #include "NTCP2.h" #include "RouterInfo.h" @@ -88,10 +87,9 @@ namespace transport Transports (); ~Transports (); - void Start (bool enableNTCP=true, bool enableSSU=true); + void Start (bool enableNTCP2=true, bool enableSSU=true); void Stop (); - bool IsBoundNTCP() const { return m_NTCPServer != nullptr; } bool IsBoundSSU() const { return m_SSUServer != nullptr; } bool IsBoundNTCP2() const { return m_NTCP2Server != nullptr; } @@ -159,7 +157,6 @@ namespace transport boost::asio::io_service::work * m_Work; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer; - NTCPServer * m_NTCPServer; SSUServer * m_SSUServer; NTCP2Server * m_NTCP2Server; mutable std::mutex m_PeersMutex; @@ -186,7 +183,6 @@ namespace transport public: // for HTTP only - const NTCPServer * GetNTCPServer () const { return m_NTCPServer; }; const SSUServer * GetSSUServer () const { return m_SSUServer; }; const NTCP2Server * GetNTCP2Server () const { return m_NTCP2Server; }; const decltype(m_Peers)& GetPeers () const { return m_Peers; }; diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 6eec3a16..468d2d00 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -42,7 +42,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/NetDb.cpp \ ../../libi2pd/NetDbRequests.cpp \ ../../libi2pd/NTCP2.cpp \ - ../../libi2pd/NTCPSession.cpp \ ../../libi2pd/Poly1305.cpp \ ../../libi2pd/Profiling.cpp \ ../../libi2pd/Reseed.cpp \ @@ -123,7 +122,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/NetDb.hpp \ ../../libi2pd/NetDbRequests.h \ ../../libi2pd/NTCP2.h \ - ../../libi2pd/NTCPSession.h \ ../../libi2pd/Poly1305.h \ ../../libi2pd/Profiling.h \ ../../libi2pd/Queue.h \ From c2f13a1496272237d348ed1f76d0836d4daaca8e Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 3 Oct 2020 22:29:52 -0400 Subject: [PATCH 0462/2950] some cleanup --- daemon/Daemon.cpp | 5 ++--- libi2pd/RouterContext.cpp | 45 +++++++-------------------------------- libi2pd/RouterContext.h | 2 +- libi2pd/RouterInfo.cpp | 14 ------------ libi2pd/RouterInfo.h | 1 - 5 files changed, 11 insertions(+), 56 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 5f98d47a..f5d4d24f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -142,8 +142,7 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - bool ntcp; i2p::config::GetOption("ntcp", ntcp); - i2p::context.PublishNTCPAddress (ntcp, !ipv6); + i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) { @@ -151,7 +150,7 @@ namespace i2p if (published) { uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port); - if (!ntcp && !ntcp2port) ntcp2port = port; // use standard port + if (!ntcp2port) ntcp2port = port; // use standard port i2p::context.PublishNTCP2Address (ntcp2port, true); // publish if (ipv6) { diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 7333e613..69e69d7c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -373,48 +373,19 @@ namespace i2p return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; } - void RouterContext::PublishNTCPAddress (bool publish, bool v4only) + void RouterContext::RemoveNTCPAddress (bool v4only) { auto& addresses = m_RouterInfo.GetAddresses (); - if (publish) + for (auto it = addresses.begin (); it != addresses.end ();) { - for (const auto& addr : addresses) // v4 + if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !(*it)->IsNTCP2 () && + (!v4only || (*it)->host.is_v4 ())) { - if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU && - addr->host.is_v4 ()) - { - // insert NTCP address with host/port from SSU - m_RouterInfo.AddNTCPAddress (addr->host.to_string ().c_str (), addr->port); - break; - } - } - if (!v4only) - { - for (const auto& addr : addresses) // v6 - { - if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU && - addr->host.is_v6 ()) - { - // insert NTCP address with host/port from SSU - m_RouterInfo.AddNTCPAddress (addr->host.to_string ().c_str (), addr->port); - break; - } - } - } - } - else - { - for (auto it = addresses.begin (); it != addresses.end ();) - { - if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !(*it)->IsNTCP2 () && - (!v4only || (*it)->host.is_v4 ())) - { - it = addresses.erase (it); - if (v4only) break; // otherwise might be more than one address - } - else - ++it; + it = addresses.erase (it); + if (v4only) break; // otherwise might be more than one address } + else + ++it; } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 6f08a87a..a576d6b6 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -89,7 +89,7 @@ namespace i2p void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon void PublishNTCP2Address (int port, bool publish = true, bool v4only = false); void UpdateNTCP2Address (bool enable); - void PublishNTCPAddress (bool publish, bool v4only = true); + void RemoveNTCPAddress (bool v4only = true); // delete NTCP address for older routers. TODO: remove later bool AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer); void RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); bool IsUnreachable () const; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 703c853f..12f81a42 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -709,20 +709,6 @@ namespace data s.write (str.c_str (), len); } - void RouterInfo::AddNTCPAddress (const char * host, int port) - { - auto addr = std::make_shared
(); - addr->host = boost::asio::ip::address::from_string (host); - addr->port = port; - addr->transportStyle = eTransportNTCP; - addr->cost = 6; - addr->date = 0; - for (const auto& it: *m_Addresses) // don't insert same address twice - if (*it == *addr) return; - m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4; - m_Addresses->push_front(std::move(addr)); // always make NTCP first - } - void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu) { auto addr = std::make_shared
(); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 1c0063b0..282c34f9 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -157,7 +157,6 @@ namespace data std::shared_ptr GetSSUAddress (bool v4only = true) const; std::shared_ptr GetSSUV6Address () const; - void AddNTCPAddress (const char * host, int port); void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0); bool AddIntroducer (const Introducer& introducer); From d3f7eea0a3e505a9adee2780036a646e6ef008fe Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:05:57 +0300 Subject: [PATCH 0463/2950] [appveyor] Disable unavailable repository Ref: https://github.com/msys2/MINGW-packages/issues/7084 --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index d5f67b14..0b105031 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,6 +26,9 @@ install: - 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" +# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 +- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" +- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" # 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 From 7ceb81cc8302d3e504b9a3106c39e0579ad7706d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:16:43 +0300 Subject: [PATCH 0464/2950] [appveyor] clean packages cache after disabling mirrors --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0b105031..350a2c05 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,9 +26,10 @@ install: - 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" -# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 +# disable inaccessible miror (doing same for sourceforge because it's laggy) and clean cache - https://github.com/msys2/MINGW-packages/issues/7084 - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syy" # 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 From 65e15d74fc255cc920a0ae30164454e480b377cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:32:21 +0300 Subject: [PATCH 0465/2950] [appveyor] print mirrorlist (testing) --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 350a2c05..c993a6ba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,10 +26,10 @@ install: - 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" -# disable inaccessible miror (doing same for sourceforge because it's laggy) and clean cache - https://github.com/msys2/MINGW-packages/issues/7084 +# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" - c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syy" +- c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # 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 From e614226926ce51f217364d0630130c245fb36437 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:39:40 +0300 Subject: [PATCH 0466/2950] [appveyor] change repository disabling way (testing) --- appveyor.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c993a6ba..346cda4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,9 +26,8 @@ install: - 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" -# disable inaccessible miror (doing same for sourceforge because it's laggy) - https://github.com/msys2/MINGW-packages/issues/7084 -- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ http:\/\/repo\.msys2\.org/#Server\ =\ http:\/\/repo\.msys2\.org/g' /etc/pacman.d/mirrorlist.*" -- c:\msys64\usr\bin\bash -lc "sed -i 's/^Server\ =\ https:\/\/sourceforge\.net/#Server\ =\ https:\/\/sourceforge\.net/g' /etc/pacman.d/mirrorlist.*" +# disable inaccessible miror - https://github.com/msys2/MINGW-packages/issues/7084 +- c:\msys64\usr\bin\bash -lc "sed -e '/repo\.msys2\.org/ s/^#*/#/' -i /etc/pacman.d/mirrorlist.*" - c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # 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" From 77231bfc6c03c8176065699b0c535c7a6b8e0cc9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:53:31 +0300 Subject: [PATCH 0467/2950] [appeveyor] rewrite mirrorlist (testing) https://github.com/msys2/MINGW-packages/issues/7084#issuecomment-703211308 --- appveyor.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 346cda4c..c6b562c4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -26,8 +26,10 @@ install: - 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" -# disable inaccessible miror - https://github.com/msys2/MINGW-packages/issues/7084 -- c:\msys64\usr\bin\bash -lc "sed -e '/repo\.msys2\.org/ s/^#*/#/' -i /etc/pacman.d/mirrorlist.*" +# disable inaccessible miror (something block sed from changing files, so rewrite them) - https://github.com/msys2/MINGW-packages/issues/7084 +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" - c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # 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" From 67b76809eab7b57c66295b0224e334ef68a4b2dc Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 4 Oct 2020 09:57:45 +0300 Subject: [PATCH 0468/2950] [appveyor] rewrite mirrorlist after updating runtime If pacman was updated on runtime update, changes which we domne earlier will be rewrited by config from package --- appveyor.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c6b562c4..10165e5f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,13 +30,16 @@ install: - c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" - c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" - c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" -- c:\msys64\usr\bin\bash -lc "cat /etc/pacman.d/mirrorlist.*" # 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 +# rewrite mirrorlist again because pacman update can rewrite it +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" +- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" # update packages and install required - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" From 243f6e755b27b58b5e33b41b8022c7afc0bd5881 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Oct 2020 09:34:15 -0400 Subject: [PATCH 0469/2950] restore copyright header --- daemon/Daemon.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index f5d4d24f..1b9c0a2c 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -1,3 +1,11 @@ +/* +* 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 #include From d218c9a9832f7419e11c94573a5a866bdef4a6e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Oct 2020 10:12:33 -0400 Subject: [PATCH 0470/2950] disable ntcpproxy --- libi2pd/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index e0dc66d8..1c565083 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -60,7 +60,7 @@ namespace config { ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") ("ntcp", value()->default_value(false), "Ignored. Always false") ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") - ("ntcpproxy", value()->default_value(""), "Proxy URL for NTCP transport") + ("ntcpproxy", value()->default_value(""), "Ignored") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") From 59032d515b0b9cb41dec1b0abc7adf8394dbfd0e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 4 Oct 2020 19:52:12 -0400 Subject: [PATCH 0471/2950] i2p.streaming.answerPings=false by default for client tunnels --- libi2pd_client/ClientContext.cpp | 8 ++++---- libi2pd_client/ClientContext.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e83e293a..04f50e6f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -444,7 +444,7 @@ namespace client } template - void ClientContext::ReadI2CPOptions (const Section& section, std::map& options) const + void ClientContext::ReadI2CPOptions (const Section& section, bool isServer, std::map& options) const { options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH); @@ -454,7 +454,7 @@ namespace client options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY); options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY); 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, DEFAULT_ANSWER_PINGS); + 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, ""); if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; @@ -570,7 +570,7 @@ namespace client i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); // I2CP std::map options; - ReadI2CPOptions (section, options); + ReadI2CPOptions (section, false, options); std::shared_ptr localDestination = nullptr; if (keys.length () > 0) @@ -694,7 +694,7 @@ namespace client // I2CP std::map options; - ReadI2CPOptions (section, options); + ReadI2CPOptions (section, true, options); std::shared_ptr localDestination = nullptr; auto it = destinations.find (keys); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 05b754fe..076aaa5f 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -115,7 +115,7 @@ namespace client template void ReadI2CPOptionsGroup (const Section& section, const std::string& group, std::map& options) const; template - void ReadI2CPOptions (const Section& section, std::map& options) const; // for tunnels + void ReadI2CPOptions (const Section& section, bool isServer, std::map& options) const; // for tunnels void ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const; // for HTTP and SOCKS proxy void CleanupUDP(const boost::system::error_code & ecode); From 471c46ad8e2f9f6869e005105730bfb87fa69e0b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Oct 2020 16:22:40 -0400 Subject: [PATCH 0472/2950] remove some HTTP headers from response --- libi2pd_client/I2PTunnel.cpp | 104 ++++++++++++++++++++++++++--------- libi2pd_client/I2PTunnel.h | 6 +- 2 files changed, 83 insertions(+), 27 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 3575e062..946d55d5 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -139,22 +139,25 @@ namespace client } } else - { - if (m_Stream) - { - auto s = shared_from_this (); - m_Stream->AsyncSend (m_Buffer, bytes_transferred, - [s](const boost::system::error_code& ecode) - { - if (!ecode) - s->Receive (); - else - s->Terminate (); - }); - } - } + WriteToStream (m_Buffer, bytes_transferred); } + void I2PTunnelConnection::WriteToStream (const uint8_t * buf, size_t len) + { + if (m_Stream) + { + auto s = shared_from_this (); + m_Stream->AsyncSend (buf, len, + [s](const boost::system::error_code& ecode) + { + if (!ecode) + s->Receive (); + else + s->Terminate (); + }); + } + } + void I2PTunnelConnection::HandleWrite (const boost::system::error_code& ecode) { if (ecode) @@ -302,7 +305,8 @@ namespace client I2PServerTunnelConnectionHTTP::I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host): - I2PTunnelConnection (owner, stream, socket, target), m_Host (host), m_HeaderSent (false), m_From (stream->GetRemoteIdentity ()) + I2PTunnelConnection (owner, stream, socket, target), m_Host (host), + m_HeaderSent (false), m_ResponseHeaderSent (false), m_From (stream->GetRemoteIdentity ()) { } @@ -333,12 +337,59 @@ namespace client else break; } - // add X-I2P fields - if (m_From) + + if (endOfHeader) { - m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n"; - m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n"; - m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n"; + // add X-I2P fields + if (m_From) + { + m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n"; + m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n"; + m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n"; + } + + m_OutHeader << "\r\n"; // end of header + m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header + m_InHeader.str (""); + m_From = nullptr; + m_HeaderSent = true; + I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); + } + } + } + + void I2PServerTunnelConnectionHTTP::WriteToStream (const uint8_t * buf, size_t len) + { + if (m_ResponseHeaderSent) + I2PTunnelConnection::WriteToStream (buf, len); + else + { + m_InHeader.clear (); + if (m_InHeader.str ().empty ()) m_OutHeader.str (""); // start of response + m_InHeader.write ((const char *)buf, len); + std::string line; + bool endOfHeader = false; + while (!endOfHeader) + { + std::getline(m_InHeader, line); + if (!m_InHeader.fail ()) + { + if (line == "\r") endOfHeader = true; + else + { + if (line.find ("Server:") != std::string::npos) continue; // exclude "Server:" + if (line.find ("Date:") != std::string::npos) continue; // exclude "Date"" + if (line[0] == 'X') + { + if (line.find ("X-Runtime:") != std::string::npos) continue; // exclude "X-Runtime:" + if (line.find ("X-Powered-By:") != std::string::npos) continue; // exclude "X-Powered-By:" + } + + m_OutHeader << line << "\n"; + } + } + else + break; } if (endOfHeader) @@ -346,12 +397,15 @@ namespace client m_OutHeader << "\r\n"; // end of header m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header m_InHeader.str (""); - m_HeaderSent = true; - I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); - } - } + m_ResponseHeaderSent = true; + I2PTunnelConnection::WriteToStream ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); + m_OutHeader.str (""); + } + else + Receive (); + } } - + I2PTunnelConnectionIRC::I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass): diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index b76a1027..f7185dfd 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -57,7 +57,8 @@ namespace client void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); virtual void Write (const uint8_t * buf, size_t len); // can be overloaded void HandleWrite (const boost::system::error_code& ecode); - + virtual void WriteToStream (const uint8_t * buf, size_t len); // can be overloaded + void StreamReceive (); void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleConnect (const boost::system::error_code& ecode); @@ -103,12 +104,13 @@ namespace client protected: void Write (const uint8_t * buf, size_t len); + void WriteToStream (const uint8_t * buf, size_t len); private: std::string m_Host; std::stringstream m_InHeader, m_OutHeader; - bool m_HeaderSent; + bool m_HeaderSent, m_ResponseHeaderSent; std::shared_ptr m_From; }; From 724662498330644693bd74df24aef144778c5bdd Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 6 Oct 2020 19:24:03 -0400 Subject: [PATCH 0473/2950] list of headers to remove --- libi2pd_client/I2PTunnel.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 946d55d5..081294c6 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -328,7 +328,7 @@ namespace client if (line == "\r") endOfHeader = true; else { - if (m_Host.length () > 0 && line.find ("Host:") != std::string::npos) + if (m_Host.length () > 0 && !line.compare(0, 5, "Host:")) m_OutHeader << "Host: " << m_Host << "\r\n"; // override host else m_OutHeader << line << "\n"; @@ -377,15 +377,19 @@ namespace client if (line == "\r") endOfHeader = true; else { - if (line.find ("Server:") != std::string::npos) continue; // exclude "Server:" - if (line.find ("Date:") != std::string::npos) continue; // exclude "Date"" - if (line[0] == 'X') - { - if (line.find ("X-Runtime:") != std::string::npos) continue; // exclude "X-Runtime:" - if (line.find ("X-Powered-By:") != std::string::npos) continue; // exclude "X-Powered-By:" - } - - m_OutHeader << line << "\n"; + static const std::vector excluded // list of excluded headers + { + "Server:", "Date:", "X-Runtime:", "X-Powered-By:", "Proxy" + }; + bool matched = false; + for (const auto& it: excluded) + if (!line.compare(0, it.length (), it)) + { + matched = true; + break; + } + if (!matched) + m_OutHeader << line << "\n"; } } else From b0c690d836822e4bd9fdc9d545aba4dc9054594f Mon Sep 17 00:00:00 2001 From: user Date: Wed, 7 Oct 2020 19:25:02 +0800 Subject: [PATCH 0474/2950] qt: build* added to .gitignore --- qt/i2pd_qt/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/qt/i2pd_qt/.gitignore b/qt/i2pd_qt/.gitignore index f1d57c58..bbf3e1e4 100644 --- a/qt/i2pd_qt/.gitignore +++ b/qt/i2pd_qt/.gitignore @@ -8,4 +8,5 @@ Makefile* object_script.* i2pd_qt_plugin_import.cpp i2pd_qt.pro.autosave* +build* From f6ff232106ee59d4feca5c22803c9b5896cf5a3b Mon Sep 17 00:00:00 2001 From: user Date: Wed, 7 Oct 2020 23:16:06 +0800 Subject: [PATCH 0475/2950] qt: crypto type added --- qt/i2pd_qt/ClientTunnelPane.cpp | 17 ++++++++++ qt/i2pd_qt/ClientTunnelPane.h | 13 ++++++++ qt/i2pd_qt/ServerTunnelPane.cpp | 17 ++++++++++ qt/i2pd_qt/ServerTunnelPane.h | 13 ++++++++ qt/i2pd_qt/TunnelConfig.cpp | 8 +++-- qt/i2pd_qt/TunnelConfig.h | 15 ++++++--- qt/i2pd_qt/mainwindow.cpp | 56 +++++++++++++++++++++++++++------ qt/i2pd_qt/mainwindow.h | 31 +++++++++++++----- 8 files changed, 146 insertions(+), 24 deletions(-) diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 256d0510..fbfa74cb 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -168,6 +168,23 @@ int ClientTunnelPane::appendClientTunnelForm( horizontalLayout_2->addItem(horizontalSpacer); tunnelGridLayout->addLayout(horizontalLayout_2); } + { + int cryptoType = tunnelConfig->getcryptoType(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2); + cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel")); + horizontalLayout_2->addWidget(cryptoTypeLabel); + ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2); + cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit")); + cryptoTypeLineEdit->setText(QString::number(cryptoType)); + cryptoTypeLineEdit->setMaximumWidth(80); + QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(cryptoTypeLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); + } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index c2e076b7..80d331de 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -53,6 +53,10 @@ private: QLabel * sigTypeLabel; QComboBox * sigTypeComboBox; + //cryptoType + QLabel * cryptoTypeLabel; + QLineEdit * cryptoTypeLineEdit; + protected slots: virtual void setGroupBoxTitle(const QString & title); @@ -61,6 +65,7 @@ private: typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0)); destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0)); portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0)); + cryptoTypeLabel->setText(QApplication::translate("cltTunForm", "Crypto type:", 0)); keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0)); destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0)); addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0)); @@ -86,6 +91,14 @@ protected: } ctc->setport(portInt); + auto cryptoTypeStr=cryptoTypeLineEdit->text(); + int cryptoTypeInt=cryptoTypeStr.toInt(&ok); + if(!ok){ + highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit); + return false; + } + ctc->setcryptoType(cryptoTypeInt); + ctc->setkeys(keysLineEdit->text().toStdString()); ctc->setaddress(addressLineEdit->text().toStdString()); diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index bc6389a9..cd751f5d 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -235,6 +235,23 @@ int ServerTunnelPane::appendServerTunnelForm( horizontalLayout_2->addItem(horizontalSpacer); tunnelGridLayout->addLayout(horizontalLayout_2); } + { + int cryptoType = tunnelConfig->getcryptoType(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2); + cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel")); + horizontalLayout_2->addWidget(cryptoTypeLabel); + ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2); + cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit")); + cryptoTypeLineEdit->setText(QString::number(cryptoType)); + cryptoTypeLineEdit->setMaximumWidth(80); + QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(cryptoTypeLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); + } { I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); appendControlsForI2CPParameters(i2cpParameters, gridIndex); diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index 0a07267b..92ee4da5 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -65,6 +65,10 @@ private: QLabel * inPortLabel; QLineEdit * inPortLineEdit; + //cryptoType + QLabel * cryptoTypeLabel; + QLineEdit * cryptoTypeLineEdit; + //accessList QLabel * accessListLabel; QLineEdit * accessListLineEdit; @@ -101,6 +105,7 @@ private: portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0)); + cryptoTypeLabel->setText(QApplication::translate("srvTunForm", "Crypto type:", 0)); accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0)); hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0)); webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0)); @@ -129,6 +134,14 @@ protected: } stc->setport(portInt); + auto cryptoTypeStr=cryptoTypeLineEdit->text(); + int cryptoTypeInt=cryptoTypeStr.toInt(&ok); + if(!ok){ + highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit); + return false; + } + stc->setcryptoType(cryptoTypeInt); + stc->setkeys(keysLineEdit->text().toStdString()); auto str=inPortLineEdit->text(); diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index 8ed72930..04fa6132 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -32,6 +32,7 @@ void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { << "port=" << port << "\n" << "destination=" << dest << "\n" << "destinationport=" << destinationPort << "\n" + << "cryptoType=" << getcryptoType() << "\n" << "signaturetype=" << sigType << "\n"; if(!keys.empty()) out << "keys=" << keys << "\n"; } @@ -41,9 +42,10 @@ void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { out << "host=" << host << "\n" << "port=" << port << "\n" << "signaturetype=" << sigType << "\n" - << "inport=" << inPort << "\n" - << "accesslist=" << accessList << "\n" - << "gzip=" << (gzip?"true":"false") << "\n" + << "inport=" << inPort << "\n"; + if(accessList.size()>0) { out << "accesslist=" << accessList << "\n"; } + out << "gzip=" << (gzip?"true":"false") << "\n" + << "cryptoType=" << getcryptoType() << "\n" << "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n" << "address=" << address << "\n" << "hostoverride=" << hostOverride << "\n" diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 059d48b5..7f262215 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -58,12 +58,14 @@ class TunnelConfig { QString type; std::string name; TunnelPane* tunnelPane; + int cryptoType; public: - TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): - type(type_), name(name_), i2cpParameters(i2cpParameters_) {} + TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_, int cryptoType_): + type(type_), name(name_), cryptoType(cryptoType_), i2cpParameters(i2cpParameters_) {} virtual ~TunnelConfig(){} const QString& getType(){return type;} const std::string& getName(){return name;} + int getcryptoType(){return cryptoType;} void setType(const QString& type_){type=type_;} void setName(const std::string& name_){name=name_;} I2CPParameters& getI2cpParameters(){return i2cpParameters;} @@ -74,6 +76,7 @@ public: virtual ServerTunnelConfig* asServerTunnelConfig()=0; void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;} TunnelPane* getTunnelPane() {return tunnelPane;} + void setcryptoType(int cryptoType_){cryptoType=cryptoType_;} private: I2CPParameters i2cpParameters; }; @@ -114,13 +117,14 @@ public: std::string keys_, std::string address_, int destinationPort_, - i2p::data::SigningKeyType sigType_): TunnelConfig(name_, type_, i2cpParameters_), + i2p::data::SigningKeyType sigType_, + int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_), dest(dest_), port(port_), keys(keys_), address(address_), destinationPort(destinationPort_), - sigType(sigType_){} + sigType(sigType_) {} std::string& getdest(){return dest;} int getport(){return port;} std::string & getkeys(){return keys;} @@ -188,7 +192,8 @@ public: bool gzip_, i2p::data::SigningKeyType sigType_, std::string address_, - bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_), + bool isUniqueLocal_, + int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_), host(host_), port(port_), keys(keys_), diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 0ce0e2f8..14a57f8a 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -159,12 +159,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren # define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option)) initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton); - initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton); initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton); - initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton); - daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";})); - serviceOption=initNonGUIOption( OPTION("","service",[]{return "";})); uiSettings->logDestinationComboBox->clear(); uiSettings->logDestinationComboBox->insertItems(0, QStringList() @@ -176,20 +172,28 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton); initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox); - + //TODO add option "logclftime" "Write full CLF-formatted date and time to log (default: write only time)" + initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton); initIPAddressBox( OPTION("","host",[]{return "";}), uiSettings->routerExternalHostLineEdit, tr("Router external address -> Host")); initTCPPortBox( OPTION("","port",[]{return "";}), uiSettings->routerExternalPortLineEdit, tr("Router external address -> Port")); - + daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";})); + serviceOption=initNonGUIOption( OPTION("","service",[]{return "";})); + //TODO add option "ifname4" Network interface to bind to for IPv4 + //TODO add option "ifname6" Network interface to bind to for IPv6 + //TODO add option "nat" If true, assume we are behind NAT. true by default + //TODO add option "ipv4" Enable communication through IPv4. true by default initCheckBox( OPTION("","ipv6",[]{return "false";}), uiSettings->ipv6CheckBox); initCheckBox( OPTION("","notransit",[]{return "false";}), uiSettings->notransitCheckBox); initCheckBox( OPTION("","floodfill",[]{return "false";}), uiSettings->floodfillCheckBox); initStringBox( OPTION("","bandwidth",[]{return "";}), uiSettings->bandwidthLineEdit); + //TODO add option "share" Max % of bandwidth limit for transit. 0-100. 100 by default initStringBox( OPTION("","family",[]{return "";}), uiSettings->familyLineEdit); initIntegerBox( OPTION("","netid",[]{return "2";}), uiSettings->netIdLineEdit, tr("NetID")); + //TODO add option "ssu" Enable SSU transport protocol (use UDP). true by default #ifdef Q_OS_WIN - initCheckBox( OPTION("","insomnia",[]{return "";}), uiSettings->insomniaCheckBox); initNonGUIOption( OPTION("","svcctl",[]{return "";})); + initCheckBox( OPTION("","insomnia",[]{return "";}), uiSettings->insomniaCheckBox); initNonGUIOption( OPTION("","close",[]{return "";})); #else uiSettings->insomniaCheckBox->setEnabled(false); @@ -201,17 +205,22 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("http","auth",[]{return "";}), uiSettings->webconsoleBasicAuthCheckBox); initStringBox( OPTION("http","user",[]{return "i2pd";}), uiSettings->webconsoleUserNameLineEditBasicAuth); initStringBox( OPTION("http","pass",[]{return "";}), uiSettings->webconsolePasswordLineEditBasicAuth); + //TODO add option "http.strictheaders Enable strict host checking on WebUI. true by default + //TODO add option "http.hostname Expected hostname for WebUI (default: localhost) initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), uiSettings->httpProxyEnabledCheckBox); initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); + //TODO add option "httpproxy.addresshelper Enable address helper (jump). true by default initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton); - initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType); initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit); initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit); initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), uiSettings->httpProxyOutBoundTunnLenLineEdit); initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), uiSettings->httpProxyOutboundTunnQuantityLineEdit); + //TODO add option "httpproxy.outproxy HTTP proxy upstream out proxy url (like http://false.i2p) + //TODO add option "httpproxy.i2cp.leaseSetType Type of LeaseSet to be sent. 1, 3 or 5. 1 by default + //TODO add option "httpproxy.i2cp.leaseSetEncType Comma separated encryption types to be used in LeaseSet type 3 or 5 initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox); initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); @@ -224,10 +233,13 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), uiSettings->socksProxyOutboundTunnQuantityLineEdit); initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + //TODO add option "socksproxy.i2cp.leaseSetType Type of LeaseSet to be sent. 1, 3 or 5. 1 by default + //TODO add option "socksproxy.i2cp.leaseSetEncType Comma separated encryption types to be used in LeaseSet type 3 or 5 initCheckBox( OPTION("sam","enabled",[]{return "false";}), uiSettings->samEnabledCheckBox); initIPAddressBox( OPTION("sam","address",[]{return "";}), uiSettings->samAddressLineEdit, tr("SAM -> IP address")); initTCPPortBox( OPTION("sam","port",[]{return "7656";}), uiSettings->samPortLineEdit, tr("SAM -> Port")); + //TODO add option "sam.singlethread If false every SAM session runs in own thread. true by default initCheckBox( OPTION("bob","enabled",[]{return "false";}), uiSettings->bobEnabledCheckBox); initIPAddressBox( OPTION("bob","address",[]{return "";}), uiSettings->bobAddressLineEdit, tr("BOB -> IP address")); @@ -236,6 +248,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), uiSettings->i2cpEnabledCheckBox); initIPAddressBox( OPTION("i2cp","address",[]{return "";}), uiSettings->i2cpAddressLineEdit, tr("I2CP -> IP address")); initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), uiSettings->i2cpPortLineEdit, tr("I2CP -> Port")); + //TODO add option "i2cp.singlethread If false every I2CP session runs in own thread. true by default initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), uiSettings->i2pControlEnabledCheckBox); initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), uiSettings->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); @@ -252,6 +265,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("reseed","verify",[]{return "";}), uiSettings->reseedVerifyCheckBox); initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton); initStringBox( OPTION("reseed","urls",[]{return "";}), uiSettings->reseedURLsLineEdit); + //TODO add option "reseed.zipfile Path to local .zip file to reseed from + //TODO add option "reseed.threshold Minimum number of known routers before requesting reseed. 25 by default + //TODO add option "reseed.proxy Url for https/socks reseed proxy initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), uiSettings->addressbookDefaultURLLineEdit); initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), uiSettings->addressbookSubscriptionsURLslineEdit); @@ -259,12 +275,34 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initUInt16Box( OPTION("limits","transittunnels",[]{return "2500";}), uiSettings->maxNumOfTransitTunnelsLineEdit, tr("maxNumberOfTransitTunnels")); initUInt16Box( OPTION("limits","openfiles",[]{return "0";}), uiSettings->maxNumOfOpenFilesLineEdit, tr("maxNumberOfOpenFiles")); initUInt32Box( OPTION("limits","coresize",[]{return "0";}), uiSettings->coreFileMaxSizeNumberLineEdit, tr("coreFileMaxSize")); + //TODO add option "limits.ntcpsoft Threshold to start probabalistic backoff with ntcp sessions (0 - use system limit) + //TODO add option "limits.ntcphard Maximum number of ntcp sessions (0 - use system limit) initCheckBox( OPTION("trust","enabled",[]{return "false";}), uiSettings->checkBoxTrustEnable); initStringBox( OPTION("trust","family",[]{return "";}), uiSettings->lineEditTrustFamily); initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters); initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden); + //TODO add option "websockets.enabled Enable websocket server. Disabled by default + //TODO add option "websockets.address Address to bind websocket server on. 127.0.0.1 by default + //TODO add option "websockets.port Port to bind websocket server on. 7666 by default + + //TODO add option "exploratory.inbound.length Exploratory inbound tunnels length. 2 by default + //TODO add option "exploratory.inbound.quantity Exploratory inbound tunnels quantity. 3 by default + //TODO add option "exploratory.outbound.length Exploratory outbound tunnels length. 2 by default + //TODO add option "exploratory.outbound.quantity Exploratory outbound tunnels length. 3 by default + + //TODO add option "ntcp2.enabled Enable NTCP2. Enabled by default + //TODO add option "ntcp2.published Enable incoming NTCP2 connections. Disabled by default + //TODO add option "ntcp2.port Port to listen for incoming NTCP2 connections (default: auto) + //TODO add option "ntcp2.addressv6 External IPv6 for incoming connections + //TODO add option "ntcp2.proxy Specify proxy server for NTCP2. Should be http://address:port or socks://address:port + + //TODO add option "nettime.enabled Enable NTP sync. Disabled by default + //TODO add option "nettime.ntpservers Comma-separated list of NTP server. pool.ntp.org by default + //TODO add option "nettime.ntpsyncinterval NTP time sync interval in hours. 72 by default + + //TODO add option "persist.profiles Enable peer profile persisting to disk. Enabled by default # undef OPTION //widgetlocks.add(new widgetlock(widget,lockbtn)); @@ -666,7 +704,7 @@ void MainWindow::layoutTunnels() { int height=0; ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0); for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { - const std::string& name=it->first; + //const std::string& name=it->first; TunnelConfig* tunconf = it->second; TunnelPane * tunnelPane=tunconf->getTunnelPane(); if(!tunnelPane)continue; diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 91c99122..5fefbc06 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -104,10 +104,13 @@ class MainWindowItem : public QObject { QWidget* widgetToFocus; QString requirementToBeValid; public: - MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {} + MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : + option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), + optionValuePresent(false) {} QWidget* getWidgetToFocus(){return widgetToFocus;} QString& getRequirementToBeValid() { return requirementToBeValid; } ConfigOption& getConfigOption() { return option; } + bool optionValuePresent; boost::any optionValue; virtual ~MainWindowItem(){} virtual void installListeners(MainWindow *mainWindow); @@ -118,7 +121,8 @@ public: //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; boost::any programOption; i2p::config::GetOptionAsAny(optName, programOption); - optionValue=programOption.empty()?boost::any(std::string("")) + optionValuePresent=!programOption.empty(); + optionValue=!optionValuePresent?boost::any(std::string("")) :boost::any_cast(programOption).value(); } virtual void saveToStringStream(std::stringstream& out){ @@ -126,7 +130,7 @@ public: std::string v = boost::any_cast(optionValue); if(v.empty())return; } - if(optionValue.empty())return; + if(!optionValuePresent || optionValue.empty())return; std::string rtti = optionValue.type().name(); std::string optName=""; if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); @@ -180,6 +184,7 @@ public: virtual void saveToStringStream(std::stringstream& out){ optionValue=fromString(lineEdit->text()); + optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -234,6 +239,7 @@ public: virtual void saveToStringStream(std::stringstream& out){ std::string logDest = comboBox->currentText().toStdString(); optionValue=logDest; + optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -251,6 +257,7 @@ public: } virtual void saveToStringStream(std::stringstream& out){ optionValue=comboBox->currentText().toStdString(); + optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -268,6 +275,7 @@ public: virtual void saveToStringStream(std::stringstream& out){ uint16_t selected = SignatureTypeComboBoxFactory::getSigType(comboBox->currentData()); optionValue=(unsigned short)selected; + optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -284,6 +292,7 @@ public: } virtual void saveToStringStream(std::stringstream& out){ optionValue=checkBox->isChecked(); + optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -613,6 +622,7 @@ private: std::string keys = ""; std::string address = "127.0.0.1"; int destinationPort = 0; + int cryptoType = 0; i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; // I2CP I2CPParameters i2cpParameters; @@ -624,7 +634,8 @@ private: keys, address, destinationPort, - sigType); + sigType, + cryptoType); saveAllConfigs(true, name); } @@ -643,6 +654,7 @@ private: i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; std::string address = "127.0.0.1"; bool isUniqueLocal = true; + int cryptoType = 0; // I2CP I2CPParameters i2cpParameters; @@ -659,7 +671,8 @@ private: gzip, sigType, address, - isUniqueLocal); + isUniqueLocal, + cryptoType); saveAllConfigs(true, name); @@ -712,6 +725,7 @@ private: // optional params std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); + int cryptoType = section.second.get(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0); int destinationPort = section.second.get(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); std::cout << "had read tunnel destinationPort: " << destinationPort << std::endl; i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); @@ -726,7 +740,8 @@ private: keys, address, destinationPort, - sigType); + sigType, + cryptoType); } else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP @@ -746,6 +761,7 @@ private: i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); + int cryptoType = section.second.get(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0); // I2CP std::map options; @@ -779,7 +795,8 @@ private: gzip, sigType, address, - isUniqueLocal); + isUniqueLocal, + cryptoType); } else LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui From e2a1cd12c36d1d00120b260158fe487ef269e17f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Oct 2020 21:13:26 -0400 Subject: [PATCH 0476/2950] don't delete unreachable routers if too few --- libi2pd/NetDb.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 5930baf7..4ce839ee 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -560,6 +560,9 @@ namespace data updatedCount++; continue; } + // make router reachable back if too few routers + if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS) + it.second->SetUnreachable (false); // find & mark expired routers if (it.second->UsesIntroducer ()) { @@ -575,7 +578,7 @@ namespace data // delete RI file m_Storage.Remove(ident); deletedCount++; - if (total - deletedCount < NETDB_MIN_ROUTERS) checkForExpiration = false; + if (total - deletedCount < NETDB_MIN_ROUTERS) checkForExpiration = false; } } // m_RouterInfos iteration From 01087450659a52fd2f5ca065c0355ba81c5bc024 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 8 Oct 2020 15:11:55 +0800 Subject: [PATCH 0477/2950] qt: bool optionValuePresent removed --- qt/i2pd_qt/mainwindow.h | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 5fefbc06..6e187b5b 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -105,12 +105,10 @@ class MainWindowItem : public QObject { QString requirementToBeValid; public: MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : - option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), - optionValuePresent(false) {} + option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {} QWidget* getWidgetToFocus(){return widgetToFocus;} QString& getRequirementToBeValid() { return requirementToBeValid; } ConfigOption& getConfigOption() { return option; } - bool optionValuePresent; boost::any optionValue; virtual ~MainWindowItem(){} virtual void installListeners(MainWindow *mainWindow); @@ -121,8 +119,7 @@ public: //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; boost::any programOption; i2p::config::GetOptionAsAny(optName, programOption); - optionValuePresent=!programOption.empty(); - optionValue=!optionValuePresent?boost::any(std::string("")) + optionValue=programOption.empty()?boost::any(std::string("")) :boost::any_cast(programOption).value(); } virtual void saveToStringStream(std::stringstream& out){ @@ -130,7 +127,7 @@ public: std::string v = boost::any_cast(optionValue); if(v.empty())return; } - if(!optionValuePresent || optionValue.empty())return; + if(optionValue.empty())return; std::string rtti = optionValue.type().name(); std::string optName=""; if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); @@ -184,7 +181,6 @@ public: virtual void saveToStringStream(std::stringstream& out){ optionValue=fromString(lineEdit->text()); - optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -239,7 +235,6 @@ public: virtual void saveToStringStream(std::stringstream& out){ std::string logDest = comboBox->currentText().toStdString(); optionValue=logDest; - optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -257,7 +252,6 @@ public: } virtual void saveToStringStream(std::stringstream& out){ optionValue=comboBox->currentText().toStdString(); - optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -275,7 +269,6 @@ public: virtual void saveToStringStream(std::stringstream& out){ uint16_t selected = SignatureTypeComboBoxFactory::getSigType(comboBox->currentData()); optionValue=(unsigned short)selected; - optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } @@ -292,7 +285,6 @@ public: } virtual void saveToStringStream(std::stringstream& out){ optionValue=checkBox->isChecked(); - optionValuePresent=true; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } From e21dac21c8b813e023fbbf44296eb4a90df3792c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Oct 2020 14:02:12 -0400 Subject: [PATCH 0478/2950] fixed #1557. don't try to send empty message --- libi2pd/Tunnel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index fe7e36af..704706ba 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -303,6 +303,7 @@ namespace tunnel { for (auto& msg : msgs) { + if (!msg.data) continue; switch (msg.deliveryType) { case eDeliveryTypeLocal: From ffa0f0afd91b786e13a479087d4092de5bed121a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 11 Oct 2020 17:51:40 -0400 Subject: [PATCH 0479/2950] check network status --- daemon/HTTPServer.cpp | 3 +++ libi2pd/NetDb.cpp | 3 ++- libi2pd/RouterContext.h | 3 ++- libi2pd/Transports.cpp | 15 ++++++++++++++- libi2pd/Transports.h | 5 +++-- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 19734038..d00387aa 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -259,6 +259,9 @@ namespace http { case eRouterErrorClockSkew: s << "
Clock skew"; break; + case eRouterErrorOffline: + s << "
Offline"; + break; default: ; } break; diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4ce839ee..318db953 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -125,7 +125,8 @@ namespace data } } if (!m_IsRunning) break; - + if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); if (ts - lastManageRequest >= 15) // manage requests every 15 seconds { diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index a576d6b6..37e1791d 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -37,7 +37,8 @@ namespace i2p enum RouterError { eRouterErrorNone = 0, - eRouterErrorClockSkew = 1 + eRouterErrorClockSkew = 1, + eRouterErrorOffline = 2 }; class RouterContext: public i2p::garlic::GarlicDestination diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 19e17f52..8a44bc3e 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -321,7 +321,8 @@ namespace transport void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { - SendMessages (ident, std::vector > {msg }); + if (m_IsOnline) + SendMessages (ident, std::vector > {msg }); } void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector >& msgs) @@ -756,5 +757,17 @@ namespace transport } return false; } + + void Transports::SetOnline (bool online) + { + if (m_IsOnline != online) + { + m_IsOnline = online; + if (online) + PeerTest (); + else + i2p::context.SetError (eRouterErrorOffline); + } + } } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index c3008b09..661337a2 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -94,7 +94,7 @@ namespace transport bool IsBoundNTCP2() const { return m_NTCP2Server != nullptr; } bool IsOnline() const { return m_IsOnline; }; - void SetOnline (bool online) { m_IsOnline = online; }; + void SetOnline (bool online); boost::asio::io_service& GetService () { return *m_Service; }; std::shared_ptr GetNextDHKeysPair (); @@ -151,7 +151,8 @@ namespace transport private: - bool m_IsOnline, m_IsRunning, m_IsNAT; + volatile bool m_IsOnline; + bool m_IsRunning, m_IsNAT; std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; From 0b372a344c0738f62420a5db3048adab428a44a2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 07:29:46 +0300 Subject: [PATCH 0480/2950] [webconsole] change error status print format Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d00387aa..3b9f6eaa 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -257,11 +257,11 @@ namespace http { switch (i2p::context.GetError ()) { case eRouterErrorClockSkew: - s << "
Clock skew"; + s << " - Clock skew"; break; case eRouterErrorOffline: - s << "
Offline"; - break; + s << " - Offline"; + break; default: ; } break; From 99d046ca11430bd59ee0bf67456f90dd648daf67 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 07:31:57 +0300 Subject: [PATCH 0481/2950] [http] handle WebDAV methods Signed-off-by: R4SAS --- libi2pd/HTTP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 4f7b03a1..484f4c0c 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -16,8 +16,8 @@ namespace i2p { namespace http { const std::vector HTTP_METHODS = { - "GET", "HEAD", "POST", "PUT", "PATCH", - "DELETE", "OPTIONS", "CONNECT", "PROPFIND" + "GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "CONNECT", // HTTP basic methods + "COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK", "SEARCH" // WebDAV methods, for SEARCH see rfc5323 }; const std::vector HTTP_VERSIONS = { "HTTP/1.0", "HTTP/1.1" From 85e9da82b023323da1541be4d2e5eed01d9d03cf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 17:36:44 +0300 Subject: [PATCH 0482/2950] [transports] validate IP when trying connect to remote peer for being in reserved IP range Signed-off-by: R4SAS --- daemon/Daemon.cpp | 6 ++++-- libi2pd/Config.cpp | 1 + libi2pd/SSU.cpp | 1 + libi2pd/Transports.cpp | 47 +++++++++++++++++++++------------------- libi2pd/Transports.h | 5 ++++- libi2pd/util.cpp | 49 +++++++++++++++++++++++++++++++++++++++++- libi2pd/util.h | 1 + 7 files changed, 84 insertions(+), 26 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 1b9c0a2c..0317704a 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -299,14 +299,16 @@ namespace i2p bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ssu; i2p::config::GetOption("ssu", ssu); + bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved); LogPrint(eLogInfo, "Daemon: starting Transports"); if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); + i2p::transport::transports.SetCheckReserved(checkInReserved); i2p::transport::transports.Start(ntcp2, ssu); - if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); - else + else { LogPrint(eLogError, "Daemon: failed to start Transports"); /** shut down netdb right away */ diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 1c565083..b924a108 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -51,6 +51,7 @@ namespace config { ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") ("ipv4", value()->default_value(true), "Enable communication through ipv4 (default: enabled)") ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)") + ("reservedrange", value()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") ("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)") ("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)") diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 0f4526bd..f9c06f37 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -459,6 +459,7 @@ namespace transport // otherwise create new session auto session = std::make_shared (*this, remoteEndpoint, router, peerTest); sessions[remoteEndpoint] = session; + // connect LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ", remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ()); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 8a44bc3e..ca86cf42 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -27,20 +27,20 @@ namespace transport { } - template + template EphemeralKeysSupplier::~EphemeralKeysSupplier () { Stop (); } - template + template void EphemeralKeysSupplier::Start () { m_IsRunning = true; m_Thread = new std::thread (std::bind (&EphemeralKeysSupplier::Run, this)); } - template + template void EphemeralKeysSupplier::Stop () { { @@ -56,7 +56,7 @@ namespace transport } } - template + template void EphemeralKeysSupplier::Run () { while (m_IsRunning) @@ -81,7 +81,7 @@ namespace transport } } - template + template void EphemeralKeysSupplier::CreateEphemeralKeys (int num) { if (num > 0) @@ -96,7 +96,7 @@ namespace transport } } - template + template std::shared_ptr EphemeralKeysSupplier::Acquire () { { @@ -115,7 +115,7 @@ namespace transport return pair; } - template + template void EphemeralKeysSupplier::Return (std::shared_ptr pair) { if (pair) @@ -131,8 +131,8 @@ namespace transport Transports transports; Transports::Transports (): - m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr), - m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), + m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_СheckReserved(true), m_Thread (nullptr), + m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr), m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), @@ -170,7 +170,7 @@ namespace transport m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); - i2p::http::URL proxyurl; + i2p::http::URL proxyurl; // create NTCP2. TODO: move to acceptor if (enableNTCP2) { @@ -252,7 +252,7 @@ namespace transport delete m_SSUServer; m_SSUServer = nullptr; } - + if (m_NTCP2Server) { m_NTCP2Server->Stop (); @@ -372,7 +372,7 @@ namespace transport } else { - LogPrint (eLogWarning, "Transports: delayed messages queue size to ", + LogPrint (eLogWarning, "Transports: delayed messages queue size to ", ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES); std::unique_lock l(m_PeersMutex); m_Peers.erase (it); @@ -393,7 +393,7 @@ namespace transport { // NTCP2 have priority over NTCP auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address && !peer.router->IsUnreachable ()) + if (address && !peer.router->IsUnreachable () && (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { auto s = std::make_shared (*m_NTCP2Server, peer.router); @@ -419,8 +419,11 @@ namespace transport if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) { auto address = peer.router->GetSSUAddress (!context.SupportsV6 ()); - m_SSUServer->CreateSession (peer.router, address->host, address->port); - return true; + if (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host)) + { + m_SSUServer->CreateSession (peer.router, address->host, address->port); + return true; + } } } LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available"); @@ -556,7 +559,7 @@ namespace transport { m_X25519KeysPairSupplier.Return (pair); } - + void Transports::PeerConnected (std::shared_ptr session) { m_Service->post([session, this]() @@ -758,16 +761,16 @@ namespace transport return false; } - void Transports::SetOnline (bool online) - { + void Transports::SetOnline (bool online) + { if (m_IsOnline != online) - { - m_IsOnline = online; + { + m_IsOnline = online; if (online) PeerTest (); else i2p::context.SetError (eRouterErrorOffline); - } - } + } + } } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 661337a2..55170ee8 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -136,6 +136,9 @@ namespace transport void PeerTest (); + void SetCheckReserved (bool check) { m_СheckReserved = check; }; + bool IsCheckReserved () { return m_СheckReserved; }; + private: void Run (); @@ -152,7 +155,7 @@ namespace transport private: volatile bool m_IsOnline; - bool m_IsRunning, m_IsNAT; + bool m_IsRunning, m_IsNAT, m_СheckReserved; std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index f5204a50..2cc101c7 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -61,6 +61,9 @@ int inet_pton_xp(int af, const char *src, void *dst) #include #endif +#define address_pair_v4(a,b) { boost::asio::ip::address_v4::from_string (a).to_ulong (), boost::asio::ip::address_v4::from_string (b).to_ulong () } +#define address_pair_v6(a,b) { boost::asio::ip::address_v6::from_string (a).to_bytes (), boost::asio::ip::address_v6::from_string (b).to_bytes () } + namespace i2p { namespace util @@ -391,6 +394,50 @@ namespace net return boost::asio::ip::address::from_string(fallback); #endif } -} + + bool IsInReservedRange(const boost::asio::ip::address& host) { + // https://en.wikipedia.org/wiki/Reserved_IP_addresses + if(host.is_v4()) + { + static const std::vector< std::pair > reservedIPv4Ranges { + address_pair_v4("0.0.0.0", "0.255.255.255"), + address_pair_v4("10.0.0.0", "10.255.255.255"), + address_pair_v4("100.64.0.0", "100.127.255.255"), + address_pair_v4("127.0.0.0", "127.255.255.255"), + address_pair_v4("169.254.0.0", "169.254.255.255"), + address_pair_v4("172.16.0.0", "172.31.255.255"), + address_pair_v4("192.0.0.0", "192.0.0.255"), + address_pair_v4("192.0.2.0", "192.0.2.255"), + address_pair_v4("192.88.99.0", "192.88.99.255"), + address_pair_v4("192.168.0.0", "192.168.255.255"), + address_pair_v4("198.18.0.0", "192.19.255.255"), + address_pair_v4("198.51.100.0", "198.51.100.255"), + address_pair_v4("203.0.113.0", "203.0.113.255"), + address_pair_v4("224.0.0.0", "255.255.255.255") + }; + + uint32_t ipv4_address = host.to_v4 ().to_ulong (); + for(const auto& it : reservedIPv4Ranges) { + if (ipv4_address >= it.first && ipv4_address <= it.second) + return true; + } + } + if(host.is_v6()) + { + 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") + }; + + boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes (); + for(const auto& it : reservedIPv6Ranges) { + if (ipv6_address >= it.first && ipv6_address <= it.second) + return true; + } + } + return false; + } +} // net } // util } // i2p diff --git a/libi2pd/util.h b/libi2pd/util.h index cb8fd8f1..56ce1e08 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -172,6 +172,7 @@ namespace util { int GetMTU (const boost::asio::ip::address& localAddress); const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6=false); + bool IsInReservedRange(const boost::asio::ip::address& host); } } } From 18bb4a71c2fe044f9435671c424e162c8145b3c8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Oct 2020 18:27:25 +0300 Subject: [PATCH 0483/2950] fix incorrect chars in variable Signed-off-by: R4SAS --- libi2pd/Transports.cpp | 6 +++--- libi2pd/Transports.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index ca86cf42..8fe4a731 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -131,7 +131,7 @@ namespace transport Transports transports; Transports::Transports (): - m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_СheckReserved(true), m_Thread (nullptr), + 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_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys @@ -393,7 +393,7 @@ namespace transport { // NTCP2 have priority over NTCP auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only - if (address && !peer.router->IsUnreachable () && (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host))) + if (address && !peer.router->IsUnreachable () && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { auto s = std::make_shared (*m_NTCP2Server, peer.router); @@ -419,7 +419,7 @@ namespace transport if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) { auto address = peer.router->GetSSUAddress (!context.SupportsV6 ()); - if (!m_СheckReserved || !i2p::util::net::IsInReservedRange(address->host)) + if (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host)) { m_SSUServer->CreateSession (peer.router, address->host, address->port); return true; diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 55170ee8..7108fbac 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -136,8 +136,8 @@ namespace transport void PeerTest (); - void SetCheckReserved (bool check) { m_СheckReserved = check; }; - bool IsCheckReserved () { return m_СheckReserved; }; + void SetCheckReserved (bool check) { m_CheckReserved = check; }; + bool IsCheckReserved () { return m_CheckReserved; }; private: @@ -155,7 +155,7 @@ namespace transport private: volatile bool m_IsOnline; - bool m_IsRunning, m_IsNAT, m_СheckReserved; + bool m_IsRunning, m_IsNAT, m_CheckReserved; std::thread * m_Thread; boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; From e3464add50dd04f9adf797a31c9f7bf8326c2a4b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 12 Oct 2020 17:15:17 -0400 Subject: [PATCH 0484/2950] don't create new tunnels if offline --- libi2pd/Tunnel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 704706ba..c91d0215 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -522,7 +522,7 @@ namespace tunnel } uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - if (ts - lastTs >= 15) // manage tunnels every 15 seconds + if (ts - lastTs >= 15 && i2p::transport::transports.IsOnline()) // manage tunnels every 15 seconds { ManageTunnels (); lastTs = ts; From 3f45a11f12a0b513ea1a8568e48a74e56feca5e9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 13 Oct 2020 15:22:39 +0300 Subject: [PATCH 0485/2950] [SSU] handle ICMP responses Windows network stack can forward ICMP to socket and simple deleting of packet can cause socket death. Same thing can happen on other systems but without socket death. Signed-off-by: R4SAS --- libi2pd/SSU.cpp | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index f9c06f37..af76ab2b 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -242,10 +242,16 @@ namespace transport void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to) { + boost::system::error_code ec; if (to.protocol () == boost::asio::ip::udp::v4()) - m_Socket.send_to (boost::asio::buffer (buf, len), to); + m_Socket.send_to (boost::asio::buffer (buf, len), to, 0, ec); else - m_SocketV6.send_to (boost::asio::buffer (buf, len), to); + m_SocketV6.send_to (boost::asio::buffer (buf, len), to, 0, ec); + + if (ec) + { + LogPrint (eLogError, "SSU: send exception: ", ec.message (), " while trying to send data to ", to.address (), ":", to.port (), " (length: ", len, ")"); + } } void SSUServer::Receive () @@ -264,7 +270,13 @@ namespace transport void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) { - if (!ecode) + if (!ecode || + ecode == boost::asio::error::connection_refused || + ecode == boost::asio::error::connection_reset || + ecode == boost::asio::error::network_unreachable || + ecode == boost::asio::error::host_unreachable) + // just try continue reading when received ICMP response otherwise socket can crash, + // but better to find out which host were sent it and mark that router as unreachable { packet->len = bytes_transferred; std::vector packets; @@ -286,7 +298,7 @@ namespace transport } else { - LogPrint (eLogError, "SSU: receive_from error: ", ec.message ()); + LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ()); delete packet; break; } @@ -301,7 +313,7 @@ namespace transport delete packet; if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogError, "SSU: receive error: ", ecode.message ()); + LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ()); m_Socket.close (); OpenSocket (); Receive (); @@ -311,7 +323,13 @@ namespace transport void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) { - if (!ecode) + if (!ecode || + ecode == boost::asio::error::connection_refused || + ecode == boost::asio::error::connection_reset || + ecode == boost::asio::error::network_unreachable || + ecode == boost::asio::error::host_unreachable) + // just try continue reading when received ICMP response otherwise socket can crash, + // but better to find out which host were sent it and mark that router as unreachable { packet->len = bytes_transferred; std::vector packets; @@ -333,7 +351,7 @@ namespace transport } else { - LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ()); + LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ()); delete packet; break; } @@ -348,7 +366,7 @@ namespace transport delete packet; if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ()); + LogPrint (eLogError, "SSU: v6 receive error: code ", ecode.value(), ": ", ecode.message ()); m_SocketV6.close (); OpenSocketV6 (); ReceiveV6 (); From 614921276e0f490f2cf7d94504049b0e40f18972 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 13 Oct 2020 12:33:27 +0000 Subject: [PATCH 0486/2950] [appveyor] update configuration to support cache (#1559) --- appveyor.yml | 45 ++++++++++++++++--------------- build/appveyor-msys2-upgrade.bash | 10 ------- 2 files changed, 24 insertions(+), 31 deletions(-) delete mode 100644 build/appveyor-msys2-upgrade.bash diff --git a/appveyor.yml b/appveyor.yml index 10165e5f..3cf51c2b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,46 +9,49 @@ 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 - MSYS_PACKAGES: mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc - MSYS_BITNESS: 64 - MSYSTEM: MINGW32 - MSYS_PACKAGES: mingw-w64-i686-boost mingw-w64-i686-miniupnpc - MSYS_BITNESS: 32 + +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" +# 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" -# disable inaccessible miror (something block sed from changing files, so rewrite them) - https://github.com/msys2/MINGW-packages/issues/7084 -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" # 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 -# rewrite mirrorlist again because pacman update can rewrite it -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/x86_64/' > /etc/pacman.d/mirrorlist.mingw64" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/mingw/i686/' > /etc/pacman.d/mirrorlist.mingw32" -- c:\msys64\usr\bin\bash -lc "echo 'Server = https://mirror.yandex.ru/mirrors/msys2/msys/$arch/' > /etc/pacman.d/mirrorlist.msys" # update packages and install required -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu ${MSYS_PACKAGES}" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu $MINGW_PACKAGE_PREFIX-boost $MINGW_PACKAGE_PREFIX-miniupnpc" build_script: -- echo MSYSTEM = %MSYSTEM%, bitness = %MSYS_BITNESS% -- c:\msys64\usr\bin\bash -lc "make USE_UPNP=yes -j3" -- 7z a -tzip -mx9 -mmt i2pd-mingw-win%MSYS_BITNESS%.zip i2pd.exe +- 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-mingw-win*.zip +- path: i2pd-*.zip diff --git a/build/appveyor-msys2-upgrade.bash b/build/appveyor-msys2-upgrade.bash deleted file mode 100644 index 20c6af69..00000000 --- a/build/appveyor-msys2-upgrade.bash +++ /dev/null @@ -1,10 +0,0 @@ -set -e -x - -base_url='http://repo.msys2.org/msys/x86_64/' -packages="libzstd-1.4.4-2-x86_64.pkg.tar.xz pacman-5.2.1-6-x86_64.pkg.tar.xz zstd-1.4.4-2-x86_64.pkg.tar.xz" -for p in $packages -do - curl "${base_url}$p" -o "$p" -done -pacman -U --noconfirm $packages -rm -f $packages From acc5592f590248067e41cdbed383eb337f3ebe6b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 13 Oct 2020 21:12:52 -0400 Subject: [PATCH 0487/2950] create DH keys for SSU session directly --- libi2pd/SSUSession.cpp | 12 ++++++++---- libi2pd/SSUSession.h | 1 + libi2pd/TransportSession.h | 3 +-- libi2pd/Transports.cpp | 14 +------------- libi2pd/Transports.h | 4 ---- 5 files changed, 11 insertions(+), 23 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 399b2fc7..9ce6e2e3 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -224,7 +224,11 @@ namespace transport return; } if (!m_DHKeysPair) - m_DHKeysPair = transports.GetNextDHKeysPair (); + { + auto pair = std::make_shared (); + pair->GenerateKeys (); + m_DHKeysPair = pair; + } CreateAESandMacKey (buf + headerSize); SendSessionCreated (buf + headerSize, sendRelayTag); } @@ -826,9 +830,9 @@ namespace transport { if (m_State == eSessionStateUnknown) { - // set connect timer - ScheduleConnectTimer (); - m_DHKeysPair = transports.GetNextDHKeysPair (); + ScheduleConnectTimer (); // set connect timer + m_DHKeysPair = std::make_shared (); + m_DHKeysPair->GenerateKeys (); SendSessionRequest (); } } diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index ea820517..3aa04638 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -166,6 +166,7 @@ namespace transport bool m_IsDataReceived; std::unique_ptr m_SignedData; // we need it for SessionConfirmed only std::map > m_RelayRequests; // nonce->Charlie + std::shared_ptr m_DHKeysPair; // X - for client and Y - for server }; } } diff --git a/libi2pd/TransportSession.h b/libi2pd/TransportSession.h index a97f246f..12d4894b 100644 --- a/libi2pd/TransportSession.h +++ b/libi2pd/TransportSession.h @@ -64,7 +64,7 @@ namespace transport public: TransportSession (std::shared_ptr router, int terminationTimeout): - m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), + m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout), m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ()) { if (router) @@ -103,7 +103,6 @@ namespace transport std::shared_ptr m_RemoteIdentity; mutable std::mutex m_RemoteIdentityMutex; - std::shared_ptr m_DHKeysPair; // X - for client and Y - for server size_t m_NumSentBytes, m_NumReceivedBytes; bool m_IsOutgoing; int m_TerminationTimeout; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 8fe4a731..4e0aa6a5 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -134,7 +134,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_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys + m_X25519KeysPairSupplier (5), // 5 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), @@ -165,7 +165,6 @@ namespace transport } i2p::config::GetOption("nat", m_IsNAT); - m_DHKeysPairSupplier.Start (); m_X25519KeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); @@ -260,7 +259,6 @@ namespace transport m_NTCP2Server = nullptr; } - m_DHKeysPairSupplier.Stop (); m_X25519KeysPairSupplier.Stop (); m_IsRunning = false; if (m_Service) m_Service->stop (); @@ -540,16 +538,6 @@ namespace transport } } - std::shared_ptr Transports::GetNextDHKeysPair () - { - return m_DHKeysPairSupplier.Acquire (); - } - - void Transports::ReuseDHKeysPair (std::shared_ptr pair) - { - m_DHKeysPairSupplier.Return (pair); - } - std::shared_ptr Transports::GetNextX25519KeysPair () { return m_X25519KeysPairSupplier.Acquire (); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 7108fbac..d480840a 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -59,7 +59,6 @@ namespace transport std::condition_variable m_Acquired; std::mutex m_AcquiredMutex; }; - typedef EphemeralKeysSupplier DHKeysPairSupplier; typedef EphemeralKeysSupplier X25519KeysPairSupplier; struct Peer @@ -97,8 +96,6 @@ namespace transport void SetOnline (bool online); boost::asio::io_service& GetService () { return *m_Service; }; - std::shared_ptr GetNextDHKeysPair (); - void ReuseDHKeysPair (std::shared_ptr pair); std::shared_ptr GetNextX25519KeysPair (); void ReuseX25519KeysPair (std::shared_ptr pair); @@ -166,7 +163,6 @@ namespace transport mutable std::mutex m_PeersMutex; std::unordered_map m_Peers; - DHKeysPairSupplier m_DHKeysPairSupplier; X25519KeysPairSupplier m_X25519KeysPairSupplier; std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; From 11691fb44abea05940f12b3579b8c73e2e28ca56 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:20:26 +0300 Subject: [PATCH 0488/2950] create GH workflow Add workflow to build on ubuntu with make --- .github/workflows/build.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..41b71bdf --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,18 @@ +name: Build on Ubuntu with make + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-16.04 + strategy: + fail-fast: true + matrix: + with_upnp: ['yes', 'no'] + steps: + - uses: actions/checkout@v2 + - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag + - name: install packages + run: apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application + run: make USE_AVX=no USE_AESNI=no USE_UPNP=yes USE_UPNP=${{ matrix.with_upnp }} -j3 From 1dbc35f13d2e120c2e15d00223f31d648de61072 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:22:00 +0300 Subject: [PATCH 0489/2950] fix workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41b71bdf..0aac49f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,8 +10,8 @@ jobs: matrix: with_upnp: ['yes', 'no'] steps: - - uses: actions/checkout@v2 - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag + uses: actions/checkout@v2 - name: install packages run: apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application From 44d3854a1393e660f0cd6e8d740862666f18c0e4 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:24:02 +0300 Subject: [PATCH 0490/2950] [workflow] use sudo when installing packages --- .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 0aac49f4..518a148c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,6 @@ jobs: - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag uses: actions/checkout@v2 - name: install packages - run: apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev + run: sudo apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application - run: make USE_AVX=no USE_AESNI=no USE_UPNP=yes USE_UPNP=${{ matrix.with_upnp }} -j3 + run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3 From 36fc0daa126393f62911c99e2f037e90cdb9ffb3 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:36:16 +0300 Subject: [PATCH 0491/2950] [workflow] use latest boost from PPA --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 518a148c..77704af5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,9 @@ jobs: - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag uses: actions/checkout@v2 - name: install packages - run: sudo apt-get install build-essential libboost-date-time-dev libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libminiupnpc-dev libssl-dev zlib1g-dev + run: | + sudo add-apt-repository ppa:mhier/libboost-latest + sudo apt-get update + sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3 From 8e24d1b909a9e910023231bdbd82ee60f5d3d42b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 07:44:22 +0300 Subject: [PATCH 0492/2950] [workflow] change options order Apply name for job, not for step. --- .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 77704af5..ba6acbf8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,14 +4,14 @@ on: [push, pull_request] jobs: build: + name: Building with USE_UPNP=${{ matrix.with_upnp }} flag runs-on: ubuntu-16.04 strategy: fail-fast: true matrix: with_upnp: ['yes', 'no'] steps: - - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - name: install packages run: | sudo add-apt-repository ppa:mhier/libboost-latest From d9d31521f9d240020846f4aff7a3938208d10541 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 08:06:22 +0300 Subject: [PATCH 0493/2950] [workflow] add windows build --- .github/workflows/build-windows.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/build-windows.yml diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 00000000..9fd66bbc --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,29 @@ +name: Build on Windows + +on: [push, pull_request] + +defaults: + run: + shell: msys2 {0} + +jobs: + build: + name: Building for ${{ matrix.arch }} + runs-on: windows-latest + strategy: + fail-fast: true + matrix: + include: [ + { msystem: MINGW64, arch: x86_64 }, + { msystem: MINGW32, arch: i686 } + ] + steps: + - uses: actions/checkout@v2 + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + install: base-devel mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-miniupnpc + update: true + - name: build application + run: make USE_UPNP=yes DEBUG=no -j3 From 2648f1ba89d5032262a72ca8b2d2d8a70e441b9a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 14 Oct 2020 08:14:33 +0300 Subject: [PATCH 0494/2950] [workflow] install required packages --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 9fd66bbc..9763f75b 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -23,7 +23,7 @@ jobs: uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} - install: base-devel mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-miniupnpc + install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc update: true - name: build application run: make USE_UPNP=yes DEBUG=no -j3 From 050390c5c44441ea5bd3917330cf908640309f38 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 14 Oct 2020 21:37:39 +0800 Subject: [PATCH 0495/2950] qt: all new general options added from docs --- qt/i2pd_qt/TunnelPane.cpp | 28 + qt/i2pd_qt/TunnelPane.h | 28 + qt/i2pd_qt/generalsettingswidget.ui | 2716 ++++++++++++++++++--------- qt/i2pd_qt/mainwindow.cpp | 82 +- qt/i2pd_qt/mainwindow.h | 3 +- 5 files changed, 1949 insertions(+), 908 deletions(-) diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index c64b37ab..60b0b6d5 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -185,6 +185,34 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, tunnelGridLayout->addLayout(horizontalLayout_2); } + { + //explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset + } + + { + //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default + } + + { + //i2p.streaming.answerPings -- enable sending pongs. true by default + } + + { + //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default + } + + { + //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default + } + + { + //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH + } + + { + //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK + } + retranslateI2CPParameters(); } diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 71331b4e..6a13b7a0 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -133,6 +133,34 @@ private: inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));; outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));; crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));; + + { + //explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset + } + + { + //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default + } + + { + //i2p.streaming.answerPings -- enable sending pongs. true by default + } + + { + //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default + } + + { + //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default + } + + { + //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH + } + + { + //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK + } } }; diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index 9e59132f..e64f9e35 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -7,7 +7,7 @@ 0 0 679 - 3033 + 4152 @@ -25,14 +25,38 @@ 0 0 679 - 3052 + 4151 - + - QLayout::SetMinAndMaxSize + QLayout::SetDefaultConstraint - + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + @@ -100,14 +124,8 @@ - - - - - 0 - 0 - - + + 0 @@ -121,44 +139,26 @@ - Tunnels configuration file: + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - + 0 - 18 + 20 661 31 - + QLayout::SetMaximumSize - + - - - - 0 - 0 - - - - - 0 - 27 - - - - - 16777215 - 27 - - + Browse… @@ -168,7 +168,7 @@ - + @@ -236,183 +236,86 @@ - - + + + + + 0 + 0 + + 0 - 98 + 51 16777215 - 98 + 51 - SAM interface + Tunnels configuration file: - + 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 + 18 661 31 - + + + QLayout::SetMaximumSize + - - - IP address to listen on: - - + - - - - - - Qt::Horizontal + + + + 0 + 0 + - + - 40 - 20 + 0 + 27 - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - 80 - 16777215 + 16777215 + 27 + + Browse… + - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - + 0 - 107 + 112 16777215 - 107 + 112 @@ -432,7 +335,7 @@ - QLayout::SetMinimumSize + QLayout::SetMinAndMaxSize @@ -539,11 +442,715 @@ + + + + Write full CLF-formatted date and time to log + + + - + + + + + 0 + 0 + + + + + 0 + 390 + + + + + 16777215 + 390 + + + + Router options + + + + + 0 + 20 + 661 + 368 + + + + + + + Enable communication through ipv4 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + Enable SSU transport protocol (use UDP) + + + + + + + Assume we are behind NAT + + + + + + + + + Bandwidth limit (integer or a letter): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Network interface to bind to for IPv4: + + + + + + + + + + + + + + Network interface to bind to for IPv6: + + + + + + + + + + + + + + Max % of bandwidth limit for transit. 0-100: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 230 + + + + + 16777215 + 230 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 1 + 182 + 661 + 21 + + + + Enable strict host checking on web UI + + + + + + -1 + 200 + 661 + 27 + + + + + + + Expected hostname for web UI: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 190 + + + + + 16777215 + 190 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Path to local .zip file to reseed from: + + + + + + + + + + Browse... + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Minimum number of known routers before requesting reseed: + + + + + + + + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + URL for https/socks reseed proxy: + + + + + + + + + + + @@ -610,116 +1217,7 @@ - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - + @@ -828,215 +1326,111 @@ - - + + 0 - 60 + 170 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 + 170 - Router external address (for incoming connections) + Trust options - - Qt::AlignJustify|Qt::AlignTop - - + 0 20 661 - 81 + 21 - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave 0 to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + + Enable explicit trust options + - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - + + + + 390 + 40 + 271 + 23 + + + + 0 - 20 - 661 - 31 + 40 + 391 + 42 - - - - - Addressbook default subscription URL for initial setup: - - - - - - - + + Make direct I2P connections only to +routers in specified Family: + - + 0 - 50 + 82 661 - 31 + 42 - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - + + Make direct I2P connections only to routers specified here. +Comma separated list of base64 identities: + + + + + + 0 + 124 + 661 + 23 + + + + + + + 0 + 147 + 661 + 21 + + + + Should we hide our router from other routers? + - + 0 - 280 + 400 16777215 - 280 + 400 @@ -1371,78 +1765,225 @@ - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 51 - - - - - 16777215 - 51 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - + 0 - 20 + 280 661 - 31 + 23 - - - QLayout::SetMaximumSize - + + Enable address helper (jump) + + + + + + 0 + 300 + 661 + 95 + + + - + + + + + HTTP proxy upstream out proxy URL (like http://false.i2p): + + + + + + + - - - Browse… - - + + + + + Type of LeaseSet to be sent. 1, 3 or 5: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Comma-separated encryption types to be used in LeaseSet type 3 or 5: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - + + + + + 0 + 121 + + + + + 16777215 + 121 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 621 + 23 + + + + Single thread for all SAM sessions + + + + + + 0 @@ -1452,127 +1993,88 @@ 0 - 215 + 98 16777215 - 215 + 98 - Router options + Router external address (for incoming connections) - + + Qt::AlignJustify|Qt::AlignTop + + 0 20 661 - 188 + 81 - + + + QLayout::SetMinAndMaxSize + - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer or a letter): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + - QLayout::SetMaximumSize + QLayout::SetMinAndMaxSize - + - NetID (network ID router belongs to. The main I2P ID is 2): + Host: - + - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave 0 to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + Qt::Horizontal @@ -1590,8 +2092,8 @@ - - + + 0 @@ -1714,226 +2216,251 @@ - - + + + + + 0 + 0 + + 0 - 98 + 128 16777215 - 98 + 128 - Reseeding + Nettime options - + 0 20 - 661 - 22 + 671 + 101 - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - + + + QLayout::SetMinAndMaxSize + - + - SU3 file to reseed from: + Enable NTP sync - + + + + + Comma-separated list of NTP servers: + + + + + + + - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - + + + + + NTP time sync interval in hours: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - + + + + + 0 + 0 + + 0 - 170 + 215 16777215 - 170 + 215 - Trust options + NTCP2 options - + - 0 - 20 - 661 - 21 + -1 + 19 + 671 + 191 - - Enable explicit trust options - - - - - - 390 - 40 - 271 - 23 - - - - - - - 0 - 40 - 391 - 42 - - - - Make direct I2P connections only to -routers in specified Family: - - - - - - 0 - 82 - 661 - 42 - - - - Make direct I2P connections only to routers specified here. -Comma separated list of base64 identities: - - - - - - 0 - 124 - 661 - 23 - - - - - - - 0 - 147 - 661 - 21 - - - - Should we hide our router from other routers? - + + + QLayout::SetMinAndMaxSize + + + + + Enable NTCP2 + + + + + + + Enable incoming NTCP2 connections + + + + + + + + + Port to listen for incoming NTCP2 connections: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + External IPv6 address for incoming connections: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Specify proxy server for NTCP2: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Proxy server should be http://address:port or socks://address:port + + + + - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - + @@ -2135,24 +2662,56 @@ Comma separated list of base64 identities: - - + + 0 - 179 + 44 16777215 - 179 + 44 - HTTP webconsole + Cryptography - + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 121 + + + + + 16777215 + 121 + + + + I2CP interface + + 0 @@ -2165,7 +2724,7 @@ Comma separated list of base64 identities: Enabled - + 0 @@ -2174,19 +2733,19 @@ Comma separated list of base64 identities: 31 - + - + IP address to listen on: - + - + Qt::Horizontal @@ -2200,7 +2759,7 @@ Comma separated list of base64 identities: - + 0 @@ -2209,16 +2768,16 @@ Comma separated list of base64 identities: 31 - + - + Port to listen on: - + 80 @@ -2228,7 +2787,7 @@ Comma separated list of base64 identities: - + Qt::Horizontal @@ -2242,103 +2801,57 @@ Comma separated list of base64 identities: - + 0 100 - 321 - 22 + 651 + 23 - Enable basic HTTP auth + Single thread for all I2CP sessions - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + + 0 - 335 + 60 16777215 - 335 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 405 + + + + + 16777215 + 405 @@ -2750,6 +3263,479 @@ Comma separated list of base64 identities: + + + + -1 + 340 + 661 + 62 + + + + + + + + + Type of LeaseSet to be sent. 1, 3 or 5: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Comma-separated encryption types to be used in LeaseSet type 3 or 5: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 128 + + + + + 16777215 + 128 + + + + Websocket Server + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + -1 + 19 + 681 + 101 + + + + + QLayout::SetMinAndMaxSize + + + + + Enable websocket server + + + + + + + + + Address to bind websocket server on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Port to bind websocket server on: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 0 + + + + + 0 + 160 + + + + + 16777215 + 160 + + + + Exploratory Tunnels + + + + + -1 + 19 + 671 + 131 + + + + + QLayout::SetMinAndMaxSize + + + + + + + Exploratory inbound tunnels length: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Exploratory inbound tunnels quantity: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Exploratory outbound tunnels length: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Exploratory outbound tunnels quantity: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 56 + + + + + 16777215 + 56 + + + + Persist profiles + + + + + 0 + 20 + 681 + 31 + + + + + QLayout::SetMinAndMaxSize + + + + + Enable peer profile persisting to disk + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 0 + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 14a57f8a..d4d34109 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -81,10 +81,10 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren onResize(); ui->stackedWidget->setCurrentIndex(0); - ui->settingsScrollArea->resize(uiSettings->settingsContentsGridLayout->sizeHint().width()+10,380); + ui->settingsScrollArea->resize(uiSettings->settingsContentsQVBoxLayout->sizeHint().width()+10,380); //QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); int w = 683; - int h = 3060; + int h = 4000; ui->settingsContents->setFixedSize(w, h); ui->settingsContents->setGeometry(QRect(0,0,w,h)); @@ -172,24 +172,24 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton); initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox); - //TODO add option "logclftime" "Write full CLF-formatted date and time to log (default: write only time)" + initCheckBox( OPTION("","logclftime",[]{return "false";}), uiSettings->logclftimeCheckBox);//"Write full CLF-formatted date and time to log (default: write only time)" initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton); initIPAddressBox( OPTION("","host",[]{return "";}), uiSettings->routerExternalHostLineEdit, tr("Router external address -> Host")); initTCPPortBox( OPTION("","port",[]{return "";}), uiSettings->routerExternalPortLineEdit, tr("Router external address -> Port")); daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";})); serviceOption=initNonGUIOption( OPTION("","service",[]{return "";})); - //TODO add option "ifname4" Network interface to bind to for IPv4 - //TODO add option "ifname6" Network interface to bind to for IPv6 - //TODO add option "nat" If true, assume we are behind NAT. true by default - //TODO add option "ipv4" Enable communication through IPv4. true by default + initStringBox( OPTION("","ifname4",[]{return "";}), uiSettings->ifname4LineEdit);//Network interface to bind to for IPv4 + initStringBox( OPTION("","ifname6",[]{return "";}), uiSettings->ifname6LineEdit);//Network interface to bind to for IPv6 + initCheckBox( OPTION("","nat",[]{return "true";}), uiSettings->natCheckBox);//If true, assume we are behind NAT. true by default + initCheckBox( OPTION("","ipv4",[]{return "true";}), uiSettings->ipv4CheckBox);//Enable communication through IPv4. true by default initCheckBox( OPTION("","ipv6",[]{return "false";}), uiSettings->ipv6CheckBox); initCheckBox( OPTION("","notransit",[]{return "false";}), uiSettings->notransitCheckBox); initCheckBox( OPTION("","floodfill",[]{return "false";}), uiSettings->floodfillCheckBox); initStringBox( OPTION("","bandwidth",[]{return "";}), uiSettings->bandwidthLineEdit); - //TODO add option "share" Max % of bandwidth limit for transit. 0-100. 100 by default + initIntegerBox( OPTION("","share",[]{return "100";}), uiSettings->shareLineEdit, tr("Share"));//Max % of bandwidth limit for transit. 0-100. 100 by default initStringBox( OPTION("","family",[]{return "";}), uiSettings->familyLineEdit); initIntegerBox( OPTION("","netid",[]{return "2";}), uiSettings->netIdLineEdit, tr("NetID")); - //TODO add option "ssu" Enable SSU transport protocol (use UDP). true by default + initCheckBox( OPTION("","ssu",[]{return "true";}), uiSettings->ssuCheckBox);//Enable SSU transport protocol (use UDP). true by default #ifdef Q_OS_WIN initNonGUIOption( OPTION("","svcctl",[]{return "";})); @@ -205,22 +205,22 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("http","auth",[]{return "";}), uiSettings->webconsoleBasicAuthCheckBox); initStringBox( OPTION("http","user",[]{return "i2pd";}), uiSettings->webconsoleUserNameLineEditBasicAuth); initStringBox( OPTION("http","pass",[]{return "";}), uiSettings->webconsolePasswordLineEditBasicAuth); - //TODO add option "http.strictheaders Enable strict host checking on WebUI. true by default - //TODO add option "http.hostname Expected hostname for WebUI (default: localhost) + initCheckBox( OPTION("http","strictheaders",[]{return "true";}), uiSettings->httpStrictHeadersCheckBox);//TODO add option Enable strict host checking on WebUI. true by default + initStringBox( OPTION("http","hostname",[]{return "localhost";}), uiSettings->httpHostnameLineEdit);//TODO add option Expected hostname for WebUI (default: localhost) initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), uiSettings->httpProxyEnabledCheckBox); initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); - //TODO add option "httpproxy.addresshelper Enable address helper (jump). true by default + initCheckBox( OPTION("httpproxy","addresshelper",[]{return "true";}), uiSettings->httpProxyAddressHelperCheckBox);//TODO add option Enable address helper (jump). true by default initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton); initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType); initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit); initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit); initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), uiSettings->httpProxyOutBoundTunnLenLineEdit); initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), uiSettings->httpProxyOutboundTunnQuantityLineEdit); - //TODO add option "httpproxy.outproxy HTTP proxy upstream out proxy url (like http://false.i2p) - //TODO add option "httpproxy.i2cp.leaseSetType Type of LeaseSet to be sent. 1, 3 or 5. 1 by default - //TODO add option "httpproxy.i2cp.leaseSetEncType Comma separated encryption types to be used in LeaseSet type 3 or 5 + initStringBox( OPTION("httpproxy","outproxy",[]{return "";}), uiSettings->httpProxyOutproxyLineEdit);//TODO add option HTTP proxy upstream out proxy url (like http://false.i2p) + initStringBox( OPTION("httpproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->httpProxyI2cpLeaseSetTypeLineEdit);//TODO add option Type of LeaseSet to be sent. 1, 3 or 5. 1 by default + initStringBox( OPTION("httpproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->httpProxyI2cpLeaseSetEncTypeLineEdit);//TODO add option Comma separated encryption types to be used in LeaseSet type 3 or 5 initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox); initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); @@ -231,15 +231,15 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), uiSettings->socksProxyInboundTunnQuantityLineEdit); initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), uiSettings->socksProxyOutBoundTunnLenLineEdit); initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), uiSettings->socksProxyOutboundTunnQuantityLineEdit); - initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); - initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); - //TODO add option "socksproxy.i2cp.leaseSetType Type of LeaseSet to be sent. 1, 3 or 5. 1 by default - //TODO add option "socksproxy.i2cp.leaseSetEncType Comma separated encryption types to be used in LeaseSet type 3 or 5 + initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); + initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + initStringBox( OPTION("socksproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->socksProxyI2cpLeaseSetTypeLineEdit);//TODO add option Type of LeaseSet to be sent. 1, 3 or 5. 1 by default + initStringBox( OPTION("socksproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->socksProxyI2cpLeaseSetEncTypeLineEdit);//TODO add option Comma separated encryption types to be used in LeaseSet type 3 or 5 initCheckBox( OPTION("sam","enabled",[]{return "false";}), uiSettings->samEnabledCheckBox); initIPAddressBox( OPTION("sam","address",[]{return "";}), uiSettings->samAddressLineEdit, tr("SAM -> IP address")); initTCPPortBox( OPTION("sam","port",[]{return "7656";}), uiSettings->samPortLineEdit, tr("SAM -> Port")); - //TODO add option "sam.singlethread If false every SAM session runs in own thread. true by default + initCheckBox( OPTION("sam","singlethread",[]{return "true";}), uiSettings->samSingleThreadCheckBox);//If false every SAM session runs in own thread. true by default initCheckBox( OPTION("bob","enabled",[]{return "false";}), uiSettings->bobEnabledCheckBox); initIPAddressBox( OPTION("bob","address",[]{return "";}), uiSettings->bobAddressLineEdit, tr("BOB -> IP address")); @@ -248,7 +248,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), uiSettings->i2cpEnabledCheckBox); initIPAddressBox( OPTION("i2cp","address",[]{return "";}), uiSettings->i2cpAddressLineEdit, tr("I2CP -> IP address")); initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), uiSettings->i2cpPortLineEdit, tr("I2CP -> Port")); - //TODO add option "i2cp.singlethread If false every I2CP session runs in own thread. true by default + //initCheckBox( OPTION("i2cp","singlethread",[]{return "true";}), uiSettings->i2cpSingleThreadCheckBox);//If false every I2CP session runs in own thread. true by default initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), uiSettings->i2pControlEnabledCheckBox); initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), uiSettings->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); @@ -265,9 +265,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("reseed","verify",[]{return "";}), uiSettings->reseedVerifyCheckBox); initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton); initStringBox( OPTION("reseed","urls",[]{return "";}), uiSettings->reseedURLsLineEdit); - //TODO add option "reseed.zipfile Path to local .zip file to reseed from - //TODO add option "reseed.threshold Minimum number of known routers before requesting reseed. 25 by default - //TODO add option "reseed.proxy Url for https/socks reseed proxy + initFileChooser( OPTION("reseed","zipfile",[]{return "";}), uiSettings->reseedZipFileLineEdit, uiSettings->reseedZipFileBrowsePushButton); //Path to local .zip file to reseed from + initUInt16Box( OPTION("reseed","threshold",[]{return "25";}), uiSettings->reseedThresholdNumberLineEdit, tr("reseedThreshold")); //Minimum number of known routers before requesting reseed. 25 by default + initStringBox( OPTION("reseed","proxy",[]{return "";}), uiSettings->reseedProxyLineEdit);//URL for https/socks reseed proxy initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), uiSettings->addressbookDefaultURLLineEdit); initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), uiSettings->addressbookSubscriptionsURLslineEdit); @@ -275,34 +275,32 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initUInt16Box( OPTION("limits","transittunnels",[]{return "2500";}), uiSettings->maxNumOfTransitTunnelsLineEdit, tr("maxNumberOfTransitTunnels")); initUInt16Box( OPTION("limits","openfiles",[]{return "0";}), uiSettings->maxNumOfOpenFilesLineEdit, tr("maxNumberOfOpenFiles")); initUInt32Box( OPTION("limits","coresize",[]{return "0";}), uiSettings->coreFileMaxSizeNumberLineEdit, tr("coreFileMaxSize")); - //TODO add option "limits.ntcpsoft Threshold to start probabalistic backoff with ntcp sessions (0 - use system limit) - //TODO add option "limits.ntcphard Maximum number of ntcp sessions (0 - use system limit) initCheckBox( OPTION("trust","enabled",[]{return "false";}), uiSettings->checkBoxTrustEnable); initStringBox( OPTION("trust","family",[]{return "";}), uiSettings->lineEditTrustFamily); initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters); initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden); - //TODO add option "websockets.enabled Enable websocket server. Disabled by default - //TODO add option "websockets.address Address to bind websocket server on. 127.0.0.1 by default - //TODO add option "websockets.port Port to bind websocket server on. 7666 by default + initCheckBox( OPTION("websockets","enabled",[]{return "false";}), uiSettings->checkBoxWebsocketsEnable); //Enable websocket server. Disabled by default + initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), uiSettings->websocketsAddressLineEdit, tr("Websockets -> IP address")); //Address to bind websocket server on. 127.0.0.1 by default + initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), uiSettings->websocketsPortLineEdit, tr("Websockets -> Port")); //Port to bind websocket server on. 7666 by default - //TODO add option "exploratory.inbound.length Exploratory inbound tunnels length. 2 by default - //TODO add option "exploratory.inbound.quantity Exploratory inbound tunnels quantity. 3 by default - //TODO add option "exploratory.outbound.length Exploratory outbound tunnels length. 2 by default - //TODO add option "exploratory.outbound.quantity Exploratory outbound tunnels length. 3 by default + initIntegerBox( OPTION("exploratory","inbound.length",[]{return "2";}), uiSettings->exploratoryInboundTunnelsLengthNumberLineEdit, tr("exploratoryInboundTunnelsLength"));//Exploratory inbound tunnels length. 2 by default + initIntegerBox( OPTION("exploratory","inbound.quantity",[]{return "3";}), uiSettings->exploratoryInboundTunnelsQuantityNumberLineEdit, tr("exploratoryInboundTunnelsQuantity"));//Exploratory inbound tunnels quantity. 3 by default + initIntegerBox( OPTION("exploratory","outbound.length",[]{return "2";}), uiSettings->exploratoryOutboundTunnelsLengthNumberLineEdit, tr("exploratoryOutboundTunnelsLength"));//Exploratory outbound tunnels length. 2 by default + initIntegerBox( OPTION("exploratory","outbound.quantity",[]{return "3";}), uiSettings->exploratoryOutboundTunnelsQuantityNumberLineEdit, tr("exploratoryOutboundTunnelsQuantity"));//Exploratory outbound tunnels length. 3 by default - //TODO add option "ntcp2.enabled Enable NTCP2. Enabled by default - //TODO add option "ntcp2.published Enable incoming NTCP2 connections. Disabled by default - //TODO add option "ntcp2.port Port to listen for incoming NTCP2 connections (default: auto) - //TODO add option "ntcp2.addressv6 External IPv6 for incoming connections - //TODO add option "ntcp2.proxy Specify proxy server for NTCP2. Should be http://address:port or socks://address:port + initCheckBox( OPTION("ntcp2","enabled",[]{return "true";}), uiSettings->checkBoxNtcp2Enable); //Enable NTCP2. Enabled by default + initCheckBox( OPTION("ntcp2","published",[]{return "false";}), uiSettings->checkBoxNtcp2Published); //Enable incoming NTCP2 connections. Disabled by default + initTCPPortBox( OPTION("ntcp2","port",[]{return "0";}), uiSettings->ntcp2PortLineEdit, tr("NTCP2 -> Port")); //Port to listen for incoming NTCP2 connections (default: auto) + initIPAddressBox( OPTION("ntcp2","addressv6",[]{return "::";}), uiSettings->ntcp2AddressV6LineEdit, tr("NTCP2 -> IPv6 address")); //External IPv6 for incoming connections + initStringBox( OPTION("ntcp2","proxy",[]{return "";}), uiSettings->lineEditNtcp2Proxy); //Specify proxy server for NTCP2. Should be http://address:port or socks://address:port - //TODO add option "nettime.enabled Enable NTP sync. Disabled by default - //TODO add option "nettime.ntpservers Comma-separated list of NTP server. pool.ntp.org by default - //TODO add option "nettime.ntpsyncinterval NTP time sync interval in hours. 72 by default + initCheckBox( OPTION("nettime","enabled",[]{return "false";}), uiSettings->checkBoxNettimeEnable); //Enable NTP sync. Disabled by default + initStringBox( OPTION("nettime","ntpservers",[]{return "pool.ntp.org";}), uiSettings->lineEditNetTimeNtpServers); //Comma-separated list of NTP servers. pool.ntp.org by default + initIntegerBox( OPTION("nettime","ntpsyncinterval",[]{return "72";}), uiSettings->nettimeNtpSyncIntervalNumberLineEdit, tr("nettimeNtpSyncInterval")); //NTP time sync interval in hours. 72 by default - //TODO add option "persist.profiles Enable peer profile persisting to disk. Enabled by default + initCheckBox( OPTION("persist","profiles",[]{return "true";}), uiSettings->checkBoxPersistProfiles);//Enable peer profile persisting to disk. Enabled by default # undef OPTION //widgetlocks.add(new widgetlock(widget,lockbtn)); diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 6e187b5b..b4f57f8f 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -116,7 +116,7 @@ public: std::string optName=""; if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); optName+=option.option.toStdString(); - //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; + qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; boost::any programOption; i2p::config::GetOptionAsAny(optName, programOption); optionValue=programOption.empty()?boost::any(std::string("")) @@ -281,6 +281,7 @@ public: virtual void installListeners(MainWindow *mainWindow); virtual void loadFromConfigOption(){ MainWindowItem::loadFromConfigOption(); + qDebug() << "setting value for checkbox " << checkBox->text(); checkBox->setChecked(boost::any_cast(optionValue)); } virtual void saveToStringStream(std::stringstream& out){ From 417b5ed6cc15379f150bfec3f5fd5c36f9c65bfb Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 14 Oct 2020 21:06:51 -0400 Subject: [PATCH 0496/2950] handle SSU v4 and v6 messages in one thread --- libi2pd/SSU.cpp | 46 ++++++++++-------------------------------- libi2pd/SSU.h | 8 +++----- libi2pd/SSUSession.cpp | 2 +- libi2pd/Transports.cpp | 2 +- 4 files changed, 16 insertions(+), 42 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index af76ab2b..07c95a7a 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -19,27 +19,25 @@ namespace transport { SSUServer::SSUServer (const boost::asio::ip::address & addr, int port): - m_OnlyV6(true), m_IsRunning(false), - m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr), - m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6), + m_OnlyV6(true), m_IsRunning(false), m_Thread (nullptr), + m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), m_EndpointV6 (addr, port), m_Socket (m_ReceiversService, m_Endpoint), m_SocketV6 (m_ReceiversServiceV6), m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), - m_TerminationTimerV6 (m_ServiceV6) + m_TerminationTimerV6 (m_Service) { OpenSocketV6 (); } SSUServer::SSUServer (int port): - m_OnlyV6(false), m_IsRunning(false), - m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr), - m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6), + m_OnlyV6(false), m_IsRunning(false), m_Thread (nullptr), + m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), 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_ServiceV6) + m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_Service) { OpenSocket (); if (context.SupportsV6 ()) @@ -98,7 +96,8 @@ namespace transport if (context.SupportsV6 ()) { m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this)); - m_ThreadV6 = new std::thread (std::bind (&SSUServer::RunV6, this)); + if (!m_Thread) + m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this)); ScheduleTerminationV6 (); } @@ -114,7 +113,6 @@ namespace transport m_TerminationTimerV6.cancel (); m_Service.stop (); m_Socket.close (); - m_ServiceV6.stop (); m_SocketV6.close (); m_ReceiversService.stop (); m_ReceiversServiceV6.stop (); @@ -136,12 +134,6 @@ namespace transport delete m_ReceiversThreadV6; m_ReceiversThreadV6 = nullptr; } - if (m_ThreadV6) - { - m_ThreadV6->join (); - delete m_ThreadV6; - m_ThreadV6 = nullptr; - } } void SSUServer::Run () @@ -159,21 +151,6 @@ namespace transport } } - void SSUServer::RunV6 () - { - while (m_IsRunning) - { - try - { - m_ServiceV6.run (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "SSU: v6 server runtime exception: ", ex.what ()); - } - } - } - void SSUServer::RunReceivers () { while (m_IsRunning) @@ -358,7 +335,7 @@ namespace transport } } - m_ServiceV6.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6)); + m_Service.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6)); ReceiveV6 (); } else @@ -456,8 +433,7 @@ namespace transport else { boost::asio::ip::udp::endpoint remoteEndpoint (addr, port); - auto& s = addr.is_v6 () ? m_ServiceV6 : m_Service; - s.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest)); + m_Service.post (std::bind (&SSUServer::CreateDirectSession, this, router, remoteEndpoint, peerTest)); } } } @@ -841,7 +817,7 @@ namespace transport auto session = it.second; if (it.first != session->GetRemoteEndpoint ()) LogPrint (eLogWarning, "SSU: remote endpoint ", session->GetRemoteEndpoint (), " doesn't match key ", it.first); - m_ServiceV6.post ([session] + m_Service.post ([session] { LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds"); session->Failed (); diff --git a/libi2pd/SSU.h b/libi2pd/SSU.h index 6a79f754..213f379f 100644 --- a/libi2pd/SSU.h +++ b/libi2pd/SSU.h @@ -64,7 +64,6 @@ namespace transport void DeleteAllSessions (); boost::asio::io_service& GetService () { return m_Service; }; - boost::asio::io_service& GetServiceV6 () { return m_ServiceV6; }; const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; }; void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to); void AddRelay (uint32_t tag, std::shared_ptr relay); @@ -82,7 +81,6 @@ namespace transport void OpenSocket (); void OpenSocketV6 (); void Run (); - void RunV6 (); void RunReceivers (); void RunReceiversV6 (); void Receive (); @@ -122,9 +120,9 @@ namespace transport bool m_OnlyV6; bool m_IsRunning; - std::thread * m_Thread, * m_ThreadV6, * m_ReceiversThread, * m_ReceiversThreadV6; - boost::asio::io_service m_Service, m_ServiceV6, m_ReceiversService, m_ReceiversServiceV6; - boost::asio::io_service::work m_Work, m_WorkV6, m_ReceiversWork, m_ReceiversWorkV6; + std::thread * m_Thread, * m_ReceiversThread, * m_ReceiversThreadV6; + boost::asio::io_service m_Service, m_ReceiversService, m_ReceiversServiceV6; + 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, diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 9ce6e2e3..860c2be3 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -49,7 +49,7 @@ namespace transport boost::asio::io_service& SSUSession::GetService () { - return IsV6 () ? m_Server.GetServiceV6 () : m_Server.GetService (); + return m_Server.GetService (); } void SSUSession::CreateAESandMacKey (const uint8_t * pubKey) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 4e0aa6a5..c6e90ad2 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -501,7 +501,7 @@ namespace transport { auto addr = router->GetSSUV6Address (); if (addr) - m_SSUServer->GetServiceV6 ().post ([this, router, addr] + m_SSUServer->GetService ().post ([this, router, addr] { m_SSUServer->CreateDirectSession (router, { addr->host, (uint16_t)addr->port }, false); }); From da94d407380f3750e8116b78ce685d34edacb88a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 18 Oct 2020 14:39:58 -0400 Subject: [PATCH 0497/2950] check if session is terminated before receive --- libi2pd_client/I2CP.cpp | 25 +++++++++++++++++-------- libi2pd_client/I2CP.h | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 24c2496b..80274d86 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -226,14 +226,13 @@ namespace client } I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): - m_Owner (owner), m_Socket (socket), m_Payload (nullptr), - m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) + m_Owner (owner), m_Socket (socket), m_SessionID (0xFFFF), + m_MessageID (0), m_IsSendAccepted (true) { } I2CPSession::~I2CPSession () { - delete[] m_Payload; } void I2CPSession::Start () @@ -264,6 +263,11 @@ namespace client void I2CPSession::ReceiveHeader () { + if (!m_Socket) + { + LogPrint (eLogError, "I2CP: Can't receive header"); + return; + } boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Header, I2CP_HEADER_SIZE), boost::asio::transfer_all (), std::bind (&I2CPSession::HandleReceivedHeader, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -279,10 +283,7 @@ namespace client if (m_PayloadLen > 0) { if (m_PayloadLen <= I2CP_MAX_MESSAGE_LENGTH) - { - m_Payload = new uint8_t[m_PayloadLen]; ReceivePayload (); - } else { LogPrint (eLogError, "I2CP: Unexpected payload length ", m_PayloadLen); @@ -299,6 +300,11 @@ namespace client void I2CPSession::ReceivePayload () { + if (!m_Socket) + { + LogPrint (eLogError, "I2CP: Can't receive payload"); + return; + } boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Payload, m_PayloadLen), boost::asio::transfer_all (), std::bind (&I2CPSession::HandleReceivedPayload, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); @@ -311,8 +317,6 @@ namespace client else { HandleMessage (); - delete[] m_Payload; - m_Payload = nullptr; m_PayloadLen = 0; ReceiveHeader (); // next message } @@ -345,6 +349,11 @@ namespace client void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len) { + if (len > I2CP_MAX_MESSAGE_LENGTH) + { + LogPrint (eLogError, "I2CP: Message to send is too long ", len); + return; + } auto socket = m_Socket; if (socket) { diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 4c6b7531..c5dc80e7 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -179,7 +179,7 @@ namespace client I2CPServer& m_Owner; std::shared_ptr m_Socket; - uint8_t m_Header[I2CP_HEADER_SIZE], * m_Payload; + uint8_t m_Header[I2CP_HEADER_SIZE], m_Payload[I2CP_MAX_MESSAGE_LENGTH]; size_t m_PayloadLen; std::shared_ptr m_Destination; From 387830e07a90f1f5b16608ea2fc5cd0161698754 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 19 Oct 2020 18:26:01 -0400 Subject: [PATCH 0498/2950] encyption type 0,4 by default for client tunnels --- libi2pd/Config.cpp | 8 ++++---- libi2pd_client/ClientContext.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b924a108..fc479532 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -108,8 +108,8 @@ namespace config { ("httpproxy.latency.max", value()->default_value("0"), "HTTP proxy max latency for tunnels") ("httpproxy.outproxy", value()->default_value(""), "HTTP proxy upstream out proxy url") ("httpproxy.addresshelper", value()->default_value(true), "Enable or disable addresshelper") - ("httpproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type") - ("httpproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type") + ("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") ; options_description socksproxy("SOCKS Proxy options"); @@ -129,8 +129,8 @@ namespace config { ("socksproxy.outproxy.enabled", value()->default_value(false), "Enable or disable SOCKS outproxy") ("socksproxy.outproxy", value()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy") ("socksproxy.outproxyport", value()->default_value(9050), "Upstream outproxy port for SOCKS Proxy") - ("socksproxy.i2cp.leaseSetType", value()->default_value("1"), "Local destination's LeaseSet type") - ("socksproxy.i2cp.leaseSetEncType", value()->default_value("0"), "Local destination's LeaseSet encryption type") + ("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") ; options_description sam("SAM bridge options"); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 04f50e6f..ab868916 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -456,7 +456,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, ""); + std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, isServer ? "" : "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 b7ebb3ea3d1b275e567c4cd015749355911f3f60 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 20 Oct 2020 19:38:49 +0300 Subject: [PATCH 0499/2950] [android] support NetworkCallback for network state changes Signed-off-by: R4SAS --- .../src/org/purplei2p/i2pd/I2PDActivity.java | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 8295e9f1..777ca748 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -15,6 +15,7 @@ import java.util.TimerTask; import android.Manifest; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.ActivityNotFoundException; @@ -25,6 +26,10 @@ import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.res.AssetManager; import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.Uri; import android.os.Bundle; import android.os.Build; @@ -41,6 +46,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; @@ -63,6 +69,7 @@ public class I2PDActivity extends Activity { private TextView textView; private boolean assetsCopied; + private NetworkStateCallback networkCallback; private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/"; //private ConfigParser parser = new ConfigParser(i2pdpath); // TODO: @@ -116,7 +123,7 @@ public class I2PDActivity extends Activity { daemonStateUpdatedListener.daemonStateUpdate(); // request permissions - if (Build.VERSION.SDK_INT >= 23) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, @@ -137,6 +144,10 @@ public class I2PDActivity extends Activity { } openBatteryOptimizationDialogIfNeeded(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + registerNetworkCallback(); + } } @Override @@ -244,7 +255,7 @@ public class I2PDActivity extends Activity { } private boolean isBatteryOptimizationsOpenOsDialogApiAvailable() { - return android.os.Build.VERSION.SDK_INT >= 23; + return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } @Override @@ -631,6 +642,33 @@ public class I2PDActivity extends Activity { return "show_battery_optimization" + (device == null ? "" : device); } + @TargetApi(Build.VERSION_CODES.M) + private void registerNetworkCallback() { + ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkRequest request = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + .build(); + networkCallback = new NetworkStateCallback(); + connectivityManager.registerNetworkCallback(request, networkCallback); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private final class NetworkStateCallback extends ConnectivityManager.NetworkCallback { + @Override + public void onAvailable(Network network) { + super.onAvailable(network); + I2PD_JNI.onNetworkStateChanged(true); + Log.i(TAG, "NetworkCallback.onAvailable"); + } + + @Override + public void onLost(Network network) { + super.onLost(network); + I2PD_JNI.onNetworkStateChanged(false); + Log.i(TAG, " NetworkCallback.onLost"); + } + } + private void quit() { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { From 17f5bcbd1cd3d40c082203130e7acc31e60a15b1 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 21 Oct 2020 14:46:31 +0800 Subject: [PATCH 0500/2950] qt: newer options added; not tested --- qt/i2pd_qt/TunnelConfig.cpp | 12 +++ qt/i2pd_qt/TunnelConfig.h | 26 +++++- qt/i2pd_qt/TunnelPane.cpp | 119 ++++++++++++++++++++++++++++ qt/i2pd_qt/TunnelPane.h | 63 ++++++++------- qt/i2pd_qt/generalsettingswidget.ui | 15 +++- qt/i2pd_qt/i2pd_qt.pro | 3 +- qt/i2pd_qt/mainwindow.cpp | 17 ++-- qt/i2pd_qt/mainwindow.h | 36 +++++++++ 8 files changed, 249 insertions(+), 42 deletions(-) diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index 04fa6132..a2cdf92b 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -24,6 +24,18 @@ void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947 out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" << i2cpParameters.getExplicitPeers().toStdString() << "\n"; + out << i2p::client::I2CP_PARAM_LEASESET_AUTH_TYPE << "=" + << i2cpParameters.get_i2cp_leaseSetAuthType().toStdString() << "\n"; + out << i2p::client::I2CP_PARAM_LEASESET_ENCRYPTION_TYPE << "=" + << i2cpParameters.get_i2cp_leaseSetEncType().toStdString() << "\n"; + out << i2p::client::I2CP_PARAM_LEASESET_PRIV_KEY << "=" + << i2cpParameters.get_i2cp_leaseSetPrivKey().toStdString() << "\n"; + out << i2p::client::I2CP_PARAM_LEASESET_TYPE << "=" + << i2cpParameters.get_i2cp_leaseSetType().toStdString() << "\n"; + out << i2p::client::I2CP_PARAM_STREAMING_ANSWER_PINGS << "=" + << (i2cpParameters.get_i2p_streaming_answerPings() ? "true" : "false") << "\n"; + out << i2p::client::I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY << "=" + << i2cpParameters.get_i2p_streaming_initialAckDelay().toStdString() << "\n"; out << "\n"; } diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 7f262215..530a525c 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -16,25 +16,49 @@ class I2CPParameters{ QString outbound_quantity; //number of outbound tunnels. 5 by default QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset + QString i2p_streaming_initialAckDelay; //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default + bool i2p_streaming_answerPings; //i2p.streaming.answerPings -- enable sending pongs. true by default + QString i2cp_leaseSetType; //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default + QString i2cp_leaseSetEncType; //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default + QString i2cp_leaseSetPrivKey; //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH + QString i2cp_leaseSetAuthType; //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK public: I2CPParameters(): inbound_length(), outbound_length(), inbound_quantity(), outbound_quantity(), crypto_tagsToSend(), - explicitPeers() {} + explicitPeers(), + i2p_streaming_initialAckDelay(), + i2p_streaming_answerPings(true), + i2cp_leaseSetType(), + i2cp_leaseSetEncType(), + i2cp_leaseSetPrivKey(), + i2cp_leaseSetAuthType() {} const QString& getInbound_length(){return inbound_length;} const QString& getOutbound_length(){return outbound_length;} const QString& getInbound_quantity(){return inbound_quantity;} const QString& getOutbound_quantity(){return outbound_quantity;} const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;} const QString& getExplicitPeers(){return explicitPeers;} + const QString& get_i2p_streaming_initialAckDelay(){return i2p_streaming_initialAckDelay;} + bool get_i2p_streaming_answerPings(){return i2p_streaming_answerPings;} + const QString& get_i2cp_leaseSetType(){return i2cp_leaseSetType;} + const QString& get_i2cp_leaseSetEncType(){return i2cp_leaseSetEncType;} + const QString& get_i2cp_leaseSetPrivKey(){return i2cp_leaseSetPrivKey;} + const QString& get_i2cp_leaseSetAuthType(){return i2cp_leaseSetAuthType;} void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;} void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;} void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;} void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;} void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;} void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;} + void set_i2p_streaming_initialAckDelay(QString i2p_streaming_initialAckDelay_){i2p_streaming_initialAckDelay=i2p_streaming_initialAckDelay_;} + void set_i2p_streaming_answerPings(bool i2p_streaming_answerPings_){i2p_streaming_answerPings=i2p_streaming_answerPings_;} + void set_i2cp_leaseSetType(QString i2cp_leaseSetType_){i2cp_leaseSetType=i2cp_leaseSetType_;} + void set_i2cp_leaseSetEncType(QString i2cp_leaseSetEncType_){i2cp_leaseSetEncType=i2cp_leaseSetEncType_;} + void set_i2cp_leaseSetPrivKey(QString i2cp_leaseSetPrivKey_){i2cp_leaseSetPrivKey=i2cp_leaseSetPrivKey_;} + void set_i2cp_leaseSetAuthType(QString i2cp_leaseSetAuthType_){i2cp_leaseSetAuthType=i2cp_leaseSetAuthType_;} }; diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 60b0b6d5..ffacfd61 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -187,30 +187,149 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, { //explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset + const QString& value=i2cpParameters.getExplicitPeers(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QLabel *_Label; + explicitPeersLabel = _Label = new QLabel(gridLayoutWidget_2); + _Label->setObjectName(QStringLiteral("_Label")); + horizontalLayout_2->addWidget(_Label); + QLineEdit *_LineEdit; + explicitPeersLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); + _LineEdit->setObjectName(QStringLiteral("_LineEdit")); + _LineEdit->setText(value); + _LineEdit->setMaximumWidth(80); + QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(_LineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default + const QString& value=i2cpParameters.get_i2p_streaming_initialAckDelay(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QLabel *_Label; + i2p_streaming_initialAckDelayLabel = _Label = new QLabel(gridLayoutWidget_2); + _Label->setObjectName(QStringLiteral("_Label")); + horizontalLayout_2->addWidget(_Label); + QLineEdit *_LineEdit; + i2p_streaming_initialAckDelayLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); + _LineEdit->setObjectName(QStringLiteral("_LineEdit")); + _LineEdit->setText(value); + _LineEdit->setMaximumWidth(80); + QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(_LineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //i2p.streaming.answerPings -- enable sending pongs. true by default + const bool value=i2cpParameters.get_i2p_streaming_answerPings(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QCheckBox *_CheckBox; + i2p_streaming_answerPingsCheckBox = _CheckBox = new QCheckBox(gridLayoutWidget_2); + _CheckBox->setObjectName(QStringLiteral("_CheckBox")); + horizontalLayout_2->addWidget(_CheckBox); + _CheckBox->setChecked(value); + QObject::connect(_CheckBox, SIGNAL(toggled(bool)), + this, SLOT(updated())); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default + const QString& value=i2cpParameters.get_i2cp_leaseSetType(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QLabel *_Label; + i2cp_leaseSetTypeLabel = _Label = new QLabel(gridLayoutWidget_2); + _Label->setObjectName(QStringLiteral("_Label")); + horizontalLayout_2->addWidget(_Label); + QLineEdit *_LineEdit; + i2cp_leaseSetTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); + _LineEdit->setObjectName(QStringLiteral("_LineEdit")); + _LineEdit->setText(value); + _LineEdit->setMaximumWidth(80); + QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(_LineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default + const QString& value=i2cpParameters.get_i2cp_leaseSetEncType(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QLabel *_Label; + i2cp_leaseSetEncTypeLabel = _Label = new QLabel(gridLayoutWidget_2); + _Label->setObjectName(QStringLiteral("_Label")); + horizontalLayout_2->addWidget(_Label); + QLineEdit *_LineEdit; + i2cp_leaseSetEncTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); + _LineEdit->setObjectName(QStringLiteral("_LineEdit")); + _LineEdit->setText(value); + _LineEdit->setMaximumWidth(80); + QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(_LineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH + const QString& value=i2cpParameters.get_i2cp_leaseSetPrivKey(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QLabel *_Label; + i2cp_leaseSetPrivKeyLabel = _Label = new QLabel(gridLayoutWidget_2); + _Label->setObjectName(QStringLiteral("_Label")); + horizontalLayout_2->addWidget(_Label); + QLineEdit *_LineEdit; + i2cp_leaseSetPrivKeyLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); + _LineEdit->setObjectName(QStringLiteral("_LineEdit")); + _LineEdit->setText(value); + _LineEdit->setMaximumWidth(80); + QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(_LineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK + const QString& value=i2cpParameters.get_i2cp_leaseSetAuthType(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + QLabel *_Label; + i2cp_leaseSetAuthTypeLabel = _Label = new QLabel(gridLayoutWidget_2); + _Label->setObjectName(QStringLiteral("_Label")); + horizontalLayout_2->addWidget(_Label); + QLineEdit *_LineEdit; + i2cp_leaseSetAuthTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); + _LineEdit->setObjectName(QStringLiteral("_LineEdit")); + _LineEdit->setText(value); + _LineEdit->setMaximumWidth(80); + QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); + horizontalLayout_2->addWidget(_LineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2); } retranslateI2CPParameters(); diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 6a13b7a0..61071059 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -11,6 +11,7 @@ #include "QLineEdit" #include "QGroupBox" #include "QVBoxLayout" +#include "QCheckBox" #include "TunnelConfig.h" @@ -89,6 +90,27 @@ protected: QLabel * crypto_tagsToSendLabel; QLineEdit * crypto_tagsToSendLineEdit; + QLabel * explicitPeersLabel; + QLineEdit * explicitPeersLineEdit; + + QLabel * i2p_streaming_initialAckDelayLabel; + QLineEdit * i2p_streaming_initialAckDelayLineEdit; + + QCheckBox * i2p_streaming_answerPingsCheckBox; + + QLabel * i2cp_leaseSetTypeLabel; + QLineEdit * i2cp_leaseSetTypeLineEdit; + + QLabel * i2cp_leaseSetEncTypeLabel; + QLineEdit * i2cp_leaseSetEncTypeLineEdit; + + QLabel * i2cp_leaseSetPrivKeyLabel; + QLineEdit * i2cp_leaseSetPrivKeyLineEdit; + + QLabel * i2cp_leaseSetAuthTypeLabel; + QLineEdit * i2cp_leaseSetAuthTypeLineEdit; + + QString readTunnelTypeComboboxData(); //should be created by factory @@ -105,6 +127,12 @@ public: i2cpParams.setOutbound_length(outbound_lengthLineEdit->text()); i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text()); i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); + i2cpParams.set_i2cp_leaseSetAuthType(i2cp_leaseSetAuthTypeLineEdit->text()); + i2cpParams.set_i2cp_leaseSetEncType(i2cp_leaseSetEncTypeLineEdit->text()); + i2cpParams.set_i2cp_leaseSetPrivKey(i2cp_leaseSetPrivKeyLineEdit->text()); + i2cpParams.set_i2cp_leaseSetType(i2cp_leaseSetTypeLineEdit->text()); + i2cpParams.set_i2p_streaming_answerPings(i2p_streaming_answerPingsCheckBox->isChecked()); + i2cpParams.set_i2p_streaming_initialAckDelay(i2p_streaming_initialAckDelayLineEdit->text()); return true; } protected: @@ -133,34 +161,13 @@ private: inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));; outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));; crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));; - - { - //explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset - } - - { - //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default - } - - { - //i2p.streaming.answerPings -- enable sending pongs. true by default - } - - { - //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default - } - - { - //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default - } - - { - //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH - } - - { - //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK - } + explicitPeersLabel->setText(QApplication::translate("tunForm", "List of comma-separated b64 addresses of peers to use:", 0));; + i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0)); + i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0)); + i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0)); + i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separated encryption types to be used in LeaseSet type 3 or 5:", 0)); + i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0)); + i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Authentication type for encrypted LeaseSet. 0 - no authentication (default), 1 - DH, 2 - PSK:", 0)); } }; diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index e64f9e35..1c71de22 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -25,7 +25,7 @@ 0 0 679 - 4151 + 4178 @@ -464,13 +464,13 @@ 0 - 390 + 417 16777215 - 390 + 417 @@ -482,7 +482,7 @@ 0 20 661 - 368 + 397 @@ -528,6 +528,13 @@ + + + + Check remote RI for being in blacklist of reserved IP ranges + + + diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 468d2d00..2f44b814 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -4,7 +4,8 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app -QMAKE_CXXFLAGS *= -std=c++11 -Wno-unused-parameter -Wno-maybe-uninitialized +QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized +CONFIG += strict_c++ c++11 DEFINES += USE_UPNP diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index d4d34109..feb1b4a9 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -190,6 +190,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("","family",[]{return "";}), uiSettings->familyLineEdit); initIntegerBox( OPTION("","netid",[]{return "2";}), uiSettings->netIdLineEdit, tr("NetID")); initCheckBox( OPTION("","ssu",[]{return "true";}), uiSettings->ssuCheckBox);//Enable SSU transport protocol (use UDP). true by default + initCheckBox( OPTION("","reservedrange",[]{return "true";}), uiSettings->reservedrange_checkbox); #ifdef Q_OS_WIN initNonGUIOption( OPTION("","svcctl",[]{return "";})); @@ -205,22 +206,22 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("http","auth",[]{return "";}), uiSettings->webconsoleBasicAuthCheckBox); initStringBox( OPTION("http","user",[]{return "i2pd";}), uiSettings->webconsoleUserNameLineEditBasicAuth); initStringBox( OPTION("http","pass",[]{return "";}), uiSettings->webconsolePasswordLineEditBasicAuth); - initCheckBox( OPTION("http","strictheaders",[]{return "true";}), uiSettings->httpStrictHeadersCheckBox);//TODO add option Enable strict host checking on WebUI. true by default - initStringBox( OPTION("http","hostname",[]{return "localhost";}), uiSettings->httpHostnameLineEdit);//TODO add option Expected hostname for WebUI (default: localhost) + initCheckBox( OPTION("http","strictheaders",[]{return "true";}), uiSettings->httpStrictHeadersCheckBox);//Enable strict host checking on WebUI. true by default + initStringBox( OPTION("http","hostname",[]{return "localhost";}), uiSettings->httpHostnameLineEdit);//Expected hostname for WebUI (default: localhost) initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), uiSettings->httpProxyEnabledCheckBox); initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); - initCheckBox( OPTION("httpproxy","addresshelper",[]{return "true";}), uiSettings->httpProxyAddressHelperCheckBox);//TODO add option Enable address helper (jump). true by default + initCheckBox( OPTION("httpproxy","addresshelper",[]{return "true";}), uiSettings->httpProxyAddressHelperCheckBox);//Enable address helper (jump). true by default initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton); initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType); initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit); initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit); initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), uiSettings->httpProxyOutBoundTunnLenLineEdit); initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), uiSettings->httpProxyOutboundTunnQuantityLineEdit); - initStringBox( OPTION("httpproxy","outproxy",[]{return "";}), uiSettings->httpProxyOutproxyLineEdit);//TODO add option HTTP proxy upstream out proxy url (like http://false.i2p) - initStringBox( OPTION("httpproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->httpProxyI2cpLeaseSetTypeLineEdit);//TODO add option Type of LeaseSet to be sent. 1, 3 or 5. 1 by default - initStringBox( OPTION("httpproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->httpProxyI2cpLeaseSetEncTypeLineEdit);//TODO add option Comma separated encryption types to be used in LeaseSet type 3 or 5 + initStringBox( OPTION("httpproxy","outproxy",[]{return "";}), uiSettings->httpProxyOutproxyLineEdit);//HTTP proxy upstream out proxy url (like http://false.i2p) + initStringBox( OPTION("httpproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->httpProxyI2cpLeaseSetTypeLineEdit);//Type of LeaseSet to be sent. 1, 3 or 5. 1 by default + initStringBox( OPTION("httpproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->httpProxyI2cpLeaseSetEncTypeLineEdit);//Comma separated encryption types to be used in LeaseSet type 3 or 5 initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox); initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); @@ -233,8 +234,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), uiSettings->socksProxyOutboundTunnQuantityLineEdit); initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); - initStringBox( OPTION("socksproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->socksProxyI2cpLeaseSetTypeLineEdit);//TODO add option Type of LeaseSet to be sent. 1, 3 or 5. 1 by default - initStringBox( OPTION("socksproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->socksProxyI2cpLeaseSetEncTypeLineEdit);//TODO add option Comma separated encryption types to be used in LeaseSet type 3 or 5 + initStringBox( OPTION("socksproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->socksProxyI2cpLeaseSetTypeLineEdit);//Type of LeaseSet to be sent. 1, 3 or 5. 1 by default + initStringBox( OPTION("socksproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->socksProxyI2cpLeaseSetEncTypeLineEdit);//Comma separated encryption types to be used in LeaseSet type 3 or 5 initCheckBox( OPTION("sam","enabled",[]{return "false";}), uiSettings->samEnabledCheckBox); initIPAddressBox( OPTION("sam","address",[]{return "";}), uiSettings->samAddressLineEdit, tr("SAM -> IP address")); diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index b4f57f8f..77c8826b 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -545,6 +545,18 @@ private: void deleteTunnelForms(); void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf); + template + std::string GetI2CPOption (const Section& section, const std::string& name, const std::string& value) const + { + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); + } + + template + std::string GetI2CPOption (const Section& section, const std::string& name, const char* value) const + { + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::string (value)); + } + template std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const { @@ -565,6 +577,19 @@ private: param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str())); std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND); param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str())); + std::string _i2cp_leaseSetAuthType = options[I2CP_PARAM_LEASESET_AUTH_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0); + param.set_i2cp_leaseSetAuthType(QString(_i2cp_leaseSetAuthType.c_str())); + const char DEFAULT_LEASESET_ENCRYPTION_TYPE[] = ""; + std::string _i2cp_leaseSetEncType = options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, DEFAULT_LEASESET_ENCRYPTION_TYPE);//todo Identity's type by default + param.set_i2cp_leaseSetEncType(QString(_i2cp_leaseSetEncType.c_str())); + std::string _i2cp_leaseSetPrivKey = options[I2CP_PARAM_LEASESET_PRIV_KEY] = GetI2CPOption (section, I2CP_PARAM_LEASESET_PRIV_KEY, ""); + param.set_i2cp_leaseSetPrivKey(QString(_i2cp_leaseSetPrivKey.c_str())); + std::string _i2cp_leaseSetType = options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); + param.set_i2cp_leaseSetType(QString(_i2cp_leaseSetType.c_str())); + std::string _i2p_streaming_answerPings= options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption (section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS); + param.set_i2p_streaming_answerPings((_i2p_streaming_answerPings.compare("true")==0)||(_i2p_streaming_answerPings.compare("yes")==0)); + std::string _i2p_streaming_initialAckDelay = options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption (section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); + param.set_i2p_streaming_initialAckDelay(QString(_i2p_streaming_initialAckDelay.c_str())); options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param } @@ -582,6 +607,17 @@ private: param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY)); const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND; param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND)); + const int _i2cp_leaseSetAuthType = 0; + param.set_i2cp_leaseSetAuthType(QString::number(_i2cp_leaseSetAuthType)); + const QString _i2cp_leaseSetEncType = "0,4"; //todo Identity's type by default + param.set_i2cp_leaseSetEncType(_i2cp_leaseSetEncType); + param.set_i2cp_leaseSetPrivKey(""); + const int _i2cp_leaseSetType = DEFAULT_LEASESET_TYPE; + param.set_i2cp_leaseSetType(QString::number(_i2cp_leaseSetType)); + bool _i2p_streaming_answerPings= DEFAULT_ANSWER_PINGS; + param.set_i2p_streaming_answerPings(_i2p_streaming_answerPings); + const int _i2p_streaming_initialAckDelay = DEFAULT_INITIAL_ACK_DELAY; + param.set_i2p_streaming_initialAckDelay(QString::number(_i2p_streaming_initialAckDelay)); } From 4001f48a2858008eb84157b5b9d6e745db77a503 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 21 Oct 2020 18:12:39 +0800 Subject: [PATCH 0501/2950] qt: visual fixes & more --- qt/i2pd_qt/.gitignore | 1 + qt/i2pd_qt/TunnelPane.cpp | 2 +- qt/i2pd_qt/TunnelPane.h | 4 +- qt/i2pd_qt/generalsettingswidget.ui | 79 ++++++++++++++++++++++------- qt/i2pd_qt/mainwindow.cpp | 14 ++++- 5 files changed, 79 insertions(+), 21 deletions(-) diff --git a/qt/i2pd_qt/.gitignore b/qt/i2pd_qt/.gitignore index bbf3e1e4..1f9d6012 100644 --- a/qt/i2pd_qt/.gitignore +++ b/qt/i2pd_qt/.gitignore @@ -9,4 +9,5 @@ object_script.* i2pd_qt_plugin_import.cpp i2pd_qt.pro.autosave* build* +nohup.out diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index ffacfd61..4b873ac1 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -31,7 +31,7 @@ void TunnelPane::setupTunnelPane( this->gridLayoutWidget_2=gridLayoutWidget_2; tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2); tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout")); - tunnelGridLayout->setContentsMargins(5, 5, 5, 5); + tunnelGridLayout->setContentsMargins(10, 25, 10, 10); tunnelGridLayout->setSpacing(5); //header diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 61071059..59303afd 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -165,9 +165,9 @@ private: i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0)); i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0)); i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0)); - i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separated encryption types to be used in LeaseSet type 3 or 5:", 0)); + i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separ. encr. types to be used in LeaseSet type 3 or 5:", 0)); i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0)); - i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Authentication type for encrypted LeaseSet. 0 - no authentication (default), 1 - DH, 2 - PSK:", 0)); + i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0)); } }; diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index 1c71de22..eabaa473 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -19,13 +19,28 @@ GeneralSettingsContentsForm + + QGroupBox { + font: bold; + border: 1px solid silver; + border-radius: 6px; + margin-top: 6px; +} + +QGroupBox::title { + subcontrol-origin: margin; + left: 7px; + padding: 0px 5px 0px 5px; +} + + 0 0 679 - 4178 + 4242 @@ -59,7 +74,7 @@ - + 0 0 @@ -67,18 +82,36 @@ 0 - 51 + 60 16777215 - 51 + 60 + + QGroupBox { + font: bold; + border: 1px solid silver; + border-radius: 6px; + margin-top: 6px; +} + +QGroupBox::title { + subcontrol-origin: margin; + left: 7px; + padding: 0px 5px 0px 5px; +} + + Configuration file: + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -90,7 +123,7 @@ - QLayout::SetMaximumSize + QLayout::SetMinAndMaxSize @@ -100,19 +133,19 @@ 0 - 0 + 25 0 - 27 + 0 16777215 - 27 + 25 @@ -309,13 +342,13 @@ 0 - 112 + 130 16777215 - 112 + 130 @@ -2329,13 +2362,13 @@ Comma separated list of base64 identities: 0 - 215 + 225 16777215 - 215 + 225 @@ -3341,7 +3374,7 @@ Comma separated list of base64 identities: - + 0 0 @@ -3349,13 +3382,13 @@ Comma separated list of base64 identities: 0 - 128 + 145 16777215 - 128 + 300 @@ -3370,12 +3403,24 @@ Comma separated list of base64 identities: -1 19 681 - 101 + 124 - QLayout::SetMinAndMaxSize + QLayout::SetDefaultConstraint + + + 10 + + + 10 + + + 10 + + + 10 diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index feb1b4a9..95712b68 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -84,7 +84,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ui->settingsScrollArea->resize(uiSettings->settingsContentsQVBoxLayout->sizeHint().width()+10,380); //QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); int w = 683; - int h = 4000; + int h = 4250; ui->settingsContents->setFixedSize(w, h); ui->settingsContents->setGeometry(QRect(0,0,w,h)); @@ -324,6 +324,18 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451)); + ui->tunnelsScrollAreaWidgetContents->setStyleSheet("QGroupBox { " \ + " font: bold;" \ + " border: 1px solid silver;" \ + " border-radius: 6px;" \ + " margin-top: 6px;" \ + "}" \ + "QGroupBox::title {" \ + " subcontrol-origin: margin;" \ + " left: 7px;" \ + " padding: 0px 5px 0px 5px;" \ + "}"); + appendTunnelForms(""); uiSettings->configFileLineEdit->setEnabled(false); From 365fce922c6fe14c24736548ded2dd59fee3971c Mon Sep 17 00:00:00 2001 From: user Date: Thu, 22 Oct 2020 00:35:59 +0800 Subject: [PATCH 0502/2950] qt: socks defaults fixes, socks outproxy enabled checkbox added; visual fixes --- qt/i2pd_qt/generalsettingswidget.ui | 1017 ++++++++++++++------------- qt/i2pd_qt/mainwindow.cpp | 7 +- 2 files changed, 516 insertions(+), 508 deletions(-) diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index eabaa473..7a35c0a5 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -40,7 +40,7 @@ QGroupBox::title { 0 0 679 - 4242 + 4434 @@ -82,13 +82,13 @@ QGroupBox::title { 0 - 60 + 80 16777215 - 60 + 80 @@ -112,46 +112,62 @@ QGroupBox::title { Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + - 0 - 18 - 661 - 31 + 12 + 19 + 651 + 51 - - - QLayout::SetMinAndMaxSize - + - - - - - - - 0 - 25 - + + + QLayout::SetMinAndMaxSize - - - 0 - 0 - + + 10 - - - 16777215 - 25 - + + 10 - - Browse… + + 10 - + + 10 + + + + + + + + + 0 + 27 + + + + + 0 + 0 + + + + + 16777215 + 27 + + + + Browse… + + + + @@ -162,40 +178,56 @@ QGroupBox::title { 0 - 51 + 80 16777215 - 51 + 80 Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - + - 0 - 20 - 661 - 31 + 12 + 19 + 651 + 51 - - - QLayout::SetMaximumSize + + + 10 + + + 10 + + + 10 + + + 10 - - - - - - Browse… + + + QLayout::SetMaximumSize - + + + + + + + Browse… + + + + @@ -212,58 +244,74 @@ QGroupBox::title { 0 - 51 + 80 16777215 - 51 + 80 Pid file: - + - 0 - 18 - 661 - 31 + 12 + 19 + 651 + 51 - - - QLayout::SetMaximumSize + + + 10 + + + 10 + + + 10 + + + 10 - - - - - - - 0 - 0 - + + + QLayout::SetMaximumSize - - - 0 - 27 - - - - - 16777215 - 27 - - - - Browse… - - + + + + + + + + 0 + 0 + + + + + 0 + 27 + + + + + 16777215 + 27 + + + + Browse… + + + + @@ -280,58 +328,74 @@ QGroupBox::title { 0 - 51 + 80 16777215 - 51 + 80 Tunnels configuration file: - + - 0 - 18 - 661 - 31 + 12 + 19 + 651 + 51 - - - QLayout::SetMaximumSize + + + 10 + + + 10 + + + 10 + + + 10 - - - - - - - 0 - 0 - + + + QLayout::SetMaximumSize - - - 0 - 27 - - - - - 16777215 - 27 - - - - Browse… - - + + + + + + + + 0 + 0 + + + + + 0 + 27 + + + + + 16777215 + 27 + + + + Browse… + + + + @@ -2885,434 +2949,377 @@ Comma separated list of base64 identities: 0 - 405 + 500 16777215 - 405 + 500 Socks proxy - + - 0 + 9 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 661 - 31 + 470 - + + + 10 + + + 10 + + + 10 + + + 10 + - + - IP address to listen on: + Enabled - + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - 80 - 16777215 - - - + + + + + Keys file: + + + + + + + + + + Browse… + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - + + + + + Signature type: + + + + + + + + + + Edit + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels length: - - + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - 80 - 16777215 - - - + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - 80 - 16777215 - + + + 0 - + + 0 + + + + + Outproxy enabled + + + + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels length: - - + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - 80 - 16777215 - - - + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 310 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Signature type: - - - - - - - - - - Edit - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - -1 - 340 - 661 - 62 - - - diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 95712b68..89178ee0 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -84,7 +84,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ui->settingsScrollArea->resize(uiSettings->settingsContentsQVBoxLayout->sizeHint().width()+10,380); //QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); int w = 683; - int h = 4250; + int h = 4550; ui->settingsContents->setFixedSize(w, h); ui->settingsContents->setGeometry(QRect(0,0,w,h)); @@ -232,8 +232,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), uiSettings->socksProxyInboundTunnQuantityLineEdit); initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), uiSettings->socksProxyOutBoundTunnLenLineEdit); initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), uiSettings->socksProxyOutboundTunnQuantityLineEdit); - initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); - initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + initCheckBox( OPTION("socksproxy","outproxy.enabled",[]{return "false";}), uiSettings->socksOutproxyEnabledCheckBox); + initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "127.0.0.1";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); + initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "9050";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); initStringBox( OPTION("socksproxy","i2cp.leaseSetType",[]{return "1";}), uiSettings->socksProxyI2cpLeaseSetTypeLineEdit);//Type of LeaseSet to be sent. 1, 3 or 5. 1 by default initStringBox( OPTION("socksproxy","i2cp.leaseSetEncType",[]{return "";}), uiSettings->socksProxyI2cpLeaseSetEncTypeLineEdit);//Comma separated encryption types to be used in LeaseSet type 3 or 5 From 49bf735c22947f57c4dfad4aaa8536895a804d96 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Oct 2020 18:59:16 -0400 Subject: [PATCH 0503/2950] don't set destination to routers --- libi2pd/Garlic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 429a2092..5f76bca1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -740,7 +740,8 @@ namespace garlic session = std::make_shared (this, true); session->SetRemoteStaticKey (staticKey); } - session->SetDestination (destination->GetIdentHash ()); // TODO: remove + if (destination->IsDestination ()) + session->SetDestination (destination->GetIdentHash ()); // TODO: remove return session; } else From 801ecaa41c988537b4abd54965c443e9fc060544 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Oct 2020 19:03:51 -0400 Subject: [PATCH 0504/2950] temporary exclude routers with non ElGamal crypto types --- libi2pd/RouterInfo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 12f81a42..8420044d 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -153,6 +153,12 @@ namespace data m_IsUnreachable = true; return; } + if (m_RouterIdentity->GetCryptoKeyType () != CRYPTO_KEY_TYPE_ELGAMAL) + { + // we support ElGamal only. TODO: remove later + m_IsUnreachable = true; + return; + } if (verifySignature) { // reject RSA signatures From d65a282e9d788a524b688a168859eb4d14735e09 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Oct 2020 18:34:15 -0400 Subject: [PATCH 0505/2950] check routers with non ElGamal encryptions for lookup, publish and tunnel build --- libi2pd/Destination.cpp | 11 +++++++---- libi2pd/RouterInfo.cpp | 6 ------ libi2pd/TunnelConfig.h | 13 ++++++++++++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 669fd791..927e98a0 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -559,7 +559,9 @@ namespace client m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); + auto msg = i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound); + if (floodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented + msg = WrapMessage (floodfill, msg); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); @@ -754,9 +756,10 @@ namespace client else AddSessionKey (replyKey, replyTag); - auto msg = WrapMessage (nextFloodfill, - CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - request->replyTunnel, replyKey, replyTag, isECIES)); + auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + request->replyTunnel, replyKey, replyTag, isECIES); + if (nextFloodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented + msg = WrapMessage (nextFloodfill, msg); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 8420044d..12f81a42 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -153,12 +153,6 @@ namespace data m_IsUnreachable = true; return; } - if (m_RouterIdentity->GetCryptoKeyType () != CRYPTO_KEY_TYPE_ELGAMAL) - { - // we support ElGamal only. TODO: remove later - m_IsUnreachable = true; - return; - } if (verifySignature) { // reject RSA signatures diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 0bd8a842..3a2fa44b 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -112,9 +112,20 @@ namespace tunnel RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); auto encryptor = ident->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); + { + if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + else + 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 EncryptECIES (std::shared_ptr& encryptor, + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const + { + memset (encrypted, 0, 512); // TODO: implement + } }; class TunnelConfig From 57d6c7a3b3c30d9b12492b18960f0de94e7d7bde Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Oct 2020 21:06:23 -0400 Subject: [PATCH 0506/2950] Added TunnelConfig.cpp. Removed CryptoWroker.h --- build/CMakeLists.txt | 1 + libi2pd/CryptoWorker.h | 88 ------------------------------ libi2pd/TunnelConfig.cpp | 114 +++++++++++++++++++++++++++++++++++++++ libi2pd/TunnelConfig.h | 99 +++------------------------------- qt/i2pd_qt/i2pd_qt.pro | 2 +- 5 files changed, 123 insertions(+), 181 deletions(-) delete mode 100644 libi2pd/CryptoWorker.h create mode 100644 libi2pd/TunnelConfig.cpp diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 4825855b..827e20d3 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -85,6 +85,7 @@ set(LIBI2PD_SRC "${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" ) diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h deleted file mode 100644 index 27b012e7..00000000 --- a/libi2pd/CryptoWorker.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* 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 CRYPTO_WORKER_H_ -#define CRYPTO_WORKER_H_ - -#include -#include -#include -#include -#include -#include - -namespace i2p -{ -namespace worker -{ - template - struct ThreadPool - { - typedef std::function ResultFunc; - typedef std::function WorkFunc; - typedef std::pair, WorkFunc> Job; - typedef std::mutex mtx_t; - typedef std::unique_lock lock_t; - typedef std::condition_variable cond_t; - ThreadPool(int workers) - { - stop = false; - if(workers > 0) - { - while(workers--) - { - threads.emplace_back([this] { - for (;;) - { - Job job; - { - lock_t lock(this->queue_mutex); - this->condition.wait( - lock, [this] { return this->stop || !this->jobs.empty(); }); - if (this->stop && this->jobs.empty()) return; - job = std::move(this->jobs.front()); - this->jobs.pop_front(); - } - ResultFunc result = job.second(); - job.first->GetService().post(result); - } - }); - } - } - }; - - void Offer(const Job & job) - { - { - lock_t lock(queue_mutex); - if (stop) return; - jobs.emplace_back(job); - } - condition.notify_one(); - } - - ~ThreadPool() - { - { - lock_t lock(queue_mutex); - stop = true; - } - condition.notify_all(); - for(auto &t: threads) t.join(); - } - - std::vector threads; - std::deque jobs; - mtx_t queue_mutex; - cond_t condition; - bool stop; - }; -} -} - -#endif diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp new file mode 100644 index 00000000..3b7955d4 --- /dev/null +++ b/libi2pd/TunnelConfig.cpp @@ -0,0 +1,114 @@ +/* +* 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 +#include +#include "Transports.h" +#include "Timestamp.h" +#include "I2PEndian.h" +#include "I2NPProtocol.h" +#include "TunnelConfig.h" + +namespace i2p +{ +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; + isEndpoint = true; + ident = r; + //nextRouter = nullptr; + nextTunnelID = 0; + + next = nullptr; + prev = nullptr; + } + + void TunnelHopConfig::SetNextIdent (const i2p::data::IdentHash& ident) + { + nextIdent = ident; + isEndpoint = false; + RAND_bytes ((uint8_t *)&nextTunnelID, 4); + if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero + } + + void TunnelHopConfig::SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) + { + nextIdent = replyIdent; + nextTunnelID = replyTunnelID; + isEndpoint = true; + } + + void TunnelHopConfig::SetNext (TunnelHopConfig * n) + { + next = n; + if (next) + { + next->prev = this; + next->isGateway = false; + isEndpoint = false; + nextIdent = next->ident->GetIdentHash (); + nextTunnelID = next->tunnelID; + } + } + + void TunnelHopConfig::SetPrev (TunnelHopConfig * p) + { + prev = p; + if (prev) + { + prev->next = this; + prev->isEndpoint = false; + isGateway = false; + } + } + + void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const + { + 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); + uint8_t flag = 0; + if (isGateway) flag |= 0x80; + if (isEndpoint) flag |= 0x40; + 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); + auto encryptor = ident->CreateEncryptor (nullptr); + if (encryptor) + { + if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + else + 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, + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const + { + memset (encrypted, 0, 512); // TODO: implement + } +} +} \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 3a2fa44b..24e6f836 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -9,13 +9,9 @@ #ifndef TUNNEL_CONFIG_H__ #define TUNNEL_CONFIG_H__ -#include -#include #include -#include #include "Identity.h" #include "RouterContext.h" -#include "Timestamp.h" namespace i2p { @@ -35,97 +31,16 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - 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; - isEndpoint = true; - ident = r; - //nextRouter = nullptr; - nextTunnelID = 0; + TunnelHopConfig (std::shared_ptr r); - next = nullptr; - prev = nullptr; - } - - void SetNextIdent (const i2p::data::IdentHash& ident) - { - nextIdent = ident; - isEndpoint = false; - RAND_bytes ((uint8_t *)&nextTunnelID, 4); - if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero - } - - void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) - { - nextIdent = replyIdent; - nextTunnelID = replyTunnelID; - isEndpoint = true; - } - - void SetNext (TunnelHopConfig * n) - { - next = n; - if (next) - { - next->prev = this; - next->isGateway = false; - isEndpoint = false; - nextIdent = next->ident->GetIdentHash (); - nextTunnelID = next->tunnelID; - } - } - - void SetPrev (TunnelHopConfig * p) - { - prev = p; - if (prev) - { - prev->next = this; - prev->isEndpoint = false; - isGateway = false; - } - } - - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const - { - 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); - uint8_t flag = 0; - if (isGateway) flag |= 0x80; - if (isEndpoint) flag |= 0x40; - 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); - auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) - { - if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) - EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); - else - 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 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 CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const; void EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const - { - memset (encrypted, 0, 512); // TODO: implement - } + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const; }; class TunnelConfig diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 2f44b814..534d5f5a 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -60,6 +60,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/TunnelEndpoint.cpp \ ../../libi2pd/TunnelGateway.cpp \ ../../libi2pd/TunnelPool.cpp \ + ../../libi2pd/TunnelConfig.cpp \ ../../libi2pd/util.cpp \ ../../libi2pd/Elligator.cpp \ ../../libi2pd/ECIESX25519AEADRatchetSession.cpp \ @@ -104,7 +105,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/CPU.h \ ../../libi2pd/Crypto.h \ ../../libi2pd/CryptoKey.h \ - ../../libi2pd/CryptoWorker.h \ ../../libi2pd/Datagram.h \ ../../libi2pd/Destination.h \ ../../libi2pd/Ed25519.h \ From b6175132eb84649dd98d84a8475d29a9cb9072e1 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 23 Oct 2020 21:41:42 +0800 Subject: [PATCH 0507/2950] android: fix for pre-init jni calls; processAssets moved to a logical place --- .../org/purplei2p/i2pd/DaemonSingleton.java | 181 -------- .../src/org/purplei2p/i2pd/DaemonWrapper.java | 387 ++++++++++++++++++ .../org/purplei2p/i2pd/ForegroundService.java | 98 +++-- .../src/org/purplei2p/i2pd/I2PDActivity.java | 236 +---------- 4 files changed, 466 insertions(+), 436 deletions(-) delete mode 100644 android/src/org/purplei2p/i2pd/DaemonSingleton.java create mode 100644 android/src/org/purplei2p/i2pd/DaemonWrapper.java diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java deleted file mode 100644 index e9e4fc06..00000000 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.purplei2p.i2pd; - -import java.util.HashSet; -import java.util.Set; -import android.os.Environment; -import android.util.Log; - -import org.purplei2p.i2pd.R; - -public class DaemonSingleton { - private static final String TAG = "i2pd"; - private static final DaemonSingleton instance = new DaemonSingleton(); - - public interface StateUpdateListener { - void daemonStateUpdate(); - } - - private final Set stateUpdateListeners = new HashSet<>(); - - public static DaemonSingleton getInstance() { - return instance; - } - - public synchronized void addStateChangeListener(StateUpdateListener listener) { - stateUpdateListeners.add(listener); - } - - public synchronized void removeStateChangeListener(StateUpdateListener listener) { - stateUpdateListeners.remove(listener); - } - - private synchronized void setState(State newState) { - if (newState == null) - throw new NullPointerException(); - - State oldState = state; - - if (oldState == null) - throw new NullPointerException(); - - if (oldState.equals(newState)) - return; - - state = newState; - fireStateUpdate1(); - } - - public synchronized void stopAcceptingTunnels() { - if (isStartedOkay()) { - setState(State.gracefulShutdownInProgress); - I2PD_JNI.stopAcceptingTunnels(); - } - } - - public synchronized void startAcceptingTunnels() { - if (isStartedOkay()) { - setState(State.startedOkay); - I2PD_JNI.startAcceptingTunnels(); - } - } - - public synchronized void reloadTunnelsConfigs() { - if (isStartedOkay()) { - I2PD_JNI.reloadTunnelsConfigs(); - } - } - - public synchronized int GetTransitTunnelsCount() { - return I2PD_JNI.GetTransitTunnelsCount(); - } - - private volatile boolean startedOkay; - - public enum State { - uninitialized(R.string.uninitialized), - starting(R.string.starting), - jniLibraryLoaded(R.string.jniLibraryLoaded), - startedOkay(R.string.startedOkay), - startFailed(R.string.startFailed), - gracefulShutdownInProgress(R.string.gracefulShutdownInProgress), - stopped(R.string.stopped); - - State(int statusStringResourceId) { - this.statusStringResourceId = statusStringResourceId; - } - - private final int statusStringResourceId; - - public int getStatusStringResourceId() { - return statusStringResourceId; - } - }; - - private volatile State state = State.uninitialized; - - public State getState() { - return state; - } - - { - setState(State.starting); - new Thread(new Runnable() { - - @Override - public void run() { - try { - I2PD_JNI.loadLibraries(); - setState(State.jniLibraryLoaded); - } catch (Throwable tr) { - lastThrowable = tr; - setState(State.startFailed); - return; - } - try { - synchronized (DaemonSingleton.this) { - I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd"); - daemonStartResult = I2PD_JNI.startDaemon(); - if ("ok".equals(daemonStartResult)) { - setState(State.startedOkay); - setStartedOkay(true); - } else - setState(State.startFailed); - } - } catch (Throwable tr) { - lastThrowable = tr; - setState(State.startFailed); - } - } - - }, "i2pdDaemonStart").start(); - } - - private Throwable lastThrowable; - private String daemonStartResult = "N/A"; - - private void fireStateUpdate1() { - Log.i(TAG, "daemon state change: " + state); - for (StateUpdateListener listener : stateUpdateListeners) { - try { - listener.daemonStateUpdate(); - } catch (Throwable tr) { - Log.e(TAG, "exception in listener ignored", tr); - } - } - } - - public Throwable getLastThrowable() { - return lastThrowable; - } - - public String getDaemonStartResult() { - return daemonStartResult; - } - - private final Object startedOkayLock = new Object(); - - public boolean isStartedOkay() { - synchronized (startedOkayLock) { - return startedOkay; - } - } - - private void setStartedOkay(boolean startedOkay) { - synchronized (startedOkayLock) { - this.startedOkay = startedOkay; - } - } - - public synchronized void stopDaemon() { - if (isStartedOkay()) { - try { - I2PD_JNI.stopDaemon(); - } catch(Throwable tr) { - Log.e(TAG, "", tr); - } - - setStartedOkay(false); - setState(State.stopped); - } - } -} diff --git a/android/src/org/purplei2p/i2pd/DaemonWrapper.java b/android/src/org/purplei2p/i2pd/DaemonWrapper.java new file mode 100644 index 00000000..7f9fcd93 --- /dev/null +++ b/android/src/org/purplei2p/i2pd/DaemonWrapper.java @@ -0,0 +1,387 @@ +package org.purplei2p.i2pd; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Set; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.AssetManager; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.os.Build; +import android.os.Environment; +import android.util.Log; + +import androidx.annotation.RequiresApi; + +public class DaemonWrapper { + private static final String TAG = "i2pd"; + private final AssetManager assetManager; + private final ConnectivityManager connectivityManager; + private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/"; + private boolean assetsCopied; + + public interface StateUpdateListener { + void daemonStateUpdate(); + } + + private final Set stateUpdateListeners = new HashSet<>(); + + public synchronized void addStateChangeListener(StateUpdateListener listener) { + stateUpdateListeners.add(listener); + } + + public synchronized void removeStateChangeListener(StateUpdateListener listener) { + stateUpdateListeners.remove(listener); + } + + private synchronized void setState(State newState) { + if (newState == null) + throw new NullPointerException(); + + State oldState = state; + + if (oldState == null) + throw new NullPointerException(); + + if (oldState.equals(newState)) + return; + + state = newState; + fireStateUpdate1(); + } + + public synchronized void stopAcceptingTunnels() { + if (isStartedOkay()) { + setState(State.gracefulShutdownInProgress); + I2PD_JNI.stopAcceptingTunnels(); + } + } + + public synchronized void startAcceptingTunnels() { + if (isStartedOkay()) { + setState(State.startedOkay); + I2PD_JNI.startAcceptingTunnels(); + } + } + + public synchronized void reloadTunnelsConfigs() { + if (isStartedOkay()) { + I2PD_JNI.reloadTunnelsConfigs(); + } + } + + public synchronized int GetTransitTunnelsCount() { + return I2PD_JNI.GetTransitTunnelsCount(); + } + + private volatile boolean startedOkay; + + public enum State { + uninitialized(R.string.uninitialized), + starting(R.string.starting), + jniLibraryLoaded(R.string.jniLibraryLoaded), + startedOkay(R.string.startedOkay), + startFailed(R.string.startFailed), + gracefulShutdownInProgress(R.string.gracefulShutdownInProgress), + stopped(R.string.stopped); + + State(int statusStringResourceId) { + this.statusStringResourceId = statusStringResourceId; + } + + private final int statusStringResourceId; + + public int getStatusStringResourceId() { + return statusStringResourceId; + } + }; + + private volatile State state = State.uninitialized; + + public State getState() { + return state; + } + + public DaemonWrapper(AssetManager assetManager, ConnectivityManager connectivityManager){ + this.assetManager = assetManager; + this.connectivityManager = connectivityManager; + setState(State.starting); + new Thread(() -> { + try { + processAssets(); + I2PD_JNI.loadLibraries(); + setState(State.jniLibraryLoaded); + registerNetworkCallback(); + } catch (Throwable tr) { + lastThrowable = tr; + setState(State.startFailed); + return; + } + try { + synchronized (DaemonWrapper.this) { + I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd"); + daemonStartResult = I2PD_JNI.startDaemon(); + if ("ok".equals(daemonStartResult)) { + setState(State.startedOkay); + setStartedOkay(true); + } else + setState(State.startFailed); + } + } catch (Throwable tr) { + lastThrowable = tr; + setState(State.startFailed); + } + }, "i2pdDaemonStart").start(); + } + + private Throwable lastThrowable; + private String daemonStartResult = "N/A"; + + private void fireStateUpdate1() { + Log.i(TAG, "daemon state change: " + state); + for (StateUpdateListener listener : stateUpdateListeners) { + try { + listener.daemonStateUpdate(); + } catch (Throwable tr) { + Log.e(TAG, "exception in listener ignored", tr); + } + } + } + + public Throwable getLastThrowable() { + return lastThrowable; + } + + public String getDaemonStartResult() { + return daemonStartResult; + } + + private final Object startedOkayLock = new Object(); + + public boolean isStartedOkay() { + synchronized (startedOkayLock) { + return startedOkay; + } + } + + private void setStartedOkay(boolean startedOkay) { + synchronized (startedOkayLock) { + this.startedOkay = startedOkay; + } + } + + public synchronized void stopDaemon() { + if (isStartedOkay()) { + try { + I2PD_JNI.stopDaemon(); + } catch(Throwable tr) { + Log.e(TAG, "", tr); + } + + setStartedOkay(false); + setState(State.stopped); + } + } + + private void processAssets() { + if (!assetsCopied) { + try { + assetsCopied = true; // prevent from running on every state update + + File holderFile = new File(i2pdpath, "assets.ready"); + String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX + StringBuilder text = new StringBuilder(); + + if (holderFile.exists()) { + try { // if holder file exists, read assets version string + FileReader fileReader = new FileReader(holderFile); + + try { + BufferedReader br = new BufferedReader(fileReader); + + try { + String line; + + while ((line = br.readLine()) != null) { + text.append(line); + } + }finally { + try { + br.close(); + } catch (IOException e) { + Log.e(TAG, "", e); + } + } + } finally { + try { + fileReader.close(); + } catch (IOException e) { + Log.e(TAG, "", e); + } + } + } catch (IOException e) { + Log.e(TAG, "", e); + } + } + + // if version differs from current app version or null, try to delete certificates folder + if (!text.toString().contains(versionName)) + try { + boolean deleteResult = holderFile.delete(); + if (!deleteResult) + Log.e(TAG, "holderFile.delete() returned " + deleteResult + ", absolute path='" + holderFile.getAbsolutePath() + "'"); + File certPath = new File(i2pdpath, "certificates"); + deleteRecursive(certPath); + } + catch (Throwable tr) { + Log.e(TAG, "", tr); + } + + // copy assets. If processed file exists, it won't be overwritten + copyAsset("addressbook"); + copyAsset("certificates"); + copyAsset("tunnels.d"); + copyAsset("i2pd.conf"); + copyAsset("subscriptions.txt"); + copyAsset("tunnels.conf"); + + // update holder file about successful copying + FileWriter writer = new FileWriter(holderFile); + try { + writer.append(versionName); + } finally { + try { + writer.close(); + } catch (IOException e) { + Log.e(TAG,"on writer close", e); + } + } + } + catch (Throwable tr) + { + Log.e(TAG,"on assets copying", tr); + } + } + } + + /** + * Copy the asset at the specified path to this app's data directory. If the + * asset is a directory, its contents are also copied. + * + * @param path + * Path to asset, relative to app's assets directory. + */ + private void copyAsset(String path) { + AssetManager manager = assetManager; + + // If we have a directory, we make it and recurse. If a file, we copy its + // contents. + try { + String[] contents = manager.list(path); + + // The documentation suggests that list throws an IOException, but doesn't + // say under what conditions. It'd be nice if it did so when the path was + // to a file. That doesn't appear to be the case. If the returned array is + // null or has 0 length, we assume the path is to a file. This means empty + // directories will get turned into files. + if (contents == null || contents.length == 0) { + copyFileAsset(path); + return; + } + + // Make the directory. + File dir = new File(i2pdpath, path); + boolean result = dir.mkdirs(); + Log.d(TAG, "dir.mkdirs() returned " + result); + + // Recurse on the contents. + for (String entry : contents) { + copyAsset(path + '/' + entry); + } + } catch (IOException e) { + Log.e(TAG, "ex ignored for path='" + path + "'", e); + } + } + + /** + * Copy the asset file specified by path to app's data directory. Assumes + * parent directories have already been created. + * + * @param path + * Path to asset, relative to app's assets directory. + */ + private void copyFileAsset(String path) { + File file = new File(i2pdpath, path); + if (!file.exists()) { + try { + try (InputStream in = assetManager.open(path)) { + try (OutputStream out = new FileOutputStream(file)) { + byte[] buffer = new byte[1024]; + int read = in.read(buffer); + while (read != -1) { + out.write(buffer, 0, read); + read = in.read(buffer); + } + } + } + } catch (IOException e) { + Log.e(TAG, "", e); + } + } + } + + private void deleteRecursive(File fileOrDirectory) { + if (fileOrDirectory.isDirectory()) { + File[] files = fileOrDirectory.listFiles(); + if (files != null) { + for (File child : files) { + deleteRecursive(child); + } + } + } + boolean deleteResult = fileOrDirectory.delete(); + if (!deleteResult) + Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'"); + } + + public void registerNetworkCallback(){ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) registerNetworkCallback0(); + } + + @TargetApi(Build.VERSION_CODES.M) + private void registerNetworkCallback0() { + NetworkRequest request = new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + .build(); + NetworkStateCallbackImpl networkCallback = new NetworkStateCallbackImpl(); + connectivityManager.registerNetworkCallback(request, networkCallback); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static final class NetworkStateCallbackImpl extends ConnectivityManager.NetworkCallback { + @Override + public void onAvailable(Network network) { + super.onAvailable(network); + I2PD_JNI.onNetworkStateChanged(true); + Log.i(TAG, "NetworkCallback.onAvailable"); + } + + @Override + public void onLost(Network network) { + super.onLost(network); + I2PD_JNI.onNetworkStateChanged(false); + Log.i(TAG, " NetworkCallback.onLost"); + } + } +} diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index c1b1cc26..c1c918ac 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -19,8 +19,12 @@ public class ForegroundService extends Service { private volatile boolean shown; - private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = - new DaemonSingleton.StateUpdateListener() { + private static ForegroundService instance; + + private static volatile DaemonWrapper daemon; + + private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = + new DaemonWrapper.StateUpdateListener() { @Override public void daemonStateUpdate() { @@ -40,7 +44,7 @@ public class ForegroundService extends Service { // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. - private int NOTIFICATION = 1; + private static final int NOTIFICATION = 1; /** * Class for clients to access. Because we know this service always @@ -53,16 +57,25 @@ public class ForegroundService extends Service { } } + public static void init(DaemonWrapper daemon) { + ForegroundService.daemon = daemon; + initCheck(); + } + + private static void initCheck() { + if(instance!=null && daemon!=null) instance.setListener(); + } + @Override public void onCreate() { notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); + instance = this; + initCheck(); + } - synchronized (this) { - DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener); - if (!shown) daemonStateUpdatedListener.daemonStateUpdate(); - } - // Tell the user we started. -// Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show(); + private void setListener() { + daemon.addStateChangeListener(daemonStateUpdatedListener); + if (!shown) daemonStateUpdatedListener.daemonStateUpdate(); } @Override @@ -73,8 +86,17 @@ public class ForegroundService extends Service { @Override public void onDestroy() { - DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener); cancelNotification(); + deinitCheck(); + instance=null; + } + + public static void deinit() { + deinitCheck(); + } + + private static void deinitCheck() { + if(daemon!=null && instance!=null)daemon.removeStateChangeListener(instance.daemonStateUpdatedListener); } private synchronized void cancelNotification() { @@ -101,35 +123,39 @@ public class ForegroundService extends Service { * Show a notification while this service is running. */ private synchronized void showNotification() { - // In this sample, we'll use the same text for the ticker and the expanded notification - CharSequence text = getText(DaemonSingleton.getInstance().getState().getStatusStringResourceId()); + if(daemon!=null) { + // In this sample, we'll use the same text for the ticker and the expanded notification + CharSequence text = getText(daemon.getState().getStatusStringResourceId()); - // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, I2PDActivity.class), 0); + // The PendingIntent to launch our activity if the user selects this notification + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, + new Intent(this, I2PDActivity.class), 0); - // If earlier version channel ID is not used - // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) - String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : ""; + // If earlier version channel ID is not used + // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) + String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : ""; - // Set the info for the views that show in the notification panel. - NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) - .setOngoing(true) - .setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon - if(Build.VERSION.SDK_INT >= 16) builder = builder.setPriority(Notification.PRIORITY_DEFAULT); - if(Build.VERSION.SDK_INT >= 21) builder = builder.setCategory(Notification.CATEGORY_SERVICE); - Notification notification = builder - .setTicker(text) // the status text - .setWhen(System.currentTimeMillis()) // the time stamp - .setContentTitle(getText(R.string.app_name)) // the label of the entry - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); + // Set the info for the views that show in the notification panel. + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) + .setOngoing(true) + .setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon + if (Build.VERSION.SDK_INT >= 16) + builder = builder.setPriority(Notification.PRIORITY_DEFAULT); + if (Build.VERSION.SDK_INT >= 21) + builder = builder.setCategory(Notification.CATEGORY_SERVICE); + Notification notification = builder + .setTicker(text) // the status text + .setWhen(System.currentTimeMillis()) // the time stamp + .setContentTitle(getText(R.string.app_name)) // the label of the entry + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked + .build(); - // Send the notification. - //mNM.notify(NOTIFICATION, notification); - startForeground(NOTIFICATION, notification); - shown = true; + // Send the notification. + //mNM.notify(NOTIFICATION, notification); + startForeground(NOTIFICATION, notification); + shown = true; + } } @RequiresApi(Build.VERSION_CODES.O) @@ -144,6 +170,4 @@ public class ForegroundService extends Service { else Log.e(TAG, "error: NOTIFICATION_SERVICE is null"); return channelId; } - - private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); } diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 777ca748..0801a655 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -1,13 +1,5 @@ package org.purplei2p.i2pd; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.BufferedReader; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Timer; @@ -24,7 +16,6 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; -import android.content.res.AssetManager; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.Network; @@ -33,7 +24,6 @@ import android.net.NetworkRequest; import android.net.Uri; import android.os.Bundle; import android.os.Build; -import android.os.Environment; import android.os.IBinder; import android.os.PowerManager; import android.preference.PreferenceManager; @@ -60,25 +50,19 @@ import android.webkit.WebViewClient; import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS; public class I2PDActivity extends Activity { - private WebView webView; - private static final String TAG = "i2pdActvt"; private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1; public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; public static final String PACKAGE_URI_SCHEME = "package:"; private TextView textView; - private boolean assetsCopied; - private NetworkStateCallback networkCallback; - private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/"; - //private ConfigParser parser = new ConfigParser(i2pdpath); // TODO: + //private ConfigParser parser = new ConfigParser(i2pdpath); // TODO - private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); + private static volatile DaemonWrapper daemon; - private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = new DaemonSingleton.StateUpdateListener() { + private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = new DaemonWrapper.StateUpdateListener() { @Override public void daemonStateUpdate() { - processAssets(); runOnUiThread(() -> { try { if (textView == null) @@ -88,9 +72,9 @@ public class I2PDActivity extends Activity { textView.setText(throwableToString(tr)); return; } - DaemonSingleton.State state = daemon.getState(); - String startResultStr = DaemonSingleton.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : ""; - String graceStr = DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : ""; + DaemonWrapper.State state = daemon.getState(); + String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : ""; + String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : ""; textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr)); } catch (Throwable tr) { Log.e(TAG,"error ignored",tr); @@ -117,6 +101,12 @@ public class I2PDActivity extends Activity { Log.i(TAG, "onCreate"); super.onCreate(savedInstanceState); + if (daemon==null) { + ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + daemon = new DaemonWrapper(getAssets(), connectivityManager); + } + ForegroundService.init(daemon); + textView = new TextView(this); setContentView(textView); daemon.addStateChangeListener(daemonStateUpdatedListener); @@ -145,15 +135,13 @@ public class I2PDActivity extends Activity { openBatteryOptimizationDialogIfNeeded(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - registerNetworkCallback(); - } } @Override protected void onDestroy() { super.onDestroy(); textView = null; + ForegroundService.deinit(); daemon.removeStateChangeListener(daemonStateUpdatedListener); //cancelGracefulStop0(); try { @@ -289,13 +277,13 @@ public class I2PDActivity extends Activity { case R.id.action_start_webview: setContentView(R.layout.webview); - this.webView = (WebView) findViewById(R.id.webview1); - this.webView.setWebViewClient(new WebViewClient()); + final WebView webView = findViewById(R.id.webview1); + webView.setWebViewClient(new WebViewClient()); - WebSettings webSettings = this.webView.getSettings(); + final WebSettings webSettings = webView.getSettings(); webSettings.setBuiltInZoomControls(true); webSettings.setJavaScriptEnabled(false); - this.webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort + webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort break; } @@ -335,7 +323,7 @@ public class I2PDActivity extends Activity { private static volatile Timer gracefulQuitTimer; private void i2pdGracefulStop() { - if (daemon.getState() == DaemonSingleton.State.stopped) { + if (daemon.getState() == DaemonWrapper.State.stopped) { Toast.makeText(this, R.string.already_stopped, Toast.LENGTH_SHORT).show(); return; } @@ -427,167 +415,6 @@ public class I2PDActivity extends Activity { }); } - /** - * Copy the asset at the specified path to this app's data directory. If the - * asset is a directory, its contents are also copied. - * - * @param path - * Path to asset, relative to app's assets directory. - */ - private void copyAsset(String path) { - AssetManager manager = getAssets(); - - // If we have a directory, we make it and recurse. If a file, we copy its - // contents. - try { - String[] contents = manager.list(path); - - // The documentation suggests that list throws an IOException, but doesn't - // say under what conditions. It'd be nice if it did so when the path was - // to a file. That doesn't appear to be the case. If the returned array is - // null or has 0 length, we assume the path is to a file. This means empty - // directories will get turned into files. - if (contents == null || contents.length == 0) { - copyFileAsset(path); - return; - } - - // Make the directory. - File dir = new File(i2pdpath, path); - boolean result = dir.mkdirs(); - Log.d(TAG, "dir.mkdirs() returned " + result); - - // Recurse on the contents. - for (String entry : contents) { - copyAsset(path + '/' + entry); - } - } catch (IOException e) { - Log.e(TAG, "ex ignored for path='" + path + "'", e); - } - } - - /** - * Copy the asset file specified by path to app's data directory. Assumes - * parent directories have already been created. - * - * @param path - * Path to asset, relative to app's assets directory. - */ - private void copyFileAsset(String path) { - File file = new File(i2pdpath, path); - if (!file.exists()) { - try { - try (InputStream in = getAssets().open(path)) { - try (OutputStream out = new FileOutputStream(file)) { - byte[] buffer = new byte[1024]; - int read = in.read(buffer); - while (read != -1) { - out.write(buffer, 0, read); - read = in.read(buffer); - } - } - } - } catch (IOException e) { - Log.e(TAG, "", e); - } - } - } - - private void deleteRecursive(File fileOrDirectory) { - if (fileOrDirectory.isDirectory()) { - File[] files = fileOrDirectory.listFiles(); - if (files != null) { - for (File child : files) { - deleteRecursive(child); - } - } - } - boolean deleteResult = fileOrDirectory.delete(); - if (!deleteResult) - Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'"); - } - - private void processAssets() { - if (!assetsCopied) { - try { - assetsCopied = true; // prevent from running on every state update - - File holderFile = new File(i2pdpath, "assets.ready"); - String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX - StringBuilder text = new StringBuilder(); - - if (holderFile.exists()) { - try { // if holder file exists, read assets version string - FileReader fileReader = new FileReader(holderFile); - - try { - BufferedReader br = new BufferedReader(fileReader); - - try { - String line; - - while ((line = br.readLine()) != null) { - text.append(line); - } - }finally { - try { - br.close(); - } catch (IOException e) { - Log.e(TAG, "", e); - } - } - } finally { - try { - fileReader.close(); - } catch (IOException e) { - Log.e(TAG, "", e); - } - } - } catch (IOException e) { - Log.e(TAG, "", e); - } - } - - // if version differs from current app version or null, try to delete certificates folder - if (!text.toString().contains(versionName)) - try { - boolean deleteResult = holderFile.delete(); - if (!deleteResult) - Log.e(TAG, "holderFile.delete() returned " + deleteResult + ", absolute path='" + holderFile.getAbsolutePath() + "'"); - File certPath = new File(i2pdpath, "certificates"); - deleteRecursive(certPath); - } - catch (Throwable tr) { - Log.e(TAG, "", tr); - } - - // copy assets. If processed file exists, it won't be overwritten - copyAsset("addressbook"); - copyAsset("certificates"); - copyAsset("tunnels.d"); - copyAsset("i2pd.conf"); - copyAsset("subscriptions.txt"); - copyAsset("tunnels.conf"); - - // update holder file about successful copying - FileWriter writer = new FileWriter(holderFile); - try { - writer.append(versionName); - } finally { - try { - writer.close(); - } catch (IOException e) { - Log.e(TAG,"on writer close", e); - } - } - } - catch (Throwable tr) - { - Log.e(TAG,"on assets copying", tr); - } - } - } - @SuppressLint("BatteryLife") private void openBatteryOptimizationDialogIfNeeded() { boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true); @@ -642,33 +469,6 @@ public class I2PDActivity extends Activity { return "show_battery_optimization" + (device == null ? "" : device); } - @TargetApi(Build.VERSION_CODES.M) - private void registerNetworkCallback() { - ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkRequest request = new NetworkRequest.Builder() - .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) - .build(); - networkCallback = new NetworkStateCallback(); - connectivityManager.registerNetworkCallback(request, networkCallback); - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private final class NetworkStateCallback extends ConnectivityManager.NetworkCallback { - @Override - public void onAvailable(Network network) { - super.onAvailable(network); - I2PD_JNI.onNetworkStateChanged(true); - Log.i(TAG, "NetworkCallback.onAvailable"); - } - - @Override - public void onLost(Network network) { - super.onLost(network); - I2PD_JNI.onNetworkStateChanged(false); - Log.i(TAG, " NetworkCallback.onLost"); - } - } - private void quit() { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { From db3e48a81a87c8ce70e727f815c011c7a3f62d52 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 24 Oct 2020 03:52:53 +0800 Subject: [PATCH 0508/2950] android: more logical daemon state changes --- .../src/org/purplei2p/i2pd/DaemonWrapper.java | 41 +++---- .../org/purplei2p/i2pd/ForegroundService.java | 111 ++++++++++-------- .../src/org/purplei2p/i2pd/I2PDActivity.java | 53 +++++---- 3 files changed, 104 insertions(+), 101 deletions(-) diff --git a/android/src/org/purplei2p/i2pd/DaemonWrapper.java b/android/src/org/purplei2p/i2pd/DaemonWrapper.java index 7f9fcd93..414a3ed1 100644 --- a/android/src/org/purplei2p/i2pd/DaemonWrapper.java +++ b/android/src/org/purplei2p/i2pd/DaemonWrapper.java @@ -12,7 +12,6 @@ import java.util.HashSet; import java.util.Set; import android.annotation.TargetApi; -import android.content.Context; import android.content.res.AssetManager; import android.net.ConnectivityManager; import android.net.Network; @@ -32,7 +31,7 @@ public class DaemonWrapper { private boolean assetsCopied; public interface StateUpdateListener { - void daemonStateUpdate(); + void daemonStateUpdate(State oldValue, State newValue); } private final Set stateUpdateListeners = new HashSet<>(); @@ -58,7 +57,7 @@ public class DaemonWrapper { return; state = newState; - fireStateUpdate1(); + fireStateUpdate1(oldState, newState); } public synchronized void stopAcceptingTunnels() { @@ -81,12 +80,10 @@ public class DaemonWrapper { } } - public synchronized int GetTransitTunnelsCount() { + public int getTransitTunnelsCount() { return I2PD_JNI.GetTransitTunnelsCount(); } - private volatile boolean startedOkay; - public enum State { uninitialized(R.string.uninitialized), starting(R.string.starting), @@ -105,7 +102,11 @@ public class DaemonWrapper { public int getStatusStringResourceId() { return statusStringResourceId; } - }; + + public boolean isStartedOkay() { + return equals(State.startedOkay) || equals(State.gracefulShutdownInProgress); + } + } private volatile State state = State.uninitialized; @@ -134,7 +135,6 @@ public class DaemonWrapper { daemonStartResult = I2PD_JNI.startDaemon(); if ("ok".equals(daemonStartResult)) { setState(State.startedOkay); - setStartedOkay(true); } else setState(State.startFailed); } @@ -148,11 +148,11 @@ public class DaemonWrapper { private Throwable lastThrowable; private String daemonStartResult = "N/A"; - private void fireStateUpdate1() { + private void fireStateUpdate1(State oldValue, State newValue) { Log.i(TAG, "daemon state change: " + state); for (StateUpdateListener listener : stateUpdateListeners) { try { - listener.daemonStateUpdate(); + listener.daemonStateUpdate(oldValue, newValue); } catch (Throwable tr) { Log.e(TAG, "exception in listener ignored", tr); } @@ -167,18 +167,8 @@ public class DaemonWrapper { return daemonStartResult; } - private final Object startedOkayLock = new Object(); - public boolean isStartedOkay() { - synchronized (startedOkayLock) { - return startedOkay; - } - } - - private void setStartedOkay(boolean startedOkay) { - synchronized (startedOkayLock) { - this.startedOkay = startedOkay; - } + return getState().isStartedOkay(); } public synchronized void stopDaemon() { @@ -189,7 +179,6 @@ public class DaemonWrapper { Log.e(TAG, "", tr); } - setStartedOkay(false); setState(State.stopped); } } @@ -197,7 +186,7 @@ public class DaemonWrapper { private void processAssets() { if (!assetsCopied) { try { - assetsCopied = true; // prevent from running on every state update + assetsCopied = true; File holderFile = new File(i2pdpath, "assets.ready"); String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX @@ -283,12 +272,10 @@ public class DaemonWrapper { * Path to asset, relative to app's assets directory. */ private void copyAsset(String path) { - AssetManager manager = assetManager; - // If we have a directory, we make it and recurse. If a file, we copy its // contents. try { - String[] contents = manager.list(path); + String[] contents = assetManager.list(path); // The documentation suggests that list throws an IOException, but doesn't // say under what conditions. It'd be nice if it did so when the path was @@ -355,7 +342,7 @@ public class DaemonWrapper { Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'"); } - public void registerNetworkCallback(){ + private void registerNetworkCallback(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) registerNetworkCallback0(); } diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index c1c918ac..c97b7f1f 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -23,22 +23,28 @@ public class ForegroundService extends Service { private static volatile DaemonWrapper daemon; + private static final Object initDeinitLock = new Object(); + private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = new DaemonWrapper.StateUpdateListener() { @Override - public void daemonStateUpdate() { - try { - synchronized (ForegroundService.this) { - if (shown) cancelNotification(); - showNotification(); - } - } catch (Throwable tr) { - Log.e(TAG,"error ignored",tr); - } + public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) { + updateNotificationText(); } }; + private void updateNotificationText() { + try { + synchronized (initDeinitLock) { + if (shown) cancelNotification(); + showNotification(); + } + } catch (Throwable tr) { + Log.e(TAG,"error ignored",tr); + } + } + private NotificationManager notificationManager; @@ -63,7 +69,9 @@ public class ForegroundService extends Service { } private static void initCheck() { - if(instance!=null && daemon!=null) instance.setListener(); + synchronized (initDeinitLock) { + if (instance != null && daemon != null) instance.setListener(); + } } @Override @@ -75,7 +83,7 @@ public class ForegroundService extends Service { private void setListener() { daemon.addStateChangeListener(daemonStateUpdatedListener); - if (!shown) daemonStateUpdatedListener.daemonStateUpdate(); + updateNotificationText(); } @Override @@ -96,18 +104,23 @@ public class ForegroundService extends Service { } private static void deinitCheck() { - if(daemon!=null && instance!=null)daemon.removeStateChangeListener(instance.daemonStateUpdatedListener); + synchronized (initDeinitLock) { + if (daemon != null && instance != null) + daemon.removeStateChangeListener(instance.daemonStateUpdatedListener); + } } - private synchronized void cancelNotification() { - // Cancel the persistent notification. - notificationManager.cancel(NOTIFICATION); + private void cancelNotification() { + synchronized (initDeinitLock) { + // Cancel the persistent notification. + notificationManager.cancel(NOTIFICATION); - stopForeground(true); + stopForeground(true); - // Tell the user we stopped. - //Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show(); - shown=false; + // Tell the user we stopped. + //Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show(); + shown = false; + } } @Override @@ -122,39 +135,41 @@ public class ForegroundService extends Service { /** * Show a notification while this service is running. */ - private synchronized void showNotification() { - if(daemon!=null) { - // In this sample, we'll use the same text for the ticker and the expanded notification - CharSequence text = getText(daemon.getState().getStatusStringResourceId()); + private void showNotification() { + synchronized (initDeinitLock) { + if (daemon != null) { + // In this sample, we'll use the same text for the ticker and the expanded notification + CharSequence text = getText(daemon.getState().getStatusStringResourceId()); - // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, I2PDActivity.class), 0); + // The PendingIntent to launch our activity if the user selects this notification + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, + new Intent(this, I2PDActivity.class), 0); - // If earlier version channel ID is not used - // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) - String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : ""; + // If earlier version channel ID is not used + // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) + String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : ""; - // Set the info for the views that show in the notification panel. - NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) - .setOngoing(true) - .setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon - if (Build.VERSION.SDK_INT >= 16) - builder = builder.setPriority(Notification.PRIORITY_DEFAULT); - if (Build.VERSION.SDK_INT >= 21) - builder = builder.setCategory(Notification.CATEGORY_SERVICE); - Notification notification = builder - .setTicker(text) // the status text - .setWhen(System.currentTimeMillis()) // the time stamp - .setContentTitle(getText(R.string.app_name)) // the label of the entry - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); + // Set the info for the views that show in the notification panel. + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) + .setOngoing(true) + .setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon + if (Build.VERSION.SDK_INT >= 16) + builder = builder.setPriority(Notification.PRIORITY_DEFAULT); + if (Build.VERSION.SDK_INT >= 21) + builder = builder.setCategory(Notification.CATEGORY_SERVICE); + Notification notification = builder + .setTicker(text) // the status text + .setWhen(System.currentTimeMillis()) // the time stamp + .setContentTitle(getText(R.string.app_name)) // the label of the entry + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked + .build(); - // Send the notification. - //mNM.notify(NOTIFICATION, notification); - startForeground(NOTIFICATION, notification); - shown = true; + // Send the notification. + //mNM.notify(NOTIFICATION, notification); + startForeground(NOTIFICATION, notification); + shown = true; + } } } diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 0801a655..97870e63 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -7,7 +7,6 @@ import java.util.TimerTask; import android.Manifest; import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.ActivityNotFoundException; @@ -18,9 +17,6 @@ import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; import android.net.Uri; import android.os.Bundle; import android.os.Build; @@ -36,7 +32,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; @@ -62,26 +57,31 @@ public class I2PDActivity extends Activity { private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = new DaemonWrapper.StateUpdateListener() { @Override - public void daemonStateUpdate() { - runOnUiThread(() -> { - try { - if (textView == null) - return; - Throwable tr = daemon.getLastThrowable(); - if (tr!=null) { - textView.setText(throwableToString(tr)); - return; - } - DaemonWrapper.State state = daemon.getState(); - String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : ""; - String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : ""; - textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr)); - } catch (Throwable tr) { - Log.e(TAG,"error ignored",tr); - } - }); + public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) { + updateStatusText(); } }; + + private void updateStatusText() { + runOnUiThread(() -> { + try { + if (textView == null) + return; + Throwable tr = daemon.getLastThrowable(); + if (tr!=null) { + textView.setText(throwableToString(tr)); + return; + } + DaemonWrapper.State state = daemon.getState(); + String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : ""; + String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : ""; + textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr)); + } catch (Throwable tr) { + Log.e(TAG,"error ignored",tr); + } + }); + } + private static volatile long graceStartedMillis; private static final Object graceStartedMillis_LOCK = new Object(); private Menu optionsMenu; @@ -110,7 +110,7 @@ public class I2PDActivity extends Activity { textView = new TextView(this); setContentView(textView); daemon.addStateChangeListener(daemonStateUpdatedListener); - daemonStateUpdatedListener.daemonStateUpdate(); + daemonStateUpdatedListener.daemonStateUpdate(DaemonWrapper.State.uninitialized, daemon.getState()); // request permissions if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { @@ -372,9 +372,10 @@ public class I2PDActivity extends Activity { if (gracefulQuitTimerOld != null) gracefulQuitTimerOld.cancel(); - if(daemon.GetTransitTunnelsCount() <= 0) { // no tunnels left + if(daemon.getTransitTunnelsCount() <= 0) { // no tunnels left Log.d(TAG, "no transit tunnels left, stopping"); i2pdStop(); + return; } final Timer gracefulQuitTimer = new Timer(true); @@ -390,7 +391,7 @@ public class I2PDActivity extends Activity { final TimerTask tickerTask = new TimerTask() { @Override public void run() { - daemonStateUpdatedListener.daemonStateUpdate(); + updateStatusText(); } }; gracefulQuitTimer.scheduleAtFixedRate(tickerTask, 0/*start delay*/, 1000/*millis period*/); From c93ee0d65d9dfa8318b8919d00b2b7f8adf34fe1 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Oct 2020 15:53:22 -0400 Subject: [PATCH 0509/2950] tunnels through ECIES routers --- libi2pd/I2NPProtocol.h | 19 +++++++++ libi2pd/Timestamp.cpp | 33 ++++++++++----- libi2pd/Timestamp.h | 3 +- libi2pd/Tunnel.cpp | 22 ++++++++-- libi2pd/TunnelConfig.cpp | 88 +++++++++++++++++++++++++++++++--------- libi2pd/TunnelConfig.h | 11 +++-- 6 files changed, 137 insertions(+), 39 deletions(-) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index fe5ca968..03f0f439 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -81,6 +81,25 @@ namespace i2p 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; + const size_t ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET = ECIES_BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET + 4; + const size_t ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET + 32; + const size_t ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET + 32; + const size_t ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET = ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET + 32; + const size_t ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET = ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET + 32; + const size_t ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET = ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET + 16; + const size_t ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET = ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET + 1; + const size_t ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET = ECIES_BUILD_REQUEST_RECORD_MORE_FLAGS_OFFSET + 3; + const size_t ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET = ECIES_BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET + 4; + const size_t ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET = ECIES_BUILD_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET + 4; + const size_t ECIES_BUILD_REQUEST_RECORD_PADDING_OFFSET = ECIES_BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET + 4; + const size_t ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 464; + + // ECIES BuildResponseRecord + const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511; + enum I2NPMessageType { eI2NPDummyMsg = 0, diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 4362a878..45684333 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -35,18 +35,24 @@ namespace util std::chrono::system_clock::now().time_since_epoch()).count (); } - static uint32_t GetLocalHoursSinceEpoch () - { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count (); - } - static uint64_t GetLocalSecondsSinceEpoch () { return std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count (); } + static uint32_t GetLocalMinutesSinceEpoch () + { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count (); + } + + static uint32_t GetLocalHoursSinceEpoch () + { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count (); + } + static int64_t g_TimeOffset = 0; // in seconds static void SyncTimeWithNTP (const std::string& address) @@ -178,14 +184,19 @@ namespace util return GetLocalMillisecondsSinceEpoch () + g_TimeOffset*1000; } - uint32_t GetHoursSinceEpoch () - { - return GetLocalHoursSinceEpoch () + g_TimeOffset/3600; - } - uint64_t GetSecondsSinceEpoch () { return GetLocalSecondsSinceEpoch () + g_TimeOffset; + } + + uint32_t GetMinutesSinceEpoch () + { + return GetLocalMinutesSinceEpoch () + g_TimeOffset/60; + } + + uint32_t GetHoursSinceEpoch () + { + return GetLocalHoursSinceEpoch () + g_TimeOffset/3600; } void GetCurrentDate (char * date) diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index 91175a49..b46f423d 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -20,8 +20,9 @@ namespace i2p namespace util { uint64_t GetMillisecondsSinceEpoch (); - uint32_t GetHoursSinceEpoch (); uint64_t GetSecondsSinceEpoch (); + uint32_t GetMinutesSinceEpoch (); + uint32_t GetHoursSinceEpoch (); void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index c91d0215..bfe466e3 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -111,7 +111,7 @@ namespace tunnel while (hop) { decryption.SetKey (hop->replyKey); - // decrypt records before and including current hop + // decrypt records before and current hop TunnelHopConfig * hop1 = hop; while (hop1) { @@ -119,8 +119,22 @@ namespace tunnel 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); + if (hop1 == hop && hop1->IsECIES ()) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16, + hop->h, 32, hop->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); + } } else LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range"); @@ -134,7 +148,7 @@ namespace tunnel while (hop) { const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE; - uint8_t ret = record[BUILD_RESPONSE_RECORD_RET_OFFSET]; + uint8_t ret = record[hop->IsECIES () ? ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET : BUILD_RESPONSE_RECORD_RET_OFFSET]; 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 3b7955d4..00f2a091 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include "Crypto.h" +#include "Log.h" #include "Transports.h" #include "Timestamp.h" #include "I2PEndian.h" @@ -76,39 +79,86 @@ namespace tunnel } } - void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const + void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) { - 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); uint8_t flag = 0; if (isGateway) flag |= 0x80; if (isEndpoint) flag |= 0x40; - 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); auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) + if (IsECIES ()) { - if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + 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, i2p::util::GetSecondsSinceEpoch () + 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 + } + 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); } memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const + const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { - memset (encrypted, 0, 512); // TODO: implement + static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars + memcpy (ck, protocolName, 32); // ck = h = protocol_name || 0 + SHA256 (ck, 32, h); // h = SHA256(h); + uint8_t hepk[32]; + encryptor->Encrypt (nullptr, hepk, nullptr, false); + MixHash (hepk, 32); + auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); + memcpy (encrypted, ephemeralKeys->GetPublicKey (), 32); encrypted += 32; + uint8_t sharedSecret[32]; + ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk) + uint8_t keydata[64]; + i2p::crypto::HKDF (ck, sharedSecret, 32, "", keydata); + memcpy (ck, keydata, 32); + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, h, 32, + keydata + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 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) } + + void TunnelHopConfig::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, h, 32); + SHA256_Update (&ctx, buf, len); + SHA256_Final (h, &ctx); + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 24e6f836..0e757071 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -30,17 +30,20 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - + uint8_t ck[32], h[32]; // for ECIES + TunnelHopConfig (std::shared_ptr r); - + 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 CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const; + bool IsECIES () const { return ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; }; + 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) const; + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); + void MixHash (const uint8_t * buf, size_t len); }; class TunnelConfig From ef5495bfb2626a42c7d4dce870c03afe18c42430 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 23 Oct 2020 22:14:00 -0400 Subject: [PATCH 0510/2950] padding for x25519 crypto key --- libi2pd/Identity.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index b2b5f2b4..490b8692 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -48,7 +48,13 @@ namespace data IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType) { - memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of + if (cryptoType == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + { + memcpy (m_StandardIdentity.publicKey, publicKey, 32); + RAND_bytes (m_StandardIdentity.publicKey, 224); + } + else + memcpy (m_StandardIdentity.publicKey, publicKey, 256); if (type != SIGNING_KEY_TYPE_DSA_SHA1) { size_t excessLen = 0; From bfcf3cfbf132ff904bcfca6557da061db4090bd5 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 24 Oct 2020 12:40:22 +0800 Subject: [PATCH 0511/2950] Fixes #1563 --- android/AndroidManifest.xml | 11 ++--- android/build.gradle | 4 +- .../{webview.xml => activity_web_console.xml} | 4 +- .../src/org/purplei2p/i2pd/I2PDActivity.java | 11 +---- .../purplei2p/i2pd/WebConsoleActivity.java | 41 +++++++++++++++++++ 5 files changed, 55 insertions(+), 16 deletions(-) rename android/res/layout/{webview.xml => activity_web_console.xml} (82%) create mode 100644 android/src/org/purplei2p/i2pd/WebConsoleActivity.java diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 88985138..8b011b8e 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -15,10 +15,10 @@ android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" - android:theme="@android:style/Theme.Holo.Light.DarkActionBar" android:requestLegacyExternalStorage="true" - android:usesCleartextTraffic="true" - > + android:theme="@android:style/Theme.Holo.Light.DarkActionBar" + android:usesCleartextTraffic="true"> + @@ -31,10 +31,10 @@ android:label="@string/app_name"> + - @@ -52,4 +52,5 @@ android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" /> - + + \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index ace2047a..7d25e28b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,6 +21,8 @@ repositories { dependencies { implementation 'androidx.core:core:1.0.2' + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' } android { @@ -90,7 +92,7 @@ android { } } -ext.abiCodes = ['armeabi-v7a':1, 'x86':2, 'arm64-v8a':3, 'x86_64':4] +ext.abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'arm64-v8a': 3, 'x86_64': 4] import com.android.build.OutputFile android.applicationVariants.all { variant -> diff --git a/android/res/layout/webview.xml b/android/res/layout/activity_web_console.xml similarity index 82% rename from android/res/layout/webview.xml rename to android/res/layout/activity_web_console.xml index 887896a7..5724b387 100644 --- a/android/res/layout/webview.xml +++ b/android/res/layout/activity_web_console.xml @@ -1,12 +1,14 @@ + + tools:context=".WebConsoleActivity"> + diff --git a/android/src/org/purplei2p/i2pd/I2PDActivity.java b/android/src/org/purplei2p/i2pd/I2PDActivity.java index 97870e63..9645d4f7 100755 --- a/android/src/org/purplei2p/i2pd/I2PDActivity.java +++ b/android/src/org/purplei2p/i2pd/I2PDActivity.java @@ -276,15 +276,8 @@ public class I2PDActivity extends Activity { return true; case R.id.action_start_webview: - setContentView(R.layout.webview); - final WebView webView = findViewById(R.id.webview1); - webView.setWebViewClient(new WebViewClient()); - - final WebSettings webSettings = webView.getSettings(); - webSettings.setBuiltInZoomControls(true); - webSettings.setJavaScriptEnabled(false); - webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort - break; + startActivity(new Intent(getApplicationContext(), WebConsoleActivity.class)); + return true; } return super.onOptionsItemSelected(item); diff --git a/android/src/org/purplei2p/i2pd/WebConsoleActivity.java b/android/src/org/purplei2p/i2pd/WebConsoleActivity.java new file mode 100644 index 00000000..24e6baeb --- /dev/null +++ b/android/src/org/purplei2p/i2pd/WebConsoleActivity.java @@ -0,0 +1,41 @@ +package org.purplei2p.i2pd; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.Activity; +import android.os.Bundle; +import android.view.MenuItem; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import java.util.Objects; + +public class WebConsoleActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_web_console); + + Objects.requireNonNull(getActionBar()).setDisplayHomeAsUpEnabled(true); + + final WebView webView = findViewById(R.id.webview1); + webView.setWebViewClient(new WebViewClient()); + + final WebSettings webSettings = webView.getSettings(); + webSettings.setBuiltInZoomControls(true); + webSettings.setJavaScriptEnabled(false); + webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort + } + + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + + if (id==android.R.id.home) { + finish(); + return true; + } + return false; + } +} From 21d99e355c2c70c2195985393ec81e81a200d6be Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 24 Oct 2020 15:48:56 -0400 Subject: [PATCH 0512/2950] MixHash(sepk) added --- libi2pd/TunnelConfig.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 00f2a091..5c2cbd53 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -98,7 +98,7 @@ namespace tunnel 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, i2p::util::GetSecondsSinceEpoch () + 600); // 10 minutes + 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) @@ -133,9 +133,11 @@ namespace tunnel SHA256 (ck, 32, h); // h = SHA256(h); uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); - MixHash (hepk, 32); + MixHash (hepk, 32); // h = SHA256(h || hepk) auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); - memcpy (encrypted, ephemeralKeys->GetPublicKey (), 32); encrypted += 32; + 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) uint8_t keydata[64]; From e9f11e204e02314c455da391940d33a2834e7be2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 24 Oct 2020 21:22:48 -0400 Subject: [PATCH 0513/2950] check if session is terminated before send --- libi2pd_client/I2CP.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 80274d86..d5436936 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -806,17 +806,23 @@ namespace client void I2CPSession::SendMessagePayloadMessage (const uint8_t * payload, size_t len) { // we don't use SendI2CPMessage to eliminate additional copy - auto l = len + 10 + I2CP_HEADER_SIZE; - uint8_t * buf = new uint8_t[l]; - htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); - buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; - htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); - htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); - htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); - memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); - boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + auto socket = m_Socket; + if (socket) + { + auto l = len + 10 + I2CP_HEADER_SIZE; + uint8_t * buf = new uint8_t[l]; + htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); + buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; + htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); + htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); + htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); + memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); + boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), + std::placeholders::_1, std::placeholders::_2, buf)); + } + else + LogPrint (eLogError, "I2CP: Can't write to the socket"); } I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread): From b35f43d79e48116e18931c994a416497e3107924 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 25 Oct 2020 17:20:15 -0400 Subject: [PATCH 0514/2950] initial implementation of STREAM FORWARD --- libi2pd_client/SAM.cpp | 92 ++++++++++++++++++++++++++++++++++++++---- libi2pd_client/SAM.h | 9 ++++- 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 63b9c7ed..2bdbf1ee 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -54,6 +54,7 @@ namespace client break; } case eSAMSocketTypeAcceptor: + case eSAMSocketTypeForward: { if (Session) { @@ -263,6 +264,8 @@ namespace client ProcessStreamConnect (separator + 1, bytes_transferred - (separator - m_Buffer) - 1, bytes_transferred - (eol - m_Buffer) - 1); else if (!strcmp (m_Buffer, SAM_STREAM_ACCEPT)) ProcessStreamAccept (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); + else if (!strcmp (m_Buffer, SAM_STREAM_FORWARD)) + ProcessStreamForward (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); else if (!strcmp (m_Buffer, SAM_DEST_GENERATE)) ProcessDestGenerate (separator + 1, bytes_transferred - (separator - m_Buffer) - 1); else if (!strcmp (m_Buffer, SAM_NAMING_LOOKUP)) @@ -358,12 +361,12 @@ namespace client std::shared_ptr forward = nullptr; if ((type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) && - params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end()) + params.find(SAM_PARAM_HOST) != params.end() && params.find(SAM_PARAM_PORT) != params.end()) { // udp forward selected boost::system::error_code e; // TODO: support hostnames in udp forward - auto addr = boost::asio::ip::address::from_string(params[SAM_VALUE_HOST], e); + auto addr = boost::asio::ip::address::from_string(params[SAM_PARAM_HOST], e); if (e) { // not an ip address @@ -371,7 +374,7 @@ namespace client return; } - auto port = std::stoi(params[SAM_VALUE_PORT]); + auto port = std::stoi(params[SAM_PARAM_PORT]); if (port == -1) { SendI2PError("Invalid port"); @@ -565,6 +568,51 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } + void SAMSocket::ProcessStreamForward (char * buf, size_t len) + { + LogPrint (eLogDebug, "SAM: stream forward: ", buf); + std::map params; + ExtractParams (buf, params); + std::string& id = params[SAM_PARAM_ID]; + auto session = m_Owner.FindSession (id); + if (!session) + { + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); + return; + } + if (session->localDestination->IsAcceptingStreams ()) + { + SendI2PError ("Already accepting"); + return; + } + auto it = params.find (SAM_PARAM_PORT); + if (it == params.end ()) + { + SendI2PError ("PORT is missing"); + return; + } + auto port = std::stoi (it->second); + if (port <= 0 || port >= 0xFFFF) + { + SendI2PError ("Invalid PORT"); + return; + } + boost::system::error_code ec; + auto ep = m_Socket.remote_endpoint (ec); + if (ec) + { + SendI2PError ("Socket error"); + return; + } + ep.port (port); + m_SocketType = eSAMSocketTypeForward; + m_ID = id; + m_IsAccepting = true; + session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PForward, + shared_from_this (), std::placeholders::_1, ep)); + SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + } + size_t SAMSocket::ProcessDatagramSend (char * buf, size_t len, const char * data) { LogPrint (eLogDebug, "SAM: datagram send: ", buf, " ", len); @@ -917,6 +965,33 @@ namespace client LogPrint (eLogWarning, "SAM: I2P acceptor has been reset"); } + void SAMSocket::HandleI2PForward (std::shared_ptr stream, + boost::asio::ip::tcp::endpoint ep) + { + if (stream) + { + LogPrint (eLogDebug, "SAM: incoming forward I2P connection for session ", m_ID); + auto newSocket = std::make_shared(m_Owner); + newSocket->SetSocketType (eSAMSocketTypeStream); + auto s = shared_from_this (); + newSocket->GetSocket ().async_connect (ep, + [s, newSocket, stream](const boost::system::error_code& ecode) + { + if (!ecode) + { + s->m_Owner.AddSocket (newSocket); + newSocket->Receive (); + newSocket->m_Stream = stream; + newSocket->I2PReceive (); + } + else + stream->AsyncClose (); + }); + } + else + LogPrint (eLogWarning, "SAM: I2P forward acceptor has been reset"); + } + void SAMSocket::HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) { LogPrint (eLogDebug, "SAM: datagram received ", len); @@ -1072,6 +1147,12 @@ namespace client std::placeholders::_1, newSocket)); } + void SAMBridge::AddSocket(std::shared_ptr socket) + { + std::unique_lock lock(m_OpenSocketsMutex); + m_OpenSockets.push_back(socket); + } + void SAMBridge::RemoveSocket(const std::shared_ptr & socket) { std::unique_lock lock(m_OpenSocketsMutex); @@ -1087,10 +1168,7 @@ namespace client if (!ec) { LogPrint (eLogDebug, "SAM: new connection from ", ep); - { - std::unique_lock l(m_OpenSocketsMutex); - m_OpenSockets.push_back(socket); - } + AddSocket (socket); socket->ReceiveHandshake (); } else diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 7b1702f5..fafd7d1c 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -48,6 +48,7 @@ namespace client const char SAM_STREAM_STATUS_CANT_REACH_PEER[] = "STREAM STATUS RESULT=CANT_REACH_PEER\n"; const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR\n"; const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT"; + const char SAM_STREAM_FORWARD[] = "STREAM FORWARD"; const char SAM_DATAGRAM_SEND[] = "DATAGRAM SEND"; const char SAM_RAW_SEND[] = "RAW SEND"; const char SAM_DEST_GENERATE[] = "DEST GENERATE"; @@ -69,14 +70,14 @@ namespace client const char SAM_PARAM_SIGNATURE_TYPE[] = "SIGNATURE_TYPE"; const char SAM_PARAM_CRYPTO_TYPE[] = "CRYPTO_TYPE"; const char SAM_PARAM_SIZE[] = "SIZE"; + const char SAM_PARAM_HOST[] = "HOST"; + const char SAM_PARAM_PORT[] = "PORT"; const char SAM_VALUE_TRANSIENT[] = "TRANSIENT"; const char SAM_VALUE_STREAM[] = "STREAM"; const char SAM_VALUE_DATAGRAM[] = "DATAGRAM"; const char SAM_VALUE_RAW[] = "RAW"; const char SAM_VALUE_TRUE[] = "true"; const char SAM_VALUE_FALSE[] = "false"; - const char SAM_VALUE_HOST[] = "HOST"; - const char SAM_VALUE_PORT[] = "PORT"; enum SAMSocketType { @@ -84,6 +85,7 @@ namespace client eSAMSocketTypeSession, eSAMSocketTypeStream, eSAMSocketTypeAcceptor, + eSAMSocketTypeForward, eSAMSocketTypeTerminated }; @@ -121,6 +123,7 @@ namespace client void I2PReceive (); void HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleI2PAccept (std::shared_ptr stream); + void HandleI2PForward (std::shared_ptr stream, boost::asio::ip::tcp::endpoint ep); void HandleWriteI2PData (const boost::system::error_code& ecode, size_t sz); void HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleI2PRawDatagramReceive (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); @@ -128,6 +131,7 @@ namespace client void ProcessSessionCreate (char * buf, size_t len); void ProcessStreamConnect (char * buf, size_t len, size_t rem); void ProcessStreamAccept (char * buf, size_t len); + void ProcessStreamForward (char * buf, size_t len); void ProcessDestGenerate (char * buf, size_t len); void ProcessNamingLookup (char * buf, size_t len); void SendI2PError(const std::string & msg); @@ -205,6 +209,7 @@ namespace client /** send raw data to remote endpoint from our UDP Socket */ void SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote); + void AddSocket(std::shared_ptr socket); void RemoveSocket(const std::shared_ptr & socket); bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const; From e41bbcb2bb12ae8a981c04f3aeec787fb53bbd92 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Oct 2020 11:19:37 -0400 Subject: [PATCH 0515/2950] handle SILENT for STREAM FORWARD --- libi2pd_client/SAM.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 2bdbf1ee..2e436637 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -608,6 +608,8 @@ namespace client m_SocketType = eSAMSocketTypeForward; m_ID = id; 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, shared_from_this (), std::placeholders::_1, ep)); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); @@ -982,7 +984,17 @@ namespace client s->m_Owner.AddSocket (newSocket); newSocket->Receive (); newSocket->m_Stream = stream; - newSocket->I2PReceive (); + newSocket->m_ID = s->m_ID; + if (!s->m_IsSilent) + { + // get remote peer address + auto dest = stream->GetRemoteIdentity()->ToBase64 (); + memcpy (newSocket->m_StreamBuffer, dest.c_str (), dest.length ()); + newSocket->m_StreamBuffer[dest.length ()] = '\n'; + newSocket->HandleI2PReceive (boost::system::error_code (),dest.length () + 1); // we send identity like it has been received from stream + } + else + newSocket->I2PReceive (); } else stream->AsyncClose (); From cc0367b079f958a9ab4e796ac3a2cccf39a0730a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Oct 2020 16:06:19 -0400 Subject: [PATCH 0516/2950] always send STREAM STATUS reply to STREAM FORWARD --- daemon/HTTPServer.cpp | 1 + libi2pd_client/SAM.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 3b9f6eaa..59c530f9 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -838,6 +838,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; default: s << "unknown"; break; } s << " [" << it->GetSocket ().remote_endpoint() << "]"; diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 2e436637..6624c6f9 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -199,7 +199,7 @@ namespace client { LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg); - if (!m_IsSilent) + if (!m_IsSilent || m_SocketType == eSAMSocketTypeForward) boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (), std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, close)); From 56f3bdd74677b3c87fe738e95653557e41da2168 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 27 Oct 2020 11:52:02 +0300 Subject: [PATCH 0517/2950] [win32] handle WinAPI errors in SSU Windows can throw WinAPI errors which are not handled by boost asio Signed-off-by: R4SAS --- libi2pd/SSU.cpp | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 07c95a7a..d29f5cd7 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -13,6 +13,10 @@ #include "NetDb.hpp" #include "SSU.h" +#ifdef _WIN32 +#include +#endif + namespace i2p { namespace transport @@ -247,11 +251,17 @@ namespace transport void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) { - if (!ecode || - ecode == boost::asio::error::connection_refused || - ecode == boost::asio::error::connection_reset || - ecode == boost::asio::error::network_unreachable || - ecode == boost::asio::error::host_unreachable) + if (!ecode + || ecode == boost::asio::error::connection_refused + || ecode == boost::asio::error::connection_reset + || ecode == boost::asio::error::network_unreachable + || ecode == boost::asio::error::host_unreachable +#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO + || ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_ + || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_ + || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_ +#endif + ) // just try continue reading when received ICMP response otherwise socket can crash, // but better to find out which host were sent it and mark that router as unreachable { @@ -300,11 +310,17 @@ namespace transport void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) { - if (!ecode || - ecode == boost::asio::error::connection_refused || - ecode == boost::asio::error::connection_reset || - ecode == boost::asio::error::network_unreachable || - ecode == boost::asio::error::host_unreachable) + if (!ecode + || ecode == boost::asio::error::connection_refused + || ecode == boost::asio::error::connection_reset + || ecode == boost::asio::error::network_unreachable + || ecode == boost::asio::error::host_unreachable +#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO + || ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_ + || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_ + || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_ +#endif + ) // just try continue reading when received ICMP response otherwise socket can crash, // but better to find out which host were sent it and mark that router as unreachable { From c400372a79dcc93b75121f6fc5ba5e938a6cc185 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Oct 2020 08:32:38 -0400 Subject: [PATCH 0518/2950] create new ratchets session if previous was not replied --- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + libi2pd/Garlic.h | 1 + libi2pd/Streaming.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index af0b5de5..1c377b28 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -169,6 +169,7 @@ namespace garlic bool IsInactive (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_INACTIVITY_TIMEOUT && CanBeRestarted (ts); } bool IsRatchets () const { return true; }; + bool IsReadyToSend () const { return m_State != eSessionStateNewSessionSent; }; uint64_t GetLastActivityTimestamp () const { return m_LastActivityTimestamp; }; private: diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index f1e363df..3c5d5de6 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -114,6 +114,7 @@ namespace garlic virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); virtual bool IsRatchets () const { return false; }; + virtual bool IsReadyToSend () const { return true; }; virtual uint64_t GetLastActivityTimestamp () const { return 0; }; // non-zero for rathets only void SetLeaseSetUpdated () diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ab08f41f..21c6d6ce 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -756,7 +756,7 @@ namespace stream return; } } - if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) // expired and detached + if (!m_RoutingSession || !m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ()) // expired and detached or new session sent m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); if (!m_CurrentOutboundTunnel && m_RoutingSession) // first message to send { From c63818f355dae64727e82cb01c37a3f4a6fdf09a Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Oct 2020 12:27:08 -0400 Subject: [PATCH 0519/2950] 2.34.0 --- ChangeLog | 29 +++++++++++++++++++ Win32/installer.iss | 2 +- android/build.gradle | 4 +-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 +++- contrib/rpm/i2pd.spec | 5 +++- debian/changelog | 6 ++++ libi2pd/version.h | 2 +- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 9 files changed, 49 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index beef7a5a..dbce5fb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,35 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.34.0] - 2020-10-27 +### Added +- Ping responses for streaming +- STREAM FORWARD for SAM +- Tunnels through ECIES-x25519 routers +- Single thread for I2CP +- Shared transient destination between proxies +- Database lookups from ECIES destinations with ratchets response +- Handle WebDAV HTTP methods +- Don't try to connect or build tunnels if offline +- Validate IP when trying connect to remote peer +- Handle ICMP responses and WinAPI errors for SSU +### Changed +- Removed NTCP +- Dropped gcc 4.7 support +- Encyption type 0,4 by default for client tunnels +- Stripped out some HTTP header for HTTP server response +- HTTP 1.1 addressbook requests +- Set LeaseSet type to 3 for ratchets if not specified +- Handle SSU v4 and v6 messages in one thread +- Eliminate DH keys thread +### Fixed +- Random crashes on I2CP session disconnect +- Stream through racthets hangs if first SYN was not acked +- Check "Last-Modified" instead "If-Modified-Since" for addressbook reponse +- Trim behind ECIESx25519 tags +- Few bugs with Android main activity +- QT visual and layout issues + ## [2.33.0] - 2020-08-24 ### Added - Shared transient addresses diff --git a/Win32/installer.iss b/Win32/installer.iss index fbbeba53..cc40c409 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.33.0" +#define I2Pd_ver "2.34.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/build.gradle b/android/build.gradle index 7d25e28b..225b5d21 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -32,8 +32,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2330 - versionName "2.33.0" + versionCode 2340 + versionName "2.34.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index 3cf51c2b..a8e7d30d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.33.0.{build} +version: 2.34.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 00bea0b0..b1f28de1 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.33.0 +Version: 2.34.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd @@ -124,6 +124,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Oct 27 2020 orignal - 2.34.0 +- update to 2.34.0 + * Mon Aug 24 2020 orignal - 2.33.0 - update to 2.33.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 22287f24..150be6a4 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.33.0 +Version: 2.34.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -122,6 +122,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Tue Oct 27 2020 orignal - 2.34.0 +- update to 2.34.0 + * Mon Aug 24 2020 orignal - 2.33.0 - update to 2.33.0 diff --git a/debian/changelog b/debian/changelog index bac3f3b3..b79f6cd6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.34.0-1) unstable; urgency=medium + + * updated to version 2.34.0 + + -- orignal Tue, 27 Oct 2020 16:00:00 +0000 + i2pd (2.33.0-1) unstable; urgency=medium * updated to version 2.33.0/0.9.47 diff --git a/libi2pd/version.h b/libi2pd/version.h index db30eee8..26ced1c3 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 33 +#define I2PD_VERSION_MINOR 34 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index d3fa2e9e..97a759c2 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From 979282a0d4784ab1003e7ed333ccbf2295110af2 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 28 Oct 2020 03:11:14 +0800 Subject: [PATCH 0520/2950] qt .pro now uses libi2pd.a and libi2pclient.a instead of sources --- qt/i2pd_qt/i2pd_qt.pro | 146 ++++------------------------------------- 1 file changed, 13 insertions(+), 133 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 534d5f5a..80968fcb 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -17,68 +17,6 @@ CONFIG(debug, debug|release) { } SOURCES += DaemonQT.cpp mainwindow.cpp \ - ../../libi2pd/api.cpp \ - ../../libi2pd/Base.cpp \ - ../../libi2pd/Blinding.cpp \ - ../../libi2pd/BloomFilter.cpp \ - ../../libi2pd/ChaCha20.cpp \ - ../../libi2pd/Config.cpp \ - ../../libi2pd/CPU.cpp \ - ../../libi2pd/Crypto.cpp \ - ../../libi2pd/CryptoKey.cpp \ - ../../libi2pd/Datagram.cpp \ - ../../libi2pd/Destination.cpp \ - ../../libi2pd/Ed25519.cpp \ - ../../libi2pd/Family.cpp \ - ../../libi2pd/FS.cpp \ - ../../libi2pd/Garlic.cpp \ - ../../libi2pd/Gost.cpp \ - ../../libi2pd/Gzip.cpp \ - ../../libi2pd/HTTP.cpp \ - ../../libi2pd/I2NPProtocol.cpp \ - ../../libi2pd/I2PEndian.cpp \ - ../../libi2pd/Identity.cpp \ - ../../libi2pd/LeaseSet.cpp \ - ../../libi2pd/Log.cpp \ - ../../libi2pd/NetDb.cpp \ - ../../libi2pd/NetDbRequests.cpp \ - ../../libi2pd/NTCP2.cpp \ - ../../libi2pd/Poly1305.cpp \ - ../../libi2pd/Profiling.cpp \ - ../../libi2pd/Reseed.cpp \ - ../../libi2pd/RouterContext.cpp \ - ../../libi2pd/RouterInfo.cpp \ - ../../libi2pd/Signature.cpp \ - ../../libi2pd/SSU.cpp \ - ../../libi2pd/SSUData.cpp \ - ../../libi2pd/SSUSession.cpp \ - ../../libi2pd/Streaming.cpp \ - ../../libi2pd/Timestamp.cpp \ - ../../libi2pd/TransitTunnel.cpp \ - ../../libi2pd/Transports.cpp \ - ../../libi2pd/Tunnel.cpp \ - ../../libi2pd/TunnelEndpoint.cpp \ - ../../libi2pd/TunnelGateway.cpp \ - ../../libi2pd/TunnelPool.cpp \ - ../../libi2pd/TunnelConfig.cpp \ - ../../libi2pd/util.cpp \ - ../../libi2pd/Elligator.cpp \ - ../../libi2pd/ECIESX25519AEADRatchetSession.cpp \ - ../../libi2pd_client/AddressBook.cpp \ - ../../libi2pd_client/BOB.cpp \ - ../../libi2pd_client/ClientContext.cpp \ - ../../libi2pd_client/HTTPProxy.cpp \ - ../../libi2pd_client/I2CP.cpp \ - ../../libi2pd_client/I2PService.cpp \ - ../../libi2pd_client/I2PTunnel.cpp \ - ../../libi2pd_client/MatchedDestination.cpp \ - ../../libi2pd_client/SAM.cpp \ - ../../libi2pd_client/SOCKS.cpp \ - ../../daemon/Daemon.cpp \ - ../../daemon/HTTPServer.cpp \ - ../../daemon/I2PControl.cpp \ - ../../daemon/i2pd.cpp \ - ../../daemon/UPnP.cpp \ ClientTunnelPane.cpp \ MainWindowItems.cpp \ ServerTunnelPane.cpp \ @@ -93,77 +31,14 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ DelayedSaveManager.cpp \ Saver.cpp \ DelayedSaveManagerImpl.cpp \ - SaverImpl.cpp + SaverImpl.cpp \ + ../../daemon/Daemon.cpp \ + ../../daemon/HTTPServer.cpp \ + ../../daemon/I2PControl.cpp \ + ../../daemon/i2pd.cpp \ + ../../daemon/UPnP.cpp HEADERS += DaemonQT.h mainwindow.h \ - ../../libi2pd/api.h \ - ../../libi2pd/Base.h \ - ../../libi2pd/Blinding.h \ - ../../libi2pd/BloomFilter.h \ - ../../libi2pd/ChaCha20.h \ - ../../libi2pd/Config.h \ - ../../libi2pd/CPU.h \ - ../../libi2pd/Crypto.h \ - ../../libi2pd/CryptoKey.h \ - ../../libi2pd/Datagram.h \ - ../../libi2pd/Destination.h \ - ../../libi2pd/Ed25519.h \ - ../../libi2pd/Family.h \ - ../../libi2pd/FS.h \ - ../../libi2pd/Garlic.h \ - ../../libi2pd/Gost.h \ - ../../libi2pd/Gzip.h \ - ../../libi2pd/HTTP.h \ - ../../libi2pd/I2NPProtocol.h \ - ../../libi2pd/I2PEndian.h \ - ../../libi2pd/Identity.h \ - ../../libi2pd/LeaseSet.h \ - ../../libi2pd/LittleBigEndian.h \ - ../../libi2pd/Log.h \ - ../../libi2pd/NetDb.hpp \ - ../../libi2pd/NetDbRequests.h \ - ../../libi2pd/NTCP2.h \ - ../../libi2pd/Poly1305.h \ - ../../libi2pd/Profiling.h \ - ../../libi2pd/Queue.h \ - ../../libi2pd/Reseed.h \ - ../../libi2pd/RouterContext.h \ - ../../libi2pd/RouterInfo.h \ - ../../libi2pd/Signature.h \ - ../../libi2pd/Siphash.h \ - ../../libi2pd/SSU.h \ - ../../libi2pd/SSUData.h \ - ../../libi2pd/SSUSession.h \ - ../../libi2pd/Streaming.h \ - ../../libi2pd/Tag.h \ - ../../libi2pd/Timestamp.h \ - ../../libi2pd/TransitTunnel.h \ - ../../libi2pd/Transports.h \ - ../../libi2pd/TransportSession.h \ - ../../libi2pd/Tunnel.h \ - ../../libi2pd/TunnelBase.h \ - ../../libi2pd/TunnelConfig.h \ - ../../libi2pd/TunnelEndpoint.h \ - ../../libi2pd/TunnelGateway.h \ - ../../libi2pd/TunnelPool.h \ - ../../libi2pd/util.h \ - ../../libi2pd/version.h \ - ../../libi2pd/Elligator.h \ - ../../libi2pd/ECIESX25519AEADRatchetSession.h \ - ../../libi2pd_client/AddressBook.h \ - ../../libi2pd_client/BOB.h \ - ../../libi2pd_client/ClientContext.h \ - ../../libi2pd_client/HTTPProxy.h \ - ../../libi2pd_client/I2CP.h \ - ../../libi2pd_client/I2PService.h \ - ../../libi2pd_client/I2PTunnel.h \ - ../../libi2pd_client/MatchedDestination.h \ - ../../libi2pd_client/SAM.h \ - ../../libi2pd_client/SOCKS.h \ - ../../daemon/Daemon.h \ - ../../daemon/HTTPServer.h \ - ../../daemon/I2PControl.h \ - ../../daemon/UPnP.h \ ClientTunnelPane.h \ MainWindowItems.h \ ServerTunnelPane.h \ @@ -180,7 +55,12 @@ HEADERS += DaemonQT.h mainwindow.h \ DelayedSaveManager.h \ Saver.h \ DelayedSaveManagerImpl.h \ - SaverImpl.h + SaverImpl.h \ + ../../daemon/Daemon.h \ + ../../daemon/HTTPServer.h \ + ../../daemon/I2PControl.h \ + ../../daemon/UPnP.h + INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client @@ -193,7 +73,7 @@ FORMS += mainwindow.ui \ routercommandswidget.ui \ generalsettingswidget.ui -LIBS += -lz +LIBS += ../../libi2pd.a ../../libi2pdclient.a -lz macx { message("using mac os x target") From 2b4a91cc806f7826a8b6b24c852f916eb1de100d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 27 Oct 2020 19:34:38 +0000 Subject: [PATCH 0521/2950] [actions] Rename worker and jobs --- .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 ba6acbf8..5e5152e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,10 +1,10 @@ -name: Build on Ubuntu with make +name: Build on Ubuntu on: [push, pull_request] jobs: build: - name: Building with USE_UPNP=${{ matrix.with_upnp }} flag + name: With USE_UPNP=${{ matrix.with_upnp }} runs-on: ubuntu-16.04 strategy: fail-fast: true From 0c29aeb9bead9a8f4039ecf4206bcb2d30975733 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 27 Oct 2020 19:40:22 +0000 Subject: [PATCH 0522/2950] [actions] add qt gui builder --- .github/workflows/build-qt.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/build-qt.yml diff --git a/.github/workflows/build-qt.yml b/.github/workflows/build-qt.yml new file mode 100644 index 00000000..6b247f1b --- /dev/null +++ b/.github/workflows/build-qt.yml @@ -0,0 +1,20 @@ +name: Build on Ubuntu + +on: [push, pull_request] + +jobs: + build: + name: With QT GUI + runs-on: ubuntu-16.04 + 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 qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application + run: | + cd qt/i2pd_qt + qmake + make USE_AVX=no USE_AESNI=no USE_UPNP=yes -j3 From a47aa8c282be0b23133922cbcf7c89034ce181bf Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 27 Oct 2020 19:55:48 +0000 Subject: [PATCH 0523/2950] [actions] build i2pd library before building gui --- .github/workflows/build-qt.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-qt.yml b/.github/workflows/build-qt.yml index 6b247f1b..6211c4c7 100644 --- a/.github/workflows/build-qt.yml +++ b/.github/workflows/build-qt.yml @@ -15,6 +15,7 @@ jobs: sudo apt-get install build-essential qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application run: | + make -j3 USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no mk_obj_dir libi2pd.a libi2pdclient.a cd qt/i2pd_qt qmake - make USE_AVX=no USE_AESNI=no USE_UPNP=yes -j3 + make -j3 From e444519889b75d570d025e5dfcd0a15a60ca1eba Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Oct 2020 16:46:39 -0400 Subject: [PATCH 0524/2950] excluded appcompat --- android/build.gradle | 2 -- android/src/org/purplei2p/i2pd/WebConsoleActivity.java | 2 -- 2 files changed, 4 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 225b5d21..2c6c782d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,8 +21,6 @@ repositories { dependencies { implementation 'androidx.core:core:1.0.2' - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' } android { diff --git a/android/src/org/purplei2p/i2pd/WebConsoleActivity.java b/android/src/org/purplei2p/i2pd/WebConsoleActivity.java index 24e6baeb..0fcf37fe 100644 --- a/android/src/org/purplei2p/i2pd/WebConsoleActivity.java +++ b/android/src/org/purplei2p/i2pd/WebConsoleActivity.java @@ -1,7 +1,5 @@ package org.purplei2p.i2pd; -import androidx.appcompat.app.AppCompatActivity; - import android.app.Activity; import android.os.Bundle; import android.view.MenuItem; From 33f2ddb6960288f7c48d2b8d0fa8632051746817 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 28 Oct 2020 20:07:28 +0300 Subject: [PATCH 0525/2950] [QT] fix build with prebuild i2pd libs Signed-off-by: R4SAS --- .github/workflows/build-qt.yml | 1 - qt/i2pd_qt/i2pd_qt.pro | 24 ++++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-qt.yml b/.github/workflows/build-qt.yml index 6211c4c7..d4fde2b9 100644 --- a/.github/workflows/build-qt.yml +++ b/.github/workflows/build-qt.yml @@ -15,7 +15,6 @@ jobs: sudo apt-get install build-essential qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application run: | - make -j3 USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no mk_obj_dir libi2pd.a libi2pdclient.a cd qt/i2pd_qt qmake make -j3 diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 80968fcb..1064e953 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -7,8 +7,6 @@ TEMPLATE = app QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized CONFIG += strict_c++ c++11 -DEFINES += USE_UPNP - CONFIG(debug, debug|release) { message(Debug build) DEFINES += DEBUG_WITH_DEFAULT_LOGGING @@ -75,6 +73,22 @@ FORMS += mainwindow.ui \ LIBS += ../../libi2pd.a ../../libi2pdclient.a -lz +libi2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" USE_UPNP=yes DEBUG=no mk_obj_dir libi2pd.a +libi2pd.target = $$PWD/../../libi2pd.a +libi2pd.depends = FORCE + +libi2pdclient.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" USE_UPNP=yes DEBUG=no mk_obj_dir libi2pdclient.a +libi2pdclient.target = $$PWD/../../libi2pdclient.a +libi2pdclient.depends = FORCE + +cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean +cleani2pd.depends = clean + +PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a +QMAKE_EXTRA_TARGETS += cleani2pd libi2pd libi2pdclient +CLEAN_DEPS += cleani2pd + + macx { message("using mac os x target") BREWROOT=/usr/local @@ -110,10 +124,12 @@ windows { QMAKE_CXXFLAGS_RELEASE = -Os QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows - #linker's -s means "strip" + # linker's -s means "strip" QMAKE_LFLAGS_RELEASE += -s - LIBS = -lminiupnpc \ + LIBS = \ + $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a \ + -lminiupnpc \ -lboost_system$$BOOST_SUFFIX \ -lboost_date_time$$BOOST_SUFFIX \ -lboost_filesystem$$BOOST_SUFFIX \ From bf0496299413a69fd364db54b79ec0b2388976e9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 28 Oct 2020 20:47:16 +0300 Subject: [PATCH 0526/2950] [QT] change i2pd make command Signed-off-by: R4SAS --- qt/i2pd_qt/i2pd_qt.pro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 1064e953..54818f71 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -71,13 +71,13 @@ FORMS += mainwindow.ui \ routercommandswidget.ui \ generalsettingswidget.ui -LIBS += ../../libi2pd.a ../../libi2pdclient.a -lz +LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz -libi2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" USE_UPNP=yes DEBUG=no mk_obj_dir libi2pd.a +libi2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api libi2pd.target = $$PWD/../../libi2pd.a libi2pd.depends = FORCE -libi2pdclient.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) OPT=\"$$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_RELEASE\" USE_UPNP=yes DEBUG=no mk_obj_dir libi2pdclient.a +libi2pdclient.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api_client libi2pdclient.target = $$PWD/../../libi2pdclient.a libi2pdclient.depends = FORCE From bdbd060229cf3d0808b83148ed89e7939d70499d Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 28 Oct 2020 21:02:41 +0300 Subject: [PATCH 0527/2950] [QT] create obj dirs before building i2pd Signed-off-by: R4SAS --- qt/i2pd_qt/i2pd_qt.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 54818f71..34b8ebfc 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -73,11 +73,11 @@ FORMS += mainwindow.ui \ LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz -libi2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api +libi2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api libi2pd.target = $$PWD/../../libi2pd.a libi2pd.depends = FORCE -libi2pdclient.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api_client +libi2pdclient.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api_client libi2pdclient.target = $$PWD/../../libi2pdclient.a libi2pdclient.depends = FORCE From d02a0c9b3a1b9f2cbee8bf364382443cfa081443 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 28 Oct 2020 21:18:02 +0300 Subject: [PATCH 0528/2950] [QT] don't build i2pd with aesni/avx for compatability with arm64 Signed-off-by: R4SAS --- qt/i2pd_qt/i2pd_qt.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 34b8ebfc..dba69143 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -73,11 +73,11 @@ FORMS += mainwindow.ui \ LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz -libi2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api +libi2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no api libi2pd.target = $$PWD/../../libi2pd.a libi2pd.depends = FORCE -libi2pdclient.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes DEBUG=no api_client +libi2pdclient.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no api_client libi2pdclient.target = $$PWD/../../libi2pdclient.a libi2pdclient.depends = FORCE From 5d256e1d800a2f7cd9f92f3fb3e27522ad2afe0d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Oct 2020 15:35:39 -0400 Subject: [PATCH 0529/2950] don't allow STREAM CONNECT and STREAM ACCEPT in command session --- libi2pd_client/SAM.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 6624c6f9..d758f31e 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -472,6 +472,11 @@ namespace client void SAMSocket::ProcessStreamConnect (char * buf, size_t len, size_t rem) { LogPrint (eLogDebug, "SAM: stream connect: ", buf); + if ( m_SocketType != eSAMSocketTypeUnknown) + { + SendI2PError ("Socket already in use"); + return; + } std::map params; ExtractParams (buf, params); std::string& id = params[SAM_PARAM_ID]; @@ -547,6 +552,11 @@ namespace client void SAMSocket::ProcessStreamAccept (char * buf, size_t len) { LogPrint (eLogDebug, "SAM: stream accept: ", buf); + if ( m_SocketType != eSAMSocketTypeUnknown) + { + SendI2PError ("Socket already in use"); + return; + } std::map params; ExtractParams (buf, params); std::string& id = params[SAM_PARAM_ID]; From 812d312a9e4c1807f768bdcb97bbccb154bef207 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 29 Oct 2020 00:38:47 +0300 Subject: [PATCH 0530/2950] [RPM] fix build on fedora >= 33 Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index b1f28de1..58c87cfb 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -56,14 +56,23 @@ cd build %endif %endif -%if 0%{?mageia} > 7 -pushd build -make %{?_smp_mflags} -popd -%else -make %{?_smp_mflags} +%if 0%{?fedora} >= 33 +pushd %{_arch}-redhat-linux-gnu %endif +%if 0%{?mageia} > 7 +pushd build +%endif + +make %{?_smp_mflags} + +%if 0%{?fedora} >= 33 +popd +%endif + +%if 0%{?mageia} > 7 +popd +%endif %install pushd build From 530eba1b911dcc682c05194d67c7a425267feb18 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 29 Oct 2020 00:51:01 +0300 Subject: [PATCH 0531/2950] [RPM] fix build on fedora >= 33 Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 58c87cfb..1fd8ce8d 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -57,7 +57,7 @@ cd build %endif %if 0%{?fedora} >= 33 -pushd %{_arch}-redhat-linux-gnu +pushd %{_target_platform} %endif %if 0%{?mageia} > 7 From b2f0278180c2e53b7a877c9993d37beaac4bc8d0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 29 Oct 2020 01:03:36 +0300 Subject: [PATCH 0532/2950] [RPM] fix build on fedora >= 33 Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 1fd8ce8d..59d5f5ab 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -81,6 +81,10 @@ pushd build pushd build %endif +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif + chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd From aaf6c1ea8b7fce01f10be087f5c4dc3680167649 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 29 Oct 2020 01:17:07 +0300 Subject: [PATCH 0533/2950] [RPM] fix build on fedora >= 33 Signed-off-by: R4SAS --- contrib/rpm/i2pd-git.spec | 8 ++++---- contrib/rpm/i2pd.spec | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 59d5f5ab..a320d6aa 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -77,14 +77,14 @@ popd %install pushd build -%if 0%{?mageia} -pushd build -%endif - %if 0%{?fedora} >= 33 pushd %{_target_platform} %endif +%if 0%{?mageia} +pushd build +%endif + chrpath -d i2pd %{__install} -D -m 755 i2pd %{buildroot}%{_sbindir}/i2pd %{__install} -d -m 755 %{buildroot}%{_datadir}/i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 150be6a4..3f5ef260 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -54,18 +54,31 @@ cd build %endif %endif -%if 0%{?mageia} > 7 -pushd build -make %{?_smp_mflags} -popd -%else -make %{?_smp_mflags} +%if 0%{?fedora} >= 33 +pushd %{_target_platform} %endif +%if 0%{?mageia} > 7 +pushd build +%endif + +make %{?_smp_mflags} + +%if 0%{?fedora} >= 33 +popd +%endif + +%if 0%{?mageia} > 7 +popd +%endif %install pushd build +%if 0%{?fedora} >= 33 +pushd %{_target_platform} +%endif + %if 0%{?mageia} pushd build %endif From 9f2a2e44a323ba94c7782e3d0e0c4a93c63dba6f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 28 Oct 2020 21:53:11 -0400 Subject: [PATCH 0534/2950] common MixHash and MixKey --- libi2pd/Crypto.cpp | 18 ++++++++++++++++-- libi2pd/Crypto.h | 10 ++++++++++ libi2pd/NTCP2.cpp | 15 --------------- libi2pd/NTCP2.h | 6 ++---- libi2pd/Tunnel.cpp | 2 +- libi2pd/TunnelConfig.cpp | 22 +++++----------------- libi2pd/TunnelConfig.h | 5 ++--- 7 files changed, 36 insertions(+), 42 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 2f10e91d..ea2cd675 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1323,6 +1323,21 @@ namespace crypto #endif } + void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, m_H, 32); + SHA256_Update (&ctx, buf, len); + SHA256_Final (m_H, &ctx); + } + + void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret) + { + HKDF (m_CK, sharedSecret, 32, "", m_CK); + // new ck is m_CK[0:31], key is m_CK[32:63] + } + // init and terminate /* std::vector > m_OpenSSLMutexes; @@ -1336,8 +1351,7 @@ namespace crypto m_OpenSSLMutexes[type]->unlock (); } }*/ - - + void InitCrypto (bool precomputation) { i2p::cpu::Detect (); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index ab84e56a..205be44d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -311,6 +311,16 @@ namespace crypto void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out, size_t outLen = 64); // salt - 32, out - 32 or 64, info <= 32 +// Noise + + struct NoiseSymmetricState + { + uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/; + + void MixHash (const uint8_t * buf, size_t len); + void MixKey (const uint8_t * sharedSecret); + }; + // init and terminate void InitCrypto (bool precomputation); void TerminateCrypto (); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index cdf660b7..7a88e4d8 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -39,21 +39,6 @@ namespace transport delete[] m_SessionConfirmedBuffer; } - void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial) - { - i2p::crypto::HKDF (m_CK, inputKeyMaterial, 32, "", m_CK); - // ck is m_CK[0:31], k is m_CK[32:63] - } - - void NTCP2Establisher::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, buf, len); - SHA256_Final (m_H, &ctx); - } - void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { static const uint8_t protocolNameHash[] = diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index df72fed0..351f17b5 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -74,7 +74,7 @@ namespace transport // RouterInfo flags const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01; - struct NTCP2Establisher + struct NTCP2Establisher: private i2p::crypto::NoiseSymmetricState { NTCP2Establisher (); ~NTCP2Establisher (); @@ -94,8 +94,6 @@ namespace transport void KDF3Alice (); // for SessionConfirmed part 2 void KDF3Bob (); - void MixKey (const uint8_t * inputKeyMaterial); - void MixHash (const uint8_t * buf, size_t len); void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate void CreateEphemeralKey (); @@ -112,7 +110,7 @@ namespace transport std::shared_ptr m_EphemeralKeys; uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 - uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/; + uint8_t m_RemoteStaticKey[32], m_IV[16]; i2p::data::IdentHash m_RemoteIdentHash; uint16_t m3p2Len; diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index bfe466e3..a74c8c91 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -124,7 +124,7 @@ namespace tunnel uint8_t nonce[12]; memset (nonce, 0, 12); if (!i2p::crypto::AEADChaCha20Poly1305 (record, TUNNEL_BUILD_RECORD_SIZE - 16, - hop->h, 32, hop->ck, nonce, record, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + 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; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 5c2cbd53..61e878d4 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -10,7 +10,6 @@ #include #include #include -#include "Crypto.h" #include "Log.h" #include "Transports.h" #include "Timestamp.h" @@ -129,8 +128,8 @@ namespace tunnel const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars - memcpy (ck, protocolName, 32); // ck = h = protocol_name || 0 - SHA256 (ck, 32, h); // h = SHA256(h); + memcpy (m_CK, protocolName, 32); // ck = h = protocol_name || 0 + SHA256 (m_CK, 32, m_H); // h = SHA256(h); uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); MixHash (hepk, 32); // h = SHA256(h || hepk) @@ -140,27 +139,16 @@ namespace tunnel encrypted += 32; uint8_t sharedSecret[32]; ephemeralKeys->Agree (hepk, sharedSecret); // x25519(sesk, hepk) - uint8_t keydata[64]; - i2p::crypto::HKDF (ck, sharedSecret, 32, "", keydata); - memcpy (ck, keydata, 32); + MixKey (sharedSecret); uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (plainText, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, h, 32, - keydata + 32, nonce, encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16, true)) // encrypt + 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 { LogPrint (eLogWarning, "Tunnel: Plaintext AEAD encryption failed"); return; } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } - - void TunnelHopConfig::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, h, 32); - SHA256_Update (&ctx, buf, len); - SHA256_Final (h, &ctx); - } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 0e757071..261394b4 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -12,12 +12,13 @@ #include #include "Identity.h" #include "RouterContext.h" +#include "Crypto.h" namespace i2p { namespace tunnel { - struct TunnelHopConfig + struct TunnelHopConfig: public i2p::crypto::NoiseSymmetricState { std::shared_ptr ident; i2p::data::IdentHash nextIdent; @@ -30,7 +31,6 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - uint8_t ck[32], h[32]; // for ECIES TunnelHopConfig (std::shared_ptr r); @@ -43,7 +43,6 @@ 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); - void MixHash (const uint8_t * buf, size_t len); }; class TunnelConfig From b12fa97a38ca9c9fc15800e2106e483687fee33a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 29 Oct 2020 18:41:21 -0400 Subject: [PATCH 0535/2950] 32 bytes private key for ECIESx25519 --- libi2pd/Identity.cpp | 20 ++++++++++++++------ libi2pd/Identity.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 490b8692..c6e5a884 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -476,7 +476,7 @@ namespace data size_t PrivateKeys::GetFullLen () const { - size_t ret = m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); + size_t ret = m_Public->GetFullLen () + GetPrivateKeyLen () + m_Public->GetSigningPrivateKeyLen (); if (IsOfflineSignature ()) ret += m_OfflineSignature.size () + m_TransientSigningPrivateKeyLen; return ret; @@ -486,9 +486,10 @@ namespace data { m_Public = std::make_shared(); size_t ret = m_Public->FromBuffer (buf, len); - if (!ret || ret + 256 > len) return 0; // overflow - memcpy (m_PrivateKey, buf + ret, 256); // private key always 256 - ret += 256; + auto cryptoKeyLen = GetPrivateKeyLen (); + if (!ret || ret + cryptoKeyLen > len) return 0; // overflow + memcpy (m_PrivateKey, buf + ret, cryptoKeyLen); + ret += cryptoKeyLen; size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen (); if(signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0; // overflow memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize); @@ -540,8 +541,9 @@ namespace data size_t PrivateKeys::ToBuffer (uint8_t * buf, size_t len) const { size_t ret = m_Public->ToBuffer (buf, len); - memcpy (buf + ret, m_PrivateKey, 256); // private key always 256 - ret += 256; + auto cryptoKeyLen = GetPrivateKeyLen (); + memcpy (buf + ret, m_PrivateKey, cryptoKeyLen); + ret += cryptoKeyLen; size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen (); if(ret + signingPrivateKeySize > len) return 0; // overflow if (IsOfflineSignature ()) @@ -657,6 +659,12 @@ namespace data return IsOfflineSignature () ? m_TransientSignatureLen : m_Public->GetSignatureLen (); } + size_t PrivateKeys::GetPrivateKeyLen () const + { + // private key length always 256, but type 4 + return (m_Public->GetCryptoKeyType () == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) ? 32 : 256; + } + uint8_t * PrivateKeys::GetPadding() { if(m_Public->GetSigningKeyType () == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index 534b8f4c..a36e7209 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -183,6 +183,7 @@ namespace data void CreateSigner () const; void CreateSigner (SigningKeyType keyType) const; + size_t GetPrivateKeyLen () const; private: From 3907c17cf5529034a349a0519fe84baa083a6d77 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 2 Nov 2020 18:49:07 -0500 Subject: [PATCH 0536/2950] handle TunnelBuildMessage for ECIES router --- libi2pd/I2NPProtocol.cpp | 53 +++++++++++++++++++++++++++++++-------- libi2pd/I2NPProtocol.h | 1 + libi2pd/RouterContext.cpp | 35 ++++++++++++++++++++++++-- libi2pd/RouterContext.h | 8 ++++-- libi2pd/TunnelConfig.cpp | 11 +++++--- libi2pd/TunnelConfig.h | 2 ++ 6 files changed, 93 insertions(+), 17 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 36e7a763..7778b9e4 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -363,37 +363,70 @@ namespace i2p BN_CTX * ctx = BN_CTX_new (); i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); BN_CTX_free (ctx); + 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 = i2p::tunnel::CreateTransitTunnel ( + auto transitTunnel = isECIES ? + 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] & 0x80, + clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) : + 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] & 0x40); i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); - record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0; } else - record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 30; // always reject with bandwidth reason (30) + retCode = 30; // always reject with bandwidth reason (30) - //TODO: fill filler - SHA256 (record + BUILD_RESPONSE_RECORD_PADDING_OFFSET, BUILD_RESPONSE_RECORD_PADDING_SIZE + 1, // + 1 byte of ret - record + BUILD_RESPONSE_RECORD_HASH_OFFSET); + 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); + } // encrypt reply i2p::crypto::CBCEncryption encryption; for (int j = 0; j < num; j++) { - encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); - encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE; - encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); + if (isECIES && j == i) + { + uint8_t nonce[12]; + memset (nonce, 0, 12); + auto noiseState = std::move (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 + { + 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.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); + } } return true; } diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 03f0f439..b8fbb303 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -98,6 +98,7 @@ namespace i2p const size_t ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE = 464; // ECIES BuildResponseRecord + const size_t ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET = 0; const size_t ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET = 511; enum I2NPMessageType diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 69e69d7c..da9b42fc 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -19,6 +19,7 @@ #include "version.h" #include "Log.h" #include "Family.h" +#include "TunnelConfig.h" #include "RouterContext.h" namespace i2p @@ -41,6 +42,13 @@ namespace i2p CreateNewRouter (); m_Decryptor = m_Keys.CreateDecryptor (nullptr); UpdateRouterInfo (); + if (IsECIES ()) + { + auto initState = new i2p::crypto::NoiseSymmetricState (); + i2p::tunnel::InitBuildRequestRecordNoiseState (*initState); + initState->MixHash (GetIdentity ()->GetEncryptionPublicKey (), 32); // h = SHA256(h || hepk) + m_InitialNoiseState.reset (initState); + } } void RouterContext::CreateNewRouter () @@ -673,9 +681,32 @@ 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) const + bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) { - return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false; + if (!m_Decryptor) 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]; + m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false); + m_CurrentNoiseState->MixKey (sharedSecret); + encrypted += 32; + uint8_t nonce[12]; + memset (nonce, 0, 12); + if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, + m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK, nonce, data, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); + return false; + } + m_CurrentNoiseState->MixHash (encrypted, TUNNEL_BUILD_RECORD_SIZE); // h = SHA256(h || ciphertext) + return true; + } + else + return m_Decryptor->Decrypt (encrypted, data, ctx, false); } i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 37e1791d..402d3816 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -84,7 +84,7 @@ namespace i2p void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; }; 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) const; + bool DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); void UpdatePort (int port); // called from Daemon void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon @@ -109,7 +109,9 @@ namespace i2p bool SupportsV4 () const { return m_RouterInfo.IsV4 (); }; void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); - + bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; }; + 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 @@ -160,6 +162,8 @@ namespace i2p std::mutex m_GarlicMutex; std::unique_ptr m_NTCP2Keys; std::unique_ptr m_StaticKeys; + // for ECIESx25519 + std::unique_ptr m_InitialNoiseState, m_CurrentNoiseState; }; extern RouterContext context; diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index 61e878d4..c0ebb766 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -127,9 +127,7 @@ namespace tunnel void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { - static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars - memcpy (m_CK, protocolName, 32); // ck = h = protocol_name || 0 - SHA256 (m_CK, 32, m_H); // h = SHA256(h); + InitBuildRequestRecordNoiseState (*this); uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); MixHash (hepk, 32); // h = SHA256(h || hepk) @@ -150,5 +148,12 @@ namespace tunnel } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } + + void InitBuildRequestRecordNoiseState (i2p::crypto::NoiseSymmetricState& state) + { + static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars + memcpy (state.m_CK, protocolName, 32); // ck = h = protocol_name || 0 + SHA256 (state.m_CK, 32, state.m_H); // h = SHA256(h); + } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 261394b4..518c1aad 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -45,6 +45,8 @@ namespace tunnel const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); }; + void InitBuildRequestRecordNoiseState (i2p::crypto::NoiseSymmetricState& state); + class TunnelConfig { public: From d820b8036edfb6045eebd9223658b30b03570868 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Nov 2020 09:20:14 -0500 Subject: [PATCH 0537/2950] correct transient signature length --- libi2pd/Streaming.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 21c6d6ce..80e8aecf 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -325,7 +325,7 @@ namespace stream if (flags & PACKET_FLAG_SIGNATURE_INCLUDED) { uint8_t signature[256]; - auto signatureLen = m_RemoteIdentity->GetSignatureLen (); + auto signatureLen = m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : m_RemoteIdentity->GetSignatureLen (); if(signatureLen <= sizeof(signature)) { memcpy (signature, optionData, signatureLen); From 4e7aafeec13338e92c5293e848b4a207cdca9bce Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Nov 2020 15:23:13 -0500 Subject: [PATCH 0538/2950] send transit tunnel reply for ECIES router --- libi2pd/I2NPProtocol.cpp | 46 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 7778b9e4..4dbb4e18 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -463,22 +463,44 @@ namespace i2p } else { - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - if (HandleBuildRequestRecords (num, buf + 1, clearText)) + if (i2p::context.IsECIES ()) { - if (clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // we are endpoint of outboud tunnel + uint8_t clearText[TUNNEL_BUILD_RECORD_SIZE]; + if (HandleBuildRequestRecords (num, buf + 1, clearText)) { - // 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))); + if (clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x40) // 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))); } - else - transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, - CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len, - bufbe32toh (clearText + 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] & 0x40) // 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))); + } + } } } From f94d03465a25a04937b2d6a05da0fa3857cefcf3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Nov 2020 15:38:25 -0500 Subject: [PATCH 0539/2950] don't create transit tunnel if decyrption failed --- libi2pd/I2NPProtocol.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 4dbb4e18..3cc254e6 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -361,8 +361,9 @@ namespace i2p { LogPrint (eLogDebug, "I2NP: Build request record ", i, " is ours"); BN_CTX * ctx = BN_CTX_new (); - i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); + bool success = i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText, ctx); BN_CTX_free (ctx); + if(!success) return false; uint8_t retCode = 0; bool isECIES = i2p::context.IsECIES (); // replace record to reply From b8064b9b4b6a4534d7e4089d57376b32c55cb144 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Nov 2020 15:42:53 -0500 Subject: [PATCH 0540/2950] copy noise state --- libi2pd/RouterContext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index da9b42fc..8b5f5b77 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -687,8 +687,10 @@ namespace i2p if (IsECIES ()) { if (!m_InitialNoiseState) return false; + m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState ()); // m_InitialNoiseState is h = SHA256(h || hepk) - m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); + memcpy (m_CurrentNoiseState->m_CK, m_InitialNoiseState->m_CK, 64); + memcpy (m_CurrentNoiseState->m_H, m_InitialNoiseState->m_H, 32); m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false); From 942b2b05e70b7882ca735aa038ed17ca85ed55ba Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Nov 2020 15:53:47 -0500 Subject: [PATCH 0541/2950] correct key for AEAD decryption --- libi2pd/RouterContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 8b5f5b77..4d60e193 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -699,7 +699,7 @@ namespace i2p uint8_t nonce[12]; memset (nonce, 0, 12); if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, - m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK, nonce, data, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK + 32, nonce, data, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt { LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); return false; From bd04f92087ea151f60d59637f6099d884c157ea3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 3 Nov 2020 18:41:27 -0500 Subject: [PATCH 0542/2950] correct public key for ECIES address --- libi2pd/Identity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index c6e5a884..7784cc90 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -51,7 +51,7 @@ namespace data if (cryptoType == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) { memcpy (m_StandardIdentity.publicKey, publicKey, 32); - RAND_bytes (m_StandardIdentity.publicKey, 224); + RAND_bytes (m_StandardIdentity.publicKey + 32, 224); } else memcpy (m_StandardIdentity.publicKey, publicKey, 256); From d5f3d6111e7d80552a3a65b100e512d4e487770c Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Nov 2020 11:52:33 -0500 Subject: [PATCH 0543/2950] correct tunnel build record size to decrept --- libi2pd/RouterContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 4d60e193..7525eceb 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -698,8 +698,8 @@ namespace i2p encrypted += 32; uint8_t nonce[12]; memset (nonce, 0, 12); - if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, TUNNEL_BUILD_RECORD_SIZE - 16, - m_CurrentNoiseState->m_H, 32, m_CurrentNoiseState->m_CK + 32, nonce, data, TUNNEL_BUILD_RECORD_SIZE - 16, false)) // decrypt + 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; From 21501cbf819a4bf20a82e3c902c8bedd9a6208c1 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Nov 2020 13:31:28 -0500 Subject: [PATCH 0544/2950] correct MixHash after decryption --- libi2pd/RouterContext.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 7525eceb..4a142291 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -687,10 +687,8 @@ namespace i2p if (IsECIES ()) { if (!m_InitialNoiseState) return false; - m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState ()); // m_InitialNoiseState is h = SHA256(h || hepk) - memcpy (m_CurrentNoiseState->m_CK, m_InitialNoiseState->m_CK, 64); - memcpy (m_CurrentNoiseState->m_H, m_InitialNoiseState->m_H, 32); + m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false); @@ -704,7 +702,7 @@ namespace i2p LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); return false; } - m_CurrentNoiseState->MixHash (encrypted, TUNNEL_BUILD_RECORD_SIZE); // h = SHA256(h || ciphertext) + m_CurrentNoiseState->MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) return true; } else From 1740715c001ff4e25ad7ffdc8f076b00ef4cab4e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Nov 2020 21:04:28 -0500 Subject: [PATCH 0545/2950] correct reply key and IV for ECIES record --- libi2pd/I2NPProtocol.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 3cc254e6..283c5641 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -410,20 +410,29 @@ namespace i2p for (int j = 0; j < num; j++) { uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE; - if (isECIES && j == i) - { - uint8_t nonce[12]; - memset (nonce, 0, 12); - auto noiseState = std::move (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 (isECIES) + { + if (j == i) { - LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed"); - return false; + uint8_t nonce[12]; + memset (nonce, 0, 12); + auto noiseState = std::move (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 + { + 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); } } else - { + { encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET); encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET); encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply); @@ -466,7 +475,7 @@ namespace i2p { if (i2p::context.IsECIES ()) { - uint8_t clearText[TUNNEL_BUILD_RECORD_SIZE]; + 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 From 6362a7bba55fd405d2ddd7a896970ddabb9f446d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Nov 2020 15:27:37 -0500 Subject: [PATCH 0546/2950] decrypt garlic on ECIES router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 34 ++++++++++------------- libi2pd/RouterContext.cpp | 9 ++++++ libi2pd/RouterContext.h | 2 +- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index aef273ed..8b67960c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -176,15 +176,6 @@ namespace garlic memcpy (m_H, hh, 32); } - void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, buf, len); - SHA256_Final (m_H, &ctx); - } - void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) { memset (nonce, 0, 4); @@ -257,7 +248,7 @@ namespace garlic uint8_t sharedSecret[32]; GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + MixKey (sharedSecret); // decrypt flags/static uint8_t nonce[12], fs[32]; @@ -277,7 +268,7 @@ namespace garlic // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + MixKey (sharedSecret); } else // all zeros flags CreateNonce (1, nonce); @@ -289,10 +280,13 @@ namespace garlic LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed"); return false; } - if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext) + m_State = eSessionStateNewSessionReceived; - GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); - + if (isStatic) + { + MixHash (buf, len); // h = SHA256(h || ciphertext) + GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); + } HandlePayload (payload.data (), len - 16, nullptr, 0); return true; @@ -469,7 +463,7 @@ namespace garlic MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + MixKey (sharedSecret); // encrypt static key section uint8_t nonce[12]; CreateNonce (0, nonce); @@ -482,7 +476,7 @@ namespace garlic offset += 48; // KDF2 GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + MixKey (sharedSecret); // encrypt payload if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt { @@ -520,9 +514,9 @@ namespace garlic MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; m_EphemeralKeys->Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + MixKey (sharedSecret); m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + MixKey (sharedSecret); uint8_t nonce[12]; CreateNonce (0, nonce); // calculate hash for zero length @@ -607,9 +601,9 @@ namespace garlic { // only fist time, we assume ephemeral keys the same m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32) + MixKey (sharedSecret); GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) - i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64) + MixKey (sharedSecret); } uint8_t nonce[12]; CreateNonce (0, nonce); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 4a142291..74f8ad34 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -653,6 +653,15 @@ namespace i2p i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, 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; + } + + void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 402d3816..139cc35e 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -135,7 +135,7 @@ namespace i2p // implements GarlicDestination void HandleI2NPMessage (const uint8_t * buf, size_t len); - bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len) { return false; }; // not implemented + bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len); private: From 4ba1be2dc08a26a646e8c9946fbe9aeefc6425ec Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Nov 2020 21:21:46 -0500 Subject: [PATCH 0547/2950] one time garlic encryption for ECIES routers --- libi2pd/Destination.cpp | 10 ++--- libi2pd/ECIESX25519AEADRatchetSession.cpp | 49 ++++++++++++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 17 ++++---- libi2pd/Garlic.cpp | 17 ++++++-- libi2pd/Garlic.h | 4 +- 5 files changed, 66 insertions(+), 31 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 927e98a0..bf6047b2 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -559,9 +559,7 @@ namespace client m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound); - if (floodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented - msg = WrapMessage (floodfill, msg); + auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); @@ -756,10 +754,8 @@ namespace client else AddSessionKey (replyKey, replyTag); - auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - request->replyTunnel, replyKey, replyTag, isECIES); - if (nextFloodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented - msg = WrapMessage (nextFloodfill, msg); + auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + request->replyTunnel, replyKey, replyTag, isECIES)); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 8b67960c..bd8d2fe6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -446,7 +446,7 @@ namespace garlic LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created"); } - bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) + bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen, bool isStatic) { ResetKeys (); // we are Alice, bpk is m_RemoteStaticKey @@ -464,31 +464,47 @@ namespace garlic uint8_t sharedSecret[32]; m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) MixKey (sharedSecret); - // encrypt static key section + // encrypt flags/static key section uint8_t nonce[12]; CreateNonce (0, nonce); - if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt + const uint8_t * fs; + if (isStatic) + fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); + else { - LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed "); + memset (out + offset, 0, 32); // all zeros flags section + fs = out + offset; + } + if (!i2p::crypto::AEADChaCha20Poly1305 (fs, 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt + { + LogPrint (eLogWarning, "Garlic: Flags/static section AEAD encryption failed "); return false; } + MixHash (out + offset, 48); // h = SHA256(h || ciphertext) offset += 48; // KDF2 - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) - MixKey (sharedSecret); + if (isStatic) + { + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) + MixKey (sharedSecret); + } + else + CreateNonce (1, 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 section AEAD encryption failed"); return false; } - MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) - + m_State = eSessionStateNewSessionSent; - if (GetOwner ()) - GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); - + if (isStatic) + { + MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) + if (GetOwner ()) + GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); + } return true; } @@ -778,6 +794,11 @@ namespace garlic return nullptr; len += 72; break; + case eSessionStateOneTime: + if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen, false)) + return nullptr; + len += 96; + break; default: return nullptr; } @@ -788,6 +809,12 @@ namespace garlic return m; } + std::shared_ptr ECIESX25519AEADRatchetSession::WrapOneTimeMessage (std::shared_ptr msg) + { + m_State = eSessionStateOneTime; + return WrapSingleMessage (msg); + } + std::vector ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr msg, bool first) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 1c377b28..755531a3 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -31,7 +31,7 @@ namespace garlic const int ECIESX25519_SEND_INACTIVITY_TIMEOUT = 5000; // number of milliseconds we can send empty(pyaload only) packet after const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 - const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 4096; // number of tags we request new tagset after + const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 8192; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; @@ -129,7 +129,9 @@ namespace garlic const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02; const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04; - class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this + class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, + private i2p::crypto::NoiseSymmetricState, + public std::enable_shared_from_this { enum SessionState { @@ -137,7 +139,8 @@ namespace garlic eSessionStateNewSessionReceived, eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, - eSessionStateEstablished + eSessionStateEstablished, + eSessionStateOneTime }; struct DHRatchet @@ -155,7 +158,8 @@ 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); + const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } @@ -175,7 +179,6 @@ namespace garlic private: void ResetKeys (); - void MixHash (const uint8_t * buf, size_t len); void CreateNonce (uint64_t seqn, uint8_t * nonce); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes std::shared_ptr CreateNewSessionTagset (); @@ -186,7 +189,7 @@ namespace garlic void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); - bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); + bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen, bool isStatic = true); 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); @@ -200,7 +203,7 @@ namespace garlic private: - uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32]; + uint8_t m_RemoteStaticKey[32]; uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only std::shared_ptr m_EphemeralKeys; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 5f76bca1..d8d034a1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -709,11 +709,20 @@ namespace garlic } } - std::shared_ptr GarlicDestination::WrapMessage (std::shared_ptr destination, - std::shared_ptr msg, bool attachLeaseSet) + std::shared_ptr GarlicDestination::WrapMessageForRouter (std::shared_ptr router, + std::shared_ptr msg) { - auto session = GetRoutingSession (destination, attachLeaseSet); - return session->WrapSingleMessage (msg); + if (router->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + { + auto session = std::make_shared(this, false); + session->SetRemoteStaticKey (router->GetIdentity ()->GetEncryptionPublicKey ()); + return session->WrapOneTimeMessage (msg); + } + else + { + auto session = GetRoutingSession (router, false); + return session->WrapSingleMessage (msg); + } } std::shared_ptr GarlicDestination::GetRoutingSession ( diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 3c5d5de6..8df830c7 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -238,8 +238,8 @@ namespace garlic std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags (); void RemoveDeliveryStatusSession (uint32_t msgID); - std::shared_ptr WrapMessage (std::shared_ptr destination, - std::shared_ptr msg, bool attachLeaseSet = false); + std::shared_ptr WrapMessageForRouter (std::shared_ptr router, + 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 From 07b77443ddbdacf9b49221d675d9c37e997a2c46 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Nov 2020 18:28:38 -0500 Subject: [PATCH 0548/2950] don't handle TunnelBuild message for ECIES router --- libi2pd/I2NPProtocol.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 283c5641..5ad6df78 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -448,7 +448,7 @@ namespace i2p { int num = buf[0]; LogPrint (eLogDebug, "I2NP: VariableTunnelBuild ", num, " records"); - if (len < num*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 1) + if (len < num*TUNNEL_BUILD_RECORD_SIZE + 1) { LogPrint (eLogError, "VaribleTunnelBuild message of ", num, " records is too short ", len); return; @@ -516,7 +516,12 @@ namespace i2p void HandleTunnelBuildMsg (uint8_t * buf, size_t len) { - if (len < NUM_TUNNEL_BUILD_RECORDS*BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE) + if (i2p::context.IsECIES ()) + { + LogPrint (eLogWarning, "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); return; From 1c7780a423659ddd7fa49d9c672992a505a9dcb8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 9 Nov 2020 15:35:50 -0500 Subject: [PATCH 0549/2950] garlic clove block for router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index bd8d2fe6..1d51e67e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -899,7 +899,7 @@ namespace garlic } } // msg - if (msg && m_Destination) + if (msg) offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset); // ack if (m_AckRequests.size () > 0) From 7e874eaa7ce707f45a3b2a46db74ae8d48b114a3 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 12 Nov 2020 15:15:02 -0500 Subject: [PATCH 0550/2950] pre-calculated h --- libi2pd/TunnelConfig.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index c0ebb766..a1b234a1 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -152,8 +152,13 @@ namespace tunnel void InitBuildRequestRecordNoiseState (i2p::crypto::NoiseSymmetricState& state) { static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars + static const uint8_t hh[32] = + { + 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, + 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 + }; // SHA256 (protocol_name || 0) memcpy (state.m_CK, protocolName, 32); // ck = h = protocol_name || 0 - SHA256 (state.m_CK, 32, state.m_H); // h = SHA256(h); + memcpy (state.m_H, hh, 32); // h = SHA256(h) } } } \ No newline at end of file From 62cd9fffa39bc296268b6134cd903d2705023835 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 15 Nov 2020 01:31:20 +0300 Subject: [PATCH 0551/2950] Automate AES-NI and AVX detection on runtime, make it default on x86-based systems (#1578) Rework CPU extensions detection code and build with AES-NI and AVX support by default --- .github/workflows/build-osx.yml | 20 +++ .github/workflows/build-qt.yml | 20 --- .github/workflows/build.yml | 18 ++- .gitignore | 3 +- Makefile | 7 +- Makefile.homebrew | 7 +- Makefile.linux | 21 +-- Makefile.mingw | 17 +-- Makefile.osx | 8 +- build/CMakeLists.txt | 16 +- build/build_mingw.cmd | 29 ++-- .../installer.iss => build/win_installer.iss | 13 +- contrib/i2pd.conf | 9 ++ daemon/Daemon.cpp | 5 +- debian/compat | 2 +- .../{02-fix-1210.patch => 01-fix-1210.patch} | 0 debian/patches/01-tune-build-opts.patch | 15 -- debian/patches/series | 3 +- libi2pd/CPU.cpp | 33 ++-- libi2pd/CPU.h | 2 +- libi2pd/Config.cpp | 18 ++- libi2pd/Crypto.cpp | 143 +++++++++--------- libi2pd/Crypto.h | 13 +- libi2pd/Identity.cpp | 2 +- libi2pd/api.cpp | 5 +- qt/i2pd_qt/i2pd_qt.pro | 16 +- 26 files changed, 208 insertions(+), 237 deletions(-) create mode 100644 .github/workflows/build-osx.yml delete mode 100644 .github/workflows/build-qt.yml rename Win32/installer.iss => build/win_installer.iss (75%) rename debian/patches/{02-fix-1210.patch => 01-fix-1210.patch} (100%) delete mode 100644 debian/patches/01-tune-build-opts.patch diff --git a/.github/workflows/build-osx.yml b/.github/workflows/build-osx.yml new file mode 100644 index 00000000..50672d26 --- /dev/null +++ b/.github/workflows/build-osx.yml @@ -0,0 +1,20 @@ +name: Build on OSX + +on: [push, pull_request] + +jobs: + build: + name: With USE_UPNP=${{ matrix.with_upnp }} + runs-on: macOS-latest + strategy: + fail-fast: true + matrix: + with_upnp: ['yes', 'no'] + steps: + - uses: actions/checkout@v2 + - name: install packages + run: | + brew update + brew install boost miniupnpc openssl@1.1 + - name: build application + run: make HOMEBREW=1 USE_UPNP=${{ matrix.with_upnp }} PREFIX=$GITHUB_WORKSPACE/output -j3 diff --git a/.github/workflows/build-qt.yml b/.github/workflows/build-qt.yml deleted file mode 100644 index d4fde2b9..00000000 --- a/.github/workflows/build-qt.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Build on Ubuntu - -on: [push, pull_request] - -jobs: - build: - name: With QT GUI - runs-on: ubuntu-16.04 - 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 qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - - name: build application - run: | - cd qt/i2pd_qt - qmake - make -j3 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e5152e0..bb995219 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,4 +18,20 @@ jobs: sudo apt-get update sudo apt-get install build-essential libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev - name: build application - run: make USE_AVX=no USE_AESNI=no USE_UPNP=${{ matrix.with_upnp }} -j3 + run: make USE_UPNP=${{ matrix.with_upnp }} -j3 + + build_qt: + name: With QT GUI + runs-on: ubuntu-16.04 + 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 qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev + - name: build application + run: | + cd qt/i2pd_qt + qmake + make -j3 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3319fa10..2506fd93 100644 --- a/.gitignore +++ b/.gitignore @@ -3,11 +3,12 @@ router.info router.keys i2p -libi2pd.so netDb /i2pd /libi2pd.a /libi2pdclient.a +/libi2pd.so +/libi2pdclient.so *.exe diff --git a/Makefile b/Makefile index 35d76b82..c359d7c7 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,6 @@ DAEMON_SRC_DIR := daemon include filelist.mk USE_AESNI := yes -USE_AVX := yes USE_STATIC := no USE_MESHNET := no USE_UPNP := no @@ -77,7 +76,7 @@ deps: mk_obj_dir @sed -i -e '/\.o:/ s/^/obj\//' $(DEPS) obj/%.o: %.cpp - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(CPU_FLAGS) -c -o $@ $< + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< # '-' is 'ignore if missing' on first run -include $(DEPS) @@ -88,11 +87,11 @@ $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) ifneq ($(USE_STATIC),yes) - $(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^ + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif $(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) - $(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^ + $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) $(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) $(AR) -r $@ $^ diff --git a/Makefile.homebrew b/Makefile.homebrew index 64301c02..c1992296 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -35,10 +35,7 @@ endif # Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2 # Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic ifeq ($(USE_AESNI),yes) - CXXFLAGS += -maes -endif -ifeq ($(USE_AVX),1) - CXXFLAGS += -mavx + CXXFLAGS += -D__AES__ -maes endif install: all @@ -51,4 +48,4 @@ install: all @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 - @ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf \ No newline at end of file + @ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf diff --git a/Makefile.linux b/Makefile.linux index 3ef4793c..6a7590c1 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -1,5 +1,5 @@ # set defaults instead redefine -CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation -Wno-psabi +CXXFLAGS ?= ${CXX_DEBUG} -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-psabi LDFLAGS ?= ${LD_DEBUG} ## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time @@ -49,7 +49,7 @@ endif # UPNP Support (miniupnpc 1.5 and higher) ifeq ($(USE_UPNP),yes) - CXXFLAGS += -DUSE_UPNP + NEEDED_CXXFLAGS += -DUSE_UPNP ifeq ($(USE_STATIC),yes) LDLIBS += $(LIBDIR)/libminiupnpc.a else @@ -58,20 +58,7 @@ endif endif ifeq ($(USE_AESNI),yes) -#check if AES-NI is supported by CPU -ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0) - machine := $(shell uname -m) - ifeq ($(machine), aarch64) - CXXFLAGS += -DARM64AES - else - CPU_FLAGS += -maes - endif -endif -endif - -ifeq ($(USE_AVX),yes) -#check if AVX supported by CPU -ifneq ($(shell $(GREP) -c avx /proc/cpuinfo),0) - CPU_FLAGS += -mavx +ifeq (, $(findstring arm, $(SYS))$(findstring aarch64, $(SYS))) # no arm and aarch64 in dumpmachine + NEEDED_CXXFLAGS += -D__AES__ -maes endif endif diff --git a/Makefile.mingw b/Makefile.mingw index 2782b715..764606b6 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -1,7 +1,7 @@ USE_WIN32_APP=yes CXX = g++ WINDRES = windres -CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN +CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -fPIC -msse INCFLAGS = -Idaemon -I. LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ @@ -42,25 +42,18 @@ LDLIBS += \ -lpthread ifeq ($(USE_WIN32_APP), yes) - CXXFLAGS += -DWIN32_APP + NEEDED_CXXFLAGS += -DWIN32_APP LDFLAGS += -mwindows DAEMON_RC += Win32/Resource.rc DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) endif ifeq ($(USE_WINXP_FLAGS), yes) - CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 + NEEDED_CXXFLAGS += -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 endif -# don't change following line to ifeq ($(USE_AESNI),yes) !!! -ifeq ($(USE_AESNI),1) - CPU_FLAGS += -maes -else - CPU_FLAGS += -msse -endif - -ifeq ($(USE_AVX),1) - CPU_FLAGS += -mavx +ifeq ($(USE_AESNI),yes) + NEEDED_CXXFLAGS += -D__AES__ -maes endif ifeq ($(USE_ASLR),yes) diff --git a/Makefile.osx b/Makefile.osx index c6af4fc2..2e52585e 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -22,12 +22,8 @@ ifeq ($(USE_UPNP),yes) endif endif -ifeq ($(USE_AESNI),1) - CXXFLAGS += -maes +ifeq ($(USE_AESNI),yes) + CXXFLAGS += -D__AES__ -maes else CXXFLAGS += -msse endif - -ifeq ($(USE_AVX),1) - CXXFLAGS += -mavx -endif diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 827e20d3..6f9fbae6 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -11,9 +11,8 @@ if(WIN32 OR MSVC OR MSYS OR MINGW) message(SEND_ERROR "cmake build for windows is not supported. Please use MSYS2 with makefiles in project root.") endif() -# configurale options -option(WITH_AESNI "Use AES-NI instructions set" OFF) -option(WITH_AVX "Use AVX instructions" OFF) +# configurable options +option(WITH_AESNI "Use AES-NI instructions set" ON) option(WITH_HARDENING "Use hardening compiler flags" OFF) option(WITH_LIBRARY "Build library" ON) option(WITH_BINARY "Build binary" ON) @@ -189,13 +188,11 @@ if(UNIX) endif() endif() -if(WITH_AESNI) +# Note: AES-NI and AVX is available on x86-based CPU's. +# Here also ARM64 implementation, but currently we don't support it. +if(WITH_AESNI AND (ARCHITECTURE MATCHES "x86_64" OR ARCHITECTURE MATCHES "i386")) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes") - add_definitions(-DAESNI) -endif() - -if(WITH_AVX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx") + add_definitions(-D__AES__) endif() if(WITH_ADDRSANITIZER) @@ -309,7 +306,6 @@ message(STATUS "Architecture : ${ARCHITECTURE}") message(STATUS "Install prefix: : ${CMAKE_INSTALL_PREFIX}") message(STATUS "Options:") message(STATUS " AESNI : ${WITH_AESNI}") -message(STATUS " AVX : ${WITH_AVX}") message(STATUS " HARDENING : ${WITH_HARDENING}") message(STATUS " LIBRARY : ${WITH_LIBRARY}") message(STATUS " BINARY : ${WITH_BINARY}") diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index ec861bb2..37a1d454 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -30,10 +30,10 @@ REM we must work in root of repo cd .. REM deleting old log files -del /S build_*.log >> nul +del /S build_*.log >> nul 2>&1 echo Receiving latest commit and cleaning up... -%xSH% "git pull && make clean" > build/build_git.log 2>&1 +%xSH% "git checkout contrib/* && git pull && make clean" > build/build.log 2>&1 echo. REM set to variable current commit hash @@ -43,16 +43,17 @@ FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO ( %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) +%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/*" > build/build.log 2>&1 + REM starting building set MSYSTEM=MINGW32 set bitness=32 call :BUILDING -echo. set MSYSTEM=MINGW64 set bitness=64 call :BUILDING -echo. REM building for WinXP set "WD=C:\msys64-xp\usr\bin\" @@ -62,7 +63,10 @@ set "xSH=%WD%bash -lc" call :BUILDING_XP echo. -del README.txt >> nul +REM compile installer +C:\PROGRA~2\INNOSE~1\ISCC.exe build\win_installer.iss + +del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul echo Build complete... pause @@ -70,20 +74,13 @@ exit /b 0 :BUILDING %xSH% "make clean" >> nul -echo Building i2pd %tag% for win%bitness%: -echo Build AVX+AESNI... -%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_aesni_%tag%.log 2>&1 -echo Build AVX... -%xSH% "make DEBUG=no USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip %FILELIST% && make clean" > build/build_win%bitness%_avx_%tag%.log 2>&1 -echo Build AESNI... -%xSH% "make DEBUG=no USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip %FILELIST% && make clean" > build/build_win%bitness%_aesni_%tag%.log 2>&1 -echo Build without extensions... -%xSH% "make DEBUG=no USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip %FILELIST% && make clean" > build/build_win%bitness%_%tag%.log 2>&1 +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... -%xSH% "make DEBUG=no USE_UPNP=yes USE_WINXP_FLAGS=yes -j%threads% && zip -r9 build/i2pd_%tag%_winxp_mingw.zip %FILELIST% && make clean" > build/build_winxp_%tag%.log 2>&1 +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 diff --git a/Win32/installer.iss b/build/win_installer.iss similarity index 75% rename from Win32/installer.iss rename to build/win_installer.iss index cc40c409..007cd643 100644 --- a/Win32/installer.iss +++ b/build/win_installer.iss @@ -1,6 +1,7 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.34.0" #define I2Pd_Publisher "PurpleI2P" +; Get application version from compiled binary +#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe") [Setup] AppName={#I2Pd_AppName} @@ -10,9 +11,9 @@ DefaultDirName={pf}\I2Pd DefaultGroupName=I2Pd UninstallDisplayIcon={app}\I2Pd.exe OutputDir=. -LicenseFile=../LICENSE +LicenseFile=..\LICENSE OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} -SetupIconFile=mask.ico +SetupIconFile=..\Win32\mask.ico InternalCompressLevel=ultra64 Compression=lzma/ultra64 SolidCompression=true @@ -23,10 +24,12 @@ AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2} AppPublisherURL=http://i2pd.website/ AppSupportURL=https://github.com/PurpleI2P/i2pd/issues AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases +CloseApplications=yes [Files] -Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64 -Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64 +Source: ..\i2pd_x32.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64; MinVersion: 6.0 +Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64; MinVersion: 6.0 +Source: ..\i2pd_xp.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64; OnlyBelowVersion: 6.0 Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 2174abe8..5ef39bc9 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -229,3 +229,12 @@ verify = true [persist] ## Save peer profiles on disk (default: true) # profiles = true + +[cpuext] +## Use CPU AES-NI instructions set when work with cryptography when available (default: true) +# aesni = true +## Use CPU AVX instructions set when work with cryptography when available (default: true) +# avx = true +## Force usage of CPU instructions set, even if they not found +## DO NOT TOUCH that option if you really don't know what are you doing! +# force = false \ No newline at end of file diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 0317704a..839495a5 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -128,7 +128,10 @@ namespace i2p LogPrint(eLogDebug, "FS: data directory: ", datadir); bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); - i2p::crypto::InitCrypto (precomputation); + bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); + bool avx; i2p::config::GetOption("cpuext.avx", avx); + bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt); + i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt); int netID; i2p::config::GetOption("netid", netID); i2p::context.SetNetID (netID); diff --git a/debian/compat b/debian/compat index f11c82a4..9a037142 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 \ No newline at end of file +10 \ No newline at end of file diff --git a/debian/patches/02-fix-1210.patch b/debian/patches/01-fix-1210.patch similarity index 100% rename from debian/patches/02-fix-1210.patch rename to debian/patches/01-fix-1210.patch diff --git a/debian/patches/01-tune-build-opts.patch b/debian/patches/01-tune-build-opts.patch deleted file mode 100644 index e06a8621..00000000 --- a/debian/patches/01-tune-build-opts.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: i2pd/Makefile -=================================================================== ---- i2pd.orig/Makefile -+++ i2pd/Makefile -@@ -13,8 +13,8 @@ DAEMON_SRC_DIR := daemon - - include filelist.mk - --USE_AESNI := yes --USE_AVX := yes -+USE_AESNI := no -+USE_AVX := no - USE_STATIC := no - USE_MESHNET := no - USE_UPNP := no diff --git a/debian/patches/series b/debian/patches/series index 002802b5..07f821c8 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1 @@ -01-tune-build-opts.patch -02-fix-1210.patch +01-fix-1210.patch diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index e7eff473..0bd830e3 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -27,37 +27,24 @@ namespace cpu bool aesni = false; bool avx = false; - void Detect() + void Detect(bool AesSwitch, bool AvxSwitch, bool force) { -#if defined(__AES__) || defined(__AVX__) - #if defined(__x86_64__) || defined(__i386__) int info[4]; __cpuid(0, info[0], info[1], info[2], info[3]); if (info[0] >= 0x00000001) { __cpuid(0x00000001, info[0], info[1], info[2], info[3]); -#ifdef __AES__ - aesni = info[2] & bit_AES; // AESNI -#endif // __AES__ -#ifdef __AVX__ - avx = info[2] & bit_AVX; // AVX -#endif // __AVX__ + if ((info[2] & bit_AES && AesSwitch) || (AesSwitch && force)) { + aesni = true; + } + if ((info[2] & bit_AVX && AvxSwitch) || (AvxSwitch && force)) { + avx = true; + } } -#endif // defined(__x86_64__) || defined(__i386__) +#endif // defined(__x86_64__) || defined(__i386__) -#ifdef __AES__ - if(aesni) - { - LogPrint(eLogInfo, "AESNI enabled"); - } -#endif // __AES__ -#ifdef __AVX__ - if(avx) - { - LogPrint(eLogInfo, "AVX enabled"); - } -#endif // __AVX__ -#endif // defined(__AES__) || defined(__AVX__) + LogPrint(eLogInfo, "AESNI ", (aesni ? "enabled" : "disabled")); + LogPrint(eLogInfo, "AVX ", (avx ? "enabled" : "disabled")); } } } diff --git a/libi2pd/CPU.h b/libi2pd/CPU.h index 9677b293..f021bccb 100644 --- a/libi2pd/CPU.h +++ b/libi2pd/CPU.h @@ -16,7 +16,7 @@ namespace cpu extern bool aesni; extern bool avx; - void Detect(); + void Detect(bool AesSwitch, bool AvxSwitch, bool force); } } diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index fc479532..d99fdde1 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -47,11 +47,11 @@ namespace config { ("ifname", value()->default_value(""), "Network interface to bind to") ("ifname4", value()->default_value(""), "Network interface to bind to for ipv4") ("ifname6", value()->default_value(""), "Network interface to bind to for ipv6") - ("nat", value()->default_value(true), "Should we assume we are behind NAT? (default: enabled)") + ("nat", bool_switch()->default_value(true), "Should we assume we are behind NAT? (default: enabled)") ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") - ("ipv4", value()->default_value(true), "Enable communication through ipv4 (default: enabled)") + ("ipv4", bool_switch()->default_value(true), "Enable communication through ipv4 (default: enabled)") ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)") - ("reservedrange", value()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") + ("reservedrange", bool_switch()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") ("daemon", bool_switch()->default_value(false), "Router will go to background after start (default: disabled)") ("service", bool_switch()->default_value(false), "Router will use system folders like '/var/lib/i2pd' (default: disabled)") @@ -59,8 +59,8 @@ 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", value()->default_value(false), "Ignored. Always false") - ("ssu", value()->default_value(true), "Enable SSU transport (default: enabled)") + ("ntcp", bool_switch()->default_value(false), "Ignored. Always false") + ("ssu", bool_switch()->default_value(true), "Enable SSU transport (default: enabled)") ("ntcpproxy", value()->default_value(""), "Ignored") #ifdef _WIN32 ("svcctl", value()->default_value(""), "Windows service management ('install' or 'remove')") @@ -266,6 +266,13 @@ namespace config { ("persist.addressbook", value()->default_value(true), "Persist full addresses (default: true)") ; + options_description cpuext("CPU encryption extensions options"); + cpuext.add_options() + ("cpuext.aesni", bool_switch()->default_value(true), "Use auto detection for AESNI CPU extensions. If false, AESNI will be not used") + ("cpuext.avx", bool_switch()->default_value(true), "Use auto detection for AVX CPU extensions. If false, AVX will be not used") + ("cpuext.force", bool_switch()->default_value(false), "Force usage of CPU extensions. Useful when cpuinfo is not available on virtual machines") + ; + m_OptionsDesc .add(general) .add(limits) @@ -286,6 +293,7 @@ namespace config { .add(ntcp2) .add(nettime) .add(persist) + .add(cpuext) ; } diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index ea2cd675..523828ce 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -119,7 +119,7 @@ namespace crypto ~CryptoConstants () { - BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae); + BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae); } }; @@ -522,7 +522,7 @@ namespace crypto bn2buf (y, encrypted + len, len); RAND_bytes (encrypted + 2*len, 256 - 2*len); } - // ecryption key and iv + // encryption key and iv EC_POINT_mul (curve, p, nullptr, key, k, ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); uint8_t keyBuf[64], iv[64], shared[32]; @@ -638,7 +638,7 @@ namespace crypto { uint64_t buf[256]; uint64_t hash[12]; // 96 bytes -#ifdef __AVX__ +#if defined(__x86_64__) || defined(__i386__) if(i2p::cpu::avx) { __asm__ @@ -657,7 +657,7 @@ namespace crypto : : [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads), [buf]"r"(buf), [hash]"r"(hash) - : "memory", "%xmm0" // TODO: change to %ymm0 later + : "memory", "%xmm0" // TODO: change to %ymm0 later ); } else @@ -688,7 +688,7 @@ namespace crypto // concatenate with msg memcpy (buf + 8, msg, len); // calculate first hash - MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes + MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes // calculate digest MD5((uint8_t *)hash, 96, digest); @@ -696,35 +696,28 @@ namespace crypto // AES #ifdef __AES__ - #ifdef ARM64AES - void init_aesenc(void){ - // TODO: Implementation - } - - #endif - #define KeyExpansion256(round0,round1) \ - "pshufd $0xff, %%xmm2, %%xmm2 \n" \ - "movaps %%xmm1, %%xmm4 \n" \ - "pslldq $4, %%xmm4 \n" \ + "pshufd $0xff, %%xmm2, %%xmm2 \n" \ + "movaps %%xmm1, %%xmm4 \n" \ + "pslldq $4, %%xmm4 \n" \ "pxor %%xmm4, %%xmm1 \n" \ - "pslldq $4, %%xmm4 \n" \ + "pslldq $4, %%xmm4 \n" \ "pxor %%xmm4, %%xmm1 \n" \ - "pslldq $4, %%xmm4 \n" \ + "pslldq $4, %%xmm4 \n" \ "pxor %%xmm4, %%xmm1 \n" \ "pxor %%xmm2, %%xmm1 \n" \ - "movaps %%xmm1, "#round0"(%[sched]) \n" \ + "movaps %%xmm1, "#round0"(%[sched]) \n" \ "aeskeygenassist $0, %%xmm1, %%xmm4 \n" \ - "pshufd $0xaa, %%xmm4, %%xmm2 \n" \ - "movaps %%xmm3, %%xmm4 \n" \ - "pslldq $4, %%xmm4 \n" \ + "pshufd $0xaa, %%xmm4, %%xmm2 \n" \ + "movaps %%xmm3, %%xmm4 \n" \ + "pslldq $4, %%xmm4 \n" \ "pxor %%xmm4, %%xmm3 \n" \ - "pslldq $4, %%xmm4 \n" \ + "pslldq $4, %%xmm4 \n" \ "pxor %%xmm4, %%xmm3 \n" \ - "pslldq $4, %%xmm4 \n" \ + "pslldq $4, %%xmm4 \n" \ "pxor %%xmm4, %%xmm3 \n" \ "pxor %%xmm2, %%xmm3 \n" \ - "movaps %%xmm3, "#round1"(%[sched]) \n" + "movaps %%xmm3, "#round1"(%[sched]) \n" #endif #ifdef __AES__ @@ -750,16 +743,16 @@ namespace crypto KeyExpansion256(192,208) "aeskeygenassist $64, %%xmm3, %%xmm2 \n" // key expansion final - "pshufd $0xff, %%xmm2, %%xmm2 \n" - "movaps %%xmm1, %%xmm4 \n" - "pslldq $4, %%xmm4 \n" + "pshufd $0xff, %%xmm2, %%xmm2 \n" + "movaps %%xmm1, %%xmm4 \n" + "pslldq $4, %%xmm4 \n" "pxor %%xmm4, %%xmm1 \n" - "pslldq $4, %%xmm4 \n" + "pslldq $4, %%xmm4 \n" "pxor %%xmm4, %%xmm1 \n" - "pslldq $4, %%xmm4 \n" + "pslldq $4, %%xmm4 \n" "pxor %%xmm4, %%xmm1 \n" "pxor %%xmm2, %%xmm1 \n" - "movups %%xmm1, 224(%[sched]) \n" + "movups %%xmm1, 224(%[sched]) \n" : // output : [key]"r"((const uint8_t *)key), [sched]"r"(GetKeySchedule ()) // input : "%xmm1", "%xmm2", "%xmm3", "%xmm4", "memory" // clogged @@ -794,9 +787,9 @@ namespace crypto { __asm__ ( - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" EncryptAES256(sched) - "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[out]) \n" : : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory" ); } @@ -833,9 +826,9 @@ namespace crypto { __asm__ ( - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" DecryptAES256(sched) - "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[out]) \n" : : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory" ); } @@ -848,7 +841,7 @@ namespace crypto #ifdef __AES__ #define CallAESIMC(offset) \ - "movaps "#offset"(%[shed]), %%xmm0 \n" \ + "movaps "#offset"(%[shed]), %%xmm0 \n" \ "aesimc %%xmm0, %%xmm0 \n" \ "movaps %%xmm0, "#offset"(%[shed]) \n" #endif @@ -873,7 +866,7 @@ namespace crypto if(i2p::cpu::aesni) { ExpandKey (key); // expand encryption key first - // then invert it using aesimc + // then invert it using aesimc __asm__ ( CallAESIMC(16) @@ -906,18 +899,18 @@ namespace crypto { __asm__ ( - "movups (%[iv]), %%xmm1 \n" + "movups (%[iv]), %%xmm1 \n" "1: \n" - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" "pxor %%xmm1, %%xmm0 \n" EncryptAES256(sched) - "movaps %%xmm0, %%xmm1 \n" - "movups %%xmm0, (%[out]) \n" + "movaps %%xmm0, %%xmm1 \n" + "movups %%xmm0, (%[out]) \n" "add $16, %[in] \n" "add $16, %[out] \n" "dec %[num] \n" "jnz 1b \n" - "movups %%xmm1, (%[iv]) \n" + "movups %%xmm1, (%[iv]) \n" : : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) @@ -951,12 +944,12 @@ namespace crypto { __asm__ ( - "movups (%[iv]), %%xmm1 \n" - "movups (%[in]), %%xmm0 \n" + "movups (%[iv]), %%xmm1 \n" + "movups (%[in]), %%xmm0 \n" "pxor %%xmm1, %%xmm0 \n" EncryptAES256(sched) - "movups %%xmm0, (%[out]) \n" - "movups %%xmm0, (%[iv]) \n" + "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[iv]) \n" : : [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()), [in]"r"(in), [out]"r"(out) @@ -975,19 +968,19 @@ namespace crypto { __asm__ ( - "movups (%[iv]), %%xmm1 \n" + "movups (%[iv]), %%xmm1 \n" "1: \n" - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" "movaps %%xmm0, %%xmm2 \n" DecryptAES256(sched) "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[out]) \n" "movaps %%xmm2, %%xmm1 \n" "add $16, %[in] \n" "add $16, %[out] \n" "dec %[num] \n" "jnz 1b \n" - "movups %%xmm1, (%[iv]) \n" + "movups %%xmm1, (%[iv]) \n" : : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), [in]"r"(in), [out]"r"(out), [num]"r"(numBlocks) @@ -1021,12 +1014,12 @@ namespace crypto { __asm__ ( - "movups (%[iv]), %%xmm1 \n" - "movups (%[in]), %%xmm0 \n" - "movups %%xmm0, (%[iv]) \n" + "movups (%[iv]), %%xmm1 \n" + "movups (%[in]), %%xmm0 \n" + "movups %%xmm0, (%[iv]) \n" DecryptAES256(sched) "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[out]) \n" : : [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()), [in]"r"(in), [out]"r"(out) @@ -1046,7 +1039,7 @@ namespace crypto __asm__ ( // encrypt IV - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" EncryptAES256(sched_iv) "movaps %%xmm0, %%xmm1 \n" // double IV encryption @@ -1056,11 +1049,11 @@ namespace crypto "1: \n" "add $16, %[in] \n" "add $16, %[out] \n" - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" "pxor %%xmm1, %%xmm0 \n" EncryptAES256(sched_l) - "movaps %%xmm0, %%xmm1 \n" - "movups %%xmm0, (%[out]) \n" + "movaps %%xmm0, %%xmm1 \n" + "movups %%xmm0, (%[out]) \n" "dec %[num] \n" "jnz 1b \n" : @@ -1097,11 +1090,11 @@ namespace crypto "1: \n" "add $16, %[in] \n" "add $16, %[out] \n" - "movups (%[in]), %%xmm0 \n" + "movups (%[in]), %%xmm0 \n" "movaps %%xmm0, %%xmm2 \n" DecryptAES256(sched_l) "pxor %%xmm1, %%xmm0 \n" - "movups %%xmm0, (%[out]) \n" + "movups %%xmm0, (%[out]) \n" "movaps %%xmm2, %%xmm1 \n" "dec %[num] \n" "jnz 1b \n" @@ -1324,23 +1317,23 @@ namespace crypto } void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) - { - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, m_H, 32); - SHA256_Update (&ctx, buf, len); - SHA256_Final (m_H, &ctx); - } + { + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, m_H, 32); + SHA256_Update (&ctx, buf, len); + SHA256_Final (m_H, &ctx); + } - void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret) - { - HKDF (m_CK, sharedSecret, 32, "", m_CK); + void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret) + { + HKDF (m_CK, sharedSecret, 32, "", m_CK); // new ck is m_CK[0:31], key is m_CK[32:63] - } - + } + // init and terminate -/* std::vector > m_OpenSSLMutexes; +/* std::vector > m_OpenSSLMutexes; static void OpensslLockingCallback(int mode, int type, const char * file, int line) { if (type > 0 && (size_t)type < m_OpenSSLMutexes.size ()) @@ -1351,10 +1344,10 @@ namespace crypto m_OpenSSLMutexes[type]->unlock (); } }*/ - - void InitCrypto (bool precomputation) + + void InitCrypto (bool precomputation, bool aesni, bool avx, bool force) { - i2p::cpu::Detect (); + i2p::cpu::Detect (aesni, avx, force); #if LEGACY_OPENSSL SSL_library_init (); #endif diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 205be44d..da7a4bf4 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -169,9 +169,6 @@ namespace crypto #ifdef __AES__ - #ifdef ARM64AES - void init_aesenc(void) __attribute__((constructor)); - #endif class ECBCryptoAESNI { public: @@ -316,13 +313,13 @@ namespace crypto struct NoiseSymmetricState { uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/; - + void MixHash (const uint8_t * buf, size_t len); - void MixKey (const uint8_t * sharedSecret); - }; - + void MixKey (const uint8_t * sharedSecret); + }; + // init and terminate - void InitCrypto (bool precomputation); + void InitCrypto (bool precomputation, bool aesni, bool avx, bool force); void TerminateCrypto (); } } diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 7784cc90..88523492 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -828,7 +828,7 @@ namespace data XORMetric operator^(const IdentHash& key1, const IdentHash& key2) { XORMetric m; -#ifdef __AVX__ +#if defined(__x86_64__) || defined(__i386__) if(i2p::cpu::avx) { __asm__ diff --git a/libi2pd/api.cpp b/libi2pd/api.cpp index 569fbd8c..faeee84d 100644 --- a/libi2pd/api.cpp +++ b/libi2pd/api.cpp @@ -37,7 +37,10 @@ namespace api i2p::fs::Init(); bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); - i2p::crypto::InitCrypto (precomputation); + bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); + bool avx; i2p::config::GetOption("cpuext.avx", avx); + bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt); + i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt); int netID; i2p::config::GetOption("netid", netID); i2p::context.SetNetID (netID); diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index dba69143..eed4cd7b 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -4,14 +4,16 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app -QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized +QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-deprecated-copy CONFIG += strict_c++ c++11 CONFIG(debug, debug|release) { message(Debug build) DEFINES += DEBUG_WITH_DEFAULT_LOGGING + I2PDMAKE += DEBUG=yes } else { message(Release build) + I2PDMAKE += DEBUG=no } SOURCES += DaemonQT.cpp mainwindow.cpp \ @@ -73,19 +75,19 @@ FORMS += mainwindow.ui \ LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz -libi2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no api +libi2pd.commands = @echo Building i2pd libraries libi2pd.target = $$PWD/../../libi2pd.a -libi2pd.depends = FORCE +libi2pd.depends = i2pd FORCE -libi2pdclient.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_AVX=no USE_AESNI=no USE_UPNP=yes DEBUG=no api_client -libi2pdclient.target = $$PWD/../../libi2pdclient.a -libi2pdclient.depends = FORCE +i2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE api_client +i2pd.target += $$PWD/../../libi2pdclient.a +i2pd.depends = FORCE cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean cleani2pd.depends = clean PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -QMAKE_EXTRA_TARGETS += cleani2pd libi2pd libi2pdclient +QMAKE_EXTRA_TARGETS += cleani2pd i2pd libi2pd CLEAN_DEPS += cleani2pd From 8b3a7486c74b27199a08dc500e2a19dfe16e53a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 14 Nov 2020 18:28:50 -0500 Subject: [PATCH 0552/2950] rename CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET to CRYPTO_KEY_TYPE_ECIES_X25519_AEAD --- libi2pd/Destination.cpp | 14 +++++++------- libi2pd/ECIESX25519AEADRatchetSession.cpp | 12 ++++++------ libi2pd/Garlic.cpp | 11 ++++++----- libi2pd/Identity.cpp | 14 +++++++------- libi2pd/Identity.h | 2 +- libi2pd/RouterContext.h | 2 +- libi2pd/TunnelConfig.h | 2 +- libi2pd_client/I2CP.cpp | 8 ++++---- 8 files changed, 33 insertions(+), 32 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index bf6047b2..d51fc63d 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -744,7 +744,7 @@ namespace client request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTimeoutTimer.cancel (); - bool isECIES = SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) && + bool isECIES = SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) && nextFloodfill->GetVersion () >= MAKE_VERSION_NUMBER(0, 9, 46); // >= 0.9.46; uint8_t replyKey[32], replyTag[32]; RAND_bytes (replyKey, 32); // random session key @@ -842,8 +842,8 @@ namespace client i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const { - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) - return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; } @@ -898,7 +898,7 @@ namespace client else encryptionKey->GenerateKeys (); encryptionKey->CreateDecryptor (); - if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) { m_ECIESx25519EncryptionKey.reset (encryptionKey); if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) @@ -1215,7 +1215,7 @@ namespace client bool ClientDestination::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_RATCHET) + 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); if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor) @@ -1227,12 +1227,12 @@ namespace client bool ClientDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { - return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519EncryptionKey : (bool)m_StandardEncryptionKey; + return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? (bool)m_ECIESx25519EncryptionKey : (bool)m_StandardEncryptionKey; } const uint8_t * ClientDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { - if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) return m_ECIESx25519EncryptionKey ? m_ECIESx25519EncryptionKey->pub : nullptr; return m_StandardEncryptionKey ? m_StandardEncryptionKey->pub : nullptr; } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 1d51e67e..3dfe4ca5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -236,7 +236,7 @@ namespace garlic if (!GetOwner ()) return false; // we are Bob // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk) + MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD), 32); // h = SHA256(h || bpk) if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { @@ -247,7 +247,7 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk) + GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, aepk) MixKey (sharedSecret); // decrypt flags/static @@ -267,7 +267,7 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk) + GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, apk) MixKey (sharedSecret); } else // all zeros flags @@ -469,7 +469,7 @@ namespace garlic CreateNonce (0, nonce); const uint8_t * fs; if (isStatic) - fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); + fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); else { memset (out + offset, 0, 32); // all zeros flags section @@ -486,7 +486,7 @@ namespace garlic // KDF2 if (isStatic) { - GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk) + GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk) MixKey (sharedSecret); } else @@ -618,7 +618,7 @@ namespace garlic // only fist time, we assume ephemeral keys the same m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) MixKey (sharedSecret); - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk) + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) MixKey (sharedSecret); } uint8_t nonce[12]; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index d8d034a1..2fe97156 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -506,7 +506,7 @@ namespace garlic else { bool found = false; - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) { // try ECIESx25519 tag uint64_t tag; @@ -536,7 +536,7 @@ namespace garlic decryption->Decrypt(buf + 514, length - 514, buf + 514); HandleAESBlock (buf + 514, length - 514, decryption, msg->from); } - else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + else if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) { // otherwise ECIESx25519 auto session = std::make_shared (this, false); // incoming @@ -712,7 +712,7 @@ namespace garlic std::shared_ptr GarlicDestination::WrapMessageForRouter (std::shared_ptr router, std::shared_ptr msg) { - if (router->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + if (router->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) { auto session = std::make_shared(this, false); session->SetRemoteStaticKey (router->GetIdentity ()->GetEncryptionPublicKey ()); @@ -728,8 +728,8 @@ namespace garlic std::shared_ptr GarlicDestination::GetRoutingSession ( std::shared_ptr destination, bool attachLeaseSet) { - if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && - SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET)) + if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && + SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) { ECIESX25519AEADRatchetSessionPtr session; uint8_t staticKey[32]; @@ -771,6 +771,7 @@ namespace garlic } return session; } + return nullptr; } void GarlicDestination::CleanupExpiredTags () diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 88523492..89f6cda0 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -48,7 +48,7 @@ namespace data IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType) { - if (cryptoType == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + if (cryptoType == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) { memcpy (m_StandardIdentity.publicKey, publicKey, 32); RAND_bytes (m_StandardIdentity.publicKey + 32, 224); @@ -426,7 +426,7 @@ namespace data case CRYPTO_KEY_TYPE_ELGAMAL: return std::make_shared(key); break; - case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET: + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: return std::make_shared(key); break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: @@ -662,7 +662,7 @@ namespace data size_t PrivateKeys::GetPrivateKeyLen () const { // private key length always 256, but type 4 - return (m_Public->GetCryptoKeyType () == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) ? 32 : 256; + return (m_Public->GetCryptoKeyType () == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) ? 32 : 256; } uint8_t * PrivateKeys::GetPadding() @@ -687,6 +687,9 @@ namespace data case CRYPTO_KEY_TYPE_ELGAMAL: return std::make_shared(key); break; + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: + return std::make_shared(key); + break; case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC: case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST: return std::make_shared(key); @@ -694,9 +697,6 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC: return std::make_shared(key); break; - case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET: - return std::make_shared(key); - break; default: LogPrint (eLogError, "Identity: Unknown crypto key type ", (int)cryptoType); }; @@ -776,7 +776,7 @@ namespace data case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC: i2p::crypto::CreateECIESGOSTR3410RandomKeys (priv, pub); break; - case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET: + case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD: i2p::crypto::CreateECIESX25519AEADRatchetRandomKeys (priv, pub); break; default: diff --git a/libi2pd/Identity.h b/libi2pd/Identity.h index a36e7209..e9cf63ed 100644 --- a/libi2pd/Identity.h +++ b/libi2pd/Identity.h @@ -64,7 +64,7 @@ namespace data const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; - const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET = 4; + const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD = 4; const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 139cc35e..8c13b842 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -109,7 +109,7 @@ namespace i2p bool SupportsV4 () const { return m_RouterInfo.IsV4 (); }; void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); - bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; }; + 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 diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 518c1aad..9aed0d25 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -39,7 +39,7 @@ namespace tunnel void SetNext (TunnelHopConfig * n); void SetPrev (TunnelHopConfig * p); - bool IsECIES () const { return ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET; }; + 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); diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index d5436936..2b9df0fa 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -46,7 +46,7 @@ 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_RATCHET && m_ECIESx25519Decryptor) + if (preferredCrypto == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor) return m_ECIESx25519Decryptor->Decrypt (encrypted, data, ctx, true); if (m_Decryptor) return m_Decryptor->Decrypt (encrypted, data, ctx, true); @@ -57,14 +57,14 @@ namespace client const uint8_t * I2CPDestination::GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const { - if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET && m_ECIESx25519Decryptor) + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD && m_ECIESx25519Decryptor) return m_ECIESx25519Decryptor->GetPubicKey (); return nullptr; } bool I2CPDestination::SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const { - return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType; + return keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD ? (bool)m_ECIESx25519Decryptor : m_EncryptionKeyType == keyType; } @@ -621,7 +621,7 @@ namespace client uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length if (offset + keyLen > len) return; - if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset); else { From 1f6be38145911ef72901eb7bdc4cee881bd33ea1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Nov 2020 13:06:02 -0500 Subject: [PATCH 0553/2950] wait for publish confirmation or publish to another floodfill --- libi2pd/NetDb.cpp | 45 ++++++++++++++++++++++++++++----------- libi2pd/NetDb.hpp | 9 +++++++- libi2pd/RouterContext.cpp | 9 ++++++-- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 318db953..0768b838 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -111,6 +111,9 @@ namespace data case eI2NPDatabaseLookup: HandleDatabaseLookupMsg (msg); break; + case eI2NPDeliveryStatus: + HandleDeliveryStatusMsg (msg); + break; case eI2NPDummyMsg: // plain RouterInfo from NTCP2 with flags for now HandleNTCP2RouterInfoMsg (msg); @@ -148,10 +151,12 @@ namespace data lastDestinationCleanup = ts; } - if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // update timestamp and publish + if (!m_HiddenMode && i2p::transport::transports.IsOnline () && + ((m_PublishReplyToken && ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) || + ts - lastPublish >= NETDB_PUBLISH_INTERVAL)) // update timestamp and publish { i2p::context.UpdateTimestamp (ts); - if (!m_HiddenMode) Publish (); + Publish (); lastPublish = ts; } if (ts - lastExploratory >= 30) // exploratory every 30 seconds @@ -992,6 +997,16 @@ namespace data } } + void NetDb::HandleDeliveryStatusMsg (std::shared_ptr msg) + { + if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) + { + LogPrint (eLogInfo, "NetDb: Publishing confirmed. reply token=", m_PublishReplyToken); + m_PublishExcluded.clear (); + m_PublishReplyToken = 0; + } + } + void NetDb::Explore (int numDestinations) { // new requests @@ -1045,18 +1060,22 @@ namespace data void NetDb::Publish () { i2p::context.UpdateStats (); // for floodfill - std::set excluded; // TODO: fill up later - for (int i = 0; i < 2; i++) + + if (m_PublishExcluded.size () > NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS) { - auto floodfill = GetClosestFloodfill (i2p::context.GetRouterInfo ().GetIdentHash (), excluded); - if (floodfill) - { - uint32_t replyToken; - RAND_bytes ((uint8_t *)&replyToken, 4); - LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); - transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); - excluded.insert (floodfill->GetIdentHash ()); - } + LogPrint (eLogError, "NetDb: Couldn't publish our RouterInfo to ", NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again"); + m_PublishExcluded.clear (); + } + + auto floodfill = GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded); + if (floodfill) + { + uint32_t replyToken; + RAND_bytes ((uint8_t *)&replyToken, 4); + LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); + m_PublishExcluded.insert (floodfill->GetIdentHash ()); + m_PublishReplyToken = replyToken; + transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); } } diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index f9a57ccd..afd1f562 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -41,6 +41,8 @@ namespace data const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours const int NETDB_PUBLISH_INTERVAL = 60 * 40; + 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 /** function for visiting a leaseset stored in a floodfill */ @@ -77,6 +79,7 @@ namespace data void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); void HandleDatabaseLookupMsg (std::shared_ptr msg); void HandleNTCP2RouterInfoMsg (std::shared_ptr m); + void HandleDeliveryStatusMsg (std::shared_ptr msg); std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; @@ -115,6 +118,8 @@ namespace data void ClearRouterInfos () { m_RouterInfos.clear (); }; + uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; }; + private: void Load (); @@ -162,9 +167,11 @@ namespace data /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ std::shared_ptr m_FloodfillBootstrap; - /** true if in hidden mode */ bool m_HiddenMode; + + std::set m_PublishExcluded; + uint32_t m_PublishReplyToken = 0; }; extern NetDb netdb; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 74f8ad34..375e0b9a 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -670,8 +670,13 @@ namespace i2p void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - std::unique_lock l(m_GarlicMutex); - i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); + 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 () From af20b13c7a54a852a16024111714d17585aecdee Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Nov 2020 17:02:01 -0500 Subject: [PATCH 0554/2950] create paired inbound tunnels if no inbound tunnels yet --- libi2pd/TunnelPool.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index d0fd401f..909248ba 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -118,7 +118,6 @@ namespace tunnel std::unique_lock l(m_OutboundTunnelsMutex); m_OutboundTunnels.insert (createdTunnel); } - //CreatePairedInboundTunnel (createdTunnel); } void TunnelPool::TunnelExpired (std::shared_ptr expiredTunnel) @@ -235,6 +234,15 @@ namespace tunnel for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } + if (!num && !m_OutboundTunnels.empty ()) + { + for (auto it: m_OutboundTunnels) + { + CreatePairedInboundTunnel (it); + num++; + if (num >= m_NumInboundTunnels) break; + } + } for (int i = num; i < m_NumInboundTunnels; i++) CreateInboundTunnel (); From 44ca315c7559f44190853b9aa3da88979e89fe2b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Nov 2020 19:38:34 -0500 Subject: [PATCH 0555/2950] don't build tunnels for all pools at the time --- libi2pd/Tunnel.cpp | 28 ++++++++++++++++------------ libi2pd/Tunnel.h | 4 ++-- libi2pd/TunnelPool.cpp | 15 +++++++++++++-- libi2pd/TunnelPool.h | 4 ++++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a74c8c91..ad918787 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -474,7 +474,7 @@ namespace tunnel { std::this_thread::sleep_for (std::chrono::seconds(1)); // wait for other parts are ready - uint64_t lastTs = 0; + uint64_t lastTs = 0, lastPoolsTs = 0; while (m_IsRunning) { try @@ -535,12 +535,20 @@ namespace tunnel while (msg); } - uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - if (ts - lastTs >= 15 && i2p::transport::transports.IsOnline()) // manage tunnels every 15 seconds + if (i2p::transport::transports.IsOnline()) { - ManageTunnels (); - lastTs = ts; - } + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); + if (ts - lastTs >= 15) // manage tunnels every 15 seconds + { + ManageTunnels (); + lastTs = ts; + } + if (ts - lastPoolsTs >= 5) // manage pools every 5 seconds + { + ManageTunnelPools (ts); + lastPoolsTs = ts; + } + } } catch (std::exception& ex) { @@ -582,7 +590,6 @@ namespace tunnel ManageInboundTunnels (); ManageOutboundTunnels (); ManageTransitTunnels (); - ManageTunnelPools (); } void Tunnels::ManagePendingTunnels () @@ -794,16 +801,13 @@ namespace tunnel } } - void Tunnels::ManageTunnelPools () + void Tunnels::ManageTunnelPools (uint64_t ts) { std::unique_lock l(m_PoolsMutex); for (auto& pool : m_Pools) { if (pool && pool->IsActive ()) - { - pool->CreateTunnels (); - pool->TestTunnels (); - } + pool->ManageTunnels (ts); } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a50bc31a..37c5cddb 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -230,7 +230,7 @@ namespace tunnel void ManagePendingTunnels (); template void ManagePendingTunnels (PendingTunnels& pendingTunnels); - void ManageTunnelPools (); + void ManageTunnelPools (uint64_t ts); std::shared_ptr CreateZeroHopsInboundTunnel (); std::shared_ptr CreateZeroHopsOutboundTunnel (); @@ -249,7 +249,7 @@ namespace tunnel std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; - + // some stats int m_NumSuccesiveTunnelCreations, m_NumFailedTunnelCreations; diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 909248ba..a44fc33d 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -26,9 +26,10 @@ namespace tunnel { TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels): m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), - m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true), - m_CustomPeerSelector(nullptr) + m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), + m_IsActive (true), m_CustomPeerSelector(nullptr) { + m_NextManageTime = i2p::util::GetSecondsSinceEpoch () + rand () % TUNNEL_POOL_MANAGE_INTERVAL; } TunnelPool::~TunnelPool () @@ -321,6 +322,16 @@ namespace tunnel } } + void TunnelPool::ManageTunnels (uint64_t ts) + { + if (ts > m_NextManageTime) + { + CreateTunnels (); + TestTunnels (); + m_NextManageTime = ts + TUNNEL_POOL_MANAGE_INTERVAL + (rand () % TUNNEL_POOL_MANAGE_INTERVAL)/2; + } + } + void TunnelPool::ProcessGarlicMessage (std::shared_ptr msg) { if (m_LocalDestination) diff --git a/libi2pd/TunnelPool.h b/libi2pd/TunnelPool.h index 04ff4ae7..d1024d04 100644 --- a/libi2pd/TunnelPool.h +++ b/libi2pd/TunnelPool.h @@ -27,6 +27,8 @@ namespace i2p { namespace tunnel { + const int TUNNEL_POOL_MANAGE_INTERVAL = 10; // in seconds + class Tunnel; class InboundTunnel; class OutboundTunnel; @@ -69,6 +71,7 @@ namespace tunnel std::shared_ptr GetNextInboundTunnel (std::shared_ptr excluded = nullptr) const; std::shared_ptr GetNewOutboundTunnel (std::shared_ptr old) const; void TestTunnels (); + void ManageTunnels (uint64_t ts); void ProcessGarlicMessage (std::shared_ptr msg); void ProcessDeliveryStatus (std::shared_ptr msg); @@ -123,6 +126,7 @@ namespace tunnel mutable std::mutex m_TestsMutex; std::map, std::shared_ptr > > m_Tests; bool m_IsActive; + uint64_t m_NextManageTime; // in seconds std::mutex m_CustomPeerSelectorMutex; ITunnelPeerSelector * m_CustomPeerSelector; From 1ae98b7fe1604a7b8ba6023fb48ff5da049fb258 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 16 Nov 2020 03:38:04 +0300 Subject: [PATCH 0556/2950] [webconsole] graceful timer for windows --- Win32/Win32App.cpp | 15 ++++++--------- Win32/Win32App.h | 2 ++ daemon/HTTPServer.cpp | 13 +++++++++++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index df345b11..1785ffd6 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -43,10 +43,7 @@ namespace i2p { namespace win32 { - static DWORD GracefulShutdownEndtime = 0; - - typedef DWORD (* IPN)(); - IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); + DWORD g_GracefulShutdownEndtime = 0; static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) { @@ -167,9 +164,9 @@ namespace win32 s << "; "; s << "Success Rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%\n"; s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); - if (GracefulShutdownEndtime != 0) + if (g_GracefulShutdownEndtime != 0) { - DWORD GracefulTimeLeft = (GracefulShutdownEndtime - GetTickCountLocal()) / 1000; + DWORD GracefulTimeLeft = (g_GracefulShutdownEndtime - GetTickCount()) / 1000; s << "Graceful shutdown, time left: "; ShowUptime(s, GracefulTimeLeft); } else @@ -247,7 +244,7 @@ namespace win32 i2p::context.SetAcceptsTunnels (false); SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); // check tunnels every second - GracefulShutdownEndtime = GetTickCountLocal() + 10*60*1000; + g_GracefulShutdownEndtime = GetTickCount() + 10*60*1000; i2p::util::DaemonWin32::Instance ().isGraceful = true; return 0; } @@ -256,7 +253,7 @@ namespace win32 i2p::context.SetAcceptsTunnels (true); KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); KillTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER); - GracefulShutdownEndtime = 0; + g_GracefulShutdownEndtime = 0; i2p::util::DaemonWin32::Instance ().isGraceful = false; return 0; } @@ -343,7 +340,7 @@ namespace win32 { case IDT_GRACEFUL_SHUTDOWN_TIMER: { - GracefulShutdownEndtime = 0; + g_GracefulShutdownEndtime = 0; PostMessage (hWnd, WM_CLOSE, 0, 0); // exit return 0; } diff --git a/Win32/Win32App.h b/Win32/Win32App.h index d242f7d3..ebe49efd 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -15,6 +15,8 @@ namespace i2p { namespace win32 { + extern DWORD g_GracefulShutdownEndtime; + bool StartWin32App (); void StopWin32App (); int RunWin32App (); diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 59c530f9..ad549a00 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -270,8 +270,17 @@ namespace http { } s << "
\r\n"; #if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY)) - if (auto remains = Daemon.gracefulShutdownInterval) - s << "Stopping in: " << remains << " seconds
\r\n"; + if (auto remains = Daemon.gracefulShutdownInterval) { + s << "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: "; + ShowUptime(s, remains); + s << "
\r\n"; + } #endif auto family = i2p::context.GetFamily (); if (family.length () > 0) From 2bd6daeb8de30d6445961ba02f2975acc678bc61 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 16 Nov 2020 03:38:52 +0300 Subject: [PATCH 0557/2950] disable aes/avx for winxp by default --- libi2pd/CPU.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libi2pd/CPU.cpp b/libi2pd/CPU.cpp index 0bd830e3..0804e2ac 100644 --- a/libi2pd/CPU.cpp +++ b/libi2pd/CPU.cpp @@ -34,10 +34,18 @@ namespace cpu __cpuid(0, info[0], info[1], info[2], info[3]); if (info[0] >= 0x00000001) { __cpuid(0x00000001, info[0], info[1], info[2], info[3]); +#if defined (_WIN32) && (WINVER == 0x0501) // WinXP + if (AesSwitch && force) { // only if forced +#else if ((info[2] & bit_AES && AesSwitch) || (AesSwitch && force)) { +#endif aesni = true; } +#if defined (_WIN32) && (WINVER == 0x0501) // WinXP + if (AvxSwitch && force) { // only if forced +#else if ((info[2] & bit_AVX && AvxSwitch) || (AvxSwitch && force)) { +#endif avx = true; } } From 4a44b18b97c65211faec7cc6742a4592a5662db8 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Nov 2020 19:56:16 -0500 Subject: [PATCH 0558/2950] fixed typo --- daemon/HTTPServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index ad549a00..3c9ddde6 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -274,6 +274,7 @@ namespace http { s << "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; From b4369470cb88c43c87e657537c4e42add3d9fd4a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Nov 2020 20:05:27 -0500 Subject: [PATCH 0559/2950] publish updated RouterInfo --- libi2pd/NetDb.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 0768b838..9a90e952 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -153,6 +153,7 @@ namespace data if (!m_HiddenMode && i2p::transport::transports.IsOnline () && ((m_PublishReplyToken && ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) || + i2p::context.GetLastUpdateTime () > lastPublish || ts - lastPublish >= NETDB_PUBLISH_INTERVAL)) // update timestamp and publish { i2p::context.UpdateTimestamp (ts); From c69c4ae8a019d3d220a522797d0987877bd9da9e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 15 Nov 2020 21:46:49 -0500 Subject: [PATCH 0560/2950] don't publish too fast --- libi2pd/NetDb.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 9a90e952..4399fb15 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -151,14 +151,22 @@ namespace data lastDestinationCleanup = ts; } - if (!m_HiddenMode && i2p::transport::transports.IsOnline () && - ((m_PublishReplyToken && ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) || - i2p::context.GetLastUpdateTime () > lastPublish || - ts - lastPublish >= NETDB_PUBLISH_INTERVAL)) // update timestamp and publish + // publish + if (!m_HiddenMode && i2p::transport::transports.IsOnline ()) { - i2p::context.UpdateTimestamp (ts); - Publish (); - lastPublish = ts; + bool publish = false; + if (m_PublishReplyToken) + { + if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true; + } + else if (i2p::context.GetLastUpdateTime () > lastPublish || + ts - lastPublish >= NETDB_PUBLISH_INTERVAL) publish = true; + if (publish) // update timestamp and publish + { + i2p::context.UpdateTimestamp (ts); + Publish (); + lastPublish = ts; + } } if (ts - lastExploratory >= 30) // exploratory every 30 seconds { From 3b630fe546d76e2c19e7540d3406888c7413e15b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 16 Nov 2020 10:04:38 -0500 Subject: [PATCH 0561/2950] fixed race condition --- libi2pd/TunnelPool.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a44fc33d..a898d69e 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -292,6 +292,8 @@ namespace tunnel } // new tests + std::unique_lock l1(m_OutboundTunnelsMutex); + std::unique_lock l2(m_InboundTunnelsMutex); auto it1 = m_OutboundTunnels.begin (); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) From 3925540517d31d62d1ad89158e2a075c9d539463 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 16 Nov 2020 12:56:22 -0500 Subject: [PATCH 0562/2950] don't update expired tunnels --- libi2pd/TunnelPool.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index a898d69e..87413c3f 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -292,8 +292,6 @@ namespace tunnel } // new tests - std::unique_lock l1(m_OutboundTunnelsMutex); - std::unique_lock l2(m_InboundTunnelsMutex); auto it1 = m_OutboundTunnels.begin (); auto it2 = m_InboundTunnels.begin (); while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) @@ -363,17 +361,24 @@ namespace tunnel } if (found) { - // restore from test failed state if any - if (test.first->GetState () == eTunnelStateTestFailed) - test.first->SetState (eTunnelStateEstablished); - if (test.second->GetState () == eTunnelStateTestFailed) - test.second->SetState (eTunnelStateEstablished); uint64_t dlt = i2p::util::GetMillisecondsSinceEpoch () - timestamp; LogPrint (eLogDebug, "Tunnels: test of ", msgID, " successful. ", dlt, " milliseconds"); - // update latency uint64_t latency = dlt / 2; - test.first->AddLatencySample(latency); - test.second->AddLatencySample(latency); + // restore from test failed state if any + if (test.first) + { + if (test.first->GetState () == eTunnelStateTestFailed) + test.first->SetState (eTunnelStateEstablished); + // update latency + test.first->AddLatencySample(latency); + } + if (test.second) + { + if (test.second->GetState () == eTunnelStateTestFailed) + test.second->SetState (eTunnelStateEstablished); + // update latency + test.second->AddLatencySample(latency); + } } else { From 0a3af12ee984c0964994dbacd9fd170c08f3c75e Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 17 Nov 2020 17:59:40 +0300 Subject: [PATCH 0563/2950] [make] track changes in includes Signed-off-by: R4SAS --- Makefile | 26 +++++++++++++------------- Makefile.mingw | 4 ++-- Win32/DaemonWin32.cpp | 4 ++-- build/build_mingw.cmd | 14 +++++++------- build/win_installer.iss | 3 ++- daemon/HTTPServer.cpp | 5 +++-- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index c359d7c7..7bb3ceda 100644 --- a/Makefile +++ b/Makefile @@ -4,13 +4,12 @@ ARLIB := libi2pd.a SHLIB_CLIENT := libi2pdclient.so ARLIB_CLIENT := libi2pdclient.a I2PD := i2pd -GREP := grep -DEPS := obj/make.dep LIB_SRC_DIR := libi2pd LIB_CLIENT_SRC_DIR := libi2pd_client DAEMON_SRC_DIR := daemon +# import source files lists include filelist.mk USE_AESNI := yes @@ -50,7 +49,12 @@ ifeq ($(USE_MESHNET),yes) NEEDED_CXXFLAGS += -DMESHNET endif -NEEDED_CXXFLAGS += -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) +NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) + +LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) +LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) +DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) +DEPS := $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d) all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD) @@ -71,32 +75,29 @@ api_client: mk_obj_dir $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) ## -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. -deps: mk_obj_dir - $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) -MM *.cpp > $(DEPS) - @sed -i -e '/\.o:/ s/^/obj\//' $(DEPS) - obj/%.o: %.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -c -o $@ $< # '-' is 'ignore if missing' on first run -include $(DEPS) -DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC)) $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS) -$(SHLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) +$(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) endif -$(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) +$(SHLIB_CLIENT): $(LIB_CLIENT_OBJS) +ifneq ($(USE_STATIC),yes) $(CXX) $(LDFLAGS) -shared -o $@ $^ $(LDLIBS) $(SHLIB) +endif -$(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) +$(ARLIB): $(LIB_OBJS) $(AR) -r $@ $^ -$(ARLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) +$(ARLIB_CLIENT): $(LIB_CLIENT_OBJS) $(AR) -r $@ $^ clean: @@ -122,7 +123,6 @@ doxygen: .PHONY: all .PHONY: clean -.PHONY: deps .PHONY: doxygen .PHONY: dist .PHONY: last-dist diff --git a/Makefile.mingw b/Makefile.mingw index 764606b6..4cd2c292 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -1,8 +1,8 @@ USE_WIN32_APP=yes CXX = g++ WINDRES = windres -CXXFLAGS := ${CXX_DEBUG} -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -fPIC -msse -INCFLAGS = -Idaemon -I. +CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -fPIC -msse +INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32 LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ # detect proper flag for c++11 support by compilers diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 1214ff68..30f4f92e 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -14,10 +14,10 @@ #include "Log.h" #ifdef _WIN32 -#include "Win32/Win32Service.h" +#include "Win32Service.h" #ifdef WIN32_APP #include -#include "Win32/Win32App.h" +#include "Win32App.h" #endif namespace i2p diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index 37a1d454..e791039e 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -23,8 +23,8 @@ set "xSH=%WD%bash -lc" set "FILELIST=i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates contrib/tunnels.d" -REM detecting number of processors and subtract 1. -set /a threads=%NUMBER_OF_PROCESSORS%-1 +REM detecting number of processors +set /a threads=%NUMBER_OF_PROCESSORS% REM we must work in root of repo cd .. @@ -33,7 +33,7 @@ REM deleting old log files 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 +%xSH% "git checkout contrib/* && git pull && make clean" > build\build.log 2>&1 echo. REM set to variable current commit hash @@ -44,7 +44,7 @@ FOR /F "usebackq" %%a IN (`%xSH% 'git describe --tags'`) DO ( %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) -%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/*" > build/build.log 2>&1 +%xSH% "unix2dos contrib/i2pd.conf contrib/tunnels.conf contrib/tunnels.d/*" >> build\build.log 2>&1 REM starting building set MSYSTEM=MINGW32 @@ -64,7 +64,7 @@ call :BUILDING_XP echo. REM compile installer -C:\PROGRA~2\INNOSE~1\ISCC.exe build\win_installer.iss +C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_ver="%tag%" build\win_installer.iss >> build\build.log 2>&1 del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul @@ -75,12 +75,12 @@ exit /b 0 :BUILDING %xSH% "make clean" >> nul 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 +%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 -%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 +%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 diff --git a/build/win_installer.iss b/build/win_installer.iss index 007cd643..8a93a2c7 100644 --- a/build/win_installer.iss +++ b/build/win_installer.iss @@ -1,7 +1,8 @@ #define I2Pd_AppName "i2pd" #define I2Pd_Publisher "PurpleI2P" ; Get application version from compiled binary -#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe") +; Disabled to use definition from command line +;#define I2Pd_ver GetFileVersionString(AddBackslash(SourcePath) + "..\i2pd_x64.exe") [Setup] AppName={#I2Pd_AppName} diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 3c9ddde6..ecc5acdd 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -30,8 +30,9 @@ #include "Daemon.h" #include "util.h" #include "ECIESX25519AEADRatchetSession.h" + #ifdef WIN32_APP -#include "Win32/Win32App.h" +#include "Win32App.h" #endif // For image and info @@ -274,7 +275,7 @@ namespace http { s << "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; From 85d796f906b8e02f1fcc073624203caaca1ae3d0 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 17 Nov 2020 21:39:46 +0300 Subject: [PATCH 0564/2950] [actions] obj directories before make on windows --- .github/workflows/build-windows.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 9763f75b..c979e43f 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -26,4 +26,6 @@ jobs: install: base-devel mingw-w64-${{ matrix.arch }}-gcc mingw-w64-${{ matrix.arch }}-boost mingw-w64-${{ matrix.arch }}-openssl mingw-w64-${{ matrix.arch }}-miniupnpc update: true - name: build application - run: make USE_UPNP=yes DEBUG=no -j3 + run: | + mkdir -p obj/Win32 obj/libi2pd obj/libi2pd_client obj/daemon + make USE_UPNP=yes DEBUG=no -j3 From feaecbe177700d86ed0eb5729190a59173093bda Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Nov 2020 15:02:06 -0500 Subject: [PATCH 0565/2950] own local destination for each 'transient' --- 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 ab868916..860e8cfd 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -590,7 +590,8 @@ namespace client localDestination = CreateNewMatchedTunnelDestination(k, dest, &options); else localDestination = CreateNewLocalDestination (k, type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT, &options); - destinations[keys] = localDestination; + if (keys != "transient") + destinations[keys] = localDestination; } } } From d8381e94866f138160b19d58f01880040ec8fb12 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 18 Nov 2020 18:11:29 -0500 Subject: [PATCH 0566/2950] disable encryption to ECIES routers --- libi2pd/Destination.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d51fc63d..44180ae5 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -559,7 +559,9 @@ namespace client 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)); + auto msg = i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound); + if (floodfill->GetIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // TODO: remove whan implemented + msg = WrapMessageForRouter (floodfill, msg); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); @@ -754,8 +756,9 @@ namespace client else AddSessionKey (replyKey, replyTag); - auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - request->replyTunnel, replyKey, replyTag, isECIES)); + auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES); + if (nextFloodfill->GetIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // TODO: remove whan implemented + msg = WrapMessageForRouter (nextFloodfill, msg); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock From 30d6bd144bf4d90d7d38ea43545cbce674e34237 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 19 Nov 2020 15:41:00 -0500 Subject: [PATCH 0567/2950] don't replace an adddress by one with DSA signature --- libi2pd_client/AddressBook.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 5c1cffbb..d695b8eb 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -454,17 +454,18 @@ namespace client auto it = m_Addresses.find (name); if (it != m_Addresses.end ()) // already exists ? { - if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash ()) // address changed? + if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash () && // address changed? + ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA { it->second->identHash = ident->GetIdentHash (); m_Storage->AddAddress (ident); + m_Storage->RemoveAddress (it->second->identHash); LogPrint (eLogInfo, "Addressbook: updated host: ", name); } } else { - //m_Addresses.emplace (name, std::make_shared
(ident->GetIdentHash ())); - m_Addresses[name] = std::make_shared
(ident->GetIdentHash ()); // for gcc 4.7 + m_Addresses.emplace (name, std::make_shared
(ident->GetIdentHash ())); m_Storage->AddAddress (ident); if (is_update) LogPrint (eLogInfo, "Addressbook: added new host: ", name); From 0436a65baa95ef1eae32e9d06c65669687a3b2f5 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 20 Nov 2020 20:31:50 -0500 Subject: [PATCH 0568/2950] upddate DSA router keys --- libi2pd/RouterContext.cpp | 53 +++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 375e0b9a..220fbc4f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -564,31 +564,42 @@ namespace i2p bool RouterContext::Load () { - std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary); - if (!fk.is_open ()) return false; - fk.seekg (0, std::ios::end); - size_t len = fk.tellg(); - fk.seekg (0, std::ios::beg); + { + std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary); + if (!fk.is_open ()) return false; + fk.seekg (0, std::ios::end); + size_t len = fk.tellg(); + fk.seekg (0, std::ios::beg); - if (len == sizeof (i2p::data::Keys)) // old keys file format - { - i2p::data::Keys keys; - fk.read ((char *)&keys, sizeof (keys)); - m_Keys = keys; + if (len == sizeof (i2p::data::Keys)) // old keys file format + { + i2p::data::Keys keys; + fk.read ((char *)&keys, sizeof (keys)); + m_Keys = keys; + } + else // new keys file format + { + uint8_t * buf = new uint8_t[len]; + fk.read ((char *)buf, len); + m_Keys.FromBuffer (buf, len); + delete[] buf; + } } - else // new keys file format + std::shared_ptr oldIdentity; + if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) { - uint8_t * buf = new uint8_t[len]; - fk.read ((char *)buf, len); - m_Keys.FromBuffer (buf, len); - delete[] buf; - } + // update keys + LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new"); + oldIdentity = m_Keys.GetPublic (); + m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); + SaveKeys (); + } // read NTCP2 keys if available std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary); if (n2k) { n2k.seekg (0, std::ios::end); - len = n2k.tellg(); + size_t len = n2k.tellg(); n2k.seekg (0, std::ios::beg); if (len == sizeof (NTCP2PrivateKeys)) { @@ -598,17 +609,15 @@ namespace i2p n2k.close (); } // read RouterInfo - m_RouterInfo.SetRouterIdentity (GetIdentity ()); + m_RouterInfo.SetRouterIdentity (oldIdentity ? oldIdentity : GetIdentity ()); i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); if (!routerInfo.IsUnreachable ()) // router.info looks good { m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); + if (oldIdentity) + m_RouterInfo.SetRouterIdentity (GetIdentity ()); // from new keys m_RouterInfo.SetProperty ("coreVersion", I2P_VERSION); m_RouterInfo.SetProperty ("router.version", I2P_VERSION); - - // Migration to 0.9.24. TODO: remove later - m_RouterInfo.DeleteProperty ("coreVersion"); - m_RouterInfo.DeleteProperty ("stat_uptime"); } else { From f4486bc075387828c5daec6c3d4b894cbd1458b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 20 Nov 2020 21:48:33 -0500 Subject: [PATCH 0569/2950] take intro key from right address --- libi2pd/SSUSession.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 860c2be3..b4f2fcdb 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -30,14 +30,15 @@ namespace transport if (router) { // we are client - auto address = router->GetSSUAddress (false); + auto address = IsV6 () ? router->GetSSUV6Address () : router->GetSSUAddress (true); if (address) m_IntroKey = address->ssu->key; m_Data.AdjustPacketSize (router); // mtu } else { // we are server - auto address = i2p::context.GetRouterInfo ().GetSSUAddress (false); + auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () : + i2p::context.GetRouterInfo ().GetSSUAddress (true); if (address) m_IntroKey = address->ssu->key; } m_CreationTime = i2p::util::GetSecondsSinceEpoch (); From 2266c3877c01af077733e54d9ab2cf5df0a42d3a Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 21 Nov 2020 19:45:06 +0300 Subject: [PATCH 0570/2950] update reseeds Signed-off-by: R4SAS --- .../certificates/reseed/meeh_at_mail.i2p.crt | 32 ------------------- libi2pd/Config.cpp | 5 ++- 2 files changed, 2 insertions(+), 35 deletions(-) delete mode 100644 contrib/certificates/reseed/meeh_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/meeh_at_mail.i2p.crt b/contrib/certificates/reseed/meeh_at_mail.i2p.crt deleted file mode 100644 index 6014c96f..00000000 --- a/contrib/certificates/reseed/meeh_at_mail.i2p.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFeTCCA2GgAwIBAgIEZZozujANBgkqhkiG9w0BAQ0FADBtMQswCQYDVQQGEwJY -WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt -b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwNbWVlaEBtYWlsLmky -cDAeFw0xNDA2MjgyMjQ5MDlaFw0yNDA2MjcyMjQ5MDlaMG0xCzAJBgNVBAYTAlhY -MQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBBbm9ueW1v -dXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1tZWVoQG1haWwuaTJw -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnVnmPE4uUvCky0yCnnVH -cJEDqzwDPupx0zr0YDlhZk5VOPPecx5haayJ/V6nXPc1aVVWn+CHfedcF2aBgN4K -5aBueS/l6l5WHcv02DofAqlTmyAws3oQeR1qoTuW24cKRtLR7h5bxv63f6bgp6e+ -RihFNez6UxErnRPuJOJEO2Im6EgVp6fz7tQ7R35zxAUeES2YILPySvzy2vYm/EEG -jXX7Ap2A5svVo90xCMOeUZ/55vLsjyIshN+tV87U4xwvAkUmwsmWVHm3BQpHkI6z -zMJie6epB8Bqm0GYm0EcElJH4OCxGTvDLoghpswbuUO7iy3JSfoL7ZCnoiQdK9K4 -yVVChj8lG+r7KaTowK96iZep+sZefjOt5VFGuW2Fi/WBv3ldiLlJAo/ZfrUM4+vG -fyNBXbl6bX87uTCGOT1p3dazo+zJMsAZ+Y93DlM/mDEWFa1kKNrs74syzaWEqF4L -KQE6VoYn80OOzafSigTVQgSwUtQtB0XGhMzJhyxU2XHWe1LFIy7Pta0B+lDiZj7c -I8nXxYjsDfEu/Elj/Ra9N6bH0awmgB5JDa+Tbir+oEM5SyDfpSaCGuatdGxjweGI -kVmFU0SqCZV/8TXbIu6MUVzTZMZVT94edifFSRad4fqw7eZbSXlPu++3d1/btn6h -ibM04nkv0mm+FxCKB/wdAkECAwEAAaMhMB8wHQYDVR0OBBYEFO7jIkSRkoXyJcho -9/Q0gDOINa5EMA0GCSqGSIb3DQEBDQUAA4ICAQBzfWO7+8HWOKLaYWToJ6XZbpNF -3wXv1yC4W/HRR80m4JSsq9r0d7838Nvd7vLVP6MY6MaVb/JnV76FdQ5WQ6ticD0Y -o3zmpqqbKVSspN0lrkig4surT88AjfVQz/vEIzKNQEbpzc3hC2LCiE2u+cK/ix4j -b9RohnaPvwLnew5RNQRpcmk+XejaNITISr2yQIwXL7TEYy8HdGCfzFSSFhKe9vkb -GsWS5ASrUzRoprswmlgRe8gEHI+d51Z7mWgna0/5mBz9bH/3QXtpxlLWm3bVV+kt -pZjQDTHE0GqG2YsD1Gmp4LU/JFhCojMTtiPCXmr9KFtpiVlx06DuKm5PC8Ak+5w+ -m/DQYYfv9z+AA5Y430bjnzwg67bhqVyyek4wcDQinFswv3h4bIB7CJujDcEqXXza -lhG1ufPPCUTMrVjh7AShohZraqlSlyQPY9vEppLwD4W1d+MqDHM7ljOH7gQYaUPi -wE30AdXEOxLZcT3aRKxkKf2esNofSuUC/+NXQvPjpuI4UJKO3eegi+M9dbnKoNWs -MPPLPpycecWPheFYM5K6Ao63cjlUY2wYwCfDTFgjA5q8i/Rp7i6Z6fLE3YWJ4VdR -WOFB7hlluQ//jMW6M1qz6IYXmlUjcXl81VEvlOH/QBNrPvX3I3SYXYgVRnVGUudB -o3eNsanvTU+TIFBh2Q== ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index d99fdde1..d16d82d3 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -197,13 +197,12 @@ namespace config { ("reseed.proxy", value()->default_value(""), "url for reseed proxy, supports http/socks") ("reseed.urls", value()->default_value( "https://reseed.i2p-projekt.de/," - "https://reseed.diva.exchange/," - "https://reseed.i2p2.no/," + "https://reseed.diva.exchange/," "https://reseed-fr.i2pd.xyz/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://i2pseed.creativecowpat.net:8443/," - "https://reseed.i2pgit.org/," + "https://reseed.i2pgit.org/," "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ; From 3dfb44de3114728b44cd84c7aba29f4d4e68af9c Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 21 Nov 2020 14:27:08 -0500 Subject: [PATCH 0571/2950] exclude DSA floodfills --- libi2pd/NetDb.cpp | 4 ++-- libi2pd/RouterInfo.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 4399fb15..e280e31b 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -240,7 +240,7 @@ namespace data std::unique_lock l(m_FloodfillsMutex); if (wasFloodfill) m_Floodfills.remove (r); - else + else if (r->IsEligibleFloodfill ()) m_Floodfills.push_back (r); } } @@ -263,7 +263,7 @@ namespace data if (inserted) { LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64()); - if (r->IsFloodfill () && r->IsReachable ()) // floodfill must be reachable + if (r->IsFloodfill () && r->IsEligibleFloodfill ()) { std::unique_lock l(m_FloodfillsMutex); m_Floodfills.push_back (r); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 282c34f9..a4b2fd22 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -184,7 +184,9 @@ namespace data bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; - + // floodfill must be reachable and not DSA + bool IsEligibleFloodfill () const { return IsReachable () && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; }; + uint8_t GetCaps () const { return m_Caps; }; void SetCaps (uint8_t caps); void SetCaps (const char * caps); From c875ff923a4a77311728aa7fdb9df72dcf47ca67 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 21 Nov 2020 18:44:40 -0500 Subject: [PATCH 0572/2950] random intro key --- libi2pd/RouterContext.cpp | 6 +++--- libi2pd/RouterInfo.cpp | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 220fbc4f..cdab624c 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -89,7 +89,7 @@ namespace i2p host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string(); if (ssu) - routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); + routerInfo.AddSSUAddress (host.c_str(), port, nullptr); } if (ipv6) { @@ -103,7 +103,7 @@ namespace i2p host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string(); if (ssu) - routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); + routerInfo.AddSSUAddress (host.c_str(), port, nullptr); } routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | @@ -486,7 +486,7 @@ namespace i2p if (ssu) { std::string host = "::1"; // TODO: read host - m_RouterInfo.AddSSUAddress (host.c_str (), port, GetIdentHash ()); + m_RouterInfo.AddSSUAddress (host.c_str (), port, nullptr); } } // NTCP2 diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 12f81a42..3fc512f6 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -719,7 +719,10 @@ namespace data addr->date = 0; addr->ssu.reset (new SSUExt ()); addr->ssu->mtu = mtu; - memcpy (addr->ssu->key, key, 32); + if (key) + memcpy (addr->ssu->key, key, 32); + else + RAND_bytes (addr->ssu->key, 32); for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; From 771480e368af28ed6218e76f586e5700eacd3c40 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Nov 2020 17:36:00 -0500 Subject: [PATCH 0573/2950] send queue for incoming I2CP messages --- libi2pd_client/I2CP.cpp | 85 ++++++++++++++++++++++++++++++++++------- libi2pd_client/I2CP.h | 11 +++++- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 2b9df0fa..05d61474 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -227,12 +227,17 @@ namespace client I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_SessionID (0xFFFF), - m_MessageID (0), m_IsSendAccepted (true) + m_MessageID (0), m_IsSendAccepted (true), m_IsSending (false) { } I2CPSession::~I2CPSession () { + if (m_SendQueue) + { + for (auto& it: *m_SendQueue) + delete[] boost::asio::buffer_cast(it); + } } void I2CPSession::Start () @@ -358,25 +363,64 @@ namespace client if (socket) { auto l = len + I2CP_HEADER_SIZE; - uint8_t * buf = new uint8_t[l]; + uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len); buf[I2CP_HEADER_TYPE_OFFSET] = type; memcpy (buf + I2CP_HEADER_SIZE, payload, len); - boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + if (m_IsSending) + { + if (!m_SendQueue) + m_SendQueue = std::make_shared (); + if (m_SendQueue->size () > I2CP_MAX_SEND_QUEUE_SIZE) + { + LogPrint (eLogError, "I2CP: Queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); + return; + } + m_SendQueue->push_back ({buf, l}); + } + else + { + m_IsSending = true; + boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, l), boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), + std::placeholders::_1, std::placeholders::_2)); + } } else LogPrint (eLogError, "I2CP: Can't write to the socket"); } - void I2CPSession::HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, const uint8_t * buf) + void I2CPSession::HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - delete[] buf; - if (ecode && ecode != boost::asio::error::operation_aborted) - Terminate (); + if (ecode) + { + if (ecode != boost::asio::error::operation_aborted) + Terminate (); + } + else if (m_SendQueue) + { + auto socket = m_Socket; + if (socket) + { + auto queue = m_SendQueue; + m_SendQueue = nullptr; + boost::asio::async_write (*socket, *queue, boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSentQueue, shared_from_this (), + std::placeholders::_1, std::placeholders::_2, queue)); + } + } + else + m_IsSending = false; } + void I2CPSession::HandleI2CPMessageSentQueue (const boost::system::error_code& ecode, std::size_t bytes_transferred, SendQueue queue) + { + for (auto& it: *queue) + delete[] boost::asio::buffer_cast(it);; + + HandleI2CPMessageSent (ecode, bytes_transferred); + } + std::string I2CPSession::ExtractString (const uint8_t * buf, size_t len) { uint8_t l = buf[0]; @@ -810,16 +854,31 @@ namespace client if (socket) { auto l = len + 10 + I2CP_HEADER_SIZE; - uint8_t * buf = new uint8_t[l]; + uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); - boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + if (m_IsSending) + { + if (!m_SendQueue) + m_SendQueue = std::make_shared (); + if (m_SendQueue->size () > I2CP_MAX_SEND_QUEUE_SIZE) + { + LogPrint (eLogError, "I2CP: Queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); + return; + } + m_SendQueue->push_back ({buf, l}); + } + else + { + m_IsSending = true; + boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, l), boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), + std::placeholders::_1, std::placeholders::_2)); + } } else LogPrint (eLogError, "I2CP: Can't write to the socket"); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index c5dc80e7..51d503aa 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -25,6 +25,7 @@ namespace client const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; + const size_t I2CP_MAX_SEND_QUEUE_SIZE = 256; const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; @@ -122,6 +123,8 @@ namespace client class I2CPServer; class I2CPSession: public std::enable_shared_from_this { + typedef std::shared_ptr > SendQueue; + public: #ifdef ANDROID @@ -167,7 +170,8 @@ namespace client void HandleMessage (); void Terminate (); - void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, const uint8_t * buf); + void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandleI2CPMessageSentQueue (const boost::system::error_code& ecode, std::size_t bytes_transferred, SendQueue queue); std::string ExtractString (const uint8_t * buf, size_t len); size_t PutString (uint8_t * buf, size_t len, const std::string& str); void ExtractMapping (const uint8_t * buf, size_t len, std::map& mapping); @@ -186,6 +190,11 @@ namespace client uint16_t m_SessionID; uint32_t m_MessageID; bool m_IsSendAccepted; + + // to client + bool m_IsSending; + uint8_t m_SendBuffer[I2CP_MAX_MESSAGE_LENGTH]; + SendQueue m_SendQueue; }; typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); From bc330ff0ea134d5d18d927609d3870192829f70f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 23 Nov 2020 01:44:21 +0300 Subject: [PATCH 0574/2950] update makefiles, license year Signed-off-by: R4SAS --- LICENSE | 2 +- Makefile | 5 +++-- Makefile.linux | 16 ++++++++-------- Makefile.mingw | 11 ++++++----- Win32/Resource.rc2 | 2 +- build/build_mingw.cmd | 2 +- contrib/android_binary_pack/build-archive | 2 +- contrib/android_binary_pack/i2pd | 10 +++++----- libi2pd/FS.cpp | 6 +++--- libi2pd/Timestamp.cpp | 2 +- libi2pd/util.cpp | 12 ++++++------ qt/i2pd_qt/i2pd.rc | 2 +- 12 files changed, 37 insertions(+), 35 deletions(-) diff --git a/LICENSE b/LICENSE index 2cb10225..9a1e4527 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2015, The PurpleI2P Project +Copyright (c) 2013-2020, The PurpleI2P Project All rights reserved. diff --git a/Makefile b/Makefile index 7bb3ceda..3e0b23cf 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_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) $(DAEMON_OBJS:.o=.d) all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD) @@ -82,7 +82,7 @@ obj/%.o: %.cpp -include $(DEPS) $(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT) - $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS) + $(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS) $(SHLIB): $(LIB_OBJS) ifneq ($(USE_STATIC),yes) @@ -130,3 +130,4 @@ doxygen: .PHONY: api_client .PHONY: mk_obj_dir .PHONY: install +.PHONY: strip diff --git a/Makefile.linux b/Makefile.linux index 6a7590c1..ee6a902b 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -33,7 +33,7 @@ ifeq ($(USE_STATIC),yes) # NOTE: on glibc you will get this warning: # Using 'getaddrinfo' in statically linked applications requires at runtime # the shared libraries from the glibc version used for linking - LIBDIR := /usr/lib + LIBDIR := /usr/lib/$(SYS) LDLIBS += $(LIBDIR)/libboost_system.a LDLIBS += $(LIBDIR)/libboost_date_time.a LDLIBS += $(LIBDIR)/libboost_filesystem.a @@ -41,20 +41,20 @@ ifeq ($(USE_STATIC),yes) LDLIBS += $(LIBDIR)/libssl.a LDLIBS += $(LIBDIR)/libcrypto.a LDLIBS += $(LIBDIR)/libz.a - LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl - USE_AESNI := no +ifeq ($(USE_UPNP),yes) + LDLIBS += $(LIBDIR)/libminiupnpc.a +endif + LDLIBS += -lpthread -ldl else LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread +ifeq ($(USE_UPNP),yes) + LDLIBS += -lminiupnpc +endif endif # UPNP Support (miniupnpc 1.5 and higher) ifeq ($(USE_UPNP),yes) NEEDED_CXXFLAGS += -DUSE_UPNP -ifeq ($(USE_STATIC),yes) - LDLIBS += $(LIBDIR)/libminiupnpc.a -else - LDLIBS += -lminiupnpc -endif endif ifeq ($(USE_AESNI),yes) diff --git a/Makefile.mingw b/Makefile.mingw index 4cd2c292..ce1966a1 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -1,9 +1,11 @@ -USE_WIN32_APP=yes -CXX = g++ +# Build application with GUI (tray, main window) +USE_WIN32_APP := yes + WINDRES = windres -CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -fPIC -msse + +CXXFLAGS := $(CXX_DEBUG) -D_MT -DWIN32_LEAN_AND_MEAN -fPIC -msse INCFLAGS = -I$(DAEMON_SRC_DIR) -IWin32 -LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc -static-libstdc++ +LDFLAGS := ${LD_DEBUG} -Wl,-Bstatic -static-libgcc # detect proper flag for c++11 support by compilers CXXVER := $(shell $(CXX) -dumpversion) @@ -38,7 +40,6 @@ LDLIBS += \ -liphlpapi \ -lole32 \ -luuid \ - -lstdc++ \ -lpthread ifeq ($(USE_WIN32_APP), yes) diff --git a/Win32/Resource.rc2 b/Win32/Resource.rc2 index 6a4f481d..9eecbc1f 100644 --- a/Win32/Resource.rc2 +++ b/Win32/Resource.rc2 @@ -25,7 +25,7 @@ BEGIN VALUE "FileDescription", "C++ I2P daemon" VALUE "FileVersion", I2PD_VERSION VALUE "InternalName", CODENAME - VALUE "LegalCopyright", "Copyright (C) 2013-2017, The PurpleI2P Project" + VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project" VALUE "OriginalFilename", "i2pd" VALUE "ProductName", "Purple I2P" VALUE "ProductVersion", I2P_VERSION diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index e791039e..aaf25843 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -2,7 +2,7 @@ setlocal enableextensions enabledelayedexpansion title Building i2pd -REM Copyright (c) 2013-2017, The PurpleI2P Project +REM Copyright (c) 2013-2020, The PurpleI2P Project REM This file is part of Purple i2pd project and licensed under BSD3 REM See full license text in LICENSE file at top of project tree diff --git a/contrib/android_binary_pack/build-archive b/contrib/android_binary_pack/build-archive index bb56cace..c439dd7f 100755 --- a/contrib/android_binary_pack/build-archive +++ b/contrib/android_binary_pack/build-archive @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2013-2017, The PurpleI2P Project +# Copyright (c) 2013-2020, The PurpleI2P Project # # This file is part of Purple i2pd project and licensed under BSD3 # diff --git a/contrib/android_binary_pack/i2pd b/contrib/android_binary_pack/i2pd index aeaae804..c31cb4ad 100755 --- a/contrib/android_binary_pack/i2pd +++ b/contrib/android_binary_pack/i2pd @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 2013-2019, The PurpleI2P Project +# Copyright (c) 2013-2020, The PurpleI2P Project # # This file is part of Purple i2pd project and licensed under BSD3 # @@ -21,13 +21,13 @@ arch=$(uname -m) screenfind=$(which screen) if [ -z $screenfind ]; then - echo "Can't find 'screen' installed. That script needs it!"; - exit 1; + echo "Can't find 'screen' installed. That script needs it!"; + exit 1; fi if [ -z i2pd-$arch ]; then - echo "Can't find i2pd binary for your archtecture."; - exit 1; + echo "Can't find i2pd binary for your archtecture."; + exit 1; fi screen -AmdS i2pd ./i2pd-$arch --datadir=$DIR diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 32fc3ec0..bd1a7ad2 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -46,13 +46,13 @@ namespace fs { dataDir = cmdline_param; return; } -#if defined(WIN32) || defined(_WIN32) +#ifdef _WIN32 char localAppData[MAX_PATH]; // check executable directory first if(!GetModuleFileName(NULL, localAppData, MAX_PATH)) { -#if defined(WIN32_APP) +#ifdef WIN32_APP MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK); #else fprintf(stderr, "Error: Unable to get application path!"); @@ -70,7 +70,7 @@ namespace fs { { if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK) { -#if defined(WIN32_APP) +#ifdef WIN32_APP MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK); #else fprintf(stderr, "Error: Unable to get AppData path!"); diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 45684333..0490350e 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -19,7 +19,7 @@ #include "I2PEndian.h" #include "Timestamp.h" -#ifdef WIN32 +#ifdef _WIN32 #ifndef _WIN64 #define _USE_32BIT_TIME_T #endif diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 2cc101c7..24814ad3 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -13,7 +13,7 @@ #include "util.h" #include "Log.h" -#ifdef WIN32 +#ifdef _WIN32 #include #include #include @@ -56,7 +56,7 @@ int inet_pton_xp(int af, const char *src, void *dst) } return 0; } -#else /* !WIN32 => UNIX */ +#else /* !_WIN32 => UNIX */ #include #include #endif @@ -109,7 +109,7 @@ namespace util namespace net { -#ifdef WIN32 +#ifdef _WIN32 bool IsWindowsXPorLater() { static bool isRequested = false; @@ -333,13 +333,13 @@ namespace net return mtu; } -#endif // WIN32 +#endif // _WIN32 int GetMTU(const boost::asio::ip::address& localAddress) { int fallback = localAddress.is_v6 () ? 1280 : 620; // fallback MTU -#ifdef WIN32 +#ifdef _WIN32 return GetMTUWindows(localAddress, fallback); #else return GetMTUUnix(localAddress, fallback); @@ -349,7 +349,7 @@ namespace net const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6) { -#ifdef WIN32 +#ifdef _WIN32 LogPrint(eLogError, "NetIface: cannot get address by interface name, not implemented on WIN32"); if(ipv6) return boost::asio::ip::address::from_string("::1"); diff --git a/qt/i2pd_qt/i2pd.rc b/qt/i2pd_qt/i2pd.rc index bebdf1d6..d31e591e 100644 --- a/qt/i2pd_qt/i2pd.rc +++ b/qt/i2pd_qt/i2pd.rc @@ -17,7 +17,7 @@ BEGIN VALUE "FileDescription", "I2Pd Qt" VALUE "FileVersion", I2PD_VERSION VALUE "InternalName", "i2pd-qt" - VALUE "LegalCopyright", "Copyright (C) 2013-2018, The PurpleI2P Project" + VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project" VALUE "LegalTrademarks1", "Distributed under the BSD 3-Clause software license, see the accompanying file COPYING or https://opensource.org/licenses/BSD-3-Clause." VALUE "OriginalFilename", "i2pd_qt.exe" VALUE "ProductName", "i2pd-qt" From 86e3b977e492e832933596f46753c73a85299d5e Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Nov 2020 21:41:27 -0500 Subject: [PATCH 0575/2950] check I2CP message size --- libi2pd_client/I2CP.cpp | 115 ++++++++++++++++++---------------------- libi2pd_client/I2CP.h | 3 +- 2 files changed, 55 insertions(+), 63 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 05d61474..a2e2d79f 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -354,40 +354,17 @@ namespace client void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len) { - if (len > I2CP_MAX_MESSAGE_LENGTH) + auto l = len + I2CP_HEADER_SIZE; + if (l > I2CP_MAX_MESSAGE_LENGTH) { - LogPrint (eLogError, "I2CP: Message to send is too long ", len); + LogPrint (eLogError, "I2CP: Message to send is too long ", l); return; } - auto socket = m_Socket; - if (socket) - { - auto l = len + I2CP_HEADER_SIZE; - uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; - htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len); - buf[I2CP_HEADER_TYPE_OFFSET] = type; - memcpy (buf + I2CP_HEADER_SIZE, payload, len); - if (m_IsSending) - { - if (!m_SendQueue) - m_SendQueue = std::make_shared (); - if (m_SendQueue->size () > I2CP_MAX_SEND_QUEUE_SIZE) - { - LogPrint (eLogError, "I2CP: Queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); - return; - } - m_SendQueue->push_back ({buf, l}); - } - else - { - m_IsSending = true; - boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, l), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - } - else - LogPrint (eLogError, "I2CP: Can't write to the socket"); + uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; + htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len); + buf[I2CP_HEADER_TYPE_OFFSET] = type; + memcpy (buf + I2CP_HEADER_SIZE, payload, len); + SendBuffer (buf, l); } void I2CPSession::HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -420,6 +397,38 @@ namespace client HandleI2CPMessageSent (ecode, bytes_transferred); } + + void I2CPSession::SendBuffer (uint8_t * buf, size_t len) + { + auto socket = m_Socket; + if (socket) + { + if (m_IsSending) + { + auto sendQueue = m_SendQueue; + if (!sendQueue) + { + sendQueue = std::make_shared (); + m_SendQueue = sendQueue; + } + else if (sendQueue->size () > I2CP_MAX_SEND_QUEUE_SIZE) + { + LogPrint (eLogError, "I2CP: Queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); + return; + } + sendQueue->push_back ({buf, len}); + } + else + { + m_IsSending = true; + boost::asio::async_write (*socket, boost::asio::buffer (buf, len), boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), + std::placeholders::_1, std::placeholders::_2)); + } + } + else + LogPrint (eLogError, "I2CP: Can't write to the socket"); + } std::string I2CPSession::ExtractString (const uint8_t * buf, size_t len) { @@ -850,38 +859,20 @@ namespace client void I2CPSession::SendMessagePayloadMessage (const uint8_t * payload, size_t len) { // we don't use SendI2CPMessage to eliminate additional copy - auto socket = m_Socket; - if (socket) + auto l = len + 10 + I2CP_HEADER_SIZE; + if (l > I2CP_MAX_MESSAGE_LENGTH) { - auto l = len + 10 + I2CP_HEADER_SIZE; - uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; - htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); - buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; - htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); - htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); - htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); - memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); - if (m_IsSending) - { - if (!m_SendQueue) - m_SendQueue = std::make_shared (); - if (m_SendQueue->size () > I2CP_MAX_SEND_QUEUE_SIZE) - { - LogPrint (eLogError, "I2CP: Queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); - return; - } - m_SendQueue->push_back ({buf, l}); - } - else - { - m_IsSending = true; - boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, l), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - } - else - LogPrint (eLogError, "I2CP: Can't write to the socket"); + LogPrint (eLogError, "I2CP: Message to send is too long ", l); + return; + } + uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; + htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); + buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; + htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); + htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); + htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); + memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); + SendBuffer (buf, l); } I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread): diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 51d503aa..ac3acd45 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -169,7 +169,8 @@ namespace client void HandleReceivedPayload (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleMessage (); void Terminate (); - + void SendBuffer (uint8_t * buf, size_t len); + void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleI2CPMessageSentQueue (const boost::system::error_code& ecode, std::size_t bytes_transferred, SendQueue queue); std::string ExtractString (const uint8_t * buf, size_t len); From 9301e39af786865665b046be85eb044ba6e72b9d Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Nov 2020 12:49:18 -0500 Subject: [PATCH 0576/2950] minimal version for floodfill 0.9.28 --- libi2pd/NetDb.hpp | 1 + libi2pd/RouterInfo.cpp | 7 +++++++ libi2pd/RouterInfo.h | 3 +-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp index afd1f562..845217e1 100644 --- a/libi2pd/NetDb.hpp +++ b/libi2pd/NetDb.hpp @@ -44,6 +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 /** function for visiting a leaseset stored in a floodfill */ typedef std::function)> LeaseSetVisitor; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3fc512f6..13776b81 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -948,5 +948,12 @@ namespace data if (encryptor) encryptor->Encrypt (data, encrypted, ctx, true); } + + bool RouterInfo::IsEligibleFloodfill () const + { + // floodfill must be reachable, >= 0.9.28 and not DSA + return IsReachable () && m_Version >= NETDB_MIN_FLOODFILL_VERSION && + GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; + } } } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index a4b2fd22..733ea44a 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -184,8 +184,7 @@ namespace data bool IsHidden () const { return m_Caps & eHidden; }; bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; }; bool IsExtraBandwidth () const { return m_Caps & RouterInfo::eExtraBandwidth; }; - // floodfill must be reachable and not DSA - bool IsEligibleFloodfill () const { return IsReachable () && GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1; }; + bool IsEligibleFloodfill () const; uint8_t GetCaps () const { return m_Caps; }; void SetCaps (uint8_t caps); From 1c5b350c2b90d53dbed1841087e4098c30903a20 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Nov 2020 18:55:48 -0500 Subject: [PATCH 0577/2950] TCP_QUICKACK --- libi2pd/NTCP2.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 7a88e4d8..bb54437e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -742,6 +742,10 @@ namespace transport void NTCP2Session::ReceiveLength () { if (IsTerminated ()) return; +#ifdef __linux__ + const int one = 1; + setsockopt(m_Socket.native_handle(), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)); +#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)); } @@ -793,6 +797,10 @@ namespace transport void NTCP2Session::Receive () { if (IsTerminated ()) return; +#ifdef __linux__ + const int one = 1; + 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)); } From c833b16544a8081d5390cb954e82a1d4b5dbffd1 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 26 Nov 2020 09:15:45 -0500 Subject: [PATCH 0578/2950] check if session expired before generating more tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 3dfe4ca5..00efee48 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1011,8 +1011,11 @@ namespace garlic void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) { - for (int i = 0; i < numTags; i++) - GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset); + if (GetOwner ()) + { + for (int i = 0; i < numTags; i++) + GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset); + } } bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) From ad36738f57fb8709893e27cb92dffe269d7ec337 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 27 Nov 2020 13:37:03 -0500 Subject: [PATCH 0579/2950] detach session from destination upon termination --- libi2pd_client/I2CP.cpp | 20 +++++++++++++++----- libi2pd_client/I2CP.h | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index a2e2d79f..5b8c09b2 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -30,6 +30,12 @@ namespace client { } + void I2CPDestination::Stop () + { + LeaseSetDestination::Stop (); + m_Owner = nullptr; + } + void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) { m_Decryptor = i2p::data::PrivateKeys::CreateDecryptor (m_Identity->GetCryptoKeyType (), key); @@ -72,7 +78,8 @@ namespace client { uint32_t length = bufbe32toh (buf); if (length > len - 4) length = len - 4; - m_Owner->SendMessagePayloadMessage (buf + 4, length); + if (m_Owner) + m_Owner->SendMessagePayloadMessage (buf + 4, length); } void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) @@ -84,7 +91,8 @@ namespace client leases[-1] = tunnels.size (); htobe16buf (leases - 3, m_Owner->GetSessionID ()); size_t l = 2/*sessionID*/ + 1/*num leases*/ + i2p::data::LEASE_SIZE*tunnels.size (); - m_Owner->SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); + if (m_Owner) + m_Owner->SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); } void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len) @@ -119,7 +127,8 @@ namespace client [s, msg, remote, nonce]() { bool sent = s->SendMsg (msg, remote); - s->m_Owner->SendMessageStatusMessage (nonce, sent ? eI2CPMessageStatusGuaranteedSuccess : eI2CPMessageStatusGuaranteedFailure); + if (s->m_Owner) + s->m_Owner->SendMessageStatusMessage (nonce, sent ? eI2CPMessageStatusGuaranteedSuccess : eI2CPMessageStatusGuaranteedFailure); }); } else @@ -130,9 +139,10 @@ namespace client if (ls) { bool sent = s->SendMsg (msg, ls); - s->m_Owner->SendMessageStatusMessage (nonce, sent ? eI2CPMessageStatusGuaranteedSuccess : eI2CPMessageStatusGuaranteedFailure); + if (s->m_Owner) + s->m_Owner->SendMessageStatusMessage (nonce, sent ? eI2CPMessageStatusGuaranteedSuccess : eI2CPMessageStatusGuaranteedFailure); } - else + else if (s->m_Owner) s->m_Owner->SendMessageStatusMessage (nonce, eI2CPMessageStatusNoLeaseSet); }); } diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index ac3acd45..460b8638 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -71,6 +71,8 @@ namespace client I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params); ~I2CPDestination () {}; + + void Stop (); void SetEncryptionPrivateKey (const uint8_t * key); void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; }; From 242fb7db14c84e5a8ff960ab3affb8a1a0a6ae81 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 28 Nov 2020 10:09:38 -0500 Subject: [PATCH 0580/2950] terminate I2CP session if destroyed explicitly --- libi2pd_client/I2CP.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 5b8c09b2..9e9d17ee 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -89,10 +89,16 @@ namespace client m_LeaseSetExpirationTime = ls.GetExpirationTime (); uint8_t * leases = ls.GetLeases (); leases[-1] = tunnels.size (); - htobe16buf (leases - 3, m_Owner->GetSessionID ()); - size_t l = 2/*sessionID*/ + 1/*num leases*/ + i2p::data::LEASE_SIZE*tunnels.size (); if (m_Owner) - m_Owner->SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); + { + uint16_t sessionID = m_Owner->GetSessionID (); + if (sessionID != 0xFFFF) + { + htobe16buf (leases - 3, sessionID); + size_t l = 2/*sessionID*/ + 1/*num leases*/ + i2p::data::LEASE_SIZE*tunnels.size (); + m_Owner->SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); + } + } } void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len) @@ -243,11 +249,7 @@ namespace client I2CPSession::~I2CPSession () { - if (m_SendQueue) - { - for (auto& it: *m_SendQueue) - delete[] boost::asio::buffer_cast(it); - } + Terminate (); } void I2CPSession::Start () @@ -358,8 +360,18 @@ namespace client m_Socket->close (); m_Socket = nullptr; } - m_Owner.RemoveSession (GetSessionID ()); - LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " terminated"); + if (m_SendQueue) + { + for (auto& it: *m_SendQueue) + delete[] boost::asio::buffer_cast(it); + m_SendQueue = nullptr; + } + if (m_SessionID != 0xFFFF) + { + m_Owner.RemoveSession (GetSessionID ()); + LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " terminated"); + m_SessionID = 0xFFFF; + } } void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len) @@ -555,11 +567,7 @@ namespace client { SendSessionStatusMessage (0); // destroy LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " destroyed"); - if (m_Destination) - { - m_Destination->Stop (); - m_Destination = 0; - } + Terminate (); } void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len) From ff971563dbdc8e18b1b894284ea5b71252d4b8e9 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 28 Nov 2020 22:25:06 -0500 Subject: [PATCH 0581/2950] cleanup queue after buffers deletion --- libi2pd_client/I2CP.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 9e9d17ee..82ee7841 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -364,6 +364,7 @@ namespace client { for (auto& it: *m_SendQueue) delete[] boost::asio::buffer_cast(it); + m_SendQueue->clear (); m_SendQueue = nullptr; } if (m_SessionID != 0xFFFF) @@ -415,7 +416,8 @@ namespace client void I2CPSession::HandleI2CPMessageSentQueue (const boost::system::error_code& ecode, std::size_t bytes_transferred, SendQueue queue) { for (auto& it: *queue) - delete[] boost::asio::buffer_cast(it);; + delete[] boost::asio::buffer_cast(it); + queue->clear (); HandleI2CPMessageSent (ecode, bytes_transferred); } From 746f53ba0792d786e3038bc9f466a8bc7d0e9198 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 29 Nov 2020 14:59:34 -0500 Subject: [PATCH 0582/2950] use SendBufferQueue for queued messages from I2P --- libi2pd/Streaming.cpp | 12 ++++- libi2pd/Streaming.h | 6 +++ libi2pd_client/I2CP.cpp | 113 +++++++++++++++++++--------------------- libi2pd_client/I2CP.h | 11 ++-- 4 files changed, 75 insertions(+), 67 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 80e8aecf..05b34d9e 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -21,10 +21,18 @@ namespace stream { void SendBufferQueue::Add (const uint8_t * buf, size_t len, SendHandler handler) { - m_Buffers.push_back (std::make_shared(buf, len, handler)); - m_Size += len; + Add (std::make_shared(buf, len, handler)); } + void SendBufferQueue::Add (std::shared_ptr buf) + { + if (buf) + { + m_Buffers.push_back (buf); + m_Size += buf->len; + } + } + size_t SendBufferQueue::Get (uint8_t * buf, size_t len) { size_t offset = 0; diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index e8b8db91..ab3c4439 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -111,6 +111,11 @@ namespace stream buf = new uint8_t[len]; memcpy (buf, b, len); } + SendBuffer (size_t l): // creat empty buffer + len(l), offset (0) + { + buf = new uint8_t[len]; + } ~SendBuffer () { delete[] buf; @@ -129,6 +134,7 @@ namespace stream ~SendBufferQueue () { CleanUp (); }; void Add (const uint8_t * buf, size_t len, SendHandler handler); + void Add (std::shared_ptr buf); size_t Get (uint8_t * buf, size_t len); size_t GetSize () const { return m_Size; }; bool IsEmpty () const { return m_Buffers.empty (); }; diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 82ee7841..cb618b5d 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -360,13 +360,8 @@ namespace client m_Socket->close (); m_Socket = nullptr; } - if (m_SendQueue) - { - for (auto& it: *m_SendQueue) - delete[] boost::asio::buffer_cast(it); - m_SendQueue->clear (); - m_SendQueue = nullptr; - } + if (!m_SendQueue.IsEmpty ()) + m_SendQueue.CleanUp (); if (m_SessionID != 0xFFFF) { m_Owner.RemoveSession (GetSessionID ()); @@ -383,11 +378,32 @@ namespace client LogPrint (eLogError, "I2CP: Message to send is too long ", l); return; } - uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; + auto sendBuf = m_IsSending ? std::make_shared (l) : nullptr; + uint8_t * buf = sendBuf ? sendBuf->buf : m_SendBuffer; htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len); buf[I2CP_HEADER_TYPE_OFFSET] = type; memcpy (buf + I2CP_HEADER_SIZE, payload, len); - SendBuffer (buf, l); + if (sendBuf) + { + if (m_SendQueue.GetSize () < I2CP_MAX_SEND_QUEUE_SIZE) + m_SendQueue.Add (sendBuf); + else + { + LogPrint (eLogWarning, "I2CP: send queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); + return; + } + } + else + { + auto socket = m_Socket; + if (socket) + { + m_IsSending = true; + boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, l), + boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, + shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + } } void I2CPSession::HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -397,62 +413,22 @@ namespace client if (ecode != boost::asio::error::operation_aborted) Terminate (); } - else if (m_SendQueue) + else if (!m_SendQueue.IsEmpty ()) { auto socket = m_Socket; if (socket) { - auto queue = m_SendQueue; - m_SendQueue = nullptr; - boost::asio::async_write (*socket, *queue, boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSentQueue, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, queue)); + auto len = m_SendQueue.Get (m_SendBuffer, I2CP_MAX_MESSAGE_LENGTH); + boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, len), + boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent, + shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } + else + m_IsSending = false; } else m_IsSending = false; } - - void I2CPSession::HandleI2CPMessageSentQueue (const boost::system::error_code& ecode, std::size_t bytes_transferred, SendQueue queue) - { - for (auto& it: *queue) - delete[] boost::asio::buffer_cast(it); - queue->clear (); - - HandleI2CPMessageSent (ecode, bytes_transferred); - } - - void I2CPSession::SendBuffer (uint8_t * buf, size_t len) - { - auto socket = m_Socket; - if (socket) - { - if (m_IsSending) - { - auto sendQueue = m_SendQueue; - if (!sendQueue) - { - sendQueue = std::make_shared (); - m_SendQueue = sendQueue; - } - else if (sendQueue->size () > I2CP_MAX_SEND_QUEUE_SIZE) - { - LogPrint (eLogError, "I2CP: Queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); - return; - } - sendQueue->push_back ({buf, len}); - } - else - { - m_IsSending = true; - boost::asio::async_write (*socket, boost::asio::buffer (buf, len), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - } - else - LogPrint (eLogError, "I2CP: Can't write to the socket"); - } std::string I2CPSession::ExtractString (const uint8_t * buf, size_t len) { @@ -885,14 +861,35 @@ namespace client LogPrint (eLogError, "I2CP: Message to send is too long ", l); return; } - uint8_t * buf = m_IsSending ? new uint8_t[l] : m_SendBuffer; + auto sendBuf = m_IsSending ? std::make_shared (l) : nullptr; + uint8_t * buf = sendBuf ? sendBuf->buf : m_SendBuffer; htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); - SendBuffer (buf, l); + if (sendBuf) + { + if (m_SendQueue.GetSize () < I2CP_MAX_SEND_QUEUE_SIZE) + m_SendQueue.Add (sendBuf); + else + { + LogPrint (eLogWarning, "I2CP: send queue size exceeds ", I2CP_MAX_SEND_QUEUE_SIZE); + return; + } + } + else + { + auto socket = m_Socket; + if (socket) + { + m_IsSending = true; + boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, l), + boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, + shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + } } I2CPServer::I2CPServer (const std::string& interface, int port, bool isSingleThread): diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 460b8638..32f32221 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -17,6 +17,7 @@ #include #include "util.h" #include "Destination.h" +#include "Streaming.h" namespace i2p { @@ -25,7 +26,7 @@ namespace client const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; - const size_t I2CP_MAX_SEND_QUEUE_SIZE = 256; + const size_t I2CP_MAX_SEND_QUEUE_SIZE = 1024*1024; // in bytes, 1M const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; @@ -125,8 +126,6 @@ namespace client class I2CPServer; class I2CPSession: public std::enable_shared_from_this { - typedef std::shared_ptr > SendQueue; - public: #ifdef ANDROID @@ -171,14 +170,12 @@ namespace client void HandleReceivedPayload (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleMessage (); void Terminate (); - void SendBuffer (uint8_t * buf, size_t len); void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandleI2CPMessageSentQueue (const boost::system::error_code& ecode, std::size_t bytes_transferred, SendQueue queue); + std::string ExtractString (const uint8_t * buf, size_t len); size_t PutString (uint8_t * buf, size_t len, const std::string& str); void ExtractMapping (const uint8_t * buf, size_t len, std::map& mapping); - void SendSessionStatusMessage (uint8_t status); void SendHostReplyMessage (uint32_t requestID, std::shared_ptr identity); @@ -197,7 +194,7 @@ namespace client // to client bool m_IsSending; uint8_t m_SendBuffer[I2CP_MAX_MESSAGE_LENGTH]; - SendQueue m_SendQueue; + i2p::stream::SendBufferQueue m_SendQueue; }; typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); From 58153c3579b7e0e9dd1632891b770b82d295ec19 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 30 Nov 2020 04:10:13 +0300 Subject: [PATCH 0583/2950] [webconsole] fix content block width 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 ecc5acdd..9f420cf0 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -70,7 +70,7 @@ namespace http { " .menu { float: left; } .menu a, .commands a { display: block; }\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: 46em; overflow: auto; }\r\n" + " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; 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" From 0ab95b1b8791cfe2fab856b42b5ffbd883a15906 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Nov 2020 12:50:15 -0500 Subject: [PATCH 0584/2950] 2.35.0 --- ChangeLog | 22 +++++++++++++++++++ android/build.gradle | 4 ++-- appveyor.yml | 2 +- contrib/rpm/i2pd-git.spec | 5 ++++- contrib/rpm/i2pd.spec | 5 ++++- debian/changelog | 6 +++++ libi2pd/version.h | 4 ++-- qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 1 + 8 files changed, 42 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbce5fb2..bc9b28df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,28 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.35.0] - 2020-11-30 +### Added +- ECIES-x25519 routers +- Random intro keys for SSU +- Graceful shutdown timer for windows +- Send queue for I2CP messages +- Update DSA router keys to EdDSA +- TCP_QUICKACK for NTCP2 sockets on Linux +### Changed +- Exclude floodfills with DSA signatures and < 0.9.28 +- Random intervals between tunnel tests and manage for tunnel pools +- Don't replace an addressbook record by one with DSA signature +- Publish RouterInfo after update +- Create paired inbound tunnels if no inbound tunnels yet +- Reseed servers list +### Fixed +- Transient signature length, if different from identity +- Terminate I2CP session if destroyed +- RouterInfo publishing confirmation +- Check if ECIES-X25519-AEAD-Ratchet session expired before generating more tags +- Correct block size for delivery type local for ECIES-X25519-AEAD-Ratchet + ## [2.34.0] - 2020-10-27 ### Added - Ping responses for streaming diff --git a/android/build.gradle b/android/build.gradle index 2c6c782d..dbe75759 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -30,8 +30,8 @@ android { applicationId "org.purplei2p.i2pd" targetSdkVersion 29 minSdkVersion 14 - versionCode 2340 - versionName "2.34.0" + versionCode 2350 + versionName "2.35.0" setProperty("archivesBaseName", archivesBaseName + "-" + versionName) ndk { abiFilters 'armeabi-v7a' diff --git a/appveyor.yml b/appveyor.yml index a8e7d30d..cc6d130b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.34.0.{build} +version: 2.35.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 a320d6aa..d622ced5 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.34.0 +Version: 2.35.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 Nov 30 2020 orignal - 2.35.0 +- update to 2.35.0 + * Tue Oct 27 2020 orignal - 2.34.0 - update to 2.34.0 diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index 3f5ef260..d147c269 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.34.0 +Version: 2.35.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -135,6 +135,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Mon Nov 30 2020 orignal - 2.35.0 +- update to 2.35.0 + * Tue Oct 27 2020 orignal - 2.34.0 - update to 2.34.0 diff --git a/debian/changelog b/debian/changelog index b79f6cd6..7ca75409 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.35.0-1) unstable; urgency=high + + * updated to version 2.35.0/0.9.48 + + -- orignal Mon, 30 Nov 2020 16:00:00 +0000 + i2pd (2.34.0-1) unstable; urgency=medium * updated to version 2.34.0 diff --git a/libi2pd/version.h b/libi2pd/version.h index 26ced1c3..f28d88c0 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 34 +#define I2PD_VERSION_MINOR 35 #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 47 +#define I2P_VERSION_MICRO 48 #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) diff --git a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml index 97a759c2..e23729a8 100644 --- a/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml +++ b/qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml @@ -35,6 +35,7 @@ + From ad84944d20c9dd86058f6bdd6c10ea15d0f62425 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 1 Dec 2020 03:55:41 +0300 Subject: [PATCH 0585/2950] [make] change AES support check --- Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index ee6a902b..da5f68b4 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -58,7 +58,7 @@ ifeq ($(USE_UPNP),yes) endif ifeq ($(USE_AESNI),yes) -ifeq (, $(findstring arm, $(SYS))$(findstring aarch64, $(SYS))) # no arm and aarch64 in dumpmachine +ifneq (, $(findstring i386, $(SYS))$(findstring i686, $(SYS))$(findstring x86_64, $(SYS))) # only x86-based CPU supports that NEEDED_CXXFLAGS += -D__AES__ -maes endif endif From 2f57013e02cb105926e6919551b67bfcee751f89 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 1 Dec 2020 05:07:41 +0300 Subject: [PATCH 0586/2950] [qt] update project file Some build systems didn't create required folders for object files, so create them manually with additional call of `mk_obj_dir` target. --- qt/i2pd_qt/i2pd_qt.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index eed4cd7b..004b6273 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -79,7 +79,7 @@ libi2pd.commands = @echo Building i2pd libraries libi2pd.target = $$PWD/../../libi2pd.a libi2pd.depends = i2pd FORCE -i2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE api_client +i2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE mk_obj_dir api_client i2pd.target += $$PWD/../../libi2pdclient.a i2pd.depends = FORCE From ce14ea6fe5b6b849a734d4683b3a97e076a7fb53 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 3 Dec 2020 09:35:43 +0300 Subject: [PATCH 0587/2950] [windows] add file version to installer Signed-off-by: R4SAS --- build/build_mingw.cmd | 2 +- build/win_installer.iss | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index aaf25843..e8f1378b 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -64,7 +64,7 @@ call :BUILDING_XP echo. REM compile installer -C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_ver="%tag%" build\win_installer.iss >> build\build.log 2>&1 +C:\PROGRA~2\INNOSE~1\ISCC.exe /dI2Pd_TextVer="%tag%" /dI2Pd_Ver="%tag%.0" build\win_installer.iss >> build\build.log 2>&1 del README.txt i2pd_x32.exe i2pd_x64.exe i2pd_xp.exe >> nul diff --git a/build/win_installer.iss b/build/win_installer.iss index 8a93a2c7..97cd4408 100644 --- a/build/win_installer.iss +++ b/build/win_installer.iss @@ -6,25 +6,35 @@ [Setup] AppName={#I2Pd_AppName} -AppVersion={#I2Pd_ver} +AppVersion={#I2Pd_TextVer} AppPublisher={#I2Pd_Publisher} + DefaultDirName={pf}\I2Pd DefaultGroupName=I2Pd UninstallDisplayIcon={app}\I2Pd.exe OutputDir=. +OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_TextVer} + LicenseFile=..\LICENSE -OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} SetupIconFile=..\Win32\mask.ico + InternalCompressLevel=ultra64 Compression=lzma/ultra64 SolidCompression=true + ArchitecturesInstallIn64BitMode=x64 -AppVerName={#I2Pd_AppName} ExtraDiskSpaceRequired=15 + AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2} +AppVerName={#I2Pd_AppName} +AppCopyright=Copyright (c) 2013-2020, The PurpleI2P Project AppPublisherURL=http://i2pd.website/ AppSupportURL=https://github.com/PurpleI2P/i2pd/issues AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases + +VersionInfoProductVersion={#I2Pd_Ver} +VersionInfoVersion={#I2Pd_Ver} + CloseApplications=yes [Files] From 32fc6482ccc3394f19a86b15ee920cbcffb92417 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 3 Dec 2020 17:58:37 -0500 Subject: [PATCH 0588/2950] moved Noise initializations to Crypto.cpp --- libi2pd/Crypto.cpp | 61 +++++++++++++++++++++++ libi2pd/Crypto.h | 4 ++ libi2pd/ECIESX25519AEADRatchetSession.cpp | 24 ++------- libi2pd/ECIESX25519AEADRatchetSession.h | 1 - libi2pd/NTCP2.cpp | 18 +------ libi2pd/RouterContext.cpp | 4 +- libi2pd/TunnelConfig.cpp | 15 +----- libi2pd/TunnelConfig.h | 2 - 8 files changed, 71 insertions(+), 58 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 523828ce..6055f888 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1316,6 +1316,8 @@ namespace crypto #endif } +// Noise + void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) { SHA256_CTX ctx; @@ -1331,6 +1333,65 @@ namespace crypto // new ck is m_CK[0:31], key is m_CK[32:63] } + void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub) + { + // pub is Bob's public static key + static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars + static const uint8_t hh[32] = + { + 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, + 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 + }; // hh = SHA256(protocol_name || 0) + memcpy (state.m_CK, protocolName, 32); // ck = protocol_name || 0 + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, hh, 32); + SHA256_Update (&ctx, pub, 32); + SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + } + + void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub) + { + // pub is Bob's public static key + static const uint8_t protocolNameHash[] = + { + 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, + 0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71 + }; // SHA256 ("Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256") + static const uint8_t hh[32] = + { + 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, + 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e + }; // SHA256 (protocolNameHash) + memcpy (state.m_CK, protocolNameHash, 32); + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, hh, 32); + SHA256_Update (&ctx, pub, 32); + SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + } + + void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) + { + // pub is Bob's public static key + static const uint8_t protocolNameHash[32] = + { + 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, + 0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c + }; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes + static const uint8_t hh[32] = + { + 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, + 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c + }; // SHA256 (protocolNameHash) + memcpy (state.m_CK, protocolNameHash, 32); + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, hh, 32); + SHA256_Update (&ctx, pub, 32); + SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + } + // init and terminate /* std::vector > m_OpenSSLMutexes; diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index da7a4bf4..c63cc45e 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -318,6 +318,10 @@ namespace crypto void MixKey (const uint8_t * sharedSecret); }; + void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router) + void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_XK (NTCP2) + void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_IK (ratchets) + // init and terminate void InitCrypto (bool precomputation, bool aesni, bool avx, bool force); void TerminateCrypto (); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 00efee48..b3b30a1b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -153,29 +153,12 @@ namespace garlic GarlicRoutingSession (owner, attachLeaseSet) { RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0; - ResetKeys (); } ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession () { } - void ECIESX25519AEADRatchetSession::ResetKeys () - { - static const uint8_t protocolNameHash[32] = - { - 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, - 0xac, 0xbe, 0x00, 0x54, 0xad, 0x17, 0x8f, 0x80, 0x79, 0xa6, 0x46, 0x82, 0x7e, 0x6e, 0xe4, 0x0c - }; // SHA256("Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256"), 40 bytes - static const uint8_t hh[32] = - { - 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, - 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c - }; // SHA256 (protocolNameHash) - memcpy (m_CK, protocolNameHash, 32); - memcpy (m_H, hh, 32); - } - void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce) { memset (nonce, 0, 4); @@ -236,8 +219,8 @@ namespace garlic if (!GetOwner ()) return false; // we are Bob // KDF1 - MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD), 32); // h = SHA256(h || bpk) - + i2p::crypto::InitNoiseIKState (*this, GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk + if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk)) { LogPrint (eLogError, "Garlic: Can't decode elligator"); @@ -448,7 +431,6 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen, bool isStatic) { - ResetKeys (); // we are Alice, bpk is m_RemoteStaticKey size_t offset = 0; if (!GenerateEphemeralKeysAndEncode (out + offset)) @@ -459,7 +441,7 @@ namespace garlic offset += 32; // KDF1 - MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk) + i2p::crypto::InitNoiseIKState (*this, m_RemoteStaticKey); // bpk MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 755531a3..e71d9782 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -178,7 +178,6 @@ namespace garlic private: - void ResetKeys (); void CreateNonce (uint64_t seqn, uint8_t * nonce); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes std::shared_ptr CreateNewSessionTagset (); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index bb54437e..1706399d 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -41,23 +41,7 @@ namespace transport void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { - static const uint8_t protocolNameHash[] = - { - 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, - 0xf2, 0x28, 0x98, 0x17, 0x71, 0x21, 0x8c, 0x1f, 0x62, 0x4e, 0x20, 0x6f, 0x28, 0xd3, 0x2f, 0x71 - }; // SHA256 ("Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256") - static const uint8_t hh[32] = - { - 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, - 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e - }; // SHA256 (protocolNameHash) - memcpy (m_CK, protocolNameHash, 32); - // h = SHA256(hh || rs) - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, hh, 32); - SHA256_Update (&ctx, rs, 32); - SHA256_Final (m_H, &ctx); + i2p::crypto::InitNoiseXKState (*this, rs); // h = SHA256(h || epub) MixHash (epub, 32); // x25519 between pub and priv diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index cdab624c..3c066532 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -19,7 +19,6 @@ #include "version.h" #include "Log.h" #include "Family.h" -#include "TunnelConfig.h" #include "RouterContext.h" namespace i2p @@ -45,8 +44,7 @@ namespace i2p if (IsECIES ()) { auto initState = new i2p::crypto::NoiseSymmetricState (); - i2p::tunnel::InitBuildRequestRecordNoiseState (*initState); - initState->MixHash (GetIdentity ()->GetEncryptionPublicKey (), 32); // h = SHA256(h || hepk) + i2p::crypto::InitNoiseNState (*initState, GetIdentity ()->GetEncryptionPublicKey ()); m_InitialNoiseState.reset (initState); } } diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp index a1b234a1..d43483c0 100644 --- a/libi2pd/TunnelConfig.cpp +++ b/libi2pd/TunnelConfig.cpp @@ -127,10 +127,9 @@ namespace tunnel void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, const uint8_t * plainText, uint8_t * encrypted, BN_CTX * ctx) { - InitBuildRequestRecordNoiseState (*this); uint8_t hepk[32]; encryptor->Encrypt (nullptr, hepk, nullptr, false); - MixHash (hepk, 32); // h = SHA256(h || hepk) + i2p::crypto::InitNoiseNState (*this, hepk); auto ephemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); memcpy (encrypted, ephemeralKeys->GetPublicKey (), 32); MixHash (encrypted, 32); // h = SHA256(h || sepk) @@ -148,17 +147,5 @@ namespace tunnel } MixHash (encrypted, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE + 16); // h = SHA256(h || ciphertext) } - - void InitBuildRequestRecordNoiseState (i2p::crypto::NoiseSymmetricState& state) - { - static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars - static const uint8_t hh[32] = - { - 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, - 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 - }; // SHA256 (protocol_name || 0) - memcpy (state.m_CK, protocolName, 32); // ck = h = protocol_name || 0 - memcpy (state.m_H, hh, 32); // h = SHA256(h) - } } } \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 9aed0d25..45693970 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -44,8 +44,6 @@ namespace tunnel void EncryptECIES (std::shared_ptr& encryptor, const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx); }; - - void InitBuildRequestRecordNoiseState (i2p::crypto::NoiseSymmetricState& state); class TunnelConfig { From abdf92c084e825008f5539ae7fcee9435fa7ee47 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 3 Dec 2020 19:43:43 -0500 Subject: [PATCH 0589/2950] encrypt message for ECIES router --- libi2pd/Crypto.cpp | 38 ++++++++++------------- libi2pd/ECIESX25519AEADRatchetSession.cpp | 36 +++++++++++++++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 8 +++-- libi2pd/Garlic.cpp | 2 +- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 6055f888..68712fc7 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1333,26 +1333,31 @@ namespace crypto // new ck is m_CK[0:31], key is m_CK[32:63] } + static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck, + const uint8_t * hh, const uint8_t * pub) + { + // pub is Bob's public static key, hh = SHA256(h) + memcpy (state.m_CK, ck, 32); + SHA256_CTX ctx; + SHA256_Init (&ctx); + SHA256_Update (&ctx, hh, 32); + SHA256_Update (&ctx, pub, 32); + SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + } + void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub) { - // pub is Bob's public static key static const char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars static const uint8_t hh[32] = { 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 }; // hh = SHA256(protocol_name || 0) - memcpy (state.m_CK, protocolName, 32); // ck = protocol_name || 0 - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, hh, 32); - SHA256_Update (&ctx, pub, 32); - SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0 } - + void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub) { - // pub is Bob's public static key static const uint8_t protocolNameHash[] = { 0x72, 0xe8, 0x42, 0xc5, 0x45, 0xe1, 0x80, 0x80, 0xd3, 0x9c, 0x44, 0x93, 0xbb, 0x91, 0xd7, 0xed, @@ -1363,17 +1368,11 @@ namespace crypto 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e }; // SHA256 (protocolNameHash) - memcpy (state.m_CK, protocolNameHash, 32); - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, hh, 32); - SHA256_Update (&ctx, pub, 32); - SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + InitNoiseState (state, protocolNameHash, hh, pub); } void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) { - // pub is Bob's public static key static const uint8_t protocolNameHash[32] = { 0x4c, 0xaf, 0x11, 0xef, 0x2c, 0x8e, 0x36, 0x56, 0x4c, 0x53, 0xe8, 0x88, 0x85, 0x06, 0x4d, 0xba, @@ -1384,12 +1383,7 @@ namespace crypto 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c }; // SHA256 (protocolNameHash) - memcpy (state.m_CK, protocolNameHash, 32); - SHA256_CTX ctx; - SHA256_Init (&ctx); - SHA256_Update (&ctx, hh, 32); - SHA256_Update (&ctx, pub, 32); - SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) + InitNoiseState (state, protocolNameHash, hh, pub); } // init and terminate diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b3b30a1b..042a318c 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -490,6 +490,31 @@ 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 (*this, 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]; + m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) + MixKey (sharedSecret); + uint8_t nonce[12]; + memset (nonce, 0, 12); + // 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 @@ -549,7 +574,7 @@ namespace garlic return true; } - + bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob and sent NSR already @@ -781,6 +806,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; } @@ -791,9 +821,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); } diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index e71d9782..1788eeb8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -140,7 +140,8 @@ namespace garlic eSessionStateNewSessionSent, eSessionStateNewSessionReplySent, eSessionStateEstablished, - eSessionStateOneTime + eSessionStateOneTime, + eSessionStateForRouter }; struct DHRatchet @@ -158,7 +159,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); } @@ -192,7 +193,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); diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 2fe97156..1d228811 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -716,7 +716,7 @@ namespace garlic { auto session = std::make_shared(this, false); session->SetRemoteStaticKey (router->GetIdentity ()->GetEncryptionPublicKey ()); - return session->WrapOneTimeMessage (msg); + return session->WrapOneTimeMessage (msg, true); } else { From e2fcab34b71c182f94bed304588897fd46c0ab5f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 3 Dec 2020 22:01:58 -0500 Subject: [PATCH 0590/2950] deccrypt and handle garlic message for ECIES router --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 24 ++++++++++++++++++++++- libi2pd/ECIESX25519AEADRatchetSession.h | 1 + libi2pd/RouterContext.cpp | 17 +++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 042a318c..ecc7412f 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -503,7 +503,7 @@ namespace garlic m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) MixKey (sharedSecret); uint8_t nonce[12]; - memset (nonce, 0, 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 { @@ -770,6 +770,28 @@ namespace garlic return true; } + bool ECIESX25519AEADRatchetSession::HandleNextMessageForRouter (const uint8_t * buf, size_t len) + { + if (!GetOwner ()) return false; + // we are Bob + i2p::crypto::InitNoiseNState (*this, GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk + MixHash (buf, 32); + uint8_t sharedSecret[32]; + GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, aepk) + 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, m_H, 32, m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt + { + LogPrint (eLogWarning, "Garlic: Payload for router AEAD verification failed"); + return false; + } + HandlePayload (payload.data (), len - 16, nullptr, 0); + return true; + } + std::shared_ptr ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr msg) { auto payload = CreatePayload (msg, m_State != eSessionStateEstablished); diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 1788eeb8..59be94c1 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -158,6 +158,7 @@ namespace garlic ~ECIESX25519AEADRatchetSession (); bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); + bool HandleNextMessageForRouter (const uint8_t * buf, size_t len); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 3c066532..5cfbd943 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -19,6 +19,7 @@ #include "version.h" #include "Log.h" #include "Family.h" +#include "ECIESX25519AEADRatchetSession.h" #include "RouterContext.h" namespace i2p @@ -672,7 +673,21 @@ namespace i2p void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); - i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); + if (IsECIES ()) + { + 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; + auto session = std::make_shared(this, false); + session->HandleNextMessageForRouter (buf, len); + } + else + i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); } void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) From 36473e388903b38b64364a30c72642096bfab386 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 4 Dec 2020 18:36:49 +0300 Subject: [PATCH 0591/2950] add naming to threads Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 2 ++ daemon/I2PControl.cpp | 2 ++ daemon/UPnP.cpp | 2 ++ libi2pd/Log.cpp | 2 ++ libi2pd/NTCP2.h | 1 - libi2pd/NetDb.cpp | 3 +++ libi2pd/SSU.cpp | 13 ++++++++++--- libi2pd/Timestamp.cpp | 2 ++ libi2pd/Transports.cpp | 5 +++++ libi2pd/Tunnel.cpp | 2 ++ libi2pd/util.cpp | 1 + libi2pd_client/AddressBook.cpp | 1 + libi2pd_client/I2PTunnel.cpp | 10 ++++++---- 13 files changed, 38 insertions(+), 8 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 9f420cf0..73849e4d 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -1312,6 +1313,7 @@ namespace http { void HTTPServer::Run () { + pthread_setname_np(pthread_self(), "Webconsole"); while (m_IsRunning) { try diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index e8c6e031..1fde9109 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "Crypto.h" #include "FS.h" @@ -131,6 +132,7 @@ namespace client void I2PControlService::Run () { + pthread_setname_np(pthread_self(), "I2PC"); while (m_IsRunning) { try { diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 92a41011..0076ddd7 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -1,6 +1,7 @@ #ifdef USE_UPNP #include #include +#include #include #include @@ -60,6 +61,7 @@ namespace transport void UPnP::Run () { + pthread_setname_np(pthread_self(), "UPnP"); while (m_IsRunning) { try diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index a0014841..d7386642 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -7,6 +7,7 @@ */ #include "Log.h" +#include //for std::transform #include @@ -179,6 +180,7 @@ namespace log { void Log::Run () { + pthread_setname_np(pthread_self(), "Logging"); Reopen (); while (m_IsRunning) { diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 351f17b5..5c9ecac9 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index e280e31b..66dac010 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "I2PEndian.h" #include "Base.h" @@ -88,6 +89,8 @@ namespace data void NetDb::Run () { + pthread_setname_np(pthread_self(), "NetDB"); + uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; while (m_IsRunning) { diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index d29f5cd7..a75306bb 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -7,6 +7,7 @@ */ #include +#include #include "Log.h" #include "Timestamp.h" #include "RouterContext.h" @@ -23,7 +24,7 @@ namespace transport { SSUServer::SSUServer (const boost::asio::ip::address & addr, int port): - m_OnlyV6(true), m_IsRunning(false), m_Thread (nullptr), + m_OnlyV6(true), m_IsRunning(false), m_Thread (nullptr), m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), m_ReceiversWork (m_ReceiversService), m_ReceiversWorkV6 (m_ReceiversServiceV6), m_EndpointV6 (addr, port), m_Socket (m_ReceiversService, m_Endpoint), @@ -36,7 +37,7 @@ namespace transport SSUServer::SSUServer (int port): m_OnlyV6(false), m_IsRunning(false), m_Thread (nullptr), - m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), + m_ReceiversThread (nullptr), m_ReceiversThreadV6 (nullptr), m_Work (m_Service), 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), @@ -100,7 +101,7 @@ namespace transport if (context.SupportsV6 ()) { m_ReceiversThreadV6 = new std::thread (std::bind (&SSUServer::RunReceiversV6, this)); - if (!m_Thread) + if (!m_Thread) m_Thread = new std::thread (std::bind (&SSUServer::Run, this)); m_ReceiversServiceV6.post (std::bind (&SSUServer::ReceiveV6, this)); ScheduleTerminationV6 (); @@ -142,6 +143,8 @@ namespace transport void SSUServer::Run () { + pthread_setname_np(pthread_self(), "SSU"); + while (m_IsRunning) { try @@ -157,6 +160,8 @@ namespace transport void SSUServer::RunReceivers () { + pthread_setname_np(pthread_self(), "SSUv4"); + while (m_IsRunning) { try @@ -179,6 +184,8 @@ namespace transport void SSUServer::RunReceiversV6 () { + pthread_setname_np(pthread_self(), "SSUv6"); + while (m_IsRunning) { try diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 0490350e..db5c3946 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "Config.h" #include "Log.h" #include "I2PEndian.h" @@ -148,6 +149,7 @@ namespace util void NTPTimeSync::Run () { + pthread_setname_np(pthread_self(), "Timesync"); while (m_IsRunning) { try diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c6e90ad2..585ef8e0 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -6,6 +6,7 @@ * See full license text in LICENSE file at top of project tree */ +#include #include "Log.h" #include "Crypto.h" #include "RouterContext.h" @@ -59,6 +60,8 @@ namespace transport template void EphemeralKeysSupplier::Run () { + pthread_setname_np(pthread_self(), "Ephemerals"); + while (m_IsRunning) { int num, total = 0; @@ -272,6 +275,8 @@ namespace transport void Transports::Run () { + pthread_setname_np(pthread_self(), "Transports"); + while (m_IsRunning && m_Service) { try diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index ad918787..a5f20963 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -10,6 +10,7 @@ #include "I2PEndian.h" #include #include +#include #include #include #include "Crypto.h" @@ -472,6 +473,7 @@ namespace tunnel void Tunnels::Run () { + pthread_setname_np(pthread_self(), "Tunnels"); std::this_thread::sleep_for (std::chrono::seconds(1)); // wait for other parts are ready uint64_t lastTs = 0, lastPoolsTs = 0; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 24814ad3..e98f939f 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -94,6 +94,7 @@ namespace util void RunnableService::Run () { + pthread_setname_np(pthread_self(), m_Name.c_str()); while (m_IsRunning) { try diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index d695b8eb..6ecbddaf 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -748,6 +748,7 @@ namespace client void AddressBookSubscription::CheckUpdates () { + pthread_setname_np(pthread_self(), "Addressbook"); bool result = MakeRequest (); m_Book.DownloadComplete (result, m_Ident, m_Etag, m_LastModified); } diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 081294c6..18b7c5a0 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -7,6 +7,7 @@ */ #include +#include #include "Base.h" #include "Log.h" #include "Destination.h" @@ -862,7 +863,7 @@ namespace client std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); dgram->SetRawReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } void I2PUDPClientTunnel::Start() { @@ -891,11 +892,11 @@ namespace client } auto remotePort = m_RecvEndpoint.port(); if (!m_LastPort || m_LastPort != remotePort) - { + { auto itr = m_Sessions.find(remotePort); - if (itr != m_Sessions.end()) + if (itr != m_Sessions.end()) m_LastSession = itr->second; - else + else { m_LastSession = std::make_shared(boost::asio::ip::udp::endpoint(m_RecvEndpoint), 0); m_Sessions.emplace (remotePort, m_LastSession); @@ -941,6 +942,7 @@ namespace client void I2PUDPClientTunnel::TryResolving() { LogPrint(eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest); + pthread_setname_np(pthread_self(), "UDP Resolver"); std::shared_ptr addr; while(!(addr = context.GetAddressBook().GetAddress(m_RemoteDest)) && !m_cancel_resolve) From a843165cb49661d0d134eab013d09b781ab99dd5 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 4 Dec 2020 19:15:06 -0500 Subject: [PATCH 0592/2950] try ratchets tag first --- libi2pd/Garlic.cpp | 73 +++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 1d228811..9c008bc0 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -485,42 +485,43 @@ namespace garlic } auto mod = length & 0x0f; // %16 buf += 4; // length - auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16 - // AES tag might be used even if encryption type is not ElGamal/AES - if (it != m_Tags.end ()) - { - // tag found. Use AES - auto decryption = it->second; - m_Tags.erase (it); // tag might be used only once - if (length >= 32) - { - uint8_t iv[32]; // IV is first 16 bytes - SHA256(buf, 32, iv); - decryption->SetIV (iv); - decryption->Decrypt (buf + 32, length - 32, buf + 32); - HandleAESBlock (buf + 32, length - 32, decryption, msg->from); - } - else - LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes"); - } - else - { - bool found = false; - if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) - { - // try ECIESx25519 tag - uint64_t 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)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); - m_ECIESx25519Tags.erase (it1); - } - } + bool found = false; + if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) + { + // try ECIESx25519 tag + uint64_t 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)) + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + m_ECIESx25519Tags.erase (it1); + } + } + if (!found) + { + auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16 + // AES tag might be used even if encryption type is not ElGamal/AES + if (it != m_Tags.end ()) // try AES tag + { + // tag found. Use AES + auto decryption = it->second; + m_Tags.erase (it); // tag might be used only once + if (length >= 32) + { + uint8_t iv[32]; // IV is first 16 bytes + SHA256(buf, 32, iv); + decryption->SetIV (iv); + decryption->Decrypt (buf + 32, length - 32, buf + 32); + HandleAESBlock (buf + 32, length - 32, decryption, msg->from); + found = true; + } + else + LogPrint (eLogWarning, "Garlic: message length ", length, " is less than 32 bytes"); + } if (!found) // assume new session { // AES tag not found. Handle depending on encryption type @@ -545,7 +546,7 @@ namespace garlic } else LogPrint (eLogError, "Garlic: Failed to decrypt message"); - } + } } } From aace200899a26c840f320794d30e8327fee17ad4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 5 Dec 2020 08:26:21 -0500 Subject: [PATCH 0593/2950] don't create paired zero hops tunnel --- libi2pd/TunnelPool.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 87413c3f..94462c93 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -235,7 +235,7 @@ namespace tunnel for (const auto& it : m_InboundTunnels) if (it->IsEstablished ()) num++; } - if (!num && !m_OutboundTunnels.empty ()) + if (!num && !m_OutboundTunnels.empty () && m_NumOutboundHops > 0) { for (auto it: m_OutboundTunnels) { @@ -559,7 +559,7 @@ namespace tunnel { config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); } - if(m_NumOutboundHops == 0 || config) + if (!m_NumOutboundHops || config) { auto newTunnel = tunnels.CreateOutboundTunnel (config); newTunnel->SetTunnelPool (shared_from_this ()); @@ -574,8 +574,12 @@ namespace tunnel void TunnelPool::CreatePairedInboundTunnel (std::shared_ptr outboundTunnel) { LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); - auto tunnel = tunnels.CreateInboundTunnel (std::make_shared(outboundTunnel->GetInvertedPeers ()), outboundTunnel); + auto tunnel = tunnels.CreateInboundTunnel ( + m_NumOutboundHops > 0 ? std::make_shared(outboundTunnel->GetInvertedPeers ()) : nullptr, + outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); + if (tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } void TunnelPool::SetCustomPeerSelector(ITunnelPeerSelector * selector) From 3100d4f90224094608215bba049f52e81e4e75da Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 7 Dec 2020 06:22:16 +0300 Subject: [PATCH 0594/2950] move thread naming to util Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 4 ++-- daemon/I2PControl.cpp | 4 ++-- daemon/UPnP.cpp | 4 ++-- libi2pd/Log.cpp | 5 +++-- libi2pd/NetDb.cpp | 12 +++++------ libi2pd/SSU.cpp | 8 ++++---- libi2pd/Timestamp.cpp | 5 +++-- libi2pd/Transports.cpp | 6 +++--- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/util.cpp | 40 +++++++++++++++++++++++++++--------- libi2pd/util.h | 6 ++++-- libi2pd_client/I2PTunnel.cpp | 4 ++-- 12 files changed, 63 insertions(+), 39 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 73849e4d..25b6ab19 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -1313,7 +1312,8 @@ namespace http { void HTTPServer::Run () { - pthread_setname_np(pthread_self(), "Webconsole"); + i2p::util::SetThreadName("Webconsole"); + while (m_IsRunning) { try diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 1fde9109..3f0033e5 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include "Crypto.h" #include "FS.h" @@ -132,7 +131,8 @@ namespace client void I2PControlService::Run () { - pthread_setname_np(pthread_self(), "I2PC"); + i2p::util::SetThreadName("I2PC"); + while (m_IsRunning) { try { diff --git a/daemon/UPnP.cpp b/daemon/UPnP.cpp index 0076ddd7..6ea33c46 100644 --- a/daemon/UPnP.cpp +++ b/daemon/UPnP.cpp @@ -1,7 +1,6 @@ #ifdef USE_UPNP #include #include -#include #include #include @@ -61,7 +60,8 @@ namespace transport void UPnP::Run () { - pthread_setname_np(pthread_self(), "UPnP"); + i2p::util::SetThreadName("UPnP"); + while (m_IsRunning) { try diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index d7386642..2b555663 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -7,7 +7,7 @@ */ #include "Log.h" -#include +#include "util.h" //for std::transform #include @@ -180,7 +180,8 @@ namespace log { void Log::Run () { - pthread_setname_np(pthread_self(), "Logging"); + i2p::util::SetThreadName("Logging"); + Reopen (); while (m_IsRunning) { diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 66dac010..20b54376 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include "I2PEndian.h" #include "Base.h" @@ -27,6 +26,7 @@ #include "ECIESX25519AEADRatchetSession.h" #include "Config.h" #include "NetDb.hpp" +#include "util.h" using namespace i2p::transport; @@ -89,7 +89,7 @@ namespace data void NetDb::Run () { - pthread_setname_np(pthread_self(), "NetDB"); + i2p::util::SetThreadName("NetDB"); uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0; while (m_IsRunning) @@ -116,7 +116,7 @@ namespace data break; case eI2NPDeliveryStatus: HandleDeliveryStatusMsg (msg); - break; + break; case eI2NPDummyMsg: // plain RouterInfo from NTCP2 with flags for now HandleNTCP2RouterInfoMsg (msg); @@ -158,12 +158,12 @@ namespace data if (!m_HiddenMode && i2p::transport::transports.IsOnline ()) { bool publish = false; - if (m_PublishReplyToken) - { + if (m_PublishReplyToken) + { 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) publish = true; if (publish) // update timestamp and publish { i2p::context.UpdateTimestamp (ts); diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index a75306bb..3b6280dd 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -7,12 +7,12 @@ */ #include -#include #include "Log.h" #include "Timestamp.h" #include "RouterContext.h" #include "NetDb.hpp" #include "SSU.h" +#include "util.h" #ifdef _WIN32 #include @@ -143,7 +143,7 @@ namespace transport void SSUServer::Run () { - pthread_setname_np(pthread_self(), "SSU"); + i2p::util::SetThreadName("SSU"); while (m_IsRunning) { @@ -160,7 +160,7 @@ namespace transport void SSUServer::RunReceivers () { - pthread_setname_np(pthread_self(), "SSUv4"); + i2p::util::SetThreadName("SSUv4"); while (m_IsRunning) { @@ -184,7 +184,7 @@ namespace transport void SSUServer::RunReceiversV6 () { - pthread_setname_np(pthread_self(), "SSUv6"); + i2p::util::SetThreadName("SSUv6"); while (m_IsRunning) { diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index db5c3946..3cd336ed 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -14,11 +14,11 @@ #include #include #include -#include #include "Config.h" #include "Log.h" #include "I2PEndian.h" #include "Timestamp.h" +#include "util.h" #ifdef _WIN32 #ifndef _WIN64 @@ -149,7 +149,8 @@ namespace util void NTPTimeSync::Run () { - pthread_setname_np(pthread_self(), "Timesync"); + i2p::util::SetThreadName("Timesync"); + while (m_IsRunning) { try diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 585ef8e0..5c2fcb6d 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -6,7 +6,6 @@ * See full license text in LICENSE file at top of project tree */ -#include #include "Log.h" #include "Crypto.h" #include "RouterContext.h" @@ -15,6 +14,7 @@ #include "Transports.h" #include "Config.h" #include "HTTP.h" +#include "util.h" using namespace i2p::data; @@ -60,7 +60,7 @@ namespace transport template void EphemeralKeysSupplier::Run () { - pthread_setname_np(pthread_self(), "Ephemerals"); + i2p::util::SetThreadName("Ephemerals"); while (m_IsRunning) { @@ -275,7 +275,7 @@ namespace transport void Transports::Run () { - pthread_setname_np(pthread_self(), "Transports"); + i2p::util::SetThreadName("Transports"); while (m_IsRunning && m_Service) { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index a5f20963..42eeeb5d 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -10,7 +10,6 @@ #include "I2PEndian.h" #include #include -#include #include #include #include "Crypto.h" @@ -23,6 +22,7 @@ #include "Config.h" #include "Tunnel.h" #include "TunnelPool.h" +#include "util.h" namespace i2p { @@ -473,7 +473,7 @@ namespace tunnel void Tunnels::Run () { - pthread_setname_np(pthread_self(), "Tunnels"); + 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; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index e98f939f..2e8e67ba 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -13,6 +13,15 @@ #include "util.h" #include "Log.h" +#if not defined (__FreeBSD__) +#include +#endif + +#if defined(__OpenBSD__) || defined(__FreeBSD__) +#include +#endif + + #ifdef _WIN32 #include #include @@ -32,7 +41,7 @@ // inet_pton exists Windows since Vista, but XP doesn't have that function! // This function was written by Petar Korponai?. See http://stackoverflow.com/questions/15660203/inet-pton-identifier-not-found -int inet_pton_xp(int af, const char *src, void *dst) +int inet_pton_xp (int af, const char *src, void *dst) { struct sockaddr_storage ss; int size = sizeof (ss); @@ -94,7 +103,8 @@ namespace util void RunnableService::Run () { - pthread_setname_np(pthread_self(), m_Name.c_str()); + SetThreadName(m_Name.c_str()); + while (m_IsRunning) { try @@ -108,10 +118,20 @@ namespace util } } + void SetThreadName (const char *name) { +#if defined (__APPLE__) + pthread_setname_np(name); +#elif defined(__FreeBSD__) + pthread_set_name_np(pthread_self(), name) +#else + pthread_setname_np(pthread_self(), name); +#endif + } + namespace net { #ifdef _WIN32 - bool IsWindowsXPorLater() + bool IsWindowsXPorLater () { static bool isRequested = false; static bool isXP = false; @@ -130,7 +150,7 @@ namespace net return isXP; } - int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback) + int GetMTUWindowsIpv4 (sockaddr_in inputAddress, int fallback) { ULONG outBufLen = 0; PIP_ADAPTER_ADDRESSES pAddresses = nullptr; @@ -184,7 +204,7 @@ namespace net return fallback; } - int GetMTUWindowsIpv6(sockaddr_in6 inputAddress, int fallback) + int GetMTUWindowsIpv6 (sockaddr_in6 inputAddress, int fallback) { ULONG outBufLen = 0; PIP_ADAPTER_ADDRESSES pAddresses = nullptr; @@ -249,7 +269,7 @@ namespace net return fallback; } - int GetMTUWindows(const boost::asio::ip::address& localAddress, int fallback) + int GetMTUWindows (const boost::asio::ip::address& localAddress, int fallback) { #ifdef UNICODE string localAddress_temporary = localAddress.to_string(); @@ -281,7 +301,7 @@ namespace net } } #else // assume unix - int GetMTUUnix(const boost::asio::ip::address& localAddress, int fallback) + int GetMTUUnix (const boost::asio::ip::address& localAddress, int fallback) { ifaddrs* ifaddr, *ifa = nullptr; if(getifaddrs(&ifaddr) == -1) @@ -336,7 +356,7 @@ namespace net } #endif // _WIN32 - int GetMTU(const boost::asio::ip::address& localAddress) + int GetMTU (const boost::asio::ip::address& localAddress) { int fallback = localAddress.is_v6 () ? 1280 : 620; // fallback MTU @@ -348,7 +368,7 @@ namespace net return fallback; } - const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6) + const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6) { #ifdef _WIN32 LogPrint(eLogError, "NetIface: cannot get address by interface name, not implemented on WIN32"); @@ -396,7 +416,7 @@ namespace net #endif } - bool IsInReservedRange(const boost::asio::ip::address& host) { + bool IsInReservedRange (const boost::asio::ip::address& host) { // https://en.wikipedia.org/wiki/Reserved_IP_addresses if(host.is_v4()) { diff --git a/libi2pd/util.h b/libi2pd/util.h index 56ce1e08..f6222b9f 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -168,11 +168,13 @@ namespace util boost::asio::io_service::work m_Work; }; + void SetThreadName (const char *name); + namespace net { int GetMTU (const boost::asio::ip::address& localAddress); - const boost::asio::ip::address GetInterfaceAddress(const std::string & ifname, bool ipv6=false); - bool IsInReservedRange(const boost::asio::ip::address& host); + const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); + bool IsInReservedRange (const boost::asio::ip::address& host); } } } diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 18b7c5a0..61c42b24 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -7,12 +7,12 @@ */ #include -#include #include "Base.h" #include "Log.h" #include "Destination.h" #include "ClientContext.h" #include "I2PTunnel.h" +#include "util.h" namespace i2p { @@ -941,8 +941,8 @@ namespace client } void I2PUDPClientTunnel::TryResolving() { + i2p::util::SetThreadName("UDP Resolver"); LogPrint(eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest); - pthread_setname_np(pthread_self(), "UDP Resolver"); std::shared_ptr addr; while(!(addr = context.GetAddressBook().GetAddress(m_RemoteDest)) && !m_cancel_resolve) From 9a2c6a76197ebf6531acb6b4d5cf7d7d955b3695 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 7 Dec 2020 06:31:46 +0300 Subject: [PATCH 0595/2950] move thread naming to util Signed-off-by: R4SAS --- libi2pd_client/AddressBook.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 6ecbddaf..a69bd660 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -748,7 +748,8 @@ namespace client void AddressBookSubscription::CheckUpdates () { - pthread_setname_np(pthread_self(), "Addressbook"); + i2p::util::SetThreadName("Addressbook"); + bool result = MakeRequest (); m_Book.DownloadComplete (result, m_Ident, m_Etag, m_LastModified); } From ac67cd7f9adf9a8ac36faaab876883fc7526ceb8 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 7 Dec 2020 08:36:06 +0300 Subject: [PATCH 0596/2950] add FreeBSD builder for GHA (#1595) --- .github/workflows/build-freebsd.yml | 20 ++++++++++++++++++++ libi2pd/util.cpp | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-freebsd.yml diff --git a/.github/workflows/build-freebsd.yml b/.github/workflows/build-freebsd.yml new file mode 100644 index 00000000..dbc4028c --- /dev/null +++ b/.github/workflows/build-freebsd.yml @@ -0,0 +1,20 @@ +name: Build on FreeBSD + +on: [push, pull_request] + +jobs: + build: + runs-on: macos-latest + name: with UPnP + steps: + - uses: actions/checkout@v2 + - name: Test in FreeBSD + id: test + uses: vmactions/freebsd-vm@v0.0.9 + with: + usesh: true + prepare: pkg install -y devel/cmake devel/gmake devel/boost-libs security/openssl net/miniupnpc + run: | + cd build + cmake -DWITH_UPNP=ON -DCMAKE_BUILD_TYPE=Release . + gmake -j2 diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 2e8e67ba..e763a848 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -122,7 +122,7 @@ namespace util #if defined (__APPLE__) pthread_setname_np(name); #elif defined(__FreeBSD__) - pthread_set_name_np(pthread_self(), name) + pthread_set_name_np(pthread_self(), name); #else pthread_setname_np(pthread_self(), name); #endif From bfc3acb83469df640882d5cb3d02c2f26e044c11 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 7 Dec 2020 19:47:50 +0300 Subject: [PATCH 0597/2950] use correct function for thread naming on OpenBSD 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 e763a848..794a3f14 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -121,7 +121,7 @@ namespace util void SetThreadName (const char *name) { #if defined (__APPLE__) pthread_setname_np(name); -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) pthread_set_name_np(pthread_self(), name); #else pthread_setname_np(pthread_self(), name); From ba79b94e0680c71f47200fc0b0b227a780730705 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 8 Dec 2020 15:16:40 -0500 Subject: [PATCH 0598/2950] try to generate missing ECIESx25519 tag in last tagset --- libi2pd/Garlic.cpp | 35 +++++++++++++++++++++++++++++------ libi2pd/Garlic.h | 3 ++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 9c008bc0..2d08f339 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -487,17 +487,19 @@ namespace garlic buf += 4; // length bool found = false; + uint64_t tag; if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) { - // try ECIESx25519 tag - uint64_t tag; + // 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)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + 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); } } @@ -542,7 +544,25 @@ namespace garlic // otherwise ECIESx25519 auto session = std::make_shared (this, false); // incoming if (!session->HandleNextMessage (buf, length, nullptr, 0)) - LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + { + // try to gererate more tags for last tagset + if (m_LastTagset) + { + for (int i = 0; i < ECIESX25519_MAX_NUM_GENERATED_TAGS; i++) + { + LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); + if (AddECIESx25519SessionNextTag (m_LastTagset) == tag) + { + if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[tag].index)) + found = true; + break; + } + } + if (!found) m_LastTagset = nullptr; + } + if (!found) + LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message"); + } } else LogPrint (eLogError, "Garlic: Failed to decrypt message"); @@ -845,6 +865,8 @@ namespace garlic } if (numExpiredTags > 0) LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ()); + if (m_LastTagset && m_LastTagset->IsExpired (ts)) + m_LastTagset = nullptr; } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) @@ -1030,11 +1052,12 @@ namespace garlic } } - void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) + uint64_t GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset}); + return tag; } void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session) diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 8df830c7..379477e8 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -245,7 +245,7 @@ namespace garlic void AddECIESx25519Key (const uint8_t * key, const uint8_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); - void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); + uint64_t AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); @@ -285,6 +285,7 @@ namespace garlic int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session + RatchetTagSetPtr m_LastTagset; // tagset last message came for // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session From ca3b8191510c1006d031d02c50edcf6b4f6a6e8f Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 10 Dec 2020 18:32:41 +0300 Subject: [PATCH 0599/2950] [avx] check ig c++ target supports AVX Signed-off-by: R4SAS --- libi2pd/Crypto.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 68712fc7..3e6279ff 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -638,7 +638,7 @@ namespace crypto { uint64_t buf[256]; uint64_t hash[12]; // 96 bytes -#if defined(__x86_64__) || defined(__i386__) +#if (defined(__x86_64__) || defined(__i386__)) && defined(__AVX__) // not all X86 targets supports AVX (like old Pentium, see #1600) if(i2p::cpu::avx) { __asm__ From 7373dae026e50f2cb3754bbd4b108b4a90291c85 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 12 Dec 2020 09:54:07 +0300 Subject: [PATCH 0600/2950] [avx] check if c++ target supports AVX (closes #1600) Signed-off-by: R4SAS --- libi2pd/Identity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 89f6cda0..9dfaa1fc 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -828,7 +828,7 @@ namespace data XORMetric operator^(const IdentHash& key1, const IdentHash& key2) { XORMetric m; -#if defined(__x86_64__) || defined(__i386__) +#if (defined(__x86_64__) || defined(__i386__)) && defined(__AVX__) // not all X86 targets supports AVX (like old Pentium, see #1600) if(i2p::cpu::avx) { __asm__ From c91a8711e358fcf0970876d07e75d0eb9506c473 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 12 Dec 2020 17:14:58 -0500 Subject: [PATCH 0601/2950] encrypted requests to ECIES floodfills --- libi2pd/Destination.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 44180ae5..8f3b495a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -559,9 +559,7 @@ namespace client m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound); - if (floodfill->GetIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // TODO: remove whan implemented - msg = WrapMessageForRouter (floodfill, msg); + auto msg = WrapMessageForRouter (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); @@ -755,10 +753,8 @@ namespace client AddECIESx25519Key (replyKey, replyTag); else AddSessionKey (replyKey, replyTag); - - auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag, isECIES); - if (nextFloodfill->GetIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // TODO: remove whan implemented - msg = WrapMessageForRouter (nextFloodfill, msg); + auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest, + request->excluded, request->replyTunnel, replyKey, replyTag, isECIES)); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock From fc2dc9a0199bf1983673ead4adde19b6ec1c9dec Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 12 Dec 2020 21:40:07 -0500 Subject: [PATCH 0602/2950] cumulative ACK bitfields --- libi2pd/SSUData.cpp | 35 +++++++++++++++++++---------------- libi2pd/SSUData.h | 6 ++++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index 4e0e712f..5458cc97 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -185,7 +185,12 @@ namespace transport std::unique_ptr(new IncompleteMessage (msg)))).first; } std::unique_ptr& incompleteMessage = it->second; - + // mark fragment as received + if (fragmentNum < 64) + incompleteMessage->receivedFragmentsBits |= (0x01 << fragmentNum); + else + LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64"); + // handle current fragment if (fragmentNum == incompleteMessage->nextFragmentNum) { @@ -220,7 +225,7 @@ 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) + if (incompleteMessage->savedFragments.insert (std::unique_ptr(savedFragment)).second) incompleteMessage->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); else LogPrint (eLogWarning, "SSU: Fragment ", (int)fragmentNum, " of message ", msgID, " already saved"); @@ -266,7 +271,7 @@ namespace transport } } else - SendFragmentAck (msgID, fragmentNum); + SendFragmentAck (msgID, incompleteMessage->receivedFragmentsBits); buf += fragmentSize; } } @@ -394,13 +399,9 @@ namespace transport m_Session.Send (buf, 48); } - void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum) + void SSUData::SendFragmentAck (uint32_t msgID, uint64_t bits) { - if (fragmentNum > 64) - { - LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64"); - return; - } + if (!bits) return; uint8_t buf[64 + 18] = {0}; uint8_t * payload = buf + sizeof (SSUHeader); *payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag @@ -410,14 +411,16 @@ namespace transport // one ack *(uint32_t *)(payload) = htobe32 (msgID); // msgID payload += 4; - div_t d = div (fragmentNum, 7); - memset (payload, 0x80, d.quot); // 0x80 means non-last - payload += d.quot; - *payload = 0x01 << d.rem; // set corresponding bit - payload++; + size_t len = 0; + while (bits) + { + *payload = (bits & 0x7F); // next 7 bits + bits >>= 7; + if (bits) *payload &= 0x80; // 0x80 means non-last + payload++; len++; + } *payload = 0; // number of fragments - - size_t len = d.quot < 4 ? 48 : 64; // 48 = 37 + 7 + 4 (3+1) + len = (len <= 4) ? 48 : 64; // 48 = 37 + 7 + 4 // encrypt message with session key m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len); m_Session.Send (buf, len); diff --git a/libi2pd/SSUData.h b/libi2pd/SSUData.h index 2e606053..902c009a 100644 --- a/libi2pd/SSUData.h +++ b/libi2pd/SSUData.h @@ -75,9 +75,11 @@ namespace transport std::shared_ptr msg; int nextFragmentNum; uint32_t lastFragmentInsertTime; // in seconds + uint64_t receivedFragmentsBits; std::set, FragmentCmp> savedFragments; - IncompleteMessage (std::shared_ptr m): msg (m), nextFragmentNum (0), lastFragmentInsertTime (0) {}; + IncompleteMessage (std::shared_ptr m): msg (m), nextFragmentNum (0), + lastFragmentInsertTime (0), receivedFragmentsBits (0) {}; void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize); }; @@ -109,7 +111,7 @@ namespace transport private: void SendMsgAck (uint32_t msgID); - void SendFragmentAck (uint32_t msgID, int fragmentNum); + void SendFragmentAck (uint32_t msgID, uint64_t bits); void ProcessAcks (uint8_t *& buf, uint8_t flag); void ProcessFragments (uint8_t * buf); void ProcessSentMessageAck (uint32_t msgID); From 31f0c350771a431710002dfffb9e94d38d913fa9 Mon Sep 17 00:00:00 2001 From: gxcreator Date: Sun, 13 Dec 2020 17:22:59 +0000 Subject: [PATCH 0603/2950] Docker: Move DEFAULT_ARGS to Dockerfile . --- contrib/docker/Dockerfile | 1 + contrib/docker/entrypoint.sh | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile index be3feea7..adb7ba75 100644 --- a/contrib/docker/Dockerfile +++ b/contrib/docker/Dockerfile @@ -11,6 +11,7 @@ ENV REPO_URL=${REPO_URL} ENV I2PD_HOME="/home/i2pd" ENV DATA_DIR="${I2PD_HOME}/data" +ENV DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0" RUN mkdir -p "$I2PD_HOME" "$DATA_DIR" \ && adduser -S -h "$I2PD_HOME" i2pd \ diff --git a/contrib/docker/entrypoint.sh b/contrib/docker/entrypoint.sh index ca9dddd4..ce897e3c 100644 --- a/contrib/docker/entrypoint.sh +++ b/contrib/docker/entrypoint.sh @@ -2,7 +2,6 @@ COMMAND=/usr/local/bin/i2pd # To make ports exposeable # Note: $DATA_DIR is defined in /etc/profile -DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0" if [ "$1" = "--help" ]; then set -- $COMMAND --help From 65945b3462a5d52dfb0b235dd4dacaea73ee30f6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 13 Dec 2020 21:55:51 -0500 Subject: [PATCH 0604/2950] correct offline signature size for close packet --- libi2pd/Streaming.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 05b34d9e..f6bf7e8b 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -701,7 +701,7 @@ namespace stream size++; // resend delay htobe16buf (packet + size, PACKET_FLAG_CLOSE | PACKET_FLAG_SIGNATURE_INCLUDED); size += 2; // flags - size_t signatureLen = m_LocalDestination.GetOwner ()->GetIdentity ()->GetSignatureLen (); + size_t signatureLen = m_LocalDestination.GetOwner ()->GetPrivateKeys ().GetSignatureLen (); htobe16buf (packet + size, signatureLen); // signature only size += 2; // options size uint8_t * signature = packet + size; From bf91e16b5d7e0d922c96f95a519c8033ce790b65 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Dec 2020 15:04:20 -0500 Subject: [PATCH 0605/2950] gererate specified number of tags if misssing tag --- libi2pd/Garlic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 2d08f339..02ded2f4 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -548,7 +548,8 @@ namespace garlic // try to gererate more tags for last tagset if (m_LastTagset) { - for (int i = 0; i < ECIESX25519_MAX_NUM_GENERATED_TAGS; i++) + auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); + for (int i = 0; i < maxTags; i++) { LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); if (AddECIESx25519SessionNextTag (m_LastTagset) == tag) From 06a7e181cd6a44cf09aeb5046a446e821673c1f9 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 15 Dec 2020 16:06:32 -0500 Subject: [PATCH 0606/2950] ECIES for new routers --- libi2pd/RouterContext.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 5cfbd943..d258b341 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -52,7 +52,8 @@ namespace i2p void RouterContext::CreateNewRouter () { - m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); + m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, + i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); SaveKeys (); NewRouterInfo (); } @@ -590,7 +591,8 @@ namespace i2p // update keys LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new"); oldIdentity = m_Keys.GetPublic (); - m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); + m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, + i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); SaveKeys (); } // read NTCP2 keys if available From 082c4f1104b64ede18f4524e3e75977ca35e1819 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 17 Dec 2020 22:17:05 +0800 Subject: [PATCH 0607/2950] qt: added about box --- qt/i2pd_qt/AboutDialog.cpp | 23 ++++ qt/i2pd_qt/AboutDialog.h | 22 ++++ qt/i2pd_qt/AboutDialog.ui | 194 +++++++++++++++++++++++++++++ qt/i2pd_qt/BuildDateTimeQt.h | 7 ++ qt/i2pd_qt/i2pd_qt.pro | 21 +++- qt/i2pd_qt/mainwindow.cpp | 44 ++++++- qt/i2pd_qt/mainwindow.h | 1 + qt/i2pd_qt/mainwindow.ui | 67 +++++++--- qt/i2pd_qt/routercommandswidget.ui | 4 +- 9 files changed, 353 insertions(+), 30 deletions(-) create mode 100644 qt/i2pd_qt/AboutDialog.cpp create mode 100644 qt/i2pd_qt/AboutDialog.h create mode 100644 qt/i2pd_qt/AboutDialog.ui create mode 100644 qt/i2pd_qt/BuildDateTimeQt.h diff --git a/qt/i2pd_qt/AboutDialog.cpp b/qt/i2pd_qt/AboutDialog.cpp new file mode 100644 index 00000000..2428c2da --- /dev/null +++ b/qt/i2pd_qt/AboutDialog.cpp @@ -0,0 +1,23 @@ +#include "AboutDialog.h" +#include "ui_AboutDialog.h" +#include +#include "version.h" +#include "BuildDateTimeQt.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + qDebug() << "AboutDialog::AboutDialog()" << endl; + ui->setupUi(this); + ui->i2pdVersionLabel->setText(I2PD_VERSION); + ui->i2pVersionLabel->setText(I2P_VERSION); + ui->buildDateTimeLabel->setText(BUILD_DATE_TIME_QT); + ui->vcsCommitInfoLabel->setText(VCS_COMMIT_INFO); +} + +AboutDialog::~AboutDialog() +{ + qDebug() << "AboutDialog::~AboutDialog()" << endl; + delete ui; +} diff --git a/qt/i2pd_qt/AboutDialog.h b/qt/i2pd_qt/AboutDialog.h new file mode 100644 index 00000000..d462de28 --- /dev/null +++ b/qt/i2pd_qt/AboutDialog.h @@ -0,0 +1,22 @@ +#ifndef ABOUTDIALOG_H +#define ABOUTDIALOG_H + +#include + +namespace Ui { +class AboutDialog; +} + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + +private: + Ui::AboutDialog *ui; +}; + +#endif // ABOUTDIALOG_H diff --git a/qt/i2pd_qt/AboutDialog.ui b/qt/i2pd_qt/AboutDialog.ui new file mode 100644 index 00000000..6e662706 --- /dev/null +++ b/qt/i2pd_qt/AboutDialog.ui @@ -0,0 +1,194 @@ + + + AboutDialog + + + Qt::WindowModal + + + + 0 + 0 + 400 + 199 + + + + About i2pd_qt + + + + :/icons/mask:/icons/mask + + + + + 10 + 160 + 381 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + 10 + 10 + 381 + 17 + + + + <html><head/><body><p><span style=" font-weight:600;">About i2pd_qt</span></p></body></html> + + + + + + 10 + 40 + 131 + 17 + + + + i2pd Version: + + + + + + 10 + 70 + 131 + 17 + + + + Build Date/Time: + + + + + + 150 + 40 + 241 + 20 + + + + I2PD_VERSION_LABEL + + + + + + 10 + 130 + 131 + 17 + + + + I2P Version: + + + + + + 150 + 130 + 241 + 17 + + + + I2P_VERSION_LABEL + + + + + + 150 + 70 + 241 + 20 + + + + BUILD_DATE_TIME_LABEL + + + + + + 10 + 100 + 131 + 17 + + + + Version Control: + + + + + + 150 + 100 + 241 + 17 + + + + VCS_COMMIT_INFO_LABEL + + + + + + + + + buttonBox + accepted() + AboutDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AboutDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/qt/i2pd_qt/BuildDateTimeQt.h b/qt/i2pd_qt/BuildDateTimeQt.h new file mode 100644 index 00000000..139e2083 --- /dev/null +++ b/qt/i2pd_qt/BuildDateTimeQt.h @@ -0,0 +1,7 @@ +#ifndef BUILDDATETIMEQT_H +#define BUILDDATETIMEQT_H + +#include +const QString BUILD_DATE_TIME_QT = QStringLiteral(__DATE__ " " __TIME__); + +#endif // BUILDDATETIMEQT_H diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 004b6273..a572e454 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -36,7 +36,8 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../daemon/HTTPServer.cpp \ ../../daemon/I2PControl.cpp \ ../../daemon/i2pd.cpp \ - ../../daemon/UPnP.cpp + ../../daemon/UPnP.cpp \ + AboutDialog.cpp HEADERS += DaemonQT.h mainwindow.h \ ClientTunnelPane.h \ @@ -59,8 +60,9 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../daemon/Daemon.h \ ../../daemon/HTTPServer.h \ ../../daemon/I2PControl.h \ - ../../daemon/UPnP.h - + ../../daemon/UPnP.h \ + AboutDialog.h \ + BuildDateTimeQt.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client @@ -71,7 +73,8 @@ FORMS += mainwindow.ui \ tunnelform.ui \ statusbuttons.ui \ routercommandswidget.ui \ - generalsettingswidget.ui + generalsettingswidget.ui \ + AboutDialog.ui LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz @@ -86,6 +89,16 @@ i2pd.depends = FORCE cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean cleani2pd.depends = clean +BuildDateTimeQtTarget.target = BuildDateTimeQt.h +BuildDateTimeQtTarget.depends = FORCE +# 'touch' is unix-only; will probably break on non-unix, TBD +BuildDateTimeQtTarget.commands = touch $$PWD/BuildDateTimeQt.h +PRE_TARGETDEPS += BuildDateTimeQt.h +QMAKE_EXTRA_TARGETS += BuildDateTimeQtTarget + +# git only, port to other VCS, too. TBD +DEFINES += VCS_COMMIT_INFO="\\\"git:$(shell git -C \""$$_PRO_FILE_PWD_"\" describe)\\\"" + PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a QMAKE_EXTRA_TARGETS += cleani2pd i2pd libi2pd CLEAN_DEPS += cleani2pd diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 89178ee0..925992a5 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,4 +1,5 @@ #include "mainwindow.h" +#include "AboutDialog.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" #include "ui_routercommandswidget.h" @@ -8,6 +9,13 @@ #include #include #include + +#include +#include +#include +#include +#include + #include "RouterContext.h" #include "Config.h" #include "FS.h" @@ -65,6 +73,10 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren statusButtonsUI->setupUi(ui->statusButtonsPane); routerCommandsUI->setupUi(routerCommandsParent); uiSettings->setupUi(ui->settingsContents); + + ui->aboutHrefLabel->setText("

" + "i2pd_qt
Version " I2PD_VERSION " · About...

"); + routerCommandsParent->hide(); ui->verticalLayout_2->addWidget(routerCommandsParent); //,statusHtmlUI(new Ui::StatusHtmlPaneForm) @@ -76,15 +88,16 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren setWindowTitle(QApplication::translate("AppTitle","I2PD")); //TODO handle resizes and change the below into resize() call - setFixedHeight(550); - ui->centralWidget->setFixedHeight(550); + constexpr auto WINDOW_HEIGHT = 610; + setFixedHeight(WINDOW_HEIGHT); + ui->centralWidget->setFixedHeight(WINDOW_HEIGHT); onResize(); ui->stackedWidget->setCurrentIndex(0); ui->settingsScrollArea->resize(uiSettings->settingsContentsQVBoxLayout->sizeHint().width()+10,380); //QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); - int w = 683; - int h = 4550; + constexpr auto w = 683; + constexpr auto h = 4550; ui->settingsContents->setFixedSize(w, h); ui->settingsContents->setGeometry(QRect(0,0,w,h)); @@ -143,6 +156,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren QObject::connect(routerCommandsUI->acceptTransitTunnelsPushButton, SIGNAL(released()), this, SLOT(enableTransit())); QObject::connect(routerCommandsUI->declineTransitTunnelsPushButton, SIGNAL(released()), this, SLOT(disableTransit())); + QObject::connect(ui->aboutHrefLabel, SIGNAL(linkActivated(const QString &)), this, SLOT(showAboutBox(const QString &))); + QObject::connect(ui->logViewerPushButton, SIGNAL(released()), this, SLOT(showLogViewerPage())); QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage())); @@ -400,6 +415,27 @@ void MainWindow::showStatusPage(StatusPage newStatusPage){ } wasSelectingAtStatusMainPage=false; } + +void MainWindow::showAboutBox(const QString & href) { + qDebug() << "MainWindow::showAboutBox(), href:" << href << endl; + AboutDialog dialog(this); + + if (!QGuiApplication::styleHints()->showIsFullScreen() && !QGuiApplication::styleHints()->showIsMaximized()) { + const QWindow * windowHandle = dialog.windowHandle(); + qDebug()<<"AboutDialog windowHandle ptr: "<<(size_t)windowHandle<screen():nullptr; //Qt 5.14+: dialog.screen() + qDebug()<<"AboutDialog screen ptr: "<<(size_t)screen<availableGeometry(); + //dialog.resize(availableGeometry.width() / 3, availableGeometry.height() * 2 / 3); + dialog.move((availableGeometry.width() - dialog.width()) / 2, + (availableGeometry.height() - dialog.height()) / 2); + } + } + //dialog.show(); + (void) dialog.exec(); +} + void MainWindow::showLogViewerPage(){ui->stackedWidget->setCurrentIndex(1);setStatusButtonsVisible(false);} void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(2);setStatusButtonsVisible(false);} void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(3);setStatusButtonsVisible(false);} diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 77c8826b..2114155b 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -442,6 +442,7 @@ public slots: void showTunnelsPage(); void showRestartPage(); void showQuitPage(); + void showAboutBox(const QString & href); private: StatusPage statusPage; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index dcdf88bd..8f942b08 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 908 - 554 + 604 @@ -35,13 +35,13 @@ 908 - 550 + 600 908 - 550 + 600 @@ -50,7 +50,7 @@ 10 10 888 - 531 + 596 @@ -58,7 +58,7 @@ QLayout::SetMaximumSize - + QLayout::SetMinimumSize @@ -67,7 +67,7 @@ 0 0 170 - 496 + 596 @@ -172,6 +172,33 @@ + + + + + 9 + + + + Qt::NoContextMenu + + + Show app name, version and build date + + + <html><head/><body><p><a href="about:i2pd_qt"><span style="text-decoration: none; color:#a0a0a0;"><span style="font-weight: 500;">i2pd_qt</span><br/>Version SHORT_VERSION · About...</span></a></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 6 + + + 0 + + + @@ -629,7 +656,7 @@ - 713 + 707 713 @@ -648,8 +675,8 @@ 0 0 - 713 - 531 + 707 + 586 @@ -690,8 +717,8 @@ 0 0 - 711 - 531 + 707 + 586 @@ -753,8 +780,8 @@ 0 0 - 711 - 531 + 707 + 586 @@ -798,8 +825,8 @@ 0 0 - 81 - 28 + 693 + 498 @@ -820,8 +847,8 @@ 0 0 - 711 - 531 + 707 + 586 @@ -903,8 +930,8 @@ 0 0 - 711 - 531 + 707 + 586 @@ -958,7 +985,7 @@ 0 0 - 711 + 707 531 diff --git a/qt/i2pd_qt/routercommandswidget.ui b/qt/i2pd_qt/routercommandswidget.ui index c5098e8e..f95db1fd 100644 --- a/qt/i2pd_qt/routercommandswidget.ui +++ b/qt/i2pd_qt/routercommandswidget.ui @@ -6,7 +6,7 @@ 0 0 - 711 + 707 300 @@ -24,7 +24,7 @@ 0 0 - 711 + 707 301 From 776dc7ec5277d436631fbfff917b60c2c27a4d72 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 17 Dec 2020 22:30:14 +0800 Subject: [PATCH 0608/2950] qt: about box fixed for older qt5 --- qt/i2pd_qt/mainwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 925992a5..48484349 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -420,6 +420,8 @@ void MainWindow::showAboutBox(const QString & href) { qDebug() << "MainWindow::showAboutBox(), href:" << href << endl; AboutDialog dialog(this); + /* + //doesn't work on older qt5: ‘class QStyleHints’ has no member named ‘showIsMaximized’ if (!QGuiApplication::styleHints()->showIsFullScreen() && !QGuiApplication::styleHints()->showIsMaximized()) { const QWindow * windowHandle = dialog.windowHandle(); qDebug()<<"AboutDialog windowHandle ptr: "<<(size_t)windowHandle< Date: Thu, 17 Dec 2020 22:45:10 +0800 Subject: [PATCH 0609/2950] qt: removed a few debug log lines --- qt/i2pd_qt/AboutDialog.cpp | 2 -- qt/i2pd_qt/mainwindow.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/qt/i2pd_qt/AboutDialog.cpp b/qt/i2pd_qt/AboutDialog.cpp index 2428c2da..ac92694a 100644 --- a/qt/i2pd_qt/AboutDialog.cpp +++ b/qt/i2pd_qt/AboutDialog.cpp @@ -8,7 +8,6 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) { - qDebug() << "AboutDialog::AboutDialog()" << endl; ui->setupUi(this); ui->i2pdVersionLabel->setText(I2PD_VERSION); ui->i2pVersionLabel->setText(I2P_VERSION); @@ -18,6 +17,5 @@ AboutDialog::AboutDialog(QWidget *parent) : AboutDialog::~AboutDialog() { - qDebug() << "AboutDialog::~AboutDialog()" << endl; delete ui; } diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 48484349..70975fb2 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -417,7 +417,6 @@ void MainWindow::showStatusPage(StatusPage newStatusPage){ } void MainWindow::showAboutBox(const QString & href) { - qDebug() << "MainWindow::showAboutBox(), href:" << href << endl; AboutDialog dialog(this); /* From d3bf8c2417a34a6dbe29d85ba82d026e51e596f8 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 17 Dec 2020 23:15:56 +0800 Subject: [PATCH 0610/2950] data: ignored *.tmp.xml --- qt/i2pd_qt/data/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 qt/i2pd_qt/data/.gitignore diff --git a/qt/i2pd_qt/data/.gitignore b/qt/i2pd_qt/data/.gitignore new file mode 100644 index 00000000..dde94bce --- /dev/null +++ b/qt/i2pd_qt/data/.gitignore @@ -0,0 +1,2 @@ +*.tmp.xml + From ccc604c0f4604bf18082f2effe5b2e9174980f37 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 01:13:50 +0800 Subject: [PATCH 0611/2950] qt: fixes #1180 --- qt/i2pd_qt/ClientTunnelPane.h | 7 +++ qt/i2pd_qt/I2pdQtUtil.cpp | 12 ++++ qt/i2pd_qt/I2pdQtUtil.h | 9 +++ qt/i2pd_qt/ServerTunnelPane.h | 11 ++++ qt/i2pd_qt/TunnelPane.cpp | 8 ++- qt/i2pd_qt/TunnelPane.h | 17 ++++++ qt/i2pd_qt/i2pd_qt.pro | 6 +- qt/i2pd_qt/mainwindow.cpp | 47 +++++++++++----- qt/i2pd_qt/mainwindow.h | 103 ++++++++++++++++++++-------------- 9 files changed, 161 insertions(+), 59 deletions(-) create mode 100644 qt/i2pd_qt/I2pdQtUtil.cpp create mode 100644 qt/i2pd_qt/I2pdQtUtil.h diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index 80d331de..f6bf4376 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -79,6 +79,13 @@ protected: ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); assert(ctc!=nullptr); + if(!isValidSingleLine(destinationLineEdit))return false; + if(!isValidSingleLine(portLineEdit))return false; + if(!isValidSingleLine(cryptoTypeLineEdit))return false; + if(!isValidSingleLine(keysLineEdit))return false; + if(!isValidSingleLine(addressLineEdit))return false; + if(!isValidSingleLine(destinationPortLineEdit))return false; + //destination ctc->setdest(destinationLineEdit->text().toStdString()); diff --git a/qt/i2pd_qt/I2pdQtUtil.cpp b/qt/i2pd_qt/I2pdQtUtil.cpp new file mode 100644 index 00000000..35a7adff --- /dev/null +++ b/qt/i2pd_qt/I2pdQtUtil.cpp @@ -0,0 +1,12 @@ +#include "I2pdQtUtil.h" + +bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow) { + bool correct = !widget->text().contains(QRegularExpression("[\r\n]"), nullptr); + if(!correct) { + mainWindow->highlightWrongInput( + QApplication::tr("Single line input expected, but it's multiline"), + inputPage, + widget); + } + return correct; +} diff --git a/qt/i2pd_qt/I2pdQtUtil.h b/qt/i2pd_qt/I2pdQtUtil.h new file mode 100644 index 00000000..90c3e521 --- /dev/null +++ b/qt/i2pd_qt/I2pdQtUtil.h @@ -0,0 +1,9 @@ +#ifndef I2pdQtUtil_H +#define I2pdQtUtil_H + +class QLineEdit; +#include "mainwindow.h" + +bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow); + +#endif // I2pdQtUtil_H diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index 92ee4da5..de844249 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -124,6 +124,17 @@ protected: if(!ok)return false; ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); assert(stc!=nullptr); + + if(!isValidSingleLine(hostLineEdit))return false; + if(!isValidSingleLine(portLineEdit))return false; + if(!isValidSingleLine(cryptoTypeLineEdit))return false; + if(!isValidSingleLine(keysLineEdit))return false; + if(!isValidSingleLine(inPortLineEdit))return false; + if(!isValidSingleLine(accessListLineEdit))return false; + if(!isValidSingleLine(hostOverrideLineEdit))return false; + if(!isValidSingleLine(webIRCPassLineEdit))return false; + if(!isValidSingleLine(addressLineEdit))return false; + stc->sethost(hostLineEdit->text().toStdString()); auto portStr=portLineEdit->text(); diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 4b873ac1..7e15a6a6 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -4,6 +4,8 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include "I2pdQtUtil.h" + TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_): QObject(), mainWindow(mainWindow_), @@ -47,8 +49,6 @@ void TunnelPane::setupTunnelPane( nameLineEdit->setText(tunnelName); setGroupBoxTitle(tunnelName); - QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), - this, SLOT(setGroupBoxTitle(const QString &))); QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updated())); @@ -399,3 +399,7 @@ void TunnelPane::hideWrongInputLabel() const { wrongInputPane->setVisible(false); mainWindow->adjustSizesAccordingToWrongLabel(); } + +bool TunnelPane::isValidSingleLine(QLineEdit* widget) { + return ::isValidSingleLine(widget, WrongInputPageEnum::tunnelsSettingsPage, mainWindow); +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 59303afd..ac21181a 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -119,6 +119,21 @@ protected: public: //returns false when invalid data at UI virtual bool applyDataFromUIToTunnelConfig() { + if(!isValidSingleLine(nameLineEdit)){ + setGroupBoxTitle(QApplication::translate("tunPage", "invalid_tunnel_name")); + return false; + } + if(!isValidSingleLine(inbound_lengthLineEdit))return false; + if(!isValidSingleLine(inbound_quantityLineEdit))return false; + if(!isValidSingleLine(outbound_lengthLineEdit))return false; + if(!isValidSingleLine(outbound_quantityLineEdit))return false; + if(!isValidSingleLine(crypto_tagsToSendLineEdit))return false; + if(!isValidSingleLine(i2cp_leaseSetAuthTypeLineEdit))return false; + if(!isValidSingleLine(i2cp_leaseSetEncTypeLineEdit))return false; + if(!isValidSingleLine(i2cp_leaseSetPrivKeyLineEdit))return false; + if(!isValidSingleLine(i2cp_leaseSetTypeLineEdit))return false; + if(!isValidSingleLine(i2p_streaming_initialAckDelayLineEdit))return false; + setGroupBoxTitle(nameLineEdit->text()); tunnelConfig->setName(nameLineEdit->text().toStdString()); tunnelConfig->setType(readTunnelTypeComboboxData()); I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); @@ -169,6 +184,8 @@ private: i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0)); i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0)); } +protected: + bool isValidSingleLine(QLineEdit* widget); }; #endif // TUNNELPANE_H diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index a572e454..c4e55f53 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -37,7 +37,8 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../daemon/I2PControl.cpp \ ../../daemon/i2pd.cpp \ ../../daemon/UPnP.cpp \ - AboutDialog.cpp + AboutDialog.cpp \ + I2pdQtUtil.cpp HEADERS += DaemonQT.h mainwindow.h \ ClientTunnelPane.h \ @@ -62,7 +63,8 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../daemon/I2PControl.h \ ../../daemon/UPnP.h \ AboutDialog.h \ - BuildDateTimeQt.h + BuildDateTimeQt.h \ + I2pdQtUtil.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 70975fb2..de2c9fb8 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,4 +1,5 @@ #include "mainwindow.h" +#include "I2pdQtUtil.h" #include "AboutDialog.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" @@ -16,6 +17,8 @@ #include #include +#include + #include "RouterContext.h" #include "Config.h" #include "FS.h" @@ -37,6 +40,7 @@ #include "DelayedSaveManagerImpl.h" #include "SaverImpl.h" + std::string programOptionsWriterCurrentSection; MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *parent) : @@ -647,13 +651,13 @@ MainWindow::~MainWindow() FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){ FileChooserItem* retVal; - retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton); + retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton, this); MainWindowItem* super=retVal; configItems.append(super); return retVal; } void MainWindow::initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){ - configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton)); + configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton, this)); } /*void MainWindow::initCombobox(ConfigOption option, QComboBox* comboBox){ configItems.append(new ComboBoxItem(option, comboBox)); @@ -669,25 +673,25 @@ void MainWindow::initSignatureTypeCombobox(ConfigOption option, QComboBox* combo configItems.append(new SignatureTypeComboBoxItem(option, comboBox)); } void MainWindow::initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated){ - configItems.append(new IPAddressStringItem(option, addressLineEdit, fieldNameTranslated)); + configItems.append(new IPAddressStringItem(option, addressLineEdit, fieldNameTranslated, this)); } void MainWindow::initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated){ - configItems.append(new TCPPortStringItem(option, portLineEdit, fieldNameTranslated)); + configItems.append(new TCPPortStringItem(option, portLineEdit, fieldNameTranslated, this)); } void MainWindow::initCheckBox(ConfigOption option, QCheckBox* checkBox) { configItems.append(new CheckBoxItem(option, checkBox)); } void MainWindow::initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){ - configItems.append(new IntegerStringItem(option, numberLineEdit, fieldNameTranslated)); + configItems.append(new IntegerStringItem(option, numberLineEdit, fieldNameTranslated, this)); } void MainWindow::initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){ - configItems.append(new UInt32StringItem(option, numberLineEdit, fieldNameTranslated)); + configItems.append(new UInt32StringItem(option, numberLineEdit, fieldNameTranslated, this)); } void MainWindow::initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){ - configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated)); + configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated, this)); } void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){ - configItems.append(new BaseStringItem(option, lineEdit, QString())); + configItems.append(new BaseStringItem(option, lineEdit, QString(), this)); } NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) { NonGUIOptionItem * retValue; @@ -789,12 +793,17 @@ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocu for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; - if(!item->isValid()){ - highlightWrongInput(QApplication::tr("Invalid value for")+" "+item->getConfigOption().section+"::"+item->getConfigOption().option+". "+item->getRequirementToBeValid()+" "+cannotSaveSettings, item->getWidgetToFocus()); + bool alreadyDisplayedIfWrong=false; + if(!item->isValid(alreadyDisplayedIfWrong)){ + if(!alreadyDisplayedIfWrong) + highlightWrongInput( + QApplication::tr("Invalid value for")+" "+item->getConfigOption().section+"::"+item->getConfigOption().option+". "+item->getRequirementToBeValid()+" "+cannotSaveSettings, + WrongInputPageEnum::generalSettingsPage, + item->getWidgetToFocus()); return false; } } - delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus); + delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus);//TODO does dataSerial work? //FIXME //onLoggingOptionsChange(); return true; @@ -814,6 +823,11 @@ void FolderChooserItem::pushButtonReleased() { void BaseStringItem::installListeners(MainWindow *mainWindow) { QObject::connect(lineEdit, SIGNAL(textChanged(const QString &)), mainWindow, SLOT(updated())); } +bool BaseStringItem::isValid(bool & alreadyDisplayedIfWrong) { + alreadyDisplayedIfWrong=true; + return ::isValidSingleLine(lineEdit, WrongInputPageEnum::generalSettingsPage, mainWindow); +} + void ComboBoxItem::installListeners(MainWindow *mainWindow) { QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), mainWindow, SLOT(updated())); } @@ -825,7 +839,8 @@ void MainWindow::updated() { ui->wrongInputLabel->setVisible(false); adjustSizesAccordingToWrongLabel(); - applyTunnelsUiToConfigs(); + bool correct = applyTunnelsUiToConfigs(); + if(!correct) return; saveAllConfigs(false); } @@ -1010,11 +1025,15 @@ void MainWindow::adjustSizesAccordingToWrongLabel() { } } -void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus) { +void MainWindow::highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus) { bool redVisible = ui->wrongInputLabel->isVisible(); ui->wrongInputLabel->setVisible(true); ui->wrongInputLabel->setText(warningText); if(!redVisible)adjustSizesAccordingToWrongLabel(); if(widgetToFocus){ui->settingsScrollArea->ensureWidgetVisible(widgetToFocus);widgetToFocus->setFocus();} - showSettingsPage(); + switch(inputPage) { + case WrongInputPageEnum::generalSettingsPage: showSettingsPage(); break; + case WrongInputPageEnum::tunnelsSettingsPage: showTunnelsPage(); break; + default: assert(false); break; + } } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 2114155b..34228e43 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -1,6 +1,8 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage }; + #include #include #include @@ -66,6 +68,8 @@ #include "DelayedSaveManagerImpl.h" #include "SaverImpl.h" +#include "I2pdQtUtil.h" + class SaverImpl; class LogViewerManager; @@ -155,19 +159,24 @@ public: }else out << boost::any_cast(optionValue); //let it throw out << "\n\n"; } - virtual bool isValid(){return true;} + virtual bool isValid(bool & alreadyDisplayedIfWrong){alreadyDisplayedIfWrong=false;return true;} }; class NonGUIOptionItem : public MainWindowItem { public: - NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {}; + NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {} virtual ~NonGUIOptionItem(){} - virtual bool isValid() { return true; } + //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; } }; class BaseStringItem : public MainWindowItem { Q_OBJECT public: QLineEdit* lineEdit; - BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_) : MainWindowItem(option_, lineEdit_, requirementToBeValid_), lineEdit(lineEdit_){}; + MainWindow *mainWindow; + BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_, MainWindow* mainWindow_): + MainWindowItem(option_, lineEdit_, requirementToBeValid_), + lineEdit(lineEdit_), + mainWindow(mainWindow_) + {}; virtual ~BaseStringItem(){} virtual void installListeners(MainWindow *mainWindow); virtual QString toString(){ @@ -183,13 +192,13 @@ public: optionValue=fromString(lineEdit->text()); MainWindowItem::saveToStringStream(out); } - virtual bool isValid() { return true; } + virtual bool isValid(bool & alreadyDisplayedIfWrong); }; class FileOrFolderChooserItem : public BaseStringItem { public: QPushButton* browsePushButton; - FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : - BaseStringItem(option_, lineEdit_, QString()), browsePushButton(browsePushButton_) {} + FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw) : + BaseStringItem(option_, lineEdit_, QString(), mw), browsePushButton(browsePushButton_) {} virtual ~FileOrFolderChooserItem(){} }; class FileChooserItem : public FileOrFolderChooserItem { @@ -197,8 +206,8 @@ class FileChooserItem : public FileOrFolderChooserItem { private slots: void pushButtonReleased(); public: - FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : - FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) { + FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw) { QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); } }; @@ -207,20 +216,20 @@ class FolderChooserItem : public FileOrFolderChooserItem{ private slots: void pushButtonReleased(); public: - FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : - FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) { + FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw) { QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); } }; class ComboBoxItem : public MainWindowItem { public: QComboBox* comboBox; - ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){}; + ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){} virtual ~ComboBoxItem(){} virtual void installListeners(MainWindow *mainWindow); virtual void loadFromConfigOption()=0; virtual void saveToStringStream(std::stringstream& out)=0; - virtual bool isValid() { return true; } + //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return ; } }; class LogDestinationComboBoxItem : public ComboBoxItem { public: @@ -237,13 +246,13 @@ public: optionValue=logDest; MainWindowItem::saveToStringStream(out); } - virtual bool isValid() { return true; } + //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; } Q_OBJECT }; class LogLevelComboBoxItem : public ComboBoxItem { public: - LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}; + LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {} virtual ~LogLevelComboBoxItem(){} virtual void loadFromConfigOption(){ MainWindowItem::loadFromConfigOption(); @@ -254,11 +263,11 @@ public: optionValue=comboBox->currentText().toStdString(); MainWindowItem::saveToStringStream(out); } - virtual bool isValid() { return true; } + //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; } }; class SignatureTypeComboBoxItem : public ComboBoxItem { public: - SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}; + SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {} virtual ~SignatureTypeComboBoxItem(){} virtual void loadFromConfigOption(){ MainWindowItem::loadFromConfigOption(); @@ -271,12 +280,12 @@ public: optionValue=(unsigned short)selected; MainWindowItem::saveToStringStream(out); } - virtual bool isValid() { return true; } + //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; } }; class CheckBoxItem : public MainWindowItem { public: QCheckBox* checkBox; - CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){}; + CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){} virtual ~CheckBoxItem(){} virtual void installListeners(MainWindow *mainWindow); virtual void loadFromConfigOption(){ @@ -288,22 +297,25 @@ public: optionValue=checkBox->isChecked(); MainWindowItem::saveToStringStream(out); } - virtual bool isValid() { return true; } + //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; } }; class BaseFormattedStringItem : public BaseStringItem { public: QString fieldNameTranslated; - BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_) : - BaseStringItem(option_, lineEdit_, requirementToBeValid_), fieldNameTranslated(fieldNameTranslated_) {}; + BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_, MainWindow* mw) : + BaseStringItem(option_, lineEdit_, requirementToBeValid_, mw), fieldNameTranslated(fieldNameTranslated_) {} virtual ~BaseFormattedStringItem(){} - virtual bool isValid()=0; + //virtual bool isValid(bool & alreadyDisplayedIfWrong)=0; }; class IntegerStringItem : public BaseFormattedStringItem { public: - IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer.")) {}; + IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer."), mw) {} virtual ~IntegerStringItem(){} - virtual bool isValid(){ + virtual bool isValid(bool & alreadyDisplayedIfWrong){ + bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); + if(!correct)return false; + alreadyDisplayedIfWrong = false; auto str=lineEdit->text(); bool ok; str.toInt(&ok); @@ -314,10 +326,13 @@ public: }; class UShortStringItem : public BaseFormattedStringItem { public: - UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer.")) {}; + UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer."), mw) {} virtual ~UShortStringItem(){} - virtual bool isValid(){ + virtual bool isValid(bool & alreadyDisplayedIfWrong){ + bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); + if(!correct)return false; + alreadyDisplayedIfWrong = false; auto str=lineEdit->text(); bool ok; str.toUShort(&ok); @@ -328,10 +343,13 @@ public: }; class UInt32StringItem : public BaseFormattedStringItem { public: - UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer.")) {}; + UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer."), mw) {} virtual ~UInt32StringItem(){} - virtual bool isValid(){ + virtual bool isValid(bool & alreadyDisplayedIfWrong){ + bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); + if(!correct)return false; + alreadyDisplayedIfWrong = false; auto str=lineEdit->text(); bool ok; str.toUInt(&ok); @@ -342,10 +360,13 @@ public: }; class UInt16StringItem : public BaseFormattedStringItem { public: - UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer.")) {}; + UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer."), mw) {} virtual ~UInt16StringItem(){} - virtual bool isValid(){ + virtual bool isValid(bool & alreadyDisplayedIfWrong){ + bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); + if(!correct)return false; + alreadyDisplayedIfWrong = false; auto str=lineEdit->text(); bool ok; str.toUShort(&ok); @@ -356,14 +377,14 @@ public: }; class IPAddressStringItem : public BaseFormattedStringItem { public: - IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address")) {}; - virtual bool isValid(){return true;}//todo + IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address"), mw) {} + //virtual bool isValid(bool & alreadyDisplayedIfWrong){return true;}//todo }; class TCPPortStringItem : public UShortStringItem { public: - TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : + UShortStringItem(option_, lineEdit_, fieldNameTranslated_,mw) {} }; namespace Ui { @@ -395,7 +416,7 @@ public: void setI2PController(i2p::qt::Controller* controller_); - void highlightWrongInput(QString warningText, QWidget* widgetToFocus); + void highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus); //typedef std::function DefaultValueGetter; From ca78601ada535f222198838f4d59c62bc8a8f95d Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 02:00:57 +0800 Subject: [PATCH 0612/2950] qt: visual fixes --- qt/i2pd_qt/mainwindow.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index de2c9fb8..3d0dc551 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -997,30 +997,33 @@ void MainWindow::backClickedFromChild() { } void MainWindow::adjustSizesAccordingToWrongLabel() { + constexpr auto HEIGHT = 581; + constexpr auto WIDTH = 707; if(ui->wrongInputLabel->isVisible()) { int dh = ui->wrongInputLabel->height()+ui->verticalLayout_7->layout()->spacing(); ui->verticalLayout_7->invalidate(); ui->wrongInputLabel->adjustSize(); ui->stackedWidget->adjustSize(); - ui->stackedWidget->setFixedHeight(531-dh); - ui->settingsPage->setFixedHeight(531-dh); - ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531-dh)); - ui->stackedWidget->setFixedHeight(531-dh); - ui->settingsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); + const auto height = HEIGHT - dh; + ui->stackedWidget->setFixedHeight(height); + ui->settingsPage->setFixedHeight(height); + ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, WIDTH, height)); + ui->stackedWidget->setFixedHeight(height); + ui->settingsScrollArea->setFixedHeight(height-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); ui->settingsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); - ui->tunnelsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing()); + ui->tunnelsScrollArea->setFixedHeight(height-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing()); ui->tunnelsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); }else{ ui->verticalLayout_7->invalidate(); ui->wrongInputLabel->adjustSize(); ui->stackedWidget->adjustSize(); - ui->stackedWidget->setFixedHeight(531); - ui->settingsPage->setFixedHeight(531); - ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531)); - ui->stackedWidget->setFixedHeight(531); - ui->settingsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); + ui->stackedWidget->setFixedHeight(HEIGHT); + ui->settingsPage->setFixedHeight(HEIGHT); + ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, WIDTH, HEIGHT)); + ui->stackedWidget->setFixedHeight(HEIGHT); + ui->settingsScrollArea->setFixedHeight(HEIGHT-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); ui->settingsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); - ui->tunnelsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing()); + ui->tunnelsScrollArea->setFixedHeight(HEIGHT-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing()); ui->tunnelsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); } } From 9c6e3ff1d774948c77e31478742a6f4096235f0d Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 03:39:08 +0800 Subject: [PATCH 0613/2950] qt: fixes #1582 --- qt/i2pd_qt/generalsettingswidget.ui | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index 7a35c0a5..e81d6f1e 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -495,6 +495,11 @@ QGroupBox::title { + + + None + + Error From 669fb62a541cbd28b60b095824de12a0f7237ad7 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 05:37:01 +0800 Subject: [PATCH 0614/2950] qt: fixed great ui pains with tunnels editing --- qt/i2pd_qt/DelayedSaveManager.h | 6 ++++-- qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 28 +++++++++++++-------------- qt/i2pd_qt/DelayedSaveManagerImpl.h | 24 ++++++++++++----------- qt/i2pd_qt/I2pdQtTypes.h | 7 +++++++ qt/i2pd_qt/Saver.h | 7 +++++-- qt/i2pd_qt/SaverImpl.cpp | 10 ++++++---- qt/i2pd_qt/SaverImpl.h | 2 +- qt/i2pd_qt/i2pd_qt.pro | 3 ++- qt/i2pd_qt/mainwindow.cpp | 16 ++++++++------- qt/i2pd_qt/mainwindow.h | 18 ++++++++--------- 10 files changed, 68 insertions(+), 53 deletions(-) create mode 100644 qt/i2pd_qt/I2pdQtTypes.h diff --git a/qt/i2pd_qt/DelayedSaveManager.h b/qt/i2pd_qt/DelayedSaveManager.h index b09aa28f..23821439 100644 --- a/qt/i2pd_qt/DelayedSaveManager.h +++ b/qt/i2pd_qt/DelayedSaveManager.h @@ -2,6 +2,7 @@ #define DELAYEDSAVEMANAGER_H #include "Saver.h" +#include "I2pdQtTypes.h" class DelayedSaveManager { @@ -12,13 +13,14 @@ public: typedef unsigned int DATA_SERIAL_TYPE; - virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool needsTunnelFocus, std::string tunnelNameToFocus)=0; + virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus)=0; //returns false iff save failed virtual bool appExiting()=0; - virtual bool needsFocusOnTunnel()=0; + virtual FocusEnum getFocusOn()=0; virtual std::string& getTunnelNameToFocus()=0; + virtual QWidget* getWidgetToFocus()=0; }; #endif // DELAYEDSAVEMANAGER_H diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp index f6704c17..b0c7c4d2 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp @@ -1,6 +1,7 @@ #include "DelayedSaveManagerImpl.h" DelayedSaveManagerImpl::DelayedSaveManagerImpl() : + widgetToFocus(nullptr), saver(nullptr), lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL), lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP), @@ -21,10 +22,12 @@ bool DelayedSaveManagerImpl::isSaverValid() { return saver != nullptr; } -void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus_) { +void DelayedSaveManagerImpl::delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus) { if(lastDataSerialSeen==dataSerial)return; - this->focusOnTunnel = focusOnTunnel; - tunnelNameToFocus = tunnelNameToFocus_; + this->reloadAfterSave = reloadAfterSave; + this->focusOn = focusOn; + this->tunnelNameToFocus = tunnelNameToFocus; + this->widgetToFocus = widgetToFocus; lastDataSerialSeen=dataSerial; assert(isSaverValid()); TIMESTAMP_TYPE now = getTime(); @@ -42,7 +45,7 @@ bool DelayedSaveManagerImpl::appExiting() { exiting=true; thread->wakeThreadAndJoinThread(); assert(isSaverValid()); - saver->save(false, ""); + saver->save(false, FocusEnum::noFocus); return true; } @@ -71,9 +74,10 @@ void DelayedSaveThread::run() { assert(saver!=nullptr); if(saveNow) { saveNow = false; - const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel(); + const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn(); const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); - saver->save(focusOnTunnel, tunnelNameToFocus); + QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus(); + saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus); continue; } if(defer) { @@ -87,9 +91,10 @@ void DelayedSaveThread::run() { if(delayedSaveManagerImpl->isExiting())return; continue; } - const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel(); + const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn(); const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); - saver->save(focusOnTunnel, tunnelNameToFocus); + QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus(); + saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus); break; //break inner loop } } @@ -131,10 +136,3 @@ Saver* DelayedSaveManagerImpl::getSaver() { return saver; } -bool DelayedSaveManagerImpl::needsFocusOnTunnel() { - return focusOnTunnel; -} - -std::string& DelayedSaveManagerImpl::getTunnelNameToFocus() { - return tunnelNameToFocus; -} diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.h b/qt/i2pd_qt/DelayedSaveManagerImpl.h index cb1f7568..c9a77c31 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.h +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.h @@ -7,14 +7,14 @@ #include #include -#include "mainwindow.h" +#include "I2pdQtTypes.h" #include "DelayedSaveManager.h" #include "Saver.h" class DelayedSaveManagerImpl; +class Saver; -class DelayedSaveThread : public QThread -{ +class DelayedSaveThread : public QThread { Q_OBJECT public: @@ -42,14 +42,17 @@ private: volatile TIMESTAMP_TYPE wakeTime; }; -class DelayedSaveManagerImpl : public DelayedSaveManager -{ +class DelayedSaveManagerImpl : public DelayedSaveManager { + FocusEnum focusOn; + std::string tunnelNameToFocus; + QWidget* widgetToFocus; + bool reloadAfterSave; public: DelayedSaveManagerImpl(); virtual ~DelayedSaveManagerImpl(); virtual void setSaver(Saver* saver); virtual void start(); - virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus); + virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus); virtual bool appExiting(); typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE; @@ -59,8 +62,10 @@ public: Saver* getSaver(); static TIMESTAMP_TYPE getTime(); - bool needsFocusOnTunnel(); - std::string& getTunnelNameToFocus(); + bool isReloadAfterSave() { return reloadAfterSave; } + FocusEnum getFocusOn() { return focusOn; } + std::string& getTunnelNameToFocus() { return tunnelNameToFocus; } + QWidget* getWidgetToFocus() { return widgetToFocus; } private: Saver* saver; @@ -74,9 +79,6 @@ private: bool exiting; DelayedSaveThread* thread; void wakeThreadAndJoinThread(); - - bool focusOnTunnel; - std::string tunnelNameToFocus; }; #endif // DELAYEDSAVEMANAGERIMPL_H diff --git a/qt/i2pd_qt/I2pdQtTypes.h b/qt/i2pd_qt/I2pdQtTypes.h new file mode 100644 index 00000000..c7b1917a --- /dev/null +++ b/qt/i2pd_qt/I2pdQtTypes.h @@ -0,0 +1,7 @@ +#ifndef I2PDQTTYPES_H +#define I2PDQTTYPES_H + +enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage }; +enum FocusEnum { noFocus, focusOnTunnelName, focusOnWidget }; + +#endif // I2PDQTTYPES_H diff --git a/qt/i2pd_qt/Saver.h b/qt/i2pd_qt/Saver.h index cefe0220..bf971fb6 100644 --- a/qt/i2pd_qt/Saver.h +++ b/qt/i2pd_qt/Saver.h @@ -4,6 +4,9 @@ #include #include #include +class QWidget; + +#include "I2pdQtTypes.h" class Saver : public QObject { @@ -11,8 +14,8 @@ class Saver : public QObject public: Saver(); - //false iff failures - virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus)=0; + //FocusEnum::focusNone iff failures //??? wtf + virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus="", QWidget* widgetToFocus=nullptr)=0; signals: void reloadTunnelsConfigAndUISignal(const QString); diff --git a/qt/i2pd_qt/SaverImpl.cpp b/qt/i2pd_qt/SaverImpl.cpp index f35ef5b7..fee2526b 100644 --- a/qt/i2pd_qt/SaverImpl.cpp +++ b/qt/i2pd_qt/SaverImpl.cpp @@ -15,7 +15,7 @@ SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList * config SaverImpl::~SaverImpl() {} -bool SaverImpl::save(const bool focusOnTunnel, const std::string& tunnelNameToFocus) { +bool SaverImpl::save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus) { //save main config { std::stringstream out; @@ -59,12 +59,14 @@ bool SaverImpl::save(const bool focusOnTunnel, const std::string& tunnelNameToFo outfile.close(); } - //reload saved configs + if(reloadAfterSave) { + //reload saved configs #if 0 - i2p::client::context.ReloadConfig(); + i2p::client::context.ReloadConfig(); #endif - if(focusOnTunnel) emit reloadTunnelsConfigAndUISignal(QString::fromStdString(tunnelNameToFocus)); + if(reloadAfterSave) emit reloadTunnelsConfigAndUISignal(focusOn==FocusEnum::focusOnTunnelName?QString::fromStdString(tunnelNameToFocus):""); + } return true; } diff --git a/qt/i2pd_qt/SaverImpl.h b/qt/i2pd_qt/SaverImpl.h index c44877a2..d20f1bbf 100644 --- a/qt/i2pd_qt/SaverImpl.h +++ b/qt/i2pd_qt/SaverImpl.h @@ -19,7 +19,7 @@ class SaverImpl : public Saver public: SaverImpl(MainWindow *mainWindowPtr_, QList * configItems_, std::map* tunnelConfigs_); virtual ~SaverImpl(); - virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus); + virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus); void setConfPath(QString& confpath_); void setTunnelsConfPath(QString& tunconfpath_); private: diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index c4e55f53..b5830d4c 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -64,7 +64,8 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../daemon/UPnP.h \ AboutDialog.h \ BuildDateTimeQt.h \ - I2pdQtUtil.h + I2pdQtUtil.h \ + I2pdQtTypes.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 3d0dc551..2c6e7523 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -783,7 +783,7 @@ void MainWindow::deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf) { } /** returns false iff not valid items present and save was aborted */ -bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){ +bool MainWindow::saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); programOptionsWriterCurrentSection=""; /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); @@ -803,7 +803,7 @@ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocu return false; } } - delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus);//TODO does dataSerial work? //FIXME + delayedSaveManagerPtr->delayedSave(reloadAfterSave, ++dataSerial, focusOn, tunnelNameToFocus, widgetToFocus);//TODO does dataSerial work? //FIXME //onLoggingOptionsChange(); return true; @@ -841,7 +841,7 @@ void MainWindow::updated() { bool correct = applyTunnelsUiToConfigs(); if(!correct) return; - saveAllConfigs(false); + saveAllConfigs(false, FocusEnum::noFocus); } void MainWindowItem::installListeners(MainWindow *mainWindow) {} @@ -916,11 +916,11 @@ bool MainWindow::applyTunnelsUiToConfigs() { return true; } -void MainWindow::reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus) { - reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString()); +void MainWindow::reloadTunnelsConfigAndUI_QString(QString tunnelNameToFocus) { + reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString(), nullptr); } -void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { +void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus, QWidget* widgetToFocus) { deleteTunnelForms(); for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { TunnelConfig* tunconf = it->second; @@ -937,8 +937,10 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol std::map::const_iterator it=mainWindow->tunnelConfigs.find(oldName); if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; + mainWindow->saveAllConfigs(true, FocusEnum::focusOnTunnelName, tunConf->getName()); } - mainWindow->saveAllConfigs(true, tunConf->getName()); + else + mainWindow->saveAllConfigs(false, FocusEnum::noFocus); } void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 34228e43..241d4efb 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -1,8 +1,6 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage }; - #include #include #include @@ -136,7 +134,7 @@ public: std::string optName=""; if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); optName+=option.option.toStdString(); - qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str(); + //qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str(); std::string sectionAsStdStr = option.section.toStdString(); if(!option.section.isEmpty() && sectionAsStdStr!=programOptionsWriterCurrentSection) { @@ -541,12 +539,12 @@ protected: public slots: /** returns false iff not valid items present and save was aborted */ - bool saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus=""); - void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus); + bool saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::string tunnelNameToFocus="", QWidget* widgetToFocus=nullptr); + void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus, QWidget* widgetToFocus); + void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI("", nullptr); } //focus none - void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); } - void reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus); + void reloadTunnelsConfigAndUI_QString(QString tunnelNameToFocus); void addServerTunnelPushButtonReleased(); void addClientTunnelPushButtonReleased(); @@ -651,7 +649,7 @@ private: tunnelConfigs.erase(it); delete tc; } - saveAllConfigs(false); + saveAllConfigs(true, FocusEnum::noFocus); } std::string GenerateNewTunnelName() { @@ -688,7 +686,7 @@ private: sigType, cryptoType); - saveAllConfigs(true, name); + saveAllConfigs(true, FocusEnum::focusOnTunnelName, name); } void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () @@ -726,7 +724,7 @@ private: cryptoType); - saveAllConfigs(true, name); + saveAllConfigs(true, FocusEnum::focusOnTunnelName, name); } void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels () From 83b10fba62b31395f82c0559665e532022308917 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 05:45:11 +0800 Subject: [PATCH 0615/2950] qt: added assert.h - it is needed for ci circumstances --- qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp index b0c7c4d2..bad6fdb5 100644 --- a/qt/i2pd_qt/DelayedSaveManagerImpl.cpp +++ b/qt/i2pd_qt/DelayedSaveManagerImpl.cpp @@ -1,5 +1,7 @@ #include "DelayedSaveManagerImpl.h" +#include + DelayedSaveManagerImpl::DelayedSaveManagerImpl() : widgetToFocus(nullptr), saver(nullptr), From 370ab6307a28552ee776e53710c4bfad9534bc36 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 06:34:22 +0800 Subject: [PATCH 0616/2950] qt: fixes #1581 --- qt/i2pd_qt/mainwindow.cpp | 31 +++++++++++++++++-------------- qt/i2pd_qt/mainwindow.h | 16 +++++++++------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 2c6e7523..1cebc230 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -177,9 +177,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren # define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option)) - initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton); - initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton); - initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton); + initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton, false); + initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton, false); + initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton, false); uiSettings->logDestinationComboBox->clear(); uiSettings->logDestinationComboBox->insertItems(0, QStringList() @@ -189,7 +189,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren ); initLogDestinationCombobox( OPTION("","log",[]{return "";}), uiSettings->logDestinationComboBox); - logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton); + logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton, false); initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox); initCheckBox( OPTION("","logclftime",[]{return "false";}), uiSettings->logclftimeCheckBox);//"Write full CLF-formatted date and time to log (default: write only time)" initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton); @@ -232,7 +232,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); initCheckBox( OPTION("httpproxy","addresshelper",[]{return "true";}), uiSettings->httpProxyAddressHelperCheckBox);//Enable address helper (jump). true by default - initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton); + initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton, false); initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType); initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit); initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit); @@ -245,7 +245,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox); initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); initTCPPortBox( OPTION("socksproxy","port",[]{return "4447";}), uiSettings->socksProxyPortLineEdit, tr("Socks proxy -> Port")); - initFileChooser( OPTION("socksproxy","keys",[]{return "";}), uiSettings->socksProxyKeyFileLineEdit, uiSettings->socksProxyKeyFilePushButton); + initFileChooser( OPTION("socksproxy","keys",[]{return "";}), uiSettings->socksProxyKeyFileLineEdit, uiSettings->socksProxyKeyFilePushButton, false); initSignatureTypeCombobox(OPTION("socksproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_socksProxySignatureType); initStringBox( OPTION("socksproxy","inbound.length",[]{return "";}), uiSettings->socksProxyInboundTunnelsLenLineEdit); initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), uiSettings->socksProxyInboundTunnQuantityLineEdit); @@ -275,8 +275,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), uiSettings->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); initTCPPortBox( OPTION("i2pcontrol","port",[]{return "7650";}), uiSettings->i2pControlPortLineEdit, tr("I2PControl -> Port")); initStringBox( OPTION("i2pcontrol","password",[]{return "";}), uiSettings->i2pControlPasswordLineEdit); - initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), uiSettings->i2pControlCertFileLineEdit, uiSettings->i2pControlCertFileBrowsePushButton); - initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), uiSettings->i2pControlKeyFileLineEdit, uiSettings->i2pControlKeyFileBrowsePushButton); + initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), uiSettings->i2pControlCertFileLineEdit, uiSettings->i2pControlCertFileBrowsePushButton, true); + initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), uiSettings->i2pControlKeyFileLineEdit, uiSettings->i2pControlKeyFileBrowsePushButton, true); initCheckBox( OPTION("upnp","enabled",[]{return "true";}), uiSettings->enableUPnPCheckBox); initStringBox( OPTION("upnp","name",[]{return "I2Pd";}), uiSettings->upnpNameLineEdit); @@ -284,9 +284,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren initCheckBox( OPTION("precomputation","elgamal",[]{return "false";}), uiSettings->useElGamalPrecomputedTablesCheckBox); initCheckBox( OPTION("reseed","verify",[]{return "";}), uiSettings->reseedVerifyCheckBox); - initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton); + initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton, true); initStringBox( OPTION("reseed","urls",[]{return "";}), uiSettings->reseedURLsLineEdit); - initFileChooser( OPTION("reseed","zipfile",[]{return "";}), uiSettings->reseedZipFileLineEdit, uiSettings->reseedZipFileBrowsePushButton); //Path to local .zip file to reseed from + initFileChooser( OPTION("reseed","zipfile",[]{return "";}), uiSettings->reseedZipFileLineEdit, uiSettings->reseedZipFileBrowsePushButton, true); //Path to local .zip file to reseed from initUInt16Box( OPTION("reseed","threshold",[]{return "25";}), uiSettings->reseedThresholdNumberLineEdit, tr("reseedThreshold")); //Minimum number of known routers before requesting reseed. 25 by default initStringBox( OPTION("reseed","proxy",[]{return "";}), uiSettings->reseedProxyLineEdit);//URL for https/socks reseed proxy @@ -649,15 +649,15 @@ MainWindow::~MainWindow() //QMessageBox::information(0, "Debug", "mw destructor 2"); } -FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){ +FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile){ FileChooserItem* retVal; - retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton, this); + retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton, this, requireExistingFile); MainWindowItem* super=retVal; configItems.append(super); return retVal; } void MainWindow::initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){ - configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton, this)); + configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton, this, true)); } /*void MainWindow::initCombobox(ConfigOption option, QComboBox* comboBox){ configItems.append(new ComboBoxItem(option, comboBox)); @@ -811,11 +811,14 @@ bool MainWindow::saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::st void FileChooserItem::pushButtonReleased() { QString fileName = lineEdit->text().trimmed(); - fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)")); + fileName = requireExistingFile ? + QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)")) : + QFileDialog::getSaveFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)")); if(fileName.length()>0)lineEdit->setText(fileName); } void FolderChooserItem::pushButtonReleased() { QString fileName = lineEdit->text().trimmed(); + assert(requireExistingFile); fileName = QFileDialog::getExistingDirectory(nullptr, tr("Open Folder"), fileName); if(fileName.length()>0)lineEdit->setText(fileName); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 241d4efb..6843a98c 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -193,10 +193,12 @@ public: virtual bool isValid(bool & alreadyDisplayedIfWrong); }; class FileOrFolderChooserItem : public BaseStringItem { +protected: + const bool requireExistingFile; public: QPushButton* browsePushButton; - FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw) : - BaseStringItem(option_, lineEdit_, QString(), mw), browsePushButton(browsePushButton_) {} + FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile_) : + BaseStringItem(option_, lineEdit_, QString(), mw), requireExistingFile(requireExistingFile_), browsePushButton(browsePushButton_) {} virtual ~FileOrFolderChooserItem(){} }; class FileChooserItem : public FileOrFolderChooserItem { @@ -204,8 +206,8 @@ class FileChooserItem : public FileOrFolderChooserItem { private slots: void pushButtonReleased(); public: - FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw) : - FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw) { + FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFile) { QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); } }; @@ -214,8 +216,8 @@ class FolderChooserItem : public FileOrFolderChooserItem{ private slots: void pushButtonReleased(); public: - FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw) : - FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw) { + FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFolder) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFolder) { QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); } }; @@ -519,7 +521,7 @@ protected: //LogDestinationComboBoxItem* logOption; FileChooserItem* logFileNameOption; - FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton); + FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile); void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); //void initCombobox(ConfigOption option, QComboBox* comboBox); void initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox); From d4b648510275705b40acdd9d93817cea48354fc1 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 06:57:49 +0800 Subject: [PATCH 0617/2950] qt: small improv --- qt/i2pd_qt/i2pd_qt.pro | 3 +++ qt/i2pd_qt/mainwindow.h | 7 ++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index b5830d4c..c445348a 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -9,7 +9,10 @@ CONFIG += strict_c++ c++11 CONFIG(debug, debug|release) { message(Debug build) + + # do not redirect logging to std::ostream and to Log pane DEFINES += DEBUG_WITH_DEFAULT_LOGGING + I2PDMAKE += DEBUG=yes } else { message(Release build) diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 6843a98c..412a060e 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -118,7 +118,7 @@ public: std::string optName=""; if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); optName+=option.option.toStdString(); - qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; + //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; boost::any programOption; i2p::config::GetOptionAsAny(optName, programOption); optionValue=programOption.empty()?boost::any(std::string("")) @@ -290,7 +290,7 @@ public: virtual void installListeners(MainWindow *mainWindow); virtual void loadFromConfigOption(){ MainWindowItem::loadFromConfigOption(); - qDebug() << "setting value for checkbox " << checkBox->text(); + //qDebug() << "setting value for checkbox " << checkBox->text(); checkBox->setChecked(boost::any_cast(optionValue)); } virtual void saveToStringStream(std::stringstream& out){ @@ -769,16 +769,13 @@ private: std::string dest; if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); - std::cout << "had read tunnel dest: " << dest << std::endl; } int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); - std::cout << "had read tunnel port: " << port << std::endl; // optional params std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); int cryptoType = section.second.get(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0); int destinationPort = section.second.get(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); - std::cout << "had read tunnel destinationPort: " << destinationPort << std::endl; i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); // I2CP std::map options; From 242e3d007c0a733598a7486556ec05a0d6d292c8 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 07:17:01 +0800 Subject: [PATCH 0618/2950] qt: fixes #1529 --- qt/i2pd_qt/mainwindow.cpp | 6 +++--- qt/i2pd_qt/mainwindow.h | 23 +++++++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 1cebc230..50698e7f 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -177,7 +177,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren # define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option)) - initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton, false); + initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton, false, true); initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton, false); initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton, false); @@ -649,9 +649,9 @@ MainWindow::~MainWindow() //QMessageBox::information(0, "Debug", "mw destructor 2"); } -FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile){ +FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile, bool readOnly){ FileChooserItem* retVal; - retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton, this, requireExistingFile); + retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton, this, requireExistingFile, readOnly); MainWindowItem* super=retVal; configItems.append(super); return retVal; diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 412a060e..9d848acf 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -102,12 +102,14 @@ class MainWindow; class MainWindowItem : public QObject { Q_OBJECT +private: ConfigOption option; QWidget* widgetToFocus; QString requirementToBeValid; + const bool readOnly; public: - MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : - option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {} + MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_, bool readOnly_=false) : + option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), readOnly(readOnly_) {} QWidget* getWidgetToFocus(){return widgetToFocus;} QString& getRequirementToBeValid() { return requirementToBeValid; } ConfigOption& getConfigOption() { return option; } @@ -125,6 +127,7 @@ public: :boost::any_cast(programOption).value(); } virtual void saveToStringStream(std::stringstream& out){ + if(readOnly)return; //should readOnly items (conf=) error somewhere, instead of silently skipping save? if(isType(optionValue)) { std::string v = boost::any_cast(optionValue); if(v.empty())return; @@ -170,8 +173,8 @@ class BaseStringItem : public MainWindowItem { public: QLineEdit* lineEdit; MainWindow *mainWindow; - BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_, MainWindow* mainWindow_): - MainWindowItem(option_, lineEdit_, requirementToBeValid_), + BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_, MainWindow* mainWindow_, bool readOnly=false): + MainWindowItem(option_, lineEdit_, requirementToBeValid_, readOnly), lineEdit(lineEdit_), mainWindow(mainWindow_) {}; @@ -197,8 +200,8 @@ protected: const bool requireExistingFile; public: QPushButton* browsePushButton; - FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile_) : - BaseStringItem(option_, lineEdit_, QString(), mw), requireExistingFile(requireExistingFile_), browsePushButton(browsePushButton_) {} + FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile_, bool readOnly) : + BaseStringItem(option_, lineEdit_, QString(), mw, readOnly), requireExistingFile(requireExistingFile_), browsePushButton(browsePushButton_) {} virtual ~FileOrFolderChooserItem(){} }; class FileChooserItem : public FileOrFolderChooserItem { @@ -206,8 +209,8 @@ class FileChooserItem : public FileOrFolderChooserItem { private slots: void pushButtonReleased(); public: - FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile) : - FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFile) { + FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile, bool readOnly) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFile, readOnly) { QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); } }; @@ -217,7 +220,7 @@ private slots: void pushButtonReleased(); public: FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFolder) : - FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFolder) { + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFolder, false) { QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); } }; @@ -521,7 +524,7 @@ protected: //LogDestinationComboBoxItem* logOption; FileChooserItem* logFileNameOption; - FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile); + FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile, bool readOnly=false); void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); //void initCombobox(ConfigOption option, QComboBox* comboBox); void initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox); From d7342586a696f17bf3ec293f115994d85c3331ed Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 07:44:37 +0800 Subject: [PATCH 0619/2950] qt: fixes #1593 --- qt/i2pd_qt/i2pd_qt.pro | 2 ++ qt/i2pd_qt/mainwindow.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index c445348a..5aefe3f5 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -13,9 +13,11 @@ CONFIG(debug, debug|release) { # do not redirect logging to std::ostream and to Log pane DEFINES += DEBUG_WITH_DEFAULT_LOGGING + DEFINES += I2PD_QT_DEBUG I2PDMAKE += DEBUG=yes } else { message(Release build) + DEFINES += I2PD_QT_RELEASE I2PDMAKE += DEBUG=no } diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 50698e7f..386b06d7 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -188,6 +188,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren << QApplication::translate("MainWindow", "file", 0) ); initLogDestinationCombobox( OPTION("","log",[]{return "";}), uiSettings->logDestinationComboBox); +#ifdef I2PD_QT_RELEASE + uiSettings->logDestinationComboBox->setEnabled(false); // #1593 +#endif logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton, false); initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox); @@ -325,7 +328,15 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren # undef OPTION //widgetlocks.add(new widgetlock(widget,lockbtn)); + + + // #1593 +#ifdef I2PD_QT_RELEASE + uiSettings->logDestComboEditPushButton->setEnabled(false); +#else widgetlocks.add(new widgetlock(uiSettings->logDestinationComboBox,uiSettings->logDestComboEditPushButton)); +#endif + widgetlocks.add(new widgetlock(uiSettings->logLevelComboBox,uiSettings->logLevelComboEditPushButton)); widgetlocks.add(new widgetlock(uiSettings->comboBox_httpPorxySignatureType,uiSettings->httpProxySignTypeComboEditPushButton)); widgetlocks.add(new widgetlock(uiSettings->comboBox_socksProxySignatureType,uiSettings->socksProxySignTypeComboEditPushButton)); From 8c61e7d227c387f2edd54d97121fb5f78324ce75 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 17 Dec 2020 18:58:30 -0500 Subject: [PATCH 0620/2950] replace LeaseSet completely if store type changes --- libi2pd/Destination.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 8f3b495a..52ede959 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -379,7 +379,8 @@ namespace client LogPrint (eLogDebug, "Destination: Remote LeaseSet"); std::lock_guard lock(m_RemoteLeaseSetsMutex); auto it = m_RemoteLeaseSets.find (key); - if (it != m_RemoteLeaseSets.end ()) + if (it != m_RemoteLeaseSets.end () && + it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type { leaseSet = it->second; if (leaseSet->IsNewer (buf + offset, len - offset)) @@ -399,6 +400,7 @@ namespace client } else { + // add or replace if (buf[DATABASE_STORE_TYPE_OFFSET] == i2p::data::NETDB_STORE_TYPE_LEASESET) leaseSet = std::make_shared (buf + offset, len - offset); // LeaseSet else From 0b084956e610e3c730b66aa4d2442275b6e67404 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 09:04:40 +0800 Subject: [PATCH 0621/2950] qt: stream.kill hrefs done - step to completion of #914 --- qt/i2pd_qt/mainwindow.cpp | 56 ++++++++++++++++++++++++++++++++++----- qt/i2pd_qt/mainwindow.h | 1 + 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 386b06d7..034b9c4a 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -45,6 +45,7 @@ std::string programOptionsWriterCurrentSection; MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *parent) : QMainWindow(parent) + ,currentLocalDestinationB32("") ,logStream(logStream_) ,delayedSaveManagerPtr(new DelayedSaveManagerImpl()) ,dataSerial(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL) @@ -135,6 +136,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren //childTextBrowser->setOpenExternalLinks(false); childTextBrowser->setOpenLinks(false); connect(textBrowser, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(anchorClickedHandler(const QUrl&))); + connect(childTextBrowser, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(anchorClickedHandler(const QUrl&))); pageWithBackButton = new PageWithBackButton(this, childTextBrowser); ui->verticalLayout_2->addWidget(pageWithBackButton); pageWithBackButton->hide(); @@ -992,20 +994,60 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { qDebug()< params; + i2p::http::URL url; + url.parse(str.toStdString()); + url.parse_query(params); + const std::string page = params["page"]; + const std::string cmd = params["cmd"]; + if(page == "local_destination") { + std::string b32 = params["b32"]; + currentLocalDestinationB32 = b32; pageWithBackButton->show(); textBrowser->hide(); std::stringstream s; - std::string strstd = str.toStdString(); + std::string strstd = currentLocalDestinationB32; i2p::http::ShowLocalDestination(s,strstd,0); childTextBrowser->setHtml(QString::fromStdString(s.str())); } + if(cmd == "closestream") { + std::string b32 = params["b32"]; + uint32_t streamID = std::stoul(params["streamID"], nullptr); + + i2p::data::IdentHash ident; + ident.FromBase32 (b32); + auto dest = i2p::client::context.FindLocalDestination (ident); + + if (streamID) { + if (dest) { + if(dest->DeleteStream (streamID)) + QMessageBox::information( + this, + QApplication::tr("Success"), + QApplication::tr("SUCCESS: Stream closed")); + else + QMessageBox::critical( + this, + QApplication::tr("Error"), + QApplication::tr("ERROR: Stream not found or already was closed")); + } + else + QMessageBox::critical( + this, + QApplication::tr("Error"), + QApplication::tr("ERROR: Destination not found")); + } + else + QMessageBox::critical( + this, + QApplication::tr("Error"), + QApplication::tr("ERROR: StreamID is null")); + std::stringstream s; + std::string strstd = currentLocalDestinationB32; + i2p::http::ShowLocalDestination(s,strstd,0); + childTextBrowser->setHtml(QString::fromStdString(s.str())); + } } void MainWindow::backClickedFromChild() { diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 9d848acf..789e4cb0 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -410,6 +410,7 @@ class DelayedSaveManagerImpl; class MainWindow : public QMainWindow { Q_OBJECT private: + std::string currentLocalDestinationB32; std::shared_ptr logStream; DelayedSaveManagerImpl* delayedSaveManagerPtr; DelayedSaveManager::DATA_SERIAL_TYPE dataSerial; From 5c2f1f36e8d1df08c98d87c6c141e5155012cab1 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 09:40:58 +0800 Subject: [PATCH 0622/2950] qt: sam session is now shown at qt->sam sessions, work towards #914 --- daemon/HTTPServer.cpp | 2 +- daemon/HTTPServer.h | 1 + qt/i2pd_qt/mainwindow.cpp | 12 +++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 25b6ab19..c0a0b72b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -820,7 +820,7 @@ namespace http { s << "SAM Sessions: no sessions currently running.
\r\n"; } - static void ShowSAMSession (std::stringstream& s, const std::string& id) + void ShowSAMSession (std::stringstream& s, const std::string& id) { auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index a977e3e8..9b50fc32 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -98,6 +98,7 @@ namespace http void ShowSAMSessions (std::stringstream& s); void ShowI2PTunnels (std::stringstream& s); void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); + void ShowSAMSession (std::stringstream& s, const std::string& id); } // http } // i2p diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 034b9c4a..e5ce2729 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1001,7 +1001,14 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { url.parse_query(params); const std::string page = params["page"]; const std::string cmd = params["cmd"]; - if(page == "local_destination") { + if(page == "sam_session") { + const std::string samID = params["sam_id"]; + pageWithBackButton->show(); + textBrowser->hide(); + std::stringstream s; + i2p::http::ShowSAMSession (s, samID); + childTextBrowser->setHtml(QString::fromStdString(s.str())); + } else if(page == "local_destination") { std::string b32 = params["b32"]; currentLocalDestinationB32 = b32; pageWithBackButton->show(); @@ -1010,8 +1017,7 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { std::string strstd = currentLocalDestinationB32; i2p::http::ShowLocalDestination(s,strstd,0); childTextBrowser->setHtml(QString::fromStdString(s.str())); - } - if(cmd == "closestream") { + } else if(cmd == "closestream") { std::string b32 = params["b32"]; uint32_t streamID = std::stoul(params["streamID"], nullptr); From a0d90717c335cfaf700cdb86e2819bd49e9c7a43 Mon Sep 17 00:00:00 2001 From: user Date: Fri, 18 Dec 2020 10:06:57 +0800 Subject: [PATCH 0623/2950] qt: i2cp server page is now shown, work towards #914 --- daemon/HTTPServer.cpp | 2 +- daemon/HTTPServer.h | 1 + qt/i2pd_qt/mainwindow.cpp | 13 +++++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c0a0b72b..aba30fd7 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -532,7 +532,7 @@ namespace http { } } - static void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id) + void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id) { auto i2cpServer = i2p::client::context.GetI2CPServer (); if (i2cpServer) diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index 9b50fc32..8e1520b8 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -99,6 +99,7 @@ namespace http void ShowI2PTunnels (std::stringstream& s); void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); void ShowSAMSession (std::stringstream& s, const std::string& id); + void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id); } // http } // i2p diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index e5ce2729..e0123dc8 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1001,14 +1001,13 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { url.parse_query(params); const std::string page = params["page"]; const std::string cmd = params["cmd"]; - if(page == "sam_session") { - const std::string samID = params["sam_id"]; + if (page == "sam_session") { pageWithBackButton->show(); textBrowser->hide(); std::stringstream s; - i2p::http::ShowSAMSession (s, samID); + i2p::http::ShowSAMSession (s, params["sam_id"]); childTextBrowser->setHtml(QString::fromStdString(s.str())); - } else if(page == "local_destination") { + } else if (page == "local_destination") { std::string b32 = params["b32"]; currentLocalDestinationB32 = b32; pageWithBackButton->show(); @@ -1017,6 +1016,12 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { std::string strstd = currentLocalDestinationB32; i2p::http::ShowLocalDestination(s,strstd,0); childTextBrowser->setHtml(QString::fromStdString(s.str())); + } else if (page == "i2cp_local_destination") { + pageWithBackButton->show(); + textBrowser->hide(); + std::stringstream s; + i2p::http::ShowI2CPLocalDestination (s, params["i2cp_id"]); + childTextBrowser->setHtml(QString::fromStdString(s.str())); } else if(cmd == "closestream") { std::string b32 = params["b32"]; uint32_t streamID = std::stoul(params["streamID"], nullptr); From a61d7fe115b3b3a34f10fc2877d20085ec5b0049 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 18 Dec 2020 20:48:08 -0500 Subject: [PATCH 0624/2950] set correct NAME for NAMING REPLY --- libi2pd_client/SAM.cpp | 14 +++++++------- libi2pd_client/SAM.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index d758f31e..9f7e771e 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -708,16 +708,16 @@ namespace client auto session = m_Owner.FindSession(m_ID); auto dest = session == nullptr ? context.GetSharedLocalDestination() : session->localDestination; if (name == "ME") - SendNamingLookupReply (dest->GetIdentity ()); + SendNamingLookupReply (name, dest->GetIdentity ()); else if ((identity = context.GetAddressBook ().GetFullAddress (name)) != nullptr) - SendNamingLookupReply (identity); + SendNamingLookupReply (name, identity); else if ((addr = context.GetAddressBook ().GetAddress (name))) { if (addr->IsIdentHash ()) { auto leaseSet = dest->FindLeaseSet (addr->identHash); if (leaseSet) - SendNamingLookupReply (leaseSet->GetIdentity ()); + SendNamingLookupReply (name, leaseSet->GetIdentity ()); else dest->RequestDestination (addr->identHash, std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete, @@ -756,7 +756,7 @@ namespace client if (leaseSet) { context.GetAddressBook ().InsertFullAddress (leaseSet->GetIdentity ()); - SendNamingLookupReply (leaseSet->GetIdentity ()); + SendNamingLookupReply (name, leaseSet->GetIdentity ()); } else { @@ -770,13 +770,13 @@ namespace client } } - void SAMSocket::SendNamingLookupReply (std::shared_ptr identity) + void SAMSocket::SendNamingLookupReply (const std::string& name, std::shared_ptr identity) { auto base64 = identity->ToBase64 (); #ifdef _MSC_VER - size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, base64.c_str ()); + size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, name.c_str (), base64.c_str ()); #else - size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, base64.c_str ()); + size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, name.c_str (), base64.c_str ()); #endif SendMessageReply (m_Buffer, l, false); } diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index fafd7d1c..9495bf6f 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -55,7 +55,7 @@ namespace client const char SAM_DEST_REPLY[] = "DEST REPLY PUB=%s PRIV=%s\n"; const char SAM_DEST_REPLY_I2P_ERROR[] = "DEST REPLY RESULT=I2P_ERROR\n"; const char SAM_NAMING_LOOKUP[] = "NAMING LOOKUP"; - const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; + const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=%s VALUE=%s\n"; const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n"; const char SAM_RAW_RECEIVED[] = "RAW RECEIVED SIZE=%lu\n"; const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; @@ -140,7 +140,7 @@ namespace client void Connect (std::shared_ptr remote, std::shared_ptr session = nullptr); void HandleConnectLeaseSetRequestComplete (std::shared_ptr leaseSet); - void SendNamingLookupReply (std::shared_ptr identity); + void SendNamingLookupReply (const std::string& name, std::shared_ptr identity); void HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr leaseSet, std::string name); void HandleSessionReadinessCheckTimer (const boost::system::error_code& ecode); void SendSessionCreateReplyOk (); From ae1b1da34282ec95a244b97eb3832a70af27300d Mon Sep 17 00:00:00 2001 From: user Date: Sat, 19 Dec 2020 21:16:40 +0800 Subject: [PATCH 0625/2950] qt: log level ui control now synced with core and log pane ui at runtime --- qt/i2pd_qt/mainwindow.cpp | 15 +++++++++++++++ qt/i2pd_qt/mainwindow.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index e0123dc8..7aa868fc 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -196,6 +196,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton, false); initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox); + + QObject::connect(uiSettings->logLevelComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(syncLogLevel(int))); + initCheckBox( OPTION("","logclftime",[]{return "false";}), uiSettings->logclftimeCheckBox);//"Write full CLF-formatted date and time to log (default: write only time)" initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton); initIPAddressBox( OPTION("","host",[]{return "";}), uiSettings->routerExternalHostLineEdit, tr("Router external address -> Host")); @@ -1109,3 +1112,15 @@ void MainWindow::highlightWrongInput(QString warningText, WrongInputPageEnum inp default: assert(false); break; } } + +void MainWindow::syncLogLevel (int /*comboBoxIndex*/) { + std::string level = uiSettings->logLevelComboBox->currentText().toLower().toStdString(); + if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug") + i2p::log::Logger().SetLogLevel(level); + else { + LogPrint(eLogError, "unknown loglevel set attempted"); + return; + } + i2p::log::Logger().Reopen (); +} + diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 789e4cb0..e1ddcc6e 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -453,7 +453,10 @@ private slots: void runPeerTest(); void enableTransit(); void disableTransit(); + public slots: + void syncLogLevel (int comboBoxIndex); + void showStatus_local_destinations_Page(); void showStatus_leasesets_Page(); void showStatus_tunnels_Page(); From da7e2f25808bba3e5dc6c59d2e37407895cb7573 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 19 Dec 2020 15:07:12 -0500 Subject: [PATCH 0626/2950] don't send message through non-established session --- libi2pd/Datagram.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 559b0a8b..9d61f5e0 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -295,11 +295,11 @@ namespace datagram } } - if (!m_RoutingSession || !m_RoutingSession->GetOwner ()) + if (!m_RoutingSession || !m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ()) { bool found = false; for (auto& it: m_PendingRoutingSessions) - if (it->GetOwner ()) // found established session + if (it->GetOwner () && m_RoutingSession->IsReadyToSend ()) // found established session { m_RoutingSession = it; m_PendingRoutingSessions.clear (); @@ -309,7 +309,7 @@ namespace datagram if (!found) { m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); - if (!m_RoutingSession->GetOwner ()) + if (!m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ()) m_PendingRoutingSessions.push_back (m_RoutingSession); } } From f2e4d5f06c8d21885f70429b0a9a2d912db1a8a1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 20 Dec 2020 19:52:06 -0500 Subject: [PATCH 0627/2950] trim behind not affter max generated tags --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index ecc7412f..a2c5b612 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -298,7 +298,10 @@ namespace garlic break; case eECIESx25519BlkNextKey: LogPrint (eLogDebug, "Garlic: next key"); - HandleNextKey (buf + offset, size, receiveTagset); + if (receiveTagset) + HandleNextKey (buf + offset, size, receiveTagset); + else + LogPrint (eLogError, "Garlic: Unexpected next key block"); break; case eECIESx25519BlkAck: { @@ -721,20 +724,19 @@ namespace garlic { if (receiveTagset->GetNextIndex () - index < GetOwner ()->GetNumRatchetInboundTags ()/2) moreTags = GetOwner ()->GetNumRatchetInboundTags (); + index -= GetOwner ()->GetNumRatchetInboundTags (); // trim behind } else { moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4 if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS; moreTags -= (receiveTagset->GetNextIndex () - index); + index -= ECIESX25519_MAX_NUM_GENERATED_TAGS; // trim behind } if (moreTags > 0) - { GenerateMoreReceiveTags (receiveTagset, moreTags); - index -= (moreTags >> 1); // /2 - if (index > 0) - receiveTagset->SetTrimBehind (index); - } + if (index > 0) + receiveTagset->SetTrimBehind (index); } return true; } From d34dc397e880eddb4af241a420440de4d4543894 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 24 Dec 2020 14:06:34 -0500 Subject: [PATCH 0628/2950] changed to 320 tags max --- libi2pd/ECIESX25519AEADRatchetSession.h | 2 +- libi2pd/Garlic.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 59be94c1..805ea8d6 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -33,7 +33,7 @@ namespace garlic const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 8192; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; - const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160; + const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 320; const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12; const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 02ded2f4..019cc387 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -551,9 +551,9 @@ namespace garlic auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); for (int i = 0; i < maxTags; i++) { - LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); if (AddECIESx25519SessionNextTag (m_LastTagset) == tag) { + LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[tag].index)) found = true; break; From b4236b04c6eed5d20b569df27eada2bfcab02d2d Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 25 Dec 2020 09:01:55 -0500 Subject: [PATCH 0629/2950] leaset creation timeout --- libi2pd_client/I2CP.cpp | 24 +++++++++++++++++++++++- libi2pd_client/I2CP.h | 5 ++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index cb618b5d..c9db4a82 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -26,7 +26,8 @@ namespace client I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, std::shared_ptr identity, bool isPublic, const std::map& params): LeaseSetDestination (service, isPublic, ¶ms), - m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()) + m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()), + m_IsCreatingLeaseSet (false), m_LeaseSetCreationTimer (service) { } @@ -34,6 +35,7 @@ namespace client { LeaseSetDestination::Stop (); m_Owner = nullptr; + m_LeaseSetCreationTimer.cancel (); } void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) @@ -84,6 +86,11 @@ namespace client void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) { + if (m_IsCreatingLeaseSet) + { + LogPrint (eLogInfo, "I2CP: LeaseSet is being created"); + return; + } uint8_t priv[256] = {0}; i2p::data::LocalLeaseSet ls (m_Identity, priv, tunnels); // we don't care about encryption key, we need leases only m_LeaseSetExpirationTime = ls.GetExpirationTime (); @@ -94,15 +101,28 @@ namespace client uint16_t sessionID = m_Owner->GetSessionID (); if (sessionID != 0xFFFF) { + m_IsCreatingLeaseSet = true; htobe16buf (leases - 3, sessionID); size_t l = 2/*sessionID*/ + 1/*num leases*/ + i2p::data::LEASE_SIZE*tunnels.size (); m_Owner->SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); + m_LeaseSetCreationTimer.expires_from_now (boost::posix_time::seconds (I2CP_LEASESET_CREATION_TIMEOUT)); + auto s = GetSharedFromThis (); + m_LeaseSetCreationTimer.async_wait ([s](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogInfo, "I2CP: LeaseSet creation timeout expired. Terminate"); + if (s->m_Owner) s->m_Owner->Stop (); + } + }); } } } void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len) { + m_IsCreatingLeaseSet = false; + m_LeaseSetCreationTimer.cancel (); auto ls = std::make_shared (m_Identity, buf, len); ls->SetExpirationTime (m_LeaseSetExpirationTime); SetLeaseSet (ls); @@ -110,6 +130,8 @@ namespace client void I2CPDestination::LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len) { + m_IsCreatingLeaseSet = false; + m_LeaseSetCreationTimer.cancel (); auto ls = (storeType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) ? std::make_shared (m_Identity, buf, len): std::make_shared (storeType, m_Identity, buf, len); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 32f32221..da7d8ffa 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -27,7 +27,8 @@ namespace client const size_t I2CP_SESSION_BUFFER_SIZE = 4096; const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; const size_t I2CP_MAX_SEND_QUEUE_SIZE = 1024*1024; // in bytes, 1M - + const int I2CP_LEASESET_CREATION_TIMEOUT = 10; // in seconds + const size_t I2CP_HEADER_LENGTH_OFFSET = 0; const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1; @@ -109,6 +110,8 @@ namespace client std::shared_ptr m_ECIESx25519Decryptor; uint8_t m_ECIESx25519PrivateKey[32]; uint64_t m_LeaseSetExpirationTime; + bool m_IsCreatingLeaseSet; + boost::asio::deadline_timer m_LeaseSetCreationTimer; }; class RunnableI2CPDestination: private i2p::util::RunnableService, public I2CPDestination From 86ff0d86dbdc3df86c7a41e7d2ba64adc00a04ab Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 26 Dec 2020 17:18:29 -0500 Subject: [PATCH 0630/2950] check if new tag was created --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 18 ++++++++++++++++-- libi2pd/Garlic.cpp | 13 ++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a2c5b612..01be859b 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -45,13 +45,13 @@ namespace garlic uint64_t RatchetTagSet::GetNextSessionTag () { - i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64) m_NextIndex++; if (m_NextIndex >= 65535) { 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 (); } @@ -687,6 +687,13 @@ namespace garlic auto index = m_SendTagset->GetNextIndex (); CreateNonce (index, nonce); // tag's index uint64_t tag = m_SendTagset->GetNextSessionTag (); + if (!tag) + { + LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for send tagset"); + if (GetOwner ()) + GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey); + return false; + } memcpy (out, &tag, 8); // ad = The session tag, 8 bytes // ciphertext = ENCRYPT(k, n, payload, ad) @@ -1050,7 +1057,14 @@ namespace garlic if (GetOwner ()) { for (int i = 0; i < numTags; i++) - GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset); + { + auto tag = GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset); + if (!tag) + { + LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for receive tagset"); + break; + } + } } } diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 019cc387..aff92837 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -546,12 +546,18 @@ namespace garlic if (!session->HandleNextMessage (buf, length, nullptr, 0)) { // try to gererate more tags for last tagset - if (m_LastTagset) + if (m_LastTagset && m_LastTagset->GetNextIndex () < 2*ECIESX25519_TAGSET_MAX_NUM_TAGS) { auto maxTags = std::max (m_NumRatchetInboundTags, ECIESX25519_MAX_NUM_GENERATED_TAGS); for (int i = 0; i < maxTags; i++) { - if (AddECIESx25519SessionNextTag (m_LastTagset) == tag) + auto nextTag = AddECIESx25519SessionNextTag (m_LastTagset); + if (!nextTag) + { + LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for last tagset"); + break; + } + if (nextTag == tag) { LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated"); if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[tag].index)) @@ -1057,7 +1063,8 @@ namespace garlic { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); - m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset}); + if (tag) + m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset}); return tag; } From 7ce92118e4451956fd8b5c9b224a236e2ebe8a26 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Dec 2020 11:18:53 -0500 Subject: [PATCH 0631/2950] handle follow-on NSR messages --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 36 ++++++++++++----------- libi2pd/ECIESX25519AEADRatchetSession.h | 5 +++- libi2pd/util.h | 14 +++++++++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 01be859b..d2286b15 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -9,6 +9,7 @@ #include #include #include "Log.h" +#include "util.h" #include "Crypto.h" #include "Elligator.h" #include "Tag.h" @@ -619,18 +620,15 @@ namespace garlic } buf += 32; len -= 32; // KDF for Reply Key Section - uint8_t h[32]; memcpy (h, m_H, 32); // save m_H + i2p::util::SaveStateHelper s(*this); // restore noise state on exit MixHash (tag, 8); // h = SHA256(h || tag) MixHash (bepk, 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - if (m_State == eSessionStateNewSessionSent) - { - // only fist time, we assume ephemeral keys the same - m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) - MixKey (sharedSecret); - GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) - MixKey (sharedSecret); - } + m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + MixKey (sharedSecret); + GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) + MixKey (sharedSecret); + uint8_t nonce[12]; CreateNonce (0, nonce); // calculate hash for zero length @@ -646,6 +644,7 @@ namespace garlic i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) if (m_State == eSessionStateNewSessionSent) { + // only first time, then we keep using existing tagsets // k_ab = keydata[0:31], k_ba = keydata[32:63] m_SendTagset = std::make_shared(shared_from_this ()); m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) @@ -667,11 +666,10 @@ namespace garlic if (m_State == eSessionStateNewSessionSent) { m_State = eSessionStateEstablished; - m_EphemeralKeys = nullptr; + //m_EphemeralKeys = nullptr; // TODO: delete after a while m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch (); GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ()); } - memcpy (m_H, h, 32); // restore m_H HandlePayload (buf, len - 16, nullptr, 0); // we have received reply to NS with LeaseSet in it @@ -762,12 +760,16 @@ namespace garlic [[fallthrough]]; #endif case eSessionStateEstablished: - if (HandleExistingSessionMessage (buf, len, receiveTagset, index)) return true; - // check NSR just in case - LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); - if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2) - GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS); - return HandleNewOutgoingSessionReply (buf, len); + if (receiveTagset->IsNS ()) + { + // our of sequence NSR + LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index); + if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2) + GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS); + return HandleNewOutgoingSessionReply (buf, len); + } + else + return HandleExistingSessionMessage (buf, len, receiveTagset, index); case eSessionStateNew: return HandleNewIncomingSession (buf, len); case eSessionStateNewSessionSent: diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 805ea8d6..86e3ffc0 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -45,7 +45,8 @@ namespace garlic public: RatchetTagSet (std::shared_ptr session): m_Session (session) {}; - + virtual bool IsNS () const { return false; }; + void DHInitialize (const uint8_t * rootKey, const uint8_t * k); void NextSessionTagRatchet (); uint64_t GetNextSessionTag (); @@ -91,6 +92,8 @@ namespace garlic NSRatchetTagSet (std::shared_ptr session): RatchetTagSet (session), m_DummySession (session) {}; + + bool IsNS () const { return true; }; private: diff --git a/libi2pd/util.h b/libi2pd/util.h index f6222b9f..e6de09ed 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -170,6 +170,20 @@ namespace util void SetThreadName (const char *name); + template + class SaveStateHelper + { + public: + + 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 726bd0d63b2553347b285e559718533634178b63 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 Jan 2021 15:03:11 -0500 Subject: [PATCH 0632/2950] check if x25519 key is valid --- libi2pd/Crypto.cpp | 5 ++- libi2pd/Crypto.h | 2 +- libi2pd/CryptoKey.cpp | 3 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 48 +++++++++++++++++++---- libi2pd/Garlic.cpp | 1 + libi2pd/RouterContext.cpp | 6 ++- 6 files changed, 52 insertions(+), 13 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 3e6279ff..68850a9d 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -351,11 +351,13 @@ namespace crypto #endif } - void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) + bool X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) { + if (pub[31] & 0x80) return false; // not x25519 key #if OPENSSL_X25519 EVP_PKEY_derive_init (m_Ctx); auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); + if (!pkey) return false; EVP_PKEY_derive_set_peer (m_Ctx, pkey); size_t len = 32; EVP_PKEY_derive (m_Ctx, shared, &len); @@ -363,6 +365,7 @@ namespace crypto #else GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx); #endif + return true; } void X25519Keys::GetPrivateKey (uint8_t * priv) const diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index c63cc45e..a6c64c70 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -89,7 +89,7 @@ namespace crypto const uint8_t * GetPublicKey () const { return m_PublicKey; }; void GetPrivateKey (uint8_t * priv) const; void SetPrivateKey (const uint8_t * priv, bool calculatePublic = false); - void Agree (const uint8_t * pub, uint8_t * shared); + bool Agree (const uint8_t * pub, uint8_t * shared); bool IsElligatorIneligible () const { return m_IsElligatorIneligible; } void SetElligatorIneligible () { m_IsElligatorIneligible = true; } diff --git a/libi2pd/CryptoKey.cpp b/libi2pd/CryptoKey.cpp index 4518a347..ad93d386 100644 --- a/libi2pd/CryptoKey.cpp +++ b/libi2pd/CryptoKey.cpp @@ -173,8 +173,7 @@ namespace crypto bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding) { - m_StaticKeys.Agree (epub, sharedSecret); - return true; + return m_StaticKeys.Agree (epub, sharedSecret); } void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index d2286b15..cbf5175a 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -231,7 +231,11 @@ namespace garlic MixHash (m_Aepk, 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, aepk) + if (!GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key"); + return false; + } MixKey (sharedSecret); // decrypt flags/static @@ -251,7 +255,11 @@ namespace garlic { // static key, fs is apk memcpy (m_RemoteStaticKey, fs, 32); - GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, apk) + if (!GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, apk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); + return false; + } MixKey (sharedSecret); } else // all zeros flags @@ -448,7 +456,11 @@ namespace garlic i2p::crypto::InitNoiseIKState (*this, m_RemoteStaticKey); // bpk MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || aepk) uint8_t sharedSecret[32]; - m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) + if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // x25519(aesk, bpk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob static key"); + return false; + } MixKey (sharedSecret); // encrypt flags/static key section uint8_t nonce[12]; @@ -504,7 +516,11 @@ namespace garlic MixHash (out + offset, 32); // h = SHA256(h || aepk) offset += 32; uint8_t sharedSecret[32]; - m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk) + 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); @@ -540,9 +556,17 @@ namespace garlic MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys->Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk) + if (!m_EphemeralKeys->Agree (m_Aepk, sharedSecret)) // sharedSecret = x25519(besk, aepk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key"); + return false; + } MixKey (sharedSecret); - m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk) + if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Alice static key"); + return false; + } MixKey (sharedSecret); uint8_t nonce[12]; CreateNonce (0, nonce); @@ -624,7 +648,11 @@ namespace garlic MixHash (tag, 8); // h = SHA256(h || tag) MixHash (bepk, 32); // h = SHA256(h || bepk) uint8_t sharedSecret[32]; - m_EphemeralKeys->Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk) + if (!m_EphemeralKeys->Agree (bepk, sharedSecret)) // sharedSecret = x25519(aesk, bepk) + { + LogPrint (eLogWarning, "Garlic: Incorrect Bob ephemeral key"); + return false; + } MixKey (sharedSecret); GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk) MixKey (sharedSecret); @@ -788,7 +816,11 @@ namespace garlic i2p::crypto::InitNoiseNState (*this, GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk MixHash (buf, 32); uint8_t sharedSecret[32]; - GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519(bsk, aepk) + 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; + } MixKey (sharedSecret); buf += 32; len -= 32; uint8_t nonce[12]; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index aff92837..6f9a37b9 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -866,6 +866,7 @@ namespace garlic { it->second.tagset->DeleteSymmKey (it->second.index); it = m_ECIESx25519Tags.erase (it); + numExpiredTags++; } else ++it; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index d258b341..ce1eede0 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -729,7 +729,11 @@ namespace i2p m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState)); m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk) uint8_t sharedSecret[32]; - m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false); + if (!m_Decryptor->Decrypt (encrypted, sharedSecret, ctx, false)) + { + LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); + return false; + } m_CurrentNoiseState->MixKey (sharedSecret); encrypted += 32; uint8_t nonce[12]; From ee3cd44f975f395a760f39d3522bef2089169447 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 4 Jan 2021 18:20:16 -0500 Subject: [PATCH 0633/2950] ReceiveRatchetTagSet --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 30 ++++++------ libi2pd/ECIESX25519AEADRatchetSession.h | 57 +++++++++++++++-------- libi2pd/Garlic.cpp | 2 +- libi2pd/Garlic.h | 10 ++-- 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index cbf5175a..2a0f5cb4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -100,7 +100,7 @@ namespace garlic m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; } - bool RatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) + bool ReceiveRatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) { auto session = GetSession (); if (!session) return false; @@ -108,7 +108,7 @@ namespace garlic } DatabaseLookupTagSet::DatabaseLookupTagSet (GarlicDestination * destination, const uint8_t * key): - RatchetTagSet (nullptr), m_Destination (destination) + ReceiveRatchetTagSet (nullptr), m_Destination (destination) { memcpy (m_Key, key, 32); Expire (); @@ -203,12 +203,12 @@ namespace garlic return false; } - std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () + std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () { uint8_t tagsetKey[32]; i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) // Session Tag Ratchet - auto tagsetNsr = (m_State == eSessionStateNewSessionReceived) ? std::make_shared(shared_from_this ()): + auto tagsetNsr = (m_State == eSessionStateNewSessionReceived) ? std::make_shared(shared_from_this ()): std::make_shared(shared_from_this ()); tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) tagsetNsr->NextSessionTagRatchet (); @@ -284,7 +284,7 @@ namespace garlic return true; } - void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index) + void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index) { size_t offset = 0; while (offset < len) @@ -352,7 +352,7 @@ namespace garlic } } - void ECIESX25519AEADRatchetSession::HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset) + void ECIESX25519AEADRatchetSession::HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset) { uint8_t flag = buf[0]; buf++; // flag if (flag & ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG) @@ -367,7 +367,7 @@ namespace garlic uint8_t sharedSecret[32], tagsetKey[32]; m_NextSendRatchet->key->Agree (m_NextSendRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) - auto newTagset = std::make_shared (shared_from_this ()); + auto newTagset = std::make_shared (); newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID); newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); @@ -409,7 +409,7 @@ namespace garlic uint8_t sharedSecret[32], tagsetKey[32]; m_NextReceiveRatchet->key->Agree (m_NextReceiveRatchet->remote, sharedSecret); i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32) - auto newTagset = std::make_shared(shared_from_this ()); + auto newTagset = std::make_shared(shared_from_this ()); newTagset->SetTagSetID (tagsetID); newTagset->DHInitialize (receiveTagset->GetNextRootKey (), tagsetKey); newTagset->NextSessionTagRatchet (); @@ -582,10 +582,10 @@ namespace garlic uint8_t keydata[64]; i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64) // k_ab = keydata[0:31], k_ba = keydata[32:63] - auto receiveTagset = std::make_shared(shared_from_this ()); + auto receiveTagset = std::make_shared(shared_from_this()); receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) receiveTagset->NextSessionTagRatchet (); - m_SendTagset = std::make_shared(shared_from_this ()); + m_SendTagset = std::make_shared(); m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) m_SendTagset->NextSessionTagRatchet (); GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? @@ -674,10 +674,10 @@ namespace garlic { // only first time, then we keep using existing tagsets // k_ab = keydata[0:31], k_ba = keydata[32:63] - m_SendTagset = std::make_shared(shared_from_this ()); + m_SendTagset = std::make_shared(); m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab) m_SendTagset->NextSessionTagRatchet (); - auto receiveTagset = std::make_shared(shared_from_this ()); + auto receiveTagset = std::make_shared(shared_from_this ()); receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba) receiveTagset->NextSessionTagRatchet (); GenerateMoreReceiveTags (receiveTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ? @@ -736,7 +736,7 @@ namespace garlic } bool ECIESX25519AEADRatchetSession::HandleExistingSessionMessage (uint8_t * buf, size_t len, - std::shared_ptr receiveTagset, int index) + std::shared_ptr receiveTagset, int index) { uint8_t nonce[12]; CreateNonce (index, nonce); // tag's index @@ -775,7 +775,7 @@ namespace garlic } bool ECIESX25519AEADRatchetSession::HandleNextMessage (uint8_t * buf, size_t len, - std::shared_ptr receiveTagset, int index) + std::shared_ptr receiveTagset, int index) { m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); switch (m_State) @@ -1086,7 +1086,7 @@ namespace garlic return cloveSize + 3; } - void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) + void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags) { if (GetOwner ()) { diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 86e3ffc0..0cc7935e 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -39,12 +39,13 @@ namespace garlic const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */ // - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */ - class ECIESX25519AEADRatchetSession; - class RatchetTagSet: public std::enable_shared_from_this + class RatchetTagSet { public: - RatchetTagSet (std::shared_ptr session): m_Session (session) {}; + RatchetTagSet () {}; + virtual ~RatchetTagSet () {}; + virtual bool IsNS () const { return false; }; void DHInitialize (const uint8_t * rootKey, const uint8_t * k); @@ -55,16 +56,12 @@ namespace garlic void GetSymmKey (int index, uint8_t * key); void DeleteSymmKey (int index); - std::shared_ptr GetSession () { return m_Session.lock (); }; int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; - void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; - + void Expire (); bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - virtual bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; - - virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); + private: @@ -79,19 +76,39 @@ namespace garlic } m_KeyData; uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32]; - int m_NextIndex, m_NextSymmKeyIndex, m_TrimBehindIndex = 0; + int m_NextIndex, m_NextSymmKeyIndex; std::unordered_map > m_ItermediateSymmKeys; - std::weak_ptr m_Session; + int m_TagSetID = 0; uint64_t m_ExpirationTimestamp = 0; }; - class NSRatchetTagSet: public RatchetTagSet + class ECIESX25519AEADRatchetSession; + class ReceiveRatchetTagSet: public RatchetTagSet, + public std::enable_shared_from_this + { + public: + + ReceiveRatchetTagSet (std::shared_ptr session): m_Session (session) {}; + + std::shared_ptr GetSession () { return m_Session.lock (); }; + void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; + + virtual bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); + + private: + + int m_TrimBehindIndex = 0; + std::weak_ptr m_Session; + }; + + class NSRatchetTagSet: public ReceiveRatchetTagSet { public: NSRatchetTagSet (std::shared_ptr session): - RatchetTagSet (session), m_DummySession (session) {}; + ReceiveRatchetTagSet (session), m_DummySession (session) {}; bool IsNS () const { return true; }; @@ -100,7 +117,7 @@ namespace garlic std::shared_ptr m_DummySession; // we need a strong pointer for NS }; - class DatabaseLookupTagSet: public RatchetTagSet + class DatabaseLookupTagSet: public ReceiveRatchetTagSet { public: @@ -160,7 +177,7 @@ namespace garlic ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet); ~ECIESX25519AEADRatchetSession (); - bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); + bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index = 0); bool HandleNextMessageForRouter (const uint8_t * buf, size_t len); std::shared_ptr WrapSingleMessage (std::shared_ptr msg); std::shared_ptr WrapOneTimeMessage (std::shared_ptr msg, bool isForRouter = false); @@ -185,13 +202,13 @@ namespace garlic void CreateNonce (uint64_t seqn, uint8_t * nonce); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes - std::shared_ptr CreateNewSessionTagset (); + std::shared_ptr CreateNewSessionTagset (); bool HandleNewIncomingSession (const uint8_t * buf, size_t len); bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); - bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); - void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); - void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); + bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr receiveTagset, int index); + void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset, int index); + void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr& receiveTagset); bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen, bool isStatic = true); bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen); @@ -203,7 +220,7 @@ namespace garlic 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); - void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); + void GenerateMoreReceiveTags (std::shared_ptr receiveTagset, int numTags); void NewNextSendRatchet (); private: diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 6f9a37b9..17406b4f 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -1060,7 +1060,7 @@ namespace garlic } } - uint64_t GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset) + uint64_t GarlicDestination::AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset) { auto index = tagset->GetNextIndex (); uint64_t tag = tagset->GetNextSessionTag (); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 379477e8..a8806921 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -215,12 +215,12 @@ namespace garlic class ECIESX25519AEADRatchetSession; typedef std::shared_ptr ECIESX25519AEADRatchetSessionPtr; - class RatchetTagSet; - typedef std::shared_ptr RatchetTagSetPtr; + class ReceiveRatchetTagSet; + typedef std::shared_ptr ReceiveRatchetTagSetPtr; struct ECIESX25519AEADRatchetIndexTagset { int index; - RatchetTagSetPtr tagset; + ReceiveRatchetTagSetPtr tagset; }; class GarlicDestination: public i2p::data::LocalDestination @@ -245,7 +245,7 @@ namespace garlic void AddECIESx25519Key (const uint8_t * key, const uint8_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 (RatchetTagSetPtr tagset); + uint64_t AddECIESx25519SessionNextTag (ReceiveRatchetTagSetPtr tagset); void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session); void RemoveECIESx25519Session (const uint8_t * staticKey); void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len); @@ -285,7 +285,7 @@ namespace garlic int m_NumRatchetInboundTags; std::unordered_map, std::hash > > m_Tags; std::unordered_map m_ECIESx25519Tags; // session tag -> session - RatchetTagSetPtr m_LastTagset; // tagset last message came for + ReceiveRatchetTagSetPtr m_LastTagset; // tagset last message came for // DeliveryStatus std::mutex m_DeliveryStatusSessionsMutex; std::unordered_map m_DeliveryStatusSessions; // msgID -> session From bc4a97774f049a53e8f1a841a3d1488dc4900681 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 4 Jan 2021 20:15:48 -0500 Subject: [PATCH 0634/2950] strong pointer to session for receive tagset --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 19 +++++++++----- libi2pd/ECIESX25519AEADRatchetSession.h | 32 +++++++---------------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 2a0f5cb4..a83c9285 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -100,6 +100,11 @@ namespace garlic m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; } + bool ReceiveRatchetTagSet::IsIndexExpired (int index) const + { + return index < m_TrimBehindIndex || !m_Session || !m_Session->GetOwner (); + } + bool ReceiveRatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) { auto session = GetSession (); @@ -203,16 +208,13 @@ namespace garlic return false; } - std::shared_ptr ECIESX25519AEADRatchetSession::CreateNewSessionTagset () + void ECIESX25519AEADRatchetSession::InitNewSessionTagset (std::shared_ptr tagsetNsr) const { uint8_t tagsetKey[32]; i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32) // Session Tag Ratchet - auto tagsetNsr = (m_State == eSessionStateNewSessionReceived) ? std::make_shared(shared_from_this ()): - std::make_shared(shared_from_this ()); tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey) tagsetNsr->NextSessionTagRatchet (); - return tagsetNsr; } bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len) @@ -501,7 +503,11 @@ namespace garlic { MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext) if (GetOwner ()) - GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS); + { + auto tagsetNsr = std::make_shared(shared_from_this (), true); + InitNewSessionTagset (tagsetNsr); + GenerateMoreReceiveTags (tagsetNsr, ECIESX25519_NSR_NUM_GENERATED_TAGS); + } } return true; } @@ -538,7 +544,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen) { // we are Bob - m_NSRSendTagset = CreateNewSessionTagset (); + m_NSRSendTagset = std::make_shared(); + InitNewSessionTagset (m_NSRSendTagset); uint64_t tag = m_NSRSendTagset->GetNextSessionTag (); size_t offset = 0; diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 0cc7935e..526f2ea4 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -46,8 +46,6 @@ namespace garlic RatchetTagSet () {}; virtual ~RatchetTagSet () {}; - virtual bool IsNS () const { return false; }; - void DHInitialize (const uint8_t * rootKey, const uint8_t * k); void NextSessionTagRatchet (); uint64_t GetNextSessionTag (); @@ -60,8 +58,7 @@ namespace garlic void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; void Expire (); - bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - + bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; private: @@ -89,32 +86,21 @@ namespace garlic { public: - ReceiveRatchetTagSet (std::shared_ptr session): m_Session (session) {}; + ReceiveRatchetTagSet (std::shared_ptr session, bool isNS = false): + m_Session (session), m_IsNS (isNS) {}; - std::shared_ptr GetSession () { return m_Session.lock (); }; + bool IsNS () const { return m_IsNS; }; + std::shared_ptr GetSession () { return m_Session; }; void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; - virtual bool IsIndexExpired (int index) const { return m_Session.expired () || index < m_TrimBehindIndex; }; + virtual bool IsIndexExpired (int index) const; virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); private: int m_TrimBehindIndex = 0; - std::weak_ptr m_Session; - }; - - class NSRatchetTagSet: public ReceiveRatchetTagSet - { - public: - - NSRatchetTagSet (std::shared_ptr session): - ReceiveRatchetTagSet (session), m_DummySession (session) {}; - - bool IsNS () const { return true; }; - - private: - - std::shared_ptr m_DummySession; // we need a strong pointer for NS + std::shared_ptr m_Session; + bool m_IsNS; }; class DatabaseLookupTagSet: public ReceiveRatchetTagSet @@ -202,7 +188,7 @@ namespace garlic void CreateNonce (uint64_t seqn, uint8_t * nonce); bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes - std::shared_ptr CreateNewSessionTagset (); + void InitNewSessionTagset (std::shared_ptr tagsetNsr) const; bool HandleNewIncomingSession (const uint8_t * buf, size_t len); bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len); From b1262d54dec0de2f659873428bf53ba408dd4aee Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Jan 2021 15:56:48 -0500 Subject: [PATCH 0635/2950] don't detach ECIESx25519 session from destination --- libi2pd/Datagram.cpp | 2 +- libi2pd/ECIESX25519AEADRatchetSession.cpp | 9 +++++++-- libi2pd/ECIESX25519AEADRatchetSession.h | 18 ++++++++++-------- libi2pd/Garlic.cpp | 11 +++++++++-- libi2pd/Garlic.h | 1 + libi2pd/Streaming.cpp | 2 +- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 9d61f5e0..32db8ff1 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -295,7 +295,7 @@ namespace datagram } } - if (!m_RoutingSession || !m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ()) + if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) { bool found = false; for (auto& it: m_PendingRoutingSessions) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index a83c9285..870995e8 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -94,15 +94,20 @@ namespace garlic m_ItermediateSymmKeys.erase (index); } - void RatchetTagSet::Expire () + void ReceiveRatchetTagSet::Expire () { if (!m_ExpirationTimestamp) m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT; } + bool ReceiveRatchetTagSet::IsExpired (uint64_t ts) const + { + return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; + } + bool ReceiveRatchetTagSet::IsIndexExpired (int index) const { - return index < m_TrimBehindIndex || !m_Session || !m_Session->GetOwner (); + return index < m_TrimBehindIndex || !m_Session || m_Session->IsTerminated (); } bool ReceiveRatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 526f2ea4..974f1b15 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -56,10 +56,7 @@ namespace garlic int GetTagSetID () const { return m_TagSetID; }; void SetTagSetID (int tagsetID) { m_TagSetID = tagsetID; }; - - void Expire (); - bool IsExpired (uint64_t ts) const { return m_ExpirationTimestamp && ts > m_ExpirationTimestamp; }; - + private: union @@ -77,7 +74,6 @@ namespace garlic std::unordered_map > m_ItermediateSymmKeys; int m_TagSetID = 0; - uint64_t m_ExpirationTimestamp = 0; }; class ECIESX25519AEADRatchetSession; @@ -93,14 +89,18 @@ namespace garlic std::shared_ptr GetSession () { return m_Session; }; void SetTrimBehind (int index) { if (index > m_TrimBehindIndex) m_TrimBehindIndex = index; }; + void Expire (); + bool IsExpired (uint64_t ts) const; + virtual bool IsIndexExpired (int index) const; virtual bool HandleNextMessage (uint8_t * buf, size_t len, int index); private: - + int m_TrimBehindIndex = 0; std::shared_ptr m_Session; bool m_IsNS; + uint64_t m_ExpirationTimestamp = 0; }; class DatabaseLookupTagSet: public ReceiveRatchetTagSet @@ -170,7 +170,8 @@ namespace garlic const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; } void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); } - + + void Terminate () { m_IsTerminated = true; } void SetDestination (const i2p::data::IdentHash& dest) // TODO: { if (!m_Destination) m_Destination.reset (new i2p::data::IdentHash (dest)); @@ -182,6 +183,7 @@ namespace garlic bool IsRatchets () const { return true; }; bool IsReadyToSend () const { return m_State != eSessionStateNewSessionSent; }; + bool IsTerminated () const { return m_IsTerminated; } uint64_t GetLastActivityTimestamp () const { return m_LastActivityTimestamp; }; private: @@ -221,7 +223,7 @@ namespace garlic std::shared_ptr m_SendTagset, m_NSRSendTagset; std::unique_ptr m_Destination;// TODO: might not need it std::list > m_AckRequests; // (tagsetid, index) - bool m_SendReverseKey = false, m_SendForwardKey = false; + bool m_SendReverseKey = false, m_SendForwardKey = false, m_IsTerminated = false; std::unique_ptr m_NextReceiveRatchet, m_NextSendRatchet; uint8_t m_PaddingSizes[32], m_NextPaddingSize; diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 17406b4f..a2b012db 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -445,9 +445,16 @@ namespace garlic void GarlicDestination::CleanUp () { + for (auto it: m_Sessions) + it.second->SetOwner (nullptr); m_Sessions.clear (); m_DeliveryStatusSessions.clear (); m_Tags.clear (); + for (auto it: m_ECIESx25519Sessions) + { + it.second->Terminate (); + it.second->SetOwner (nullptr); + } m_ECIESx25519Sessions.clear (); m_ECIESx25519Tags.clear (); } @@ -852,7 +859,7 @@ namespace garlic { if (it->second->CheckExpired (ts)) { - it->second->SetOwner (nullptr); + it->second->Terminate (); it = m_ECIESx25519Sessions.erase (it); } else @@ -1077,7 +1084,7 @@ namespace garlic { if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ())) { - it->second->SetOwner (nullptr); // detach + it->second->Terminate (); // detach m_ECIESx25519Sessions.erase (it); } else diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index a8806921..4288e74b 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -115,6 +115,7 @@ namespace garlic virtual bool MessageConfirmed (uint32_t msgID); virtual bool IsRatchets () const { return false; }; virtual bool IsReadyToSend () const { return true; }; + virtual bool IsTerminated () const { return !GetOwner (); }; virtual uint64_t GetLastActivityTimestamp () const { return 0; }; // non-zero for rathets only void SetLeaseSetUpdated () diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index f6bf7e8b..a873a660 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -764,7 +764,7 @@ namespace stream return; } } - if (!m_RoutingSession || !m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ()) // expired and detached or new session sent + if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) // expired and detached or new session sent m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true); if (!m_CurrentOutboundTunnel && m_RoutingSession) // first message to send { From aedcd1bcc031448eb56a138d6e767bd9780196ef Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 7 Jan 2021 14:51:23 -0500 Subject: [PATCH 0636/2950] remove tag after tagset expiration --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 2 +- libi2pd/Garlic.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index 870995e8..b8c47b73 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -107,7 +107,7 @@ namespace garlic bool ReceiveRatchetTagSet::IsIndexExpired (int index) const { - return index < m_TrimBehindIndex || !m_Session || m_Session->IsTerminated (); + return index < m_TrimBehindIndex; } bool ReceiveRatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index a2b012db..42aca5be 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -876,7 +876,12 @@ namespace garlic numExpiredTags++; } else + { + auto session = it->second.tagset->GetSession (); + if (!session || session->IsTerminated()) + it->second.tagset->Expire (); ++it; + } } if (numExpiredTags > 0) LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ()); @@ -1101,7 +1106,7 @@ namespace garlic auto it = m_ECIESx25519Sessions.find (staticKey); if (it != m_ECIESx25519Sessions.end ()) { - it->second->SetOwner (nullptr); + it->second->Terminate (); m_ECIESx25519Sessions.erase (it); } } From 29176dd9bff9b244c3dcf8b4c3063d8da409cf6b Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 9 Jan 2021 18:59:09 -0500 Subject: [PATCH 0637/2950] count last send time for expiration --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 3 ++- libi2pd/ECIESX25519AEADRatchetSession.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index b8c47b73..bfba7852 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -1117,7 +1117,8 @@ namespace garlic bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts) { CleanupUnconfirmedLeaseSet (ts); - return ts > m_LastActivityTimestamp + ECIESX25519_EXPIRATION_TIMEOUT; + return ts > m_LastActivityTimestamp + ECIESX25519_RECEIVE_EXPIRATION_TIMEOUT && // seconds + ts*1000 > m_LastSentTimestamp + ECIESX25519_SEND_EXPIRATION_TIMEOUT*1000; // milliseconds } std::shared_ptr WrapECIESX25519AEADRatchetMessage (std::shared_ptr msg, const uint8_t * key, uint64_t tag) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index 974f1b15..3aaa3d62 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -26,10 +26,10 @@ namespace i2p namespace garlic { const int ECIESX25519_RESTART_TIMEOUT = 120; // number of second since session creation we can restart session after - const int ECIESX25519_EXPIRATION_TIMEOUT = 480; // in seconds const int ECIESX25519_INACTIVITY_TIMEOUT = 90; // number of seconds we receive nothing and should restart if we can const int ECIESX25519_SEND_INACTIVITY_TIMEOUT = 5000; // number of milliseconds we can send empty(pyaload only) packet after - const int ECIESX25519_INCOMING_TAGS_EXPIRATION_TIMEOUT = 600; // in seconds + const int ECIESX25519_SEND_EXPIRATION_TIMEOUT = 480; // in seconds + const int ECIESX25519_RECEIVE_EXPIRATION_TIMEOUT = 600; // in seconds const int ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT = 180; // 180 const int ECIESX25519_TAGSET_MAX_NUM_TAGS = 8192; // number of tags we request new tagset after const int ECIESX25519_MIN_NUM_GENERATED_TAGS = 24; @@ -218,7 +218,7 @@ namespace garlic uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only std::shared_ptr m_EphemeralKeys; SessionState m_State = eSessionStateNew; - uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming + uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds) m_LastSentTimestamp = 0; // in milliseconds std::shared_ptr m_SendTagset, m_NSRSendTagset; std::unique_ptr m_Destination;// TODO: might not need it From 2bc0850b0fe363015401ecdadd422101ab7fab92 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 13 Jan 2021 21:06:12 +0300 Subject: [PATCH 0638/2950] [android] add refresh on swipe in webconsole Signed-off-by: R4SAS --- android/AndroidManifest.xml | 4 +++ android/build.gradle | 1 + android/res/layout/activity_web_console.xml | 16 +++++++--- .../purplei2p/i2pd/WebConsoleActivity.java | 32 +++++++++++++++++-- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 8b011b8e..d0e8ecb6 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -18,6 +18,10 @@ android:requestLegacyExternalStorage="true" android:theme="@android:style/Theme.Holo.Light.DarkActionBar" android:usesCleartextTraffic="true"> + + diff --git a/android/build.gradle b/android/build.gradle index dbe75759..0c208c91 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,6 +21,7 @@ repositories { dependencies { implementation 'androidx.core:core:1.0.2' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' } android { diff --git a/android/res/layout/activity_web_console.xml b/android/res/layout/activity_web_console.xml index 5724b387..60d22a0b 100644 --- a/android/res/layout/activity_web_console.xml +++ b/android/res/layout/activity_web_console.xml @@ -1,14 +1,22 @@ - - + android:layout_height="fill_parent" + android:id="@+id/swipe"> + + + + + diff --git a/android/src/org/purplei2p/i2pd/WebConsoleActivity.java b/android/src/org/purplei2p/i2pd/WebConsoleActivity.java index 0fcf37fe..5e20e8fa 100644 --- a/android/src/org/purplei2p/i2pd/WebConsoleActivity.java +++ b/android/src/org/purplei2p/i2pd/WebConsoleActivity.java @@ -2,14 +2,18 @@ package org.purplei2p.i2pd; import android.app.Activity; import android.os.Bundle; +import android.os.Handler; import android.view.MenuItem; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import java.util.Objects; public class WebConsoleActivity extends Activity { + private WebView webView; + private SwipeRefreshLayout swipeRefreshLayout; @Override protected void onCreate(Bundle savedInstanceState) { @@ -18,19 +22,43 @@ public class WebConsoleActivity extends Activity { Objects.requireNonNull(getActionBar()).setDisplayHomeAsUpEnabled(true); - final WebView webView = findViewById(R.id.webview1); + webView = (WebView) findViewById(R.id.webview1); webView.setWebViewClient(new WebViewClient()); final WebSettings webSettings = webView.getSettings(); webSettings.setBuiltInZoomControls(true); webSettings.setJavaScriptEnabled(false); webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort + + swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + swipeRefreshLayout.setRefreshing(true); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + swipeRefreshLayout.setRefreshing(false); + webView.reload(); + } + }, 1000); + } + }); + } + + @Override + public void onBackPressed() { + if (webView.canGoBack()) { + webView.goBack(); + } else { + super.onBackPressed(); + } } public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); - if (id==android.R.id.home) { + if (id == android.R.id.home) { finish(); return true; } From 8f25b66760ed2863c2468f464ab6e959ba3a816b Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 14 Jan 2021 11:24:03 -0500 Subject: [PATCH 0639/2950] limit tunnel length to 8 hops --- libi2pd/Tunnel.cpp | 4 ++-- libi2pd/Tunnel.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 42eeeb5d..5355a7b6 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -42,8 +42,8 @@ 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 : numHops; - auto msg = NewI2NPShortMessage (); + 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; // shuffle records diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 37c5cddb..7e8edca7 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -37,7 +37,8 @@ namespace tunnel const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes const int TUNNEL_CREATION_TIMEOUT = 30; // 30 seconds const int STANDARD_NUM_RECORDS = 4; // in VariableTunnelBuild message - + const int MAX_NUM_RECORDS = 8; + enum TunnelState { eTunnelStatePending, From 1235d18d67baec57a2f4a54b8ef7b5b16582af26 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Jan 2021 17:15:41 -0500 Subject: [PATCH 0640/2950] pass address to NTCP2 session --- libi2pd/NTCP2.cpp | 8 +++++--- libi2pd/NTCP2.h | 3 ++- libi2pd/Transports.cpp | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 1706399d..eb03dc62 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -317,7 +317,8 @@ namespace transport return true; } - NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter): + NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter, + std::shared_ptr addr): TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT), m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), @@ -332,7 +333,8 @@ namespace transport if (in_RemoteRouter) // Alice { m_Establisher->m_RemoteIdentHash = GetRemoteIdentity ()->GetIdentHash (); - auto addr = in_RemoteRouter->GetNTCP2Address (true); // we need a published address + if (!addr) + addr = in_RemoteRouter->GetNTCP2Address (true); // we need a published address if (addr) { memcpy (m_Establisher->m_RemoteStaticKey, addr->ntcp2->staticKey, 32); @@ -653,7 +655,7 @@ namespace transport SendTerminationAndTerminate (eNTCP2Message3Error); return; } - auto addr = ri.GetNTCP2Address (false); // any NTCP2 address + auto addr = ri.GetNTCP2Address (false, false); // any NTCP2 address including v6 if (!addr) { LogPrint (eLogError, "NTCP2: No NTCP2 address found in SessionConfirmed"); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 5c9ecac9..f80ba75a 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -123,7 +123,8 @@ namespace transport { public: - NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter = nullptr); + NTCP2Session (NTCP2Server& server, std::shared_ptr in_RemoteRouter = nullptr, + std::shared_ptr addr = nullptr); ~NTCP2Session (); void Terminate (); void TerminateByTimeout (); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 5c2fcb6d..574810b8 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -398,7 +398,7 @@ namespace transport auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only if (address && !peer.router->IsUnreachable () && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { - auto s = std::make_shared (*m_NTCP2Server, peer.router); + auto s = std::make_shared (*m_NTCP2Server, peer.router, address); if(m_NTCP2Server->UsingProxy()) { From 1a9e11d86daf5ccf5c11161fd9db9c1622f82819 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Jan 2021 12:58:27 -0500 Subject: [PATCH 0641/2950] don't send updated LeaseSet through a terminated session --- libi2pd/Streaming.cpp | 4 +++- libi2pd/Streaming.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index a873a660..0d482303 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -817,7 +817,7 @@ namespace stream void Stream::SendUpdatedLeaseSet () { - if (m_RoutingSession) + if (m_RoutingSession && !m_RoutingSession->IsTerminated ()) { if (m_RoutingSession->IsLeaseSetNonConfirmed ()) { @@ -838,6 +838,8 @@ namespace stream SendQuickAck (); } } + else + SendQuickAck (); } void Stream::ScheduleResend () diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index ab3c4439..fe035136 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -61,7 +61,7 @@ namespace stream const int SYN_TIMEOUT = 200; // how long we wait for SYN after follow-on, in milliseconds const size_t MAX_PENDING_INCOMING_BACKLOG = 128; const int PENDING_INCOMING_TIMEOUT = 10; // in seconds - const int MAX_RECEIVE_TIMEOUT = 30; // in seconds + const int MAX_RECEIVE_TIMEOUT = 20; // in seconds struct Packet { From e0cec79ad67d5df227eaa682c5b4dc837865ab3e Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Jan 2021 18:58:16 -0500 Subject: [PATCH 0642/2950] try both ipv4 and ipv6 NTCP2 addresses if presented --- libi2pd/RouterInfo.cpp | 18 ++++++++++++++++++ libi2pd/RouterInfo.h | 2 ++ libi2pd/Transports.cpp | 22 +++++++++++++++++----- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 13776b81..afbaadbf 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -935,6 +935,24 @@ namespace data }); } + std::shared_ptr RouterInfo::GetPublishedNTCP2V4Address () const + { + return GetAddress ( + [](std::shared_ptr address)->bool + { + return address->IsPublishedNTCP2 () && address->host.is_v4 (); + }); + } + + std::shared_ptr RouterInfo::GetPublishedNTCP2V6Address () const + { + return GetAddress ( + [](std::shared_ptr address)->bool + { + return address->IsPublishedNTCP2 () && address->host.is_v6 (); + }); + } + std::shared_ptr RouterInfo::GetProfile () const { if (!m_Profile) diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 733ea44a..ff767a8b 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -154,6 +154,8 @@ namespace data int GetVersion () const { return m_Version; }; Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr std::shared_ptr GetNTCP2Address (bool publishedOnly, bool v4only = true) const; + std::shared_ptr GetPublishedNTCP2V4Address () const; + std::shared_ptr GetPublishedNTCP2V6Address () const; std::shared_ptr GetSSUAddress (bool v4only = true) const; std::shared_ptr GetSSUV6Address () const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 574810b8..c559c65c 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -389,13 +389,23 @@ namespace transport peer.router = netdb.FindRouter (ident); // try to get new one from netdb if (peer.router) // we have RI already { - if (!peer.numAttempts) // NTCP2 + if (peer.numAttempts < 2) // NTCP2, 0 - ipv6, 1- ipv4 { - peer.numAttempts++; if (m_NTCP2Server) // we support NTCP2 { - // NTCP2 have priority over NTCP - auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only + std::shared_ptr address; + if (!peer.numAttempts) // NTCP2 ipv6 + { + if (context.SupportsV6 ()) + address = peer.router->GetPublishedNTCP2V6Address (); + peer.numAttempts++; + } + if (!address && peer.numAttempts == 1) // NTCP2 ipv4 + { + if (context.SupportsV4 ()) + address = peer.router->GetPublishedNTCP2V4Address (); + peer.numAttempts++; + } if (address && !peer.router->IsUnreachable () && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { auto s = std::make_shared (*m_NTCP2Server, peer.router, address); @@ -415,8 +425,10 @@ namespace transport return true; } } + else + peer.numAttempts = 2; // switch to SSU } - if (peer.numAttempts == 1)// SSU + if (peer.numAttempts == 2)// SSU { peer.numAttempts++; if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) From 6fc5f88a3bb6feeb700b44b92da2355fae2d00b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Jan 2021 19:19:34 -0500 Subject: [PATCH 0643/2950] dump addressbook in hosts.txt format --- libi2pd/Config.cpp | 3 +- libi2pd_client/AddressBook.cpp | 83 ++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index d16d82d3..b17b2609 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -212,7 +212,8 @@ namespace config { ("addressbook.defaulturl", value()->default_value( "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt" ), "AddressBook subscription URL for initial setup") - ("addressbook.subscriptions", value()->default_value(""), "AddressBook subscriptions URLs, separated by comma"); + ("addressbook.subscriptions", value()->default_value(""), "AddressBook subscriptions URLs, separated by comma") + ("addressbook.hostsfile", value()->default_value(""), "File to dump addresses in hosts.txt format"); options_description trust("Trust options"); trust.add_options() diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index a69bd660..ba2d8276 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -34,14 +34,13 @@ namespace client // TODO: this is actually proxy class class AddressBookFilesystemStorage: public AddressBookStorage { - private: - i2p::fs::HashedStorage storage; - std::string etagsPath, indexPath, localPath; - public: + AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") { i2p::config::GetOption("persist.addressbook", m_IsPersist); + if (m_IsPersist) + i2p::config::GetOption("addressbook.hostsfile", m_HostsFile); } std::shared_ptr GetAddress (const i2p::data::IdentHash& ident) const; void AddAddress (std::shared_ptr address); @@ -62,7 +61,10 @@ namespace client private: + i2p::fs::HashedStorage storage; + std::string etagsPath, indexPath, localPath; bool m_IsPersist; + std::string m_HostsFile; // file to dump hosts.txt, empty if not used }; bool AddressBookFilesystemStorage::Init() @@ -183,35 +185,59 @@ namespace client int AddressBookFilesystemStorage::Save (const std::map >& addresses) { - if (addresses.empty()) { + if (addresses.empty()) + { LogPrint(eLogWarning, "Addressbook: not saving empty addressbook"); return 0; } int num = 0; - std::ofstream f (indexPath, std::ofstream::out); // in text mode - - if (!f.is_open ()) { - LogPrint (eLogWarning, "Addressbook: Can't open ", indexPath); - return 0; - } - - for (const auto& it: addresses) { - if (it.second->IsValid ()) - { - f << it.first << ","; - if (it.second->IsIdentHash ()) - f << it.second->identHash.ToBase32 (); - else - f << it.second->blindedPublicKey->ToB33 (); - f << std::endl; - num++; + // save index file + std::ofstream f (indexPath, std::ofstream::out); // in text mode + if (f.is_open ()) + { + for (const auto& it: addresses) + { + if (it.second->IsValid ()) + { + f << it.first << ","; + if (it.second->IsIdentHash ()) + f << it.second->identHash.ToBase32 (); + else + f << it.second->blindedPublicKey->ToB33 (); + f << std::endl; + num++; + } + else + LogPrint (eLogWarning, "Addressbook: invalid address ", it.first); + } + LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); } else - LogPrint (eLogWarning, "Addressbook: invalid address ", it.first); - } - LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved"); + LogPrint (eLogWarning, "Addressbook: Can't open ", indexPath); + } + if (!m_HostsFile.empty ()) + { + // dump full hosts.txt + std::ofstream f (m_HostsFile, std::ofstream::out); // in text mode + if (f.is_open ()) + { + for (const auto& it: addresses) + { + std::shared_ptr addr; + if (it.second->IsIdentHash ()) + { + addr = GetAddress (it.second->identHash); + if (addr) + f << it.first << "=" << addr->ToBase64 () << std::endl; + } + } + } + else + LogPrint (eLogWarning, "Addressbook: Can't open ", m_HostsFile); + } + return num; } @@ -494,7 +520,7 @@ namespace client while (!f.eof ()) { getline(f, s); - if (!s.length()) continue; // skip empty line + if (s.empty () || s[0] == '#') continue; // skip empty line or comment m_Subscriptions.push_back (std::make_shared (*this, s)); } LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); @@ -507,9 +533,10 @@ namespace client std::vector subsList; boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on); - for (size_t i = 0; i < subsList.size (); i++) + for (const auto& s: subsList) { - m_Subscriptions.push_back (std::make_shared (*this, subsList[i])); + if (s.empty () || s[0] == '#') continue; // skip empty line or comment + m_Subscriptions.push_back (std::make_shared (*this, s)); } LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); } From 67dab9b6d26bca67a963b455a58fd808eea093aa Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Thu, 21 Jan 2021 11:07:01 +0200 Subject: [PATCH 0644/2950] Fix clang warning --- libi2pd/NTCP2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index eb03dc62..d72aa014 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1519,7 +1519,7 @@ namespace transport boost::asio::streambuf * readbuff = new boost::asio::streambuf; boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n", - [this, readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) + [readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred) { if(ec) { From 9d5bb1b2b696f1f11d5c136e046872390037ff73 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 Jan 2021 21:25:52 -0500 Subject: [PATCH 0645/2950] drop routing path for LeaseSet resend --- libi2pd/ECIESX25519AEADRatchetSession.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libi2pd/ECIESX25519AEADRatchetSession.cpp b/libi2pd/ECIESX25519AEADRatchetSession.cpp index bfba7852..81b83477 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.cpp +++ b/libi2pd/ECIESX25519AEADRatchetSession.cpp @@ -914,10 +914,13 @@ namespace garlic payloadLen += msg->GetPayloadLength () + 13; if (m_Destination) payloadLen += 32; } - auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated || - (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && - ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ? - GetOwner ()->GetLeaseSet () : nullptr; + if (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT) + { + // resubmit non-confirmed LeaseSet + SetLeaseSetUpdateStatus (eLeaseSetUpdated); + SetSharedRoutingPath (nullptr); // invalidate path since leaseset was not confirmed + } + auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated) ? GetOwner ()->GetLeaseSet () : nullptr; if (leaseSet) { payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13; From 2e0019c8c8c7f524710c9abf581e8794eaac267a Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Jan 2021 11:34:11 -0500 Subject: [PATCH 0646/2950] check if NTCP2 address is valid before connection attempt --- libi2pd/Transports.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index c559c65c..b76df540 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -397,16 +397,24 @@ namespace transport if (!peer.numAttempts) // NTCP2 ipv6 { if (context.SupportsV6 ()) + { address = peer.router->GetPublishedNTCP2V6Address (); + if (address && m_CheckReserved && !i2p::util::net::IsInReservedRange(address->host)) + address = nullptr; + } peer.numAttempts++; } if (!address && peer.numAttempts == 1) // NTCP2 ipv4 { - if (context.SupportsV4 ()) + if (context.SupportsV4 () && !peer.router->IsUnreachable ()) + { address = peer.router->GetPublishedNTCP2V4Address (); + if (address && m_CheckReserved && !i2p::util::net::IsInReservedRange(address->host)) + address = nullptr; + } peer.numAttempts++; } - if (address && !peer.router->IsUnreachable () && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) + if (address) { auto s = std::make_shared (*m_NTCP2Server, peer.router, address); From 2d998aba435443a190a82e34b31e858ae436e76d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Jan 2021 15:44:54 -0500 Subject: [PATCH 0647/2950] fixed typo --- libi2pd/Transports.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b76df540..18459264 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -399,7 +399,7 @@ namespace transport if (context.SupportsV6 ()) { address = peer.router->GetPublishedNTCP2V6Address (); - if (address && m_CheckReserved && !i2p::util::net::IsInReservedRange(address->host)) + if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) address = nullptr; } peer.numAttempts++; @@ -409,7 +409,7 @@ namespace transport if (context.SupportsV4 () && !peer.router->IsUnreachable ()) { address = peer.router->GetPublishedNTCP2V4Address (); - if (address && m_CheckReserved && !i2p::util::net::IsInReservedRange(address->host)) + if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) address = nullptr; } peer.numAttempts++; From 07282ec39f5457b4fc8eb338f1c8bcec5692a627 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Jan 2021 19:42:44 -0500 Subject: [PATCH 0648/2950] get local yggdrasil ipv6 address --- libi2pd/util.cpp | 30 ++++++++++++++++++++++++++++++ libi2pd/util.h | 1 + 2 files changed, 31 insertions(+) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 794a3f14..bb3f60d1 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -416,6 +416,36 @@ namespace net #endif } + boost::asio::ip::address_v6 GetYggdrasilAddress () + { +#ifdef _WIN32 + // TODO: implement + return boost::asio::ip::address_v6 (); +#else + ifaddrs * addrs = nullptr; + auto err = getifaddrs(&addrs); + if (!err) + { + ifaddrs * cur = addrs; + while(cur) + { + if (cur->ifa_addr && cur->ifa_addr->sa_family == AF_INET6) + { + sockaddr_in6* sa = (sockaddr_in6*)cur->ifa_addr; + if (sa->sin6_addr.s6_addr[0] == 0x02 || sa->sin6_addr.s6_addr[0] == 0x03) + { + boost::asio::ip::address_v6::bytes_type bytes; + memcpy (bytes.data (), &sa->sin6_addr, 16); + return boost::asio::ip::address_v6 (bytes); + } + } + cur = cur->ifa_next; + } + } + return boost::asio::ip::address_v6 (); +#endif + } + bool IsInReservedRange (const boost::asio::ip::address& host) { // https://en.wikipedia.org/wiki/Reserved_IP_addresses if(host.is_v4()) diff --git a/libi2pd/util.h b/libi2pd/util.h index e6de09ed..7a45dc9b 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -188,6 +188,7 @@ namespace util { int GetMTU (const boost::asio::ip::address& localAddress); const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); + boost::asio::ip::address_v6 GetYggdrasilAddress (); bool IsInReservedRange (const boost::asio::ip::address& host); } } From ed4c00e4f4e662d9b3faa40de9a2fa99c265dc3f Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Jan 2021 21:21:35 -0500 Subject: [PATCH 0649/2950] check yggdrasil ipv6 range --- libi2pd/util.cpp | 5 ++++- libi2pd/util.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index bb3f60d1..123d233c 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -446,7 +446,8 @@ namespace net #endif } - bool IsInReservedRange (const boost::asio::ip::address& host) { + bool IsInReservedRange (const boost::asio::ip::address& host, bool checkYggdrasil) + { // https://en.wikipedia.org/wiki/Reserved_IP_addresses if(host.is_v4()) { @@ -486,6 +487,8 @@ namespace net if (ipv6_address >= it.first && ipv6_address <= it.second) return true; } + if (checkYggdrasil && (ipv6_address[0] == 0x02 || ipv6_address[0] == 0x03)) // yggdrasil? + return true; } return false; } diff --git a/libi2pd/util.h b/libi2pd/util.h index 7a45dc9b..fedab8e1 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -189,7 +189,7 @@ namespace util int GetMTU (const boost::asio::ip::address& localAddress); const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); boost::asio::ip::address_v6 GetYggdrasilAddress (); - bool IsInReservedRange (const boost::asio::ip::address& host); + bool IsInReservedRange (const boost::asio::ip::address& host, bool checkYggdrasil = true); } } } From d13fbe5549ae328911ce8e98ff97ace4c4d0ef41 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Jan 2021 19:48:33 -0500 Subject: [PATCH 0650/2950] support reseed throught the Yggdrasil --- libi2pd/Config.cpp | 3 ++ libi2pd/HTTP.cpp | 9 +++- libi2pd/Reseed.cpp | 129 ++++++++++++++++++++++++++++++--------------- libi2pd/Reseed.h | 7 ++- 4 files changed, 103 insertions(+), 45 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index b17b2609..bceca198 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -205,6 +205,9 @@ namespace config { "https://reseed.i2pgit.org/," "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") + ("reseed.yggurls", value()->default_value( + "http://[324:9de3:fea4:f6ac::ace]:7070/" + ), "Reseed URLs through the Yggdrasil, separated by comma") ; options_description addressbook("AddressBook options"); diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index 484f4c0c..d4ca3b8b 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -111,7 +111,14 @@ namespace http { pos_p = pos_c + 1; } /* hostname[:port][/path] */ - pos_c = url.find_first_of(":/", pos_p); + if (url[pos_p] == '[') // ipv6 + { + auto pos_b = url.find(']', pos_p); + if (pos_b == std::string::npos) return false; + pos_c = url.find_first_of(":/", pos_b); + } + else + pos_c = url.find_first_of(":/", pos_p); if (pos_c == std::string::npos) { /* only hostname, without post and path */ host = url.substr(pos_p, std::string::npos); diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 2812f413..80b834e6 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -86,7 +86,15 @@ namespace data std::vector httpsReseedHostList; boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); - if (reseedURLs.length () == 0) + std::vector yggReseedHostList; + if (!i2p::util::net::GetYggdrasilAddress ().is_unspecified ()) + { + LogPrint (eLogInfo, "Reseed: yggdrasil is supported"); + std::string yggReseedURLs; i2p::config::GetOption("reseed.yggurls", yggReseedURLs); + boost::split(yggReseedHostList, yggReseedURLs, boost::is_any_of(","), boost::token_compress_on); + } + + if (httpsReseedHostList.empty () && yggReseedHostList.empty()) { LogPrint (eLogWarning, "Reseed: No reseed servers specified"); return 0; @@ -95,9 +103,12 @@ namespace data int reseedRetries = 0; while (reseedRetries < 10) { - auto ind = rand () % httpsReseedHostList.size (); - std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3"; - auto num = ReseedFromSU3Url (reseedUrl); + auto ind = rand () % (httpsReseedHostList.size () + yggReseedHostList.size ()); + bool isHttps = ind < httpsReseedHostList.size (); + std::string reseedUrl = isHttps ? httpsReseedHostList[ind] : + yggReseedHostList[ind - httpsReseedHostList.size ()]; + reseedUrl += "i2pseeds.su3"; + auto num = ReseedFromSU3Url (reseedUrl, isHttps); if (num > 0) return num; // success reseedRetries++; } @@ -110,10 +121,10 @@ namespace data * @param url * @return number of entries added to netDb */ - int Reseeder::ReseedFromSU3Url (const std::string& url) + int Reseeder::ReseedFromSU3Url (const std::string& url, bool isHttps) { LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url); - std::string su3 = HttpsRequest (url); + std::string su3 = isHttps ? HttpsRequest (url) : YggdrasilRequest (url); if (su3.length () > 0) { std::stringstream s(su3); @@ -667,42 +678,7 @@ namespace data if (!ecode) { LogPrint (eLogDebug, "Reseed: Connected to ", url.host, ":", url.port); - i2p::http::HTTPReq req; - req.uri = url.to_string(); - req.AddHeader("User-Agent", "Wget/1.11.4"); - req.AddHeader("Connection", "close"); - s.write_some (boost::asio::buffer (req.to_string())); - // read response - std::stringstream rs; - char recv_buf[1024]; size_t l = 0; - do { - l = s.read_some (boost::asio::buffer (recv_buf, sizeof(recv_buf)), ecode); - if (l) rs.write (recv_buf, l); - } while (!ecode && l); - // process response - std::string data = rs.str(); - i2p::http::HTTPRes res; - int len = res.parse(data); - if (len <= 0) { - LogPrint(eLogWarning, "Reseed: incomplete/broken response from ", url.host); - return ""; - } - if (res.code != 200) { - LogPrint(eLogError, "Reseed: failed to reseed from ", url.host, ", http code ", res.code); - return ""; - } - data.erase(0, len); /* drop http headers from response */ - LogPrint(eLogDebug, "Reseed: got ", data.length(), " bytes of data from ", url.host); - if (res.is_chunked()) { - std::stringstream in(data), out; - if (!i2p::http::MergeChunkedResponse(in, out)) { - LogPrint(eLogWarning, "Reseed: failed to merge chunked response from ", url.host); - return ""; - } - LogPrint(eLogDebug, "Reseed: got ", data.length(), "(", out.tellg(), ") bytes of data from ", url.host); - data = out.str(); - } - return data; + return ReseedRequest (s, url.to_string()); } else LogPrint (eLogError, "Reseed: SSL handshake failed: ", ecode.message ()); @@ -711,5 +687,74 @@ namespace data LogPrint (eLogError, "Reseed: Couldn't connect to ", url.host, ": ", ecode.message ()); return ""; } + + template + std::string Reseeder::ReseedRequest (Stream& s, const std::string& uri) + { + boost::system::error_code ecode; + i2p::http::HTTPReq req; + req.uri = uri; + req.AddHeader("User-Agent", "Wget/1.11.4"); + req.AddHeader("Connection", "close"); + s.write_some (boost::asio::buffer (req.to_string())); + // read response + std::stringstream rs; + char recv_buf[1024]; size_t l = 0; + do { + l = s.read_some (boost::asio::buffer (recv_buf, sizeof(recv_buf)), ecode); + if (l) rs.write (recv_buf, l); + } while (!ecode && l); + // process response + std::string data = rs.str(); + i2p::http::HTTPRes res; + int len = res.parse(data); + if (len <= 0) { + LogPrint(eLogWarning, "Reseed: incomplete/broken response from ", uri); + return ""; + } + if (res.code != 200) { + LogPrint(eLogError, "Reseed: failed to reseed from ", uri, ", http code ", res.code); + return ""; + } + data.erase(0, len); /* drop http headers from response */ + LogPrint(eLogDebug, "Reseed: got ", data.length(), " bytes of data from ", uri); + if (res.is_chunked()) { + std::stringstream in(data), out; + if (!i2p::http::MergeChunkedResponse(in, out)) { + LogPrint(eLogWarning, "Reseed: failed to merge chunked response from ", uri); + return ""; + } + LogPrint(eLogDebug, "Reseed: got ", data.length(), "(", out.tellg(), ") bytes of data from ", uri); + data = out.str(); + } + return data; + } + + std::string Reseeder::YggdrasilRequest (const std::string& address) + { + i2p::http::URL url; + if (!url.parse(address)) + { + LogPrint(eLogError, "Reseed: failed to parse url: ", address); + return ""; + } + url.schema = "http"; + if (!url.port) url.port = 80; + + boost::system::error_code ecode; + boost::asio::io_service service; + boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6()); + + s.connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::from_string (url.host), url.port), ecode); + if (!ecode) + { + LogPrint (eLogDebug, "Reseed: Connected to yggdrasil ", url.host, ":", url.port); + return ReseedRequest (s, url.to_string()); + } + else + LogPrint (eLogError, "Reseed: Couldn't connect to yggdrasil ", url.host, ": ", ecode.message ()); + + return ""; + } } } diff --git a/libi2pd/Reseed.h b/libi2pd/Reseed.h index 345b45bf..8039c07e 100644 --- a/libi2pd/Reseed.h +++ b/libi2pd/Reseed.h @@ -31,7 +31,6 @@ namespace data ~Reseeder(); void Bootstrap (); int ReseedFromServers (); - int ReseedFromSU3Url (const std::string& url); int ProcessSU3File (const char * filename); int ProcessZIPFile (const char * filename); @@ -39,6 +38,7 @@ namespace data private: + int ReseedFromSU3Url (const std::string& url, bool isHttps = true); void LoadCertificate (const std::string& filename); int ProcessSU3Stream (std::istream& s); @@ -47,7 +47,10 @@ namespace data bool FindZipDataDescriptor (std::istream& s); std::string HttpsRequest (const std::string& address); - + std::string YggdrasilRequest (const std::string& address); + template + std::string ReseedRequest (Stream& s, const std::string& uri); + private: std::map m_SigningKeys; From fd73aab7d034267db29720896f4f2db51cca0445 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Jan 2021 19:53:00 -0500 Subject: [PATCH 0651/2950] acetone's certificate --- .../reseed/acetone_at_mail.i2p.crt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 contrib/certificates/reseed/acetone_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/acetone_at_mail.i2p.crt b/contrib/certificates/reseed/acetone_at_mail.i2p.crt new file mode 100644 index 00000000..13f9f17d --- /dev/null +++ b/contrib/certificates/reseed/acetone_at_mail.i2p.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIEctG1gDANBgkqhkiG9w0BAQ0FADBwMQswCQYDVQQGEwJY +WDELMAkGA1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnlt +b3VzIE5ldHdvcmsxDDAKBgNVBAsMA0kyUDEZMBcGA1UEAwwQYWNldG9uZUBtYWls +LmkycDAeFw0yMTAxMjUxMDMyMjBaFw0zMTAxMjMxMDMyMjBaMHAxCzAJBgNVBAYT +AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNVBAoMFUkyUCBBbm9u +eW1vdXMgTmV0d29yazEMMAoGA1UECwwDSTJQMRkwFwYDVQQDDBBhY2V0b25lQG1h +aWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwqF/BRRmvZ54 +5XArgxbytDi7m7MDjFE/whUADruHj/9jXGCxE8DDiiKTt3yhfakV0SNo5xk7AMD+ +wqiSNC5JCHTm18gd2M4cQLIaOVRqucLLge4XVgk2WPX6OT98wfxh7mqA3wlSdEpj +dY3Txtkf7VfZLicG76/RBtLFW3aBdsn63hZaQqZE4x/5MJyPVZx59+lys5RmMi0o +LpXJy4HOu1/Gl1iKDJoI/ARFG3y7uP/B+ZtZBitJetTs0HcqycnNJq0tVZf2HiGF +JNy67AL4foxNYPXP6QsvXvp6LRpGANaBCkFCBlriSF+x1zO2H3uAkRnuLYXuKIfB +HudejTp4R57VgZGiHYoawHaF17FVAApue9G8O82XYECjhET35B9yFoOBHTvaMxLU +CKrmayH8KMQon95mfe1qpoO3/YDa8DCxkjAfjdtytat7nt2pGZMH6/cLJxcFiofh +RtRVvb+omv/X12j/6iCFrwP4NvBnAZsa736igbjpyee5n+CSyYxd9cJkRX1vQVk7 +WFSqL58Pz+g6CKJmdMPvqNOfUQ6mieBeejmx35B4pLzLcoNxw8R3O1+I2l4dg042 +dEydKRQNwdzOec4jYwnKR40iwIyZxpchXWGRbBdyF5RQCbIIo60QBJlfXMJ2svan +q5lYIeWeY3mlODXu4KH4K09y10KT8FsCAwEAAaMhMB8wHQYDVR0OBBYEFMh+DoIL +APNiu2o+6I9A49joNYQuMA0GCSqGSIb3DQEBDQUAA4ICAQBFeOJi0rmkqN5/E3IB +nE2x4mUeLI82tUcN2D3Yu8J81vy4DnH+oMRQFDtYEHW5pfirRmgSZ7MQwYQnqWLp +iTE7SyCxlqGrmVsYp7PzfS1pUT2QeWPtsNYUDdraG0Zr9BkIGB60VMhjMSa9WUrj +lbchzr6E/j/EsEOE7IK08JxIDKCDZM2LLwis4tAM6tmiylkMf2RlUBIRBs1TCO+q +x3yByttNE2P4nQyQVQpjc1qsaOMvJvbxun37dwo+oTQy+hwkA86BWTDRYdN3xwOk +OfAOtlX6zM/wCKMN0ZRnjZoh59ZCn4JXokt3IjZ4n8qJOuJFRKeKGmGeKA8uaGW8 +ih5tdB99Gu5Z8LOT1FxAJKwQBn5My0JijPoMit4B0WKNC8hy2zc2YvNfflu1ZRj5 +wF4E5ktbtT/LWFSoRPas/GFS8wSXk/kbSB0ArDcRRszb3JHqbALmSQxngz3rfwb3 +SHwQIIg956gjMDueEX5CrGrMqigiK53b9fqtpghUrHDsqtEXqeImpAY65PX1asqo +metDNuETHF7XrAjP7TGJfnrYQyeK90iS7j1G68ScBGkKY2nsTnFoXkSk5s5D338E +SUzPaOlh91spmkVY6gQTVQ7BakADBHw+zBgDA1gBN/4JPvgN36hquj63+aG1cKy3 +3ZUnv2ipo2fpr69NtuBnutK6gw== +-----END CERTIFICATE----- From 5931cb59abe19c0722d3bc51dc99145c067e01f5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 26 Jan 2021 18:53:56 +0300 Subject: [PATCH 0652/2950] fix thread setname on NetBSD Signed-off-by: R4SAS --- libi2pd/util.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 123d233c..ff27718a 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -119,10 +119,12 @@ namespace util } void SetThreadName (const char *name) { -#if defined (__APPLE__) +#if defined(__APPLE__) pthread_setname_np(name); #elif defined(__FreeBSD__) || defined(__OpenBSD__) pthread_set_name_np(pthread_self(), name); +#elif defined(__NetBSD__) + pthread_setname_np(pthread_self(), "%s", (void *)name); #else pthread_setname_np(pthread_self(), name); #endif @@ -437,15 +439,15 @@ namespace net boost::asio::ip::address_v6::bytes_type bytes; memcpy (bytes.data (), &sa->sin6_addr, 16); return boost::asio::ip::address_v6 (bytes); - } - } + } + } cur = cur->ifa_next; - } + } } return boost::asio::ip::address_v6 (); -#endif - } - +#endif + } + bool IsInReservedRange (const boost::asio::ip::address& host, bool checkYggdrasil) { // https://en.wikipedia.org/wiki/Reserved_IP_addresses From 85902b358ac52332dde696c41f46aded8e617ef7 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 26 Jan 2021 13:43:20 -0500 Subject: [PATCH 0653/2950] remove [] from yggdrasil reseed address --- libi2pd/Reseed.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 80b834e6..33471b10 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -91,7 +91,8 @@ namespace data { LogPrint (eLogInfo, "Reseed: yggdrasil is supported"); std::string yggReseedURLs; i2p::config::GetOption("reseed.yggurls", yggReseedURLs); - boost::split(yggReseedHostList, yggReseedURLs, boost::is_any_of(","), boost::token_compress_on); + if (!yggReseedURLs.empty ()) + boost::split(yggReseedHostList, yggReseedURLs, boost::is_any_of(","), boost::token_compress_on); } if (httpsReseedHostList.empty () && yggReseedHostList.empty()) @@ -744,8 +745,11 @@ namespace data boost::system::error_code ecode; boost::asio::io_service service; boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6()); - - s.connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::from_string (url.host), url.port), ecode); + + if (url.host.length () < 2) return ""; // assume [] + auto host = url.host.substr (1, url.host.length () - 2); + LogPrint (eLogDebug, "Reseed: Connecting to yggdrasil ", url.host, ":", url.port); + s.connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::from_string (host), url.port), ecode); if (!ecode) { LogPrint (eLogDebug, "Reseed: Connected to yggdrasil ", url.host, ":", url.port); From 7c8280934a7a25db6ac802cffdeab4f2f8470b77 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 27 Jan 2021 06:48:35 +0300 Subject: [PATCH 0654/2950] update addressbook subscriptions Signed-off-by: R4SAS --- contrib/i2pd.conf | 2 +- contrib/subscriptions.txt | 3 ++- libi2pd/Config.cpp | 2 +- libi2pd_client/HTTPProxy.cpp | 5 +++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 5ef39bc9..13801076 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -237,4 +237,4 @@ verify = true # avx = true ## Force usage of CPU instructions set, even if they not found ## DO NOT TOUCH that option if you really don't know what are you doing! -# force = false \ No newline at end of file +# force = false diff --git a/contrib/subscriptions.txt b/contrib/subscriptions.txt index 8f4afb03..76d73993 100644 --- a/contrib/subscriptions.txt +++ b/contrib/subscriptions.txt @@ -1,3 +1,4 @@ -http://inr.i2p/export/alive-hosts.txt +http://reg.i2p/hosts.txt +http://identiguy.i2p/hosts.txt http://stats.i2p/cgi-bin/newhosts.txt http://i2p-projekt.i2p/hosts.txt diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index bceca198..5de489d0 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -213,7 +213,7 @@ namespace config { options_description addressbook("AddressBook options"); addressbook.add_options() ("addressbook.defaulturl", value()->default_value( - "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt" + "http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt" ), "AddressBook subscription URL for initial setup") ("addressbook.subscriptions", value()->default_value(""), "AddressBook subscriptions URLs, separated by comma") ("addressbook.hostsfile", value()->default_value(""), "File to dump addresses in hosts.txt format"); diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 64080752..b2b07fba 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -32,8 +32,9 @@ namespace i2p { namespace proxy { std::map jumpservices = { - { "inr.i2p", "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/search/?q=" }, - { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, + { "reg.i2p", "http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/jump/" }, + { "identiguy.i2p", "http://3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva.b32.i2p/cgi-bin/query?hostname=" }, + { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; static const char *pageHead = From 484f69f16b92a26f1847a4ba1f6a24de805b7116 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Jan 2021 13:33:12 -0500 Subject: [PATCH 0655/2950] try to select reachable router of inbound tunnel gateway --- libi2pd/TunnelPool.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libi2pd/TunnelPool.cpp b/libi2pd/TunnelPool.cpp index 94462c93..784dc84e 100644 --- a/libi2pd/TunnelPool.cpp +++ b/libi2pd/TunnelPool.cpp @@ -414,7 +414,8 @@ namespace tunnel else if (i2p::transport::transports.GetNumPeers () > 25) { auto r = i2p::transport::transports.GetRandomPeer (); - if (r && !r->GetProfile ()->IsBad ()) + if (r && !r->GetProfile ()->IsBad () && + (numHops > 1 || !inbound || r->IsReachable ())) // first must be reachable { prevHop = r; peers.push_back (r->GetRouterIdentity ()); @@ -430,6 +431,12 @@ namespace tunnel LogPrint (eLogError, "Tunnels: Can't select next hop for ", prevHop->GetIdentHashBase64 ()); return false; } + if (inbound && (i == numHops - 1) && !hop->IsReachable ()) + { + // if first is not reachable try again + auto hop1 = nextHop (prevHop); + if (hop1) hop = hop1; + } prevHop = hop; peers.push_back (hop->GetRouterIdentity ()); } From df7fda9e0cd5ef0f3104152d158c7e522c481d94 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Jan 2021 07:46:20 -0500 Subject: [PATCH 0656/2950] support ratchets for shared local destination --- libi2pd_client/ClientContext.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 860e8cfd..cac472f9 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -404,9 +404,10 @@ namespace client { std::map params { - { I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, "2" }, - { I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, "2" }, - { I2CP_PARAM_LEASESET_TYPE, "3" } + { I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, "3" }, + { I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, "3" }, + { I2CP_PARAM_LEASESET_TYPE, "3" }, + { I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, "0,4" } }; m_SharedLocalDestination = CreateNewLocalDestination (false, i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, ¶ms); // non-public, EDDSA From daa3f8699bb4945db37eac20893b35f3a00eea64 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Jan 2021 09:32:33 -0500 Subject: [PATCH 0657/2950] don't detect Yggdrasil for android --- libi2pd/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index ff27718a..a1dbe4a8 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -420,7 +420,7 @@ namespace net boost::asio::ip::address_v6 GetYggdrasilAddress () { -#ifdef _WIN32 +#if (defined(_WIN32) || defined(ANDROID)) // TODO: implement return boost::asio::ip::address_v6 (); #else From 1ba5d258190f3493c6739d820fa23a88c4f845f6 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Jan 2021 12:12:40 -0500 Subject: [PATCH 0658/2950] correct detection of chunked response --- libi2pd/HTTP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index d4ca3b8b..b967cbb5 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -346,7 +346,7 @@ namespace http { auto it = headers.find("Transfer-Encoding"); if (it == headers.end()) return false; - if (it->second.find("chunked") == std::string::npos) + if (it->second.find("chunked") != std::string::npos) return true; return false; } From 82649ab2a7cccb87dd876836a9aa8582b4bb2fce Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Jan 2021 13:27:49 -0500 Subject: [PATCH 0659/2950] IsYggdrasilAddress added --- libi2pd/util.cpp | 16 ++++++++++++++-- libi2pd/util.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index a1dbe4a8..a36ab25f 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -418,6 +418,17 @@ namespace net #endif } + static bool IsYggdrasilAddress (const uint8_t addr[16]) + { + return addr[0] == 0x02 || addr[0] == 0x03; + } + + bool IsYggdrasilAddress (const boost::asio::ip::address& addr) + { + if (!addr.is_v6 ()) return false; + return IsYggdrasilAddress (addr.to_v6 ().to_bytes ().data ()); + } + boost::asio::ip::address_v6 GetYggdrasilAddress () { #if (defined(_WIN32) || defined(ANDROID)) @@ -434,7 +445,7 @@ namespace net if (cur->ifa_addr && cur->ifa_addr->sa_family == AF_INET6) { sockaddr_in6* sa = (sockaddr_in6*)cur->ifa_addr; - if (sa->sin6_addr.s6_addr[0] == 0x02 || sa->sin6_addr.s6_addr[0] == 0x03) + if (IsYggdrasilAddress(sa->sin6_addr.s6_addr)) { boost::asio::ip::address_v6::bytes_type bytes; memcpy (bytes.data (), &sa->sin6_addr, 16); @@ -444,6 +455,7 @@ namespace net cur = cur->ifa_next; } } + if(addrs) freeifaddrs(addrs); return boost::asio::ip::address_v6 (); #endif } @@ -489,7 +501,7 @@ namespace net if (ipv6_address >= it.first && ipv6_address <= it.second) return true; } - if (checkYggdrasil && (ipv6_address[0] == 0x02 || ipv6_address[0] == 0x03)) // yggdrasil? + if (checkYggdrasil && IsYggdrasilAddress (ipv6_address.data ())) // yggdrasil? return true; } return false; diff --git a/libi2pd/util.h b/libi2pd/util.h index fedab8e1..bd02c648 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -190,6 +190,7 @@ namespace util const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); boost::asio::ip::address_v6 GetYggdrasilAddress (); bool IsInReservedRange (const boost::asio::ip::address& host, bool checkYggdrasil = true); + bool IsYggdrasilAddress (const boost::asio::ip::address& addr); } } } From 129b4a213532592330f647dc22de144cfcba127a Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Jan 2021 16:50:53 -0500 Subject: [PATCH 0660/2950] don't support NTCP1 address in RouterInfo --- libi2pd/RouterInfo.cpp | 66 +++++++++++++++++++----------------------- libi2pd/RouterInfo.h | 10 ++----- 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index afbaadbf..a1c8821f 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -198,14 +198,14 @@ namespace data auto address = std::make_shared
(); s.read ((char *)&address->cost, sizeof (address->cost)); s.read ((char *)&address->date, sizeof (address->date)); - bool isNTCP2Only = false; + bool isHost = false, isIntroKey = false, isStaticKey = false; char transportStyle[6]; - auto transportStyleLen = ReadString (transportStyle, 6, s) - 1; + ReadString (transportStyle, 6, s); if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2 - { + { address->transportStyle = eTransportNTCP; - if (transportStyleLen > 4 && transportStyle[4] == '2') isNTCP2Only= true; - } + address->ntcp2.reset (new NTCP2Ext ()); + } else if (!strcmp (transportStyle, "SSU")) { address->transportStyle = eTransportSSU; @@ -230,22 +230,7 @@ namespace data { boost::system::error_code ecode; address->host = boost::asio::ip::address::from_string (value, ecode); - if (!ecode) - { -#if BOOST_VERSION >= 104900 - if (!address->host.is_unspecified ()) // check if address is valid -#else - address->host.to_string (ecode); - if (!ecode) -#endif - { - // add supported protocol - if (address->host.is_v4 ()) - supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV4 : eSSUV4; - else - supportedTransports |= (address->transportStyle == eTransportNTCP) ? eNTCPV6 : eSSUV6; - } - } + if (!ecode && !address->host.is_unspecified ()) isHost = true; } else if (!strcmp (key, "port")) address->port = boost::lexical_cast(value); @@ -259,7 +244,7 @@ namespace data else if (!strcmp (key, "key")) { if (address->ssu) - Base64ToByteStream (value, strlen (value), address->ssu->key, 32); + isIntroKey = (Base64ToByteStream (value, strlen (value), address->ssu->key, 32) == 32); else LogPrint (eLogWarning, "RouterInfo: Unexpected field 'key' for NTCP"); } @@ -267,14 +252,11 @@ namespace data ExtractCaps (value); else if (!strcmp (key, "s")) // ntcp2 static key { - if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); - supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; Base64ToByteStream (value, strlen (value), address->ntcp2->staticKey, 32); + isStaticKey = true; } else if (!strcmp (key, "i")) // ntcp2 iv { - if (!address->ntcp2) address->ntcp2.reset (new NTCP2Ext ()); - supportedTransports |= (address->host.is_v4 ()) ? eNTCP2V4 : eNTCP2V6; Base64ToByteStream (value, strlen (value), address->ntcp2->iv, 16); address->ntcp2->isPublished = true; // presence if "i" means "published" } @@ -314,9 +296,22 @@ namespace data } if (!s) return; } - if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented - if (isNTCP2Only && address->ntcp2) address->ntcp2->isNTCP2Only = true; - if (supportedTransports & ~(eNTCPV4 | eNTCPV6)) // exclude NTCP only + if (address->transportStyle == eTransportNTCP) + { + if (isStaticKey && isHost) + supportedTransports |= address->host.is_v4 () ? eNTCP2V4 : eNTCP2V6; + } + else if (address->transportStyle == eTransportSSU) + { + if (isIntroKey) + { + if (isHost) + supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6; + else + if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented + } + } + if (supportedTransports) { addresses->push_back(address); m_SupportedTransports |= supportedTransports; @@ -741,7 +736,6 @@ namespace data addr->cost = port ? 3 : 14; // override from RouterContext::PublishNTCP2Address addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); - addr->ntcp2->isNTCP2Only = true; // NTCP2 only address if (port) addr->ntcp2->isPublished = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->iv, iv, 16); @@ -834,24 +828,24 @@ namespace data bool RouterInfo::IsV6 () const { - return m_SupportedTransports & (eNTCPV6 | eSSUV6 | eNTCP2V6); + return m_SupportedTransports & (eSSUV6 | eNTCP2V6); } bool RouterInfo::IsV4 () const { - return m_SupportedTransports & (eNTCPV4 | eSSUV4 | eNTCP2V4); + return m_SupportedTransports & (eSSUV4 | eNTCP2V4); } void RouterInfo::EnableV6 () { if (!IsV6 ()) - m_SupportedTransports |= eNTCPV6 | eSSUV6 | eNTCP2V6; + m_SupportedTransports |= eSSUV6 | eNTCP2V6; } void RouterInfo::EnableV4 () { if (!IsV4 ()) - m_SupportedTransports |= eNTCPV4 | eSSUV4 | eNTCP2V4; + m_SupportedTransports |= eSSUV4 | eNTCP2V4; } @@ -859,7 +853,7 @@ namespace data { if (IsV6 ()) { - m_SupportedTransports &= ~(eNTCPV6 | eSSUV6 | eNTCP2V6); + m_SupportedTransports &= ~(eSSUV6 | eNTCP2V6); for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; @@ -875,7 +869,7 @@ namespace data { if (IsV4 ()) { - m_SupportedTransports &= ~(eNTCPV4 | eSSUV4 | eNTCP2V4); + m_SupportedTransports &= ~(eSSUV4 | eNTCP2V4); for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) { auto addr = *it; diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index ff767a8b..a5303e84 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -54,12 +54,10 @@ namespace data enum SupportedTranports { - eNTCPV4 = 0x01, - eNTCPV6 = 0x02, + eNTCP2V4 = 0x01, + eNTCP2V6 = 0x02, eSSUV4 = 0x04, - eSSUV6 = 0x08, - eNTCP2V4 = 0x10, - eNTCP2V6 = 0x20 + eSSUV6 = 0x08 }; enum Caps @@ -104,7 +102,6 @@ namespace data Tag<32> staticKey; Tag<16> iv; bool isPublished = false; - bool isNTCP2Only = false; }; struct Address @@ -136,7 +133,6 @@ namespace data bool IsNTCP2 () const { return (bool)ntcp2; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; }; - bool IsNTCP2Only () const { return ntcp2 && ntcp2->isNTCP2Only; }; }; typedef std::list > Addresses; From 9e5935aea5c979a3a41a1c200811687b48356f68 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 30 Jan 2021 18:32:17 -0500 Subject: [PATCH 0661/2950] NTCP2Mesh added --- libi2pd/NTCP2.cpp | 2 +- libi2pd/RouterInfo.cpp | 23 +++++++++++++++++------ libi2pd/RouterInfo.h | 5 +++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index d72aa014..1c2a71cf 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -655,7 +655,7 @@ namespace transport SendTerminationAndTerminate (eNTCP2Message3Error); return; } - auto addr = ri.GetNTCP2Address (false, false); // any NTCP2 address including v6 + auto addr = ri.GetNTCP2Address (false); // any NTCP2 address if (!addr) { LogPrint (eLogError, "NTCP2: No NTCP2 address found in SessionConfirmed"); diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index a1c8821f..34d377cb 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -16,6 +16,7 @@ #include #endif #include "version.h" +#include "util.h" #include "Crypto.h" #include "Base.h" #include "Timestamp.h" @@ -298,8 +299,18 @@ namespace data } if (address->transportStyle == eTransportNTCP) { - if (isStaticKey && isHost) - supportedTransports |= address->host.is_v4 () ? eNTCP2V4 : eNTCP2V6; + if (isStaticKey) + { + if (isHost) + { + if (address->host.is_v6 ()) + supportedTransports |= i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6; + else + supportedTransports |= eNTCP2V4; + } + else if (!address->ntcp2->isPublished) + supportedTransports |= eNTCP2V4; // most likely, since we don't have host + } } else if (address->transportStyle == eTransportSSU) { @@ -920,12 +931,12 @@ namespace data return nullptr; } - std::shared_ptr RouterInfo::GetNTCP2Address (bool publishedOnly, bool v4only) const + std::shared_ptr RouterInfo::GetNTCP2Address (bool publishedOnly) const { return GetAddress ( - [publishedOnly, v4only](std::shared_ptr address)->bool - { - return address->IsNTCP2 () && (!publishedOnly || address->IsPublishedNTCP2 ()) && (!v4only || address->host.is_v4 ()); + [publishedOnly](std::shared_ptr address)->bool + { + return address->IsNTCP2 () && (!publishedOnly || address->IsPublishedNTCP2 ()); }); } diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index a5303e84..50ed3576 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -57,7 +57,8 @@ namespace data eNTCP2V4 = 0x01, eNTCP2V6 = 0x02, eSSUV4 = 0x04, - eSSUV6 = 0x08 + eSSUV6 = 0x08, + eNTCP2V6Mesh = 0x10 }; enum Caps @@ -149,7 +150,7 @@ namespace data uint64_t GetTimestamp () const { return m_Timestamp; }; int GetVersion () const { return m_Version; }; Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr - std::shared_ptr GetNTCP2Address (bool publishedOnly, bool v4only = true) const; + std::shared_ptr GetNTCP2Address (bool publishedOnly) const; std::shared_ptr GetPublishedNTCP2V4Address () const; std::shared_ptr GetPublishedNTCP2V6Address () const; std::shared_ptr GetSSUAddress (bool v4only = true) const; From aad2d68edbc9df8981b1d94ceb723d4e802a1a8b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Jan 2021 17:25:07 -0500 Subject: [PATCH 0662/2950] NTCP2 transports through the Yggdrasil --- libi2pd/Config.cpp | 6 ++++++ libi2pd/NTCP2.cpp | 2 +- libi2pd/RouterContext.cpp | 9 +++++++++ libi2pd/RouterContext.h | 2 ++ libi2pd/RouterInfo.cpp | 35 +++++++++++++++++++++++++++++++++++ libi2pd/RouterInfo.h | 4 ++++ libi2pd/Transports.cpp | 16 +++++++++++++++- 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 5de489d0..eb7a230e 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -276,6 +276,11 @@ namespace config { ("cpuext.force", bool_switch()->default_value(false), "Force usage of CPU extensions. Useful when cpuinfo is not available on virtual machines") ; + options_description meshnets("Meshnet transports options"); + meshnets.add_options() + ("meshnets.yggdrasil", bool_switch()->default_value(false), "Support transports through the Yggdrasil (deafult: false)") + ; + m_OptionsDesc .add(general) .add(limits) @@ -297,6 +302,7 @@ namespace config { .add(nettime) .add(persist) .add(cpuext) + .add(meshnets) ; } diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 1c2a71cf..130a6a20 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1181,7 +1181,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 ()) + else if (address->host.is_v6() && (context.SupportsV6 () || context.SupportsMesh ())) { m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ())); try diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index ce1eede0..33cfb943 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -521,6 +521,15 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::SetSupportsMesh (bool supportsmesh) + { + if (supportsmesh) + m_RouterInfo.EnableMesh (); + else + m_RouterInfo.DisableMesh (); + UpdateRouterInfo (); + } + void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) { bool updated = false; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 8c13b842..81921d1c 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -107,8 +107,10 @@ namespace i2p void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; bool SupportsV4 () const { return m_RouterInfo.IsV4 (); }; + bool SupportsMesh () const { return m_RouterInfo.IsMesh (); }; void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); + void SetSupportsMesh (bool supportsmesh); bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; }; std::unique_ptr& GetCurrentNoiseState () { return m_CurrentNoiseState; }; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 34d377cb..3f710aec 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -847,6 +847,11 @@ namespace data return m_SupportedTransports & (eSSUV4 | eNTCP2V4); } + bool RouterInfo::IsMesh () const + { + return m_SupportedTransports & eNTCP2V6Mesh; + } + void RouterInfo::EnableV6 () { if (!IsV6 ()) @@ -892,6 +897,27 @@ namespace data } } + void RouterInfo::EnableMesh () + { + if (!IsMesh ()) + m_SupportedTransports |= eNTCP2V6Mesh; + } + + void RouterInfo::DisableMesh () + { + if (IsMesh ()) + { + m_SupportedTransports &= ~eNTCP2V6Mesh; + for (auto it = m_Addresses->begin (); it != m_Addresses->end ();) + { + auto addr = *it; + if (i2p::util::net::IsYggdrasilAddress (addr->host)) + it = m_Addresses->erase (it); + else + ++it; + } + } + } bool RouterInfo::UsesIntroducer () const { @@ -957,6 +983,15 @@ namespace data return address->IsPublishedNTCP2 () && address->host.is_v6 (); }); } + + std::shared_ptr RouterInfo::GetYggdrasilAddress () const + { + return GetAddress ( + [](std::shared_ptr address)->bool + { + return i2p::util::net::IsYggdrasilAddress (address->host); + }); + } std::shared_ptr RouterInfo::GetProfile () const { diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 50ed3576..fc55a9e2 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -155,6 +155,7 @@ namespace data std::shared_ptr GetPublishedNTCP2V6Address () const; std::shared_ptr GetSSUAddress (bool v4only = true) const; std::shared_ptr GetSSUV6Address () const; + 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); @@ -171,10 +172,13 @@ namespace data bool IsNTCP2 (bool v4only = true) const; bool IsV6 () const; bool IsV4 () const; + bool IsMesh () const; void EnableV6 (); void DisableV6 (); void EnableV4 (); void DisableV4 (); + void EnableMesh (); + void DisableMesh (); bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool HasValidAddresses () const { return m_SupportedTransports; }; bool UsesIntroducer () const; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 18459264..5d6fc5f1 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -442,13 +442,27 @@ namespace transport if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) { auto address = peer.router->GetSSUAddress (!context.SupportsV6 ()); - if (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host)) + if (address && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) { m_SSUServer->CreateSession (peer.router, address->host, address->port); return true; } } } + if (peer.numAttempts == 3) // Mesh + { + peer.numAttempts++; + if (context.SupportsMesh () && m_NTCP2Server) + { + auto address = peer.router->GetYggdrasilAddress (); + if (address) + { + auto s = std::make_shared (*m_NTCP2Server, peer.router, address); + m_NTCP2Server->Connect (address->host, address->port, s); + return true; + } + } + } LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available"); i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed peer.Done (); From ba3acdac754bfbfb77fb31e7daf66bbd4a3feea5 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Jan 2021 17:50:10 -0500 Subject: [PATCH 0663/2950] NTCP2 transports through the Yggdrasil --- daemon/Daemon.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 839495a5..ba11e500 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -144,6 +144,18 @@ namespace i2p ipv4 = false; ipv6 = true; #endif + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + boost::asio::ip::address_v6 yggaddr; + if (ygg) + { + yggaddr = i2p::util::net::GetYggdrasilAddress (); + if (yggaddr.is_unspecified ()) + { + LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled"); + ygg = false; + } + } + uint16_t port; i2p::config::GetOption("port", port); if (!i2p::config::IsDefault("port")) { @@ -152,7 +164,8 @@ namespace i2p } i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - + i2p::context.SetSupportsMesh (ygg); + i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); if (ntcp2) @@ -170,6 +183,8 @@ namespace i2p if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ()) i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured } + if (ygg) + i2p::context.UpdateNTCP2V6Address (yggaddr); } else i2p::context.PublishNTCP2Address (port, false); // unpublish From c4fc0f4ecf48d09e3f591685bba88ce5d4b22ad3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Jan 2021 18:30:53 -0500 Subject: [PATCH 0664/2950] add Yggdrasil address --- daemon/Daemon.cpp | 2 +- libi2pd/RouterContext.cpp | 17 ++++++++++++++++- libi2pd/RouterContext.h | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index ba11e500..c53a5d47 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -164,7 +164,7 @@ namespace i2p } i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); - i2p::context.SetSupportsMesh (ygg); + i2p::context.SetSupportsMesh (ygg, yggaddr); i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 33cfb943..9faa75aa 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -521,10 +521,25 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::SetSupportsMesh (bool supportsmesh) + 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); + if (!port) i2p::config::GetOption("port", port); + if (!port) + { + auto& addresses = m_RouterInfo.GetAddresses (); + for (auto& addr: addresses) + { + port = addr->port; + if (port) break; + } + } + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); + } else m_RouterInfo.DisableMesh (); UpdateRouterInfo (); diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 81921d1c..1def089a 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -110,7 +110,7 @@ namespace i2p bool SupportsMesh () const { return m_RouterInfo.IsMesh (); }; void SetSupportsV6 (bool supportsV6); void SetSupportsV4 (bool supportsV4); - void SetSupportsMesh (bool supportsmesh); + 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; }; From fef4f13b8f99685c79aea4e80c82a408071f0eaf Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 31 Jan 2021 19:09:38 -0500 Subject: [PATCH 0665/2950] don't insert Yggdrasil address twice --- libi2pd/RouterContext.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 9faa75aa..62f5701f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -529,16 +529,19 @@ namespace i2p uint16_t port = 0; i2p::config::GetOption ("ntcp2.port", port); if (!port) i2p::config::GetOption("port", port); - if (!port) - { - auto& addresses = m_RouterInfo.GetAddresses (); - for (auto& addr: addresses) + bool foundMesh = false; + auto& addresses = m_RouterInfo.GetAddresses (); + for (auto& addr: addresses) + { + if (!port) port = addr->port; + if (i2p::util::net::IsYggdrasilAddress (addr->host)) { - port = addr->port; - if (port) break; - } - } - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); + foundMesh = true; + break; + } + } + if (!foundMesh) + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); } else m_RouterInfo.DisableMesh (); From ea19802d3fc05068ec02e2748c83d23a11c9c569 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 1 Feb 2021 12:47:41 -0500 Subject: [PATCH 0666/2950] update right ipv6 only --- libi2pd/RouterContext.cpp | 4 +++- libi2pd/util.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 62f5701f..df50b67f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -550,13 +550,15 @@ namespace i2p void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) { + bool isYgg = i2p::util::net::IsYggdrasilAddress (host); bool updated = false; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) { if (addr->IsPublishedNTCP2 ()) { - if (addr->host.is_v6 ()) + bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host); + if (addr->host.is_v6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1))) { if (addr->host != host) { diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index a36ab25f..b70aed8d 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -449,6 +449,7 @@ namespace net { boost::asio::ip::address_v6::bytes_type bytes; memcpy (bytes.data (), &sa->sin6_addr, 16); + freeifaddrs(addrs); return boost::asio::ip::address_v6 (bytes); } } From bfb1380dd2e8eff5c067412e50e2058078528193 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 1 Feb 2021 13:18:48 -0500 Subject: [PATCH 0667/2950] don't update Yggdrasil address from SSU --- libi2pd/RouterContext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index df50b67f..96a33041 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -245,7 +245,8 @@ 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; if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU) From ace80c29e7caf25ea50534370962443faada5991 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 1 Feb 2021 18:00:03 -0500 Subject: [PATCH 0668/2950] meshnets.yggaddress added --- daemon/Daemon.cpp | 21 +++++++++++++++++---- libi2pd/Config.cpp | 1 + libi2pd/RouterInfo.cpp | 3 ++- libi2pd/util.cpp | 4 ++-- libi2pd/util.h | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index c53a5d47..70c4affc 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -148,11 +148,24 @@ namespace i2p boost::asio::ip::address_v6 yggaddr; if (ygg) { - yggaddr = i2p::util::net::GetYggdrasilAddress (); - if (yggaddr.is_unspecified ()) + std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress); + if (!yggaddress.empty ()) { - LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled"); - ygg = false; + yggaddr = boost::asio::ip::address_v6::from_string (yggaddress); + if (yggaddr.is_unspecified () || i2p::util::net::GetMTU (yggaddr) != 0xFFFF) // ygg's MTU is always 65535 + { + LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress); + ygg = false; + } + } + else + { + yggaddr = i2p::util::net::GetYggdrasilAddress (); + if (yggaddr.is_unspecified ()) + { + LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled"); + ygg = false; + } } } diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index eb7a230e..9da0bbe0 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -279,6 +279,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.yggaddress", value()->default_value(""), "Yggdrasil address to publish") ; m_OptionsDesc diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 3f710aec..13988f5f 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -980,7 +980,8 @@ namespace data return GetAddress ( [](std::shared_ptr address)->bool { - return address->IsPublishedNTCP2 () && address->host.is_v6 (); + return address->IsPublishedNTCP2 () && address->host.is_v6 () && + !i2p::util::net::IsYggdrasilAddress (address->host); }); } diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index b70aed8d..f9beacf0 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -461,7 +461,7 @@ namespace net #endif } - bool IsInReservedRange (const boost::asio::ip::address& host, bool checkYggdrasil) + bool IsInReservedRange (const boost::asio::ip::address& host) { // https://en.wikipedia.org/wiki/Reserved_IP_addresses if(host.is_v4()) @@ -502,7 +502,7 @@ namespace net if (ipv6_address >= it.first && ipv6_address <= it.second) return true; } - if (checkYggdrasil && IsYggdrasilAddress (ipv6_address.data ())) // yggdrasil? + if (IsYggdrasilAddress (ipv6_address.data ())) // yggdrasil? return true; } return false; diff --git a/libi2pd/util.h b/libi2pd/util.h index bd02c648..d4b9da51 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -189,7 +189,7 @@ namespace util int GetMTU (const boost::asio::ip::address& localAddress); const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); boost::asio::ip::address_v6 GetYggdrasilAddress (); - bool IsInReservedRange (const boost::asio::ip::address& host, bool checkYggdrasil = true); + bool IsInReservedRange (const boost::asio::ip::address& host); bool IsYggdrasilAddress (const boost::asio::ip::address& addr); } } From 05c7aacfa5e01f92c899fca9f6a700d94cce6810 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 1 Feb 2021 22:24:51 -0500 Subject: [PATCH 0669/2950] check for NTCP for yggdrasil address --- libi2pd/RouterInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 13988f5f..d0784ece 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -990,7 +990,7 @@ namespace data return GetAddress ( [](std::shared_ptr address)->bool { - return i2p::util::net::IsYggdrasilAddress (address->host); + return address->IsPublishedNTCP2 () && i2p::util::net::IsYggdrasilAddress (address->host); }); } From a74f685a5d262a2e66972f47879460f09a52476f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 2 Feb 2021 19:29:13 -0500 Subject: [PATCH 0670/2950] check local address --- daemon/Daemon.cpp | 3 ++- libi2pd/util.cpp | 11 +++++++++++ libi2pd/util.h | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 70c4affc..80d56651 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -152,7 +152,8 @@ namespace i2p if (!yggaddress.empty ()) { yggaddr = boost::asio::ip::address_v6::from_string (yggaddress); - if (yggaddr.is_unspecified () || i2p::util::net::GetMTU (yggaddr) != 0xFFFF) // ygg's MTU is always 65535 + if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) || + !i2p::util::net::IsLocalAddress (yggaddr)) { LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress); ygg = false; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index f9beacf0..22530a70 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -461,6 +461,17 @@ namespace net #endif } + bool IsLocalAddress (const boost::asio::ip::address& addr) + { + auto mtu = // TODO: implement better +#ifdef _WIN32 + GetMTUWindows(addr, 0); +#else + GetMTUUnix(addr, 0); +#endif + return mtu > 0; + } + bool IsInReservedRange (const boost::asio::ip::address& host) { // https://en.wikipedia.org/wiki/Reserved_IP_addresses diff --git a/libi2pd/util.h b/libi2pd/util.h index d4b9da51..0cab4121 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -189,6 +189,7 @@ namespace util int GetMTU (const boost::asio::ip::address& localAddress); const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); boost::asio::ip::address_v6 GetYggdrasilAddress (); + bool IsLocalAddress (const boost::asio::ip::address& addr); bool IsInReservedRange (const boost::asio::ip::address& host); bool IsYggdrasilAddress (const boost::asio::ip::address& addr); } From 0e5dc15005e819bf5b84b62bebe31275683e0fee Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 2 Feb 2021 21:39:16 -0500 Subject: [PATCH 0671/2950] create Yggdrasil address for new router --- libi2pd/RouterContext.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 96a33041..797bb5d7 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -72,6 +72,7 @@ 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 nat; i2p::config::GetOption("nat", nat); std::string ifname; i2p::config::GetOption("ifname", ifname); std::string ifname4; i2p::config::GetOption("ifname4", ifname4); @@ -105,7 +106,7 @@ namespace i2p if (ssu) routerInfo.AddSSUAddress (host.c_str(), port, nullptr); } - + routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC routerInfo.SetProperty ("netId", std::to_string (m_NetID)); @@ -117,11 +118,12 @@ namespace i2p if (ntcp2) // we don't store iv in the address if non published so we must update it from keys { if (!m_NTCP2Keys) NewNTCP2Keys (); - UpdateNTCP2Address (true); bool published; i2p::config::GetOption("ntcp2.published", published); + if (ipv4 || !published) UpdateNTCP2Address (true); // create not published NTCP2 address if (published) { - PublishNTCP2Address (port, true); + if (ipv4) + PublishNTCP2Address (port, true); if (ipv6) { // add NTCP2 ipv6 address @@ -130,6 +132,15 @@ namespace i2p i2p::config::GetOption ("ntcp2.addressv6", host); m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); } + if (ygg) + { + auto yggaddr = i2p::util::net::GetYggdrasilAddress (); + if (!yggaddr.is_unspecified ()) + { + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); + UpdateRouterInfo (); + } + } } } } From 6966539b86f02cd9fff779908e60f4b944be5ba5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 1 Feb 2021 14:36:51 +0300 Subject: [PATCH 0672/2950] reindent Datagram, Daemon, update default subscription in config example Signed-off-by: R4SAS --- contrib/i2pd.conf | 4 +- daemon/Daemon.cpp | 685 ++++++++++++++++++++++--------------------- libi2pd/Datagram.cpp | 74 ++--- 3 files changed, 383 insertions(+), 380 deletions(-) diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf index 13801076..0c2ec5bc 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -192,8 +192,8 @@ verify = true [addressbook] ## AddressBook subscription URL for initial setup -## Default: inr.i2p at "mainline" I2P Network -# defaulturl = http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt +## 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 diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 80d56651..ccbfbb1d 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -35,403 +35,406 @@ namespace i2p { - namespace util +namespace util +{ + class Daemon_Singleton::Daemon_Singleton_Private { - class Daemon_Singleton::Daemon_Singleton_Private - { - public: - Daemon_Singleton_Private() {}; - ~Daemon_Singleton_Private() {}; + public: + Daemon_Singleton_Private() {}; + ~Daemon_Singleton_Private() {}; - std::unique_ptr httpServer; - std::unique_ptr m_I2PControlService; - std::unique_ptr UPnP; - std::unique_ptr m_NTPSync; - }; + std::unique_ptr httpServer; + std::unique_ptr m_I2PControlService; + std::unique_ptr UPnP; + std::unique_ptr m_NTPSync; + }; - Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {} - Daemon_Singleton::~Daemon_Singleton() { - delete &d; - } + Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {} + Daemon_Singleton::~Daemon_Singleton() { + delete &d; + } - bool Daemon_Singleton::IsService () const - { - bool service = false; + bool Daemon_Singleton::IsService () const + { + bool service = false; #ifndef _WIN32 - i2p::config::GetOption("service", service); + i2p::config::GetOption("service", service); #endif - return service; - } + return service; + } - bool Daemon_Singleton::init(int argc, char* argv[]) { - return init(argc, argv, nullptr); - } + bool Daemon_Singleton::init(int argc, char* argv[]) { + return init(argc, argv, nullptr); + } - bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr logstream) + bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr logstream) + { + i2p::config::Init(); + i2p::config::ParseCmdline(argc, argv); + + std::string config; i2p::config::GetOption("conf", config); + std::string datadir; i2p::config::GetOption("datadir", datadir); + i2p::fs::DetectDataDir(datadir, IsService()); + i2p::fs::Init(); + + datadir = i2p::fs::GetDataDir(); + + if (config == "") { - i2p::config::Init(); - i2p::config::ParseCmdline(argc, argv); - - std::string config; i2p::config::GetOption("conf", config); - std::string datadir; i2p::config::GetOption("datadir", datadir); - i2p::fs::DetectDataDir(datadir, IsService()); - i2p::fs::Init(); - - datadir = i2p::fs::GetDataDir(); - - if (config == "") - { - config = i2p::fs::DataDirPath("i2pd.conf"); - if (!i2p::fs::Exists (config)) { - // use i2pd.conf only if exists - config = ""; /* reset */ - } + config = i2p::fs::DataDirPath("i2pd.conf"); + if (!i2p::fs::Exists (config)) { + // use i2pd.conf only if exists + config = ""; /* reset */ } + } - i2p::config::ParseConfig(config); - i2p::config::Finalize(); + i2p::config::ParseConfig(config); + i2p::config::Finalize(); - i2p::config::GetOption("daemon", isDaemon); + i2p::config::GetOption("daemon", isDaemon); - std::string logs = ""; i2p::config::GetOption("log", logs); - std::string logfile = ""; i2p::config::GetOption("logfile", logfile); - std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel); - bool logclftime; i2p::config::GetOption("logclftime", logclftime); + std::string logs = ""; i2p::config::GetOption("log", logs); + std::string logfile = ""; i2p::config::GetOption("logfile", logfile); + std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel); + bool logclftime; i2p::config::GetOption("logclftime", logclftime); - /* setup logging */ - if (logclftime) - i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]"); + /* setup logging */ + if (logclftime) + i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]"); - if (isDaemon && (logs == "" || logs == "stdout")) - logs = "file"; + if (isDaemon && (logs == "" || logs == "stdout")) + logs = "file"; - i2p::log::Logger().SetLogLevel(loglevel); - if (logstream) { - LogPrint(eLogInfo, "Log: will send messages to std::ostream"); - i2p::log::Logger().SendTo (logstream); - } else if (logs == "file") { - if (logfile == "") - logfile = i2p::fs::DataDirPath("i2pd.log"); - LogPrint(eLogInfo, "Log: will send messages to ", logfile); - i2p::log::Logger().SendTo (logfile); + i2p::log::Logger().SetLogLevel(loglevel); + if (logstream) { + LogPrint(eLogInfo, "Log: will send messages to std::ostream"); + i2p::log::Logger().SendTo (logstream); + } else if (logs == "file") { + if (logfile == "") + logfile = i2p::fs::DataDirPath("i2pd.log"); + LogPrint(eLogInfo, "Log: will send messages to ", logfile); + i2p::log::Logger().SendTo (logfile); #ifndef _WIN32 - } else if (logs == "syslog") { - LogPrint(eLogInfo, "Log: will send messages to syslog"); - i2p::log::Logger().SendTo("i2pd", LOG_DAEMON); + } else if (logs == "syslog") { + LogPrint(eLogInfo, "Log: will send messages to syslog"); + i2p::log::Logger().SendTo("i2pd", LOG_DAEMON); #endif - } else { - // use stdout -- default - } + } else { + // use stdout -- default + } - LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); - LogPrint(eLogDebug, "FS: main config file: ", config); - LogPrint(eLogDebug, "FS: data directory: ", datadir); + LogPrint(eLogInfo, "i2pd v", VERSION, " starting"); + LogPrint(eLogDebug, "FS: main config file: ", config); + LogPrint(eLogDebug, "FS: data directory: ", datadir); - bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); - bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); - bool avx; i2p::config::GetOption("cpuext.avx", avx); - bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt); - i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt); + bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); + bool aesni; i2p::config::GetOption("cpuext.aesni", aesni); + bool avx; i2p::config::GetOption("cpuext.avx", avx); + bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt); + i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt); - int netID; i2p::config::GetOption("netid", netID); - i2p::context.SetNetID (netID); - i2p::context.Init (); + int netID; i2p::config::GetOption("netid", netID); + 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; + // manual override for meshnet + ipv4 = false; + ipv6 = true; #endif - bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); - boost::asio::ip::address_v6 yggaddr; - if (ygg) + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + boost::asio::ip::address_v6 yggaddr; + if (ygg) + { + std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress); + if (!yggaddress.empty ()) { - std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress); - if (!yggaddress.empty ()) + yggaddr = boost::asio::ip::address_v6::from_string (yggaddress); + if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) || + !i2p::util::net::IsLocalAddress (yggaddr)) { - yggaddr = boost::asio::ip::address_v6::from_string (yggaddress); - if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) || - !i2p::util::net::IsLocalAddress (yggaddr)) - { - LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress); - ygg = false; - } + LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress); + ygg = false; } - else - { - yggaddr = i2p::util::net::GetYggdrasilAddress (); - if (yggaddr.is_unspecified ()) - { - LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled"); - ygg = false; - } - } - } - - uint16_t port; i2p::config::GetOption("port", port); - if (!i2p::config::IsDefault("port")) - { - LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port); - i2p::context.UpdatePort (port); - } - i2p::context.SetSupportsV6 (ipv6); - i2p::context.SetSupportsV4 (ipv4); - i2p::context.SetSupportsMesh (ygg, yggaddr); - - i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) - { - bool published; i2p::config::GetOption("ntcp2.published", published); - if (published) - { - uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port); - if (!ntcp2port) ntcp2port = port; // use standard port - i2p::context.PublishNTCP2Address (ntcp2port, true); // publish - if (ipv6) - { - std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr); - auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr); - if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ()) - i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured - } - if (ygg) - i2p::context.UpdateNTCP2V6Address (yggaddr); - } - else - i2p::context.PublishNTCP2Address (port, false); // unpublish - } - - bool transit; i2p::config::GetOption("notransit", transit); - i2p::context.SetAcceptsTunnels (!transit); - uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); - SetMaxNumTransitTunnels (transitTunnels); - - bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); - if (isFloodfill) { - LogPrint(eLogInfo, "Daemon: router will be floodfill"); - i2p::context.SetFloodfill (true); - } else { - i2p::context.SetFloodfill (false); - } - - /* this section also honors 'floodfill' flag, if set above */ - std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); - if (bandwidth.length () > 0) - { - if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X') - { - i2p::context.SetBandwidth (bandwidth[0]); - LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps"); - } - else - { - auto value = std::atoi(bandwidth.c_str()); - if (value > 0) - { - i2p::context.SetBandwidth (value); - LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps"); - } - else - { - LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'"); - i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); - } - } - } - else if (isFloodfill) - { - LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'"); - i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1); } else { - LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'"); - i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); - } - - int shareRatio; i2p::config::GetOption("share", shareRatio); - i2p::context.SetShareRatio (shareRatio); - - std::string family; i2p::config::GetOption("family", family); - i2p::context.SetFamily (family); - if (family.length () > 0) - LogPrint(eLogInfo, "Daemon: family set to ", family); - - bool trust; i2p::config::GetOption("trust.enabled", trust); - if (trust) - { - LogPrint(eLogInfo, "Daemon: explicit trust enabled"); - std::string fam; i2p::config::GetOption("trust.family", fam); - std::string routers; i2p::config::GetOption("trust.routers", routers); - bool restricted = false; - if (fam.length() > 0) + yggaddr = i2p::util::net::GetYggdrasilAddress (); + if (yggaddr.is_unspecified ()) { - std::set fams; - size_t pos = 0, comma; - do - { - comma = fam.find (',', pos); - fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); - pos = comma + 1; - } - while (comma != std::string::npos); - i2p::transport::transports.RestrictRoutesToFamilies(fams); - restricted = fams.size() > 0; + LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled"); + ygg = false; } - if (routers.length() > 0) { - std::set idents; - size_t pos = 0, comma; - do - { - comma = routers.find (',', pos); - i2p::data::IdentHash ident; - ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); - idents.insert (ident); - pos = comma + 1; - } - while (comma != std::string::npos); - LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routers"); - i2p::transport::transports.RestrictRoutesToRouters(idents); - restricted = idents.size() > 0; - } - if(!restricted) - LogPrint(eLogError, "Daemon: no trusted routers of families specified"); } - - bool hidden; i2p::config::GetOption("trust.hidden", hidden); - if (hidden) - { - LogPrint(eLogInfo, "Daemon: using hidden mode"); - i2p::data::netdb.SetHidden(true); - } - return true; } - bool Daemon_Singleton::start() + uint16_t port; i2p::config::GetOption("port", port); + if (!i2p::config::IsDefault("port")) { - i2p::log::Logger().Start(); - LogPrint(eLogInfo, "Daemon: starting NetDB"); - i2p::data::netdb.Start(); + LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port); + i2p::context.UpdatePort (port); + } + i2p::context.SetSupportsV6 (ipv6); + i2p::context.SetSupportsV4 (ipv4); + i2p::context.SetSupportsMesh (ygg, yggaddr); - bool upnp; i2p::config::GetOption("upnp.enabled", upnp); - if (upnp) { - d.UPnP = std::unique_ptr(new i2p::transport::UPnP); - d.UPnP->Start (); - } - - bool nettime; i2p::config::GetOption("nettime.enabled", nettime); - if (nettime) + i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + if (ntcp2) + { + bool published; i2p::config::GetOption("ntcp2.published", published); + if (published) { - d.m_NTPSync = std::unique_ptr(new i2p::util::NTPTimeSync); - d.m_NTPSync->Start (); + uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port); + if (!ntcp2port) ntcp2port = port; // use standard port + i2p::context.PublishNTCP2Address (ntcp2port, true); // publish + if (ipv6) + { + std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr); + auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr); + if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ()) + i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured + } + if (ygg) + i2p::context.UpdateNTCP2V6Address (yggaddr); + } } + else + i2p::context.PublishNTCP2Address (port, false); // unpublish + } - bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - bool ssu; i2p::config::GetOption("ssu", ssu); - bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved); - LogPrint(eLogInfo, "Daemon: starting Transports"); - if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); - if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); + bool transit; i2p::config::GetOption("notransit", transit); + i2p::context.SetAcceptsTunnels (!transit); + uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); + SetMaxNumTransitTunnels (transitTunnels); - i2p::transport::transports.SetCheckReserved(checkInReserved); - i2p::transport::transports.Start(ntcp2, ssu); - if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) - LogPrint(eLogInfo, "Daemon: Transports started"); + bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); + if (isFloodfill) { + LogPrint(eLogInfo, "Daemon: router will be floodfill"); + i2p::context.SetFloodfill (true); + } + else + { + i2p::context.SetFloodfill (false); + } + + /* this section also honors 'floodfill' flag, if set above */ + std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth); + if (bandwidth.length () > 0) + { + if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X') + { + i2p::context.SetBandwidth (bandwidth[0]); + LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps"); + } else { - LogPrint(eLogError, "Daemon: failed to start Transports"); - /** shut down netdb right away */ - i2p::transport::transports.Stop(); - i2p::data::netdb.Stop(); - return false; - } - - bool http; i2p::config::GetOption("http.enabled", http); - if (http) { - std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); - try + auto value = std::atoi(bandwidth.c_str()); + if (value > 0) { - d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); - d.httpServer->Start(); - } - catch (std::exception& ex) + i2p::context.SetBandwidth (value); + LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps"); + } + else { - LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); - ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); + LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'"); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); } } - - - LogPrint(eLogInfo, "Daemon: starting Tunnels"); - i2p::tunnel::tunnels.Start(); - - LogPrint(eLogInfo, "Daemon: starting Client"); - i2p::client::context.Start (); - - // I2P Control Protocol - bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); - if (i2pcontrol) { - std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); - uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); - LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); - try - { - d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); - d.m_I2PControlService->Start (); - } - catch (std::exception& ex) - { - LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); - ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); - } - } - return true; + } + else if (isFloodfill) + { + LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'"); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1); + } + else + { + LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'"); + i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); } - bool Daemon_Singleton::stop() + int shareRatio; i2p::config::GetOption("share", shareRatio); + i2p::context.SetShareRatio (shareRatio); + + std::string family; i2p::config::GetOption("family", family); + i2p::context.SetFamily (family); + if (family.length () > 0) + LogPrint(eLogInfo, "Daemon: family set to ", family); + + bool trust; i2p::config::GetOption("trust.enabled", trust); + if (trust) { - LogPrint(eLogInfo, "Daemon: shutting down"); - LogPrint(eLogInfo, "Daemon: stopping Client"); - i2p::client::context.Stop(); - LogPrint(eLogInfo, "Daemon: stopping Tunnels"); - i2p::tunnel::tunnels.Stop(); - - if (d.UPnP) + LogPrint(eLogInfo, "Daemon: explicit trust enabled"); + std::string fam; i2p::config::GetOption("trust.family", fam); + std::string routers; i2p::config::GetOption("trust.routers", routers); + bool restricted = false; + if (fam.length() > 0) { - d.UPnP->Stop (); - d.UPnP = nullptr; + std::set fams; + size_t pos = 0, comma; + do + { + comma = fam.find (',', pos); + fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); + pos = comma + 1; + } + while (comma != std::string::npos); + i2p::transport::transports.RestrictRoutesToFamilies(fams); + restricted = fams.size() > 0; } - - if (d.m_NTPSync) - { - d.m_NTPSync->Stop (); - d.m_NTPSync = nullptr; + if (routers.length() > 0) { + std::set idents; + size_t pos = 0, comma; + do + { + comma = routers.find (',', pos); + i2p::data::IdentHash ident; + ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); + idents.insert (ident); + pos = comma + 1; + } + while (comma != std::string::npos); + LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routers"); + i2p::transport::transports.RestrictRoutesToRouters(idents); + restricted = idents.size() > 0; } + if(!restricted) + LogPrint(eLogError, "Daemon: no trusted routers of families specified"); + } - LogPrint(eLogInfo, "Daemon: stopping Transports"); + bool hidden; i2p::config::GetOption("trust.hidden", hidden); + if (hidden) + { + LogPrint(eLogInfo, "Daemon: using hidden mode"); + i2p::data::netdb.SetHidden(true); + } + return true; + } + + bool Daemon_Singleton::start() + { + i2p::log::Logger().Start(); + LogPrint(eLogInfo, "Daemon: starting NetDB"); + i2p::data::netdb.Start(); + + bool upnp; i2p::config::GetOption("upnp.enabled", upnp); + if (upnp) { + d.UPnP = std::unique_ptr(new i2p::transport::UPnP); + d.UPnP->Start (); + } + + bool nettime; i2p::config::GetOption("nettime.enabled", nettime); + if (nettime) + { + d.m_NTPSync = std::unique_ptr(new i2p::util::NTPTimeSync); + d.m_NTPSync->Start (); + } + + bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); + bool ssu; i2p::config::GetOption("ssu", ssu); + bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved); + LogPrint(eLogInfo, "Daemon: starting Transports"); + if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled"); + if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); + + i2p::transport::transports.SetCheckReserved(checkInReserved); + i2p::transport::transports.Start(ntcp2, ssu); + if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) + LogPrint(eLogInfo, "Daemon: Transports started"); + else + { + LogPrint(eLogError, "Daemon: failed to start Transports"); + /** shut down netdb right away */ i2p::transport::transports.Stop(); - LogPrint(eLogInfo, "Daemon: stopping NetDB"); i2p::data::netdb.Stop(); - if (d.httpServer) { - LogPrint(eLogInfo, "Daemon: stopping HTTP Server"); - d.httpServer->Stop(); - d.httpServer = nullptr; - } - if (d.m_I2PControlService) - { - LogPrint(eLogInfo, "Daemon: stopping I2PControl"); - d.m_I2PControlService->Stop (); - d.m_I2PControlService = nullptr; - } - i2p::crypto::TerminateCrypto (); - i2p::log::Logger().Stop(); - - return true; + return false; } + + bool http; i2p::config::GetOption("http.enabled", http); + if (http) { + std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); + uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); + LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort); + try + { + d.httpServer = std::unique_ptr(new i2p::http::HTTPServer(httpAddr, httpPort)); + d.httpServer->Start(); + } + catch (std::exception& ex) + { + LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ()); + ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ()); + } + } + + + LogPrint(eLogInfo, "Daemon: starting Tunnels"); + i2p::tunnel::tunnels.Start(); + + LogPrint(eLogInfo, "Daemon: starting Client"); + i2p::client::context.Start (); + + // I2P Control Protocol + bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol); + if (i2pcontrol) { + std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr); + uint16_t i2pcpPort; i2p::config::GetOption("i2pcontrol.port", i2pcpPort); + LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort); + try + { + d.m_I2PControlService = std::unique_ptr(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort)); + d.m_I2PControlService->Start (); + } + catch (std::exception& ex) + { + LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ()); + ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ()); + } + } + return true; + } + + bool Daemon_Singleton::stop() + { + LogPrint(eLogInfo, "Daemon: shutting down"); + LogPrint(eLogInfo, "Daemon: stopping Client"); + i2p::client::context.Stop(); + LogPrint(eLogInfo, "Daemon: stopping Tunnels"); + i2p::tunnel::tunnels.Stop(); + + if (d.UPnP) + { + d.UPnP->Stop (); + d.UPnP = nullptr; + } + + if (d.m_NTPSync) + { + d.m_NTPSync->Stop (); + d.m_NTPSync = nullptr; + } + + LogPrint(eLogInfo, "Daemon: stopping Transports"); + i2p::transport::transports.Stop(); + LogPrint(eLogInfo, "Daemon: stopping NetDB"); + i2p::data::netdb.Stop(); + if (d.httpServer) { + LogPrint(eLogInfo, "Daemon: stopping HTTP Server"); + d.httpServer->Stop(); + d.httpServer = nullptr; + } + if (d.m_I2PControlService) + { + LogPrint(eLogInfo, "Daemon: stopping I2PControl"); + d.m_I2PControlService->Stop (); + d.m_I2PControlService = nullptr; + } + i2p::crypto::TerminateCrypto (); + i2p::log::Logger().Stop(); + + return true; + } } } diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index 32db8ff1..d000a9e0 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -49,8 +49,8 @@ namespace datagram std::shared_ptr DatagramDestination::GetSession(const i2p::data::IdentHash & ident) { return ObtainSession(ident); - } - + } + void DatagramDestination::SendDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) { if (session) @@ -67,21 +67,21 @@ namespace datagram auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, fromPort, toPort, false, !session->IsRatchets ()); // datagram session->SendMsg(msg); - } - } + } + } void DatagramDestination::SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) { if (session) session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw } - + void DatagramDestination::FlushSendQueue (std::shared_ptr session) { if (session) session->FlushSendQueue (); - } - + } + void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len) { i2p::data::IdentityEx identity; @@ -242,7 +242,7 @@ namespace datagram if (msg || m_SendQueue.empty ()) m_SendQueue.push_back(msg); // flush queue right away if full - if (!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) + if (!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) FlushSendQueue(); } @@ -286,14 +286,14 @@ namespace datagram m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent); if (!m_RemoteLeaseSet) { - if(!m_RequestingLS) + if(!m_RequestingLS) { m_RequestingLS = true; m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1)); } return nullptr; - } - } + } + } if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) { @@ -305,81 +305,81 @@ namespace datagram m_PendingRoutingSessions.clear (); found = true; break; - } + } if (!found) - { + { m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); if (!m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ()) m_PendingRoutingSessions.push_back (m_RoutingSession); - } - } - + } + } + auto path = m_RoutingSession->GetSharedRoutingPath(); if (path && m_RoutingSession->IsRatchets () && m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT) - { + { m_RoutingSession->SetSharedRoutingPath (nullptr); path = nullptr; } - - if (path) + + if (path) { if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ()) - { + { // bad outbound tunnel, switch outbound tunnel path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel); if (!path->outboundTunnel) m_RoutingSession->SetSharedRoutingPath (nullptr); - } - - if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) + } + + if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) { // bad lease, switch to next one - if (m_RemoteLeaseSet) + if (m_RemoteLeaseSet) { auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding( - [&](const i2p::data::Lease& l) -> bool + [&](const i2p::data::Lease& l) -> bool { return l.tunnelID == path->remoteLease->tunnelID; }); auto sz = ls.size(); - if (sz) + if (sz) { auto idx = rand() % sz; path->remoteLease = ls[idx]; } else m_RoutingSession->SetSharedRoutingPath (nullptr); - } - else - { + } + else + { // no remote lease set? LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32()); m_RoutingSession->SetSharedRoutingPath (nullptr); - } + } } - } - else + } + else { // no current path, make one path = std::make_shared(); path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(); if (!path->outboundTunnel) return nullptr; - - if (m_RemoteLeaseSet) + + if (m_RemoteLeaseSet) { // pick random next good lease auto ls = m_RemoteLeaseSet->GetNonExpiredLeases(); auto sz = ls.size(); - if (sz) + if (sz) { auto idx = rand() % sz; path->remoteLease = ls[idx]; } else return nullptr; - } - else + } + else { // no remote lease set currently, bail LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32()); From f59d509b15f3c502a747a1184163538436738e0b Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 3 Feb 2021 15:12:27 +0300 Subject: [PATCH 0673/2950] fix rebase result build issue Signed-off-by: R4SAS --- daemon/Daemon.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index ccbfbb1d..e9d9110c 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -199,7 +199,6 @@ namespace util } if (ygg) i2p::context.UpdateNTCP2V6Address (yggaddr); - } } else i2p::context.PublishNTCP2Address (port, false); // unpublish From 33b82b5669ed8a622ad01b4da43cd5b8f847faa0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Feb 2021 14:24:43 -0500 Subject: [PATCH 0674/2950] check transport compatibility with peer before connecting --- libi2pd/Transports.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 5d6fc5f1..17345901 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -351,6 +351,7 @@ namespace transport try { auto r = netdb.FindRouter (ident); + if (!r || !r->IsCompatible (i2p::context.GetRouterInfo ())) return; { std::unique_lock l(m_PeersMutex); it = m_Peers.insert (std::pair(ident, { 0, r, {}, From 89e8d99294d4f444ae15c40ee5ee801147af680d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 3 Feb 2021 20:09:43 -0500 Subject: [PATCH 0675/2950] check availability of particular address --- libi2pd/RouterInfo.cpp | 5 +++++ libi2pd/RouterInfo.h | 3 ++- libi2pd/Transports.cpp | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index d0784ece..8da49fc6 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -837,6 +837,11 @@ namespace data return m_SupportedTransports & (eNTCP2V4 | eNTCP2V6); } + bool RouterInfo::IsNTCP2V6 () const + { + return m_SupportedTransports & eNTCP2V6; + } + bool RouterInfo::IsV6 () const { return m_SupportedTransports & (eSSUV6 | eNTCP2V6); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index fc55a9e2..45670ee5 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -170,6 +170,7 @@ namespace data bool IsSSU (bool v4only = true) const; bool IsSSUV6 () const; bool IsNTCP2 (bool v4only = true) const; + bool IsNTCP2V6 () const; bool IsV6 () const; bool IsV4 () const; bool IsMesh () const; @@ -179,7 +180,7 @@ namespace data void DisableV4 (); void EnableMesh (); void DisableMesh (); - bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; + bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; }; bool HasValidAddresses () const { return m_SupportedTransports; }; bool UsesIntroducer () const; bool IsIntroducer () const { return m_Caps & eSSUIntroducer; }; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 17345901..01a4b337 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -397,7 +397,7 @@ namespace transport std::shared_ptr address; if (!peer.numAttempts) // NTCP2 ipv6 { - if (context.SupportsV6 ()) + if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsNTCP2V6 ()) { address = peer.router->GetPublishedNTCP2V6Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) @@ -407,7 +407,7 @@ namespace transport } if (!address && peer.numAttempts == 1) // NTCP2 ipv4 { - if (context.SupportsV4 () && !peer.router->IsUnreachable ()) + if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsNTCP2 (true) && !peer.router->IsUnreachable ()) { address = peer.router->GetPublishedNTCP2V4Address (); if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) @@ -453,7 +453,7 @@ namespace transport if (peer.numAttempts == 3) // Mesh { peer.numAttempts++; - if (context.SupportsMesh () && m_NTCP2Server) + if (m_NTCP2Server && context.GetRouterInfo ().IsMesh () && peer.router->IsMesh ()) { auto address = peer.router->GetYggdrasilAddress (); if (address) From dc64d1738ab2d1c2d19bad321bc8c691314ef721 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 Feb 2021 21:48:13 -0500 Subject: [PATCH 0676/2950] try both ipv4 and ipv6 SSU addresses if presented --- libi2pd/Transports.cpp | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 01a4b337..2eadda85 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -437,20 +437,41 @@ namespace transport else peer.numAttempts = 2; // switch to SSU } - if (peer.numAttempts == 2)// SSU + if (peer.numAttempts == 2 || peer.numAttempts == 3) // SSU { - peer.numAttempts++; - if (m_SSUServer && peer.router->IsSSU (!context.SupportsV6 ())) - { - auto address = peer.router->GetSSUAddress (!context.SupportsV6 ()); - if (address && (!m_CheckReserved || !i2p::util::net::IsInReservedRange(address->host))) + if (m_SSUServer) + { + std::shared_ptr address; + if (peer.numAttempts == 2) // SSU ipv6 + { + if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsSSUV6 ()) + { + address = peer.router->GetSSUV6Address (); + if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) + address = nullptr; + } + peer.numAttempts++; + } + if (!address && peer.numAttempts == 3) // SSU ipv4 + { + if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsSSU (true)) + { + address = peer.router->GetSSUAddress (true); + if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host)) + address = nullptr; + } + peer.numAttempts++; + } + if (address) { m_SSUServer->CreateSession (peer.router, address->host, address->port); return true; - } + } } + else + peer.numAttempts += 2; // switch to Mesh } - if (peer.numAttempts == 3) // Mesh + if (peer.numAttempts == 4) // Mesh { peer.numAttempts++; if (m_NTCP2Server && context.GetRouterInfo ().IsMesh () && peer.router->IsMesh ()) @@ -464,7 +485,7 @@ namespace transport } } } - LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available"); + LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available"); i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed peer.Done (); std::unique_lock l(m_PeersMutex); From 2d0e2191979e0730907a6b3921f132842353ee20 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 5 Feb 2021 17:24:11 -0500 Subject: [PATCH 0677/2950] add Yggdrasil adddress even if NTCP2 is not published. Correct reachable capacity --- libi2pd/RouterContext.cpp | 31 +++++++++++++++++++------------ libi2pd/RouterContext.h | 3 ++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 797bb5d7..1fe66762 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 (eRouterStatusOK), + m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -77,6 +77,7 @@ namespace i2p std::string ifname; i2p::config::GetOption("ifname", ifname); std::string ifname4; i2p::config::GetOption("ifname4", ifname4); std::string ifname6; i2p::config::GetOption("ifname6", ifname6); + uint8_t caps = 0; if (ipv4) { std::string host = "127.0.0.1"; @@ -90,7 +91,10 @@ namespace i2p host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string(); if (ssu) + { routerInfo.AddSSUAddress (host.c_str(), port, nullptr); + caps |= i2p::data::RouterInfo::eReachable | i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer; // R, BC + } } if (ipv6) { @@ -104,11 +108,13 @@ namespace i2p host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string(); if (ssu) + { routerInfo.AddSSUAddress (host.c_str(), port, nullptr); + caps |= i2p::data::RouterInfo::eReachable; // R + } } - routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | - i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC + routerInfo.SetCaps (caps); // caps + L routerInfo.SetProperty ("netId", std::to_string (m_NetID)); routerInfo.SetProperty ("router.version", I2P_VERSION); routerInfo.CreateBuffer (m_Keys); @@ -132,17 +138,18 @@ namespace i2p i2p::config::GetOption ("ntcp2.addressv6", host); m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (host), port); } - if (ygg) - { - auto yggaddr = i2p::util::net::GetYggdrasilAddress (); - if (!yggaddr.is_unspecified ()) - { - m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); - UpdateRouterInfo (); - } - } } } + if (ygg) + { + auto yggaddr = i2p::util::net::GetYggdrasilAddress (); + if (!yggaddr.is_unspecified ()) + { + if (!m_NTCP2Keys) NewNTCP2Keys (); + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); + UpdateRouterInfo (); + } + } } void RouterContext::UpdateRouterInfo () diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 1def089a..12b77d65 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -31,7 +31,8 @@ namespace i2p eRouterStatusOK = 0, eRouterStatusTesting = 1, eRouterStatusFirewalled = 2, - eRouterStatusError = 3 + eRouterStatusError = 3, + eRouterStatusUnknown = 4 }; enum RouterError From 313921da566cfbcebce906326bd410c3707c6e38 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Feb 2021 14:49:42 -0500 Subject: [PATCH 0678/2950] publish and request through exploratory tunnel if floodfill is not reachable --- libi2pd/I2NPProtocol.cpp | 21 ++++++++++++++++----- libi2pd/I2NPProtocol.h | 2 +- libi2pd/NetDb.cpp | 15 ++++++++++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 5ad6df78..6897148b 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -244,7 +244,8 @@ namespace i2p return m; } - std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router, uint32_t replyToken) + std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router, + uint32_t replyToken, std::shared_ptr replyTunnel) { if (!router) // we send own RouterInfo router = context.GetSharedRouterInfo (); @@ -258,10 +259,20 @@ namespace i2p uint8_t * buf = payload + DATABASE_STORE_HEADER_SIZE; if (replyToken) { - memset (buf, 0, 4); // zero tunnelID means direct reply - buf += 4; - memcpy (buf, router->GetIdentHash (), 32); - buf += 32; + if (replyTunnel) + { + htobe32buf (buf, replyTunnel->GetNextTunnelID ()); + buf += 4; // reply tunnelID + memcpy (buf, replyTunnel->GetNextIdentHash (), 32); + 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; diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index b8fbb303..c9b0fc04 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -276,7 +276,7 @@ namespace tunnel const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false); std::shared_ptr CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector routers); - std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router = nullptr, uint32_t replyToken = 0); + std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr router = nullptr, uint32_t replyToken = 0, std::shared_ptr replyTunnel = nullptr); std::shared_ptr CreateDatabaseStoreMsg (const i2p::data::IdentHash& storeHash, std::shared_ptr leaseSet); // for floodfill only std::shared_ptr CreateDatabaseStoreMsg (std::shared_ptr leaseSet, uint32_t replyToken = 0, std::shared_ptr replyTunnel = nullptr); bool IsRouterInfoMsg (std::shared_ptr msg); diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 20b54376..c3e33411 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -643,6 +643,7 @@ namespace data auto floodfill = GetClosestFloodfill (destination, dest->GetExcludedPeers ()); if (floodfill) { + if (direct && !floodfill->IsCompatible (i2p::context.GetRouterInfo ())) direct = false; // check if fllodfill is reachable if (direct) transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); else @@ -1087,7 +1088,19 @@ namespace data LogPrint (eLogInfo, "NetDb: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); m_PublishExcluded.insert (floodfill->GetIdentHash ()); m_PublishReplyToken = replyToken; - transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); + if (floodfill->IsCompatible (i2p::context.GetRouterInfo ())) // able to connect? + // send directly + transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); + else + { + // otherwise through exploratory + auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); + auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr; + auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr; + if (inbound && outbound) + outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, + CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound)); + } } } From 374e0cbbc3d1c135471bded4aee02550f50bd8d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Feb 2021 18:11:34 -0500 Subject: [PATCH 0679/2950] enable NTCP2 server for Yggdrasil --- daemon/Daemon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index e9d9110c..247f5f7f 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -339,7 +339,7 @@ namespace util if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled"); i2p::transport::transports.SetCheckReserved(checkInReserved); - i2p::transport::transports.Start(ntcp2, ssu); + i2p::transport::transports.Start(ntcp2 || i2p::context.SupportsMesh (), ssu); if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2()) LogPrint(eLogInfo, "Daemon: Transports started"); else From 1bc3de8df47c63d68ab861bea43048d856dfe503 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Feb 2021 18:23:50 -0500 Subject: [PATCH 0680/2950] add Yggdrasil address without NTCP2 --- daemon/Daemon.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 247f5f7f..91db50fd 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -197,13 +197,13 @@ namespace util if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ()) i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured } - if (ygg) - i2p::context.UpdateNTCP2V6Address (yggaddr); } else i2p::context.PublishNTCP2Address (port, false); // unpublish } - + if (ygg) + i2p::context.UpdateNTCP2V6Address (yggaddr); + bool transit; i2p::config::GetOption("notransit", transit); i2p::context.SetAcceptsTunnels (!transit); uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); From 3b32da4f5ce5dfd7e8428f4836736a6cdb5fe5f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Feb 2021 19:07:39 -0500 Subject: [PATCH 0681/2950] don't disable NTCP2 address if Yggdrasil address is presented --- daemon/Daemon.cpp | 4 ++++ libi2pd/RouterContext.cpp | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 91db50fd..e33f3d6d 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -202,7 +202,11 @@ namespace util i2p::context.PublishNTCP2Address (port, false); // unpublish } if (ygg) + { + if (!ntcp2) + i2p::context.PublishNTCP2Address (port, true); i2p::context.UpdateNTCP2V6Address (yggaddr); + } bool transit; i2p::config::GetOption("notransit", transit); i2p::context.SetAcceptsTunnels (!transit); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 1fe66762..b2e83178 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -679,7 +679,8 @@ namespace i2p // read NTCP2 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); - if (ntcp2) + bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); + if (ntcp2 || ygg) { if (!m_NTCP2Keys) NewNTCP2Keys (); UpdateNTCP2Address (true); // enable NTCP2 From c164601acf82bac02bfac100e8888fc58f6bda50 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Feb 2021 21:25:16 -0500 Subject: [PATCH 0682/2950] reseed from clearnet only if ipv4 or ipv6 is enabled --- libi2pd/Reseed.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 33471b10..2e453b00 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -82,10 +82,17 @@ namespace data */ int Reseeder::ReseedFromServers () { - std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs); + bool ipv6; i2p::config::GetOption("ipv6", ipv6); + bool ipv4; i2p::config::GetOption("ipv4", ipv4); + std::vector httpsReseedHostList; - boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); - + if (ipv4 || ipv6) + { + std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs); + if (!reseedURLs.empty ()) + boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on); + } + std::vector yggReseedHostList; if (!i2p::util::net::GetYggdrasilAddress ().is_unspecified ()) { From 7e4c33d27e9cb1b5711a2c4bcb27689366a74c09 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 7 Feb 2021 10:39:26 -0500 Subject: [PATCH 0683/2950] resend RouterInfo after some interval --- libi2pd/NTCP2.cpp | 11 ++++++++++- libi2pd/NTCP2.h | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 130a6a20..dc485d5b 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -343,6 +343,8 @@ namespace transport else LogPrint (eLogWarning, "NTCP2: Missing NTCP2 parameters"); } + m_NextRouterInfoResendTime = i2p::util::GetSecondsSinceEpoch () + NTCP2_ROUTERINFO_RESEND_INTERVAL + + rand ()%NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD; } NTCP2Session::~NTCP2Session () @@ -1012,7 +1014,14 @@ namespace transport m_NumSentBytes += bytes_transferred; i2p::transport::transports.UpdateSentBytes (bytes_transferred); LogPrint (eLogDebug, "NTCP2: Next frame sent ", bytes_transferred); - SendQueue (); + if (m_LastActivityTimestamp > m_NextRouterInfoResendTime) + { + m_NextRouterInfoResendTime += NTCP2_ROUTERINFO_RESEND_INTERVAL + + rand ()%NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD; + SendRouterInfo (); + } + else + SendQueue (); } } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index f80ba75a..a7708872 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -34,6 +34,8 @@ 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_ROUTERINFO_RESEND_INTERVAL = 25*60; // 25 minuntes in seconds + const int NTCP2_ROUTERINFO_RESEND_INTERVAL_THRESHOLD = 25*60; // 25 minuntes const int NTCP2_CLOCK_SKEW = 60; // in seconds const int NTCP2_MAX_OUTGOING_QUEUE_SIZE = 500; // how many messages we can queue up @@ -212,6 +214,7 @@ namespace transport bool m_IsSending; std::list > m_SendQueue; + uint64_t m_NextRouterInfoResendTime; // seconds since epoch }; class NTCP2Server: private i2p::util::RunnableServiceWithWork From 9d8eaf0ccb07b82b59753f530c4b73623dd8f3cd Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 8 Feb 2021 19:41:46 +0300 Subject: [PATCH 0684/2950] [win32] dont create notification when taskbar (explorer) restarted Signed-off-by: R4SAS --- Win32/Win32App.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 1785ffd6..15157355 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -80,18 +80,19 @@ namespace win32 DestroyMenu(hPopup); } - static void AddTrayIcon (HWND hWnd) + static void AddTrayIcon (HWND hWnd, bool notify = false) { NOTIFYICONDATA nid; memset(&nid, 0, sizeof(nid)); nid.cbSize = sizeof(nid); nid.hWnd = hWnd; nid.uID = ID_TRAY_ICON; + nid.uFlags = notify ? NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO : NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO; nid.uCallbackMessage = WM_TRAYICON; nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON)); strcpy (nid.szTip, "i2pd"); - strcpy (nid.szInfo, "i2pd is starting"); + if (notify) strcpy (nid.szInfo, "i2pd is starting"); Shell_NotifyIcon(NIM_ADD, &nid ); } @@ -195,7 +196,7 @@ namespace win32 case WM_CREATE: { s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); - AddTrayIcon (hWnd); + AddTrayIcon (hWnd, true); break; } case WM_CLOSE: @@ -380,7 +381,7 @@ namespace win32 default: { if (uMsg == s_uTaskbarRestart) - AddTrayIcon (hWnd); + AddTrayIcon (hWnd, false); break; } } From 01df1647bcfe7a9b92a90b457fdf2683e338a4f9 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 9 Feb 2021 08:32:35 +0300 Subject: [PATCH 0685/2950] [httpproxy] add viewport and update styles on error Signed-off-by: R4SAS --- libi2pd_client/HTTPProxy.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index b2b07fba..5deaa7b5 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -39,10 +39,12 @@ namespace proxy { static const char *pageHead = "\r\n" + " \r\n" " I2Pd HTTP proxy\r\n" " \r\n" "\r\n" ; From abe1af7b4f3d1cf3e2161965568d65cf3ceda443 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 10 Feb 2021 17:00:35 +0300 Subject: [PATCH 0686/2950] moved qt and android sources inn separate repositories Signed-off-by: R4SAS --- android/.gitignore | 18 - android/AndroidManifest.xml | 60 - android/README.md | 19 - android/assets/addressbook/addresses.csv | 693 --- android/assets/certificates | 1 - android/assets/i2pd.conf | 92 - android/assets/subscriptions.txt | 3 - android/assets/tunnels.conf | 33 - android/assets/tunnels.d | 1 - android/build.gradle | 105 - android/build.xml | 96 - android/gradle.properties | 3 - android/gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - android/gradlew | 172 - android/gradlew.bat | 84 - android/jni/Android.mk | 73 - android/jni/Application.mk | 36 - android/jni/DaemonAndroid.cpp | 222 - android/jni/DaemonAndroid.h | 97 - android/jni/i2pd_android.cpp | 114 - android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 53 - android/proguard-project.txt | 20 - android/project.properties | 14 - android/res/drawable/icon.png | Bin 37177 -> 0 bytes .../drawable/itoopie_notification_icon.png | Bin 1940 -> 0 bytes android/res/layout/activity_perms_asker.xml | 26 - .../res/layout/activity_perms_explanation.xml | 25 - android/res/layout/activity_web_console.xml | 22 - android/res/menu/options_main.xml | 31 - android/res/values-ru/strings.xml | 40 - android/res/values/strings.xml | 41 - android/res/values/template-dimens.xml | 16 - android/settings.gradle | 1 - .../src/org/purplei2p/i2pd/DaemonWrapper.java | 374 -- .../org/purplei2p/i2pd/ForegroundService.java | 188 - .../src/org/purplei2p/i2pd/I2PDActivity.java | 486 --- .../i2pd/I2PDPermsAskerActivity.java | 170 - .../i2pd/I2PDPermsExplanationActivity.java | 38 - android/src/org/purplei2p/i2pd/I2PD_JNI.java | 31 - .../i2pd/NetworkStateChangeReceiver.java | 30 - .../purplei2p/i2pd/WebConsoleActivity.java | 67 - qt/.gitignore | 1 - qt/i2pd_qt/.gitignore | 13 - qt/i2pd_qt/AboutDialog.cpp | 21 - qt/i2pd_qt/AboutDialog.h | 22 - qt/i2pd_qt/AboutDialog.ui | 194 - qt/i2pd_qt/BuildDateTimeQt.h | 7 - qt/i2pd_qt/ClientTunnelPane.cpp | 220 - qt/i2pd_qt/ClientTunnelPane.h | 126 - qt/i2pd_qt/DaemonQT.cpp | 195 - qt/i2pd_qt/DaemonQT.h | 88 - qt/i2pd_qt/DelayedSaveManager.cpp | 3 - qt/i2pd_qt/DelayedSaveManager.h | 26 - qt/i2pd_qt/DelayedSaveManagerImpl.cpp | 140 - qt/i2pd_qt/DelayedSaveManagerImpl.h | 84 - qt/i2pd_qt/I2pdQtTypes.h | 7 - qt/i2pd_qt/I2pdQtUtil.cpp | 12 - qt/i2pd_qt/I2pdQtUtil.h | 9 - qt/i2pd_qt/MainWindowItems.cpp | 2 - qt/i2pd_qt/MainWindowItems.h | 17 - qt/i2pd_qt/README.md | 3 - qt/i2pd_qt/Saver.cpp | 6 - qt/i2pd_qt/Saver.h | 25 - qt/i2pd_qt/SaverImpl.cpp | 81 - qt/i2pd_qt/SaverImpl.h | 33 - qt/i2pd_qt/ServerTunnelPane.cpp | 278 -- qt/i2pd_qt/ServerTunnelPane.h | 183 - qt/i2pd_qt/SignatureTypeComboboxFactory.cpp | 2 - qt/i2pd_qt/SignatureTypeComboboxFactory.h | 86 - qt/i2pd_qt/TunnelConfig.cpp | 67 - qt/i2pd_qt/TunnelConfig.h | 260 -- qt/i2pd_qt/TunnelPane.cpp | 405 -- qt/i2pd_qt/TunnelPane.h | 191 - qt/i2pd_qt/TunnelsPageUpdateListener.h | 12 - qt/i2pd_qt/data/.gitignore | 2 - .../data/icons/128x128/website.i2pd.i2pd.png | Bin 19680 -> 0 bytes .../data/icons/16x16/website.i2pd.i2pd.png | Bin 1379 -> 0 bytes .../data/icons/22x22/website.i2pd.i2pd.png | Bin 1770 -> 0 bytes .../data/icons/24x24/website.i2pd.i2pd.png | Bin 1944 -> 0 bytes .../data/icons/256x256/website.i2pd.i2pd.png | Bin 54469 -> 0 bytes .../data/icons/32x32/website.i2pd.i2pd.png | Bin 2890 -> 0 bytes .../data/icons/48x48/website.i2pd.i2pd.png | Bin 4910 -> 0 bytes .../data/icons/512x512/website.i2pd.i2pd.png | Bin 171666 -> 0 bytes .../data/icons/64x64/website.i2pd.i2pd.png | Bin 7273 -> 0 bytes qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml | 57 - qt/i2pd_qt/data/website.i2pd.i2pd.desktop | 11 - qt/i2pd_qt/generalsettingswidget.ui | 3810 ----------------- qt/i2pd_qt/i2pd.qrc | 6 - qt/i2pd_qt/i2pd.rc | 32 - qt/i2pd_qt/i2pd_qt.pro | 179 - qt/i2pd_qt/logviewermanager.cpp | 45 - qt/i2pd_qt/logviewermanager.h | 130 - qt/i2pd_qt/mainwindow.cpp | 1126 ----- qt/i2pd_qt/mainwindow.h | 883 ---- qt/i2pd_qt/mainwindow.ui | 1053 ----- qt/i2pd_qt/pagewithbackbutton.cpp | 24 - qt/i2pd_qt/pagewithbackbutton.h | 21 - qt/i2pd_qt/resources/icons/mask.ico | Bin 156564 -> 0 bytes qt/i2pd_qt/resources/images/icon.png | Bin 8712 -> 0 bytes qt/i2pd_qt/routercommandswidget.ui | 127 - qt/i2pd_qt/statusbuttons.ui | 163 - qt/i2pd_qt/textbrowsertweaked1.cpp | 9 - qt/i2pd_qt/textbrowsertweaked1.h | 26 - qt/i2pd_qt/tunnelform.ui | 104 - qt/i2pd_qt/widgetlock.cpp | 1 - qt/i2pd_qt/widgetlock.h | 35 - qt/i2pd_qt/widgetlockregistry.cpp | 2 - qt/i2pd_qt/widgetlockregistry.h | 27 - 109 files changed, 14293 deletions(-) delete mode 100644 android/.gitignore delete mode 100755 android/AndroidManifest.xml delete mode 100644 android/README.md delete mode 100644 android/assets/addressbook/addresses.csv delete mode 120000 android/assets/certificates delete mode 100644 android/assets/i2pd.conf delete mode 100644 android/assets/subscriptions.txt delete mode 100644 android/assets/tunnels.conf delete mode 120000 android/assets/tunnels.d delete mode 100644 android/build.gradle delete mode 100644 android/build.xml delete mode 100644 android/gradle.properties delete mode 100644 android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 android/gradlew delete mode 100644 android/gradlew.bat delete mode 100755 android/jni/Android.mk delete mode 100755 android/jni/Application.mk delete mode 100644 android/jni/DaemonAndroid.cpp delete mode 100644 android/jni/DaemonAndroid.h delete mode 100755 android/jni/i2pd_android.cpp delete mode 100644 android/jni/org_purplei2p_i2pd_I2PD_JNI.h delete mode 100644 android/proguard-project.txt delete mode 100644 android/project.properties delete mode 100644 android/res/drawable/icon.png delete mode 100644 android/res/drawable/itoopie_notification_icon.png delete mode 100644 android/res/layout/activity_perms_asker.xml delete mode 100644 android/res/layout/activity_perms_explanation.xml delete mode 100644 android/res/layout/activity_web_console.xml delete mode 100644 android/res/menu/options_main.xml delete mode 100755 android/res/values-ru/strings.xml delete mode 100755 android/res/values/strings.xml delete mode 100644 android/res/values/template-dimens.xml delete mode 100644 android/settings.gradle delete mode 100644 android/src/org/purplei2p/i2pd/DaemonWrapper.java delete mode 100644 android/src/org/purplei2p/i2pd/ForegroundService.java delete mode 100755 android/src/org/purplei2p/i2pd/I2PDActivity.java delete mode 100644 android/src/org/purplei2p/i2pd/I2PDPermsAskerActivity.java delete mode 100644 android/src/org/purplei2p/i2pd/I2PDPermsExplanationActivity.java delete mode 100644 android/src/org/purplei2p/i2pd/I2PD_JNI.java delete mode 100644 android/src/org/purplei2p/i2pd/NetworkStateChangeReceiver.java delete mode 100644 android/src/org/purplei2p/i2pd/WebConsoleActivity.java delete mode 100644 qt/.gitignore delete mode 100644 qt/i2pd_qt/.gitignore delete mode 100644 qt/i2pd_qt/AboutDialog.cpp delete mode 100644 qt/i2pd_qt/AboutDialog.h delete mode 100644 qt/i2pd_qt/AboutDialog.ui delete mode 100644 qt/i2pd_qt/BuildDateTimeQt.h delete mode 100644 qt/i2pd_qt/ClientTunnelPane.cpp delete mode 100644 qt/i2pd_qt/ClientTunnelPane.h delete mode 100644 qt/i2pd_qt/DaemonQT.cpp delete mode 100644 qt/i2pd_qt/DaemonQT.h delete mode 100644 qt/i2pd_qt/DelayedSaveManager.cpp delete mode 100644 qt/i2pd_qt/DelayedSaveManager.h delete mode 100644 qt/i2pd_qt/DelayedSaveManagerImpl.cpp delete mode 100644 qt/i2pd_qt/DelayedSaveManagerImpl.h delete mode 100644 qt/i2pd_qt/I2pdQtTypes.h delete mode 100644 qt/i2pd_qt/I2pdQtUtil.cpp delete mode 100644 qt/i2pd_qt/I2pdQtUtil.h delete mode 100644 qt/i2pd_qt/MainWindowItems.cpp delete mode 100644 qt/i2pd_qt/MainWindowItems.h delete mode 100644 qt/i2pd_qt/README.md delete mode 100644 qt/i2pd_qt/Saver.cpp delete mode 100644 qt/i2pd_qt/Saver.h delete mode 100644 qt/i2pd_qt/SaverImpl.cpp delete mode 100644 qt/i2pd_qt/SaverImpl.h delete mode 100644 qt/i2pd_qt/ServerTunnelPane.cpp delete mode 100644 qt/i2pd_qt/ServerTunnelPane.h delete mode 100644 qt/i2pd_qt/SignatureTypeComboboxFactory.cpp delete mode 100644 qt/i2pd_qt/SignatureTypeComboboxFactory.h delete mode 100644 qt/i2pd_qt/TunnelConfig.cpp delete mode 100644 qt/i2pd_qt/TunnelConfig.h delete mode 100644 qt/i2pd_qt/TunnelPane.cpp delete mode 100644 qt/i2pd_qt/TunnelPane.h delete mode 100644 qt/i2pd_qt/TunnelsPageUpdateListener.h delete mode 100644 qt/i2pd_qt/data/.gitignore delete mode 100644 qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png delete mode 100644 qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml delete mode 100644 qt/i2pd_qt/data/website.i2pd.i2pd.desktop delete mode 100644 qt/i2pd_qt/generalsettingswidget.ui delete mode 100644 qt/i2pd_qt/i2pd.qrc delete mode 100644 qt/i2pd_qt/i2pd.rc delete mode 100644 qt/i2pd_qt/i2pd_qt.pro delete mode 100644 qt/i2pd_qt/logviewermanager.cpp delete mode 100644 qt/i2pd_qt/logviewermanager.h delete mode 100644 qt/i2pd_qt/mainwindow.cpp delete mode 100644 qt/i2pd_qt/mainwindow.h delete mode 100644 qt/i2pd_qt/mainwindow.ui delete mode 100644 qt/i2pd_qt/pagewithbackbutton.cpp delete mode 100644 qt/i2pd_qt/pagewithbackbutton.h delete mode 100644 qt/i2pd_qt/resources/icons/mask.ico delete mode 100644 qt/i2pd_qt/resources/images/icon.png delete mode 100644 qt/i2pd_qt/routercommandswidget.ui delete mode 100644 qt/i2pd_qt/statusbuttons.ui delete mode 100644 qt/i2pd_qt/textbrowsertweaked1.cpp delete mode 100644 qt/i2pd_qt/textbrowsertweaked1.h delete mode 100644 qt/i2pd_qt/tunnelform.ui delete mode 100644 qt/i2pd_qt/widgetlock.cpp delete mode 100644 qt/i2pd_qt/widgetlock.h delete mode 100644 qt/i2pd_qt/widgetlockregistry.cpp delete mode 100644 qt/i2pd_qt/widgetlockregistry.h diff --git a/android/.gitignore b/android/.gitignore deleted file mode 100644 index 57a0a6cd..00000000 --- a/android/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -gen -tests -bin -libs -log* -obj -.cxx -.gradle -.idea -.externalNativeBuild -ant.properties -local.properties -build.sh -android.iml -build -*.iml -*.local -*.jks diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml deleted file mode 100755 index d0e8ecb6..00000000 --- a/android/AndroidManifest.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/README.md b/android/README.md deleted file mode 100644 index e0850b15..00000000 --- a/android/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# how to compile? -## Install the gradle + NDK or use android-studio -[https://gradle.org/install/](https://gradle.org/install/) - -## Install the depencies -``` -git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0 -git clone https://github.com/PurpleI2P/android-ifaddrs.git -git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git -git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git -``` -## Set libs in jni/Application.mk on 24 line: -``` -# change to your own -I2PD_LIBS_PATH = /home/user/i2pd/android/ -``` - -## compile apk file -gradle clean assembleRelease diff --git a/android/assets/addressbook/addresses.csv b/android/assets/addressbook/addresses.csv deleted file mode 100644 index 97a43dfc..00000000 --- a/android/assets/addressbook/addresses.csv +++ /dev/null @@ -1,693 +0,0 @@ -00.i2p,zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq -0ipfs.i2p,cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza -0xcc.i2p,gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq -1.fcp.freenet.i2p,cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq -102chan.i2p,xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq -1st.i2p,rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq -2.fcp.freenet.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta -333.i2p,ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza -55cancri.i2p,b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua -adab.i2p,pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha -alice.i2p,iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq -always.i2p,wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq -amazone.i2p,e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa -amiga.i2p,edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q -amobius.i2p,rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq -anarchistfaq.i2p,xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q -animal.i2p,5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla -anodex.i2p,25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a -anoncoin.i2p,nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa -anongw.i2p,owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq -anonsfw.i2p,ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq -anonymnet.i2p,77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa -anonynanny.i2p,l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja -anonyradio.i2p,cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq -antipiracyagency.i2p,by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq -antipiratbyran.i2p,y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a -aosp.i2p,ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q -arc2.i2p,rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na -archaicbinarybbs.i2p,t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa -archiv.tutorials.i2p,lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq -archive.i2p,x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq -archive.syndie.i2p,abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq -ardor-wallet.i2p,tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq -ardvark.i2p,jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq -arf.i2p,o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq -arkan.i2p,7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq -asciiwhite.i2p,itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq -aspnet.i2p,tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a -asylum.i2p,p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha -auchan.i2p,6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a -aum.i2p,ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq -awup.i2p,v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga -b.i2p,272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq -bacardi.i2p,hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq -backup.i2p,kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq -badfish.i2p,f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a -badtoyz.i2p,3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna -barry.i2p,4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq -bash.i2p,s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q -bdl.i2p,kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a -bdsm.i2p,pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq -betaguru.i2p,d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq -beyond.i2p,uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa -bible.i2p,pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda -bible4u.i2p,xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq -bigbrother.i2p,tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq -bitlox.i2p,lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq -bittorrent.i2p,pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q -bk1k.i2p,nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq -bl.i2p,e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a -black.i2p,sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq -blackbox.i2p,7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa -blackexchange.i2p,ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q -blog.curiosity.i2p,yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta -blog.polecat.i2p,orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq -blog.tinlans.i2p,ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda -bluebeam.i2p,lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a -blueheron.i2p,anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa -bnc.i2p,fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa -bob.i2p,i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa -bobcat.i2p,ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq -bobthebuilder.i2p,qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q -boerse.i2p,7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq -bofh.i2p,auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a -boing.i2p,bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a -books.manveru.i2p,eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq -bote.i2p,bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a -bozo.i2p,7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq -brittanyworld.i2p,e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa -bt.i2p,uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq -bugfuzz.i2p,ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq -burntout.i2p,lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq -bytepay.i2p,7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq -ca.i2pd.i2p,u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba -cases.i2p,kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a -cathugger.i2p,vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba -cbs.i2p,u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq -cerapadus.i2p,zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq -cerebrum.i2p,u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq -cgan.i2p,43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa -chat.i2p,ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq -chess.fillament.i2p,tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya -chess.i2p,sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa -china.i2p,wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq -chitanka.i2p,u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba -ciaran.i2p,2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna -ciphercraft.i2p,7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca -closedshop.i2p,6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq -cneal.i2p,g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba -co.i2p,3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q -codevoid.i2p,2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa -colombo-bt.i2p,cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa -complication.i2p,x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a -comwiz.i2p,6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq -confessions.i2p,lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa -connelly.i2p,5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq -costeira.i2p,abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa -cowsay.i2p,q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q -crstrack.i2p,mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja -crypthost.i2p,zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca -crypto.i2p,vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta -cryptostorm.i2p,mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq -curiosity.i2p,eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq -cvs.i2p,yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba -danwin1210.i2p,eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba -darknetnow.i2p,gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q -darknut.i2p,2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya -darkrealm.i2p,gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq -darrob.i2p,hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja -dashninja.i2p,dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma -davidkra.i2p,nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a -dcherukhin.i2p,qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a -de-ebook-archiv.i2p,6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q -de-ebooks.i2p,epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq -dead.i2p,7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq -deadgod.i2p,63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa -debian-multimedia.i2p,cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq -decadence.i2p,pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq -deepwebradio.i2p,2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la -def2.i2p,cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da -def3.i2p,xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la -def4.i2p,yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq -deploy.i2p,ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a -det.i2p,y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q -detonate.i2p,nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja -dev.i2p,cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna -di.i2p,3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa -diasporg.i2p,edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua -diftracker.i2p,m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka -dm.i2p,heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq -docs.i2p,ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za -docs.i2p2.i2p,las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna -downloads.legion.i2p,xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq -dox.i2p,vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a -dropbox.i2p,omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq -duck.i2p,3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua -dumpteam.i2p,2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa -dust.i2p,u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq -dvdr-core.i2p,fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q -dyad.i2p,7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka -e-reading.i2p,z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq -easygpg2.i2p,bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora -eboochka.i2p,ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq -ebooks.i2p,bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq -echelon.i2p,afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq -echo.baffled.i2p,bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha -eco.i2p,2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa -eddysblog.i2p,ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq -edge.i2p,aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta -eepdot.i2p,t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa -eepshare-project.i2p,sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq -eepsites.i2p,isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq -elf.i2p,duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa -elgoog.i2p,z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya -ems.i2p,734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q -epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa -es.hiddenanswers.i2p,cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa -eschaton.i2p,xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q -esuwiki.i2p,cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa -evil.i2p,ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a -evilchat.i2p,s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla -evilgit.i2p,mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla -exch.i2p,vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq -exchange.gostcoin.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva -exchanged.i2p,ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra -exitpoint.i2p,5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta -exotrack.i2p,blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva -explorer.gostcoin.i2p,ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za -fa.i2p,6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka -falafel.i2p,djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq -false.i2p,77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha -false2.i2p,j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa -fantasy-worlds.i2p,62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq -fcp.entropy.i2p,de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq -fcp.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta -fedo.i2p,zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq -feedspace.i2p,kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa -ferret.i2p,kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q -fido.r4sas.i2p,i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q -fifi4all.i2p,v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa -files.hypercubus.i2p,qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa -files.i2p,w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa -files.nickster.i2p,yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq -fillament.i2p,udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq -firerabbit.i2p,awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q -flibs.i2p,ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a -flibusta.i2p,zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq -flipkick.i2p,aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq -flock.i2p,hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q -floureszination.i2p,vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq -forum.fr.i2p,onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq -forum.i2p,33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya -forum.rus.i2p,zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga -forums.i2p,tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya -fproxy.i2p,keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a -fproxy.tino.i2p,fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha -fproxy2.i2p,r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza -fr.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq -freeciv.nightblade.i2p,rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta -freedomarchives.i2p,4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q -freedomforum.i2p,abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua -freefallheavens.i2p,giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq -freenet.eco.i2p,2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a -freshcoffee.i2p,sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q -frooze.i2p,m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja -frosk.i2p,63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq -frostmirror.i2p,ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq -fs.i2p,ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q -fsoc.i2p,vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q -galen.i2p,4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q -gaming.i2p,rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q -garden.i2p,qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq -gaytorrents.i2p,fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q -general.i2p,5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq -gernika.i2p,wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a -ginnegappen.i2p,kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja -git-ssh.crypthost.i2p,llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a -git.crypthost.i2p,7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa -git.psi.i2p,em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa -git.repo.i2p,vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq -git.volatile.i2p,gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq -glog.i2p,ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq -gloinsblog.i2p,zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a -go.i2p,ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q -gonzo2000.i2p,nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a -google.i2p,4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq -gostcoin.i2p,4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq -gott.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja -greenflog.i2p,zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq -gstbtc.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva -gusion.i2p,4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta -guttersnipe.i2p,kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq -hack8.i2p,un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq -hagen.i2p,e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q -heisenberg.i2p,jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq -heligoland.i2p,gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq -hidden.i2p,iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq -hiddenanswers.i2p,kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq -hiddenbooru.i2p,zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q -hiddenchan.i2p,6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa -hiddengate.i2p,rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq -home.duck.i2p,jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma -hopekiller.i2p,kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa -hotline.i2p,6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq -hq.postman.i2p,27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq -http.entropy.i2p,ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq -human.i2p,nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa -i2host.i2p,awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q -i2jump.i2p,633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa -i2p-bt.postman.i2p,jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla -i2p-epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa -i2p-javadocs.i2p,icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq -i2p-projekt.i2p,udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna -i2pbote.i2p,tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a -i2pbuggenie.i2p,bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q -i2pchan.i2p,tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq -i2pd.i2p,4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa -i2pdocs.str4d.i2p,yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq -i2peek-a-boo.i2p,qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa -i2pforum.i2p,tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda -i2pjump.i2p,2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka -i2plugins.i2p,bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a -i2pmetrics.i2p,v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a -i2pnews.i2p,tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq -i2podisy.i2p,3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq -i2push.i2p,mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq -i2pwiki.i2p,nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq -iamevil.i2p,au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja -icu812.i2p,bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva -id3nt.i2p,ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q -identiguy.i2p,3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva -ilcosmista.i2p,6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q -ilita.i2p,isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba -illuminati.i2p,syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla -imhotep.i2p,qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a -in.i2p,r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq -infosecurity.i2p,v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba -infoserver.i2p,jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q -inproxy.tino.i2p,ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma -inr.i2p,joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq -instantexchange.i2p,5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq -investigaciones.i2p,n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha -invisible-internet.i2p,jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq -io.i2p,tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q -irc.00.i2p,bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq -irc.arcturus.i2p,5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq -irc.baffled.i2p,5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq -irc.carambar.i2p,hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq -irc.cerapadus.i2p,e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq -irc.dg.i2p,fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq -irc.duck.i2p,chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq -irc.echelon.i2p,ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq -irc.freshcoffee.i2p,ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa -irc.i2p,l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq -irc.ilita.i2p,5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a -irc.ircbnc.i2p,4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa -irc.killyourtv.i2p,wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq -irc.nickster.i2p,dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a -irc.orz.i2p,7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq -irc.postman.i2p,mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq -irc.r4sas.i2p,hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la -ircssl.cerapadus.i2p,4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea -irongeeks.i2p,ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a -iscofsi.i2p,enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq -isotoxin.i2p,wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq -itemname.i2p,o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq -ivorytower.i2p,fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq -j.i2p,kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea -jabber-2.i2p,pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na -jabber.duck.i2p,rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq -jake.i2p,v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq -jar.i2p,2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq -jazzy.i2p,ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa -jdot.i2p,kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq -jhor.i2p,c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa -jikx.i2p,aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq -jisko.i2p,jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca -jmg.i2p,oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq -jnymo.i2p,nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda -jrandom.dev.i2p,htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq -jrandom.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja -jrrecology.i2p,qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq -jwebcache.i2p,xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa -k1773r.i2p,zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq -kaji.i2p,z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq -kaji2.i2p,4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a -keys.echelon.i2p,mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva -keys.i2p,6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba -keyserver.sigterm.i2p,isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga -killyourtv.i2p,aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda -knijka.i2p,knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa -knotwork.i2p,2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq -kohaar.i2p,qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q -krabs.i2p,3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca -kuroneko.i2p,wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq -kycklingar.i2p,gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva -lazyguy.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq -legion.i2p,5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq -legwork.i2p,cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a -lenta.i2p,nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra -libertor.i2p,7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq -library.i2p,brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a -lifebox.i2p,pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq -linuxagent.i2p,ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq -lists.i2p2.i2p,vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua -lm.i2p,yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q -lodikon.i2p,u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a -lolicatgirls.i2p,a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla -lolifox.i2p,7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca -longhorn.i2p,pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a -lp.i2p,jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq -lucky.i2p,wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa -luckypunk.i2p,y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka -lunokhod.i2p,3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa -m16.i2p,ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva -mac7.i2p,3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q -madman2003.i2p,a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq -magix.i2p,cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq -magnets.i2p,snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca -manas.i2p,6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba -manveru.i2p,pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq -marcos.i2p,vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq -marshmallow.i2p,svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q -marxists.i2p,lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq -mattermost.i2p,x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya -me.i2p,dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na -meeh.i2p,4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa -mesh.firerabbit.i2p,3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq -messageinabottle.i2p,avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a -metrics.i2p,z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq -mhatta.i2p,o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq -microbleu.i2p,mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa -microsoft.i2p,hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza -mindisl0st.i2p,u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a -mindspore.i2p,uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q -modulus.i2p,ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a -monerotools.i2p,5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q -monerujo.i2p,puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq -morph.i2p,iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa -mosbot.i2p,5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a -mosfet.i2p,s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q -moxonom.i2p,gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq -mp3.aum.i2p,n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq -mp3.tc.i2p,w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa -mpaa.i2p,m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya -mrbamboo.i2p,tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa -mrflibble.i2p,u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq -mrplod.i2p,fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq -mtn.i2p,xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq -mtn.i2p-projekt.i2p,f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa -mtn.i2p2.i2p,l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a -mtn.meeh.i2p,h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la -mudgaard.i2p,yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq -mush.zeit.i2p,dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha -music.i2p,akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia -mysterious.i2p,p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq -mywastedlife.i2p,ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq -nacl.i2p,bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia -nano.i2p,ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba -nassai.i2p,v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q -neodome.i2p,5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq -news-i2pn.i2p,wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca -news.neodome.i2p,trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq -news.underscore.i2p,rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q -newsbyte.i2p,gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq -nibble.i2p,jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa -nic.i2p,vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq -nickster.i2p,zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq -nickster2.i2p,eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq -nickyb.i2p,gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa -nightblade.i2p,p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha -ninja.i2p,q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya -nm.i2p,3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya -nntp.baffled.i2p,kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a -nntp.duck.i2p,gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q -nntp.fr.i2p,npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva -nntp.i2p,wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q -no.i2p,lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba -noname56.i2p,oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa -nop.i2p,ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca -normal.i2p,j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma -normanabcd.i2p,si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a -nothingburger.i2p,tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq -nothingspecial.i2p,wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga -novospice.i2p,ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq -nsa.i2p,nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga -nvspc.i2p,anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra -nxt-wallet.i2p,33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a -obmen.i2p,vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa -obscuratus.i2p,i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota -ogg.aum.i2p,wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q -ogg.baffled.i2p,tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq -ol.i2p,bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq -onboard.i2p,qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq -onelon.i2p,irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha -onhere.i2p,vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva -oniichan.i2p,nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq -onionforum.i2p,yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q -ooo.i2p,iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a -opal.i2p,li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa -open4you.i2p,ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a -opendiftracker.i2p,bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq -openforums.i2p,lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q -opentracker.dg2.i2p,w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa -orion.i2p,5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga -orz.i2p,oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq -os3.i2p,s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq -osiristomb.i2p,t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq -ot.knotwork.i2p,cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq -outproxy-tor.meeh.i2p,77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq -outproxy.h2ik.i2p,nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza -outproxyng.h2ik.i2p,v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq -overchan.oniichan.i2p,g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya -p4bl0.i2p,lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga -pants.i2p,xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq -papel.i2p,mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq -pasta-nojs.i2p,dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la -paste.crypthost.i2p,2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq -paste.i2p2.i2p,b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq -paste.r4sas.i2p,csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa -pastebin.i2p,mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa -pastethis.i2p,erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha -pdforge.i2p,wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq -perv.i2p,f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq -pgp.duck.i2p,wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha -pharos.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa -pharoz.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa -phonebooth.i2p,noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq -photo.i2p,fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq -piespy.i2p,vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a -pisekot.i2p,7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq -pizdabol.i2p,5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa -planet.i2p,y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq -plugins.i2p,wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia -polecat.i2p,het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq -politguy.i2p,6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq -pomoyka.i2p,omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q -pool.gostcoin.i2p,m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa -pop.mail.i2p,bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq -pop.postman.i2p,ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya -pravtor.i2p,2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq -pris.i2p,ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a -project-future.i2p,ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta -projectmayhem2012-086.i2p,ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq -protokol.i2p,f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq -proxynet.i2p,7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a -psi.i2p,avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a -psy.i2p,s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q -psyco.i2p,eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q -pt.hiddenanswers.i2p,o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a -ptm.i2p,7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa -ptt.i2p,q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha -pull.git.repo.i2p,3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q -push.git.repo.i2p,jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a -pycache.awup.i2p,w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra -r4sas.i2p,2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq -radio.r4sas.i2p,cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla -ragnarok.i2p,jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca -ransack.i2p,mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq -rasputin-sucks.i2p,fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq -rebel.i2p,nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq -red.i2p,fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa -redpanda.i2p,3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea -redzara.i2p,ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va -reefer.i2p,4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa -relatelist.i2p,utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq -repo.i2p,uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa -repo.r4sas.i2p,ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq -reseed.i2p,j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq -retrobbs-nntp.i2p,fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q -retrobbs.i2p,mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq -retrobbs2.i2p,ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q -revo-ua.i2p,hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq -riaa.i2p,lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa -rideronthestorm.i2p,xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq -romster.i2p,eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a -rootd.i2p,mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq -rospravosudie.i2p,z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q -rotten.i2p,j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq -rpi.i2p,56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq -rslight.i2p,bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq -rsync.thetower.i2p,w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa -ru.hiddenanswers.i2p,o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva -ru.i2p,m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja -rufurus.i2p,7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca -rus.i2p,gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga -ruslibgen.i2p,kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq -rutor.i2p,tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq -salt.i2p,6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq -sasquotch.i2p,p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q -schwarzwald.i2p,4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq -sciencebooks.i2p,ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq -scp.duck.i2p,ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda -search.i2p,nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q -secretchat.i2p,cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q -secure.thetinhat.i2p,4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala -seeker.i2p,ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq -seomon.i2p,5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q -septu.i2p,5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra -serien.i2p,3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda -ses.i2p,5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja -shiftfox.i2p,wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq -shoieq3.i2p,3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q -shoronil.i2p,7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa -short.i2p,z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba -sion.i2p,lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q -sirup.i2p,aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma -site.games.i2p,zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja -skank.i2p,qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q -slack.i2p,gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja -slacker.i2p,wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq -smeghead.i2p,ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja -smtp.mail.i2p,kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya -smtp.postman.i2p,jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q -socks1.tor.i2p,sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq -sonax.i2p,jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq -sponge.i2p,o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq -squid.i2p,r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq -squid2.i2p,hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila -sqz.i2p,3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq -ssh.i2p,xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq -stasher.i2p,6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa -stats.i2p,7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq -status.str4d.i2p,ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q -sto-man.i2p,rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa -str4d.i2p,wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa -stream.i2p,prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna -streams.darkrealm.i2p,ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq -striker.i2p,4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq -subrosa.i2p,g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq -subterra.i2p,vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq -sugadude.i2p,yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq -suicidal.i2p,yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq -sungo.i2p,h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q -surrender.adab.i2p,jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta -susi.i2p,qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq -syncline.i2p,5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra -syndie-project.i2p,xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq -syndie.echelon.i2p,vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta -syndie.i2p,7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq -syndiemedia.i2p,4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma -tabak.i2p,y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia -tahoeserve.i2p,yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa -tc.i2p,qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a -telegram.i2p,i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja -templar.i2p,zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q -terror.i2p,wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq -thebland.i2p,oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda -thebreton.i2p,woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq -thedarkside.i2p,fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca -theland.i2p,26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa -thetower.i2p,3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a -thornworld.i2p,vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva -tino.i2p,e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq -tinyurl.i2p,mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa -tome.i2p,qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq -tor-gw.meeh.i2p,ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza -tor-www-proxy.i2p,xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q -torapa.i2p,eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta -torrentfinder.i2p,mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq -torrfreedom.i2p,nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq -trac.i2p,kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca -trac.i2p2.i2p,i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa -tracker-fr.i2p,qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea -tracker.awup.i2p,dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq -tracker.crypthost.i2p,ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq -tracker.fr.i2p,rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q -tracker.i2p,lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q -tracker.lodikon.i2p,q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra -tracker.mastertracker.i2p,tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda -tracker.postman.i2p,jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq -tracker.psi.i2p,vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa -tracker.thebland.i2p,s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq -tracker.welterde.i2p,cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa -tracker2.postman.i2p,ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna -traditio.i2p,wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq -trevorreznik.i2p,wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma -true.i2p,pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq -trwcln.i2p,evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq -trypanom.i2p,tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q -ts.i2p,nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq -ttc.i2p,wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq -ttp.i2p,uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a -tumbach.i2p,u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq -tutorials.i2p,zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja -ugha.i2p,z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda -uk.i2p,vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a -underground.i2p,dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica -underscore.i2p,3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa -unqueued.i2p,3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq -up.i2p,25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q -update.dg.i2p,iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja -update.killyourtv.i2p,gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq -update.postman.i2p,u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq -utansans.i2p,u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda -v2mail.i2p,4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a -vadino.i2p,aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra -visibility.i2p,pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq -volatile.i2p,q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a -vpnbest.i2p,ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea -vudu.i2p,3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q -w.i2p,j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq -wa11ed.city.i2p,7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa -wahoo.i2p,vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa -wallet.gostcoin.i2p,reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda -wallsgetbombed.i2p,tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq -web.telegram.i2p,re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a -wiht.i2p,yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca -wiki.fr.i2p,lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq -wiki.ilita.i2p,r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a -wintermute.i2p,4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila -wspucktracker.i2p,ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq -www.aum.i2p,3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq -www.baffled.i2p,lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq -www.fr.i2p,rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea -www.i2p,ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va -www.i2p2.i2p,rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga -www.imule.i2p,657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq -www.infoserver.i2p,fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq -www.janonymous.i2p,vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq -www.mail.i2p,nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba -www.nntp.i2p,kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka -www.postman.i2p,rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq -www.syndie.i2p,vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva -www1.squid.i2p,vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa -xc.i2p,mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq -xeha.i2p,oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq -xilog.i2p,eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq -xmpp.crypthost.i2p,ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba -xmpp.rpi.i2p,3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca -xn--l2bl5aw.i2p,d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa -xolotl.i2p,rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq -xotc.i2p,gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq -z-lab.i2p,s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba -zab.i2p,n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq -zcash.i2p,zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q -zener.i2p,mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca -zerobin.i2p,3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq -zeroman.i2p,gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq -zeronet.i2p,fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna -znc.i2p,uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa -znc.str4d.i2p,ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq -zzz.i2p,ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq diff --git a/android/assets/certificates b/android/assets/certificates deleted file mode 120000 index 01b21e5d..00000000 --- a/android/assets/certificates +++ /dev/null @@ -1 +0,0 @@ -../../contrib/certificates \ No newline at end of file diff --git a/android/assets/i2pd.conf b/android/assets/i2pd.conf deleted file mode 100644 index 14254248..00000000 --- a/android/assets/i2pd.conf +++ /dev/null @@ -1,92 +0,0 @@ -## Configuration file for a typical i2pd user -## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/ -## for more options you can use in this file. - -#logfile = /sdcard/i2pd/i2pd.log -loglevel = none -#tunnelsdir = /sdcard/i2pd/tunnels.d - -# host = 1.2.3.4 -# port = 4567 - -ipv4 = true -ipv6 = false - -# ntcp = true -# ntcpproxy = http://127.0.0.1:8118 -# ssu = true - -bandwidth = L -# share = 100 - -# notransit = true -# floodfill = true - -[ntcp2] -enabled = true - -[http] -enabled = true -address = 127.0.0.1 -port = 7070 -# auth = true -# user = i2pd -# pass = changeme - -[httpproxy] -enabled = true -address = 127.0.0.1 -port = 4444 -inbound.length = 1 -inbound.quantity = 5 -outbound.length = 1 -outbound.quantity = 5 -signaturetype=7 -i2cp.leaseSetType=3 -i2cp.leaseSetEncType=0,4 -keys = proxy-keys.dat -# addresshelper = true -# outproxy = http://false.i2p -## httpproxy section also accepts I2CP parameters, like "inbound.length" etc. - -[socksproxy] -enabled = true -address = 127.0.0.1 -port = 4447 -keys = proxy-keys.dat -# outproxy.enabled = false -# outproxy = 127.0.0.1 -# outproxyport = 9050 -## socksproxy section also accepts I2CP parameters, like "inbound.length" etc. - -[sam] -enabled = false -# address = 127.0.0.1 -# port = 7656 - -[precomputation] -elgamal = true - -[upnp] -enabled = true -# name = I2Pd - -[reseed] -verify = true -## Path to local reseed data file (.su3) for manual reseeding -# file = /path/to/i2pseeds.su3 -## or HTTPS URL to reseed from -# file = https://legit-website.com/i2pseeds.su3 -## Path to local ZIP file or HTTPS URL to reseed from -# zipfile = /path/to/netDb.zip -## If you run i2pd behind a proxy server, set proxy server for reseeding here -## Should be http://address:port or socks://address:port -# proxy = http://127.0.0.1:8118 -## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default -# threshold = 25 - -[limits] -transittunnels = 50 - -[persist] -profiles = false diff --git a/android/assets/subscriptions.txt b/android/assets/subscriptions.txt deleted file mode 100644 index 8f4afb03..00000000 --- a/android/assets/subscriptions.txt +++ /dev/null @@ -1,3 +0,0 @@ -http://inr.i2p/export/alive-hosts.txt -http://stats.i2p/cgi-bin/newhosts.txt -http://i2p-projekt.i2p/hosts.txt diff --git a/android/assets/tunnels.conf b/android/assets/tunnels.conf deleted file mode 100644 index c39a0220..00000000 --- a/android/assets/tunnels.conf +++ /dev/null @@ -1,33 +0,0 @@ -#[IRC-IRC2P] -#type = client -#address = 127.0.0.1 -#port = 6668 -#destination = irc.postman.i2p -#destinationport = 6667 -#keys = irc-keys.dat - -#[IRC-ILITA] -#type = client -#address = 127.0.0.1 -#port = 6669 -#destination = irc.ilita.i2p -#destinationport = 6667 -#keys = irc-keys.dat - -#[SMTP] -#type = client -#address = 127.0.0.1 -#port = 7659 -#destination = smtp.postman.i2p -#destinationport = 25 -#keys = smtp-keys.dat - -#[POP3] -#type = client -#address = 127.0.0.1 -#port = 7660 -#destination = pop.postman.i2p -#destinationport = 110 -#keys = pop3-keys.dat - -# see more examples at https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/ diff --git a/android/assets/tunnels.d b/android/assets/tunnels.d deleted file mode 120000 index ff262031..00000000 --- a/android/assets/tunnels.d +++ /dev/null @@ -1 +0,0 @@ -../../contrib/tunnels.d \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 0c208c91..00000000 --- a/android/build.gradle +++ /dev/null @@ -1,105 +0,0 @@ -buildscript { - repositories { - mavenCentral() - jcenter() - google() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' - } -} - -apply plugin: 'com.android.application' - -repositories { - jcenter() - maven { - url 'https://maven.google.com' - } - google() -} - -dependencies { - implementation 'androidx.core:core:1.0.2' - implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' -} - -android { - compileSdkVersion 29 - buildToolsVersion "28.0.3" - defaultConfig { - applicationId "org.purplei2p.i2pd" - targetSdkVersion 29 - minSdkVersion 14 - versionCode 2350 - versionName "2.35.0" - setProperty("archivesBaseName", archivesBaseName + "-" + versionName) - ndk { - abiFilters 'armeabi-v7a' - abiFilters 'x86' - //abiFilters 'arm64-v8a' - //abiFilters 'x86_64' - } - externalNativeBuild { - ndkBuild { - arguments "-j3" - } - } - } - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['src'] - res.srcDirs = ['res'] - jniLibs.srcDirs = ['libs'] - assets.srcDirs = ['assets'] - } - } - splits { - abi { - // change that to true if you need splitted apk - enable true - reset() - //include "armeabi-v7a", "arm64-v8a", "x86", "x86_64" - include "armeabi-v7a", "x86" - universalApk true - } - } - signingConfigs { - orignal { - storeFile file("i2pdapk.jks") - storePassword "android" - keyAlias "i2pdapk" - keyPassword "android" - } - } - buildTypes { - release { - minifyEnabled false - signingConfig signingConfigs.orignal - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' - } - } - externalNativeBuild { - ndkBuild { - path './jni/Android.mk' - } - } - compileOptions { - sourceCompatibility = '1.8' - targetCompatibility = '1.8' - } -} - -ext.abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'arm64-v8a': 3, 'x86_64': 4] -import com.android.build.OutputFile - -android.applicationVariants.all { variant -> - variant.outputs.each { output -> - def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) - - if (baseAbiVersionCode != null) { - output.versionCodeOverride = baseAbiVersionCode + variant.versionCode - } - } -} diff --git a/android/build.xml b/android/build.xml deleted file mode 100644 index ed8196c3..00000000 --- a/android/build.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 6678daaf..00000000 --- a/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -android.enableJetifier=true -android.useAndroidX=true -org.gradle.parallel=true \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f6b961fd5a86aa5fbfe90f707c3138408be7c718..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54329 zcmagFV|ZrKvM!pAZQHhO+qP}9lTNj?q^^Y^VFp)SH8qbSJ)2BQ2giqr}t zFG7D6)c?v~^Z#E_K}1nTQbJ9gQ9<%vVRAxVj)8FwL5_iTdUB>&m3fhE=kRWl;g`&m z!W5kh{WsV%fO*%je&j+Lv4xxK~zsEYQls$Q-p&dwID|A)!7uWtJF-=Tm1{V@#x*+kUI$=%KUuf2ka zjiZ{oiL1MXE2EjciJM!jrjFNwCh`~hL>iemrqwqnX?T*MX;U>>8yRcZb{Oy+VKZos zLiFKYPw=LcaaQt8tj=eoo3-@bG_342HQ%?jpgAE?KCLEHC+DmjxAfJ%Og^$dpC8Xw zAcp-)tfJm}BPNq_+6m4gBgBm3+CvmL>4|$2N$^Bz7W(}fz1?U-u;nE`+9`KCLuqg} zwNstNM!J4Uw|78&Y9~9>MLf56to!@qGkJw5Thx%zkzj%Ek9Nn1QA@8NBXbwyWC>9H z#EPwjMNYPigE>*Ofz)HfTF&%PFj$U6mCe-AFw$U%-L?~-+nSXHHKkdgC5KJRTF}`G zE_HNdrE}S0zf4j{r_f-V2imSqW?}3w-4=f@o@-q+cZgaAbZ((hn))@|eWWhcT2pLpTpL!;_5*vM=sRL8 zqU##{U#lJKuyqW^X$ETU5ETeEVzhU|1m1750#f}38_5N9)B_2|v@1hUu=Kt7-@dhA zq_`OMgW01n`%1dB*}C)qxC8q;?zPeF_r;>}%JYmlER_1CUbKa07+=TV45~symC*g8 zW-8(gag#cAOuM0B1xG8eTp5HGVLE}+gYTmK=`XVVV*U!>H`~j4+ROIQ+NkN$LY>h4 zqpwdeE_@AX@PL};e5vTn`Ro(EjHVf$;^oiA%@IBQq>R7_D>m2D4OwwEepkg}R_k*M zM-o;+P27087eb+%*+6vWFCo9UEGw>t&WI17Pe7QVuoAoGHdJ(TEQNlJOqnjZ8adCb zI`}op16D@v7UOEo%8E-~m?c8FL1utPYlg@m$q@q7%mQ4?OK1h%ODjTjFvqd!C z-PI?8qX8{a@6d&Lb_X+hKxCImb*3GFemm?W_du5_&EqRq!+H?5#xiX#w$eLti-?E$;Dhu`{R(o>LzM4CjO>ICf z&DMfES#FW7npnbcuqREgjPQM#gs6h>`av_oEWwOJZ2i2|D|0~pYd#WazE2Bbsa}X@ zu;(9fi~%!VcjK6)?_wMAW-YXJAR{QHxrD5g(ou9mR6LPSA4BRG1QSZT6A?kelP_g- zH(JQjLc!`H4N=oLw=f3{+WmPA*s8QEeEUf6Vg}@!xwnsnR0bl~^2GSa5vb!Yl&4!> zWb|KQUsC$lT=3A|7vM9+d;mq=@L%uWKwXiO9}a~gP4s_4Yohc!fKEgV7WbVo>2ITbE*i`a|V!^p@~^<={#?Gz57 zyPWeM2@p>D*FW#W5Q`1`#5NW62XduP1XNO(bhg&cX`-LYZa|m-**bu|>}S;3)eP8_ zpNTnTfm8 ze+7wDH3KJ95p)5tlwk`S7mbD`SqHnYD*6`;gpp8VdHDz%RR_~I_Ar>5)vE-Pgu7^Y z|9Px+>pi3!DV%E%4N;ii0U3VBd2ZJNUY1YC^-e+{DYq+l@cGtmu(H#Oh%ibUBOd?C z{y5jW3v=0eV0r@qMLgv1JjZC|cZ9l9Q)k1lLgm))UR@#FrJd>w^`+iy$c9F@ic-|q zVHe@S2UAnc5VY_U4253QJxm&Ip!XKP8WNcnx9^cQ;KH6PlW8%pSihSH2(@{2m_o+m zr((MvBja2ctg0d0&U5XTD;5?d?h%JcRJp{_1BQW1xu&BrA3(a4Fh9hon-ly$pyeHq zG&;6q?m%NJ36K1Sq_=fdP(4f{Hop;_G_(i?sPzvB zDM}>*(uOsY0I1j^{$yn3#U(;B*g4cy$-1DTOkh3P!LQ;lJlP%jY8}Nya=h8$XD~%Y zbV&HJ%eCD9nui-0cw!+n`V~p6VCRqh5fRX z8`GbdZ@73r7~myQLBW%db;+BI?c-a>Y)m-FW~M=1^|<21_Sh9RT3iGbO{o-hpN%d6 z7%++#WekoBOP^d0$$|5npPe>u3PLvX_gjH2x(?{&z{jJ2tAOWTznPxv-pAv<*V7r$ z6&glt>7CAClWz6FEi3bToz-soY^{ScrjwVPV51=>n->c(NJngMj6TyHty`bfkF1hc zkJS%A@cL~QV0-aK4>Id!9dh7>0IV;1J9(myDO+gv76L3NLMUm9XyPauvNu$S<)-|F zZS}(kK_WnB)Cl`U?jsdYfAV4nrgzIF@+%1U8$poW&h^c6>kCx3;||fS1_7JvQT~CV zQ8Js+!p)3oW>Df(-}uqC`Tcd%E7GdJ0p}kYj5j8NKMp(KUs9u7?jQ94C)}0rba($~ zqyBx$(1ae^HEDG`Zc@-rXk1cqc7v0wibOR4qpgRDt#>-*8N3P;uKV0CgJE2SP>#8h z=+;i_CGlv+B^+$5a}SicVaSeaNn29K`C&=}`=#Nj&WJP9Xhz4mVa<+yP6hkrq1vo= z1rX4qg8dc4pmEvq%NAkpMK>mf2g?tg_1k2%v}<3`$6~Wlq@ItJ*PhHPoEh1Yi>v57 z4k0JMO)*=S`tKvR5gb-(VTEo>5Y>DZJZzgR+j6{Y`kd|jCVrg!>2hVjz({kZR z`dLlKhoqT!aI8=S+fVp(5*Dn6RrbpyO~0+?fy;bm$0jmTN|t5i6rxqr4=O}dY+ROd zo9Et|x}!u*xi~>-y>!M^+f&jc;IAsGiM_^}+4|pHRn{LThFFpD{bZ|TA*wcGm}XV^ zr*C6~@^5X-*R%FrHIgo-hJTBcyQ|3QEj+cSqp#>&t`ZzB?cXM6S(lRQw$I2?m5=wd z78ki`R?%;o%VUhXH?Z#(uwAn9$m`npJ=cA+lHGk@T7qq_M6Zoy1Lm9E0UUysN)I_x zW__OAqvku^>`J&CB=ie@yNWsaFmem}#L3T(x?a`oZ+$;3O-icj2(5z72Hnj=9Z0w% z<2#q-R=>hig*(t0^v)eGq2DHC%GymE-_j1WwBVGoU=GORGjtaqr0BNigOCqyt;O(S zKG+DoBsZU~okF<7ahjS}bzwXxbAxFfQAk&O@>LsZMsZ`?N?|CDWM(vOm%B3CBPC3o z%2t@%H$fwur}SSnckUm0-k)mOtht`?nwsDz=2#v=RBPGg39i#%odKq{K^;bTD!6A9 zskz$}t)sU^=a#jLZP@I=bPo?f-L}wpMs{Tc!m7-bi!Ldqj3EA~V;4(dltJmTXqH0r z%HAWKGutEc9vOo3P6Q;JdC^YTnby->VZ6&X8f{obffZ??1(cm&L2h7q)*w**+sE6dG*;(H|_Q!WxU{g)CeoT z(KY&bv!Usc|m+Fqfmk;h&RNF|LWuNZ!+DdX*L=s-=_iH=@i` z?Z+Okq^cFO4}_n|G*!)Wl_i%qiMBaH8(WuXtgI7EO=M>=i_+;MDjf3aY~6S9w0K zUuDO7O5Ta6+k40~xh~)D{=L&?Y0?c$s9cw*Ufe18)zzk%#ZY>Tr^|e%8KPb0ht`b( zuP@8#Ox@nQIqz9}AbW0RzE`Cf>39bOWz5N3qzS}ocxI=o$W|(nD~@EhW13Rj5nAp; zu2obEJa=kGC*#3=MkdkWy_%RKcN=?g$7!AZ8vBYKr$ePY(8aIQ&yRPlQ=mudv#q$q z4%WzAx=B{i)UdLFx4os?rZp6poShD7Vc&mSD@RdBJ=_m^&OlkEE1DFU@csgKcBifJ zz4N7+XEJhYzzO=86 z#%eBQZ$Nsf2+X0XPHUNmg#(sNt^NW1Y0|M(${e<0kW6f2q5M!2YE|hSEQ*X-%qo(V zHaFwyGZ0on=I{=fhe<=zo{=Og-_(to3?cvL4m6PymtNsdDINsBh8m>a%!5o3s(en) z=1I z6O+YNertC|OFNqd6P=$gMyvmfa`w~p9*gKDESFqNBy(~Zw3TFDYh}$iudn)9HxPBi zdokK@o~nu?%imcURr5Y~?6oo_JBe}t|pU5qjai|#JDyG=i^V~7+a{dEnO<(y>ahND#_X_fcEBNiZ)uc&%1HVtx8Ts z*H_Btvx^IhkfOB#{szN*n6;y05A>3eARDXslaE>tnLa>+`V&cgho?ED+&vv5KJszf zG4@G;7i;4_bVvZ>!mli3j7~tPgybF5|J6=Lt`u$D%X0l}#iY9nOXH@(%FFJLtzb%p zzHfABnSs;v-9(&nzbZytLiqqDIWzn>JQDk#JULcE5CyPq_m#4QV!}3421haQ+LcfO*>r;rg6K|r#5Sh|y@h1ao%Cl)t*u`4 zMTP!deC?aL7uTxm5^nUv#q2vS-5QbBKP|drbDXS%erB>fYM84Kpk^au99-BQBZR z7CDynflrIAi&ahza+kUryju5LR_}-Z27g)jqOc(!Lx9y)e z{cYc&_r947s9pteaa4}dc|!$$N9+M38sUr7h(%@Ehq`4HJtTpA>B8CLNO__@%(F5d z`SmX5jbux6i#qc}xOhumzbAELh*Mfr2SW99=WNOZRZgoCU4A2|4i|ZVFQt6qEhH#B zK_9G;&h*LO6tB`5dXRSBF0hq0tk{2q__aCKXYkP#9n^)@cq}`&Lo)1KM{W+>5mSed zKp~=}$p7>~nK@va`vN{mYzWN1(tE=u2BZhga5(VtPKk(*TvE&zmn5vSbjo zZLVobTl%;t@6;4SsZ>5+U-XEGUZGG;+~|V(pE&qqrp_f~{_1h@5ZrNETqe{bt9ioZ z#Qn~gWCH!t#Ha^n&fT2?{`}D@s4?9kXj;E;lWV9Zw8_4yM0Qg-6YSsKgvQ*fF{#Pq z{=(nyV>#*`RloBVCs;Lp*R1PBIQOY=EK4CQa*BD0MsYcg=opP?8;xYQDSAJBeJpw5 zPBc_Ft9?;<0?pBhCmOtWU*pN*;CkjJ_}qVic`}V@$TwFi15!mF1*m2wVX+>5p%(+R zQ~JUW*zWkalde{90@2v+oVlkxOZFihE&ZJ){c?hX3L2@R7jk*xjYtHi=}qb+4B(XJ z$gYcNudR~4Kz_WRq8eS((>ALWCO)&R-MXE+YxDn9V#X{_H@j616<|P(8h(7z?q*r+ zmpqR#7+g$cT@e&(%_|ipI&A%9+47%30TLY(yuf&*knx1wNx|%*H^;YB%ftt%5>QM= z^i;*6_KTSRzQm%qz*>cK&EISvF^ovbS4|R%)zKhTH_2K>jP3mBGn5{95&G9^a#4|K zv+!>fIsR8z{^x4)FIr*cYT@Q4Z{y}};rLHL+atCgHbfX*;+k&37DIgENn&=k(*lKD zG;uL-KAdLn*JQ?@r6Q!0V$xXP=J2i~;_+i3|F;_En;oAMG|I-RX#FwnmU&G}w`7R{ z788CrR-g1DW4h_`&$Z`ctN~{A)Hv_-Bl!%+pfif8wN32rMD zJDs$eVWBYQx1&2sCdB0!vU5~uf)=vy*{}t{2VBpcz<+~h0wb7F3?V^44*&83Z2#F` z32!rd4>uc63rQP$3lTH3zb-47IGR}f)8kZ4JvX#toIpXH`L%NnPDE~$QI1)0)|HS4 zVcITo$$oWWwCN@E-5h>N?Hua!N9CYb6f8vTFd>h3q5Jg-lCI6y%vu{Z_Uf z$MU{{^o~;nD_@m2|E{J)q;|BK7rx%`m``+OqZAqAVj-Dy+pD4-S3xK?($>wn5bi90CFAQ+ACd;&m6DQB8_o zjAq^=eUYc1o{#+p+ zn;K<)Pn*4u742P!;H^E3^Qu%2dM{2slouc$AN_3V^M7H_KY3H)#n7qd5_p~Za7zAj|s9{l)RdbV9e||_67`#Tu*c<8!I=zb@ z(MSvQ9;Wrkq6d)!9afh+G`!f$Ip!F<4ADdc*OY-y7BZMsau%y?EN6*hW4mOF%Q~bw z2==Z3^~?q<1GTeS>xGN-?CHZ7a#M4kDL zQxQr~1ZMzCSKFK5+32C%+C1kE#(2L=15AR!er7GKbp?Xd1qkkGipx5Q~FI-6zt< z*PTpeVI)Ngnnyaz5noIIgNZtb4bQdKG{Bs~&tf)?nM$a;7>r36djllw%hQxeCXeW^ z(i6@TEIuxD<2ulwLTt|&gZP%Ei+l!(%p5Yij6U(H#HMkqM8U$@OKB|5@vUiuY^d6X zW}fP3;Kps6051OEO(|JzmVU6SX(8q>*yf*x5QoxDK={PH^F?!VCzES_Qs>()_y|jg6LJlJWp;L zKM*g5DK7>W_*uv}{0WUB0>MHZ#oJZmO!b3MjEc}VhsLD~;E-qNNd?x7Q6~v zR=0$u>Zc2Xr}>x_5$-s#l!oz6I>W?lw;m9Ae{Tf9eMX;TI-Wf_mZ6sVrMnY#F}cDd z%CV*}fDsXUF7Vbw>PuDaGhu631+3|{xp<@Kl|%WxU+vuLlcrklMC!Aq+7n~I3cmQ! z`e3cA!XUEGdEPSu``&lZEKD1IKO(-VGvcnSc153m(i!8ohi`)N2n>U_BemYJ`uY>8B*Epj!oXRLV}XK}>D*^DHQ7?NY*&LJ9VSo`Ogi9J zGa;clWI8vIQqkngv2>xKd91K>?0`Sw;E&TMg&6dcd20|FcTsnUT7Yn{oI5V4@Ow~m zz#k~8TM!A9L7T!|colrC0P2WKZW7PNj_X4MfESbt<-soq*0LzShZ}fyUx!(xIIDwx zRHt^_GAWe0-Vm~bDZ(}XG%E+`XhKpPlMBo*5q_z$BGxYef8O!ToS8aT8pmjbPq)nV z%x*PF5ZuSHRJqJ!`5<4xC*xb2vC?7u1iljB_*iUGl6+yPyjn?F?GOF2_KW&gOkJ?w z3e^qc-te;zez`H$rsUCE0<@7PKGW?7sT1SPYWId|FJ8H`uEdNu4YJjre`8F*D}6Wh z|FQ`xf7yiphHIAkU&OYCn}w^ilY@o4larl?^M7&8YI;hzBIsX|i3UrLsx{QDKwCX< zy;a>yjfJ6!sz`NcVi+a!Fqk^VE^{6G53L?@Tif|j!3QZ0fk9QeUq8CWI;OmO-Hs+F zuZ4sHLA3{}LR2Qlyo+{d@?;`tpp6YB^BMoJt?&MHFY!JQwoa0nTSD+#Ku^4b{5SZVFwU9<~APYbaLO zu~Z)nS#dxI-5lmS-Bnw!(u15by(80LlC@|ynj{TzW)XcspC*}z0~8VRZq>#Z49G`I zgl|C#H&=}n-ajxfo{=pxPV(L*7g}gHET9b*s=cGV7VFa<;Htgjk>KyW@S!|z`lR1( zGSYkEl&@-bZ*d2WQ~hw3NpP=YNHF^XC{TMG$Gn+{b6pZn+5=<()>C!N^jncl0w6BJ zdHdnmSEGK5BlMeZD!v4t5m7ct7{k~$1Ie3GLFoHjAH*b?++s<|=yTF+^I&jT#zuMx z)MLhU+;LFk8bse|_{j+d*a=&cm2}M?*arjBPnfPgLwv)86D$6L zLJ0wPul7IenMvVAK$z^q5<^!)7aI|<&GGEbOr=E;UmGOIa}yO~EIr5xWU_(ol$&fa zR5E(2vB?S3EvJglTXdU#@qfDbCYs#82Yo^aZN6`{Ex#M)easBTe_J8utXu(fY1j|R z9o(sQbj$bKU{IjyhosYahY{63>}$9_+hWxB3j}VQkJ@2$D@vpeRSldU?&7I;qd2MF zSYmJ>zA(@N_iK}m*AMPIJG#Y&1KR)6`LJ83qg~`Do3v^B0>fU&wUx(qefuTgzFED{sJ65!iw{F2}1fQ3= ziFIP{kezQxmlx-!yo+sC4PEtG#K=5VM9YIN0z9~c4XTX?*4e@m;hFM!zVo>A`#566 z>f&3g94lJ{r)QJ5m7Xe3SLau_lOpL;A($wsjHR`;xTXgIiZ#o&vt~ zGR6KdU$FFbLfZCC3AEu$b`tj!9XgOGLSV=QPIYW zjI!hSP#?8pn0@ezuenOzoka8!8~jXTbiJ6+ZuItsWW03uzASFyn*zV2kIgPFR$Yzm zE<$cZlF>R8?Nr2_i?KiripBc+TGgJvG@vRTY2o?(_Di}D30!k&CT`>+7ry2!!iC*X z<@=U0_C#16=PN7bB39w+zPwDOHX}h20Ap);dx}kjXX0-QkRk=cr};GYsjSvyLZa-t zzHONWddi*)RDUH@RTAsGB_#&O+QJaaL+H<<9LLSE+nB@eGF1fALwjVOl8X_sdOYme z0lk!X=S(@25=TZHR7LlPp}fY~yNeThMIjD}pd9+q=j<_inh0$>mIzWVY+Z9p<{D^#0Xk+b_@eNSiR8;KzSZ#7lUsk~NGMcB8C2c=m2l5paHPq`q{S(kdA7Z1a zyfk2Y;w?^t`?@yC5Pz9&pzo}Hc#}mLgDmhKV|PJ3lKOY(Km@Fi2AV~CuET*YfUi}u zfInZnqDX(<#vaS<^fszuR=l)AbqG{}9{rnyx?PbZz3Pyu!eSJK`uwkJU!ORQXy4x83r!PNgOyD33}}L=>xX_93l6njNTuqL8J{l%*3FVn3MG4&Fv*`lBXZ z?=;kn6HTT^#SrPX-N)4EZiIZI!0ByXTWy;;J-Tht{jq1mjh`DSy7yGjHxIaY%*sTx zuy9#9CqE#qi>1misx=KRWm=qx4rk|}vd+LMY3M`ow8)}m$3Ggv&)Ri*ON+}<^P%T5 z_7JPVPfdM=Pv-oH<tecoE}(0O7|YZc*d8`Uv_M*3Rzv7$yZnJE6N_W=AQ3_BgU_TjA_T?a)U1csCmJ&YqMp-lJe`y6>N zt++Bi;ZMOD%%1c&-Q;bKsYg!SmS^#J@8UFY|G3!rtyaTFb!5@e(@l?1t(87ln8rG? z--$1)YC~vWnXiW3GXm`FNSyzu!m$qT=Eldf$sMl#PEfGmzQs^oUd=GIQfj(X=}dw+ zT*oa0*oS%@cLgvB&PKIQ=Ok?>x#c#dC#sQifgMwtAG^l3D9nIg(Zqi;D%807TtUUCL3_;kjyte#cAg?S%e4S2W>9^A(uy8Ss0Tc++ZTjJw1 z&Em2g!3lo@LlDyri(P^I8BPpn$RE7n*q9Q-c^>rfOMM6Pd5671I=ZBjAvpj8oIi$! zl0exNl(>NIiQpX~FRS9UgK|0l#s@#)p4?^?XAz}Gjb1?4Qe4?j&cL$C8u}n)?A@YC zfmbSM`Hl5pQFwv$CQBF=_$Sq zxsV?BHI5bGZTk?B6B&KLdIN-40S426X3j_|ceLla*M3}3gx3(_7MVY1++4mzhH#7# zD>2gTHy*%i$~}mqc#gK83288SKp@y3wz1L_e8fF$Rb}ex+`(h)j}%~Ld^3DUZkgez zOUNy^%>>HHE|-y$V@B}-M|_{h!vXpk01xaD%{l{oQ|~+^>rR*rv9iQen5t?{BHg|% zR`;S|KtUb!X<22RTBA4AAUM6#M?=w5VY-hEV)b`!y1^mPNEoy2K)a>OyA?Q~Q*&(O zRzQI~y_W=IPi?-OJX*&&8dvY0zWM2%yXdFI!D-n@6FsG)pEYdJbuA`g4yy;qrgR?G z8Mj7gv1oiWq)+_$GqqQ$(ZM@#|0j7})=#$S&hZwdoijFI4aCFLVI3tMH5fLreZ;KD zqA`)0l~D2tuIBYOy+LGw&hJ5OyE+@cnZ0L5+;yo2pIMdt@4$r^5Y!x7nHs{@>|W(MzJjATyWGNwZ^4j+EPU0RpAl-oTM@u{lx*i0^yyWPfHt6QwPvYpk9xFMWfBFt!+Gu6TlAmr zeQ#PX71vzN*_-xh&__N`IXv6`>CgV#eA_%e@7wjgkj8jlKzO~Ic6g$cT`^W{R{606 zCDP~+NVZ6DMO$jhL~#+!g*$T!XW63#(ngDn#Qwy71yj^gazS{e;3jGRM0HedGD@pt z?(ln3pCUA(ekqAvvnKy0G@?-|-dh=eS%4Civ&c}s%wF@0K5Bltaq^2Os1n6Z3%?-Q zAlC4goQ&vK6TpgtzkHVt*1!tBYt-`|5HLV1V7*#45Vb+GACuU+QB&hZ=N_flPy0TY zR^HIrdskB#<$aU;HY(K{a3(OQa$0<9qH(oa)lg@Uf>M5g2W0U5 zk!JSlhrw8quBx9A>RJ6}=;W&wt@2E$7J=9SVHsdC?K(L(KACb#z)@C$xXD8^!7|uv zZh$6fkq)aoD}^79VqdJ!Nz-8$IrU(_-&^cHBI;4 z^$B+1aPe|LG)C55LjP;jab{dTf$0~xbXS9!!QdcmDYLbL^jvxu2y*qnx2%jbL%rB z{aP85qBJe#(&O~Prk%IJARcdEypZ)vah%ZZ%;Zk{eW(U)Bx7VlzgOi8)x z`rh4l`@l_Ada7z&yUK>ZF;i6YLGwI*Sg#Fk#Qr0Jg&VLax(nNN$u-XJ5=MsP3|(lEdIOJ7|(x3iY;ea)5#BW*mDV%^=8qOeYO&gIdJVuLLN3cFaN=xZtFB=b zH{l)PZl_j^u+qx@89}gAQW7ofb+k)QwX=aegihossZq*+@PlCpb$rpp>Cbk9UJO<~ zDjlXQ_Ig#W0zdD3&*ei(FwlN#3b%FSR%&M^ywF@Fr>d~do@-kIS$e%wkIVfJ|Ohh=zc zF&Rnic^|>@R%v?@jO}a9;nY3Qrg_!xC=ZWUcYiA5R+|2nsM*$+c$TOs6pm!}Z}dfM zGeBhMGWw3$6KZXav^>YNA=r6Es>p<6HRYcZY)z{>yasbC81A*G-le8~QoV;rtKnkx z;+os8BvEe?0A6W*a#dOudsv3aWs?d% z0oNngyVMjavLjtjiG`!007#?62ClTqqU$@kIY`=x^$2e>iqIy1>o|@Tw@)P)B8_1$r#6>DB_5 zmaOaoE~^9TolgDgooKFuEFB#klSF%9-~d2~_|kQ0Y{Ek=HH5yq9s zDq#1S551c`kSiWPZbweN^A4kWiP#Qg6er1}HcKv{fxb1*BULboD0fwfaNM_<55>qM zETZ8TJDO4V)=aPp_eQjX%||Ud<>wkIzvDlpNjqW>I}W!-j7M^TNe5JIFh#-}zAV!$ICOju8Kx)N z0vLtzDdy*rQN!7r>Xz7rLw8J-(GzQlYYVH$WK#F`i_i^qVlzTNAh>gBWKV@XC$T-` z3|kj#iCquDhiO7NKum07i|<-NuVsX}Q}mIP$jBJDMfUiaWR3c|F_kWBMw0_Sr|6h4 zk`_r5=0&rCR^*tOy$A8K;@|NqwncjZ>Y-75vlpxq%Cl3EgH`}^^~=u zoll6xxY@a>0f%Ddpi;=cY}fyG!K2N-dEyXXmUP5u){4VnyS^T4?pjN@Ot4zjL(Puw z_U#wMH2Z#8Pts{olG5Dy0tZj;N@;fHheu>YKYQU=4Bk|wcD9MbA`3O4bj$hNRHwzb zSLcG0SLV%zywdbuwl(^E_!@&)TdXge4O{MRWk2RKOt@!8E{$BU-AH(@4{gxs=YAz9LIob|Hzto0}9cWoz6Tp2x0&xi#$ zHh$dwO&UCR1Ob2w00-2eG7d4=cN(Y>0R#$q8?||q@iTi+7-w-xR%uMr&StFIthC<# zvK(aPduwuNB}oJUV8+Zl)%cnfsHI%4`;x6XW^UF^e4s3Z@S<&EV8?56Wya;HNs0E> z`$0dgRdiUz9RO9Au3RmYq>K#G=X%*_dUbSJHP`lSfBaN8t-~@F>)BL1RT*9I851A3 z<-+Gb#_QRX>~av#Ni<#zLswtu-c6{jGHR>wflhKLzC4P@b%8&~u)fosoNjk4r#GvC zlU#UU9&0Hv;d%g72Wq?Ym<&&vtA3AB##L}=ZjiTR4hh7J)e>ei} zt*u+>h%MwN`%3}b4wYpV=QwbY!jwfIj#{me)TDOG`?tI!%l=AwL2G@9I~}?_dA5g6 zCKgK(;6Q0&P&K21Tx~k=o6jwV{dI_G+Ba*Zts|Tl6q1zeC?iYJTb{hel*x>^wb|2RkHkU$!+S4OU4ZOKPZjV>9OVsqNnv5jK8TRAE$A&^yRwK zj-MJ3Pl?)KA~fq#*K~W0l4$0=8GRx^9+?w z!QT8*-)w|S^B0)ZeY5gZPI2G(QtQf?DjuK(s^$rMA!C%P22vynZY4SuOE=wX2f8$R z)A}mzJi4WJnZ`!bHG1=$lwaxm!GOnRbR15F$nRC-M*H<*VfF|pQw(;tbSfp({>9^5 zw_M1-SJ9eGF~m(0dvp*P8uaA0Yw+EkP-SWqu zqal$hK8SmM7#Mrs0@OD+%_J%H*bMyZiWAZdsIBj#lkZ!l2c&IpLu(5^T0Ge5PHzR} zn;TXs$+IQ_&;O~u=Jz+XE0wbOy`=6>m9JVG} zJ~Kp1e5m?K3x@@>!D)piw^eMIHjD4RebtR`|IlckplP1;r21wTi8v((KqNqn%2CB< zifaQc&T}*M&0i|LW^LgdjIaX|o~I$`owHolRqeH_CFrqCUCleN130&vH}dK|^kC>) z-r2P~mApHotL4dRX$25lIcRh_*kJaxi^%ZN5-GAAMOxfB!6flLPY-p&QzL9TE%ho( zRwftE3sy5<*^)qYzKkL|rE>n@hyr;xPqncY6QJ8125!MWr`UCWuC~A#G1AqF1@V$kv>@NBvN&2ygy*{QvxolkRRb%Ui zsmKROR%{*g*WjUUod@@cS^4eF^}yQ1>;WlGwOli z+Y$(8I`0(^d|w>{eaf!_BBM;NpCoeem2>J}82*!em=}}ymoXk>QEfJ>G(3LNA2-46 z5PGvjr)Xh9>aSe>vEzM*>xp{tJyZox1ZRl}QjcvX2TEgNc^(_-hir@Es>NySoa1g^ zFow_twnHdx(j?Q_3q51t3XI7YlJ4_q&(0#)&a+RUy{IcBq?)eaWo*=H2UUVIqtp&lW9JTJiP&u zw8+4vo~_IJXZIJb_U^&=GI1nSD%e;P!c{kZALNCm5c%%oF+I3DrA63_@4)(v4(t~JiddILp7jmoy+>cD~ivwoctFfEL zP*#2Rx?_&bCpX26MBgp^4G>@h`Hxc(lnqyj!*t>9sOBcXN(hTwEDpn^X{x!!gPX?1 z*uM$}cYRwHXuf+gYTB}gDTcw{TXSOUU$S?8BeP&sc!Lc{{pEv}x#ELX>6*ipI1#>8 zKes$bHjiJ1OygZge_ak^Hz#k;=od1wZ=o71ba7oClBMq>Uk6hVq|ePPt)@FM5bW$I z;d2Or@wBjbTyZj|;+iHp%Bo!Vy(X3YM-}lasMItEV_QrP-Kk_J4C>)L&I3Xxj=E?| zsAF(IfVQ4w+dRRnJ>)}o^3_012YYgFWE)5TT=l2657*L8_u1KC>Y-R{7w^S&A^X^U}h20jpS zQsdeaA#WIE*<8KG*oXc~$izYilTc#z{5xhpXmdT-YUnGh9v4c#lrHG6X82F2-t35} zB`jo$HjKe~E*W$=g|j&P>70_cI`GnOQ;Jp*JK#CT zuEGCn{8A@bC)~0%wsEv?O^hSZF*iqjO~_h|>xv>PO+?525Nw2472(yqS>(#R)D7O( zg)Zrj9n9$}=~b00=Wjf?E418qP-@8%MQ%PBiCTX=$B)e5cHFDu$LnOeJ~NC;xmOk# z>z&TbsK>Qzk)!88lNI8fOE2$Uxso^j*1fz>6Ot49y@=po)j4hbTIcVR`ePHpuJSfp zxaD^Dn3X}Na3@<_Pc>a;-|^Pon(>|ytG_+U^8j_JxP=_d>L$Hj?|0lz>_qQ#a|$+( z(x=Lipuc8p4^}1EQhI|TubffZvB~lu$zz9ao%T?%ZLyV5S9}cLeT?c} z>yCN9<04NRi~1oR)CiBakoNhY9BPnv)kw%*iv8vdr&&VgLGIs(-FbJ?d_gfbL2={- zBk4lkdPk~7+jIxd4{M(-W1AC_WcN&Oza@jZoj zaE*9Y;g83#m(OhA!w~LNfUJNUuRz*H-=$s*z+q+;snKPRm9EptejugC-@7-a-}Tz0 z@KHra#Y@OXK+KsaSN9WiGf?&jlZ!V7L||%KHP;SLksMFfjkeIMf<1e~t?!G3{n)H8 zQAlFY#QwfKuj;l@<$YDATAk;%PtD%B(0<|8>rXU< zJ66rkAVW_~Dj!7JGdGGi4NFuE?7ZafdMxIh65Sz7yQoA7fBZCE@WwysB=+`kT^LFX zz8#FlSA5)6FG9(qL3~A24mpzL@@2D#>0J7mMS1T*9UJ zvOq!!a(%IYY69+h45CE?(&v9H4FCr>gK0>mK~F}5RdOuH2{4|}k@5XpsX7+LZo^Qa4sH5`eUj>iffoBVm+ zz4Mtf`h?NW$*q1yr|}E&eNl)J``SZvTf6Qr*&S%tVv_OBpbjnA0&Vz#(;QmGiq-k! zgS0br4I&+^2mgA15*~Cd00cXLYOLA#Ep}_)eED>m+K@JTPr_|lSN}(OzFXQSBc6fM z@f-%2;1@BzhZa*LFV z-LrLmkmB%<<&jEURBEW>soaZ*rSIJNwaV%-RSaCZi4X)qYy^PxZ=oL?6N-5OGOMD2 z;q_JK?zkwQ@b3~ln&sDtT5SpW9a0q+5Gm|fpVY2|zqlNYBR}E5+ahgdj!CvK$Tlk0 z9g$5N;aar=CqMsudQV>yb4l@hN(9Jcc=1(|OHsqH6|g=K-WBd8GxZ`AkT?OO z-z_Ued-??Z*R4~L7jwJ%-`s~FK|qNAJ;EmIVDVpk{Lr7T4l{}vL)|GuUuswe9c5F| zv*5%u01hlv08?00Vpwyk*Q&&fY8k6MjOfpZfKa@F-^6d=Zv|0@&4_544RP5(s|4VPVP-f>%u(J@23BHqo2=zJ#v9g=F!cP((h zpt0|(s++ej?|$;2PE%+kc6JMmJjDW)3BXvBK!h!E`8Y&*7hS{c_Z?4SFP&Y<3evqf z9-ke+bSj$%Pk{CJlJbWwlBg^mEC^@%Ou?o>*|O)rl&`KIbHrjcpqsc$Zqt0^^F-gU2O=BusO+(Op}!jNzLMc zT;0YT%$@ClS%V+6lMTfhuzzxomoat=1H?1$5Ei7&M|gxo`~{UiV5w64Np6xV zVK^nL$)#^tjhCpTQMspXI({TW^U5h&Wi1Jl8g?P1YCV4=%ZYyjSo#5$SX&`r&1PyC zzc;uzCd)VTIih|8eNqFNeBMe#j_FS6rq81b>5?aXg+E#&$m++Gz9<+2)h=K(xtn}F ziV{rmu+Y>A)qvF}ms}4X^Isy!M&1%$E!rTO~5(p+8{U6#hWu>(Ll1}eD64Xa>~73A*538wry?v$vW z>^O#FRdbj(k0Nr&)U`Tl(4PI*%IV~;ZcI2z&rmq=(k^}zGOYZF3b2~Klpzd2eZJl> zB=MOLwI1{$RxQ7Y4e30&yOx?BvAvDkTBvWPpl4V8B7o>4SJn*+h1Ms&fHso%XLN5j z-zEwT%dTefp~)J_C8;Q6i$t!dnlh-!%haR1X_NuYUuP-)`IGWjwzAvp!9@h`kPZhf zwLwFk{m3arCdx8rD~K2`42mIN4}m%OQ|f)4kf%pL?Af5Ul<3M2fv>;nlhEPR8b)u} zIV*2-wyyD%%) zl$G@KrC#cUwoL?YdQyf9WH)@gWB{jd5w4evI& zOFF)p_D8>;3-N1z6mES!OPe>B^<;9xsh)){Cw$Vs-ez5nXS95NOr3s$IU;>VZSzKn zBvub8_J~I%(DozZW@{)Vp37-zevxMRZ8$8iRfwHmYvyjOxIOAF2FUngKj289!(uxY zaClWm!%x&teKmr^ABrvZ(ikx{{I-lEzw5&4t3P0eX%M~>$wG0ZjA4Mb&op+0$#SO_ z--R`>X!aqFu^F|a!{Up-iF(K+alKB{MNMs>e(i@Tpy+7Z-dK%IEjQFO(G+2mOb@BO zP>WHlS#fSQm0et)bG8^ZDScGnh-qRKIFz zfUdnk=m){ej0i(VBd@RLtRq3Ep=>&2zZ2%&vvf?Iex01hx1X!8U+?>ER;yJlR-2q4 z;Y@hzhEC=d+Le%=esE>OQ!Q|E%6yG3V_2*uh&_nguPcZ{q?DNq8h_2ahaP6=pP-+x zK!(ve(yfoYC+n(_+chiJ6N(ZaN+XSZ{|H{TR1J_s8x4jpis-Z-rlRvRK#U%SMJ(`C z?T2 zF(NNfO_&W%2roEC2j#v*(nRgl1X)V-USp-H|CwFNs?n@&vpRcj@W@xCJwR6@T!jt377?XjZ06=`d*MFyTdyvW!`mQm~t3luzYzvh^F zM|V}rO>IlBjZc}9Z zd$&!tthvr>5)m;5;96LWiAV0?t)7suqdh0cZis`^Pyg@?t>Ms~7{nCU;z`Xl+raSr zXpp=W1oHB*98s!Tpw=R5C)O{{Inl>9l7M*kq%#w9a$6N~v?BY2GKOVRkXYCgg*d

<5G2M1WZP5 zzqSuO91lJod(SBDDw<*sX(+F6Uq~YAeYV#2A;XQu_p=N5X+#cmu19Qk>QAnV=k!?wbk5I;tDWgFc}0NkvC*G=V+Yh1cyeJVq~9czZiDXe+S=VfL2g`LWo8om z$Y~FQc6MFjV-t1Y`^D9XMwY*U_re2R?&(O~68T&D4S{X`6JYU-pz=}ew-)V0AOUT1 zVOkHAB-8uBcRjLvz<9HS#a@X*Kc@|W)nyiSgi|u5$Md|P()%2(?olGg@ypoJwp6>m z*dnfjjWC>?_1p;%1brqZyDRR;8EntVA92EJ3ByOxj6a+bhPl z;a?m4rQAV1@QU^#M1HX)0+}A<7TCO`ZR_RzF}X9-M>cRLyN4C+lCk2)kT^3gN^`IT zNP~fAm(wyIoR+l^lQDA(e1Yv}&$I!n?&*p6?lZcQ+vGLLd~fM)qt}wsbf3r=tmVYe zl)ntf#E!P7wlakP9MXS7m0nsAmqxZ*)#j;M&0De`oNmFgi$ov#!`6^4)iQyxg5Iuj zjLAhzQ)r`^hf7`*1`Rh`X;LVBtDSz@0T?kkT1o!ijeyTGt5vc^Cd*tmNgiNo^EaWvaC8$e+nb_{W01j3%=1Y&92YacjCi>eNbwk%-gPQ@H-+4xskQ}f_c=jg^S-# zYFBDf)2?@5cy@^@FHK5$YdAK9cI;!?Jgd}25lOW%xbCJ>By3=HiK@1EM+I46A)Lsd zeT|ZH;KlCml=@;5+hfYf>QNOr^XNH%J-lvev)$Omy8MZ`!{`j>(J5cG&ZXXgv)TaF zg;cz99i$4CX_@3MIb?GL0s*8J=3`#P(jXF(_(6DXZjc@(@h&=M&JG)9&Te1?(^XMW zjjC_70|b=9hB6pKQi`S^Ls7JyJw^@P>Ko^&q8F&?>6i;#CbxUiLz1ZH4lNyd@QACd zu>{!sqjB!2Dg}pbAXD>d!3jW}=5aN0b;rw*W>*PAxm7D)aw(c*RX2@bTGEI|RRp}vw7;NR2wa;rXN{L{Q#=Fa z$x@ms6pqb>!8AuV(prv>|aU8oWV={C&$c zMa=p=CDNOC2tISZcd8~18GN5oTbKY+Vrq;3_obJlfSKRMk;Hdp1`y`&LNSOqeauR_ z^j*Ojl3Ohzb5-a49A8s|UnM*NM8tg}BJXdci5%h&;$afbmRpN0&~9rCnBA`#lG!p zc{(9Y?A0Y9yo?wSYn>iigf~KP$0*@bGZ>*YM4&D;@{<%Gg5^uUJGRrV4 z(aZOGB&{_0f*O=Oi0k{@8vN^BU>s3jJRS&CJOl3o|BE{FAA&a#2YYiX3pZz@|Go-F z|Fly;7eX2OTs>R}<`4RwpHFs9nwh)B28*o5qK1Ge=_^w0m`uJOv!=&!tzt#Save(C zgKU=Bsgql|`ui(e1KVxR`?>Dx>(rD1$iWp&m`v)3A!j5(6vBm*z|aKm*T*)mo(W;R zNGo2`KM!^SS7+*9YxTm6YMm_oSrLceqN*nDOAtagULuZl5Q<7mOnB@Hq&P|#9y{5B z!2x+2s<%Cv2Aa0+u{bjZXS);#IFPk(Ph-K7K?3i|4ro> zRbqJoiOEYo(Im^((r}U4b8nvo_>4<`)ut`24?ILnglT;Pd&U}$lV3U$F9#PD(O=yV zgNNA=GW|(E=&m_1;uaNmipQe?pon4{T=zK!N!2_CJL0E*R^XXIKf*wi!>@l}3_P9Z zF~JyMbW!+n-+>!u=A1ESxzkJy$DRuG+$oioG7(@Et|xVbJ#BCt;J43Nvj@MKvTxzy zMmjNuc#LXBxFAwIGZJk~^!q$*`FME}yKE8d1f5Mp}KHNq(@=Z8YxV}0@;YS~|SpGg$_jG7>_8WWYcVx#4SxpzlV9N4aO>K{c z$P?a_fyDzGX$Of3@ykvedGd<@-R;M^Shlj*SswJLD+j@hi_&_>6WZ}#AYLR0iWMK|A zH_NBeu(tMyG=6VO-=Pb>-Q#$F*or}KmEGg*-n?vWQREURdB#+6AvOj*I%!R-4E_2$ zU5n9m>RWs|Wr;h2DaO&mFBdDb-Z{APGQx$(L`if?C|njd*fC=rTS%{o69U|meRvu?N;Z|Y zbT|ojL>j;q*?xXmnHH#3R4O-59NV1j=uapkK7}6@Wo*^Nd#(;$iuGsb;H315xh3pl zHaJ>h-_$hdNl{+|Zb%DZH%ES;*P*v0#}g|vrKm9;j-9e1M4qX@zkl&5OiwnCz=tb6 zz<6HXD+rGIVpGtkb{Q^LIgExOm zz?I|oO9)!BOLW#krLmWvX5(k!h{i>ots*EhpvAE;06K|u_c~y{#b|UxQ*O@Ks=bca z^_F0a@61j3I(Ziv{xLb8AXQj3;R{f_l6a#H5ukg5rxwF9A$?Qp-Mo54`N-SKc}fWp z0T)-L@V$$&my;l#Ha{O@!fK4-FSA)L&3<${Hcwa7ue`=f&YsXY(NgeDU#sRlT3+9J z6;(^(sjSK@3?oMo$%L-nqy*E;3pb0nZLx6 z;h5)T$y8GXK1DS-F@bGun8|J(v-9o=42&nLJy#}M5D0T^5VWBNn$RpC zZzG6Bt66VY4_?W=PX$DMpKAI!d`INr) zkMB{XPQ<52rvWVQqgI0OL_NWxoe`xxw&X8yVftdODPj5|t}S6*VMqN$-h9)1MBe0N zYq?g0+e8fJCoAksr0af1)FYtz?Me!Cxn`gUx&|T;)695GG6HF7!Kg1zzRf_{VWv^bo81v4$?F6u2g|wxHc6eJQAg&V z#%0DnWm2Rmu71rPJ8#xFUNFC*V{+N_qqFH@gYRLZ6C?GAcVRi>^n3zQxORPG)$-B~ z%_oB?-%Zf7d*Fe;cf%tQwcGv2S?rD$Z&>QC2X^vwYjnr5pa5u#38cHCt4G3|efuci z@3z=#A13`+ztmp;%zjXwPY_aq-;isu*hecWWX_=Z8paSqq7;XYnUjK*T>c4~PR4W7 z#C*%_H&tfGx`Y$w7`dXvVhmovDnT>btmy~SLf>>~84jkoQ%cv=MMb+a{JV&t0+1`I z32g_Y@yDhKe|K^PevP~MiiVl{Ou7^Mt9{lOnXEQ`xY^6L8D$705GON{!1?1&YJEl#fTf5Z)da=yiEQ zGgtC-soFGOEBEB~ZF_{7b(76En>d}mI~XIwNw{e>=Fv)sgcw@qOsykWr?+qAOZSVrQfg}TNI ztKNG)1SRrAt6#Q?(me%)>&A_^DM`pL>J{2xu>xa$3d@90xR61TQDl@fu%_85DuUUA za9tn64?At;{`BAW6oykwntxHeDpXsV#{tmt5RqdN7LtcF4vR~_kZNT|wqyR#z^Xcd zFdymVRZvyLfTpBT>w9<)Ozv@;Yk@dOSVWbbtm^y@@C>?flP^EgQPAwsy75bveo=}T zFxl(f)s)j(0#N_>Or(xEuV(n$M+`#;Pc$1@OjXEJZumkaekVqgP_i}p`oTx;terTx zZpT+0dpUya2hqlf`SpXN{}>PfhajNk_J0`H|2<5E;U5Vh4F8er z;RxLSFgpGhkU>W?IwdW~NZTyOBrQ84H7_?gviIf71l`EETodG9a1!8e{jW?DpwjL? zGEM&eCzwoZt^P*8KHZ$B<%{I}>46IT%jJ3AnnB5P%D2E2Z_ z1M!vr#8r}1|KTqWA4%67ZdbMW2YJ81b(KF&SQ2L1Qn(y-=J${p?xLMx3W7*MK;LFQ z6Z`aU;;mTL4XrrE;HY*Rkh6N%?qviUGNAKiCB~!P}Z->IpO6E(gGd7I#eDuT7j|?nZ zK}I(EJ>$Kb&@338M~O+em9(L!+=0zBR;JAQesx|3?Ok90)D1aS9P?yTh6Poh8Cr4X zk3zc=f2rE7jj+aP7nUsr@~?^EGP>Q>h#NHS?F{Cn`g-gD<8F&dqOh-0sa%pfL`b+1 zUsF*4a~)KGb4te&K0}bE>z3yb8% zibb5Q%Sfiv7feb1r0tfmiMv z@^4XYwg@KZI=;`wC)`1jUA9Kv{HKe2t$WmRcR4y8)VAFjRi zaz&O7Y2tDmc5+SX(bj6yGHYk$dBkWc96u3u&F)2yEE~*i0F%t9Kg^L6MJSb&?wrXi zGSc;_rln$!^ybwYBeacEFRsVGq-&4uC{F)*Y;<0y7~USXswMo>j4?~5%Zm!m@i@-> zXzi82sa-vpU{6MFRktJy+E0j#w`f`>Lbog{zP|9~hg(r{RCa!uGe>Yl536cn$;ouH za#@8XMvS-kddc1`!1LVq;h57~zV`7IYR}pp3u!JtE6Q67 zq3H9ZUcWPm2V4IukS}MCHSdF0qg2@~ufNx9+VMjQP&exiG_u9TZAeAEj*jw($G)zL zq9%#v{wVyOAC4A~AF=dPX|M}MZV)s(qI9@aIK?Pe+~ch|>QYb+78lDF*Nxz2-vpRbtQ*F4$0fDbvNM#CCatgQ@z1+EZWrt z2dZfywXkiW=no5jus-92>gXn5rFQ-COvKyegmL=4+NPzw6o@a?wGE-1Bt;pCHe;34K%Z z-FnOb%!nH;)gX+!a3nCk?5(f1HaWZBMmmC@lc({dUah+E;NOros{?ui1zPC-Q0);w zEbJmdE$oU$AVGQPdm{?xxI_0CKNG$LbY*i?YRQ$(&;NiA#h@DCxC(U@AJ$Yt}}^xt-EC_ z4!;QlLkjvSOhdx!bR~W|Ezmuf6A#@T`2tsjkr>TvW*lFCMY>Na_v8+{Y|=MCu1P8y z89vPiH5+CKcG-5lzk0oY>~aJC_0+4rS@c@ZVKLAp`G-sJB$$)^4*A!B zmcf}lIw|VxV9NSoJ8Ag3CwN&d7`|@>&B|l9G8tXT^BDHOUPrtC70NgwN4${$k~d_4 zJ@eo6%YQnOgq$th?0{h`KnqYa$Nz@vlHw<%!C5du6<*j1nwquk=uY}B8r7f|lY+v7 zm|JU$US08ugor8E$h3wH$c&i~;guC|3-tqJy#T;v(g( zBZtPMSyv%jzf->435yM(-UfyHq_D=6;ouL4!ZoD+xI5uCM5ay2m)RPmm$I}h>()hS zO!0gzMxc`BPkUZ)WXaXam%1;)gedA7SM8~8yIy@6TPg!hR0=T>4$Zxd)j&P-pXeSF z9W`lg6@~YDhd19B9ETv(%er^Xp8Yj@AuFVR_8t*KS;6VHkEDKI#!@l!l3v6`W1`1~ zP{C@keuV4Q`Rjc08lx?zmT$e$!3esc9&$XZf4nRL(Z*@keUbk!GZi(2Bmyq*saOD? z3Q$V<*P-X1p2}aQmuMw9nSMbOzuASsxten7DKd6A@ftZ=NhJ(0IM|Jr<91uAul4JR zADqY^AOVT3a(NIxg|U;fyc#ZnSzw2cr}#a5lZ38>nP{05D)7~ad7JPhw!LqOwATXtRhK!w0X4HgS1i<%AxbFmGJx9?sEURV+S{k~g zGYF$IWSlQonq6}e;B(X(sIH|;52+(LYW}v_gBcp|x%rEAVB`5LXg_d5{Q5tMDu0_2 z|LOm$@K2?lrLNF=mr%YP|U-t)~9bqd+wHb4KuPmNK<}PK6e@aosGZK57=Zt+kcszVOSbe;`E^dN! ze7`ha3WUUU7(nS0{?@!}{0+-VO4A{7+nL~UOPW9_P(6^GL0h${SLtqG!} zKl~Ng5#@Sy?65wk9z*3SA`Dpd4b4T^@C8Fhd8O)k_4%0RZL5?#b~jmgU+0|DB%0Z) zql-cPC>A9HPjdOTpPC` zQwvF}uB5kG$Xr4XnaH#ruSjM*xG?_hT7y3G+8Ox`flzU^QIgb_>2&-f+XB6MDr-na zSi#S+c!ToK84<&m6sCiGTd^8pNdXo+$3^l3FL_E`0 z>8it5YIDxtTp2Tm(?}FX^w{fbfgh7>^8mtvN>9fWgFN_*a1P`Gz*dyOZF{OV7BC#j zQV=FQM5m>47xXgapI$WbPM5V`V<7J9tD)oz@d~MDoM`R^Y6-Na(lO~uvZlpu?;zw6 zVO1faor3dg#JEb5Q*gz4<W8tgC3nE2BG2jeIQs1)<{In&7hJ39x=;ih;CJDy)>0S1at*7n?Wr0ahYCpFjZ|@u91Zl7( zv;CSBRC65-6f+*JPf4p1UZ)k=XivKTX6_bWT~7V#rq0Xjas6hMO!HJN8GdpBKg_$B zwDHJF6;z?h<;GXFZan8W{XFNPpOj!(&I1`&kWO86p?Xz`a$`7qV7Xqev|7nn_lQuX ziGpU1MMYt&5dE2A62iX3;*0WzNB9*nSTzI%62A+N?f?;S>N@8M=|ef3gtQTIA*=yq zQAAjOqa!CkHOQo4?TsqrrsJLclXcP?dlAVv?v`}YUjo1Htt;6djP@NPFH+&p1I+f_ z)Y279{7OWomY8baT(4TAOlz1OyD{4P?(DGv3XyJTA2IXe=kqD)^h(@*E3{I~w;ws8 z)ZWv7E)pbEM zd3MOXRH3mQhks9 zv6{s;k0y5vrcjXaVfw8^>YyPo=oIqd5IGI{)+TZq5Z5O&hXAw%ZlL}^6FugH;-%vP zAaKFtt3i^ag226=f0YjzdPn6|4(C2sC5wHFX{7QF!tG1E-JFA`>eZ`}$ymcRJK?0c zN363o{&ir)QySOFY0vcu6)kX#;l??|7o{HBDVJN+17rt|w3;(C_1b>d;g9Gp=8YVl zYTtA52@!7AUEkTm@P&h#eg+F*lR zQ7iotZTcMR1frJ0*V@Hw__~CL>_~2H2cCtuzYIUD24=Cv!1j6s{QS!v=PzwQ(a0HS zBKx04KA}-Ue+%9d`?PG*hIij@54RDSQpA7|>qYVIrK_G6%6;#ZkR}NjUgmGju)2F`>|WJoljo)DJgZr4eo1k1i1+o z1D{>^RlpIY8OUaOEf5EBu%a&~c5aWnqM zxBpJq98f=%M^{4mm~5`CWl%)nFR64U{(chmST&2jp+-r z3675V<;Qi-kJud%oWnCLdaU-)xTnMM%rx%Jw6v@=J|Ir=4n-1Z23r-EVf91CGMGNz zb~wyv4V{H-hkr3j3WbGnComiqmS0vn?n?5v2`Vi>{Ip3OZUEPN7N8XeUtF)Ry6>y> zvn0BTLCiqGroFu|m2zG-;Xb6;W`UyLw)@v}H&(M}XCEVXZQoWF=Ykr5lX3XWwyNyF z#jHv)A*L~2BZ4lX?AlN3X#axMwOC)PoVy^6lCGse9bkGjb=qz%kDa6}MOmSwK`cVO zt(e*MW-x}XtU?GY5}9{MKhRhYOlLhJE5=ca+-RmO04^ z66z{40J=s=ey9OCdc(RCzy zd7Zr1%!y3}MG(D=wM_ebhXnJ@MLi7cImDkhm0y{d-Vm81j`0mbi4lF=eirlr)oW~a zCd?26&j^m4AeXEsIUXiTal)+SPM4)HX%%YWF1?(FV47BaA`h9m67S9x>hWMVHx~Hg z1meUYoLL(p@b3?x|9DgWeI|AJ`Ia84*P{Mb%H$ZRROouR4wZhOPX15=KiBMHl!^JnCt$Az`KiH^_d>cev&f zaG2>cWf$=A@&GP~DubsgYb|L~o)cn5h%2`i^!2)bzOTw2UR!>q5^r&2Vy}JaWFUQE04v>2;Z@ZPwXr?y&G(B^@&y zsd6kC=hHdKV>!NDLIj+3rgZJ|dF`%N$DNd;B)9BbiT9Ju^Wt%%u}SvfM^=|q-nxDG zuWCQG9e#~Q5cyf8@y76#kkR^}{c<_KnZ0QsZcAT|YLRo~&tU|N@BjxOuy`#>`X~Q< z?R?-Gsk$$!oo(BveQLlUrcL#eirhgBLh`qHEMg`+sR1`A=1QX7)ZLMRT+GBy?&mM8 zQG^z-!Oa&J-k7I(3_2#Q6Bg=NX<|@X&+YMIOzfEO2$6Mnh}YV!m!e^__{W@-CTprr zbdh3f=BeCD$gHwCrmwgM3LAv3!Mh$wM)~KWzp^w)Cu6roO7uUG5z*}i0_0j47}pK; ztN530`ScGatLOL06~zO)Qmuv`h!gq5l#wx(EliKe&rz-5qH(hb1*fB#B+q`9=jLp@ zOa2)>JTl7ovxMbrif`Xe9;+fqB1K#l=Dv!iT;xF zdkCvS>C5q|O;}ns3AgoE({Ua-zNT-9_5|P0iANmC6O76Sq_(AN?UeEQJ>#b54fi3k zFmh+P%b1x3^)0M;QxXLP!BZ^h|AhOde*{9A=f3|Xq*JAs^Y{eViF|=EBfS6L%k4ip zk+7M$gEKI3?bQg?H3zaE@;cyv9kv;cqK$VxQbFEsy^iM{XXW0@2|DOu$!-k zSFl}Y=jt-VaT>Cx*KQnHTyXt}f9XswFB9ibYh+k2J!ofO+nD?1iw@mwtrqI4_i?nE zhLkPp41ED62me}J<`3RN80#vjW;wt`pP?%oQ!oqy7`miL>d-35a=qotK$p{IzeSk# ze_$CFYp_zIkrPFVaW^s#U4xT1lI^A0IBe~Y<4uS%zSV=wcuLr%gQT=&5$&K*bwqx| zWzCMiz>7t^Et@9CRUm9E+@hy~sBpm9fri$sE1zgLU((1?Yg{N1Sars=DiW&~Zw=3I zi7y)&oTC?UWD2w97xQ&5vx zRXEBGeJ(I?Y}eR0_O{$~)bMJRTsNUPIfR!xU9PE7A>AMNr_wbrFK>&vVw=Y;RH zO$mlpmMsQ}-FQ2cSj7s7GpC+~^Q~dC?y>M}%!-3kq(F3hGWo9B-Gn02AwUgJ>Z-pKOaj zysJBQx{1>Va=*e@sLb2z&RmQ7ira;aBijM-xQ&cpR>X3wP^foXM~u1>sv9xOjzZpX z0K;EGouSYD~oQ&lAafj3~EaXfFShC+>VsRlEMa9cg9i zFxhCKO}K0ax6g4@DEA?dg{mo>s+~RPI^ybb^u--^nTF>**0l5R9pocwB?_K)BG_)S zyLb&k%XZhBVr7U$wlhMqwL)_r&&n%*N$}~qijbkfM|dIWP{MyLx}X&}ES?}7i;9bW zmTVK@zR)7kE2+L42Q`n4m0VVg5l5(W`SC9HsfrLZ=v%lpef=Gj)W59VTLe+Z$8T8i z4V%5+T0t8LnM&H>Rsm5C%qpWBFqgTwL{=_4mE{S3EnBXknM&u8n}A^IIM4$s3m(Rd z>zq=CP-!9p9es2C*)_hoL@tDYABn+o#*l;6@7;knWIyDrt5EuakO99S$}n((Fj4y} zD!VvuRzghcE{!s;jC*<_H$y6!6QpePo2A3ZbX*ZzRnQq*b%KK^NF^z96CHaWmzU@f z#j;y?X=UP&+YS3kZx7;{ zDA{9(wfz7GF`1A6iB6fnXu0?&d|^p|6)%3$aG0Uor~8o? z*e}u#qz7Ri?8Uxp4m_u{a@%bztvz-BzewR6bh*1Xp+G=tQGpcy|4V_&*aOqu|32CM zz3r*E8o8SNea2hYJpLQ-_}R&M9^%@AMx&`1H8aDx4j%-gE+baf2+9zI*+Pmt+v{39 zDZ3Ix_vPYSc;Y;yn68kW4CG>PE5RoaV0n@#eVmk?p$u&Fy&KDTy!f^Hy6&^-H*)#u zdrSCTJPJw?(hLf56%2;_3n|ujUSJOU8VPOTlDULwt0jS@j^t1WS z!n7dZIoT+|O9hFUUMbID4Ec$!cc($DuQWkocVRcYSikFeM&RZ=?BW)mG4?fh#)KVG zcJ!<=-8{&MdE)+}?C8s{k@l49I|Zwswy^ZN3;E!FKyglY~Aq?4m74P-0)sMTGXqd5(S<-(DjjM z&7dL-Mr8jhUCAG$5^mI<|%`;JI5FVUnNj!VO2?Jiqa|c2;4^n!R z`5KK0hyB*F4w%cJ@Un6GC{mY&r%g`OX|1w2$B7wxu97%<@~9>NlXYd9RMF2UM>(z0 zouu4*+u+1*k;+nFPk%ly!nuMBgH4sL5Z`@Rok&?Ef=JrTmvBAS1h?C0)ty5+yEFRz zY$G=coQtNmT@1O5uk#_MQM1&bPPnspy5#>=_7%WcEL*n$;sSAZcXxMpcXxLe;_mLA z5F_paad+bGZV*oh@8h0(|D2P!q# zTHjmiphJ=AazSeKQPkGOR-D8``LjzToyx{lfK-1CDD6M7?pMZOdLKFtjZaZMPk4}k zW)97Fh(Z+_Fqv(Q_CMH-YYi?fR5fBnz7KOt0*t^cxmDoIokc=+`o# zrud|^h_?KW=Gv%byo~(Ln@({?3gnd?DUf-j2J}|$Mk>mOB+1{ZQ8HgY#SA8END(Zw z3T+W)a&;OO54~m}ffemh^oZ!Vv;!O&yhL0~hs(p^(Yv=(3c+PzPXlS5W79Er8B1o* z`c`NyS{Zj_mKChj+q=w)B}K za*zzPhs?c^`EQ;keH{-OXdXJet1EsQ)7;{3eF!-t^4_Srg4(Ot7M*E~91gwnfhqaM zNR7dFaWm7MlDYWS*m}CH${o?+YgHiPC|4?X?`vV+ws&Hf1ZO-w@OGG^o4|`b{bLZj z&9l=aA-Y(L11!EvRjc3Zpxk7lc@yH1e$a}8$_-r$)5++`_eUr1+dTb@ zU~2P1HM#W8qiNN3b*=f+FfG1!rFxnNlGx{15}BTIHgxO>Cq4 z;#9H9YjH%>Z2frJDJ8=xq>Z@H%GxXosS@Z>cY9ppF+)e~t_hWXYlrO6)0p7NBMa`+ z^L>-#GTh;k_XnE)Cgy|0Dw;(c0* zSzW14ZXozu)|I@5mRFF1eO%JM=f~R1dkNpZM+Jh(?&Zje3NgM{2ezg1N`AQg5%+3Y z64PZ0rPq6;_)Pj-hyIOgH_Gh`1$j1!jhml7ksHA1`CH3FDKiHLz+~=^u@kUM{ilI5 z^FPiJ7mSrzBs9{HXi2{sFhl5AyqwUnU{sPcUD{3+l-ZHAQ)C;c$=g1bdoxeG(5N01 zZy=t8i{*w9m?Y>V;uE&Uy~iY{pY4AV3_N;RL_jT_QtLFx^KjcUy~q9KcLE3$QJ{!)@$@En{UGG7&}lc*5Kuc^780;7Bj;)X?1CSy*^^ zPP^M)Pr5R>mvp3_hmCtS?5;W^e@5BjE>Cs<`lHDxj<|gtOK4De?Sf0YuK5GX9G93i zMYB{8X|hw|T6HqCf7Cv&r8A$S@AcgG1cF&iJ5=%+x;3yB`!lQ}2Hr(DE8=LuNb~Vs z=FO&2pdc16nD$1QL7j+!U^XWTI?2qQKt3H8=beVTdHHa9=MiJ&tM1RRQ-=+vy!~iz zj3O{pyRhCQ+b(>jC*H)J)%Wq}p>;?@W*Eut@P&?VU+Sdw^4kE8lvX|6czf{l*~L;J zFm*V~UC;3oQY(ytD|D*%*uVrBB}BbAfjK&%S;z;7$w68(8PV_whC~yvkZmX)xD^s6 z{$1Q}q;99W?*YkD2*;)tRCS{q2s@JzlO~<8x9}X<0?hCD5vpydvOw#Z$2;$@cZkYrp83J0PsS~!CFtY%BP=yxG?<@#{7%2sy zOc&^FJxsUYN36kSY)d7W=*1-{7ghPAQAXwT7z+NlESlkUH&8ODlpc8iC*iQ^MAe(B z?*xO4i{zFz^G=^G#9MsLKIN64rRJykiuIVX5~0#vAyDWc9-=6BDNT_aggS2G{B>dD ze-B%d3b6iCfc5{@yz$>=@1kdK^tX9qh0=ocv@9$ai``a_ofxT=>X7_Y0`X}a^M?d# z%EG)4@`^Ej_=%0_J-{ga!gFtji_byY&Vk@T1c|ucNAr(JNr@)nCWj?QnCyvXg&?FW;S-VOmNL6^km_dqiVjJuIASVGSFEos@EVF7St$WE&Z%)`Q##+0 zjaZ=JI1G@0!?l|^+-ZrNd$WrHBi)DA0-Eke>dp=_XpV<%CO_Wf5kQx}5e<90dt>8k zAi00d0rQ821nA>B4JHN7U8Zz=0;9&U6LOTKOaC1FC8GgO&kc=_wHIOGycL@c*$`ce703t%>S}mvxEnD-V!;6c`2(p74V7D0No1Xxt`urE66$0(ThaAZ1YVG#QP$ zy~NN%kB*zhZ2Y!kjn826pw4bh)75*e!dse+2Db(;bN34Uq7bLpr47XTX{8UEeC?2i z*{$`3dP}32${8pF$!$2Vq^gY|#w+VA_|o(oWmQX8^iw#n_crb(K3{69*iU?<%C-%H zuKi)3M1BhJ@3VW>JA`M>L~5*_bxH@Euy@niFrI$82C1}fwR$p2E&ZYnu?jlS}u7W9AyfdXh2pM>78bIt3 z)JBh&XE@zA!kyCDfvZ1qN^np20c1u#%P6;6tU&dx0phT1l=(mw7`u!-0e=PxEjDds z9E}{E!7f9>jaCQhw)&2TtG-qiD)lD(4jQ!q{`x|8l&nmtHkdul# zy+CIF8lKbp9_w{;oR+jSLtTfE+B@tOd6h=QePP>rh4@~!8c;Hlg9m%%&?e`*Z?qz5-zLEWfi>`ord5uHF-s{^bexKAoMEV@9nU z^5nA{f{dW&g$)BAGfkq@r5D)jr%!Ven~Q58c!Kr;*Li#`4Bu_?BU0`Y`nVQGhNZk@ z!>Yr$+nB=`z#o2nR0)V3M7-eVLuY`z@6CT#OTUXKnxZn$fNLPv7w1y7eGE=Qv@Hey`n;`U=xEl|q@CCV^#l)s0ZfT+mUf z^(j5r4)L5i2jnHW4+!6Si3q_LdOLQi<^fu?6WdohIkn79=jf%Fs3JkeXwF(?_tcF? z?z#j6iXEd(wJy4|p6v?xNk-)iIf2oX5^^Y3q3ziw16p9C6B;{COXul%)`>nuUoM*q zzmr|NJ5n)+sF$!yH5zwp=iM1#ZR`O%L83tyog-qh1I z0%dcj{NUs?{myT~33H^(%0QOM>-$hGFeP;U$puxoJ>>o-%Lk*8X^rx1>j|LtH$*)>1C!Pv&gd16%`qw5LdOIUbkNhaBBTo}5iuE%K&ZV^ zAr_)kkeNKNYJRgjsR%vexa~&8qMrQYY}+RbZ)egRg9_$vkoyV|Nc&MH@8L)`&rpqd zXnVaI@~A;Z^c3+{x=xgdhnocA&OP6^rr@rTvCnhG6^tMox$ulw2U7NgUtW%|-5VeH z_qyd47}1?IbuKtqNbNx$HR`*+9o=8`%vM8&SIKbkX9&%TS++x z5|&6P<%=F$C?owUI`%uvUq^yW0>`>yz!|WjzsoB9dT;2Dx8iSuK%%_XPgy0dTD4kd zDXF@&O_vBVVKQq(9YTClUPM30Sk7B!v7nOyV`XC!BA;BIVwphh+c)?5VJ^(C;GoQ$ zvBxr7_p*k$T%I1ke}`U&)$uf}I_T~#3XTi53OX)PoXVgxEcLJgZG^i47U&>LY(l%_ z;9vVDEtuMCyu2fqZeez|RbbIE7@)UtJvgAcVwVZNLccswxm+*L&w`&t=ttT=sv6Aq z!HouSc-24Y9;0q$>jX<1DnnGmAsP))- z^F~o99gHZw`S&Aw7e4id6Lg7kMk-e)B~=tZ!kE7sGTOJ)8@q}np@j7&7Sy{2`D^FH zI7aX%06vKsfJ168QnCM2=l|i>{I{%@gcr>ExM0Dw{PX6ozEuqFYEt z087%MKC;wVsMV}kIiuu9Zz9~H!21d!;Cu#b;hMDIP7nw3xSX~#?5#SSjyyg+Y@xh| z%(~fv3`0j#5CA2D8!M2TrG=8{%>YFr(j)I0DYlcz(2~92?G*?DeuoadkcjmZszH5& zKI@Lis%;RPJ8mNsbrxH@?J8Y2LaVjUIhRUiO-oqjy<&{2X~*f|)YxnUc6OU&5iac= z*^0qwD~L%FKiPmlzi&~a*9sk2$u<7Al=_`Ox^o2*kEv?p`#G(p(&i|ot8}T;8KLk- zPVf_4A9R`5^e`Om2LV*cK59EshYXse&IoByj}4WZaBomoHAPKqxRKbPcD`lMBI)g- zeMRY{gFaUuecSD6q!+b5(?vAnf>c`Z(8@RJy%Ulf?W~xB1dFAjw?CjSn$ph>st5bc zUac1aD_m6{l|$#g_v6;=32(mwpveQDWhmjR7{|B=$oBhz`7_g7qNp)n20|^^op3 zSfTdWV#Q>cb{CMKlWk91^;mHap{mk)o?udk$^Q^^u@&jd zfZ;)saW6{e*yoL6#0}oVPb2!}r{pAUYtn4{P~ES9tTfC5hXZnM{HrC8^=Pof{G4%Bh#8 ze~?C9m*|fd8MK;{L^!+wMy>=f^8b&y?yr6KnTq28$pFMBW9Oy7!oV5z|VM$s-cZ{I|Xf@}-)1=$V&x7e;9v81eiTi4O5-vs?^5pCKy2l>q);!MA zS!}M48l$scB~+Umz}7NbwyTn=rqt@`YtuwiQSMvCMFk2$83k50Q>OK5&fe*xCddIm)3D0I6vBU<+!3=6?(OhkO|b4fE_-j zimOzyfBB_*7*p8AmZi~X2bgVhyPy>KyGLAnOpou~sx9)S9%r)5dE%ADs4v%fFybDa_w*0?+>PsEHTbhKK^G=pFz z@IxLTCROWiKy*)cV3y%0FwrDvf53Ob_XuA1#tHbyn%Ko!1D#sdhBo`;VC*e1YlhrC z?*y3rp86m#qI|qeo8)_xH*G4q@70aXN|SP+6MQ!fJQqo1kwO_v7zqvUfU=Gwx`CR@ zRFb*O8+54%_8tS(ADh}-hUJzE`s*8wLI>1c4b@$al)l}^%GuIXjzBK!EWFO8W`>F^ ze7y#qPS0NI7*aU)g$_ziF(1ft;2<}6Hfz10cR8P}67FD=+}MfhrpOkF3hFhQu;Q1y zu%=jJHTr;0;oC94Hi@LAF5quAQ(rJG(uo%BiRQ@8U;nhX)j0i?0SL2g-A*YeAqF>RVCBOTrn{0R27vu}_S zS>tX4!#&U4W;ikTE!eFH+PKw%p+B(MR2I%n#+m0{#?qRP_tR@zpgCb=4rcrL!F=;A zh%EIF8m6%JG+qb&mEfuFTLHSxUAZEvC-+kvZKyX~SA3Umt`k}}c!5dy?-sLIM{h@> z!2=C)@nx>`;c9DdwZ&zeUc(7t<21D7qBj!|1^Mp1eZ6)PuvHx+poKSDCSBMFF{bKy z;9*&EyKitD99N}%mK8431rvbT+^%|O|HV23{;RhmS{$5tf!bIPoH9RKps`-EtoW5h zo6H_!s)Dl}2gCeGF6>aZtah9iLuGd19^z0*OryPNt{70RvJSM<#Ox9?HxGg04}b^f zrVEPceD%)#0)v5$YDE?f`73bQ6TA6wV;b^x*u2Ofe|S}+q{s5gr&m~4qGd!wOu|cZ||#h_u=k*fB;R6&k?FoM+c&J;ISg70h!J7*xGus)ta4veTdW)S^@sU@ z4$OBS=a~@F*V0ECic;ht4@?Jw<9kpjBgHfr2FDPykCCz|v2)`JxTH55?b3IM={@DU z!^|9nVO-R#s{`VHypWyH0%cs;0GO3E;It6W@0gX6wZ%W|Dzz&O%m17pa19db(er}C zUId1a4#I+Ou8E1MU$g=zo%g7K(=0Pn$)Rk z<4T2u<0rD)*j+tcy2XvY+0 z0d2pqm4)4lDewsAGThQi{2Kc3&C=|OQF!vOd#WB_`4gG3@inh-4>BoL!&#ij8bw7? zqjFRDaQz!J-YGitV4}$*$hg`vv%N)@#UdzHFI2E<&_@0Uw@h_ZHf}7)G;_NUD3@18 zH5;EtugNT0*RXVK*by>WS>jaDDfe!A61Da=VpIK?mcp^W?!1S2oah^wowRnrYjl~`lgP-mv$?yb6{{S55CCu{R z$9;`dyf0Y>uM1=XSl_$01Lc1Iy68IosWN8Q9Op=~I(F<0+_kKfgC*JggjxNgK6 z-3gQm6;sm?J&;bYe&(dx4BEjvq}b`OT^RqF$J4enP1YkeBK#>l1@-K`ajbn05`0J?0daOtnzh@l3^=BkedW1EahZlRp;`j*CaT;-21&f2wU z+Nh-gc4I36Cw+;3UAc<%ySb`#+c@5y ze~en&bYV|kn?Cn|@fqmGxgfz}U!98$=drjAkMi`43I4R%&H0GKEgx-=7PF}y`+j>r zg&JF`jomnu2G{%QV~Gf_-1gx<3Ky=Md9Q3VnK=;;u0lyTBCuf^aUi?+1+`4lLE6ZK zT#(Bf`5rmr(tgTbIt?yA@y`(Ar=f>-aZ}T~>G32EM%XyFvhn&@PWCm#-<&ApLDCXT zD#(9m|V(OOo7PmE@`vD4$S5;+9IQm19dd zvMEU`)E1_F+0o0-z>YCWqg0u8ciIknU#{q02{~YX)gc_u;8;i233D66pf(IkTDxeN zL=4z2)?S$TV9=ORVr&AkZMl<4tTh(v;Ix1{`pPVqI3n2ci&4Dg+W|N8TBUfZ*WeLF zqCH_1Q0W&f9T$lx3CFJ$o@Lz$99 zW!G&@zFHxTaP!o#z^~xgF|(vrHz8R_r9eo;TX9}2ZyjslrtH=%6O)?1?cL&BT(Amp zTGFU1%%#xl&6sH-UIJk_PGk_McFn7=%yd6tAjm|lnmr8bE2le3I~L{0(ffo}TQjyo zHZZI{-}{E4ohYTlZaS$blB!h$Jq^Rf#(ch}@S+Ww&$b);8+>g84IJcLU%B-W?+IY& zslcZIR>+U4v3O9RFEW;8NpCM0w1ROG84=WpKxQ^R`{=0MZCubg3st z48AyJNEvyxn-jCPTlTwp4EKvyEwD3e%kpdY?^BH0!3n6Eb57_L%J1=a*3>|k68A}v zaW`*4YitylfD}ua8V)vb79)N_Ixw_mpp}yJGbNu+5YYOP9K-7nf*jA1#<^rb4#AcS zKg%zCI)7cotx}L&J8Bqo8O1b0q;B1J#B5N5Z$Zq=wX~nQFgUfAE{@u0+EnmK{1hg> zC{vMfFLD;L8b4L+B51&LCm|scVLPe6h02rws@kGv@R+#IqE8>Xn8i|vRq_Z`V;x6F zNeot$1Zsu`lLS92QlLWF54za6vOEKGYQMdX($0JN*cjG7HP&qZ#3+bEN$8O_PfeAb z0R5;=zXac2IZ?fxu59?Nka;1lKm|;0)6|#RxkD05P5qz;*AL@ig!+f=lW5^Jbag%2 z%9@iM0ph$WFlxS!`p31t92z~TB}P-*CS+1Oo_g;7`6k(Jyj8m8U|Q3Sh7o-Icp4kV zK}%qri5>?%IPfamXIZ8pXbm-#{ytiam<{a5A+3dVP^xz!Pvirsq7Btv?*d7eYgx7q zWFxrzb3-%^lDgMc=Vl7^={=VDEKabTG?VWqOngE`Kt7hs236QKidsoeeUQ_^FzsXjprCDd@pW25rNx#6x&L6ZEpoX9Ffzv@olnH3rGOSW( zG-D|cV0Q~qJ>-L}NIyT?T-+x+wU%;+_GY{>t(l9dI%Ximm+Kmwhee;FK$%{dnF;C% zFjM2&$W68Sz#d*wtfX?*WIOXwT;P6NUw}IHdk|)fw*YnGa0rHx#paG!m=Y6GkS4VX zX`T$4eW9k1W!=q8!(#8A9h67fw))k_G)Q9~Q1e3f`aV@kbcSv7!priDUN}gX(iXTy zr$|kU0Vn%*ylmyDCO&G0Z3g>%JeEPFAW!5*H2Ydl>39w3W+gEUjL&vrRs(xGP{(ze zy7EMWF14@Qh>X>st8_029||TP0>7SG9on_xxeR2Iam3G~Em$}aGsNt$iES9zFa<3W zxtOF*!G@=PhfHO!=9pVPXMUVi30WmkPoy$02w}&6A7mF)G6-`~EVq5CwD2`9Zu`kd)52``#V zNSb`9dG~8(dooi1*-aSMf!fun7Sc`-C$-E(3BoSC$2kKrVcI!&yC*+ff2+C-@!AT_ zsvlAIV+%bRDfd{R*TMF><1&_a%@yZ0G0lg2K;F>7b+7A6pv3-S7qWIgx+Z?dt8}|S z>Qbb6x(+^aoV7FQ!Ph8|RUA6vXWQH*1$GJC+wXLXizNIc9p2yLzw9 z0=MdQ!{NnOwIICJc8!+Jp!zG}**r#E!<}&Te&}|B4q;U57$+pQI^}{qj669zMMe_I z&z0uUCqG%YwtUc8HVN7?0GHpu=bL7&{C>hcd5d(iFV{I5c~jpX&!(a{yS*4MEoYXh z*X4|Y@RVfn;piRm-C%b@{0R;aXrjBtvx^HO;6(>i*RnoG0Rtcd25BT6edxTNOgUAOjn zJ2)l{ipj8IP$KID2}*#F=M%^n&=bA0tY98@+2I+7~A&T-tw%W#3GV>GTmkHaqftl)#+E zMU*P(Rjo>8%P@_@#UNq(_L{}j(&-@1iY0TRizhiATJrnvwSH0v>lYfCI2ex^><3$q znzZgpW0JlQx?JB#0^^s-Js1}}wKh6f>(e%NrMwS`Q(FhazkZb|uyB@d%_9)_xb$6T zS*#-Bn)9gmobhAtvBmL+9H-+0_0US?g6^TOvE8f3v=z3o%NcPjOaf{5EMRnn(_z8- z$|m0D$FTU zDy;21v-#0i)9%_bZ7eo6B9@Q@&XprR&oKl4m>zIj-fiRy4Dqy@VVVs?rscG| zmzaDQ%>AQTi<^vYCmv#KOTd@l7#2VIpsj?nm_WfRZzJako`^uU%Nt3e;cU*y*|$7W zLm%fX#i_*HoUXu!NI$ey>BA<5HQB=|nRAwK!$L#n-Qz;~`zACig0PhAq#^5QS<8L2 zS3A+8%vbVMa7LOtTEM?55apt(DcWh#L}R^P2AY*c8B}Cx=6OFAdMPj1f>k3#^#+Hk z6uW1WJW&RlBRh*1DLb7mJ+KO>!t^t8hX1#_Wk`gjDio9)9IGbyCAGI4DJ~orK+YRv znjxRMtshZQHc$#Y-<-JOV6g^Cr@odj&Xw5B(FmI)*qJ9NHmIz_r{t)TxyB`L-%q5l ztzHgD;S6cw?7Atg*6E1!c6*gPRCb%t7D%z<(xm+K{%EJNiI2N0l8ud0Ch@_av_RW? zIr!nO4dL5466WslE6MsfMss7<)-S!e)2@r2o=7_W)OO`~CwklRWzHTfpB)_HYwgz=BzLhgZ9S<{nLBOwOIgJU=94uj6r!m>Xyn9>&xP+=5!zG_*yEoRgM0`aYts z^)&8(>z5C-QQ*o_s(8E4*?AX#S^0)aqB)OTyX>4BMy8h(cHjA8ji1PRlox@jB*1n? zDIfyDjzeg91Ao(;Q;KE@zei$}>EnrF6I}q&Xd=~&$WdDsyH0H7fJX|E+O~%LS*7^Q zYzZ4`pBdY{b7u72gZm6^5~O-57HwzwAz{)NvVaowo`X02tL3PpgLjwA`^i9F^vSpN zAqH3mRjG8VeJNHZ(1{%!XqC+)Z%D}58Qel{_weSEHoygT9pN@i zi=G;!Vj6XQk2tuJC>lza%ywz|`f7TIz*EN2Gdt!s199Dr4Tfd_%~fu8gXo~|ogt5Q zlEy_CXEe^BgsYM^o@L?s33WM14}7^T(kqohOX_iN@U?u;$l|rAvn{rwy>!yfZw13U zB@X9)qt&4;(C6dP?yRsoTMI!j-f1KC!<%~i1}u7yLXYn)(#a;Z6~r>hp~kfP));mi zcG%kdaB9H)z9M=H!f>kM->fTjRVOELNwh1amgKQT=I8J66kI)u_?0@$$~5f`u%;zl zC?pkr^p2Fe=J~WK%4ItSzKA+QHqJ@~m|Cduv=Q&-P8I5rQ-#G@bYH}YJr zUS(~(w|vKyU(T(*py}jTUp%I%{2!W!K(i$uvotcPjVddW z8_5HKY!oBCwGZcs-q`4Yt`Zk~>K?mcxg51wkZlX5e#B08I75F7#dgn5yf&Hrp`*%$ zQ;_Qg>TYRzBe$x=T(@WI9SC!ReSas9vDm(yslQjBJZde5z8GDU``r|N(MHcxNopGr z_}u39W_zwWDL*XYYt>#Xo!9kL#97|EAGyGBcRXtLTd59x%m=3i zL^9joWYA)HfL15l9%H?q`$mY27!<9$7GH(kxb%MV>`}hR4a?+*LH6aR{dzrX@?6X4 z3e`9L;cjqYb`cJmophbm(OX0b)!AFG?5`c#zLagzMW~o)?-!@e80lvk!p#&CD8u5_r&wp4O0zQ>y!k5U$h_K;rWGk=U)zX!#@Q%|9g*A zWx)qS1?fq6X<$mQTB$#3g;;5tHOYuAh;YKSBz%il3Ui6fPRv#v62SsrCdMRTav)Sg zTq1WOu&@v$Ey;@^+_!)cf|w_X<@RC>!=~+A1-65O0bOFYiH-)abINwZvFB;hJjL_$ z(9iScmUdMp2O$WW!520Hd0Q^Yj?DK%YgJD^ez$Z^?@9@Ab-=KgW@n8nC&88)TDC+E zlJM)L3r+ZJfZW_T$;Imq*#2<(j+FIk8ls7)WJ6CjUu#r5PoXxQs4b)mZza<8=v{o)VlLRM<9yw^0En#tXAj`Sylxvki{<1DPe^ zhjHwx^;c8tb?Vr$6ZB;$Ff$+3(*oinbwpN-#F)bTsXq@Sm?43MC#jQ~`F|twI=7oC zH4TJtu#;ngRA|Y~w5N=UfMZi?s0%ZmKUFTAye&6Y*y-%c1oD3yQ%IF2q2385Zl+=> zfz=o`Bedy|U;oxbyb^rB9ixG{Gb-{h$U0hVe`J;{ql!s_OJ_>>eoQn(G6h7+b^P48 zG<=Wg2;xGD-+d@UMZ!c;0>#3nws$9kIDkK13IfloGT@s14AY>&>>^#>`PT7GV$2Hp zN<{bN*ztlZu_%W=&3+=#3bE(mka6VoHEs~0BjZ$+=0`a@R$iaW)6>wp2w)=v2@|2d z%?34!+iOc5S@;AAC4hELWLH56RGxo4jw8MDMU0Wk2k_G}=Vo(>eRFo(g3@HjG|`H3 zm8b*dK=moM*oB<)*A$M9!!5o~4U``e)wxavm@O_R(`P|u%9^LGi(_%IF<6o;NLp*0 zKsfZ0#24GT8(G`i4UvoMh$^;kOhl?`0yNiyrC#HJH=tqOH^T_d<2Z+ zeN>Y9Zn!X4*DMCK^o75Zk2621bdmV7Rx@AX^alBG4%~;G_vUoxhfhFRlR&+3WwF^T zaL)8xPq|wCZoNT^>3J0K?e{J-kl+hu2rZI>CUv#-z&u@`hjeb+bBZ>bcciQVZ{SbW zez04s9oFEgc8Z+Kp{XFX`MVf-s&w9*dx7wLen(_@y34}Qz@&`$2+osqfxz4&d}{Ql z*g1ag00Gu+$C`0avds{Q65BfGsu9`_`dML*rX~hyWIe$T>CsPRoLIr%MTk3pJ^2zH1qub1MBzPG}PO;Wmav9w%F7?%l=xIf#LlP`! z_Nw;xBQY9anH5-c8A4mME}?{iewjz(Sq-29r{fV;Fc>fv%0!W@(+{={Xl-sJ6aMoc z)9Q+$bchoTGTyWU_oI19!)bD=IG&OImfy;VxNXoIO2hYEfO~MkE#IXTK(~?Z&!ae! zl8z{D&2PC$Q*OBC(rS~-*-GHNJ6AC$@eve>LB@Iq;jbBZj`wk4|LGogE||Ie=M5g= z9d`uYQ1^Sr_q2wmZE>w2WG)!F%^KiqyaDtIAct?}D~JP4shTJy5Bg+-(EA8aXaxbd~BKMtTf2iQ69jD1o* zZF9*S3!v-TdqwK$%&?91Sh2=e63;X0Lci@n7y3XOu2ofyL9^-I767eHESAq{m+@*r zbVDx!FQ|AjT;!bYsXv8ilQjy~Chiu&HNhFXt3R_6kMC8~ChEFqG@MWu#1Q1#=~#ix zrkHpJre_?#r=N0wv`-7cHHqU`phJX2M_^{H0~{VP79Dv{6YP)oA1&TSfKPEPZn2)G z9o{U1huZBLL;Tp_0OYw@+9z(jkrwIGdUrOhKJUbwy?WBt zlIK)*K0lQCY0qZ!$%1?3A#-S70F#YyUnmJF*`xx?aH5;gE5pe-15w)EB#nuf6B*c~ z8Z25NtY%6Wlb)bUA$w%HKs5$!Z*W?YKV-lE0@w^{4vw;J>=rn?u!rv$&eM+rpU6rc=j9>N2Op+C{D^mospMCjF2ZGhe4eADA#skp2EA26%p3Ex9wHW8l&Y@HX z$Qv)mHM}4*@M*#*ll5^hE9M^=q~eyWEai*P;4z<9ZYy!SlNE5nlc7gm;M&Q zKhKE4d*%A>^m0R?{N}y|i6i^k>^n4(wzKvlQeHq{l&JuFD~sTsdhs`(?lFK@Q{pU~ zb!M3c@*3IwN1RUOVjY5>uT+s-2QLWY z4T2>fiSn>>Fob+%B868-v9D@AfWr#M8eM6w#eAlhc#zk6jkLxGBGk`E3$!A@*am!R zy>29&ptYK6>cvP`b!syNp)Q$0UOW|-O@)8!?94GOYF_}+zlW%fCEl|Tep_zx05g6q z>tp47e-&R*hSNe{6{H!mL?+j$c^TXT{C&@T-xIaesNCl05 z9SLb@q&mSb)I{VXMaiWa3PWj=Ed!>*GwUe;^|uk=Pz$njNnfFY^MM>E?zqhf6^{}0 zx&~~dA5#}1ig~7HvOQ#;d9JZBeEQ+}-~v$at`m!(ai z$w(H&mWCC~;PQ1$%iuz3`>dWeb3_p}X>L2LK%2l59Tyc}4m0>9A!8rhoU3m>i2+hl zx?*qs*c^j}+WPs>&v1%1Ko8_ivAGIn@QK7A`hDz-Emkcgv2@wTbYhkiwX2l=xz*XG zaiNg+j4F-I>9v+LjosI-QECrtKjp&0T@xIMKVr+&)gyb4@b3y?2CA?=ooN zT#;rU86WLh(e@#mF*rk(NV-qSIZyr z$6!ZUmzD)%yO-ot`rw3rp6?*_l*@Z*IB0xn4|BGPWHNc-1ZUnNSMWmDh=EzWJRP`) zl%d%J613oXzh5;VY^XWJi{lB`f#u+ThvtP7 zq(HK<4>tw(=yzSBWtYO}XI`S1pMBe3!jFxBHIuwJ(@%zdQFi1Q_hU2eDuHqXte7Ki zOV55H2D6u#4oTfr7|u*3p75KF&jaLEDpxk!4*bhPc%mpfj)Us3XIG3 zIKMX^s^1wt8YK7Ky^UOG=w!o5e7W-<&c|fw2{;Q11vm@J{)@N3-p1U>!0~sKWHaL= zWV(0}1IIyt1p%=_-Fe5Kfzc71wg}`RDDntVZv;4!=&XXF-$48jS0Sc;eDy@Sg;+{A zFStc{dXT}kcIjMXb4F7MbX~2%i;UrBxm%qmLKb|2=?uPr00-$MEUIGR5+JG2l2Nq` zkM{{1RO_R)+8oQ6x&-^kCj)W8Z}TJjS*Wm4>hf+4#VJP)OBaDF%3pms7DclusBUw} z{ND#!*I6h85g6DzNvdAmnwWY{&+!KZM4DGzeHI?MR@+~|su0{y-5-nICz_MIT_#FE zm<5f3zlaKq!XyvY3H`9s&T};z!cK}G%;~!rpzk9-6L}4Rg7vXtKFsl}@sT#U#7)x- z7UWue5sa$R>N&b{J61&gvKcKlozH*;OjoDR+elkh|4bJ!_3AZNMOu?n9&|L>OTD78 z^i->ah_Mqc|Ev)KNDzfu1P3grBIM#%`QZqj5W{qu(HocQhjyS;UINoP`{J+DvV?|1 z_sw6Yr3z6%e7JKVDY<$P=M)dbk@~Yw9|2!Cw!io3%j92wTD!c^e9Vj+7VqXo3>u#= zv#M{HHJ=e$X5vQ>>ML?E8#UlmvJgTnb73{PSPTf*0)mcj6C z{KsfUbDK|F$E(k;ER%8HMdDi`=BfpZzP3cl5yJHu;v^o2FkHNk;cXc17tL8T!CsYI zfeZ6sw@;8ia|mY_AXjCS?kUfxdjDB28)~Tz1dGE|{VfBS9`0m2!m1yG?hR})er^pl4c@9Aq+|}ZlDaHL)K$O| z%9Jp-imI-Id0|(d5{v~w6mx)tUKfbuVD`xNt04Mry%M+jXzE>4(TBsx#&=@wT2Vh) z1yeEY&~17>0%P(eHP0HB^|7C+WJxQBTG$uyOWY@iDloRIb-Cf!p<{WQHR!422#F34 zG`v|#CJ^G}y9U*7jgTlD{D&y$Iv{6&PYG>{Ixg$pGk?lWrE#PJ8KunQC@}^6OP!|< zS;}p3to{S|uZz%kKe|;A0bL0XxPB&Q{J(9PyX`+Kr`k~r2}yP^ND{8!v7Q1&vtk& z2Y}l@J@{|2`oA%sxvM9i0V+8IXrZ4;tey)d;LZI70Kbim<4=WoTPZy=Yd|34v#$Kh zx|#YJ8s`J>W&jt#GcMpx84w2Z3ur-rK7gf-p5cE)=w1R2*|0mj12hvapuUWM0b~dG zMg9p8FmAZI@i{q~0@QuY44&mMUNXd7z>U58shA3o`p5eVLpq>+{(<3->DWuSFVZwC zxd50Uz(w~LxC4}bgag#q#NNokK@yNc+Q|Ap!u>Ddy+df>v;j@I12CDNN9do+0^n8p zMQs7X#+FVF0C5muGfN{r0|Nkql%BQT|K(DDNdR2pzM=_ea5+GO|J67`05AV92t@4l z0Qno0078PIHdaQGHZ~Scw!dzgqjK~3B7kf>BcP__&lLyU(cu3B^uLo%{j|Mb0NR)tkeT7Hcwp4O# z)yzu>cvG(d9~0a^)eZ;;%3ksk@F&1eEBje~ zW+-_s)&RgiweQc!otF>4%vbXKaOU41{!hw?|2`Ld3I8$&#WOsq>EG)1ANb!{N4z9@ zsU!bPG-~-bqCeIDzo^Q;gnucB{tRzm{ZH^Orphm2U+REA!*<*J6YQV83@&xoDl%#wnl5qcBqCcAF-vX5{30}(oJrnSH z{RY85hylK2dMOh2%oO1J8%)0?8TOL%rS8)+CsDv}aQ>4D)Jv+DLK)9gI^n-T^$)Tc zFPUD75qJm!Y-KBqj;JP4dV4 z`X{lGmn<)1IGz330}s}Jrjtf{(lnuuNHe5(ezA(pYa=1|Ff-LhPFK8 zyJh_b{yzu0yll6ZkpRzRjezyYivjyjW7QwO;@6X`m;2Apn2EK2!~7S}-*=;5*7K$B z`x(=!^?zgj(-`&ApZJXI09aDLXaT@<;CH=?fBOY5d|b~wBA@@p^K#nxr`)?i?SqTupI_PJ(A3cx`z~9mX_*)>L F{|7XC?P&l2 diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3b803211..00000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Tue Aug 20 14:39:08 MSK 2019 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/android/gradlew b/android/gradlew deleted file mode 100755 index cccdd3d5..00000000 --- a/android/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat deleted file mode 100644 index f9553162..00000000 --- a/android/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/jni/Android.mk b/android/jni/Android.mk deleted file mode 100755 index 07dc7080..00000000 --- a/android/jni/Android.mk +++ /dev/null @@ -1,73 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := i2pd -LOCAL_CPP_FEATURES := rtti exceptions -LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH) -LOCAL_STATIC_LIBRARIES := \ - boost_system \ - boost_date_time \ - boost_filesystem \ - boost_program_options \ - crypto ssl \ - miniupnpc -LOCAL_LDLIBS := -lz - -LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \ - $(wildcard $(LIB_SRC_PATH)/*.cpp)\ - $(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\ - $(DAEMON_SRC_PATH)/Daemon.cpp \ - $(DAEMON_SRC_PATH)/UPnP.cpp \ - $(DAEMON_SRC_PATH)/HTTPServer.cpp \ - $(DAEMON_SRC_PATH)/I2PControl.cpp - -include $(BUILD_SHARED_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := boost_system -LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include -include $(PREBUILT_STATIC_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := boost_date_time -LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include -include $(PREBUILT_STATIC_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := boost_filesystem -LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include -include $(PREBUILT_STATIC_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := boost_program_options -LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include -include $(PREBUILT_STATIC_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := crypto -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include -include $(PREBUILT_STATIC_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := ssl -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libssl.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include -LOCAL_STATIC_LIBRARIES := crypto -include $(PREBUILT_STATIC_LIBRARY) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := miniupnpc -LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a -LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include -include $(PREBUILT_STATIC_LIBRARY) diff --git a/android/jni/Application.mk b/android/jni/Application.mk deleted file mode 100755 index 0c291661..00000000 --- a/android/jni/Application.mk +++ /dev/null @@ -1,36 +0,0 @@ -#APP_ABI := armeabi-v7a x86 -#APP_PLATFORM := android-14 - -# ABI arm64-v8a and x86_64 supported only from platform-21 -#APP_ABI := arm64-v8a x86_64 -#APP_PLATFORM := android-21 - -NDK_TOOLCHAIN_VERSION := clang -#APP_STL := c++_shared -APP_STL := c++_static - -# Enable c++17 extensions in source code -APP_CPPFLAGS += -std=c++17 -fexceptions -frtti - -APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP -ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) -APP_CPPFLAGS += -DANDROID_ARM7A -endif - -# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0 -# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/android-ifaddrs.git -# change to your own -I2PD_LIBS_PATH = /path/to/libraries -BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt -OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt -MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt -IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs - -# don't change me -I2PD_SRC_PATH = $(PWD)/.. - -LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd -LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client -DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp deleted file mode 100644 index 39c06ea0..00000000 --- a/android/jni/DaemonAndroid.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* -* 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 -#include -#include -#include -#include -#include -//#include "mainwindow.h" -#include "FS.h" -#include "DaemonAndroid.h" -#include "Daemon.h" - -namespace i2p -{ -namespace android -{ -/* Worker::Worker (DaemonAndroidImpl& daemon): - m_Daemon (daemon) - { - } - - void Worker::startDaemon() - { - Log.d(TAG"Performing daemon start..."); - m_Daemon.start(); - Log.d(TAG"Daemon started."); - emit resultReady(); - } - void Worker::restartDaemon() - { - Log.d(TAG"Performing daemon restart..."); - m_Daemon.restart(); - Log.d(TAG"Daemon restarted."); - emit resultReady(); - } - void Worker::stopDaemon() { - Log.d(TAG"Performing daemon stop..."); - m_Daemon.stop(); - Log.d(TAG"Daemon stopped."); - emit resultReady(); - } - - Controller::Controller(DaemonAndroidImpl& daemon): - m_Daemon (daemon) - { - Worker *worker = new Worker (m_Daemon); - worker->moveToThread(&workerThread); - connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); - connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); - connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); - connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); - connect(worker, &Worker::resultReady, this, &Controller::handleResults); - workerThread.start(); - } - Controller::~Controller() - { - Log.d(TAG"Closing and waiting for daemon worker thread..."); - workerThread.quit(); - workerThread.wait(); - Log.d(TAG"Waiting for daemon worker thread finished."); - if(m_Daemon.isRunning()) - { - Log.d(TAG"Stopping the daemon..."); - m_Daemon.stop(); - Log.d(TAG"Stopped the daemon."); - } - } -*/ - std::string dataDir = ""; - - DaemonAndroidImpl::DaemonAndroidImpl () - //: - /*mutex(nullptr), */ - //m_IsRunning(false), - //m_RunningChangedCallback(nullptr) - { - } - - DaemonAndroidImpl::~DaemonAndroidImpl () - { - //delete mutex; - } - - bool DaemonAndroidImpl::init(int argc, char* argv[]) - { - //mutex=new QMutex(QMutex::Recursive); - //setRunningCallback(0); - //m_IsRunning=false; - - // make sure assets are ready before proceed - i2p::fs::DetectDataDir(dataDir, false); - int numAttempts = 0; - do - { - if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready - numAttempts++; - std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second - } - while (numAttempts <= 10); // 10 seconds max - return Daemon.init(argc,argv); - } - - void DaemonAndroidImpl::start() - { - //QMutexLocker locker(mutex); - //setRunning(true); - Daemon.start(); - } - - void DaemonAndroidImpl::stop() - { - //QMutexLocker locker(mutex); - Daemon.stop(); - //setRunning(false); - } - - void DaemonAndroidImpl::restart() - { - //QMutexLocker locker(mutex); - stop(); - start(); - } - /* - void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb) - { - m_RunningChangedCallback = cb; - } - - bool DaemonAndroidImpl::isRunning() - { - return m_IsRunning; - } - - void DaemonAndroidImpl::setRunning(bool newValue) - { - bool oldValue = m_IsRunning; - if(oldValue!=newValue) - { - m_IsRunning = newValue; - if(m_RunningChangedCallback) - m_RunningChangedCallback(); - } - } -*/ - static DaemonAndroidImpl daemon; - static char* argv[1]={strdup("tmp")}; - /** - * returns error details if failed - * returns "ok" if daemon initialized and started okay - */ - std::string start(/*int argc, char* argv[]*/) - { - try - { - //int result; - - { - //Log.d(TAG"Initialising the daemon..."); - bool daemonInitSuccess = daemon.init(1,argv); - if(!daemonInitSuccess) - { - //QMessageBox::critical(0, "Error", "Daemon init failed"); - return "Daemon init failed"; - } - //Log.d(TAG"Initialised, creating the main window..."); - //MainWindow w; - //Log.d(TAG"Before main window.show()..."); - //w.show (); - - { - //i2p::qt::Controller daemonQtController(daemon); - //Log.d(TAG"Starting the daemon..."); - //emit daemonQtController.startDaemon(); - //daemon.start (); - //Log.d(TAG"Starting GUI event loop..."); - //result = app.exec(); - //daemon.stop (); - daemon.start(); - } - } - - //QMessageBox::information(&w, "Debug", "demon stopped"); - //Log.d(TAG"Exiting the application"); - //return result; - } - catch (boost::exception& ex) - { - std::stringstream ss; - ss << boost::diagnostic_information(ex); - return ss.str(); - } - catch (std::exception& ex) - { - std::stringstream ss; - ss << ex.what(); - return ss.str(); - } - catch(...) - { - return "unknown exception"; - } - return "ok"; - } - - void stop() - { - daemon.stop(); - } - - void SetDataDir(std::string jdataDir) - { - dataDir = jdataDir; - } -} -} diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h deleted file mode 100644 index 912f6f49..00000000 --- a/android/jni/DaemonAndroid.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -* 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 DAEMON_ANDROID_H -#define DAEMON_ANDROID_H - -#include - -namespace i2p -{ -namespace android -{ - class DaemonAndroidImpl - { - public: - - DaemonAndroidImpl (); - ~DaemonAndroidImpl (); - - //typedef void (*runningChangedCallback)(); - - /** - * @return success - */ - bool init(int argc, char* argv[]); - void start(); - void stop(); - void restart(); - //void setRunningCallback(runningChangedCallback cb); - //bool isRunning(); - private: - //void setRunning(bool running); - private: - //QMutex* mutex; - //bool m_IsRunning; - //runningChangedCallback m_RunningChangedCallback; - }; - - /** - * returns "ok" if daemon init failed - * returns errinfo if daemon initialized and started okay - */ - std::string start(); - - // stops the daemon - void stop(); - - // set datadir received from jni - void SetDataDir(std::string jdataDir); - /* - class Worker : public QObject - { - Q_OBJECT - public: - - Worker (DaemonAndroidImpl& daemon); - - private: - - DaemonAndroidImpl& m_Daemon; - - public slots: - void startDaemon(); - void restartDaemon(); - void stopDaemon(); - - signals: - void resultReady(); - }; - - class Controller : public QObject - { - Q_OBJECT - QThread workerThread; - public: - Controller(DaemonAndroidImpl& daemon); - ~Controller(); - private: - DaemonAndroidImpl& m_Daemon; - - public slots: - void handleResults(){} - signals: - void startDaemon(); - void stopDaemon(); - void restartDaemon(); - }; - */ -} -} - -#endif // DAEMON_ANDROID_H diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp deleted file mode 100755 index c6e309dd..00000000 --- a/android/jni/i2pd_android.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -* 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 -#include "org_purplei2p_i2pd_I2PD_JNI.h" -#include "DaemonAndroid.h" -#include "RouterContext.h" -#include "ClientContext.h" -#include "Transports.h" -#include "Tunnel.h" - -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith - (JNIEnv *env, jclass clazz) { -#if defined(__arm__) - #if defined(__ARM_ARCH_7A__) - #if defined(__ARM_NEON__) - #if defined(__ARM_PCS_VFP) - #define ABI "armeabi-v7a/NEON (hard-float)" - #else - #define ABI "armeabi-v7a/NEON" - #endif - #else - #if defined(__ARM_PCS_VFP) - #define ABI "armeabi-v7a (hard-float)" - #else - #define ABI "armeabi-v7a" - #endif - #endif - #else - #define ABI "armeabi" - #endif - #elif defined(__i386__) - #define ABI "x86" - #elif defined(__x86_64__) - #define ABI "x86_64" - #elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ - #define ABI "mips64" - #elif defined(__mips__) - #define ABI "mips" - #elif defined(__aarch64__) - #define ABI "arm64-v8a" - #else - #define ABI "unknown" -#endif - - return env->NewStringUTF(ABI); -} - -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon - (JNIEnv *env, jclass clazz) { - return env->NewStringUTF(i2p::android::start().c_str()); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon - (JNIEnv *env, jclass clazz) { - i2p::android::stop(); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels - (JNIEnv *env, jclass clazz) { - i2p::context.SetAcceptsTunnels (false); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels - (JNIEnv *env, jclass clazz) { - i2p::context.SetAcceptsTunnels (true); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs - (JNIEnv *env, jclass clazz) { - i2p::client::context.ReloadConfig(); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged - (JNIEnv *env, jclass clazz, jboolean isConnected) { - bool isConnectedBool = (bool) isConnected; - i2p::transport::transports.SetOnline (isConnectedBool); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir - (JNIEnv *env, jclass clazz, jstring jdataDir) { - - /* - // Method 1: convert UTF-16 jstring to std::string (https://stackoverflow.com/a/41820336) - const jclass stringClass = env->GetObjectClass(jdataDir); - const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); - const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jdataDir, getBytes, env->NewStringUTF("UTF-8")); - - size_t length = (size_t) env->GetArrayLength(stringJbytes); - jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL); - - std::string dataDir = std::string((char *)pBytes, length); - env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); - - env->DeleteLocalRef(stringJbytes); - env->DeleteLocalRef(stringClass); */ - - // Method 2: get string chars and make char array. - auto dataDir = env->GetStringUTFChars(jdataDir, NULL); - env->ReleaseStringUTFChars(jdataDir, dataDir); - - // Set DataDir - i2p::android::SetDataDir(dataDir); -} - -JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount - (JNIEnv *env, jclass clazz) { - return i2p::tunnel::tunnels.CountTransitTunnels(); -} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h deleted file mode 100644 index 68935ad1..00000000 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* 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 -*/ - -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class org_purplei2p_i2pd_I2PD_JNI */ - -#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI -#define _Included_org_purplei2p_i2pd_I2PD_JNI -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_purplei2p_i2pd_I2PD_JNI - * Method: stringFromJNI - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith - (JNIEnv *, jclass); - -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged - (JNIEnv * env, jclass clazz, jboolean isConnected); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir - (JNIEnv *env, jclass clazz, jstring jdataDir); - -JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount - (JNIEnv *, jclass); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/android/proguard-project.txt b/android/proguard-project.txt deleted file mode 100644 index f2fe1559..00000000 --- a/android/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/android/project.properties b/android/project.properties deleted file mode 100644 index 82181932..00000000 --- a/android/project.properties +++ /dev/null @@ -1,14 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-29 diff --git a/android/res/drawable/icon.png b/android/res/drawable/icon.png deleted file mode 100644 index 9a2f7404a20eef22adc6da0fb1538b6c507c97f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37177 zcmV*QKwrO!P)+0Ht zRaESi-jQBYNbmjLgGJWcdAp>$_ z`J?w6we1@u)>=cfJ8!n|?6j;k58iiE3;;|!Wg_VtsXqBlNzvc}V$_{NM-}yd=Ye~S z{2vcm6q7EFzw^3*a|P;kS2?*s&c6l#^0PC9|K+g|`_$pb%isb1$+lg)`2htRQb0Cs z-NApY*W+@z;0uEIyj|H7Cn(%(RH&kGWM!&=2$q--6#OBd699sN0Orwvwp)A0O0U}wzkPINXBlz0_gSn z|LL3C7i9e?5d;9-W*RnNK>olx`(<@Mn3`Dl=dmM45AXyOo}Hfgs~g{&Z@!hRTDP79 z;B78n;sH|!^9swCvOe;S0(hfi`7i00Ggt(GwB%9K zr%p<3zU%@Uzvm7!zveP4ACQ+-dBgk*QUH*%X3hB3xFDBbe&qq6bMjJewVL9!M8|kF zJ1vRdI6sPCc0p`sZbs_5+>9YpdK?g;PZRp&zhvUL(G&nKx#+_9VS`d?UV2*3Z@AhP zdg>8Vh;xK4InT;R45MbZ5CDL4PGjTk_t?xSJk@c5mK*&CZZ*bt zXQq$7KQVgv?7QxmAKT}i_sJ0@FDqRF0E;o_&kx;e4i;|{`OIk%{N6h)Jmez$Kd%~; z)Wobe03bg*^<{Dg5b0BqgRY;(p~p0=B^czVR8YJSYEEX8paH<-lj2L)XqzZuKX zHwzqx1pIy){yWrvKz~h6P1W$slWrLF9FmQ*4I2e&wHh}9fL^CRsRQ-A{A~To6{`Z* z&A%gI+N_+Xm?w31lztSKMYEtXAKbxxN>WnN2c;#I$j;0#?q@SNTP`_u0Uno2=I!wcV6H4C;(yTu;GD^KL48cX+WPGQ6`KY zB?7>-$){W~d`KL7<#_|&v{KR@{;Ppc9-G=RZ1DKe05Ga(+(|hBEqVV_0zd}@dh0H8PA@cX`&l0G?x;7t&8000BtxXL+COP~onJw1QY zfjIUgl#wHgL;&ENlbAT$19npeOLJVv^I~q{xjk^?MBl*kV{T?9IYk>fbnssQAUiwj zHyf+=#URHaG0teJYFaQMHL)O($BfH2q*9dzkd_x$-}9D}&QDKEPZHO!-=yAg+kH`S z@y_>^u9W|C8crp8$qCNYo>S%^py&>kGrh%AyLt20zXA|TOUu+gK>FmU#q0Bl08rmt zchdw*QIe4u6iwo&>a1@%S?_aYMXfsdl<|XJdiklViIfM~7W zRYHD#{_hAO>hR%3zv)VOA0WplsVOOf$Lk5D4$K&wEu@W2mEz&nx``+YUFF-0LnrBJ zvwj1z&)U4PWQ`mgnHy~x$-`jq@4&$zP(5qvS|%i=M7_Iu_3AG&Gc$#a8#na<(kDkR zZ7ppS0IJH$FCS{iPmhzLS+mkEf{-dmIO&w>nrkoAXJn?{Rl7g9*eOq!ErxWi@gO-k zOyZzK;@$oVaJjB?;^cAH7z_rwfB$~%w|>9-3WdiKd&I@i=Ei2loE4Fm&}f^OB*Z|b z5^GaCDG16zPcA@4jP4ir@dvA(?QS!lnP5LH$ho59Tm?C3UgQ7>7z=4_{*~g0(F3mB zvSnL`-|z2hLOc-`3U7=Ei0U0G@`9^9LBR`^C%A;GCgV>3}Fp`w>fjQKc#z zHt4{;$jVI|R$kn-F3^#BW^%-tA;yBbu+{kQ+a(a4+R*itn3Nj%!t&)SKiIN)YabjZ z0+2!d2a&Iquk3MTr`RLxGpxO@&7D2-e+rz`^fU@UjTxSlnnhEmB#{`1L|_6Dc$?Y@ zDhnk8{%`6pr&t7Z^Ecc1C09+?XJw~f+|eX$(yJqrW9_5Vkm{DnA=;C`#8SBEUk_BAAp`%>~h-+q>)H&wi=&E(Hh6 zD~O6&`suFQye{L-QHDv1Bh4401Xz%B z=FBFWw||2N@B4$@)lt7NE2HM|5yM*MUO2D*{E9hEfz2xuV^l2p_NnyP>9^O|?=T-xI^v8+6MfxF4N(BBzz zbDVjmB2Yf{57k#Ztuh41OZZ2RVe~s3m2~YQ&C~pSYmwRg%ih3xP${*b#>*hzBQV1fdW8qQ`eMiIb~|DAst@krxF!e zQ>axEB%x8M^ZI|za~fJWK>W|5#S8#X&4@bF)fD+De7O_jtdmv715y~AL(NSbl!(wY zMQih~BoWbgeBYk^Zvw#VIkWrPNlpYHiW(9CpwksR?dmIoh;cG8F+mmU8;K}OpqE?} zB9#^H834c-`&9!nY2swk+|sPkv!mpAQ|xJpLM$~4MpfgCNDz6W+DcTW?t&4@&vj0b zPP4pa^DcG8iqG_MiO$=*Tbzqc7!~g@_16^U6OY{KLO>uW9sUiXZ0`7U{KUdP6GF7i ztTg)md++yk>Yj)ggsB=25495L>Y|u6$B$`KgAk?g`12VLPm}pC9Yq; z?pN8aux$BK0)Vp>ZKG3Y!JL8mEO<1ZKtLc8kvA#rpt7(JQ3%2Hvz(IL-s%aBo{$kY z@0`mYWd78PBXot31e2z*fIyA_2M32p^h&#Ln-mhtb`=$7-tfvx?|A^w{biMXnX40J zK}1p10Kgfg`}dSpb>yWq5^9QwE+^@^Yq@uKdA+|`szzb&x95lFeG+J=`Q7c8t8X% zq<%Cc!N?d72{V0f<~+9dJW2@x9lRxj&hEGGXFK`oasZ0Dzj2XM7G)rKM%Xm6eqYfIM^N43w0Vp0s|ir`rPnFq_RYvw8C6W6VPoFY}8O6oe42aFwhH zZl`r>{eAHLG!9lyZYtffc{c-q^vr}mxEk%x+2zrZ1~HCtXcS=Nhv1+@-irIXA7X!fLQzp@+UoY#k9zP`@N0On#`j4)zX#Y$M z6qurIg$O7vsxdzTS{>Sb8$Gfixay({uD<)3XP?*%fQ}kH3hUOcJLztiG1)r0z?Z(} z3ey~=i+e;0N*EZ7)S!Oj*)4vhZup=^sJ{g5IH5(h)U+g0Rawg~ynK%Fi;vbWr2d?l z4&z`DP|l%|qrG*UbM6jqBYwJVg{!lBDj_74o0mn4_m%a*@l(YhM0hhU(vtsGysOo?ZtXgjot=GhrG#@JJG-sZ zQ+Rx@K9aD~0U{B3i_!*7V5KzA7C4cI9Xxmtsj95ymtKBu{O2F6TP+6*XGR!@0wA3K zpi6bIc$Es`VOxst`qTaA5kf+#X-R!>oD6^fz`i{dODqxEmEC-k=n2#@N+b{h2-FC> zzJMfI&eyj$7%m$zHnVc_OwcoOZ_SAuB4kGaE){orA~@1#&UBqH!u)ddgt z?`3P;!4q}JY15{WZQHi%4O=y!e&{ zzi%om93oUz*7m`1vH$`AmF0~u*`3P&b%s_80i~T2A^~9Gauqcq!FIY}<`W`TuiWrX zc6Ro{#qTUO;Urn7V$d6MMQA3&qWwxArw6o=ku|{O}_L z0IDmSA9BP59&;({iK2P=xBWo`92(5JRGR9zh}Bnx&b{oi%eJ3$&fLOZdSLY9BF+7h za&H){%Y~N*L`uFLDuD>xrMN{+;0QK*+fT&t;$qUt(q&8e@Zm)hcWkX%8>gRTkpwdd zTa9DmgL4gyp3hi%X8c1dS1$igzkdCs&6_u?ed>Oa0dm`I3;3-IZYKaxRnh!s!BD@j z)4z#u&c3r~hXCLpM4~B8FS`2YNG2S1VCvKe#T}eE(3GPDSnz=L z2v?&8-l}#AL?pGa!FM8(C5_D$e9+*6Gm3Y&d>v~zQ=n89aoB#U!=eFz@D}e%L^#R2 zd-v}Bi`{P3?b)+O=~MNS)W!PyBMZ!4QN4Sxke|v1+V?jDp7eY)a z2jD&4<4m71=|E7EmzOiAvZVWiSmR7i2oVprxasg{Fi;|~PTzJy^tIb+YHH61AiG>$ z!9F!Vi2(tC4?kR@4IDT?dgb+}>Jk%@?)0+l4ZdJ4Aw)Q+_CY|Q@er}<(~xMH!>TLX z*WGmUjql!c^Y5KMCnT%Hm!!_tjthsI2g1(+0wo8p-xi6$JJc>{0i=pi6ch)!~lB%j$*X zu0P-NlY)}nKPTF#=q9A-;uVFf2Q>h44hRsqOY4FnsCBcio_EZEoPXhLvgExl0Dx!b zrk~qVC%zG5n%Z*^a*Wp&ZeI_o-CBEK1qurbuXyYq4^+;-=2|{#OkrPl?ym(90O;!S z1pvrR4elodW77v+!M)&z2tvc|mO=!60$*RLNLvS2*X1*GYjJP8UE{C9V3*n+q<4+1n)zvy@WJf>Otu6q`cx88W40N`mE zv9sIibT3C4CJB^?>{!#d-?@#UR^L)FCC&NJs?{q$I{oz1>2uFN+n3J$wE+SE=bv|h z1^`!IcH95?u(K|p9(u1e0t&_zP%28XmMJ0TOU~J_e%rgJOc^%@0RHihNBR8u*PT#E z6h*<-M^T3{g!WKJ{jnb7-g_Pq0I<{y=d|ut$7_-Lae9I3 zd-|%5JzFITCbh}EN;W(EtDb-9fxDM~v4ed2>8E{g{8|BdYvG$(Y^+m$@b7n*q^8B+ z-|k<}`C--?^+G}jm18ZFLZX_TzU7;pZ%;mD>?8nq?zw09@2BM=Kf_{XQUsQ24a~WdaAh%mn~~ARO&Ehyc`-4C|=wwuo14(kQbim^IGTP}7dM4y{&Oyw$9 z4+4Y(5I}j5h3K|W32#>0o`;HhtJO+^!QfHBky{Yizq>j59jh=RQ71-eoGZfd+SzGVsM&Hh}QTIEOI)MYb6OLrOCZoXRrp|JA2-=*8m_tKeum9 z`Tq(a3l}cb5)xyjf4%tZ-jp=wv&~(rArO)C!)}ZouDXLW$!Q*?NNT=w_3CvC=ggTk z5dhE4&Hho>;t(wq0HSpfXC+FpOoK)a6@O4r_*oDP+zl}dh#(x^5Dy#PpSHL9wCo`; zch<)ILsIjG8N?)w2gcN2L7F-G6+-4}k35TioYf{jUH50M}f7 zg9Ir!+D01C9j;0|%3$Eu&Of&5Qivi?83AHEZU`;^I;^Z{ED)x}J=* zG;+Ni`^+=Rpn?LDpO;5dQc`GAQW8x}NT3-R8G_U4 zq}kcoG$|>GW@cv43FF6;1-IPttG8&s_yvp|J4RT&dW|+_%&4)GbBjO@WAxbEdue>dRYixZ(Hosi&SirYuf&R<=-DR;p!XXWcovz2D!4 znDg29n-hCyZ#~s%`+OC`m)iO*#kz{K(ZDOCqoYYnOUq#uG(97IURSeqk<&N{0An1C z9-sAKkOVVp>DoxSVb6}j;r-6}?2~1sR;!tGb$Na?Ao+QDq`keJgcOCUs!BNHFcAZ> ziYC(OYUiEk)-J~o_AhMZM?TNbh#jX9H$Y<$AqZ9pUgqa2Q@J3D+-k9KQIfb`r{l#X zC5Qa3J8oM*mM>i@1Ok4dC<;VTWQD^=vX@?dh5x1i0RWrbCb(U0Ejl`8l@J&@+HS}p zoNGV0loTK!gz~1YrG&{@m3P(fEm>ZVu(LGD=z zNRIPnQK-zvTK!9@F{1VQhFbSC=xt^@Mj1G8AZcuDq=8_Nn5lt;Ts~ZiG3ui@{O*v8 zzI@yI^pnq6I@>y|9i5$eRa0fAGQngr3hf;op_rH$?(_M)R-45;Y5WB5bANx%MF=@; zohS#%VyDGVyHyVl1pJH;${Azq{CTs;TmSih;(Obm+Vl{LMoz?6%a?1vDL~FTYYut$ z-S_zPGfpd9{`EKCq*yOe7(x;`N)M0#yrKImLUaxFciwULnA>i@spio~|G{s$<)))j zoCGOas#jW+IN8~DXWUg03fBld#LzHs7^z;{?kN_QvQ6vDEDh(PI#?4M8%vs+n*Qrp z5%F+Hq4dv<+UO#^9DUpwt6n@sYGTdZ8>p(=w(j)PreE~tn{QU+_sb`H_w4<_>zq1e z3fZx9CkgrkL~t`Q1O2s^vF@PH4IEyOR#R1-7Yv266h%$v8c#J-L%dzG#?t^yCTbuC zA`>0eQHh8Ui4cy{2mu2FV+s>7s-zZ`3MmZQa!9oT|;&D=Krg!Zhr_zv1N}l+DU@#ene>$ z73ex}js-&o<<-^JjtvBZ!}VMqY-g67XkypJh*5CL4iYKah+VJ}iAZ4s#d{;5?`zGs zi^zKI7(ZZdzkQ3w8QfYIZ&%&CP3h##N;_-TI*3d1xZI(xt)XCO9e{7ZvHF~|PS4%E zY1d~HCv@9$b5xp=tYX(5iG1>@z0+z201j>)#t@Nq_B@~=SIqBBPc=1yI9ptNL$uiHC50+un>GHN+Z9*I;_ zBAk*Plu*tOxkg){FxSd=-dVgA0Nt=*!=bH*4KfJy1#tsMwzamM)$nEI z)Kn=xd73l=+4dCJMXRQ9O=Dn0q(lEHx|A9G>PUJ0EpLdNGZcI`Fo(q&f}=XSQf{f5JNPW!oY=a5B<-{Zd- zK-R4+2@M;O`FLAP(|o_uAySuyC-ko(17L=`nj=n7X4Jy zFl0Cr87EK_u2Pk&#K-(XF9hHIIlKsjf`CBbDgrEkAXCu6+^7yU1Sp+1{Myx*P96EqyI+1XYevA4pQoZ= zgnGc35da3g=J@kni<|)3o0^)AD@pOI1q1*JhZi+@Ts!V>tXh9>qGN`lXx$PyhHy!w zCd8SiqrP^@^sKCmf0dP$U$uVy1~z;4Z2JED?;iw-PxEsCNR(r;3C9n1n=>$CAbLoG z6a#@80R}-3F|Z(??%c7L4I12ULT#yVRjegPQJL=qSdZ{I1=V)=c>Ug)GwxfxZR_nQ zE-ntc7Ljlmm@zrd7d1y`mVcMvamEZb<|134sxt6UkcR{h_fx_l9UTr~ZKEI%iNG0W z#I1VJ#k^?J+OW@8-mx!K+2IkqyX_H&(!VdMS^6Y@XWTZuIyTazbFv@a zUi14pMY$(XM_L1)vAllif8Dlq=RE*$*=3iLmtX!j2LMqJs4`OJWDQ9eX)4%zcH~qG zJ%U1Wa8N=KQbWpXfls7eTJd-VwkBP*9mgS$AUtLD+1vlg#0iN-@QHo z6f%{$PxF%|r43D5JBmXUoqIwRHD1xX&S8sO(ox&C{CnwJNtPsPb2vC>j5+LfF3B<< zGGqvU3 z^uGJAd3efcmvsK=|8AxCJ^1&Zv~&5S1%z`hWM*alzN69fSc2t@kixo;Inbpjz4`{f_>v2GTx_h+*wmz16YMii^%uT9#ynL2L(0U!VWGz0 zKU!bY?bXU>Ab^h}BOOwEd#93;l5khBqyJwV#{3^u@A!W9DyX>8&DO!-aQ(&S4m>Oi z`YWBxeo3Ti9Wqp(hb&{7qH+a378JlidtIWVPXUD8N(0riZp}-p0`;iS>aaVse}7G& zVPj%O@{-!(>JJGay}pp3*XzZ|$Vg_;>)C{f6WNO|zIa02oJr$G3CmWkgm?)*uLe# zNs}g2EnBu?`Nfx9NCEI*C`14t5C~*Mi4nrlC>7@ndO=5YOoq{F&hz@aKOuxD7hQ5r z+{f>2xi!|=TRCN^A`jZ*$AtUymIz_N|()8@AV#)PN8|?GbjJPLS2n zqerp#mMjU@*N2zG>@P1r;X1Hv)jDn7+}Wgf?_MbwY@@~H?HU2-$f80F8eE|K9B`b} z7Nl3AV;u7}Z_2Z==F>vzF{ev82n29&rNz5Kg1)kB$|=*&SoEK_O2e@yrJOMZz$1T* z|J_Ya(eZ;{u5pG4(W)+N`$XJjs(RCz9((i7b=z8EW1|=8LzBnmo&pSaYO%@@4hJhND%2J)e)kt^hWy8)eO^_8b)NxL^_JE>App2D#&R9;=R6%{n4~fu5RY%y4;_L^r`G8GM2Jt8 zUn(oDzLpT80$@=l$L3oiE*)wldhj2}820Roh4zqJdD*i>5{lweyLMDOWaZQ6$%5lV z#a|$Vz+eiZTiXbVX3QKMfpZEYk>HRaPy&Gx(4GXR#sQ6SC>lp)TM+MWZO5lOJ7K3z zoMs#ahsOrSIY>{@&LSFleV|$UxNDVILaR433whAj(EV=jq?wYE!mF#R``2mn$ZFQg9=%+5`kOM>M9xX&bzO5{(bg4o8RC3 z3X2pRcMLQ3w@XAks_#;{hG;nw>pQnocd#)=2xOdQ5;OFKoS5Mxgg`deqf1$eQ}PI& zz90jq4{#vDBtaG^1WG{2w?6_U5CsCgND*U|FfrGLIfapE4|L=0s%;1wG$hklfB`1K zpzZXQ(*JaSPOIdmSM!JTn_s=FasvQFIwPsy=VxxWyKh~|uK|$uwhjQG)fH_W21~#Q zW}2p_2^`?ZoIec*yDBlrPOc~*&F#gL8?b$IO>KQ?f*gJOAVaR@XaMQ8NO~&M7PXTX zyUGVR^yBn0wcgFB}u;nryh5W^4I4LgiHYy}wW{df4Nyr+ytN%;Rd zkzz_eJH}*K@oD*fZ1mS5Tc6CfcI*`vd%t2qJO4{}t9!xkF1y+VfQ%hGmK5*nTX6NO z3(^M-E}+}D?O^9#bZYAI&&n5x!Ghs-Qx?-$;5aiy90JvA^{%f4s;_D(oK$#5=T{By z&b3WR(o^}URGfiBCNhfsrFhR%0)ue`WNHBakxw(D6yW+&nDx7G|Lk;3$hE-bS0M=m zA(f-HJ&09hZfvdgqO#2oPk@0Fz@ih75~;_aBooGETagl_gHEJ9scs;o0{4Dcg)jE{ z(d`c~QzE0{|iml!vrFck0(@K>(nsshI;1cJHj{G+6vLf!n9ZBs%Pe9Ji0J zQHw5}xw&EPt<@g<{quS}{#891T?z`4O*o?<0y76i;?#UQ3X;uWjAMC;8~83Gc=7OpfIo=b4LlFlPE-yprqc9 zm)11l;~gCsl5ECxljG1o!Gw^?U^9yRz7K2o!mV9Oa(epgufJY?xSdd_Ga_BkxSJbI zMxKqL3SBAn}-h(ui? zs!1!l#STzC12h8a*TKo65GO<+n%clL1`{=5rF#|DGZ~UD3*q*Z<2w(|IRud*Abf#y zhv{+OSt)S)R1`P)aqovU=niPOe@-gKW?SJ2XwVpkEK*3qw`(4IGgv{Dff53{NknfDYe^eJMX*i zue;~WKDY7UGc^dYu?|R*$OjE7;2(YT5$^-!B$CmiN7J=y*Rp%>`@fh+AA03On=r1( ztV`yMD?j2I7zjitq#W(a2J}m^A>OPZE5-=BK|o03sCR`>)2X1nTR?;-1^t8+Wb-7v z(Eb5xg)}&HX<%GAZb$(F$+8Dgrcx}qp+7hnwp4j=$9vW27iYvnXQ#q$6cJJx2!NW- zAZpu#X!oiJsT=|UtOfzmRvD>LIylV|x_VqQgG}+t+GafVMLo_O9EAnb5x9oO+W2lU1uJp5xke_=XCXIiki%7dH# zQ-Se0Hrz8S83G|-oMTUe4C4db$HNQu`@+62|A)Ff_%ClqemHGKI>3=B^M*8vWQ%(T%Ou9@q>b<`zcc%ps8w zDS<2y?5OqO>Q~D!Ip2;uPESOnS;GAv)!~&5e(2O`P?X+>8XYv*a01E+5g0(BvViCf z*21q<17dr#tmjLjqMYxjq+x4iQlc*rigKi-rOGe7@S-O&hD7m@eY`{> zC?UsM7GWTSLN@J()mVk+FV2Ed7fz*00>wL<+wkW47Hq2UKokfvV+`;s3_eA}@C+*o z5{;;Fbz*;8BW%WaC?W9}AqmGndZPasMm z(9g`3$YC8Fu8aL%?RRF`o}QML-mQ>E-_*0MO7ZsK0n3t;n@if;+WG+bIb__}Nvx!F zA6@$SrX4T7`si$fkm3}n;TYVk@Oo*Zk)p-F5`Q`)9)priU>wjm$2}ibW69PISPTMc zI)YfTtpi)CJQ$KHs@526XvU_<|Zh5DwPGuoZFp zHF$#>5*;!os`fPV2t=p+H3?JkFr z=0Vk1PvHOk#kakkT!a9OGOh?5DrC{ZEOLfw6!P_2&@!~Gt?d$lnC7~gqM{s5*=3CA zQo1|f>xCmK(n)-NUmqYprIeKJLtb8v^uR-Z^Tj0^B7#1{c$r3$qqia)giwgadg!GZ z+%qc)y_-HP-qMamo7(W~MVUBjXe1`&*pMA-z^XDg-dNv){s|_eIrZ=aG}w#+hNoH4 z>2+g6bp>J^i3s{-fM_`KhLsG22r${}KxjE0IVTM@9YNgjZWSIpI~5}{tf+1e;+D57 zAqfQkyeJdN5i+_08WfE~76>98G8BcQxY39GEdeMRM_QB)I*G#NQ=w`=MzjHw@@yz? z3E-J!jmU{LAl@z`H_ixeh~e4gjTn|@#)xz)7H@6>s2!SOJqpkJ05D-#pa>iakwu$k z)8{C9ni1vcQpN`T>eZqaRS@a4LlruFK_7SBe*0~`vlyK-XEyfjEA9j2r;yy7!K|jX zLMq$oUH|YCx148|vmz*wkJ`NgD1vl1Cglq_HQx?O0KdX<=X+JSVoVI?6gr_O99DyX z>=*-1$+M%fHHfE{H6Sm}h%~1jK{cE*9hPQ6Nb_MuSt(*1u?YGN;81bsw)}AY#b{7b z=UIt6PmjUaY#aWts1mucM%*$r0ZncNk9=8=nzkTbyetcmW(l6428{tui-bB?2oHQ* zhrfJKgU@z%VpC-|-rUfN_qMh}7AOi+E%1jJLMnq9c>;3Pk!Bi{CFc0>@r5A zTd=*xi~b2lBsp|&`7~^~@ET2j^r$cdDi+6v_4W{J1|@%O>>Y-g0Gla7;x zDDuO_b>34Er|43);=JKDIGI2;HDtl(Vjsl0!CPK;|Hgu*9mz^IH6ZagI( zOZU03Xj3cxeOWd*fG>A<;`Mbcc;>qo7VakH4NI1U7L4NCoF|G;>K|vNRnpKyjQZ3pU3~Cc~G~&E9%W7iuW*58T!800` ze^weQEh&RD$|;T>GlEx?SM~vNqU6Tw7qI0kmWr({u5a%B+k%VCQm*Z2x@ifaFk3h} z{CjZe=m;c5=)gGe!S;4&47g-$EIa`XBK_9u)>ycpH!;_SMt2BLEp5bvTpR305uAq` z0|zCW5Njj&WY-?ptTNPK6gUrOOnc#=M1;;#0!ggELuaKRDN>K$y|y3ckBGtKJR54; zgSg|pDqJ)w8fOiSM5j;dDF_nWy`%=Ot!u%8sR_7YavTbhOo+9~h%}3cx9c!8)r=7t z7QC^c4Vx;uamJuX@Saw9#yKYC*|D#|kJr|6Vf%o`SkXD>{F#&-awwXj&#o*@ozN2Irw zp*y$}f190z0f{EOy{Qd>5X0qTqT%wXcx` z!sSQe`|B%qetz38;BBWa~~S zx-Y@86VG0lhS6CzfB?_0XvC$Xqah0vP3{oh-`b7^Qxl*v29Xj3RgSxs)S#>-fafpH z#LyHoLMj70#8Xr_2ZAa?Zkz#k&qzjnhl1LUAmpB|-rhF($Ineeaf1(wHnu`z{D74l zm}Ek?zxBX(o%n(q1puNjuLz=Xn=wzd2t#E98+w)$D013lk zYSidoTtEMd)VZ@}&#kQ)(_?5yYv5F)E}jEN z+GvhIZ_v=`E5(H)B49U)&=~OSibkAW7=?Jd+_UqamR3{5rn zxKm+8H0uPMJ}?5O=G$P9yl`5&Fr&bTduAphBU%qxBzS*o2UZlj@VB#4ArRo1Wlaz$ z!5_~^LYH5IKnNcBvH|P&cj4&^GLRobVGEr_*cBXrDlonx~p00`#_C4_Lj7|jIk(1|1}Uk#ck z3p!U}Mov^+Q$t5}ZEY=2PfwFNJ6*q++jYR*EH0g)YZ{F zd-kamMse}$J0Bf8IrA3I3nBo1$X(QXZ@JH_0Gz|^*AC3Y;nb}NjUQeydaVfO91$iF z56w-*wQualurvz>C7F7H;_!PFjUgjOk3YmEfD!_YbA(iekj9~xDV|y0fD1-MLoZUe z0~$Ws(SfHfNQWn&K`&9fzM&N#Y-`7p=cl6}$pn{Ag+PyTe=8n7KK&j|0wwT;G)x=d z00%)zgnVF3OuF!DL`FOS>_5Yu3y-G8{Q{*DHwzg&q((*S5kIfFqGV)Lbk`S`Uv}l6 zAAacZW&rZ2QKPkW>(>74Z7l~(SZYFyuw}SG z{e~LVn0U+I+P&KZLL}`_u2!$Q$g%~L3TW+C0N(RR8wQwkLU_hKWN?oje?9E8hg6OU zxi(xpIvO`EEQialLJW7Oga?*{m-Yo!2EU>~(ZcQN5hf8YtZYU|<(NAx3Ob46?Qhx; zXO}QJ&khb?eR(&Y`l=qcPD{Y#JR3T^M-NBuxzfX!8i5jc0~#jh*`Sl?LBEf)3Gj!y zPH-G@G@x+8cz{ZRksHJmZr2qho3vA|dj9Em)}*947XS#YTenuT+061U21r$Xvo@+| z*fWb3zP>&uXV=T0fBNahjN}1N^6<{gdZ5B%hZ zo?SI~JscDSH61~40D+z$R}yeY-(H{uon947wsoN16$-Dt5D2;h8g7}Ah%~1G*S}c~ zl>s6p2OuE?2R2yX95Bfg)$KvNu(A=?PKbj=Cm^UYEZW$LE62u#yN5f2c=+==OdH_9 z#Uo?T+8tg|h{IG>dSjqtQD;gC6z$+oP(l!87Que8b}9l6MmSfAELyoiNQF~BH8a%N z?{7wvdHtBNBgVPio)7?e>a;1s&ko4=(Iam(>MO6k@p^aEsG@-Vt=C#2PCu>ThFIso zhXC*e3m(wL$Hj?Jk&!}NTpS%eYSc*uOm1!(|Kp$T3`Rv;?rQUH5-8DY|GfnE+t9?I zv!bFc5Uz{#{*oVB2?YvtcvZZ#stJGns1{Xi0T|@)nv9^z@YuO&aQjp&c)Jpc#$b>r z7~=<&S7RJ{DI5>nyr=>NNhX{&zyX^50R+7)`VMJ8+-x(}Q!YR^%Bokh_A{$+P4L2>Uz&Dj1 zm~{dKN?_3oc>012lr;MBheZ`=aD`wsiZJRZ^b&=`BqF48{9#cA+Py0NI6Vn^iNfX6 z@chaq+<0m{2noAZi#NC7ud`ENH3;E&h=g50AiQeOZWLfQ3J9qTm2ClRsOZL$?Hzb+ zT??Arp>TWQae7CjXSb9ef}%GoMTo#Dk+?u)CJ>oXA~FKX2n0rn$iDr3&uc{B1e72A zUHk|~>uD+#BN1bqViEl#uCYZ#?if5|;PmFEHU)ri_BnHYQoR$u9UPi5aG;9pEDt$l zQUIA5DzREQaywU{O7;CJvr=?!jd#p zEB?WQoPVq?S^s97?Uazpya(;Z*gKjciNyYv5_I`B7-a!Ljl&aU2QpFQdwzR&KtoET z4zFI3jXU10#7zq;u;8==%pM$xfWnXxslyAGWa75PmALZNGF&j+iTrpIbP_>>D~MOu zw4kX=!K3ri5Mz^J(F?fa-73UdCCn&@Ky#OZzkgPT^NO4pmt#YdD+F025GjGhBqF46 zl(+a%((K3nWI zWX;DhvCfw+zx28V4?K8}Ys{FjWX+n@{3iv3F}{86I(g8{*+HI=pb_YS_67oPw?Ibe z`b7>Pagj}=V^Dj@g(hDcc5m2;UE6jc(jHO9fwi(hUK^PZwR%tW?i$fx(Ej}BJ<8o@ z-~NlFiT9Ro{>WiY-yTrf2g#y|asJ(>%95T7kAub-HdlEtAt&5&@~ykY4^kRYAZYg} zc=)q$Z1BRRS$N=+I^6qVEs7icxO#jnqRbMKB4oUDNfw@6(TIhc+F;TBKYQODCS`TE zeV_BR=`-7VUsx7cdY7Vth>DG9tg*#(6O))2)7~%fO^hZnro3u2u_Pw8SWyJTLQ{G# zyUXsfz3=q$%+t>K{+QjR2nyKnef?e6UR(+cGtZp+{Q7+dQ-3#Zpd!nLJ1;FkzE6hB zCg82w5T4sMfJbi}2~i;U_r^XL7RUD%=A$R1!>I^x+XZw5b-cDai1m#Tv|0KF4*H*jTwg_hPP$Cj;|U7ek6 zS z!hw;jbi{ey*)(6u<_eK502nZXyhZC0o3##dQ0qXiIRKl>;U^+_8wy>iWI5Kh?`rND zclKm$_gmYvPZA{K#!Xt>(a2uO_nh}02{g{F6l=P?0vC)E@T*IUvA;8cl1v+%GCkr> zOU3&@Bx&K-ueM`La}2kgTY#(PkCxFHJ^y-^)cZtTbEx(H&L ziIPkkCKWp|sn~_Fg-)brD2Ey^jN@48ma3XaokBm zw%1A;VXH@r5OQRG;C8!-%jH6MclSr)b-X$7c!g2V5OvZbr<`vxt{+BOnwsb(_B{~A z16cjTv9QSmrj^~3^JS{Da=j7z@^73*}O2IitBoaYGLjxHY7=Ws(Bp#2GL?S_Au^1T`7~lYo zSmwX_s;jGa?b&)!cTeY{L{uE%Rz{>b#1e-GAfpdD{Xr%&KQaU%dNlb2mfIy}aSBS(UB3XVjguRIdd4Hl2U92BmA-YD5 zl?h2(m8AM+W?7wAFZyEe$$vc+Kl*(YkY8;B)M#B~dXnd-F| zR;v52n-;(sZe3J?+ZR{BsZcQX{=!*=q^fi?epL&Pt(-S@tRud3PyP5YQ~$7f?Hhj^ zyv&4(ib^3bFV{Nbj5F9h_uTWLFS1387SX1rCQ1mQ2M!znaHz)o{BujQfBe&1F6r&- zz1U28tKD){zD>+iD0f2B(CzyL!$Ozy0s0RGgxQ z{Bb?VoS8GkbtxUcA%{)IkEs@R?W;8liwotBwhjw`HDltmnvM0F|7(meV&P0>oM)7+ z98S^BlT0Igkc@zXLm(6im6?Oun8tMLK%!OLpKKDElI=)JI&{I@n~=5j2_d=8Olk)T za*KOA-e~G2MUws=z!Ve^LI`|5AK$xo?+JbA8S@oqS6%tNR;==CY4$OO!Q#V`XhVAs zmVG4_i~@dtMLAU6g2{lcpoXN$U=1EDNg(h!L}WN6WOyY&rs(KQ;D6rg#)~`rm@~qI z+s-XONrnyU8zOjhR{*;^;_%0e!M+HGA_=I>vf<}xf6cpqLBpo&}3nEpR$rDthb}Okz zt&qN6mYjiyv+{&{_Uvpw_+dfvo+o$Bm6wz5&Mtv529M9jmM&X99Nk{E$j(yU+2}%`4+RH4R8-mF#(7`P|4i3gsdkHd;xSiS<1+_Y~9#Wrd zmKu}o@FN6WG_@E}w}ge*R!*^lo9tj&UTJ6J{)UdDfR|Q!CnN@nS9^tdUQrYo=R>@{gJG6!KZvjwYi}P9MIxx}QE~ns_o6J*mU;nB zkTe;R27@FJxD<-=EIVdaxG^fv0f$WR%w|7U9|&PYwjGPdr>92IJrdf3I{G386p13k zDI&`yBHJUwWE|FD=~ko!vPALCCmPY%tK#2Z8wGz<$2T6^gB>j)s5$^age(cE5&WUS zs-wH(2^At?_}iDq;lfEd5C)rpC)$92yDo%p{IdnuN#~9fWx-nDDrVy9F(*G|i-2}^@rEPyE3EDnCQd7L;(5=zk9;7VybN{&y>?x)QSs73q}rs1>lgV1ck`VMimw|qgHdWLut`E(P8u=O5#uj zJ?dxS-7y~94OysDM5Vbjr?}&Wh1azH_zyonRx&1LW@f@>vvHfv#uqL;hd=PZgB$?z za*J=L$r1PXlxe!jhZ6Rbr;}|O!sd&(@5&0CGscI6Zebv5!Y)&ogUvpRrRJ#mq6V7! zlV}-8qOmuLx*in*1xDvPF{#7}&0yHl9K-(Z1V-mM@ZE(4IIGG7)nLQjZqqulLPiMi zpREJyz@m?IGdX3a4BVwM2AJGVh%)iDokojP)GLf`WXhv$IR98ZQ+^yQ^N1jqy{QN`Yyyl*Y)AHlO8Kh1um69=fg)k)(;H zJ{4>0gDB3hLy;)F4hdOq86LZU45tVJKs6Xt-NN?P7~ZT6W7WP8Ksc_PmW}z(L*x;IP|=lkH=NMFij`;&Byc zR%hVvH%~x@`{bL;L*pv$cTM9 z^C;I`^CePSyI0u0eFqsz@bCHUojJew@BdotRtlC7Gv|C_X2PXZaHo=^N7NQ2YHkH} zbpGYKYrk^W@9+I>PhNhe(%m(neIft>fcbOJB5$sJTNpw%GKA}M)bwwRQ$|joXP?CK zY&k4sghl#3ntA*%$P8A+AQO?xL}DDA`;9Pq^#QTp45Hr%z|X>nQ569*)Z?d-PQ%oj zA)?vs@;2tB=N!0T+&Q)PJ#&BW;s1uqLoaq<>We;kI-!&dw!>1t5PJgzVF%v)!FV_n zg2vtizVzS@>}`)g5>m5OgaD!-KokUIdli&r*)cNLg;Dt~)D*chF-J> zG<He{83*B^ zG9v6#o$@~a{PXE+uf0Zx&fR@~yeIR{yY5&(joeFYV%`;|nuc`8M3aD^UtKG5+rif> zDhqzJX~WK)02Bb)CjyWm%goHA0|NsL0K_6&xe&(9l_>iDM4?JK(>pb(a$V7wPQ(*f zi{*zwhJZjI0wf}GiHMv4JZ7mpV1$K$6(RvMf&nv#AfgB%X7!o=&X6AN07bW8lNzfk zs@g?O*!k@Je>!;8Ew}$T+*9;zn^3_SQu=Fvf=GI%G-08C4m$U_v%TQNYHg7;c)KjWb92@b!N-qC2eP zk5`tXFkK#Q<_&)VgMEmz@7joFzYax_hsR5fHp?<$=sHH`IPkZd$D^j$eNy4nu>fLm zj?3?_$2em)$`ggd02%rtGLgt0^#E2R-(A-%w_k$+v^(=WQoK82;8V6abLNr${vM&O zuHFQIZ-4J5-_uY1a~@^+*H}sCDJVoD zKp+AaiNFnR@~9anAu~!NRt#Y)iaslVAc-PGVp?0Gvp>nTHb_Xb^TO(U`ywc!7mORJ zSLGa*V>M=$CGq%8RTzlr@Yp3hzP1hDcx(?O#Rf%^hC`kq?x<95z`+@VWm!n-2EZ98 z6>!z8LVR;UF~$|T5K>KC`?q?WJ2nm9o}UlPN?id%IgTO{gcBx;Z+!zUmvfL(^zcK> zVVDer>2OFC-&s_K+s>~5kV^LHsVhOGO4y8J=AC1d5V0DvxBaF!V88{oR3!RJe})^6BzgzNrD$A$y`K-CuEpuW<+)-^S*C?UX;0B>5NG~(A$#;0tZ-K$&CegV;EY7G*CE^ub zJXg*{iIT_5l|o)F7LiI?C{D0dd8(!IqB2^PMXe~0a-9fb76=3or1}S(as(1>xM)Hq z6p6sF7$%kZ;8X;x+T8;N3Q-i^JG(T97%GTR6d8)5fD&N)K|dZ{(*aIIESa1I-DG%e zcMwy{+{koE5CwwgxB0QDIf^NzZX|SuKdv|kyG=={M==h=V$gIGlpF9Wz-80&@YF4n zuy{faR3p`Q`Y_-adbnL71COom!93d}5JMOodOqTH2?yr|ayAhyq4HpNOMcNgBVRxG zZhdmhv>Mvq+4re$p6;*R2XOF-6Q>Zj%R%2=zatU!C+f#d$zEk5vVoCMd0g!;5UdiL zp)2!!*}5|lR##tl{S8J}Zy)O&@UzyAPF^!=wAeS$&psA_42J=xb?EW;8mg{po3$Li zv_tL5*c)q@kSk=6JUQFYxFK-hq(twJ1)AXs85l9RNepfg0zzzp46o=$rj*X}GS*Xpan(XUe#0W+5KBc|2~KTLg}jHi#$?d{}G@RnfM!MzL~#6eG1_IH(QBy14k@ zE@iQtPc%)hscoxM;%ef}Z+-Qf?8+OiCVO}8IUO7cdV0DL2n6_y88b;oM+e$l1BswN zR#!d2`-&i1yEHQ}F%e5<=?UAM2mX3@(Zq3+9I&#laXZqcU3<;+&Sfj#34ClG5AZz<^z*s3~+p76~>qMiJF4EE<~z)8eS>j)5}^V+&olXi_%5 zzo-ItU0IC_C+7m3BbGEFPz3bre?V8Y&3kw5IqjC|IyyRztQ59|;{Ji)?y(aypK-fA{zNh`I~35SmKKH2 zz5YwRb8BiMXDoZQ|LYayHP(|)-Lmnq$KT+e2tZ8zP>9;IzSa88KkjMx&p-e3u$IR7 z+WyUFx~Y>C+wv^N8R6g`5lr6a{lJ2gI*~>t)Fx`d#Y~7q0U>|^4IDkVa#}V_#vqVX z2ou*VoH;rZ6HC143aM!AizBJ&Fd2a)5(qR!Bt7&)02ro)M8be&ngAHCn30E;fB^zv zTA2$DMZmg-2!e4F=hdVG1ei4<9XFp@j9V91V$ry46ld6w&@IH&L126YUgPLu2nEGc zn+DJuEX3Ym3nn{C;H38BUOp`K9q~$AG3kx>pVQ?GY)6tEz-L4$ptC&?>+S1V@3NP7 zUa-ixWX|lcynekx&s(HQKe;0+y|PR{=lSObHud(mHw?}!e6sePCEwxzVqHC5Kbty# z#^@(w%UAuS=Sd-8hKK;l`NzBqO+k=kNsMuf!c^G}O>2O~4FD7pNk>BGsOwUph;(>$ zRu(Dx!W!m|O2;$bo`TF}Mx%&EV}n0Y#9}cJW?)pFjLWCx;PJ0d z#Kn_yAktJ~ZXLF_e)tZ1VY&?-yNJGkivDmCi9s(Wi}WJ}#^E8BAOQQjRS3k3bjM`8 z8`}-`K6;A;1QskJ5|LftnJ126<$r|-WASm(pnSwul$#|0Kz|@iE6U@z=N+u zt9E2(arWgKLh!l+Umfl~e_C&J-=XB9RfV= zTtCo-PbI`U+S=RNtywc>QbGs`^!b1F_xt}g@?~rFWB2v_Ggz-RBhC`T2m0dxiN-YC zoOKyUViOD=fn{amK#vOZIEzLEsSQKMfN;XVKq!eoR3DtE1ysYrKrjh^L_adIL2UOtQG|11A|?G z2=JR>`O>trlZATb&y&CFKKFF@AX|3q<^X70=bAnH>vA9X{@~ARyHk z{Aj~10+CSMl(`sM>|Jonjh=84wVg@W4$DK{0~C^?&k-pZ_5?$>v^Yrhb99e_^VD?h zP??wza@^NH6%WBUKkn-t=ur_&Si=>tArG>rGX{}l4#S2*K$v>aZS)OJWWT?OL_mne zlqIeOW_Hr|sI$ad@)^k0835YSzU6`5zM`wHxF&zk*oir9U%IKFDZg;?jV~?z_tMh} zAVcQ&`^|ICUC7;Tx4d!fhDJTCT@uJw&wnKG;_~N0uls9_gCt}`iA*FW5|JO8-uiH5 zVF2(6Zd{)>A7-KsDwnajISji@Pxyu>Cy=2YA>PDOA=U6m$tir0A^B(1;t**ncM)i6 zx$AIlE&#Y^MF%!CMN*$>5Kxjpv7;>x5t)PUPXOa4((N_a5ZeWjNZ=FAz6w+w^pApk>^ecYZmwv!|(Y>9W@zA6YS#o|XUsfK@AB z=h0|XFD@&gnVA{NKvVCgWLQ1FE~De>zeitK`f7ZQe@C*G28}RrP&<={fx(Jso{P3tL;GfIv^0LTBjk9q;$RkMv%rVirq*!ZxUE>#>Vy3uxHY9!GE3K!!_% zNHI)K%{kB!(2>v>L_&tWM_V9?fv64vIl~tL2Zv3{MXlbO>U^9~Wso9asp53cIIT31 zbMc%1TyZl1K5AU`X-$qERXfc&GpCC-K&l$`)jj~y+*z~415I1lr=FyLkhL|pG5}gy zW}4uZ-9lSi+v@;c-%?P2!S3*Z>&FXKb1SvtoJyq#`Erh>bDe11paiGZnWrEyxrvcV z1t#!rH1sy2sYgYgSAuEr6ECy!RETA9jt^p(5(rMZ{4hj9Cs2Zw`$BkO+W@w;#*ow* zY!XFWw=g!}iJx6qgmFcw9Tm;ugXLl}2w)DINU^m!2Aj=;c$5z6D-NpMat2GxL7Ucv zd^vYek(Ycxs3js`gq2IZ^R);2|MMpZSX#HcwxgoDf;82hz9i`DHf%D#dh<;r5)RXX zflpI`N0syAG=r9Tj37os*n^3mF1OC}HA?hwAXqnjU<4P7YRle++)MxEN=R z@*>+U!RruEk!8pC&dG;J37*>A55+AZoJfiB*kw9MUCJSf6q^o4!HukA`Zrlj#{s<; z5)n=!4>-9VP&)peSDeKoG!MUDa;e zZ0)&vg|Xphuc_;HJsVyrwI;iSbm}n_Dw`GXkzlU@;C+plBILqCaXtK;AI`kP1}e#D$<4 z0wux;Uo!%sNHA4cN zEcxpl=Kd>JCg1()3Uk9dkB45C>f#4QA9YzyYBv}dw>bNN6e4vLN@+HF{R-AMhOlyP z2v2P2gF47+NXa3I0fDBZ5T4&QfO}u>z@3BPj(VK++9N}(V?rpkF~~UjqsDNUMhK8J zIVKi42gmXG5nF_kK+qf3asOLgC`wasW|bHHF$2*gLvT>e&0`Z_vQ+-@Zetjd;)SM4 z$IwPk{kJ0J<3O?*A`wr{6N5q~B0X20mHyW!AO14{>z~j3Oa2@npMv%F^e_NCBO^Wa zSz@T;s`aZOi(AM1(uabnOr&81DMNja ziiM-ov7seo%r>VQd~449TC+!f|dPfYz(PA zRc6^RccgbvdG}C%!XXRT(H6(ek2hjZM;s1WNU2^8R>&wJM=*RzgC5~W&$lAoC1Kv= zOhl6w>=I2;3q^FuB8Ar>!mv0LnPOc-1kA{L-*FN}%0si(28oC#)zBQA{6&?$6l1i~ z#c-1Ov2aw&$;06|3fyNz=5?fV@qV|Gdn-@ZTkOzS`VFU!5!fZ!F}hMn5Xq44YQb<=Ds z1JmtQc5eb_66S(}(+rT-;ZvPoBt!IJp>x)F_~?%S z=vlehpQ%tw!2eQLcx(dle0ESm zQu-pt$U8U(95w;}ezy;0nKn!y&jhe!!RaTC`(upNzkNj!PWWRzy6sDg$Rq!{Pu4C;7sdjNAscrdZV1yL06 zx3yhp=+B0!=7W5|9ho!-;N&W+w3l#$8-yQ6;Pm+Y5eg@1Z;1KVQXs?3&;3SkgmWqf#0v}KsYuE#PohZ*_$G1 zg|IHPoYbkUBwx<5vZQos3^F{ONNINzcs!#vZbI~?N3vvOfsc3xGWd;8jaY|6~^d%X9^^71Jf#e z7+>tc9SP0kM`#&x z&f&C+cx`t8Eq)D`Psu`tOTyavFjnl3LW|dc@DENwsX%piPVXxrD_OrTxTU&N>$S?2 zLgEx0gq=W#J=G%;xWok#)nb|c?C840K)fS6J4=Yi6Z~_4dBFr=#oVW!i zr$k8G5v{W`-FiulCj<_#&jIoouwW>Nq^|KvbLWzd&Q8i0<6Rw{Jr|vGUb4NXeMuy4 zOUw6M$bGg7(jIQZ=H>yMQRzXNQ-nD<=d^fI4zfH7?puBk%Xaia76nW!^`^XuX2D<_ zBXb?_$4tDoCy4b8QB>vH@!fL@QUul_fyq)sgmiFJKBbS7Dk(b@0ir;0*UOE#^Th)Y zL>V`qU51-x=fGrmk6eQyQ8f0ccxi_p^QydN zFiq`Wt?g|GP2GI3vZ6A!KCo?CYrMl&qU6IPxIQp_Cxk%eBGF7ez0KLZldCxBa5@CT zF!<*H`HWagYbzLI{A*wTijNX@%f>C+pVp$;X(bsKb3mk)CBkPfMr-IGIzusBFfKiH zhzD=@*(1|2rQC;=dj{~-yB%oiOQ1N@j_N`W;+h2lU}~8gV+x#@QQ^k*v$ApT>s@&K zoj%MT?SpMlw>-t%nEFv90qJRW)OW=2!>4NTz#Gl5$r45sWZ(~1R=^>@cV9i_X#}i2 z5W&WSQCvAK3x!!WytJ(!Z`T_z5>=o$5guOx#&sB^%SdYB`;nsTqyqu}`X63@>q~Do zt{=5IxVt=E^deWv8eFnE_IYPuBu(%z1BS2B>=3l1_M%}JA6mcTbAWsTCW#VZEamOz zojG&-u3ftyZmjS5hFh4D%=euwSWF{?(A1QxB_qR=hTWa@D9w~HGRKipmIYv#3|09q z%&X2seUFOeJA3f<{sDA_G@LOq1L@8bfpuZJf_$G0hb-XMrw<~bTL>mBoIA#cm}bFg z6XEmN;B+Y1)e^#QUaZ62ue4xIT|Y9@(?BIV{(DI&rj@ymIgU>UJ4_JeWY=DE3` zp!nm;b~N;sKtVn@Cno?8fH4CJts|uB1NZ;(m%n6x`SYKxJ-heF%h$Z#rziC%a`LkI zI{&sQBBM&Nk_V9r$8ErJ!eQeINtnruR=IN*G#pINOc&II%0CClX=oECPNY3OJ)ALy z%f4`VJ|pUN?JfQP>FY#Qp>MI~u~phkD^3UzQ(rNm;M{_#yP?=4*wEC4C6h8Bi-)!c z4T~esr{L@{ndpx(tg9QqmZl(H-Ps4-Vwhf;2A5ri#eleO;?Z@zxOq-4*3?IE^SnIR z6d7ylg82Q5d-2`BZ^5(M!r0v_psjZRS-x_(ooSdqTEW-mS*9EsuPwHA)nNkReO2-5V10xxt&kC6lZ(Y1OVp-O5bx@c6bAX&i zHh1nk+S=MmdU|@88s+xqU;5|#*0$C^cef?KA(~aRIO9AekGR;F! zt4BvDfr}<&42so|;e^_27jRZ}1`?KtO${ORMO3V=_2WOAy0EdX7p?vz%5%N=>byKm zEpuVXlx#e=xf>VWwHi;n(}Dbn3o-rdix4w7np>KX;iy4gRv9ebj$d6;h_Xx@%;Rik z*=33~^YLR2^Wb#j^#xxSj0)}#E`6_*39lL2=i8_ z%RvqO^vp%*|0Q7j<`c_4n#4{GFaTd9DkMT+b|GnyLV> z<5YQ4(#VD`!Yfb3n|nieaeE*|C?8LXv zP6=}w#{q{(3Hl-i-mFcPq$gCkv8OSDo$U#5qX^78ISrB27>+D-c6GS`AQFij@%x5h zsv}2?us!nf6Ps?k_*++Oru)~u5LiVR7(131F}OwYv z#jq*G_|0qW=#LsWdjBKEybk>0qGH@QuNb-6Iq0 zTr?paOrTh~H-H1ZZrFv)!ve7rh6pGmAsUUj0YKBba>NNRxPyVUtj?2G$ z?Pk93otFY{Qkh8B(bLlefXb7!N-9N}mA@EHR0BY9X)*mAAfJL=aKQxv0HM9T-Q=9x z#?(}O^Tk&le->Kq@9k`2X`$~TGu>GYizNik%@gPi9F}x)2F03zgf8OtXIo&CgyB7q zp~Enw;PlIjOR->-3%OYpNVC=8ySM%bS6_W4sz#2)v(G+@`|i6Bk3RYcuKUuBD9=3~ zSs3SpcjB3(mPTBh&GG`@!J- zqCRd$w&Pru<(|$6sA#ezIWb<6qmB+CFmwu+JP$kCqquKX7u?EwL6SPW9KXAw5@WK1 zFn9oC3U5T3G#7t+@CBT8)Z-1a@~cV^p3KBXaD}50hUWDg%p@V8NIS>}u^sN2~)9M!_SGL%MS^%Jb&JCr(31 z4WKu=2Gi^gl%%=PF1O<67v$rDap{OBEzsl8FH(}44*u)v9;gPxuP-mdwuT5Ed1nCr zPz8vYjguWT90HVuupu}*S4G3d?zFTt8jVJen=|zF^|A7ba-p`auDhtBq<&X#?bTy# zBXm1e#Gy&)LF!UcAZPP>y`{RXr|T7%XcM_WR89RHARmW4_~3)2y}ez0?z!hkFc>o1 z8j~4IU;Ec@-h6Atozy6r?G~oleU2JtlheVtK{+hoBNAKyI0Tjr6+PJ6(u)PvX-IR5 zM^v^Bfdsf{VisEZ0_aj3k+dj8?nP7$qf1?bTm&)OQ-YWyhM=Pv|FyUnmrTq+M6=#k z_COQ}c6TQ5hm~FU^`)gK_9=LDeGgvUsUXuf9;Qi;vpM*|05MrukF)*Dk_oW1ayX)A-XzXT5YJ#%z({d!0%~C zNnQeXEvdllDmOw2^N2yjWBu!WQ4>FTp#>9*o%q&yg;=%6kNe;1g~)1P>b^nho>Pga zISdxkO|fa28fUv*E*Fi*;~!Xc(v1|6N!j!fJA3>4CMM#EQIlMwEtMtd5J)U=*dWt( z)}!<~2Ua10$mw>zKC>Hz7hilaX=`g2?!NnOU{L9F#*CTYPD^)xTT95rX|}nFLoS0P zI5R0cLyGzn;-yLi`dqT3B=Exb;N-2Or<2tRd6`M9qnvDeV0d#m3 zHwkOe(yy-!JUnzaKq4-4^FuS-yP5_u`4jlkIK(FL;D0*_n>n zqFu^^Ko#(mD$*zSCM^d<$$`CH4G<~CjB*bc=fhLI!w;SkB#qQXJhsqZCt^7s31^M+BHt_H$&LMZbbTCo&KWQb`4mH|L*b*&0veN=Ux`Pp zy>7Rg#$vIP>RagHWS^9&gu8=%i|4o}8!Af*lu&TaiCs|44z))}DEh958r`B<`e}9M zPJ4hXS+a!KY&K$=CVk_LH_+MH$t}xbH{NjbIMdXBb^GnNJ<{8yUEmd`rDZwi3U(b9n8--2WYd|mGIkwtB^$UbAX(L)z;Rcr>6&rM1tRO#~oF%SnOs1 zk8Itt?Psx|XHus9EL)~yI#I;T!Lg7}uTq%mjilHW9AZAgS}(S?cB4Go&PV0iiGBXVad6Hu3DU z<~WOsDyP{L$E`NI{o&Pbzwy&YeTHF}yVUSM*5QikE85q|wsMe08*_VuK%}L08 zZB92|Rx_^R#WkxtwhaWpzI?^S1+T2x^y&|uZJzL_D=RRy%!Q}DS&K$b@WXB=Vm z#8$Qqi^FRd`JGGK$jbe(=+x20*H%xN*S~Y`Uv3B{YMIYoO&K>&z1PDzI5(Kfu~n*%gIFXxiDDZcae8!KbQrKJ_E z9kmlOT~jQ^bb4x4ECR+2sAfmFv`Tuoxv^&;KR=)J_V%8%2hlW*1Hd_7I5*JN(pnf?ku^x1KHOO+?Lp3-JBPfrb{z)*kDZcPXPkuQW<&%T>c4)}lQDc43?LK)gmca*<2p>1Bo@~|1q&8SXi2j- zsPn$C&N}NMsOxhJbJjH0^==+|rQhBCSNPodipxt`PEL-sZQC{-02VDg*SBHEruifF z0w5{yZ~VK7JakZ2kv45byP!`h0>q%uUx1_mh!pJu@1$HSPb}Y_CmI4If+!_qN zhrUko5rAO$?GJecp2`sk7&EBF6EK+yh9s!KV6k{iHTwE=tABt5?LkIe!2G0K7UcC8(vDncT$K9{BV<55mU@%@gju273^2#gu(@#Hr zN;$~*vE#|Ey}S6xGe&2rdqR&dlxLhj!!_QDvN!=J^nb!n)gDya=D>jev+6;3QU3I5 zW*KKHHrdp0H)>d4eY^p?yLFzCowsoFmMyD}emI?{?2zZ)Air7aa~_P_NFbd04|`XXjJ z=4lBL4zUPMrNppFnI?xWFs@U^48p<4vHw|qf^U@|Rkk9-+kF7#1Val;Ot6?nET+O_ zDlC=&;|WlSfe@2fEYWSSXt!a7I*A=C)yR=>VsCaWpGG~@rbcje(#R%iZq&bQq)xi@=4h^&E-g)JS&&)Gz9p~w2t<|3 zknJY9x%={c-#KUgxB)jdJFyb-{hlY!eUc~l-t)cZ{LXpb_q@w>yw?m-nMg=z2L2RZ zi!ce`-{u$M_G#JBnZWVx1R6RM`0Av-0@%_g?>J?NU`2H|`{lc*qy+3ov$C^q-mz=f z(Q|$O)M?`#J>Ai5?agG;$eg8IH$(LEogx%WgwbuRtL+W6RRA6h2>id)pYh|z(*p+% z@Um+sPE-!+uUv!5al;*j+({hfFM3~6YlBA%0kjSnf?Rv`RbzrL! zFiJbs){yL{bthbzu4lhOXMby!V={M8oBp`(Wm{r6#vQFYa(KX~SUuf66aahY?cG=3 zert5}l3U{V`D5wo-Wrgv-5kdwk3@`Bt2Hezci4x9VfvY9BB8a^LPv2*3=6uaG$y z=Ng60tvm6p=bMo2kuZI@8$-MbRGA`_U}*3qu(vs4gyPK1^tdGY|UWasYca}t;kBIeDXUFGpQy8OY~tbEUGVX(;OxED!nOfkK;6#&9ff4_t#+E(#5xQ$AfqJjex^tD}W*-P+9Q|sCy96m*~PwQ*qcK<>hhw_rpPA7yzXL&;VJX zs3>!Ozp3TJMz<^7jKvL>;dK*9lF-%d6RN67hMpuzJxKu~g~LHY2$f}7kxbK&bX}*+ z1d(m3Vj2caCSVxgiUJ~~4i=`WGE2QG2K0EmXlS81Vd8jwWQiPl@V-@_*h%AI07&8# zlBlcM+P7m#QeJ*GAc%0eoT8$lLabc5(&*^u006YKoa$G>7UmBb6K)P%d!2W>9^o-n z`jnehA`+P37^xRxq_hOh+9@0}Ph$HapXiLX5k`eymZY%TW^TM`!Gsqd``s%i zKRnimv7<)FM;e;Uox7_qIF1Lu_n%$gd+;BhJLYTpVZNAU0H06CXFSOXWgS4@eD?=I zvT|8RTL+eYb;+8|&#tc??JSx-(q1G~qTobZr#her;?2kq05E^y=)IdZcb{CeP%61* zp_%M^FZySzSXO$Hl*Is-S^Imxe(Pa@cYMMe&V&Y@f3D!`NX0oHpNRdJ7BY` zP!vU|stT9OB@P}uC;(=5w0E5O=Z1!cFZ6zihuN}Rk%5u+A{sQqkj|p}ON6G{3J8uN zMjpzf;^d2=x3vy8{XzGs&PNF$q|=vr;OYZ)WY~~=bxdigx#8W7=EV+V-VJm0lCq+A zoNn^NaN;B!TAuhQy!b z5$%it>GIZ7dgtAKGng$A3Q8}n@TZG%^Ul6zj##mBCHCz5_h%-Q{m-$#yz9HOYP&hS z(}(?rk^b_|nyvc)V9(x~|8M!0i=Ke?_I6xqC>}YQ?%A`456Lh1egVxUrS{P@!lGwA zJx;?ACcJW*vC+RnJ*YIU$tubJmzgtXCZ|oChWqcoU(_Axb5b3x|EtGUv-eQf*m1*F z_jI;ba={tF#k#TtOcpjX)6!dk9@y>nej~_;;lr7)(}!JKcW#_N@!I3p*r($xN>008P6kCFK|%pbaW z)28o!C-Y7-DRlXK)z6t=a7j*99j;ThWB|O%;!n2 z({r630s<;kc$?lu-i&VS4P_?37H;Z2_C<`XwzgIP!14!v+OG4!wj}EYA@W74!UD3Y z8-$Pq;Fe!|?X`X-NN#Q}2Y}M6CT%&EIMEU0VGzSOWf9~uLPbS6IrQNnDukeQ#}57O z#?x%0YHzwPh{;!6b{d>RYaW1~~rkKmE9srHOU@?ACfuDqc z%JEhJ$n-k;eN59TD+K^jx3bz7bcY$qNw?c_5F60woJONPi zL~5n5e$QWCx8~0>05NuS>5~)6jfsyx8p7Xyv#TH;^KUCJ8J|-;qJUTg8NiV2vJ~tM zm?K7wSR85(+|-L*|`(}zOio(zR=|Pq@FSrGrUXM&7C{9q_w5>>91$rq`4*6S;;{_pb!}+^fvNF zctiJ5-n1mq9$kx6!rB*J**rHl7XVN>dAg6#WP`y%AdrQ)pn)D_gpm3(f9OYW&L{wM zbw{rJ%8f?Rs8I&O5ki`psPv7y6CxH1&H;dMI7lpl48X&K$4z#_b@MWI?B2QJCfC(j zqqQqO)3Zqcpddmf5)Q>0urju(r6WId7h-r9sgRGqiO;{fIu)<=`{!Qi5hT`Z@CXQ@ z7gVtf9$-TYhc*L1R#sNO62#E;K5@k}oDSxgJxj;$f7gqO@g{O|m;gu~aPBJh7C|mi z5RJ+J*smXb!d10v+Z!{a^3s{kNuMdPkTS-pprB-Tv=*!4n`;{N6E}yC`QJsV*PrpX z9y%e!6eM|)N(MML#rba21q5`XmoHwtqzM2iEiLWWrD~d|OVk@NUl-BcZeYrl2Amlj z^~Yp@kahr|61502fFO$`H(z_|1?|C~{P6h+D8BYa&m7Rcn5vI2E|nZn6K}L-#*3jtyUW zOZxRti6WR_XZB(a0SC1+pYErtBU|tn{r$&pUh=iO8}}S-AZ}Sh{L3kf=5nPn6g8VI zNT>kg2?;n?cy20l*XBq?@fPF{?e}%EV8J2|fF7)?+OfAL{nbZ)o{mQ!w#&;N$k5*3 zne~2I#mpB~;v)NNKjdHbq+7U1a{T zI@zwsL3uAf+*M;9`Y|GS=7m2zkHXPK@~LAdzqH5$RZT^ayIt;RB*BBsOr{g0L7XFj z%3vWdBx?a6k&N{FBK^t3|0TY0_hRzmD{tY}JKg{B)*H&Hb?f;Ax0|-!c1QV>PyOb( z(4{i*7S0Ddl@aIWoOyGdKYHZH&rYIa?^x`)4lc>b6GEpH1g2ncNH%70ldKGGlIzKd zjSZyvrwF480G%*p687(@F~7{mINj!&3m!6=(JRA92gq62AplU3G`pcWZHIv{G|l#f zs5vjb@)mz!*}e3aPd*<4@R$%nB80G~esc)ZE2oj2)w{m*BG#6Qb>3|k65`yPI`_(q z-8*)#m@bvwajW-+GvokLrQ@;`Z?ZntEWI3jhwh-YKj|rqe-k~Z>f3<${yjBcdXvi2 z=>m3}Ee^0~DjoXVM!L@Y!t3=O27t7*v@dL-{_@G^`Jx-H@2kK{7yvqJ#x!~WJ#17H37({>U_+JJpz5#ptkc%B5B5}}?uOnT|9|uz z>}>VsW~BNBTp~DK&&uQV>XafW#JO7;5D>)mEg(&kOBW70+@_7L-uLc!J185?NBZzB^p2 zZB6c_or?d*-R{s!XhsVF6ptw;^+)S3t-J;~HPsG>!vKjS#d+^1iIBA@fBLu2)B;de zu3Y&yaY?`M;>(v@BTtJUpF&Pfj^y+CSaC`5?BfR;-?%Mpe(nVO7{MV(k|*Jj(~NH2 zPoM66Lu-}0-wS6YejGU7vm5@8KBN9<{UtZir<-pk5^=+1rhcBpZ()iAQ8cq2VIU_v z7rw5}LG7Kf(1-l|e7U{7-5fJ^%w4{wj%WYDv&243%NHgXQHjcB$mW{fE$TjYq=R|L z_XER>)zNJ|(E;IWu%}YJ)6+dvmO>Q9**GjfKtTGynuPqM0?3L-J;$T1lj_|4NADqdhG>y(xuifcP8w+`KlM zCP|Vkad8d+f%c5?c&ai|AkYhD3UanvbkTQ$#Ef>#m@#7) z05W;-DZL2xZ*+Pq}vs2@>fv{dlhXE&f#aPn*-mWL9?h zx|SY4b-cB>bPV}m`}+fK(S*Zc06<$uD=|$@D3SWQVVy;-u!W;9yzqzpHq9;dcNU?g zVhtdyeEls^F@8eE!dn)tpDLGDF3h?b?PeF*9NLrEov7WH?nwJVGL)#=wRgAV$@EBp zo&c*qbaX&JvtV4MRJIW=;giw40+dKRu6IZtk8@Wr)Ppu|@?*v0Z*lads z>clB#)sAfgeJ3RVgkhRCN+bs*@@Ld53Ykar6BP0IpZnCZL4A5$_5>MOG?Fx)Y!pHW zGQD!<0#$ALXS+?zbJ+J`@&pC@kHk=(94Qh)_dnA4+~FZ3hyEs6pL{hLO~S6(Rhz1r zz2SgSwPV|WmxZpUs#Zp$QB8XS;UMJVBx?z8yQWyx{h&+AeS*3Pd27P zs>fY<-^dZoPtTklKyN_S^Ku2h|JzYoRb^xU@XyWmFi-n60{HjV`W66C^K$c8M`wo~ zPsT4BS(s+(Qa_nY+GQa*DNz83Gqte@h%k9nHbqZk(nvPT((y|u4!|sz6_1asduXR2GOGA^8ObYle?>k}IwlX0hXPK0y+RRN6(SFXSFl zpbznSg)wB5DX-bkgFfrj+`og`qH#NN3i9e#uU%(c&J%q)?us$)B1DoUqHzI6KQho& z9%siyYC)qtPey~fcYQ%baoHK?EW8Or9_;>7d>orc{^vXHyquz!@?6)8vb-M{W3s<1O7oVR`L0D`SW)r1(G_r7 zt7VX>SO5@=cJZrcUP*$%AmN-rq7w4+^ToRNHu0DL_|j$n{E%Ru`#S_a7F)5e?!!Sd$)QlH{=xC%%`VP{WUG<` zLNFpx8xKT}s!lhrrnX?UMTgJAisl^zIGrpN4oBQVNVzg~q}pXeHDls1G)MgL1G{}b zOHvj=2InMG+V?7XWJ%4Jh+R;kia_kJs@fBKG^f7Jl9EM`L5rRqKLLPf)O4GsfFij} z!8wnMddQBzuaDGrw^&lL2r_74ng#~|PntI`5jUYJ>1I##fTB6$TSko@_P+p7Qc^-J zNm&FLv=BlNiMaA5;(%_3B$Kv4vh_T(Wn)bX0CM>7VPQ$hBFLb{8*l&0smjhPWRebl zY@f>H_LuLw_rbLQFn|6+OF$L|H%iJXio9us8!{c`B0GItY)DbwQfrgEFeFO^mp|sr zx-D0R|H;uK12;~a?lZEobd8GK{F0J6?>8Mk)SYJYkffQg1Z83H!Q)z>U0GT3+q;*h zi{Cuvh_7F17b1$}vis7+m=R@93n3IsN)`q!vNPrv-!#8K9NkZ2*Uie}^X6oVK%2zs z_E52CUQvU`b!9mKOe!z6yjW*}RXFZ4N4nSTG?{_o@tpkZCn4f=2)NyxxLknOgN#H{ z*ey%s+_1!QnWLfcXm>c`FzTuyPn)BgWm64Mmq>o_fsBSm`NPukyfy%^+3c3EEF*pJ z;lbq(#hQ*C(|7OY*DFZSP>&EB)+x&CD{|1Hhf`z{o{tsn$Y#O-W RE#UwF002ovPDHLkV1gi%A?yGE diff --git a/android/res/drawable/itoopie_notification_icon.png b/android/res/drawable/itoopie_notification_icon.png deleted file mode 100644 index fa99e7fc66b68ea9550dd70cd00b36611ecd9fa9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1940 zcmXX{2{c>j9#2o7mnjvAqb(hkNjjY=MXRAiD;~LOEY(E1JW^EElCi{AQL*$?aR)Ox z$NDTS*Fi>zsSO`oZ$FSRBSLSCeb=3H1Qi->toh7B-@?L6ch@L^MG8=B?qpE#Ywde zSe<`wYVJ-Sm|?sPAz}@me_Kd9D_yzZHINb0;ib0!$MTBzbW-_B$3a0b^?Gqh_Ih*? z=g3?z-|FyGir_pBALfmlktWw-tDX)Jd!3Xg2>vt~uczjcumjCDM2Hk2OthYBl2Zte zifZ?T=jC>KMN-L-o7!$NxVWSvVRG@{Pjznsg#?SaNHQ0;x<{fweFaU2poX?vhk;o7 z(2+SEUiLaGzp<+X2od;3aj>fqqKdx&KWaNs6m;d>%a+}A+|k2X_kqz0uG{KtKGy2+ zwaDQjj13WLkmuzlmwqB*=n0ChcsRCKZ;FUXf ze9!Jc_DQThZpvh?bDz@qf>;M>e7 zJ+bWswJilNo=x~<{5WMXbICL;$vL^Gkx+gmQe}-$l|i%P*s4B}!hQIm6GV;LC0?8| zgG%F~;Gy8KQ%#Ih1MsYgj5;cMxLeFKJ%A*XnE+oo5&Cr8>X3LZf;}HbPHf`DWhqxL zD?axBc;rivu&Zs_T~5N!%GF>+je*o(=r+k~hYPn%%#$LRyoE!jvw$N~+F(7fNXIpS z>hy8w)4b1L4xTF=pY3@OdW2ak@V}VbzCl{MDVcEi4w4@uK>_}G4iI7g6))JL74$&R z(_gjO?#paH3hK{nvm;qj&j~Bq8YRb{NwHP^lOSh2*xos?3*>oSK7*Ish{$bZL|M&g zD`3tC`RA~LXu9GL0=v`Rtxk}flo5Ah>CoxuA>Tln#ayW(L`XP&YbkXxXNhO9EgB&3 zE0YXDw4EX+IYT2+s}jd&QWpQQs1sW?tj1&xFIR-jp5hfUPyW5iny-$QzyIVL0#KR`C~6h}xo8Xj#{ zr#7rDZ?&x0*c;7WxR32AZFL=`QAA}g(H+|0pEr+HEek+*$B!%XcdG~2*WDFyyj2xC z^%d}ntwDGCzz=3c_0;IM5`Uoz|KVRG>c_pmbZTx4SDGLlvBD0`PRpi+_d#3ePEYv3 z!h5_1?a)GIm?Dwnlh8fVHdC{sWGo>a_6b*iMn}cvWULz;`yFsD?~)PHG>aiP7K`mB z)?fMYF|E-X-gLM(`{XT<-wJMVcR_Q1Np?K7i(41*&Wt^8onsxc?4<=~on+nNxpj)Q z6N;AVQJx*(ks_q>$+&2vm0P#;k!!k0(eu<_AO`YyTgFYtkKY+H-wu8A2ObIi9skPKXxcg+^SI=uS4iIy(+t{T8L@LcCbOH^@)me;H<*}JO}wI;8yv0Y3C3PTAzz1Q-S|3^+@_j{ zl>=@3>QNeot{uOB!OXZ-0842K$)k5&cNTZZ_HpsP>ak8Pn28Snfhs7ft0S1dRIKYW z3}TCH2)bhHmA5LAulnL?*&`cF-C&;x@2q-KfoWbyVk+gs8vK-A Vg*^@~1UD$k!_5bJ;ClJy{{UE{z48D6 diff --git a/android/res/layout/activity_perms_asker.xml b/android/res/layout/activity_perms_asker.xml deleted file mode 100644 index 778c9ef5..00000000 --- a/android/res/layout/activity_perms_asker.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - -

\r\n
\r\n"; } + if(dest->IsPublic()) + { + std::string webroot; i2p::config::GetOption("http.webroot", webroot); + auto base32 = dest->GetIdentHash ().ToBase32 (); + s << "
\r\n\r\n
\r\n" + "
\r\n" + " \r\n" + " \r\n" + " \r\n" + " 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"; - 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 0854/2950] [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 0855/2950] [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 0856/2950] [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 0857/2950] [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 0858/2950] 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 0859/2950] [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 0860/2950] 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 0861/2950] 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 0862/2950] 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 0863/2950] [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 0864/2950] [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 0865/2950] [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 0866/2950] [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 0867/2950] [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 0868/2950] [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 0869/2950] [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 0870/2950] [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 0871/2950] [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 0872/2950] [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 0873/2950] 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 0874/2950] [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 0875/2950] 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 0876/2950] 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 0877/2950] [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 0878/2950] 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 0879/2950] 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 0880/2950] 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 0881/2950] 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 0882/2950] 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 0883/2950] 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 0884/2950] 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 0885/2950] 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 0886/2950] 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 0887/2950] 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 0888/2950] 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 0889/2950] 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 0890/2950] 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 0891/2950] 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 0892/2950] 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 0893/2950] 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 0894/2950] 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 0895/2950] 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 0896/2950] 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 0897/2950] 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 0898/2950] [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 0899/2950] 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 0900/2950] [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 0901/2950] [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 0902/2950] [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 0903/2950] [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 0904/2950] [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 0905/2950] 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 0906/2950] [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 0907/2950] [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 0908/2950] 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 0909/2950] 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 0910/2950] 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 0911/2950] [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 0912/2950] [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 0913/2950] [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 0914/2950] [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 0915/2950] [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 0916/2950] 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 0917/2950] [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 0918/2950] [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 0919/2950] [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 0920/2950] [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 0921/2950] [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 0922/2950] 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 0923/2950] [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 0924/2950] [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 0925/2950] 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 0926/2950] 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 0927/2950] [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 0928/2950] [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 0929/2950] [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 0930/2950] [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 0931/2950] 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 0932/2950] 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 0933/2950] 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 0934/2950] 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 0935/2950] 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 0936/2950] 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 0937/2950] 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 0938/2950] [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 0939/2950] 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 0940/2950] 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 0941/2950] 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 0942/2950] 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 0943/2950] 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 0944/2950] 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 0945/2950] [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 0946/2950] 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 0947/2950] 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 0948/2950] 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 0949/2950] 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 0950/2950] 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 0951/2950] [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 0952/2950] [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 0953/2950] [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 0954/2950] 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 0955/2950] 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 0956/2950] 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 0957/2950] [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 0958/2950] 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 0959/2950] [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 0960/2950] 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 0961/2950] 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 0962/2950] [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 0963/2950] 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 0964/2950] 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 0965/2950] 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 0966/2950] 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 0967/2950] 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 0968/2950] 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 0969/2950] 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 0970/2950] 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 0971/2950] 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 0972/2950] 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 0973/2950] 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 0974/2950] 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 0975/2950] 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 0976/2950] 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 0977/2950] 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 0978/2950] 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 0979/2950] 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 0980/2950] 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 0981/2950] 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 0982/2950] 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 0983/2950] 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 0984/2950] 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 0985/2950] 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 0986/2950] 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 0987/2950] 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 0988/2950] 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 0989/2950] 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 0990/2950] 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 0991/2950] 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 0992/2950] 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 0993/2950] 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 0994/2950] 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 0995/2950] 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 0996/2950] 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 0997/2950] 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 0998/2950] 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 0999/2950] 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 1000/2950] 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 1001/2950] 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 1002/2950] 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 1003/2950] 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 1004/2950] [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 1005/2950] [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 1006/2950] [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 1007/2950] 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 1008/2950] 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 1009/2950] 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 1010/2950] 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 1011/2950] 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 1012/2950] 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 1013/2950] 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 1014/2950] 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 1015/2950] 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 1016/2950] 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 1017/2950] 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 1018/2950] 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 1019/2950] 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 1020/2950] [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 1021/2950] 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 1022/2950] 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 1023/2950] 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 1024/2950] 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 1025/2950] [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 1026/2950] [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 1027/2950] [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 1028/2950] [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 1029/2950] [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 1030/2950] [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 1031/2950] [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 1032/2950] [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 1033/2950] 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 1034/2950] 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 1035/2950] 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 1036/2950] 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 1037/2950] [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 1038/2950] 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 1039/2950] 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 1040/2950] 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 1041/2950] [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 1042/2950] [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 1043/2950] [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 1044/2950] [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 1045/2950] [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 1046/2950] [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 1047/2950] 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 1048/2950] 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 1049/2950] [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 1050/2950] [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 1051/2950] 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 1052/2950] 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 1053/2950] [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 1054/2950] 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 1055/2950] [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 1056/2950] [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 1057/2950] 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 1058/2950] 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 1059/2950] 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 1060/2950] 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 1061/2950] 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 1062/2950] 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 1063/2950] 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 1064/2950] 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 1065/2950] 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 1066/2950] 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 1067/2950] 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 1068/2950] 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 1069/2950] 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 1070/2950] 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 1071/2950] 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 1072/2950] 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 1073/2950] 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 1074/2950] 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 1075/2950] 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 1076/2950] 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 1077/2950] 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 1078/2950] 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 1079/2950] [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 1080/2950] [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 1081/2950] [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 1082/2950] 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 1083/2950] 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 1084/2950] 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 1085/2950] 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 1086/2950] 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 1087/2950] 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 1088/2950] 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 1089/2950] 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 1090/2950] 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 1091/2950] 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 1092/2950] 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 1093/2950] [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 1094/2950] 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 1095/2950] 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 1096/2950] 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 1097/2950] 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 1098/2950] 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 1099/2950] 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 1100/2950] 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 1101/2950] 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 1102/2950] 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 1103/2950] 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 1104/2950] 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 1105/2950] 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 1106/2950] [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 1107/2950] [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 1108/2950] 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 1109/2950] 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 1110/2950] 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 1111/2950] [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 1112/2950] [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 1113/2950] 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 1114/2950] 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 1115/2950] 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 1116/2950] 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 1117/2950] 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 1118/2950] 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 1119/2950] 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 1120/2950] 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 1121/2950] 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 1122/2950] 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 1123/2950] 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 1124/2950] [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 1125/2950] 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 1126/2950] 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 1127/2950] 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 1128/2950] 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 1129/2950] 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 1130/2950] 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 1131/2950] 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 1132/2950] 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 1133/2950] [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 1134/2950] [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 = "