diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index ef7c7d21..adc4d1ea 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,10 +13,12 @@ namespace i2p { namespace client { - LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map * params): - m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), - m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), - m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), + LeaseSetDestination::LeaseSetDestination (std::shared_ptr service, bool isPublic, const std::map * params): + m_IsRunning (false), m_Thread (nullptr), + m_Service(std::move(service)), + m_IsPublic (isPublic), + m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (*m_Service), + m_PublishVerificationTimer (*m_Service), m_PublishDelayTimer (*m_Service), m_CleanupTimer (*m_Service), m_LeaseSetType (DEFAULT_LEASESET_TYPE) { int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH; @@ -124,7 +126,7 @@ namespace client { try { - m_Service.run (); + m_Service->run (); } catch (std::exception& ex) { @@ -168,7 +170,7 @@ namespace client m_Pool->SetLocalDestination (nullptr); i2p::tunnel::tunnels.StopTunnelPool (m_Pool); } - m_Service.stop (); + m_Service->stop (); if (m_Thread) { m_Thread->join (); @@ -302,7 +304,7 @@ namespace client if (m_IsPublic) { auto s = shared_from_this (); - m_Service.post ([s](void) + m_Service->post ([s](void) { s->m_PublishVerificationTimer.cancel (); s->Publish (); @@ -326,7 +328,7 @@ namespace client memcpy (data.k, key, 32); memcpy (data.t, tag, 32); auto s = shared_from_this (); - m_Service.post ([s,data](void) + m_Service->post ([s,data](void) { s->AddSessionKey (data.k, data.t); }); @@ -335,12 +337,12 @@ namespace client void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); + m_Service->post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); } void LeaseSetDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); + m_Service->post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); } void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) @@ -646,10 +648,10 @@ namespace client if (!m_Pool || !IsReady ()) { if (requestComplete) - m_Service.post ([requestComplete](void){requestComplete (nullptr);}); + m_Service->post ([requestComplete](void){requestComplete (nullptr);}); return false; } - m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete, nullptr)); + m_Service->post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete, nullptr)); return true; } @@ -658,7 +660,7 @@ namespace client if (!dest || !m_Pool || !IsReady ()) { if (requestComplete) - m_Service.post ([requestComplete](void){requestComplete (nullptr);}); + m_Service->post ([requestComplete](void){requestComplete (nullptr);}); return false; } auto storeHash = dest->GetStoreHash (); @@ -666,17 +668,17 @@ namespace client if (leaseSet) { if (requestComplete) - m_Service.post ([requestComplete, leaseSet](void){requestComplete (leaseSet);}); + m_Service->post ([requestComplete, leaseSet](void){requestComplete (leaseSet);}); return true; } - m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), storeHash, requestComplete, dest)); + m_Service->post (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) + m_Service->post ([dest, notify, s](void) { auto it = s->m_LeaseSetRequests.find (dest); if (it != s->m_LeaseSetRequests.end ()) @@ -700,7 +702,7 @@ namespace client auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, excluded); if (floodfill) { - auto request = std::make_shared (m_Service); + auto request = std::make_shared (GetService()); request->requestedBlindedKey = requestedBlindedKey; // for encrypted LeaseSet2 if (requestComplete) request->requestComplete.push_back (requestComplete); @@ -843,8 +845,8 @@ namespace client } } - ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): - LeaseSetDestination (isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), + ClientDestination::ClientDestination (std::shared_ptr ioc, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): + LeaseSetDestination (std::move(ioc), isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 35a9dbae..4e4ebef0 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -95,7 +95,9 @@ namespace client public: - LeaseSetDestination (bool isPublic, const std::map * params = nullptr); + LeaseSetDestination (std::shared_ptr service, bool isPublic, const std::map * params = nullptr); + LeaseSetDestination (bool isPublic, const std::map * params = nullptr) : + LeaseSetDestination(std::make_shared(), isPublic, params) {}; ~LeaseSetDestination (); const std::string& GetNickname () const { return m_Nickname; }; @@ -106,7 +108,7 @@ namespace client virtual bool Reconfigure(std::map i2cpOpts); bool IsRunning () const { return m_IsRunning; }; - boost::asio::io_service& GetService () { return m_Service; }; + boost::asio::io_service& GetService () { return *m_Service; }; std::shared_ptr GetTunnelPool () { return m_Pool; }; bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; }; std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); @@ -159,7 +161,7 @@ namespace client volatile bool m_IsRunning; std::thread * m_Thread; - boost::asio::io_service m_Service; + std::shared_ptr m_Service; mutable std::mutex m_RemoteLeaseSetsMutex; std::map > m_RemoteLeaseSets; std::map > m_LeaseSetRequests; @@ -196,8 +198,9 @@ namespace client // if cancelled before ready, informs promise with nullptr void Ready(ReadyPromise & p); #endif - - ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); + ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr) : + ClientDestination(std::make_shared(), keys, isPublic, params) {}; + ClientDestination (std::shared_ptr service, const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params = nullptr); ~ClientDestination (); virtual bool Start (); diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c286007c..4515e347 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -312,6 +312,18 @@ namespace client return localDestination; } + std::shared_ptr ClientContext::CreateNewSAMDestination (std::shared_ptr ioctx, bool isPublic, + i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType, + const std::map * params) + { + i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType); + auto localDestination = std::make_shared (keys, isPublic, params); + std::unique_lock l(m_DestinationsMutex); + m_Destinations[localDestination->GetIdentHash ()] = localDestination; + localDestination->Start (); + return localDestination; + } + std::shared_ptr ClientContext::CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map * params) { MatchedTunnelDestination * cl = new MatchedTunnelDestination(keys, name, params); @@ -337,6 +349,23 @@ namespace client } } + std::shared_ptr ClientContext::CreateNewSAMDestination (std::shared_ptr ioctx, const i2p::data::PrivateKeys& keys, bool isPublic, + const std::map * params) + { + auto it = m_Destinations.find (keys.GetPublic ()->GetIdentHash ()); + if (it != m_Destinations.end ()) + { + LogPrint (eLogWarning, "Clients: Local destination ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " exists, removing it"); + it->second->Stop(); + m_Destinations.erase(it); + } + auto localDestination = std::make_shared (ioctx, keys, isPublic, params); + std::unique_lock l(m_DestinationsMutex); + m_Destinations[keys.GetPublic ()->GetIdentHash ()] = localDestination; + localDestination->Start (); + return localDestination; + } + std::shared_ptr ClientContext::CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params) { diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 71e052c3..3442bbb5 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -64,10 +64,15 @@ namespace client void ReloadConfig (); std::shared_ptr GetSharedLocalDestination () const { return m_SharedLocalDestination; }; - std::shared_ptr CreateNewLocalDestination (bool isPublic = false, // transient + std::shared_ptr CreateNewLocalDestination (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); + std::shared_ptr CreateNewSAMDestination (std::shared_ptr ioctx, 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); // used by SAM only + const std::map * params = nullptr); + std::shared_ptr CreateNewSAMDestination (std::shared_ptr ioctx, const i2p::data::PrivateKeys& keys, bool isPublic = true, + const std::map * params = nullptr); std::shared_ptr CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true, const std::map * params = nullptr); std::shared_ptr CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map * params = nullptr); diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 224d84e8..d7ed1d03 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1001,8 +1001,9 @@ namespace client SAMBridge::SAMBridge (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_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint), + m_Service(std::make_shared()), + m_Acceptor (*m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), + m_DatagramEndpoint (boost::asio::ip::address::from_string(address), port-1), m_DatagramSocket (*m_Service, m_DatagramEndpoint), m_SignatureTypes { {"DSA_SHA1", i2p::data::SIGNING_KEY_TYPE_DSA_SHA1}, @@ -1046,7 +1047,7 @@ namespace client for (auto& it: m_Sessions) it.second->CloseStreams (); m_Sessions.clear (); - m_Service.stop (); + m_Service->stop (); if (m_Thread) { m_Thread->join (); @@ -1061,7 +1062,7 @@ namespace client { try { - m_Service.run (); + m_Service->run (); } catch (std::exception& ex) { @@ -1116,7 +1117,7 @@ namespace client { i2p::data::PrivateKeys keys; if (!keys.FromBase64 (destination)) return nullptr; - localDestination = i2p::client::context.CreateNewLocalDestination (keys, true, params); + localDestination = i2p::client::context.CreateNewSAMDestination (m_Service, keys, true, params); } else // transient { @@ -1144,7 +1145,7 @@ namespace client } } } - localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); + localDestination = i2p::client::context.CreateNewSAMDestination (m_Service, true, signatureType, cryptoType, params); } if (localDestination) { diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index aebdccb6..00981ecd 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -184,7 +184,7 @@ namespace client void Start (); void Stop (); - boost::asio::io_service& GetService () { return m_Service; }; + boost::asio::io_service& GetService () { return *m_Service; }; std::shared_ptr CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); @@ -213,7 +213,7 @@ namespace client bool m_IsRunning; std::thread * m_Thread; - boost::asio::io_service m_Service; + std::shared_ptr m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::socket m_DatagramSocket;