From 6377631ae76f123c4adce7a8e53bfecaa1c98b8f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Nov 2016 12:51:39 -0500 Subject: [PATCH 01/17] OpenSSL 1.1 for EVP_PKEY --- Crypto.cpp | 6 ++++-- Crypto.h | 10 +++++++--- Family.cpp | 2 +- Reseed.cpp | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 6b5fb7d6..42514857 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -270,8 +270,10 @@ namespace crypto { if (m_IsUpdated) { - bn2buf (m_DH->pub_key, m_PublicKey, 256); - BN_free (m_DH->pub_key); m_DH->pub_key = NULL; + const BIGNUM * priv_key, * pub_key; + DH_get0_key (m_DH, &pub_key, &priv_key); + bn2buf (pub_key, m_PublicKey, 256); + DH_set0_key (m_DH, NULL, NULL); m_IsUpdated= false; } return m_PublicKey; diff --git a/Crypto.h b/Crypto.h index 7d9a38d7..115fefda 100644 --- a/Crypto.h +++ b/Crypto.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "Base.h" @@ -281,6 +282,8 @@ namespace crypto void InitCrypto (bool precomputation); void TerminateCrypto (); +} +} // take care about openssl version #include @@ -318,9 +321,10 @@ inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) { *pub_key = dh->pub_key; *priv_key = dh->priv_key; } +inline int EVP_PKEY_base_id(const EVP_PKEY *pkey) + { return EVP_PKEY_type(pkey->type); } +inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) + { return pkey->pkey.rsa; } #endif -} -} - #endif diff --git a/Family.cpp b/Family.cpp index c1840e51..ce995a4a 100644 --- a/Family.cpp +++ b/Family.cpp @@ -40,7 +40,7 @@ namespace data if (family) family[0] = 0; } auto pkey = X509_get_pubkey (cert); - int keyType = EVP_PKEY_type(pkey->type); + int keyType = EVP_PKEY_base_id (pkey); switch (keyType) { case EVP_PKEY_DSA: diff --git a/Reseed.cpp b/Reseed.cpp index d8a265db..65de62b4 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -350,9 +350,11 @@ namespace data if (terminator) terminator[0] = 0; } // extract RSA key (we need n only, e = 65537) - RSA * key = X509_get_pubkey (cert)->pkey.rsa; + RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert)); + const BIGNUM * n, * e, * d; + RSA_get0_key(key, &n, &e, &d); PublicKey value; - i2p::crypto::bn2buf (key->n, value, 512); + i2p::crypto::bn2buf (n, value, 512); if (cn) m_SigningKeys[cn] = value; else From 3bbe1e9c0cd794eac4dff2772737eb189e249be7 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Nov 2016 14:59:21 -0500 Subject: [PATCH 02/17] excluded deprecated reseed --- Config.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Config.cpp b/Config.cpp index aa75b8db..d11802cc 100644 --- a/Config.cpp +++ b/Config.cpp @@ -165,7 +165,6 @@ namespace config { "https://netdb.i2p2.no/," "https://us.reseed.i2p2.no:444/," "https://uk.reseed.i2p2.no:444/," - "https://i2p.manas.ca:8443/," "https://i2p-0.manas.ca:8443/," "https://reseed.i2p.vzaws.com:8443/," "https://download.xxlspeed.com/," From 89d69a5d5a61865edeb53a6cb3691b0dce67d327 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Nov 2016 18:38:29 -0500 Subject: [PATCH 03/17] rollback due the race condition --- Crypto.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 42514857..c70b62ef 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -270,10 +270,9 @@ namespace crypto { if (m_IsUpdated) { - const BIGNUM * priv_key, * pub_key; - DH_get0_key (m_DH, &pub_key, &priv_key); - bn2buf (pub_key, m_PublicKey, 256); - DH_set0_key (m_DH, NULL, NULL); + // TODO: seems race condition here + bn2buf (m_DH->pub_key, m_PublicKey, 256); + BN_free (m_DH->pub_key); m_DH->pub_key = NULL; m_IsUpdated= false; } return m_PublicKey; From aa47e11471325056b4489e7326f857c6db9d0a95 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 10 Nov 2016 21:44:40 -0500 Subject: [PATCH 04/17] fixed race condition --- Crypto.cpp | 20 +++----------------- Crypto.h | 5 ++--- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index c70b62ef..f9478646 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -224,7 +224,7 @@ namespace crypto // DH - DHKeys::DHKeys (): m_IsUpdated (true) + DHKeys::DHKeys () { m_DH = DH_new (); DH_set0_pqg (m_DH, BN_dup (elgp), NULL, BN_dup (elgg)); @@ -236,7 +236,7 @@ namespace crypto DH_free (m_DH); } - void DHKeys::GenerateKeys (uint8_t * priv, uint8_t * pub) + void DHKeys::GenerateKeys () { BIGNUM * priv_key = NULL, * pub_key = NULL; #if !defined(__x86_64__) // use short exponent for non x64 @@ -261,21 +261,7 @@ namespace crypto DH_get0_key (m_DH, (const BIGNUM **)&pub_key, (const BIGNUM **)&priv_key); } - if (priv) bn2buf (priv_key, priv, 256); - if (pub) bn2buf (pub_key, pub, 256); - m_IsUpdated = true; - } - - const uint8_t * DHKeys::GetPublicKey () - { - if (m_IsUpdated) - { - // TODO: seems race condition here - bn2buf (m_DH->pub_key, m_PublicKey, 256); - BN_free (m_DH->pub_key); m_DH->pub_key = NULL; - m_IsUpdated= false; - } - return m_PublicKey; + bn2buf (pub_key, m_PublicKey, 256); } void DHKeys::Agree (const uint8_t * pub, uint8_t * shared) diff --git a/Crypto.h b/Crypto.h index 115fefda..476d2a26 100644 --- a/Crypto.h +++ b/Crypto.h @@ -36,15 +36,14 @@ namespace crypto DHKeys (); ~DHKeys (); - void GenerateKeys (uint8_t * priv = nullptr, uint8_t * pub = nullptr); - const uint8_t * GetPublicKey (); + void GenerateKeys (); + const uint8_t * GetPublicKey () const { return m_PublicKey; }; void Agree (const uint8_t * pub, uint8_t * shared); private: DH * m_DH; uint8_t m_PublicKey[256]; - bool m_IsUpdated; }; // ElGamal From 74aa961561895c661bfada1859a6b58e84c8fe93 Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Fri, 11 Nov 2016 09:42:18 +0000 Subject: [PATCH 05/17] Fix RTD: Use 4 spaces, not tabs in docs --- docs/building/windows.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/building/windows.md b/docs/building/windows.md index 0aa76877..7cc09cb8 100644 --- a/docs/building/windows.md +++ b/docs/building/windows.md @@ -30,16 +30,16 @@ Where $ARCH is `i686` or `x86_64` (matching your system). - Open MSYS2 Shell (from Start menu). - Install all prerequisites and download i2pd source: - export ARCH='i686' # or 'x86_64' - export MINGW='mingw32' # or 'mingw64' - pacman -S mingw-w64-$ARCH-boost mingw-w64-$ARCH-openssl mingw-w64-$ARCH-gcc git make - mkdir -p /c/dev/i2pd - cd /c/dev/i2pd - git clone https://github.com/PurpleI2P/i2pd.git - cd i2pd - # we need compiler on PATH which is usually heavily cluttered on Windows - export PATH=/$MINGW/bin:/usr/bin - make + export ARCH='i686' # or 'x86_64' + export MINGW='mingw32' # or 'mingw64' + pacman -S mingw-w64-$ARCH-boost mingw-w64-$ARCH-openssl mingw-w64-$ARCH-gcc git make + mkdir -p /c/dev/i2pd + cd /c/dev/i2pd + git clone https://github.com/PurpleI2P/i2pd.git + cd i2pd + # we need compiler on PATH which is usually heavily cluttered on Windows + export PATH=/$MINGW/bin:/usr/bin + make ### Caveats From 91427264c3d97d38158b0d34fd65cf3411bfbb40 Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Fri, 11 Nov 2016 10:01:38 +0000 Subject: [PATCH 06/17] Fix link to configuration --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index a4bcbb77..1ce9eed6 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -48,7 +48,7 @@ Enable/disable i2pd to be started on bootup: ## Configuring i2pd -See [configuration page](i2pd.readthedocs.io/page/configuration.html). +See [configuration documentation](/page/configuration.html). ## Browsing and hosting websites From 6f2357c695bc90896c2bd86a2e02da6b0c6c6f5e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 11 Nov 2016 12:44:44 -0500 Subject: [PATCH 07/17] fixed openssl 1.1 crash --- Identity.cpp | 2 +- Signature.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Identity.cpp b/Identity.cpp index 9e07382f..f39e9bd8 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -488,7 +488,7 @@ namespace data switch (m_Public->GetSigningKeyType ()) { case SIGNING_KEY_TYPE_DSA_SHA1: - m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey)); + m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey)); break; case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: m_Signer.reset (new i2p::crypto::ECDSAP256Signer (m_SigningPrivateKey)); diff --git a/Signature.h b/Signature.h index 7962bc2d..1d90d8a3 100644 --- a/Signature.h +++ b/Signature.h @@ -77,10 +77,11 @@ namespace crypto { public: - DSASigner (const uint8_t * signingPrivateKey) + DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) + // openssl 1.1 always requires DSA public key even for signing { m_PrivateKey = CreateDSA (); - DSA_set0_key (m_PrivateKey, NULL, BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL)); + DSA_set0_key (m_PrivateKey, BN_bin2bn (signingPublicKey, DSA_PUBLIC_KEY_LENGTH, NULL), BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL)); } ~DSASigner () From 8676a1b4efcb7210e20767d7c30d62a636406dc0 Mon Sep 17 00:00:00 2001 From: atnaguzin Date: Sat, 12 Nov 2016 17:49:16 +0300 Subject: [PATCH 08/17] update changelog, added leaseset list to client/server tunnel pages --- ChangeLog | 4 ++++ Destination.h | 1 + HTTPServer.cpp | 11 +++++++++-- debian/changelog | 6 ++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 98b33e81..dd1bac57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.10.1] - 2016-11-07 +### Fixed +- Fixed some performance issues for Windows and Android + ## [2.10.0] - 2016-10-17 ### Added - Datagram i2p tunnels diff --git a/Destination.h b/Destination.h index ba19a32a..121b7e16 100644 --- a/Destination.h +++ b/Destination.h @@ -143,6 +143,7 @@ namespace client // for HTTP only int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; + const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; }; }; class ClientDestination: public LeaseSetDestination diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 99edf508..556051aa 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -225,7 +225,7 @@ namespace http { else s << numKBytesSent / 1024 / 1024 << " GiB"; s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)
\r\n"; - s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n
\r\n"; + s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
\r\n\r\n

\r\n"; s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; @@ -253,7 +253,7 @@ namespace http { s << address->host.to_string() << ":" << address->port << "
\r\n"; } s << "

\r\n
\r\n"; - s << "
\r\nRouters: " << i2p::data::netdb.GetNumRouters () << " "; + s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; @@ -287,6 +287,13 @@ namespace http { s << "Base64:
\r\n
\r\n
\r\n"; s << "LeaseSets: " << dest->GetNumRemoteLeaseSets () << "
\r\n"; + if(dest->GetNumRemoteLeaseSets()) + { + s << "
\r\n\r\n

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

\r\n
\r\n"; + } auto pool = dest->GetTunnelPool (); if (pool) { diff --git a/debian/changelog b/debian/changelog index 1ecafa34..f71b2e4a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.10.1-1) unstable; urgency=low + + * updated to version 2.10.1 + + -- orignal Mon, 7 Nov 2016 14:18:30 +0000 + i2pd (2.10.0-1) unstable; urgency=low * updated to version 2.10.0/0.9.27 From f76b014a5296d04875acac0ea59cddabcca84ac2 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 13 Nov 2016 09:14:05 -0500 Subject: [PATCH 09/17] re-run PeerTest --- Transports.cpp | 19 ++++++++++++++++--- Transports.h | 6 ++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Transports.cpp b/Transports.cpp index 358ca4c7..d41253d6 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -108,7 +108,8 @@ namespace transport Transports transports; Transports::Transports (): - m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_PeerCleanupTimer (m_Service), + m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), + m_PeerCleanupTimer (m_Service), m_PeerTestTimer (m_Service), m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0), m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) @@ -168,11 +169,14 @@ 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)); + 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 () { m_PeerCleanupTimer.cancel (); + m_PeerTestTimer.cancel (); m_Peers.clear (); if (m_SSUServer) { @@ -546,8 +550,7 @@ namespace transport { if (RoutesRestricted()) return; if (m_SSUServer) - { - + { bool statusChanged = false; for (int i = 0; i < 5; i++) { @@ -688,6 +691,16 @@ namespace transport } } + void Transports::HandlePeerTestTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + PeerTest (); + m_PeerTestTimer.expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); + m_PeerTestTimer.async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); + } + } + std::shared_ptr Transports::GetRandomPeer () const { if (m_Peers.empty ()) return nullptr; diff --git a/Transports.h b/Transports.h index 9ecfd719..1fe262a9 100644 --- a/Transports.h +++ b/Transports.h @@ -66,6 +66,7 @@ namespace transport }; const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds + const int PEER_TEST_INTERVAL = 71; // in minutes const int MAX_NUM_DELAYED_MESSAGES = 50; class Transports { @@ -127,7 +128,8 @@ namespace transport 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); + void NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident); void HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, i2p::data::IdentHash ident, std::shared_ptr resolver); @@ -144,7 +146,7 @@ namespace transport std::thread * m_Thread; boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; - boost::asio::deadline_timer m_PeerCleanupTimer; + boost::asio::deadline_timer m_PeerCleanupTimer, m_PeerTestTimer; NTCPServer * m_NTCPServer; SSUServer * m_SSUServer; From eaa7adc88c528a4aba1f535ca0b534a86caa2700 Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Sun, 13 Nov 2016 23:04:41 +0000 Subject: [PATCH 10/17] Update usage.md --- docs/usage.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 1ce9eed6..7cb206c1 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -23,12 +23,12 @@ To display all available options: i2pd can be controlled with signals. Process ID by default is written to file `~/.i2pd/i2pd.pid` or `/var/run/i2pd/i2pd.pid`. You can use `kill` utility to send signals like this: - kill -TERM $( cat /var/run/i2pd/i2pd.pid ) + kill -INT $( cat /var/run/i2pd/i2pd.pid ) i2pd supports the following signals: - TERM - Graceful shutdown. i2pd will wait for 10 minutes and stop. Send second TERM signal to shutdown i2pd immediately. - HUP - Reload configuration files. +* INT - Graceful shutdown. i2pd will wait for 10 minutes and stop. Send second INT signal to shutdown i2pd immediately. +* HUP - Reload configuration files. ### systemd unit From ea31ca5ee815ca615d3834efc99909d69b9997aa Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 14 Nov 2016 12:05:44 -0500 Subject: [PATCH 11/17] add reseed from floodfill option --- Config.cpp | 3 +- NetDb.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++--- NetDb.h | 9 ++++++ NetDbRequests.cpp | 9 ++++-- Tag.h | 8 ++++- 5 files changed, 100 insertions(+), 9 deletions(-) diff --git a/Config.cpp b/Config.cpp index d11802cc..8d932048 100644 --- a/Config.cpp +++ b/Config.cpp @@ -157,7 +157,8 @@ namespace config { options_description reseed("Reseed options"); reseed.add_options() - ("reseed.verify", value()->default_value(false), "Verify .su3 signature") + ("reseed.verify", value()->default_value(false), "Verify .su3 signature") + ("reseed.floodfill", value()->default_value(""), "Path to router info of floodfill to reseed from") ("reseed.file", value()->default_value(""), "Path to .su3 file") ("reseed.urls", value()->default_value( "https://reseed.i2p-projekt.de/," diff --git a/NetDb.cpp b/NetDb.cpp index dbfa4bcb..e667dc11 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -14,6 +14,7 @@ #include "RouterContext.h" #include "Garlic.h" #include "NetDb.h" +#include "Config.h" using namespace i2p::transport; @@ -23,7 +24,7 @@ namespace data { NetDb netdb; - NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_HiddenMode(false) + NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_FloodfillBootstrap(nullptr), m_HiddenMode(false) { } @@ -140,6 +141,8 @@ namespace data LogPrint(eLogError, "NetDb: no known routers, reseed seems to be totally failed"); break; } + else // we have peers now + m_FloodfillBootstrap = nullptr; if (numRouters < 2500 || ts - lastExploratory >= 90) { numRouters = 800/numRouters; @@ -295,13 +298,62 @@ namespace data m_Reseeder = new Reseeder (); m_Reseeder->LoadCertificates (); // we need certificates for SU3 verification } - int reseedRetries = 0; + int reseedRetries = 0; + + // try reseeding from floodfill first if specified + std::string riPath; + if(i2p::config::GetOption("reseed.floodfill", riPath)) { + auto ri = std::make_shared(riPath); + if (ri->IsFloodfill()) { + const uint8_t * riData = ri->GetBuffer(); + int riLen = ri->GetBufferLen(); + if(!i2p::data::netdb.AddRouterInfo(riData, riLen)) { + // bad router info + LogPrint(eLogError, "NetDb: bad router info"); + return; + } + m_FloodfillBootstrap = ri; + ReseedFromFloodfill(*ri); + // don't try reseed servers if trying to boostrap from floodfill + return; + } + } + while (reseedRetries < 10 && !m_Reseeder->ReseedNowSU3 ()) reseedRetries++; if (reseedRetries >= 10) LogPrint (eLogWarning, "NetDb: failed to reseed after 10 attempts"); } + void NetDb::ReseedFromFloodfill(const RouterInfo & ri, int numRouters, int numFloodfills) + { + LogPrint(eLogInfo, "NetDB: reseeding from floodfill ", ri.GetIdentHashBase64()); + std::vector > requests; + + i2p::data::IdentHash ourIdent = i2p::context.GetIdentHash(); + i2p::data::IdentHash ih = ri.GetIdentHash(); + i2p::data::IdentHash randomIdent; + + // make floodfill lookups + while(numFloodfills > 0) { + randomIdent.Randomize(); + auto msg = i2p::CreateRouterInfoDatabaseLookupMsg(randomIdent, ourIdent, 0, false); + requests.push_back(msg); + numFloodfills --; + } + + // make regular router lookups + while(numRouters > 0) { + randomIdent.Randomize(); + auto msg = i2p::CreateRouterInfoDatabaseLookupMsg(randomIdent, ourIdent, 0, true); + requests.push_back(msg); + numRouters --; + } + + // send them off + i2p::transport::transports.SendMessages(ih, requests); + } + bool NetDb::LoadRouterInfo (const std::string & path) { auto r = std::make_shared(path); @@ -498,6 +550,21 @@ namespace data m_Requests.RequestComplete (destination, nullptr); } } + + void NetDb::RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete) + { + + auto dest = m_Requests.CreateRequest (destination, exploritory, requestComplete); // non-exploratory + if (!dest) + { + LogPrint (eLogWarning, "NetDb: destination ", destination.ToBase64(), " is requested already"); + return; + } + LogPrint(eLogInfo, "NetDb: destination ", destination.ToBase64(), " being requested directly from ", from.ToBase64()); + // direct + transports.SendMessage (from, dest->CreateRequestMessage (nullptr, nullptr)); + } + void NetDb::HandleDatabaseStoreMsg (std::shared_ptr m) { @@ -620,7 +687,7 @@ namespace data if (!dest->IsExploratory ()) { // reply to our destination. Try other floodfills - if (outbound && inbound ) + if (outbound && inbound) { std::vector msgs; auto count = dest->GetExcludedPeers ().size (); @@ -664,7 +731,7 @@ namespace data // no more requests for detination possible. delete it m_Requests.RequestComplete (ident, nullptr); } - else + else if(!m_FloodfillBootstrap) LogPrint (eLogWarning, "NetDb: requested destination for ", key, " not found"); // try responses @@ -681,7 +748,10 @@ namespace data { // router with ident not found or too old (1 hour) LogPrint (eLogDebug, "NetDb: found new/outdated router. Requesting RouterInfo ..."); - RequestDestination (router); + if(m_FloodfillBootstrap) + RequestDestinationFrom(router, m_FloodfillBootstrap->GetIdentHash(), true); + else + RequestDestination (router); } else LogPrint (eLogDebug, "NetDb: [:|||:]"); diff --git a/NetDb.h b/NetDb.h index d295ebbe..94c8a086 100644 --- a/NetDb.h +++ b/NetDb.h @@ -60,6 +60,7 @@ 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 HandleDatabaseStoreMsg (std::shared_ptr msg); void HandleDatabaseSearchReplyMsg (std::shared_ptr msg); @@ -98,6 +99,9 @@ namespace data void VisitRouterInfos(RouterInfoVisitor v); /** visit N random router that match using filter, then visit them with a visitor, return number of RouterInfos that were visited */ size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n); + + + private: void Load (); @@ -110,6 +114,8 @@ namespace data void ManageRequests (); void ManageLookupResponses (); + void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20); + template std::shared_ptr GetRandomRouter (Filter filter) const; @@ -135,6 +141,9 @@ namespace data friend class NetDbRequests; NetDbRequests m_Requests; + /** router info we are bootstrapping from or nullptr if we are not currently doing that*/ + std::shared_ptr m_FloodfillBootstrap; + std::map, uint64_t> > m_LookupResponses; // ident->(closest FFs, timestamp) /** true if in hidden mode */ diff --git a/NetDbRequests.cpp b/NetDbRequests.cpp index 474d3693..866bc6d9 100644 --- a/NetDbRequests.cpp +++ b/NetDbRequests.cpp @@ -11,10 +11,15 @@ namespace data std::shared_ptr RequestedDestination::CreateRequestMessage (std::shared_ptr router, std::shared_ptr replyTunnel) { - auto msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, + std::shared_ptr msg; + if(replyTunnel) + msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination, replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory, &m_ExcludedPeers); - m_ExcludedPeers.insert (router->GetIdentHash ()); + else + msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers); + if(router) + m_ExcludedPeers.insert (router->GetIdentHash ()); m_CreationTime = i2p::util::GetSecondsSinceEpoch (); return msg; } diff --git a/Tag.h b/Tag.h index 30dfa654..3d21183f 100644 --- a/Tag.h +++ b/Tag.h @@ -11,6 +11,7 @@ #include #include +#include #include "Base.h" namespace i2p { @@ -49,7 +50,12 @@ public: { memset(m_Buf, c, sz); } - + + void Randomize() + { + RAND_bytes(m_Buf, sz); + } + std::string ToBase64 () const { char str[sz*2]; From 98484d54c0fbf877917797d9f63a8c86285c8180 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Nov 2016 13:13:57 -0500 Subject: [PATCH 12/17] check for outdated routers in reseed --- Reseed.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Reseed.cpp b/Reseed.cpp index 65de62b4..427e839d 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -305,6 +305,22 @@ namespace data if (end - contentPos >= contentLength) break; // we are beyond contentLength } + if (numFiles) // check if routers are not outdated + { + auto ts = i2p::util::GetMillisecondsSinceEpoch (); + int numOutdated = 0; + i2p::data::netdb.VisitRouterInfos ( + [&numOutdated, ts](std::shared_ptr r) + { + if (r && ts > r->GetTimestamp () + i2p::data::NETDB_MAX_EXPIRATION_TIMEOUT*1000LL) + { + LogPrint (eLogError, "Reseed: router ", r->GetIdentHash().ToBase64 (), " is outdated by ", (ts - r->GetTimestamp ())/1000LL/3600LL, " hours"); + numOutdated++; + } + }); + if (numOutdated > numFiles/2) // more than half + LogPrint (eLogError, "Reseed: mammoth's shit"); + } return numFiles; } From 89b624308e636544a3a062e37815517643bafa4c Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Mon, 14 Nov 2016 21:40:03 +0300 Subject: [PATCH 13/17] added ASCII art --- Reseed.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Reseed.cpp b/Reseed.cpp index 427e839d..f6656872 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -320,6 +320,14 @@ namespace data }); if (numOutdated > numFiles/2) // more than half LogPrint (eLogError, "Reseed: mammoth's shit"); + LogPrint (eLogError, " *_____*", + std::endl, " *_*****_*", + std::endl, " *_(O)_(O)_*", + std::endl, "**____V____**", + std::endl, "**_________**", + std::endl, "**_________**", + std::endl, " *_________*", + std::endl, " ***___***"); } return numFiles; } From ea191afd9db67cab77d633890e20e1f0d2228741 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Nov 2016 13:48:34 -0500 Subject: [PATCH 14/17] fixed build error --- Reseed.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Reseed.cpp b/Reseed.cpp index f6656872..214f5bdf 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -319,15 +319,17 @@ namespace data } }); if (numOutdated > numFiles/2) // more than half + { LogPrint (eLogError, "Reseed: mammoth's shit"); - LogPrint (eLogError, " *_____*", + /*LogPrint (eLogError, " *_____*", std::endl, " *_*****_*", std::endl, " *_(O)_(O)_*", std::endl, "**____V____**", std::endl, "**_________**", std::endl, "**_________**", std::endl, " *_________*", - std::endl, " ***___***"); + std::endl, " ***___***");*/ + } } return numFiles; } From 87fd0e6f29206f9aa67d682c3b622b81bf27db1c Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Mon, 14 Nov 2016 22:38:35 +0300 Subject: [PATCH 15/17] recommit fixed ASCII art --- Reseed.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Reseed.cpp b/Reseed.cpp index 214f5bdf..9356222a 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -319,17 +319,15 @@ namespace data } }); if (numOutdated > numFiles/2) // more than half - { - LogPrint (eLogError, "Reseed: mammoth's shit"); - /*LogPrint (eLogError, " *_____*", - std::endl, " *_*****_*", - std::endl, " *_(O)_(O)_*", - std::endl, "**____V____**", - std::endl, "**_________**", - std::endl, "**_________**", - std::endl, " *_________*", - std::endl, " ***___***");*/ - } + LogPrint (eLogError, "Reseed: mammoth's shit\n" + " *_____*\n" + " *_*****_*\n" + " *_(O)_(O)_*\n" + " **____V____**\n" + " **_________**\n" + " **_________**\n" + " *_________*\n" + " ***___***"); } return numFiles; } From 2eea85b7864e754c11a844b5864a40d7f84f0246 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Nov 2016 15:04:40 -0500 Subject: [PATCH 16/17] increase reseed expiration time to 81 hours --- Reseed.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Reseed.cpp b/Reseed.cpp index 9356222a..8c8cc881 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -312,13 +312,14 @@ namespace data i2p::data::netdb.VisitRouterInfos ( [&numOutdated, ts](std::shared_ptr r) { - if (r && ts > r->GetTimestamp () + i2p::data::NETDB_MAX_EXPIRATION_TIMEOUT*1000LL) + if (r && ts > r->GetTimestamp () + 3*i2p::data::NETDB_MAX_EXPIRATION_TIMEOUT*1000LL) // 81 hours { LogPrint (eLogError, "Reseed: router ", r->GetIdentHash().ToBase64 (), " is outdated by ", (ts - r->GetTimestamp ())/1000LL/3600LL, " hours"); numOutdated++; } }); if (numOutdated > numFiles/2) // more than half + { LogPrint (eLogError, "Reseed: mammoth's shit\n" " *_____*\n" " *_*****_*\n" @@ -328,6 +329,8 @@ namespace data " **_________**\n" " *_________*\n" " ***___***"); + numFiles = numFiles > numOutdated ? numFiles - numOutdated : 0; + } } return numFiles; } From ecdb60b44e4827aa1973124e94cd2cc5f31a02d6 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 14 Nov 2016 16:23:42 -0500 Subject: [PATCH 17/17] cleanup netdb after failed reseed --- NetDb.h | 2 +- Reseed.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/NetDb.h b/NetDb.h index 94c8a086..f6d64309 100644 --- a/NetDb.h +++ b/NetDb.h @@ -99,7 +99,7 @@ namespace data void VisitRouterInfos(RouterInfoVisitor v); /** visit N random router that match using filter, then visit them with a visitor, return number of RouterInfos that were visited */ size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n); - + void ClearRouterInfos () { m_RouterInfos.clear (); }; private: diff --git a/Reseed.cpp b/Reseed.cpp index 8c8cc881..3ea69eff 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -312,7 +312,7 @@ namespace data i2p::data::netdb.VisitRouterInfos ( [&numOutdated, ts](std::shared_ptr r) { - if (r && ts > r->GetTimestamp () + 3*i2p::data::NETDB_MAX_EXPIRATION_TIMEOUT*1000LL) // 81 hours + if (r && ts > r->GetTimestamp () + 10*i2p::data::NETDB_MAX_EXPIRATION_TIMEOUT*1000LL) // 270 hours { LogPrint (eLogError, "Reseed: router ", r->GetIdentHash().ToBase64 (), " is outdated by ", (ts - r->GetTimestamp ())/1000LL/3600LL, " hours"); numOutdated++; @@ -329,7 +329,8 @@ namespace data " **_________**\n" " *_________*\n" " ***___***"); - numFiles = numFiles > numOutdated ? numFiles - numOutdated : 0; + i2p::data::netdb.ClearRouterInfos (); + numFiles = 0; } } return numFiles;