From cdf05a9c9c62352dd073909c571d6cfc7c4f7fe3 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 30 May 2010 01:33:03 +0000 Subject: [PATCH] moved UDP trackers over to use a single socket --- ChangeLog | 1 + include/libtorrent/aux_/session_impl.hpp | 20 +-- include/libtorrent/tracker_manager.hpp | 4 + include/libtorrent/udp_socket.hpp | 5 + include/libtorrent/udp_tracker_connection.hpp | 21 +-- src/session_impl.cpp | 149 +++++++++--------- src/tracker_manager.cpp | 11 ++ src/udp_tracker_connection.cpp | 111 ++++++------- 8 files changed, 160 insertions(+), 162 deletions(-) diff --git a/ChangeLog b/ChangeLog index fce2e40f5..893e419e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * moved UDP trackers over to use a single socket * added feature to make asserts log to a file instead of breaking the process (production asserts) * optimized disk I/O cache clearing diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index c7d686aee..4f46fcb45 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -300,6 +300,7 @@ namespace libtorrent // in case we just set a socks proxy, we might have to // open the socks incoming connection if (!m_socks_listen_socket) open_new_incoming_socks_connection(); + m_udp_socket.set_proxy_settings(m_peer_proxy); } void set_web_seed_proxy(proxy_settings const& s) { m_web_seed_proxy = s; } @@ -317,7 +318,7 @@ namespace libtorrent void set_dht_proxy(proxy_settings const& s) { m_dht_proxy = s; - m_dht_socket.set_proxy_settings(s); + m_udp_socket.set_proxy_settings(s); } proxy_settings const& dht_proxy() const { return m_dht_proxy; } @@ -693,18 +694,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_DHT boost::intrusive_ptr m_dht; dht_settings m_dht_settings; - // if this is set to true, the dht listen port - // will be set to the same as the tcp listen port - // and will be synchronlized with it as it changes - // it defaults to true - bool m_dht_same_port; - // see m_external_listen_port. This is the same - // but for the udp port used by the DHT. - int m_external_udp_port; - - rate_limited_udp_socket m_dht_socket; - // these are used when starting the DHT // (and bootstrapping it), and then erased std::list m_dht_router_nodes; @@ -717,6 +707,12 @@ namespace libtorrent deadline_timer m_dht_announce_timer; #endif + // see m_external_listen_port. This is the same + // but for the udp port used by the DHT. + int m_external_udp_port; + + rate_limited_udp_socket m_udp_socket; + #ifndef TORRENT_DISABLE_ENCRYPTION pe_settings m_pe_settings; #endif diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 62da5f34c..21becdf0f 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -209,6 +209,8 @@ namespace libtorrent address const& bind_interface() const { return m_req.bind_ip; } void sent_bytes(int bytes); void received_bytes(int bytes); + virtual bool on_receive(error_code const& ec, udp::endpoint const& ep + , char const* buf, int size) { return false; } protected: boost::weak_ptr m_requester; @@ -242,6 +244,8 @@ namespace libtorrent void sent_bytes(int bytes); void received_bytes(int bytes); + + bool incoming_udp(error_code const& e, udp::endpoint const& ep, char const* buf, int size); private: diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp index 0370e127e..31f39b106 100644 --- a/include/libtorrent/udp_socket.hpp +++ b/include/libtorrent/udp_socket.hpp @@ -77,6 +77,11 @@ namespace libtorrent proxy_settings const& get_proxy_settings() { return m_proxy_settings; } bool is_closed() const { return m_abort; } + tcp::endpoint local_endpoint() const + { + udp::endpoint ep = m_ipv4_sock.local_endpoint(); + return tcp::endpoint(ep.address(), ep.port()); + } protected: diff --git a/include/libtorrent/udp_tracker_connection.hpp b/include/libtorrent/udp_tracker_connection.hpp index 822c4f0eb..aed2fee77 100644 --- a/include/libtorrent/udp_tracker_connection.hpp +++ b/include/libtorrent/udp_tracker_connection.hpp @@ -72,7 +72,7 @@ namespace libtorrent , tracker_manager& man , tracker_request const& req , boost::weak_ptr c - , aux::session_impl const& ses + , aux::session_impl& ses , proxy_settings const& ps); void start(); @@ -91,14 +91,14 @@ namespace libtorrent boost::intrusive_ptr self() { return boost::intrusive_ptr(this); } - void name_lookup(error_code const& error, udp::resolver::iterator i); + void name_lookup(error_code const& error, tcp::resolver::iterator i); void timeout(error_code const& error); - void on_receive(error_code const& e, udp::endpoint const& ep + bool on_receive(error_code const& e, udp::endpoint const& ep , char const* buf, int size); - void on_connect_response(char const* buf, int size); - void on_announce_response(char const* buf, int size); - void on_scrape_response(char const* buf, int size); + bool on_connect_response(char const* buf, int size); + bool on_announce_response(char const* buf, int size); + bool on_scrape_response(char const* buf, int size); void send_udp_connect(); void send_udp_announce(); @@ -108,13 +108,14 @@ namespace libtorrent tracker_manager& m_man; - udp::resolver m_name_lookup; - udp_socket m_socket; +// udp::resolver m_name_lookup; +// udp_socket m_socket; + bool m_abort; udp::endpoint m_target; - std::list m_endpoints; + std::list m_endpoints; int m_transaction_id; - aux::session_impl const& m_ses; + aux::session_impl& m_ses; int m_attempts; struct connection_cache_entry diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b4834a438..9af7e7e74 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -340,7 +340,9 @@ namespace aux { { TORRENT_SETTING(integer, max_peers_reply) TORRENT_SETTING(integer, search_branching) +#ifndef TORRENT_NO_DEPRECATE TORRENT_SETTING(integer, service_port) +#endif TORRENT_SETTING(integer, max_fail_count) TORRENT_SETTING(integer, max_torrent_search_reply) }; @@ -506,12 +508,11 @@ namespace aux { , m_last_second_tick(m_created) , m_last_choke(m_created) #ifndef TORRENT_DISABLE_DHT - , m_dht_same_port(true) - , m_external_udp_port(0) - , m_dht_socket(m_io_service, boost::bind(&session_impl::on_receive_udp, this, _1, _2, _3, _4) - , m_half_open) , m_dht_announce_timer(m_io_service) #endif + , m_external_udp_port(0) + , m_udp_socket(m_io_service, boost::bind(&session_impl::on_receive_udp, this, _1, _2, _3, _4) + , m_half_open) , m_timer(m_io_service) , m_lsd_announce_timer(m_io_service) , m_host_resolver(m_io_service) @@ -531,6 +532,8 @@ namespace aux { (*m_logger) << time_now_string() << "\n"; #endif + open_listen_port(); + #ifndef TORRENT_DISABLE_DHT m_next_dht_torrent = m_torrents.begin(); #endif @@ -743,8 +746,6 @@ namespace aux { boost::bind(&session_impl::on_dht_announce, this, _1)); #endif - open_listen_port(); - m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this))); } @@ -1040,7 +1041,6 @@ namespace aux { if (m_natpmp) m_natpmp->close(); #ifndef TORRENT_DISABLE_DHT if (m_dht) m_dht->stop(); - m_dht_socket.close(); m_dht_announce_timer.cancel(ec); #endif m_timer.cancel(ec); @@ -1109,6 +1109,11 @@ namespace aux { m_download_rate.close(); m_upload_rate.close(); + + // #error closing the udp socket here means that + // the uTP connections cannot be closed gracefully + m_udp_socket.close(); + m_external_udp_port = 0; } void session_impl::set_port_filter(port_filter const& f) @@ -1342,7 +1347,7 @@ namespace aux { // not even that worked, give up if (m_alerts.should_post()) m_alerts.post_alert(listen_failed_alert(ep, ec)); -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING char msg[200]; snprintf(msg, 200, "cannot bind to interface \"%s\": %s" , print_endpoint(ep).c_str(), ec.message().c_str()); @@ -1356,7 +1361,7 @@ namespace aux { { if (m_alerts.should_post()) m_alerts.post_alert(listen_failed_alert(ep, ec)); -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING char msg[200]; snprintf(msg, 200, "cannot listen on interface \"%s\": %s" , print_endpoint(ep).c_str(), ec.message().c_str()); @@ -1368,7 +1373,7 @@ namespace aux { if (m_alerts.should_post()) m_alerts.post_alert(listen_succeeded_alert(ep)); -#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING (*m_logger) << "listening on: " << ep << " external port: " << s.external_port << "\n"; #endif @@ -1395,6 +1400,16 @@ namespace aux { if (s.sock) { + // if we're configured to listen on port 0 (i.e. let the + // OS decide), update the listen_interface member with the + // actual port we ended up listening on, so that the other + // sockets can be bound to the same one + if (m_listen_interface.port() == 0) + { + error_code ec; + m_listen_interface.port(s.sock->local_endpoint(ec).port()); + } + m_listen_sockets.push_back(s); async_accept(s.sock); } @@ -1447,6 +1462,27 @@ namespace aux { else m_ipv4_interface = m_listen_interface; } + + } + + error_code ec; + m_udp_socket.bind(udp::endpoint(m_listen_interface.address(), m_listen_interface.port()), ec); + if (ec) + { + if (m_alerts.should_post()) + m_alerts.post_alert(listen_failed_alert(m_listen_interface, ec)); +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING + char msg[200]; + snprintf(msg, sizeof(msg), "cannot bind to UDP interface \"%s\": %s" + , print_endpoint(m_listen_interface).c_str(), ec.message().c_str()); + (*m_logger) << msg << "\n"; +#endif + } + else + { + m_external_udp_port = m_udp_socket.local_port(); + maybe_update_udp_mapping(0, m_listen_interface.port(), m_listen_interface.port()); + maybe_update_udp_mapping(1, m_listen_interface.port(), m_listen_interface.port()); } open_new_incoming_socks_connection(); @@ -1536,6 +1572,12 @@ namespace aux { if (m_alerts.should_post()) m_alerts.post_alert(listen_failed_alert(tcp::endpoint( address_v4::any(), m_listen_interface.port()), e)); +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING + char msg[200]; + snprintf(msg, sizeof(msg), "cannot bind to port %d: %s" + , m_listen_interface.port(), e.message().c_str()); + (*m_logger) << msg << "\n"; +#endif return; } open_new_incoming_i2p_connection(); @@ -1553,18 +1595,27 @@ namespace aux { if (e == asio::error::connection_refused || e == asio::error::connection_reset || e == asio::error::connection_aborted) + { m_dht->on_unreachable(ep); + if (m_tracker_manager.incoming_udp(e, ep, buf, len)) + m_stat.received_tracker_bytes(len + 28); + } if (m_alerts.should_post()) m_alerts.post_alert(udp_error_alert(ep, e)); return; } - if (len > 20 && *buf == 'd' && m_dht) + if (len > 20 && *buf == 'd' && buf[len-1] == 'e' && m_dht) { // this is probably a dht message m_dht->on_receive(ep, buf, len); } + // maybe it's a udp tracker response + else if (m_tracker_manager.incoming_udp(e, ep, buf, len)) + { + m_stat.received_tracker_bytes(len + 28); + } } #endif @@ -3174,22 +3225,6 @@ namespace aux { open_listen_port(); - bool new_listen_address = m_listen_interface.address() != new_interface.address(); - -#ifndef TORRENT_DISABLE_DHT - if ((new_listen_address || m_dht_same_port) && m_dht) - { - if (m_dht_same_port) - m_dht_settings.service_port = new_interface.port(); - // the listen interface changed, rebind the dht listen socket as well - error_code ec; - m_dht_socket.bind(udp::endpoint(m_listen_interface.address(), m_dht_settings.service_port), ec); - - maybe_update_udp_mapping(0, m_dht_settings.service_port, m_dht_settings.service_port); - maybe_update_udp_mapping(1, m_dht_settings.service_port, m_dht_settings.service_port); - } -#endif - #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING m_logger = create_log("main_session", listen_port(), false); (*m_logger) << time_now_string() << "\n"; @@ -3261,17 +3296,14 @@ namespace aux { mutex::scoped_lock l(m_mutex); TORRENT_ASSERT(map_transport >= 0 && map_transport <= 1); -#ifndef TORRENT_DISABLE_DHT if (mapping == m_udp_mapping[map_transport] && port != 0) { m_external_udp_port = port; - m_dht_settings.service_port = port; if (m_alerts.should_post()) m_alerts.post_alert(portmap_alert(mapping, port , map_transport)); return; } -#endif if (mapping == m_tcp_mapping[map_transport] && port != 0) { @@ -3405,24 +3437,7 @@ namespace aux { m_dht->stop(); m_dht = 0; } - if (m_dht_settings.service_port == 0 - || m_dht_same_port) - { - m_dht_same_port = true; - if (m_listen_interface.port() > 0) - m_dht_settings.service_port = m_listen_interface.port(); - else - m_dht_settings.service_port = 45000 + (rand() % 10000); - } - m_external_udp_port = m_dht_settings.service_port; - maybe_update_udp_mapping(0, m_dht_settings.service_port, m_dht_settings.service_port); - maybe_update_udp_mapping(1, m_dht_settings.service_port, m_dht_settings.service_port); - m_dht = new dht::dht_tracker(*this, m_dht_socket, m_dht_settings, &startup_state); - if (!m_dht_socket.is_open() || m_dht_socket.local_port() != m_dht_settings.service_port) - { - error_code ec; - m_dht_socket.bind(udp::endpoint(m_listen_interface.address(), m_dht_settings.service_port), ec); - } + m_dht = new dht::dht_tracker(*this, m_udp_socket, m_dht_settings, &startup_state); for (std::list::iterator i = m_dht_router_nodes.begin() , end(m_dht_router_nodes.end()); i != end; ++i) @@ -3488,27 +3503,7 @@ namespace aux { void session_impl::set_dht_settings(dht_settings const& settings) { - // only change the dht listen port in case the settings - // contains a vaiid port, and if it is different from - // the current setting - if (settings.service_port != 0) - m_dht_same_port = false; - else - m_dht_same_port = true; - if (!m_dht_same_port - && settings.service_port != m_dht_settings.service_port - && m_dht) - { - error_code ec; - m_dht_socket.bind(udp::endpoint(m_listen_interface.address(), settings.service_port), ec); - - maybe_update_udp_mapping(0, settings.service_port, settings.service_port); - maybe_update_udp_mapping(1, settings.service_port, settings.service_port); - m_external_udp_port = settings.service_port; - } m_dht_settings = settings; - if (m_dht_same_port) - m_dht_settings.service_port = m_listen_interface.port(); } void session_impl::on_dht_state_callback(condition& c @@ -3766,12 +3761,11 @@ namespace aux { m_tcp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp , m_listen_interface.port(), m_listen_interface.port()); } -#ifndef TORRENT_DISABLE_DHT - if (m_dht) + if (m_udp_socket.is_open()) + { m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp - , m_dht_settings.service_port - , m_dht_settings.service_port); -#endif + , m_listen_interface.port(), m_listen_interface.port()); + } } void session_impl::start_upnp(upnp* u) @@ -3786,12 +3780,11 @@ namespace aux { m_tcp_mapping[1] = m_upnp->add_mapping(upnp::tcp , m_listen_interface.port(), m_listen_interface.port()); } -#ifndef TORRENT_DISABLE_DHT - if (m_dht) + if (m_udp_socket.is_open()) + { m_udp_mapping[1] = m_upnp->add_mapping(upnp::udp - , m_dht_settings.service_port - , m_dht_settings.service_port); -#endif + , m_listen_interface.port(), m_listen_interface.port()); + } } void session_impl::stop_lsd() diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index 23fb893f2..4ece3850d 100644 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -252,6 +252,17 @@ namespace libtorrent con->start(); } + bool tracker_manager::incoming_udp(error_code const& e + , udp::endpoint const& ep, char const* buf, int size) + { + for (tracker_connections_t::iterator i = m_connections.begin() + , end(m_connections.end()); i != end; ++i) + { + if ((*i)->on_receive(e, ep, buf, size)) return true; + } + return false; + } + void tracker_manager::abort_all_requests(bool all) { // removes all connections from m_connections diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index 34ea1812f..ca604064e 100644 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -66,19 +66,16 @@ namespace libtorrent , tracker_manager& man , tracker_request const& req , boost::weak_ptr c - , aux::session_impl const& ses + , aux::session_impl& ses , proxy_settings const& proxy) : tracker_connection(man, req, ios, c) , m_man(man) - , m_name_lookup(ios) - , m_socket(ios, boost::bind(&udp_tracker_connection::on_receive, self(), _1, _2, _3, _4), cc) + , m_abort(false) , m_transaction_id(0) , m_ses(ses) , m_attempts(0) , m_state(action_error) { - TORRENT_ASSERT(refcount() == 1); - m_socket.set_proxy_settings(proxy); } void udp_tracker_connection::start() @@ -94,15 +91,15 @@ namespace libtorrent if (ec) { // never call fail() when the session mutex is locked! - m_socket.get_io_service().post(boost::bind( + m_ses.m_io_service.post(boost::bind( &tracker_connection::fail_disp, self(), ec)); return; } session_settings const& settings = m_ses.settings(); - udp::resolver::query q(hostname, to_string(port).elems); - m_name_lookup.async_resolve(q + tcp::resolver::query q(hostname, to_string(port).elems); + m_ses.m_host_resolver.async_resolve(q , boost::bind( &udp_tracker_connection::name_lookup, self(), _1, _2)); set_timeout(tracker_req().event == tracker_request::stopped @@ -116,10 +113,11 @@ namespace libtorrent } void udp_tracker_connection::name_lookup(error_code const& error - , udp::resolver::iterator i) + , tcp::resolver::iterator i) { + if (m_abort) return; if (error == asio::error::operation_aborted) return; - if (error || i == udp::resolver::iterator()) + if (error || i == tcp::resolver::iterator()) { fail(error); return; @@ -141,11 +139,11 @@ namespace libtorrent // we're listening on. To make sure the tracker get our // correct listening address. - std::transform(i, udp::resolver::iterator(), std::back_inserter(m_endpoints) - , boost::bind(&udp::resolver::iterator::value_type::endpoint, _1)); + std::transform(i, tcp::resolver::iterator(), std::back_inserter(m_endpoints) + , boost::bind(&tcp::resolver::iterator::value_type::endpoint, _1)); // remove endpoints that are filtered by the IP filter - for (std::list::iterator i = m_endpoints.begin(); + for (std::list::iterator i = m_endpoints.begin(); i != m_endpoints.end();) { if (m_ses.m_ip_filter.access(i->address()) == ip_filter::blocked) @@ -160,8 +158,8 @@ namespace libtorrent return; } - std::list::iterator iter = m_endpoints.begin(); - m_target = *iter; + std::list::iterator iter = m_endpoints.begin(); + m_target = udp::endpoint(iter->address(), iter->port()); if (bind_interface() != address_v4::any()) { @@ -188,20 +186,12 @@ namespace libtorrent } else { - m_target = *iter; + m_target = udp::endpoint(iter->address(), iter->port()); } } if (cb) cb->m_tracker_address = tcp::endpoint(m_target.address(), m_target.port()); - error_code ec; - m_socket.bind(udp::endpoint(bind_interface(), 0), ec); - if (ec) - { - fail(ec); - return; - } - mutex::scoped_lock l(m_cache_mutex); std::map::iterator cc = m_connection_cache.find(m_target.address()); @@ -233,31 +223,27 @@ namespace libtorrent snprintf(msg, 200, "*** UDP_TRACKER [ timed out url: %s ]", tracker_req().url.c_str()); if (cb) cb->debug_log(msg); #endif - m_socket.close(); - m_name_lookup.cancel(); + m_abort = true; fail(error_code(errors::timed_out)); } void udp_tracker_connection::close() { error_code ec; - m_socket.close(); - m_name_lookup.cancel(); tracker_connection::close(); } - void udp_tracker_connection::on_receive(error_code const& e + bool udp_tracker_connection::on_receive(error_code const& e , udp::endpoint const& ep, char const* buf, int size) { // ignore resposes before we've sent any requests - if (m_state == action_error) return; + if (m_state == action_error) return false; - if (!m_socket.is_open()) return; // the operation was aborted + if (m_abort) return false; // ignore packet not sent from the tracker - if (m_target != ep) return; + if (m_target != ep) return false; - received_bytes(size + 28); // assuming UDP/IP header if (e) fail(e); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING @@ -271,7 +257,7 @@ namespace libtorrent #endif // ignore packets smaller than 8 bytes - if (size < 8) return; + if (size < 8) return false; restart_read_timeout(); @@ -289,16 +275,16 @@ namespace libtorrent #endif // ignore packets with incorrect transaction id - if (m_transaction_id != transaction) return; + if (m_transaction_id != transaction) return false; if (action == action_error) { fail(error_code(errors::tracker_failure), -1, std::string(ptr, size - 8).c_str()); - return; + return true; } // ignore packets that's not a response to our message - if (action != m_state) return; + if (action != m_state) return false; #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING if (cb) @@ -313,22 +299,20 @@ namespace libtorrent switch (m_state) { case action_connect: - on_connect_response(buf, size); - break; + return on_connect_response(buf, size); case action_announce: - on_announce_response(buf, size); - break; + return on_announce_response(buf, size); case action_scrape: - on_scrape_response(buf, size); - break; + return on_scrape_response(buf, size); default: break; } + return false; } - void udp_tracker_connection::on_connect_response(char const* buf, int size) + bool udp_tracker_connection::on_connect_response(char const* buf, int size) { // ignore packets smaller than 16 bytes - if (size < 16) return; + if (size < 16) return false; restart_read_timeout(); buf += 8; // skip header @@ -347,6 +331,7 @@ namespace libtorrent send_udp_announce(); else if (tracker_req().kind == tracker_request::scrape_request) send_udp_scrape(); + return true; } void udp_tracker_connection::send_udp_connect() @@ -362,7 +347,7 @@ namespace libtorrent cb->debug_log(msg); } #endif - if (!m_socket.is_open()) return; // the operation was aborted + if (m_abort) return; char buf[16]; char* ptr = buf; @@ -377,7 +362,7 @@ namespace libtorrent TORRENT_ASSERT(ptr - buf == sizeof(buf)); error_code ec; - m_socket.send(m_target, buf, 16, ec); + m_ses.m_udp_socket.send(m_target, buf, 16, ec); m_state = action_connect; sent_bytes(16 + 28); // assuming UDP/IP header ++m_attempts; @@ -393,7 +378,7 @@ namespace libtorrent if (m_transaction_id == 0) m_transaction_id = std::rand() ^ (std::rand() << 16); - if (!m_socket.is_open()) return; // the operation was aborted + if (m_abort) return; std::map::iterator i = m_connection_cache.find(m_target.address()); @@ -413,7 +398,7 @@ namespace libtorrent TORRENT_ASSERT(out - buf == sizeof(buf)); error_code ec; - m_socket.send(m_target, buf, sizeof(buf), ec); + m_ses.m_udp_socket.send(m_target, buf, sizeof(buf), ec); m_state = action_scrape; sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header ++m_attempts; @@ -424,9 +409,9 @@ namespace libtorrent } } - void udp_tracker_connection::on_announce_response(char const* buf, int size) + bool udp_tracker_connection::on_announce_response(char const* buf, int size) { - if (size < 20) return; + if (size < 20) return false; buf += 8; // skip header restart_read_timeout(); @@ -438,7 +423,7 @@ namespace libtorrent if ((size - 20) % 6 != 0) { fail(error_code(errors::invalid_tracker_response_length)); - return; + return false; } boost::shared_ptr cb = requester(); @@ -455,7 +440,7 @@ namespace libtorrent if (!cb) { m_man.remove_request(this); - return; + return true; } std::vector peer_list; @@ -476,7 +461,7 @@ namespace libtorrent } std::list
ip_list; - for (std::list::const_iterator i = m_endpoints.begin() + for (std::list::const_iterator i = m_endpoints.begin() , end(m_endpoints.end()); i != end; ++i) { ip_list.push_back(i->address()); @@ -487,9 +472,10 @@ namespace libtorrent m_man.remove_request(this); close(); + return true; } - void udp_tracker_connection::on_scrape_response(char const* buf, int size) + bool udp_tracker_connection::on_scrape_response(char const* buf, int size) { restart_read_timeout(); int action = detail::read_int32(buf); @@ -498,25 +484,25 @@ namespace libtorrent if (transaction != m_transaction_id) { fail(error_code(errors::invalid_tracker_transaction_id)); - return; + return false; } if (action == action_error) { fail(error_code(errors::tracker_failure), -1, std::string(buf, size - 8).c_str()); - return; + return true; } if (action != action_scrape) { fail(error_code(errors::invalid_tracker_action)); - return; + return true; } if (size < 20) { fail(error_code(errors::invalid_tracker_response_length)); - return; + return true; } int complete = detail::read_int32(buf); @@ -527,7 +513,7 @@ namespace libtorrent if (!cb) { close(); - return; + return true; } cb->tracker_scrape_response(tracker_req() @@ -535,6 +521,7 @@ namespace libtorrent m_man.remove_request(this); close(); + return true; } void udp_tracker_connection::send_udp_announce() @@ -542,7 +529,7 @@ namespace libtorrent if (m_transaction_id == 0) m_transaction_id = std::rand() ^ (std::rand() << 16); - if (!m_socket.is_open()) return; // the operation was aborted + if (m_abort) return; char buf[8 + 4 + 4 + 20 + 20 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 2 + 2]; char* out = buf; @@ -598,7 +585,7 @@ namespace libtorrent #endif error_code ec; - m_socket.send(m_target, buf, sizeof(buf), ec); + m_ses.m_udp_socket.send(m_target, buf, sizeof(buf), ec); m_state = action_announce; sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header ++m_attempts;