fix crash in udp_socket when using SOCKS5 proxy
This commit is contained in:
parent
8aae74ea03
commit
e5720eafd8
|
@ -85,6 +85,7 @@
|
|||
incoming connection
|
||||
* added more detailed instrumentation of the disk I/O thread
|
||||
|
||||
* fixed crash in udp trackers when using SOCKS5 proxy
|
||||
* fixed reconnect delay when leaving upload only mode
|
||||
* fixed default values being set incorrectly in add_torrent_params through add_magnet_uri in python bindings
|
||||
* implemented unaligned write (for unbuffered I/O)
|
||||
|
|
|
@ -119,6 +119,8 @@ namespace libtorrent
|
|||
int flags;
|
||||
};
|
||||
|
||||
// number of outstanding UDP socket operations
|
||||
// using the UDP socket buffer
|
||||
int num_outstanding() const
|
||||
{
|
||||
return m_v4_outstanding
|
||||
|
@ -160,6 +162,7 @@ namespace libtorrent
|
|||
void unwrap(error_code const& e, char const* buf, int size);
|
||||
|
||||
void maybe_realloc_buffers(int which = 3);
|
||||
bool maybe_clear_callback();
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
#if defined BOOST_HAS_PTHREADS
|
||||
|
@ -218,6 +221,11 @@ namespace libtorrent
|
|||
// we have to queue the packets, we'll flush
|
||||
// them once we're connected
|
||||
std::deque<queued_packet> m_queue;
|
||||
|
||||
// counts the number of outstanding async
|
||||
// operations hanging on this socket
|
||||
int m_outstanding_ops;
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
bool m_started;
|
||||
int m_magic;
|
||||
|
|
|
@ -80,6 +80,7 @@ udp_socket::udp_socket(asio::io_service& ios
|
|||
, m_queue_packets(false)
|
||||
, m_tunnel_packets(false)
|
||||
, m_abort(false)
|
||||
, m_outstanding_ops(0)
|
||||
{
|
||||
#ifdef TORRENT_DEBUG
|
||||
m_magic = 0x1337;
|
||||
|
@ -111,6 +112,7 @@ udp_socket::~udp_socket()
|
|||
#ifdef TORRENT_DEBUG
|
||||
m_magic = 0;
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops == 0);
|
||||
}
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
|
@ -155,6 +157,21 @@ void udp_socket::send_hostname(char const* hostname, int port
|
|||
qp.flags = 0;
|
||||
}
|
||||
|
||||
bool udp_socket::maybe_clear_callback()
|
||||
{
|
||||
if (m_outstanding_ops + m_v4_outstanding
|
||||
#if TORRENT_USE_IPV6
|
||||
+ m_v6_outstanding
|
||||
#endif
|
||||
== 0)
|
||||
{
|
||||
// "this" may be destructed in the callback
|
||||
m_callback.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void udp_socket::send(udp::endpoint const& ep, char const* p, int len
|
||||
, error_code& ec, int flags)
|
||||
{
|
||||
|
@ -259,12 +276,7 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
|
|||
|
||||
if (m_abort)
|
||||
{
|
||||
if (num_outstanding() == 0)
|
||||
{
|
||||
// "this" may be destructed in the callback
|
||||
callback_t tmp = m_callback;
|
||||
m_callback.clear();
|
||||
}
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -293,12 +305,7 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
|
|||
&& e != asio::error::operation_aborted
|
||||
&& e != asio::error::message_size)
|
||||
{
|
||||
if (num_outstanding() == 0)
|
||||
{
|
||||
// "this" may be destructed in the callback
|
||||
callback_t tmp = m_callback;
|
||||
m_callback.clear();
|
||||
}
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -547,12 +554,7 @@ void udp_socket::close()
|
|||
m_connection_ticket = -1;
|
||||
}
|
||||
|
||||
if (num_outstanding() == 0)
|
||||
{
|
||||
// "this" may be destructed in the callback
|
||||
callback_t tmp = m_callback;
|
||||
m_callback.clear();
|
||||
}
|
||||
maybe_clear_callback();
|
||||
}
|
||||
|
||||
void udp_socket::set_buf_size(int s)
|
||||
|
@ -706,6 +708,7 @@ void udp_socket::set_proxy_settings(proxy_settings const& ps)
|
|||
m_queue_packets = true;
|
||||
// connect to socks5 server and open up the UDP tunnel
|
||||
tcp::resolver::query q(ps.hostname, to_string(ps.port).elems);
|
||||
++m_outstanding_ops;
|
||||
m_resolver.async_resolve(q, boost::bind(
|
||||
&udp_socket::on_name_lookup, this, _1, _2));
|
||||
}
|
||||
|
@ -713,9 +716,18 @@ void udp_socket::set_proxy_settings(proxy_settings const& ps)
|
|||
|
||||
void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
||||
{
|
||||
if (e == asio::error::operation_aborted) return;
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
|
||||
if (e == asio::error::operation_aborted) return;
|
||||
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
if (e)
|
||||
|
@ -729,6 +741,7 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
|||
m_proxy_addr.address(i->endpoint().address());
|
||||
m_proxy_addr.port(i->endpoint().port());
|
||||
// on_connect may be called from within this thread
|
||||
++m_outstanding_ops;
|
||||
m_cc.enqueue(boost::bind(&udp_socket::on_connect, this, _1)
|
||||
, boost::bind(&udp_socket::on_timeout, this), seconds(10));
|
||||
}
|
||||
|
@ -745,8 +758,15 @@ void udp_socket::on_timeout()
|
|||
|
||||
void udp_socket::on_connect(int ticket)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
|
||||
if (m_abort) return;
|
||||
if (is_closed()) return;
|
||||
|
@ -757,6 +777,7 @@ void udp_socket::on_connect(int ticket)
|
|||
m_connection_ticket = ticket;
|
||||
error_code ec;
|
||||
m_socks5_sock.open(m_proxy_addr.address().is_v4()?tcp::v4():tcp::v6(), ec);
|
||||
++m_outstanding_ops;
|
||||
m_socks5_sock.async_connect(tcp::endpoint(m_proxy_addr.address(), m_proxy_addr.port())
|
||||
, boost::bind(&udp_socket::on_connected, this, _1));
|
||||
}
|
||||
|
@ -766,11 +787,18 @@ void udp_socket::on_connected(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::on_connected");
|
||||
#endif
|
||||
|
||||
if (e == asio::error::operation_aborted) return;
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
|
||||
if (e == asio::error::operation_aborted) return;
|
||||
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
|
@ -803,6 +831,7 @@ void udp_socket::on_connected(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::on_handshake1");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_write(m_socks5_sock, asio::buffer(m_tmp_buf, p - m_tmp_buf)
|
||||
, boost::bind(&udp_socket::handshake1, this, _1));
|
||||
}
|
||||
|
@ -812,6 +841,14 @@ void udp_socket::handshake1(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::on_handshake1");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
|
@ -820,6 +857,7 @@ void udp_socket::handshake1(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::on_handshake2");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_read(m_socks5_sock, asio::buffer(m_tmp_buf, 2)
|
||||
, boost::bind(&udp_socket::handshake2, this, _1));
|
||||
}
|
||||
|
@ -829,7 +867,15 @@ void udp_socket::handshake2(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::on_handshake2");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
|
||||
if (e) return;
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
@ -866,6 +912,7 @@ void udp_socket::handshake2(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::on_handshake3");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_write(m_socks5_sock, asio::buffer(m_tmp_buf, p - m_tmp_buf)
|
||||
, boost::bind(&udp_socket::handshake3, this, _1));
|
||||
}
|
||||
|
@ -882,6 +929,14 @@ void udp_socket::handshake3(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::on_handshake3");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
|
@ -890,6 +945,7 @@ void udp_socket::handshake3(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::on_handshake4");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_read(m_socks5_sock, asio::buffer(m_tmp_buf, 2)
|
||||
, boost::bind(&udp_socket::handshake4, this, _1));
|
||||
}
|
||||
|
@ -899,6 +955,14 @@ void udp_socket::handshake4(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::on_handshake4");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
|
@ -944,6 +1008,7 @@ void udp_socket::socks_forward_udp()
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::connect1");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_write(m_socks5_sock, asio::buffer(m_tmp_buf, p - m_tmp_buf)
|
||||
, boost::bind(&udp_socket::connect1, this, _1));
|
||||
}
|
||||
|
@ -953,6 +1018,14 @@ void udp_socket::connect1(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::connect1");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
|
@ -961,6 +1034,7 @@ void udp_socket::connect1(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::connect2");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_read(m_socks5_sock, asio::buffer(m_tmp_buf, 10)
|
||||
, boost::bind(&udp_socket::connect2, this, _1));
|
||||
}
|
||||
|
@ -970,6 +1044,14 @@ void udp_socket::connect2(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::connect2");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
|
@ -1020,6 +1102,7 @@ void udp_socket::connect2(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("udp_socket::hung_up");
|
||||
#endif
|
||||
++m_outstanding_ops;
|
||||
asio::async_read(m_socks5_sock, asio::buffer(m_tmp_buf, 10)
|
||||
, boost::bind(&udp_socket::hung_up, this, _1));
|
||||
}
|
||||
|
@ -1029,6 +1112,14 @@ void udp_socket::hung_up(error_code const& e)
|
|||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("udp_socket::hung_up");
|
||||
#endif
|
||||
TORRENT_ASSERT(m_outstanding_ops > 0);
|
||||
--m_outstanding_ops;
|
||||
if (m_abort)
|
||||
{
|
||||
maybe_clear_callback();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
|
Loading…
Reference in New Issue