Browse Source

Merge pull request #1159 from majestrate/gut-streaming-limits

remove streaming bans
pull/1161/head
orignal 7 years ago committed by GitHub
parent
commit
413f8e8462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 82
      libi2pd/Streaming.cpp
  2. 36
      libi2pd/Streaming.h
  3. 4
      libi2pd_client/ClientContext.cpp
  4. 2
      libi2pd_client/I2PTunnel.h

82
libi2pd/Streaming.cpp

@ -903,11 +903,7 @@ namespace stream
StreamingDestination::StreamingDestination (std::shared_ptr<i2p::client::ClientDestination> owner, uint16_t localPort, bool gzip): StreamingDestination::StreamingDestination (std::shared_ptr<i2p::client::ClientDestination> owner, uint16_t localPort, bool gzip):
m_Owner (owner), m_LocalPort (localPort), m_Gzip (gzip), m_Owner (owner), m_LocalPort (localPort), m_Gzip (gzip),
m_LastIncomingReceiveStreamID (0), m_LastIncomingReceiveStreamID (0),
m_PendingIncomingTimer (m_Owner->GetService ()), m_PendingIncomingTimer (m_Owner->GetService ())
m_ConnTrackTimer(m_Owner->GetService()),
m_ConnsPerMinute(DEFAULT_MAX_CONNS_PER_MIN),
m_LastBanClear(i2p::util::GetMillisecondsSinceEpoch()),
m_EnableDrop(false)
{ {
} }
@ -923,7 +919,6 @@ namespace stream
void StreamingDestination::Start () void StreamingDestination::Start ()
{ {
ScheduleConnTrack();
} }
void StreamingDestination::Stop () void StreamingDestination::Stop ()
@ -931,15 +926,10 @@ namespace stream
ResetAcceptor (); ResetAcceptor ();
m_PendingIncomingTimer.cancel (); m_PendingIncomingTimer.cancel ();
m_PendingIncomingStreams.clear (); m_PendingIncomingStreams.clear ();
m_ConnTrackTimer.cancel();
{ {
std::unique_lock<std::mutex> l(m_StreamsMutex); std::unique_lock<std::mutex> l(m_StreamsMutex);
m_Streams.clear (); m_Streams.clear ();
} }
{
std::unique_lock<std::mutex> l(m_ConnsMutex);
m_Conns.clear ();
}
} }
void StreamingDestination::HandleNextPacket (Packet * packet) void StreamingDestination::HandleNextPacket (Packet * packet)
@ -971,17 +961,7 @@ namespace stream
auto incomingStream = CreateNewIncomingStream (); auto incomingStream = CreateNewIncomingStream ();
incomingStream->HandleNextPacket (packet); // SYN incomingStream->HandleNextPacket (packet); // SYN
auto ident = incomingStream->GetRemoteIdentity(); auto ident = incomingStream->GetRemoteIdentity();
if(ident && m_EnableDrop)
{
auto ih = ident->GetIdentHash();
if(DropNewStream(ih))
{
// drop
LogPrint(eLogWarning, "Streaming: Dropping connection, too many inbound streams from ", ih.ToBase32());
incomingStream->Terminate();
return;
}
}
m_LastIncomingReceiveStreamID = receiveStreamID; m_LastIncomingReceiveStreamID = receiveStreamID;
// handle saved packets if any // handle saved packets if any
@ -1176,63 +1156,5 @@ namespace stream
return msg; return msg;
} }
void StreamingDestination::SetMaxConnsPerMinute(const uint32_t conns)
{
m_EnableDrop = conns > 0;
m_ConnsPerMinute = conns;
LogPrint(eLogDebug, "Streaming: Set max conns per minute per destination to ", conns);
}
bool StreamingDestination::DropNewStream(const i2p::data::IdentHash & ih)
{
std::lock_guard<std::mutex> lock(m_ConnsMutex);
if (m_Banned.size() > MAX_BANNED_CONNS) return true; // overload
auto end = std::end(m_Banned);
if ( std::find(std::begin(m_Banned), end, ih) != end) return true; // already banned
auto itr = m_Conns.find(ih);
if (itr == m_Conns.end())
m_Conns[ih] = 0;
m_Conns[ih] += 1;
bool ban = m_Conns[ih] >= m_ConnsPerMinute;
if (ban)
{
m_Banned.push_back(ih);
m_Conns.erase(ih);
LogPrint(eLogWarning, "Streaming: ban ", ih.ToBase32());
}
return ban;
}
void StreamingDestination::HandleConnTrack(const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
{ // acquire lock
std::lock_guard<std::mutex> lock(m_ConnsMutex);
// clear conn tracking
m_Conns.clear();
// check for ban clear
auto ts = i2p::util::GetMillisecondsSinceEpoch();
if (ts - m_LastBanClear >= DEFAULT_BAN_INTERVAL)
{
// clear bans
m_Banned.clear();
m_LastBanClear = ts;
}
}
// reschedule timer
ScheduleConnTrack();
}
}
void StreamingDestination::ScheduleConnTrack()
{
m_ConnTrackTimer.expires_from_now (boost::posix_time::seconds(60));
m_ConnTrackTimer.async_wait (
std::bind (&StreamingDestination::HandleConnTrack,
shared_from_this (), std::placeholders::_1));
}
} }
} }

36
libi2pd/Streaming.h

@ -53,22 +53,6 @@ namespace stream
const int PENDING_INCOMING_TIMEOUT = 10; // in seconds const int PENDING_INCOMING_TIMEOUT = 10; // in seconds
const int MAX_RECEIVE_TIMEOUT = 30; // in seconds const int MAX_RECEIVE_TIMEOUT = 30; // in seconds
/** i2cp option for limiting inbound stremaing connections */
const char I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN[] = "maxconns";
/** default maximum connections attempts per minute per destination */
const uint32_t DEFAULT_MAX_CONNS_PER_MIN = 600;
/**
* max banned destinations per local destination
* TODO: make configurable
*/
const uint16_t MAX_BANNED_CONNS = 9999;
/**
* length of a ban in ms
* TODO: make configurable
*/
const uint64_t DEFAULT_BAN_INTERVAL = 60 * 60 * 1000;
struct Packet struct Packet
{ {
size_t len, offset; size_t len, offset;
@ -273,9 +257,6 @@ namespace stream
void HandleDataMessagePayload (const uint8_t * buf, size_t len); void HandleDataMessagePayload (const uint8_t * buf, size_t len);
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort); std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort);
/** set max connections per minute per destination */
void SetMaxConnsPerMinute(const uint32_t conns);
Packet * NewPacket () { return m_PacketsPool.Acquire(); } Packet * NewPacket () { return m_PacketsPool.Acquire(); }
void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); } void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); }
@ -286,13 +267,6 @@ namespace stream
std::shared_ptr<Stream> CreateNewIncomingStream (); std::shared_ptr<Stream> CreateNewIncomingStream ();
void HandlePendingIncomingTimer (const boost::system::error_code& ecode); void HandlePendingIncomingTimer (const boost::system::error_code& ecode);
/** handle cleaning up connection tracking for ratelimits */
void HandleConnTrack(const boost::system::error_code& ecode);
bool DropNewStream(const i2p::data::IdentHash & ident);
void ScheduleConnTrack();
private: private:
std::shared_ptr<i2p::client::ClientDestination> m_Owner; std::shared_ptr<i2p::client::ClientDestination> m_Owner;
@ -306,17 +280,7 @@ namespace stream
boost::asio::deadline_timer m_PendingIncomingTimer; boost::asio::deadline_timer m_PendingIncomingTimer;
std::map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN std::map<uint32_t, std::list<Packet *> > m_SavedPackets; // receiveStreamID->packets, arrived before SYN
std::mutex m_ConnsMutex;
/** how many connections per minute did each identity have */
std::map<i2p::data::IdentHash, uint32_t> m_Conns;
boost::asio::deadline_timer m_ConnTrackTimer;
uint32_t m_ConnsPerMinute;
/** banned identities */
std::vector<i2p::data::IdentHash> m_Banned;
uint64_t m_LastBanClear;
i2p::util::MemoryPool<Packet> m_PacketsPool; i2p::util::MemoryPool<Packet> m_PacketsPool;
bool m_EnableDrop;
public: public:

4
libi2pd_client/ClientContext.cpp

@ -567,7 +567,7 @@ namespace client
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL); i2p::data::CryptoKeyType cryptoType = section.second.get (I2P_CLIENT_TUNNEL_CRYPTO_TYPE, i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
@ -618,8 +618,6 @@ namespace client
else // regular server tunnel by default else // regular server tunnel by default
serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip); serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip);
LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns);
serverTunnel->SetMaxConnsPerMinute(maxConns);
if(!isUniqueLocal) if(!isUniqueLocal)
{ {
LogPrint(eLogInfo, "Clients: disabling loopback address mapping"); LogPrint(eLogInfo, "Clients: disabling loopback address mapping");

2
libi2pd_client/I2PTunnel.h

@ -280,8 +280,6 @@ namespace client
const char* GetName() { return m_Name.c_str (); } const char* GetName() { return m_Name.c_str (); }
void SetMaxConnsPerMinute(const uint32_t conns) { m_PortDestination->SetMaxConnsPerMinute(conns); }
private: private:
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver); std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);

Loading…
Cancel
Save