diff --git a/src/broadcast_socket.cpp b/src/broadcast_socket.cpp index c5a11f2cf..f6610df1e 100644 --- a/src/broadcast_socket.cpp +++ b/src/broadcast_socket.cpp @@ -113,6 +113,11 @@ namespace libtorrent asio::error_code ec; std::vector
interfaces = enum_net_interfaces(ios, ec); + if (multicast_endpoint.address().is_v4()) + open_multicast_socket(ios, address_v4::any(), loopback); + else + open_multicast_socket(ios, address_v6::any(), loopback); + for (std::vector
::const_iterator i = interfaces.begin() , end(interfaces.end()); i != end; ++i) { @@ -123,58 +128,54 @@ namespace libtorrent // ignore any loopback interface if (is_loopback(*i)) continue; - boost::shared_ptr s(new datagram_socket(ios)); - if (i->is_v4()) - { - s->open(udp::v4(), ec); - if (ec) continue; - s->set_option(datagram_socket::reuse_address(true), ec); - if (ec) continue; - s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec); - if (ec) continue; - s->set_option(join_group(multicast_endpoint.address()), ec); - if (ec) continue; - s->set_option(outbound_interface(i->to_v4()), ec); - if (ec) continue; - } - else - { - s->open(udp::v6(), ec); - if (ec) continue; - s->set_option(datagram_socket::reuse_address(true), ec); - if (ec) continue; - s->bind(udp::endpoint(address_v6::any(), multicast_endpoint.port()), ec); - if (ec) continue; - s->set_option(join_group(multicast_endpoint.address()), ec); - if (ec) continue; -// s->set_option(outbound_interface(i->to_v6()), ec); -// if (ec) continue; - } - s->set_option(hops(255), ec); - if (ec) continue; - s->set_option(enable_loopback(loopback), ec); - if (ec) continue; - m_sockets.push_back(socket_entry(s)); - socket_entry& se = m_sockets.back(); - s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer)) - , se.remote, bind(&broadcast_socket::on_receive, this, &se, _1, _2)); #ifndef NDEBUG // std::cerr << "broadcast socket [ if: " << i->to_v4().to_string() // << " group: " << multicast_endpoint.address() << " ]" << std::endl; #endif + open_unicast_socket(ios, *i); } - open_unicast_socket(ios, address_v4::any()); - open_unicast_socket(ios, address_v6::any()); + } + + void broadcast_socket::open_multicast_socket(io_service& ios + , address const& addr, bool loopback) + { + using namespace asio::ip::multicast; + + asio::error_code ec; + boost::shared_ptr s(new datagram_socket(ios)); + if (addr.is_v4()) + s->open(udp::v4(), ec); + else + s->open(udp::v6(), ec); + if (ec) return; + s->set_option(datagram_socket::reuse_address(true), ec); + if (ec) return; + s->bind(udp::endpoint(addr, m_multicast_endpoint.port()), ec); + if (ec) return; + s->set_option(join_group(m_multicast_endpoint.address()), ec); + if (ec) return; + s->set_option(hops(255), ec); + if (ec) return; + s->set_option(enable_loopback(loopback), ec); + if (ec) return; + m_sockets.push_back(socket_entry(s)); + socket_entry& se = m_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::open_unicast_socket(io_service& ios, address const& addr) { + using namespace asio::ip::multicast; 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; + if (addr.is_v4()) + s->set_option(outbound_interface(addr.to_v4()), 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)) @@ -191,22 +192,6 @@ namespace libtorrent i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e); #ifndef NDEBUG // std::cerr << " sending on " << i->socket->local_endpoint().address().to_string() << " to: " << m_multicast_endpoint << std::endl; -#endif - if (e) - { - i->socket->close(e); - i->socket.reset(); - } - } - - for (std::list::iterator i = m_sockets.begin() - , end(m_sockets.end()); i != end; ++i) - { - if (!i->socket) continue; - asio::error_code e; - i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e); -#ifndef NDEBUG -// std::cerr << " sending on " << i->socket->local_endpoint().address().to_string() << " to: " << m_multicast_endpoint << std::endl; #endif if (e) {