Compare commits

..

15 Commits

Author SHA1 Message Date
orignal
f34abe60fa 2.45.1 2023-01-11 13:52:20 -05:00
orignal
a3c305032a don't set Firewalled upon SessionCreated if ports mismatch 2023-01-08 08:25:23 -05:00
orignal
2921eaa055 differentiate symmetric and full cone NAT 2023-01-07 12:11:51 -05:00
orignal
1cc68ea402 differentiate symmetric and full cone NAT 2023-01-07 12:06:26 -05:00
orignal
c18e8f6c78 drop too long LeaseSet without processing 2023-01-07 10:54:49 -05:00
orignal
e59ca8420e temporary change back to C++17 2023-01-06 18:20:26 -05:00
orignal
a6f9a56e40 support C++20 2023-01-06 14:08:39 -05:00
R4SAS
4011502f5f [docker] put config in correct place
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-06 03:59:03 +03:00
orignal
acd6af709e don't use netdb memory pool for local RouterInfo 2023-01-05 18:16:36 -05:00
orignal
55704ece3a drop duplicated I2NP messages 2023-01-05 15:33:41 -05:00
orignal
0d3ede56cb reject duplicated trnsit tunnel 2023-01-05 11:59:47 -05:00
R4SAS
06fae976b3 [style] update editorconfig
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-04 17:10:06 +03:00
orignal
e95035c143 Merge pull request #1835 from kleenexi2p/openssl
Fix segfault when UPnP is enabled
2023-01-04 08:45:17 -05:00
kleenex
55be5c74f0 Fix segfault when UPnP is enabled
Added null check.

Signed-off-by: kleenex <kleenex@i2pmail.org>
2023-01-04 22:41:54 +09:00
R4SAS
a1c16e129d [rpm] fix date
Signed-off-by: R4SAS <r4sas@i2pmail.org>
2023-01-04 16:28:42 +03:00
20 changed files with 160 additions and 44 deletions

View File

@@ -13,6 +13,11 @@ insert_final_newline = true
indent_style = tab indent_style = tab
indent_size = 4 indent_size = 4
[*.cmd]
indent_style = space
indent_size = 2
end_of_line = crlf
[*.{h,cpp}] [*.{h,cpp}]
indent_style = tab indent_style = tab
indent_size = 4 indent_size = 4

View File

@@ -1,6 +1,17 @@
# for this file format description, # for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog # see https://github.com/olivierlacan/keep-a-changelog
## [2.45.1] - 2023-01-11
### Added
- Full Cone NAT status error
### Changed
- Drop duplicated I2NP messages in SSU2
- Set rejection code 30 if tunnel with id already exists
- Network status is always OK if peer test msg 5 received
### Fixed
- UPnP crash if SSU2 or NTCP2 is disabled
- Crash on termination for some platforms
## [2.45.0] - 2023-01-03 ## [2.45.0] - 2023-01-03
### Added ### Added
- Test for Symmetric NAT with peer test msgs 6 and 7 - Test for Symmetric NAT with peer test msgs 6 and 7

View File

@@ -20,7 +20,11 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[8-9]"),3) # gcc 4.8 - 4.9
else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6 else ifeq ($(shell expr match ${CXXVER} "[5-6]"),1) # gcc 5 - 6
NEEDED_CXXFLAGS += -std=c++11 NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "[1,7-9]"),1) # gcc >= 7 else ifeq ($(shell expr match ${CXXVER} "[7-9]"),1) # gcc 7 - 9
NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "1[0-9]"),2) # gcc 10 - 19
# NEEDED_CXXFLAGS += -std=c++20
NEEDED_CXXFLAGS += -std=c++17 NEEDED_CXXFLAGS += -std=c++17
LDLIBS = -latomic LDLIBS = -latomic
else # not supported else # not supported

View File

@@ -60,8 +60,8 @@ RUN apk update \
RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++ RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl miniupnpc musl-utils libstdc++
# 3. Copy preconfigured config file and entrypoint # 3. Copy preconfigured config file and entrypoint
COPY i2pd-docker.conf "$I2PD_HOME/i2pd.conf" COPY i2pd-docker.conf "$DATA_DIR/i2pd.conf"
RUN chown i2pd:nobody "$I2PD_HOME/i2pd.conf" RUN chown i2pd:nobody "$DATA_DIR/i2pd.conf"
COPY entrypoint.sh /entrypoint.sh COPY entrypoint.sh /entrypoint.sh
RUN chmod a+x /entrypoint.sh RUN chmod a+x /entrypoint.sh

View File

@@ -1,7 +1,7 @@
%define git_hash %(git rev-parse HEAD | cut -c -7) %define git_hash %(git rev-parse HEAD | cut -c -7)
Name: i2pd-git Name: i2pd-git
Version: 2.45.0 Version: 2.45.1
Release: git%{git_hash}%{?dist} Release: git%{git_hash}%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Conflicts: i2pd Conflicts: i2pd
@@ -158,7 +158,10 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* Mon Tue 3 2023 orignal <orignal@i2pmail.org> - 2.45.0 * Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0 - update to 2.45.0
* Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0 * Sun Nov 20 2022 orignal <orignal@i2pmail.org> - 2.44.0

View File

@@ -1,5 +1,5 @@
Name: i2pd Name: i2pd
Version: 2.45.0 Version: 2.45.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: I2P router written in C++ Summary: I2P router written in C++
Conflicts: i2pd-git Conflicts: i2pd-git
@@ -155,6 +155,9 @@ getent passwd i2pd >/dev/null || \
%changelog %changelog
* Wed Jan 11 2023 orignal <orignal@i2pmail.org> - 2.45.1
- update to 2.45.1
* Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0 * Tue Jan 3 2023 orignal <orignal@i2pmail.org> - 2.45.0
- update to 2.45.0 - update to 2.45.0

View File

@@ -245,6 +245,9 @@ namespace http {
case eRouterErrorSymmetricNAT: case eRouterErrorSymmetricNAT:
s << " - " << tr("Symmetric NAT"); s << " - " << tr("Symmetric NAT");
break; break;
case eRouterErrorFullConeNAT:
s << " - " << tr("Full cone NAT");
break;
case eRouterErrorNoDescriptors: case eRouterErrorNoDescriptors:
s << " - " << tr("No Descriptors"); s << " - " << tr("No Descriptors");
break; break;

View File

@@ -163,7 +163,7 @@ namespace transport
if (!a) return; if (!a) return;
for (const auto& address : *a) for (const auto& address : *a)
{ {
if (!address->host.is_v6 () && address->port) if (address && !address->host.is_v6 () && address->port)
TryPortMapping (address); TryPortMapping (address);
} }
m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes m_Timer.expires_from_now (boost::posix_time::minutes(20)); // every 20 minutes
@@ -215,7 +215,7 @@ namespace transport
if (!a) return; if (!a) return;
for (const auto& address : *a) for (const auto& address : *a)
{ {
if (!address->host.is_v6 () && address->port) if (address && !address->host.is_v6 () && address->port)
CloseMapping (address); CloseMapping (address);
} }
} }

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
i2pd (2.45.1-1) unstable; urgency=medium
* updated to version 2.45.1/0.9.57
-- orignal <orignal@i2pmail.org> Wed, 11 Jan 2023 19:00:00 +0000
i2pd (2.45.0-1) unstable; urgency=high i2pd (2.45.0-1) unstable; urgency=high
* updated to version 2.45.0/0.9.57 * updated to version 2.45.0/0.9.57

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -392,7 +392,8 @@ namespace i2p
clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET, clearText + ECIES_BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); clearText[ECIES_BUILD_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); if (!i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel))
retCode = 30;
} }
else else
retCode = 30; // always reject with bandwidth reason (30) retCode = 30; // always reject with bandwidth reason (30)
@@ -590,7 +591,8 @@ namespace i2p
layerKey, ivKey, layerKey, ivKey,
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG, clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_GATEWAY_FLAG,
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG); clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel); if (!i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel))
retCode = 30;
} }
// encrypt reply // encrypt reply

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -807,6 +807,11 @@ namespace data
uint8_t storeType = buf[DATABASE_STORE_TYPE_OFFSET]; uint8_t storeType = buf[DATABASE_STORE_TYPE_OFFSET];
if (storeType) // LeaseSet or LeaseSet2 if (storeType) // LeaseSet or LeaseSet2
{ {
if (len > MAX_LS_BUFFER_SIZE + offset)
{
LogPrint (eLogError, "NetDb: Database store message is too long ", len);
return;
}
if (!m->from) // unsolicited LS must be received directly if (!m->from) // unsolicited LS must be received directly
{ {
if (storeType == NETDB_STORE_TYPE_LEASESET) // 1 if (storeType == NETDB_STORE_TYPE_LEASESET) // 1

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -240,7 +240,6 @@ namespace i2p
if (status != m_Status) if (status != m_Status)
{ {
m_Status = status; m_Status = status;
m_Error = eRouterErrorNone;
switch (m_Status) switch (m_Status)
{ {
case eRouterStatusOK: case eRouterStatusOK:
@@ -249,6 +248,9 @@ namespace i2p
case eRouterStatusFirewalled: case eRouterStatusFirewalled:
SetUnreachable (true, false); // ipv4 SetUnreachable (true, false); // ipv4
break; break;
case eRouterStatusTesting:
m_Error = eRouterErrorNone;
break;
default: default:
; ;
} }
@@ -260,7 +262,6 @@ namespace i2p
if (status != m_StatusV6) if (status != m_StatusV6)
{ {
m_StatusV6 = status; m_StatusV6 = status;
m_ErrorV6 = eRouterErrorNone;
switch (m_StatusV6) switch (m_StatusV6)
{ {
case eRouterStatusOK: case eRouterStatusOK:
@@ -269,6 +270,9 @@ namespace i2p
case eRouterStatusFirewalled: case eRouterStatusFirewalled:
SetUnreachable (false, true); // ipv6 SetUnreachable (false, true); // ipv6
break; break;
case eRouterStatusTesting:
m_ErrorV6 = eRouterErrorNone;
break;
default: default:
; ;
} }

View File

@@ -48,7 +48,8 @@ namespace garlic
eRouterErrorClockSkew = 1, eRouterErrorClockSkew = 1,
eRouterErrorOffline = 2, eRouterErrorOffline = 2,
eRouterErrorSymmetricNAT = 3, eRouterErrorSymmetricNAT = 3,
eRouterErrorNoDescriptors = 4 eRouterErrorFullConeNAT = 4,
eRouterErrorNoDescriptors = 5
}; };
class RouterContext: public i2p::garlic::GarlicDestination class RouterContext: public i2p::garlic::GarlicDestination

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -206,13 +206,13 @@ namespace data
s.read ((char *)&m_Timestamp, sizeof (m_Timestamp)); s.read ((char *)&m_Timestamp, sizeof (m_Timestamp));
m_Timestamp = be64toh (m_Timestamp); m_Timestamp = be64toh (m_Timestamp);
// read addresses // read addresses
auto addresses = netdb.NewRouterInfoAddresses (); auto addresses = NewAddresses ();
uint8_t numAddresses; uint8_t numAddresses;
s.read ((char *)&numAddresses, sizeof (numAddresses)); s.read ((char *)&numAddresses, sizeof (numAddresses));
for (int i = 0; i < numAddresses; i++) for (int i = 0; i < numAddresses; i++)
{ {
uint8_t supportedTransports = 0; uint8_t supportedTransports = 0;
auto address = netdb.NewRouterInfoAddress (); auto address = NewAddress ();
uint8_t cost; // ignore uint8_t cost; // ignore
s.read ((char *)&cost, sizeof (cost)); s.read ((char *)&cost, sizeof (cost));
s.read ((char *)&address->date, sizeof (address->date)); s.read ((char *)&address->date, sizeof (address->date));
@@ -974,6 +974,16 @@ namespace data
return netdb.NewRouterInfoBuffer (); return netdb.NewRouterInfoBuffer ();
} }
std::shared_ptr<RouterInfo::Address> RouterInfo::NewAddress () const
{
return netdb.NewRouterInfoAddress ();
}
boost::shared_ptr<RouterInfo::Addresses> RouterInfo::NewAddresses () const
{
return netdb.NewRouterInfoAddresses ();
}
void RouterInfo::RefreshTimestamp () void RouterInfo::RefreshTimestamp ()
{ {
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
@@ -1255,6 +1265,16 @@ namespace data
return std::make_shared<Buffer> (); return std::make_shared<Buffer> ();
} }
std::shared_ptr<RouterInfo::Address> LocalRouterInfo::NewAddress () const
{
return std::make_shared<Address> ();
}
boost::shared_ptr<RouterInfo::Addresses> LocalRouterInfo::NewAddresses () const
{
return boost::make_shared<Addresses> ();
}
bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4) bool LocalRouterInfo::AddSSU2Introducer (const Introducer& introducer, bool v4)
{ {
auto addresses = GetAddresses (); auto addresses = GetAddresses ();

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -285,6 +285,8 @@ namespace data
template<typename Filter> template<typename Filter>
std::shared_ptr<const Address> GetAddress (Filter filter) const; std::shared_ptr<const Address> GetAddress (Filter filter) const;
virtual std::shared_ptr<Buffer> NewBuffer () const; virtual std::shared_ptr<Buffer> NewBuffer () const;
virtual std::shared_ptr<Address> NewAddress () const;
virtual boost::shared_ptr<Addresses> NewAddresses () const;
private: private:
@@ -324,6 +326,8 @@ namespace data
void UpdateCapsProperty (); void UpdateCapsProperty ();
void WriteString (const std::string& str, std::ostream& s) const; void WriteString (const std::string& str, std::ostream& s) const;
std::shared_ptr<Buffer> NewBuffer () const override; std::shared_ptr<Buffer> NewBuffer () const override;
std::shared_ptr<Address> NewAddress () const override;
boost::shared_ptr<Addresses> NewAddresses () const override;
private: private:

View File

@@ -221,6 +221,7 @@ namespace transport
m_IncompleteMessages.clear (); m_IncompleteMessages.clear ();
m_RelaySessions.clear (); m_RelaySessions.clear ();
m_PeerTests.clear (); m_PeerTests.clear ();
m_ReceivedI2NPMsgIDs.clear ();
m_Server.RemoveSession (m_SourceConnID); m_Server.RemoveSession (m_SourceConnID);
transports.PeerDisconnected (shared_from_this ()); transports.PeerDisconnected (shared_from_this ());
LogPrint (eLogDebug, "SSU2: Session terminated"); LogPrint (eLogDebug, "SSU2: Session terminated");
@@ -1450,7 +1451,7 @@ namespace transport
nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header
memcpy (nextMsg->GetNTCP2Header (), buf + offset, size); memcpy (nextMsg->GetNTCP2Header (), buf + offset, size);
nextMsg->FromNTCP2 (); // SSU2 has the same format as NTCP2 nextMsg->FromNTCP2 (); // SSU2 has the same format as NTCP2
m_Handler.PutNextMessage (std::move (nextMsg)); HandleI2NPMsg (std::move (nextMsg));
m_IsDataReceived = true; m_IsDataReceived = true;
break; break;
} }
@@ -1667,23 +1668,17 @@ namespace transport
LogPrint (eLogInfo, "SSU2: Our port ", ep.port (), " received from ", m_RemoteEndpoint, " is different from ", m_Server.GetPort (isV4)); LogPrint (eLogInfo, "SSU2: Our port ", ep.port (), " received from ", m_RemoteEndpoint, " is different from ", m_Server.GetPort (isV4));
if (isV4) if (isV4)
{ {
if (i2p::context.GetStatus () == eRouterStatusTesting || if (i2p::context.GetStatus () == eRouterStatusTesting)
m_State == eSSU2SessionStatePeerTest)
{
i2p::context.SetStatus (eRouterStatusFirewalled);
i2p::context.SetError (eRouterErrorSymmetricNAT); i2p::context.SetError (eRouterErrorSymmetricNAT);
m_Server.RescheduleIntroducersUpdateTimer (); else if (m_State == eSSU2SessionStatePeerTest)
} i2p::context.SetError (eRouterErrorFullConeNAT);
} }
else else
{ {
if (i2p::context.GetStatusV6 () == eRouterStatusTesting || if (i2p::context.GetStatusV6 () == eRouterStatusTesting)
m_State == eSSU2SessionStatePeerTest)
{
i2p::context.SetStatusV6 (eRouterStatusFirewalled);
i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT); i2p::context.SetErrorV6 (eRouterErrorSymmetricNAT);
m_Server.RescheduleIntroducersUpdateTimerV6 (); else if (m_State == eSSU2SessionStatePeerTest)
} i2p::context.SetErrorV6 (eRouterErrorFullConeNAT);
} }
} }
else else
@@ -1696,6 +1691,8 @@ namespace transport
i2p::context.SetStatus (eRouterStatusOK); i2p::context.SetStatus (eRouterStatusOK);
i2p::context.SetError (eRouterErrorNone); i2p::context.SetError (eRouterErrorNone);
} }
else if (i2p::context.GetError () == eRouterErrorFullConeNAT)
i2p::context.SetError (eRouterErrorNone);
} }
else else
{ {
@@ -1705,6 +1702,8 @@ namespace transport
i2p::context.SetStatusV6 (eRouterStatusOK); i2p::context.SetStatusV6 (eRouterStatusOK);
i2p::context.SetErrorV6 (eRouterErrorNone); i2p::context.SetErrorV6 (eRouterErrorNone);
} }
else if (i2p::context.GetErrorV6 () == eRouterErrorFullConeNAT)
i2p::context.SetErrorV6 (eRouterErrorNone);
} }
} }
} }
@@ -1738,7 +1737,7 @@ namespace transport
{ {
// we have all follow-on fragments already // we have all follow-on fragments already
m->msg->FromNTCP2 (); m->msg->FromNTCP2 ();
m_Handler.PutNextMessage (std::move (m->msg)); HandleI2NPMsg (std::move (m->msg));
m_IncompleteMessages.erase (it); m_IncompleteMessages.erase (it);
} }
} }
@@ -1760,14 +1759,14 @@ namespace transport
if (isLast) if (isLast)
{ {
it->second->msg->FromNTCP2 (); it->second->msg->FromNTCP2 ();
m_Handler.PutNextMessage (std::move (it->second->msg)); HandleI2NPMsg (std::move (it->second->msg));
m_IncompleteMessages.erase (it); m_IncompleteMessages.erase (it);
} }
else else
{ {
if (ConcatOutOfSequenceFragments (it->second)) if (ConcatOutOfSequenceFragments (it->second))
{ {
m_Handler.PutNextMessage (std::move (it->second->msg)); HandleI2NPMsg (std::move (it->second->msg));
m_IncompleteMessages.erase (it); m_IncompleteMessages.erase (it);
} }
else else
@@ -2268,6 +2267,29 @@ namespace transport
} }
} }
void SSU2Session::HandleI2NPMsg (std::shared_ptr<I2NPMessage>&& msg)
{
if (!msg) return;
int32_t msgID = msg->GetMsgID ();
#if __cplusplus >= 202002L // C++ 20 or higher
if (!m_ReceivedI2NPMsgIDs.contains (msgID))
#else
if (!m_ReceivedI2NPMsgIDs.count (msgID))
#endif
{
if (!msg->IsExpired ())
{
// m_LastActivityTimestamp is updated in ProcessData before
m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp);
m_Handler.PutNextMessage (std::move (msg));
}
else
LogPrint (eLogDebug, "SSU2: Message ", msgID, " expired");
}
else
LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received");
}
bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep)
{ {
if (size < 2) return false; if (size < 2) return false;
@@ -2790,6 +2812,20 @@ namespace transport
else else
++it; ++it;
} }
if (m_ReceivedI2NPMsgIDs.size () > SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS || ts > m_LastActivityTimestamp + SSU2_DECAY_INTERVAL)
// decay
m_ReceivedI2NPMsgIDs.clear ();
else
{
// delete old received msgIDs
for (auto it = m_ReceivedI2NPMsgIDs.begin (); it != m_ReceivedI2NPMsgIDs.end ();)
{
if (ts > it->second + SSU2_RECEIVED_I2NP_MSGIDS_CLEANUP_TIMEOUT)
it = m_ReceivedI2NPMsgIDs.erase (it);
else
++it;
}
}
if (!m_OutOfSequencePackets.empty ()) if (!m_OutOfSequencePackets.empty ())
{ {
if (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || if (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES ||

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, The PurpleI2P Project * Copyright (c) 2022-2023, 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
* *
@@ -39,6 +39,9 @@ namespace transport
const int SSU2_RESEND_INTERVAL = 300; // in milliseconds const int SSU2_RESEND_INTERVAL = 300; // in milliseconds
const int SSU2_MAX_NUM_RESENDS = 5; const int SSU2_MAX_NUM_RESENDS = 5;
const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds
const int SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS = 5000; // how many msgID we store for duplicates check
const int SSU2_RECEIVED_I2NP_MSGIDS_CLEANUP_TIMEOUT = 10; // in seconds
const int SSU2_DECAY_INTERVAL = 20; // in seconds
const size_t SSU2_MIN_WINDOW_SIZE = 16; // in packets const size_t SSU2_MIN_WINDOW_SIZE = 16; // in packets
const size_t SSU2_MAX_WINDOW_SIZE = 256; // in packets const size_t SSU2_MAX_WINDOW_SIZE = 256; // in packets
const size_t SSU2_MIN_RTO = 100; // in milliseconds const size_t SSU2_MIN_RTO = 100; // in milliseconds
@@ -308,6 +311,7 @@ namespace transport
void HandleRelayIntro (const uint8_t * buf, size_t len, int attempts = 0); void HandleRelayIntro (const uint8_t * buf, size_t len, int attempts = 0);
void HandleRelayResponse (const uint8_t * buf, size_t len); void HandleRelayResponse (const uint8_t * buf, size_t len);
void HandlePeerTest (const uint8_t * buf, size_t len); void HandlePeerTest (const uint8_t * buf, size_t len);
void HandleI2NPMsg (std::shared_ptr<I2NPMessage>&& msg);
size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep); size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r); size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
@@ -351,6 +355,7 @@ namespace transport
SSU2TerminationReason m_TerminationReason; SSU2TerminationReason m_TerminationReason;
size_t m_MaxPayloadSize; size_t m_MaxPayloadSize;
std::unique_ptr<i2p::data::IdentHash> m_PathChallenge; std::unique_ptr<i2p::data::IdentHash> m_PathChallenge;
std::unordered_map<uint32_t, uint32_t> m_ReceivedI2NPMsgIDs; // msgID -> timestamp in seconds
}; };
inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce) inline uint64_t CreateHeaderMask (const uint8_t * kh, const uint8_t * nonce)

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -433,12 +433,16 @@ namespace tunnel
} }
} }
void Tunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel) bool Tunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel)
{ {
if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second) if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second)
m_TransitTunnels.push_back (tunnel); m_TransitTunnels.push_back (tunnel);
else else
{
LogPrint (eLogError, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists"); LogPrint (eLogError, "Tunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists");
return false;
}
return true;
} }
void Tunnels::Start () void Tunnels::Start ()

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2022, The PurpleI2P Project * Copyright (c) 2013-2023, 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
* *
@@ -210,7 +210,7 @@ namespace tunnel
std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; }; std::shared_ptr<TunnelPool> GetExploratoryPool () const { return m_ExploratoryPool; };
std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID); std::shared_ptr<TunnelBase> GetTunnel (uint32_t tunnelID);
int GetTransitTunnelsExpirationTimeout (); int GetTransitTunnelsExpirationTimeout ();
void AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel); bool AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel);
void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel); void AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel);
void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel); void AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel);
std::shared_ptr<InboundTunnel> CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel); std::shared_ptr<InboundTunnel> CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel);

View File

@@ -17,7 +17,7 @@
#define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MAJOR 2
#define I2PD_VERSION_MINOR 45 #define I2PD_VERSION_MINOR 45
#define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_MICRO 1
#define I2PD_VERSION_PATCH 0 #define I2PD_VERSION_PATCH 0
#ifdef GITVER #ifdef GITVER
#define I2PD_VERSION GITVER #define I2PD_VERSION GITVER