From 189d618261ff6dc94b31a9e806d40b1f5b0f85b4 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 13 Apr 2009 05:11:44 +0000 Subject: [PATCH] improved IPv6 support (skips unsupported tests on windows) --- include/libtorrent/broadcast_socket.hpp | 3 +++ src/broadcast_socket.cpp | 31 ++++++++++++++++++++++++- src/session_impl.cpp | 26 +++++++-------------- test/test_primitives.cpp | 3 ++- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/include/libtorrent/broadcast_socket.hpp b/include/libtorrent/broadcast_socket.hpp index ad0be1299..00b246fdc 100644 --- a/include/libtorrent/broadcast_socket.hpp +++ b/include/libtorrent/broadcast_socket.hpp @@ -48,6 +48,9 @@ namespace libtorrent TORRENT_EXPORT bool is_any(address const& addr); TORRENT_EXPORT int cidr_distance(address const& a1, address const& a2); + // determines if the operating system supports IPv6 + TORRENT_EXPORT bool supports_ipv6(); + int common_bits(unsigned char const* b1 , unsigned char const* b2, int n); diff --git a/src/broadcast_socket.cpp b/src/broadcast_socket.cpp index 6e496c353..c1f90d5fe 100644 --- a/src/broadcast_socket.cpp +++ b/src/broadcast_socket.cpp @@ -51,7 +51,9 @@ namespace libtorrent { bool is_local(address const& a) { +#if TORRENT_USE_IPV6 if (a.is_v6()) return a.to_v6().is_link_local(); +#endif address_v4 a4 = a.to_v4(); unsigned long ip = a4.to_ulong(); return ((ip & 0xff000000) == 0x0a000000 @@ -61,28 +63,51 @@ namespace libtorrent bool is_loopback(address const& addr) { +#if TORRENT_USE_IPV6 if (addr.is_v4()) - return addr.to_v4() == address_v4::loopback(); + return addr.to_v4() == address_v4::loopback(); else return addr.to_v6() == address_v6::loopback(); +#else + return addr.to_v4() == address_v4::loopback(); +#endif } bool is_multicast(address const& addr) { +#if TORRENT_USE_IPV6 if (addr.is_v4()) return addr.to_v4().is_multicast(); else return addr.to_v6().is_multicast(); +#else + return addr.to_v4().is_multicast(); +#endif } bool is_any(address const& addr) { +#if TORRENT_USE_IPV6 if (addr.is_v4()) return addr.to_v4() == address_v4::any(); else if (addr.to_v6().is_v4_mapped()) return (addr.to_v6().to_v4() == address_v4::any()); else return addr.to_v6() == address_v6::any(); +#else + return addr.to_v4() == address_v4::any(); +#endif + } + + bool supports_ipv6() + { +#if TORRENT_USE_IPV6 + error_code ec; + address::from_string("::1", ec); + return !ec; +#else + return false; +#endif } address guess_local_address(io_service& ios) @@ -128,13 +153,16 @@ namespace libtorrent // between the addresses. int cidr_distance(address const& a1, address const& a2) { +#if TORRENT_USE_IPV6 if (a1.is_v4() && a2.is_v4()) { +#endif // both are v4 address_v4::bytes_type b1 = a1.to_v4().to_bytes(); address_v4::bytes_type b2 = a2.to_v4().to_bytes(); return address_v4::bytes_type::static_size * 8 - common_bits(b1.c_array(), b2.c_array(), b1.size()); +#if TORRENT_USE_IPV6 } address_v6::bytes_type b1; @@ -145,6 +173,7 @@ namespace libtorrent else b2 = a2.to_v6().to_bytes(); return address_v6::bytes_type::static_size * 8 - common_bits(b1.c_array(), b2.c_array(), b1.size()); +#endif } broadcast_socket::broadcast_socket(io_service& ios diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 70a04db6f..7aab5b11e 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -737,27 +737,19 @@ namespace aux { } #if TORRENT_USE_IPV6 -#ifdef TORRENT_WINDOWS // only try to open the IPv6 port if IPv6 is installed - SOCKADDR_STORAGE storage; - int len = sizeof(storage); - if (WSAStringToAddressA("::1", AF_INET6, 0, - (sockaddr*)&storage, &len) != SOCKET_ERROR) + if (supports_ipv6()) { -#endif + s = setup_listener( + tcp::endpoint(address_v6::any(), m_listen_interface.port()) + , m_listen_port_retries, true); - s = setup_listener( - tcp::endpoint(address_v6::any(), m_listen_interface.port()) - , m_listen_port_retries, true); - - if (s.sock) - { - m_listen_sockets.push_back(s); - async_accept(s.sock); + if (s.sock) + { + m_listen_sockets.push_back(s); + async_accept(s.sock); + } } -#ifdef TORRENT_WINDOWS - } -#endif #endif // TORRENT_USE_IPV6 // set our main IPv4 and IPv6 interfaces diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index 52620bdce..dc4e4e5bb 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -652,7 +652,8 @@ int test_main() TEST_CHECK(is_local(address::from_string("10.1.1.56", ec))); TEST_CHECK(!is_local(address::from_string("14.14.251.63", ec))); TEST_CHECK(is_loopback(address::from_string("127.0.0.1", ec))); - TEST_CHECK(is_loopback(address::from_string("::1", ec))); + if (supports_ipv6()) + TEST_CHECK(is_loopback(address::from_string("::1", ec))); TEST_CHECK(is_any(address_v6::any())); TEST_CHECK(is_any(address_v4::any())); TEST_CHECK(!is_any(address::from_string("31.53.21.64", ec)));