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.packet), m_multicastGroup,
91 [
this, p = packet.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) {
128 ifname +
": " + std::strerror(errno)));
136 const protocol::endpoint& multicastGroup,
137 const boost::asio::ip::address& localAddress,
138 const shared_ptr<const ndn::net::NetworkInterface>& netif)
140 BOOST_ASSERT(!sock.is_open());
142 sock.open(multicastGroup.protocol());
143 sock.set_option(protocol::socket::reuse_address(
true));
145 if (multicastGroup.address().is_v4()) {
146 BOOST_ASSERT(localAddress.is_v4());
147 sock.bind(multicastGroup);
148 sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v4(),
149 localAddress.to_v4()));
152 BOOST_ASSERT(localAddress.is_v6());
153 sock.set_option(boost::asio::ip::v6_only(
true));
157 if (multicastGroup.address().to_v6().scope_id() == 0)
158 sock.bind(protocol::endpoint(boost::asio::ip::address_v6::any(), multicastGroup.port()));
161 sock.bind(multicastGroup);
162 sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v6()));
171 const protocol::endpoint& localEndpoint,
172 const shared_ptr<const ndn::net::NetworkInterface>& netif,
175 BOOST_ASSERT(!sock.is_open());
177 sock.open(localEndpoint.protocol());
178 sock.set_option(protocol::socket::reuse_address(
true));
179 sock.set_option(boost::asio::ip::multicast::enable_loopback(enableLoopback));
181 if (localEndpoint.address().is_v4()) {
182 sock.bind(localEndpoint);
183 if (!localEndpoint.address().is_unspecified())
184 sock.set_option(boost::asio::ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
187 sock.set_option(boost::asio::ip::v6_only(
true));
188 sock.bind(localEndpoint);
190 sock.set_option(boost::asio::ip::multicast::outbound_interface(netif->
getIndex()));
198 if (ep.address().is_v4()) {
199 return (static_cast<uint64_t>(ep.port()) << 32) |
200 static_cast<uint64_t>(ep.address().to_v4().to_ulong());
204 const auto& addrBytes = ep.address().to_v6().to_bytes();
205 boost::hash_range(seed, addrBytes.begin(), addrBytes.end());
206 boost::hash_combine(seed, ep.port());
void setPersistency(ndn::nfd::FacePersistency newPersistency)
changes face persistency setting
static void openRxSocket(protocol::socket &sock, const protocol::endpoint &multicastGroup, const boost::asio::ip::address &localAddress, const shared_ptr< const ndn::net::NetworkInterface > &netif=nullptr)
NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport< boost::asio::ip::udp, Multicast >), MulticastUdpTransport)
ssize_t getSendQueueLength() final
#define NFD_LOG_FACE_TRACE(msg)
Log a message at TRACE level.
void setRemoteUri(const FaceUri &uri)
std::string getName() const
Returns the name of the interface, unique on the system.
static void runElevated(F &&f)
void doClose() override
performs Transport specific operations to close the transport
stores a packet along with the remote endpoint
const ssize_t QUEUE_ERROR
indicates that the transport was unable to retrieve the queue capacity/length
void setLinkType(ndn::nfd::LinkType linkType)
Implements Transport for datagram-based protocols.
ssize_t computeMtu(const Endpoint &localEndpoint)
computes maximum payload size in a UDP packet
void setScope(ndn::nfd::FaceScope scope)
static EndpointId makeEndpointId(const typename protocol::endpoint &ep)
MulticastUdpTransport(const protocol::endpoint &multicastGroup, protocol::socket &&recvSocket, protocol::socket &&sendSocket, ndn::nfd::LinkType linkType)
Creates a UDP-based transport for multicast communication.
static void bindToDevice(int fd, const std::string &ifname)
#define NFD_LOG_FACE_INFO(msg)
Log a message at INFO level.
Copyright (c) 2011-2015 Regents of the University of California.
static void openTxSocket(protocol::socket &sock, const protocol::endpoint &localEndpoint, const shared_ptr< const ndn::net::NetworkInterface > &netif=nullptr, bool enableLoopback=false)
void setLocalUri(const FaceUri &uri)
ssize_t getTxQueueLength(int fd)
obtain send queue length from a specified system socket
represents the underlying protocol and address used by a Face
void setSendQueueCapacity(ssize_t sendQueueCapacity)
int getIndex() const
Returns an opaque ID that uniquely identifies the interface on the system.
uint64_t EndpointId
identifies an endpoint on the link
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.