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/Config.cpp b/Config.cpp index 71fcbfbd..8d932048 100644 --- a/Config.cpp +++ b/Config.cpp @@ -166,7 +166,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/," diff --git a/Crypto.cpp b/Crypto.cpp index 6b5fb7d6..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,20 +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) - { - 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 7d9a38d7..476d2a26 100644 --- a/Crypto.h +++ b/Crypto.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "Base.h" @@ -35,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 @@ -281,6 +281,8 @@ namespace crypto void InitCrypto (bool precomputation); void TerminateCrypto (); +} +} // take care about openssl version #include @@ -318,9 +320,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/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/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/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/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/NetDb.h b/NetDb.h index 94c8a086..ba65b1e4 100644 --- a/NetDb.h +++ b/NetDb.h @@ -100,8 +100,8 @@ namespace data /** 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: void Load (); diff --git a/Reseed.cpp b/Reseed.cpp index d8a265db..3ea69eff 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -305,6 +305,34 @@ 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 () + 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++; + } + }); + if (numOutdated > numFiles/2) // more than half + { + LogPrint (eLogError, "Reseed: mammoth's shit\n" + " *_____*\n" + " *_*****_*\n" + " *_(O)_(O)_*\n" + " **____V____**\n" + " **_________**\n" + " **_________**\n" + " *_________*\n" + " ***___***"); + i2p::data::netdb.ClearRouterInfos (); + numFiles = 0; + } + } return numFiles; } @@ -350,9 +378,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 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 () 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; 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 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 diff --git a/docs/usage.md b/docs/usage.md index a4bcbb77..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 @@ -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