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)
{