forward-port reuse address patch for windows
This commit is contained in:
parent
07d7d72a58
commit
e584c30b29
|
@ -84,6 +84,7 @@
|
|||
* almost completely changed the storage interface (for custom storage)
|
||||
* added support for hashing pieces in multiple threads
|
||||
|
||||
* improve reliability of binding listen sockets
|
||||
* support SNI in https web seeds and trackers
|
||||
* fix unhandled exception in DHT when receiving a DHT packet over IPv6
|
||||
|
||||
|
|
|
@ -120,7 +120,21 @@ namespace libtorrent
|
|||
size_t size(Protocol const&) const { return sizeof(m_value); }
|
||||
int m_value;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct exclusive_address_use
|
||||
{
|
||||
exclusive_address_use(int enable): m_value(enable) {}
|
||||
template<class Protocol>
|
||||
int level(Protocol const&) const { return SOL_SOCKET; }
|
||||
template<class Protocol>
|
||||
int name(Protocol const&) const { return SO_EXCLUSIVEADDRUSE; }
|
||||
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_WINDOWS
|
||||
|
||||
#ifdef IPV6_TCLASS
|
||||
struct traffic_class
|
||||
|
|
|
@ -1708,16 +1708,14 @@ namespace aux {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// SO_REUSEADDR on windows is a bit special. It actually allows
|
||||
// two active sockets to bind to the same port. That means we
|
||||
// may end up binding to the same socket as some other random
|
||||
// application. Don't do it!
|
||||
#ifndef TORRENT_WINDOWS
|
||||
{
|
||||
error_code err; // ignore errors here
|
||||
// this is best-effort. ignore errors
|
||||
error_code err;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
ret.sock->set_option(exclusive_address_use(true), err);
|
||||
#endif
|
||||
ret.sock->set_option(tcp::acceptor::reuse_address(true), err);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
if (!ipv4)
|
||||
|
@ -1726,6 +1724,7 @@ namespace aux {
|
|||
#ifdef IPV6_V6ONLY
|
||||
ret.sock->set_option(v6only(true), err);
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_WINDOWS
|
||||
|
||||
#ifndef PROTECTION_LEVEL_UNRESTRICTED
|
||||
|
@ -1733,7 +1732,7 @@ namespace aux {
|
|||
#endif
|
||||
// enable Teredo on windows
|
||||
ret.sock->set_option(v6_protection_level(PROTECTION_LEVEL_UNRESTRICTED), err);
|
||||
#endif
|
||||
#endif // TORRENT_WINDOWS
|
||||
}
|
||||
#endif // TORRENT_USE_IPV6
|
||||
|
||||
|
@ -4893,6 +4892,9 @@ retry:
|
|||
tcp::endpoint bind_ep(address_v4(), 0);
|
||||
if (m_settings.get_int(settings_pack::outgoing_port) > 0)
|
||||
{
|
||||
#ifdef TORRENT_WINDOWS
|
||||
s.set_option(exclusive_address_use(true), ec);
|
||||
#endif
|
||||
s.set_option(tcp::acceptor::reuse_address(true), ec);
|
||||
// ignore errors because the underlying socket may not
|
||||
// be opened yet. This happens when we're routing through
|
||||
|
|
|
@ -789,6 +789,14 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
|||
{
|
||||
m_ipv4_sock.open(udp::v4(), ec);
|
||||
if (ec) return;
|
||||
|
||||
// this is best-effort. ignore errors
|
||||
error_code err;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
m_ipv4_sock.set_option(exclusive_address_use(true), err);
|
||||
#endif
|
||||
m_ipv4_sock.set_option(boost::asio::socket_base::reuse_address(true), err);
|
||||
|
||||
m_ipv4_sock.bind(ep, ec);
|
||||
if (ec) return;
|
||||
udp::socket::non_blocking_io ioc(true);
|
||||
|
@ -807,10 +815,17 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
|||
if (is_any(ep.address())) ep6.address(address_v6::any());
|
||||
m_ipv6_sock.open(udp::v6(), ec);
|
||||
if (ec) return;
|
||||
#ifdef IPV6_V6ONLY
|
||||
m_ipv6_sock.set_option(v6only(true), ec);
|
||||
ec.clear();
|
||||
|
||||
// this is best-effort. ignore errors
|
||||
error_code err;
|
||||
#ifdef TORRENT_WINDOWS
|
||||
m_ipv4_sock.set_option(exclusive_address_use(true), err);
|
||||
#endif
|
||||
m_ipv4_sock.set_option(boost::asio::socket_base::reuse_address(true), err);
|
||||
#ifdef IPV6_V6ONLY
|
||||
m_ipv6_sock.set_option(v6only(true), err);
|
||||
#endif
|
||||
|
||||
m_ipv6_sock.bind(ep6, ec);
|
||||
if (ec != error_code(boost::system::errc::address_not_available
|
||||
, boost::system::generic_category()))
|
||||
|
|
Loading…
Reference in New Issue