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