delay 5 seconds before reconnecting socks5 proxy for UDP ASSOCIATE

This commit is contained in:
arvidn 2017-05-20 06:07:24 -04:00 committed by Arvid Norberg
parent 83735fdbb4
commit acd98d5c40
5 changed files with 50 additions and 2 deletions

View File

@ -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

View File

@ -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];

@ -1 +1 @@
Subproject commit 70feadef80dc76ae6d5e7c2f92334377d698dd7d
Subproject commit 96e8e2414df955c04b37b6bccd2b7360a54ff2f1

View File

@ -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<sim::asio::io_service> 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<lt::session> ses = std::make_shared<lt::session>(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);
}

View File

@ -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);
}