From bbfe58d03ce35fccb35ecca39aac51d1580500cd Mon Sep 17 00:00:00 2001 From: arvidn Date: Sat, 10 Dec 2016 14:31:09 -0500 Subject: [PATCH] fix bind-to-device for UDP sockets --- include/libtorrent/aux_/session_impl.hpp | 5 ++--- include/libtorrent/udp_socket.hpp | 1 + src/session_impl.cpp | 25 +++++++++++++++++++++--- src/udp_socket.cpp | 18 ++++++++--------- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index b27e390c1..22c9618c9 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -579,10 +579,9 @@ namespace libtorrent bool is_dht_running() const { return (m_dht.get() != nullptr); } int external_udp_port() const override { - for (std::list::const_iterator i = m_listen_sockets.begin() - , end(m_listen_sockets.end()); i != end; ++i) + for (auto const& s : m_listen_sockets) { - if (i->udp_sock) return i->udp_external_port; + if (s.udp_sock) return s.udp_external_port; } return -1; } diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp index cf2c251de..7e2d1f1fe 100644 --- a/include/libtorrent/udp_socket.hpp +++ b/include/libtorrent/udp_socket.hpp @@ -89,6 +89,7 @@ namespace libtorrent void send(udp::endpoint const& ep, span p , error_code& ec, int flags = 0); + void open(udp const& protocol, error_code& ec); void bind(udp::endpoint const& ep, error_code& ec); void close(); int local_port() const { return m_bind_port; } diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 0b43ef17d..8480af08c 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1635,8 +1635,28 @@ namespace aux { = (flags & open_ssl_socket) ? socket_type_t::utp_ssl : socket_type_t::udp; + udp::endpoint const udp_bind_ep(bind_ep.address(), bind_ep.port()); ret.udp_sock = std::make_shared(m_io_service); + ret.udp_sock->open(udp_bind_ep.protocol(), ec); + if (ec) + { +#ifndef TORRENT_DISABLE_LOGGING + if (should_log()) + { + session_log("failed to open UDP socket: %s: %s" + , device.c_str(), ec.message().c_str()); + } +#endif + + last_op = listen_failed_alert::open; + if (m_alerts.should_post()) + m_alerts.emplace_alert(device + , bind_ep, last_op, ec, udp_sock_type); + + return ret; + } + #if TORRENT_HAS_BINDTODEVICE if (!device.empty()) { @@ -1661,8 +1681,7 @@ namespace aux { } } #endif - ret.udp_sock->bind(udp::endpoint(bind_ep.address(), bind_ep.port()) - , ec); + ret.udp_sock->bind(udp_bind_ep, ec); last_op = listen_failed_alert::bind; if (ec) @@ -1670,7 +1689,7 @@ namespace aux { #ifndef TORRENT_DISABLE_LOGGING if (should_log()) { - session_log("failed to open UDP socket: %s: %s" + session_log("failed to bind UDP socket: %s: %s" , device.c_str(), ec.message().c_str()); } #endif diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index 27ebdd62e..d453b21eb 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -404,7 +404,7 @@ void udp_socket::close() m_abort = true; } -void udp_socket::bind(udp::endpoint const& ep, error_code& ec) +void udp_socket::open(udp const& protocol, error_code& ec) { TORRENT_ASSERT(is_single_thread()); @@ -413,16 +413,11 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec) if (m_socket.is_open()) m_socket.close(ec); ec.clear(); - if (ep.address().is_v4()) - { - m_socket.open(udp::v4(), ec); - if (ec) return; - } + m_socket.open(protocol, ec); + if (ec) return; #if TORRENT_USE_IPV6 - else if (ep.address().is_v6()) + if (protocol == udp::v6()) { - m_socket.open(udp::v6(), ec); - if (ec) return; error_code err; m_socket.set_option(boost::asio::ip::v6_only(true), err); @@ -439,7 +434,12 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec) m_socket.set_option(exclusive_address_use(true), err); #endif m_socket.set_option(boost::asio::socket_base::reuse_address(true), err); +} +void udp_socket::bind(udp::endpoint const& ep, error_code& ec) +{ + if (!m_socket.is_open()) open(ep.protocol(), ec); + if (ec) return; m_socket.bind(ep, ec); if (ec) return; udp::socket::non_blocking_io ioc(true);