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
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
session_settings m_settings;

View File

@ -171,6 +171,21 @@ namespace libtorrent
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

View File

@ -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)
{