diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index b6c464480..36b440ac2 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -593,7 +593,11 @@ namespace aux { std::uint16_t ssl_listen_port() const override; std::uint16_t ssl_listen_port(listen_socket_t* sock) const; + // used by the DHT tracker, returns a UDP listen port int get_listen_port(transport ssl, aux::listen_socket_handle const& s) override; + // used by peer connections, returns a TCP listen port + // or zero if no matching listen socket is found + int listen_port(transport ssl, address const& local_addr) override; std::uint32_t get_tracker_key(address const& iface) const; diff --git a/include/libtorrent/aux_/session_interface.hpp b/include/libtorrent/aux_/session_interface.hpp index edd4948ad..2a62702e4 100644 --- a/include/libtorrent/aux_/session_interface.hpp +++ b/include/libtorrent/aux_/session_interface.hpp @@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/socket.hpp" // for tcp::endpoint #include "libtorrent/aux_/vector.hpp" #include "libtorrent/aux_/listen_socket_handle.hpp" +#include "libtorrent/aux_/session_udp_sockets.hpp" // for transport #include "libtorrent/session_types.hpp" #include "libtorrent/flags.hpp" #include "libtorrent/link.hpp" // for torrent_list_index_t @@ -201,6 +202,8 @@ namespace aux { virtual std::uint16_t listen_port() const = 0; virtual std::uint16_t ssl_listen_port() const = 0; + virtual int listen_port(aux::transport ssl, address const& local_addr) = 0; + virtual void for_each_listen_socket(std::function f) = 0; // ask for which interface and port to bind outgoing peer connections on diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index b39eb251d..28137db84 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -2084,11 +2084,18 @@ namespace { entry handshake; entry::dictionary_type& m = handshake["m"].dict(); + std::shared_ptr t = associated_torrent().lock(); + TORRENT_ASSERT(t); + // if we're using a proxy, our listen port won't be useful // anyway. - auto const port = m_ses.listen_port(); - if (port != 0 && is_outgoing()) - handshake["p"] = port; + if (is_outgoing()) + { + auto const port = m_ses.listen_port( + t->is_ssl_torrent() ? aux::transport::ssl : aux::transport::plaintext + , local_endpoint().address()); + if (port != 0) handshake["p"] = port; + } // only send the port in case we bade the connection // on incoming connections the other end already knows @@ -2108,8 +2115,6 @@ namespace { #endif handshake["yourip"] = remote_address; handshake["reqq"] = m_settings.get_int(settings_pack::max_allowed_in_request_queue); - std::shared_ptr t = associated_torrent().lock(); - TORRENT_ASSERT(t); m["upload_only"] = upload_only_msg; m["ut_holepunch"] = holepunch_msg; diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 76cea3d94..3bf3c5677 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -5456,6 +5456,21 @@ namespace aux { return socket->udp_external_port; } + int session_impl::listen_port(transport const ssl, address const& local_addr) + { + auto socket = std::find_if(m_listen_sockets.begin(), m_listen_sockets.end() + , [&](std::shared_ptr const& e) + { + auto const& listen_addr = e->external_address.external_address(); + return e->ssl == ssl + && (listen_addr == local_addr + || (listen_addr.is_v4() == local_addr.is_v4() && listen_addr.is_unspecified())); + }); + if (socket != m_listen_sockets.end()) + return (*socket)->tcp_external_port; + return 0; + } + void session_impl::announce_lsd(sha1_hash const& ih, int port, bool broadcast) { // use internal listen port for local peers