26 #ifndef NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
27 #define NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
35 #include <boost/asio/defer.hpp>
48 template<
class Protocol,
class Addressing>
70 receiveDatagram(span<const uint8_t> buffer,
const boost::system::error_code& error);
77 doSend(
const Block& packet)
override;
80 handleSend(
const boost::system::error_code& error,
size_t nBytesSent);
83 handleReceive(
const boost::system::error_code& error,
size_t nBytesReceived);
101 std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
102 bool m_hasRecentlyReceived =
false;
106 template<
class T,
class U>
108 : m_socket(std::move(socket))
110 boost::asio::socket_base::send_buffer_size sendBufferSizeOption;
111 boost::system::error_code error;
112 m_socket.get_option(sendBufferSizeOption, error);
114 NFD_LOG_FACE_WARN(
"Failed to obtain send queue capacity from socket: " << error.message());
122 [
this] (
auto&&... args) {
127 template<
class T,
class U>
133 NFD_LOG_FACE_WARN(
"Failed to obtain send queue length from socket: " << std::strerror(errno));
138 template<
class T,
class U>
144 if (m_socket.is_open()) {
147 boost::system::error_code error;
148 m_socket.cancel(error);
149 m_socket.close(error);
159 template<
class T,
class U>
165 m_socket.async_send(boost::asio::buffer(packet),
167 [
this, packet] (
auto&&... args) {
168 this->handleSend(std::forward<decltype(args)>(args)...);
172 template<
class T,
class U>
175 const boost::system::error_code& error)
178 return processErrorCode(error);
182 auto [isOk, element] = Block::fromBuffer(buffer);
188 if (element.size() != buffer.size()) {
189 NFD_LOG_FACE_WARN(
"Received datagram size and decoded element size don't match");
193 m_hasRecentlyReceived =
true;
195 if constexpr (std::is_same_v<addressing, Multicast>)
196 this->receive(element, m_sender);
198 this->receive(element);
201 template<
class T,
class U>
205 receiveDatagram(ndn::make_span(m_receiveBuffer).first(nBytesReceived), error);
207 if (m_socket.is_open())
208 m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
209 [
this] (
auto&&... args) {
210 this->handleReceive(std::forward<decltype(args)>(args)...);
214 template<
class T,
class U>
219 return processErrorCode(error);
224 template<
class T,
class U>
233 error == boost::asio::error::operation_aborted) {
238 if (getPersistency() == ndn::nfd::FACE_PERSISTENCY_PERMANENT) {
248 template<
class T,
class U>
252 return m_hasRecentlyReceived;
255 template<
class T,
class U>
259 m_hasRecentlyReceived =
false;
Implements a Transport for datagram-based protocols.
protocol::endpoint m_sender
void processErrorCode(const boost::system::error_code &error)
ssize_t getSendQueueLength() override
Returns the current send queue length of the transport (in octets).
DatagramTransport(typename protocol::socket &&socket)
Construct datagram transport.
bool hasRecentlyReceived() const
void doSend(const Block &packet) override
Performs Transport specific operations to send a packet.
void resetRecentlyReceived()
void handleSend(const boost::system::error_code &error, size_t nBytesSent)
void receiveDatagram(span< const uint8_t > buffer, const boost::system::error_code &error)
Receive datagram, translate buffer into packet, deliver to parent class.
protocol::socket m_socket
void handleReceive(const boost::system::error_code &error, size_t nBytesReceived)
void doClose() override
Performs Transport specific operations to close the transport.
The lower half of a Face.
void setSendQueueCapacity(ssize_t sendQueueCapacity) noexcept
#define NFD_LOG_FACE_ERROR(msg)
Log a message at ERROR level.
#define NFD_LOG_FACE_DEBUG(msg)
Log a message at DEBUG level.
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.
#define NFD_LOG_FACE_TRACE(msg)
Log a message at TRACE level.
#define NFD_LOG_MEMBER_DECL()
@ CLOSED
the transport is closed, and can be safely deallocated
@ CLOSING
the transport is being closed gracefully, either by the peer or by a call to close()
@ FAILED
the transport is being closed due to a failure
constexpr ssize_t QUEUE_ERROR
Indicates that the transport was unable to retrieve the queue capacity/length.
ssize_t getTxQueueLength(int fd)
Obtain send queue length from a specified system socket.
boost::asio::io_context & getGlobalIoService()
Returns the global io_context instance for the calling thread.