NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
datagram-transport.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #ifndef NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
27 #define NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
28 
29 #include "transport.hpp"
30 #include "core/global-io.hpp"
31 
32 #include <array>
33 
34 namespace nfd {
35 namespace face {
36 
37 struct Unicast {};
38 struct Multicast {};
39 
44 template<class Protocol, class Addressing = Unicast>
46 {
47 public:
48  typedef Protocol protocol;
49 
54  explicit
56 
59  void
60  receiveDatagram(const uint8_t* buffer, size_t nBytesReceived,
61  const boost::system::error_code& error);
62 
63 protected:
64  void
65  doClose() override;
66 
67  void
68  doSend(Transport::Packet&& packet) override;
69 
70  void
71  handleSend(const boost::system::error_code& error,
72  size_t nBytesSent, const Block& payload);
73 
74  void
75  handleReceive(const boost::system::error_code& error,
76  size_t nBytesReceived);
77 
78  void
79  processErrorCode(const boost::system::error_code& error);
80 
81  bool
82  hasRecentlyReceived() const;
83 
84  void
85  resetRecentlyReceived();
86 
87  static EndpointId
88  makeEndpointId(const typename protocol::endpoint& ep);
89 
90 protected:
92  typename protocol::endpoint m_sender;
93 
95 
96 private:
97  std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
98  bool m_hasRecentlyReceived;
99 };
100 
101 
102 template<class T, class U>
104  : m_socket(std::move(socket))
105  , m_hasRecentlyReceived(false)
106 {
107  m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
109  boost::asio::placeholders::error,
110  boost::asio::placeholders::bytes_transferred));
111 }
112 
113 template<class T, class U>
114 void
116 {
117  NFD_LOG_FACE_TRACE(__func__);
118 
119  if (m_socket.is_open()) {
120  // Cancel all outstanding operations and close the socket.
121  // Use the non-throwing variants and ignore errors, if any.
122  boost::system::error_code error;
123  m_socket.cancel(error);
124  m_socket.close(error);
125  }
126 
127  // Ensure that the Transport stays alive at least until
128  // all pending handlers are dispatched
129  getGlobalIoService().post([this] {
131  });
132 }
133 
134 template<class T, class U>
135 void
137 {
138  NFD_LOG_FACE_TRACE(__func__);
139 
140  m_socket.async_send(boost::asio::buffer(packet.packet),
142  boost::asio::placeholders::error,
143  boost::asio::placeholders::bytes_transferred,
144  packet.packet));
145 }
146 
147 template<class T, class U>
148 void
149 DatagramTransport<T, U>::receiveDatagram(const uint8_t* buffer, size_t nBytesReceived,
150  const boost::system::error_code& error)
151 {
152  if (error)
153  return processErrorCode(error);
154 
155  NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes from " << m_sender);
156 
157  bool isOk = false;
158  Block element;
159  std::tie(isOk, element) = Block::fromBuffer(buffer, nBytesReceived);
160  if (!isOk) {
161  NFD_LOG_FACE_WARN("Failed to parse incoming packet from " << m_sender);
162  // This packet won't extend the face lifetime
163  return;
164  }
165  if (element.size() != nBytesReceived) {
166  NFD_LOG_FACE_WARN("Received datagram size and decoded element size don't match");
167  // This packet won't extend the face lifetime
168  return;
169  }
170  m_hasRecentlyReceived = true;
171 
172  Transport::Packet tp(std::move(element));
174  this->receive(std::move(tp));
175 }
176 
177 template<class T, class U>
178 void
179 DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error,
180  size_t nBytesReceived)
181 {
182  receiveDatagram(m_receiveBuffer.data(), nBytesReceived, error);
183 
184  if (m_socket.is_open())
185  m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
187  boost::asio::placeholders::error,
188  boost::asio::placeholders::bytes_transferred));
189 }
190 
191 template<class T, class U>
192 void
193 DatagramTransport<T, U>::handleSend(const boost::system::error_code& error,
194  size_t nBytesSent, const Block& payload)
195 // 'payload' is unused; it's needed to retain the underlying Buffer
196 {
197  if (error)
198  return processErrorCode(error);
199 
200  NFD_LOG_FACE_TRACE("Successfully sent: " << nBytesSent << " bytes");
201 }
202 
203 template<class T, class U>
204 void
205 DatagramTransport<T, U>::processErrorCode(const boost::system::error_code& error)
206 {
207  NFD_LOG_FACE_TRACE(__func__);
208 
213  // transport is shutting down, ignore any errors
214  return;
215  }
216 
218  NFD_LOG_FACE_DEBUG("Permanent face ignores error: " << error.message());
219  return;
220  }
221 
222  NFD_LOG_FACE_ERROR("Send or receive operation failed: " << error.message());
224  doClose();
225 }
226 
227 template<class T, class U>
228 bool
230 {
231  return m_hasRecentlyReceived;
232 }
233 
234 template<class T, class U>
235 void
237 {
238  m_hasRecentlyReceived = false;
239 }
240 
241 template<class T, class U>
243 DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint& ep)
244 {
245  return 0;
246 }
247 
248 } // namespace face
249 } // namespace nfd
250 
251 #endif // NFD_DAEMON_FACE_DATAGRAM_TRANSPORT_HPP
void doSend(Transport::Packet &&packet) override
performs Transport specific operations to send a packet
void handleSend(const boost::system::error_code &error, size_t nBytesSent, const Block &payload)
#define NFD_LOG_INCLASS_DECLARE()
Definition: logger.hpp:36
static std::tuple< bool, Block > fromBuffer(ConstBufferPtr buffer, size_t offset)
Try to parse Block from a wire buffer.
Definition: block.cpp:195
#define NFD_LOG_FACE_TRACE(msg)
Log a message at TRACE level.
Definition: face-log.hpp:79
void doClose() override
performs Transport specific operations to close the transport
#define NFD_LOG_FACE_ERROR(msg)
Log a message at ERROR level.
Definition: face-log.hpp:91
void handleReceive(const boost::system::error_code &error, size_t nBytesReceived)
stores a packet along with the remote endpoint
Definition: transport.hpp:113
STL namespace.
detail::SimulatorIo & getGlobalIoService()
Definition: global-io.cpp:48
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
Implements Transport for datagram-based protocols.
the transport is being closed due to a failure
static EndpointId makeEndpointId(const typename protocol::endpoint &ep)
void receiveDatagram(const uint8_t *buffer, size_t nBytesReceived, const boost::system::error_code &error)
Receive datagram, translate buffer into packet, deliver to parent class.
size_t size() const
Get size of encoded wire, including Type-Length-Value.
Definition: block.cpp:299
#define NFD_LOG_FACE_DEBUG(msg)
Log a message at DEBUG level.
Definition: face-log.hpp:82
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
void processErrorCode(const boost::system::error_code &error)
EndpointId remoteEndpoint
identifies the remote endpoint
Definition: transport.hpp:132
the transport is closed, and can be safely deallocated
void post(const std::function< void()> &callback)
Definition: global-io.cpp:34
the transport is being closed gracefully, either by the peer or by a call to close() ...
TransportState getState() const
Definition: transport.hpp:445
void setState(TransportState newState)
set transport state
Definition: transport.cpp:174
Catch-all error for socket component errors that don&#39;t fit in other categories.
Definition: base.hpp:83
DatagramTransport(typename protocol::socket &&socket)
Construct datagram transport.
void receive(Packet &&packet)
receive a link-layer packet
Definition: transport.cpp:117
uint64_t EndpointId
identifies an endpoint on the link
Definition: transport.hpp:109
the lower part of a Face
Definition: transport.hpp:104
#define NFD_LOG_FACE_WARN(msg)
Log a message at WARN level.
Definition: face-log.hpp:88
ndn::nfd::FacePersistency getPersistency() const
Definition: transport.hpp:414