Browse Source

[SSU] handle ICMP responses

Windows network stack can forward ICMP to socket and simple deleting of
packet can cause socket death. Same thing can happen on other systems
but without socket death.

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/1564/head
R4SAS 4 years ago
parent
commit
3f45a11f12
Signed by: r4sas
GPG Key ID: 66F6C87B98EBCFE2
  1. 34
      libi2pd/SSU.cpp

34
libi2pd/SSU.cpp

@ -242,10 +242,16 @@ namespace transport @@ -242,10 +242,16 @@ namespace transport
void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to)
{
boost::system::error_code ec;
if (to.protocol () == boost::asio::ip::udp::v4())
m_Socket.send_to (boost::asio::buffer (buf, len), to);
m_Socket.send_to (boost::asio::buffer (buf, len), to, 0, ec);
else
m_SocketV6.send_to (boost::asio::buffer (buf, len), to);
m_SocketV6.send_to (boost::asio::buffer (buf, len), to, 0, ec);
if (ec)
{
LogPrint (eLogError, "SSU: send exception: ", ec.message (), " while trying to send data to ", to.address (), ":", to.port (), " (length: ", len, ")");
}
}
void SSUServer::Receive ()
@ -264,7 +270,13 @@ namespace transport @@ -264,7 +270,13 @@ namespace transport
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{
if (!ecode)
if (!ecode ||
ecode == boost::asio::error::connection_refused ||
ecode == boost::asio::error::connection_reset ||
ecode == boost::asio::error::network_unreachable ||
ecode == boost::asio::error::host_unreachable)
// just try continue reading when received ICMP response otherwise socket can crash,
// but better to find out which host were sent it and mark that router as unreachable
{
packet->len = bytes_transferred;
std::vector<SSUPacket *> packets;
@ -286,7 +298,7 @@ namespace transport @@ -286,7 +298,7 @@ namespace transport
}
else
{
LogPrint (eLogError, "SSU: receive_from error: ", ec.message ());
LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ());
delete packet;
break;
}
@ -301,7 +313,7 @@ namespace transport @@ -301,7 +313,7 @@ namespace transport
delete packet;
if (ecode != boost::asio::error::operation_aborted)
{
LogPrint (eLogError, "SSU: receive error: ", ecode.message ());
LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ());
m_Socket.close ();
OpenSocket ();
Receive ();
@ -311,7 +323,13 @@ namespace transport @@ -311,7 +323,13 @@ namespace transport
void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{
if (!ecode)
if (!ecode ||
ecode == boost::asio::error::connection_refused ||
ecode == boost::asio::error::connection_reset ||
ecode == boost::asio::error::network_unreachable ||
ecode == boost::asio::error::host_unreachable)
// just try continue reading when received ICMP response otherwise socket can crash,
// but better to find out which host were sent it and mark that router as unreachable
{
packet->len = bytes_transferred;
std::vector<SSUPacket *> packets;
@ -333,7 +351,7 @@ namespace transport @@ -333,7 +351,7 @@ namespace transport
}
else
{
LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ());
LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ());
delete packet;
break;
}
@ -348,7 +366,7 @@ namespace transport @@ -348,7 +366,7 @@ namespace transport
delete packet;
if (ecode != boost::asio::error::operation_aborted)
{
LogPrint (eLogError, "SSU: v6 receive error: ", ecode.message ());
LogPrint (eLogError, "SSU: v6 receive error: code ", ecode.value(), ": ", ecode.message ());
m_SocketV6.close ();
OpenSocketV6 ();
ReceiveV6 ();

Loading…
Cancel
Save