removed dht ping from peer_from_tracker. in trunk: implemented a rate limited DHT ping (once a second per torrent) and space optimized the peer structure
This commit is contained in:
@@ -139,43 +139,9 @@ namespace libtorrent
|
|||||||
tcp::endpoint ip;
|
tcp::endpoint ip;
|
||||||
connection_type type;
|
connection_type type;
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
// the number of failed connection attempts
|
||||||
// Hints encryption support of peer. Only effective for
|
// this peer has
|
||||||
// and when the outgoing encryption policy allows both
|
boost::uint8_t failcount;
|
||||||
// encrypted and non encrypted connections
|
|
||||||
// (pe_settings::out_enc_policy == enabled). The initial
|
|
||||||
// state of this flag determines the initial connection
|
|
||||||
// attempt type (true = encrypted, false = standard).
|
|
||||||
// This will be toggled everytime either an encrypted or
|
|
||||||
// non-encrypted handshake fails.
|
|
||||||
bool pe_support;
|
|
||||||
#endif
|
|
||||||
// the number of failed connection attempts this peer has
|
|
||||||
int failcount;
|
|
||||||
|
|
||||||
// the number of times this peer has been
|
|
||||||
// part of a piece that failed the hash check
|
|
||||||
int hashfails;
|
|
||||||
|
|
||||||
// this is true if the peer is a seed
|
|
||||||
bool seed;
|
|
||||||
|
|
||||||
int fast_reconnects;
|
|
||||||
|
|
||||||
// true if this peer currently is unchoked
|
|
||||||
// because of an optimistic unchoke.
|
|
||||||
// when the optimistic unchoke is moved to
|
|
||||||
// another peer, this peer will be choked
|
|
||||||
// if this is true
|
|
||||||
bool optimistically_unchoked;
|
|
||||||
|
|
||||||
// the time when this peer was optimistically unchoked
|
|
||||||
// the last time.
|
|
||||||
libtorrent::ptime last_optimistically_unchoked;
|
|
||||||
|
|
||||||
// the time when the peer connected to us
|
|
||||||
// or disconnected if it isn't connected right now
|
|
||||||
libtorrent::ptime connected;
|
|
||||||
|
|
||||||
// for every valid piece we receive where this
|
// for every valid piece we receive where this
|
||||||
// peer was one of the participants, we increase
|
// peer was one of the participants, we increase
|
||||||
@@ -183,15 +149,63 @@ namespace libtorrent
|
|||||||
// where this peer was a participant, we decrease
|
// where this peer was a participant, we decrease
|
||||||
// this value. If it sinks below a threshold, its
|
// this value. If it sinks below a threshold, its
|
||||||
// considered a bad peer and will be banned.
|
// considered a bad peer and will be banned.
|
||||||
int trust_points;
|
boost::int8_t trust_points;
|
||||||
|
|
||||||
// if this is true, the peer has previously participated
|
// a bitmap combining the peer_source flags
|
||||||
// in a piece that failed the piece hash check. This will
|
// from peer_info.
|
||||||
// put the peer on parole and only request entire pieces.
|
boost::uint8_t source;
|
||||||
// if a piece pass that was partially requested from this
|
|
||||||
// peer it will leave parole mode and continue download
|
// the number of times this peer has been
|
||||||
|
// part of a piece that failed the hash check
|
||||||
|
boost::uint8_t hashfails;
|
||||||
|
|
||||||
|
// the number of times we have allowed a fast
|
||||||
|
// reconnect for this peer.
|
||||||
|
boost::uint8_t fast_reconnects:4;
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
// Hints encryption support of peer. Only effective
|
||||||
|
// for and when the outgoing encryption policy
|
||||||
|
// allows both encrypted and non encrypted
|
||||||
|
// connections (pe_settings::out_enc_policy
|
||||||
|
// == enabled). The initial state of this flag
|
||||||
|
// determines the initial connection attempt
|
||||||
|
// type (true = encrypted, false = standard).
|
||||||
|
// This will be toggled everytime either an
|
||||||
|
// encrypted or non-encrypted handshake fails.
|
||||||
|
bool pe_support:1;
|
||||||
|
#endif
|
||||||
|
// true if this peer currently is unchoked
|
||||||
|
// because of an optimistic unchoke.
|
||||||
|
// when the optimistic unchoke is moved to
|
||||||
|
// another peer, this peer will be choked
|
||||||
|
// if this is true
|
||||||
|
bool optimistically_unchoked:1;
|
||||||
|
|
||||||
|
// this is true if the peer is a seed
|
||||||
|
bool seed:1;
|
||||||
|
|
||||||
|
// if this is true, the peer has previously
|
||||||
|
// participated in a piece that failed the piece
|
||||||
|
// hash check. This will put the peer on parole
|
||||||
|
// and only request entire pieces. If a piece pass
|
||||||
|
// that was partially requested from this peer it
|
||||||
|
// will leave parole mode and continue download
|
||||||
// pieces as normal peers.
|
// pieces as normal peers.
|
||||||
bool on_parole;
|
bool on_parole:1;
|
||||||
|
|
||||||
|
// is set to true if this peer has been banned
|
||||||
|
bool banned:1;
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
// this is set to true when this peer as been
|
||||||
|
// pinged by the DHT
|
||||||
|
bool added_to_dht:1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// if the peer is connected now, this
|
||||||
|
// will refer to a valid peer_connection
|
||||||
|
peer_connection* connection;
|
||||||
|
|
||||||
// this is the accumulated amount of
|
// this is the accumulated amount of
|
||||||
// uploaded and downloaded data to this
|
// uploaded and downloaded data to this
|
||||||
@@ -205,16 +219,13 @@ namespace libtorrent
|
|||||||
size_type prev_amount_upload;
|
size_type prev_amount_upload;
|
||||||
size_type prev_amount_download;
|
size_type prev_amount_download;
|
||||||
|
|
||||||
// is set to true if this peer has been banned
|
// the time when this peer was optimistically unchoked
|
||||||
bool banned;
|
// the last time.
|
||||||
|
libtorrent::ptime last_optimistically_unchoked;
|
||||||
|
|
||||||
// a bitmap combining the peer_source flags
|
// the time when the peer connected to us
|
||||||
// from peer_info.
|
// or disconnected if it isn't connected right now
|
||||||
int source;
|
libtorrent::ptime connected;
|
||||||
|
|
||||||
// if the peer is connected now, this
|
|
||||||
// will refer to a valid peer_connection
|
|
||||||
peer_connection* connection;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int num_peers() const { return m_peers.size(); }
|
int num_peers() const { return m_peers.size(); }
|
||||||
@@ -231,6 +242,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
bool has_peer(policy::peer const* p) const;
|
bool has_peer(policy::peer const* p) const;
|
||||||
|
|
||||||
|
int num_seeds() const { return m_num_seeds; }
|
||||||
int num_connect_candidates() const { return m_num_connect_candidates; }
|
int num_connect_candidates() const { return m_num_connect_candidates; }
|
||||||
void recalculate_connect_candidates()
|
void recalculate_connect_candidates()
|
||||||
{
|
{
|
||||||
@@ -260,6 +272,9 @@ namespace libtorrent
|
|||||||
// have the connectable state (we have a listen
|
// have the connectable state (we have a listen
|
||||||
// port for them).
|
// port for them).
|
||||||
int m_num_connect_candidates;
|
int m_num_connect_candidates;
|
||||||
|
|
||||||
|
// the number of seeds in the peer list
|
||||||
|
int m_num_seeds;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -456,12 +456,13 @@ namespace libtorrent
|
|||||||
|
|
||||||
void peer_connection::fast_reconnect(bool r)
|
void peer_connection::fast_reconnect(bool r)
|
||||||
{
|
{
|
||||||
if (peer_info_struct() && peer_info_struct()->fast_reconnects > 1) return;
|
if (!peer_info_struct() || peer_info_struct()->fast_reconnects > 1)
|
||||||
|
return;
|
||||||
m_fast_reconnect = r;
|
m_fast_reconnect = r;
|
||||||
peer_info_struct()->connected = time_now()
|
peer_info_struct()->connected = time_now()
|
||||||
- seconds(m_ses.settings().min_reconnect_time
|
- seconds(m_ses.settings().min_reconnect_time
|
||||||
* m_ses.settings().max_failcount);
|
* m_ses.settings().max_failcount);
|
||||||
if (peer_info_struct()) ++peer_info_struct()->fast_reconnects;
|
++peer_info_struct()->fast_reconnects;
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::announce_piece(int index)
|
void peer_connection::announce_piece(int index)
|
||||||
@@ -565,7 +566,7 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
peer_info_struct()->on_parole = true;
|
peer_info_struct()->on_parole = true;
|
||||||
++peer_info_struct()->hashfails;
|
++peer_info_struct()->hashfails;
|
||||||
int& trust_points = peer_info_struct()->trust_points;
|
boost::int8_t& trust_points = peer_info_struct()->trust_points;
|
||||||
|
|
||||||
// we decrease more than we increase, to keep the
|
// we decrease more than we increase, to keep the
|
||||||
// allowed failed/passed ratio low.
|
// allowed failed/passed ratio low.
|
||||||
|
@@ -385,6 +385,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p) p->clear_peer(&i->second);
|
if (p) p->clear_peer(&i->second);
|
||||||
|
if (i->second.seed) --m_num_seeds;
|
||||||
m_peers.erase(i++);
|
m_peers.erase(i++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,8 +472,10 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
int connect_candidates = 0;
|
int connect_candidates = 0;
|
||||||
|
int seeds = 0;
|
||||||
for (iterator i = m_peers.begin(); i != m_peers.end(); ++i)
|
for (iterator i = m_peers.begin(); i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
|
if (i->second.seed) ++seeds;
|
||||||
if (!is_connect_candidate(i->second, finished)) continue;
|
if (!is_connect_candidate(i->second, finished)) continue;
|
||||||
++connect_candidates;
|
++connect_candidates;
|
||||||
|
|
||||||
@@ -504,6 +507,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_num_connect_candidates = connect_candidates;
|
m_num_connect_candidates = connect_candidates;
|
||||||
|
m_num_seeds = seeds;
|
||||||
TORRENT_ASSERT(min_connect_time <= now);
|
TORRENT_ASSERT(min_connect_time <= now);
|
||||||
|
|
||||||
#if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
|
#if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
|
||||||
@@ -532,19 +536,37 @@ namespace libtorrent
|
|||||||
if (m_torrent->has_picker())
|
if (m_torrent->has_picker())
|
||||||
p = &m_torrent->picker();
|
p = &m_torrent->picker();
|
||||||
|
|
||||||
|
bool pinged = false;
|
||||||
|
|
||||||
ptime now = time_now();
|
ptime now = time_now();
|
||||||
// remove old disconnected peers from the list
|
// remove old disconnected peers from the list
|
||||||
for (iterator i = m_peers.begin(); i != m_peers.end();)
|
for (iterator i = m_peers.begin(); i != m_peers.end();)
|
||||||
{
|
{
|
||||||
|
peer& pe = i->second;
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
// try to send a DHT ping to this peer
|
||||||
|
// as well, to figure out if it supports
|
||||||
|
// DHT (uTorrent and BitComet doesn't
|
||||||
|
// advertise support)
|
||||||
|
if (!pinged && !pe.added_to_dht)
|
||||||
|
{
|
||||||
|
udp::endpoint node(pe.ip.address(), pe.ip.port());
|
||||||
|
m_torrent->session().add_dht_node(node);
|
||||||
|
pe.added_to_dht = true;
|
||||||
|
pinged = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// this timeout has to be customizable!
|
// this timeout has to be customizable!
|
||||||
// don't remove banned peers, they should
|
// don't remove banned peers, they should
|
||||||
// remain banned
|
// remain banned
|
||||||
if (i->second.connection == 0
|
if (pe.connection == 0
|
||||||
&& i->second.connected != min_time()
|
&& pe.connected != min_time()
|
||||||
&& !i->second.banned
|
&& !pe.banned
|
||||||
&& now - i->second.connected > minutes(120))
|
&& now - pe.connected > minutes(120))
|
||||||
{
|
{
|
||||||
if (p) p->clear_peer(&i->second);
|
if (p) p->clear_peer(&pe);
|
||||||
|
if (pe.seed) --m_num_seeds;
|
||||||
m_peers.erase(i++);
|
m_peers.erase(i++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -770,6 +792,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
if (m_torrent->has_picker())
|
if (m_torrent->has_picker())
|
||||||
m_torrent->picker().clear_peer(&i->second);
|
m_torrent->picker().clear_peer(&i->second);
|
||||||
|
if (i->second.seed) --m_num_seeds;
|
||||||
m_peers.erase(i);
|
m_peers.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -851,16 +874,11 @@ namespace libtorrent
|
|||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
if (flags & 0x01) i->second.pe_support = true;
|
if (flags & 0x01) i->second.pe_support = true;
|
||||||
#endif
|
#endif
|
||||||
if (flags & 0x02) i->second.seed = true;
|
if (flags & 0x02)
|
||||||
|
{
|
||||||
// try to send a DHT ping to this peer
|
i->second.seed = true;
|
||||||
// as well, to figure out if it supports
|
++m_num_seeds;
|
||||||
// DHT (uTorrent and BitComet doesn't
|
}
|
||||||
// advertise support)
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
|
||||||
udp::endpoint node(remote.address(), remote.port());
|
|
||||||
m_torrent->session().add_dht_node(node);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -879,7 +897,11 @@ namespace libtorrent
|
|||||||
// if we're connected to this peer
|
// if we're connected to this peer
|
||||||
// we already know if it's a seed or not
|
// we already know if it's a seed or not
|
||||||
// so we don't have to trust this source
|
// so we don't have to trust this source
|
||||||
if ((flags & 0x02) && !i->second.connection) i->second.seed = true;
|
if ((flags & 0x02) && !i->second.connection)
|
||||||
|
{
|
||||||
|
if (!i->second.seed) ++m_num_seeds;
|
||||||
|
i->second.seed = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
||||||
if (i->second.connection)
|
if (i->second.connection)
|
||||||
@@ -1295,24 +1317,28 @@ namespace libtorrent
|
|||||||
policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
|
policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
|
||||||
: ip(ip_)
|
: ip(ip_)
|
||||||
, type(t)
|
, type(t)
|
||||||
|
, failcount(0)
|
||||||
|
, trust_points(0)
|
||||||
|
, source(src)
|
||||||
|
, hashfails(0)
|
||||||
|
, fast_reconnects(0)
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
, pe_support(true)
|
, pe_support(true)
|
||||||
#endif
|
#endif
|
||||||
, failcount(0)
|
|
||||||
, hashfails(0)
|
|
||||||
, seed(false)
|
|
||||||
, fast_reconnects(0)
|
|
||||||
, optimistically_unchoked(false)
|
, optimistically_unchoked(false)
|
||||||
, last_optimistically_unchoked(min_time())
|
, seed(false)
|
||||||
, connected(min_time())
|
|
||||||
, trust_points(0)
|
|
||||||
, on_parole(false)
|
, on_parole(false)
|
||||||
|
, banned(false)
|
||||||
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
, added_to_dht(false)
|
||||||
|
#endif
|
||||||
|
, connection(0)
|
||||||
, prev_amount_upload(0)
|
, prev_amount_upload(0)
|
||||||
, prev_amount_download(0)
|
, prev_amount_download(0)
|
||||||
, banned(false)
|
, last_optimistically_unchoked(min_time())
|
||||||
, source(src)
|
, connected(min_time())
|
||||||
, connection(0)
|
|
||||||
{
|
{
|
||||||
|
TORRENT_ASSERT((src & 0xff) == src);
|
||||||
TORRENT_ASSERT(connected < time_now());
|
TORRENT_ASSERT(connected < time_now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3392,9 +3392,8 @@ namespace libtorrent
|
|||||||
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end()
|
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end()
|
||||||
, !boost::bind(&peer_connection::is_connecting, _1));
|
, !boost::bind(&peer_connection::is_connecting, _1));
|
||||||
|
|
||||||
st.list_peers = std::distance(m_policy.begin_peer(), m_policy.end_peer());
|
st.list_peers = m_policy.num_peers();
|
||||||
st.list_seeds = (int)std::count_if(m_policy.begin_peer(), m_policy.end_peer()
|
st.list_seeds = m_policy.num_seeds();
|
||||||
, boost::bind(&policy::peer::seed, bind(&policy::iterator::value_type::second, _1)));
|
|
||||||
st.connect_candidates = m_policy.num_connect_candidates();
|
st.connect_candidates = m_policy.num_connect_candidates();
|
||||||
|
|
||||||
st.storage_mode = m_storage_mode;
|
st.storage_mode = m_storage_mode;
|
||||||
|
Reference in New Issue
Block a user