From 55dbbb3546004b2c57e2ac14a45892aacf53b730 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 23 Nov 2016 16:30:36 -0500 Subject: [PATCH 01/11] fixed memory leak --- Crypto.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Crypto.h b/Crypto.h index b9d25216..ee5f49ca 100644 --- a/Crypto.h +++ b/Crypto.h @@ -302,7 +302,11 @@ inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **p { *pr = sig->r; *ps = sig->s; } inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) - { sig->r = r; sig->s = s; return 1; } + { + if (sig->r) BN_free (sig->r); + if (sig->s) BN_free (sig->s); + sig->r = r; sig->s = s; return 1; + } inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { *pr = sig->r; *ps = sig->s; } From 006e4526e885ccd6a59d99d3c71e11ff77a14b82 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 23 Nov 2016 16:41:27 -0500 Subject: [PATCH 02/11] fixed memory leak --- Signature.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Signature.h b/Signature.h index 1d90d8a3..a4f37980 100644 --- a/Signature.h +++ b/Signature.h @@ -155,9 +155,10 @@ namespace crypto ECDSAVerifier (const uint8_t * signingKey) { m_PublicKey = EC_KEY_new_by_curve_name (curve); - EC_KEY_set_public_key_affine_coordinates (m_PublicKey, - BN_bin2bn (signingKey, keyLen/2, NULL), - BN_bin2bn (signingKey + keyLen/2, keyLen/2, NULL)); + 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); + BN_free (x); BN_free (y); } ~ECDSAVerifier () From a92652f4ad4722fb249bf24c45d70a9a0b391694 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 24 Nov 2016 10:11:46 -0500 Subject: [PATCH 03/11] add ifname4 and ifname6 options --- Config.cpp | 6 ++++-- RouterContext.cpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Config.cpp b/Config.cpp index d8dd6a27..6f4014ba 100644 --- a/Config.cpp +++ b/Config.cpp @@ -41,6 +41,8 @@ namespace config { ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") ("host", value()->default_value("0.0.0.0"), "External IP") ("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()->zero_tokens()->default_value(true), "Should we assume we are behind NAT?") ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") ("ipv4", value()->zero_tokens()->default_value(true), "Enable communication through ipv4") @@ -59,7 +61,7 @@ namespace config { ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; - + options_description limits("Limits options"); limits.add_options() ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") @@ -192,7 +194,7 @@ namespace config { ("trust.family", value()->default_value(""), "Router Familiy to trust for first hops") ("trust.routers", value()->default_value(""), "Only Connect to these routers") ("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") diff --git a/RouterContext.cpp b/RouterContext.cpp index 7847bef7..c1341a62 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -74,6 +74,22 @@ namespace i2p routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddNTCPAddress (host.c_str(), port); } + + std::string ifname4; i2p::config::GetOption("ifname4", ifname4); + if(ifname4.size()) + { + std::string host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string(); + routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash()); + routerInfo.AddNTCPAddress (host.c_str(), port); + } + std::string ifname6; i2p::config::GetOption("ifname6", ifname6); + if (ifname6.size()) + { + std::string host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string(); + routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash()); + routerInfo.AddNTCPAddress (host.c_str(), port); + } + routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC routerInfo.SetProperty ("netId", std::to_string (m_NetID)); From 50f0099645b043277426b2fb4eca119826f81760 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 24 Nov 2016 13:56:37 -0500 Subject: [PATCH 04/11] don't add multiple router addresses --- RouterContext.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index c1341a62..3c37e88c 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -53,6 +53,8 @@ namespace i2p bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool nat; i2p::config::GetOption("nat", nat); std::string ifname; i2p::config::GetOption("ifname", ifname); + std::string ifname4; i2p::config::GetOption("ifname4", ifname4); + std::string ifname6; i2p::config::GetOption("ifname6", ifname6); if (ipv4) { std::string host = "127.0.0.1"; @@ -61,6 +63,10 @@ namespace i2p else if (!nat && !ifname.empty()) /* bind to interface, we have no NAT so set external address too */ host = i2p::util::net::GetInterfaceAddress(ifname, false).to_string(); // v4 + + if(ifname4.size()) + host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string(); + routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddNTCPAddress (host.c_str(), port); } @@ -71,24 +77,13 @@ namespace i2p i2p::config::GetOption("host", host); else if (!ifname.empty()) host = i2p::util::net::GetInterfaceAddress(ifname, true).to_string(); // v6 - routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); - routerInfo.AddNTCPAddress (host.c_str(), port); - } - std::string ifname4; i2p::config::GetOption("ifname4", ifname4); - if(ifname4.size()) - { - std::string host = i2p::util::net::GetInterfaceAddress(ifname4, false).to_string(); - routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash()); + if(ifname6.size()) + host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string(); + + routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddNTCPAddress (host.c_str(), port); } - std::string ifname6; i2p::config::GetOption("ifname6", ifname6); - if (ifname6.size()) - { - std::string host = i2p::util::net::GetInterfaceAddress(ifname6, true).to_string(); - routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash()); - routerInfo.AddNTCPAddress (host.c_str(), port); - } routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC From d092b21da7c4a63b44b59a4ddd24e7ded7f6de63 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 24 Nov 2016 16:02:14 -0500 Subject: [PATCH 05/11] assume ElGamal data size as 222 bytes --- Crypto.cpp | 4 ++-- Crypto.h | 2 +- Garlic.cpp | 2 +- TunnelConfig.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 54180677..91b0ad08 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -308,12 +308,12 @@ namespace crypto BN_free (b1); } - void ElGamalEncryption::Encrypt (const uint8_t * data, int len, uint8_t * encrypted, bool zeroPadding) const + void ElGamalEncryption::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) const { // create m uint8_t m[255]; m[0] = 0xFF; - memcpy (m+33, data, len); + memcpy (m+33, data, 222); SHA256 (m+33, 222, m+1); // calculate b = b1*m mod p BIGNUM * b = BN_new (); diff --git a/Crypto.h b/Crypto.h index ee5f49ca..a04a93da 100644 --- a/Crypto.h +++ b/Crypto.h @@ -54,7 +54,7 @@ namespace crypto ElGamalEncryption (const uint8_t * key); ~ElGamalEncryption (); - void Encrypt (const uint8_t * data, int len, uint8_t * encrypted, bool zeroPadding = false) const; + void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false) const; private: diff --git a/Garlic.cpp b/Garlic.cpp index 94ca82eb..306ac816 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -188,7 +188,7 @@ namespace garlic RAND_bytes (elGamal.preIV, 32); // Pre-IV uint8_t iv[32]; // IV is first 16 bytes SHA256(elGamal.preIV, 32, iv); - m_ElGamalEncryption->Encrypt ((uint8_t *)&elGamal, sizeof(elGamal), buf, true); + m_ElGamalEncryption->Encrypt ((uint8_t *)&elGamal, buf, true); m_Encryption.SetIV (iv); buf += 514; len += 514; diff --git a/TunnelConfig.h b/TunnelConfig.h index 23417ed9..cb31243f 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -102,7 +102,7 @@ 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); i2p::crypto::ElGamalEncryption elGamalEncryption (ident->GetEncryptionPublicKey ()); - elGamalEncryption.Encrypt (clearText, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); + elGamalEncryption.Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } }; From c6ddae2d8e7308c6f08c0c4b91cd02e62748c88a Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 25 Nov 2016 13:45:41 -0500 Subject: [PATCH 06/11] excluded obsolete boost dependancies --- docs/building/unix.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/building/unix.md b/docs/building/unix.md index 17623159..b5c38aed 100644 --- a/docs/building/unix.md +++ b/docs/building/unix.md @@ -64,12 +64,10 @@ You will need a compiler and other tools that could be installed with `build-ess Also you will need a bunch of development libraries: sudo apt-get install \ - libboost-chrono-dev \ libboost-date-time-dev \ libboost-filesystem-dev \ libboost-program-options-dev \ libboost-system-dev \ - libboost-thread-dev \ libssl-dev If you need UPnP support miniupnpc development library should be installed (don't forget to rerun CMake with needed option): From 0e14b54b6d4c74fbd4d7f4ec4cfd629a0667a7cd Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 25 Nov 2016 22:36:35 -0500 Subject: [PATCH 07/11] break circular reference --- Destination.cpp | 15 +++++++++++---- Streaming.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 7b2e896d..66fb4cef 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -700,13 +700,20 @@ namespace client { m_ReadyChecker.cancel(); m_StreamingDestination->Stop (); + m_StreamingDestination->SetOwner (nullptr); m_StreamingDestination = nullptr; for (auto& it: m_StreamingDestinationsByPorts) + { it.second->Stop (); - if(m_DatagramDestination) - delete m_DatagramDestination; - m_DatagramDestination = nullptr; - return true; + it.second->SetOwner (nullptr); + } + m_StreamingDestinationsByPorts.clear (); + if (m_DatagramDestination) + { + delete m_DatagramDestination; + m_DatagramDestination = nullptr; + } + return true; } else return false; diff --git a/Streaming.h b/Streaming.h index e4a1562c..65a8d8b4 100644 --- a/Streaming.h +++ b/Streaming.h @@ -224,6 +224,7 @@ namespace stream void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; 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); From 5e5aefa2901c338de2af45cb87f031a45fb437f3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 27 Nov 2016 10:14:54 -0500 Subject: [PATCH 08/11] cleanup leaseset requests on stop --- Destination.cpp | 11 ++++++++--- Garlic.cpp | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 66fb4cef..9016c825 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -85,9 +85,6 @@ namespace client { if (m_IsRunning) Stop (); - for (auto& it: m_LeaseSetRequests) - it.second->Complete (nullptr); - m_LeaseSetRequests.clear (); if (m_Pool) i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); } @@ -132,6 +129,14 @@ namespace client m_CleanupTimer.cancel (); m_PublishConfirmationTimer.cancel (); m_PublishVerificationTimer.cancel (); + + for (auto& it: m_LeaseSetRequests) + { + it.second->Complete (nullptr); + it.second->requestTimeoutTimer.cancel (); + } + m_LeaseSetRequests.clear (); + m_IsRunning = false; if (m_Pool) { diff --git a/Garlic.cpp b/Garlic.cpp index 306ac816..a11d89a0 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -392,6 +392,10 @@ namespace garlic GarlicDestination::~GarlicDestination () { + m_Sessions.clear (); + m_DeliveryStatusSessions.clear (); + m_Tags.clear (); + LogPrint (eLogInfo, "Garlic: destination destoryed"); } void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag) From c8b935151aa47bb8eb8627d9d3f442daf626de26 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 28 Nov 2016 13:47:10 -0500 Subject: [PATCH 09/11] fixed tremination crash --- Destination.cpp | 19 +++++++------------ Destination.h | 1 - Garlic.cpp | 5 +---- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 9016c825..d4982ed6 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -13,7 +13,7 @@ namespace i2p namespace client { LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map * params): - m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_IsPublic (isPublic), + m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), m_PublishReplyToken (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_CleanupTimer (m_Service) { @@ -87,6 +87,8 @@ namespace client Stop (); if (m_Pool) i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); + for (auto& it: m_LeaseSetRequests) + it.second->Complete (nullptr); } void LeaseSetDestination::Run () @@ -110,12 +112,12 @@ namespace client { m_IsRunning = true; m_Pool->SetLocalDestination (shared_from_this ()); - m_Pool->SetActive (true); - m_Thread = new std::thread (std::bind (&LeaseSetDestination::Run, 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)); + shared_from_this (), std::placeholders::_1)); + m_Thread = new std::thread (std::bind (&LeaseSetDestination::Run, shared_from_this ())); + return true; } else @@ -129,13 +131,6 @@ namespace client m_CleanupTimer.cancel (); m_PublishConfirmationTimer.cancel (); m_PublishVerificationTimer.cancel (); - - for (auto& it: m_LeaseSetRequests) - { - it.second->Complete (nullptr); - it.second->requestTimeoutTimer.cancel (); - } - m_LeaseSetRequests.clear (); m_IsRunning = false; if (m_Pool) diff --git a/Destination.h b/Destination.h index 5b3ee655..1ccb0a9c 100644 --- a/Destination.h +++ b/Destination.h @@ -137,7 +137,6 @@ namespace client volatile bool m_IsRunning; std::thread * m_Thread; boost::asio::io_service m_Service; - boost::asio::io_service::work m_Work; mutable std::mutex m_RemoteLeaseSetsMutex; std::map > m_RemoteLeaseSets; std::map > m_LeaseSetRequests; diff --git a/Garlic.cpp b/Garlic.cpp index a11d89a0..8f1d59b6 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -392,10 +392,7 @@ namespace garlic GarlicDestination::~GarlicDestination () { - m_Sessions.clear (); - m_DeliveryStatusSessions.clear (); - m_Tags.clear (); - LogPrint (eLogInfo, "Garlic: destination destoryed"); + LogPrint (eLogInfo, "Garlic: destination destroyed"); } void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag) From 3480824290ccf1b1e9c50c3fbbbd02d73b9e8083 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 28 Nov 2016 14:37:17 -0500 Subject: [PATCH 10/11] correct leaseset requests cleanup --- Destination.cpp | 9 +++++++-- Garlic.cpp | 1 - 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index d4982ed6..91f2a2bb 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -87,8 +87,6 @@ namespace client Stop (); if (m_Pool) i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); - for (auto& it: m_LeaseSetRequests) - it.second->Complete (nullptr); } void LeaseSetDestination::Run () @@ -132,6 +130,13 @@ namespace client m_PublishConfirmationTimer.cancel (); m_PublishVerificationTimer.cancel (); + for (auto& it: m_LeaseSetRequests) + { + it.second->Complete (nullptr); + it.second->requestTimeoutTimer.cancel (); + } + m_LeaseSetRequests.clear (); + m_IsRunning = false; if (m_Pool) { diff --git a/Garlic.cpp b/Garlic.cpp index 8f1d59b6..306ac816 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -392,7 +392,6 @@ namespace garlic GarlicDestination::~GarlicDestination () { - LogPrint (eLogInfo, "Garlic: destination destroyed"); } void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag) From e726d216bbe274c7653d2df9a783f7ab18fdba2a Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 28 Nov 2016 22:47:37 -0500 Subject: [PATCH 11/11] cleanup tags on stop --- Destination.cpp | 1 + Garlic.cpp | 6 ++++++ Garlic.h | 1 + 3 files changed, 8 insertions(+) diff --git a/Destination.cpp b/Destination.cpp index 91f2a2bb..80951dc4 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -150,6 +150,7 @@ namespace client delete m_Thread; m_Thread = 0; } + CleanUp (); // GarlicDestination return true; } else diff --git a/Garlic.cpp b/Garlic.cpp index 306ac816..ab20ac8f 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -394,6 +394,12 @@ namespace garlic { } + void GarlicDestination::CleanUp () + { + m_Sessions.clear (); + m_DeliveryStatusSessions.clear (); + m_Tags.clear (); + } void GarlicDestination::AddSessionKey (const uint8_t * key, const uint8_t * tag) { if (key) diff --git a/Garlic.h b/Garlic.h index 010338cd..a7e2d264 100644 --- a/Garlic.h +++ b/Garlic.h @@ -156,6 +156,7 @@ namespace garlic GarlicDestination (): m_NumTags (32) {}; // 32 tags by default ~GarlicDestination (); + void CleanUp (); void SetNumTags (int numTags) { m_NumTags = numTags; }; std::shared_ptr GetRoutingSession (std::shared_ptr destination, bool attachLeaseSet); void CleanupExpiredTags ();