forked from premiere/premiere-libtorrent
fixed assert bug in policy and generalized the tracker_connection observer interface a bit
This commit is contained in:
parent
d9e93a3e99
commit
d9e10440f3
|
@ -77,6 +77,8 @@ namespace libtorrent
|
|||
virtual bool tick();
|
||||
virtual bool send_finished() const
|
||||
{ return m_send_buffer.empty(); }
|
||||
virtual tracker_request const& tracker_req() const
|
||||
{ return m_req; }
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -192,10 +192,14 @@ 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(
|
||||
tracker_request const& r
|
||||
, std::vector<peer_entry>& e, int interval
|
||||
, int complete, int incomplete);
|
||||
virtual void tracker_request_timed_out();
|
||||
virtual void tracker_request_error(int response_code, const std::string& str);
|
||||
virtual void tracker_request_timed_out(
|
||||
tracker_request const& r);
|
||||
virtual void tracker_request_error(tracker_request const& r
|
||||
, int response_code, const std::string& str);
|
||||
|
||||
// generates a request string for sending
|
||||
// to the tracker
|
||||
|
|
|
@ -70,11 +70,6 @@ namespace libtorrent
|
|||
// returns -1 if gzip header is invalid or the header size in bytes
|
||||
int gzip_header(const char* buf, int size);
|
||||
|
||||
bool inflate_gzip(
|
||||
std::vector<char>& buffer
|
||||
, request_callback* requester
|
||||
, int maximum_tracker_response_length);
|
||||
|
||||
struct tracker_request
|
||||
{
|
||||
tracker_request()
|
||||
|
@ -116,13 +111,16 @@ namespace libtorrent
|
|||
request_callback(): m_manager(0) {}
|
||||
virtual ~request_callback() {}
|
||||
virtual void tracker_response(
|
||||
std::vector<peer_entry>& peers
|
||||
tracker_request const&
|
||||
, std::vector<peer_entry>& peers
|
||||
, int interval
|
||||
, int complete
|
||||
, int incomplete) = 0;
|
||||
virtual void tracker_request_timed_out() = 0;
|
||||
virtual void tracker_request_timed_out(
|
||||
tracker_request const&) = 0;
|
||||
virtual void tracker_request_error(
|
||||
int response_code
|
||||
tracker_request const&
|
||||
, int response_code
|
||||
, const std::string& description) = 0;
|
||||
|
||||
address m_tracker_address;
|
||||
|
@ -134,6 +132,12 @@ namespace libtorrent
|
|||
tracker_manager* m_manager;
|
||||
};
|
||||
|
||||
bool inflate_gzip(
|
||||
std::vector<char>& buffer
|
||||
, tracker_request const& req
|
||||
, request_callback* requester
|
||||
, int maximum_tracker_response_length);
|
||||
|
||||
struct tracker_connection: boost::noncopyable
|
||||
{
|
||||
tracker_connection(boost::weak_ptr<request_callback> r)
|
||||
|
@ -145,6 +149,7 @@ namespace libtorrent
|
|||
bool has_requester() const { return !m_requester.expired(); }
|
||||
request_callback& requester();
|
||||
virtual ~tracker_connection() {}
|
||||
virtual tracker_request const& tracker_req() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ namespace libtorrent
|
|||
|
||||
virtual bool tick();
|
||||
virtual bool send_finished() const;
|
||||
virtual tracker_request const& tracker_req() const
|
||||
{ return m_request; }
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace libtorrent
|
|||
"0123456789";
|
||||
|
||||
std::stringstream ret;
|
||||
ret << std::hex << std::setfill('0');
|
||||
ret << std::hex << std::setfill('0');
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
if (std::count(
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace libtorrent
|
|||
|
||||
if (m_req.kind == tracker_request::scrape_request)
|
||||
{
|
||||
// TODO: find and replace "announce" with "scrape"
|
||||
// find and replace "announce" with "scrape"
|
||||
// in request
|
||||
|
||||
std::size_t pos = request.find("announce");
|
||||
|
@ -242,7 +242,7 @@ namespace libtorrent
|
|||
if (d > seconds(m_settings.tracker_timeout) ||
|
||||
(!has_requester() && d > seconds(m_settings.stop_tracker_timeout)))
|
||||
{
|
||||
if (has_requester()) requester().tracker_request_timed_out();
|
||||
if (has_requester()) requester().tracker_request_timed_out(m_req);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ namespace libtorrent
|
|||
if (m_socket->has_error())
|
||||
{
|
||||
if (has_requester()) requester().tracker_request_error(
|
||||
-1, "connection refused");
|
||||
m_req, -1, "connection refused");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -298,8 +298,7 @@ namespace libtorrent
|
|||
{
|
||||
if (has_requester())
|
||||
{
|
||||
requester().tracker_request_error(
|
||||
200
|
||||
requester().tracker_request_error(m_req, 200
|
||||
, "too large tracker response");
|
||||
}
|
||||
return true;
|
||||
|
@ -327,8 +326,7 @@ namespace libtorrent
|
|||
{
|
||||
if (has_requester())
|
||||
{
|
||||
requester().tracker_request_error(
|
||||
-1
|
||||
requester().tracker_request_error(m_req, -1
|
||||
, "invalid tracker response, connection closed");
|
||||
}
|
||||
return true;
|
||||
|
@ -353,7 +351,7 @@ namespace libtorrent
|
|||
if (m_server_protocol.substr(0, 5) != "HTTP/")
|
||||
{
|
||||
std::string error_msg = "unknown protocol in response: " + m_server_protocol;
|
||||
if (has_requester()) requester().tracker_request_error(-1, error_msg.c_str());
|
||||
if (has_requester()) requester().tracker_request_error(m_req, -1, error_msg.c_str());
|
||||
return true;
|
||||
}
|
||||
line >> m_code;
|
||||
|
@ -366,8 +364,9 @@ namespace libtorrent
|
|||
if (received <= 0)
|
||||
{
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(-1, "invalid tracker "
|
||||
"response, connection closed while reading header");
|
||||
requester().tracker_request_error(m_req, -1
|
||||
, "invalid tracker response, connection closed "
|
||||
"while reading header");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -395,8 +394,7 @@ namespace libtorrent
|
|||
{
|
||||
if (has_requester())
|
||||
{
|
||||
requester().tracker_request_error(
|
||||
-1,
|
||||
requester().tracker_request_error(m_req, -1,
|
||||
"invalid content-length in tracker response");
|
||||
}
|
||||
return true;
|
||||
|
@ -405,8 +403,7 @@ namespace libtorrent
|
|||
{
|
||||
if (has_requester())
|
||||
{
|
||||
requester().tracker_request_error(
|
||||
-1
|
||||
requester().tracker_request_error(m_req, -1
|
||||
, "content-length is greater than maximum response length");
|
||||
}
|
||||
return true;
|
||||
|
@ -416,8 +413,7 @@ namespace libtorrent
|
|||
{
|
||||
if (has_requester())
|
||||
{
|
||||
requester().tracker_request_error(
|
||||
-1
|
||||
requester().tracker_request_error(m_req, -1
|
||||
, "content-length is smaller than minimum response length");
|
||||
}
|
||||
return true;
|
||||
|
@ -435,7 +431,8 @@ namespace libtorrent
|
|||
error_str += line.substr(18, line.length() - 18 - 2);
|
||||
error_str += "\"";
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(-1, error_str.c_str());
|
||||
requester().tracker_request_error(m_req, -1
|
||||
, error_str.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +458,8 @@ namespace libtorrent
|
|||
error_str += boost::lexical_cast<std::string>(m_code);
|
||||
error_str += ") without 'Location' header";
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(m_code, error_str.c_str());
|
||||
requester().tracker_request_error(m_req
|
||||
, m_code, error_str.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -499,7 +497,7 @@ namespace libtorrent
|
|||
{
|
||||
boost::shared_ptr<request_callback> r = m_requester.lock();
|
||||
if (!r) return true;
|
||||
if (inflate_gzip(m_buffer, r.get(),
|
||||
if (inflate_gzip(m_buffer, m_req, r.get(),
|
||||
m_settings.tracker_maximum_response_length))
|
||||
return true;
|
||||
}
|
||||
|
@ -515,8 +513,7 @@ namespace libtorrent
|
|||
{
|
||||
if (has_requester())
|
||||
{
|
||||
requester().tracker_request_error(
|
||||
-1
|
||||
requester().tracker_request_error(m_req, -1
|
||||
, "invalid tracker response (body > content_length)");
|
||||
}
|
||||
return true;
|
||||
|
@ -532,7 +529,7 @@ namespace libtorrent
|
|||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
peer_entry http_tracker_connection::extract_peer_info(const entry& info)
|
||||
{
|
||||
|
@ -577,7 +574,7 @@ namespace libtorrent
|
|||
entry const& failure = e["failure reason"];
|
||||
|
||||
if (has_requester()) requester().tracker_request_error(
|
||||
m_code, failure.string().c_str());
|
||||
m_req, m_code, failure.string().c_str());
|
||||
return;
|
||||
}
|
||||
catch (type_error const&) {}
|
||||
|
@ -592,7 +589,7 @@ namespace libtorrent
|
|||
entry scrape_data = e["files"][ih];
|
||||
int complete = scrape_data["complete"].integer();
|
||||
int incomplete = scrape_data["incomplete"].integer();
|
||||
requester().tracker_response(peer_list, 0, complete
|
||||
requester().tracker_response(m_req, peer_list, 0, complete
|
||||
, incomplete);
|
||||
return;
|
||||
}
|
||||
|
@ -639,16 +636,16 @@ namespace libtorrent
|
|||
try { incomplete = e["incomplete"].integer(); }
|
||||
catch(type_error& e) {}
|
||||
|
||||
requester().tracker_response(peer_list, interval, complete
|
||||
requester().tracker_response(m_req, peer_list, interval, complete
|
||||
, incomplete);
|
||||
}
|
||||
catch(type_error& e)
|
||||
{
|
||||
requester().tracker_request_error(-1, e.what());
|
||||
requester().tracker_request_error(m_req, -1, e.what());
|
||||
}
|
||||
catch(std::runtime_error& e)
|
||||
{
|
||||
requester().tracker_request_error(-1, e.what());
|
||||
requester().tracker_request_error(m_req, -1, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -345,8 +345,7 @@ namespace libtorrent
|
|||
// TODO: make this selection better
|
||||
|
||||
for (std::vector<peer>::iterator i = m_peers.begin();
|
||||
i != m_peers.end();
|
||||
++i)
|
||||
i != m_peers.end(); ++i)
|
||||
{
|
||||
peer_connection* c = i->connection;
|
||||
|
||||
|
@ -389,16 +388,15 @@ namespace libtorrent
|
|||
// TODO: make this selection better
|
||||
|
||||
for (std::vector<peer>::iterator i = m_peers.begin();
|
||||
i != m_peers.end();
|
||||
++i)
|
||||
i != m_peers.end(); ++i)
|
||||
{
|
||||
peer_connection* c = i->connection;
|
||||
if (c == 0) continue;
|
||||
if (c->is_disconnecting()) continue;
|
||||
if (!c->is_choked()) continue;
|
||||
if (!c->is_peer_interested()) continue;
|
||||
if (c->share_diff()
|
||||
< -free_upload_amount) continue;
|
||||
if (c->share_diff() < -free_upload_amount
|
||||
&& m_torrent->ratio() != 0) continue;
|
||||
if (c->statistics().download_rate() < max_down_speed) continue;
|
||||
// if (i->last_optimistically_unchoked > min_time) continue;
|
||||
|
||||
|
@ -613,7 +611,7 @@ namespace libtorrent
|
|||
// every minute, disconnect the worst peer in hope of finding a better peer
|
||||
|
||||
boost::posix_time::ptime local_time = second_clock::universal_time();
|
||||
if(m_last_optimistic_disconnect + boost::posix_time::seconds(120) <= local_time)
|
||||
if (m_last_optimistic_disconnect + boost::posix_time::seconds(120) <= local_time)
|
||||
{
|
||||
m_last_optimistic_disconnect = local_time;
|
||||
--max_connections; // this will have the effect of disconnecting the worst peer
|
||||
|
@ -627,7 +625,8 @@ namespace libtorrent
|
|||
|
||||
while (num_connected_peers > max_connections)
|
||||
{
|
||||
assert(disconnect_one_peer());
|
||||
bool ret = disconnect_one_peer();
|
||||
assert(ret);
|
||||
--num_connected_peers;
|
||||
}
|
||||
}
|
||||
|
@ -714,8 +713,7 @@ namespace libtorrent
|
|||
{
|
||||
// choke peers that have leeched too much without giving anything back
|
||||
for (std::vector<peer>::iterator i = m_peers.begin();
|
||||
i != m_peers.end();
|
||||
++i)
|
||||
i != m_peers.end(); ++i)
|
||||
{
|
||||
peer_connection* c = i->connection;
|
||||
if (c == 0) continue;
|
||||
|
|
|
@ -280,7 +280,8 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
void torrent::tracker_response(
|
||||
std::vector<peer_entry>& peer_list
|
||||
tracker_request const& r
|
||||
, std::vector<peer_entry>& peer_list
|
||||
, int interval
|
||||
, int complete
|
||||
, int incomplete)
|
||||
|
@ -1259,11 +1260,13 @@ namespace libtorrent
|
|||
for (int i = req.first; i < req.first + req.second; ++i)
|
||||
{
|
||||
assert(m_requested_metadata[i] > 0);
|
||||
--m_requested_metadata[i];
|
||||
if (m_requested_metadata[i] > 0)
|
||||
--m_requested_metadata[i];
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::tracker_request_timed_out()
|
||||
void torrent::tracker_request_timed_out(
|
||||
tracker_request const&)
|
||||
{
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
debug_log("*** tracker timed out");
|
||||
|
@ -1283,7 +1286,8 @@ namespace libtorrent
|
|||
// TODO: with some response codes, we should just consider
|
||||
// the tracker as a failure and not retry
|
||||
// it anymore
|
||||
void torrent::tracker_request_error(int response_code, const std::string& str)
|
||||
void torrent::tracker_request_error(tracker_request const& r
|
||||
, int response_code, const std::string& str)
|
||||
{
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
debug_log(std::string("*** tracker error: ") + str);
|
||||
|
|
|
@ -197,6 +197,7 @@ namespace libtorrent
|
|||
|
||||
bool inflate_gzip(
|
||||
std::vector<char>& buffer
|
||||
, tracker_request const& req
|
||||
, request_callback* requester
|
||||
, int maximum_tracker_response_length)
|
||||
{
|
||||
|
@ -205,7 +206,7 @@ namespace libtorrent
|
|||
int header_len = gzip_header(&buffer[0], (int)buffer.size());
|
||||
if (header_len < 0)
|
||||
{
|
||||
requester->tracker_request_error(200, "invalid gzip header in tracker response");
|
||||
requester->tracker_request_error(req, 200, "invalid gzip header in tracker response");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -229,7 +230,7 @@ namespace libtorrent
|
|||
// and just deflate the buffer
|
||||
if (inflateInit2(&str, -15) != Z_OK)
|
||||
{
|
||||
requester->tracker_request_error(200, "gzip out of memory");
|
||||
requester->tracker_request_error(req, 200, "gzip out of memory");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -242,7 +243,8 @@ namespace libtorrent
|
|||
if (inflate_buffer.size() >= (unsigned)maximum_tracker_response_length)
|
||||
{
|
||||
inflateEnd(&str);
|
||||
requester->tracker_request_error(200, "tracker response too large");
|
||||
requester->tracker_request_error(req, 200
|
||||
, "tracker response too large");
|
||||
return true;
|
||||
}
|
||||
int new_size = (int)inflate_buffer.size() * 2;
|
||||
|
@ -262,7 +264,7 @@ namespace libtorrent
|
|||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
requester->tracker_request_error(200, "gzip error");
|
||||
requester->tracker_request_error(req, 200, "gzip error");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -351,7 +353,8 @@ namespace libtorrent
|
|||
catch (const std::exception& e)
|
||||
{
|
||||
if (c->has_requester())
|
||||
c->requester().tracker_request_error(-1, e.what());
|
||||
c->requester().tracker_request_error(c->tracker_req()
|
||||
, -1, e.what());
|
||||
}
|
||||
if (c->has_requester()) c->requester().m_manager = 0;
|
||||
i = m_connections.erase(i);
|
||||
|
@ -469,7 +472,7 @@ namespace libtorrent
|
|||
if (!c.expired())
|
||||
{
|
||||
boost::shared_ptr<request_callback> r = c.lock();
|
||||
r->tracker_request_error(-1, e.what());
|
||||
r->tracker_request_error(req, -1, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,8 @@ namespace libtorrent
|
|||
{
|
||||
if (m_attempts >= udp_connection_retries)
|
||||
{
|
||||
if (has_requester()) requester().tracker_request_timed_out();
|
||||
if (has_requester())
|
||||
requester().tracker_request_timed_out(m_request);
|
||||
return true;
|
||||
}
|
||||
send_udp_connect();
|
||||
|
@ -118,7 +119,8 @@ namespace libtorrent
|
|||
{
|
||||
if (m_attempts >= udp_announce_retries)
|
||||
{
|
||||
if (has_requester()) requester().tracker_request_timed_out();
|
||||
if (has_requester())
|
||||
requester().tracker_request_timed_out(m_request);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -140,7 +142,8 @@ namespace libtorrent
|
|||
if (ret == udp_buffer_size)
|
||||
{
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(-1, "tracker reply too big");
|
||||
requester().tracker_request_error(
|
||||
m_request, -1, "tracker reply too big");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -239,7 +242,8 @@ namespace libtorrent
|
|||
if (action == error)
|
||||
{
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(-1, std::string(buf, buf + len - 8));
|
||||
requester().tracker_request_error(
|
||||
m_request, -1, std::string(buf, buf + len - 8));
|
||||
return true;
|
||||
}
|
||||
if (action != announce) return false;
|
||||
|
@ -260,7 +264,8 @@ namespace libtorrent
|
|||
if ((len - 24) % 6 != 0)
|
||||
{
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(-1, "invalid tracker response");
|
||||
requester().tracker_request_error(
|
||||
m_request, -1, "invalid tracker response");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -281,7 +286,8 @@ namespace libtorrent
|
|||
peer_list.push_back(e);
|
||||
}
|
||||
|
||||
requester().tracker_response(peer_list, interval, complete, incomplete);
|
||||
requester().tracker_response(m_request, peer_list, interval
|
||||
, complete, incomplete);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -306,7 +312,8 @@ namespace libtorrent
|
|||
if (action == error)
|
||||
{
|
||||
if (has_requester())
|
||||
requester().tracker_request_error(-1, std::string(ptr, buf + len));
|
||||
requester().tracker_request_error(
|
||||
m_request, -1, std::string(ptr, buf + len));
|
||||
return true;
|
||||
}
|
||||
if (action != connect) return false;
|
||||
|
|
Loading…
Reference in New Issue