From 86a256972875da0e24ee9bba3cdba6ff646d17b6 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 19 Feb 2013 06:48:53 +0000 Subject: [PATCH] separate anonymous mode and force-proxy mode, and tighten it up a bit --- ChangeLog | 1 + docs/manual.rst | 18 +++++++++++------- include/libtorrent/session_settings.hpp | 16 ++++++++++++---- include/libtorrent/torrent.hpp | 2 +- include/libtorrent/udp_socket.hpp | 2 ++ src/session.cpp | 3 ++- src/session_impl.cpp | 20 +++++++++++--------- src/torrent.cpp | 6 +++--- src/udp_socket.cpp | 15 ++++++++++++++- 9 files changed, 57 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8568a4f4a..ce2ab1621 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * separate anonymous mode and force-proxy mode, and tighten it up a bit * add per-tracker scrape information to announce_entry * report errors in read_piece_alert * DHT memory optimization diff --git a/docs/manual.rst b/docs/manual.rst index 144aa10bc..6b9a4aba6 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -4592,6 +4592,7 @@ session_settings bool ignore_resume_timestamps; bool no_recheck_incomplete_resume; bool anonymous_mode; + bool force_proxy; int tick_interval; int share_mode_target; @@ -5339,14 +5340,17 @@ mode. ``anonymous_mode`` defaults to false. When set to true, the client tries to hide its identity to a certain degree. The peer-ID will no longer include the client's fingerprint. The user-agent will be reset to an -empty string. Trackers will only be used if they are using a proxy -server. The listen sockets are closed, and incoming connections will -only be accepted through a SOCKS5 or I2P proxy (if a peer proxy is set up and -is run on the same machine as the tracker proxy). Since no incoming connections -are accepted, NAT-PMP, UPnP, DHT and local peer discovery are all turned off -when this setting is enabled. +empty string. -If you're using I2P, it might make sense to enable anonymous mode as well. +If you're using I2P, it might make sense to enable anonymous mode. + +``force_proxy`` disables any communication that's not going over a proxy. +Enabling this requires a proxy to be configured as well, see ``set_proxy_settings``. +The listen sockets are closed, and incoming connections will +only be accepted through a SOCKS5 or I2P proxy (if a peer proxy is set up and +is run on the same machine as the tracker proxy). This setting also +disabled peer country lookups, since those are done via DNS lookups that +aren't supported by proxies. ``tick_interval`` specifies the number of milliseconds between internal ticks. This is the frequency with which bandwidth quota is distributed to diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 8914be327..1ef1268c1 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -758,12 +758,20 @@ namespace libtorrent bool no_recheck_incomplete_resume; // when this is true, libtorrent will take actions to make sure no - // privacy sensitive information is leaked out from the client. This - // mode is assumed to be combined with using a proxy for all your - // traffic. With this option, your true IP address will not be exposed - // nor anything that can tie your connection to your true IP + // privacy sensitive information is leaked out from the client. + // With this option, your IP address will not be exposed over + // the wire protocol. Other measures will also be taken to make it + // harder to track you. bool anonymous_mode; + // when this is true, no connection will ever be made without going + // through a proxy. If you set up a proxy and prefer connections not + // supported by the proxy to fail, rather than circumventing it, set + // this to true. For instance, reverse DNS lookups can rarely be + // made via a proxy, so resolving peer countries is disabled with + // this switch. + bool force_proxy; + // the number of milliseconds between internal ticks. Should be no // more than one second (i.e. 1000). int tick_interval; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 64b3be682..b8de970e4 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -347,7 +347,7 @@ namespace libtorrent bool resolving_countries() const { - return m_resolve_countries && !m_ses.settings().anonymous_mode; + return m_resolve_countries && !m_ses.settings().force_proxy; } #endif diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp index 6db391336..896ff4d04 100644 --- a/include/libtorrent/udp_socket.hpp +++ b/include/libtorrent/udp_socket.hpp @@ -96,6 +96,7 @@ namespace libtorrent void set_proxy_settings(proxy_settings const& ps); 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; } tcp::endpoint local_endpoint(error_code& ec) const @@ -235,6 +236,7 @@ namespace libtorrent char m_tmp_buf[270]; bool m_queue_packets; bool m_tunnel_packets; + bool m_force_proxy; bool m_abort; udp::endpoint m_proxy_addr; // while we're connecting to the proxy diff --git a/src/session.cpp b/src/session.cpp index 387ed8587..db8673151 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -1247,7 +1247,8 @@ namespace libtorrent , max_pex_peers(50) , ignore_resume_timestamps(false) , no_recheck_incomplete_resume(false) - , anonymous_mode(false) + , anonymous_mode(true) + , force_proxy(false) , tick_interval(100) , report_web_seed_downloads(true) , share_mode_target(3) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index b58f9edce..52f5899b2 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -410,6 +410,7 @@ namespace aux { TORRENT_SETTING(boolean, ignore_resume_timestamps) TORRENT_SETTING(boolean, no_recheck_incomplete_resume) TORRENT_SETTING(boolean, anonymous_mode) + TORRENT_SETTING(boolean, force_proxy) TORRENT_SETTING(integer, tick_interval) TORRENT_SETTING(boolean, report_web_seed_downloads) TORRENT_SETTING(integer, share_mode_target) @@ -2024,9 +2025,6 @@ namespace aux { || m_settings.active_limit != s.active_limit)) m_auto_manage_time_scaler = 2; - // if anonymous mode was enabled, clear out the peer ID - bool anonymous = (m_settings.anonymous_mode != s.anonymous_mode && s.anonymous_mode); - if (m_settings.report_web_seed_downloads != s.report_web_seed_downloads) { // if this flag changed, update all web seed connections @@ -2065,9 +2063,13 @@ namespace aux { if (connections_limit_changed) update_connections_limit(); if (unchoke_limit_changed) update_unchoke_limit(); - // enable anonymous mode. We don't want to accept any incoming + bool force_proxy = (m_settings.force_proxy != s.force_proxy && s.force_proxy); + + m_udp_socket.set_force_proxy(s.force_proxy); + + // in force_proxy mode, we don't want to accept any incoming // connections, except through a proxy. - if (anonymous) + if (force_proxy) { m_settings.user_agent.clear(); url_random((char*)&m_peer_id[0], (char*)&m_peer_id[0] + 20); @@ -5368,10 +5370,10 @@ retry: if (m_socks_listen_socket && m_socks_listen_socket->is_open()) return m_socks_listen_port; - // if not, don't tell the tracker anything if we're in anonymous + // 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 elsewere - if (m_settings.anonymous_mode) return 0; + if (m_settings.force_proxy) return 0; if (m_listen_sockets.empty()) return 0; return m_listen_sockets.front().external_port; } @@ -5386,10 +5388,10 @@ retry: && m_proxy.hostname == m_proxy.hostname) return m_socks_listen_port; - // if not, don't tell the tracker anything if we're in anonymous + // 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 elsewere - if (m_settings.anonymous_mode) return 0; + if (m_settings.force_proxy) return 0; if (m_listen_sockets.empty()) return 0; for (std::list::const_iterator i = m_listen_sockets.begin() , end(m_listen_sockets.end()); i != end; ++i) diff --git a/src/torrent.cpp b/src/torrent.cpp index 135564bda..ae96af134 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2406,10 +2406,10 @@ namespace libtorrent if (!is_any(bind_interface)) req.bind_ip = bind_interface; else req.bind_ip = m_ses.m_listen_interface.address(); - if (settings().anonymous_mode) + if (settings().force_proxy) { - // in anonymous_mode we don't talk directly to trackers - // only if there is a proxy + // in force_proxy mode we don't talk directly to trackers + // unless there is a proxy std::string protocol = req.url.substr(0, req.url.find(':')); int proxy_type = m_ses.m_proxy.type; diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index 9f97cd00e..9b255fea0 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -73,6 +73,7 @@ udp_socket::udp_socket(asio::io_service& ios , m_resolver(ios) , m_queue_packets(false) , m_tunnel_packets(false) + , m_force_proxy(false) , m_abort(false) , m_outstanding_ops(0) #if TORRENT_USE_IPV6 @@ -143,6 +144,10 @@ void udp_socket::send_hostname(char const* hostname, int port wrap(hostname, port, p, len, ec); return; } + else if (m_force_proxy) + { + return; + } // this function is only supported when we're using a proxy TORRENT_ASSERT(m_queue_packets); @@ -175,6 +180,10 @@ void udp_socket::send(udp::endpoint const& ep, char const* p, int len wrap(ep, p, len, ec); return; } + else if (m_force_proxy) + { + return; + } if (m_queue_packets) { @@ -187,6 +196,10 @@ void udp_socket::send(udp::endpoint const& ep, char const* p, int len return; } } + else if (m_force_proxy) + { + return; + } #if TORRENT_USE_IPV6 if (ep.address().is_v6() && m_ipv6_sock.is_open()) @@ -430,7 +443,7 @@ void udp_socket::on_read_impl(udp::socket* s, udp::endpoint const& ep if (ep == m_proxy_addr) unwrap(e, m_buf, bytes_transferred); } - else + else if (!m_force_proxy) // block incoming packets that aren't coming via the proxy { call_handler(e, ep, m_buf, bytes_transferred); }