set port in handshake based on source address (#3172)

This commit is contained in:
Steven Siloti 2018-07-15 12:15:04 -07:00 committed by Arvid Norberg
parent 52af3eaa7f
commit e5be30157f
4 changed files with 32 additions and 5 deletions

View File

@ -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;

View File

@ -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<void(aux::listen_socket_handle const&)> f) = 0;
// ask for which interface and port to bind outgoing peer connections on

View File

@ -2084,11 +2084,18 @@ namespace {
entry handshake;
entry::dictionary_type& m = handshake["m"].dict();
std::shared_ptr<torrent> 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<torrent> t = associated_torrent().lock();
TORRENT_ASSERT(t);
m["upload_only"] = upload_only_msg;
m["ut_holepunch"] = holepunch_msg;

View File

@ -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<listen_socket_t> 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