diff --git a/include/libtorrent/aux_/listen_socket_handle.hpp b/include/libtorrent/aux_/listen_socket_handle.hpp index a6634471a..bb451aca1 100644 --- a/include/libtorrent/aux_/listen_socket_handle.hpp +++ b/include/libtorrent/aux_/listen_socket_handle.hpp @@ -35,24 +35,11 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/address.hpp" #include "libtorrent/socket.hpp" // for tcp::endpoint -#include "libtorrent/ip_voter.hpp" -#include "libtorrent/aux_/session_udp_sockets.hpp" #include namespace libtorrent { namespace aux { - struct listen_socket_base - { - // this may be empty but can be set - // to the WAN IP address of a NAT router - ip_voter external_address; - - // this is a cached local endpoint for the listen TCP socket - tcp::endpoint local_endpoint; - - // indicates whether this is an SSL listen socket or not - transport ssl = transport::plaintext; - }; + struct listen_socket_t; struct TORRENT_EXTRA_EXPORT listen_socket_handle { @@ -60,7 +47,7 @@ namespace libtorrent { namespace aux { listen_socket_handle() {} - listen_socket_handle(std::shared_ptr s) // NOLINT + listen_socket_handle(std::shared_ptr s) // NOLINT : m_sock(s) {} @@ -92,10 +79,10 @@ namespace libtorrent { namespace aux { return *this; } - listen_socket_base* impl() const; + listen_socket_t* get() const; private: - std::weak_ptr m_sock; + std::weak_ptr m_sock; }; } } diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 0a1be877e..c69830a0f 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -48,6 +48,7 @@ POSSIBILITY OF SUCH DAMAGE. #endif #include "libtorrent/session.hpp" // for user_load_function_t +#include "libtorrent/ip_voter.hpp" #include "libtorrent/entry.hpp" #include "libtorrent/socket.hpp" #include "libtorrent/peer_id.hpp" @@ -132,7 +133,7 @@ namespace aux { TORRENT_EXTRA_EXPORT entry save_dht_settings(dht_settings const& settings); #endif - struct listen_socket_t : listen_socket_base + struct listen_socket_t { listen_socket_t() { @@ -142,11 +143,23 @@ namespace aux { udp_port_mapping[1] = -1; } + // listen_socket_t should not be copied or moved because + // references to it are held by the DHT and tracker announce + // code. That code expects a listen_socket_t to always refer + // to the same socket. It would be easy to accidently + // invalidate that assumption if copying or moving were allowed. listen_socket_t(listen_socket_t const&) = delete; listen_socket_t(listen_socket_t&&) = delete; listen_socket_t& operator=(listen_socket_t const&) = delete; listen_socket_t& operator=(listen_socket_t&&) = delete; + // this may be empty but can be set + // to the WAN IP address of a NAT router + ip_voter external_address; + + // this is a cached local endpoint for the listen TCP socket + tcp::endpoint local_endpoint; + // the name of the device the socket is bound to, may be empty // if the socket is not bound to a device std::string device; @@ -170,6 +183,9 @@ namespace aux { int tcp_port_mapping[2]; int udp_port_mapping[2]; + // indicates whether this is an SSL listen socket or not + transport ssl = transport::plaintext; + // the actual sockets (TCP listen socket and UDP socket) // An entry does not necessarily have a UDP or TCP socket. One of these // pointers may be nullptr! @@ -1087,7 +1103,7 @@ namespace aux { , error_code& ec , int flags) { - auto s = static_cast(sock.impl()); + listen_socket_t* s = sock.get(); if (!s) { ec = boost::asio::error::bad_descriptor; @@ -1108,7 +1124,7 @@ namespace aux { , error_code& ec , int flags) { - auto s = static_cast(sock.impl()); + listen_socket_t* s = sock.get(); if (!s) { ec = boost::asio::error::bad_descriptor; diff --git a/simulation/setup_dht.cpp b/simulation/setup_dht.cpp index 62dc390bd..c9f26105b 100644 --- a/simulation/setup_dht.cpp +++ b/simulation/setup_dht.cpp @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/time.hpp" #include "libtorrent/kademlia/node.hpp" #include "libtorrent/kademlia/dht_observer.hpp" +#include "libtorrent/aux_/session_impl.hpp" #include "setup_transfer.hpp" #include // for unique_ptr #include @@ -76,9 +77,9 @@ namespace { return dht::generate_id(addr); } - std::shared_ptr sim_listen_socket(tcp::endpoint ep) + std::shared_ptr sim_listen_socket(tcp::endpoint ep) { - auto ls = std::make_shared(); + auto ls = std::make_shared(); ls->external_address.cast_vote(ep.address(), 1, lt::address()); ls->local_endpoint = ep; return ls; @@ -241,7 +242,7 @@ private: bool const m_ipv6; lt::udp::socket m_socket; lt::udp::socket& sock() { return m_socket; } - std::shared_ptr m_ls; + std::shared_ptr m_ls; lt::dht::node m_dht; lt::udp::endpoint m_ep; char m_buffer[1300]; diff --git a/simulation/test_dht_rate_limit.cpp b/simulation/test_dht_rate_limit.cpp index 6b5c1f239..8fc51356e 100644 --- a/simulation/test_dht_rate_limit.cpp +++ b/simulation/test_dht_rate_limit.cpp @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "simulator/simulator.hpp" #include "libtorrent/aux_/listen_socket_handle.hpp" +#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/udp_socket.hpp" #include "libtorrent/kademlia/dht_tracker.hpp" #include "libtorrent/kademlia/dht_state.hpp" @@ -103,7 +104,7 @@ TORRENT_TEST(dht_rate_limit) // receiver (the DHT under test) lt::udp_socket sock(dht_ios); obs o; - auto ls = std::make_shared(); + auto ls = std::make_shared(); ls->external_address.cast_vote(address_v4::from_string("40.30.20.10"), 1, lt::address()); ls->local_endpoint = tcp::endpoint(address_v4::from_string("40.30.20.10"), 8888); error_code ec; @@ -231,7 +232,7 @@ TORRENT_TEST(dht_delete_socket) sock.bind(udp::endpoint(address_v4::from_string("40.30.20.10"), 8888), ec); obs o; - auto ls = std::make_shared(); + auto ls = std::make_shared(); ls->external_address.cast_vote(address_v4::from_string("40.30.20.10"), 1, lt::address()); ls->local_endpoint = tcp::endpoint(address_v4::from_string("40.30.20.10"), 8888); dht_settings dhtsett; diff --git a/src/error_code.cpp b/src/error_code.cpp index a0899c05e..f39bc42ef 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -169,7 +169,7 @@ namespace libtorrent { "not an SSL torrent", "banned by port filter", "invalid session handle used", - "", + "listen socket has been closed", "", "", "", diff --git a/src/listen_socket_handle.cpp b/src/listen_socket_handle.cpp index 51c29f6c1..0309caace 100644 --- a/src/listen_socket_handle.cpp +++ b/src/listen_socket_handle.cpp @@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "libtorrent/aux_/listen_socket_handle.hpp" +#include "libtorrent/aux_/session_impl.hpp" namespace libtorrent { namespace aux { @@ -58,7 +59,7 @@ namespace libtorrent { namespace aux { return s->ssl == transport::ssl; } - listen_socket_base* listen_socket_handle::impl() const + listen_socket_t* listen_socket_handle::get() const { return m_sock.lock().get(); } diff --git a/src/session_impl.cpp b/src/session_impl.cpp index bd5df4fbe..afd2d0738 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1212,7 +1212,7 @@ namespace { if (req.outgoing_socket) { - auto ls = static_cast(req.outgoing_socket.impl()); + auto ls = req.outgoing_socket.get(); req.listen_port = listen_port(ls); #ifdef TORRENT_USE_OPENSSL // SSL torrents use the SSL listen port @@ -1229,7 +1229,7 @@ namespace { // SSL torrents use the SSL listen port if (use_ssl) req.listen_port = ssl_listen_port(ls.get()); #endif - req.outgoing_socket = listen_socket_handle(ls); + req.outgoing_socket = ls; m_tracker_manager.queue_request(get_io_service(), req, c); } } @@ -1954,7 +1954,7 @@ namespace { { #ifndef TORRENT_DISABLE_DHT if (m_dht) - m_dht->delete_socket(listen_socket_handle(*remove_iter)); + m_dht->delete_socket(*remove_iter); #endif #ifndef TORRENT_DISABLE_LOGGING @@ -1984,7 +1984,7 @@ namespace { #ifndef TORRENT_DISABLE_DHT if (m_dht) - m_dht->new_socket(listen_socket_handle(m_listen_sockets.back())); + m_dht->new_socket(m_listen_sockets.back()); #endif } } @@ -5690,7 +5690,7 @@ namespace { , std::move(m_dht_state)); for (auto& s : m_listen_sockets) - m_dht->new_socket(listen_socket_handle(s)); + m_dht->new_socket(s); for (auto const& n : m_dht_router_nodes) { @@ -6862,7 +6862,7 @@ namespace { // restart the DHT with a new node ID #ifndef TORRENT_DISABLE_DHT - if (m_dht) m_dht->update_node_id(listen_socket_handle(sock)); + if (m_dht) m_dht->update_node_id(sock); #endif } diff --git a/test/test_dht.cpp b/test/test_dht.cpp index 5659bdaa9..a34b0b179 100644 --- a/test/test_dht.cpp +++ b/test/test_dht.cpp @@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/hasher.hpp" #include "libtorrent/aux_/time.hpp" #include "libtorrent/aux_/listen_socket_handle.hpp" +#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/kademlia/node_id.hpp" #include "libtorrent/kademlia/routing_table.hpp" @@ -123,26 +124,26 @@ struct mock_socket final : socket_manager } }; -std::shared_ptr dummy_listen_socket(udp::endpoint src) +std::shared_ptr dummy_listen_socket(udp::endpoint src) { - auto ret = std::make_shared(); + auto ret = std::make_shared(); ret->local_endpoint = tcp::endpoint(src.address(), src.port()); ret->external_address.cast_vote(src.address(), 1, rand_v4()); return ret; } -std::shared_ptr dummy_listen_socket4() +std::shared_ptr dummy_listen_socket4() { - auto ret = std::make_shared(); + auto ret = std::make_shared(); ret->local_endpoint = tcp::endpoint(addr4("192.168.4.1"), 6881); ret->external_address.cast_vote(addr4("236.0.0.1"), 1, rand_v4()); return ret; } #if TORRENT_USE_IPV6 -std::shared_ptr dummy_listen_socket6() +std::shared_ptr dummy_listen_socket6() { - auto ret = std::make_shared(); + auto ret = std::make_shared(); ret->local_endpoint = tcp::endpoint(addr6("2002::1"), 6881); ret->external_address.cast_vote(addr6("2002::1"), 1, rand_v6()); return ret; @@ -518,7 +519,7 @@ struct obs : dht::dht_observer void set_external_address(aux::listen_socket_handle const& s, address const& addr , address const& source) override { - s.impl()->external_address.cast_vote(addr, 1, rand_v4()); + s.get()->external_address.cast_vote(addr, 1, rand_v4()); } void get_peers(sha1_hash const& ih) override {} @@ -572,7 +573,7 @@ struct dht_test_setup dht_settings sett; mock_socket s; - std::shared_ptr ls; + std::shared_ptr ls; obs observer; counters cnt; std::unique_ptr dht_storage;