*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-09-16 01:14:16 +00:00
parent 2406d5e54d
commit 579d63f49d
18 changed files with 192 additions and 139 deletions

View File

@ -1002,8 +1002,17 @@ entry write_resume_data();
</pre> </pre>
</blockquote> </blockquote>
<p><tt class="literal"><span class="pre">write_resume_data()</span></tt> generates fast-resume data and returns it as an <a class="reference" href="#entry">entry</a>. This <a class="reference" href="#entry">entry</a> <p><tt class="literal"><span class="pre">write_resume_data()</span></tt> generates fast-resume data and returns it as an <a class="reference" href="#entry">entry</a>. This <a class="reference" href="#entry">entry</a>
is suitable for being bencoded. For more information about how fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>. is suitable for being bencoded. For more information about how fast-resume works, see <a class="reference" href="#fast-resume">fast resume</a>.</p>
It may throw <a class="reference" href="#invalid-handle">invalid_handle</a> if the torrent handle is invalid.</p> <p>There are three cases where this function will just return an empty <tt class="literal"><span class="pre">entry</span></tt>:</p>
<blockquote>
<ol class="arabic simple">
<li>The torrent handle is invalid.</li>
<li>The torrent is checking (or is queued for checking) its storage, it will obviously
not be ready to write resume data.</li>
<li>The torrent hasn't received valid metadata and was started without metadata
(see libtorrent's <a class="reference" href="#metadata-from-peers">metadata from peers</a> extension)</li>
</ol>
</blockquote>
<p>Note that by the time this function returns, the resume data may already be invalid if the torrent <p>Note that by the time this function returns, the resume data may already be invalid if the torrent
is still downloading! The recommended practice is to first pause the torrent, then generate the is still downloading! The recommended practice is to first pause the torrent, then generate the
fast resume data, and then close it down.</p> fast resume data, and then close it down.</p>
@ -1820,7 +1829,7 @@ struct torrent_finished_alert: alert
<div class="section" id="metadata-received-alert"> <div class="section" id="metadata-received-alert">
<h2><a name="metadata-received-alert">metadata_received_alert</a></h2> <h2><a name="metadata-received-alert">metadata_received_alert</a></h2>
<p>This alert is generated when the metadata has been completely received and the torrent <p>This alert is generated when the metadata has been completely received and the torrent
can start downloading. It is not generated on torrents that are started with metadata, bu can start downloading. It is not generated on torrents that are started with metadata, but
only those that needs to download it from peers (when utilizing the libtorrent extension). only those that needs to download it from peers (when utilizing the libtorrent extension).
It is generated at severity level <tt class="literal"><span class="pre">info</span></tt>.</p> It is generated at severity level <tt class="literal"><span class="pre">info</span></tt>.</p>
<pre class="literal-block"> <pre class="literal-block">
@ -2130,7 +2139,7 @@ piece.</td>
</tr> </tr>
<tr><td><tt class="literal"><span class="pre">adler32</span></tt></td> <tr><td><tt class="literal"><span class="pre">adler32</span></tt></td>
<td>The adler32 checksum of the data in the <td>The adler32 checksum of the data in the
blocks specified by <tt class="literal"><span class="pre">bitmsk</span></tt>.</td> blocks specified by <tt class="literal"><span class="pre">bitmask</span></tt>.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -957,7 +957,14 @@ write_resume_data()
``write_resume_data()`` generates fast-resume data and returns it as an entry_. This entry_ ``write_resume_data()`` generates fast-resume data and returns it as an entry_. This entry_
is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_. is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_.
It may throw invalid_handle_ if the torrent handle is invalid.
There are three cases where this function will just return an empty ``entry``:
1. The torrent handle is invalid.
2. The torrent is checking (or is queued for checking) its storage, it will obviously
not be ready to write resume data.
3. The torrent hasn't received valid metadata and was started without metadata
(see libtorrent's `metadata from peers`_ extension)
Note that by the time this function returns, the resume data may already be invalid if the torrent Note that by the time this function returns, the resume data may already be invalid if the torrent
is still downloading! The recommended practice is to first pause the torrent, then generate the is still downloading! The recommended practice is to first pause the torrent, then generate the
@ -1854,7 +1861,7 @@ metadata_received_alert
----------------------- -----------------------
This alert is generated when the metadata has been completely received and the torrent This alert is generated when the metadata has been completely received and the torrent
can start downloading. It is not generated on torrents that are started with metadata, bu can start downloading. It is not generated on torrents that are started with metadata, but
only those that needs to download it from peers (when utilizing the libtorrent extension). only those that needs to download it from peers (when utilizing the libtorrent extension).
It is generated at severity level ``info``. It is generated at severity level ``info``.
@ -2174,7 +2181,7 @@ The file format is a bencoded dictionary containing the following fields:
| | | | piece. | | | | | | piece. | |
| | +-------------+--------------------------------------------+ | | | +-------------+--------------------------------------------+ |
| | | ``adler32`` | The adler32 checksum of the data in the | | | | | ``adler32`` | The adler32 checksum of the data in the | |
| | | | blocks specified by ``bitmsk``. | | | | | | blocks specified by ``bitmask``. | |
| | | | | | | | | | | |
| | +-------------+--------------------------------------------+ | | | +-------------+--------------------------------------------+ |
| | | | | |

View File

@ -84,11 +84,18 @@ namespace libtorrent
public: public:
hasher() { SHA1Init(&m_context); } hasher() { SHA1Init(&m_context); }
hasher(const char* data, int len)
{
SHA1Init(&m_context);
assert(data != 0);
assert(len > 0);
SHA1Update(&m_context, reinterpret_cast<unsigned char const*>(data), len);
}
void update(const char* data, int len) void update(const char* data, int len)
{ {
assert(data != 0); assert(data != 0);
assert(len > 0); assert(len > 0);
SHA1Update(&m_context, reinterpret_cast<unsigned char*>(const_cast<char*>(data)), len); SHA1Update(&m_context, reinterpret_cast<unsigned char const*>(data), len);
} }
sha1_hash final() sha1_hash final()

View File

@ -71,7 +71,7 @@ namespace libtorrent
, std::string const& hostname , std::string const& hostname
, unsigned short port , unsigned short port
, std::string const& request , std::string const& request
, request_callback* c , boost::weak_ptr<request_callback> c
, const http_settings& stn , const http_settings& stn
, std::string const& password = ""); , std::string const& password = "");
virtual bool tick(); virtual bool tick();

View File

@ -65,10 +65,18 @@ namespace libtorrent
{} {}
int piece_index; int piece_index;
int block_index; int block_index;
bool operator==(const piece_block& b) const
bool operator<(piece_block const& b) const
{
if (piece_index < b.piece_index) return true;
if (piece_index == b.piece_index) return block_index < b.block_index;
return false;
}
bool operator==(piece_block const& b) const
{ return piece_index == b.piece_index && block_index == b.block_index; } { return piece_index == b.piece_index && block_index == b.block_index; }
bool operator!=(const piece_block& b) const bool operator!=(piece_block const& b) const
{ return piece_index != b.piece_index || block_index != b.block_index; } { return piece_index != b.piece_index || block_index != b.block_index; }
}; };

View File

@ -202,7 +202,7 @@ namespace libtorrent
ptime not_tried_yet(boost::gregorian::date(1970,boost::gregorian::Jan,1)); ptime not_tried_yet(boost::gregorian::date(1970,boost::gregorian::Jan,1));
return p.connection == 0 return p.connection == 0
&& p.connected!=not_tried_yet && p.connected != not_tried_yet
&& second_clock::local_time() - p.connected > minutes(30); && second_clock::local_time() - p.connected > minutes(30);
} }
}; };

View File

@ -115,7 +115,10 @@ namespace libtorrent
// loop in session_impl will check for this state // loop in session_impl will check for this state
// on all torrents once every second, and take // on all torrents once every second, and take
// the necessary actions then. // the necessary actions then.
void abort() { m_abort = true; m_event = tracker_request::stopped; } void abort()
{
m_abort = true; m_event = tracker_request::stopped;
}
bool is_aborted() const { return m_abort; } bool is_aborted() const { return m_abort; }
// is called every second by session. This will // is called every second by session. This will

View File

@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/weak_ptr.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@ -98,7 +99,7 @@ namespace libtorrent
{ {
friend class tracker_manager; friend class tracker_manager;
request_callback(): m_manager(0) {} request_callback(): m_manager(0) {}
virtual ~request_callback(); virtual ~request_callback() {}
virtual void tracker_response( virtual void tracker_response(
std::vector<peer_entry>& peers std::vector<peer_entry>& peers
, int interval) = 0; , int interval) = 0;
@ -118,18 +119,19 @@ namespace libtorrent
struct tracker_connection: boost::noncopyable struct tracker_connection: boost::noncopyable
{ {
tracker_connection(request_callback* r) tracker_connection(boost::weak_ptr<request_callback> r)
: m_requester(r) : m_requester(r)
{} {}
virtual bool tick() = 0; virtual bool tick() = 0;
virtual bool send_finished() const = 0; virtual bool send_finished() const = 0;
request_callback* requester() { return m_requester; } bool has_requester() const { return !m_requester.expired(); }
request_callback& requester();
virtual ~tracker_connection() {} virtual ~tracker_connection() {}
private: protected:
request_callback* m_requester; boost::weak_ptr<request_callback> m_requester;
}; };
@ -143,9 +145,10 @@ namespace libtorrent
void tick(); void tick();
void queue_request( void queue_request(
tracker_request r tracker_request r
, request_callback* c = 0 , boost::weak_ptr<request_callback> c
= boost::weak_ptr<request_callback>()
, std::string const& password = ""); , std::string const& password = "");
void abort_request(request_callback* c); // void abort_request(request_callback* c);
void abort_all_requests(); void abort_all_requests();
bool send_finished() const; bool send_finished() const;
@ -156,10 +159,10 @@ namespace libtorrent
tracker_connections_t m_connections; tracker_connections_t m_connections;
const http_settings& m_settings; const http_settings& m_settings;
}; };
/*
inline request_callback::~request_callback() inline request_callback::~request_callback()
{ if (m_manager) m_manager->abort_request(this); } { if (m_manager) m_manager->abort_request(this); }
*/
} }
#endif // TORRENT_TRACKER_MANAGER_HPP_INCLUDED #endif // TORRENT_TRACKER_MANAGER_HPP_INCLUDED

View File

@ -68,7 +68,7 @@ namespace libtorrent
tracker_request const& req tracker_request const& req
, std::string const& hostname , std::string const& hostname
, unsigned short port , unsigned short port
, request_callback* c , boost::weak_ptr<request_callback> c
, const http_settings& stn); , const http_settings& stn);
virtual bool tick(); virtual bool tick();

View File

@ -81,7 +81,7 @@ namespace libtorrent
, std::string const& hostname , std::string const& hostname
, unsigned short port , unsigned short port
, std::string const& request , std::string const& request
, request_callback* c , boost::weak_ptr<request_callback> c
, const http_settings& stn , const http_settings& stn
, std::string const& password) , std::string const& password)
: tracker_connection(c) : tracker_connection(c)
@ -114,7 +114,7 @@ namespace libtorrent
// TODO: this is a problem. DNS-lookup is blocking! // TODO: this is a problem. DNS-lookup is blocking!
// (may block up to 5 seconds) // (may block up to 5 seconds)
address a(connect_to_host->c_str(), port); address a(connect_to_host->c_str(), port);
if (c) c->m_tracker_address = a; if (has_requester()) requester().m_tracker_address = a;
boost::shared_ptr<socket> s(new socket(socket::tcp, false)); boost::shared_ptr<socket> s(new socket(socket::tcp, false));
s->connect(a); s->connect(a);
@ -191,12 +191,12 @@ namespace libtorrent
} }
m_send_buffer += "\r\n\r\n"; m_send_buffer += "\r\n\r\n";
#ifndef NDEBUG #ifndef NDEBUG
if (c) if (has_requester())
{ {
c->debug_log("==> TRACKER_REQUEST [ str: " + m_send_buffer + " ]"); requester().debug_log("==> TRACKER_REQUEST [ str: " + m_send_buffer + " ]");
std::stringstream info_hash_str; std::stringstream info_hash_str;
info_hash_str << req.info_hash; info_hash_str << req.info_hash;
c->debug_log("info_hash: " + info_hash_str.str() + "\n"); requester().debug_log("info_hash: " + info_hash_str.str() + "\n");
} }
#endif #endif
m_socket = s; m_socket = s;
@ -215,14 +215,14 @@ namespace libtorrent
time_duration d = second_clock::local_time() - m_request_time; time_duration d = second_clock::local_time() - m_request_time;
if (d > seconds(m_settings.tracker_timeout) || if (d > seconds(m_settings.tracker_timeout) ||
(requester() == 0 && d > seconds(m_settings.stop_tracker_timeout))) (!has_requester() && d > seconds(m_settings.stop_tracker_timeout)))
{ {
if (requester()) requester()->tracker_request_timed_out(); if (has_requester()) requester().tracker_request_timed_out();
return true; return true;
} }
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log("tracker connection tick"); if (has_requester()) requester().debug_log("tracker connection tick");
#endif #endif
// if we have a send buffer and the socket is ready for writing // if we have a send buffer and the socket is ready for writing
@ -257,7 +257,7 @@ namespace libtorrent
m_request_time = boost::posix_time::second_clock::local_time(); m_request_time = boost::posix_time::second_clock::local_time();
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log("tracker connection socket readable"); if (has_requester()) requester().debug_log("tracker connection socket readable");
#endif #endif
// if the receive buffer is full, expand it with http_buffer_size // if the receive buffer is full, expand it with http_buffer_size
@ -265,9 +265,9 @@ namespace libtorrent
{ {
if ((int)m_buffer.size() > m_settings.tracker_maximum_response_length) if ((int)m_buffer.size() > m_settings.tracker_maximum_response_length)
{ {
if (requester()) if (has_requester())
{ {
requester()->tracker_request_error( requester().tracker_request_error(
200 200
, "too large tracker response"); , "too large tracker response");
} }
@ -287,16 +287,16 @@ namespace libtorrent
if (received > 0) m_recv_pos += received; if (received > 0) m_recv_pos += received;
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log("received: " + boost::lexical_cast<std::string>(m_recv_pos)); if (has_requester()) requester().debug_log("received: " + boost::lexical_cast<std::string>(m_recv_pos));
#endif #endif
if (m_state == read_status) if (m_state == read_status)
{ {
if (received <= 0) if (received <= 0)
{ {
if (requester()) if (has_requester())
{ {
requester()->tracker_request_error( requester().tracker_request_error(
-1 -1
, "invalid tracker response, connection closed"); , "invalid tracker response, connection closed");
} }
@ -309,7 +309,7 @@ namespace libtorrent
if (newline == end) return false; if (newline == end) return false;
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log(std::string(m_buffer.begin(), newline)); if (has_requester()) requester().debug_log(std::string(m_buffer.begin(), newline));
#endif #endif
std::istringstream line(std::string(m_buffer.begin(), newline)); std::istringstream line(std::string(m_buffer.begin(), newline));
@ -322,7 +322,7 @@ namespace libtorrent
if (m_server_protocol.substr(0, 5) != "HTTP/") if (m_server_protocol.substr(0, 5) != "HTTP/")
{ {
std::string error_msg = "unknown protocol in response: " + m_server_protocol; std::string error_msg = "unknown protocol in response: " + m_server_protocol;
if (requester()) requester()->tracker_request_error(-1, error_msg.c_str()); if (has_requester()) requester().tracker_request_error(-1, error_msg.c_str());
return true; return true;
} }
line >> m_code; line >> m_code;
@ -337,7 +337,7 @@ namespace libtorrent
{ {
std::string error_msg = boost::lexical_cast<std::string>(m_code) std::string error_msg = boost::lexical_cast<std::string>(m_code)
+ " " + m_server_message; + " " + m_server_message;
if (requester()) requester()->tracker_request_error( if (has_requester()) requester().tracker_request_error(
m_code, error_msg.c_str()); m_code, error_msg.c_str());
return true; return true;
} }
@ -347,8 +347,8 @@ namespace libtorrent
{ {
if (received <= 0) if (received <= 0)
{ {
if (requester()) if (has_requester())
requester()->tracker_request_error(-1, "invalid tracker " requester().tracker_request_error(-1, "invalid tracker "
"response, connection closed while reading header"); "response, connection closed while reading header");
return true; return true;
} }
@ -363,7 +363,7 @@ namespace libtorrent
line.assign(m_buffer.begin(), newline); line.assign(m_buffer.begin(), newline);
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log(line); if (has_requester()) requester().debug_log(line);
#endif #endif
if (line.substr(0, 16) == "Content-Length: ") if (line.substr(0, 16) == "Content-Length: ")
@ -375,9 +375,9 @@ namespace libtorrent
} }
catch(boost::bad_lexical_cast&) catch(boost::bad_lexical_cast&)
{ {
if (requester()) if (has_requester())
{ {
requester()->tracker_request_error( requester().tracker_request_error(
-1, -1,
"invalid content-length in tracker response"); "invalid content-length in tracker response");
} }
@ -385,9 +385,9 @@ namespace libtorrent
} }
if (m_content_length > m_settings.tracker_maximum_response_length) if (m_content_length > m_settings.tracker_maximum_response_length)
{ {
if (requester()) if (has_requester())
{ {
requester()->tracker_request_error( requester().tracker_request_error(
-1 -1
, "content-length is greater than maximum response length"); , "content-length is greater than maximum response length");
} }
@ -396,9 +396,9 @@ namespace libtorrent
if (m_content_length < minimum_tracker_response_length && m_code == 200) if (m_content_length < minimum_tracker_response_length && m_code == 200)
{ {
if (requester()) if (has_requester())
{ {
requester()->tracker_request_error( requester().tracker_request_error(
-1 -1
, "content-length is smaller than minimum response length"); , "content-length is smaller than minimum response length");
} }
@ -416,8 +416,8 @@ namespace libtorrent
std::string error_str = "unknown content encoding in response: \""; std::string error_str = "unknown content encoding in response: \"";
error_str += line.substr(18, line.length() - 18 - 2); error_str += line.substr(18, line.length() - 18 - 2);
error_str += "\""; error_str += "\"";
if (requester()) if (has_requester())
requester()->tracker_request_error(-1, error_str.c_str()); requester().tracker_request_error(-1, error_str.c_str());
return true; return true;
} }
} }
@ -433,7 +433,7 @@ namespace libtorrent
{ {
m_state = read_body; m_state = read_body;
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log("end of http header"); if (has_requester()) requester().debug_log("end of http header");
#endif #endif
if (m_code >= 300 && m_code < 400) if (m_code >= 300 && m_code < 400)
{ {
@ -442,13 +442,13 @@ namespace libtorrent
std::string error_str = "got redirection response ("; std::string error_str = "got redirection response (";
error_str += boost::lexical_cast<std::string>(m_code); error_str += boost::lexical_cast<std::string>(m_code);
error_str += ") without 'Location' header"; error_str += ") without 'Location' header";
if (requester()) if (has_requester())
requester()->tracker_request_error(m_code, error_str.c_str()); requester().tracker_request_error(m_code, error_str.c_str());
return true; return true;
} }
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) requester()->debug_log("Redirecting to \"" + m_location + "\""); if (has_requester()) requester().debug_log("Redirecting to \"" + m_location + "\"");
#endif #endif
std::string::size_type i = m_location.find('?'); std::string::size_type i = m_location.find('?');
if (i == std::string::npos) if (i == std::string::npos)
@ -456,7 +456,7 @@ namespace libtorrent
else else
m_req.url.assign(m_location.begin(), m_location.begin() + i); m_req.url.assign(m_location.begin(), m_location.begin() + i);
m_man.queue_request(m_req, requester(), m_password); m_man.queue_request(m_req, m_requester, m_password);
return true; return true;
} }
} }
@ -479,8 +479,9 @@ namespace libtorrent
// GZIP // GZIP
if (m_content_encoding == gzip) if (m_content_encoding == gzip)
{ {
if (inflate_gzip(m_buffer, boost::shared_ptr<request_callback> r = m_requester.lock();
requester(), if (!r) return true;
if (inflate_gzip(m_buffer, r.get(),
m_settings.tracker_maximum_response_length)) m_settings.tracker_maximum_response_length))
return true; return true;
} }
@ -494,9 +495,9 @@ namespace libtorrent
} }
else if (m_recv_pos > m_content_length && m_content_length > 0) else if (m_recv_pos > m_content_length && m_content_length > 0)
{ {
if (requester()) if (has_requester())
{ {
requester()->tracker_request_error( requester().tracker_request_error(
-1 -1
, "invalid tracker response (body > content_length)"); , "invalid tracker response (body > content_length)");
} }
@ -508,8 +509,8 @@ namespace libtorrent
} }
catch (std::exception&) catch (std::exception&)
{ {
if (requester()) if (has_requester())
requester()->debug_log(std::string(m_buffer.begin(), m_buffer.end())); requester().debug_log(std::string(m_buffer.begin(), m_buffer.end()));
throw; throw;
} }
#endif #endif
@ -548,7 +549,7 @@ namespace libtorrent
void http_tracker_connection::parse(const entry& e) void http_tracker_connection::parse(const entry& e)
{ {
if (requester() == 0) return; if (!has_requester()) return;
std::vector<peer_entry> peer_list; std::vector<peer_entry> peer_list;
try try
@ -596,15 +597,15 @@ namespace libtorrent
} }
} }
requester()->tracker_response(peer_list, interval); requester().tracker_response(peer_list, interval);
} }
catch(type_error& e) catch(type_error& e)
{ {
requester()->tracker_request_error(-1, e.what()); requester().tracker_request_error(-1, e.what());
} }
catch(std::runtime_error& e) catch(std::runtime_error& e)
{ {
requester()->tracker_request_error(-1, e.what()); requester().tracker_request_error(-1, e.what());
} }
} }

View File

@ -1951,10 +1951,6 @@ namespace libtorrent
// ok, now we have got enough of the handshake. Is this connection // ok, now we have got enough of the handshake. Is this connection
// attached to a torrent? // attached to a torrent?
// TODO: if the protocol is to be extended
// these 8 bytes would be used to describe the
// extensions available on the other side
// currently disabled
#ifndef TORRENT_DISABLE_EXTENSIONS #ifndef TORRENT_DISABLE_EXTENSIONS
if (m_recv_buffer[7] & 0x01) if (m_recv_buffer[7] & 0x01)
m_supports_extensions = true; m_supports_extensions = true;

View File

@ -567,6 +567,7 @@ namespace libtorrent
// TODO: we must also remove peers that // TODO: we must also remove peers that
// we failed to connect to from this list // we failed to connect to from this list
// to avoid being part of a DDOS-attack // to avoid being part of a DDOS-attack
// remove old disconnected peers from the list // remove old disconnected peers from the list
m_peers.erase( m_peers.erase(
std::remove_if(m_peers.begin() std::remove_if(m_peers.begin()
@ -770,6 +771,7 @@ namespace libtorrent
// if the connection comes from the tracker, // if the connection comes from the tracker,
// it's probably just a NAT-check. Ignore the // it's probably just a NAT-check. Ignore the
// num connections constraint then. // num connections constraint then.
// TODO: only allow _one_ connection to use this // TODO: only allow _one_ connection to use this
// override at a time // override at a time
if (m_torrent->num_peers() >= m_max_connections if (m_torrent->num_peers() >= m_max_connections
@ -928,6 +930,7 @@ namespace libtorrent
} }
if (!interested) if (!interested)
i->connection->send_not_interested(); i->connection->send_not_interested();
assert(i->connection->is_interesting() == interested);
} }
} }
} }
@ -1002,7 +1005,7 @@ namespace libtorrent
if (p == 0) return false; if (p == 0) return false;
assert(!p->banned); assert(!p->banned);
assert(!p->connection); assert(!p->connection);
assert(p->type==peer::connectable); assert(p->type == peer::connectable);
return connect_peer(p); return connect_peer(p);
} }

View File

@ -369,9 +369,7 @@ namespace libtorrent { namespace detail
{ {
m_tracker_manager.abort_all_requests(); m_tracker_manager.abort_all_requests();
for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i = for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i =
m_torrents.begin(); m_torrents.begin(); i != m_torrents.end(); ++i)
i != m_torrents.end();
++i)
{ {
i->second->abort(); i->second->abort();
tracker_request req = i->second->generate_tracker_request(); tracker_request req = i->second->generate_tracker_request();
@ -491,12 +489,6 @@ namespace libtorrent { namespace detail
boost::shared_ptr<peer_connection> c( boost::shared_ptr<peer_connection> c(
new peer_connection(*this, m_selector, s)); new peer_connection(*this, m_selector, s));
/* if (m_upload_rate != -1)
{
c->upload_bandwidth_quota()->given = 0;
c->update_send_quota_left();
}
*/
m_connections.insert(std::make_pair(s, c)); m_connections.insert(std::make_pair(s, c));
m_selector.monitor_readability(s); m_selector.monitor_readability(s);
m_selector.monitor_errors(s); m_selector.monitor_errors(s);
@ -669,8 +661,7 @@ namespace libtorrent { namespace detail
req.listen_port = m_listen_interface.port; req.listen_port = m_listen_interface.port;
req.key = m_key; req.key = m_key;
m_tracker_manager.queue_request( m_tracker_manager.queue_request(
req req, i->second);
, boost::get_pointer(i->second));
} }
// tick() will set the used upload quota // tick() will set the used upload quota
@ -701,6 +692,9 @@ namespace libtorrent { namespace detail
i->second->distribute_resources(); i->second->distribute_resources();
} }
// TODO: there's a problem when removing torrents while
// they're waiting for tracker response. The requester-pointer
// will become invalid.
m_tracker_manager.tick(); m_tracker_manager.tick();
} }

View File

@ -353,8 +353,6 @@ namespace libtorrent
// TODO: this assert will be hit if a file has size 0 // TODO: this assert will be hit if a file has size 0
assert(read_bytes > 0); assert(read_bytes > 0);
// in.read(buf + buf_pos, read_bytes);
// int actual_read = in.gcount();
size_type actual_read = in.read(buf + buf_pos, read_bytes); size_type actual_read = in.read(buf + buf_pos, read_bytes);
if (read_bytes != actual_read) if (read_bytes != actual_read)
@ -471,15 +469,7 @@ namespace libtorrent
fs::path path = m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path); fs::path path = m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path);
file_offset = 0; file_offset = 0;
/*
out.close();
out.clear();
if (fs::exists(path))
out.open(path, std::ios_base::binary | std::ios_base::in);
else
out.open(path, std::ios_base::binary);
*/
out.open(path, file::out); out.open(path, file::out);
} }
} }
@ -1233,7 +1223,7 @@ namespace libtorrent
{ {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
data.progress = (float)current_slot / m_info.num_pieces(); data.progress = (float)current_slot / m_info.num_pieces();
if (data.abort) if (data.abort || data.torrent_ptr->is_aborted())
return; return;
} }
} }

View File

@ -375,11 +375,8 @@ namespace libtorrent
} }
} }
// TODO: may report too much if two peers are downloading std::map<piece_block, int> downloading_piece;
// the same block for (const_peer_iterator i = begin(); i != end(); ++i)
for (const_peer_iterator i = begin();
i != end();
++i)
{ {
boost::optional<piece_block_progress> p boost::optional<piece_block_progress> p
= i->second->downloading_piece(); = i->second->downloading_piece();
@ -387,13 +384,28 @@ namespace libtorrent
{ {
if (m_have_pieces[p->piece_index]) if (m_have_pieces[p->piece_index])
continue; continue;
if (m_picker->is_finished(piece_block(p->piece_index, p->block_index)))
piece_block block(p->piece_index, p->block_index);
if (m_picker->is_finished(block))
continue; continue;
total_done += p->bytes_downloaded; std::map<piece_block, int>::iterator dp
= downloading_piece.find(block);
if (dp != downloading_piece.end())
{
if (dp->second < p->bytes_downloaded)
dp->second = p->bytes_downloaded;
}
else
{
downloading_piece[block] = p->bytes_downloaded;
}
assert(p->bytes_downloaded <= p->full_block_bytes); assert(p->bytes_downloaded <= p->full_block_bytes);
} }
} }
for (std::map<piece_block, int>::iterator i = downloading_piece.begin();
i != downloading_piece.end(); ++i)
total_done += i->second;
return total_done; return total_done;
} }
@ -945,8 +957,19 @@ namespace libtorrent
st.state = torrent_status::connecting_to_tracker; st.state = torrent_status::connecting_to_tracker;
else else
st.state = torrent_status::downloading_metadata; st.state = torrent_status::downloading_metadata;
// TODO: implement progress
st.progress = 0.f; if (m_have_metadata.empty())
{
st.progress = 0.f;
}
else
{
st.progress = std::count(
m_have_metadata.begin()
, m_have_metadata.end()
, true) / 256.f;
}
return st; return st;
} }

View File

@ -365,13 +365,11 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<int> piece_index; std::vector<int> piece_index;
if (m_ses == 0) if (m_ses == 0) return entry();
throw invalid_handle();
boost::mutex::scoped_lock l(m_ses->m_mutex); boost::mutex::scoped_lock l(m_ses->m_mutex);
torrent* t = m_ses->find_torrent(m_info_hash); torrent* t = m_ses->find_torrent(m_info_hash);
if (t == 0) if (t == 0) return entry();
throw invalid_handle();
if (!t->valid_metadata()) return entry(); if (!t->valid_metadata()) return entry();

View File

@ -280,6 +280,13 @@ namespace libtorrent
return ret; return ret;
} }
request_callback& tracker_connection::requester()
{
boost::shared_ptr<request_callback> r = m_requester.lock();
assert(r);
return *r;
}
void tracker_manager::tick() void tracker_manager::tick()
{ {
@ -293,17 +300,17 @@ namespace libtorrent
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
if (c->requester()) if (c->has_requester())
c->requester()->tracker_request_error(-1, e.what()); c->requester().tracker_request_error(-1, e.what());
} }
if (c->requester()) c->requester()->m_manager = 0; if (c->has_requester()) c->requester().m_manager = 0;
i = m_connections.erase(i); i = m_connections.erase(i);
} }
} }
void tracker_manager::queue_request( void tracker_manager::queue_request(
tracker_request req tracker_request req
, request_callback* c , boost::weak_ptr<request_callback> c
, std::string const& password) , std::string const& password)
{ {
assert(req.num_want >= 0); assert(req.num_want >= 0);
@ -387,14 +394,18 @@ namespace libtorrent
m_connections.push_back(con); m_connections.push_back(con);
if (con->requester()) con->requester()->m_manager = this; if (con->has_requester()) con->requester().m_manager = this;
} }
catch (std::exception& e) catch (std::exception& e)
{ {
if (c) c->tracker_request_error(-1, e.what()); if (!c.expired())
{
boost::shared_ptr<request_callback> r = c.lock();
r->tracker_request_error(-1, e.what());
}
} }
} }
/*
void tracker_manager::abort_request(request_callback* c) void tracker_manager::abort_request(request_callback* c)
{ {
assert(c != 0); assert(c != 0);
@ -408,7 +419,7 @@ namespace libtorrent
} }
} }
} }
*/
void tracker_manager::abort_all_requests() void tracker_manager::abort_all_requests()
{ {
// removes all connections from m_connections // removes all connections from m_connections
@ -422,7 +433,7 @@ namespace libtorrent
i != m_connections.end(); i != m_connections.end();
++i) ++i)
{ {
if ((*i)->requester() == 0) keep_connections.push_back(*i); if (!(*i)->has_requester()) keep_connections.push_back(*i);
} }
std::swap(m_connections, keep_connections); std::swap(m_connections, keep_connections);

View File

@ -61,7 +61,7 @@ namespace libtorrent
tracker_request const& req tracker_request const& req
, std::string const& hostname , std::string const& hostname
, unsigned short port , unsigned short port
, request_callback* c , boost::weak_ptr<request_callback> c
, const http_settings& stn) , const http_settings& stn)
: tracker_connection(c) : tracker_connection(c)
, m_request_time(boost::posix_time::second_clock::local_time()) , m_request_time(boost::posix_time::second_clock::local_time())
@ -74,7 +74,7 @@ namespace libtorrent
// TODO: this is a problem. DNS-lookup is blocking! // TODO: this is a problem. DNS-lookup is blocking!
// (may block up to 5 seconds) // (may block up to 5 seconds)
address a(hostname.c_str(), port); address a(hostname.c_str(), port);
if (c) c->m_tracker_address = a; if (has_requester()) requester().m_tracker_address = a;
m_socket.reset(new socket(socket::udp, false)); m_socket.reset(new socket(socket::udp, false));
m_socket->connect(a); m_socket->connect(a);
@ -101,7 +101,7 @@ namespace libtorrent
{ {
if (m_attempts >= udp_connection_retries) if (m_attempts >= udp_connection_retries)
{ {
if (requester()) requester()->tracker_request_timed_out(); if (has_requester()) requester().tracker_request_timed_out();
return true; return true;
} }
send_udp_connect(); send_udp_connect();
@ -113,7 +113,7 @@ namespace libtorrent
{ {
if (m_attempts >= udp_announce_retries) if (m_attempts >= udp_announce_retries)
{ {
if (requester()) requester()->tracker_request_timed_out(); if (has_requester()) requester().tracker_request_timed_out();
return true; return true;
} }
@ -134,8 +134,8 @@ namespace libtorrent
} }
if (ret == udp_buffer_size) if (ret == udp_buffer_size)
{ {
if (requester()) if (has_requester())
requester()->tracker_request_error(-1, "tracker reply too big"); requester().tracker_request_error(-1, "tracker reply too big");
return true; return true;
} }
@ -217,8 +217,8 @@ namespace libtorrent
if (len < 8) if (len < 8)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) if (has_requester())
requester()->debug_log("udp_tracker_connection: " requester().debug_log("udp_tracker_connection: "
"got a message with size < 8, ignoring"); "got a message with size < 8, ignoring");
#endif #endif
return false; return false;
@ -233,8 +233,8 @@ namespace libtorrent
if (action == error) if (action == error)
{ {
if (requester()) if (has_requester())
requester()->tracker_request_error(-1, std::string(buf, buf + len - 8)); requester().tracker_request_error(-1, std::string(buf, buf + len - 8));
return true; return true;
} }
if (action != announce) return false; if (action != announce) return false;
@ -242,8 +242,8 @@ namespace libtorrent
if (len < 12) if (len < 12)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) if (has_requester())
requester()->debug_log("udp_tracker_connection: " requester().debug_log("udp_tracker_connection: "
"got a message with size < 12, ignoring"); "got a message with size < 12, ignoring");
#endif #endif
return false; return false;
@ -252,12 +252,12 @@ namespace libtorrent
int num_peers = (len - 12) / 6; int num_peers = (len - 12) / 6;
if ((len - 12) % 6 != 0) if ((len - 12) % 6 != 0)
{ {
if (requester()) if (has_requester())
requester()->tracker_request_error(-1, "invalid tracker response"); requester().tracker_request_error(-1, "invalid tracker response");
return true; return true;
} }
if (requester() == 0) return true; if (!has_requester()) return true;
std::vector<peer_entry> peer_list; std::vector<peer_entry> peer_list;
for (int i = 0; i < num_peers; ++i) for (int i = 0; i < num_peers; ++i)
@ -274,7 +274,7 @@ namespace libtorrent
peer_list.push_back(e); peer_list.push_back(e);
} }
requester()->tracker_response(peer_list, interval); requester().tracker_response(peer_list, interval);
return true; return true;
} }
@ -286,8 +286,8 @@ namespace libtorrent
if (len < 8) if (len < 8)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) if (has_requester())
requester()->debug_log("udp_tracker_connection: " requester().debug_log("udp_tracker_connection: "
"got a message with size < 8, ignoring"); "got a message with size < 8, ignoring");
#endif #endif
return false; return false;
@ -298,16 +298,16 @@ namespace libtorrent
if (action == error) if (action == error)
{ {
if (requester()) if (has_requester())
requester()->tracker_request_error(-1, std::string(ptr, buf + len)); requester().tracker_request_error(-1, std::string(ptr, buf + len));
return true; return true;
} }
if (action != connect) return false; if (action != connect) return false;
if (m_transaction_id != transaction) if (m_transaction_id != transaction)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) if (has_requester())
requester()->debug_log("udp_tracker_connection: " requester().debug_log("udp_tracker_connection: "
"got a message with incorrect transaction id, ignoring"); "got a message with incorrect transaction id, ignoring");
#endif #endif
return false; return false;
@ -316,8 +316,8 @@ namespace libtorrent
if (len < 16) if (len < 16)
{ {
#ifndef NDEBUG #ifndef NDEBUG
if (requester()) if (has_requester())
requester()->debug_log("udp_tracker_connection: " requester().debug_log("udp_tracker_connection: "
"got a connection message size < 16, ignoring"); "got a connection message size < 16, ignoring");
#endif #endif
return false; return false;