mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-23 13:24:20 +00:00
fix memory leak with udp tunnel
This commit is contained in:
parent
43c3bdf7c5
commit
577d9ddf65
31
Datagram.cpp
31
Datagram.cpp
@ -12,8 +12,10 @@ namespace i2p
|
|||||||
namespace datagram
|
namespace datagram
|
||||||
{
|
{
|
||||||
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
|
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
|
||||||
m_Owner (owner.get()), m_Receiver (nullptr)
|
m_Owner (owner.get()),
|
||||||
|
m_Receiver (nullptr)
|
||||||
{
|
{
|
||||||
|
m_Identity.FromBase64 (owner->GetIdentity()->ToBase64());
|
||||||
}
|
}
|
||||||
|
|
||||||
DatagramDestination::~DatagramDestination ()
|
DatagramDestination::~DatagramDestination ()
|
||||||
@ -24,16 +26,16 @@ namespace datagram
|
|||||||
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort)
|
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort)
|
||||||
{
|
{
|
||||||
auto owner = m_Owner;
|
auto owner = m_Owner;
|
||||||
auto i = owner->GetIdentity();
|
std::vector<uint8_t> v(MAX_DATAGRAM_SIZE);
|
||||||
uint8_t buf[MAX_DATAGRAM_SIZE];
|
uint8_t * buf = v.data();
|
||||||
auto identityLen = i->ToBuffer (buf, MAX_DATAGRAM_SIZE);
|
auto identityLen = m_Identity.ToBuffer (buf, MAX_DATAGRAM_SIZE);
|
||||||
uint8_t * signature = buf + identityLen;
|
uint8_t * signature = buf + identityLen;
|
||||||
auto signatureLen = i->GetSignatureLen ();
|
auto signatureLen = m_Identity.GetSignatureLen ();
|
||||||
uint8_t * buf1 = signature + signatureLen;
|
uint8_t * buf1 = signature + signatureLen;
|
||||||
size_t headerLen = identityLen + signatureLen;
|
size_t headerLen = identityLen + signatureLen;
|
||||||
|
|
||||||
memcpy (buf1, payload, len);
|
memcpy (buf1, payload, len);
|
||||||
if (i->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
if (m_Identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
||||||
{
|
{
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256(buf1, len, hash);
|
SHA256(buf1, len, hash);
|
||||||
@ -48,7 +50,7 @@ namespace datagram
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
|
||||||
{
|
{
|
||||||
i2p::data::IdentityEx identity;
|
i2p::data::IdentityEx identity;
|
||||||
size_t identityLen = identity.FromBuffer (buf, len);
|
size_t identityLen = identity.FromBuffer (buf, len);
|
||||||
@ -93,7 +95,7 @@ namespace datagram
|
|||||||
uint8_t uncompressed[MAX_DATAGRAM_SIZE];
|
uint8_t uncompressed[MAX_DATAGRAM_SIZE];
|
||||||
size_t uncompressedLen = m_Inflator.Inflate (buf, len, uncompressed, MAX_DATAGRAM_SIZE);
|
size_t uncompressedLen = m_Inflator.Inflate (buf, len, uncompressed, MAX_DATAGRAM_SIZE);
|
||||||
if (uncompressedLen)
|
if (uncompressedLen)
|
||||||
HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen);
|
HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
|
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
|
||||||
@ -121,7 +123,7 @@ namespace datagram
|
|||||||
if (m_Sessions.empty ()) return;
|
if (m_Sessions.empty ()) return;
|
||||||
auto now = i2p::util::GetMillisecondsSinceEpoch();
|
auto now = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
|
LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
|
||||||
std::lock_guard<std::mutex> lock(m_SessionsMutex);
|
std::unique_lock<std::mutex> lock(m_SessionsMutex);
|
||||||
// for each session ...
|
// for each session ...
|
||||||
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
|
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
|
||||||
{
|
{
|
||||||
@ -270,13 +272,16 @@ namespace datagram
|
|||||||
|
|
||||||
bool DatagramSession::ShouldUpdateRoutingPath() const
|
bool DatagramSession::ShouldUpdateRoutingPath() const
|
||||||
{
|
{
|
||||||
|
bool dead = m_RoutingSession == nullptr || m_RoutingSession->GetSharedRoutingPath () == nullptr;
|
||||||
auto now = i2p::util::GetMillisecondsSinceEpoch ();
|
auto now = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
// we need to rotate paths becuase the routing path is too old
|
// we need to rotate paths becuase the routing path is too old
|
||||||
if (now - m_LastPathChange >= DATAGRAM_SESSION_PATH_SWITCH_INTERVAL) return true;
|
// if (now - m_LastPathChange >= DATAGRAM_SESSION_PATH_SWITCH_INTERVAL) return true;
|
||||||
// our path looks dead so we need to rotate paths
|
// too fast switching paths
|
||||||
if (now - m_LastSuccess >= DATAGRAM_SESSION_PATH_TIMEOUT) return true;
|
if (now - m_LastPathChange < DATAGRAM_SESSION_PATH_MIN_LIFETIME ) return false;
|
||||||
|
// our path looks dead so we need to rotate paths
|
||||||
|
if (now - m_LastSuccess >= DATAGRAM_SESSION_PATH_TIMEOUT) return !dead;
|
||||||
// if we have a routing session and routing path we don't need to switch paths
|
// if we have a routing session and routing path we don't need to switch paths
|
||||||
return m_RoutingSession == nullptr || m_RoutingSession->GetSharedRoutingPath () == nullptr;
|
return dead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,13 +133,14 @@ namespace datagram
|
|||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
|
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
|
||||||
|
|
||||||
void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
|
||||||
|
|
||||||
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
|
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
|
||||||
Receiver FindReceiver(uint16_t port);
|
Receiver FindReceiver(uint16_t port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
i2p::client::ClientDestination * m_Owner;
|
i2p::client::ClientDestination * m_Owner;
|
||||||
|
i2p::data::IdentityEx m_Identity;
|
||||||
Receiver m_Receiver; // default
|
Receiver m_Receiver; // default
|
||||||
std::mutex m_SessionsMutex;
|
std::mutex m_SessionsMutex;
|
||||||
std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions;
|
std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions;
|
||||||
|
@ -559,23 +559,23 @@ namespace client
|
|||||||
}
|
}
|
||||||
/** create new udp session */
|
/** create new udp session */
|
||||||
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0);
|
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0);
|
||||||
m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_RemoteEndpoint, ih, localPort, remotePort));
|
m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort));
|
||||||
return m_Sessions.back();
|
return m_Sessions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||||
boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash to,
|
boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash * to,
|
||||||
uint16_t ourPort, uint16_t theirPort) :
|
uint16_t ourPort, uint16_t theirPort) :
|
||||||
m_Destination(localDestination->GetDatagramDestination()),
|
m_Destination(localDestination->GetDatagramDestination()),
|
||||||
m_Service(localDestination->GetService()),
|
m_Service(localDestination->GetService()),
|
||||||
IPSocket(localDestination->GetService(), localEndpoint),
|
IPSocket(localDestination->GetService(), localEndpoint),
|
||||||
Identity(to),
|
|
||||||
SendEndpoint(endpoint),
|
SendEndpoint(endpoint),
|
||||||
LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
||||||
LocalPort(ourPort),
|
LocalPort(ourPort),
|
||||||
RemotePort(theirPort)
|
RemotePort(theirPort)
|
||||||
{
|
{
|
||||||
|
memcpy(Identity, to->data(), 32);
|
||||||
Receive();
|
Receive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,13 +592,7 @@ namespace client
|
|||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint);
|
LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint);
|
||||||
LastActivity = i2p::util::GetMillisecondsSinceEpoch();
|
LastActivity = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
uint8_t * data = new uint8_t[len];
|
m_Destination->SendDatagramTo(m_Buffer, len, Identity, 0, 0);
|
||||||
memcpy(data, m_Buffer, len);
|
|
||||||
m_Service.post([&,len, data] () {
|
|
||||||
m_Destination->SendDatagramTo(data, len, Identity, 0, 0);
|
|
||||||
delete [] data;
|
|
||||||
});
|
|
||||||
|
|
||||||
Receive();
|
Receive();
|
||||||
} else {
|
} else {
|
||||||
LogPrint(eLogError, "UDPSession: ", ecode.message());
|
LogPrint(eLogError, "UDPSession: ", ecode.message());
|
||||||
@ -727,7 +721,7 @@ namespace client
|
|||||||
if(m_Session) delete m_Session;
|
if(m_Session) delete m_Session;
|
||||||
|
|
||||||
boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0);
|
boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0);
|
||||||
m_Session = new UDPSession(m_LocalEndpoint, m_LocalDest, ep, *m_RemoteIdent, LocalPort, RemotePort);
|
m_Session = new UDPSession(m_LocalEndpoint, m_LocalDest, ep, m_RemoteIdent, LocalPort, RemotePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t /*fromPort*/,
|
void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t /*fromPort*/,
|
||||||
|
@ -155,7 +155,7 @@ namespace client
|
|||||||
|
|
||||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash ident,
|
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
||||||
uint16_t ourPort, uint16_t theirPort);
|
uint16_t ourPort, uint16_t theirPort);
|
||||||
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
||||||
void Receive();
|
void Receive();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user