From 3077fdcb6a9b6fe23604ff150b74615dfb338405 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 7 Sep 2008 10:03:59 +0000 Subject: [PATCH] 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) --- .../libtorrent/http_tracker_connection.hpp | 6 +++ include/libtorrent/tracker_manager.hpp | 1 + include/libtorrent/udp_tracker_connection.hpp | 1 + src/http_tracker_connection.cpp | 52 +++++++++++-------- src/tracker_manager.cpp | 1 + src/udp_tracker_connection.cpp | 7 ++- 6 files changed, 44 insertions(+), 24 deletions(-) diff --git a/include/libtorrent/http_tracker_connection.hpp b/include/libtorrent/http_tracker_connection.hpp index 04701fc00..ec34260b0 100644 --- a/include/libtorrent/http_tracker_connection.hpp +++ b/include/libtorrent/http_tracker_connection.hpp @@ -75,6 +75,7 @@ namespace libtorrent , proxy_settings const& ps , std::string const& password = ""); + void start(); void close(); private: @@ -92,6 +93,11 @@ namespace libtorrent tracker_manager& m_man; boost::shared_ptr 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; }; } diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index c9d1f52c6..8b3781bf8 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -194,6 +194,7 @@ namespace libtorrent void fail(int code, char const* msg); void fail_timeout(); + virtual void start() = 0; virtual void close(); address const& bind_interface() const { return m_bind_interface; } diff --git a/include/libtorrent/udp_tracker_connection.hpp b/include/libtorrent/udp_tracker_connection.hpp index dd0dea9fe..fe51df1fb 100644 --- a/include/libtorrent/udp_tracker_connection.hpp +++ b/include/libtorrent/udp_tracker_connection.hpp @@ -74,6 +74,7 @@ namespace libtorrent , session_settings const& stn , proxy_settings const& ps); + void start(); void close(); private: diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index b87ee0a28..f83163bd2 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -79,11 +79,19 @@ namespace libtorrent , std::string const& auth) : tracker_connection(man, req, ios, bind_infc, c) , 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 - 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" // in request @@ -92,7 +100,7 @@ namespace libtorrent if (pos == std::string::npos) { fail(-1, ("scrape is not available on url: '" - + req.url +"'").c_str()); + + tracker_req().url +"'").c_str()); return; } url.replace(pos, 8, "scrape"); @@ -109,70 +117,70 @@ namespace libtorrent url += "info_hash="; url += escape_string( - reinterpret_cast(req.info_hash.begin()), 20); + reinterpret_cast(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 += escape_string( - reinterpret_cast(req.pid.begin()), 20); + reinterpret_cast(tracker_req().pid.begin()), 20); url += "&port="; - url += boost::lexical_cast(req.listen_port); + url += boost::lexical_cast(tracker_req().listen_port); url += "&uploaded="; - url += boost::lexical_cast(req.uploaded); + url += boost::lexical_cast(tracker_req().uploaded); url += "&downloaded="; - url += boost::lexical_cast(req.downloaded); + url += boost::lexical_cast(tracker_req().downloaded); url += "&left="; - url += boost::lexical_cast(req.left); + url += boost::lexical_cast(tracker_req().left); - if (req.event != tracker_request::none) + if (tracker_req().event != tracker_request::none) { const char* event_string[] = {"completed", "started", "stopped"}; url += "&event="; - url += event_string[req.event - 1]; + url += event_string[tracker_req().event - 1]; } url += "&key="; std::stringstream key_string; - key_string << std::hex << req.key; + key_string << std::hex << tracker_req().key; url += key_string.str(); url += "&compact=1"; url += "&numwant="; url += boost::lexical_cast( - (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 += stn.announce_ip.to_string(); + url += m_settings.announce_ip.to_string(); } #ifndef TORRENT_DISABLE_ENCRYPTION url += "&supportcrypto=1"; #endif url += "&ipv6="; - url += req.ipv6; + url += tracker_req().ipv6; // extension that tells the tracker that // we don't need any peer_id's in the response 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))); - int timeout = req.event==tracker_request::stopped - ?stn.stop_tracker_timeout - :stn.tracker_completion_timeout; + int timeout = tracker_req().event==tracker_request::stopped + ?m_settings.stop_tracker_timeout + :m_settings.tracker_completion_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) diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index 6a0b28d60..621c3b99c 100644 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -229,6 +229,7 @@ namespace libtorrent boost::shared_ptr cb = con->requester(); if (cb) cb->m_manager = this; + con->start(); } void tracker_manager::abort_all_requests() diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index e19d5696d..191be4c61 100644 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -93,14 +93,17 @@ namespace libtorrent , m_state(action_error) { m_socket.set_proxy_settings(proxy); + } + void udp_tracker_connection::start() + { std::string hostname; int port; char const* error; using boost::tuples::ignore; boost::tie(ignore, ignore, hostname, port, ignore, error) - = parse_url_components(req.url); + = parse_url_components(tracker_req().url); if (error) { @@ -112,7 +115,7 @@ namespace libtorrent m_name_lookup.async_resolve(q , boost::bind( &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.tracker_completion_timeout , m_settings.tracker_receive_timeout);