From acd98d5c40591366a7e43e62848bb2509448fc7c Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 20 May 2017 06:07:24 -0400 Subject: [PATCH] delay 5 seconds before reconnecting socks5 proxy for UDP ASSOCIATE --- ChangeLog | 1 + include/libtorrent/udp_socket.hpp | 2 ++ simulation/libsimulator | 2 +- simulation/test_socks5.cpp | 36 +++++++++++++++++++++++++++++++ src/udp_socket.cpp | 11 +++++++++- 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a510743c..8612c5af5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * delay 5 seconds before reconnecting socks5 proxy for UDP ASSOCIATE * fix NAT-PMP crash when removing a mapping at the wrong time * improve path sanitization (filter unicode text direction characters) * deprecate partial_piece_info::piece_state diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp index 47a358789..edf9bea3f 100644 --- a/include/libtorrent/udp_socket.hpp +++ b/include/libtorrent/udp_socket.hpp @@ -234,6 +234,7 @@ namespace libtorrent void connect1(error_code const& e); void connect2(error_code const& e); void hung_up(error_code const& e); + void retry_socks_connect(error_code const& ec); void drain_queue(); @@ -268,6 +269,7 @@ namespace libtorrent #endif tcp::socket m_socks5_sock; + deadline_timer m_retry_timer; aux::proxy_settings m_proxy_settings; tcp::resolver m_resolver; char m_tmp_buf[270]; diff --git a/simulation/libsimulator b/simulation/libsimulator index 70feadef8..96e8e2414 160000 --- a/simulation/libsimulator +++ b/simulation/libsimulator @@ -1 +1 @@ -Subproject commit 70feadef80dc76ae6d5e7c2f92334377d698dd7d +Subproject commit 96e8e2414df955c04b37b6bccd2b7360a54ff2f1 diff --git a/simulation/test_socks5.cpp b/simulation/test_socks5.cpp index a0a3982b4..7bbc87585 100644 --- a/simulation/test_socks5.cpp +++ b/simulation/test_socks5.cpp @@ -254,3 +254,39 @@ TORRENT_TEST(udp_tracker) TEST_CHECK(announced); } +TORRENT_TEST(socks5_udp_retry) +{ + // this test is asserting that when a UDP associate command fails, we have a + // 5 second delay before we try again. There is no need to actually add a + // torrent for this test, just to open the udp socket with a socks5 proxy + using namespace libtorrent; + + // setup the simulation + sim::default_config network_cfg; + sim::simulation sim{network_cfg}; + std::unique_ptr ios = make_io_service(sim, 0); + lt::session_proxy zombie; + + sim::asio::io_service proxy_ios{sim, addr("50.50.50.50") }; + // close UDP associate connectons prematurely + sim::socks_server socks5(proxy_ios, 5555, 5, socks_flag::disconnect_udp_associate); + + lt::settings_pack pack = settings(); + // create session + std::shared_ptr ses = std::make_shared(pack, *ios); + set_proxy(*ses, settings_pack::socks5); + + // run for 60 seconds.The sokcks5 retry interval is expected to be 5 seconds, + // meaning there should have been 12 connection attempts + sim::timer t(sim, lt::seconds(60), [&](boost::system::error_code const& ec) + { + fprintf(stderr, "shutting down\n"); + // shut down + zombie = ses->abort(); + ses.reset(); + }); + sim.run(); + + // number of UDP ASSOCIATE commands invoked on the socks proxy + TEST_EQUAL(socks5.cmd_counts()[2], 12); +} diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index b12b7cc4e..d2e6ae3b8 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -74,6 +74,7 @@ udp_socket::udp_socket(io_service& ios) , m_restart_v6(false) #endif , m_socks5_sock(ios) + , m_retry_timer(ios) , m_resolver(ios) , m_queue_packets(false) , m_tunnel_packets(false) @@ -1464,7 +1465,15 @@ void udp_socket::hung_up(error_code const& e) if (e == boost::asio::error::operation_aborted || m_abort) return; - // the socks connection was closed, re-open it + // the socks connection was closed, re-open it in a bit + m_retry_timer.expires_from_now(seconds(5)); + m_retry_timer.async_wait(boost::bind(&udp_socket::retry_socks_connect + , this, _1)); +} + +void udp_socket::retry_socks_connect(error_code const& ec) +{ + if (ec) return; set_proxy_settings(m_proxy_settings); }