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)
|
* almost completely changed the storage interface (for custom storage)
|
||||||
* added support for hashing pieces in multiple threads
|
* added support for hashing pieces in multiple threads
|
||||||
|
|
||||||
|
* improve reliability of binding listen sockets
|
||||||
* support SNI in https web seeds and trackers
|
* support SNI in https web seeds and trackers
|
||||||
* fix unhandled exception in DHT when receiving a DHT packet over IPv6
|
* 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); }
|
size_t size(Protocol const&) const { return sizeof(m_value); }
|
||||||
int 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
|
#ifdef IPV6_TCLASS
|
||||||
struct traffic_class
|
struct traffic_class
|
||||||
|
|
|
@ -1708,16 +1708,14 @@ namespace aux {
|
||||||
return ret;
|
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);
|
ret.sock->set_option(tcp::acceptor::reuse_address(true), err);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if TORRENT_USE_IPV6
|
#if TORRENT_USE_IPV6
|
||||||
if (!ipv4)
|
if (!ipv4)
|
||||||
|
@ -1726,6 +1724,7 @@ namespace aux {
|
||||||
#ifdef IPV6_V6ONLY
|
#ifdef IPV6_V6ONLY
|
||||||
ret.sock->set_option(v6only(true), err);
|
ret.sock->set_option(v6only(true), err);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TORRENT_WINDOWS
|
#ifdef TORRENT_WINDOWS
|
||||||
|
|
||||||
#ifndef PROTECTION_LEVEL_UNRESTRICTED
|
#ifndef PROTECTION_LEVEL_UNRESTRICTED
|
||||||
|
@ -1733,7 +1732,7 @@ namespace aux {
|
||||||
#endif
|
#endif
|
||||||
// enable Teredo on windows
|
// enable Teredo on windows
|
||||||
ret.sock->set_option(v6_protection_level(PROTECTION_LEVEL_UNRESTRICTED), err);
|
ret.sock->set_option(v6_protection_level(PROTECTION_LEVEL_UNRESTRICTED), err);
|
||||||
#endif
|
#endif // TORRENT_WINDOWS
|
||||||
}
|
}
|
||||||
#endif // TORRENT_USE_IPV6
|
#endif // TORRENT_USE_IPV6
|
||||||
|
|
||||||
|
@ -4893,6 +4892,9 @@ retry:
|
||||||
tcp::endpoint bind_ep(address_v4(), 0);
|
tcp::endpoint bind_ep(address_v4(), 0);
|
||||||
if (m_settings.get_int(settings_pack::outgoing_port) > 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);
|
s.set_option(tcp::acceptor::reuse_address(true), ec);
|
||||||
// ignore errors because the underlying socket may not
|
// ignore errors because the underlying socket may not
|
||||||
// be opened yet. This happens when we're routing through
|
// 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);
|
m_ipv4_sock.open(udp::v4(), ec);
|
||||||
if (ec) return;
|
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);
|
m_ipv4_sock.bind(ep, ec);
|
||||||
if (ec) return;
|
if (ec) return;
|
||||||
udp::socket::non_blocking_io ioc(true);
|
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());
|
if (is_any(ep.address())) ep6.address(address_v6::any());
|
||||||
m_ipv6_sock.open(udp::v6(), ec);
|
m_ipv6_sock.open(udp::v6(), ec);
|
||||||
if (ec) return;
|
if (ec) return;
|
||||||
#ifdef IPV6_V6ONLY
|
|
||||||
m_ipv6_sock.set_option(v6only(true), ec);
|
// this is best-effort. ignore errors
|
||||||
ec.clear();
|
error_code err;
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
m_ipv4_sock.set_option(exclusive_address_use(true), err);
|
||||||
#endif
|
#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);
|
m_ipv6_sock.bind(ep6, ec);
|
||||||
if (ec != error_code(boost::system::errc::address_not_available
|
if (ec != error_code(boost::system::errc::address_not_available
|
||||||
, boost::system::generic_category()))
|
, boost::system::generic_category()))
|
||||||
|
|
Loading…
Reference in New Issue