From b23e9e3795f9448d6a198574378bff719412839a Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 22 Dec 2007 17:33:04 +0000 Subject: [PATCH] attempt to fix #201. Uses separate sockets to send broadcast messages in order to be sure to receive unicast responses --- include/libtorrent/broadcast_socket.hpp | 10 +++++++++ src/broadcast_socket.cpp | 28 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/libtorrent/broadcast_socket.hpp b/include/libtorrent/broadcast_socket.hpp index df656f4ea..f02751212 100644 --- a/include/libtorrent/broadcast_socket.hpp +++ b/include/libtorrent/broadcast_socket.hpp @@ -69,12 +69,22 @@ namespace libtorrent boost::shared_ptr socket; char buffer[1024]; udp::endpoint remote; + void close() { socket->close(); } }; void on_receive(socket_entry* s, asio::error_code const& ec , std::size_t bytes_transferred); + void open_unicast_socket(io_service& ios, address const& addr); + // these sockets are used to + // join the multicast group (on each interface) + // and receive multicast messages std::list m_sockets; + // these sockets are not bound to any + // specific port and are used to + // send messages to the multicast group + // and receive unicast responses + std::list m_unicast_sockets; udp::endpoint m_multicast_endpoint; receive_handler_t m_on_receive; diff --git a/src/broadcast_socket.cpp b/src/broadcast_socket.cpp index e03ad2274..73d11d91c 100644 --- a/src/broadcast_socket.cpp +++ b/src/broadcast_socket.cpp @@ -163,12 +163,29 @@ namespace libtorrent // << " group: " << multicast_endpoint.address() << " ]" << std::endl; #endif } + + open_unicast_socket(ios, address_v4::any()); + open_unicast_socket(ios, address_v6::any()); + } + + void broadcast_socket::open_unicast_socket(io_service& ios, address const& addr) + { + asio::error_code ec; + boost::shared_ptr s(new datagram_socket(ios)); + s->open(addr.is_v4() ? udp::v4() : udp::v6(), ec); + if (ec) return; + s->bind(udp::endpoint(addr, 0), ec); + if (ec) return; + m_unicast_sockets.push_back(socket_entry(s)); + socket_entry& se = m_unicast_sockets.back(); + s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer)) + , se.remote, bind(&broadcast_socket::on_receive, this, &se, _1, _2)); } void broadcast_socket::send(char const* buffer, int size, asio::error_code& ec) { - for (std::list::iterator i = m_sockets.begin() - , end(m_sockets.end()); i != end; ++i) + for (std::list::iterator i = m_unicast_sockets.begin() + , end(m_unicast_sockets.end()); i != end; ++i) { asio::error_code e; i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e); @@ -192,11 +209,8 @@ namespace libtorrent { m_on_receive.clear(); - for (std::list::iterator i = m_sockets.begin() - , end(m_sockets.end()); i != end; ++i) - { - i->socket->close(); - } + std::for_each(m_sockets.begin(), m_sockets.end(), bind(&socket_entry::close, _1)); + std::for_each(m_unicast_sockets.begin(), m_unicast_sockets.end(), bind(&socket_entry::close, _1)); } }