exposed some more peer info

This commit is contained in:
Arvid Norberg 2007-05-25 19:42:10 +00:00
parent 685f79b82f
commit bb71832f5f
11 changed files with 173 additions and 177 deletions

View File

@ -269,7 +269,7 @@ int peer_index(libtorrent::tcp::endpoint addr, std::vector<libtorrent::peer_info
void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const& peers)
{
using namespace libtorrent;
out << " down (total) up (total) q r flags source fail block-progress "
out << " down (total) up (total) que req flags source fail hshf sndb inactive wait block-progress "
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
"country "
#endif
@ -287,20 +287,27 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
<< "(" << add_suffix(i->total_download) << ") " << esc("0")
<< esc("31") << (i->up_speed > 0 ? add_suffix(i->up_speed) + "/s ": " ")
<< "(" << add_suffix(i->total_upload) << ") " << esc("0")
<< to_string(i->download_queue_length, 2) << " "
<< to_string(i->upload_queue_length, 2) << " "
<< to_string(i->download_queue_length, 3) << " "
<< to_string(i->upload_queue_length, 3) << " "
<< ((i->flags & peer_info::interesting)?'I':'.')
<< ((i->flags & peer_info::choked)?'C':'.')
<< ((i->flags & peer_info::remote_interested)?'i':'.')
<< ((i->flags & peer_info::remote_choked)?'c':'.')
<< ((i->flags & peer_info::supports_extensions)?'e':'.')
<< ((i->flags & peer_info::local_connection)?'l':'r') << " "
<< ((i->flags & peer_info::local_connection)?'l':'r')
<< ((i->flags & peer_info::seed)?'s':'.')
<< ((i->flags & peer_info::on_parole)?'p':'.')
<< " "
<< ((i->source & peer_info::tracker)?"T":"_")
<< ((i->source & peer_info::pex)?"P":"_")
<< ((i->source & peer_info::dht)?"D":"_")
<< ((i->source & peer_info::lsd)?"L":"_")
<< ((i->source & peer_info::resume_data)?"R":"_") << " ";
out << to_string(i->failcount, 4) << " ";
<< ((i->source & peer_info::resume_data)?"R":"_") << " "
<< to_string(i->failcount, 4) << " "
<< to_string(i->num_hashfails, 4) << " "
<< to_string(i->send_buffer_size, 4) << " "
<< to_string(total_seconds(i->last_active), 8) << " "
<< to_string(total_seconds(i->last_request), 4) << " ";
if (i->downloading_piece_index >= 0)
{

View File

@ -130,7 +130,7 @@ namespace libtorrent
void on_receive(asio::error_code const& error
, std::size_t bytes_transferred);
virtual void get_peer_info(peer_info& p) const;
virtual void get_specific_peer_info(peer_info& p) const;
virtual bool in_handshake() const;
#ifndef TORRENT_DISABLE_EXTENSIONS

View File

@ -174,9 +174,6 @@ namespace libtorrent
void set_non_prioritized(bool b)
{ m_non_prioritized = b; }
bool on_parole() const
{ return m_on_parole; }
// this adds an announcement in the announcement queue
// it will let the peer know that we have the given piece
void announce_piece(int index);
@ -209,6 +206,8 @@ namespace libtorrent
void update_interest();
virtual void get_peer_info(peer_info& p) const;
// returns the torrent this connection is a part of
// may be zero if the connection is an incoming connection
// and it hasn't received enough information to determine
@ -264,7 +263,6 @@ namespace libtorrent
// trust management.
void received_valid_data(int index);
void received_invalid_data(int index);
int trust_points() const;
size_type share_diff() const;
@ -335,7 +333,6 @@ namespace libtorrent
ptime m_last_choke;
#endif
virtual void get_peer_info(peer_info& p) const = 0;
// is true until we can be sure that the other end
// speaks our protocol (be it bittorrent or http).
@ -371,6 +368,8 @@ namespace libtorrent
protected:
virtual void get_specific_peer_info(peer_info& p) const = 0;
virtual void write_choke() = 0;
virtual void write_unchoke() = 0;
virtual void write_interested() = 0;
@ -475,6 +474,9 @@ namespace libtorrent
// the time when we last got a part of a
// piece packet from this peer
ptime m_last_piece;
// the time we sent a request to
// this peer the last time
ptime m_last_request;
int m_packet_size;
int m_recv_pos;
@ -582,14 +584,6 @@ namespace libtorrent
// that we give the free upload, to keep the balance.
size_type m_free_upload;
// for every valid piece we receive where this
// peer was one of the participants, we increase
// this value. For every invalid piece we receive
// 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 m_trust_points;
// if this is true, this peer is assumed to handle all piece
// requests in fifo order. All skipped blocks are re-requested
// immediately instead of having a looser requirement
@ -645,14 +639,6 @@ namespace libtorrent
// are preferred.
bool m_prefer_whole_pieces;
// 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 m_on_parole;
// if this is true, the blocks picked by the piece
// picker will be merged before passed to the
// request function. i.e. subsequent blocks are

View File

@ -54,7 +54,9 @@ namespace libtorrent
local_connection = 0x20,
handshake = 0x40,
connecting = 0x80,
queued = 0x100
queued = 0x100,
on_parole = 0x200,
seed = 0x400
};
unsigned int flags;
@ -79,10 +81,21 @@ namespace libtorrent
size_type total_upload;
peer_id pid;
std::vector<bool> pieces;
bool seed; // true if this is a seed
int upload_limit;
int download_limit;
// time since last request
time_duration last_request;
// time since last download or upload
time_duration last_active;
// the size of the send buffer for this peer
int send_buffer_size;
// the number of failed hashes for this peer
int num_hashfails;
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
// in case the session settings is set
// to resolve countries, this is set to

View File

@ -138,6 +138,10 @@ namespace libtorrent
// 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;
@ -149,6 +153,22 @@ namespace libtorrent
// or disconnected if it isn't connected right now
libtorrent::ptime connected;
// for every valid piece we receive where this
// peer was one of the participants, we increase
// this value. For every invalid piece we receive
// 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;
// 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;
// this is the accumulated amount of
// uploaded and downloaded data to this
// peer. It only accounts for what was

View File

@ -111,7 +111,7 @@ namespace libtorrent
std::string const& url() const { return m_url; }
virtual void get_peer_info(peer_info& p) const;
virtual void get_specific_peer_info(peer_info& p) const;
virtual bool in_handshake() const;
// the following functions appends messages

View File

@ -179,56 +179,10 @@ namespace libtorrent
setup_send();
}
void bt_peer_connection::get_peer_info(peer_info& p) const
void bt_peer_connection::get_specific_peer_info(peer_info& p) const
{
assert(!associated_torrent().expired());
p.down_speed = statistics().download_rate();
p.up_speed = statistics().upload_rate();
p.payload_down_speed = statistics().download_payload_rate();
p.payload_up_speed = statistics().upload_payload_rate();
p.pid = pid();
p.ip = remote();
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
p.country[0] = m_country[0];
p.country[1] = m_country[1];
#endif
p.total_download = statistics().total_payload_download();
p.total_upload = statistics().total_payload_upload();
if (m_bandwidth_limit[upload_channel].throttle() == bandwidth_limit::inf)
p.upload_limit = -1;
else
p.upload_limit = m_bandwidth_limit[upload_channel].throttle();
if (m_bandwidth_limit[download_channel].throttle() == bandwidth_limit::inf)
p.download_limit = -1;
else
p.download_limit = m_bandwidth_limit[download_channel].throttle();
p.load_balancing = total_free_upload();
p.download_queue_length = (int)download_queue().size();
p.upload_queue_length = (int)upload_queue().size();
if (boost::optional<piece_block_progress> ret = downloading_piece_progress())
{
p.downloading_piece_index = ret->piece_index;
p.downloading_block_index = ret->block_index;
p.downloading_progress = ret->bytes_downloaded;
p.downloading_total = ret->full_block_bytes;
}
else
{
p.downloading_piece_index = -1;
p.downloading_block_index = -1;
p.downloading_progress = 0;
p.downloading_total = 0;
}
p.flags = 0;
if (is_interesting()) p.flags |= peer_info::interesting;
if (is_choked()) p.flags |= peer_info::choked;
if (is_peer_interested()) p.flags |= peer_info::remote_interested;
@ -240,23 +194,9 @@ namespace libtorrent
if (is_connecting() && !is_queued()) p.flags |= peer_info::connecting;
if (is_queued()) p.flags |= peer_info::queued;
p.pieces = get_bitfield();
p.seed = is_seed();
p.client = m_client_version;
p.connection_type = peer_info::standard_bittorrent;
if (peer_info_struct())
{
p.source = peer_info_struct()->source;
p.failcount = peer_info_struct()->failcount;
}
else
{
assert(!is_local());
p.source = 0;
p.failcount = 0;
}
}
bool bt_peer_connection::in_handshake() const

View File

@ -90,6 +90,7 @@ namespace libtorrent
, m_max_out_request_queue(m_ses.settings().max_out_request_queue)
, m_timeout(m_ses.settings().peer_timeout)
, m_last_piece(time_now())
, m_last_request(time_now())
, m_packet_size(0)
, m_recv_pos(0)
, m_current_send_buffer(0)
@ -109,7 +110,6 @@ namespace libtorrent
, m_num_pieces(0)
, m_desired_queue_size(2)
, m_free_upload(0)
, m_trust_points(0)
, m_assume_fifo(false)
, m_num_invalid_requests(0)
, m_disconnecting(false)
@ -120,7 +120,6 @@ namespace libtorrent
, m_writing(false)
, m_reading(false)
, m_prefer_whole_pieces(false)
, m_on_parole(false)
, m_request_large_blocks(false)
, m_non_prioritized(false)
, m_refs(0)
@ -164,6 +163,7 @@ namespace libtorrent
, m_max_out_request_queue(m_ses.settings().max_out_request_queue)
, m_timeout(m_ses.settings().peer_timeout)
, m_last_piece(time_now())
, m_last_request(time_now())
, m_packet_size(0)
, m_recv_pos(0)
, m_current_send_buffer(0)
@ -181,7 +181,6 @@ namespace libtorrent
, m_num_pieces(0)
, m_desired_queue_size(2)
, m_free_upload(0)
, m_trust_points(0)
, m_assume_fifo(false)
, m_num_invalid_requests(0)
, m_disconnecting(false)
@ -192,7 +191,6 @@ namespace libtorrent
, m_writing(false)
, m_reading(false)
, m_prefer_whole_pieces(false)
, m_on_parole(false)
, m_request_large_blocks(false)
, m_non_prioritized(false)
, m_refs(0)
@ -405,11 +403,14 @@ namespace libtorrent
}
#endif
m_on_parole = false;
m_trust_points++;
// TODO: make this limit user settable
if (m_trust_points > 20) m_trust_points = 20;
if (peer_info_struct())
{
peer_info_struct()->on_parole = false;
int& trust_points = peer_info_struct()->trust_points;
trust_points++;
// TODO: make this limit user settable
if (trust_points > 20) trust_points = 20;
}
}
void peer_connection::received_invalid_data(int index)
@ -424,20 +425,20 @@ namespace libtorrent
}
#endif
m_on_parole = true;
if (peer_info_struct())
{
peer_info_struct()->on_parole = true;
++peer_info_struct()->hashfails;
int& trust_points = peer_info_struct()->trust_points;
// we decrease more than we increase, to keep the
// allowed failed/passed ratio low.
// TODO: make this limit user settable
m_trust_points -= 2;
if (m_trust_points < -7) m_trust_points = -7;
// we decrease more than we increase, to keep the
// allowed failed/passed ratio low.
// TODO: make this limit user settable
trust_points -= 2;
if (trust_points < -7) trust_points = -7;
}
}
int peer_connection::trust_points() const
{
return m_trust_points;
}
size_type peer_connection::total_free_upload() const
{
return m_free_upload;
@ -1557,9 +1558,14 @@ namespace libtorrent
{
if (handled = (*i)->write_request(r)) break;
}
if (!handled) write_request(r);
if (!handled)
{
write_request(r);
m_last_request = time_now();
}
#else
write_request(r);
m_last_request = time_now();
#endif
#ifdef TORRENT_VERBOSE_LOGGING
@ -1678,6 +1684,81 @@ namespace libtorrent
return false;
}
void peer_connection::get_peer_info(peer_info& p) const
{
assert(!associated_torrent().expired());
p.down_speed = statistics().download_rate();
p.up_speed = statistics().upload_rate();
p.payload_down_speed = statistics().download_payload_rate();
p.payload_up_speed = statistics().upload_payload_rate();
p.pid = pid();
p.ip = remote();
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
p.country[0] = m_country[0];
p.country[1] = m_country[1];
#endif
p.total_download = statistics().total_payload_download();
p.total_upload = statistics().total_payload_upload();
if (m_bandwidth_limit[upload_channel].throttle() == bandwidth_limit::inf)
p.upload_limit = -1;
else
p.upload_limit = m_bandwidth_limit[upload_channel].throttle();
if (m_bandwidth_limit[download_channel].throttle() == bandwidth_limit::inf)
p.download_limit = -1;
else
p.download_limit = m_bandwidth_limit[download_channel].throttle();
p.load_balancing = total_free_upload();
p.download_queue_length = (int)download_queue().size();
p.upload_queue_length = (int)upload_queue().size();
if (boost::optional<piece_block_progress> ret = downloading_piece_progress())
{
p.downloading_piece_index = ret->piece_index;
p.downloading_block_index = ret->block_index;
p.downloading_progress = ret->bytes_downloaded;
p.downloading_total = ret->full_block_bytes;
}
else
{
p.downloading_piece_index = -1;
p.downloading_block_index = -1;
p.downloading_progress = 0;
p.downloading_total = 0;
}
p.pieces = get_bitfield();
ptime now = time_now();
p.last_request = now - m_last_request;
p.last_active = now - std::max(m_last_sent, m_last_receive);
// this will set the flags so that we can update them later
p.flags = 0;
get_specific_peer_info(p);
p.flags |= is_seed() ? peer_info::seed : 0;
if (peer_info_struct())
{
p.source = peer_info_struct()->source;
p.failcount = peer_info_struct()->failcount;
p.num_hashfails = peer_info_struct()->hashfails;
p.flags |= peer_info_struct()->on_parole ? peer_info::on_parole : 0;
}
else
{
p.source = 0;
p.failcount = 0;
p.num_hashfails = 0;
}
p.send_buffer_size = send_buffer_size();
}
void peer_connection::cut_receive_buffer(int size, int packet_size)
{
@ -2131,10 +2212,6 @@ namespace libtorrent
assert(m_reading);
m_reading = false;
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read " << bytes_transferred << " bytes\n";
#endif
if (error)
{
#ifdef TORRENT_VERBOSE_LOGGING
@ -2146,6 +2223,9 @@ namespace libtorrent
do
{
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read " << bytes_transferred << " bytes\n";
#endif
// correct the dl quota usage, if not all of the buffer was actually read
if (!m_ignore_bandwidth_limits)
m_bandwidth_limit[download_channel].use_quota(bytes_transferred);
@ -2185,9 +2265,6 @@ namespace libtorrent
, max_receive), ec);
if (ec && ec != asio::error::would_block)
throw asio::system_error(ec);
#ifdef TORRENT_VERBOSE_LOGGING
(*m_logger) << "read_some " << bytes_transferred << " bytes\n";
#endif
}
while (bytes_transferred > 0);

View File

@ -187,7 +187,7 @@ namespace libtorrent
interesting_pieces.reserve(100);
bool prefer_whole_pieces = c.prefer_whole_pieces()
|| c.on_parole();
|| (c.peer_info_struct() && c.peer_info_struct()->on_parole);
if (!prefer_whole_pieces)
{
@ -1394,9 +1394,12 @@ namespace libtorrent
: ip(ip_)
, type(t)
, failcount(0)
, hashfails(0)
, seed(false)
, last_optimistically_unchoked(min_time())
, connected(min_time())
, trust_points(0)
, on_parole(false)
, prev_amount_upload(0)
, prev_amount_download(0)
, banned(false)

View File

@ -903,13 +903,16 @@ namespace libtorrent
, end(peers.end()); i != end; ++i)
{
peer_iterator p = m_connections.find(*i);
peer_connection& peer = *p->second;
if (p == m_connections.end()) continue;
p->second->received_invalid_data(index);
peer.received_invalid_data(index);
// either, we have received too many failed hashes
// or this was the only peer that sent us this piece.
// TODO: make this a changable setting
if (p->second->trust_points() <= -7 || peers.size() == 1)
if ((peer.peer_info_struct()
&& peer.peer_info_struct()->trust_points <= -7)
|| peers.size() == 1)
{
// we don't trust this peer anymore
// ban it.

View File

@ -592,56 +592,8 @@ namespace libtorrent
}
}
void web_peer_connection::get_peer_info(peer_info& p) const
void web_peer_connection::get_specific_peer_info(peer_info& p) const
{
assert(!associated_torrent().expired());
p.down_speed = statistics().download_rate();
p.up_speed = statistics().upload_rate();
p.payload_down_speed = statistics().download_payload_rate();
p.payload_up_speed = statistics().upload_payload_rate();
p.pid = pid();
p.ip = remote();
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
p.country[0] = m_country[0];
p.country[1] = m_country[1];
#endif
p.total_download = statistics().total_payload_download();
p.total_upload = statistics().total_payload_upload();
if (m_bandwidth_limit[upload_channel].throttle() == bandwidth_limit::inf)
p.upload_limit = -1;
else
p.upload_limit = m_bandwidth_limit[upload_channel].throttle();
if (m_bandwidth_limit[download_channel].throttle() == bandwidth_limit::inf)
p.download_limit = -1;
else
p.download_limit = m_bandwidth_limit[download_channel].throttle();
p.load_balancing = total_free_upload();
p.download_queue_length = (int)download_queue().size();
p.upload_queue_length = (int)upload_queue().size();
if (boost::optional<piece_block_progress> ret = downloading_piece_progress())
{
p.downloading_piece_index = ret->piece_index;
p.downloading_block_index = ret->block_index;
p.downloading_progress = ret->bytes_downloaded;
p.downloading_total = ret->full_block_bytes;
}
else
{
p.downloading_piece_index = -1;
p.downloading_block_index = -1;
p.downloading_progress = 0;
p.downloading_total = 0;
}
p.flags = 0;
if (is_interesting()) p.flags |= peer_info::interesting;
if (is_choked()) p.flags |= peer_info::choked;
if (is_peer_interested()) p.flags |= peer_info::remote_interested;
@ -651,14 +603,9 @@ namespace libtorrent
p.flags |= peer_info::handshake;
if (is_connecting() && !is_queued()) p.flags |= peer_info::connecting;
if (is_queued()) p.flags |= peer_info::queued;
p.pieces = get_bitfield();
p.seed = is_seed();
p.client = m_server_string;
p.connection_type = peer_info::web_seed;
p.source = 0;
p.failcount = 0;
}
bool web_peer_connection::in_handshake() const