fixed bug in udp_socket when the sockets own lifetime was dependent on the callback
This commit is contained in:
parent
67bed1407f
commit
ba8163ca9c
|
@ -64,6 +64,10 @@ namespace libtorrent
|
|||
void set_proxy_settings(proxy_settings const& ps);
|
||||
proxy_settings const& get_proxy_settings() { return m_proxy_settings; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
~udp_socket() { m_magic = 0; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
callback_t m_callback;
|
||||
|
@ -94,6 +98,7 @@ namespace libtorrent
|
|||
char m_v4_buf[1600];
|
||||
char m_v6_buf[1600];
|
||||
int m_bind_port;
|
||||
uint8_t m_outstanding;
|
||||
|
||||
tcp::socket m_socks5_sock;
|
||||
int m_connection_ticket;
|
||||
|
@ -103,6 +108,9 @@ namespace libtorrent
|
|||
char m_tmp_buf[100];
|
||||
bool m_tunnel_packets;
|
||||
udp::endpoint m_proxy_addr;
|
||||
#ifndef NDEBUG
|
||||
int m_magic;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,20 +18,33 @@ udp_socket::udp_socket(asio::io_service& ios, udp_socket::callback_t const& c
|
|||
, m_ipv4_sock(ios)
|
||||
, m_ipv6_sock(ios)
|
||||
, m_bind_port(0)
|
||||
, m_outstanding(0)
|
||||
, m_socks5_sock(ios)
|
||||
, m_connection_ticket(-1)
|
||||
, m_cc(cc)
|
||||
, m_resolver(ios)
|
||||
, m_tunnel_packets(false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
m_magic = 0x1337;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define CHECK_MAGIC check_magic_ cm_(m_magic)
|
||||
struct check_magic_
|
||||
{
|
||||
check_magic_(int& m_): m(m_) { TORRENT_ASSERT(m == 0x1337); }
|
||||
~check_magic_() { TORRENT_ASSERT(m == 0x1337); }
|
||||
int& m;
|
||||
};
|
||||
#else
|
||||
#define CHECK_MAGIC (void)
|
||||
#endif
|
||||
|
||||
void udp_socket::send(udp::endpoint const& ep, char const* p, int len, error_code& ec)
|
||||
{
|
||||
if (ec == asio::error::operation_aborted) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (m_tunnel_packets)
|
||||
{
|
||||
// send udp packets through SOCKS5 server
|
||||
|
@ -47,10 +60,26 @@ void udp_socket::send(udp::endpoint const& ep, char const* p, int len, error_cod
|
|||
|
||||
void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_transferred)
|
||||
{
|
||||
if (e == asio::error::operation_aborted) return;
|
||||
|
||||
TORRENT_ASSERT(m_magic == 0x1337);
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
TORRENT_ASSERT(m_outstanding > 0);
|
||||
--m_outstanding;
|
||||
|
||||
if (e == asio::error::operation_aborted)
|
||||
{
|
||||
if (m_outstanding == 0)
|
||||
{
|
||||
// "this" may be destructed in the callback
|
||||
// that's why we need to unlock
|
||||
l.unlock();
|
||||
callback_t tmp = m_callback;
|
||||
m_callback.clear();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
if (!m_callback) return;
|
||||
|
||||
if (e)
|
||||
|
@ -59,9 +88,9 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
|
|||
try {
|
||||
#endif
|
||||
if (s == &m_ipv4_sock)
|
||||
get_io_service().post(boost::bind(m_callback, e, m_v4_ep, (char*)0, 0));
|
||||
m_callback(e, m_v4_ep, 0, 0);
|
||||
else
|
||||
get_io_service().post(boost::bind(m_callback, e, m_v6_ep, (char*)0, 0));
|
||||
m_callback(e, m_v6_ep, 0, 0);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch(std::exception&) {}
|
||||
#endif
|
||||
|
@ -94,7 +123,7 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
|
|||
if (m_tunnel_packets && m_v4_ep == m_proxy_addr)
|
||||
unwrap(e, m_v4_buf, bytes_transferred);
|
||||
else
|
||||
get_io_service().post(boost::bind(m_callback, e, m_v4_ep, m_v4_buf, bytes_transferred));
|
||||
m_callback(e, m_v4_ep, m_v4_buf, bytes_transferred);
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch(std::exception&) {}
|
||||
|
@ -111,7 +140,7 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
|
|||
if (m_tunnel_packets && m_v6_ep == m_proxy_addr)
|
||||
unwrap(e, m_v6_buf, bytes_transferred);
|
||||
else
|
||||
get_io_service().post(boost::bind(m_callback, e, m_v6_ep, m_v6_buf, bytes_transferred));
|
||||
m_callback(e, m_v6_ep, m_v6_buf, bytes_transferred);
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch(std::exception&) {}
|
||||
|
@ -119,10 +148,12 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
|
|||
s->async_receive_from(asio::buffer(m_v6_buf, sizeof(m_v6_buf))
|
||||
, m_v6_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2));
|
||||
}
|
||||
++m_outstanding;
|
||||
}
|
||||
|
||||
void udp_socket::wrap(udp::endpoint const& ep, char const* p, int len, error_code& ec)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
char header[20];
|
||||
|
@ -147,6 +178,7 @@ void udp_socket::wrap(udp::endpoint const& ep, char const* p, int len, error_cod
|
|||
// unwrap the UDP packet from the SOCKS5 header
|
||||
void udp_socket::unwrap(error_code const& e, char const* buf, int size)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
// the minimum socks5 header size
|
||||
|
@ -177,27 +209,37 @@ void udp_socket::unwrap(error_code const& e, char const* buf, int size)
|
|||
return;
|
||||
}
|
||||
|
||||
get_io_service().post(boost::bind(m_callback, e, sender, p, size - (p - buf)));
|
||||
m_callback(e, sender, p, size - (p - buf));
|
||||
}
|
||||
|
||||
void udp_socket::close()
|
||||
{
|
||||
TORRENT_ASSERT(m_magic == 0x1337);
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
error_code ec;
|
||||
m_ipv4_sock.close(ec);
|
||||
m_ipv6_sock.close(ec);
|
||||
m_socks5_sock.close(ec);
|
||||
m_callback.clear();
|
||||
if (m_connection_ticket >= 0)
|
||||
{
|
||||
m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
}
|
||||
|
||||
if (m_outstanding == 0)
|
||||
{
|
||||
// "this" may be destructed in the callback
|
||||
// that's why we need to unlock
|
||||
l.unlock();
|
||||
callback_t tmp = m_callback;
|
||||
m_callback.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
if (m_ipv4_sock.is_open()) m_ipv4_sock.close(ec);
|
||||
|
@ -221,11 +263,13 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
|||
m_ipv6_sock.async_receive_from(asio::buffer(m_v6_buf, sizeof(m_v6_buf))
|
||||
, m_v6_ep, boost::bind(&udp_socket::on_read, this, &m_ipv6_sock, _1, _2));
|
||||
}
|
||||
++m_outstanding;
|
||||
m_bind_port = ep.port();
|
||||
}
|
||||
|
||||
void udp_socket::bind(int port)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
error_code ec;
|
||||
|
@ -239,6 +283,7 @@ void udp_socket::bind(int port)
|
|||
m_ipv4_sock.bind(udp::endpoint(address_v4::any(), port), ec);
|
||||
m_ipv4_sock.async_receive_from(asio::buffer(m_v4_buf, sizeof(m_v4_buf))
|
||||
, m_v4_ep, boost::bind(&udp_socket::on_read, this, &m_ipv4_sock, _1, _2));
|
||||
++m_outstanding;
|
||||
}
|
||||
m_ipv6_sock.open(udp::v6(), ec);
|
||||
if (!ec)
|
||||
|
@ -247,12 +292,14 @@ void udp_socket::bind(int port)
|
|||
m_ipv6_sock.bind(udp::endpoint(address_v6::any(), port), ec);
|
||||
m_ipv6_sock.async_receive_from(asio::buffer(m_v6_buf, sizeof(m_v6_buf))
|
||||
, m_v6_ep, boost::bind(&udp_socket::on_read, this, &m_ipv6_sock, _1, _2));
|
||||
++m_outstanding;
|
||||
}
|
||||
m_bind_port = port;
|
||||
}
|
||||
|
||||
void udp_socket::set_proxy_settings(proxy_settings const& ps)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
error_code ec;
|
||||
|
@ -275,6 +322,7 @@ 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) return;
|
||||
CHECK_MAGIC;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
|
@ -286,6 +334,7 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
|||
|
||||
void udp_socket::on_timeout()
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
error_code ec;
|
||||
|
@ -295,6 +344,7 @@ void udp_socket::on_timeout()
|
|||
|
||||
void udp_socket::on_connect(int ticket)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
m_connection_ticket = ticket;
|
||||
|
@ -306,12 +356,13 @@ void udp_socket::on_connect(int ticket)
|
|||
|
||||
void udp_socket::on_connected(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
// send SOCKS5 authentication methods
|
||||
|
@ -335,6 +386,7 @@ void udp_socket::on_connected(error_code const& e)
|
|||
|
||||
void udp_socket::handshake1(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -345,6 +397,7 @@ void udp_socket::handshake1(error_code const& e)
|
|||
|
||||
void udp_socket::handshake2(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
@ -390,6 +443,7 @@ void udp_socket::handshake2(error_code const& e)
|
|||
|
||||
void udp_socket::handshake3(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -400,6 +454,7 @@ void udp_socket::handshake3(error_code const& e)
|
|||
|
||||
void udp_socket::handshake4(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -418,6 +473,7 @@ void udp_socket::handshake4(error_code const& e)
|
|||
|
||||
void udp_socket::socks_forward_udp()
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -437,6 +493,7 @@ void udp_socket::socks_forward_udp()
|
|||
|
||||
void udp_socket::connect1(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -447,6 +504,7 @@ void udp_socket::connect1(error_code const& e)
|
|||
|
||||
void udp_socket::connect2(error_code const& e)
|
||||
{
|
||||
CHECK_MAGIC;
|
||||
if (e) return;
|
||||
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
|
Loading…
Reference in New Issue