moved UDP trackers over to use a single socket

This commit is contained in:
Arvid Norberg 2010-05-30 01:33:03 +00:00
parent c796157f81
commit cdf05a9c9c
8 changed files with 160 additions and 162 deletions

View File

@ -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

View File

@ -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<dht::dht_tracker> 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<udp::endpoint> 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

View File

@ -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<request_callback> 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:

View File

@ -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:

View File

@ -72,7 +72,7 @@ namespace libtorrent
, tracker_manager& man
, tracker_request const& req
, boost::weak_ptr<request_callback> 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<udp_tracker_connection> self()
{ return boost::intrusive_ptr<udp_tracker_connection>(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<udp::endpoint> m_endpoints;
std::list<tcp::endpoint> m_endpoints;
int m_transaction_id;
aux::session_impl const& m_ses;
aux::session_impl& m_ses;
int m_attempts;
struct connection_cache_entry

View File

@ -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<listen_failed_alert>())
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<listen_failed_alert>())
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<listen_succeeded_alert>())
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<listen_failed_alert>())
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<listen_failed_alert>())
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<udp_error_alert>())
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<portmap_alert>())
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<udp::endpoint>::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()

View File

@ -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

View File

@ -66,19 +66,16 @@ namespace libtorrent
, tracker_manager& man
, tracker_request const& req
, boost::weak_ptr<request_callback> 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<udp::endpoint>::iterator i = m_endpoints.begin();
for (std::list<tcp::endpoint>::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<udp::endpoint>::iterator iter = m_endpoints.begin();
m_target = *iter;
std::list<tcp::endpoint>::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<address, connection_cache_entry>::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<address, connection_cache_entry>::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<request_callback> cb = requester();
@ -455,7 +440,7 @@ namespace libtorrent
if (!cb)
{
m_man.remove_request(this);
return;
return true;
}
std::vector<peer_entry> peer_list;
@ -476,7 +461,7 @@ namespace libtorrent
}
std::list<address> ip_list;
for (std::list<udp::endpoint>::const_iterator i = m_endpoints.begin()
for (std::list<tcp::endpoint>::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;