deprecate (and disable) the force-proxy setting. Instead, always use the proxy when set, never fall back on circumventing it
This commit is contained in:
parent
2ba0e5ae2c
commit
b750b6cc2c
@ -1,3 +1,4 @@
|
||||
* deprecated force_proxy setting (when set, the proxy is always used)
|
||||
* add support for Port Control Protocol (PCP)
|
||||
* deliver notification of alerts being dropped via alerts_dropped_alert
|
||||
* deprecated alert::progress_notification alert category, split into
|
||||
|
@ -752,7 +752,6 @@ namespace aux {
|
||||
void update_socket_buffer_size();
|
||||
void update_dht_announce_interval();
|
||||
void update_anonymous_mode();
|
||||
void update_force_proxy();
|
||||
void update_download_rate();
|
||||
void update_upload_rate();
|
||||
void update_connections_limit();
|
||||
|
@ -621,6 +621,7 @@ namespace libtorrent {
|
||||
// same write cache line as is configured in the disk cache.
|
||||
allow_partial_disk_writes,
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
// If true, disables any communication that's not going over a proxy.
|
||||
// Enabling this requires a proxy to be configured as well, see
|
||||
// proxy_type and proxy_hostname settings. The listen sockets are
|
||||
@ -630,6 +631,9 @@ namespace libtorrent {
|
||||
// country lookups, since those are done via DNS lookups that aren't
|
||||
// supported by proxies.
|
||||
force_proxy,
|
||||
#else
|
||||
deprecated_force_proxy,
|
||||
#endif
|
||||
|
||||
// if false, prevents libtorrent to advertise share-mode support
|
||||
support_share_mode,
|
||||
|
@ -97,7 +97,6 @@ namespace libtorrent {
|
||||
|
||||
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; }
|
||||
udp::endpoint local_endpoint(error_code& ec) const
|
||||
@ -152,8 +151,6 @@ namespace libtorrent {
|
||||
|
||||
std::shared_ptr<socks5> m_socks5_connection;
|
||||
|
||||
// TODO: 3 add a unit test for force-proxy
|
||||
bool m_force_proxy:1;
|
||||
bool m_abort:1;
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
|
@ -117,60 +117,6 @@ TORRENT_TEST(ip_notifier_setting)
|
||||
}
|
||||
#endif
|
||||
|
||||
TORRENT_TEST(force_proxy)
|
||||
{
|
||||
// setup the simulation
|
||||
sim::default_config network_cfg;
|
||||
sim::simulation sim{network_cfg};
|
||||
std::unique_ptr<sim::asio::io_service> ios{new sim::asio::io_service(sim
|
||||
, address_v4::from_string("50.0.0.1"))};
|
||||
lt::session_proxy zombie;
|
||||
|
||||
lt::settings_pack pack = settings();
|
||||
pack.set_bool(settings_pack::force_proxy, true);
|
||||
// create session
|
||||
std::shared_ptr<lt::session> ses = std::make_shared<lt::session>(pack, *ios);
|
||||
|
||||
// disable force proxy in 3 seconds (this should make us open up listen
|
||||
// sockets)
|
||||
sim::timer t1(sim, lt::seconds(3), [&](boost::system::error_code const& ec)
|
||||
{
|
||||
lt::settings_pack p;
|
||||
p.set_bool(settings_pack::force_proxy, false);
|
||||
ses->apply_settings(p);
|
||||
});
|
||||
|
||||
int num_listen_tcp = 0;
|
||||
int num_listen_udp = 0;
|
||||
print_alerts(*ses, [&](lt::session& ses, lt::alert const* a) {
|
||||
if (auto la = alert_cast<listen_succeeded_alert>(a))
|
||||
{
|
||||
if (la->socket_type == socket_type_t::tcp)
|
||||
++num_listen_tcp;
|
||||
else if (la->socket_type == socket_type_t::udp)
|
||||
++num_listen_udp;
|
||||
}
|
||||
});
|
||||
|
||||
// run for 10 seconds.
|
||||
sim::timer t2(sim, lt::seconds(10), [&](boost::system::error_code const& ec)
|
||||
{
|
||||
fprintf(stderr, "shutting down\n");
|
||||
// shut down
|
||||
zombie = ses->abort();
|
||||
ses.reset();
|
||||
});
|
||||
sim.run();
|
||||
|
||||
// on session construction, we won't listen to TCP since we're in force-proxy
|
||||
// mode. We will open up the UDP sockets though, since they are used for
|
||||
// outgoing connections too.
|
||||
// when we disable force-proxy, we'll re-open the sockets and listen on TCP
|
||||
// connections this time, so we'll get a tcp_listen and a udp_listen.
|
||||
TEST_EQUAL(num_listen_tcp, 1);
|
||||
TEST_EQUAL(num_listen_udp, 2);
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
struct test_plugin : lt::torrent_plugin
|
||||
{
|
||||
|
@ -153,10 +153,8 @@ TORRENT_TEST(socks5_tcp_announce)
|
||||
}
|
||||
);
|
||||
|
||||
// since force_proxy is enabled, don't send the port
|
||||
TEST_EQUAL(tracker_port, 0);
|
||||
TEST_EQUAL(tracker_port, 6881);
|
||||
TEST_CHECK(alert_port != -1);
|
||||
TEST_CHECK(tracker_port != -1);
|
||||
}
|
||||
|
||||
TORRENT_TEST(udp_tracker)
|
||||
|
@ -114,7 +114,6 @@ void set_proxy(lt::session& ses, int proxy_type, int flags, bool proxy_peer_conn
|
||||
p.set_bool(settings_pack::proxy_hostnames, true);
|
||||
p.set_bool(settings_pack::proxy_peer_connections, proxy_peer_connections);
|
||||
p.set_bool(settings_pack::proxy_tracker_connections, true);
|
||||
p.set_bool(settings_pack::force_proxy, true);
|
||||
|
||||
ses.apply_settings(p);
|
||||
}
|
||||
|
@ -2086,8 +2086,9 @@ namespace {
|
||||
|
||||
// if we're using a proxy, our listen port won't be useful
|
||||
// anyway.
|
||||
if (!m_settings.get_bool(settings_pack::force_proxy) && is_outgoing())
|
||||
handshake["p"] = m_ses.listen_port();
|
||||
auto const port = m_ses.listen_port();
|
||||
if (port != 0 && is_outgoing())
|
||||
handshake["p"] = port;
|
||||
|
||||
// only send the port in case we bade the connection
|
||||
// on incoming connections the other end already knows
|
||||
|
@ -167,8 +167,7 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
|
||||
|
||||
TORRENT_ASSERT(prio >= 0 && prio < 3);
|
||||
|
||||
bool ssl = false;
|
||||
if (protocol == "https") ssl = true;
|
||||
bool const ssl = (protocol == "https");
|
||||
|
||||
std::stringstream request;
|
||||
|
||||
|
@ -1272,10 +1272,7 @@ namespace aux {
|
||||
!= m_settings.get_int(settings_pack::ssl_listen))
|
||||
||
|
||||
#endif
|
||||
(pack.has_val(settings_pack::force_proxy)
|
||||
&& !pack.get_bool(settings_pack::force_proxy)
|
||||
&& m_settings.get_bool(settings_pack::force_proxy))
|
||||
|| (pack.has_val(settings_pack::listen_interfaces)
|
||||
(pack.has_val(settings_pack::listen_interfaces)
|
||||
&& pack.get_str(settings_pack::listen_interfaces)
|
||||
!= m_settings.get_str(settings_pack::listen_interfaces));
|
||||
|
||||
@ -1660,7 +1657,6 @@ namespace aux {
|
||||
, operation_t::alloc_recvbuf, err);
|
||||
}
|
||||
|
||||
ret->udp_sock->sock.set_force_proxy(m_settings.get_bool(settings_pack::force_proxy));
|
||||
// this call is necessary here because, unless the settings actually
|
||||
// change after the session is up and listening, at no other point
|
||||
// set_proxy_settings is called with the correct proxy configuration,
|
||||
@ -1785,7 +1781,7 @@ namespace aux {
|
||||
// of a new socket failing to bind due to a conflict with a stale socket
|
||||
std::vector<listen_endpoint_t> eps;
|
||||
|
||||
duplex const incoming = m_settings.get_bool(settings_pack::force_proxy)
|
||||
duplex const incoming = m_settings.get_int(settings_pack::proxy_type) != settings_pack::none
|
||||
? duplex::only_outgoing
|
||||
: duplex::accept_incoming;
|
||||
|
||||
@ -2071,7 +2067,6 @@ namespace aux {
|
||||
, operation_t::alloc_recvbuf, err);
|
||||
}
|
||||
|
||||
udp_sock->sock.set_force_proxy(m_settings.get_bool(settings_pack::force_proxy));
|
||||
// this call is necessary here because, unless the settings actually
|
||||
// change after the session is up and listening, at no other point
|
||||
// set_proxy_settings is called with the correct proxy configuration,
|
||||
@ -2604,8 +2599,9 @@ namespace aux {
|
||||
}
|
||||
async_accept(listener, ssl);
|
||||
|
||||
// don't accept any connections from our local sockets
|
||||
if (m_settings.get_bool(settings_pack::force_proxy))
|
||||
// don't accept any connections from our local sockets if we're using a
|
||||
// proxy
|
||||
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none)
|
||||
return;
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
@ -5387,12 +5383,17 @@ namespace aux {
|
||||
|
||||
std::uint16_t session_impl::listen_port(listen_socket_t* sock) const
|
||||
{
|
||||
// if not, don't tell the tracker anything if we're in force_proxy
|
||||
// mode. We don't want to leak our listen port since it can
|
||||
// potentially identify us if it is leaked elsewhere
|
||||
if (m_settings.get_bool(settings_pack::force_proxy)) return 0;
|
||||
if (m_listen_sockets.empty()) return 0;
|
||||
if (sock) return std::uint16_t(sock->tcp_external_port);
|
||||
if (sock)
|
||||
{
|
||||
// if we're using a proxy, we won't be able to accept any TCP
|
||||
// connections. We may be able to accept uTP connections though, so
|
||||
// announce the UDP port instead
|
||||
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none)
|
||||
return std::uint16_t(sock->udp_external_port);
|
||||
else
|
||||
return std::uint16_t(sock->tcp_external_port);
|
||||
}
|
||||
return std::uint16_t(m_listen_sockets.front()->tcp_external_port);
|
||||
}
|
||||
|
||||
@ -5406,15 +5407,30 @@ namespace aux {
|
||||
std::uint16_t session_impl::ssl_listen_port(listen_socket_t* sock) const
|
||||
{
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
if (sock) return std::uint16_t(sock->tcp_external_port);
|
||||
|
||||
// if not, don't tell the tracker anything if we're in force_proxy
|
||||
// mode. We don't want to leak our listen port since it can
|
||||
// potentially identify us if it is leaked elsewhere
|
||||
if (m_settings.get_bool(settings_pack::force_proxy)) return 0;
|
||||
if (sock)
|
||||
{
|
||||
// if we're using a proxy, we won't be able to accept any TCP
|
||||
// connections. We may be able to accept uTP connections though, so
|
||||
// announce the UDP port instead
|
||||
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none)
|
||||
return std::uint16_t(sock->udp_external_port);
|
||||
else
|
||||
return std::uint16_t(sock->tcp_external_port);
|
||||
}
|
||||
|
||||
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none)
|
||||
return 0;
|
||||
|
||||
for (auto const& s : m_listen_sockets)
|
||||
{
|
||||
if (s->ssl == transport::ssl) return std::uint16_t(s->tcp_external_port);
|
||||
if (s->ssl == transport::ssl)
|
||||
{
|
||||
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none)
|
||||
return std::uint16_t(s->udp_external_port);
|
||||
else
|
||||
return std::uint16_t(s->tcp_external_port);
|
||||
}
|
||||
}
|
||||
#else
|
||||
TORRENT_UNUSED(sock);
|
||||
@ -6411,56 +6427,6 @@ namespace aux {
|
||||
if (m_upnp) m_upnp->set_user_agent("");
|
||||
}
|
||||
|
||||
void session_impl::update_force_proxy()
|
||||
{
|
||||
if (!m_settings.get_bool(settings_pack::force_proxy))
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
session_log("force-proxy disabled");
|
||||
#endif
|
||||
// we need to close and remove all listen sockets during a transition
|
||||
// from force-proxy to not-force-proxy. reopen_listen_sockets() won't
|
||||
// do anything with half-opened sockets.
|
||||
error_code ec;
|
||||
for (auto& i : m_listen_sockets)
|
||||
{
|
||||
if (i->udp_sock) i->udp_sock->sock.close();
|
||||
if (i->sock) i->sock->close(ec);
|
||||
}
|
||||
m_listen_sockets.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
session_log("force-proxy enabled");
|
||||
#endif
|
||||
|
||||
// when enabling force-proxy, we no longer wand to accept connections via
|
||||
// a regular listen socket, only via a proxy. We also want to enable
|
||||
// force-proxy on all udp sockets
|
||||
for (auto& i : m_listen_sockets)
|
||||
{
|
||||
i->udp_sock->sock.set_force_proxy(m_settings.get_bool(settings_pack::force_proxy));
|
||||
|
||||
// close the TCP listen sockets
|
||||
if (i->sock)
|
||||
{
|
||||
error_code ec;
|
||||
i->sock->close(ec);
|
||||
i->sock.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// enable force_proxy mode. We don't want to accept any incoming
|
||||
// connections, except through a proxy.
|
||||
stop_lsd();
|
||||
stop_upnp();
|
||||
stop_natpmp();
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
stop_dht();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
void session_impl::update_local_download_rate()
|
||||
{
|
||||
|
@ -192,7 +192,7 @@ constexpr int CLOSE_FILE_INTERVAL = 0;
|
||||
DEPRECATED_SET(contiguous_recv_buffer, true, nullptr),
|
||||
SET(ban_web_seeds, true, nullptr),
|
||||
SET(allow_partial_disk_writes, true, nullptr),
|
||||
SET(force_proxy, false, &session_impl::update_force_proxy),
|
||||
DEPRECATED_SET(force_proxy, false, nullptr),
|
||||
SET(support_share_mode, true, nullptr),
|
||||
SET(support_merkle_torrents, true, nullptr),
|
||||
SET(report_redundant_bytes, true, nullptr),
|
||||
|
@ -2889,48 +2889,6 @@ bool is_downloading_state(int const st)
|
||||
req.triggered_manually = aep.triggered_manually;
|
||||
aep.triggered_manually = false;
|
||||
|
||||
if (settings().get_bool(settings_pack::force_proxy))
|
||||
{
|
||||
// in force_proxy mode we don't talk directly to trackers
|
||||
// we only allow trackers if there is a proxy and issue
|
||||
// a warning if there isn't one
|
||||
std::string const protocol = req.url.substr(0, req.url.find(':'));
|
||||
int const proxy_type = settings().get_int(settings_pack::proxy_type);
|
||||
|
||||
// http can run over any proxy, so as long as one is used
|
||||
// it's OK. If no proxy is configured, skip this tracker
|
||||
if ((protocol == "http" || protocol == "https")
|
||||
&& proxy_type == settings_pack::none)
|
||||
{
|
||||
aep.next_announce = now + minutes32(10);
|
||||
if (m_ses.alerts().should_post<anonymous_mode_alert>()
|
||||
|| req.triggered_manually)
|
||||
{
|
||||
m_ses.alerts().emplace_alert<anonymous_mode_alert>(get_handle()
|
||||
, anonymous_mode_alert::tracker_not_anonymous, req.url);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// for UDP, only socks5 and i2p proxies will work.
|
||||
// if we're not using one of those proxies with a UDP
|
||||
// tracker, skip it
|
||||
if (protocol == "udp"
|
||||
&& proxy_type != settings_pack::socks5
|
||||
&& proxy_type != settings_pack::socks5_pw
|
||||
&& proxy_type != settings_pack::i2p_proxy)
|
||||
{
|
||||
aep.next_announce = now + minutes32(10);
|
||||
if (m_ses.alerts().should_post<anonymous_mode_alert>()
|
||||
|| req.triggered_manually)
|
||||
{
|
||||
m_ses.alerts().emplace_alert<anonymous_mode_alert>(get_handle()
|
||||
, anonymous_mode_alert::tracker_not_anonymous, req.url);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
req.auth = tracker_login();
|
||||
#endif
|
||||
|
@ -153,7 +153,6 @@ udp_socket::udp_socket(io_service& ios)
|
||||
: m_socket(ios)
|
||||
, m_buf(new receive_buffer())
|
||||
, m_bind_port(0)
|
||||
, m_force_proxy(false)
|
||||
, m_abort(true)
|
||||
{}
|
||||
|
||||
@ -186,9 +185,7 @@ int udp_socket::read(span<packet> pkts, error_code& ec)
|
||||
// SOCKS5 cannot wrap ICMP errors. And even if it could, they certainly
|
||||
// would not arrive as unwrapped (regular) ICMP errors. If we're using
|
||||
// a proxy we must ignore these
|
||||
if (m_force_proxy
|
||||
|| (m_socks5_connection
|
||||
&& m_socks5_connection->active())) continue;
|
||||
if (m_proxy_settings.type != settings_pack::none) continue;
|
||||
|
||||
p.error = ec;
|
||||
p.data = span<char>();
|
||||
@ -202,11 +199,22 @@ int udp_socket::read(span<packet> pkts, error_code& ec)
|
||||
{
|
||||
// if the source IP doesn't match the proxy's, ignore the packet
|
||||
if (p.from != m_socks5_connection->target()) continue;
|
||||
// if we failed to unwrap, silently ignore the packet
|
||||
if (!unwrap(p.from, p.data)) continue;
|
||||
}
|
||||
// block incoming packets that aren't coming via the proxy
|
||||
// if force proxy mode is enabled
|
||||
else if (m_force_proxy) continue;
|
||||
else
|
||||
{
|
||||
// if we don't proxy trackers or peers, we may be receiving unwrapped
|
||||
// packets and we must let them through.
|
||||
bool const proxy_only
|
||||
= m_proxy_settings.proxy_peer_connections
|
||||
&& m_proxy_settings.proxy_tracker_connections
|
||||
;
|
||||
|
||||
// if we proxy everything, block all packets that aren't coming from
|
||||
// the proxy
|
||||
if (m_proxy_settings.type != settings_pack::none && proxy_only) continue;
|
||||
}
|
||||
}
|
||||
|
||||
pkts[aux::numeric_cast<std::size_t>(ret)] = p;
|
||||
@ -233,22 +241,29 @@ void udp_socket::send_hostname(char const* hostname, int const port
|
||||
return;
|
||||
}
|
||||
|
||||
bool const use_proxy
|
||||
= ((flags & peer_connection) && m_proxy_settings.proxy_peer_connections)
|
||||
|| ((flags & tracker_connection) && m_proxy_settings.proxy_tracker_connections)
|
||||
|| !(flags & (tracker_connection | peer_connection))
|
||||
;
|
||||
|
||||
if (use_proxy && m_proxy_settings.type != settings_pack::none)
|
||||
{
|
||||
if (m_socks5_connection && m_socks5_connection->active())
|
||||
{
|
||||
// send udp packets through SOCKS5 server
|
||||
wrap(hostname, port, p, ec, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_force_proxy)
|
||||
else
|
||||
{
|
||||
ec = error_code(boost::system::errc::permission_denied, generic_category());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// the overload that takes a hostname is really only supported when we're
|
||||
// using a proxy
|
||||
address target = make_address(hostname, ec);
|
||||
address const target = make_address(hostname, ec);
|
||||
if (!ec) send(udp::endpoint(target, std::uint16_t(port)), p, ec, flags);
|
||||
}
|
||||
|
||||
@ -264,21 +279,26 @@ void udp_socket::send(udp::endpoint const& ep, span<char const> p
|
||||
return;
|
||||
}
|
||||
|
||||
const bool allow_proxy
|
||||
bool const use_proxy
|
||||
= ((flags & peer_connection) && m_proxy_settings.proxy_peer_connections)
|
||||
|| ((flags & tracker_connection) && m_proxy_settings.proxy_tracker_connections)
|
||||
|| !(flags & (tracker_connection | peer_connection))
|
||||
;
|
||||
|
||||
if (allow_proxy && m_socks5_connection && m_socks5_connection->active())
|
||||
if (use_proxy && m_proxy_settings.type != settings_pack::none)
|
||||
{
|
||||
if (m_socks5_connection && m_socks5_connection->active())
|
||||
{
|
||||
// send udp packets through SOCKS5 server
|
||||
wrap(ep, p, ec, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = error_code(boost::system::errc::permission_denied, generic_category());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_force_proxy) return;
|
||||
|
||||
// set the DF flag for the socket and clear it again in the destructor
|
||||
set_dont_frag df(m_socket, (flags & dont_fragment)
|
||||
&& is_v4(ep));
|
||||
@ -314,7 +334,6 @@ void udp_socket::wrap(udp::endpoint const& ep, span<char const> p
|
||||
void udp_socket::wrap(char const* hostname, int const port, span<char const> p
|
||||
, error_code& ec, udp_send_flags_t const flags)
|
||||
{
|
||||
TORRENT_UNUSED(flags);
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
std::array<char, 270> header;
|
||||
|
@ -91,9 +91,11 @@ namespace libtorrent {
|
||||
|
||||
aux::session_settings const& settings = m_man.settings();
|
||||
|
||||
int const proxy_type = settings.get_int(settings_pack::proxy_type);
|
||||
|
||||
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))
|
||||
&& (proxy_type == settings_pack::socks5
|
||||
|| proxy_type == settings_pack::socks5_pw))
|
||||
{
|
||||
m_hostname = hostname;
|
||||
m_target.port(std::uint16_t(port));
|
||||
|
@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "libtorrent/alert_types.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/aux_/path.hpp"
|
||||
#include "libtorrent/flags.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
@ -60,40 +61,25 @@ char const* proxy_name[] = {
|
||||
"i2p_proxy"
|
||||
};
|
||||
|
||||
std::vector<std::string> rejected_trackers;
|
||||
using flags_t = flags::bitfield_flag<std::uint32_t, struct test_proxy_tag>;
|
||||
|
||||
bool alert_predicate(lt::alert const* a)
|
||||
{
|
||||
anonymous_mode_alert const* am = alert_cast<anonymous_mode_alert>(a);
|
||||
if (am == nullptr) return false;
|
||||
constexpr flags_t expect_http_connection = 1_bit;
|
||||
constexpr flags_t expect_udp_connection = 2_bit;
|
||||
//constexpr flags_t expect_http_reject = 3_bit;
|
||||
//constexpr flags_t expect_udp_reject = 4_bit;
|
||||
constexpr flags_t expect_dht_msg = 5_bit;
|
||||
constexpr flags_t expect_peer_connection = 6_bit;
|
||||
|
||||
if (am->kind == anonymous_mode_alert::tracker_not_anonymous)
|
||||
rejected_trackers.push_back(am->str);
|
||||
constexpr flags_t dont_proxy_peers = 10_bit;
|
||||
constexpr flags_t dont_proxy_trackers = 11_bit;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum flags_t
|
||||
{
|
||||
force_proxy_mode = 1,
|
||||
expect_http_connection = 2,
|
||||
expect_udp_connection = 4,
|
||||
expect_http_reject = 8,
|
||||
expect_udp_reject = 16,
|
||||
expect_dht_msg = 32,
|
||||
expect_peer_connection = 64,
|
||||
expect_possible_udp_connection = 128,
|
||||
expect_possible_dht_msg = 256,
|
||||
};
|
||||
|
||||
session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, flags_t const flags)
|
||||
{
|
||||
#ifdef TORRENT_DISABLE_DHT
|
||||
// if DHT is disabled, we won't get any requests to it
|
||||
flags &= ~expect_dht_msg;
|
||||
#endif
|
||||
std::printf("\n=== TEST == proxy: %s anonymous-mode: %s\n\n"
|
||||
, proxy_name[proxy_type], (flags & force_proxy_mode) ? "yes" : "no");
|
||||
std::printf("\n=== TEST == proxy: %s \n\n", proxy_name[proxy_type]);
|
||||
int const http_port = start_web_server();
|
||||
int const udp_port = start_udp_tracker();
|
||||
int const dht_port = start_dht();
|
||||
@ -114,7 +100,6 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
sett.set_int(settings_pack::tracker_receive_timeout, 2);
|
||||
sett.set_bool(settings_pack::announce_to_all_trackers, true);
|
||||
sett.set_bool(settings_pack::announce_to_all_tiers, true);
|
||||
sett.set_bool(settings_pack::force_proxy, flags & force_proxy_mode);
|
||||
sett.set_int(settings_pack::alert_mask, alert_mask);
|
||||
sett.set_bool(settings_pack::enable_upnp, false);
|
||||
sett.set_bool(settings_pack::enable_natpmp, false);
|
||||
@ -138,9 +123,11 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
// wheras in anonymous mode, we just fail
|
||||
sett.set_str(settings_pack::proxy_hostname, "non-existing.com");
|
||||
sett.set_int(settings_pack::proxy_type, proxy_type);
|
||||
sett.set_bool(settings_pack::proxy_peer_connections, !(flags & dont_proxy_peers));
|
||||
sett.set_bool(settings_pack::proxy_tracker_connections, !(flags & dont_proxy_trackers));
|
||||
sett.set_int(settings_pack::proxy_port, 4444);
|
||||
|
||||
lt::session* s = new lt::session(sett);
|
||||
std::unique_ptr<lt::session> s(new lt::session(sett));
|
||||
|
||||
error_code ec;
|
||||
remove_all("tmp1_privacy", ec);
|
||||
@ -153,11 +140,13 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
std::snprintf(http_tracker_url, sizeof(http_tracker_url)
|
||||
, "http://127.0.0.1:%d/announce", http_port);
|
||||
t->add_tracker(http_tracker_url, 0);
|
||||
std::printf("http tracker: %s\n", http_tracker_url);
|
||||
|
||||
char udp_tracker_url[200];
|
||||
std::snprintf(udp_tracker_url, sizeof(udp_tracker_url)
|
||||
, "udp://127.0.0.1:%d/announce", udp_port);
|
||||
t->add_tracker(udp_tracker_url, 1);
|
||||
std::printf("udp tracker: %s\n", udp_tracker_url);
|
||||
|
||||
add_torrent_params addp;
|
||||
addp.flags &= ~torrent_flags::paused;
|
||||
@ -175,42 +164,31 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
std::printf("connect_peer: 127.0.0.1:%d\n", peer_port);
|
||||
h.connect_peer({address_v4::from_string("127.0.0.1"), std::uint16_t(peer_port)});
|
||||
|
||||
rejected_trackers.clear();
|
||||
std::vector<std::string> accepted_trackers;
|
||||
|
||||
const int timeout = 20;
|
||||
const int timeout = 30;
|
||||
|
||||
for (int i = 0; i < timeout; ++i)
|
||||
{
|
||||
print_alerts(*s, "s", false, false, &alert_predicate);
|
||||
print_alerts(*s, "s", false, false
|
||||
, [&](lt::alert const* a)
|
||||
{
|
||||
if (auto const* ta = alert_cast<tracker_reply_alert>(a))
|
||||
accepted_trackers.push_back(ta->tracker_url());
|
||||
return false;
|
||||
});
|
||||
std::this_thread::sleep_for(lt::milliseconds(100));
|
||||
|
||||
if (num_udp_announces() >= prev_udp_announces + 1
|
||||
&& num_peer_hits() > 0)
|
||||
&& num_peer_hits() > 0
|
||||
&& !accepted_trackers.empty())
|
||||
break;
|
||||
}
|
||||
|
||||
// we should have announced to the tracker by now
|
||||
if (flags & expect_possible_udp_connection)
|
||||
{
|
||||
// this flag is true if we may fail open, but also might not have had
|
||||
// enough time to fail yet
|
||||
TEST_CHECK(num_udp_announces() == prev_udp_announces
|
||||
|| num_udp_announces() == prev_udp_announces + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EQUAL(num_udp_announces(), prev_udp_announces
|
||||
+ ((flags & expect_udp_connection) != 0 ? 1 : 0));
|
||||
}
|
||||
+ ((flags & expect_udp_connection) ? 1 : 0));
|
||||
|
||||
if (flags & expect_possible_udp_connection)
|
||||
{
|
||||
// this flag is true if we may fail open, but also might not have had
|
||||
// enough time to fail yet
|
||||
TEST_CHECK(num_dht_hits() == 0 || num_dht_hits() == 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & expect_dht_msg)
|
||||
{
|
||||
TEST_CHECK(num_dht_hits() > 0);
|
||||
@ -219,7 +197,6 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
{
|
||||
TEST_EQUAL(num_dht_hits(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & expect_peer_connection)
|
||||
{
|
||||
@ -230,17 +207,31 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
||||
TEST_EQUAL(num_peer_hits(), 0);
|
||||
}
|
||||
|
||||
if (flags & expect_udp_reject)
|
||||
TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end()
|
||||
, udp_tracker_url) != rejected_trackers.end());
|
||||
if (flags & expect_http_connection)
|
||||
{
|
||||
TEST_CHECK(std::find(accepted_trackers.begin(), accepted_trackers.end()
|
||||
, http_tracker_url) != accepted_trackers.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_CHECK(std::find(accepted_trackers.begin(), accepted_trackers.end()
|
||||
, http_tracker_url) == accepted_trackers.end());
|
||||
}
|
||||
|
||||
if (flags & expect_http_reject)
|
||||
TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end()
|
||||
, http_tracker_url) != rejected_trackers.end());
|
||||
if (flags & expect_udp_connection)
|
||||
{
|
||||
TEST_CHECK(std::find(accepted_trackers.begin(), accepted_trackers.end()
|
||||
, udp_tracker_url) != accepted_trackers.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_CHECK(std::find(accepted_trackers.begin(), accepted_trackers.end()
|
||||
, udp_tracker_url) == accepted_trackers.end());
|
||||
}
|
||||
|
||||
std::printf("%s: ~session\n", time_now_string());
|
||||
session_proxy pr = s->abort();
|
||||
delete s;
|
||||
s.reset();
|
||||
|
||||
stop_peer();
|
||||
stop_dht();
|
||||
@ -261,79 +252,88 @@ TORRENT_TEST(no_proxy)
|
||||
| expect_http_connection | expect_dht_msg | expect_peer_connection);
|
||||
}
|
||||
|
||||
// since we don't actually have a proxy in this test, make sure libtorrent
|
||||
// doesn't send any outgoing packets to either tracker or the peer
|
||||
TORRENT_TEST(socks4)
|
||||
{
|
||||
test_proxy(settings_pack::socks4, expect_udp_connection | expect_dht_msg);
|
||||
test_proxy(settings_pack::socks4, {});
|
||||
}
|
||||
|
||||
TORRENT_TEST(socks5)
|
||||
{
|
||||
test_proxy(settings_pack::socks5, expect_possible_udp_connection
|
||||
| expect_possible_dht_msg);
|
||||
test_proxy(settings_pack::socks5, {});
|
||||
}
|
||||
|
||||
TORRENT_TEST(socks5_pw)
|
||||
{
|
||||
test_proxy(settings_pack::socks5_pw,expect_possible_udp_connection
|
||||
| expect_possible_dht_msg);
|
||||
test_proxy(settings_pack::socks5_pw, {});
|
||||
}
|
||||
|
||||
TORRENT_TEST(http)
|
||||
{
|
||||
test_proxy(settings_pack::http, expect_udp_connection | expect_dht_msg);
|
||||
test_proxy(settings_pack::http, {});
|
||||
}
|
||||
|
||||
TORRENT_TEST(http_pt)
|
||||
TORRENT_TEST(http_pw)
|
||||
{
|
||||
test_proxy(settings_pack::http_pw, expect_udp_connection | expect_dht_msg);
|
||||
test_proxy(settings_pack::http_pw, {});
|
||||
}
|
||||
|
||||
// if we configure trackers to not be proxied, they should be let through
|
||||
TORRENT_TEST(socks4_tracker)
|
||||
{
|
||||
test_proxy(settings_pack::socks4, dont_proxy_trackers | expect_http_connection | expect_udp_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(socks5_tracker)
|
||||
{
|
||||
test_proxy(settings_pack::socks5, dont_proxy_trackers | expect_http_connection | expect_udp_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(socks5_pw_tracker)
|
||||
{
|
||||
test_proxy(settings_pack::socks5_pw, dont_proxy_trackers | expect_http_connection | expect_udp_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(http_tracker)
|
||||
{
|
||||
test_proxy(settings_pack::http, dont_proxy_trackers | expect_http_connection | expect_udp_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(http_pw_tracker)
|
||||
{
|
||||
test_proxy(settings_pack::http_pw, dont_proxy_trackers | expect_http_connection | expect_udp_connection);
|
||||
}
|
||||
|
||||
// if we configure peers to not be proxied, they should be let through
|
||||
TORRENT_TEST(socks4_peer)
|
||||
{
|
||||
test_proxy(settings_pack::socks4, dont_proxy_peers | expect_peer_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(socks5_peer)
|
||||
{
|
||||
test_proxy(settings_pack::socks5, dont_proxy_peers | expect_peer_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(socks5_pw_peer)
|
||||
{
|
||||
test_proxy(settings_pack::socks5_pw, dont_proxy_peers | expect_peer_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(http_peer)
|
||||
{
|
||||
test_proxy(settings_pack::http, dont_proxy_peers | expect_peer_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(http_pw_peer)
|
||||
{
|
||||
test_proxy(settings_pack::http_pw, dont_proxy_peers | expect_peer_connection);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
TORRENT_TEST(i2p)
|
||||
{
|
||||
test_proxy(settings_pack::i2p_proxy, expect_udp_connection | expect_dht_msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
// using anonymous mode
|
||||
|
||||
// anonymous mode doesn't require a proxy when one isn't configured. It could be
|
||||
// used with a VPN for instance. This will all changed in 1.0, where anonymous
|
||||
// mode is separated from force_proxy
|
||||
|
||||
TORRENT_TEST(anon_no_proxy)
|
||||
{
|
||||
test_proxy(settings_pack::none, force_proxy_mode | expect_peer_connection);
|
||||
}
|
||||
|
||||
TORRENT_TEST(anon_socks4)
|
||||
{
|
||||
test_proxy(settings_pack::socks4, force_proxy_mode | expect_udp_reject);
|
||||
}
|
||||
|
||||
TORRENT_TEST(anon_socks5)
|
||||
{
|
||||
test_proxy(settings_pack::socks5, force_proxy_mode);
|
||||
}
|
||||
|
||||
TORRENT_TEST(anon_socks5_pw)
|
||||
{
|
||||
test_proxy(settings_pack::socks5_pw, force_proxy_mode);
|
||||
}
|
||||
|
||||
TORRENT_TEST(anon_http)
|
||||
{
|
||||
test_proxy(settings_pack::http, force_proxy_mode | expect_udp_reject);
|
||||
}
|
||||
|
||||
TORRENT_TEST(anon_http_pw)
|
||||
{
|
||||
test_proxy(settings_pack::http_pw, force_proxy_mode | expect_udp_reject);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
TORRENT_TEST(anon_i2p)
|
||||
{
|
||||
test_proxy(settings_pack::i2p_proxy, force_proxy_mode);
|
||||
test_proxy(settings_pack::i2p_proxy, {});
|
||||
}
|
||||
#endif
|
||||
|
@ -568,7 +568,6 @@ void test_proxy(bool proxy_trackers)
|
||||
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);
|
||||
|
@ -181,7 +181,6 @@ void test_transfer(int proxy_type, settings_pack const& sett
|
||||
pack_p.set_str(settings_pack::proxy_password, "testpass");
|
||||
pack_p.set_int(settings_pack::proxy_type, proxy_type);
|
||||
pack_p.set_int(settings_pack::proxy_port, proxy_port);
|
||||
pack_p.set_bool(settings_pack::force_proxy, true);
|
||||
|
||||
// test resetting the proxy in quick succession.
|
||||
// specifically the udp_socket connecting to a new
|
||||
|
Loading…
x
Reference in New Issue
Block a user