diff --git a/docs/manual.rst b/docs/manual.rst index 6e35e96bc..33ccc07a4 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -539,6 +539,11 @@ struct has the following members:: size_type total_dht_download; size_type total_dht_upload; + float tracker_upload_rate; + float tracker_download_rate; + size_type total_tracker_download; + size_type total_tracker_upload; + size_type total_redundant_bytes; size_type total_failed_bytes; diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 12c4faee4..d4659b487 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -1370,7 +1370,10 @@ int main(int ac, char* av[]) << esc("31") << add_suffix(sess_stat.ip_overhead_upload_rate) << "/s" << esc("0") << " DHT: " << esc("32") << add_suffix(sess_stat.dht_download_rate) << "/s" << esc("0") << " " - << esc("31") << add_suffix(sess_stat.dht_upload_rate) << "/s" << esc("0") << " ====\n" + << esc("31") << add_suffix(sess_stat.dht_upload_rate) << "/s" << esc("0") + << " tracker: " + << esc("32") << add_suffix(sess_stat.tracker_download_rate) << "/s" << esc("0") << " " + << esc("31") << add_suffix(sess_stat.tracker_upload_rate) << "/s" << esc("0") << " ====\n" "==== waste: " << add_suffix(sess_stat.total_redundant_bytes) << " fail: " << add_suffix(sess_stat.total_failed_bytes) << " unchoked: " << sess_stat.num_unchoked << " / " << sess_stat.allowed_upload_slots diff --git a/include/libtorrent/session_status.hpp b/include/libtorrent/session_status.hpp index 5f78d74ab..c79b4d3bd 100644 --- a/include/libtorrent/session_status.hpp +++ b/include/libtorrent/session_status.hpp @@ -74,6 +74,11 @@ namespace libtorrent size_type total_dht_download; size_type total_dht_upload; + float tracker_upload_rate; + float tracker_download_rate; + size_type total_tracker_download; + size_type total_tracker_upload; + size_type total_redundant_bytes; size_type total_failed_bytes; diff --git a/include/libtorrent/stat.hpp b/include/libtorrent/stat.hpp index 3e84d733b..fe9824164 100644 --- a/include/libtorrent/stat.hpp +++ b/include/libtorrent/stat.hpp @@ -126,12 +126,28 @@ namespace libtorrent { TORRENT_ASSERT(bytes >= 0); m_stat[download_dht_protocol].add(bytes); + // assuming IPv4 and UDP headers + m_stat[download_ip_protocol].add(28); } void sent_dht_bytes(int bytes) { TORRENT_ASSERT(bytes >= 0); m_stat[upload_dht_protocol].add(bytes); + // assuming IPv4 and UDP headers + m_stat[upload_ip_protocol].add(28); + } + + void received_tracker_bytes(int bytes) + { + TORRENT_ASSERT(bytes >= 0); + m_stat[download_tracker_protocol].add(bytes); + } + + void sent_tracker_bytes(int bytes) + { + TORRENT_ASSERT(bytes >= 0); + m_stat[upload_tracker_protocol].add(bytes); } void received_bytes(int bytes_payload, int bytes_protocol) @@ -176,6 +192,8 @@ namespace libtorrent int download_ip_overhead() const { return m_stat[download_ip_protocol].counter(); } int upload_dht() const { return m_stat[upload_dht_protocol].counter(); } int download_dht() const { return m_stat[download_dht_protocol].counter(); } + int download_tracker() const { return m_stat[download_tracker_protocol].counter(); } + int upload_tracker() const { return m_stat[upload_tracker_protocol].counter(); } // should be called once every second void second_tick(float tick_interval) @@ -207,7 +225,8 @@ namespace libtorrent return m_stat[upload_payload].total() + m_stat[upload_protocol].total() + m_stat[upload_ip_protocol].total() - + m_stat[upload_dht_protocol].total(); + + m_stat[upload_dht_protocol].total() + + m_stat[upload_tracker_protocol].total(); } size_type total_download() const @@ -215,7 +234,8 @@ namespace libtorrent return m_stat[download_payload].total() + m_stat[download_protocol].total() + m_stat[download_ip_protocol].total() - + m_stat[download_dht_protocol].total(); + + m_stat[download_dht_protocol].total() + + m_stat[download_tracker_protocol].total(); } float upload_payload_rate() const @@ -265,10 +285,12 @@ namespace libtorrent upload_protocol, upload_ip_protocol, upload_dht_protocol, + upload_tracker_protocol, download_payload, download_protocol, download_ip_protocol, download_dht_protocol, + download_tracker_protocol, num_channels }; diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 3669943f9..6ae356c53 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -70,6 +70,7 @@ namespace libtorrent class tracker_manager; struct timeout_handler; struct tracker_connection; + namespace aux { struct session_impl; } // returns -1 if gzip header is invalid or the header size in bytes TORRENT_EXPORT int gzip_header(const char* buf, int size); @@ -197,6 +198,8 @@ namespace libtorrent virtual void start() = 0; virtual void close(); address const& bind_interface() const { return m_bind_interface; } + void sent_bytes(int bytes); + void received_bytes(int bytes); protected: boost::weak_ptr m_requester; @@ -210,8 +213,8 @@ namespace libtorrent { public: - tracker_manager(session_settings const& s, proxy_settings const& ps) - : m_settings(s) + tracker_manager(aux::session_impl& ses, proxy_settings const& ps) + : m_ses(ses) , m_proxy(ps) , m_abort(false) {} @@ -228,6 +231,9 @@ namespace libtorrent void remove_request(tracker_connection const*); bool empty() const; int num_requests() const; + + void sent_bytes(int bytes); + void received_bytes(int bytes); private: @@ -237,7 +243,7 @@ namespace libtorrent typedef std::list > tracker_connections_t; tracker_connections_t m_connections; - session_settings const& m_settings; + aux::session_impl& m_ses; proxy_settings const& m_proxy; bool m_abort; }; diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index f3a647fa8..b85727095 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -182,6 +182,9 @@ namespace libtorrent m_tracker_connection->get(url, seconds(timeout) , 1, &m_ps, 5, m_settings.user_agent, m_bind_iface); + // the url + 100 estimated header size + sent_bytes(url.size() + 100); + #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) boost::shared_ptr cb = requester(); @@ -232,6 +235,8 @@ namespace libtorrent return; } + received_bytes(size + parser.body_start()); + // handle tracker response entry e; e = bdecode(data, data + size); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 13e0fb75b..e201f0c20 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -155,7 +155,7 @@ namespace aux { #else , m_upload_channel(m_io_service, peer_connection::upload_channel) #endif - , m_tracker_manager(m_settings, m_tracker_proxy) + , m_tracker_manager(*this, m_tracker_proxy) , m_listen_port_retries(listen_port_range.second - listen_port_range.first) , m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_abort(false) @@ -1096,8 +1096,15 @@ namespace aux { } // drain the IP overhead from the bandwidth limiters - m_download_channel.drain(m_stat.download_ip_overhead() + m_stat.download_dht()); - m_upload_channel.drain(m_stat.upload_ip_overhead() + m_stat.upload_dht()); + m_download_channel.drain( + m_stat.download_ip_overhead() + + m_stat.download_dht() + + m_stat.download_tracker()); + + m_upload_channel.drain( + m_stat.upload_ip_overhead() + + m_stat.upload_dht() + + m_stat.upload_tracker()); m_stat.second_tick(tick_interval); @@ -2019,6 +2026,12 @@ namespace aux { s.dht_upload_rate = m_stat.transfer_rate(stat::upload_dht_protocol); s.total_dht_upload = m_stat.total_transfer(stat::upload_dht_protocol); + // tracker + s.tracker_download_rate = m_stat.transfer_rate(stat::download_tracker_protocol); + s.total_tracker_download = m_stat.total_transfer(stat::download_tracker_protocol); + s.tracker_upload_rate = m_stat.transfer_rate(stat::upload_tracker_protocol); + s.total_tracker_upload = m_stat.total_transfer(stat::upload_tracker_protocol); + #ifndef TORRENT_DISABLE_DHT if (m_dht) { diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index 621c3b99c..e0053096a 100644 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -47,6 +47,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/bencode.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/peer_connection.hpp" +#include "libtorrent/aux_/session_impl.hpp" using namespace libtorrent; using boost::tuples::make_tuple; @@ -156,6 +157,16 @@ namespace libtorrent close(); } + void tracker_connection::sent_bytes(int bytes) + { + m_man.sent_bytes(bytes); + } + + void tracker_connection::received_bytes(int bytes) + { + m_man.received_bytes(bytes); + } + void tracker_connection::fail_timeout() { boost::shared_ptr cb = requester(); @@ -169,6 +180,18 @@ namespace libtorrent m_man.remove_request(this); } + void tracker_manager::sent_bytes(int bytes) + { + aux::session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); + m_ses.m_stat.sent_tracker_bytes(bytes); + } + + void tracker_manager::received_bytes(int bytes) + { + aux::session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); + m_ses.m_stat.received_tracker_bytes(bytes); + } + void tracker_manager::remove_request(tracker_connection const* c) { mutex_t::scoped_lock l(m_mutex); @@ -209,13 +232,13 @@ namespace libtorrent { con = new http_tracker_connection( ios, cc, *this, req, bind_infc, c - , m_settings, m_proxy, auth); + , m_ses.settings(), m_proxy, auth); } else if (protocol == "udp") { con = new udp_tracker_connection( ios, cc, *this, req, bind_infc - , c, m_settings, m_proxy); + , c, m_ses.settings(), m_proxy); } else { diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index 191be4c61..921101b26 100644 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -208,6 +208,7 @@ namespace libtorrent // ignore packet not sent from the tracker if (m_target != ep) return; + received_bytes(size + 28); // assuming UDP/IP header if (e) fail(-1, e.message().c_str()); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING @@ -320,6 +321,7 @@ namespace libtorrent error_code ec; m_socket.send(m_target, buf, 16, ec); m_state = action_connect; + sent_bytes(16 + 28); // assuming UDP/IP header ++m_attempts; if (ec) { @@ -349,6 +351,7 @@ namespace libtorrent error_code ec; m_socket.send(m_target, buf, sizeof(buf), ec); m_state = action_scrape; + sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header ++m_attempts; if (ec) { @@ -509,6 +512,7 @@ namespace libtorrent error_code ec; m_socket.send(m_target, buf, sizeof(buf), ec); m_state = action_announce; + sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header ++m_attempts; if (ec) {