From ef48c92a4e7a6be5cac5ad1470e2626b3754b6e2 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 25 Jul 2010 01:31:15 +0000 Subject: [PATCH] fixed SOCKS5 bug for routing UDP packets --- ChangeLog | 1 + examples/client_test.cpp | 35 ++++++++++++++++++++++++------- include/libtorrent/udp_socket.hpp | 1 + src/udp_socket.cpp | 18 +++++++++++++++- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index d4b965855..ce4e5344e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,7 @@ incoming connection * added more detailed instrumentation of the disk I/O thread + * fixed SOCKS5 bug for routing UDP packets * fixed bug on windows when verifying resume data for a torrent where one of its directories had been removed * fixed race condition in peer-list with DHT diff --git a/examples/client_test.cpp b/examples/client_test.cpp index c3bd3d507..22c8669d7 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -774,6 +774,8 @@ int main(int argc, char* argv[]) " -R number of blocks per read cache line\n" " -O Disallow disk job reordering\n" " -P Use the specified SOCKS5 proxy\n" + " -L Use the specified username and password for the\n" + " proxy specified by -P\n" " -H Don't start DHT\n" " -W Set the max number of peers to keep in the peer list\n" " " @@ -794,6 +796,8 @@ int main(int argc, char* argv[]) settings.disk_cache_algorithm = session_settings::largest_contiguous; settings.volatile_read_cache = true; + proxy_settings ps; + int refresh_delay = 1; bool start_dht = true; @@ -947,20 +951,28 @@ int main(int argc, char* argv[]) break; } *port++ = 0; - proxy_settings ps; ps.hostname = arg; ps.port = atoi(port); if (ps.port == 0) { fprintf(stderr, "invalid proxy port\n"); break; } - ps.type = proxy_settings::socks5; - ses.set_peer_proxy(ps); - ses.set_web_seed_proxy(ps); - ses.set_tracker_proxy(ps); -#ifndef TORRENT_DISABLE_DHT - ses.set_dht_proxy(ps); -#endif + if (ps.type == proxy_settings::none) + ps.type = proxy_settings::socks5; + } + break; + case 'L': + { + char* pw = (char*) strchr(arg, ':'); + if (pw == 0) + { + fprintf(stderr, "invalid proxy username and password specified\n"); + break; + } + *pw++ = 0; + ps.username = arg; + ps.password = pw; + ps.type = proxy_settings::socks5_pw; } break; case 'I': outgoing_interface = arg; break; @@ -968,6 +980,13 @@ int main(int argc, char* argv[]) ++i; // skip the argument } + ses.set_peer_proxy(ps); + ses.set_web_seed_proxy(ps); + ses.set_tracker_proxy(ps); +#ifndef TORRENT_DISABLE_DHT + ses.set_dht_proxy(ps); +#endif + ses.listen_on(std::make_pair(listen_port, listen_port + 10) , bind_to_interface.c_str()); diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp index 415cd5823..beb901b52 100644 --- a/include/libtorrent/udp_socket.hpp +++ b/include/libtorrent/udp_socket.hpp @@ -108,6 +108,7 @@ namespace libtorrent void socks_forward_udp(mutex::scoped_lock& l); void connect1(error_code const& e); void connect2(error_code const& e); + void hung_up(error_code const& e); void wrap(udp::endpoint const& ep, char const* p, int len, error_code& ec); void unwrap(error_code const& e, char const* buf, int size); diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index bdc030efd..c4f28bdbe 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -646,7 +646,7 @@ void udp_socket::socks_forward_udp(mutex::scoped_lock& l) write_uint8(5, p); // SOCKS VERSION 5 write_uint8(3, p); // UDP ASSOCIATE command write_uint8(0, p); // reserved - write_uint8(0, p); // ATYP IPv4 + write_uint8(1, p); // ATYP IPv4 write_uint32(0, p); // IP any write_uint16(m_bind_port, p); @@ -705,6 +705,22 @@ void udp_socket::connect2(error_code const& e) udp_socket::send(p.ep, &p.buf[0], p.buf.size(), ec); m_queue.pop_front(); } + + asio::async_read(m_socks5_sock, asio::buffer(m_tmp_buf, 10) + , boost::bind(&udp_socket::hung_up, this, _1)); +} + +void udp_socket::hung_up(error_code const& e) +{ + CHECK_MAGIC; + mutex::scoped_lock l(m_mutex); + + if (e == asio::error::operation_aborted || m_abort) return; + + l.unlock(); + + // the socks connection was closed, re-open it + set_proxy_settings(m_proxy_settings); } rate_limited_udp_socket::rate_limited_udp_socket(io_service& ios