*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-03-21 02:03:37 +00:00
parent aa7055c212
commit bb52b74a9e
17 changed files with 356 additions and 59 deletions

View File

@ -45,32 +45,33 @@
<li><a class="reference" href="#file-error-alert" id="id37" name="id37">file_error_alert</a></li>
<li><a class="reference" href="#tracker-alert" id="id38" name="id38">tracker_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id39" name="id39">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id40" name="id40">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id41" name="id41">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id42" name="id42">torrent_finished_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id43" name="id43">dispatcher</a></li>
<li><a class="reference" href="#peer-ban-alert" id="id40" name="id40">peer_ban_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id41" name="id41">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id42" name="id42">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id43" name="id43">torrent_finished_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id44" name="id44">dispatcher</a></li>
</ul>
</li>
<li><a class="reference" href="#exceptions" id="id44" name="id44">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id45" name="id45">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id46" name="id46">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id47" name="id47">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id48" name="id48">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id49" name="id49">invalid_torrent_file</a></li>
<li><a class="reference" href="#exceptions" id="id45" name="id45">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id46" name="id46">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id47" name="id47">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id48" name="id48">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id49" name="id49">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id50" name="id50">invalid_torrent_file</a></li>
</ul>
</li>
<li><a class="reference" href="#examples" id="id50" name="id50">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id51" name="id51">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id52" name="id52">simple client</a></li>
<li><a class="reference" href="#examples" id="id51" name="id51">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id52" name="id52">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id53" name="id53">simple client</a></li>
</ul>
</li>
<li><a class="reference" href="#fast-resume" id="id53" name="id53">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id54" name="id54">file format</a></li>
<li><a class="reference" href="#fast-resume" id="id54" name="id54">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id55" name="id55">file format</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id55" name="id55">extensions</a></li>
<li><a class="reference" href="#filenames-checks" id="id56" name="id56">filenames checks</a></li>
<li><a class="reference" href="#aknowledgements" id="id57" name="id57">aknowledgements</a></li>
<li><a class="reference" href="#extensions" id="id56" name="id56">extensions</a></li>
<li><a class="reference" href="#filenames-checks" id="id57" name="id57">filenames checks</a></li>
<li><a class="reference" href="#aknowledgements" id="id58" name="id58">aknowledgements</a></li>
</ul>
</div>
<div class="section" id="introduction">
@ -584,6 +585,10 @@ struct torrent_handle
void connect_peer(const address&amp; adr) const;
void set_ratio(float ratio);
void pause();
void resume();
bool is_paused() const;
void set_tracker_login(std::string const&amp; username, std::string const&amp; password);
void use_interface(const char* net_interface);
@ -620,6 +625,11 @@ in return. With this setting it will work much like the standard clients.</p>
attempt to upload in return for each download. e.g. if set to 2, the client will try to upload
2 bytes for every byte received. The default setting for this is 0, which will make it work
as a standard client.</p>
<p><tt class="literal"><span class="pre">pause()</span></tt>, and <tt class="literal"><span class="pre">resume()</span></tt> will disconnect all peers and reconnect all peers respectively.
When a torrent is paused, it will however remember all share ratios to all peers and remember
all potential (not connected) peers. You can use <tt class="literal"><span class="pre">is_paused()</span></tt> to determine if a torrent
is currently paused. Torrents may be paused automatically if there is a file error (eg. disk full)
or something similar. See <a class="reference" href="#file-error-alert">file_error_alert</a>.</p>
<p><tt class="literal"><span class="pre">set_tracker_login()</span></tt> sets a username and password that will be sent along in the HTTP-request
of the tracker announce. Set this if the tracker requires authorization.</p>
<p><tt class="literal"><span class="pre">use_interface()</span></tt> sets the network interface this torrent will use when it opens outgoing
@ -1162,7 +1172,7 @@ struct listen_failed_alert: alert
<div class="section" id="file-error-alert">
<h2><a name="file-error-alert">file_error_alert</a></h2>
<p>If the storage fails to read or write files that it needs access to, this alert is
generated and the torrent is aborted. It is generated as severity level <tt class="literal"><span class="pre">fatal</span></tt>.</p>
generated and the torrent is paused. It is generated as severity level <tt class="literal"><span class="pre">fatal</span></tt>.</p>
<pre class="literal-block">
struct file_error_alert: alert
{
@ -1211,6 +1221,26 @@ struct hash_failed_alert: alert
};
</pre>
</div>
<div class="section" id="peer-ban-alert">
<h2><a name="peer-ban-alert">peer_ban_alert</a></h2>
<p>This alert is generated when a peer is banned because it has sent too many corrupt pieces
to us. It is generated at severity level <tt class="literal"><span class="pre">info</span></tt>. The <tt class="literal"><span class="pre">handle</span></tt> member is a <a class="reference" href="#torrent-handle">torrent_handle</a>
to the torrent that this peer was a member of.</p>
<pre class="literal-block">
struct peer_ban_alert: alert
{
peer_error_alert(
address const&amp; pip
, torrent_handle h
, const std::string&amp; msg);
virtual std::auto_ptr&lt;alert&gt; clone() const;
address ip;
torrent_handle handle;
};
</pre>
</div>
<div class="section" id="peer-error-alert">
<h2><a name="peer-error-alert">peer_error_alert</a></h2>
<p>This alert is generated when a peer sends invalid data over the peer-peer protocol. The peer

View File

@ -584,6 +584,10 @@ Its declaration looks like this::
void connect_peer(const address& adr) const;
void set_ratio(float ratio);
void pause();
void resume();
bool is_paused() const;
void set_tracker_login(std::string const& username, std::string const& password);
void use_interface(const char* net_interface);
@ -626,6 +630,12 @@ attempt to upload in return for each download. e.g. if set to 2, the client will
2 bytes for every byte received. The default setting for this is 0, which will make it work
as a standard client.
``pause()``, and ``resume()`` will disconnect all peers and reconnect all peers respectively.
When a torrent is paused, it will however remember all share ratios to all peers and remember
all potential (not connected) peers. You can use ``is_paused()`` to determine if a torrent
is currently paused. Torrents may be paused automatically if there is a file error (eg. disk full)
or something similar. See file_error_alert_.
``set_tracker_login()`` sets a username and password that will be sent along in the HTTP-request
of the tracker announce. Set this if the tracker requires authorization.
@ -1213,7 +1223,7 @@ file_error_alert
----------------
If the storage fails to read or write files that it needs access to, this alert is
generated and the torrent is aborted. It is generated as severity level ``fatal``.
generated and the torrent is paused. It is generated as severity level ``fatal``.
::
@ -1271,6 +1281,29 @@ This alert is generated as severity level ``info``.
};
peer_ban_alert
--------------
This alert is generated when a peer is banned because it has sent too many corrupt pieces
to us. It is generated at severity level ``info``. The ``handle`` member is a torrent_handle_
to the torrent that this peer was a member of.
::
struct peer_ban_alert: alert
{
peer_error_alert(
address const& pip
, torrent_handle h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
address ip;
torrent_handle handle;
};
peer_error_alert
----------------

View File

@ -319,6 +319,25 @@ int main(int argc, char* argv[])
, handles.end()
, boost::bind(&torrent_handle::force_reannounce, _1));
}
if(c == 'p')
{
// pause all torrents
std::for_each(
handles.begin()
, handles.end()
, boost::bind(&torrent_handle::pause, _1));
}
if(c == 'u')
{
// unpause all torrents
std::for_each(
handles.begin()
, handles.end()
, boost::bind(&torrent_handle::resume, _1));
}
}
std::auto_ptr<alert> a;

View File

@ -72,6 +72,22 @@ namespace libtorrent
int piece_index;
};
struct peer_ban_alert: alert
{
peer_ban_alert(const address& pip, torrent_handle h, const std::string& msg)
: alert(alert::info, msg)
, ip(pip)
, handle(h)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_ban_alert(*this)); }
address ip;
torrent_handle handle;
};
struct peer_error_alert: alert
{
peer_error_alert(const address& pip, const std::string& msg)

View File

@ -199,6 +199,9 @@ namespace libtorrent
// if it was an incoming connection, it is remote
bool is_local() const { return m_active; }
void set_failed() { m_failed = true; }
bool failed() const { return m_failed; }
#ifndef NDEBUG
boost::shared_ptr<logger> m_logger;
#endif
@ -385,6 +388,12 @@ namespace libtorrent
// we have choked the upload to the peer
bool m_choked;
// this is set to true if the connection timed
// out or closed the connection. In that
// case we will not try to reconnect to
// this peer
bool m_failed;
// this is set to true if the handshake from
// the peer indicated that it supports the
// extension protocol

View File

@ -76,6 +76,11 @@ namespace libtorrent
// return false if the connection closed
void new_connection(peer_connection& c);
// this is called if a peer timed-out or
// forcefully closed the connection. This
// will mark the connection as non-reconnectale
void peer_failed(peer_connection const& c);
// the given connection was just closed
void connection_closed(const peer_connection& c);
@ -163,6 +168,11 @@ namespace libtorrent
peer_connection* connection;
};
int num_peers() const
{
return m_num_peers;
}
private:
bool unchoke_one_peer();

View File

@ -188,9 +188,14 @@ namespace libtorrent
// in loops that iterate over them.
std::vector<connection_map::iterator> m_disconnect_peer;
// the peer id that is generated at the start of each torrent
// the peer id that is generated at the start of the session
peer_id m_peer_id;
// the key is an id that is used to identify the
// client with the tracker only. It is randomized
// at startup
int m_key;
// the range of ports we try to listen on
std::pair<int, int> m_listen_port_range;

View File

@ -101,14 +101,15 @@ namespace libtorrent
// tracker request
bool should_request() const
{
// boost::posix_time::time_duration d = m_next_request - boost::posix_time::second_clock::local_time();
// return d.is_negative();
return m_next_request < boost::posix_time::second_clock::local_time();
namespace time = boost::posix_time;
return !m_paused &&
m_next_request < time::second_clock::local_time();
}
void force_tracker_request()
{
m_next_request = boost::posix_time::second_clock::local_time();
namespace time = boost::posix_time;
m_next_request = time::second_clock::local_time();
}
void print(std::ostream& os) const;
@ -121,6 +122,10 @@ namespace libtorrent
size_type bytes_left() const;
size_type bytes_done() const;
void pause();
void resume();
bool is_paused() const { return m_paused; }
torrent_status status() const;
void use_interface(const char* net_interface);
@ -188,7 +193,7 @@ namespace libtorrent
// generates a request string for sending
// to the tracker
tracker_request generate_tracker_request(int port);
tracker_request generate_tracker_request();
std::string tracker_password() const;
boost::posix_time::ptime next_announce() const
@ -293,6 +298,9 @@ namespace libtorrent
// been aborted.
bool m_abort;
// is true if this torrent has been paused
bool m_paused;
tracker_request::event_t m_event;
void parse_response(const entry& e, std::vector<peer_entry>& peer_list);

View File

@ -96,6 +96,7 @@ namespace libtorrent
};
state_t state;
bool paused;
float progress;
boost::posix_time::time_duration next_announce;
boost::posix_time::time_duration announce_interval;
@ -152,6 +153,10 @@ namespace libtorrent
const torrent_info& get_torrent_info() const;
bool is_valid() const;
bool is_paused() const;
void pause();
void resume();
// set the interface to bind outgoing connections
// to.
void use_interface(const char* net_interface);

View File

@ -90,6 +90,8 @@ namespace libtorrent
unsigned short listen_port;
event_t event;
std::string url;
int key;
int num_want;
};
struct request_callback

View File

@ -151,11 +151,16 @@ namespace libtorrent
m_send_buffer += "&event=";
m_send_buffer += event_string[req.event - 1];
}
m_send_buffer += "&key=";
// TODO: this should be encoded as hex
m_send_buffer += boost::lexical_cast<std::string>((unsigned int)req.key);
m_send_buffer += "&compact=1";
m_send_buffer += "&num_want=";
m_send_buffer += boost::lexical_cast<std::string>(req.num_want);
// extension that tells the tracker that
// we don't need any peer_id's in the response
m_send_buffer += "&no_peer_id=1";
m_send_buffer += "&compact=1";
m_send_buffer += " HTTP/1.0\r\nAccept-Encoding: gzip\r\n"
"User-Agent: ";

View File

@ -97,6 +97,7 @@ namespace libtorrent
, m_peer_choked(true)
, m_interesting(false)
, m_choked(true)
, m_failed(false)
, m_supports_extensions(false)
, m_num_pieces(0)
, m_free_upload(0)
@ -159,6 +160,7 @@ namespace libtorrent
, m_peer_choked(true)
, m_interesting(false)
, m_choked(true)
, m_failed(false)
, m_supports_extensions(false)
, m_num_pieces(0)
, m_free_upload(0)
@ -247,8 +249,10 @@ namespace libtorrent
void peer_connection::received_invalid_data()
{
m_trust_points--;
if (m_trust_points < -5) m_trust_points = -5;
// we decrease more than we increase, to keep the
// allowed failed/passed ratio low.
m_trust_points -= 2;
if (m_trust_points < -7) m_trust_points = -7;
}
int peer_connection::trust_points() const
@ -1530,6 +1534,16 @@ namespace libtorrent
throw protocol_error("got info-hash that is not in our session");
}
if (m_torrent->is_paused())
{
// paused torrents will not accept
// incoming connections
#ifndef NDEBUG
(*m_logger) << " rejected connection to paused torrent\n";
#endif
throw protocol_error("connection rejected by paused torrent");
}
// assume the other end has no pieces
m_have_piece.resize(m_torrent->torrent_file().num_pieces());
std::fill(m_have_piece.begin(), m_have_piece.end(), false);
@ -1576,6 +1590,13 @@ namespace libtorrent
std::copy(m_recv_buffer.begin(), m_recv_buffer.begin() + 20, (char*)tmp.begin());
std::stringstream s;
s << "received peer_id: " << tmp << " client: " << identify_client(tmp) << "\n";
s << "as ascii: ";
for (peer_id::iterator i = tmp.begin(); i != tmp.end(); ++i)
{
if (std::isprint(*i)) s << *i;
else s << ".";
}
s << "\n";
(*m_logger) << s.str();
}
#endif

View File

@ -456,12 +456,11 @@ namespace libtorrent
{
if(i->connection) continue;
if(i->banned) continue;
if(i->type==peer::not_connectable) continue;
if(i->type == peer::not_connectable) continue;
assert(i->connected <= local_time);
boost::posix_time::ptime next_connect
= i->connected + boost::posix_time::seconds(10 * 60);
boost::posix_time::ptime next_connect = i->connected;
if (next_connect <= ptime)
{
@ -736,6 +735,8 @@ namespace libtorrent
assert(i != m_peers.end());
i->type = peer::not_connectable;
i->id.port = address::any_port;
i->banned = true;
}
@ -782,7 +783,7 @@ namespace libtorrent
if (i->connection != 0)
throw protocol_error("duplicate connection, closing");
if (i->banned)
throw protocol_error("ip address banned, disconnected");
throw protocol_error("ip address banned, closing");
}
assert(i->connection == 0);
@ -948,6 +949,11 @@ namespace libtorrent
c.add_free_upload(-diff);
}
}
if (!c.is_choked())
{
c.send_choke();
--m_num_unchoked;
}
}
bool policy::unchoke_one_peer()
@ -999,7 +1005,7 @@ namespace libtorrent
bool policy::disconnect_one_peer()
{
peer *p=find_disconnect_candidate();
peer *p = find_disconnect_candidate();
if(!p)
return false;
p->connection->disconnect();
@ -1014,16 +1020,26 @@ namespace libtorrent
, m_peers.end()
, match_peer_connection(c));
// if we couldn't find the connection in our list, just ignore it.
if (i == m_peers.end()) return;
assert(i->connection == &c);
i->connected = boost::posix_time::second_clock::local_time();
if (!i->connection->is_choked() && !m_torrent->is_aborted())
{
// if the peer that is diconnecting is unchoked
// then unchoke another peer in order to maintain
// the total number of unchoked peers
--m_num_unchoked;
unchoke_one_peer();
}
if (c.failed())
{
i->type = peer::not_connectable;
i->id.port = address::any_port;
}
// if the share ratio is 0 (infinite), the
// m_available_free_upload isn't used,
// because it isn't necessary.

View File

@ -277,6 +277,7 @@ namespace libtorrent { namespace detail
std::srand((unsigned int)std::time(0));
m_key = rand() + (rand() << 15) + (rand() << 30);
std::string print = cl_fprint.to_string();
assert(print.length() == 8);
@ -423,7 +424,10 @@ namespace libtorrent { namespace detail
++i)
{
i->second->abort();
m_tracker_manager.queue_request(i->second->generate_tracker_request(m_listen_interface.port));
tracker_request req = i->second->generate_tracker_request();
req.listen_port = m_listen_interface.port;
req.key = m_key;
m_tracker_manager.queue_request(req);
}
m_connections.clear();
m_torrents.clear();
@ -438,7 +442,7 @@ namespace libtorrent { namespace detail
// SEND SOCKETS
// ************************
// let the writable clients send data
// let the writable connections send data
for (std::vector<boost::shared_ptr<socket> >::iterator i
= writable_clients.begin();
i != writable_clients.end();
@ -473,10 +477,9 @@ namespace libtorrent { namespace detail
, e.what()));
}
m_selector.remove(*i);
m_connections.erase(p);
// pause the torrent
t->pause();
assert(m_selector.count_read_monitors() == (int)m_connections.size() + (bool)m_listen_socket);
t->abort();
}
catch (std::exception& e)
{
@ -488,6 +491,7 @@ namespace libtorrent { namespace detail
peer_error_alert(p->first->sender(), e.what()));
}
p->second->set_failed();
m_selector.remove(*i);
m_connections.erase(p);
assert(m_selector.count_read_monitors() == (int)m_connections.size() + (bool)m_listen_socket);
@ -547,7 +551,6 @@ namespace libtorrent { namespace detail
{
try
{
// (*m_logger) << "readable: " << p->first->sender().as_string() << "\n";
p->second->receive_data();
}
catch (file_error& e)
@ -563,10 +566,8 @@ namespace libtorrent { namespace detail
, e.what()));
}
m_selector.remove(*i);
m_connections.erase(p);
assert(m_selector.count_read_monitors() == (int)m_connections.size() + (bool)m_listen_socket);
t->abort();
t->pause();
}
catch (std::exception& e)
{
@ -577,6 +578,7 @@ namespace libtorrent { namespace detail
}
// the connection wants to disconnect for some reason, remove it
// from the connection-list
p->second->set_failed();
m_selector.remove(*i);
m_connections.erase(p);
assert(m_selector.count_read_monitors() == (int)m_connections.size() + (bool)m_listen_socket);
@ -611,6 +613,7 @@ namespace libtorrent { namespace detail
// the connection may have been disconnected in the receive or send phase
if (p != m_connections.end())
{
p->second->set_failed();
m_connections.erase(p);
assert(m_selector.count_read_monitors() == (int)m_connections.size() + (bool)m_listen_socket);
}
@ -651,6 +654,7 @@ namespace libtorrent { namespace detail
m_alerts.post_alert(
peer_error_alert(j->first->sender(), "connection timed out"));
}
j->second->set_failed();
m_selector.remove(j->first);
m_connections.erase(j);
assert(m_selector.count_read_monitors() == (int)m_connections.size() + (bool)m_listen_socket);
@ -668,8 +672,10 @@ namespace libtorrent { namespace detail
{
if (i->second->is_aborted())
{
m_tracker_manager.queue_request(
i->second->generate_tracker_request(m_listen_interface.port));
tracker_request req = i->second->generate_tracker_request();
req.listen_port = m_listen_interface.port;
req.key = m_key;
m_tracker_manager.queue_request(req);
i->second->disconnect_all();
purge_connections();
#ifndef NDEBUG
@ -683,8 +689,11 @@ namespace libtorrent { namespace detail
}
else if (i->second->should_request())
{
tracker_request req = i->second->generate_tracker_request();
req.listen_port = m_listen_interface.port;
req.key = m_key;
m_tracker_manager.queue_request(
i->second->generate_tracker_request(m_listen_interface.port)
req
, boost::get_pointer(i->second));
}

View File

@ -220,6 +220,7 @@ namespace libtorrent
, address const& net_interface)
: m_block_size(calculate_block_size(torrent_file))
, m_abort(false)
, m_paused(false)
, m_event(tracker_request::started)
, m_torrent_file(torrent_file)
, m_storage(m_torrent_file, save_path)
@ -419,11 +420,18 @@ namespace libtorrent
if (p == m_connections.end()) continue;
p->second->received_invalid_data();
if (p->second->trust_points() <= -5)
if (p->second->trust_points() <= -7)
{
// we don't trust this peer anymore
// ban it.
m_policy->ban_peer(*p->second);
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_ban_alert(
p->first
, get_handle()
, "banning peer because of too many corrupt pieces"));
}
}
}
@ -473,10 +481,8 @@ namespace libtorrent
return m_username + ":" + m_password;
}
tracker_request torrent::generate_tracker_request(int port)
tracker_request torrent::generate_tracker_request()
{
assert(port > 0);
assert((unsigned short)port == port);
m_duration = 1800;
m_next_request = boost::posix_time::second_clock::local_time() + boost::posix_time::seconds(m_duration);
@ -486,9 +492,16 @@ namespace libtorrent
req.downloaded = m_stat.total_payload_download();
req.uploaded = m_stat.total_payload_upload();
req.left = bytes_left();
req.listen_port = port;
req.event = m_event;
req.url = m_torrent_file.trackers()[m_currently_trying_tracker].url;
req.num_want = (m_policy->get_max_connections()
- m_policy->num_peers()) * 2;
// default initialize, these should be set by caller
// before passing the request to the tracker_manager
req.listen_port = 0;
req.key = 0;
return req;
}
@ -530,9 +543,6 @@ namespace libtorrent
m_policy->connection_closed(*p);
m_connections.erase(i);
#ifndef NDEBUG
// m_picker.integrity_check(this);
#endif
}
peer_connection& torrent::connect_to_peer(const address& a)
@ -670,12 +680,31 @@ namespace libtorrent
}
#endif
void torrent::pause()
{
disconnect_all();
// TODO: announce to tracker that we stopped!
// possibly with some delay
m_paused = true;
}
void torrent::resume()
{
m_paused = false;
// TODO: announce to the tracker that we started.
// possibly with some delay
// make pulse be called as soon as possible
m_time_scaler = 0;
}
void torrent::second_tick()
{
m_time_scaler++;
if (m_time_scaler >= 10)
if (m_paused) return;
m_time_scaler--;
if (m_time_scaler <= 0)
{
m_time_scaler = 0;
m_time_scaler = 10;
m_policy->pulse();
}
@ -738,6 +767,7 @@ namespace libtorrent
= m_torrent_file.trackers()[m_last_working_tracker].url;
}
st.paused = m_paused;
st.total_done = bytes_done();
// payload transfer
@ -759,9 +789,10 @@ namespace libtorrent
st.next_announce = next_announce()
- boost::posix_time::second_clock::local_time();
if (st.next_announce.is_negative()) st.next_announce
= boost::posix_time::seconds(0);
st.announce_interval = boost::posix_time::seconds(m_duration);
st.num_peers = (int)m_connections.size();
st.pieces = &m_have_pieces;

View File

@ -204,7 +204,18 @@ namespace libtorrent
else
st.state = torrent_status::queued_for_checking;
st.progress = d->progress;
st.paused = false;
st.next_announce = boost::posix_time::time_duration();
st.announce_interval = boost::posix_time::time_duration();
st.total_download = 0;
st.total_upload = 0;
st.total_payload_download = 0;
st.total_payload_upload = 0;
st.download_rate = 0.f;
st.upload_rate = 0.f;
st.num_peers = 0;
st.pieces = 0;
st.total_done = 0;
return st;
}
}
@ -234,6 +245,73 @@ namespace libtorrent
throw invalid_handle();
}
bool torrent_handle::is_paused() const
{
INVARIANT_CHECK;
if (m_ses == 0) throw invalid_handle();
{
boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash);
if (t != 0) return t->is_paused();
}
if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
if (d != 0) return d->torrent_ptr->is_paused();
}
throw invalid_handle();
}
void torrent_handle::pause()
{
INVARIANT_CHECK;
if (m_ses == 0) throw invalid_handle();
{
boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash);
if (t != 0) return t->pause();
}
if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
if (d != 0) return d->torrent_ptr->pause();
}
throw invalid_handle();
}
void torrent_handle::resume()
{
INVARIANT_CHECK;
if (m_ses == 0) throw invalid_handle();
{
boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash);
if (t != 0) return t->resume();
}
if (m_chk)
{
boost::mutex::scoped_lock l(m_chk->m_mutex);
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
if (d != 0) return d->torrent_ptr->resume();
}
throw invalid_handle();
}
void torrent_handle::set_tracker_login(std::string const& name, std::string const& password)
{
INVARIANT_CHECK;

View File

@ -180,7 +180,7 @@ namespace libtorrent
// ip address
detail::write_int32(0, ptr);
// num_want
detail::write_int32(-1, ptr);
detail::write_int32(m_request.num_want, ptr);
// port
detail::write_uint16(m_request.listen_port, ptr);