diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 64bc38db6..e5391d546 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -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; diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index 31cb3f907..cf61f6516 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -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); @@ -786,10 +782,20 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i) 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(); - 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); } diff --git a/test/test_privacy.cpp b/test/test_privacy.cpp index 41b09a64f..58e22ff12 100644 --- a/test/test_privacy.cpp +++ b/test/test_privacy.cpp @@ -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; }