diff --git a/HTTPServer.cpp b/HTTPServer.cpp
index f10289ef..fdc5b38f 100644
--- a/HTTPServer.cpp
+++ b/HTTPServer.cpp
@@ -174,7 +174,7 @@ namespace http {
s << "Uptime: ";
ShowUptime(s, i2p::context.GetUptime ());
s << "
\r\n";
- s << "Status: ";
+ s << "Network status: ";
switch (i2p::context.GetStatus ())
{
case eRouterStatusOK: s << "OK"; break;
@@ -183,6 +183,13 @@ namespace http {
default: s << "Unknown";
}
s << "
\r\n";
+#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
+ if (auto remains = Daemon.gracefullShutdownInterval) {
+ s << "Stopping in: ";
+ s << remains << " seconds";
+ s << "
\r\n";
+ }
+#endif
auto family = i2p::context.GetFamily ();
if (family.length () > 0)
s << "Family: " << family << "
\r\n";
@@ -415,15 +422,9 @@ namespace http {
s << " Accept transit tunnels
\r\n";
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
if (Daemon.gracefullShutdownInterval)
- {
- s << " Cancel gracefull shutdown (";
- s << Daemon.gracefullShutdownInterval;
- s << " seconds remains)
\r\n";
- }
+ s << " Cancel gracefull shutdown";
else
- {
s << " Start gracefull shutdown
\r\n";
- }
#endif
#ifdef WIN32_APP
s << " Gracefull shutdown
\r\n";
diff --git a/Makefile.linux b/Makefile.linux
index 1376260a..b0549f43 100644
--- a/Makefile.linux
+++ b/Makefile.linux
@@ -28,15 +28,13 @@ endif
NEEDED_CXXFLAGS += -fPIC
ifeq ($(USE_STATIC),yes)
+# NOTE: on glibc you will get this warning:
+# Using 'getaddrinfo' in statically linked applications requires at runtime
+# the shared libraries from the glibc version used for linking
LIBDIR := /usr/lib
- LDLIBS = $(LIBDIR)/libboost_system.a
- LDLIBS += $(LIBDIR)/libboost_date_time.a
- LDLIBS += $(LIBDIR)/libboost_filesystem.a
- LDLIBS += $(LIBDIR)/libboost_program_options.a
- LDLIBS += $(LIBDIR)/libssl.a
- LDLIBS += $(LIBDIR)/libcrypto.a
- LDLIBS += $(LIBDIR)/libz.a
- LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt
+ LDLIBS = -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options
+ LDLIBS += -lssl -lcrypto -lz -ldl -lpthread -lrt
+ LDLIBS += -static-libstdc++ -static-libgcc -static
USE_AESNI := no
else
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
diff --git a/NTCPSession.cpp b/NTCPSession.cpp
index 2f99a772..1f177aa3 100644
--- a/NTCPSession.cpp
+++ b/NTCPSession.cpp
@@ -21,7 +21,7 @@ namespace transport
NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr in_RemoteRouter):
TransportSession (in_RemoteRouter, NTCP_TERMINATION_TIMEOUT),
m_Server (server), m_Socket (m_Server.GetService ()),
- m_TerminationTimer (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false),
+ m_IsEstablished (false), m_IsTerminated (false),
m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false)
{
m_Establisher = new Establisher;
@@ -78,7 +78,6 @@ namespace transport
m_Server.RemoveNTCPSession (shared_from_this ());
m_SendQueue.clear ();
m_NextMessage = nullptr;
- m_TerminationTimer.cancel ();
LogPrint (eLogDebug, "NTCP: session terminated");
}
}
@@ -110,7 +109,6 @@ namespace transport
boost::asio::async_write (m_Socket, boost::asio::buffer (&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase1Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
- ScheduleTermination ();
}
void NTCPSession::ServerLogin ()
@@ -124,7 +122,6 @@ namespace transport
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (),
std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
- ScheduleTermination ();
}
}
@@ -558,7 +555,7 @@ namespace transport
m_Handler.Flush ();
}
- ScheduleTermination (); // reset termination timer
+ m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
Receive ();
}
}
@@ -685,6 +682,7 @@ namespace transport
}
else
{
+ m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
m_NumSentBytes += bytes_transferred;
i2p::transport::transports.UpdateSentBytes (bytes_transferred);
if (!m_SendQueue.empty())
@@ -692,8 +690,6 @@ namespace transport
Send (m_SendQueue);
m_SendQueue.clear ();
}
- else
- ScheduleTermination (); // reset termination timer
}
}
@@ -728,29 +724,11 @@ namespace transport
else
Send (msgs);
}
-
- void NTCPSession::ScheduleTermination ()
- {
- m_TerminationTimer.cancel ();
- m_TerminationTimer.expires_from_now (boost::posix_time::seconds(GetTerminationTimeout ()));
- m_TerminationTimer.async_wait (std::bind (&NTCPSession::HandleTerminationTimer,
- shared_from_this (), std::placeholders::_1));
- }
-
- void NTCPSession::HandleTerminationTimer (const boost::system::error_code& ecode)
- {
- if (ecode != boost::asio::error::operation_aborted)
- {
- LogPrint (eLogDebug, "NTCP: No activity for ", GetTerminationTimeout (), " seconds");
- //Terminate ();
- m_Socket.close ();// invoke Terminate () from HandleReceive
- }
- }
//-----------------------------------------
NTCPServer::NTCPServer ():
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
- m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr)
+ m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr)
{
}
@@ -810,7 +788,8 @@ namespace transport
}
}
}
- }
+ }
+ ScheduleTermination ();
}
}
@@ -821,13 +800,17 @@ namespace transport
if (m_IsRunning)
{
m_IsRunning = false;
- if (m_NTCPAcceptor)
- delete m_NTCPAcceptor;
- m_NTCPAcceptor = nullptr;
- if (m_NTCPV6Acceptor)
- delete m_NTCPV6Acceptor;
- m_NTCPV6Acceptor = nullptr;
-
+ m_TerminationTimer.cancel ();
+ if (m_NTCPAcceptor)
+ {
+ delete m_NTCPAcceptor;
+ m_NTCPAcceptor = nullptr;
+ }
+ if (m_NTCPV6Acceptor)
+ {
+ delete m_NTCPV6Acceptor;
+ m_NTCPV6Acceptor = nullptr;
+ }
m_Service.stop ();
if (m_Thread)
{
@@ -991,5 +974,31 @@ namespace transport
m_BanList[addr] = ts + NTCP_BAN_EXPIRATION_TIMEOUT;
LogPrint (eLogWarning, "NTCP: ", addr, " has been banned for ", NTCP_BAN_EXPIRATION_TIMEOUT, " seconds");
}
+
+ void NTCPServer::ScheduleTermination ()
+ {
+ m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_CHECK_TIMEOUT));
+ m_TerminationTimer.async_wait (std::bind (&NTCPServer::HandleTerminationTimer,
+ this, std::placeholders::_1));
+ }
+
+ void NTCPServer::HandleTerminationTimer (const boost::system::error_code& ecode)
+ {
+ if (ecode != boost::asio::error::operation_aborted)
+ {
+ auto ts = i2p::util::GetSecondsSinceEpoch ();
+ for (auto& it: m_NTCPSessions)
+ if (it.second->IsTerminationTimeoutExpired (ts))
+ {
+ auto session = it.second;
+ m_Service.post ([session]
+ {
+ LogPrint (eLogDebug, "NTCP: No activity for ", session->GetTerminationTimeout (), " seconds");
+ session->Terminate ();
+ });
+ }
+ ScheduleTermination ();
+ }
+ }
}
}
diff --git a/NTCPSession.h b/NTCPSession.h
index 59b6bb58..a3d95c62 100644
--- a/NTCPSession.h
+++ b/NTCPSession.h
@@ -37,6 +37,7 @@ namespace transport
const size_t NTCP_MAX_MESSAGE_SIZE = 16384;
const size_t NTCP_BUFFER_SIZE = 4160; // fits 4 tunnel messages (4*1028)
const int NTCP_TERMINATION_TIMEOUT = 120; // 2 minutes
+ const int NTCP_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
const size_t NTCP_DEFAULT_PHASE3_SIZE = 2/*size*/ + i2p::data::DEFAULT_IDENTITY_SIZE/*387*/ + 4/*ts*/ + 15/*padding*/ + 40/*signature*/; // 448
const int NTCP_BAN_EXPIRATION_TIMEOUT = 70; // in second
const int NTCP_CLOCK_SKEW = 60; // in seconds
@@ -53,8 +54,8 @@ namespace transport
void Done ();
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
- bool IsEstablished () const { return m_IsEstablished; };
-
+ bool IsEstablished () const { return m_IsEstablished; };
+
void ClientLogin ();
void ServerLogin ();
void SendI2NPMessages (const std::vector >& msgs);
@@ -95,16 +96,10 @@ namespace transport
void Send (const std::vector >& msgs);
void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector > msgs);
-
- // timer
- void ScheduleTermination ();
- void HandleTerminationTimer (const boost::system::error_code& ecode);
-
private:
NTCPServer& m_Server;
boost::asio::ip::tcp::socket m_Socket;
- boost::asio::deadline_timer m_TerminationTimer;
bool m_IsEstablished, m_IsTerminated;
i2p::crypto::CBCDecryption m_Decryption;
@@ -146,8 +141,8 @@ namespace transport
std::shared_ptr FindNTCPSession (const i2p::data::IdentHash& ident);
void Connect (const boost::asio::ip::address& address, int port, std::shared_ptr conn);
- bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; };
- bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; };
+ bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; };
+ bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; };
boost::asio::io_service& GetService () { return m_Service; };
void Ban (const boost::asio::ip::address& addr);
@@ -159,6 +154,10 @@ namespace transport
void HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error);
void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr conn);
+
+ // timer
+ void ScheduleTermination ();
+ void HandleTerminationTimer (const boost::system::error_code& ecode);
private:
@@ -166,6 +165,7 @@ namespace transport
std::thread * m_Thread;
boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work;
+ boost::asio::deadline_timer m_TerminationTimer;
boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor;
std::map > m_NTCPSessions; // access from m_Thread only
std::map m_BanList; // IP -> ban expiration time in seconds
diff --git a/SSU.cpp b/SSU.cpp
index 0c3662d3..3d3fefdd 100644
--- a/SSU.cpp
+++ b/SSU.cpp
@@ -17,7 +17,8 @@ namespace transport
m_Work (m_Service), m_WorkV6 (m_ServiceV6), m_ReceiversWork (m_ReceiversService),
m_EndpointV6 (addr, port),
m_Socket (m_ReceiversService, m_Endpoint), m_SocketV6 (m_ReceiversService),
- m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service)
+ m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service),
+ m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6)
{
m_SocketV6.open (boost::asio::ip::udp::v6());
m_SocketV6.set_option (boost::asio::ip::v6_only (true));
@@ -32,7 +33,8 @@ namespace transport
m_Work (m_Service), m_WorkV6 (m_ServiceV6), m_ReceiversWork (m_ReceiversService),
m_Endpoint (boost::asio::ip::udp::v4 (), port), m_EndpointV6 (boost::asio::ip::udp::v6 (), port),
m_Socket (m_ReceiversService, m_Endpoint), m_SocketV6 (m_ReceiversService),
- m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service)
+ m_IntroducersUpdateTimer (m_Service), m_PeerTestsCleanupTimer (m_Service),
+ m_TerminationTimer (m_Service), m_TerminationTimerV6 (m_ServiceV6)
{
m_Socket.set_option (boost::asio::socket_base::receive_buffer_size (65535));
@@ -59,11 +61,13 @@ namespace transport
{
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
m_ReceiversService.post (std::bind (&SSUServer::Receive, this));
+ ScheduleTermination ();
}
if (context.SupportsV6 ())
{
m_ThreadV6 = new std::thread (std::bind (&SSUServer::RunV6, this));
m_ReceiversService.post (std::bind (&SSUServer::ReceiveV6, this));
+ ScheduleTerminationV6 ();
}
SchedulePeerTestsCleanupTimer ();
ScheduleIntroducersUpdateTimer (); // wait for 30 seconds and decide if we need introducers
@@ -640,6 +644,58 @@ namespace transport
SchedulePeerTestsCleanupTimer ();
}
}
+
+ void SSUServer::ScheduleTermination ()
+ {
+ m_TerminationTimer.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_CHECK_TIMEOUT));
+ m_TerminationTimer.async_wait (std::bind (&SSUServer::HandleTerminationTimer,
+ this, std::placeholders::_1));
+ }
+
+ void SSUServer::HandleTerminationTimer (const boost::system::error_code& ecode)
+ {
+ if (ecode != boost::asio::error::operation_aborted)
+ {
+ auto ts = i2p::util::GetSecondsSinceEpoch ();
+ for (auto& it: m_Sessions)
+ if (it.second->IsTerminationTimeoutExpired (ts))
+ {
+ auto session = it.second;
+ m_Service.post ([session]
+ {
+ LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
+ session->Failed ();
+ });
+ }
+ ScheduleTermination ();
+ }
+ }
+
+ void SSUServer::ScheduleTerminationV6 ()
+ {
+ m_TerminationTimerV6.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_CHECK_TIMEOUT));
+ m_TerminationTimerV6.async_wait (std::bind (&SSUServer::HandleTerminationTimerV6,
+ this, std::placeholders::_1));
+ }
+
+ void SSUServer::HandleTerminationTimerV6 (const boost::system::error_code& ecode)
+ {
+ if (ecode != boost::asio::error::operation_aborted)
+ {
+ auto ts = i2p::util::GetSecondsSinceEpoch ();
+ for (auto& it: m_SessionsV6)
+ if (it.second->IsTerminationTimeoutExpired (ts))
+ {
+ auto session = it.second;
+ m_ServiceV6.post ([session]
+ {
+ LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
+ session->Failed ();
+ });
+ }
+ ScheduleTerminationV6 ();
+ }
+ }
}
}
diff --git a/SSU.h b/SSU.h
index d779c025..182fa0eb 100644
--- a/SSU.h
+++ b/SSU.h
@@ -23,6 +23,7 @@ namespace transport
const int SSU_KEEP_ALIVE_INTERVAL = 30; // 30 seconds
const int SSU_PEER_TEST_TIMEOUT = 60; // 60 seconds
const int SSU_TO_INTRODUCER_SESSION_DURATION = 3600; // 1 hour
+ const int SSU_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds
const size_t SSU_MAX_NUM_INTRODUCERS = 3;
struct SSUPacket
@@ -90,6 +91,12 @@ namespace transport
void SchedulePeerTestsCleanupTimer ();
void HandlePeerTestsCleanupTimer (const boost::system::error_code& ecode);
+ // timer
+ void ScheduleTermination ();
+ void HandleTerminationTimer (const boost::system::error_code& ecode);
+ void ScheduleTerminationV6 ();
+ void HandleTerminationTimerV6 (const boost::system::error_code& ecode);
+
private:
struct PeerTest
@@ -106,7 +113,8 @@ namespace transport
boost::asio::io_service::work m_Work, m_WorkV6, m_ReceiversWork;
boost::asio::ip::udp::endpoint m_Endpoint, m_EndpointV6;
boost::asio::ip::udp::socket m_Socket, m_SocketV6;
- boost::asio::deadline_timer m_IntroducersUpdateTimer, m_PeerTestsCleanupTimer;
+ boost::asio::deadline_timer m_IntroducersUpdateTimer, m_PeerTestsCleanupTimer,
+ m_TerminationTimer, m_TerminationTimerV6;
std::list m_Introducers; // introducers we are connected to
std::map > m_Sessions, m_SessionsV6;
std::map m_Relays; // we are introducer
diff --git a/SSUSession.cpp b/SSUSession.cpp
index bf4058a5..9245f652 100644
--- a/SSUSession.cpp
+++ b/SSUSession.cpp
@@ -14,7 +14,7 @@ namespace transport
SSUSession::SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint,
std::shared_ptr router, bool peerTest ):
TransportSession (router, SSU_TERMINATION_TIMEOUT),
- m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_Timer (GetService ()),
+ m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_ConnectTimer (GetService ()),
m_IsPeerTest (peerTest),m_State (eSessionStateUnknown), m_IsSessionKey (false),
m_RelayTag (0),m_Data (*this), m_IsDataReceived (false)
{
@@ -97,7 +97,7 @@ namespace transport
{
if (!len) return; // ignore zero-length packets
if (m_State == eSessionStateEstablished)
- ScheduleTermination ();
+ m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
if (m_IsSessionKey && Validate (buf, len, m_MacKey)) // try session key first
DecryptSessionKey (buf, len);
@@ -229,7 +229,7 @@ namespace transport
}
LogPrint (eLogDebug, "SSU message: session created");
- m_Timer.cancel (); // connect timer
+ m_ConnectTimer.cancel (); // connect timer
SignedData s; // x,y, our IP, our port, remote IP, remote port, relayTag, signed on time
auto headerSize = GetSSUHeaderSize (buf);
if (headerSize >= len)
@@ -804,9 +804,9 @@ namespace transport
void SSUSession::ScheduleConnectTimer ()
{
- m_Timer.cancel ();
- m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
- m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
+ m_ConnectTimer.cancel ();
+ m_ConnectTimer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
+ m_ConnectTimer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
shared_from_this (), std::placeholders::_1));
}
@@ -826,8 +826,8 @@ namespace transport
if (m_State == eSessionStateUnknown)
{
// set connect timer
- m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
- m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
+ m_ConnectTimer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
+ m_ConnectTimer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
shared_from_this (), std::placeholders::_1));
}
uint32_t nonce;
@@ -840,8 +840,8 @@ namespace transport
{
m_State = eSessionStateIntroduced;
// set connect timer
- m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
- m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
+ m_ConnectTimer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
+ m_ConnectTimer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
shared_from_this (), std::placeholders::_1));
}
@@ -851,7 +851,7 @@ namespace transport
SendSesionDestroyed ();
transports.PeerDisconnected (shared_from_this ());
m_Data.Stop ();
- m_Timer.cancel ();
+ m_ConnectTimer.cancel ();
}
void SSUSession::Done ()
@@ -868,7 +868,7 @@ namespace transport
transports.PeerConnected (shared_from_this ());
if (m_IsPeerTest)
SendPeerTest ();
- ScheduleTermination ();
+ m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
}
void SSUSession::Failed ()
@@ -880,24 +880,6 @@ namespace transport
}
}
- void SSUSession::ScheduleTermination ()
- {
- m_Timer.cancel ();
- m_Timer.expires_from_now (boost::posix_time::seconds(GetTerminationTimeout ()));
- m_Timer.async_wait (std::bind (&SSUSession::HandleTerminationTimer,
- shared_from_this (), std::placeholders::_1));
- }
-
- void SSUSession::HandleTerminationTimer (const boost::system::error_code& ecode)
- {
- if (ecode != boost::asio::error::operation_aborted)
- {
- LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", GetTerminationTimeout (), " seconds");
- Failed ();
- }
- }
-
-
void SSUSession::SendI2NPMessages (const std::vector >& msgs)
{
GetService ().post (std::bind (&SSUSession::PostI2NPMessages, shared_from_this (), msgs));
@@ -1126,7 +1108,7 @@ namespace transport
FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48);
Send (buf, 48);
LogPrint (eLogDebug, "SSU: keep-alive sent");
- ScheduleTermination ();
+ m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
}
}
diff --git a/SSUSession.h b/SSUSession.h
index c2f24ce3..69669187 100644
--- a/SSUSession.h
+++ b/SSUSession.h
@@ -77,6 +77,7 @@ namespace transport
void WaitForIntroduction ();
void Close ();
void Done ();
+ void Failed ();
boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; };
bool IsV6 () const { return m_RemoteEndpoint.address ().is_v6 (); };
void SendI2NPMessages (const std::vector >& msgs);
@@ -114,7 +115,6 @@ namespace transport
void ProcessRelayResponse (const uint8_t * buf, size_t len);
void ProcessRelayIntro (const uint8_t * buf, size_t len);
void Established ();
- void Failed ();
void ScheduleConnectTimer ();
void HandleConnectTimer (const boost::system::error_code& ecode);
void ProcessPeerTest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
@@ -131,15 +131,12 @@ namespace transport
void DecryptSessionKey (uint8_t * buf, size_t len);
bool Validate (uint8_t * buf, size_t len, const i2p::crypto::MACKey& macKey);
- void ScheduleTermination ();
- void HandleTerminationTimer (const boost::system::error_code& ecode);
-
private:
friend class SSUData; // TODO: change in later
SSUServer& m_Server;
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
- boost::asio::deadline_timer m_Timer;
+ boost::asio::deadline_timer m_ConnectTimer;
bool m_IsPeerTest;
SessionState m_State;
bool m_IsSessionKey;
diff --git a/TransportSession.h b/TransportSession.h
index 1b057bc7..9c97d02e 100644
--- a/TransportSession.h
+++ b/TransportSession.h
@@ -9,6 +9,7 @@
#include "Crypto.h"
#include "RouterInfo.h"
#include "I2NPProtocol.h"
+#include "Timestamp.h"
namespace i2p
{
@@ -54,7 +55,8 @@ namespace transport
public:
TransportSession (std::shared_ptr router, int terminationTimeout):
- m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout)
+ m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout),
+ m_LastActivityTimestamp (i2p::util::GetSecondsSinceEpoch ())
{
if (router)
m_RemoteIdentity = router->GetRouterIdentity ();
@@ -72,6 +74,8 @@ namespace transport
int GetTerminationTimeout () const { return m_TerminationTimeout; };
void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; };
+ bool IsTerminationTimeoutExpired (uint64_t ts) const
+ { return ts >= m_LastActivityTimestamp + GetTerminationTimeout (); };
virtual void SendI2NPMessages (const std::vector >& msgs) = 0;
@@ -82,6 +86,7 @@ namespace transport
size_t m_NumSentBytes, m_NumReceivedBytes;
bool m_IsOutgoing;
int m_TerminationTimeout;
+ uint64_t m_LastActivityTimestamp;
};
}
}
diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt
index 99d6a5ad..f9f21fd4 100644
--- a/build/CMakeLists.txt
+++ b/build/CMakeLists.txt
@@ -357,7 +357,7 @@ if (WITH_BINARY)
endif ()
if (WITH_UPNP)
- target_link_libraries("${PROJECT_NAME}" "miniupnpc")
+ target_link_libraries("${PROJECT_NAME}" "${MINIUPNPC_LIBRARY}")
endif ()
# FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04
diff --git a/build/cmake_modules/FindMiniUPnPc.cmake b/build/cmake_modules/FindMiniUPnPc.cmake
index 8d5d3860..6a5d4220 100644
--- a/build/cmake_modules/FindMiniUPnPc.cmake
+++ b/build/cmake_modules/FindMiniUPnPc.cmake
@@ -1,6 +1,6 @@
# - Find MINIUPNPC
-if(MINIUPNPC_INCLUDE_DIR)
+if(MINIUPNPC_INCLUDE_DIR AND MINIUPNPC_LIBRARY)
set(MINIUPNPC_FOUND TRUE)
else()
@@ -11,15 +11,18 @@ else()
$ENV{SystemDrive}
${PROJECT_SOURCE_DIR}/../..
)
-
- if(MINIUPNPC_INCLUDE_DIR)
+
+ find_library(MINIUPNPC_LIBRARY miniupnpc)
+
+ if(MINIUPNPC_INCLUDE_DIR AND MINIUPNPC_LIBRARY)
set(MINIUPNPC_FOUND TRUE)
message(STATUS "Found MiniUPnP headers: ${MINIUPNPC_INCLUDE_DIR}")
+ message(STATUS "Found MiniUPnP library: ${MINIUPNPC_LIBRARY}")
else()
set(MINIUPNPC_FOUND FALSE)
message(STATUS "MiniUPnP not found.")
endif()
- mark_as_advanced(MINIUPNPC_INCLUDE_DIR)
+ mark_as_advanced(MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY)
endif()