From 393d4bc23139644312a383c68030a0dabed348bd Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 24 Sep 2014 16:39:31 -0400 Subject: [PATCH] create SAM session --- SAM.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++- SAM.h | 12 ++++++++++++ Streaming.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ Streaming.h | 7 +++++++ 4 files changed, 119 insertions(+), 1 deletion(-) diff --git a/SAM.cpp b/SAM.cpp index 1e4238c9..0a81e305 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -1,5 +1,6 @@ #include #include +#include "base64.h" #include "Log.h" #include "SAM.h" @@ -14,7 +15,11 @@ namespace stream SAMSocket::~SAMSocket () { - delete m_Stream; + if (m_Stream) + { + m_Stream->Close (); + delete m_Stream; + } } void SAMSocket::Terminate () @@ -201,5 +206,47 @@ namespace stream if (ecode != boost::asio::error::operation_aborted) Accept (); } + + bool SAMBridge::CreateSession (const std::string& id, const char * destination, size_t len) + { + if (m_Sessions.find (id) != m_Sessions.end ()) // session exists + return false; + + StreamingDestination * localDestination = nullptr; + if (destination) + { + uint8_t * buf = new uint8_t[len]; + size_t l = i2p::data::Base64ToByteStream (destination, len, buf, len); + i2p::data::PrivateKeys keys; + keys.FromBuffer (buf, l); + delete[] buf; + localDestination = GetLocalDestination (keys); + } + else // transient + localDestination = CreateNewLocalDestination (); + if (localDestination) + { + SAMSession session; + session.localDestination = localDestination; + session.isTransient = !destination; + m_Sessions[id] = session; + return true; + } + return false; + } + + void SAMBridge::CloseSession (const std::string& id) + { + auto it = m_Sessions.find (id); + if (it != m_Sessions.end ()) + { + for (auto it1 : it->second.sockets) + delete it1; + it->second.sockets.clear (); + if (it->second.isTransient) + DeleteLocalDestination (it->second.localDestination); + m_Sessions.erase (it); + } + } } } diff --git a/SAM.h b/SAM.h index 9a22a0b7..bf59425f 100644 --- a/SAM.h +++ b/SAM.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include "Streaming.h" @@ -48,6 +50,13 @@ namespace stream Stream * m_Stream; }; + struct SAMSession + { + StreamingDestination * localDestination; + std::list sockets; + bool isTransient; + }; + class SAMBridge { public: @@ -59,6 +68,8 @@ namespace stream void Stop (); boost::asio::io_service& GetService () { return m_Service; }; + bool CreateSession (const std::string& id, const char * destination = nullptr, size_t len = 0); // null means transient + void CloseSession (const std::string& id); private: @@ -74,6 +85,7 @@ namespace stream boost::asio::io_service m_Service; boost::asio::ip::tcp::acceptor m_Acceptor; SAMSocket * m_NewSocket; + std::map m_Sessions; }; } } diff --git a/Streaming.cpp b/Streaming.cpp index a51b6909..166d5535 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -551,8 +551,17 @@ namespace stream m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this, 3); // 3-hops tunnel } + StreamingDestination::StreamingDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys): + m_Service (service), m_Keys (keys), m_LeaseSet (nullptr), m_IsPublic (false) + { + CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); + dh.GenerateKeyPair(i2p::context.GetRandomNumberGenerator (), m_EncryptionPrivateKey, m_EncryptionPublicKey); + m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this, 3); // 3-hops tunnel + } + StreamingDestination::~StreamingDestination () { + // TODO: delete streams if (m_Pool) i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); delete m_LeaseSet; @@ -701,6 +710,34 @@ namespace stream return localDestination; } + StreamingDestination * StreamingDestinations::CreateNewLocalDestination () + { + auto localDestination = new StreamingDestination (m_Service); + m_Destinations[localDestination->GetIdentHash ()] = localDestination; + return localDestination; + } + + void StreamingDestinations::DeleteLocalDestination (StreamingDestination * destination) + { + if (!destination) return; + auto it = m_Destinations.find (destination->GetIdentHash ()); + if (it != m_Destinations.end ()) + { + delete it->second; + m_Destinations.erase (it); + } + } + + StreamingDestination * StreamingDestinations::GetLocalDestination (const i2p::data::PrivateKeys& keys) + { + auto it = m_Destinations.find (keys.GetPublic ().GetIdentHash ()); + if (it != m_Destinations.end ()) + return it->second; + auto localDestination = new StreamingDestination (m_Service, keys); + m_Destinations[keys.GetPublic ().GetIdentHash ()] = localDestination; + return localDestination; + } + Stream * StreamingDestinations::CreateClientStream (const i2p::data::LeaseSet& remote) { if (!m_SharedLocalDestination) return nullptr; @@ -770,6 +807,21 @@ namespace stream return destinations.GetSharedLocalDestination (); } + StreamingDestination * CreateNewLocalDestination () + { + return destinations.CreateNewLocalDestination (); + } + + void DeleteLocalDestination (StreamingDestination * destination) + { + destinations.DeleteLocalDestination (destination); + } + + StreamingDestination * GetLocalDestination (const i2p::data::PrivateKeys& keys) + { + return destinations.GetLocalDestination (keys); + } + StreamingDestination * FindLocalDestination (const i2p::data::IdentHash& destination) { return destinations.FindLocalDestination (destination); diff --git a/Streaming.h b/Streaming.h index 5b8ad08a..977246d2 100644 --- a/Streaming.h +++ b/Streaming.h @@ -143,6 +143,7 @@ namespace stream StreamingDestination (boost::asio::io_service& service); StreamingDestination (boost::asio::io_service& service, const std::string& fullPath); + StreamingDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys); ~StreamingDestination (); const i2p::data::LeaseSet * GetLeaseSet (); @@ -194,6 +195,9 @@ namespace stream Stream * CreateClientStream (const i2p::data::LeaseSet& remote); void DeleteStream (Stream * stream); StreamingDestination * GetSharedLocalDestination () const { return m_SharedLocalDestination; }; + StreamingDestination * CreateNewLocalDestination (); + void DeleteLocalDestination (StreamingDestination * destination); + StreamingDestination * GetLocalDestination (const i2p::data::PrivateKeys& keys); StreamingDestination * FindLocalDestination (const i2p::data::IdentHash& destination) const; StreamingDestination * LoadLocalDestination (const std::string& filename); @@ -219,6 +223,9 @@ namespace stream void StartStreaming (); void StopStreaming (); StreamingDestination * GetSharedLocalDestination (); + StreamingDestination * CreateNewLocalDestination (); + void DeleteLocalDestination (StreamingDestination * destination); + StreamingDestination * GetLocalDestination (const i2p::data::PrivateKeys& keys); StreamingDestination * FindLocalDestination (const i2p::data::IdentHash& destination); StreamingDestination * LoadLocalDestination (const std::string& filename);