diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 570c5e56..b770de58 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -131,11 +131,17 @@ namespace transport void NTCPSession::ServerLogin () { - // receive Phase1 - 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 (); + boost::system::error_code ec; + auto ep = m_Socket.remote_endpoint(ec); + if (!ec) + { + m_ConnectedFrom = ep.address (); + // receive Phase1 + 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 (); + } } void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred) @@ -482,6 +488,7 @@ namespace transport if (ecode) { LogPrint (eLogError, "Read error: ", ecode.message ()); + if (!m_NumReceivedBytes) m_Server.Ban (m_ConnectedFrom); //if (ecode != boost::asio::error::operation_aborted) Terminate (); } @@ -857,7 +864,20 @@ namespace transport if (!ec) { LogPrint (eLogInfo, "Connected from ", ep); - conn->ServerLogin (); + auto it = m_BanList.find (ep.address ()); + if (it != m_BanList.end ()) + { + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + if (ts < it->second) + { + LogPrint (eLogInfo, ep.address (), " is banned for ", it->second - ts, " more seconds"); + conn = nullptr; + } + else + m_BanList.erase (it); + } + if (conn) + conn->ServerLogin (); } else LogPrint (eLogError, "Connected from error ", ec.message ()); @@ -923,5 +943,12 @@ namespace transport conn->ClientLogin (); } } + + void NTCPServer::Ban (const boost::asio::ip::address& addr) + { + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + m_BanList[addr] = ts + NTCP_BAN_EXPIRATION_TIMEOUT; + LogPrint (eLogInfo, addr, " has been banned for ", NTCP_BAN_EXPIRATION_TIMEOUT, " seconds"); + } } } diff --git a/NTCPSession.h b/NTCPSession.h index c264b7b0..608a2c7c 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -45,6 +45,7 @@ namespace transport const size_t NTCP_BUFFER_SIZE = 4160; // fits 4 tunnel messages (4*1028) const int NTCP_TERMINATION_TIMEOUT = 120; // 2 minutes 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 class NTCPServer; class NTCPSession: public TransportSession, public std::enable_shared_from_this @@ -138,6 +139,7 @@ namespace transport std::vector m_SendQueue; size_t m_NumSentBytes, m_NumReceivedBytes; + boost::asio::ip::address m_ConnectedFrom; // for ban }; // TODO: move to NTCP.h/.cpp @@ -157,7 +159,8 @@ namespace transport void Connect (const boost::asio::ip::address& address, int port, std::shared_ptr conn); boost::asio::io_service& GetService () { return m_Service; }; - + void Ban (const boost::asio::ip::address& addr); + private: void Run (); @@ -175,6 +178,7 @@ namespace transport boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor; std::mutex m_NTCPSessionsMutex; std::map > m_NTCPSessions; + std::map m_BanList; // IP -> ban expiration time in seconds public: