32 #include <boost/functional/hash.hpp>
37 #include <sys/socket.h>
46 protocol::socket&& recvSocket,
47 protocol::socket&& sendSocket,
50 , m_multicastGroup(multicastGroup)
51 , m_sendSocket(std::
move(sendSocket))
60 protocol::socket::send_buffer_size sendBufferSizeOption;
61 boost::system::error_code error;
62 m_sendSocket.get_option(sendBufferSizeOption);
64 NFD_LOG_FACE_WARN(
"Failed to obtain send queue capacity from socket: " << error.message());
79 NFD_LOG_FACE_WARN(
"Failed to obtain send queue length from socket: " << std::strerror(errno));
89 m_sendSocket.async_send_to(boost::asio::buffer(packet), m_multicastGroup,
91 [
this, packet] (
auto&&... args) {
92 this->
handleSend(std::forward<decltype(args)>(args)...);
97 MulticastUdpTransport::doClose()
99 if (m_sendSocket.is_open()) {
104 boost::system::error_code error;
105 m_sendSocket.cancel(error);
106 m_sendSocket.close(error);
124 #if defined(__linux__) && !defined(__ANDROID__)
126 if (::setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname.data(), ifname.size() + 1) < 0) {
127 NDN_THROW_ERRNO(MulticastUdpTransport::Error(
"Cannot bind multicast rx socket to " + ifname));
135 const protocol::endpoint& multicastGroup,
136 const boost::asio::ip::address& localAddress,
137 const shared_ptr<const ndn::net::NetworkInterface>& netif)
139 BOOST_ASSERT(!sock.is_open());
141 sock.open(multicastGroup.protocol());
142 sock.set_option(protocol::socket::reuse_address(
true));
144 if (multicastGroup.address().is_v4()) {
145 BOOST_ASSERT(localAddress.is_v4());
146 sock.bind(multicastGroup);
147 sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v4(),
148 localAddress.to_v4()));
151 BOOST_ASSERT(localAddress.is_v6());
152 sock.set_option(boost::asio::ip::v6_only(
true));
156 if (multicastGroup.address().to_v6().scope_id() == 0)
157 sock.bind(protocol::endpoint(boost::asio::ip::address_v6::any(), multicastGroup.port()));
160 sock.bind(multicastGroup);
161 sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v6()));
170 const protocol::endpoint& localEndpoint,
171 const shared_ptr<const ndn::net::NetworkInterface>& netif,
174 BOOST_ASSERT(!sock.is_open());
176 sock.open(localEndpoint.protocol());
177 sock.set_option(protocol::socket::reuse_address(
true));
178 sock.set_option(boost::asio::ip::multicast::enable_loopback(enableLoopback));
180 if (localEndpoint.address().is_v4()) {
181 sock.bind(localEndpoint);
182 if (!localEndpoint.address().is_unspecified())
183 sock.set_option(boost::asio::ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
186 sock.set_option(boost::asio::ip::v6_only(
true));
187 sock.bind(localEndpoint);
189 sock.set_option(boost::asio::ip::multicast::outbound_interface(netif->
getIndex()));
197 if (ep.address().is_v4()) {
198 return (
static_cast<uint64_t
>(ep.port()) << 32) |
199 static_cast<uint64_t
>(ep.address().to_v4().to_ulong());
203 const auto& addrBytes = ep.address().to_v6().to_bytes();
204 boost::hash_range(seed, addrBytes.begin(), addrBytes.end());
205 boost::hash_combine(seed, ep.port());