32 #include <boost/functional/hash.hpp> 37 #include <sys/socket.h> 46 protocol::socket&& recvSocket,
47 protocol::socket&& sendSocket,
48 ndn::nfd::LinkType linkType)
50 , m_multicastGroup(multicastGroup)
51 , m_sendSocket(
std::move(sendSocket))
53 this->
setLocalUri(FaceUri(m_sendSocket.local_endpoint()));
55 this->
setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
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 (::setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname.data(), ifname.size() + 1) < 0) {
126 ifname +
": " + std::strerror(errno)));
134 const protocol::endpoint& multicastGroup,
135 const boost::asio::ip::address& localAddress,
136 const shared_ptr<const ndn::net::NetworkInterface>& netif)
138 BOOST_ASSERT(!sock.is_open());
140 sock.open(multicastGroup.protocol());
141 sock.set_option(protocol::socket::reuse_address(
true));
143 if (multicastGroup.address().is_v4()) {
144 BOOST_ASSERT(localAddress.is_v4());
145 sock.bind(multicastGroup);
146 sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v4(),
147 localAddress.to_v4()));
150 BOOST_ASSERT(localAddress.is_v6());
151 sock.set_option(boost::asio::ip::v6_only(
true));
155 if (multicastGroup.address().to_v6().scope_id() == 0)
156 sock.bind(protocol::endpoint(boost::asio::ip::address_v6::any(), multicastGroup.port()));
159 sock.bind(multicastGroup);
160 sock.set_option(boost::asio::ip::multicast::join_group(multicastGroup.address().to_v6()));
169 const protocol::endpoint& localEndpoint,
170 const shared_ptr<const ndn::net::NetworkInterface>& netif,
173 BOOST_ASSERT(!sock.is_open());
175 sock.open(localEndpoint.protocol());
176 sock.set_option(protocol::socket::reuse_address(
true));
177 sock.set_option(boost::asio::ip::multicast::enable_loopback(enableLoopback));
179 if (localEndpoint.address().is_v4()) {
180 sock.bind(localEndpoint);
181 if (!localEndpoint.address().is_unspecified())
182 sock.set_option(boost::asio::ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
185 sock.set_option(boost::asio::ip::v6_only(
true));
186 sock.bind(localEndpoint);
188 sock.set_option(boost::asio::ip::multicast::outbound_interface(netif->getIndex()));
196 if (ep.address().is_v4()) {
197 return (static_cast<uint64_t>(ep.port()) << 32) |
198 static_cast<uint64_t
>(ep.address().to_v4().to_ulong());
202 const auto& addrBytes = ep.address().to_v6().to_bytes();
203 boost::hash_range(seed, addrBytes.begin(), addrBytes.end());
204 boost::hash_combine(seed, ep.port());
void setSendQueueCapacity(ssize_t sendQueueCapacity)
void setLocalUri(const FaceUri &uri)
void doClose() override
performs Transport specific operations to close the transport
#define NFD_LOG_FACE_TRACE(msg)
Log a message at TRACE level.
void setScope(ndn::nfd::FaceScope scope)
#define NFD_LOG_MEMBER_INIT_SPECIALIZED(cls, name)
const ssize_t QUEUE_ERROR
indicates that the transport was unable to retrieve the queue capacity/length
static void openTxSocket(protocol::socket &sock, const protocol::endpoint &localEndpoint, const shared_ptr< const ndn::net::NetworkInterface > &netif=nullptr, bool enableLoopback=false)
MulticastUdpTransport(const protocol::endpoint &multicastGroup, protocol::socket &&recvSocket, protocol::socket &&sendSocket, ndn::nfd::LinkType linkType)
Creates a UDP-based transport for multicast communication.
ssize_t computeMtu(const Endpoint &localEndpoint)
computes maximum payload size in a UDP packet
stores a packet along with the remote endpoint
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.
static void bindToDevice(int fd, const std::string &ifname)
ssize_t getSendQueueLength() final
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
static void runElevated(F &&f)
static EndpointId makeEndpointId(const typename protocol::endpoint &ep)
#define NFD_LOG_FACE_INFO(msg)
Log a message at INFO level.
uint64_t EndpointId
identifies an endpoint on the link
ssize_t getTxQueueLength(int fd)
obtain send queue length from a specified system socket
void setLinkType(ndn::nfd::LinkType linkType)
void setPersistency(ndn::nfd::FacePersistency newPersistency)
changes face persistency setting
Implements Transport for datagram-based protocols.
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)
void setRemoteUri(const FaceUri &uri)