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:
Arvid Norberg 2008-04-01 17:38:19 +00:00
parent 1511f2f59b
commit 4161be867e
4 changed files with 126 additions and 85 deletions

View File

@ -139,43 +139,9 @@ namespace libtorrent
tcp::endpoint ip;
connection_type type;
#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;
#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;
// the number of failed connection attempts
// this peer has
boost::uint8_t failcount;
// for every valid piece we receive where this
// peer was one of the participants, we increase
@ -183,15 +149,63 @@ namespace libtorrent
// where this peer was a participant, we decrease
// this value. If it sinks below a threshold, its
// 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
// 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
// a bitmap combining the peer_source flags
// from peer_info.
boost::uint8_t source;
// 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.
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
// uploaded and downloaded data to this
@ -205,16 +219,13 @@ namespace libtorrent
size_type prev_amount_upload;
size_type prev_amount_download;
// is set to true if this peer has been banned
bool banned;
// the time when this peer was optimistically unchoked
// the last time.
libtorrent::ptime last_optimistically_unchoked;
// a bitmap combining the peer_source flags
// from peer_info.
int source;
// if the peer is connected now, this
// will refer to a valid peer_connection
peer_connection* connection;
// the time when the peer connected to us
// or disconnected if it isn't connected right now
libtorrent::ptime connected;
};
int num_peers() const { return m_peers.size(); }
@ -231,6 +242,7 @@ namespace libtorrent
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; }
void recalculate_connect_candidates()
{
@ -260,6 +272,9 @@ namespace libtorrent
// have the connectable state (we have a listen
// port for them).
int m_num_connect_candidates;
// the number of seeds in the peer list
int m_num_seeds;
};
}

View File

@ -456,12 +456,13 @@ namespace libtorrent
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;
peer_info_struct()->connected = time_now()
- seconds(m_ses.settings().min_reconnect_time
* 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)
@ -565,7 +566,7 @@ namespace libtorrent
{
peer_info_struct()->on_parole = true;
++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
// allowed failed/passed ratio low.

View File

@ -385,6 +385,7 @@ namespace libtorrent
}
}
if (p) p->clear_peer(&i->second);
if (i->second.seed) --m_num_seeds;
m_peers.erase(i++);
}
}
@ -471,8 +472,10 @@ namespace libtorrent
}
int connect_candidates = 0;
int seeds = 0;
for (iterator i = m_peers.begin(); i != m_peers.end(); ++i)
{
if (i->second.seed) ++seeds;
if (!is_connect_candidate(i->second, finished)) continue;
++connect_candidates;
@ -504,6 +507,7 @@ namespace libtorrent
}
m_num_connect_candidates = connect_candidates;
m_num_seeds = seeds;
TORRENT_ASSERT(min_connect_time <= now);
#if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
@ -532,19 +536,37 @@ namespace libtorrent
if (m_torrent->has_picker())
p = &m_torrent->picker();
bool pinged = false;
ptime now = time_now();
// remove old disconnected peers from the list
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!
// don't remove banned peers, they should
// remain banned
if (i->second.connection == 0
&& i->second.connected != min_time()
&& !i->second.banned
&& now - i->second.connected > minutes(120))
if (pe.connection == 0
&& pe.connected != min_time()
&& !pe.banned
&& 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++);
}
else
@ -770,6 +792,7 @@ namespace libtorrent
}
if (m_torrent->has_picker())
m_torrent->picker().clear_peer(&i->second);
if (i->second.seed) --m_num_seeds;
m_peers.erase(i);
}
}
@ -851,16 +874,11 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_ENCRYPTION
if (flags & 0x01) i->second.pe_support = true;
#endif
if (flags & 0x02) i->second.seed = true;
// 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)
#ifndef TORRENT_DISABLE_DHT
udp::endpoint node(remote.address(), remote.port());
m_torrent->session().add_dht_node(node);
#endif
if (flags & 0x02)
{
i->second.seed = true;
++m_num_seeds;
}
}
else
{
@ -879,7 +897,11 @@ namespace libtorrent
// if we're connected to this peer
// we already know if it's a seed or not
// 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 (i->second.connection)
@ -1295,24 +1317,28 @@ namespace libtorrent
policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
: ip(ip_)
, type(t)
, failcount(0)
, trust_points(0)
, source(src)
, hashfails(0)
, fast_reconnects(0)
#ifndef TORRENT_DISABLE_ENCRYPTION
, pe_support(true)
#endif
, failcount(0)
, hashfails(0)
, seed(false)
, fast_reconnects(0)
, optimistically_unchoked(false)
, last_optimistically_unchoked(min_time())
, connected(min_time())
, trust_points(0)
, seed(false)
, on_parole(false)
, banned(false)
#ifndef TORRENT_DISABLE_DHT
, added_to_dht(false)
#endif
, connection(0)
, prev_amount_upload(0)
, prev_amount_download(0)
, banned(false)
, source(src)
, connection(0)
, last_optimistically_unchoked(min_time())
, connected(min_time())
{
TORRENT_ASSERT((src & 0xff) == src);
TORRENT_ASSERT(connected < time_now());
}

View File

@ -3392,9 +3392,8 @@ namespace libtorrent
st.num_peers = (int)std::count_if(m_connections.begin(), m_connections.end()
, !boost::bind(&peer_connection::is_connecting, _1));
st.list_peers = std::distance(m_policy.begin_peer(), m_policy.end_peer());
st.list_seeds = (int)std::count_if(m_policy.begin_peer(), m_policy.end_peer()
, boost::bind(&policy::peer::seed, bind(&policy::iterator::value_type::second, _1)));
st.list_peers = m_policy.num_peers();
st.list_seeds = m_policy.num_seeds();
st.connect_candidates = m_policy.num_connect_candidates();
st.storage_mode = m_storage_mode;