first steps towards removing session_impl dependency from tracker connections, to improve their testability

This commit is contained in:
Arvid Norberg 2014-10-21 00:28:51 +00:00
parent ffb66ec156
commit 9b37efe6a8
12 changed files with 98 additions and 100 deletions

View File

@ -263,7 +263,7 @@ namespace libtorrent
void main_thread();
void open_listen_port();
void maybe_open_listen_port();
void init_settings();
torrent_peer_allocator_interface* get_peer_allocator() { return &m_peer_allocator; }

View File

@ -58,7 +58,7 @@ namespace libtorrent
struct http_connection;
class entry;
class http_parser;
namespace aux { struct session_impl; struct session_settings; }
namespace aux { struct session_settings; }
class TORRENT_EXTRA_EXPORT http_tracker_connection
: public tracker_connection
@ -71,7 +71,6 @@ namespace libtorrent
, tracker_manager& man
, tracker_request const& req
, boost::weak_ptr<request_callback> c
, aux::session_impl& ses
, std::string const& password = ""
#if TORRENT_USE_I2P
, i2p_connection* i2p_conn = 0
@ -98,9 +97,7 @@ namespace libtorrent
tracker_manager& m_man;
boost::shared_ptr<http_connection> m_tracker_connection;
aux::session_impl& m_ses;
address m_tracker_ip;
io_service& m_ios;
#if TORRENT_USE_I2P
i2p_connection* m_i2p_conn;
#endif

View File

@ -50,6 +50,8 @@ namespace libtorrent
#define TORRENT_EXPORT_DEPRECATED
#endif
namespace aux { struct session_settings; }
// TODO: 2 this type is only used internally now. move it to an internal
// header and make this type properly deprecated.
@ -64,6 +66,10 @@ namespace libtorrent
, proxy_peer_connections(true)
{}
// construct the proxy_settings object from the settings
// this constructor is implemented in session_impl.cpp
proxy_settings(aux::session_settings const& sett);
// the name or IP of the proxy server. ``port`` is the port number the
// proxy listens to. If required, ``username`` and ``password`` can be
// set to authenticate with the proxy.

View File

@ -63,6 +63,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/size_type.hpp"
#include "libtorrent/union_endpoint.hpp"
#include "libtorrent/udp_socket.hpp" // for udp_socket_observer
#include "libtorrent/session_settings.hpp"
#ifdef TORRENT_USE_OPENSSL
#include <boost/asio/ssl/context.hpp>
#endif
@ -75,7 +76,9 @@ namespace libtorrent
struct tracker_connection;
class udp_tracker_connection;
class http_tracker_connection;
namespace aux { struct session_impl; }
class udp_socket;
struct resolver_interface;
namespace aux { struct session_impl; struct session_settings; }
// returns -1 if gzip header is invalid or the header size in bytes
TORRENT_EXTRA_EXPORT int gzip_header(const char* buf, int size);
@ -319,9 +322,7 @@ namespace libtorrent
{
public:
tracker_manager(aux::session_impl& ses)
: m_ses(ses)
, m_abort(false) {}
tracker_manager(aux::session_impl& ses);
~tracker_manager();
void queue_request(
@ -351,6 +352,11 @@ namespace libtorrent
boost::shared_ptr<udp_tracker_connection> c
, boost::uint64_t tid);
aux::session_settings const& settings() const { return m_settings; }
class udp_socket& udp_socket() { return m_udp_socket; }
struct ip_filter const& ip_filter() const { return m_ip_filter; }
resolver_interface& host_resolver() { return m_host_resolver; }
private:
typedef mutex mutex_t;
@ -365,6 +371,11 @@ namespace libtorrent
http_conns_t m_http_conns;
aux::session_impl& m_ses;
struct ip_filter const& m_ip_filter;
class udp_socket& m_udp_socket;
resolver_interface& m_host_resolver;
aux::session_settings const& m_settings;
bool m_abort;
};
}

View File

@ -59,8 +59,6 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
namespace aux { struct session_impl; }
class TORRENT_EXTRA_EXPORT udp_tracker_connection: public tracker_connection
{
friend class tracker_manager;
@ -70,9 +68,7 @@ namespace libtorrent
io_service& ios
, tracker_manager& man
, tracker_request const& req
, boost::weak_ptr<request_callback> c
, aux::session_impl& ses
, proxy_settings const& ps);
, boost::weak_ptr<request_callback> c);
void start();
void close();
@ -126,8 +122,6 @@ namespace libtorrent
// TODO: 3 this should be a vector
std::list<tcp::endpoint> m_endpoints;
aux::session_impl& m_ses;
struct connection_cache_entry
{
boost::int64_t connection_id;
@ -137,8 +131,6 @@ namespace libtorrent
static std::map<address, connection_cache_entry> m_connection_cache;
static mutex m_cache_mutex;
proxy_settings m_proxy;
udp::endpoint m_target;
boost::uint32_t m_transaction_id;

View File

@ -57,8 +57,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/torrent.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/broadcast_socket.hpp" // for is_local
#include "libtorrent/aux_/session_settings.hpp"
#include "libtorrent/resolver_interface.hpp"
#include "libtorrent/ip_filter.hpp"
using namespace libtorrent;
@ -74,7 +76,6 @@ namespace libtorrent
, tracker_manager& man
, tracker_request const& req
, boost::weak_ptr<request_callback> c
, aux::session_impl& ses
, std::string const& auth
#if TORRENT_USE_I2P
, i2p_connection* i2p_conn
@ -82,8 +83,6 @@ namespace libtorrent
)
: tracker_connection(man, req, ios, c)
, m_man(man)
, m_ses(ses)
, m_ios(ios)
#if TORRENT_USE_I2P
, m_i2p_conn(i2p_conn)
#endif
@ -114,7 +113,7 @@ namespace libtorrent
static const bool i2p = false;
#endif
aux::session_settings const& settings = m_ses.settings();
aux::session_settings const& settings = m_man.settings();
// if request-string already contains
// some parameters, append an ampersand instead
@ -159,11 +158,11 @@ namespace libtorrent
, tracker_req().num_want);
url += str;
#ifndef TORRENT_DISABLE_ENCRYPTION
if (m_ses.settings().get_int(settings_pack::in_enc_policy) != settings_pack::pe_disabled
&& m_ses.settings().get_bool(settings_pack::announce_crypto_support))
if (settings.get_int(settings_pack::in_enc_policy) != settings_pack::pe_disabled
&& settings.get_bool(settings_pack::announce_crypto_support))
url += "&supportcrypto=1";
#endif
if (stats && m_ses.settings().get_bool(settings_pack::report_redundant_bytes))
if (stats && settings.get_bool(settings_pack::report_redundant_bytes))
{
url += "&redundant=";
url += to_string(tracker_req().redundant).elems;
@ -185,14 +184,15 @@ namespace libtorrent
}
else
#endif
if (!m_ses.settings().get_bool(settings_pack::anonymous_mode))
if (!settings.get_bool(settings_pack::anonymous_mode))
{
std::string announce_ip = settings.get_str(settings_pack::announce_ip);
if (!announce_ip.empty())
{
url += "&ip=" + escape_string(announce_ip.c_str(), announce_ip.size());
}
else if (m_ses.settings().get_bool(settings_pack::announce_double_nat)
// TODO: support this somehow
/* else if (settings.get_bool(settings_pack::announce_double_nat)
&& is_local(m_ses.listen_address()))
{
// only use the global external listen address here
@ -201,10 +201,11 @@ namespace libtorrent
// source IP to determine our origin
url += "&ip=" + print_address(m_ses.listen_address());
}
*/
}
}
m_tracker_connection.reset(new http_connection(m_ios, m_ses.m_host_resolver
m_tracker_connection.reset(new http_connection(get_io_service(), m_man.host_resolver()
, boost::bind(&http_tracker_connection::on_response, shared_from_this(), _1, _2, _3, _4)
, true, settings.get_int(settings_pack::max_http_recv_buffer_size)
, boost::bind(&http_tracker_connection::on_connect, shared_from_this(), _1)
@ -222,7 +223,7 @@ namespace libtorrent
// to avoid being blocked for slow or failing responses. Chances
// are that we're shutting down, and this should be a best-effort
// attempt. It's not worth stalling shutdown.
proxy_settings ps = m_ses.proxy();
proxy_settings ps(settings);
m_tracker_connection->get(url, seconds(timeout)
, tracker_req().event == tracker_request::stopped ? 2 : 1
, &ps, 5, settings.get_bool(settings_pack::anonymous_mode)
@ -267,7 +268,7 @@ namespace libtorrent
for (std::vector<tcp::endpoint>::iterator i = endpoints.begin();
i != endpoints.end();)
{
if (m_ses.m_ip_filter.access(i->address()) == ip_filter::blocked)
if (m_man.ip_filter().access(i->address()) == ip_filter::blocked)
i = endpoints.erase(i);
else
++i;

View File

@ -985,17 +985,7 @@ namespace libtorrent
proxy_settings session::proxy() const
{
aux::session_settings sett = get_settings();
proxy_settings ret;
ret.hostname = sett.get_str(settings_pack::proxy_hostname);
ret.username = sett.get_str(settings_pack::proxy_username);
ret.password = sett.get_str(settings_pack::proxy_password);
ret.type = sett.get_int(settings_pack::proxy_type);
ret.port = sett.get_int(settings_pack::proxy_port);
ret.proxy_hostnames = sett.get_bool(settings_pack::proxy_hostnames);
ret.proxy_peer_connections = sett.get_bool(
settings_pack::proxy_peer_connections);
return ret;
return proxy_settings(sett);
}
void session::set_peer_proxy(proxy_settings const& s)

View File

@ -227,14 +227,17 @@ void network_thread_pool::process_job(socket_job const& j, bool post)
}
}
namespace detail
// TODO: 2 find a better place for this function
proxy_settings::proxy_settings(aux::session_settings const& sett)
{
std::string generate_auth_string(std::string const& user
, std::string const& passwd)
{
if (user.empty()) return std::string();
return user + ":" + passwd;
}
hostname = sett.get_str(settings_pack::proxy_hostname);
username = sett.get_str(settings_pack::proxy_username);
password = sett.get_str(settings_pack::proxy_password);
type = sett.get_int(settings_pack::proxy_type);
port = sett.get_int(settings_pack::proxy_port);
proxy_hostnames = sett.get_bool(settings_pack::proxy_hostnames);
proxy_peer_connections = sett.get_bool(
settings_pack::proxy_peer_connections);
}
namespace aux {
@ -674,6 +677,19 @@ namespace aux {
session_log(" generated peer ID: %s", m_peer_id.to_string().c_str());
#endif
settings_pack* copy = new settings_pack(pack);
m_io_service.post(boost::bind(&session_impl::apply_settings_pack, this, copy));
// call update_* after settings set initialized
m_io_service.post(boost::bind(&session_impl::init_settings, this));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
session_log(" spawning network thread");
#endif
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
}
void session_impl::init_settings()
{
#ifndef TORRENT_NO_DEPRECATE
update_local_download_rate();
update_local_upload_rate();
@ -689,18 +705,6 @@ namespace aux {
update_lsd();
update_dht();
settings_pack* copy = new settings_pack(pack);
m_io_service.post(boost::bind(&session_impl::apply_settings_pack, this, copy));
m_io_service.post(boost::bind(&session_impl::maybe_open_listen_port, this));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
session_log(" spawning network thread");
#endif
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
}
void session_impl::maybe_open_listen_port()
{
if (m_listen_sockets.empty())
{
update_listen_interfaces();
@ -1179,17 +1183,7 @@ namespace aux {
proxy_settings session_impl::proxy() const
{
proxy_settings ret;
ret.hostname = m_settings.get_str(settings_pack::proxy_hostname);
ret.username = m_settings.get_str(settings_pack::proxy_username);
ret.password = m_settings.get_str(settings_pack::proxy_password);
ret.type = m_settings.get_int(settings_pack::proxy_type);
ret.port = m_settings.get_int(settings_pack::proxy_port);
ret.proxy_hostnames = m_settings.get_bool(settings_pack::proxy_hostnames);
ret.proxy_peer_connections = m_settings.get_bool(
settings_pack::proxy_peer_connections);
return ret;
return proxy_settings(m_settings);
}
void session_impl::load_state(lazy_entry const* e)

View File

@ -177,7 +177,7 @@ namespace libtorrent
close();
}
// TODO: 3 replace this with performance counters. remove depedency on session
// TODO: 3 replace this with performance counters. remove depedency on session_impl
void tracker_connection::sent_bytes(int bytes)
{
m_man.sent_bytes(bytes);
@ -194,6 +194,15 @@ namespace libtorrent
m_man.remove_request(this);
}
tracker_manager::tracker_manager(aux::session_impl& ses)
: m_ses(ses)
, m_ip_filter(ses.m_ip_filter)
, m_udp_socket(ses.m_udp_socket)
, m_host_resolver(ses.m_host_resolver)
, m_settings(ses.settings())
, m_abort(false)
{}
tracker_manager::~tracker_manager()
{
TORRENT_ASSERT(m_abort);
@ -271,8 +280,7 @@ namespace libtorrent
{
boost::shared_ptr<http_tracker_connection> con
= boost::make_shared<http_tracker_connection>(
ios, *this, req, c
, m_ses, auth
ios, *this, req, c, auth
#if TORRENT_USE_I2P
, &m_ses.m_i2p_conn
#endif
@ -285,7 +293,7 @@ namespace libtorrent
{
boost::shared_ptr<udp_tracker_connection> con
= boost::make_shared<udp_tracker_connection>(
ios, *this, req , c, m_ses, m_ses.proxy());
ios, *this, req , c);
m_udp_conns[con->transaction_id()] = con;
con->start();
return;

View File

@ -48,10 +48,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/parse_url.hpp"
#include "libtorrent/udp_tracker_connection.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/broadcast_socket.hpp" // for is_any
#include "libtorrent/random.hpp"
#include "libtorrent/aux_/session_settings.hpp"
#include "libtorrent/resolver_interface.hpp"
#include "libtorrent/ip_filter.hpp"
namespace libtorrent
{
@ -61,17 +63,12 @@ namespace libtorrent
mutex udp_tracker_connection::m_cache_mutex;
// TODO: 2 it would be nice to not have a dependency on session_impl here
udp_tracker_connection::udp_tracker_connection(
io_service& ios
, tracker_manager& man
, tracker_request const& req
, boost::weak_ptr<request_callback> c
, aux::session_impl& ses
, proxy_settings const& proxy)
, boost::weak_ptr<request_callback> c)
: tracker_connection(man, req, ios, c)
, m_ses(ses)
, m_proxy(proxy)
, m_transaction_id(0)
, m_attempts(0)
, m_state(action_error)
@ -98,11 +95,11 @@ namespace libtorrent
return;
}
aux::session_settings const& settings = m_ses.settings();
aux::session_settings const& settings = m_man.settings();
if (m_proxy.proxy_hostnames
&& (m_proxy.type == settings_pack::socks5
|| m_proxy.type == settings_pack::socks5_pw))
if (settings.get_bool(settings_pack::proxy_hostnames)
&& (settings.get_int(settings_pack::proxy_type) == settings_pack::socks5
|| settings.get_int(settings_pack::proxy_type) == settings_pack::socks5_pw))
{
m_hostname = hostname;
m_target.port(port);
@ -116,7 +113,7 @@ namespace libtorrent
// when stopping, pass in the prefer cache flag, because we
// don't want to get stuck on DNS lookups when shutting down
// if we can avoid it
m_ses.m_host_resolver.async_resolve(hostname
m_man.host_resolver().async_resolve(hostname
, tracker_req().event == tracker_request::stopped
? resolver_interface::prefer_cache
: 0
@ -165,7 +162,7 @@ namespace libtorrent
if (cb) cb->debug_log("*** UDP_TRACKER trying next IP [ host: \"%s\" ip: \"%s\" ]"
, m_hostname.c_str(), print_endpoint(m_target).c_str());
#endif
m_ses.m_io_service.post(boost::bind(
get_io_service().post(boost::bind(
&udp_tracker_connection::start_announce, shared_from_this()));
}
@ -209,7 +206,7 @@ namespace libtorrent
for (std::list<tcp::endpoint>::iterator k = m_endpoints.begin();
k != m_endpoints.end();)
{
if (m_ses.m_ip_filter.access(k->address()) == ip_filter::blocked)
if (m_man.ip_filter().access(k->address()) == ip_filter::blocked)
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
if (cb) cb->debug_log("*** UDP_TRACKER [ IP blocked by filter: %s ]"
@ -431,7 +428,7 @@ namespace libtorrent
mutex::scoped_lock l(m_cache_mutex);
connection_cache_entry& cce = m_connection_cache[m_target.address()];
cce.connection_id = connection_id;
cce.expires = time_now() + seconds(m_ses.m_settings.get_int(settings_pack::udp_tracker_token_expiry));
cce.expires = time_now() + seconds(m_man.settings().get_int(settings_pack::udp_tracker_token_expiry));
if (tracker_req().kind == tracker_request::announce_request)
send_udp_announce();
@ -467,11 +464,11 @@ namespace libtorrent
error_code ec;
if (!m_hostname.empty())
{
m_ses.m_udp_socket.send_hostname(m_hostname.c_str(), m_target.port(), buf, 16, ec);
m_man.udp_socket().send_hostname(m_hostname.c_str(), m_target.port(), buf, 16, ec);
}
else
{
m_ses.m_udp_socket.send(m_target, buf, 16, ec);
m_man.udp_socket().send(m_target, buf, 16, ec);
}
m_state = action_connect;
sent_bytes(16 + 28); // assuming UDP/IP header
@ -509,11 +506,11 @@ namespace libtorrent
error_code ec;
if (!m_hostname.empty())
{
m_ses.m_udp_socket.send_hostname(m_hostname.c_str(), m_target.port(), buf, sizeof(buf), ec);
m_man.udp_socket().send_hostname(m_hostname.c_str(), m_target.port(), buf, sizeof(buf), ec);
}
else
{
m_ses.m_udp_socket.send(m_target, buf, sizeof(buf), ec);
m_man.udp_socket().send(m_target, buf, sizeof(buf), ec);
}
m_state = action_scrape;
sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header
@ -642,7 +639,7 @@ namespace libtorrent
tracker_request const& req = tracker_req();
const bool stats = req.send_stats;
aux::session_settings const& settings = m_ses.settings();
aux::session_settings const& settings = m_man.settings();
std::map<address, connection_cache_entry>::iterator i
= m_connection_cache.find(m_target.address());
@ -706,11 +703,11 @@ namespace libtorrent
if (!m_hostname.empty())
{
m_ses.m_udp_socket.send_hostname(m_hostname.c_str(), m_target.port(), buf, out - buf, ec);
m_man.udp_socket().send_hostname(m_hostname.c_str(), m_target.port(), buf, out - buf, ec);
}
else
{
m_ses.m_udp_socket.send(m_target, buf, out - buf, ec);
m_man.udp_socket().send(m_target, buf, out - buf, ec);
}
m_state = action_announce;
sent_bytes(out - buf + 28); // assuming UDP/IP header

View File

@ -71,6 +71,10 @@ void test_pex()
pack.set_int(settings_pack::max_retry_port_bind, 800);
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:48200");
pack.set_bool(settings_pack::enable_dht, false);
pack.set_bool(settings_pack::enable_upnp, false);
pack.set_bool(settings_pack::enable_natpmp, false);
pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_forced);
pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_forced);

View File

@ -180,8 +180,6 @@ struct udp_tracker
error_code ec;
udp::endpoint from;
size_t bytes_transferred;
bool done = false;
m_socket.async_receive_from(
asio::buffer(buffer, sizeof(buffer)), from, 0
, boost::bind(&udp_tracker::on_udp_receive, this, _1, _2, &from, &buffer[0], sizeof(buffer)));