fix crash when tracker connections fails in the constructor (used to be the case for scrape when there were no url transform from announce to scrape)

This commit is contained in:
Arvid Norberg 2008-09-07 10:03:59 +00:00
parent a61c1ee01d
commit 3077fdcb6a
6 changed files with 44 additions and 24 deletions

View File

@ -75,6 +75,7 @@ namespace libtorrent
, proxy_settings const& ps , proxy_settings const& ps
, std::string const& password = ""); , std::string const& password = "");
void start();
void close(); void close();
private: private:
@ -92,6 +93,11 @@ namespace libtorrent
tracker_manager& m_man; tracker_manager& m_man;
boost::shared_ptr<http_connection> m_tracker_connection; boost::shared_ptr<http_connection> m_tracker_connection;
session_settings const& m_settings;
address m_bind_iface;
proxy_settings const& m_ps;
connection_queue& m_cc;
io_service& m_ios;
}; };
} }

View File

@ -194,6 +194,7 @@ namespace libtorrent
void fail(int code, char const* msg); void fail(int code, char const* msg);
void fail_timeout(); void fail_timeout();
virtual void start() = 0;
virtual void close(); virtual void close();
address const& bind_interface() const { return m_bind_interface; } address const& bind_interface() const { return m_bind_interface; }

View File

@ -74,6 +74,7 @@ namespace libtorrent
, session_settings const& stn , session_settings const& stn
, proxy_settings const& ps); , proxy_settings const& ps);
void start();
void close(); void close();
private: private:

View File

@ -79,11 +79,19 @@ namespace libtorrent
, std::string const& auth) , std::string const& auth)
: tracker_connection(man, req, ios, bind_infc, c) : tracker_connection(man, req, ios, bind_infc, c)
, m_man(man) , m_man(man)
, m_settings(stn)
, m_bind_iface(bind_infc)
, m_ps(ps)
, m_cc(cc)
, m_ios(ios)
{}
void http_tracker_connection::start()
{ {
// TODO: authentication // TODO: authentication
std::string url = req.url; std::string url = tracker_req().url;
if (req.kind == tracker_request::scrape_request) if (tracker_req().kind == tracker_request::scrape_request)
{ {
// find and replace "announce" with "scrape" // find and replace "announce" with "scrape"
// in request // in request
@ -92,7 +100,7 @@ namespace libtorrent
if (pos == std::string::npos) if (pos == std::string::npos)
{ {
fail(-1, ("scrape is not available on url: '" fail(-1, ("scrape is not available on url: '"
+ req.url +"'").c_str()); + tracker_req().url +"'").c_str());
return; return;
} }
url.replace(pos, 8, "scrape"); url.replace(pos, 8, "scrape");
@ -109,70 +117,70 @@ namespace libtorrent
url += "info_hash="; url += "info_hash=";
url += escape_string( url += escape_string(
reinterpret_cast<const char*>(req.info_hash.begin()), 20); reinterpret_cast<const char*>(tracker_req().info_hash.begin()), 20);
if (req.kind == tracker_request::announce_request) if (tracker_req().kind == tracker_request::announce_request)
{ {
url += "&peer_id="; url += "&peer_id=";
url += escape_string( url += escape_string(
reinterpret_cast<const char*>(req.pid.begin()), 20); reinterpret_cast<const char*>(tracker_req().pid.begin()), 20);
url += "&port="; url += "&port=";
url += boost::lexical_cast<std::string>(req.listen_port); url += boost::lexical_cast<std::string>(tracker_req().listen_port);
url += "&uploaded="; url += "&uploaded=";
url += boost::lexical_cast<std::string>(req.uploaded); url += boost::lexical_cast<std::string>(tracker_req().uploaded);
url += "&downloaded="; url += "&downloaded=";
url += boost::lexical_cast<std::string>(req.downloaded); url += boost::lexical_cast<std::string>(tracker_req().downloaded);
url += "&left="; url += "&left=";
url += boost::lexical_cast<std::string>(req.left); url += boost::lexical_cast<std::string>(tracker_req().left);
if (req.event != tracker_request::none) if (tracker_req().event != tracker_request::none)
{ {
const char* event_string[] = {"completed", "started", "stopped"}; const char* event_string[] = {"completed", "started", "stopped"};
url += "&event="; url += "&event=";
url += event_string[req.event - 1]; url += event_string[tracker_req().event - 1];
} }
url += "&key="; url += "&key=";
std::stringstream key_string; std::stringstream key_string;
key_string << std::hex << req.key; key_string << std::hex << tracker_req().key;
url += key_string.str(); url += key_string.str();
url += "&compact=1"; url += "&compact=1";
url += "&numwant="; url += "&numwant=";
url += boost::lexical_cast<std::string>( url += boost::lexical_cast<std::string>(
(std::min)(req.num_want, 999)); (std::min)(tracker_req().num_want, 999));
if (stn.announce_ip != address()) if (m_settings.announce_ip != address())
{ {
url += "&ip="; url += "&ip=";
url += stn.announce_ip.to_string(); url += m_settings.announce_ip.to_string();
} }
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
url += "&supportcrypto=1"; url += "&supportcrypto=1";
#endif #endif
url += "&ipv6="; url += "&ipv6=";
url += req.ipv6; url += tracker_req().ipv6;
// extension that tells the tracker that // extension that tells the tracker that
// we don't need any peer_id's in the response // we don't need any peer_id's in the response
url += "&no_peer_id=1"; url += "&no_peer_id=1";
} }
m_tracker_connection.reset(new http_connection(ios, cc m_tracker_connection.reset(new http_connection(m_ios, m_cc
, boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4))); , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4)));
int timeout = req.event==tracker_request::stopped int timeout = tracker_req().event==tracker_request::stopped
?stn.stop_tracker_timeout ?m_settings.stop_tracker_timeout
:stn.tracker_completion_timeout; :m_settings.tracker_completion_timeout;
m_tracker_connection->get(url, seconds(timeout) m_tracker_connection->get(url, seconds(timeout)
, 1, &ps, 5, stn.user_agent, bind_infc); , 1, &m_ps, 5, m_settings.user_agent, m_bind_iface);
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)

View File

@ -229,6 +229,7 @@ namespace libtorrent
boost::shared_ptr<request_callback> cb = con->requester(); boost::shared_ptr<request_callback> cb = con->requester();
if (cb) cb->m_manager = this; if (cb) cb->m_manager = this;
con->start();
} }
void tracker_manager::abort_all_requests() void tracker_manager::abort_all_requests()

View File

@ -93,14 +93,17 @@ namespace libtorrent
, m_state(action_error) , m_state(action_error)
{ {
m_socket.set_proxy_settings(proxy); m_socket.set_proxy_settings(proxy);
}
void udp_tracker_connection::start()
{
std::string hostname; std::string hostname;
int port; int port;
char const* error; char const* error;
using boost::tuples::ignore; using boost::tuples::ignore;
boost::tie(ignore, ignore, hostname, port, ignore, error) boost::tie(ignore, ignore, hostname, port, ignore, error)
= parse_url_components(req.url); = parse_url_components(tracker_req().url);
if (error) if (error)
{ {
@ -112,7 +115,7 @@ namespace libtorrent
m_name_lookup.async_resolve(q m_name_lookup.async_resolve(q
, boost::bind( , boost::bind(
&udp_tracker_connection::name_lookup, self(), _1, _2)); &udp_tracker_connection::name_lookup, self(), _1, _2));
set_timeout(req.event == tracker_request::stopped set_timeout(tracker_req().event == tracker_request::stopped
? m_settings.stop_tracker_timeout ? m_settings.stop_tracker_timeout
: m_settings.tracker_completion_timeout : m_settings.tracker_completion_timeout
, m_settings.tracker_receive_timeout); , m_settings.tracker_receive_timeout);