From c929f4fb69dce92e4294680baa0671d1c5953da6 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 23 Nov 2007 22:14:33 +0000 Subject: [PATCH] fix for systems where IPv6 sockets bound to INADDR_ANY also listens on IPv4 connections --- include/libtorrent/aux_/session_impl.hpp | 2 +- include/libtorrent/socket.hpp | 15 +++++++++++++++ src/session_impl.cpp | 6 ++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 090196a4f..95089b649 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -473,7 +473,7 @@ namespace libtorrent // we might need more than one listen socket std::list m_listen_sockets; - listen_socket_t setup_listener(tcp::endpoint ep, int retries); + listen_socket_t setup_listener(tcp::endpoint ep, int retries, bool v6_only = false); // the settings for the client session_settings m_settings; diff --git a/include/libtorrent/socket.hpp b/include/libtorrent/socket.hpp index 514be256c..499842dd7 100755 --- a/include/libtorrent/socket.hpp +++ b/include/libtorrent/socket.hpp @@ -171,6 +171,21 @@ namespace libtorrent return Endpoint(addr, port); } } + + struct v6only + { + v6only(bool enable): m_value(enable) {} + template + int level(Protocol const&) const { return IPPROTO_IPV6; } + template + int name(Protocol const&) const { return IPV6_V6ONLY; } + template + int const* data(Protocol const&) const { return &m_value; } + template + size_t size(Protocol const&) const { return sizeof(m_value); } + int m_value; + }; + } #endif // TORRENT_SOCKET_HPP_INCLUDED diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 3c8625fef..69f2c1bc1 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -814,13 +814,15 @@ namespace detail return m_ipv6_interface; } - session_impl::listen_socket_t session_impl::setup_listener(tcp::endpoint ep, int retries) + session_impl::listen_socket_t session_impl::setup_listener(tcp::endpoint ep + , int retries, bool v6_only) { asio::error_code ec; listen_socket_t s; s.sock.reset(new socket_acceptor(m_io_service)); s.sock->open(ep.protocol(), ec); s.sock->set_option(socket_acceptor::reuse_address(true), ec); + if (ep.protocol() == tcp::v6()) s.sock->set_option(v6only(v6_only), ec); s.sock->bind(ep, ec); while (ec && retries > 0) { @@ -913,7 +915,7 @@ namespace detail s = setup_listener( tcp::endpoint(address_v6::any(), m_listen_interface.port()) - , m_listen_port_retries); + , m_listen_port_retries, true); if (s.sock) {