mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-07 06:09:42 +00:00
Compare commits
11 Commits
833e0a936e
...
2.55.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1293e122bc | ||
|
|
24bcc651e0 | ||
|
|
8713974f40 | ||
|
|
d48bf33fc5 | ||
|
|
0f14f9a302 | ||
|
|
55708d2a6d | ||
|
|
3bdfa5562b | ||
|
|
3995448014 | ||
|
|
7497741846 | ||
|
|
36939898fe | ||
|
|
b4bcd9914a |
41
ChangeLog
41
ChangeLog
@@ -1,6 +1,47 @@
|
||||
# for this file format description,
|
||||
# see https://github.com/olivierlacan/keep-a-changelog
|
||||
|
||||
## [2.55.0] - 2024-12-30
|
||||
### Added
|
||||
- Support boost 1.87
|
||||
- "i2p.streaming.maxConcurrentStreams" tunnel's param to limit number of simultaneous streams
|
||||
- Separate thread for tunnel build requests
|
||||
- Show next peer and connectivity on "Transit tunnels" page
|
||||
- Tunnel name for local destination thread
|
||||
- Throttle incoming ECIESx25519 sessions
|
||||
- Send tunnel data to transport session directly if possible
|
||||
- Publish 'R' cap for yggdrasil-only routers, and 'U' cap for routers through proxy
|
||||
- Random tunnel rejection when medium congestion
|
||||
- Save unreachable router's endpoint to use it next time without introducers
|
||||
- Recognize symmetric NAT from peer test message 7
|
||||
- Resend HolePunch and RelayResponse messages
|
||||
### Changed
|
||||
- Removed own implementation of AESNI and always use one from openssl
|
||||
- Renamed main thread to i2pd-daemon
|
||||
- Set i2p.streaming.profile=2 for shared local destination
|
||||
- Reduced LeaseSet and RouterInfo lookup timeouts
|
||||
- Cleanup ECIES sessions and tags more often
|
||||
- Check LeaseSet expiration time
|
||||
- Handle NTCP2 session handshakes in separate thread
|
||||
- Limit last decline time by 1.5 hours in router's profile
|
||||
- Don't handle RelayRequest and RelayIntro with same nonce twice
|
||||
- Increased hole punch expiration interval
|
||||
- Send peer test message 6 with delay if message 4 was received before message 5
|
||||
- Pre-calculate more x25519 keys for transports in runtime
|
||||
- Don't request LeaseSet for incoming stream
|
||||
- Terminate incoming stream right away if no remote LeaseSet
|
||||
- Handle choked, new RTO and window size calculation and resetting algorithm for streams
|
||||
### Fixed
|
||||
- Empty string in addressbook subscriptions
|
||||
- ECIESx25519 sessions without destination
|
||||
- Missing RouterInfo buffer in NetDb
|
||||
- Invalid I2PControl certificate
|
||||
- Routers disappear from NetDb when offline
|
||||
- Peer test message 6 sent to unknown endpoint
|
||||
- Race condition with LeaseSet update
|
||||
- Excessive CPU usage by streams
|
||||
- Crash on shutdown
|
||||
|
||||
## [2.54.0] - 2024-10-06
|
||||
### Added
|
||||
- Maintain recently connected routers list to avoid false-positive peer test
|
||||
|
||||
@@ -2,13 +2,13 @@ Description: Enable UPnP usage in package
|
||||
Author: r4sas <r4sas@i2pmail.org>
|
||||
|
||||
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
||||
Last-Update: 2022-03-23
|
||||
Last-Update: 2024-12-30
|
||||
|
||||
--- i2pd.orig/Makefile
|
||||
+++ i2pd/Makefile
|
||||
@@ -31,7 +31,7 @@ include filelist.mk
|
||||
@@ -31,7 +31,7 @@ # import source files lists
|
||||
include filelist.mk
|
||||
|
||||
USE_AESNI := $(or $(USE_AESNI),yes)
|
||||
USE_STATIC := $(or $(USE_STATIC),no)
|
||||
-USE_UPNP := $(or $(USE_UPNP),no)
|
||||
+USE_UPNP := $(or $(USE_UPNP),yes)
|
||||
|
||||
@@ -2,13 +2,13 @@ Description: Enable UPnP usage in package
|
||||
Author: r4sas <r4sas@i2pmail.org>
|
||||
|
||||
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
||||
Last-Update: 2022-03-23
|
||||
Last-Update: 2024-12-30
|
||||
|
||||
--- i2pd.orig/Makefile
|
||||
+++ i2pd/Makefile
|
||||
@@ -31,7 +31,7 @@ include filelist.mk
|
||||
@@ -31,7 +31,7 @@ # import source files lists
|
||||
include filelist.mk
|
||||
|
||||
USE_AESNI := $(or $(USE_AESNI),yes)
|
||||
USE_STATIC := $(or $(USE_STATIC),no)
|
||||
-USE_UPNP := $(or $(USE_UPNP),no)
|
||||
+USE_UPNP := $(or $(USE_UPNP),yes)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
%define git_hash %(git rev-parse HEAD | cut -c -7)
|
||||
|
||||
Name: i2pd-git
|
||||
Version: 2.54.0
|
||||
Version: 2.55.0
|
||||
Release: git%{git_hash}%{?dist}
|
||||
Summary: I2P router written in C++
|
||||
Conflicts: i2pd
|
||||
@@ -148,6 +148,9 @@ getent passwd i2pd >/dev/null || \
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Dec 30 2024 orignal <orignal@i2pmail.org> - 2.55.0
|
||||
- update to 2.55.0
|
||||
|
||||
* Sun Oct 6 2024 orignal <orignal@i2pmail.org> - 2.54.0
|
||||
- update to 2.54.0
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: i2pd
|
||||
Version: 2.54.0
|
||||
Version: 2.55.0
|
||||
Release: 1%{?dist}
|
||||
Summary: I2P router written in C++
|
||||
Conflicts: i2pd-git
|
||||
@@ -146,6 +146,9 @@ getent passwd i2pd >/dev/null || \
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Dec 30 2024 orignal <orignal@i2pmail.org> - 2.55.0
|
||||
- update to 2.55.0
|
||||
|
||||
* Sun Oct 6 2024 orignal <orignal@i2pmail.org> - 2.54.0
|
||||
- update to 2.54.0
|
||||
|
||||
|
||||
@@ -826,7 +826,7 @@ namespace http {
|
||||
if (i2p::tunnel::tunnels.CountTransitTunnels())
|
||||
{
|
||||
s << "<b>" << tr("Transit Tunnels") << ":</b><br>\r\n";
|
||||
s << "<table><thead><th>⇒</th><th>ID</th><th>⇒</th><th>" << tr("Amount") << "</th></thead><tbody class=\"tableitem\">";
|
||||
s << "<table><thead><th>⇒</th><th>ID</th><th>⇒</th><th>" << tr("Amount") << "</th><th>" << tr("Next") << "</th></thead><tbody class=\"tableitem\">";
|
||||
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||
{
|
||||
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
|
||||
@@ -836,7 +836,7 @@ namespace http {
|
||||
else
|
||||
s << "<tr><td>⇒</td><td>" << it->GetTunnelID () << "</td><td>⇒</td><td>";
|
||||
ShowTraffic(s, it->GetNumTransmittedBytes ());
|
||||
s << "</td></tr>\r\n";
|
||||
s << "</td><td>" << it->GetNextPeerName () << "</td></tr>\r\n";
|
||||
}
|
||||
s << "</tbody></table>\r\n";
|
||||
}
|
||||
|
||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
||||
i2pd (2.55.0-1) unstable; urgency=medium
|
||||
|
||||
* updated to version 2.55.0
|
||||
|
||||
-- orignal <orignal@i2pmail.org> Mon, 30 Dec 2024 16:00:00 +0000
|
||||
|
||||
i2pd (2.54.0-1) unstable; urgency=medium
|
||||
|
||||
* updated to version 2.54.0/0.9.64
|
||||
|
||||
6
debian/patches/01-upnp.patch
vendored
6
debian/patches/01-upnp.patch
vendored
@@ -2,13 +2,13 @@ Description: Enable UPnP usage in package
|
||||
Author: r4sas <r4sas@i2pmail.org>
|
||||
|
||||
Reviewed-By: r4sas <r4sas@i2pmail.org>
|
||||
Last-Update: 2022-03-23
|
||||
Last-Update: 2024-12-30
|
||||
|
||||
--- i2pd.orig/Makefile
|
||||
+++ i2pd/Makefile
|
||||
@@ -31,7 +31,7 @@ include filelist.mk
|
||||
@@ -31,7 +31,7 @@ # import source files lists
|
||||
include filelist.mk
|
||||
|
||||
USE_AESNI := $(or $(USE_AESNI),yes)
|
||||
USE_STATIC := $(or $(USE_STATIC),no)
|
||||
-USE_UPNP := $(or $(USE_UPNP),no)
|
||||
+USE_UPNP := $(or $(USE_UPNP),yes)
|
||||
|
||||
@@ -833,7 +833,7 @@ namespace client
|
||||
request->requestedBlindedKey = requestedBlindedKey; // for encrypted LeaseSet2
|
||||
if (requestComplete)
|
||||
request->requestComplete.push_back (requestComplete);
|
||||
auto ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
auto ret = m_LeaseSetRequests.insert (std::pair<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> >(dest,request));
|
||||
if (ret.second) // inserted
|
||||
{
|
||||
@@ -916,7 +916,7 @@ namespace client
|
||||
nextFloodfill->GetIdentHash (), 0, msg
|
||||
}
|
||||
});
|
||||
request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT));
|
||||
request->requestTimeoutTimer.expires_from_now (boost::posix_time::milliseconds(LEASESET_REQUEST_TIMEOUT));
|
||||
request->requestTimeoutTimer.async_wait (std::bind (&LeaseSetDestination::HandleRequestTimoutTimer,
|
||||
shared_from_this (), std::placeholders::_1, dest));
|
||||
}
|
||||
@@ -933,7 +933,7 @@ namespace client
|
||||
if (it != m_LeaseSetRequests.end ())
|
||||
{
|
||||
bool done = false;
|
||||
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
if (ts < it->second->requestTime + MAX_LEASESET_REQUEST_TIMEOUT)
|
||||
{
|
||||
auto floodfill = i2p::data::netdb.GetClosestFloodfill (dest, it->second->excluded);
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace client
|
||||
const int PUBLISH_VERIFICATION_TIMEOUT = 10; // in seconds after successful publish
|
||||
const int PUBLISH_MIN_INTERVAL = 20; // in seconds
|
||||
const int PUBLISH_REGULAR_VERIFICATION_INTERNAL = 100; // in seconds periodically
|
||||
const int LEASESET_REQUEST_TIMEOUT = 5; // in seconds
|
||||
const int MAX_LEASESET_REQUEST_TIMEOUT = 40; // in seconds
|
||||
const int LEASESET_REQUEST_TIMEOUT = 1600; // in milliseconds
|
||||
const int MAX_LEASESET_REQUEST_TIMEOUT = 12000; // in milliseconds
|
||||
const int DESTINATION_CLEANUP_TIMEOUT = 44; // in seconds
|
||||
const int DESTINATION_CLEANUP_TIMEOUT_VARIANCE = 30; // in seconds
|
||||
const unsigned int MAX_NUM_FLOODFILLS_PER_REQUEST = 7;
|
||||
|
||||
@@ -1435,6 +1435,12 @@ namespace transport
|
||||
boost::asio::post (m_Server.GetService (), std::bind (&NTCP2Session::SendRouterInfo, shared_from_this ()));
|
||||
}
|
||||
|
||||
i2p::data::RouterInfo::SupportedTransports NTCP2Session::GetTransportType () const
|
||||
{
|
||||
if (m_RemoteEndpoint.address ().is_v4 ()) return i2p::data::RouterInfo::eNTCP2V4;
|
||||
return i2p::util::net::IsYggdrasilAddress (m_RemoteEndpoint.address ()) ? i2p::data::RouterInfo::eNTCP2V6Mesh : i2p::data::RouterInfo::eNTCP2V6;
|
||||
}
|
||||
|
||||
NTCP2Server::NTCP2Server ():
|
||||
RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
|
||||
m_ProxyType(eNoProxy), m_Resolver(GetService ()),
|
||||
@@ -1544,6 +1550,7 @@ namespace transport
|
||||
|
||||
void NTCP2Server::Stop ()
|
||||
{
|
||||
m_EstablisherService.Stop ();
|
||||
{
|
||||
// we have to copy it because Terminate changes m_NTCP2Sessions
|
||||
auto ntcpSessions = m_NTCP2Sessions;
|
||||
@@ -1559,7 +1566,6 @@ namespace transport
|
||||
m_TerminationTimer.cancel ();
|
||||
m_ProxyEndpoint = nullptr;
|
||||
}
|
||||
m_EstablisherService.Stop ();
|
||||
StopIOService ();
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ namespace transport
|
||||
void SetRemoteEndpoint (const boost::asio::ip::tcp::endpoint& ep) { m_RemoteEndpoint = ep; };
|
||||
|
||||
bool IsEstablished () const override { return m_IsEstablished; };
|
||||
i2p::data::RouterInfo::SupportedTransports GetTransportType () const override;
|
||||
bool IsTerminated () const { return m_IsTerminated; };
|
||||
|
||||
void ClientLogin (); // Alice
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace data
|
||||
{
|
||||
RequestedDestination::RequestedDestination (const IdentHash& destination, bool isExploratory, bool direct):
|
||||
m_Destination (destination), m_IsExploratory (isExploratory), m_IsDirect (direct), m_IsActive (true),
|
||||
m_CreationTime (i2p::util::GetSecondsSinceEpoch ()), m_LastRequestTime (0), m_NumAttempts (0)
|
||||
m_CreationTime (i2p::util::GetMillisecondsSinceEpoch ()), m_LastRequestTime (0), m_NumAttempts (0)
|
||||
{
|
||||
if (i2p::context.IsFloodfill ())
|
||||
m_ExcludedPeers.insert (i2p::context.GetIdentHash ()); // exclude self if floodfill
|
||||
@@ -44,7 +44,7 @@ namespace data
|
||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers);
|
||||
if(router)
|
||||
m_ExcludedPeers.insert (router->GetIdentHash ());
|
||||
m_LastRequestTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
m_LastRequestTime = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
m_NumAttempts++;
|
||||
return msg;
|
||||
}
|
||||
@@ -55,7 +55,7 @@ namespace data
|
||||
i2p::context.GetRouterInfo ().GetIdentHash () , 0, false, &m_ExcludedPeers);
|
||||
m_ExcludedPeers.insert (floodfill);
|
||||
m_NumAttempts++;
|
||||
m_LastRequestTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
m_LastRequestTime = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace data
|
||||
|
||||
void NetDbRequests::ManageRequests ()
|
||||
{
|
||||
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
for (auto it = m_RequestedDestinations.begin (); it != m_RequestedDestinations.end ();)
|
||||
{
|
||||
auto& dest = it->second;
|
||||
@@ -328,7 +328,8 @@ namespace data
|
||||
|
||||
void NetDbRequests::ScheduleManageRequests ()
|
||||
{
|
||||
m_ManageRequestsTimer.expires_from_now (boost::posix_time::seconds(MANAGE_REQUESTS_INTERVAL));
|
||||
m_ManageRequestsTimer.expires_from_now (boost::posix_time::milliseconds(MANAGE_REQUESTS_INTERVAL +
|
||||
m_Rng () % MANAGE_REQUESTS_INTERVAL_VARIANCE));
|
||||
m_ManageRequestsTimer.async_wait (std::bind (&NetDbRequests::HandleManageRequestsTimer,
|
||||
this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
@@ -24,15 +24,16 @@ namespace i2p
|
||||
namespace data
|
||||
{
|
||||
const int MAX_NUM_REQUEST_ATTEMPTS = 5;
|
||||
const uint64_t MANAGE_REQUESTS_INTERVAL = 1; // in seconds
|
||||
const uint64_t MIN_REQUEST_TIME = 5; // in seconds
|
||||
const uint64_t MAX_REQUEST_TIME = MAX_NUM_REQUEST_ATTEMPTS * (MIN_REQUEST_TIME + MANAGE_REQUESTS_INTERVAL);
|
||||
const uint64_t MANAGE_REQUESTS_INTERVAL = 400; // in milliseconds
|
||||
const uint64_t MANAGE_REQUESTS_INTERVAL_VARIANCE = 300; // in milliseconds
|
||||
const uint64_t MIN_REQUEST_TIME = 1200; // in milliseconds
|
||||
const uint64_t MAX_REQUEST_TIME = MAX_NUM_REQUEST_ATTEMPTS * (MIN_REQUEST_TIME + MANAGE_REQUESTS_INTERVAL + MANAGE_REQUESTS_INTERVAL_VARIANCE);
|
||||
const uint64_t EXPLORATORY_REQUEST_INTERVAL = 55; // in seconds
|
||||
const uint64_t EXPLORATORY_REQUEST_INTERVAL_VARIANCE = 170; // in seconds
|
||||
const uint64_t DISCOVERED_REQUEST_INTERVAL = 360; // in milliseconds
|
||||
const uint64_t DISCOVERED_REQUEST_INTERVAL_VARIANCE = 540; // in milliseconds
|
||||
const uint64_t MAX_EXPLORATORY_REQUEST_TIME = 30; // in seconds
|
||||
const uint64_t REQUEST_CACHE_TIME = MAX_REQUEST_TIME + 40; // in seconds
|
||||
const uint64_t MAX_EXPLORATORY_REQUEST_TIME = 30000; // in milliseconds
|
||||
const uint64_t REQUEST_CACHE_TIME = MAX_REQUEST_TIME + 40000; // in milliseconds
|
||||
const uint64_t REQUESTED_DESTINATIONS_POOL_CLEANUP_INTERVAL = 191; // in seconds
|
||||
|
||||
class RequestedDestination
|
||||
@@ -71,7 +72,7 @@ namespace data
|
||||
IdentHash m_Destination;
|
||||
bool m_IsExploratory, m_IsDirect, m_IsActive;
|
||||
std::unordered_set<IdentHash> m_ExcludedPeers;
|
||||
uint64_t m_CreationTime, m_LastRequestTime; // in seconds
|
||||
uint64_t m_CreationTime, m_LastRequestTime; // in milliseconds
|
||||
std::list<RequestComplete> m_RequestComplete;
|
||||
int m_NumAttempts;
|
||||
};
|
||||
@@ -115,9 +116,9 @@ namespace data
|
||||
|
||||
private:
|
||||
|
||||
i2p::util::MemoryPoolMt<RequestedDestination> m_RequestedDestinationsPool;
|
||||
std::unordered_map<IdentHash, std::shared_ptr<RequestedDestination> > m_RequestedDestinations;
|
||||
std::list<IdentHash> m_DiscoveredRouterHashes;
|
||||
i2p::util::MemoryPoolMt<RequestedDestination> m_RequestedDestinationsPool;
|
||||
boost::asio::deadline_timer m_ManageRequestsTimer, m_ExploratoryTimer,
|
||||
m_CleanupTimer, m_DiscoveredRoutersTimer;
|
||||
std::mt19937 m_Rng;
|
||||
|
||||
@@ -1195,6 +1195,19 @@ namespace data
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string RouterInfo::GetTransportName (SupportedTransports tr)
|
||||
{
|
||||
switch (tr)
|
||||
{
|
||||
case eNTCP2V4: return "NTCP2V4";
|
||||
case eNTCP2V6: return "NTCP2V6";
|
||||
case eSSU2V4: return "SSU2V4";
|
||||
case eSSU2V6: return "SSU2V6";
|
||||
case eNTCP2V6Mesh: return "Mesh";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
|
||||
{
|
||||
|
||||
@@ -363,6 +363,10 @@ namespace data
|
||||
int m_Version;
|
||||
Congestion m_Congestion;
|
||||
mutable std::shared_ptr<RouterProfile> m_Profile;
|
||||
|
||||
public:
|
||||
|
||||
static std::string GetTransportName (SupportedTransports tr);
|
||||
};
|
||||
|
||||
class LocalRouterInfo: public RouterInfo
|
||||
|
||||
@@ -3114,5 +3114,10 @@ namespace transport
|
||||
else if (!sent && !m_SentPackets.empty ()) // if only acks received, nothing sent and we still have something to resend
|
||||
Resend (i2p::util::GetMillisecondsSinceEpoch ()); // than right time to resend
|
||||
}
|
||||
|
||||
i2p::data::RouterInfo::SupportedTransports SSU2Session::GetTransportType () const
|
||||
{
|
||||
return m_RemoteEndpoint.address ().is_v4 () ? i2p::data::RouterInfo::eSSU2V4 : i2p::data::RouterInfo::eSSU2V6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,6 +267,7 @@ namespace transport
|
||||
size_t Resend (uint64_t ts); // return number of resent packets
|
||||
uint64_t GetLastResendTime () const { return m_LastResendTime; };
|
||||
bool IsEstablished () const override { return m_State == eSSU2SessionStateEstablished; };
|
||||
i2p::data::RouterInfo::SupportedTransports GetTransportType () const override;
|
||||
uint64_t GetConnID () const { return m_SourceConnID; };
|
||||
SSU2SessionState GetState () const { return m_State; };
|
||||
void SetState (SSU2SessionState state) { m_State = state; };
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "I2PEndian.h"
|
||||
#include "Crypto.h"
|
||||
#include "Log.h"
|
||||
#include "Identity.h"
|
||||
#include "RouterInfo.h"
|
||||
#include "RouterContext.h"
|
||||
#include "I2NPProtocol.h"
|
||||
#include "Garlic.h"
|
||||
@@ -41,6 +43,21 @@ namespace tunnel
|
||||
i2p::transport::transports.UpdateTotalTransitTransmittedBytes (TUNNEL_DATA_MSG_SIZE);
|
||||
}
|
||||
|
||||
std::string TransitTunnel::GetNextPeerName () const
|
||||
{
|
||||
return i2p::data::GetIdentHashAbbreviation (GetNextIdentHash ());
|
||||
}
|
||||
|
||||
void TransitTunnel::SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg)
|
||||
{
|
||||
LogPrint (eLogError, "TransitTunnel: We are not a gateway for ", GetTunnelID ());
|
||||
}
|
||||
|
||||
void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg)
|
||||
{
|
||||
LogPrint (eLogError, "TransitTunnel: Incoming tunnel message is not supported ", GetTunnelID ());
|
||||
}
|
||||
|
||||
TransitTunnelParticipant::~TransitTunnelParticipant ()
|
||||
{
|
||||
}
|
||||
@@ -67,16 +84,18 @@ namespace tunnel
|
||||
}
|
||||
}
|
||||
|
||||
void TransitTunnel::SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg)
|
||||
std::string TransitTunnelParticipant::GetNextPeerName () const
|
||||
{
|
||||
LogPrint (eLogError, "TransitTunnel: We are not a gateway for ", GetTunnelID ());
|
||||
}
|
||||
|
||||
void TransitTunnel::HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg)
|
||||
{
|
||||
LogPrint (eLogError, "TransitTunnel: Incoming tunnel message is not supported ", GetTunnelID ());
|
||||
}
|
||||
|
||||
if (m_Sender)
|
||||
{
|
||||
auto transport = m_Sender->GetCurrentTransport ();
|
||||
if (transport)
|
||||
return TransitTunnel::GetNextPeerName () + "-" +
|
||||
i2p::data::RouterInfo::GetTransportName (transport->GetTransportType ());
|
||||
}
|
||||
return TransitTunnel::GetNextPeerName ();
|
||||
}
|
||||
|
||||
void TransitTunnelGateway::SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg)
|
||||
{
|
||||
TunnelMessageBlock block;
|
||||
@@ -92,6 +111,19 @@ namespace tunnel
|
||||
m_Gateway.SendBuffer ();
|
||||
}
|
||||
|
||||
std::string TransitTunnelGateway::GetNextPeerName () const
|
||||
{
|
||||
const auto& sender = m_Gateway.GetSender ();
|
||||
if (sender)
|
||||
{
|
||||
auto transport = sender->GetCurrentTransport ();
|
||||
if (transport)
|
||||
return TransitTunnel::GetNextPeerName () + "-" +
|
||||
i2p::data::RouterInfo::GetTransportName (transport->GetTransportType ());
|
||||
}
|
||||
return TransitTunnel::GetNextPeerName ();
|
||||
}
|
||||
|
||||
void TransitTunnelEndpoint::HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg)
|
||||
{
|
||||
auto newMsg = CreateEmptyTunnelDataMsg (true);
|
||||
@@ -101,6 +133,30 @@ namespace tunnel
|
||||
m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg);
|
||||
}
|
||||
|
||||
void TransitTunnelEndpoint::FlushTunnelDataMsgs ()
|
||||
{
|
||||
m_Endpoint.FlushI2NPMsgs ();
|
||||
}
|
||||
|
||||
std::string TransitTunnelEndpoint::GetNextPeerName () const
|
||||
{
|
||||
auto hash = m_Endpoint.GetCurrentHash ();
|
||||
if (hash)
|
||||
{
|
||||
const auto& sender = m_Endpoint.GetSender ();
|
||||
if (sender)
|
||||
{
|
||||
auto transport = sender->GetCurrentTransport ();
|
||||
if (transport)
|
||||
return i2p::data::GetIdentHashAbbreviation (*hash) + "-" +
|
||||
i2p::data::RouterInfo::GetTransportName (transport->GetTransportType ());
|
||||
else
|
||||
return i2p::data::GetIdentHashAbbreviation (*hash);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
|
||||
const i2p::data::IdentHash& nextIdent, uint32_t nextTunnelID,
|
||||
const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey,
|
||||
|
||||
@@ -33,11 +33,13 @@ namespace tunnel
|
||||
const i2p::crypto::AESKey& layerKey, const i2p::crypto::AESKey& ivKey);
|
||||
|
||||
virtual size_t GetNumTransmittedBytes () const { return 0; };
|
||||
virtual std::string GetNextPeerName () const;
|
||||
|
||||
// implements TunnelBase
|
||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out) override;
|
||||
|
||||
private:
|
||||
|
||||
i2p::crypto::AESKey m_LayerKey, m_IVKey;
|
||||
@@ -56,6 +58,7 @@ namespace tunnel
|
||||
~TransitTunnelParticipant ();
|
||||
|
||||
size_t GetNumTransmittedBytes () const override { return m_NumTransmittedBytes; };
|
||||
std::string GetNextPeerName () const override;
|
||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||
void FlushTunnelDataMsgs () override;
|
||||
|
||||
@@ -79,7 +82,8 @@ namespace tunnel
|
||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg) override;
|
||||
void FlushTunnelDataMsgs () override;
|
||||
size_t GetNumTransmittedBytes () const override { return m_Gateway.GetNumSentBytes (); };
|
||||
|
||||
std::string GetNextPeerName () const override;
|
||||
|
||||
private:
|
||||
|
||||
std::mutex m_SendMutex;
|
||||
@@ -97,10 +101,12 @@ namespace tunnel
|
||||
m_Endpoint (false) {}; // transit endpoint is always outbound
|
||||
|
||||
void Cleanup () override { m_Endpoint.Cleanup (); }
|
||||
|
||||
|
||||
void HandleTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage>&& tunnelMsg) override;
|
||||
void FlushTunnelDataMsgs () override;
|
||||
size_t GetNumTransmittedBytes () const override { return m_Endpoint.GetNumReceivedBytes (); }
|
||||
|
||||
std::string GetNextPeerName () const override;
|
||||
|
||||
private:
|
||||
|
||||
TunnelEndpoint m_Endpoint;
|
||||
|
||||
@@ -151,6 +151,7 @@ namespace transport
|
||||
};
|
||||
virtual void SendI2NPMessages (std::list<std::shared_ptr<I2NPMessage> >& msgs) = 0;
|
||||
virtual bool IsEstablished () const = 0;
|
||||
virtual i2p::data::RouterInfo::SupportedTransports GetTransportType () const = 0;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -55,6 +55,13 @@ namespace transport
|
||||
m_Thread->join ();
|
||||
m_Thread = nullptr;
|
||||
}
|
||||
if (!m_Queue.empty ())
|
||||
{
|
||||
// clean up queue
|
||||
std::queue<std::shared_ptr<Keys> > tmp;
|
||||
std::swap (m_Queue, tmp);
|
||||
}
|
||||
m_KeysPool.CleanUpMt ();
|
||||
}
|
||||
|
||||
template<typename Keys>
|
||||
|
||||
@@ -54,8 +54,8 @@ namespace transport
|
||||
private:
|
||||
|
||||
const int m_QueueSize;
|
||||
std::queue<std::shared_ptr<Keys> > m_Queue;
|
||||
i2p::util::MemoryPoolMt<Keys> m_KeysPool;
|
||||
std::queue<std::shared_ptr<Keys> > m_Queue;
|
||||
|
||||
bool m_IsRunning;
|
||||
std::unique_ptr<std::thread> m_Thread;
|
||||
|
||||
@@ -296,6 +296,8 @@ namespace tunnel
|
||||
|
||||
bool m_IsRunning;
|
||||
std::thread * m_Thread;
|
||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool;
|
||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
|
||||
std::map<uint32_t, std::shared_ptr<InboundTunnel> > m_PendingInboundTunnels; // by replyMsgID
|
||||
std::map<uint32_t, std::shared_ptr<OutboundTunnel> > m_PendingOutboundTunnels; // by replyMsgID
|
||||
std::list<std::shared_ptr<InboundTunnel> > m_InboundTunnels;
|
||||
@@ -306,8 +308,6 @@ namespace tunnel
|
||||
std::list<std::shared_ptr<TunnelPool>> m_Pools;
|
||||
std::shared_ptr<TunnelPool> m_ExploratoryPool;
|
||||
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_Queue;
|
||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_ENPOINT_MESSAGE_SIZE> > m_I2NPTunnelEndpointMessagesMemoryPool;
|
||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_TUNNEL_MESSAGE_SIZE> > m_I2NPTunnelMessagesMemoryPool;
|
||||
uint32_t m_MaxNumTransitTunnels;
|
||||
// count of tunnels for total TCSR algorithm
|
||||
int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations;
|
||||
|
||||
@@ -60,5 +60,12 @@ namespace tunnel
|
||||
msgs.swap (msgs1);
|
||||
SendMessagesTo (to, std::move (msgs1));
|
||||
}
|
||||
|
||||
void TunnelTransportSender::Reset ()
|
||||
{
|
||||
m_CurrentTransport.reset ();
|
||||
if (m_PendingTransport.valid ())
|
||||
m_PendingTransport = std::future<std::shared_ptr<i2p::transport::TransportSession> >();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@ namespace tunnel
|
||||
|
||||
void SendMessagesTo (const i2p::data::IdentHash& to, std::list<std::shared_ptr<I2NPMessage> >&& msgs);
|
||||
void SendMessagesTo (const i2p::data::IdentHash& to, std::list<std::shared_ptr<I2NPMessage> >& msgs); // send and clear
|
||||
|
||||
std::shared_ptr<const i2p::transport::TransportSession> GetCurrentTransport () const { return m_CurrentTransport.lock (); }
|
||||
void Reset ();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2023, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2024, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
@@ -21,10 +21,7 @@ namespace i2p
|
||||
{
|
||||
namespace tunnel
|
||||
{
|
||||
TunnelEndpoint::~TunnelEndpoint ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TunnelEndpoint::HandleDecryptedTunnelDataMsg (std::shared_ptr<I2NPMessage> msg)
|
||||
{
|
||||
m_NumReceivedBytes += TUNNEL_DATA_MSG_SIZE;
|
||||
@@ -331,13 +328,13 @@ namespace tunnel
|
||||
break;
|
||||
case eDeliveryTypeTunnel:
|
||||
if (!m_IsInbound) // outbound transit tunnel
|
||||
i2p::transport::transports.SendMessage (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data));
|
||||
SendMessageTo (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data));
|
||||
else
|
||||
LogPrint (eLogError, "TunnelMessage: Delivery type 'tunnel' arrived from an inbound tunnel, dropped");
|
||||
break;
|
||||
case eDeliveryTypeRouter:
|
||||
if (!m_IsInbound) // outbound transit tunnel
|
||||
i2p::transport::transports.SendMessage (msg.hash, msg.data);
|
||||
i2p::transport::transports.SendMessage (msg.hash, msg.data); // send right away, because most likely it's single message
|
||||
else // we shouldn't send this message. possible leakage
|
||||
LogPrint (eLogError, "TunnelMessage: Delivery type 'router' arrived from an inbound tunnel, dropped");
|
||||
break;
|
||||
@@ -366,5 +363,35 @@ namespace tunnel
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelEndpoint::SendMessageTo (const i2p::data::IdentHash& to, std::shared_ptr<i2p::I2NPMessage> msg)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
if (!m_Sender && m_I2NPMsgs.empty ()) // first message
|
||||
m_CurrentHash = to;
|
||||
else if (m_CurrentHash != to) // new target router
|
||||
{
|
||||
FlushI2NPMsgs (); // flush message to previous
|
||||
if (m_Sender) m_Sender->Reset (); // reset sender
|
||||
m_CurrentHash = to; // set new target router
|
||||
} // otherwise add msg to the list for current target router
|
||||
m_I2NPMsgs.push_back (msg);
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelEndpoint::FlushI2NPMsgs ()
|
||||
{
|
||||
if (!m_I2NPMsgs.empty ())
|
||||
{
|
||||
if (!m_Sender) m_Sender = std::make_unique<TunnelTransportSender>();
|
||||
m_Sender->SendMessagesTo (m_CurrentHash, m_I2NPMsgs); // send and clear
|
||||
}
|
||||
}
|
||||
|
||||
const i2p::data::IdentHash * TunnelEndpoint::GetCurrentHash () const
|
||||
{
|
||||
return (m_Sender || !m_I2NPMsgs.empty ()) ? &m_CurrentHash : nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2021, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2024, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
@@ -11,8 +11,10 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include "I2NPProtocol.h"
|
||||
#include "TunnelBase.h"
|
||||
|
||||
@@ -20,7 +22,7 @@ namespace i2p
|
||||
{
|
||||
namespace tunnel
|
||||
{
|
||||
class TunnelEndpoint
|
||||
class TunnelEndpoint final
|
||||
{
|
||||
struct TunnelMessageBlockEx: public TunnelMessageBlock
|
||||
{
|
||||
@@ -39,18 +41,23 @@ namespace tunnel
|
||||
public:
|
||||
|
||||
TunnelEndpoint (bool isInbound): m_IsInbound (isInbound), m_NumReceivedBytes (0), m_CurrentMsgID (0) {};
|
||||
~TunnelEndpoint ();
|
||||
~TunnelEndpoint () = default;
|
||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||
void Cleanup ();
|
||||
|
||||
void HandleDecryptedTunnelDataMsg (std::shared_ptr<I2NPMessage> msg);
|
||||
void FlushI2NPMsgs ();
|
||||
|
||||
const i2p::data::IdentHash * GetCurrentHash () const; // return null if not avaiable
|
||||
const std::unique_ptr<TunnelTransportSender>& GetSender () const { return m_Sender; };
|
||||
|
||||
private:
|
||||
|
||||
void HandleFollowOnFragment (uint32_t msgID, bool isLastFragment, uint8_t fragmentNum, const uint8_t * fragment, size_t size);
|
||||
bool ConcatFollowOnFragment (TunnelMessageBlockEx& msg, const uint8_t * fragment, size_t size) const; // true if success
|
||||
void HandleCurrenMessageFollowOnFragment (const uint8_t * fragment, size_t size, bool isLastFragment);
|
||||
void HandleNextMessage (const TunnelMessageBlock& msg);
|
||||
void SendMessageTo (const i2p::data::IdentHash& to, std::shared_ptr<i2p::I2NPMessage> msg);
|
||||
|
||||
void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, const uint8_t * fragment, size_t size);
|
||||
bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added
|
||||
@@ -65,6 +72,10 @@ namespace tunnel
|
||||
size_t m_NumReceivedBytes;
|
||||
TunnelMessageBlockEx m_CurrentMessage;
|
||||
uint32_t m_CurrentMsgID;
|
||||
// I2NP messages to send
|
||||
std::list<std::shared_ptr<i2p::I2NPMessage> > m_I2NPMsgs; // to send
|
||||
i2p::data::IdentHash m_CurrentHash; // send msgs to
|
||||
std::unique_ptr<TunnelTransportSender> m_Sender;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace tunnel
|
||||
void PutTunnelDataMsg (const TunnelMessageBlock& block);
|
||||
void SendBuffer ();
|
||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||
const std::unique_ptr<TunnelTransportSender>& GetSender () const { return m_Sender; };
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define MAKE_VERSION_NUMBER(a,b,c) ((a*100+b)*100+c)
|
||||
|
||||
#define I2PD_VERSION_MAJOR 2
|
||||
#define I2PD_VERSION_MINOR 54
|
||||
#define I2PD_VERSION_MINOR 55
|
||||
#define I2PD_VERSION_MICRO 0
|
||||
#define I2PD_VERSION_PATCH 0
|
||||
#ifdef GITVER
|
||||
|
||||
Reference in New Issue
Block a user