Merge pull request #1149 from majestrate/fix-ntcp-threading-race

Fix ntcp threading race
pull/1154/head
orignal 6 years ago committed by GitHub
commit 479edaf80d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -24,6 +24,12 @@ namespace i2p
{ {
namespace transport namespace transport
{ {
struct NTCPWork
{
std::shared_ptr<NTCPSession> session;
};
NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter): NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT), TransportSession (in_RemoteRouter, NTCP_ESTABLISH_TIMEOUT),
m_Server (server), m_Socket (m_Server.GetService ()), m_Server (server), m_Socket (m_Server.GetService ()),
@ -177,19 +183,20 @@ namespace transport
} }
} }
// TODO: check for number of pending keys // TODO: check for number of pending keys
auto s = shared_from_this (); auto work = new NTCPWork{shared_from_this()};
// TODO: we need to pass this for gcc 4.7, should be removed later on m_Server.Work(work->session, [work, this]() -> std::function<void(void)> {
m_Server.Work(s, [s, this]() -> std::function<void(void)> { if (!work->session->m_DHKeysPair)
if (!s->m_DHKeysPair) work->session->m_DHKeysPair = transports.GetNextDHKeysPair ();
s->m_DHKeysPair = transports.GetNextDHKeysPair (); work->session->CreateAESKey (work->session->m_Establisher->phase1.pubKey);
s->CreateAESKey (s->m_Establisher->phase1.pubKey); return std::bind(&NTCPSession::SendPhase2, work->session, work);
return std::bind(&NTCPSession::SendPhase2, s);
}); });
} }
} }
void NTCPSession::SendPhase2 () void NTCPSession::SendPhase2 (NTCPWork * work)
{ {
if(work)
delete work;
const uint8_t * y = m_DHKeysPair->GetPublicKey (); const uint8_t * y = m_DHKeysPair->GetPublicKey ();
memcpy (m_Establisher->phase2.pubKey, y, 256); memcpy (m_Establisher->phase2.pubKey, y, 256);
uint8_t xy[512]; uint8_t xy[512];
@ -242,17 +249,17 @@ namespace transport
} }
else else
{ {
auto s = shared_from_this (); auto work = new NTCPWork{shared_from_this()};
// TODO: we need to pass this for gcc 4.7, should be removed later on m_Server.Work(work->session, [work, this]() -> std::function<void(void)> {
m_Server.Work(s, [s, this]() -> std::function<void(void)> { work->session->CreateAESKey (work->session->m_Establisher->phase2.pubKey);
s->CreateAESKey (s->m_Establisher->phase2.pubKey); return std::bind(&NTCPSession::HandlePhase2, work->session, work);
return std::bind(&NTCPSession::HandlePhase2, s);
}); });
} }
} }
void NTCPSession::HandlePhase2 () void NTCPSession::HandlePhase2 (NTCPWork * work)
{ {
if(work) delete work;
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16);

@ -35,6 +35,8 @@ namespace transport
} encrypted; } encrypted;
}; };
struct NTCPWork;
const size_t NTCP_MAX_MESSAGE_SIZE = 16384; const size_t NTCP_MAX_MESSAGE_SIZE = 16384;
const size_t NTCP_BUFFER_SIZE = 1028; // fits 1 tunnel data message const size_t NTCP_BUFFER_SIZE = 1028; // fits 1 tunnel data message
const int NTCP_CONNECT_TIMEOUT = 5; // 5 seconds const int NTCP_CONNECT_TIMEOUT = 5; // 5 seconds
@ -77,12 +79,12 @@ namespace transport
void SendPhase3 (); void SendPhase3 ();
void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2 (); void HandlePhase2 (NTCPWork * work=nullptr);
void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
//server //server
void SendPhase2 (); void SendPhase2 (NTCPWork * work=nullptr);
void SendPhase4 (uint32_t tsA, uint32_t tsB); void SendPhase4 (uint32_t tsA, uint32_t tsB);
void HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB); void HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB);

Loading…
Cancel
Save