forked from premiere/premiere-libtorrent
moved UDP trackers over to use a single socket
This commit is contained in:
parent
c796157f81
commit
cdf05a9c9c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue