fix for systems where IPv6 sockets bound to INADDR_ANY also listens on IPv4 connections

This commit is contained in:
Arvid Norberg 2007-11-23 22:14:33 +00:00
parent 88e69d0edc
commit c929f4fb69
3 changed files with 20 additions and 3 deletions

View File

@ -473,7 +473,7 @@ namespace libtorrent
// we might need more than one listen socket // we might need more than one listen socket
std::list<listen_socket_t> m_listen_sockets; std::list<listen_socket_t> 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 // the settings for the client
session_settings m_settings; session_settings m_settings;

View File

@ -171,6 +171,21 @@ namespace libtorrent
return Endpoint(addr, port); return Endpoint(addr, port);
} }
} }
struct v6only
{
v6only(bool enable): m_value(enable) {}
template<class Protocol>
int level(Protocol const&) const { return IPPROTO_IPV6; }
template<class Protocol>
int name(Protocol const&) const { return IPV6_V6ONLY; }
template<class Protocol>
int const* data(Protocol const&) const { return &m_value; }
template<class Protocol>
size_t size(Protocol const&) const { return sizeof(m_value); }
int m_value;
};
} }
#endif // TORRENT_SOCKET_HPP_INCLUDED #endif // TORRENT_SOCKET_HPP_INCLUDED

View File

@ -814,13 +814,15 @@ namespace detail
return m_ipv6_interface; 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; asio::error_code ec;
listen_socket_t s; listen_socket_t s;
s.sock.reset(new socket_acceptor(m_io_service)); s.sock.reset(new socket_acceptor(m_io_service));
s.sock->open(ep.protocol(), ec); s.sock->open(ep.protocol(), ec);
s.sock->set_option(socket_acceptor::reuse_address(true), 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); s.sock->bind(ep, ec);
while (ec && retries > 0) while (ec && retries > 0)
{ {
@ -913,7 +915,7 @@ namespace detail
s = setup_listener( s = setup_listener(
tcp::endpoint(address_v6::any(), m_listen_interface.port()) tcp::endpoint(address_v6::any(), m_listen_interface.port())
, m_listen_port_retries); , m_listen_port_retries, true);
if (s.sock) if (s.sock)
{ {