EMANE  1.0.1
boundarymessagemanager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2016 - Adjacent Link LLC, Bridgewater, New
3  * Jersey
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of Adjacent Link LLC nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "boundarymessagemanager.h"
36 #include "logservice.h"
38 #include "netadaptermessage.h"
39 
42 #include "emane/upstreampacket.h"
43 
44 #include <sstream>
45 #include <iomanip>
46 #include <algorithm>
47 #include <cstring>
48 
50  id_{id},
51  bOpen_{}{}
52 
54 {
55  if(thread_.joinable())
56  {
57  close();
58  }
59 }
60 
62  const INETAddr & remoteAddress)
63 {
64  localAddress_ = localAddress;
65  remoteAddress_ = remoteAddress;
66 
67  try
68  {
69  udp_.open(localAddress_,true);
70  }
71  catch(...)
72  {
73  std::stringstream sstream;
74 
75  sstream<<"NEM "
76  <<std::setw(3)
77  <<std::setfill('0')
78  <<id_
79  <<": Unable to open receive socket to transport: '"
80  <<localAddress_.str()
81  <<"'."
82  <<std::endl
83  <<std::endl
84  <<"Possible reason(s):"
85  <<std::endl
86  <<" * "
87  <<localAddress_.str()
88  <<" is not this host."
89  <<std::endl
90  <<std::ends;
91 
92  throw BoundaryMessageManagerException(sstream.str());
93  }
94 
95  thread_ = std::thread{&BoundaryMessageManager::processNetworkMessage,this};
96 
97  bOpen_ = true;
98 }
99 
101 {
102  if(thread_.joinable())
103  {
104  ThreadUtils::cancel(thread_);
105 
106  thread_.join();
107  }
108 
109  udp_.close();
110 
111  bOpen_ = false;
112 }
113 
115  const void * pPacketData,
116  size_t packetDataLength,
117  const ControlMessages & msgs)
118 {
119  return sendPacketMessage(packetInfo,
120  Utils::VectorIO{{const_cast<void *>(pPacketData),packetDataLength}},
121  packetDataLength,
122  msgs);
123 }
124 
125 
127  const Utils::VectorIO & packetIO,
128  size_t packetDataLength,
129  const ControlMessages & msgs)
130 {
131  ssize_t len = 0;
132 
133  ControlMessageSerializer controlMessageSerializer(msgs);
134 
135  NetAdapterDataMessage dataMessage;
136  memset(&dataMessage,0,sizeof(dataMessage));
137 
138  dataMessage.u16Src_ = packetInfo.getSource();
139  dataMessage.u16Dst_ = packetInfo.getDestination();
140  dataMessage.u8Priority_ = packetInfo.getPriority();
141  dataMessage.u16DataLen_ = packetDataLength;
142  dataMessage.u16CtrlLen_ = controlMessageSerializer.getLength();
143 
144  NetAdapterDataMessageToNet(&dataMessage);
145 
146  NetAdapterHeader header;
147  memset(&header,0,sizeof(header));
148  header.u16Id_ = NETADAPTER_DATA_MSG;
149  header.u16Length_ =
150  sizeof(header) +
151  sizeof(dataMessage) +
152  packetDataLength +
153  controlMessageSerializer.getLength();
154 
155  NetAdapterHeaderToNet(&header);
156 
157  const Utils::VectorIO & controlVectorIO =
158  controlMessageSerializer.getVectorIO();
159 
160  Utils::VectorIO vectorIO;
161  vectorIO.push_back({&header,sizeof(header)});
162  vectorIO.push_back({&dataMessage,sizeof(dataMessage)});
163 
164  vectorIO.insert(vectorIO.end(),
165  packetIO.begin(),
166  packetIO.end());
167 
168  vectorIO.insert(vectorIO.end(),
169  controlVectorIO.begin(),
170  controlVectorIO.end());
171 
172  if((len = udp_.send(&vectorIO[0],
173  static_cast<int>(vectorIO.size()),
174  remoteAddress_)) == -1)
175  {
177  ERROR_LEVEL,"NEM %03d BoundaryMessageManager error "
178  "on message send (expected:%zu actual:%zd)",
179  id_,
180  packetDataLength,
181  len);
182  }
183 
184  std::for_each(msgs.begin(),msgs.end(),[](const ControlMessage * p){delete p;});
185 }
186 
188 {
189  ssize_t len = 0;
190 
191  ControlMessageSerializer controlMessageSerializer(msgs);
192 
193  NetAdapterHeader header;
194  memset(&header,0,sizeof(header));
195 
196  header.u16Id_ = NETADAPTER_CTRL_MSG;
197  header.u16Length_ = sizeof(header) + controlMessageSerializer.getLength() + 2;
198 
199  NetAdapterHeaderToNet(&header);
200 
201  NetAdapterControlMessage controlMessage;
202 
203  memset(&controlMessage,0,sizeof(NetAdapterControlMessage));
204  controlMessage.u16CtrlLen_ = controlMessageSerializer.getLength();
205 
206  NetAdapterControlMessageToNet(&controlMessage);
207 
208  Utils::VectorIO vectorIO;
209  vectorIO.push_back({&header,sizeof(header)});
210  vectorIO.push_back({&controlMessage,sizeof(controlMessage)});
211 
212  const Utils::VectorIO & controlMessageVectorIO =
213  controlMessageSerializer.getVectorIO();
214 
215  vectorIO.insert(vectorIO.end(),
216  controlMessageVectorIO.begin(),
217  controlMessageVectorIO.end());
218 
219  if((len = udp_.send(&vectorIO[0],
220  static_cast<int>(vectorIO.size()),
221  remoteAddress_)) == -1)
222  {
224  ERROR_LEVEL,"NEM %03d BoundaryMessageManager "
225  "error on control message send (expected:%hu actual:%zu)",
226  id_,
227  header.u16Length_,
228  len);
229  }
230 
231  std::for_each(msgs.begin(),msgs.end(),[](const ControlMessage * p){delete p;});
232 }
233 
234 void EMANE::BoundaryMessageManager::processNetworkMessage()
235 {
236  unsigned char buf[65536];
237  ssize_t len = 0;
238  NEMId dstNemId;
239 
241  DEBUG_LEVEL,
242  "NEM %03d BoundaryMessageManager::processNetworkMessage",
243  id_);
244 
245  while(1)
246  {
247  dstNemId = 0;
248 
249  memset(&buf,0,sizeof(buf));
250 
251  if((len = udp_.recv(buf,sizeof(buf),0)) > 0)
252  {
254  DEBUG_LEVEL,
255  "NEM %03d BoundaryMessageManager Pkt Rcvd len: %zd",
256  id_,len);
257 
258  if(static_cast<size_t>(len) >= sizeof(NetAdapterHeader))
259  {
260  NetAdapterHeader * pHeader = reinterpret_cast<NetAdapterHeader *>(buf);
261 
262  NetAdapterHeaderToHost(pHeader);
263 
264  if(static_cast<size_t>(len) == pHeader->u16Length_)
265  {
266  len -= sizeof(NetAdapterHeader);
267 
268  switch(pHeader->u16Id_)
269  {
270  case NETADAPTER_DATA_MSG:
271 
272  if(static_cast<size_t>(len) >= sizeof(NetAdapterDataMessage))
273  {
274  NetAdapterDataMessage * pMsg = reinterpret_cast<NetAdapterDataMessage *>(pHeader->data_);
275 
277 
278  len -= sizeof(NetAdapterDataMessage);
279 
280  if(pMsg->u16Dst_ == htons(NETADAPTER_BROADCAST_ADDRESS))
281  {
282  dstNemId = NEM_BROADCAST_MAC_ADDRESS;
283  }
284  else
285  {
286  dstNemId = pMsg->u16Dst_;
287  }
288 
289  if(static_cast<size_t>(len) >= pMsg->u16DataLen_)
290  {
291  PacketInfo pinfo{pMsg->u16Src_, dstNemId, pMsg->u8Priority_,Clock::now()};
292 
293 
294  UpstreamPacket pkt(pinfo,
295  pMsg->data_,
296  pMsg->u16DataLen_);
297 
298  len -= pMsg->u16DataLen_;
299 
300  ControlMessages controlMessages;
301 
302  if(static_cast<size_t>(len) == pMsg->u16CtrlLen_)
303  {
304  const ControlMessages & controlMessages =
306  pMsg->u16CtrlLen_);
307 
308  try
309  {
311  pMsg->data_,
312  pMsg->u16DataLen_,
313  controlMessages);
314  }
315  catch(...)
316  {
317  // cannot really do too much at this point, so we'll log it
318  // good candidate spot to generate and error event as well
320  ERROR_LEVEL,
321  "NEM %03d BoundaryMessageManager::processNetworkMessage "
322  "processUpstreamPacket exception caught",
323  id_);
324  }
325  }
326  else
327  {
329  ERROR_LEVEL,
330  "NEM %03d BoundaryMessageManager::processNetworkMessage "
331  "processUpstreamPacket size too small for control message data",
332  id_);
333 
334 
335  }
336 
337  }
338  else
339  {
341  ERROR_LEVEL,
342  "NEM %03d BoundaryMessageManager::processNetworkMessage "
343  "processUpstreamPacket size too small for data message",
344  id_);
345  }
346  }
347  else
348  {
350  ERROR_LEVEL,
351  "NEM %03d BoundaryMessageManager::processNetworkMessage "
352  "processUpstreamPacket size too small for packet data message",
353  id_);
354  }
355 
356  break;
357 
358  case NETADAPTER_CTRL_MSG:
359 
360  if(static_cast<size_t>(len) >= sizeof(NetAdapterControlMessage))
361  {
362  NetAdapterControlMessage * pMsg =
363  reinterpret_cast<NetAdapterControlMessage *>(pHeader->data_);
364 
366 
367  len -= sizeof(NetAdapterControlMessage);
368 
369  ControlMessages controlMessages;
370 
371  if(static_cast<size_t>(len) == pMsg->u16CtrlLen_)
372  {
373  const ControlMessages & controlMessages =
375  pMsg->u16CtrlLen_);
376 
377  try
378  {
379  doProcessControlMessage(controlMessages);
380  }
381  catch(...)
382  {
383  // cannot really do too much at this point, so we'll log it
384  // good candidate spot to generate and error event as well
386  ERROR_LEVEL,
387  "NEM %03d BoundaryMessageManager::processNetworkMessage "
388  "processDownstreamControl exception caught",
389  id_);
390  }
391  }
392  else
393  {
395  ERROR_LEVEL,
396  "NEM %03d BoundaryMessageManager control message size mismatch",
397  id_);
398  }
399  }
400 
401  break;
402 
403  default:
405  ERROR_LEVEL,
406  "NEM %03d BoundaryMessageManager Received unknown message type: %d",
407  id_,
408  pHeader->u16Id_);
409  break;
410  }
411  }
412  else
413  {
415  ERROR_LEVEL,
416  "NEM %03d BoundaryMessageManager Message mismatch expected %hd got %zd",
417  id_,
418  pHeader->u16Length_,
419  len);
420  }
421  }
422  else
423  {
425  ERROR_LEVEL,
426  "NEM %03d BoundaryMessageManager Message Header mismatch expected %zu got %zd",
427  id_,
428  sizeof(NetAdapterHeader),
429  len);
430  }
431 
432  }
433  else
434  {
435  // read error
437  ERROR_LEVEL,
438  "NEM %03d BoundaryMessageManager Message Header read error",
439  id_);
440 
441  break;
442  }
443  }
444 }
NetAdapterHeader * NetAdapterHeaderToHost(NetAdapterHeader *pMsg)
A Packet class that allows upstream processing to strip layer headers as the packet travels up the st...
data shared between network adapter and nem.
void close()
Definition: socket.cc:40
virtual void doProcessControlMessage(const ControlMessages &msgs)=0
void open(const INETAddr &address, bool bReuseAddress=false)
#define LOGGER_VERBOSE_LOGGING(logger, level, fmt, args...)
NetAdapterControlMessage * NetAdapterControlMessageToHost(NetAdapterControlMessage *ctrl)
std::list< const ControlMessage * > ControlMessages
void sendPacketMessage(const PacketInfo &packetInfo, const void *pPacketData, size_t packetLength, const ControlMessages &msgs)
NEMId getSource() const
Definition: packetinfo.inl:64
information shared between network adapter and nem.
virtual void doProcessPacketMessage(const PacketInfo &, const void *pPacketData, size_t packetLength, const ControlMessages &msgs)=0
NEMId getDestination() const
Definition: packetinfo.inl:70
constexpr NEMId NEM_BROADCAST_MAC_ADDRESS
Definition: types.h:69
ssize_t send(const iovec *iov, int iovcnt, const INETAddr &remoteAddress, int flags=0) const
std::vector< iovec > VectorIO
Definition: vectorio.h:43
NetAdapterDataMessage * NetAdapterDataMessageToNet(NetAdapterDataMessage *pkt)
converts netadapter data message from host to network byte order.
void sendControlMessage(const ControlMessages &msgs)
Store source, destination, creation time and priority information for a packet.
Definition: packetinfo.h:50
static ControlMessages create(const void *pData, size_t length)
std::string str(bool bWithPort=true) const
Definition: inetaddr.cc:409
int cancel(std::thread &thread)
Definition: threadutils.h:65
void open(const INETAddr &localAddress, const INETAddr &remoteAddress)
std::uint16_t NEMId
Definition: types.h:52
ControlMessage interface is the base for all control messages.
NetAdapter message header.
Priority getPriority() const
Definition: packetinfo.inl:76
Exception thrown by the during BoundaryMessageManagerException to indicate connection failure...
ssize_t recv(void *buf, size_t len, int flags=0)
NetAdapterControlMessage * NetAdapterControlMessageToNet(NetAdapterControlMessage *ctrl)
const std::uint16_t NETADAPTER_DATA_MSG
#define LOGGER_STANDARD_LOGGING(logger, level, fmt, args...)
const std::uint16_t NETADAPTER_CTRL_MSG
NetAdapterHeader * NetAdapterHeaderToNet(NetAdapterHeader *pMsg)
static LogService * instance()
Definition: singleton.h:56
NetAdapterDataMessage * NetAdapterDataMessageToHost(NetAdapterDataMessage *pkt)
converts netadapter data message from network to host byte order.
const std::uint16_t NETADAPTER_BROADCAST_ADDRESS
definition of the broadcast address used between network adapter and nem.
const Utils::VectorIO & getVectorIO() const