Merge pull request #112 from arvidn/proxy_tracker_connections

move proxy_settings into aux and add support to controlling proxy individually for trackers
This commit is contained in:
Arvid Norberg 2015-08-30 07:57:10 -04:00
commit 686896bd38
27 changed files with 392 additions and 181 deletions

View File

@ -69,10 +69,11 @@ set(sources
session_handle
session_impl
session_settings
proxy_settings
session_stats
settings_pack
socket_io
socket_type
socket_type
socks5_stream
stat
stat_cache

View File

@ -1,3 +1,4 @@
* add option to not proxy tracker connections through proxy
* removed sparse-regions feature
* support using 0 disk threads (to perform disk I/O in network thread)
* removed deprecated handle_alert template

View File

@ -694,6 +694,7 @@ SOURCES =
performance_counters
resolver
session_settings
proxy_settings
file_progress
# -- extensions --

View File

@ -166,6 +166,7 @@ nobase_include_HEADERS = \
aux_/session_call.hpp \
aux_/session_impl.hpp \
aux_/session_settings.hpp \
aux_/proxy_settings.hpp \
aux_/session_interface.hpp \
aux_/time.hpp \
aux_/file_progress.hpp \

View File

@ -0,0 +1,145 @@
/*
Copyright (c) 2003-2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_PROXY_SETTINGS_HPP_INCLUDED
#define TORRENT_PROXY_SETTINGS_HPP_INCLUDED
#include "libtorrent/version.hpp"
#include "libtorrent/config.hpp"
#include <string>
#include <boost/cstdint.hpp>
namespace libtorrent {
struct settings_pack;
namespace aux {
struct session_settings;
// The ``proxy_settings`` structs contains the information needed to
// direct certain traffic to a proxy.
struct TORRENT_DEPRECATED_EXPORT proxy_settings
{
// defaults constructs proxy settings, initializing it to the default
// settings.
proxy_settings();
// construct the proxy_settings object from the settings
// this constructor is implemented in session_impl.cpp
proxy_settings(settings_pack const& sett);
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.
std::string hostname;
// when using a proy type that requires authentication, the username
// and password fields must be set to the credentials for the proxy.
std::string username;
std::string password;
#ifndef TORRENT_NO_DEPRECATE
// the type of proxy to use. Assign one of these to the
// proxy_settings::type field.
enum proxy_type
{
// This is the default, no proxy server is used, all other fields are
// ignored.
none,
// The server is assumed to be a `SOCKS4 server`_ that requires a
// username.
//
// .. _`SOCKS4 server`: http://www.ufasoft.com/doc/socks4_protocol.htm
socks4,
// The server is assumed to be a SOCKS5 server (`RFC 1928`_) that does
// not require any authentication. The username and password are
// ignored.
//
// .. _`RFC 1928`: http://www.faqs.org/rfcs/rfc1928.html
socks5,
// The server is assumed to be a SOCKS5 server that supports plain
// text username and password authentication (`RFC 1929`_). The
// username and password specified may be sent to the proxy if it
// requires.
//
// .. _`RFC 1929`: http://www.faqs.org/rfcs/rfc1929.html
socks5_pw,
// The server is assumed to be an HTTP proxy. If the transport used
// for the connection is non-HTTP, the server is assumed to support
// the CONNECT_ method. i.e. for web seeds and HTTP trackers, a plain
// proxy will suffice. The proxy is assumed to not require
// authorization. The username and password will not be used.
//
// .. _CONNECT: http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01
http,
// The server is assumed to be an HTTP proxy that requires user
// authorization. The username and password will be sent to the proxy.
http_pw,
// route through an i2p SAM proxy
i2p_proxy
};
#endif
// tells libtorrent what kind of proxy server it is. See proxy_type
// enum for options
boost::uint8_t type;
// the port the proxy server is running on
boost::uint16_t port;
// defaults to true. It means that hostnames should be attempted to be
// resolved through the proxy instead of using the local DNS service.
// This is only supported by SOCKS5 and HTTP.
bool proxy_hostnames;
// determines whether or not to excempt peer and web seed connections
// from using the proxy. This defaults to true, i.e. peer connections are
// proxied by default.
bool proxy_peer_connections;
// if true, tracker connections are subject to the proxy settings
bool proxy_tracker_connections;
};
}
}
#endif

View File

@ -64,7 +64,6 @@ namespace libtorrent
{
class peer_connection;
class torrent;
struct proxy_settings;
struct socket_job;
#ifndef TORRENT_NO_DEPRECATE
struct pe_settings;
@ -101,6 +100,7 @@ namespace libtorrent
namespace libtorrent { namespace aux
{
struct proxy_settings;
struct session_settings;
#if !defined TORRENT_DISABLE_LOGGING || TORRENT_USE_ASSERTS

View File

@ -87,7 +87,7 @@ POSSIBILITY OF SUCH DAMAGE.
// only export this type if deprecated functions are enabled
#ifdef TORRENT_NO_DEPRECATE
#define TORRENT_DEPRECATED_EXPORT
#define TORRENT_DEPRECATED_EXPORT TORRENT_EXTRA_EXPORT
#else
#define TORRENT_DEPRECATED_EXPORT TORRENT_EXPORT
#endif

View File

@ -104,7 +104,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
std::string m_sendbuffer;
void get(std::string const& url, time_duration timeout = seconds(30)
, int prio = 0, proxy_settings const* ps = 0, int handle_redirects = 5
, int prio = 0, aux::proxy_settings const* ps = 0, int handle_redirects = 5
, std::string const& user_agent = std::string()
, address const& bind_addr = address_v4::any()
, int resolve_flags = 0, std::string const& auth_ = std::string()
@ -114,7 +114,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
);
void start(std::string const& hostname, int port
, time_duration timeout, int prio = 0, proxy_settings const* ps = 0
, time_duration timeout, int prio = 0, aux::proxy_settings const* ps = 0
, bool ssl = false, int handle_redirect = 5
, address const& bind_addr = address_v4::any()
, int resolve_flags = 0
@ -186,7 +186,7 @@ private:
// specifies whether or not the connection is
// configured to use a proxy
proxy_settings m_proxy;
aux::proxy_settings m_proxy;
// the address to bind to. address_v4::any()
// means do not bind

View File

@ -169,7 +169,7 @@ public:
i2p_connection(io_service& ios);
~i2p_connection();
proxy_settings proxy() const;
aux::proxy_settings proxy() const;
bool is_open() const
{

View File

@ -34,20 +34,23 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_INSTANTIATE_CONNECTION
#include "libtorrent/socket_type.hpp"
#include <boost/shared_ptr.hpp>
namespace libtorrent
{
struct proxy_settings;
namespace aux {
struct proxy_settings;
}
struct utp_socket_manager;
struct socket_type;
// instantiate a socket_type (s) according to the specified criteria
TORRENT_EXTRA_EXPORT bool instantiate_connection(io_service& ios
, proxy_settings const& ps, socket_type& s
, void* ssl_context = 0
, utp_socket_manager* sm = 0
, bool peer_connection = false);
, aux::proxy_settings const& ps, socket_type& s
, void* ssl_context
, utp_socket_manager* sm
, bool peer_connection
, bool tracker_connection);
}
#endif

View File

@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/version.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/aux_/proxy_settings.hpp"
#include <boost/cstdint.hpp>
#include <string>
@ -46,109 +47,8 @@ namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
#define TORRENT_EXPORT_DEPRECATED TORRENT_EXPORT
#else
#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.
// The ``proxy_settings`` structs contains the information needed to
// direct certain traffic to a proxy.
struct TORRENT_EXPORT_DEPRECATED proxy_settings
{
// defaults constructs proxy settings, initializing it to the default
// settings.
proxy_settings() : type(0)
, port(0), proxy_hostnames(true)
, proxy_peer_connections(true)
{}
// construct the proxy_settings object from the settings
// this constructor is implemented in session_impl.cpp
proxy_settings(settings_pack const& sett);
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.
std::string hostname;
// when using a proy type that requires authentication, the username
// and password fields must be set to the credentials for the proxy.
std::string username;
std::string password;
#ifndef TORRENT_NO_DEPRECATE
// the type of proxy to use. Assign one of these to the
// proxy_settings::type field.
enum proxy_type
{
// This is the default, no proxy server is used, all other fields are
// ignored.
none,
// The server is assumed to be a `SOCKS4 server`_ that requires a
// username.
//
// .. _`SOCKS4 server`: http://www.ufasoft.com/doc/socks4_protocol.htm
socks4,
// The server is assumed to be a SOCKS5 server (`RFC 1928`_) that does
// not require any authentication. The username and password are
// ignored.
//
// .. _`RFC 1928`: http://www.faqs.org/rfcs/rfc1928.html
socks5,
// The server is assumed to be a SOCKS5 server that supports plain
// text username and password authentication (`RFC 1929`_). The
// username and password specified may be sent to the proxy if it
// requires.
//
// .. _`RFC 1929`: http://www.faqs.org/rfcs/rfc1929.html
socks5_pw,
// The server is assumed to be an HTTP proxy. If the transport used
// for the connection is non-HTTP, the server is assumed to support
// the CONNECT_ method. i.e. for web seeds and HTTP trackers, a plain
// proxy will suffice. The proxy is assumed to not require
// authorization. The username and password will not be used.
//
// .. _CONNECT: http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01
http,
// The server is assumed to be an HTTP proxy that requires user
// authorization. The username and password will be sent to the proxy.
http_pw,
// route through an i2p SAM proxy
i2p_proxy
};
#endif
// tells libtorrent what kind of proxy server it is. See proxy_type
// enum for options
boost::uint8_t type;
// the port the proxy server is running on
boost::uint16_t port;
// defaults to true. It means that hostnames should be attempted to be
// resolved through the proxy instead of using the local DNS service.
// This is only supported by SOCKS5 and HTTP.
bool proxy_hostnames;
// determines whether or not to excempt peer and web seed connections
// from using the proxy. This defaults to true, i.e. peer connections are
// proxied by default.
bool proxy_peer_connections;
};
#ifndef TORRENT_NO_DEPRECATE
typedef aux::proxy_settings proxy_settings;
// This holds most of the session-wide settings in libtorrent. Pass this
// to session::set_settings() to change the settings, initialize it from

View File

@ -644,6 +644,10 @@ namespace libtorrent
// unlikely to matter anyway
auto_sequential,
// if true, trackerconnections are made over the configured proxy, if
// any.
proxy_tracker_connections,
max_bool_setting_internal
};

View File

@ -71,7 +71,12 @@ namespace libtorrent
udp_socket(io_service& ios);
~udp_socket();
enum flags_t { dont_drop = 1, peer_connection = 2, dont_queue = 4 };
enum flags_t {
dont_drop = 1
, peer_connection = 2
, tracker_connection = 4
, dont_queue = 8
};
bool is_open() const
{
@ -96,8 +101,8 @@ namespace libtorrent
void close();
int local_port() const { return m_bind_port; }
void set_proxy_settings(proxy_settings const& ps);
proxy_settings const& get_proxy_settings() { return m_proxy_settings; }
void set_proxy_settings(aux::proxy_settings const& ps);
aux::proxy_settings const& get_proxy_settings() { return m_proxy_settings; }
void set_force_proxy(bool f) { m_force_proxy = f; }
bool is_closed() const { return m_abort; }
@ -236,7 +241,7 @@ namespace libtorrent
#endif
tcp::socket m_socks5_sock;
proxy_settings m_proxy_settings;
aux::proxy_settings m_proxy_settings;
tcp::resolver m_resolver;
char m_tmp_buf[270];
bool m_queue_packets;

View File

@ -108,6 +108,7 @@ libtorrent_rasterbar_la_SOURCES = \
session_handle.cpp \
session_impl.cpp \
session_settings.cpp \
proxy_settings.cpp \
settings_pack.cpp \
sha1.cpp \
smart_ban.cpp \

View File

@ -108,7 +108,7 @@ http_connection::~http_connection()
}
void http_connection::get(std::string const& url, time_duration timeout, int prio
, proxy_settings const* ps, int handle_redirects, std::string const& user_agent
, aux::proxy_settings const* ps, int handle_redirects, std::string const& user_agent
, address const& bind_addr, int resolve_flags, std::string const& auth_
#if TORRENT_USE_I2P
, i2p_connection* i2p_conn
@ -223,7 +223,7 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
}
void http_connection::start(std::string const& hostname, int port
, time_duration timeout, int prio, proxy_settings const* ps, bool ssl
, time_duration timeout, int prio, aux::proxy_settings const* ps, bool ssl
, int handle_redirects
, address const& bind_addr
, int resolve_flags
@ -307,9 +307,9 @@ void http_connection::start(std::string const& hostname, int port
}
#endif
proxy_settings const* proxy = ps;
aux::proxy_settings const* proxy = ps;
#if TORRENT_USE_I2P
proxy_settings i2p_proxy;
aux::proxy_settings i2p_proxy;
if (is_i2p)
{
i2p_proxy = i2p_conn->proxy();
@ -326,7 +326,7 @@ void http_connection::start(std::string const& hostname, int port
{
proxy = 0;
}
proxy_settings null_proxy;
aux::proxy_settings null_proxy;
void* userdata = 0;
#ifdef TORRENT_USE_OPENSSL
@ -347,8 +347,11 @@ void http_connection::start(std::string const& hostname, int port
userdata = m_ssl_ctx;
}
#endif
// assume this is not a tracker connection. Tracker connections that
// shouldn't be subject to the proxy should pass in NULL as the proxy
// pointer.
instantiate_connection(m_timer.get_io_service()
, proxy ? *proxy : null_proxy, m_sock, userdata);
, proxy ? *proxy : null_proxy, m_sock, userdata, NULL, false, false);
if (m_bind_addr != address_v4::any())
{

View File

@ -215,10 +215,11 @@ 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(settings);
aux::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)
, ps.proxy_tracker_connections ? &ps : NULL
, 5, settings.get_bool(settings_pack::anonymous_mode)
? "" : settings.get_str(settings_pack::user_agent)
, bind_interface()
, tracker_req().event == tracker_request::stopped

View File

@ -105,9 +105,9 @@ namespace libtorrent
if (m_sam_socket) m_sam_socket->close(e);
}
proxy_settings i2p_connection::proxy() const
aux::proxy_settings i2p_connection::proxy() const
{
proxy_settings ret;
aux::proxy_settings ret;
ret.hostname = m_hostname;
ret.port = m_port;
ret.type = settings_pack::i2p_proxy;

View File

@ -40,11 +40,14 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
// TODO: 2 peer_connection and tracker_connection should probably be flags
// TODO: 2 move this function into libtorrent::aux namespace
bool instantiate_connection(io_service& ios
, proxy_settings const& ps, socket_type& s
, aux::proxy_settings const& ps, socket_type& s
, void* ssl_context
, utp_socket_manager* sm
, bool peer_connection)
, bool peer_connection
, bool tracker_connection)
{
#ifndef TORRENT_USE_OPENSSL
TORRENT_UNUSED(ssl_context);
@ -77,7 +80,8 @@ namespace libtorrent
}
#endif
else if (ps.type == settings_pack::none
|| (peer_connection && !ps.proxy_peer_connections))
|| (peer_connection && !ps.proxy_peer_connections)
|| (tracker_connection && !ps.proxy_tracker_connections))
{
#ifdef TORRENT_USE_OPENSSL
if (ssl_context)

78
src/proxy_settings.cpp Normal file
View File

@ -0,0 +1,78 @@
/*
Copyright (c) 2003-2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/aux_/proxy_settings.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/aux_/session_settings.hpp"
namespace libtorrent {
namespace aux {
proxy_settings::proxy_settings()
: type(0)
, port(0)
, proxy_hostnames(true)
, proxy_peer_connections(true)
, proxy_tracker_connections(true)
{}
proxy_settings::proxy_settings(settings_pack const& sett)
{
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);
proxy_tracker_connections = sett.get_bool(
settings_pack::proxy_tracker_connections);
}
proxy_settings::proxy_settings(aux::session_settings const& sett)
{
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);
proxy_tracker_connections = sett.get_bool(
settings_pack::proxy_tracker_connections);
}
} // namespace aux
} // namespace libtorrent

View File

@ -220,31 +220,6 @@ void network_thread_pool::process_job(socket_job const& j, bool post)
}
}
// TODO: 2 find a better place for this function
proxy_settings::proxy_settings(settings_pack const& sett)
{
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);
}
proxy_settings::proxy_settings(aux::session_settings const& sett)
{
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 {
void session_impl::init_peer_class_filter(bool unlimited_local)
@ -2125,7 +2100,7 @@ retry:
m_socks_listen_socket = boost::shared_ptr<socket_type>(new socket_type(m_io_service));
bool ret = instantiate_connection(m_io_service, proxy()
, *m_socks_listen_socket);
, *m_socks_listen_socket, NULL, NULL, false, false);
TORRENT_ASSERT_VAL(ret, ret);
TORRENT_UNUSED(ret);
@ -2197,7 +2172,7 @@ retry:
m_i2p_listen_socket = boost::shared_ptr<socket_type>(new socket_type(m_io_service));
bool ret = instantiate_connection(m_io_service, m_i2p_conn.proxy()
, *m_i2p_listen_socket);
, *m_i2p_listen_socket, NULL, NULL, true, false);
TORRENT_ASSERT_VAL(ret, ret);
TORRENT_UNUSED(ret);

View File

@ -211,6 +211,7 @@ namespace libtorrent
SET_NOPREV(proxy_hostnames, true, 0),
SET_NOPREV(proxy_peer_connections, true, 0),
SET_NOPREV(auto_sequential, true, &session_impl::update_auto_sequential),
SET_NOPREV(proxy_tracker_connections, true, 0),
};
int_setting_entry_t int_settings[settings_pack::num_int_settings] =

View File

@ -863,7 +863,7 @@ namespace libtorrent
, m_ssl_ctx.get()
#endif
));
proxy_settings ps = m_ses.proxy();
aux::proxy_settings ps = m_ses.proxy();
conn->get(m_url, seconds(30), 0, &ps
, 5, settings().get_str(settings_pack::user_agent));
set_state(torrent_status::downloading_metadata);
@ -6198,7 +6198,7 @@ namespace libtorrent
return;
}
proxy_settings const& ps = m_ses.proxy();
aux::proxy_settings const& ps = m_ses.proxy();
if (ps.type == settings_pack::http
|| ps.type == settings_pack::http_pw)
{
@ -6410,7 +6410,8 @@ namespace libtorrent
if (!userdata) userdata = m_ses.ssl_ctx();
}
#endif
bool ret = instantiate_connection(m_ses.get_io_service(), m_ses.proxy(), *s, userdata, 0, true);
bool ret = instantiate_connection(m_ses.get_io_service(), m_ses.proxy()
, *s, userdata, 0, true, false);
(void)ret;
TORRENT_ASSERT(ret);
@ -7515,7 +7516,12 @@ namespace libtorrent
return false;
}
bool ret = instantiate_connection(m_ses.get_io_service(), m_ses.i2p_proxy(), *s);
// It's not entirely obvious why this peer connection is not marked as
// one. The main feature of a peer connection is that whether or not we
// proxy it is configurable. When we use i2p, we want to always prox
// everything via i2p.
bool ret = instantiate_connection(m_ses.get_io_service()
, m_ses.i2p_proxy(), *s, NULL, NULL, false, false);
(void)ret;
TORRENT_ASSERT(ret);
s->get<i2p_stream>()->set_destination(static_cast<i2p_peer*>(peerinfo)->destination);
@ -7556,7 +7562,7 @@ namespace libtorrent
#endif
bool ret = instantiate_connection(m_ses.get_io_service()
, m_ses.proxy(), *s, userdata, sm, true);
, m_ses.proxy(), *s, userdata, sm, true, false);
(void)ret;
TORRENT_ASSERT(ret);

View File

@ -180,7 +180,13 @@ void udp_socket::send(udp::endpoint const& ep, char const* p, int len
return;
}
if (!(flags & peer_connection) || m_proxy_settings.proxy_peer_connections)
const bool allow_proxy
= ((flags & peer_connection) && m_proxy_settings.proxy_peer_connections)
|| ((flags & tracker_connection) && m_proxy_settings.proxy_tracker_connections)
|| (flags & (tracker_connection | peer_connection)) == 0
;
if (allow_proxy)
{
if (m_tunnel_packets)
{
@ -770,7 +776,7 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
m_bind_port = ep.port();
}
void udp_socket::set_proxy_settings(proxy_settings const& ps)
void udp_socket::set_proxy_settings(aux::proxy_settings const& ps)
{
CHECK_MAGIC;
TORRENT_ASSERT(is_single_thread());
@ -838,7 +844,7 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
// if we can't connect to the proxy, and
// we're not in privacy mode, try to just
// not use a proxy
m_proxy_settings = proxy_settings();
m_proxy_settings = aux::proxy_settings();
m_tunnel_packets = false;
}

View File

@ -504,12 +504,13 @@ namespace libtorrent
if (!m_hostname.empty())
{
m_man.get_udp_socket().send_hostname(m_hostname.c_str()
, m_target.port(), buf, 16, ec);
, m_target.port(), buf, 16, ec
, udp_socket::tracker_connection);
}
else
{
m_man.get_udp_socket().send(m_target, buf, 16, ec);
m_man.get_udp_socket().send(m_target, buf, 16, ec
, udp_socket::tracker_connection);
}
++m_attempts;
@ -566,11 +567,13 @@ namespace libtorrent
error_code ec;
if (!m_hostname.empty())
{
m_man.get_udp_socket().send_hostname(m_hostname.c_str(), m_target.port(), buf, sizeof(buf), ec);
m_man.get_udp_socket().send_hostname(m_hostname.c_str(), m_target.port()
, buf, sizeof(buf), ec, udp_socket::tracker_connection);
}
else
{
m_man.get_udp_socket().send(m_target, buf, sizeof(buf), ec);
m_man.get_udp_socket().send(m_target, buf, sizeof(buf), ec
, udp_socket::tracker_connection);
}
m_state = action_scrape;
sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header
@ -764,11 +767,13 @@ namespace libtorrent
if (!m_hostname.empty())
{
m_man.get_udp_socket().send_hostname(m_hostname.c_str()
, m_target.port(), buf, out - buf, ec);
, m_target.port(), buf, out - buf, ec
, udp_socket::tracker_connection);
}
else
{
m_man.get_udp_socket().send(m_target, buf, out - buf, ec);
m_man.get_udp_socket().send(m_target, buf, out - buf, ec
, udp_socket::tracker_connection);
}
m_state = action_announce;
sent_bytes(out - buf + 28); // assuming UDP/IP header

View File

@ -292,8 +292,8 @@ namespace libtorrent
// create the new socket with this ID
m_new_connection = id;
instantiate_connection(m_sock.get_io_service(), proxy_settings(), *c
, m_ssl_context, this, true);
instantiate_connection(m_sock.get_io_service(), aux::proxy_settings(), *c
, m_ssl_context, this, true, false);
utp_stream* str = NULL;

View File

@ -106,7 +106,7 @@ void reset_globals()
}
void run_test(std::string const& url, int size, int status, int connected
, boost::optional<error_code> ec, proxy_settings const& ps
, boost::optional<error_code> ec, aux::proxy_settings const& ps
, std::string const& auth = std::string())
{
reset_globals();
@ -174,7 +174,7 @@ void run_suite(std::string const& protocol
, flags & flag_chunked_encoding
, flags & flag_keepalive);
proxy_settings ps;
aux::proxy_settings ps;
ps.hostname = "127.0.0.1";
ps.username = "testuser";
ps.password = "testpass";

View File

@ -471,12 +471,13 @@ TORRENT_TEST(try_next)
TEST_EQUAL(tr[1].fails, 1);
TEST_EQUAL(tr[1].verified, false);
TEST_CHECK(tr[1].last_error == boost::asio::error::timed_out
const bool tracker_error = tr[1].last_error == boost::asio::error::timed_out
|| tr[1].last_error == boost::system::error_condition(boost::system::errc::connection_refused)
#ifdef TORRENT_WINDOWS
|| tr[1].last_error == boost::system::error_code(boost::system::system_category(), ERROR_CONNECTION_REFUSED)
|| tr[1].last_error == boost::system::error_code(ERROR_CONNECTION_REFUSED, boost::system::system_category())
#endif
);
;
TEST_EQUAL(tracker_error, true);
TEST_EQUAL(tr[2].fails, 0);
TEST_EQUAL(tr[2].verified, true);
@ -567,3 +568,72 @@ TORRENT_TEST(http_peers)
fprintf(stderr, "done\n");
}
void test_proxy(bool proxy_trackers)
{
int http_port = start_web_server();
settings_pack pack = settings();
pack.set_bool(settings_pack::announce_to_all_trackers, true);
pack.set_bool(settings_pack::announce_to_all_tiers, false);
pack.set_int(settings_pack::tracker_completion_timeout, 2);
pack.set_int(settings_pack::tracker_receive_timeout, 1);
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:39775");
pack.set_bool(settings_pack::force_proxy, true);
pack.set_str(settings_pack::proxy_hostname, "non-existing.com");
pack.set_int(settings_pack::proxy_type, settings_pack::socks5);
pack.set_int(settings_pack::proxy_port, 4444);
pack.set_bool(settings_pack::proxy_tracker_connections, proxy_trackers);
boost::scoped_ptr<lt::session> s(new lt::session(pack));
error_code ec;
remove_all("tmp2_tracker", ec);
create_directory("tmp2_tracker", ec);
std::ofstream file(combine_path("tmp2_tracker", "temporary").c_str());
boost::shared_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
file.close();
char tracker_url[200];
// and this should not be announced to (since the one before it succeeded)
snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce"
, http_port);
t->add_tracker(tracker_url, 0);
add_torrent_params addp;
addp.flags &= ~add_torrent_params::flag_paused;
addp.flags &= ~add_torrent_params::flag_auto_managed;
addp.flags |= add_torrent_params::flag_seed_mode;
addp.ti = t;
addp.save_path = "tmp2_tracker";
torrent_handle h = s->add_torrent(addp);
// wait to hit the tracker
const alert* a = wait_for_alert(*s, tracker_reply_alert::alert_type, "s");
if (proxy_trackers)
{
TEST_CHECK(a == NULL);
}
else
{
TEST_CHECK(a != NULL);
}
fprintf(stderr, "destructing session\n");
s.reset();
fprintf(stderr, "done\n");
fprintf(stderr, "stop_web_server\n");
stop_web_server();
fprintf(stderr, "done\n");
}
TORRENT_TEST(tracker_proxy)
{
fprintf(stderr, "\n\nnot proxying tracker connections (expect to reach the tracker)\n\n");
test_proxy(false);
fprintf(stderr, "\n\nproxying tracker connections through non-existent proxy (do not expect to reach the tracker)\n\n");
test_proxy(true);
}