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));
85 MulticastUdpTransport::doSend(
const Block& packet)
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) {
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());
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)
#define NFD_LOG_FACE_DEBUG(msg)
Log a message at DEBUG level.
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.
uint64_t EndpointId
Identifies a remote endpoint on the link.
ssize_t computeMtu(const Endpoint &localEndpoint)
computes maximum payload size in a UDP packet
#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)
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
static EndpointId makeEndpointId(const typename protocol::endpoint &ep)
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)
void handleSend(const boost::system::error_code &error, size_t nBytesSent)