diff options
Diffstat (limited to 'libtorrent/src/broadcast_socket.cpp')
-rw-r--r-- | libtorrent/src/broadcast_socket.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/libtorrent/src/broadcast_socket.cpp b/libtorrent/src/broadcast_socket.cpp index 16f0a0728..c7b7e71c8 100644 --- a/libtorrent/src/broadcast_socket.cpp +++ b/libtorrent/src/broadcast_socket.cpp @@ -99,6 +99,44 @@ namespace libtorrent return ret; } + // count the length of the common bit prefix + int common_bits(unsigned char const* b1 + , unsigned char const* b2, int n) + { + for (int i = 0; i < n; ++i, ++b1, ++b2) + { + unsigned char a = *b1 ^ *b2; + if (a == 0) continue; + int ret = i * 8 + 8; + for (; a > 0; a >>= 1) --ret; + return ret; + } + return n * 8; + } + + // returns the number of bits in that differ from the right + // between the addresses. + int cidr_distance(address const& a1, address const& a2) + { + if (a1.is_v4() == a2.is_v4()) + { + // 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()); + } + + address_v6::bytes_type b1; + address_v6::bytes_type b2; + if (a1.is_v4()) b1 = address_v6::v4_mapped(a1.to_v4()).to_bytes(); + else b1 = a1.to_v6().to_bytes(); + if (a2.is_v4()) b2 = address_v6::v4_mapped(a2.to_v4()).to_bytes(); + 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()); + } + broadcast_socket::broadcast_socket(asio::io_service& ios , udp::endpoint const& multicast_endpoint , receive_handler_t const& handler |