Skip to content

Commit

Permalink
check for duplicate destination
Browse files Browse the repository at this point in the history
  • Loading branch information
orignal committed Jan 19, 2022
1 parent 5a35de8 commit afad405
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 16 deletions.
55 changes: 41 additions & 14 deletions libi2pd_client/I2CP.cpp
@@ -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
*
Expand Down Expand Up @@ -519,21 +519,26 @@ namespace client
void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len)
{
RAND_bytes ((uint8_t *)&m_SessionID, 2);
m_Owner.InsertSession (shared_from_this ());
auto identity = std::make_shared<i2p::data::IdentityEx>();
size_t offset = identity->FromBuffer (buf, len);
if (!offset)
{
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;
}
uint16_t optionsSize = bufbe16toh (buf + offset);
offset += 2;
if (optionsSize > len - offset)
{
LogPrint (eLogError, "I2CP: Options size ", optionsSize, "exceeds message size");
SendSessionStatusMessage (3); // invalid
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
return;
}
std::map<std::string, std::string> params;
Expand All @@ -549,33 +554,41 @@ namespace client
m_Destination = m_Owner.IsSingleThread () ?
std::make_shared<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params):
std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params);
SendSessionStatusMessage (1); // created
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created");
m_Destination->Start ();
if (m_Owner.InsertSession (shared_from_this ()))
{
SendSessionStatusMessage (eI2CPSessionStatusCreated); // created
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created");
m_Destination->Start ();
}
else
{
LogPrint (eLogError, "I2CP: Session already exists");
SendSessionStatusMessage (eI2CPSessionStatusRefused);
}
}
else
{
LogPrint (eLogError, "I2CP: Session already exists");
SendSessionStatusMessage (4); // refused
SendSessionStatusMessage (eI2CPSessionStatusRefused); // refused
}
}
else
{
LogPrint (eLogError, "I2CP: Create session signature verification failed");
SendSessionStatusMessage (3); // invalid
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
}
}

void I2CPSession::DestroySessionMessageHandler (const uint8_t * buf, size_t len)
{
SendSessionStatusMessage (0); // destroy
SendSessionStatusMessage (eI2CPSessionStatusDestroyed); // destroy
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " destroyed");
Terminate ();
}

void I2CPSession::ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len)
{
uint8_t status = 3; // rejected
I2CPSessionStatus status = eI2CPSessionStatusInvalid; // rejected
if(len > sizeof(uint16_t))
{
uint16_t sessionID = bufbe16toh(buf);
Expand Down Expand Up @@ -605,7 +618,7 @@ namespace client
if(m_Destination->Reconfigure(opts))
{
LogPrint(eLogInfo, "I2CP: Reconfigured destination");
status = 2; // updated
status = eI2CPSessionStatusUpdated; // updated
}
else
LogPrint(eLogWarning, "I2CP: Failed to reconfigure destination");
Expand All @@ -630,11 +643,11 @@ namespace client
SendSessionStatusMessage (status);
}

void I2CPSession::SendSessionStatusMessage (uint8_t status)
void I2CPSession::SendSessionStatusMessage (I2CPSessionStatus status)
{
uint8_t buf[3];
htobe16buf (buf, m_SessionID);
buf[2] = status;
buf[2] = (uint8_t)status;
SendI2CPMessage (I2CP_SESSION_STATUS_MESSAGE, buf, 3);
}

Expand Down Expand Up @@ -1009,5 +1022,19 @@ namespace client
{
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;
}
}
}
14 changes: 12 additions & 2 deletions libi2pd_client/I2CP.h
@@ -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
*
Expand Down Expand Up @@ -61,6 +61,15 @@ namespace client
eI2CPMessageStatusNoLeaseSet = 21
};

enum I2CPSessionStatus
{
eI2CPSessionStatusDestroyed = 0,
eI2CPSessionStatusCreated = 1,
eI2CPSessionStatusUpdated = 2,
eI2CPSessionStatusInvalid = 3,
eI2CPSessionStatusRefused = 4
};

// params
const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability";

Expand Down Expand Up @@ -180,7 +189,7 @@ namespace client
std::string ExtractString (const uint8_t * buf, size_t len);
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 SendSessionStatusMessage (uint8_t status);
void SendSessionStatusMessage (I2CPSessionStatus status);
void SendHostReplyMessage (uint32_t requestID, std::shared_ptr<const i2p::data::IdentityEx> identity);

private:
Expand Down Expand Up @@ -216,6 +225,7 @@ namespace client

bool InsertSession (std::shared_ptr<I2CPSession> session);
void RemoveSession (uint16_t sessionID);
std::shared_ptr<I2CPSession> FindSessionByIdentHash (const i2p::data::IdentHash& ident) const;

private:

Expand Down

0 comments on commit afad405

Please sign in to comment.