check for duplicate destination

pull/1727/head
orignal 3 years ago
parent 5a35de8dc9
commit afad405ed9

@ -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,13 +519,18 @@ 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;
}
if (m_Owner.FindSessionByIdentHash (identity->GetIdentHash ()))
{
LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ());
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
return; return;
} }
uint16_t optionsSize = bufbe16toh (buf + offset); uint16_t optionsSize = bufbe16toh (buf + offset);
@ -533,7 +538,7 @@ namespace client
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;
}
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2020, 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
* *
@ -61,6 +61,15 @@ namespace client
eI2CPMessageStatusNoLeaseSet = 21 eI2CPMessageStatusNoLeaseSet = 21
}; };
enum I2CPSessionStatus
{
eI2CPSessionStatusDestroyed = 0,
eI2CPSessionStatusCreated = 1,
eI2CPSessionStatusUpdated = 2,
eI2CPSessionStatusInvalid = 3,
eI2CPSessionStatusRefused = 4
};
// params // params
const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability";
@ -180,7 +189,7 @@ namespace client
std::string ExtractString (const uint8_t * buf, size_t len); std::string ExtractString (const uint8_t * buf, size_t len);
size_t PutString (uint8_t * buf, size_t len, const std::string& str); size_t PutString (uint8_t * buf, size_t len, const std::string& str);
void ExtractMapping (const uint8_t * buf, size_t len, std::map<std::string, std::string>& mapping); void ExtractMapping (const uint8_t * buf, size_t len, std::map<std::string, std::string>& mapping);
void SendSessionStatusMessage (uint8_t status); void SendSessionStatusMessage (I2CPSessionStatus status);
void SendHostReplyMessage (uint32_t requestID, std::shared_ptr<const i2p::data::IdentityEx> identity); void SendHostReplyMessage (uint32_t requestID, std::shared_ptr<const i2p::data::IdentityEx> identity);
private: private:
@ -216,6 +225,7 @@ namespace client
bool InsertSession (std::shared_ptr<I2CPSession> session); bool InsertSession (std::shared_ptr<I2CPSession> session);
void RemoveSession (uint16_t sessionID); void RemoveSession (uint16_t sessionID);
std::shared_ptr<I2CPSession> FindSessionByIdentHash (const i2p::data::IdentHash& ident) const;
private: private:

Loading…
Cancel
Save