From d241e5d5cbf7c78de7badf19608a164d355dbf54 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 19 Nov 2024 19:11:09 -0500 Subject: [PATCH 01/19] handle transit tunnel build messages in separate thread --- libi2pd/TransitTunnel.cpp | 73 +++++++++++++++++++++++++++++++++++++++ libi2pd/TransitTunnel.h | 27 +++++++++++---- libi2pd/Tunnel.cpp | 8 +++-- libi2pd/Tunnel.h | 5 +-- 4 files changed, 101 insertions(+), 12 deletions(-) diff --git a/libi2pd/TransitTunnel.cpp b/libi2pd/TransitTunnel.cpp index edf96c31..8284dc14 100644 --- a/libi2pd/TransitTunnel.cpp +++ b/libi2pd/TransitTunnel.cpp @@ -122,14 +122,86 @@ namespace tunnel } } + TransitTunnels::TransitTunnels (): + m_IsRunning (false) + { + } + + TransitTunnels::~TransitTunnels () + { + Stop (); + } + void TransitTunnels::Start () { + m_IsRunning = true; + m_Thread.reset (new std::thread (std::bind (&TransitTunnels::Run, this))); } void TransitTunnels::Stop () { + m_IsRunning = false; + m_TunnelBuildMsgQueue.WakeUp (); + if (m_Thread) + { + m_Thread->join (); + m_Thread = nullptr; + } m_TransitTunnels.clear (); } + + void TransitTunnels::Run () + { + i2p::util::SetThreadName("TBM"); + uint64_t lastTs = 0; + std::list > msgs; + while (m_IsRunning) + { + try + { + if (m_TunnelBuildMsgQueue.Wait (TRANSIT_TUNNELS_QUEUE_WAIT_INTERVAL, 0)) + { + m_TunnelBuildMsgQueue.GetWholeQueue (msgs); + while (!msgs.empty ()) + { + auto msg = msgs.front (); msgs.pop_front (); + if (!msg) continue; + uint8_t typeID = msg->GetTypeID (); + switch (typeID) + { + case eI2NPShortTunnelBuild: + HandleShortTransitTunnelBuildMsg (std::move (msg)); + break; + case eI2NPVariableTunnelBuild: + HandleVariableTransitTunnelBuildMsg (std::move (msg)); + break; + default: + LogPrint (eLogWarning, "TransitTunnel: Unexpected message type ", (int) typeID); + } + if (!m_IsRunning) break; + } + } + if (m_IsRunning) + { + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); + if (ts >= lastTs + TUNNEL_MANAGE_INTERVAL || ts + TUNNEL_MANAGE_INTERVAL < lastTs) + { + ManageTransitTunnels (ts); + lastTs = ts; + } + } + } + catch (std::exception& ex) + { + LogPrint (eLogError, "TransitTunnel: Runtime exception: ", ex.what ()); + } + } + } + + void TransitTunnels::PostTransitTunnelBuildMsg (std::shared_ptr&& msg) + { + if (msg) m_TunnelBuildMsgQueue.Put (msg); + } void TransitTunnels::HandleShortTransitTunnelBuildMsg (std::shared_ptr&& msg) { @@ -234,6 +306,7 @@ namespace tunnel { if (transitTunnel) { + LogPrint (eLogDebug, "TransitTunnel: Failed to send reply for transit tunnel ", transitTunnel->GetTunnelID ()); auto t = transitTunnel->GetCreationTime (); if (t > i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT) // make transit tunnel expired diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index fc8676d0..bff1a8dd 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -14,6 +14,7 @@ #include #include #include "Crypto.h" +#include "Queue.h" #include "I2NPProtocol.h" #include "TunnelEndpoint.h" #include "TunnelGateway.h" @@ -109,33 +110,45 @@ namespace tunnel const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey, bool isGateway, bool isEndpoint); + + const int TRANSIT_TUNNELS_QUEUE_WAIT_INTERVAL = 10; // in seconds + class TransitTunnels { public: + TransitTunnels (); + ~TransitTunnels (); + void Start (); void Stop (); - void ManageTransitTunnels (uint64_t ts); - + void PostTransitTunnelBuildMsg (std::shared_ptr&& msg); + size_t GetNumTransitTunnels () const { return m_TransitTunnels.size (); } int GetTransitTunnelsExpirationTimeout (); - - void HandleShortTransitTunnelBuildMsg (std::shared_ptr&& msg); - void HandleVariableTransitTunnelBuildMsg (std::shared_ptr&& msg); private: bool AddTransitTunnel (std::shared_ptr tunnel); + void ManageTransitTunnels (uint64_t ts); + + void HandleShortTransitTunnelBuildMsg (std::shared_ptr&& msg); + void HandleVariableTransitTunnelBuildMsg (std::shared_ptr&& msg); bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText); + void Run (); + private: + volatile bool m_IsRunning; + std::unique_ptr m_Thread; std::list > m_TransitTunnels; - + i2p::util::Queue > m_TunnelBuildMsgQueue; + public: // for HTTP only - auto& GetTransitTunnels () const { return m_TransitTunnels; }; + const auto& GetTransitTunnels () const { return m_TransitTunnels; }; }; } } diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index d809e48a..e7443b6c 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -373,6 +373,7 @@ namespace tunnel std::shared_ptr Tunnels::GetTunnel (uint32_t tunnelID) { + std::lock_guard l(m_TunnelsMutex); auto it = m_Tunnels.find(tunnelID); if (it != m_Tunnels.end ()) return it->second; @@ -382,11 +383,13 @@ namespace tunnel bool Tunnels::AddTunnel (std::shared_ptr tunnel) { if (!tunnel) return false; + std::lock_guard l(m_TunnelsMutex); return m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second; } void Tunnels::RemoveTunnel (uint32_t tunnelID) { + std::lock_guard l(m_TunnelsMutex); m_Tunnels.erase (tunnelID); } @@ -655,7 +658,7 @@ namespace tunnel return; } else - m_TransitTunnels.HandleShortTransitTunnelBuildMsg (std::move (msg)); + m_TransitTunnels.PostTransitTunnelBuildMsg (std::move (msg)); } void Tunnels::HandleVariableTunnelBuildMsg (std::shared_ptr msg) @@ -678,7 +681,7 @@ namespace tunnel } } else - m_TransitTunnels.HandleVariableTransitTunnelBuildMsg (std::move (msg)); + m_TransitTunnels.PostTransitTunnelBuildMsg (std::move (msg)); } void Tunnels::HandleTunnelBuildReplyMsg (std::shared_ptr msg, bool isShort) @@ -710,7 +713,6 @@ namespace tunnel ManagePendingTunnels (ts); ManageInboundTunnels (ts); ManageOutboundTunnels (ts); - m_TransitTunnels.ManageTransitTunnels (ts); } void Tunnels::ManagePendingTunnels (uint64_t ts) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index fcccd236..a25012a4 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -300,8 +300,9 @@ namespace tunnel std::map > m_PendingOutboundTunnels; // by replyMsgID std::list > m_InboundTunnels; std::list > m_OutboundTunnels; + mutable std::mutex m_TunnelsMutex; std::unordered_map > m_Tunnels; // tunnelID->tunnel known by this id - std::mutex m_PoolsMutex; + mutable std::mutex m_PoolsMutex; std::list> m_Pools; std::shared_ptr m_ExploratoryPool; i2p::util::Queue > m_Queue; @@ -320,7 +321,7 @@ namespace tunnel // for HTTP only const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; }; const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; - auto& GetTransitTunnels () const { return m_TransitTunnels.GetTransitTunnels (); }; + const auto& GetTransitTunnels () const { return m_TransitTunnels.GetTransitTunnels (); }; size_t CountTransitTunnels() const; size_t CountInboundTunnels() const; From 09ae278306c3467a65881ead01779e52a73e7e96 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Nov 2024 13:27:25 -0500 Subject: [PATCH 02/19] const GetSize() --- libi2pd/Queue.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Queue.h b/libi2pd/Queue.h index ec62bddf..0e3e4fde 100644 --- a/libi2pd/Queue.h +++ b/libi2pd/Queue.h @@ -84,7 +84,7 @@ namespace util return m_Queue.empty (); } - int GetSize () + int GetSize () const { std::unique_lock l(m_QueueMutex); return m_Queue.size (); @@ -134,7 +134,7 @@ namespace util private: std::list m_Queue; - std::mutex m_QueueMutex; + mutable std::mutex m_QueueMutex; std::condition_variable m_NonEmpty; }; } From a248a2a73253afbbb92dcac77128cd012b78edd9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Nov 2024 13:28:01 -0500 Subject: [PATCH 03/19] Show TBM Queue size --- daemon/HTTPServer.cpp | 1 + libi2pd/TransitTunnel.h | 1 + libi2pd/Tunnel.h | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 21c7b6c6..a13e8e57 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -701,6 +701,7 @@ namespace http { { s << "" << tr("Tunnels") << ":
\r\n"; s << "" << tr("Queue size") << ": " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n
\r\n"; + s << "" << tr("TBM Queue size") << ": " << i2p::tunnel::tunnels.GetTBMQueueSize () << "
\r\n
\r\n"; auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool (); diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index bff1a8dd..c4a6e156 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -149,6 +149,7 @@ namespace tunnel // for HTTP only const auto& GetTransitTunnels () const { return m_TransitTunnels; }; + size_t GetTunnelBuildMsgQueueSize () const { return m_TunnelBuildMsgQueue.GetSize (); }; }; } } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index a25012a4..2d0641e3 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -327,7 +327,8 @@ namespace tunnel size_t CountInboundTunnels() const; size_t CountOutboundTunnels() const; - int GetQueueSize () { return m_Queue.GetSize (); }; + size_t GetQueueSize () const { return m_Queue.GetSize (); }; + size_t GetTBMQueueSize () const { return m_TransitTunnels.GetTunnelBuildMsgQueueSize (); }; int GetTunnelCreationSuccessRate () const { return std::round(m_TunnelCreationSuccessRate * 100); } // in percents double GetPreciseTunnelCreationSuccessRate () const { return m_TunnelCreationSuccessRate * 100; } // in percents int GetTotalTunnelCreationSuccessRate () const // in percents From 6fb3c7c3ba44e1d3b2d9d70395e876689fc22327 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 23 Nov 2024 18:34:33 -0500 Subject: [PATCH 04/19] removed dependancy from boost_system for newer compliers --- Makefile.linux | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index aa67626a..9c3e6895 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -13,12 +13,9 @@ LDFLAGS ?= ${LD_DEBUG} CXXVER := $(shell $(CXX) -dumpversion) ifeq ($(shell expr match $(CXX) 'clang'),5) NEEDED_CXXFLAGS += -std=c++17 -else ifeq ($(shell expr match ${CXXVER} "7"),1) # gcc 7 - NEEDED_CXXFLAGS += -std=c++17 - LDLIBS = -lboost_filesystem else ifeq ($(shell expr match ${CXXVER} "[8-9]"),1) # gcc 8 - 9 NEEDED_CXXFLAGS += -std=c++17 - LDLIBS = -lstdc++fs + LDLIBS = -lboost_system -lstdc++fs else ifeq ($(shell expr match ${CXXVER} "1[0-2]"),2) # gcc 10 - 12 NEEDED_CXXFLAGS += -std=c++17 else ifeq ($(shell expr match ${CXXVER} "1[3-9]"),2) # gcc 13+ @@ -34,7 +31,6 @@ ifeq ($(USE_STATIC),yes) # Using 'getaddrinfo' in statically linked applications requires at runtime # the shared libraries from the glibc version used for linking LIBDIR := /usr/lib/$(SYS) - LDLIBS += $(LIBDIR)/libboost_system.a LDLIBS += $(LIBDIR)/libboost_program_options.a LDLIBS += $(LIBDIR)/libssl.a LDLIBS += $(LIBDIR)/libcrypto.a @@ -44,7 +40,7 @@ ifeq ($(USE_UPNP),yes) endif LDLIBS += -lpthread -ldl else - LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_program_options -lpthread -latomic + LDLIBS += -lcrypto -lssl -lz -lboost_program_options -lpthread -latomic ifeq ($(USE_UPNP),yes) LDLIBS += -lminiupnpc endif From 5f1b31213f8d69bca35acf5589356da9162a64cc Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Nov 2024 08:12:40 -0500 Subject: [PATCH 05/19] more adequate initial RTT --- libi2pd/Streaming.cpp | 4 ++-- libi2pd/Streaming.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index ece2979d..0569c873 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -537,7 +537,7 @@ namespace stream m_LocalDestination.DeletePacket (sentPacket); acknowledged = true; if (m_WindowSize < MAX_WINDOW_SIZE && !m_IsFirstACK) - if (m_RTT < m_LocalDestination.GetRandom () % INITIAL_RTT) // dirty + if (m_RTT < m_LocalDestination.GetRandom () % INITIAL_RTO) // dirty m_WindowIncCounter++; } else @@ -1143,7 +1143,7 @@ namespace stream CancelRemoteLeaseChange (); UpdateCurrentRemoteLease (true); } - if (m_RemoteLeaseChangeTime && m_IsRemoteLeaseChangeInProgress && ts > m_RemoteLeaseChangeTime + INITIAL_RTT) + if (m_RemoteLeaseChangeTime && m_IsRemoteLeaseChangeInProgress && ts > m_RemoteLeaseChangeTime + INITIAL_RTO) { CancelRemoteLeaseChange (); m_CurrentRemoteLease = m_NextRemoteLease; diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 11fc04d1..14a4e80b 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -60,7 +60,7 @@ namespace stream const double SLOWRTT_EWMA_ALPHA = 0.05; const double PREV_SPEED_KEEP_TIME_COEFF = 0.35; // 0.1 - 1 // how long will the window size stay around the previous drop level, less is longer const int MIN_RTO = 20; // in milliseconds - const int INITIAL_RTT = 8000; // in milliseconds + const int INITIAL_RTT = 1500; // in milliseconds const int INITIAL_RTO = 9000; // in milliseconds const int INITIAL_PACING_TIME = 1000 * INITIAL_RTT / INITIAL_WINDOW_SIZE; // in microseconds const int MIN_SEND_ACK_TIMEOUT = 2; // in milliseconds From 34745386974845ab3b9e1e2b15c2013f3b2a2f7b Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Nov 2024 10:08:27 -0500 Subject: [PATCH 06/19] replaced boost::asio::io_service by boost::asio:io_context --- daemon/UPnP.h | 2 +- libi2pd/Destination.cpp | 4 ++-- libi2pd/Destination.h | 10 +++++----- libi2pd/NTCP2.h | 2 +- libi2pd/Reseed.cpp | 4 ++-- libi2pd/SSU2.h | 4 ++-- libi2pd/Streaming.cpp | 4 ++-- libi2pd/Streaming.h | 6 +++--- libi2pd/Timestamp.cpp | 2 +- libi2pd/Timestamp.h | 2 +- libi2pd/Transports.cpp | 4 ++-- libi2pd/Transports.h | 6 +++--- libi2pd/util.h | 6 +++--- libi2pd_client/BOB.h | 4 ++-- libi2pd_client/ClientContext.cpp | 4 ++-- libi2pd_client/ClientContext.h | 4 ++-- libi2pd_client/I2CP.cpp | 2 +- libi2pd_client/I2CP.h | 4 ++-- libi2pd_client/I2PService.h | 2 +- libi2pd_client/SAM.h | 2 +- 20 files changed, 39 insertions(+), 39 deletions(-) diff --git a/daemon/UPnP.h b/daemon/UPnP.h index d865df40..2a5fe9f3 100644 --- a/daemon/UPnP.h +++ b/daemon/UPnP.h @@ -67,7 +67,7 @@ namespace transport std::unique_ptr m_Thread; std::condition_variable m_Started; std::mutex m_StartedMutex; - boost::asio::io_service m_Service; + boost::asio::io_context m_Service; boost::asio::deadline_timer m_Timer; bool m_upnpUrlsInitialized = false; struct UPNPUrls m_upnpUrls; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 08acc0ed..a165d5b9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -23,7 +23,7 @@ namespace i2p { namespace client { - LeaseSetDestination::LeaseSetDestination (boost::asio::io_service& service, + LeaseSetDestination::LeaseSetDestination (boost::asio::io_context& service, bool isPublic, const std::map * params): m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), @@ -1000,7 +1000,7 @@ namespace client return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; } - ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + ClientDestination::ClientDestination (boost::asio::io_context& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (service, isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 8d49ef82..7516c90f 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -107,7 +107,7 @@ namespace client // leaseSet = nullptr means not found struct LeaseSetRequest { - LeaseSetRequest (boost::asio::io_service& service): requestTime (0), requestTimeoutTimer (service) {}; + LeaseSetRequest (boost::asio::io_context& service): requestTime (0), requestTimeoutTimer (service) {}; std::unordered_set excluded; uint64_t requestTime; boost::asio::deadline_timer requestTimeoutTimer; @@ -125,10 +125,10 @@ namespace client public: - LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map * params = nullptr); + LeaseSetDestination (boost::asio::io_context& service, bool isPublic, const std::map * params = nullptr); ~LeaseSetDestination (); const std::string& GetNickname () const { return m_Nickname; }; - boost::asio::io_service& GetService () { return m_Service; }; + auto& GetService () { return m_Service; }; virtual void Start (); virtual void Stop (); @@ -195,7 +195,7 @@ namespace client private: - boost::asio::io_service& m_Service; + boost::asio::io_context& m_Service; mutable std::mutex m_RemoteLeaseSetsMutex; std::unordered_map > m_RemoteLeaseSets; std::unordered_map > m_LeaseSetRequests; @@ -241,7 +241,7 @@ namespace client public: - ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys, + ClientDestination (boost::asio::io_context& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); ~ClientDestination (); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 27acb529..e1718bb0 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -253,7 +253,7 @@ namespace transport void Start (); void Stop (); - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; std::mt19937& GetRng () { return m_Rng; }; bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index f8307a56..13e18d99 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -552,7 +552,7 @@ namespace data if (!url.port) url.port = 443; - boost::asio::io_service service; + boost::asio::io_context service; boost::system::error_code ecode; boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); @@ -746,7 +746,7 @@ namespace data if (!url.port) url.port = 80; boost::system::error_code ecode; - boost::asio::io_service service; + boost::asio::io_context service; boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6()); auto it = boost::asio::ip::tcp::resolver(service).resolve ( diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index 95f053a9..715e72ab 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -61,7 +61,7 @@ namespace transport public: ReceiveService (const std::string& name): RunnableService (name) {}; - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; void Start () { StartIOService (); }; void Stop () { StopIOService (); }; }; @@ -73,7 +73,7 @@ namespace transport void Start (); void Stop (); - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; void SetLocalAddress (const boost::asio::ip::address& localAddress); bool SetProxy (const std::string& address, uint16_t port); bool UsesProxy () const { return m_IsThroughProxy; }; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 0569c873..8caccfcf 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -66,7 +66,7 @@ namespace stream } } - Stream::Stream (boost::asio::io_service& service, StreamingDestination& local, + Stream::Stream (boost::asio::io_context& service, StreamingDestination& local, std::shared_ptr remote, int port): m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_DropWindowDelaySequenceNumber (0), m_TunnelsChangeSequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_PreviousReceivedSequenceNumber (-1), @@ -95,7 +95,7 @@ namespace stream m_PacketACKInterval = (1000000LL*STREAMING_MTU)/inboundSpeed; } - Stream::Stream (boost::asio::io_service& service, StreamingDestination& local): + Stream::Stream (boost::asio::io_context& service, StreamingDestination& local): m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_DropWindowDelaySequenceNumber (0), m_TunnelsChangeSequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_PreviousReceivedSequenceNumber (-1), m_LastConfirmedReceivedSequenceNumber (0), // for limit inbound speed diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 14a4e80b..d2fcc6b9 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -175,9 +175,9 @@ namespace stream { public: - Stream (boost::asio::io_service& service, StreamingDestination& local, + Stream (boost::asio::io_context& service, StreamingDestination& local, std::shared_ptr remote, int port = 0); // outgoing - Stream (boost::asio::io_service& service, StreamingDestination& local); // incoming + Stream (boost::asio::io_context& service, StreamingDestination& local); // incoming ~Stream (); uint32_t GetSendStreamID () const { return m_SendStreamID; }; @@ -255,7 +255,7 @@ namespace stream private: - boost::asio::io_service& m_Service; + boost::asio::io_context& m_Service; uint32_t m_SendStreamID, m_RecvStreamID, m_SequenceNumber; uint32_t m_DropWindowDelaySequenceNumber; uint32_t m_TunnelsChangeSequenceNumber; diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index c5c37cd7..51f68ded 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -60,7 +60,7 @@ namespace util static void SyncTimeWithNTP (const std::string& address) { LogPrint (eLogInfo, "Timestamp: NTP request to ", address); - boost::asio::io_service service; + boost::asio::io_context service; boost::system::error_code ec; auto it = boost::asio::ip::udp::resolver (service).resolve ( boost::asio::ip::udp::resolver::query (address, "ntp"), ec); diff --git a/libi2pd/Timestamp.h b/libi2pd/Timestamp.h index d949d416..00c60433 100644 --- a/libi2pd/Timestamp.h +++ b/libi2pd/Timestamp.h @@ -52,7 +52,7 @@ namespace util bool m_IsRunning; std::unique_ptr m_Thread; - boost::asio::io_service m_Service; + boost::asio::io_context m_Service; boost::asio::deadline_timer m_Timer; int m_SyncInterval; std::vector m_NTPServersList; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b07b1b0b..cd879cb3 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -174,8 +174,8 @@ namespace transport { if (!m_Service) { - m_Service = new boost::asio::io_service (); - m_Work = new boost::asio::io_service::work (*m_Service); + m_Service = new boost::asio::io_context (); + m_Work = new boost::asio::io_context::work (*m_Service); m_PeerCleanupTimer = new boost::asio::deadline_timer (*m_Service); m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service); m_UpdateBandwidthTimer = new boost::asio::deadline_timer (*m_Service); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 8271108d..431237a3 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -139,7 +139,7 @@ namespace transport bool IsOnline() const { return m_IsOnline; }; void SetOnline (bool online); - boost::asio::io_service& GetService () { return *m_Service; }; + auto& GetService () { return *m_Service; }; std::shared_ptr GetNextX25519KeysPair (); void ReuseX25519KeysPair (std::shared_ptr pair); @@ -207,8 +207,8 @@ namespace transport volatile bool m_IsOnline; bool m_IsRunning, m_IsNAT, m_CheckReserved; std::thread * m_Thread; - boost::asio::io_service * m_Service; - boost::asio::io_service::work * m_Work; + boost::asio::io_context * m_Service; + boost::asio::io_context::work * m_Work; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer, * m_UpdateBandwidthTimer; SSU2Server * m_SSU2Server; diff --git a/libi2pd/util.h b/libi2pd/util.h index 48bcb801..dd065052 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -177,7 +177,7 @@ namespace util RunnableService (const std::string& name): m_Name (name), m_IsRunning (false) {} virtual ~RunnableService () {} - boost::asio::io_service& GetIOService () { return m_Service; } + auto& GetIOService () { return m_Service; } bool IsRunning () const { return m_IsRunning; }; void StartIOService (); @@ -194,7 +194,7 @@ namespace util std::string m_Name; volatile bool m_IsRunning; std::unique_ptr m_Thread; - boost::asio::io_service m_Service; + boost::asio::io_context m_Service; }; class RunnableServiceWithWork: public RunnableService @@ -206,7 +206,7 @@ namespace util private: - boost::asio::io_service::work m_Work; + boost::asio::io_context::work m_Work; }; void SetThreadName (const char *name); diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 1f5fda5f..79066154 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -254,7 +254,7 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; void AddDestination (const std::string& name, std::shared_ptr dest); void DeleteDestination (const std::string& name); std::shared_ptr FindDestination (const std::string& name); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index aa49f83e..72051805 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -345,7 +345,7 @@ namespace client } std::shared_ptr ClientContext::CreateNewLocalDestination ( - boost::asio::io_service& service, bool isPublic, + boost::asio::io_context& service, bool isPublic, i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType, const std::map * params) { @@ -399,7 +399,7 @@ namespace client return localDestination; } - std::shared_ptr ClientContext::CreateNewLocalDestination (boost::asio::io_service& service, + std::shared_ptr ClientContext::CreateNewLocalDestination (boost::asio::io_context& service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params) { auto it = m_Destinations.find (keys.GetPublic ()->GetIdentHash ()); diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index adec607a..febd5f16 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -79,13 +79,13 @@ namespace client i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, const std::map * params = nullptr); // used by SAM only - std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, + std::shared_ptr CreateNewLocalDestination (boost::asio::io_context& service, bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL, const std::map * params = nullptr); // same as previous but on external io_service std::shared_ptr CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); - std::shared_ptr CreateNewLocalDestination (boost::asio::io_service& service, + std::shared_ptr CreateNewLocalDestination (boost::asio::io_context& service, const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); // same as previous but on external io_service std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index fc6d1b40..7aec7549 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -24,7 +24,7 @@ namespace i2p namespace client { - I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, + I2CPDestination::I2CPDestination (boost::asio::io_context& service, std::shared_ptr owner, std::shared_ptr identity, bool isPublic, bool isSameThread, const std::map& params): LeaseSetDestination (service, isPublic, ¶ms), diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index 620ff52e..e929c1e1 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -81,7 +81,7 @@ namespace client { public: - I2CPDestination (boost::asio::io_service& service, std::shared_ptr owner, + I2CPDestination (boost::asio::io_context& service, std::shared_ptr owner, std::shared_ptr identity, bool isPublic, bool isSameThread, const std::map& params); ~I2CPDestination () {}; @@ -227,7 +227,7 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; bool IsSingleThread () const { return m_IsSingleThread; }; bool InsertSession (std::shared_ptr session); diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index d35c954d..adcc3da7 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -61,7 +61,7 @@ namespace client } void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, uint16_t port = 0); void CreateStream(StreamRequestComplete complete, std::shared_ptr address, uint16_t port); - inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); } + auto& GetService () { return m_LocalDestination->GetService (); } virtual void Start () = 0; virtual void Stop () = 0; diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 3ed8f00c..10ef4957 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -246,7 +246,7 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); bool AddSession (std::shared_ptr session); From ffd18baf30d0259f140e74f5c47ff455e54f2dd8 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Nov 2024 16:00:06 -0500 Subject: [PATCH 07/19] support boost 1.87 --- daemon/HTTPServer.cpp | 4 ++-- daemon/HTTPServer.h | 4 ++-- daemon/I2PControl.cpp | 2 +- daemon/I2PControl.h | 4 ++-- libi2pd/Destination.cpp | 30 ++++++++++++------------ libi2pd/NTCP2.cpp | 21 ++++++++--------- libi2pd/NetDbRequests.cpp | 8 +++---- libi2pd/Reseed.cpp | 20 ++++++---------- libi2pd/RouterContext.cpp | 24 +++++++++---------- libi2pd/RouterContext.h | 2 +- libi2pd/RouterInfo.cpp | 2 +- libi2pd/SSU2.cpp | 24 +++++++++---------- libi2pd/Streaming.cpp | 12 +++++----- libi2pd/Streaming.h | 10 ++++---- libi2pd/Timestamp.cpp | 8 +++---- libi2pd/Transports.cpp | 20 ++++++++-------- libi2pd/Transports.h | 2 +- libi2pd/util.cpp | 10 ++++---- libi2pd/util.h | 4 ++-- libi2pd_client/BOB.cpp | 12 +++++----- libi2pd_client/ClientContext.cpp | 6 ++--- libi2pd_client/HTTPProxy.cpp | 24 ++++++++++--------- libi2pd_client/I2CP.cpp | 6 ++--- libi2pd_client/I2PService.h | 2 +- libi2pd_client/I2PTunnel.cpp | 15 ++++++------ libi2pd_client/I2PTunnel.h | 4 ++-- libi2pd_client/SAM.cpp | 16 ++++++------- libi2pd_client/SOCKS.cpp | 40 ++++++++++++++++---------------- 28 files changed, 164 insertions(+), 172 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a13e8e57..e32bd459 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -1486,8 +1486,8 @@ namespace http { } HTTPServer::HTTPServer (const std::string& address, int port): - m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)), + m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service.get_executor ()), + m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::make_address(address), port)), m_Hostname(address) { } diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index f751c5a8..38b790d4 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -83,8 +83,8 @@ namespace http bool m_IsRunning; std::unique_ptr m_Thread; - boost::asio::io_service m_Service; - boost::asio::io_service::work m_Work; + boost::asio::io_context m_Service; + boost::asio::executor_work_guard m_Work; boost::asio::ip::tcp::acceptor m_Acceptor; std::string m_Hostname; }; diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 43c74199..1ea75bbb 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -31,7 +31,7 @@ namespace client { I2PControlService::I2PControlService (const std::string& address, int port): m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), + m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::make_address(address), port)), m_SSLContext (boost::asio::ssl::context::sslv23), m_ShutdownTimer (m_Service) { diff --git a/daemon/I2PControl.h b/daemon/I2PControl.h index af152631..ff32c131 100644 --- a/daemon/I2PControl.h +++ b/daemon/I2PControl.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2022, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -88,7 +88,7 @@ namespace client bool m_IsRunning; std::thread * m_Thread; - boost::asio::io_service m_Service; + boost::asio::io_context m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ssl::context m_SSLContext; boost::asio::deadline_timer m_ShutdownTimer; diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a165d5b9..2d1aa2c8 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -294,7 +294,7 @@ namespace client if (m_IsPublic) { auto s = shared_from_this (); - m_Service.post ([s](void) + boost::asio::post (m_Service, [s](void) { s->m_PublishVerificationTimer.cancel (); s->Publish (); @@ -322,7 +322,7 @@ namespace client memcpy (data.k, key, 32); memcpy (data.t, tag, 32); auto s = shared_from_this (); - m_Service.post ([s,data](void) + boost::asio::post (m_Service, [s,data](void) { s->AddSessionKey (data.k, data.t); }); @@ -339,7 +339,7 @@ namespace client memcpy (data.k, key, 32); data.t = tag; auto s = shared_from_this (); - m_Service.post ([s,data](void) + boost::asio::post (m_Service, [s,data](void) { s->AddECIESx25519Key (data.k, data.t); }); @@ -355,7 +355,7 @@ namespace client m_IncomingMsgsQueue.push_back (msg); } if (empty) - m_Service.post([s = shared_from_this ()]() + boost::asio::post (m_Service, [s = shared_from_this ()]() { std::list > receivedMsgs; { @@ -370,7 +370,7 @@ namespace client void LeaseSetDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); - m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msgID)); + boost::asio::post (m_Service, std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msgID)); } void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len) @@ -608,7 +608,7 @@ namespace client void LeaseSetDestination::SetLeaseSetUpdated (bool post) { if (post) - m_Service.post([s = shared_from_this ()]() { s->UpdateLeaseSet (); }); + boost::asio::post (m_Service, [s = shared_from_this ()]() { s->UpdateLeaseSet (); }); else UpdateLeaseSet (); } @@ -690,7 +690,7 @@ namespace client auto s = shared_from_this (); msg->onDrop = [s]() { - s->GetService ().post([s]() + boost::asio::post (s->GetService (), [s]() { s->m_PublishConfirmationTimer.cancel (); s->HandlePublishConfirmationTimer (boost::system::error_code()); @@ -775,10 +775,10 @@ namespace client if (!m_Pool || !IsReady ()) { if (requestComplete) - m_Service.post ([requestComplete](void){requestComplete (nullptr);}); + boost::asio::post (m_Service, [requestComplete](void){requestComplete (nullptr);}); return false; } - m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete, nullptr)); + boost::asio::post (m_Service, std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete, nullptr)); return true; } @@ -787,7 +787,7 @@ namespace client if (!dest || !m_Pool || !IsReady ()) { if (requestComplete) - m_Service.post ([requestComplete](void){requestComplete (nullptr);}); + boost::asio::post (m_Service, [requestComplete](void){requestComplete (nullptr);}); return false; } auto storeHash = dest->GetStoreHash (); @@ -795,17 +795,17 @@ namespace client if (leaseSet) { if (requestComplete) - m_Service.post ([requestComplete, leaseSet](void){requestComplete (leaseSet);}); + boost::asio::post (m_Service, [requestComplete, leaseSet](void){requestComplete (leaseSet);}); return true; } - m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), storeHash, requestComplete, dest)); + boost::asio::post (m_Service, std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), storeHash, requestComplete, dest)); return true; } void LeaseSetDestination::CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify) { auto s = shared_from_this (); - m_Service.post ([dest, notify, s](void) + boost::asio::post (m_Service, [dest, notify, s](void) { auto it = s->m_LeaseSetRequests.find (dest); if (it != s->m_LeaseSetRequests.end ()) @@ -903,7 +903,7 @@ namespace client auto s = shared_from_this (); msg->onDrop = [s, dest, request]() { - s->GetService ().post([s, dest, request]() + boost::asio::post (s->GetService (), [s, dest, request]() { s->SendNextLeaseSetRequest (dest, request); }); @@ -1215,7 +1215,7 @@ namespace client if (leaseSet) { auto stream = CreateStream (leaseSet, port); - GetService ().post ([streamRequestComplete, stream]() + boost::asio::post (GetService (), [streamRequestComplete, stream]() { streamRequestComplete(stream); }); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 33c33596..38efc825 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -406,7 +406,7 @@ namespace transport void NTCP2Session::Done () { - m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ())); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); } void NTCP2Session::Established () @@ -508,7 +508,7 @@ namespace transport { // we don't care about padding, send SessionCreated and close session SendSessionCreated (); - m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ())); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); } else if (paddingLen > 0) { @@ -1296,7 +1296,7 @@ namespace transport void NTCP2Session::SendTerminationAndTerminate (NTCP2TerminationReason reason) { SendTermination (reason); - m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ())); // let termination message go + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); // let termination message go } void NTCP2Session::SendI2NPMessages (std::list >& msgs) @@ -1313,7 +1313,7 @@ namespace transport m_IntermediateQueue.splice (m_IntermediateQueue.end (), msgs); } if (empty) - m_Server.GetService ().post (std::bind (&NTCP2Session::PostI2NPMessages, shared_from_this ())); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::PostI2NPMessages, shared_from_this ())); } void NTCP2Session::PostI2NPMessages () @@ -1350,7 +1350,7 @@ namespace transport void NTCP2Session::SendLocalRouterInfo (bool update) { if (update || !IsOutgoing ()) // we send it in SessionConfirmed for outgoing session - m_Server.GetService ().post (std::bind (&NTCP2Session::SendRouterInfo, shared_from_this ())); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::SendRouterInfo, shared_from_this ())); } NTCP2Server::NTCP2Server (): @@ -1374,14 +1374,13 @@ namespace transport { LogPrint(eLogInfo, "NTCP2: Using proxy to connect to peers"); // TODO: resolve proxy until it is resolved - boost::asio::ip::tcp::resolver::query q(m_ProxyAddress, std::to_string(m_ProxyPort)); boost::system::error_code e; - auto itr = m_Resolver.resolve(q, e); + auto itr = m_Resolver.resolve(m_ProxyAddress, std::to_string(m_ProxyPort), e); if(e) LogPrint(eLogCritical, "NTCP2: Failed to resolve proxy ", e.message()); else { - m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr)); + m_ProxyEndpoint.reset (new boost::asio::ip::tcp::endpoint(*itr.begin ())); if (m_ProxyEndpoint) LogPrint(eLogDebug, "NTCP2: m_ProxyEndpoint ", *m_ProxyEndpoint); } @@ -1541,7 +1540,7 @@ namespace transport } LogPrint (eLogDebug, "NTCP2: Connecting to ", conn->GetRemoteEndpoint (), " (", i2p::data::GetIdentHashAbbreviation (conn->GetRemoteIdentity ()->GetIdentHash ()), ")"); - GetService ().post([this, conn]() + boost::asio::post (GetService (), [this, conn]() { if (this->AddNTCP2Session (conn)) { @@ -1762,7 +1761,7 @@ namespace transport LogPrint (eLogError, "NTCP2: Can't connect to unspecified address"); return; } - GetService().post([this, conn]() + boost::asio::post (GetService(), [this, conn]() { if (this->AddNTCP2Session (conn)) { @@ -1860,7 +1859,7 @@ namespace transport { readbuff->commit(transferred); i2p::http::HTTPRes res; - if(res.parse(boost::asio::buffer_cast(readbuff->data()), readbuff->size()) > 0) + if(res.parse(std::string {boost::asio::buffers_begin(readbuff->data ()), boost::asio::buffers_begin(readbuff->data ()) + readbuff->size ()}) > 0) { if(res.code == 200) { diff --git a/libi2pd/NetDbRequests.cpp b/libi2pd/NetDbRequests.cpp index 0e632c26..63d161cd 100644 --- a/libi2pd/NetDbRequests.cpp +++ b/libi2pd/NetDbRequests.cpp @@ -179,7 +179,7 @@ namespace data void NetDbRequests::RequestComplete (const IdentHash& ident, std::shared_ptr r) { - GetIOService ().post ([this, ident, r]() + boost::asio::post (GetIOService (), [this, ident, r]() { std::shared_ptr request; auto it = m_RequestedDestinations.find (ident); @@ -267,7 +267,7 @@ namespace data { if (dest->IsActive ()) { - s->GetIOService ().post ([s, dest]() + boost::asio::post (s->GetIOService (), [s, dest]() { if (dest->IsActive ()) s->SendNextRequest (dest); }); @@ -345,7 +345,7 @@ namespace data void NetDbRequests::PostDatabaseSearchReplyMsg (std::shared_ptr msg) { - GetIOService ().post ([this, msg]() + boost::asio::post (GetIOService (), [this, msg]() { HandleDatabaseSearchReplyMsg (msg); }); @@ -431,7 +431,7 @@ namespace data void NetDbRequests::PostRequestDestination (const IdentHash& destination, const RequestedDestination::RequestComplete& requestComplete, bool direct) { - GetIOService ().post ([this, destination, requestComplete, direct]() + boost::asio::post (GetIOService (), [this, destination, requestComplete, direct]() { RequestDestination (destination, requestComplete, direct); }); diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 13e18d99..6cf277bf 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -562,11 +562,10 @@ namespace data if(proxyUrl.schema.size()) { // proxy connection - auto it = boost::asio::ip::tcp::resolver(service).resolve ( - boost::asio::ip::tcp::resolver::query (proxyUrl.host, std::to_string(proxyUrl.port)), ecode); + auto it = boost::asio::ip::tcp::resolver(service).resolve (proxyUrl.host, std::to_string(proxyUrl.port), ecode); if(!ecode) { - s.lowest_layer().connect(*it, ecode); + s.lowest_layer().connect(*it.begin (), ecode); if(!ecode) { auto & sock = s.next_layer(); @@ -599,7 +598,7 @@ namespace data LogPrint(eLogError, "Reseed: HTTP CONNECT read error: ", ecode.message()); return ""; } - if(proxyRes.parse(boost::asio::buffer_cast(readbuf.data()), readbuf.size()) <= 0) + if(proxyRes.parse(std::string {boost::asio::buffers_begin(readbuf.data ()), boost::asio::buffers_begin(readbuf.data ()) + readbuf.size ()}) <= 0) { sock.close(); LogPrint(eLogError, "Reseed: HTTP CONNECT malformed reply"); @@ -638,13 +637,11 @@ namespace data else { // direct connection - auto it = boost::asio::ip::tcp::resolver(service).resolve ( - boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode); + auto endpoints = boost::asio::ip::tcp::resolver(service).resolve (url.host, std::to_string(url.port), ecode); if (!ecode) { bool connected = false; - boost::asio::ip::tcp::resolver::iterator end; - while (it != end) + for (auto it = endpoints.begin (); it != endpoints.end ();) { boost::asio::ip::tcp::endpoint ep = *it; bool supported = false; @@ -749,14 +746,11 @@ namespace data boost::asio::io_context service; boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6()); - auto it = boost::asio::ip::tcp::resolver(service).resolve ( - boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode); - + auto endpoints = boost::asio::ip::tcp::resolver(service).resolve (url.host, std::to_string(url.port), ecode); if (!ecode) { bool connected = false; - boost::asio::ip::tcp::resolver::iterator end; - while (it != end) + for (auto it = endpoints.begin (); it != endpoints.end ();) { boost::asio::ip::tcp::endpoint ep = *it; if ( diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 558e9608..fdcdb145 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -140,7 +140,7 @@ namespace i2p { boost::asio::ip::address addr; if (!host.empty ()) - addr = boost::asio::ip::address::from_string (host); + addr = boost::asio::ip::make_address (host); if (!addr.is_v4()) addr = boost::asio::ip::address_v4 (); routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); @@ -161,7 +161,7 @@ namespace i2p { boost::asio::ip::address addr; if (!host.empty ()) - addr = boost::asio::ip::address::from_string (host); + addr = boost::asio::ip::make_address (host); if (!addr.is_v4()) addr = boost::asio::ip::address_v4 (); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); @@ -192,7 +192,7 @@ namespace i2p ntcp2Host = host; boost::asio::ip::address addr; if (!ntcp2Host.empty ()) - addr = boost::asio::ip::address::from_string (ntcp2Host); + addr = boost::asio::ip::make_address (ntcp2Host); if (!addr.is_v6()) addr = boost::asio::ip::address_v6 (); routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); @@ -211,7 +211,7 @@ namespace i2p { boost::asio::ip::address addr; if (!host.empty ()) - addr = boost::asio::ip::address::from_string (host); + addr = boost::asio::ip::make_address (host); if (!addr.is_v6()) addr = boost::asio::ip::address_v6 (); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); @@ -802,7 +802,7 @@ namespace i2p i2p::config::GetOption("host", ntcp2Host); if (!ntcp2Host.empty () && ntcp2Port) { - auto addr = boost::asio::ip::address::from_string (ntcp2Host); + auto addr = boost::asio::ip::make_address (ntcp2Host); if (addr.is_v6 ()) { m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); @@ -831,7 +831,7 @@ namespace i2p std::string host; i2p::config::GetOption("host", host); if (!host.empty ()) { - auto addr = boost::asio::ip::address::from_string (host); + auto addr = boost::asio::ip::make_address (host); if (addr.is_v6 ()) { m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); @@ -900,7 +900,7 @@ namespace i2p std::string host; i2p::config::GetOption("host", host); if (!host.empty ()) { - auto addr = boost::asio::ip::address::from_string (host); + auto addr = boost::asio::ip::make_address (host); if (addr.is_v4 ()) { m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); @@ -930,7 +930,7 @@ namespace i2p std::string host; i2p::config::GetOption("host", host); if (!host.empty ()) { - auto addr = boost::asio::ip::address::from_string (host); + auto addr = boost::asio::ip::make_address (host); if (addr.is_v4 ()) { m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); @@ -1185,7 +1185,7 @@ namespace i2p void RouterContext::ProcessGarlicMessage (std::shared_ptr msg) { if (m_Service) - m_Service->GetService ().post (std::bind (&RouterContext::PostGarlicMessage, this, msg)); + boost::asio::post (m_Service->GetService (), std::bind (&RouterContext::PostGarlicMessage, this, msg)); else LogPrint (eLogError, "Router: service is NULL"); } @@ -1213,7 +1213,7 @@ namespace i2p void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { if (m_Service) - m_Service->GetService ().post (std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg)); + boost::asio::post (m_Service->GetService (), std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg)); else LogPrint (eLogError, "Router: service is NULL"); } @@ -1242,7 +1242,7 @@ namespace i2p } data; memcpy (data.k, key, 32); data.t = tag; - m_Service->GetService ().post ([this,data](void) + boost::asio::post (m_Service->GetService (), [this,data](void) { AddECIESx25519Key (data.k, data.t); }); @@ -1408,7 +1408,7 @@ namespace i2p auto onDrop = [this]() { if (m_Service) - m_Service->GetService ().post ([this]() { HandlePublishResendTimer (boost::system::error_code ()); }); + boost::asio::post (m_Service->GetService (), [this]() { HandlePublishResendTimer (boost::system::error_code ()); }); }; if (i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()) || // already connected (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) && // are we able to connect diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 0dfef254..5060866a 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -90,7 +90,7 @@ namespace garlic public: RouterService (): RunnableServiceWithWork ("Router") {}; - boost::asio::io_service& GetService () { return GetIOService (); }; + auto& GetService () { return GetIOService (); }; void Start () { StartIOService (); }; void Stop () { StopIOService (); }; }; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 2321a1e0..0d53f6cd 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -257,7 +257,7 @@ namespace data if (!strcmp (key, "host")) { boost::system::error_code ecode; - address->host = boost::asio::ip::address::from_string (value, ecode); + address->host = boost::asio::ip::make_address (value, ecode); if (!ecode && !address->host.is_unspecified ()) { if (!i2p::transport::transports.IsInReservedRange (address->host) || diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index a53c877c..982940c5 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -81,7 +81,7 @@ namespace transport found = true; LogPrint (eLogDebug, "SSU2: Opening IPv4 socket at Start"); OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV4, port)); - m_ReceiveService.GetService ().post( + boost::asio::post (m_ReceiveService.GetService (), [this]() { Receive (m_SocketV4); @@ -93,8 +93,8 @@ namespace transport found = true; LogPrint (eLogDebug, "SSU2: Opening IPv6 socket at Start"); OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV6, port)); - m_ReceiveService.GetService ().post( - [this]() + boost::asio::post (m_ReceiveService.GetService (), + [this]() { Receive (m_SocketV6); }); @@ -451,7 +451,7 @@ namespace transport m_ReceivedPacketsQueue.push_back (packet); } if (empty) - GetService ().post([this]() { HandleReceivedPacketsQueue (); }); + boost::asio::post (GetService (), [this]() { HandleReceivedPacketsQueue (); }); } void SSU2Server::InsertToReceivedPacketsQueue (std::list& packets) @@ -471,7 +471,7 @@ namespace transport } } if (!queueSize) - GetService ().post([this]() { HandleReceivedPacketsQueue (); }); + boost::asio::post (GetService (), [this]() { HandleReceivedPacketsQueue (); }); } void SSU2Server::HandleReceivedPacketsQueue () @@ -522,7 +522,7 @@ namespace transport void SSU2Server::RequestRemoveSession (uint64_t connID) { - GetService ().post ([connID, this]() { RemoveSession (connID); }); + boost::asio::post (GetService (), [connID, this]() { RemoveSession (connID); }); } void SSU2Server::AddSessionByRouterHash (std::shared_ptr session) @@ -550,7 +550,7 @@ namespace transport // move unsent msgs to new session oldSession->MoveSendQueue (session); // terminate existing - GetService ().post (std::bind (&SSU2Session::RequestTermination, oldSession, eSSU2TerminationReasonReplacedByNewSession)); + boost::asio::post (GetService (), std::bind (&SSU2Session::RequestTermination, oldSession, eSSU2TerminationReasonReplacedByNewSession)); } } } @@ -878,7 +878,7 @@ namespace transport { // session with router found, trying to send peer test if requested if (peerTest && existingSession->IsEstablished ()) - GetService ().post ([existingSession]() { existingSession->SendPeerTest (); }); + boost::asio::post (GetService (), [existingSession]() { existingSession->SendPeerTest (); }); return false; } // check is no pending session @@ -905,9 +905,9 @@ namespace transport session->SetOnEstablished ([session]() {session->SendPeerTest (); }); if (isValidEndpoint) // we know endpoint - GetService ().post ([session]() { session->Connect (); }); + boost::asio::post (GetService (), [session]() { session->Connect (); }); else if (address->UsesIntroducer ()) // we don't know endpoint yet - GetService ().post (std::bind (&SSU2Server::ConnectThroughIntroducer, this, session)); + boost::asio::post (GetService (), std::bind (&SSU2Server::ConnectThroughIntroducer, this, session)); else return false; } @@ -1050,7 +1050,7 @@ namespace transport if (!remoteAddr || !remoteAddr->IsPeerTesting () || (v4 && !remoteAddr->IsV4 ()) || (!v4 && !remoteAddr->IsV6 ())) return false; if (session->IsEstablished ()) - GetService ().post ([session]() { session->SendPeerTest (); }); + boost::asio::post (GetService (), [session]() { session->SendPeerTest (); }); else session->SetOnEstablished ([session]() { session->SendPeerTest (); }); return true; @@ -1764,7 +1764,7 @@ namespace transport bool SSU2Server::SetProxy (const std::string& address, uint16_t port) { boost::system::error_code ecode; - auto addr = boost::asio::ip::address::from_string (address, ecode); + auto addr = boost::asio::ip::make_address (address, ecode); if (!ecode && !addr.is_unspecified () && port) { m_IsThroughProxy = true; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 8caccfcf..efa190cf 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -667,7 +667,7 @@ namespace stream { // make sure that AsycReceive complete auto s = shared_from_this(); - m_Service.post ([s]() + boost::asio::post (m_Service, [s]() { s->m_ReceiveTimer.cancel (); }); @@ -695,7 +695,7 @@ namespace stream else if (handler) handler(boost::system::error_code ()); auto s = shared_from_this (); - m_Service.post ([s, buffer]() + boost::asio::post (m_Service, [s, buffer]() { if (buffer) s->m_SendBuffer.Add (buffer); @@ -1058,7 +1058,7 @@ namespace stream m_LocalDestination.GetOwner ()->Sign (packet, size, signature); p->len = size; - m_Service.post (std::bind (&Stream::SendPacket, shared_from_this (), p)); + boost::asio::post (m_Service, std::bind (&Stream::SendPacket, shared_from_this (), p)); LogPrint (eLogDebug, "Streaming: FIN sent, sSID=", m_SendStreamID); } @@ -1855,7 +1855,7 @@ namespace stream if (it == m_Streams.end ()) return false; auto s = it->second; - m_Owner->GetService ().post ([this, s] () + boost::asio::post (m_Owner->GetService (), [this, s] () { s->Close (); // try to send FIN s->Terminate (false); @@ -1868,7 +1868,7 @@ namespace stream { m_Acceptor = acceptor; // we must set it immediately for IsAcceptorSet auto s = shared_from_this (); - m_Owner->GetService ().post([s](void) + boost::asio::post (m_Owner->GetService (), [s](void) { // take care about incoming queue for (auto& it: s->m_PendingIncomingStreams) @@ -1887,7 +1887,7 @@ namespace stream void StreamingDestination::AcceptOnce (const Acceptor& acceptor) { - m_Owner->GetService ().post([acceptor, this](void) + boost::asio::post (m_Owner->GetService (), [acceptor, this](void) { if (!m_PendingIncomingStreams.empty ()) { diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index d2fcc6b9..e5dba39f 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -202,7 +202,7 @@ namespace stream size_t ReadSome (uint8_t * buf, size_t len) { return ConcatenatePackets (buf, len); }; size_t Receive (uint8_t * buf, size_t len, int timeout); - void AsyncClose() { m_Service.post(std::bind(&Stream::Close, shared_from_this())); }; + void AsyncClose() { boost::asio::post(m_Service, std::bind(&Stream::Close, shared_from_this())); }; /** only call close from destination thread, use Stream::AsyncClose for other threads */ void Close (); @@ -238,7 +238,7 @@ namespace stream void UpdateCurrentRemoteLease (bool expired = false); template - void HandleReceiveTimer (const boost::system::error_code& ecode, const Buffer& buffer, ReceiveHandler handler, int remainingTimeout); + void HandleReceiveTimer (const boost::system::error_code& ecode, Buffer& buffer, ReceiveHandler handler, int remainingTimeout); void ScheduleSend (); void HandleSendTimer (const boost::system::error_code& ecode); @@ -375,7 +375,7 @@ namespace stream void Stream::AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout) { auto s = shared_from_this(); - m_Service.post ([s, buffer, handler, timeout](void) + boost::asio::post (m_Service, [s, buffer, handler, timeout](void) { if (!s->m_ReceiveQueue.empty () || s->m_Status == eStreamStatusReset) s->HandleReceiveTimer (boost::asio::error::make_error_code (boost::asio::error::operation_aborted), buffer, handler, 0); @@ -394,9 +394,9 @@ namespace stream } template - void Stream::HandleReceiveTimer (const boost::system::error_code& ecode, const Buffer& buffer, ReceiveHandler handler, int remainingTimeout) + void Stream::HandleReceiveTimer (const boost::system::error_code& ecode, Buffer& buffer, ReceiveHandler handler, int remainingTimeout) { - size_t received = ConcatenatePackets (boost::asio::buffer_cast(buffer), boost::asio::buffer_size(buffer)); + size_t received = ConcatenatePackets ((uint8_t *)buffer.data (), buffer.size ()); if (received > 0) handler (boost::system::error_code (), received); else if (ecode == boost::asio::error::operation_aborted) diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 51f68ded..210ef3b9 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -62,14 +62,12 @@ namespace util LogPrint (eLogInfo, "Timestamp: NTP request to ", address); boost::asio::io_context service; boost::system::error_code ec; - auto it = boost::asio::ip::udp::resolver (service).resolve ( - boost::asio::ip::udp::resolver::query (address, "ntp"), ec); + auto endpoints = boost::asio::ip::udp::resolver (service).resolve (address, "ntp", ec); if (!ec) { bool found = false; - boost::asio::ip::udp::resolver::iterator end; boost::asio::ip::udp::endpoint ep; - while (it != end) + for (auto it = endpoints.begin (); it != endpoints.end ();) { ep = *it; if (!ep.address ().is_unspecified ()) @@ -154,7 +152,7 @@ namespace util { m_IsRunning = true; LogPrint(eLogInfo, "Timestamp: NTP time sync starting"); - m_Service.post (std::bind (&NTPTimeSync::Sync, this)); + boost::asio::post (m_Service, std::bind (&NTPTimeSync::Sync, this)); m_Thread.reset (new std::thread (std::bind (&NTPTimeSync::Run, this))); } else diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index cd879cb3..e2f8c730 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -175,7 +175,7 @@ namespace transport if (!m_Service) { m_Service = new boost::asio::io_context (); - m_Work = new boost::asio::io_context::work (*m_Service); + m_Work = new boost::asio::executor_work_guard (m_Service->get_executor ()); m_PeerCleanupTimer = new boost::asio::deadline_timer (*m_Service); m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service); m_UpdateBandwidthTimer = new boost::asio::deadline_timer (*m_Service); @@ -249,7 +249,7 @@ namespace transport if (!address.empty ()) { boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string (address, ec); + auto addr = boost::asio::ip::make_address (address, ec); if (!ec) { if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr); @@ -275,7 +275,7 @@ namespace transport if (!address.empty ()) { boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string (address, ec); + auto addr = boost::asio::ip::make_address (address, ec); if (!ec) { if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr); @@ -302,7 +302,7 @@ namespace transport if (!address.empty ()) { boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string (address, ec); + auto addr = boost::asio::ip::make_address (address, ec); if (!ec && m_NTCP2Server && i2p::util::net::IsYggdrasilAddress (addr)) m_NTCP2Server->SetLocalAddress (addr); } @@ -462,7 +462,7 @@ namespace transport void Transports::SendMessages (const i2p::data::IdentHash& ident, std::list >&& msgs) { - m_Service->post ([this, ident, msgs = std::move(msgs)] () mutable + boost::asio::post (*m_Service, [this, ident, msgs = std::move(msgs)] () mutable { PostMessages (ident, msgs); }); @@ -719,7 +719,7 @@ namespace transport void Transports::RequestComplete (std::shared_ptr r, const i2p::data::IdentHash& ident) { - m_Service->post (std::bind (&Transports::HandleRequestComplete, this, r, ident)); + boost::asio::post (*m_Service, std::bind (&Transports::HandleRequestComplete, this, r, ident)); } void Transports::HandleRequestComplete (std::shared_ptr r, i2p::data::IdentHash ident) @@ -856,7 +856,7 @@ namespace transport void Transports::PeerConnected (std::shared_ptr session) { - m_Service->post([session, this]() + boost::asio::post (*m_Service, [session, this]() { auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; @@ -928,7 +928,7 @@ namespace transport void Transports::PeerDisconnected (std::shared_ptr session) { - m_Service->post([session, this]() + boost::asio::post (*m_Service, [session, this]() { auto remoteIdentity = session->GetRemoteIdentity (); if (!remoteIdentity) return; @@ -1276,7 +1276,7 @@ namespace transport std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress); if (!yggaddress.empty ()) { - yggaddr = boost::asio::ip::address_v6::from_string (yggaddress); + yggaddr = boost::asio::ip::make_address (yggaddress).to_v6 (); if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) || !i2p::util::net::IsLocalAddress (yggaddr)) { @@ -1321,7 +1321,7 @@ namespace transport if (ipv6) { std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr); - auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr); + auto addr = boost::asio::ip::make_address (ipv6Addr).to_v6 (); if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ()) i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 431237a3..5829b9f3 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -208,7 +208,7 @@ namespace transport bool m_IsRunning, m_IsNAT, m_CheckReserved; std::thread * m_Thread; boost::asio::io_context * m_Service; - boost::asio::io_context::work * m_Work; + boost::asio::executor_work_guard * m_Work; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer, * m_UpdateBandwidthTimer; SSU2Server * m_SSU2Server; diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 47cecbbe..aff3d0e0 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -123,8 +123,8 @@ const char *inet_ntop_xp(int af, const void *src, char *dst, socklen_t size) #endif #endif -#define address_pair_v4(a,b) { boost::asio::ip::address_v4::from_string (a).to_ulong (), boost::asio::ip::address_v4::from_string (b).to_ulong () } -#define address_pair_v6(a,b) { boost::asio::ip::address_v6::from_string (a).to_bytes (), boost::asio::ip::address_v6::from_string (b).to_bytes () } +#define address_pair_v4(a,b) { boost::asio::ip::make_address (a).to_v4 ().to_uint (), boost::asio::ip::make_address(b).to_v4 ().to_uint () } +#define address_pair_v6(a,b) { boost::asio::ip::make_address (a).to_v6 ().to_bytes (), boost::asio::ip::make_address(b).to_v6 ().to_bytes () } namespace i2p { @@ -478,7 +478,7 @@ namespace net inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN); freeifaddrs(addrs); std::string cur_ifaddr(addr); - return boost::asio::ip::address::from_string(cur_ifaddr); + return boost::asio::ip::make_address(cur_ifaddr); } } } @@ -498,7 +498,7 @@ namespace net fallback = "127.0.0.1"; LogPrint(eLogWarning, "NetIface: Cannot find IPv4 address for interface ", ifname); } - return boost::asio::ip::address::from_string(fallback); + return boost::asio::ip::make_address(fallback); #endif } @@ -664,7 +664,7 @@ namespace net address_pair_v4("224.0.0.0", "255.255.255.255") }; - uint32_t ipv4_address = host.to_v4 ().to_ulong (); + uint32_t ipv4_address = host.to_v4 ().to_uint (); for (const auto& it : reservedIPv4Ranges) { if (ipv4_address >= it.first && ipv4_address <= it.second) return true; diff --git a/libi2pd/util.h b/libi2pd/util.h index dd065052..7bd35e67 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -202,11 +202,11 @@ namespace util protected: RunnableServiceWithWork (const std::string& name): - RunnableService (name), m_Work (GetIOService ()) {} + RunnableService (name), m_Work (GetIOService ().get_executor ()) {} private: - boost::asio::io_context::work m_Work; + boost::asio::executor_work_guard m_Work; }; void SetThreadName (const char *name); diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index 23c3b72f..f2dab223 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -129,7 +129,7 @@ namespace client BOBI2POutboundTunnel::BOBI2POutboundTunnel (const std::string& outhost, uint16_t port, std::shared_ptr localDestination, bool quiet): BOBI2PTunnel (localDestination), - m_Endpoint (boost::asio::ip::address::from_string (outhost), port), m_IsQuiet (quiet) + m_Endpoint (boost::asio::ip::make_address (outhost), port), m_IsQuiet (quiet) { } @@ -220,7 +220,7 @@ namespace client if (!inhost.empty ()) { boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string (inhost, ec); + auto addr = boost::asio::ip::make_address (inhost, ec); if (!ec) ep.address (addr); else @@ -425,7 +425,7 @@ namespace client { // TODO: FIXME: temporary validation, until hostname support is added boost::system::error_code ec; - boost::asio::ip::address::from_string(m_InHost, ec); + boost::asio::ip::make_address(m_InHost, ec); if (ec) { SendReplyError("inhost must be a valid IPv4 address."); @@ -436,7 +436,7 @@ namespace client { // TODO: FIXME: temporary validation, until hostname support is added boost::system::error_code ec; - boost::asio::ip::address::from_string(m_OutHost, ec); + boost::asio::ip::make_address(m_OutHost, ec); if (ec) { SendReplyError("outhost must be a IPv4 address."); @@ -828,7 +828,7 @@ namespace client BOBCommandChannel::BOBCommandChannel (const std::string& address, uint16_t port): RunnableService ("BOB"), - m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)) + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::make_address(address), port)) { // command -> handler m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler; diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 72051805..8c8c2bfa 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -631,7 +631,7 @@ namespace client if (type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { // udp client // TODO: hostnames - boost::asio::ip::udp::endpoint end (boost::asio::ip::address::from_string(address), port); + boost::asio::ip::udp::endpoint end (boost::asio::ip::make_address(address), port); if (!localDestination) localDestination = m_SharedLocalDestination; @@ -787,7 +787,7 @@ namespace client { // udp server tunnel // TODO: hostnames - boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); + boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::make_address(host), port); if (address.empty ()) { if (!endpoint.address ().is_unspecified () && endpoint.address ().is_v6 ()) @@ -795,7 +795,7 @@ namespace client else address = "127.0.0.1"; } - auto localAddress = boost::asio::ip::address::from_string(address); + auto localAddress = boost::asio::ip::make_address(address); auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, inPort, gzip); if(!isUniqueLocal) { diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index dba65815..13e0f571 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -98,7 +98,7 @@ namespace proxy { typedef std::function ProxyResolvedHandler; - void HandleUpstreamProxyResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr, ProxyResolvedHandler handler); + void HandleUpstreamProxyResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::results_type endpoints, ProxyResolvedHandler handler); void SocksProxySuccess(); void HandoverToUpstreamProxy(); @@ -584,20 +584,22 @@ namespace proxy { } else { - boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port)); - m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { - m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamHTTPProxyConnect, this, std::placeholders::_1)); - })); + m_proxy_resolver.async_resolve(m_ProxyURL.host, std::to_string(m_ProxyURL.port), std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, + std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) + { + m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamHTTPProxyConnect, this, std::placeholders::_1)); + })); } } else if (m_ProxyURL.schema == "socks") { /* handle upstream socks proxy */ if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified - boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port)); - m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { - m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); - })); + m_proxy_resolver.async_resolve(m_ProxyURL.host, std::to_string(m_ProxyURL.port), std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, + std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) + { + m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); + })); } else { @@ -606,10 +608,10 @@ namespace proxy { } } - void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler) + void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::results_type endpoints, ProxyResolvedHandler handler) { if(ec) GenericProxyError(tr("Cannot resolve upstream proxy"), ec.message()); - else handler(*it); + else handler(*endpoints.begin ()); } void HTTPReqHandler::HandleUpstreamSocksProxyConnect(const boost::system::error_code & ec) diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 7aec7549..1949746a 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -88,7 +88,7 @@ namespace client void I2CPDestination::CreateNewLeaseSet (const std::vector >& tunnels) { - GetService ().post (std::bind (&I2CPDestination::PostCreateNewLeaseSet, this, tunnels)); + boost::asio::post (GetService (), std::bind (&I2CPDestination::PostCreateNewLeaseSet, this, tunnels)); } void I2CPDestination::PostCreateNewLeaseSet (std::vector > tunnels) @@ -170,7 +170,7 @@ namespace client { // send in destination's thread auto s = GetSharedFromThis (); - GetService ().post ( + boost::asio::post (GetService (), [s, msg, remote, nonce]() { bool sent = s->SendMsg (msg, remote); @@ -1079,7 +1079,7 @@ namespace client I2CPServer::I2CPServer (const std::string& interface, uint16_t port, bool isSingleThread): RunnableService ("I2CP"), m_IsSingleThread (isSingleThread), m_Acceptor (GetIOService (), - boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) + boost::asio::ip::tcp::endpoint(boost::asio::ip::make_address(interface), port)) { memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index adcc3da7..d3ed36fa 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -283,7 +283,7 @@ namespace client public: TCPIPAcceptor (const std::string& address, uint16_t port, std::shared_ptr localDestination = nullptr) : - ServiceAcceptor (boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port), localDestination) {} + ServiceAcceptor (boost::asio::ip::tcp::endpoint (boost::asio::ip::make_address(address), port), localDestination) {} }; } } diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5ba83e1f..ed0533a7 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -717,7 +717,7 @@ namespace client { m_Endpoint.port (m_Port); boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string (m_Address, ec); + auto addr = boost::asio::ip::make_address (m_Address, ec); if (!ec) { m_Endpoint.address (addr); @@ -726,7 +726,7 @@ namespace client else { auto resolver = std::make_shared(GetService ()); - resolver->async_resolve (boost::asio::ip::tcp::resolver::query (m_Address, ""), + resolver->async_resolve (m_Address, "", std::bind (&I2PServerTunnel::HandleResolve, this, std::placeholders::_1, std::placeholders::_2, resolver)); } @@ -743,7 +743,7 @@ namespace client ClearHandlers (); } - void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::results_type endpoints, std::shared_ptr resolver) { if (!ecode) @@ -752,8 +752,7 @@ namespace client boost::asio::ip::tcp::endpoint ep; if (m_LocalAddress) { - boost::asio::ip::tcp::resolver::iterator end; - while (it != end) + for (auto it = endpoints.begin (); it != endpoints.end ();) { ep = *it; if (!ep.address ().is_unspecified ()) @@ -780,7 +779,7 @@ namespace client else { found = true; - ep = *it; // first available + ep = *endpoints.begin (); // first available } if (!found) { @@ -789,7 +788,7 @@ namespace client } auto addr = ep.address (); - LogPrint (eLogInfo, "I2PTunnel: Server tunnel ", (*it).host_name (), " has been resolved to ", addr); + LogPrint (eLogInfo, "I2PTunnel: Server tunnel ", (*endpoints.begin ()).host_name (), " has been resolved to ", addr); m_Endpoint.address (addr); Accept (); } @@ -806,7 +805,7 @@ namespace client void I2PServerTunnel::SetLocalAddress (const std::string& localAddress) { boost::system::error_code ec; - auto addr = boost::asio::ip::address::from_string(localAddress, ec); + auto addr = boost::asio::ip::make_address(localAddress, ec); if (!ec) m_LocalAddress.reset (new boost::asio::ip::address (addr)); else diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index b94eb9e4..0b01688d 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -208,7 +208,7 @@ namespace client private: - void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::results_type endpoints, std::shared_ptr resolver); void Accept (); diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index e4cbae8a..c124be9b 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -371,7 +371,7 @@ namespace client // udp forward selected boost::system::error_code e; // TODO: support hostnames in udp forward - auto addr = boost::asio::ip::address::from_string(params[SAM_PARAM_HOST], e); + auto addr = boost::asio::ip::make_address(params[SAM_PARAM_HOST], e); if (e) { // not an ip address @@ -624,7 +624,7 @@ namespace client auto socket = session->acceptQueue.front ().first; session->acceptQueue.pop_front (); if (socket) - m_Owner.GetService ().post (std::bind(&SAMSocket::TerminateClose, socket)); + boost::asio::post (m_Owner.GetService (), std::bind(&SAMSocket::TerminateClose, socket)); } if (session->acceptQueue.size () < SAM_SESSION_MAX_ACCEPT_QUEUE_SIZE) { @@ -1046,13 +1046,13 @@ namespace client else { auto s = shared_from_this (); - m_Owner.GetService ().post ([s] { s->Terminate ("stream read error"); }); + boost::asio::post (m_Owner.GetService (), [s] { s->Terminate ("stream read error"); }); } } else { auto s = shared_from_this (); - m_Owner.GetService ().post ([s] { s->Terminate ("stream read error (op aborted)"); }); + boost::asio::post (m_Owner.GetService (), [s] { s->Terminate ("stream read error (op aborted)"); }); } } else @@ -1102,7 +1102,7 @@ namespace client auto socket = session->acceptQueue.front ().first; session->acceptQueue.pop_front (); if (socket) - m_Owner.GetService ().post (std::bind(&SAMSocket::TerminateClose, socket)); + boost::asio::post (m_Owner.GetService (), std::bind(&SAMSocket::TerminateClose, socket)); } if (!session->acceptQueue.empty ()) { @@ -1236,7 +1236,7 @@ namespace client void SAMSocket::HandleStreamSend(const boost::system::error_code & ec) { - m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); + boost::asio::post (m_Owner.GetService (), std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); } SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type): @@ -1310,8 +1310,8 @@ namespace client SAMBridge::SAMBridge (const std::string& address, uint16_t portTCP, uint16_t portUDP, bool singleThread): RunnableService ("SAM"), m_IsSingleThread (singleThread), - m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), portTCP)), - m_DatagramEndpoint (boost::asio::ip::address::from_string(address), (!portUDP) ? portTCP-1 : portUDP), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), + m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::make_address(address), portTCP)), + m_DatagramEndpoint (boost::asio::ip::make_address(address), (!portUDP) ? portTCP-1 : portUDP), m_DatagramSocket (GetIOService (), m_DatagramEndpoint), m_SignatureTypes { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, diff --git a/libi2pd_client/SOCKS.cpp b/libi2pd_client/SOCKS.cpp index 0961690b..27df33c8 100644 --- a/libi2pd_client/SOCKS.cpp +++ b/libi2pd_client/SOCKS.cpp @@ -126,9 +126,8 @@ namespace proxy void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void Terminate(); void AsyncSockRead(); - boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method); - boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); - boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); + boost::asio::const_buffer GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); + boost::asio::const_buffer GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); bool Socks5ChooseAuth(); void Socks5UserPasswdResponse (); void SocksRequestFailed(errTypes error); @@ -145,9 +144,9 @@ namespace proxy template void SendUpstreamRequest(std::shared_ptr& upstreamSock); void HandleUpstreamConnected(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + const boost::asio::ip::tcp::endpoint& ep); void HandleUpstreamResolved(const boost::system::error_code & ecode, - boost::asio::ip::tcp::resolver::iterator itr); + boost::asio::ip::tcp::resolver::results_type endpoints); boost::asio::ip::tcp::resolver m_proxy_resolver; uint8_t m_sock_buff[socks_buffer_size]; @@ -233,17 +232,17 @@ namespace proxy Done(shared_from_this()); } - boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS4Response(SOCKSHandler::errTypes error, uint32_t ip, uint16_t port) + boost::asio::const_buffer SOCKSHandler::GenerateSOCKS4Response(SOCKSHandler::errTypes error, uint32_t ip, uint16_t port) { assert(error >= SOCKS4_OK); m_response[0] = '\x00'; // version m_response[1] = error; // response code htobe16buf(m_response + 2, port); // port htobe32buf(m_response + 4, ip); // IP - return boost::asio::const_buffers_1(m_response,8); + return boost::asio::const_buffer (m_response,8); } - boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) + boost::asio::const_buffer SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) { size_t size = 6; // header + port assert(error <= SOCKS5_ADDR_UNSUP); @@ -280,14 +279,14 @@ namespace proxy } break; } - return boost::asio::const_buffers_1(m_response, size); + return boost::asio::const_buffer (m_response, size); } bool SOCKSHandler::Socks5ChooseAuth() { m_response[0] = '\x05'; // Version m_response[1] = m_authchosen; // Response code - boost::asio::const_buffers_1 response(m_response, 2); + boost::asio::const_buffer response(m_response, 2); if (m_authchosen == AUTH_UNACCEPTABLE) { LogPrint(eLogWarning, "SOCKS: v5 authentication negotiation failed"); @@ -307,14 +306,14 @@ namespace proxy m_response[0] = 1; // Version of the subnegotiation m_response[1] = 0; // Response code LogPrint(eLogDebug, "SOCKS: v5 user/password response"); - boost::asio::async_write(*m_sock, boost::asio::const_buffers_1(m_response, 2), + boost::asio::async_write(*m_sock, boost::asio::const_buffer(m_response, 2), std::bind(&SOCKSHandler::SentSocksResponse, shared_from_this(), std::placeholders::_1)); } /* All hope is lost beyond this point */ void SOCKSHandler::SocksRequestFailed(SOCKSHandler::errTypes error) { - boost::asio::const_buffers_1 response(nullptr,0); + boost::asio::const_buffer response(nullptr,0); assert(error != SOCKS4_OK && error != SOCKS5_OK); switch (m_socksv) { @@ -334,7 +333,7 @@ namespace proxy void SOCKSHandler::SocksRequestSuccess() { - boost::asio::const_buffers_1 response(nullptr,0); + boost::asio::const_buffer response(nullptr,0); // TODO: this should depend on things like the command type and callbacks may change switch (m_socksv) { @@ -691,9 +690,8 @@ namespace proxy if (m_UpstreamProxyPort) // TCP { EnterState(UPSTREAM_RESOLVE); - boost::asio::ip::tcp::resolver::query q(m_UpstreamProxyAddress, std::to_string(m_UpstreamProxyPort)); - m_proxy_resolver.async_resolve(q, std::bind(&SOCKSHandler::HandleUpstreamResolved, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + m_proxy_resolver.async_resolve(m_UpstreamProxyAddress, std::to_string(m_UpstreamProxyPort), + std::bind(&SOCKSHandler::HandleUpstreamResolved, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else if (!m_UpstreamProxyAddress.empty ())// local { @@ -729,7 +727,7 @@ namespace proxy void SOCKSHandler::SocksUpstreamSuccess(std::shared_ptr& upstreamSock) { LogPrint(eLogInfo, "SOCKS: Upstream success"); - boost::asio::const_buffers_1 response(nullptr, 0); + boost::asio::const_buffer response(nullptr, 0); switch (m_socksv) { case SOCKS4: @@ -775,7 +773,8 @@ namespace proxy LogPrint(eLogError, "SOCKS: No upstream socket to send handshake to"); } - void SOCKSHandler::HandleUpstreamConnected(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr) + void SOCKSHandler::HandleUpstreamConnected(const boost::system::error_code & ecode, + const boost::asio::ip::tcp::endpoint& ep) { if (ecode) { LogPrint(eLogWarning, "SOCKS: Could not connect to upstream proxy: ", ecode.message()); @@ -786,7 +785,8 @@ namespace proxy SendUpstreamRequest(m_upstreamSock); } - void SOCKSHandler::HandleUpstreamResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr) + void SOCKSHandler::HandleUpstreamResolved(const boost::system::error_code & ecode, + boost::asio::ip::tcp::resolver::results_type endpoints) { if (ecode) { // error resolving @@ -798,7 +798,7 @@ namespace proxy EnterState(UPSTREAM_CONNECT); auto & service = GetOwner()->GetService(); m_upstreamSock = std::make_shared(service); - boost::asio::async_connect(*m_upstreamSock, itr, + boost::asio::async_connect(*m_upstreamSock, endpoints, std::bind(&SOCKSHandler::HandleUpstreamConnected, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } From cc768de8ea4845165075da50ae6251a72b978754 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 25 Nov 2024 19:16:42 -0500 Subject: [PATCH 08/19] iterator through resolver's results --- libi2pd/Reseed.cpp | 10 ++++------ libi2pd/Timestamp.cpp | 5 ++--- libi2pd_client/I2PTunnel.cpp | 5 ++--- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 6cf277bf..e58e898b 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -641,9 +641,9 @@ namespace data if (!ecode) { bool connected = false; - for (auto it = endpoints.begin (); it != endpoints.end ();) + for (const auto& it: endpoints) { - boost::asio::ip::tcp::endpoint ep = *it; + boost::asio::ip::tcp::endpoint ep = it; bool supported = false; if (!ep.address ().is_unspecified ()) { @@ -663,7 +663,6 @@ namespace data break; } } - it++; } if (!connected) { @@ -750,9 +749,9 @@ namespace data if (!ecode) { bool connected = false; - for (auto it = endpoints.begin (); it != endpoints.end ();) + for (const auto& it: endpoints) { - boost::asio::ip::tcp::endpoint ep = *it; + boost::asio::ip::tcp::endpoint ep = it; if ( i2p::util::net::IsYggdrasilAddress (ep.address ()) && i2p::context.SupportsMesh () @@ -766,7 +765,6 @@ namespace data break; } } - it++; } if (!connected) { diff --git a/libi2pd/Timestamp.cpp b/libi2pd/Timestamp.cpp index 210ef3b9..a22e9bde 100644 --- a/libi2pd/Timestamp.cpp +++ b/libi2pd/Timestamp.cpp @@ -67,9 +67,9 @@ namespace util { bool found = false; boost::asio::ip::udp::endpoint ep; - for (auto it = endpoints.begin (); it != endpoints.end ();) + for (const auto& it: endpoints) { - ep = *it; + ep = it; if (!ep.address ().is_unspecified ()) { if (ep.address ().is_v4 ()) @@ -86,7 +86,6 @@ namespace util } } if (found) break; - it++; } if (!found) { diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index ed0533a7..bbe09508 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -752,9 +752,9 @@ namespace client boost::asio::ip::tcp::endpoint ep; if (m_LocalAddress) { - for (auto it = endpoints.begin (); it != endpoints.end ();) + for (const auto& it: endpoints) { - ep = *it; + ep = it; if (!ep.address ().is_unspecified ()) { if (ep.address ().is_v4 ()) @@ -773,7 +773,6 @@ namespace client } } if (found) break; - it++; } } else From 8b9f427aa4882690662feea3e66f4a808bb36ac3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 27 Nov 2024 18:31:58 -0500 Subject: [PATCH 09/19] handle session handshakes in separate thread --- libi2pd/NTCP2.cpp | 149 ++++++++++++++++++++++++++++------------------ libi2pd/NTCP2.h | 20 ++++++- 2 files changed, 109 insertions(+), 60 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 38efc825..ca5e9260 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -491,7 +491,6 @@ namespace transport void NTCP2Session::HandleSessionRequestReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - (void) bytes_transferred; if (ecode) { LogPrint (eLogWarning, "NTCP2: SessionRequest read error: ", ecode.message ()); @@ -499,38 +498,47 @@ namespace transport } else { - LogPrint (eLogDebug, "NTCP2: SessionRequest received ", bytes_transferred); - uint16_t paddingLen = 0; - bool clockSkew = false; - if (m_Establisher->ProcessSessionRequestMessage (paddingLen, clockSkew)) - { - if (clockSkew) + boost::asio::post (m_Server.GetEstablisherService (), + [s = shared_from_this (), bytes_transferred] () { - // we don't care about padding, send SessionCreated and close session - SendSessionCreated (); - boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); - } - else if (paddingLen > 0) - { - if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max - { - boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer + 64, paddingLen), boost::asio::transfer_all (), - std::bind(&NTCP2Session::HandleSessionRequestPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - else - { - LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long"); - Terminate (); - } - } - else - SendSessionCreated (); - } - else - Terminate (); + s->ProcessSessionRequest (bytes_transferred);; + }); } } + void NTCP2Session::ProcessSessionRequest (size_t len) + { + LogPrint (eLogDebug, "NTCP2: SessionRequest received ", len); + uint16_t paddingLen = 0; + bool clockSkew = false; + if (m_Establisher->ProcessSessionRequestMessage (paddingLen, clockSkew)) + { + if (clockSkew) + { + // we don't care about padding, send SessionCreated and close session + SendSessionCreated (); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + else if (paddingLen > 0) + { + if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max + { + boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionRequestBuffer + 64, paddingLen), boost::asio::transfer_all (), + std::bind(&NTCP2Session::HandleSessionRequestPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + else + { + LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + } + else + SendSessionCreated (); + } + else + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + void NTCP2Session::HandleSessionRequestPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -539,7 +547,13 @@ namespace transport Terminate (); } else - SendSessionCreated (); + { + boost::asio::post (m_Server.GetEstablisherService (), + [s = shared_from_this ()] () + { + s->SendSessionCreated (); + }); + } } void NTCP2Session::SendSessionCreated () @@ -561,35 +575,44 @@ namespace transport else { m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval; - LogPrint (eLogDebug, "NTCP2: SessionCreated received ", bytes_transferred); - uint16_t paddingLen = 0; - if (m_Establisher->ProcessSessionCreatedMessage (paddingLen)) - { - if (paddingLen > 0) + boost::asio::post (m_Server.GetEstablisherService (), + [s = shared_from_this (), bytes_transferred] () { - if (paddingLen <= NTCP2_SESSION_CREATED_MAX_SIZE - 64) // session created is 287 bytes max - { - boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionCreatedBuffer + 64, paddingLen), boost::asio::transfer_all (), - std::bind(&NTCP2Session::HandleSessionCreatedPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - else - { - LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long"); - Terminate (); - } - } - else - SendSessionConfirmed (); - } - else - { - if (GetRemoteIdentity ()) - i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); // assume wrong s key - Terminate (); - } + s->ProcessSessionCreated (bytes_transferred); + }); } } + void NTCP2Session::ProcessSessionCreated (size_t len) + { + LogPrint (eLogDebug, "NTCP2: SessionCreated received ", len); + uint16_t paddingLen = 0; + if (m_Establisher->ProcessSessionCreatedMessage (paddingLen)) + { + if (paddingLen > 0) + { + if (paddingLen <= NTCP2_SESSION_CREATED_MAX_SIZE - 64) // session created is 287 bytes max + { + boost::asio::async_read (m_Socket, boost::asio::buffer(m_Establisher->m_SessionCreatedBuffer + 64, paddingLen), boost::asio::transfer_all (), + std::bind(&NTCP2Session::HandleSessionCreatedPaddingReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + else + { + LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + } + else + SendSessionConfirmed (); + } + else + { + if (GetRemoteIdentity ()) + i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true); // assume wrong s key + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + } + void NTCP2Session::HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -600,7 +623,11 @@ namespace transport else { m_Establisher->m_SessionCreatedBufferLen += bytes_transferred; - SendSessionConfirmed (); + boost::asio::post (m_Server.GetEstablisherService (), + [s = shared_from_this ()] () + { + s->SendSessionConfirmed (); + }); } } @@ -679,7 +706,7 @@ namespace transport // part 2 std::vector buf(m_Establisher->m3p2Len - 16); // -MAC memset (nonce, 0, 12); // set nonce to 0 again - if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf.data ())) + if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf.data ())) // TODO:handle in establisher thread { KeyDerivationFunctionDataPhase (); // Bob data phase keys @@ -811,7 +838,11 @@ namespace transport void NTCP2Session::ClientLogin () { m_Establisher->CreateEphemeralKey (); - SendSessionRequest (); + boost::asio::post (m_Server.GetEstablisherService (), + [s = shared_from_this ()] () + { + s->SendSessionRequest (); + }); } void NTCP2Session::ServerLogin () @@ -1367,6 +1398,7 @@ namespace transport void NTCP2Server::Start () { + m_EstablisherService.Start (); if (!IsRunning ()) { StartIOService (); @@ -1476,6 +1508,7 @@ namespace transport m_TerminationTimer.cancel (); m_ProxyEndpoint = nullptr; } + m_EstablisherService.Stop (); StopIOService (); } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index e1718bb0..7f5c97aa 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -172,9 +172,11 @@ namespace transport void HandleSessionRequestSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionRequestReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void ProcessSessionRequest (size_t len); void HandleSessionRequestPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionCreatedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionCreatedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void ProcessSessionCreated (size_t len); void HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionConfirmedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); @@ -239,6 +241,18 @@ namespace transport class NTCP2Server: private i2p::util::RunnableServiceWithWork { + private: + + class EstablisherService: public i2p::util::RunnableServiceWithWork + { + public: + + EstablisherService (): RunnableServiceWithWork ("NTCP2e") {}; + auto& GetService () { return GetIOService (); }; + void Start () { StartIOService (); }; + void Stop () { StopIOService (); }; + }; + public: enum ProxyType @@ -247,13 +261,14 @@ namespace transport eSocksProxy, eHTTPProxy }; - + NTCP2Server (); ~NTCP2Server (); void Start (); void Stop (); auto& GetService () { return GetIOService (); }; + auto& GetEstablisherService () { return m_EstablisherService.GetService (); }; std::mt19937& GetRng () { return m_Rng; }; bool AddNTCP2Session (std::shared_ptr session, bool incoming = false); @@ -294,7 +309,8 @@ namespace transport std::unique_ptr m_ProxyEndpoint; std::shared_ptr m_Address4, m_Address6, m_YggdrasilAddress; std::mt19937 m_Rng; - + EstablisherService m_EstablisherService; + public: // for HTTP/I2PControl From 56145d0f3c80270fe3c7a6cdf094f7b8dbbf5ae4 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Nov 2024 21:56:26 -0500 Subject: [PATCH 10/19] bind tunnel gateway to transport session --- libi2pd/Transports.cpp | 40 ++++++++++++++++++++++----------------- libi2pd/Transports.h | 9 +++++---- libi2pd/TunnelGateway.cpp | 32 ++++++++++++++++++++++++++++++- libi2pd/TunnelGateway.h | 6 +++++- 4 files changed, 64 insertions(+), 23 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index e2f8c730..03416137 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -447,28 +447,29 @@ namespace transport return std::max (bwCongestionLevel, tbwCongestionLevel); } - void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) + std::future > Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { if (m_IsOnline) - SendMessages (ident, { msg }); + return SendMessages (ident, { msg }); + return {}; // invalid future } - void Transports::SendMessages (const i2p::data::IdentHash& ident, std::list >& msgs) + std::future > Transports::SendMessages (const i2p::data::IdentHash& ident, std::list >& msgs) { std::list > msgs1; msgs.swap (msgs1); - SendMessages (ident, std::move (msgs1)); + return SendMessages (ident, std::move (msgs1)); } - void Transports::SendMessages (const i2p::data::IdentHash& ident, std::list >&& msgs) + std::future > Transports::SendMessages (const i2p::data::IdentHash& ident, std::list >&& msgs) { - boost::asio::post (*m_Service, [this, ident, msgs = std::move(msgs)] () mutable + return boost::asio::post (*m_Service, boost::asio::use_future ([this, ident, msgs = std::move(msgs)] () mutable { - PostMessages (ident, msgs); - }); + return PostMessages (ident, msgs); + })); } - void Transports::PostMessages (const i2p::data::IdentHash& ident, std::list >& msgs) + std::shared_ptr Transports::PostMessages (const i2p::data::IdentHash& ident, std::list >& msgs) { if (ident == i2p::context.GetRouterInfo ().GetIdentHash ()) { @@ -476,9 +477,9 @@ namespace transport for (auto& it: msgs) m_LoopbackHandler.PutNextMessage (std::move (it)); m_LoopbackHandler.Flush (); - return; + return nullptr; } - if(RoutesRestricted() && !IsRestrictedPeer(ident)) return; + if(RoutesRestricted() && !IsRestrictedPeer(ident)) return nullptr; std::shared_ptr peer; { std::lock_guard l(m_PeersMutex); @@ -489,13 +490,13 @@ namespace transport if (!peer) { // check if not banned - if (i2p::data::IsRouterBanned (ident)) return; // don't create peer to unreachable router + if (i2p::data::IsRouterBanned (ident)) return nullptr; // don't create peer to unreachable router // try to connect bool connected = false; try { auto r = netdb.FindRouter (ident); - if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return; // router found but non-reachable + if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return nullptr; // router found but non-reachable peer = std::make_shared(r, i2p::util::GetSecondsSinceEpoch ()); { @@ -509,12 +510,16 @@ namespace transport { LogPrint (eLogError, "Transports: PostMessages exception:", ex.what ()); } - if (!connected) return; + if (!connected) return nullptr; } - if (!peer) return; + if (!peer) return nullptr; if (peer->IsConnected ()) - peer->sessions.front ()->SendI2NPMessages (msgs); + { + auto session = peer->sessions.front (); + if (session) session->SendI2NPMessages (msgs); + return session; + } else { auto sz = peer->delayedMessages.size (); @@ -527,7 +532,7 @@ namespace transport LogPrint (eLogWarning, "Transports: Router ", ident.ToBase64 (), " is banned. Peer dropped"); std::lock_guard l(m_PeersMutex); m_Peers.erase (ident); - return; + return nullptr; } } if (sz > MAX_NUM_DELAYED_MESSAGES/2) @@ -549,6 +554,7 @@ namespace transport m_Peers.erase (ident); } } + return nullptr; } bool Transports::ConnectToPeer (const i2p::data::IdentHash& ident, std::shared_ptr peer) diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 5829b9f3..b72d5b70 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -143,9 +144,9 @@ namespace transport std::shared_ptr GetNextX25519KeysPair (); void ReuseX25519KeysPair (std::shared_ptr pair); - void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); - void SendMessages (const i2p::data::IdentHash& ident, std::list >& msgs); - void SendMessages (const i2p::data::IdentHash& ident, std::list >&& msgs); + std::future > SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg); + std::future > SendMessages (const i2p::data::IdentHash& ident, std::list >& msgs); + std::future > SendMessages (const i2p::data::IdentHash& ident, std::list >&& msgs); void PeerConnected (std::shared_ptr session); void PeerDisconnected (std::shared_ptr session); @@ -189,7 +190,7 @@ namespace transport void Run (); void RequestComplete (std::shared_ptr r, const i2p::data::IdentHash& ident); void HandleRequestComplete (std::shared_ptr r, i2p::data::IdentHash ident); - void PostMessages (const i2p::data::IdentHash& ident, std::list >& msgs); + std::shared_ptr PostMessages (const i2p::data::IdentHash& ident, std::list >& msgs); bool ConnectToPeer (const i2p::data::IdentHash& ident, std::shared_ptr peer); void SetPriority (std::shared_ptr peer) const; void HandlePeerCleanupTimer (const boost::system::error_code& ecode); diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 78a63fc4..4b9e037a 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -220,6 +220,7 @@ namespace tunnel void TunnelGateway::SendBuffer () { + // create list or tunnel messages m_Buffer.CompleteCurrentTunnelDataMessage (); std::list > newTunnelMsgs; const auto& tunnelDataMsgs = m_Buffer.GetTunnelDataMsgs (); @@ -234,7 +235,36 @@ namespace tunnel m_NumSentBytes += TUNNEL_DATA_MSG_SIZE; } m_Buffer.ClearTunnelDataMsgs (); - i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), std::move (newTunnelMsgs)); + + // send + if (m_CurrentTransport && !m_CurrentTransport->IsEstablished ()) // check if session became invalid since last call + m_CurrentTransport = nullptr; + if (!m_CurrentTransport) + { + // try to obtain transport from peding reequest or send thought transport is not complete + if (m_PendingTransport.valid ()) // pending request? + { + if (m_PendingTransport.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + { + // pending request complete + m_CurrentTransport = m_PendingTransport.get (); // take tarnsports used in pending request + if (m_CurrentTransport && !m_CurrentTransport->IsEstablished ()) + m_CurrentTransport = nullptr; + } + else // still pending + { + // send through transports, but don't update pedning transport + i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), std::move (newTunnelMsgs)); + return; + } + } + } + if (m_CurrentTransport) // session is good + // send to session directly + m_CurrentTransport->SendI2NPMessages (newTunnelMsgs); + else // no session yet + // send through transports + m_PendingTransport = i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), std::move (newTunnelMsgs)); } } } diff --git a/libi2pd/TunnelGateway.h b/libi2pd/TunnelGateway.h index 741bbe84..ba36ac73 100644 --- a/libi2pd/TunnelGateway.h +++ b/libi2pd/TunnelGateway.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2021, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -12,7 +12,9 @@ #include #include #include +#include #include "I2NPProtocol.h" +#include "TransportSession.h" #include "TunnelBase.h" namespace i2p @@ -57,6 +59,8 @@ namespace tunnel TunnelBase * m_Tunnel; TunnelGatewayBuffer m_Buffer; size_t m_NumSentBytes; + std::shared_ptr m_CurrentTransport; + std::future > m_PendingTransport; }; } } From fcc70025fda78e4ce15cc4985d5109bf489d3efa Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Nov 2024 11:31:13 -0500 Subject: [PATCH 11/19] use reference instead naked pointer to tunnel in tunnel gateway --- libi2pd/TransitTunnel.h | 2 +- libi2pd/Tunnel.h | 2 +- libi2pd/TunnelGateway.cpp | 8 ++++---- libi2pd/TunnelGateway.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libi2pd/TransitTunnel.h b/libi2pd/TransitTunnel.h index c4a6e156..14f9b997 100644 --- a/libi2pd/TransitTunnel.h +++ b/libi2pd/TransitTunnel.h @@ -73,7 +73,7 @@ namespace tunnel const i2p::data::IdentHash& nextIdent, uint32_t nextTunnelID, const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey): TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, - layerKey, ivKey), m_Gateway(this) {}; + layerKey, ivKey), m_Gateway(*this) {}; void SendTunnelDataMsg (std::shared_ptr msg) override; void FlushTunnelDataMsgs () override; diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 2d0641e3..e11a360d 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -139,7 +139,7 @@ namespace tunnel public: OutboundTunnel (std::shared_ptr config): - Tunnel (config), m_Gateway (this), m_EndpointIdentHash (config->GetLastIdentHash ()) {}; + Tunnel (config), m_Gateway (*this), m_EndpointIdentHash (config->GetLastIdentHash ()) {}; void SendTunnelDataMsgTo (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr msg); virtual void SendTunnelDataMsgs (const std::vector& msgs); // multiple messages diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 4b9e037a..73ca02b8 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -227,8 +227,8 @@ namespace tunnel for (auto& tunnelMsg : tunnelDataMsgs) { auto newMsg = CreateEmptyTunnelDataMsg (false); - m_Tunnel->EncryptTunnelMsg (tunnelMsg, newMsg); - htobe32buf (newMsg->GetPayload (), m_Tunnel->GetNextTunnelID ()); + m_Tunnel.EncryptTunnelMsg (tunnelMsg, newMsg); + htobe32buf (newMsg->GetPayload (), m_Tunnel.GetNextTunnelID ()); newMsg->FillI2NPMessageHeader (eI2NPTunnelData); if (tunnelMsg->onDrop) newMsg->onDrop = tunnelMsg->onDrop; newTunnelMsgs.push_back (newMsg); @@ -254,7 +254,7 @@ namespace tunnel else // still pending { // send through transports, but don't update pedning transport - i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), std::move (newTunnelMsgs)); + i2p::transport::transports.SendMessages (m_Tunnel.GetNextIdentHash (), std::move (newTunnelMsgs)); return; } } @@ -264,7 +264,7 @@ namespace tunnel m_CurrentTransport->SendI2NPMessages (newTunnelMsgs); else // no session yet // send through transports - m_PendingTransport = i2p::transport::transports.SendMessages (m_Tunnel->GetNextIdentHash (), std::move (newTunnelMsgs)); + m_PendingTransport = i2p::transport::transports.SendMessages (m_Tunnel.GetNextIdentHash (), std::move (newTunnelMsgs)); } } } diff --git a/libi2pd/TunnelGateway.h b/libi2pd/TunnelGateway.h index ba36ac73..cd70b4d8 100644 --- a/libi2pd/TunnelGateway.h +++ b/libi2pd/TunnelGateway.h @@ -47,7 +47,7 @@ namespace tunnel { public: - TunnelGateway (TunnelBase * tunnel): + TunnelGateway (TunnelBase& tunnel): m_Tunnel (tunnel), m_NumSentBytes (0) {}; void SendTunnelDataMsg (const TunnelMessageBlock& block); void PutTunnelDataMsg (const TunnelMessageBlock& block); @@ -56,7 +56,7 @@ namespace tunnel private: - TunnelBase * m_Tunnel; + TunnelBase& m_Tunnel; TunnelGatewayBuffer m_Buffer; size_t m_NumSentBytes; std::shared_ptr m_CurrentTransport; From 31ff0ff1cba2a40a4634d00bd49d96b810c8607c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Nov 2024 21:29:03 -0500 Subject: [PATCH 12/19] use weak_ptr for transport session --- libi2pd/TunnelGateway.cpp | 20 ++++++++++++-------- libi2pd/TunnelGateway.h | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/libi2pd/TunnelGateway.cpp b/libi2pd/TunnelGateway.cpp index 73ca02b8..fabc71bb 100644 --- a/libi2pd/TunnelGateway.cpp +++ b/libi2pd/TunnelGateway.cpp @@ -237,9 +237,8 @@ namespace tunnel m_Buffer.ClearTunnelDataMsgs (); // send - if (m_CurrentTransport && !m_CurrentTransport->IsEstablished ()) // check if session became invalid since last call - m_CurrentTransport = nullptr; - if (!m_CurrentTransport) + auto currentTransport = m_CurrentTransport.lock (); + if (!currentTransport) { // try to obtain transport from peding reequest or send thought transport is not complete if (m_PendingTransport.valid ()) // pending request? @@ -247,9 +246,14 @@ namespace tunnel if (m_PendingTransport.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { // pending request complete - m_CurrentTransport = m_PendingTransport.get (); // take tarnsports used in pending request - if (m_CurrentTransport && !m_CurrentTransport->IsEstablished ()) - m_CurrentTransport = nullptr; + currentTransport = m_PendingTransport.get (); // take tarnsports used in pending request + if (currentTransport) + { + if (currentTransport->IsEstablished ()) + m_CurrentTransport = currentTransport; + else + currentTransport = nullptr; + } } else // still pending { @@ -259,9 +263,9 @@ namespace tunnel } } } - if (m_CurrentTransport) // session is good + if (currentTransport) // session is good // send to session directly - m_CurrentTransport->SendI2NPMessages (newTunnelMsgs); + currentTransport->SendI2NPMessages (newTunnelMsgs); else // no session yet // send through transports m_PendingTransport = i2p::transport::transports.SendMessages (m_Tunnel.GetNextIdentHash (), std::move (newTunnelMsgs)); diff --git a/libi2pd/TunnelGateway.h b/libi2pd/TunnelGateway.h index cd70b4d8..4cfd5308 100644 --- a/libi2pd/TunnelGateway.h +++ b/libi2pd/TunnelGateway.h @@ -59,7 +59,7 @@ namespace tunnel TunnelBase& m_Tunnel; TunnelGatewayBuffer m_Buffer; size_t m_NumSentBytes; - std::shared_ptr m_CurrentTransport; + std::weak_ptr m_CurrentTransport; std::future > m_PendingTransport; }; } From 7b0ff2850cf0b54953652cdb6b77ff9eb51bf18f Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 1 Dec 2024 16:53:08 -0500 Subject: [PATCH 13/19] close session if x25519 fails --- libi2pd/NTCP2.cpp | 92 +++++++++++++++++++++++++++++++---------------- libi2pd/NTCP2.h | 22 ++++++------ 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index ca5e9260..8b10a7d5 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -42,28 +42,29 @@ namespace transport delete[] m_SessionConfirmedBuffer; } - void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) + bool NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { i2p::crypto::InitNoiseXKState (*this, rs); // h = SHA256(h || epub) MixHash (epub, 32); // x25519 between pub and priv uint8_t inputKeyMaterial[32]; - priv.Agree (pub, inputKeyMaterial); + if (!priv.Agree (pub, inputKeyMaterial)) return false; MixKey (inputKeyMaterial); + return true; } - void NTCP2Establisher::KDF1Alice () + bool NTCP2Establisher::KDF1Alice () { - KeyDerivationFunction1 (m_RemoteStaticKey, *m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); + return KeyDerivationFunction1 (m_RemoteStaticKey, *m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); } - void NTCP2Establisher::KDF1Bob () + bool NTCP2Establisher::KDF1Bob () { - KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); + return KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); } - void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) + bool NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) { MixHash (sessionRequest + 32, 32); // encrypted payload @@ -74,33 +75,35 @@ namespace transport // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; - m_EphemeralKeys->Agree (GetRemotePub (), inputKeyMaterial); - + if (!m_EphemeralKeys->Agree (GetRemotePub (), inputKeyMaterial)) return false; MixKey (inputKeyMaterial); + return true; } - void NTCP2Establisher::KDF2Alice () + bool NTCP2Establisher::KDF2Alice () { - KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetRemotePub ()); + return KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetRemotePub ()); } - void NTCP2Establisher::KDF2Bob () + bool NTCP2Establisher::KDF2Bob () { - KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); + return KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ()); } - void NTCP2Establisher::KDF3Alice () + bool NTCP2Establisher::KDF3Alice () { uint8_t inputKeyMaterial[32]; - i2p::context.GetNTCP2StaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); + if (!i2p::context.GetNTCP2StaticKeys ().Agree (GetRemotePub (), inputKeyMaterial)) return false; MixKey (inputKeyMaterial); + return true; } - void NTCP2Establisher::KDF3Bob () + bool NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - m_EphemeralKeys->Agree (m_RemoteStaticKey, inputKeyMaterial); + if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, inputKeyMaterial)) return false; MixKey (inputKeyMaterial); + return true; } void NTCP2Establisher::CreateEphemeralKey () @@ -108,7 +111,7 @@ namespace transport m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair (); } - void NTCP2Establisher::CreateSessionRequestMessage (std::mt19937& rng) + bool NTCP2Establisher::CreateSessionRequestMessage (std::mt19937& rng) { // create buffer and fill padding auto paddingLength = rng () % (NTCP2_SESSION_REQUEST_MAX_SIZE - 64); // message length doesn't exceed 287 bytes @@ -121,7 +124,7 @@ namespace transport encryption.Encrypt (GetPub (), 32, m_SessionRequestBuffer); // X encryption.GetIV (m_IV); // save IV for SessionCreated // encryption key for next block - KDF1Alice (); + if (!KDF1Alice ()) return false; // fill options uint8_t options[32]; // actual options size is 16 bytes memset (options, 0, 16); @@ -147,9 +150,10 @@ namespace transport uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionRequestBuffer + 32, 32, true); // encrypt + return true; } - void NTCP2Establisher::CreateSessionCreatedMessage (std::mt19937& rng) + bool NTCP2Establisher::CreateSessionCreatedMessage (std::mt19937& rng) { auto paddingLen = rng () % (NTCP2_SESSION_CREATED_MAX_SIZE - 64); m_SessionCreatedBufferLen = paddingLen + 64; @@ -160,7 +164,7 @@ namespace transport encryption.SetIV (m_IV); encryption.Encrypt (GetPub (), 32, m_SessionCreatedBuffer); // Y // encryption key for next block (m_K) - KDF2Bob (); + if (!KDF2Bob ()) return false; uint8_t options[16]; memset (options, 0, 16); htobe16buf (options + 2, paddingLen); // padLen @@ -169,7 +173,7 @@ namespace transport uint8_t nonce[12]; memset (nonce, 0, 12); // set nonce to zero i2p::crypto::AEADChaCha20Poly1305 (options, 16, GetH (), 32, GetK (), nonce, m_SessionCreatedBuffer + 32, 32, true); // encrypt - + return true; } void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce) @@ -184,17 +188,18 @@ namespace transport i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, GetH (), 32, GetK (), nonce, m_SessionConfirmedBuffer, 48, true); // encrypt } - void NTCP2Establisher::CreateSessionConfirmedMessagePart2 (const uint8_t * nonce) + bool NTCP2Establisher::CreateSessionConfirmedMessagePart2 (const uint8_t * nonce) { // part 2 // update AD again MixHash (m_SessionConfirmedBuffer, 48); // encrypt m3p2, it must be filled in SessionRequest - KDF3Alice (); + if (!KDF3Alice ()) return false; uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2, m3p2Len, true); // encrypt // update h again MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext) + return true; } bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew) @@ -207,7 +212,11 @@ namespace transport decryption.Decrypt (m_SessionRequestBuffer, 32, GetRemotePub ()); decryption.GetIV (m_IV); // save IV for SessionCreated // decryption key for next block - KDF1Bob (); + if (!KDF1Bob ()) + { + LogPrint (eLogWarning, "NTCP2: SessionRequest KDF failed"); + return false; + } // verify MAC and decrypt options block (32 bytes), use m_H as AD uint8_t nonce[12], options[16]; memset (nonce, 0, 12); // set nonce to zero @@ -262,7 +271,11 @@ namespace transport decryption.SetIV (m_IV); decryption.Decrypt (m_SessionCreatedBuffer, 32, GetRemotePub ()); // decryption key for next block (m_K) - KDF2Alice (); + if (!KDF2Alice ()) + { + LogPrint (eLogWarning, "NTCP2: SessionCreated KDF failed"); + return false; + } // decrypt and verify MAC uint8_t payload[16]; uint8_t nonce[12]; @@ -309,7 +322,11 @@ namespace transport // update AD again MixHash (m_SessionConfirmedBuffer, 48); - KDF3Bob (); + if (!KDF3Bob ()) + { + LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part2 KDF failed"); + return false; + } if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, GetH (), 32, GetK (), nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt // calculate new h again for KDF data MixHash (m_SessionConfirmedBuffer + 48, m3p2Len); // h = SHA256(h || ciphertext) @@ -466,7 +483,12 @@ namespace transport void NTCP2Session::SendSessionRequest () { - m_Establisher->CreateSessionRequestMessage (m_Server.GetRng ()); + if (!m_Establisher->CreateSessionRequestMessage (m_Server.GetRng ())) + { + LogPrint (eLogWarning, "NTCP2: Send SessionRequest KDF failed"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + return; + } // send message m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch (); boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionRequestBuffer, m_Establisher->m_SessionRequestBufferLen), boost::asio::transfer_all (), @@ -558,7 +580,12 @@ namespace transport void NTCP2Session::SendSessionCreated () { - m_Establisher->CreateSessionCreatedMessage (m_Server.GetRng ()); + if (!m_Establisher->CreateSessionCreatedMessage (m_Server.GetRng ())) + { + LogPrint (eLogWarning, "NTCP2: Send SessionCreated KDF failed"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + return; + } // send message m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch (); boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionCreatedBuffer, m_Establisher->m_SessionCreatedBufferLen), boost::asio::transfer_all (), @@ -637,7 +664,12 @@ namespace transport CreateNonce (1, nonce); // set nonce to 1 m_Establisher->CreateSessionConfirmedMessagePart1 (nonce); memset (nonce, 0, 12); // set nonce back to 0 - m_Establisher->CreateSessionConfirmedMessagePart2 (nonce); + if (!m_Establisher->CreateSessionConfirmedMessagePart2 (nonce)) + { + LogPrint (eLogWarning, "NTCP2: Send SessionConfirmed Part2 KDF failed"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + return; + } // send message boost::asio::async_write (m_Socket, boost::asio::buffer (m_Establisher->m_SessionConfirmedBuffer, m_Establisher->m3p2Len + 48), boost::asio::transfer_all (), std::bind(&NTCP2Session::HandleSessionConfirmedSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 7f5c97aa..f0cee06a 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -95,21 +95,21 @@ namespace transport const uint8_t * GetCK () const { return m_CK; }; const uint8_t * GetH () const { return m_H; }; - void KDF1Alice (); - void KDF1Bob (); - void KDF2Alice (); - void KDF2Bob (); - void KDF3Alice (); // for SessionConfirmed part 2 - void KDF3Bob (); + bool KDF1Alice (); + bool KDF1Bob (); + bool KDF2Alice (); + bool KDF2Bob (); + bool KDF3Alice (); // for SessionConfirmed part 2 + bool KDF3Bob (); - void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH - void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate + bool KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH + bool KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate void CreateEphemeralKey (); - void CreateSessionRequestMessage (std::mt19937& rng); - void CreateSessionCreatedMessage (std::mt19937& rng); + bool CreateSessionRequestMessage (std::mt19937& rng); + bool CreateSessionCreatedMessage (std::mt19937& rng); void CreateSessionConfirmedMessagePart1 (const uint8_t * nonce); - void CreateSessionConfirmedMessagePart2 (const uint8_t * nonce); + bool CreateSessionConfirmedMessagePart2 (const uint8_t * nonce); bool ProcessSessionRequestMessage (uint16_t& paddingLen, bool& clockSkew); bool ProcessSessionCreatedMessage (uint16_t& paddingLen); From b17bbd754a6662c2ba0fa7b4dc4744d7a1bd16ae Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 3 Dec 2024 00:40:30 +0300 Subject: [PATCH 14/19] [gha] winxp: forced overwrite files from boost package --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d587ba05..38449bf7 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -231,7 +231,7 @@ jobs: cd MINGW-packages/mingw-w64-boost MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck - name: Install boost package - run: pacman --noconfirm -U MINGW-packages/mingw-w64-boost/mingw-w64-i686-*-any.pkg.tar.zst + run: pacman --noconfirm --overwrite -U MINGW-packages/mingw-w64-boost/mingw-w64-i686-*-any.pkg.tar.zst # Building i2pd - name: Build application From 1a32ed908889364d1d5ad39893e588358cc6df12 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Tue, 3 Dec 2024 00:44:14 +0300 Subject: [PATCH 15/19] [gha] winxp: fix option order --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 38449bf7..ed7147ff 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -231,7 +231,7 @@ jobs: cd MINGW-packages/mingw-w64-boost MINGW_ARCH=mingw32 makepkg-mingw -sCLf --noconfirm --nocheck - name: Install boost package - run: pacman --noconfirm --overwrite -U MINGW-packages/mingw-w64-boost/mingw-w64-i686-*-any.pkg.tar.zst + run: pacman --noconfirm -U --overwrite MINGW-packages/mingw-w64-boost/mingw-w64-i686-*-any.pkg.tar.zst # Building i2pd - name: Build application From e518b92a891743179417e92e057eb5a779045e08 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 2 Dec 2024 19:05:12 -0500 Subject: [PATCH 16/19] calculate X_I2P_DEST* headers once for series of HTTP requests --- libi2pd_client/I2PTunnel.cpp | 31 ++++++++++++++++++------------- libi2pd_client/I2PTunnel.h | 14 +++++++------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index bbe09508..3a3c491e 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -375,10 +375,10 @@ namespace client } I2PServerTunnelConnectionHTTP::I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, - const boost::asio::ip::tcp::endpoint& target, const std::string& host, + const boost::asio::ip::tcp::endpoint& target, const std::string& host, const std::string& XI2P, std::shared_ptr sslCtx): - I2PTunnelConnection (owner, stream, target, true, sslCtx), m_Host (host), - m_HeaderSent (false), m_ResponseHeaderSent (false), m_From (stream->GetRemoteIdentity ()) + I2PTunnelConnection (owner, stream, target, true, sslCtx), m_Host (host), m_XI2P (XI2P), + m_HeaderSent (false), m_ResponseHeaderSent (false) { if (sslCtx) SSL_set_tlsext_host_name(GetSSL ()->native_handle(), host.c_str ()); @@ -448,17 +448,12 @@ namespace client if (!connection) m_OutHeader << "Connection: close\r\n"; // add X-I2P fields - if (m_From) - { - m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n"; - m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n"; - m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n"; - } - - m_OutHeader << "\r\n"; // end of header + m_OutHeader << m_XI2P; + // end of header + m_OutHeader << "\r\n"; + m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header m_InHeader.str (""); - m_From = nullptr; m_HeaderSent = true; I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); } @@ -876,7 +871,17 @@ namespace client std::shared_ptr I2PServerTunnelHTTP::CreateI2PConnection (std::shared_ptr stream) { - return std::make_shared (this, stream, GetEndpoint (), m_Host, GetSSLCtx ()); + if (m_XI2P.empty () || stream->GetRemoteIdentity () != m_From.lock ()) + { + auto from = stream->GetRemoteIdentity (); + m_From = from; + std::stringstream ss; + ss << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(from->GetIdentHash ()) << "\r\n"; + ss << X_I2P_DEST_HASH << ": " << from->GetIdentHash ().ToBase64 () << "\r\n"; + ss << X_I2P_DEST_B64 << ": " << from->ToBase64 () << "\r\n"; + m_XI2P = ss.str (); + } + return std::make_shared (this, stream, GetEndpoint (), m_Host, m_XI2P, GetSSLCtx ()); } I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address, diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 0b01688d..aa53f0b6 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -31,9 +31,9 @@ namespace client const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds // for HTTP tunnels - const char X_I2P_DEST_HASH[] = "X-I2P-DestHash"; // hash in base64 - const char X_I2P_DEST_B64[] = "X-I2P-DestB64"; // full address in base64 - const char X_I2P_DEST_B32[] = "X-I2P-DestB32"; // .b32.i2p address + constexpr char X_I2P_DEST_HASH[] = "X-I2P-DestHash"; // hash in base64 + constexpr char X_I2P_DEST_B64[] = "X-I2P-DestB64"; // full address in base64 + constexpr char X_I2P_DEST_B32[] = "X-I2P-DestB32"; // .b32.i2p address const int I2P_TUNNEL_HTTP_MAX_HEADER_SIZE = 8192; class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this @@ -107,7 +107,7 @@ namespace client public: I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, - const boost::asio::ip::tcp::endpoint& target, const std::string& host, + const boost::asio::ip::tcp::endpoint& target, const std::string& host, const std::string& XI2P, std::shared_ptr sslCtx = nullptr); protected: @@ -117,10 +117,9 @@ namespace client private: - std::string m_Host; + std::string m_Host, m_XI2P; std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent, m_ResponseHeaderSent; - std::shared_ptr m_From; }; class I2PTunnelConnectionIRC: public I2PTunnelConnection @@ -242,7 +241,8 @@ namespace client private: - std::string m_Host; + std::string m_Host, m_XI2P; + std::weak_ptr m_From; }; class I2PServerTunnelIRC: public I2PServerTunnel From f79a2e81ffede33d7c7fc70e85634568dbf31d94 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Dec 2024 18:36:57 -0500 Subject: [PATCH 17/19] calculate data phase keys after verification --- libi2pd/NTCP2.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 8b10a7d5..cfc24e08 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -740,15 +740,8 @@ namespace transport memset (nonce, 0, 12); // set nonce to 0 again if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf.data ())) // TODO:handle in establisher thread { - KeyDerivationFunctionDataPhase (); - // Bob data phase keys - m_SendKey = m_Kba; - m_ReceiveKey = m_Kab; - SetSipKeys (m_Sipkeysba, m_Sipkeysab); - memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); - memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); - // payload - // process RI + // payload + // RI block must be first if (buf[0] != eNTCP2BlkRouterInfo) { LogPrint (eLogWarning, "NTCP2: Unexpected block ", (int)buf[0], " in SessionConfirmed"); @@ -825,12 +818,20 @@ namespace transport SendTerminationAndTerminate (eNTCP2Banned); return; } - // TODO: process options + // TODO: process options block // ready to communicate SetRemoteIdentity (ri1->GetRouterIdentity ()); if (m_Server.AddNTCP2Session (shared_from_this (), true)) { + KeyDerivationFunctionDataPhase (); + // Bob data phase keys + m_SendKey = m_Kba; + m_ReceiveKey = m_Kab; + SetSipKeys (m_Sipkeysba, m_Sipkeysab); + memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); + memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); + Established (); ReceiveLength (); } From e996db03c05eb83ff3814964a659a7775dd3cf82 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Dec 2024 20:57:40 -0500 Subject: [PATCH 18/19] process SessionConfirmed in establisher's thread --- libi2pd/NTCP2.cpp | 248 +++++++++++++++++++++++++--------------------- libi2pd/NTCP2.h | 4 +- 2 files changed, 138 insertions(+), 114 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index cfc24e08..cbfbc84e 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -344,6 +344,7 @@ namespace transport m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), m_Establisher (new NTCP2Establisher), + m_SendKey (nullptr), m_ReceiveKey (nullptr), #if OPENSSL_SIPHASH m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), #else @@ -721,6 +722,7 @@ namespace transport void NTCP2Session::HandleSessionConfirmedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { + (void) bytes_transferred; if (ecode) { LogPrint (eLogWarning, "NTCP2: SessionConfirmed read error: ", ecode.message ()); @@ -729,123 +731,143 @@ namespace transport else { m_HandshakeInterval = i2p::util::GetMillisecondsSinceEpoch () - m_HandshakeInterval; - LogPrint (eLogDebug, "NTCP2: SessionConfirmed received"); - // part 1 - uint8_t nonce[12]; - CreateNonce (1, nonce); - if (m_Establisher->ProcessSessionConfirmedMessagePart1 (nonce)) - { - // part 2 - std::vector buf(m_Establisher->m3p2Len - 16); // -MAC - memset (nonce, 0, 12); // set nonce to 0 again - if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf.data ())) // TODO:handle in establisher thread + boost::asio::post (m_Server.GetEstablisherService (), + [s = shared_from_this ()] () { - // payload - // RI block must be first - if (buf[0] != eNTCP2BlkRouterInfo) - { - LogPrint (eLogWarning, "NTCP2: Unexpected block ", (int)buf[0], " in SessionConfirmed"); - Terminate (); - return; - } - auto size = bufbe16toh (buf.data () + 1); - if (size > buf.size () - 3 || size > i2p::data::MAX_RI_BUFFER_SIZE + 1) - { - LogPrint (eLogError, "NTCP2: Unexpected RouterInfo size ", size, " in SessionConfirmed"); - Terminate (); - return; - } - // TODO: check flag - i2p::data::RouterInfo ri (buf.data () + 4, size - 1); // 1 byte block type + 2 bytes size + 1 byte flag - if (ri.IsUnreachable ()) - { - LogPrint (eLogError, "NTCP2: RouterInfo verification failed in SessionConfirmed from ", GetRemoteEndpoint ()); - SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); - return; - } - LogPrint(eLogDebug, "NTCP2: SessionConfirmed from ", GetRemoteEndpoint (), - " (", i2p::data::GetIdentHashAbbreviation (ri.GetIdentHash ()), ")"); - auto ts = i2p::util::GetMillisecondsSinceEpoch (); - if (ts > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes - { - LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed for ", (ts - ri.GetTimestamp ())/1000LL, " seconds"); - SendTerminationAndTerminate (eNTCP2Message3Error); - return; - } - if (ts + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri.GetTimestamp ()) // 2 minutes - { - LogPrint (eLogError, "NTCP2: RouterInfo is from future for ", (ri.GetTimestamp () - ts)/1000LL, " seconds"); - SendTerminationAndTerminate (eNTCP2Message3Error); - return; - } - // update RouterInfo in netdb - auto ri1 = i2p::data::netdb.AddRouterInfo (ri.GetBuffer (), ri.GetBufferLen ()); // ri1 points to one from netdb now - if (!ri1) - { - LogPrint (eLogError, "NTCP2: Couldn't update RouterInfo from SessionConfirmed in netdb"); - Terminate (); - return; - } - std::shared_ptr profile; // not null if older - if (ri.GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ()) - { - // received RouterInfo is older than one in netdb - profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile - if (profile && profile->IsDuplicated ()) - { - SendTerminationAndTerminate (eNTCP2Banned); - return; - } - } - - auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri1->GetNTCP2V4Address () : - (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri1->GetYggdrasilAddress () : ri1->GetNTCP2V6Address ()); - if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32)) - { - LogPrint (eLogError, "NTCP2: Wrong static key in SessionConfirmed"); - Terminate (); - return; - } - if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && - (!m_RemoteEndpoint.address ().is_v6 () || (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? - memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet - memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address - { - if (profile) // older router? - profile->Duplicated (); // mark router as duplicated in profile - else - LogPrint (eLogInfo, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); - SendTerminationAndTerminate (eNTCP2Banned); - return; - } - // TODO: process options block - - // ready to communicate - SetRemoteIdentity (ri1->GetRouterIdentity ()); - if (m_Server.AddNTCP2Session (shared_from_this (), true)) - { - KeyDerivationFunctionDataPhase (); - // Bob data phase keys - m_SendKey = m_Kba; - m_ReceiveKey = m_Kab; - SetSipKeys (m_Sipkeysba, m_Sipkeysab); - memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); - memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); - - Established (); - ReceiveLength (); - } - else - Terminate (); - } - else - Terminate (); - } - else - Terminate (); + s->ProcessSessionConfirmed ();; + }); } } + void NTCP2Session::ProcessSessionConfirmed () + { + // run on establisher thread + LogPrint (eLogDebug, "NTCP2: SessionConfirmed received"); + // part 1 + uint8_t nonce[12]; + CreateNonce (1, nonce); + if (m_Establisher->ProcessSessionConfirmedMessagePart1 (nonce)) + { + // part 2 + auto buf = std::make_shared > (m_Establisher->m3p2Len - 16); // -MAC + memset (nonce, 0, 12); // set nonce to 0 again + if (m_Establisher->ProcessSessionConfirmedMessagePart2 (nonce, buf->data ())) // TODO:handle in establisher thread + { + // payload + // RI block must be first + if ((*buf)[0] != eNTCP2BlkRouterInfo) + { + LogPrint (eLogWarning, "NTCP2: Unexpected block ", (int)(*buf)[0], " in SessionConfirmed"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + return; + } + auto size = bufbe16toh (buf->data () + 1); + if (size > buf->size () - 3 || size > i2p::data::MAX_RI_BUFFER_SIZE + 1) + { + LogPrint (eLogError, "NTCP2: Unexpected RouterInfo size ", size, " in SessionConfirmed"); + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + return; + } + boost::asio::post (m_Server.GetService (), + [s = shared_from_this (), buf, size] () + { + s->EstablishSessionAfterSessionConfirmed (buf, size); + }); + } + else + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + else + boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::Terminate, shared_from_this ())); + } + + void NTCP2Session::EstablishSessionAfterSessionConfirmed (std::shared_ptr > buf, size_t size) + { + // run on main NTCP2 thread + KeyDerivationFunctionDataPhase (); + // Bob data phase keys + m_SendKey = m_Kba; + m_ReceiveKey = m_Kab; + SetSipKeys (m_Sipkeysba, m_Sipkeysab); + memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); + memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); + // we need to set keys for SendTerminationAndTerminate + // TODO: check flag + i2p::data::RouterInfo ri (buf->data () + 4, size - 1); // 1 byte block type + 2 bytes size + 1 byte flag + if (ri.IsUnreachable ()) + { + LogPrint (eLogError, "NTCP2: RouterInfo verification failed in SessionConfirmed from ", GetRemoteEndpoint ()); + SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); + return; + } + LogPrint(eLogDebug, "NTCP2: SessionConfirmed from ", GetRemoteEndpoint (), + " (", i2p::data::GetIdentHashAbbreviation (ri.GetIdentHash ()), ")"); + auto ts = i2p::util::GetMillisecondsSinceEpoch (); + if (ts > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes + { + LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed for ", (ts - ri.GetTimestamp ())/1000LL, " seconds"); + SendTerminationAndTerminate (eNTCP2Message3Error); + return; + } + if (ts + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri.GetTimestamp ()) // 2 minutes + { + LogPrint (eLogError, "NTCP2: RouterInfo is from future for ", (ri.GetTimestamp () - ts)/1000LL, " seconds"); + SendTerminationAndTerminate (eNTCP2Message3Error); + return; + } + // update RouterInfo in netdb + auto ri1 = i2p::data::netdb.AddRouterInfo (ri.GetBuffer (), ri.GetBufferLen ()); // ri1 points to one from netdb now + if (!ri1) + { + LogPrint (eLogError, "NTCP2: Couldn't update RouterInfo from SessionConfirmed in netdb"); + Terminate (); + return; + } + std::shared_ptr profile; // not null if older + if (ri.GetTimestamp () + i2p::data::NETDB_EXPIRATION_TIMEOUT_THRESHOLD*1000LL < ri1->GetTimestamp ()) + { + // received RouterInfo is older than one in netdb + profile = i2p::data::GetRouterProfile (ri1->GetIdentHash ()); // retrieve profile + if (profile && profile->IsDuplicated ()) + { + SendTerminationAndTerminate (eNTCP2Banned); + return; + } + } + + auto addr = m_RemoteEndpoint.address ().is_v4 () ? ri1->GetNTCP2V4Address () : + (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? ri1->GetYggdrasilAddress () : ri1->GetNTCP2V6Address ()); + if (!addr || memcmp (m_Establisher->m_RemoteStaticKey, addr->s, 32)) + { + LogPrint (eLogError, "NTCP2: Wrong static key in SessionConfirmed"); + Terminate (); + return; + } + if (addr->IsPublishedNTCP2 () && m_RemoteEndpoint.address () != addr->host && + (!m_RemoteEndpoint.address ().is_v6 () || (i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data () + 1, addr->host.to_v6 ().to_bytes ().data () + 1, 7) : // from the same yggdrasil subnet + memcmp (m_RemoteEndpoint.address ().to_v6 ().to_bytes ().data (), addr->host.to_v6 ().to_bytes ().data (), 8)))) // temporary address + { + if (profile) // older router? + profile->Duplicated (); // mark router as duplicated in profile + else + LogPrint (eLogInfo, "NTCP2: Host mismatch between published address ", addr->host, " and actual endpoint ", m_RemoteEndpoint.address ()); + SendTerminationAndTerminate (eNTCP2Banned); + return; + } + // TODO: process options block + + // ready to communicate + SetRemoteIdentity (ri1->GetRouterIdentity ()); + if (m_Server.AddNTCP2Session (shared_from_this (), true)) + { + Established (); + ReceiveLength (); + } + else + Terminate (); + } + void NTCP2Session::SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey) { #if OPENSSL_SIPHASH diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index f0cee06a..108c58f6 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -180,7 +180,9 @@ namespace transport void HandleSessionCreatedPaddingReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionConfirmedSent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleSessionConfirmedReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); - + void ProcessSessionConfirmed (); + void EstablishSessionAfterSessionConfirmed (std::shared_ptr > buf, size_t size); + // data void ReceiveLength (); void HandleReceivedLength (const boost::system::error_code& ecode, std::size_t bytes_transferred); From 13604ccbb60bb3ef38125db3df5d1d6bad7b0985 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Dec 2024 22:15:11 -0500 Subject: [PATCH 19/19] Changing the window calculation algorithm, increasing the minimum window size --- libi2pd/Streaming.cpp | 28 ++++++++++++++++++++-------- libi2pd/Streaming.h | 4 +++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index efa190cf..7a0a39a4 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -73,7 +73,7 @@ namespace stream m_LastConfirmedReceivedSequenceNumber (0), // for limit inbound speed m_Status (eStreamStatusNew), m_IsIncoming (false), m_IsAckSendScheduled (false), m_IsNAcked (false), m_IsFirstACK (false), m_IsResendNeeded (false), m_IsFirstRttSample (false), m_IsSendTime (true), m_IsWinDropped (false), - m_IsTimeOutResend (false), m_IsImmediateAckRequested (false), m_IsRemoteLeaseChangeInProgress (false), m_LocalDestination (local), + m_IsTimeOutResend (false), m_IsImmediateAckRequested (false), m_IsRemoteLeaseChangeInProgress (false), m_DoubleWinIncCounter (false), m_LocalDestination (local), m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_SendTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port), m_RTT (INITIAL_RTT), m_SlowRTT (INITIAL_RTT), m_SlowRTT2 (INITIAL_RTT), m_WindowSize (INITIAL_WINDOW_SIZE), m_LastWindowDropSize (0), @@ -101,7 +101,7 @@ namespace stream m_LastConfirmedReceivedSequenceNumber (0), // for limit inbound speed m_Status (eStreamStatusNew), m_IsIncoming (true), m_IsAckSendScheduled (false), m_IsNAcked (false), m_IsFirstACK (false), m_IsResendNeeded (false), m_IsFirstRttSample (false), m_IsSendTime (true), m_IsWinDropped (false), - m_IsTimeOutResend (false), m_IsImmediateAckRequested (false), m_IsRemoteLeaseChangeInProgress (false), m_LocalDestination (local), + m_IsTimeOutResend (false), m_IsImmediateAckRequested (false), m_IsRemoteLeaseChangeInProgress (false), m_DoubleWinIncCounter (false), m_LocalDestination (local), m_ReceiveTimer (m_Service), m_SendTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_RTT (INITIAL_RTT), m_SlowRTT (INITIAL_RTT), m_SlowRTT2 (INITIAL_RTT), m_WindowSize (INITIAL_WINDOW_SIZE), m_LastWindowDropSize (0), m_WindowDropTargetSize (0), m_WindowIncCounter (0), @@ -495,6 +495,7 @@ namespace stream return; } int rttSample = INT_MAX; + int incCounter = 0; m_IsNAcked = false; m_IsResendNeeded = false; int nackCount = packet->GetNACKCount (); @@ -537,8 +538,7 @@ namespace stream m_LocalDestination.DeletePacket (sentPacket); acknowledged = true; if (m_WindowSize < MAX_WINDOW_SIZE && !m_IsFirstACK) - if (m_RTT < m_LocalDestination.GetRandom () % INITIAL_RTO) // dirty - m_WindowIncCounter++; + incCounter++; } else break; @@ -552,7 +552,7 @@ namespace stream m_SlowRTT2 = rttSample; m_PrevRTTSample = rttSample; m_Jitter = rttSample / 10; // 10% - m_Jitter += 5; // for low-latency connections + m_Jitter += 15; // for low-latency connections m_IsFirstRttSample = false; } else @@ -569,9 +569,23 @@ namespace stream jitter = m_PrevRTTSample - rttSample; else jitter = rttSample / 10; // 10% - jitter += 5; // for low-latency connections + jitter += 15; // for low-latency connections m_Jitter = (0.05 * jitter) + (1.0 - 0.05) * m_Jitter; } + if (rttSample > m_SlowRTT) + { + incCounter = 0; + m_DoubleWinIncCounter = 1; + } + else if (rttSample < m_SlowRTT) + { + if (m_DoubleWinIncCounter) + { + incCounter = incCounter * 2; + m_DoubleWinIncCounter = 0; + } + } + m_WindowIncCounter = m_WindowIncCounter + incCounter; // // delay-based CC if ((m_SlowRTT2 > m_SlowRTT + m_Jitter && rttSample > m_SlowRTT2 && rttSample > m_PrevRTTSample) && !m_IsWinDropped) // Drop window if RTT grows too fast, late detection @@ -1297,8 +1311,6 @@ namespace stream else if (m_IsResendNeeded) // resend packets ResendPacket (); // delay-based CC - else if (!m_IsWinDropped && int(m_SentPackets.size ()) == m_WindowSize) // we sending packets too fast, early detection - ProcessWindowDrop (); else if (m_WindowSize > int(m_SentPackets.size ())) // send packets SendBuffer (); } diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index e5dba39f..36c13eff 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -19,6 +19,7 @@ #include #include #include "Base.h" +#include "Gzip.h" #include "I2PEndian.h" #include "Identity.h" #include "LeaseSet.h" @@ -54,7 +55,7 @@ namespace stream const size_t COMPRESSION_THRESHOLD_SIZE = 66; const int MAX_NUM_RESEND_ATTEMPTS = 10; const int INITIAL_WINDOW_SIZE = 10; - const int MIN_WINDOW_SIZE = 2; + const int MIN_WINDOW_SIZE = 3; const int MAX_WINDOW_SIZE = 512; const double RTT_EWMA_ALPHA = 0.25; const double SLOWRTT_EWMA_ALPHA = 0.05; @@ -274,6 +275,7 @@ namespace stream bool m_IsTimeOutResend; bool m_IsImmediateAckRequested; bool m_IsRemoteLeaseChangeInProgress; + bool m_DoubleWinIncCounter; StreamingDestination& m_LocalDestination; std::shared_ptr m_RemoteIdentity; std::shared_ptr m_TransientVerifier; // in case of offline key