summaryrefslogtreecommitdiffstats
path: root/libtorrent/src/broadcast_socket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libtorrent/src/broadcast_socket.cpp')
-rw-r--r--libtorrent/src/broadcast_socket.cpp38
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