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
void SSUServer::Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to) 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()) 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 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 () void SSUServer::Receive ()
@ -264,7 +270,13 @@ namespace transport
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) 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; packet->len = bytes_transferred;
std::vector<SSUPacket *> packets; std::vector<SSUPacket *> packets;
@ -286,7 +298,7 @@ namespace transport
} }
else else
{ {
LogPrint (eLogError, "SSU: receive_from error: ", ec.message ()); LogPrint (eLogError, "SSU: receive_from error: code ", ec.value(), ": ", ec.message ());
delete packet; delete packet;
break; break;
} }
@ -301,7 +313,7 @@ namespace transport
delete packet; delete packet;
if (ecode != boost::asio::error::operation_aborted) 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 (); m_Socket.close ();
OpenSocket (); OpenSocket ();
Receive (); Receive ();
@ -311,7 +323,13 @@ namespace transport
void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) 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; packet->len = bytes_transferred;
std::vector<SSUPacket *> packets; std::vector<SSUPacket *> packets;
@ -333,7 +351,7 @@ namespace transport
} }
else else
{ {
LogPrint (eLogError, "SSU: v6 receive_from error: ", ec.message ()); LogPrint (eLogError, "SSU: v6 receive_from error: code ", ec.value(), ": ", ec.message ());
delete packet; delete packet;
break; break;
} }
@ -348,7 +366,7 @@ namespace transport
delete packet; delete packet;
if (ecode != boost::asio::error::operation_aborted) 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 (); m_SocketV6.close ();
OpenSocketV6 (); OpenSocketV6 ();
ReceiveV6 (); ReceiveV6 ();

Loading…
Cancel
Save