From 81978b214c111a030a658468c403ea60129300db Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Nov 2016 09:24:49 -0500 Subject: [PATCH 01/12] correct NTCP sessions termination --- NTCPSession.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index a9e13fc5..73cd1828 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -803,6 +803,12 @@ namespace transport void NTCPServer::Stop () { + { + // we have to copy it because Terminate changes m_NTCPSessions + auto ntcpSessions = m_NTCPSessions; + for (auto& it: ntcpSessions) + it.second->Terminate (); + } m_NTCPSessions.clear (); if (m_IsRunning) From 1d8807a6ba880bf330cedf51bfb2fbe88bb15513 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Nov 2016 14:51:26 -0500 Subject: [PATCH 02/12] handle async_receive_from errors --- SSU.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/SSU.cpp b/SSU.cpp index 72091e00..c5f64709 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -207,8 +207,12 @@ namespace transport } else { - LogPrint (eLogError, "SSU: receive error: ", ecode.message ()); delete packet; + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogError, "SSU: receive error: ", ecode.message ()); + Receive (); + } } } @@ -234,8 +238,12 @@ namespace transport } else { - LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ()); delete packet; + if (ecode != boost::asio::error::operation_aborted) + { + LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ()); + ReceiveV6 (); + } } } From 230c2aaf269f60a42a81f3c75d90283fa097a761 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 30 Nov 2016 21:14:10 -0500 Subject: [PATCH 03/12] reopen UDP socket in case of error --- SSU.cpp | 41 +++++++++++++++++++++++++---------------- SSU.h | 2 ++ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/SSU.cpp b/SSU.cpp index c5f64709..91c14ccf 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -20,11 +20,7 @@ namespace transport m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6) { - 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 (65535)); - m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (65535)); - m_SocketV6.bind (m_EndpointV6); + OpenSocketV6 (); } SSUServer::SSUServer (int port): @@ -32,27 +28,36 @@ namespace transport m_Thread (nullptr), m_ThreadV6 (nullptr), m_ReceiversThread (nullptr), m_Work (m_Service), m_WorkV6 (m_ServiceV6), m_ReceiversWork (m_ReceiversService), m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port), - m_Socket (m_ReceiversService, m_Endpoint), m_SocketV6 (m_ReceiversService), + m_Socket (m_ReceiversService), m_SocketV6 (m_ReceiversService), m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service), m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6) { - - m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (65535)); - m_Socket.set_option (boost::asio::socket_base::send_buffer_size (65535)); + OpenSocket (); if (context.SupportsV6 ()) - { - 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 (65535)); - m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (65535)); - m_SocketV6.bind (m_EndpointV6); - } + OpenSocketV6 (); } SSUServer::~SSUServer () { } + void SSUServer::OpenSocket () + { + m_Socket.open (boost::asio::ip::udp::v4()); + m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (65535)); + m_Socket.set_option (boost::asio::socket_base::send_buffer_size (65535)); + m_Socket.bind (m_Endpoint); + } + + 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 (65535)); + m_SocketV6.set_option (boost::asio::socket_base::send_buffer_size (65535)); + m_SocketV6.bind (m_EndpointV6); + } + void SSUServer::Start () { m_IsRunning = true; @@ -211,6 +216,8 @@ namespace transport if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogError, "SSU: receive error: ", ecode.message ()); + m_Socket.close (); + OpenSocket (); Receive (); } } @@ -242,6 +249,8 @@ namespace transport if (ecode != boost::asio::error::operation_aborted) { LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ()); + m_SocketV6.close (); + OpenSocketV6 (); ReceiveV6 (); } } diff --git a/SSU.h b/SSU.h index 182fa0eb..7016e23e 100644 --- a/SSU.h +++ b/SSU.h @@ -68,6 +68,8 @@ namespace transport private: + void OpenSocket (); + void OpenSocketV6 (); void Run (); void RunV6 (); void RunReceivers (); From 0d589895f62925c718d7d26cafd2ba7434875d1d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Dec 2016 10:51:01 -0500 Subject: [PATCH 04/12] print time difference with one in timestamp message --- NTCPSession.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 73cd1828..3ef986f2 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -589,7 +589,8 @@ namespace transport else { // timestamp - LogPrint (eLogDebug, "NTCP: Timestamp"); + int diff = (int)bufbe32toh (buf + 2) - (int)i2p::util::GetSecondsSinceEpoch (); + LogPrint (eLogInfo, "NTCP: Timestamp. Time difference ", diff, " seconds"); return true; } } @@ -650,7 +651,7 @@ namespace transport sendBuffer = m_TimeSyncBuffer; len = 4; htobuf16(sendBuffer, 0); - htobe32buf (sendBuffer + 2, time (0)); + htobe32buf (sendBuffer + 2, i2p::util::GetSecondsSinceEpoch ()); } int rem = (len + 6) & 0x0F; // %16 int padding = 0; @@ -966,7 +967,7 @@ namespace transport { if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogError, "NTCP: Not connected in ", NTCP_CONNECT_TIMEOUT, " seconds"); + LogPrint (eLogInfo, "NTCP: Not connected in ", NTCP_CONNECT_TIMEOUT, " seconds"); conn->Terminate (); } }); @@ -981,7 +982,7 @@ namespace transport timer->cancel (); if (ecode) { - LogPrint (eLogError, "NTCP: Connect error ", ecode.message ()); + LogPrint (eLogInfo, "NTCP: Connect error ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); conn->Terminate (); From 06b0a504623d9579b04d0e7cb5b17a01ace45038 Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Thu, 1 Dec 2016 20:17:28 +0300 Subject: [PATCH 05/12] static libminiupnpc --- Makefile.linux | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index 28081c81..8def8299 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -45,10 +45,14 @@ else LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread endif -# UPNP Support (miniupnpc 1.5 or 1.6) +# UPNP Support (miniupnpc 1.5 and higher) ifeq ($(USE_UPNP),yes) - LDFLAGS += -lminiupnpc CXXFLAGS += -DUSE_UPNP +ifeq ($(USE_STATIC),yes) + LDLIBS += $(LIBDIR)/libminiupnpc.a +else + LDLIBS += -lminiupnpc +endif endif IS_64 := $(shell $(CXX) -dumpmachine 2>&1 | $(GREP) -c "64") From 5c20751937c032e64f7102c1d95ed4d115e59160 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Dec 2016 14:06:23 -0500 Subject: [PATCH 06/12] give priority to ipv6 --- RouterInfo.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index b570d6c2..fe236816 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -256,7 +256,10 @@ namespace data } if (isValidAddress) { - addresses->push_back(std::make_shared
(address)); + if (supportedTransports & eNTCPV6) // ipv6 NTCP ? + addresses->push_front(std::make_shared
(address)); // ipv6 has priority over ipv4 + else + addresses->push_back(std::make_shared
(address)); m_SupportedTransports |= supportedTransports; } } From b8a01d2ff131e38f5827163227d863db749cc3e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Dec 2016 15:03:54 -0500 Subject: [PATCH 07/12] rollback --- RouterInfo.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index fe236816..b570d6c2 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -256,10 +256,7 @@ namespace data } if (isValidAddress) { - if (supportedTransports & eNTCPV6) // ipv6 NTCP ? - addresses->push_front(std::make_shared
(address)); // ipv6 has priority over ipv4 - else - addresses->push_back(std::make_shared
(address)); + addresses->push_back(std::make_shared
(address)); m_SupportedTransports |= supportedTransports; } } From 2651723b50b14e56f8e44312ad3fe6e566437117 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Dec 2016 19:23:55 -0500 Subject: [PATCH 08/12] fixed termination crash --- Destination.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 80951dc4..3a5846bd 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -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 () @@ -128,14 +130,7 @@ 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_PublishVerificationTimer.cancel (); m_IsRunning = false; if (m_Pool) @@ -706,12 +701,12 @@ namespace client { m_ReadyChecker.cancel(); m_StreamingDestination->Stop (); - m_StreamingDestination->SetOwner (nullptr); + //m_StreamingDestination->SetOwner (nullptr); m_StreamingDestination = nullptr; for (auto& it: m_StreamingDestinationsByPorts) { it.second->Stop (); - it.second->SetOwner (nullptr); + //it.second->SetOwner (nullptr); } m_StreamingDestinationsByPorts.clear (); if (m_DatagramDestination) From 87228429d6ff0cb0f8c100b2f8db59d955a79036 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Dec 2016 19:24:15 -0500 Subject: [PATCH 09/12] handle receive_from errors --- SSU.cpp | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/SSU.cpp b/SSU.cpp index 91c14ccf..cd0c0292 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -199,13 +199,26 @@ namespace transport boost::system::error_code ec; size_t moreBytes = m_Socket.available(ec); - while (moreBytes && packets.size () < 25) - { - packet = new SSUPacket (); - packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from); - packets.push_back (packet); - moreBytes = m_Socket.available(); - } + if (!ec) + { + while (moreBytes && packets.size () < 25) + { + packet = new SSUPacket (); + packet->len = m_Socket.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V4), packet->from, 0, ec); + if (!ec) + { + packets.push_back (packet); + moreBytes = m_Socket.available(ec); + if (ec) break; + } + else + { + LogPrint (eLogError, "SSU: receive_from error: ", ec.message ()); + delete packet; + break; + } + } + } m_Service.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_Sessions)); Receive (); @@ -231,15 +244,29 @@ namespace transport std::vector packets; packets.push_back (packet); - size_t moreBytes = m_SocketV6.available (); - while (moreBytes && packets.size () < 25) + boost::system::error_code ec; + size_t moreBytes = m_SocketV6.available (ec); + if (!ec) { - packet = new SSUPacket (); - packet->len = m_SocketV6.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from); - packets.push_back (packet); - moreBytes = m_SocketV6.available(); + while (moreBytes && packets.size () < 25) + { + packet = new SSUPacket (); + packet->len = m_SocketV6.receive_from (boost::asio::buffer (packet->buf, SSU_MTU_V6), packet->from, 0, ec); + if (!ec) + { + packets.push_back (packet); + moreBytes = m_SocketV6.available(ec); + if (ec) break; + } + else + { + LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ()); + delete packet; + break; + } + } } - + m_ServiceV6.post (std::bind (&SSUServer::HandleReceivedPackets, this, packets, &m_SessionsV6)); ReceiveV6 (); } From db83cbe58f0ed504aae9cf5758a0388782d949c6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 1 Dec 2016 22:14:43 -0500 Subject: [PATCH 10/12] handle read_some errors --- NTCPSession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 3ef986f2..81cfe687 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -537,11 +537,11 @@ namespace transport { boost::system::error_code ec; size_t moreBytes = m_Socket.available(ec); - if (moreBytes) + if (moreBytes && !ec) { if (moreBytes > NTCP_BUFFER_SIZE - m_ReceiveBufferOffset) moreBytes = NTCP_BUFFER_SIZE - m_ReceiveBufferOffset; - moreBytes = m_Socket.read_some (boost::asio::buffer (m_ReceiveBuffer + m_ReceiveBufferOffset, moreBytes)); + moreBytes = m_Socket.read_some (boost::asio::buffer (m_ReceiveBuffer + m_ReceiveBufferOffset, moreBytes), ec); if (ec) { LogPrint (eLogInfo, "NTCP: Read more bytes error: ", ec.message ()); From 7a7ae4cc833088113e299abc729df52503d96c42 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Dec 2016 11:17:22 -0500 Subject: [PATCH 11/12] select ipv4 peers for peer test --- NetDb.cpp | 6 +++--- NetDb.h | 2 +- SSU.cpp | 4 ++-- SSU.h | 2 +- Transports.cpp | 25 ++++++++++++++----------- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/NetDb.cpp b/NetDb.cpp index 5a622441..e75cf217 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -1008,12 +1008,12 @@ namespace data }); } - std::shared_ptr NetDb::GetRandomPeerTestRouter () const + std::shared_ptr NetDb::GetRandomPeerTestRouter (bool v4only) const { return GetRandomRouter ( - [](std::shared_ptr router)->bool + [v4only](std::shared_ptr router)->bool { - return !router->IsHidden () && router->IsPeerTesting (); + return !router->IsHidden () && router->IsPeerTesting () && router->IsSSU (v4only); }); } diff --git a/NetDb.h b/NetDb.h index ba65b1e4..954cc74e 100644 --- a/NetDb.h +++ b/NetDb.h @@ -69,7 +69,7 @@ namespace data std::shared_ptr GetRandomRouter () const; std::shared_ptr GetRandomRouter (std::shared_ptr compatibleWith) const; std::shared_ptr GetHighBandwidthRandomRouter (std::shared_ptr compatibleWith) const; - std::shared_ptr GetRandomPeerTestRouter () const; + std::shared_ptr GetRandomPeerTestRouter (bool v4only = true) const; 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/SSU.cpp b/SSU.cpp index cd0c0292..198fed4b 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -342,9 +342,9 @@ namespace transport return nullptr; } - void SSUServer::CreateSession (std::shared_ptr router, bool peerTest) + void SSUServer::CreateSession (std::shared_ptr router, bool peerTest, bool v4only) { - auto address = router->GetSSUAddress (!context.SupportsV6 ()); + auto address = router->GetSSUAddress (v4only || !context.SupportsV6 ()); if (address) CreateSession (router, address->host, address->port, peerTest); else diff --git a/SSU.h b/SSU.h index 7016e23e..9d8e2878 100644 --- a/SSU.h +++ b/SSU.h @@ -42,7 +42,7 @@ namespace transport ~SSUServer (); void Start (); void Stop (); - void CreateSession (std::shared_ptr router, bool peerTest = false); + void CreateSession (std::shared_ptr router, bool peerTest = false, bool v4only = false); void CreateSession (std::shared_ptr router, const boost::asio::ip::address& addr, int port, bool peerTest = false); void CreateDirectSession (std::shared_ptr router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest); diff --git a/Transports.cpp b/Transports.cpp index d06d8670..1b9d52a1 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -519,7 +519,7 @@ namespace transport void Transports::DetectExternalIP () { if (RoutesRestricted()) - { + { LogPrint(eLogInfo, "Transports: restricted routes enabled, not detecting ip"); i2p::context.SetStatus (eRouterStatusOK); return; @@ -527,13 +527,14 @@ namespace transport if (m_SSUServer) { bool nat; i2p::config::GetOption("nat", nat); - if (nat) + bool isv4 = i2p::context.SupportsV4 (); + if (nat && isv4) i2p::context.SetStatus (eRouterStatusTesting); for (int i = 0; i < 5; i++) { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (); - if (router && router->IsSSU (!context.SupportsV6 ())) - m_SSUServer->CreateSession (router, true); // peer test + auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4 + if (router) + m_SSUServer->CreateSession (router, true, isv4); // peer test else { // if not peer test capable routers found pick any @@ -549,23 +550,25 @@ namespace transport void Transports::PeerTest () { - if (RoutesRestricted()) return; + if (RoutesRestricted() || !i2p::context.SupportsV4 ()) return; if (m_SSUServer) - { + { bool statusChanged = false; for (int i = 0; i < 5; i++) { - auto router = i2p::data::netdb.GetRandomPeerTestRouter (); - if (router && router->IsSSU (!context.SupportsV6 ())) + auto router = i2p::data::netdb.GetRandomPeerTestRouter (true); // v4 only + if (router) { if (!statusChanged) { statusChanged = true; i2p::context.SetStatus (eRouterStatusTesting); // first time only } - m_SSUServer->CreateSession (router, true); // peer test + m_SSUServer->CreateSession (router, true, true); // peer test v4 } - } + } + if (!statusChanged) + LogPrint (eLogWarning, "Can't find routers for peer test"); } } From 739b6645f8941af16ea9869be17c9dda13b429fd Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 2 Dec 2016 16:10:49 -0500 Subject: [PATCH 12/12] eliminate bad_function_call exception --- Destination.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 3a5846bd..61960464 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -527,7 +527,8 @@ namespace client if (floodfill) { auto request = std::make_shared (m_Service); - request->requestComplete.push_back (requestComplete); + if (requestComplete) + request->requestComplete.push_back (requestComplete); auto ts = i2p::util::GetSecondsSinceEpoch (); auto ret = m_LeaseSetRequests.insert (std::pair >(dest,request)); if (ret.second) // inserted @@ -537,7 +538,7 @@ namespace client { // request failed m_LeaseSetRequests.erase (ret.first); - requestComplete (nullptr); + if (requestComplete) requestComplete (nullptr); } } else // duplicate @@ -547,13 +548,13 @@ namespace client //ret.first->second->requestComplete.push_back (requestComplete); if (ts > ret.first->second->requestTime + MAX_LEASESET_REQUEST_TIMEOUT) m_LeaseSetRequests.erase (ret.first); - requestComplete (nullptr); + if (requestComplete) requestComplete (nullptr); } } else { LogPrint (eLogError, "Destination: Can't request LeaseSet, no floodfills found"); - requestComplete (nullptr); + if (requestComplete) requestComplete (nullptr); } }