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. // 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 // 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); void set_proxy(proxy_settings const& s);
proxy_settings proxy() const; 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); wrap(hostname, port, p, len, ec);
return; return;
} }
else if (m_force_proxy)
{
return;
}
// this function is only supported when we're using a proxy // 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); address target = address::from_string(hostname, ec);
if (!ec) send(udp::endpoint(target, port), p, len, ec, 0); if (!ec) send(udp::endpoint(target, port), p, len, ec, 0);
@ -786,10 +782,20 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
if (e) if (e)
{ {
call_handler(e, udp::endpoint(), 0, 0); 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(); drain_queue();
return; 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); udp_socket::send_hostname(p.hostname, p.ep.port(), &p.buf[0], p.buf.size(), ec);
free(p.hostname); 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); 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, 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 #ifdef TORRENT_DISABLE_DHT
// if DHT is disabled, we won't get any requests to it // 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; sett.enable_outgoing_utp = false;
s->set_settings(sett); 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; proxy_settings ps;
ps.hostname = "non-existing.com"; ps.hostname = "non-existing.com";
ps.port = 4444; ps.port = 4444;
@ -148,9 +150,9 @@ void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
rejected_trackers.clear(); rejected_trackers.clear();
#ifdef TORRENT_USE_VALGRIND #ifdef TORRENT_USE_VALGRIND
const int timeout = 90; const int timeout = 100;
#else #else
const int timeout = 15; const int timeout = 20;
#endif #endif
for (int i = 0; i < timeout; ++i) 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()); TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end(), http_tracker_url) != rejected_trackers.end());
fprintf(stderr, "%s: ~session\n", time_now_string()); fprintf(stderr, "%s: ~session\n", time_now_string());
session_proxy pr = s->abort();
delete s; delete s;
fprintf(stderr, "%s: ~session done\n", time_now_string());
stop_peer(); stop_peer();
stop_dht(); stop_dht();
stop_tracker(); stop_tracker();
stop_web_server(); stop_web_server();
return pr;
} }
int test_main() int test_main()
{ {
session_proxy pr[20];
// not using anonymous mode // not using anonymous mode
// UDP fails open if we can't connect to the proxy // UDP fails open if we can't connect to the proxy
// or if the proxy doesn't support UDP // 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); pr[0] = 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); pr[1] = test_proxy(proxy_settings::socks4, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::socks5, expect_udp_connection | expect_dht_msg); pr[2] = test_proxy(proxy_settings::socks5, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::socks5_pw, expect_udp_connection | expect_dht_msg); pr[3] = test_proxy(proxy_settings::socks5_pw, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::http, expect_udp_connection | expect_dht_msg); pr[4] = test_proxy(proxy_settings::http, expect_udp_connection | expect_dht_msg);
test_proxy(proxy_settings::http_pw, expect_udp_connection | expect_dht_msg); pr[5] = 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[6] = test_proxy(proxy_settings::i2p_proxy, expect_udp_connection | expect_dht_msg);
// using anonymous mode // using anonymous mode
// anonymous mode doesn't require a proxy when one isn't configured. It could be // 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 // used with a VPN for instance. This will all changed in 1.0, where anonymous
// mode is separated from force_proxy // mode is separated from force_proxy
test_proxy(proxy_settings::none, anonymous_mode | expect_peer_connection); pr[7] = test_proxy(proxy_settings::none, anonymous_mode | expect_peer_connection);
test_proxy(proxy_settings::socks4, anonymous_mode | expect_udp_reject); pr[8] = test_proxy(proxy_settings::socks4, anonymous_mode | expect_udp_reject);
test_proxy(proxy_settings::socks5, anonymous_mode); pr[9] = test_proxy(proxy_settings::socks5, anonymous_mode);
test_proxy(proxy_settings::socks5_pw, anonymous_mode); pr[10] = test_proxy(proxy_settings::socks5_pw, anonymous_mode);
test_proxy(proxy_settings::http, anonymous_mode | expect_udp_reject); pr[11] = test_proxy(proxy_settings::http, anonymous_mode | expect_udp_reject);
test_proxy(proxy_settings::http_pw, anonymous_mode | expect_udp_reject); pr[12] = test_proxy(proxy_settings::http_pw, anonymous_mode | expect_udp_reject);
test_proxy(proxy_settings::i2p_proxy, anonymous_mode); pr[13] = test_proxy(proxy_settings::i2p_proxy, anonymous_mode);
return 0; return 0;
} }