From bd1ef5397cf303c05c5b9ae65d99d99368a0e727 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 17 Feb 2011 06:47:26 +0000 Subject: [PATCH] clean up broadcasting --- include/libtorrent/broadcast_socket.hpp | 24 ++++++++------- src/broadcast_socket.cpp | 40 +++++++++++-------------- src/lsd.cpp | 5 +--- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/include/libtorrent/broadcast_socket.hpp b/include/libtorrent/broadcast_socket.hpp index f560357a9..ebcb28968 100644 --- a/include/libtorrent/broadcast_socket.hpp +++ b/include/libtorrent/broadcast_socket.hpp @@ -70,7 +70,9 @@ namespace libtorrent , receive_handler_t const& handler, bool loopback = true); ~broadcast_socket() { close(); } - void send(char const* buffer, int size, error_code& ec); + enum flags_t { broadcast = 1 }; + void send(char const* buffer, int size, error_code& ec, int flags = 0); + void close(); int num_send_sockets() const { return m_unicast_sockets.size(); } void enable_ip_broadcast(bool e); @@ -80,19 +82,27 @@ namespace libtorrent struct socket_entry { socket_entry(boost::shared_ptr const& s) - : socket(s) {} + : socket(s), broadcast(false) {} socket_entry(boost::shared_ptr const& s - , address_v4 const& mask): socket(s), netmask(mask) {} + , address_v4 const& mask): socket(s), netmask(mask), broadcast(false) {} boost::shared_ptr socket; - char buffer[1024]; + char buffer[1500]; udp::endpoint remote; address_v4 netmask; + bool broadcast; void close() { if (!socket) return; error_code ec; socket->close(ec); } + bool can_broadcast() const + { + error_code ec; + return broadcast + && netmask != address_v4() + && socket->local_endpoint(ec).address().is_v4(); + } address_v4 broadcast_address() const { error_code ec; @@ -118,12 +128,6 @@ namespace libtorrent std::list m_unicast_sockets; udp::endpoint m_multicast_endpoint; receive_handler_t m_on_receive; - - // if set, use IP broadcast as well as IP multicast - // this is off by default because it's expensive in - // terms of bandwidth usage - bool m_ip_broadcast; - }; } diff --git a/src/broadcast_socket.cpp b/src/broadcast_socket.cpp index c1125365a..95256032d 100644 --- a/src/broadcast_socket.cpp +++ b/src/broadcast_socket.cpp @@ -205,7 +205,6 @@ namespace libtorrent , bool loopback) : m_multicast_endpoint(multicast_endpoint) , m_on_receive(handler) - , m_ip_broadcast(false) { TORRENT_ASSERT(is_multicast(m_multicast_endpoint.address())); @@ -232,9 +231,10 @@ namespace libtorrent ec = error_code(); open_multicast_socket(ios, i->interface_address, loopback, ec); #ifndef NDEBUG -// fprintf(stderr, "broadcast socket [ if: %s group: %s ] %s\n" +// fprintf(stderr, "broadcast socket [ if: %s group: %s mask: %s ] %s\n" // , i->interface_address.to_string().c_str() -// , print_address(multicast_endpoint.address()).c_str() +// , multicast_endpoint.address().to_string().c_str() +// , i->netmask.to_string().c_str() // , ec.message().c_str()); #endif open_unicast_socket(ios, i->interface_address @@ -242,21 +242,6 @@ namespace libtorrent } } - void broadcast_socket::enable_ip_broadcast(bool e) - { - if (e == m_ip_broadcast) return; - m_ip_broadcast = e; - - asio::socket_base::broadcast option(m_ip_broadcast); - error_code ec; - for (std::list::iterator i = m_unicast_sockets.begin() - , end(m_unicast_sockets.end()); i != end; ++i) - { - if (!i->socket) continue; - i->socket->set_option(option, ec); - } - } - void broadcast_socket::open_multicast_socket(io_service& ios , address const& addr, bool loopback, error_code& ec) { @@ -294,8 +279,15 @@ namespace libtorrent if (ec) return; s->bind(udp::endpoint(addr, 0), ec); if (ec) return; + m_unicast_sockets.push_back(socket_entry(s, mask)); socket_entry& se = m_unicast_sockets.back(); + + // allow sending broadcast messages + asio::socket_base::broadcast option(true); + s->set_option(option, ec); + if (!ec) se.broadcast = true; + #if defined TORRENT_ASIO_DEBUGGING add_outstanding_async("broadcast_socket::on_receive"); #endif @@ -303,7 +295,7 @@ namespace libtorrent , se.remote, boost::bind(&broadcast_socket::on_receive, this, &se, _1, _2)); } - void broadcast_socket::send(char const* buffer, int size, error_code& ec) + void broadcast_socket::send(char const* buffer, int size, error_code& ec, int flags) { for (std::list::iterator i = m_unicast_sockets.begin() , end(m_unicast_sockets.end()); i != end; ++i) @@ -311,6 +303,13 @@ namespace libtorrent if (!i->socket) continue; error_code e; i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e); + + // if the user specified the broadcast flag, send one to the broadcast + // address as well + if ((flags & broadcast_socket::broadcast) && i->can_broadcast()) + i->socket->send_to(asio::buffer(buffer, size) + , udp::endpoint(i->broadcast_address(), m_multicast_endpoint.port()), 0, e); + #ifndef NDEBUG // fprintf(stderr, " sending on unicast %s to: %s\n", print_address(i->socket->local_endpoint().address()).c_str() // , print_endpoint(m_multicast_endpoint).c_str()); @@ -331,9 +330,6 @@ namespace libtorrent if (!i->socket) continue; error_code e; i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e); - if (m_ip_broadcast && i->socket->local_endpoint(e).address().is_v4()) - i->socket->send_to(asio::buffer(buffer, size) - , udp::endpoint(i->broadcast_address(), m_multicast_endpoint.port()), 0, e); #ifndef NDEBUG // extern std::string print_address(address const& addr); // extern std::string print_endpoint(udp::endpoint const& ep); diff --git a/src/lsd.cpp b/src/lsd.cpp index 0c8aa2b88..32c2c4095 100644 --- a/src/lsd.cpp +++ b/src/lsd.cpp @@ -98,8 +98,7 @@ void lsd::announce(sha1_hash const& ih, int listen_port, bool broadcast) m_retry_count = 1; error_code ec; - m_socket.enable_ip_broadcast(broadcast); - m_socket.send(msg, msg_len, ec); + m_socket.send(msg, msg_len, ec, broadcast ? broadcast_socket::broadcast : 0); if (ec) { m_disabled = true; @@ -131,8 +130,6 @@ void lsd::resend_announce(error_code const& e, std::string msg) if (e) return; error_code ec; - // don't broadcast resends - m_socket.enable_ip_broadcast(false); m_socket.send(msg.c_str(), int(msg.size()), ec); ++m_retry_count;