update SSU2 introducers if Firewalled

pull/1786/head
orignal 2 years ago
parent 4a3e481a83
commit ea0ed9e844

@ -1321,7 +1321,7 @@ namespace data
size_t len = address.IsSSU2 () ? 32 : 16;
WriteString (address.i.ToBase64 (len), properties); properties << ';';
}
if (address.transportStyle == eTransportSSU || (address.IsSSU2 () && isPublished))
if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
{
// write introducers if any
if (address.ssu && !address.ssu->introducers.empty())

@ -21,7 +21,9 @@ namespace transport
RunnableServiceWithWork ("SSU2"), m_ReceiveService ("SSU2r"),
m_SocketV4 (m_ReceiveService.GetService ()), m_SocketV6 (m_ReceiveService.GetService ()),
m_AddressV4 (boost::asio::ip::address_v4()), m_AddressV6 (boost::asio::ip::address_v6()),
m_TerminationTimer (GetService ()), m_ResendTimer (GetService ())
m_TerminationTimer (GetService ()), m_ResendTimer (GetService ()),
m_IntroducersUpdateTimer (GetService ()), m_IntroducersUpdateTimerV6 (GetService ()),
m_IsPublished (true)
{
}
@ -30,6 +32,7 @@ namespace transport
if (!IsRunning ())
{
StartIOService ();
i2p::config::GetOption ("ssu2.published", m_IsPublished);
bool found = false;
auto& addresses = i2p::context.GetRouterInfo ().GetAddresses ();
for (const auto& address: addresses)
@ -59,6 +62,7 @@ namespace transport
{
Receive (m_SocketV4);
});
ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers
}
if (address->IsV6 ())
{
@ -69,6 +73,7 @@ namespace transport
{
Receive (m_SocketV6);
});
ScheduleIntroducersUpdateTimerV6 (); // wait for 30 seconds and decide if we need introducers
}
}
else
@ -827,6 +832,90 @@ namespace transport
}
}
}
}
void SSU2Server::ScheduleIntroducersUpdateTimer ()
{
if (m_IsPublished)
{
m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL));
m_IntroducersUpdateTimer.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer,
this, std::placeholders::_1, true));
}
}
void SSU2Server::RescheduleIntroducersUpdateTimer ()
{
if (m_IsPublished)
{
m_IntroducersUpdateTimer.cancel ();
m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL/2));
m_IntroducersUpdateTimer.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer,
this, std::placeholders::_1, true));
}
}
void SSU2Server::ScheduleIntroducersUpdateTimerV6 ()
{
if (m_IsPublished)
{
m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL));
m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer,
this, std::placeholders::_1, false));
}
}
void SSU2Server::RescheduleIntroducersUpdateTimerV6 ()
{
if (m_IsPublished)
{
m_IntroducersUpdateTimerV6.cancel ();
m_IntroducersUpdateTimerV6.expires_from_now (boost::posix_time::seconds(SSU2_KEEP_ALIVE_INTERVAL/2));
m_IntroducersUpdateTimerV6.async_wait (std::bind (&SSU2Server::HandleIntroducersUpdateTimer,
this, std::placeholders::_1, false));
}
}
void SSU2Server::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4)
{
if (ecode != boost::asio::error::operation_aborted)
{
// timeout expired
if (v4)
{
if (i2p::context.GetStatus () == eRouterStatusTesting)
{
// we still don't know if we need introducers
ScheduleIntroducersUpdateTimer ();
return;
}
if (i2p::context.GetStatus () != eRouterStatusFirewalled)
{
// we don't need introducers
m_Introducers.clear ();
return;
}
UpdateIntroducers (true);
ScheduleIntroducersUpdateTimer ();
}
else
{
if (i2p::context.GetStatusV6 () == eRouterStatusTesting)
{
// we still don't know if we need introducers
ScheduleIntroducersUpdateTimerV6 ();
return;
}
if (i2p::context.GetStatusV6 () != eRouterStatusFirewalled)
{
// we don't need introducers
m_IntroducersV6.clear ();
return;
}
UpdateIntroducers (false);
ScheduleIntroducersUpdateTimerV6 ();
}
}
}
}
}

@ -23,6 +23,7 @@ namespace transport
const size_t SSU2_MAX_NUM_INTRODUCERS = 3;
const int SSU2_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour
const int SSU2_TO_INTRODUCER_SESSION_EXPIRATION = 4800; // 80 minutes
const int SSU2_KEEP_ALIVE_INTERVAL = 30; // 30 seconds
class SSU2Server: private i2p::util::RunnableServiceWithWork
{
@ -82,7 +83,9 @@ namespace transport
uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep);
std::pair<uint64_t, uint32_t> NewIncomingToken (const boost::asio::ip::udp::endpoint& ep);
void RescheduleIntroducersUpdateTimer ();
void RescheduleIntroducersUpdateTimerV6 ();
private:
boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
@ -103,7 +106,10 @@ namespace transport
std::list<std::shared_ptr<SSU2Session> > FindIntroducers (int maxNumIntroducers,
bool v4, const std::set<i2p::data::IdentHash>& excluded) const;
void UpdateIntroducers (bool v4);
void ScheduleIntroducersUpdateTimer ();
void HandleIntroducersUpdateTimer (const boost::system::error_code& ecode, bool v4);
void ScheduleIntroducersUpdateTimerV6 ();
private:
ReceiveService m_ReceiveService;
@ -116,8 +122,10 @@ namespace transport
std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
std::list<std::shared_ptr<SSU2Session> > m_Introducers, m_IntroducersV6; // introducers we are connected to
i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer;
boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer,
m_IntroducersUpdateTimer, m_IntroducersUpdateTimerV6;
std::shared_ptr<SSU2Session> m_LastSession;
bool m_IsPublished; // if we maintain introducers
public:

@ -1831,7 +1831,13 @@ namespace transport
else
{
if (GetRouterStatus () == eRouterStatusTesting)
{
SetRouterStatus (eRouterStatusFirewalled);
if (m_Address->IsV4 ())
m_Server.RescheduleIntroducersUpdateTimer ();
else
m_Server.RescheduleIntroducersUpdateTimerV6 ();
}
}
}
else

Loading…
Cancel
Save