mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-18 04:19:58 +00:00
SSU2: check if socket is opened before sending data, handle network_reset error
Signed-off-by: r4sas <r4sas@i2pmail.org>
This commit is contained in:
parent
dc6a42c26f
commit
ae439b5385
@ -30,7 +30,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
return boost::posix_time::second_clock::local_time();
|
return boost::posix_time::second_clock::local_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
RouterProfile::RouterProfile ():
|
RouterProfile::RouterProfile ():
|
||||||
m_LastUpdateTime (GetTime ()), m_IsUpdated (false),
|
m_LastUpdateTime (GetTime ()), m_IsUpdated (false),
|
||||||
m_LastDeclineTime (0), m_LastUnreachableTime (0),
|
m_LastDeclineTime (0), m_LastUnreachableTime (0),
|
||||||
@ -175,8 +175,8 @@ namespace data
|
|||||||
{
|
{
|
||||||
m_HasConnected = true;
|
m_HasConnected = true;
|
||||||
UpdateTime ();
|
UpdateTime ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterProfile::IsLowPartcipationRate () const
|
bool RouterProfile::IsLowPartcipationRate () const
|
||||||
{
|
{
|
||||||
return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate
|
return 4*m_NumTunnelsAgreed < m_NumTunnelsDeclined; // < 20% rate
|
||||||
@ -223,7 +223,7 @@ namespace data
|
|||||||
m_LastUnreachableTime = 0;
|
m_LastUnreachableTime = 0;
|
||||||
return (bool)m_LastUnreachableTime;
|
return (bool)m_LastUnreachableTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterProfile::IsUseful() const {
|
bool RouterProfile::IsUseful() const {
|
||||||
return
|
return
|
||||||
m_NumTunnelsAgreed >= PEER_PROFILE_USEFUL_THRESHOLD ||
|
m_NumTunnelsAgreed >= PEER_PROFILE_USEFUL_THRESHOLD ||
|
||||||
@ -240,7 +240,7 @@ namespace data
|
|||||||
auto it = g_Profiles.find (identHash);
|
auto it = g_Profiles.find (identHash);
|
||||||
if (it != g_Profiles.end ())
|
if (it != g_Profiles.end ())
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
auto profile = std::make_shared<RouterProfile> ();
|
auto profile = std::make_shared<RouterProfile> ();
|
||||||
profile->Load (identHash); // if possible
|
profile->Load (identHash); // if possible
|
||||||
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
||||||
@ -261,7 +261,7 @@ namespace data
|
|||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
||||||
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
||||||
{
|
{
|
||||||
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL)
|
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL)
|
||||||
{
|
{
|
||||||
if (it->second->IsUpdated ())
|
if (it->second->IsUpdated ())
|
||||||
@ -270,11 +270,11 @@ namespace data
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& it: tmp)
|
for (auto& it: tmp)
|
||||||
if (it.second) it.second->Save (it.first);
|
if (it.second) it.second->Save (it.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveProfiles ()
|
void SaveProfiles ()
|
||||||
{
|
{
|
||||||
@ -288,22 +288,22 @@ namespace data
|
|||||||
for (auto& it: tmp)
|
for (auto& it: tmp)
|
||||||
if (it.second->IsUseful() && it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
|
if (it.second->IsUseful() && it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
|
||||||
it.second->Save (it.first);
|
it.second->Save (it.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteObsoleteProfiles ()
|
void DeleteObsoleteProfiles ()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto ts = GetTime ();
|
auto ts = GetTime ();
|
||||||
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
std::unique_lock<std::mutex> l(g_ProfilesMutex);
|
||||||
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
|
||||||
{
|
{
|
||||||
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
|
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
|
||||||
it = g_Profiles.erase (it);
|
it = g_Profiles.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
std::time_t now = std::time(nullptr);
|
std::time_t now = std::time(nullptr);
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ namespace transport
|
|||||||
if (address->IsV4 ())
|
if (address->IsV4 ())
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
|
LogPrint (eLogDebug, "SSU2: Opening IPv4 socket at Start");
|
||||||
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV4, port));
|
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV4, port));
|
||||||
m_ReceiveService.GetService ().post(
|
m_ReceiveService.GetService ().post(
|
||||||
[this]()
|
[this]()
|
||||||
@ -89,6 +90,7 @@ namespace transport
|
|||||||
if (address->IsV6 ())
|
if (address->IsV6 ())
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
|
LogPrint (eLogDebug, "SSU2: Opening IPv6 socket at Start");
|
||||||
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV6, port));
|
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV6, port));
|
||||||
m_ReceiveService.GetService ().post(
|
m_ReceiveService.GetService ().post(
|
||||||
[this]()
|
[this]()
|
||||||
@ -243,10 +245,12 @@ namespace transport
|
|||||||
if (!ecode
|
if (!ecode
|
||||||
|| ecode == boost::asio::error::connection_refused
|
|| ecode == boost::asio::error::connection_refused
|
||||||
|| ecode == boost::asio::error::connection_reset
|
|| ecode == boost::asio::error::connection_reset
|
||||||
|
|| ecode == boost::asio::error::network_reset
|
||||||
|| ecode == boost::asio::error::network_unreachable
|
|| ecode == boost::asio::error::network_unreachable
|
||||||
|| ecode == boost::asio::error::host_unreachable
|
|| ecode == boost::asio::error::host_unreachable
|
||||||
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
|
||||||
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
|
|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
|
||||||
|
|| ecode.value() == boost::winapi::WSAENETRESET_ // 10052
|
||||||
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|
||||||
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
|
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
|
||||||
#endif
|
#endif
|
||||||
@ -303,7 +307,7 @@ namespace transport
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto ep = socket.local_endpoint ();
|
auto ep = socket.local_endpoint ();
|
||||||
socket.close ();
|
LogPrint (eLogCritical, "SSU2: Reopening socket in HandleReceivedFrom: code ", ecode.value(), ": ", ecode.message ());
|
||||||
OpenSocket (ep);
|
OpenSocket (ep);
|
||||||
Receive (socket);
|
Receive (socket);
|
||||||
}
|
}
|
||||||
@ -558,16 +562,25 @@ namespace transport
|
|||||||
SendThroughProxy (header, headerLen, nullptr, 0, payload, payloadLen, to);
|
SendThroughProxy (header, headerLen, nullptr, 0, payload, payloadLen, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<boost::asio::const_buffer> bufs
|
std::vector<boost::asio::const_buffer> bufs
|
||||||
{
|
{
|
||||||
boost::asio::buffer (header, headerLen),
|
boost::asio::buffer (header, headerLen),
|
||||||
boost::asio::buffer (payload, payloadLen)
|
boost::asio::buffer (payload, payloadLen)
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
if (to.address ().is_v6 ())
|
if (to.address ().is_v6 ())
|
||||||
|
{
|
||||||
|
if (!m_SocketV6.is_open ()) return;
|
||||||
m_SocketV6.send_to (bufs, to, 0, ec);
|
m_SocketV6.send_to (bufs, to, 0, ec);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!m_SocketV4.is_open ()) return;
|
||||||
m_SocketV4.send_to (bufs, to, 0, ec);
|
m_SocketV4.send_to (bufs, to, 0, ec);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ec)
|
if (!ec)
|
||||||
i2p::transport::transports.UpdateSentBytes (headerLen + payloadLen);
|
i2p::transport::transports.UpdateSentBytes (headerLen + payloadLen);
|
||||||
else
|
else
|
||||||
@ -582,17 +595,25 @@ namespace transport
|
|||||||
SendThroughProxy (header, headerLen, headerX, headerXLen, payload, payloadLen, to);
|
SendThroughProxy (header, headerLen, headerX, headerXLen, payload, payloadLen, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<boost::asio::const_buffer> bufs
|
std::vector<boost::asio::const_buffer> bufs
|
||||||
{
|
{
|
||||||
boost::asio::buffer (header, headerLen),
|
boost::asio::buffer (header, headerLen),
|
||||||
boost::asio::buffer (headerX, headerXLen),
|
boost::asio::buffer (headerX, headerXLen),
|
||||||
boost::asio::buffer (payload, payloadLen)
|
boost::asio::buffer (payload, payloadLen)
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
if (to.address ().is_v6 ())
|
if (to.address ().is_v6 ())
|
||||||
|
{
|
||||||
|
if (!m_SocketV6.is_open ()) return;
|
||||||
m_SocketV6.send_to (bufs, to, 0, ec);
|
m_SocketV6.send_to (bufs, to, 0, ec);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!m_SocketV4.is_open ()) return;
|
||||||
m_SocketV4.send_to (bufs, to, 0, ec);
|
m_SocketV4.send_to (bufs, to, 0, ec);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ec)
|
if (!ec)
|
||||||
i2p::transport::transports.UpdateSentBytes (headerLen + headerXLen + payloadLen);
|
i2p::transport::transports.UpdateSentBytes (headerLen + headerXLen + payloadLen);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user