|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2021, The PurpleI2P Project |
|
|
|
* Copyright (c) 2013-2022, The PurpleI2P Project |
|
|
|
* |
|
|
|
* |
|
|
|
* This file is part of Purple i2pd project and licensed under BSD3 |
|
|
|
* This file is part of Purple i2pd project and licensed under BSD3 |
|
|
|
* |
|
|
|
* |
|
|
@ -519,21 +519,26 @@ namespace client |
|
|
|
void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len) |
|
|
|
void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
RAND_bytes ((uint8_t *)&m_SessionID, 2); |
|
|
|
RAND_bytes ((uint8_t *)&m_SessionID, 2); |
|
|
|
m_Owner.InsertSession (shared_from_this ()); |
|
|
|
|
|
|
|
auto identity = std::make_shared<i2p::data::IdentityEx>(); |
|
|
|
auto identity = std::make_shared<i2p::data::IdentityEx>(); |
|
|
|
size_t offset = identity->FromBuffer (buf, len); |
|
|
|
size_t offset = identity->FromBuffer (buf, len); |
|
|
|
if (!offset) |
|
|
|
if (!offset) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogError, "I2CP: Create session malformed identity"); |
|
|
|
LogPrint (eLogError, "I2CP: Create session malformed identity"); |
|
|
|
SendSessionStatusMessage (3); // invalid
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (m_Owner.FindSessionByIdentHash (identity->GetIdentHash ())) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ()); |
|
|
|
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
uint16_t optionsSize = bufbe16toh (buf + offset); |
|
|
|
uint16_t optionsSize = bufbe16toh (buf + offset); |
|
|
|
offset += 2; |
|
|
|
offset += 2; |
|
|
|
if (optionsSize > len - offset) |
|
|
|
if (optionsSize > len - offset) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogError, "I2CP: Options size ", optionsSize, "exceeds message size"); |
|
|
|
LogPrint (eLogError, "I2CP: Options size ", optionsSize, "exceeds message size"); |
|
|
|
SendSessionStatusMessage (3); // invalid
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
std::map<std::string, std::string> params; |
|
|
|
std::map<std::string, std::string> params; |
|
|
@ -549,33 +554,41 @@ namespace client |
|
|
|
m_Destination = m_Owner.IsSingleThread () ? |
|
|
|
m_Destination = m_Owner.IsSingleThread () ? |
|
|
|
std::make_shared<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params): |
|
|
|
std::make_shared<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params): |
|
|
|
std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params); |
|
|
|
std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params); |
|
|
|
SendSessionStatusMessage (1); // created
|
|
|
|
if (m_Owner.InsertSession (shared_from_this ())) |
|
|
|
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created"); |
|
|
|
{ |
|
|
|
m_Destination->Start (); |
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusCreated); // created
|
|
|
|
|
|
|
|
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created"); |
|
|
|
|
|
|
|
m_Destination->Start (); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogError, "I2CP: Session already exists"); |
|
|
|
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusRefused); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogError, "I2CP: Session already exists"); |
|
|
|
LogPrint (eLogError, "I2CP: Session already exists"); |
|
|
|
SendSessionStatusMessage (4); // refused
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusRefused); // refused
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogError, "I2CP: Create session signature verification failed"); |
|
|
|
LogPrint (eLogError, "I2CP: Create session signature verification failed"); |
|
|
|
SendSessionStatusMessage (3); // invalid
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void I2CPSession::DestroySessionMessageHandler (const uint8_t * buf, size_t len) |
|
|
|
void I2CPSession::DestroySessionMessageHandler (const uint8_t * buf, size_t len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
SendSessionStatusMessage (0); // destroy
|
|
|
|
SendSessionStatusMessage (eI2CPSessionStatusDestroyed); // destroy
|
|
|
|
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " destroyed"); |
|
|
|
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " destroyed"); |
|
|
|
Terminate (); |
|
|
|
Terminate (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len) |
|
|
|
void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t status = 3; // rejected
|
|
|
|
I2CPSessionStatus status = eI2CPSessionStatusInvalid; // rejected
|
|
|
|
if(len > sizeof(uint16_t)) |
|
|
|
if(len > sizeof(uint16_t)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint16_t sessionID = bufbe16toh(buf); |
|
|
|
uint16_t sessionID = bufbe16toh(buf); |
|
|
@ -605,7 +618,7 @@ namespace client |
|
|
|
if(m_Destination->Reconfigure(opts)) |
|
|
|
if(m_Destination->Reconfigure(opts)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint(eLogInfo, "I2CP: Reconfigured destination"); |
|
|
|
LogPrint(eLogInfo, "I2CP: Reconfigured destination"); |
|
|
|
status = 2; // updated
|
|
|
|
status = eI2CPSessionStatusUpdated; // updated
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
LogPrint(eLogWarning, "I2CP: Failed to reconfigure destination"); |
|
|
|
LogPrint(eLogWarning, "I2CP: Failed to reconfigure destination"); |
|
|
@ -630,11 +643,11 @@ namespace client |
|
|
|
SendSessionStatusMessage (status); |
|
|
|
SendSessionStatusMessage (status); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void I2CPSession::SendSessionStatusMessage (uint8_t status) |
|
|
|
void I2CPSession::SendSessionStatusMessage (I2CPSessionStatus status) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t buf[3]; |
|
|
|
uint8_t buf[3]; |
|
|
|
htobe16buf (buf, m_SessionID); |
|
|
|
htobe16buf (buf, m_SessionID); |
|
|
|
buf[2] = status; |
|
|
|
buf[2] = (uint8_t)status; |
|
|
|
SendI2CPMessage (I2CP_SESSION_STATUS_MESSAGE, buf, 3); |
|
|
|
SendI2CPMessage (I2CP_SESSION_STATUS_MESSAGE, buf, 3); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1009,5 +1022,19 @@ namespace client |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_Sessions.erase (sessionID); |
|
|
|
m_Sessions.erase (sessionID); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<I2CPSession> I2CPServer::FindSessionByIdentHash (const i2p::data::IdentHash& ident) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
for (const auto& it: m_Sessions) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (it.second) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto dest = it.second->GetDestination (); |
|
|
|
|
|
|
|
if (dest && dest->GetIdentHash () == ident) |
|
|
|
|
|
|
|
return it.second; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|