*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-09-12 10:12:16 +00:00
parent b2150236b0
commit 492565b979
10 changed files with 119 additions and 78 deletions

View File

@ -39,7 +39,7 @@
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id34" name="id34">begin_files() end_files() rbegin_files() rend_files()</a></li>
<li><a class="reference" href="#num-files-file-at" id="id35" name="id35">num_files() file_at()</a></li>
<li><a class="reference" href="#print" id="id36" name="id36">print()</a></li>
<li><a class="reference" href="#trackers-prioritize-tracker" id="id37" name="id37">trackers() prioritize_tracker()</a></li>
<li><a class="reference" href="#trackers" id="id37" name="id37">trackers()</a></li>
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id38" name="id38">total_size() piece_length() piece_size() num_pieces()</a></li>
<li><a class="reference" href="#hash-for-piece-info-hash" id="id39" name="id39">hash_for_piece() info_hash()</a></li>
<li><a class="reference" href="#name-comment-creation-date" id="id40" name="id40">name() comment() creation_date()</a></li>
@ -635,7 +635,7 @@ class torrent_info
{
public:
torrent_info(const entry&amp; torrent_file)
torrent_info(entry const&amp; torrent_file)
torrent_info(int piece_size, const char* name);
entry create_torrent() const;
@ -645,7 +645,7 @@ public:
void add_tracker(std::string const&amp; url, int tier = 0);
void add_file(boost::filesystem::path file, size_type size);
typedef std::vector&gt;file_entry&gt;::const_iterator file_iterator;
typedef std::vector&lt;file_entry&gt;::const_iterator file_iterator;
typedef std::vector&lt;file_entry&gt;::const_reverse_iterator reverse_file_iterator;
file_iterator begin_files() const;
@ -654,11 +654,9 @@ public:
reverse_file_iterator rend_files() const;
int num_files() const;
const file_entry&amp; file_at(int index) const;
file_entry const&amp; file_at(int index) const;
const std::vector&lt;announce_entry&gt;&amp; trackers() const;
int prioritize_tracker(int index);
std::vector&lt;announce_entry&gt; const&amp; trackers() const;
size_type total_size() const;
size_type piece_length() const;
@ -720,12 +718,11 @@ void print(std::ostream&amp; os) const;
<p>The <tt class="literal"><span class="pre">print()</span></tt> function is there for debug purposes only. It will print the info from
the torrent file to the given outstream.</p>
</div>
<div class="section" id="trackers-prioritize-tracker">
<h2><a name="trackers-prioritize-tracker">trackers() prioritize_tracker()</a></h2>
<div class="section" id="trackers">
<h2><a name="trackers">trackers()</a></h2>
<blockquote>
<pre class="literal-block">
const std::vector&lt;announce_entry&gt;&amp; trackers() const;
int prioritize_tracker(int index);
</pre>
</blockquote>
<p>The <tt class="literal"><span class="pre">trackers()</span></tt> function will return a sorted vector of <tt class="literal"><span class="pre">announce_entry</span></tt>.
@ -735,14 +732,11 @@ ones with lower tier will always be tried before the one with higher tier number
<pre class="literal-block">
struct announce_entry
{
announce_entry(std::string const&amp; url);
std::string url;
int tier;
};
</pre>
<p>The <tt class="literal"><span class="pre">prioritize_tracker()</span></tt> is used internally to move a tracker to the front
of its tier group. i.e. It will never be moved pass a tracker with a different tier
number. For more information about how multiple trackers are dealt with, see the
<a class="reference" href="http://home.elp.rr.com/tur/multitracker-spec.txt">specification</a>.</p>
</div>
<div class="section" id="total-size-piece-length-piece-size-num-pieces">
<h2><a name="total-size-piece-length-piece-size-num-pieces">total_size() piece_length() piece_size() num_pieces()</a></h2>
@ -813,6 +807,9 @@ struct torrent_handle
void set_tracker_login(std::string const&amp; username, std::string const&amp; password);
std::vector&lt;announce_entry&gt; const&amp; trackers() const;
void replace_trackers(std::vector&lt;announce_entry&gt; const&amp;);
void set_ratio(float ratio);
void set_max_uploads(int max_uploads);
void set_max_connections(int max_connections);
@ -840,6 +837,7 @@ struct torrent_handle
<p>The default constructor will initialize the handle to an invalid state. Which means you cannot
perform any operation on it, unless you first assign it a valid handle. If you try to perform
any operation on an uninitialized handle, it will throw <tt class="literal"><span class="pre">invalid_handle</span></tt>.</p>
<p><em>TODO: document ``trackers()`` and ``replace_trackers()``</em></p>
<div class="section" id="save-path">
<h2><a name="save-path">save_path()</a></h2>
<blockquote>
@ -1691,13 +1689,16 @@ struct file_error_alert: alert
<p>This alert is generated on tracker time outs, premature disconnects, invalid response or
a HTTP response other than &quot;200 OK&quot;. From the alert you can get the handle to the torrent
the tracker belongs to. This alert is generated as severity level <tt class="literal"><span class="pre">warning</span></tt>.</p>
<p>The <tt class="literal"><span class="pre">times_in_row</span></tt> member says how many times in a row this tracker has failed.</p>
<pre class="literal-block">
struct tracker_alert: alert
{
tracker_alert(const torrent_handle&amp; h, const std::string&amp; msg);
tracker_alert(const torrent_handle&amp; h, int times
, const std::string&amp; msg);
virtual std::auto_ptr&lt;alert&gt; clone() const;
torrent_handle handle;
int times_in_row;
};
</pre>
</div>

View File

@ -559,7 +559,7 @@ The ``torrent_info`` has the following synopsis::
{
public:
torrent_info(const entry& torrent_file)
torrent_info(entry const& torrent_file)
torrent_info(int piece_size, const char* name);
entry create_torrent() const;
@ -569,7 +569,7 @@ The ``torrent_info`` has the following synopsis::
void add_tracker(std::string const& url, int tier = 0);
void add_file(boost::filesystem::path file, size_type size);
typedef std::vector>file_entry>::const_iterator file_iterator;
typedef std::vector<file_entry>::const_iterator file_iterator;
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
file_iterator begin_files() const;
@ -578,11 +578,9 @@ The ``torrent_info`` has the following synopsis::
reverse_file_iterator rend_files() const;
int num_files() const;
const file_entry& file_at(int index) const;
file_entry const& file_at(int index) const;
const std::vector<announce_entry>& trackers() const;
int prioritize_tracker(int index);
std::vector<announce_entry> const& trackers() const;
size_type total_size() const;
size_type piece_length() const;
@ -649,13 +647,12 @@ The ``print()`` function is there for debug purposes only. It will print the inf
the torrent file to the given outstream.
trackers() prioritize_tracker()
-------------------------------
trackers()
----------
::
const std::vector<announce_entry>& trackers() const;
int prioritize_tracker(int index);
The ``trackers()`` function will return a sorted vector of ``announce_entry``.
Each announce entry contains a string, which is the tracker url, and a tier index. The
@ -666,17 +663,11 @@ ones with lower tier will always be tried before the one with higher tier number
struct announce_entry
{
announce_entry(std::string const& url);
std::string url;
int tier;
};
The ``prioritize_tracker()`` is used internally to move a tracker to the front
of its tier group. i.e. It will never be moved pass a tracker with a different tier
number. For more information about how multiple trackers are dealt with, see the
specification_.
.. _specification: http://home.elp.rr.com/tur/multitracker-spec.txt
total_size() piece_length() piece_size() num_pieces()
-----------------------------------------------------
@ -756,6 +747,9 @@ Its declaration looks like this::
void set_tracker_login(std::string const& username, std::string const& password);
std::vector<announce_entry> const& trackers() const;
void replace_trackers(std::vector<announce_entry> const&);
void set_ratio(float ratio);
void set_max_uploads(int max_uploads);
void set_max_connections(int max_connections);
@ -784,6 +778,7 @@ The default constructor will initialize the handle to an invalid state. Which me
perform any operation on it, unless you first assign it a valid handle. If you try to perform
any operation on an uninitialized handle, it will throw ``invalid_handle``.
*TODO: document ``trackers()`` and ``replace_trackers()``*
save_path()
-----------
@ -1709,17 +1704,22 @@ This alert is generated on tracker time outs, premature disconnects, invalid res
a HTTP response other than "200 OK". From the alert you can get the handle to the torrent
the tracker belongs to. This alert is generated as severity level ``warning``.
The ``times_in_row`` member says how many times in a row this tracker has failed.
::
struct tracker_alert: alert
{
tracker_alert(const torrent_handle& h, const std::string& msg);
tracker_alert(const torrent_handle& h, int times
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
torrent_handle handle;
int times_in_row;
};
hash_failed_alert
-----------------

View File

@ -43,15 +43,18 @@ namespace libtorrent
struct tracker_alert: alert
{
tracker_alert(const torrent_handle& h
, int times
, const std::string& msg)
: alert(alert::warning, msg)
, handle(h)
, times_in_row(times)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new tracker_alert(*this)); }
torrent_handle handle;
int times_in_row;
};
struct hash_failed_alert: alert

View File

@ -93,10 +93,6 @@ namespace libtorrent
struct invalid_encoding: std::exception
{
invalid_encoding()
{
int i = 0;
}
virtual const char* what() const throw() { return "invalid bencoding"; }
};

View File

@ -301,6 +301,11 @@ namespace libtorrent
piece_manager& filesystem();
torrent_info const& torrent_file() const { return m_torrent_file; }
std::vector<announce_entry> const& trackers() const
{ return m_trackers; }
void replace_trackers(std::vector<announce_entry> const& urls);
torrent_handle get_handle() const;
// DEBUG
@ -343,6 +348,7 @@ namespace libtorrent
private:
void try_next_tracker();
int prioritize_tracker(int tracker_index);
torrent_info m_torrent_file;
@ -396,11 +402,13 @@ namespace libtorrent
std::auto_ptr<piece_picker> m_picker;
std::vector<announce_entry> m_trackers;
// this is an index into m_torrent_file.trackers()
int m_last_working_tracker;
int m_currently_trying_tracker;
// the number of connection attempts that has
// failed in a row
// failed in a row, this is currently used to
// determine the timeout until next try.
int m_failed_trackers;
// this is a counter that is increased every

View File

@ -183,6 +183,9 @@ namespace libtorrent
torrent_status status() const;
void get_download_queue(std::vector<partial_piece_info>& queue) const;
std::vector<announce_entry> const& trackers() const;
void replace_trackers(std::vector<announce_entry> const&);
bool has_metadata() const;
const torrent_info& get_torrent_info() const;
bool is_valid() const;

View File

@ -67,6 +67,7 @@ namespace libtorrent
struct announce_entry
{
announce_entry(std::string const& u): url(u), tier(0) {}
std::string url;
int tier;
};
@ -115,11 +116,6 @@ namespace libtorrent
const std::vector<announce_entry>& trackers() const { return m_urls; }
// this will move the tracker with the given index
// to a prioritized position in the list (move it towards
// the begining) and return the new index to the tracker.
int prioritize_tracker(int index);
size_type total_size() const { assert(m_piece_length > 0); return m_total_size; }
size_type piece_length() const { assert(m_piece_length > 0); return m_piece_length; }
int num_pieces() const { assert(m_piece_length > 0); return (int)m_piece_hash.size(); }

View File

@ -162,6 +162,7 @@ namespace libtorrent
, m_policy()
, m_ses(ses)
, m_picker(0)
, m_trackers(m_torrent_file.trackers())
, m_last_working_tracker(-1)
, m_currently_trying_tracker(0)
, m_failed_trackers(0)
@ -213,6 +214,7 @@ namespace libtorrent
, m_download_bandwidth_limit(std::numeric_limits<int>::max())
, m_save_path(save_path)
{
m_trackers.push_back(announce_entry(tracker_url));
m_requested_metadata.resize(256, 0);
m_policy.reset(new policy(this));
m_torrent_file.add_tracker(tracker_url);
@ -265,7 +267,7 @@ namespace libtorrent
if (interval < 60) interval = 60;
m_last_working_tracker
= m_torrent_file.prioritize_tracker(m_currently_trying_tracker);
= prioritize_tracker(m_currently_trying_tracker);
m_next_request = boost::posix_time::second_clock::local_time()
+ boost::posix_time::seconds(m_duration);
m_currently_trying_tracker = 0;
@ -416,15 +418,20 @@ namespace libtorrent
// decrease the trust point of all peers that sent
// parts of this piece.
for (std::vector<address>::iterator i = downloaders.begin();
i != downloaders.end();
++i)
// first, build a set of all peers that participated
std::set<address> peers;
std::copy(downloaders.begin(), downloaders.end(), std::inserter(peers, peers.begin()));
for (std::set<address>::iterator i = peers.begin()
, end(peers.end()); i != end; ++i)
{
peer_iterator p = m_connections.find(*i);
if (p == m_connections.end()) continue;
p->second->received_invalid_data();
if (p->second->trust_points() <= -7)
// either, we have received too many failed hashes
// or this was the only peer that sent us this piece.
if (p->second->trust_points() <= -7 || peers.size() == 1)
{
// we don't trust this peer anymore
// ban it.
@ -467,9 +474,11 @@ namespace libtorrent
// increase the trust point of all peers that sent
// parts of this piece.
for (std::vector<address>::iterator i = downloaders.begin();
i != downloaders.end();
++i)
std::set<address> peers;
std::copy(downloaders.begin(), downloaders.end(), std::inserter(peers, peers.begin()));
for (std::set<address>::iterator i = peers.begin()
, end(peers.end()); i != end; ++i)
{
peer_iterator p = m_connections.find(*i);
if (p == m_connections.end()) continue;
@ -487,6 +496,15 @@ namespace libtorrent
return m_username + ":" + m_password;
}
void torrent::replace_trackers(std::vector<announce_entry> const& urls)
{
assert(!urls.empty());
m_trackers = urls;
if (m_currently_trying_tracker >= (int)m_trackers.size())
m_currently_trying_tracker = m_trackers.size()-1;
m_last_working_tracker = -1;
}
tracker_request torrent::generate_tracker_request()
{
m_duration = 1800;
@ -502,7 +520,7 @@ namespace libtorrent
req.left = bytes_left();
if (req.left == -1) req.left = 1000;
req.event = m_event;
req.url = m_torrent_file.trackers()[m_currently_trying_tracker].url;
req.url = m_trackers[m_currently_trying_tracker].url;
req.num_want = std::max(
(m_policy->get_max_connections()
- m_policy->num_peers()), 0);
@ -637,12 +655,27 @@ namespace libtorrent
force_tracker_request();
}
// this will move the tracker with the given index
// to a prioritized position in the list (move it towards
// the begining) and return the new index to the tracker.
int torrent::prioritize_tracker(int index)
{
assert(index >= 0);
if (index >= (int)m_trackers.size()) return (int)m_trackers.size()-1;
while (index > 0 && m_trackers[index].tier == m_trackers[index-1].tier)
{
std::swap(m_trackers[index].url, m_trackers[index-1].url);
--index;
}
return index;
}
void torrent::try_next_tracker()
{
++m_currently_trying_tracker;
if ((unsigned)m_currently_trying_tracker >= m_torrent_file.trackers().size())
if ((unsigned)m_currently_trying_tracker >= m_trackers.size())
{
int delay = tracker_retry_delay_min
+ std::min(m_failed_trackers, (int)tracker_failed_max)
@ -659,6 +692,7 @@ namespace libtorrent
// don't delay before trying the next tracker
m_next_request = boost::posix_time::second_clock::local_time();
}
}
void torrent::check_files(detail::piece_checker_data& data,
@ -921,7 +955,7 @@ namespace libtorrent
if (m_last_working_tracker >= 0)
{
st.current_tracker
= m_torrent_file.trackers()[m_last_working_tracker].url;
= m_trackers[m_last_working_tracker].url;
}
st.progress = st.total_done
@ -1060,9 +1094,10 @@ namespace libtorrent
{
std::stringstream s;
s << "tracker: \""
<< m_torrent_file.trackers()[m_currently_trying_tracker].url
<< m_trackers[m_currently_trying_tracker].url
<< "\" timed out";
m_ses.m_alerts.post_alert(tracker_alert(get_handle(), s.str()));
m_ses.m_alerts.post_alert(tracker_alert(get_handle()
, m_failed_trackers, s.str()));
}
try_next_tracker();
}
@ -1079,9 +1114,10 @@ namespace libtorrent
{
std::stringstream s;
s << "tracker: \""
<< m_torrent_file.trackers()[m_currently_trying_tracker].url
<< m_trackers[m_currently_trying_tracker].url
<< "\" " << str;
m_ses.m_alerts.post_alert(tracker_alert(get_handle(), s.str()));
m_ses.m_alerts.post_alert(tracker_alert(get_handle()
, m_failed_trackers, s.str()));
}

View File

@ -313,6 +313,22 @@ namespace libtorrent
throw invalid_handle();
}
std::vector<announce_entry> const& torrent_handle::trackers() const
{
INVARIANT_CHECK;
return call_member<std::vector<announce_entry> const&>(m_ses
, m_chk, m_info_hash, boost::bind(&torrent::trackers, _1));
}
void torrent_handle::replace_trackers(std::vector<announce_entry> const& urls)
{
INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash
, boost::bind(&torrent::replace_trackers, _1, urls));
}
const torrent_info& torrent_handle::get_torrent_info() const
{
INVARIANT_CHECK;

View File

@ -193,9 +193,8 @@ namespace libtorrent
const entry::list_type& ll = j->list();
for (entry::list_type::const_iterator k = ll.begin(); k != ll.end(); ++k)
{
announce_entry e;
announce_entry e(k->string());
e.tier = (int)std::distance(l.begin(), j);
e.url = k->string();
m_urls.push_back(e);
}
}
@ -220,10 +219,7 @@ namespace libtorrent
{
i = torrent_file.find_key("announce");
if (i == 0) throw invalid_torrent_file();
announce_entry e;
e.tier = 0;
e.url = i->string();
m_urls.push_back(e);
m_urls.push_back(announce_entry(i->string()));
}
// extract creation date
@ -271,8 +267,7 @@ namespace libtorrent
void torrent_info::add_tracker(std::string const& url, int tier)
{
announce_entry e;
e.url = url;
announce_entry e(url);
e.tier = tier;
m_urls.push_back(e);
}
@ -414,19 +409,6 @@ namespace libtorrent
assert(false);
}
int torrent_info::prioritize_tracker(int index)
{
assert(index >= 0);
if (index >= (int)m_urls.size()) return (int)m_urls.size()-1;
while (index > 0 && m_urls[index].tier == m_urls[index-1].tier)
{
std::swap(m_urls[index].url, m_urls[index-1].url);
--index;
}
return index;
}
void torrent_info::print(std::ostream& os) const
{
os << "trackers:\n";