forked from premiere/premiere-libtorrent
added abuse protection to DHT. nodes that hammer will be ignored
This commit is contained in:
parent
20621cae02
commit
a7f6e3bccb
|
@ -127,7 +127,20 @@ namespace libtorrent { namespace dht
|
||||||
|
|
||||||
// used to resolve hostnames for nodes
|
// used to resolve hostnames for nodes
|
||||||
udp::resolver m_host_resolver;
|
udp::resolver m_host_resolver;
|
||||||
|
|
||||||
|
// used to ignore abusive dht nodes
|
||||||
|
struct node_ban_entry
|
||||||
|
{
|
||||||
|
node_ban_entry(): count(0) {}
|
||||||
|
udp::endpoint src;
|
||||||
|
ptime limit;
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { num_ban_nodes = 20 };
|
||||||
|
|
||||||
|
node_ban_entry m_ban_nodes[num_ban_nodes];
|
||||||
|
|
||||||
// reference counter for intrusive_ptr
|
// reference counter for intrusive_ptr
|
||||||
mutable boost::detail::atomic_count m_refs;
|
mutable boost::detail::atomic_count m_refs;
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace libtorrent
|
||||||
time_duration operator/(int rhs) const { return time_duration(diff / rhs); }
|
time_duration operator/(int rhs) const { return time_duration(diff / rhs); }
|
||||||
explicit time_duration(boost::int64_t d) : diff(d) {}
|
explicit time_duration(boost::int64_t d) : diff(d) {}
|
||||||
time_duration& operator-=(time_duration const& c) { diff -= c.diff; return *this; }
|
time_duration& operator-=(time_duration const& c) { diff -= c.diff; return *this; }
|
||||||
|
time_duration operator+(time_duration const& c) { return time_duration(diff + c.diff); }
|
||||||
boost::int64_t diff;
|
boost::int64_t diff;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -405,6 +405,54 @@ namespace libtorrent { namespace dht
|
||||||
|
|
||||||
if (error) return;
|
if (error) return;
|
||||||
|
|
||||||
|
node_ban_entry* match = 0;
|
||||||
|
node_ban_entry* min = m_ban_nodes;
|
||||||
|
ptime now = time_now();
|
||||||
|
for (node_ban_entry* i = m_ban_nodes; i < m_ban_nodes + num_ban_nodes; ++i)
|
||||||
|
{
|
||||||
|
if (i->src == m_remote_endpoint[current_buffer])
|
||||||
|
{
|
||||||
|
match = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i->count < min->count) min = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
++match->count;
|
||||||
|
if (match->count >= 20)
|
||||||
|
{
|
||||||
|
if (now < match->limit)
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||||
|
if (match->count == 20)
|
||||||
|
{
|
||||||
|
TORRENT_LOG(dht_tracker) << time_now_string() << " BANNING PEER [ ip: "
|
||||||
|
<< m_remote_endpoint[current_buffer] << " | "
|
||||||
|
"time: " << total_seconds((now - match->limit) + seconds(5))
|
||||||
|
<< " | count: " << match->count << " ]";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// we've received 20 messages in less than 5 seconds from
|
||||||
|
// this node. Ignore it until it's silent for 5 minutes
|
||||||
|
match->limit = now + minutes(5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we got 50 messages from this peer, but it was in
|
||||||
|
// more than 5 seconds. Reset the counter and the timer
|
||||||
|
match->count = 0;
|
||||||
|
match->limit = now + seconds(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min->count = 1;
|
||||||
|
min->limit = now + seconds(5);
|
||||||
|
min->src = m_remote_endpoint[current_buffer];
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||||
++m_total_message_input;
|
++m_total_message_input;
|
||||||
m_total_in_bytes += bytes_transferred;
|
m_total_in_bytes += bytes_transferred;
|
||||||
|
|
Loading…
Reference in New Issue