added the ability to get scrape data from the tracker announce reply

This commit is contained in:
Arvid Norberg 2005-02-21 13:59:24 +00:00
parent d0b9fe8778
commit 782a3cfdc6
10 changed files with 116 additions and 2402 deletions

File diff suppressed because it is too large Load Diff

View File

@ -189,7 +189,7 @@ The basic usage is as follows:
* query the torrent_handles for progress (see torrent_handle_)
* query the session for information
* add and remove torrents from the session at run-time
* destruct all torrent_handles
* save resume data for all torrent_handles (optional)
* destruct session object
Each class and function is described in this manual.
@ -799,6 +799,10 @@ Its declaration looks like this::
bool is_paused() const;
bool is_seed() const;
int num_complete() const;
int num_incomplete() const;
int num_downloaded() const;
bool has_metadata() const;
boost::filsystem::path save_path() const;
@ -924,7 +928,25 @@ is_seed()
Returns true if the torrent is in seed mode (i.e. if it has finished downloading).
num_complete() num_incomplete() num_downloaded()
------------------------------------------------
::
int num_complete() const;
int num_incomplete() const;
int num_downloaded() const;
These members returns the optional scrape data returned by the tracker in the announce response.
If the tracker did not return any scrape data the return value of these functions are -1. Note
that in some cases the tracker can return some scrape data, so there is no guarantee that all
functions returns -1 just because one of them do. ``num_complete()`` is the total number of
seeds in the swarm. ``num_incomplete()`` is the number of downloaders in the swarm and
``num_downloaded()`` is the number of times this torrent has been downloaded.
has_metadata()
--------------
::

View File

@ -150,6 +150,15 @@ namespace libtorrent
float ratio() const
{ return m_ratio; }
int num_complete() const
{ return m_complete; }
int num_incomplete() const
{ return m_incomplete; }
int num_downloaded() const
{ return m_downloaded; }
// --------------------------------------------
// PEER MANAGEMENT
@ -192,7 +201,8 @@ namespace libtorrent
// (either http_tracker_connection or udp_tracker_connection)
// when this torrent got a response from its tracker request
// or when a failure occured
virtual void tracker_response(std::vector<peer_entry>& e, int interval);
virtual void tracker_response(std::vector<peer_entry>& e, int interval
, int complete, int incomplete, int downloaded);
virtual void tracker_request_timed_out();
virtual void tracker_request_error(int response_code, const std::string& str);
@ -393,6 +403,12 @@ namespace libtorrent
// from the tracker
int m_duration;
// the scrape data from the tracker response, this
// is optional and may be -1.
int m_complete;
int m_incomplete;
int m_downloaded;
std::map<address, peer_connection*> m_connections;
// this is the upload and download statistics for the whole torrent.

View File

@ -197,6 +197,13 @@ namespace libtorrent
void pause();
void resume();
// interface for requesting tracker scrape data
// from tha last tracker announce response
// (optional, only sent by some trackers)
int num_complete() const;
int num_incomplete() const;
int num_downloaded() const;
// set the interface to bind outgoing connections
// to.
void use_interface(const char* net_interface);

View File

@ -104,7 +104,10 @@ namespace libtorrent
virtual ~request_callback() {}
virtual void tracker_response(
std::vector<peer_entry>& peers
, int interval) = 0;
, int interval
, int complete
, int incomplete
, int downloaded) = 0;
virtual void tracker_request_timed_out() = 0;
virtual void tracker_request_error(
int response_code

View File

@ -542,7 +542,7 @@ namespace libtorrent
return ret;
}
void http_tracker_connection::parse(const entry& e)
void http_tracker_connection::parse(entry const& e)
{
if (!has_requester()) return;
@ -553,13 +553,13 @@ namespace libtorrent
try
{
const entry& failure = e["failure reason"];
entry const& failure = e["failure reason"];
if (has_requester()) requester().tracker_request_error(
m_code, failure.string().c_str());
return;
}
catch (const type_error&) {}
catch (type_error const&) {}
int interval = (int)e["interval"].integer();
@ -587,7 +587,7 @@ namespace libtorrent
}
else
{
const entry::list_type& l = e["peers"].list();
entry::list_type const& l = e["peers"].list();
for(entry::list_type::const_iterator i = l.begin(); i != l.end(); ++i)
{
peer_entry p = extract_peer_info(*i);
@ -595,7 +595,23 @@ namespace libtorrent
}
}
requester().tracker_response(peer_list, interval);
// look for optional crape info
int complete = -1;
int incomplete = -1;
int downloaded = -1;
try
{
entry const& f = e["files"];
entry const& sd = f[std::string(m_req.info_hash.begin()
, m_req.info_hash.end())];
complete = sd["complete"].integer();
incomplete = sd["incomplete"].integer();
downloaded = sd["downloaded"].integer();
}
catch(type_error& e) {}
requester().tracker_response(peer_list, interval, complete
, incomplete, downloaded);
}
catch(type_error& e)
{

View File

@ -132,8 +132,7 @@ namespace libtorrent { namespace detail
if (!t->abort)
{
boost::mutex::scoped_lock l(m_ses.m_mutex);
m_ses.m_torrents.insert(
std::make_pair(t->info_hash, t->torrent_ptr)).first;
m_ses.m_torrents.insert(std::make_pair(t->info_hash, t->torrent_ptr));
m_torrents.pop_front();
if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info))
{

View File

@ -160,6 +160,9 @@ namespace libtorrent
, m_storage(0)
, m_next_request(second_clock::universal_time())
, m_duration(1800)
, m_complete(-1)
, m_incomplete(-1)
, m_downloaded(-1)
, m_policy()
, m_ses(ses)
, m_picker(0)
@ -203,6 +206,9 @@ namespace libtorrent
, m_storage(0)
, m_next_request(second_clock::universal_time())
, m_duration(1800)
, m_complete(-1)
, m_incomplete(-1)
, m_downloaded(-1)
, m_policy()
, m_ses(ses)
, m_picker(0)
@ -271,7 +277,10 @@ namespace libtorrent
void torrent::tracker_response(
std::vector<peer_entry>& peer_list
, int interval)
, int interval
, int complete
, int incomplete
, int downloaded)
{
m_failed_trackers = 0;
// less than 5 minutes announce intervals
@ -294,6 +303,10 @@ namespace libtorrent
m_next_request = second_clock::universal_time() + boost::posix_time::seconds(m_duration);
}
if (complete >= 0) m_complete = complete;
if (incomplete >= 0) m_incomplete = incomplete;
if (downloaded >= 0) m_downloaded = downloaded;
// connect to random peers from the list
std::random_shuffle(peer_list.begin(), peer_list.end());

View File

@ -271,6 +271,28 @@ namespace libtorrent
, bind(&torrent::resume, _1));
}
int torrent_handle::num_complete() const
{
INVARIANT_CHECK;
return call_member<int>(m_ses, m_chk, m_info_hash
, bind(&torrent::num_complete, _1));
}
int torrent_handle::num_incomplete() const
{
INVARIANT_CHECK;
return call_member<int>(m_ses, m_chk, m_info_hash
, bind(&torrent::num_incomplete, _1));
}
int torrent_handle::num_downloaded() const
{
INVARIANT_CHECK;
return call_member<int>(m_ses, m_chk, m_info_hash
, bind(&torrent::num_downloaded, _1));
}
void torrent_handle::set_tracker_login(std::string const& name, std::string const& password)
{
INVARIANT_CHECK;

View File

@ -241,18 +241,20 @@ namespace libtorrent
}
if (action != announce) return false;
if (len < 12)
if (len < 24)
{
#ifndef NDEBUG
if (has_requester())
requester().debug_log("udp_tracker_connection: "
"got a message with size < 12, ignoring");
"got a message with size < 24, ignoring");
#endif
return false;
}
int interval = detail::read_int32(buf);
int num_peers = (len - 12) / 6;
if ((len - 12) % 6 != 0)
int incomplete = detail::read_int32(buf);
int complete = detail::read_int32(buf);
int num_peers = (len - 24) / 6;
if ((len - 24) % 6 != 0)
{
if (has_requester())
requester().tracker_request_error(-1, "invalid tracker response");
@ -276,7 +278,7 @@ namespace libtorrent
peer_list.push_back(e);
}
requester().tracker_response(peer_list, interval);
requester().tracker_response(peer_list, interval, complete, incomplete, -1);
return true;
}