diff --git a/Destination.cpp b/Destination.cpp index 7b2e896d..80951dc4 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) { @@ -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); } @@ -113,12 +110,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 @@ -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) { @@ -145,6 +150,7 @@ namespace client delete m_Thread; m_Thread = 0; } + CleanUp (); // GarlicDestination return true; } else @@ -700,13 +706,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/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 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 (); diff --git a/NTCPSession.cpp b/NTCPSession.cpp index b65532be..a9e13fc5 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -951,15 +951,28 @@ namespace transport { 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 (eLogError, "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)); + std::bind (&NTCPServer::HandleConnect, this, std::placeholders::_1, conn, timer)); + } }); } - void NTCPServer::HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn) + void NTCPServer::HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer) { + timer->cancel (); if (ecode) { LogPrint (eLogError, "NTCP: Connect error ", ecode.message ()); diff --git a/NTCPSession.h b/NTCPSession.h index a3d95c62..639942f2 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -36,6 +36,7 @@ namespace transport const size_t NTCP_MAX_MESSAGE_SIZE = 16384; const size_t NTCP_BUFFER_SIZE = 4160; // fits 4 tunnel messages (4*1028) + const int NTCP_CONNECT_TIMEOUT = 5; // 5 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 @@ -153,7 +154,7 @@ namespace transport 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); + void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn, std::shared_ptr timer); // timer void ScheduleTermination (); 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); 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):