if proxy name server lookup fails, and we're not in anonymous mode, disable the proxy and continue

This commit is contained in:
Arvid Norberg 2013-10-20 21:08:59 +00:00
parent e8db4fe67a
commit 3aa2d46b4b
3 changed files with 40 additions and 27 deletions

View File

@ -689,7 +689,10 @@ namespace libtorrent
// These functions sets and queries the proxy settings to be used for the session.
//
// For more information on what settings are available for proxies, see
// proxy_settings.
// proxy_settings. If the session is not in anonymous mode, proxies that
// aren't working or fail, will automatically be disabled and packets will
// flow without using any proxy. If you want to enforce using a proxy, even when
// the proxy doesn't work, enable anonymous_mode in session_settings.
void set_proxy(proxy_settings const& s);
proxy_settings proxy() const;

View File

@ -148,13 +148,9 @@ 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
if (!m_queue_packets)
if (!m_queue_packets && !m_force_proxy)
{
address target = address::from_string(hostname, ec);
if (!ec) send(udp::endpoint(target, port), p, len, ec, 0);
@ -785,11 +781,21 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
TORRENT_ASSERT(is_single_thread());
if (e)
{
if (m_force_proxy)
{
call_handler(e, udp::endpoint(), 0, 0);
}
else
{
// 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_tunnel_packets = false;
}
drain_queue();
return;
}
@ -1352,7 +1358,7 @@ void udp_socket::drain_queue()
udp_socket::send_hostname(p.hostname, p.ep.port(), &p.buf[0], p.buf.size(), ec);
free(p.hostname);
}
else if (!m_force_proxy) // block incoming packets that aren't coming via the proxy
else
{
udp_socket::send(p.ep, &p.buf[0], p.buf.size(), ec, p.flags);
}

View File

@ -75,7 +75,7 @@ enum flags_t
expect_peer_connection = 64,
};
void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
session_proxy test_proxy(proxy_settings::proxy_type proxy_type, int flags)
{
#ifdef TORRENT_DISABLE_DHT
// if DHT is disabled, we won't get any requests to it
@ -112,6 +112,8 @@ void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
sett.enable_outgoing_utp = false;
s->set_settings(sett);
// in non-anonymous mode we circumvent/ignore the proxy if it fails
// wheras in anonymous mode, we just fail
proxy_settings ps;
ps.hostname = "non-existing.com";
ps.port = 4444;
@ -148,9 +150,9 @@ void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
rejected_trackers.clear();
#ifdef TORRENT_USE_VALGRIND
const int timeout = 90;
const int timeout = 100;
#else
const int timeout = 15;
const int timeout = 20;
#endif
for (int i = 0; i < timeout; ++i)
@ -192,40 +194,42 @@ void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end(), http_tracker_url) != rejected_trackers.end());
fprintf(stderr, "%s: ~session\n", time_now_string());
session_proxy pr = s->abort();
delete s;
fprintf(stderr, "%s: ~session done\n", time_now_string());
stop_peer();
stop_dht();
stop_tracker();
stop_web_server();
return pr;
}
int test_main()
{
session_proxy pr[20];
// not using anonymous mode
// UDP fails open if we can't connect to the proxy
// or if the proxy doesn't support UDP
test_proxy(proxy_settings::none, expect_udp_connection | expect_http_connection | expect_dht_msg | expect_peer_connection);
test_proxy(proxy_settings::socks4, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::socks5, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::socks5_pw, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::http, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::http_pw, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::i2p_proxy, expect_udp_connection | expect_dht_msg);
pr[0] = test_proxy(proxy_settings::none, expect_udp_connection | expect_http_connection | expect_dht_msg | expect_peer_connection);
pr[1] = test_proxy(proxy_settings::socks4, expect_udp_connection | expect_dht_msg);
pr[2] = test_proxy(proxy_settings::socks5, expect_udp_connection | expect_dht_msg);
pr[3] = test_proxy(proxy_settings::socks5_pw, expect_udp_connection | expect_dht_msg);
pr[4] = test_proxy(proxy_settings::http, expect_udp_connection | expect_dht_msg);
pr[5] = test_proxy(proxy_settings::http_pw, expect_udp_connection | expect_dht_msg);
pr[6] = test_proxy(proxy_settings::i2p_proxy, expect_udp_connection | expect_dht_msg);
// 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
test_proxy(proxy_settings::none, anonymous_mode | expect_peer_connection);
test_proxy(proxy_settings::socks4, anonymous_mode | expect_udp_reject);
test_proxy(proxy_settings::socks5, anonymous_mode);
test_proxy(proxy_settings::socks5_pw, anonymous_mode);
test_proxy(proxy_settings::http, anonymous_mode | expect_udp_reject);
test_proxy(proxy_settings::http_pw, anonymous_mode | expect_udp_reject);
test_proxy(proxy_settings::i2p_proxy, anonymous_mode);
pr[7] = test_proxy(proxy_settings::none, anonymous_mode | expect_peer_connection);
pr[8] = test_proxy(proxy_settings::socks4, anonymous_mode | expect_udp_reject);
pr[9] = test_proxy(proxy_settings::socks5, anonymous_mode);
pr[10] = test_proxy(proxy_settings::socks5_pw, anonymous_mode);
pr[11] = test_proxy(proxy_settings::http, anonymous_mode | expect_udp_reject);
pr[12] = test_proxy(proxy_settings::http_pw, anonymous_mode | expect_udp_reject);
pr[13] = test_proxy(proxy_settings::i2p_proxy, anonymous_mode);
return 0;
}