EMANE  1.2.1
boundarymessagemanager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2017 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "boundarymessagemanager.h"
35 #include "logservice.h"
37 #include "netadaptermessage.h"
38 
41 #include "emane/upstreampacket.h"
42 
43 #include <sstream>
44 #include <iomanip>
45 #include <algorithm>
46 #include <cstring>
47 #include <sys/socket.h>
48 #include <unistd.h>
49 
51  id_{id},
52  bOpen_{},
53  iSockFd_{-1},
54  iSessionSockFd_{-1},
55  bConnected_{}{}
56 
57 
59 {
60  if(thread_.joinable())
61  {
62  close();
63  }
64 }
65 
67  const INETAddr & remoteAddress,
68  Protocol protocol)
69 {
70  localAddress_ = localAddress;
71  remoteAddress_ = remoteAddress;
72  protocol_ = protocol;
73 
74  try
75  {
76  if(protocol_ == Protocol::PROTOCOL_UDP)
77  {
78  udp_.open(localAddress_,true);
79  }
80  // note: Protocol::PROTOCOL_TCP_* sockets open in thread
81  }
82  catch(...)
83  {
84  std::stringstream sstream;
85 
86  sstream<<"NEM "
87  <<std::setw(3)
88  <<std::setfill('0')
89  <<id_
90  <<": Unable to open receive socket to transport: '"
91  <<localAddress_.str()
92  <<"'."
93  <<std::endl
94  <<std::endl
95  <<"Possible reason(s):"
96  <<std::endl
97  <<" * "
98  <<localAddress_.str()
99  <<" is not this host."
100  <<std::endl
101  <<std::ends;
102 
103  throw BoundaryMessageManagerException(sstream.str());
104  }
105 
106  if(protocol_ == Protocol::PROTOCOL_UDP)
107  {
108  thread_ = std::thread{&BoundaryMessageManager::processNetworkMessageUDP,this};
109  }
110  else
111  {
112  thread_ = std::thread{&BoundaryMessageManager::processNetworkMessageTCP,this};
113  }
114 
115  bOpen_ = true;
116 }
117 
119 {
120  if(bOpen_)
121  {
122  if(thread_.joinable())
123  {
124  ThreadUtils::cancel(thread_);
125 
126  thread_.join();
127  }
128 
129  if(protocol_ == Protocol::PROTOCOL_UDP)
130  {
131  udp_.close();
132  }
133  else
134  {
135  ::close(iSockFd_);
136 
137  if(bConnected_ && protocol_ == Protocol::PROTOCOL_TCP_SERVER)
138  {
139  ::close(iSessionSockFd_);
140  }
141  }
142 
143 
144  bOpen_ = false;
145  }
146 }
147 
149  const void * pPacketData,
150  size_t packetDataLength,
151  const ControlMessages & msgs)
152 {
153  return sendPacketMessage(packetInfo,
154  Utils::VectorIO{{const_cast<void *>(pPacketData),packetDataLength}},
155  packetDataLength,
156  msgs);
157 }
158 
159 
161  const Utils::VectorIO & packetIO,
162  size_t packetDataLength,
163  const ControlMessages & msgs)
164 {
165  ssize_t len = 0;
166 
167  ControlMessageSerializer controlMessageSerializer(msgs);
168 
169  NetAdapterDataMessage dataMessage;
170  memset(&dataMessage,0,sizeof(dataMessage));
171 
172  dataMessage.u16Src_ = packetInfo.getSource();
173  dataMessage.u16Dst_ = packetInfo.getDestination();
174  dataMessage.u8Priority_ = packetInfo.getPriority();
175  dataMessage.u32DataLen_ = packetDataLength;
176  dataMessage.u32CtrlLen_ = controlMessageSerializer.getLength();
177 
178  NetAdapterDataMessageToNet(&dataMessage);
179 
180  NetAdapterHeader header;
181  memset(&header,0,sizeof(header));
182  header.u16Id_ = NETADAPTER_DATA_MSG;
183  header.u32Length_ =
184  sizeof(header) +
185  sizeof(dataMessage) +
186  packetDataLength +
187  controlMessageSerializer.getLength();
188 
189  NetAdapterHeaderToNet(&header);
190 
191  const Utils::VectorIO & controlVectorIO =
192  controlMessageSerializer.getVectorIO();
193 
194  Utils::VectorIO vectorIO;
195  vectorIO.push_back({&header,sizeof(header)});
196  vectorIO.push_back({&dataMessage,sizeof(dataMessage)});
197 
198  vectorIO.insert(vectorIO.end(),
199  packetIO.begin(),
200  packetIO.end());
201 
202  vectorIO.insert(vectorIO.end(),
203  controlVectorIO.begin(),
204  controlVectorIO.end());
205 
206  if(protocol_ == Protocol::PROTOCOL_UDP)
207  {
208  if((len = udp_.send(&vectorIO[0],
209  static_cast<int>(vectorIO.size()),
210  remoteAddress_)) == -1)
211  {
213  ERROR_LEVEL,"NEM %03d BoundaryMessageManager error "
214  "on message send (expected:%zu actual:%zd)",
215  id_,
216  packetDataLength,
217  len);
218  }
219  }
220  else
221  {
222  msghdr msg;
223  memset(&msg,0,sizeof(msg));
224  msg.msg_iov = const_cast<iovec *>(&vectorIO[0]);
225  msg.msg_iovlen = vectorIO.size();
226 
227  std::lock_guard<std::mutex> m(mutex_);
228 
229  if(bConnected_)
230  {
231  if((len = sendmsg(iSessionSockFd_,&msg,0)) == -1)
232  {
234  ERROR_LEVEL,"NEM %03d BoundaryMessageManager error "
235  "on message send (expected:%zu actual:%zd)",
236  id_,
237  packetDataLength,
238  len);
239  }
240  }
241  else
242  {
244  DEBUG_LEVEL,"NEM %03d BoundaryMessageManager "
245  "not connected",
246  id_);
247  }
248  }
249 
250  std::for_each(msgs.begin(),msgs.end(),[](const ControlMessage * p){delete p;});
251 }
252 
254 {
255  ssize_t len = 0;
256 
257  ControlMessageSerializer controlMessageSerializer(msgs);
258 
259  NetAdapterHeader header;
260  memset(&header,0,sizeof(header));
261 
262  header.u16Id_ = NETADAPTER_CTRL_MSG;
263  header.u32Length_ = sizeof(header) + controlMessageSerializer.getLength() + 4;
264 
265  NetAdapterHeaderToNet(&header);
266 
267  NetAdapterControlMessage controlMessage;
268 
269  memset(&controlMessage,0,sizeof(NetAdapterControlMessage));
270  controlMessage.u32CtrlLen_ = controlMessageSerializer.getLength();
271 
272  NetAdapterControlMessageToNet(&controlMessage);
273 
274  Utils::VectorIO vectorIO;
275  vectorIO.push_back({&header,sizeof(header)});
276  vectorIO.push_back({&controlMessage,sizeof(controlMessage)});
277 
278  const Utils::VectorIO & controlMessageVectorIO =
279  controlMessageSerializer.getVectorIO();
280 
281  vectorIO.insert(vectorIO.end(),
282  controlMessageVectorIO.begin(),
283  controlMessageVectorIO.end());
284 
285  if(protocol_ == Protocol::PROTOCOL_UDP)
286  {
287  if((len = udp_.send(&vectorIO[0],
288  static_cast<int>(vectorIO.size()),
289  remoteAddress_)) == -1)
290  {
292  ERROR_LEVEL,"NEM %03d BoundaryMessageManager "
293  "error on control message send (expected:%u actual:%zu)",
294  id_,
295  header.u32Length_,
296  len);
297  }
298  }
299  else
300  {
301  msghdr msg;
302  memset(&msg,0,sizeof(msg));
303 
304  msg.msg_iov = const_cast<iovec *>(&vectorIO[0]);
305  msg.msg_iovlen = vectorIO.size();
306 
307  std::lock_guard<std::mutex> m(mutex_);
308 
309  if(bConnected_)
310  {
311  if((len = sendmsg(iSessionSockFd_,&msg,0)) == -1)
312  {
314  ERROR_LEVEL,"NEM %03d BoundaryMessageManager "
315  "error on control message send (expected:%u actual:%zu)",
316  id_,
317  header.u32Length_,
318  len);
319  }
320  }
321  else
322  {
324  DEBUG_LEVEL,"NEM %03d BoundaryMessageManager "
325  "not connected",
326  id_);
327  }
328  }
329 
330  std::for_each(msgs.begin(),msgs.end(),[](const ControlMessage * p){delete p;});
331 }
332 
333 
334 void EMANE::BoundaryMessageManager::handleNetworkMessage(void * buf,size_t len)
335 {
336  NEMId dstNemId{};
337 
338  if(static_cast<size_t>(len) >= sizeof(NetAdapterHeader))
339  {
340  NetAdapterHeader * pHeader = reinterpret_cast<NetAdapterHeader *>(buf);
341 
342  NetAdapterHeaderToHost(pHeader);
343 
344  if(static_cast<size_t>(len) == pHeader->u32Length_)
345  {
346  len -= sizeof(NetAdapterHeader);
347 
348  switch(pHeader->u16Id_)
349  {
350  case NETADAPTER_DATA_MSG:
351 
352  if(static_cast<size_t>(len) >= sizeof(NetAdapterDataMessage))
353  {
354  NetAdapterDataMessage * pMsg = reinterpret_cast<NetAdapterDataMessage *>(pHeader->data_);
355 
357 
358  len -= sizeof(NetAdapterDataMessage);
359 
360  if(pMsg->u16Dst_ == htons(NETADAPTER_BROADCAST_ADDRESS))
361  {
362  dstNemId = NEM_BROADCAST_MAC_ADDRESS;
363  }
364  else
365  {
366  dstNemId = pMsg->u16Dst_;
367  }
368 
369  if(static_cast<size_t>(len) >= pMsg->u32DataLen_)
370  {
371  PacketInfo pinfo{pMsg->u16Src_, dstNemId, pMsg->u8Priority_,Clock::now()};
372 
373 
374  UpstreamPacket pkt(pinfo,
375  pMsg->data_,
376  pMsg->u32DataLen_);
377 
378  len -= pMsg->u32DataLen_;
379 
380  ControlMessages controlMessages;
381 
382  if(static_cast<size_t>(len) == pMsg->u32CtrlLen_)
383  {
384  const ControlMessages & controlMessages =
386  pMsg->u32CtrlLen_);
387 
388  try
389  {
391  pMsg->data_,
392  pMsg->u32DataLen_,
393  controlMessages);
394  }
395  catch(...)
396  {
397  // cannot really do too much at this point, so we'll log it
398  // good candidate spot to generate and error event as well
400  ERROR_LEVEL,
401  "NEM %03d BoundaryMessageManager::processNetworkMessage "
402  "processUpstreamPacket exception caught",
403  id_);
404  }
405  }
406  else
407  {
409  ERROR_LEVEL,
410  "NEM %03d BoundaryMessageManager::processNetworkMessage "
411  "processUpstreamPacket size too small for control message data",
412  id_);
413 
414 
415  }
416 
417  }
418  else
419  {
421  ERROR_LEVEL,
422  "NEM %03d BoundaryMessageManager::processNetworkMessage "
423  "processUpstreamPacket size too small for data message",
424  id_);
425  }
426  }
427  else
428  {
430  ERROR_LEVEL,
431  "NEM %03d BoundaryMessageManager::processNetworkMessage "
432  "processUpstreamPacket size too small for packet data message",
433  id_);
434  }
435 
436  break;
437 
438  case NETADAPTER_CTRL_MSG:
439 
440  if(static_cast<size_t>(len) >= sizeof(NetAdapterControlMessage))
441  {
442  NetAdapterControlMessage * pMsg =
443  reinterpret_cast<NetAdapterControlMessage *>(pHeader->data_);
444 
446 
447  len -= sizeof(NetAdapterControlMessage);
448 
449  ControlMessages controlMessages;
450 
451  if(static_cast<size_t>(len) == pMsg->u32CtrlLen_)
452  {
453  const ControlMessages & controlMessages =
455  pMsg->u32CtrlLen_);
456 
457  try
458  {
459  doProcessControlMessage(controlMessages);
460  }
461  catch(...)
462  {
463  // cannot really do too much at this point, so we'll log it
464  // good candidate spot to generate and error event as well
466  ERROR_LEVEL,
467  "NEM %03d BoundaryMessageManager::processNetworkMessage "
468  "processDownstreamControl exception caught",
469  id_);
470  }
471  }
472  else
473  {
475  ERROR_LEVEL,
476  "NEM %03d BoundaryMessageManager control message size mismatch",
477  id_);
478  }
479  }
480 
481  break;
482 
483  default:
485  ERROR_LEVEL,
486  "NEM %03d BoundaryMessageManager Received unknown message type: %d",
487  id_,
488  pHeader->u16Id_);
489  break;
490  }
491  }
492  else
493  {
495  ERROR_LEVEL,
496  "NEM %03d BoundaryMessageManager Message mismatch expected %hd got %zd",
497  id_,
498  pHeader->u32Length_,
499  len);
500  }
501  }
502  else
503  {
505  ERROR_LEVEL,
506  "NEM %03d BoundaryMessageManager Message Header mismatch expected %zu got %zd",
507  id_,
508  sizeof(NetAdapterHeader),
509  len);
510  }
511 }
512 
513 void EMANE::BoundaryMessageManager::processNetworkMessageUDP()
514 {
515  unsigned char buf[65536];
516  ssize_t len = 0;
517 
519  DEBUG_LEVEL,
520  "NEM %03d BoundaryMessageManager::processNetworkMessage",
521  id_);
522 
523  while(1)
524  {
525  if((len = udp_.recv(buf,sizeof(buf),0)) > 0)
526  {
528  DEBUG_LEVEL,
529  "NEM %03d BoundaryMessageManager Pkt Rcvd len: %zd",
530  id_,len);
531 
532  handleNetworkMessage(buf,len);
533  }
534  else
535  {
536  // read error
538  ERROR_LEVEL,
539  "NEM %03d BoundaryMessageManager Message Header read error",
540  id_);
541 
542  break;
543  }
544  }
545 }
546 
547 void EMANE::BoundaryMessageManager::processNetworkMessageTCP()
548 {
549  unsigned char buf[1024];
550  std::uint32_t u32MessageSizeBytes{};
551  std::vector<uint8_t> message{};
552  bool bLocalConnected{};
553  bool bLocalOpen{};
554  int iSockFd{-1};
555 
557  DEBUG_LEVEL,
558  "NEM %03d BoundaryMessageManager::processNetworkMessageTCP",
559  id_);
560  while(1)
561  {
562  if(!bLocalOpen)
563  {
564  if((iSockFd = socket(localAddress_.getFamily(),
565  SOCK_STREAM,
566  0)) == -1)
567  {
569  ERROR_LEVEL,
570  "NEM %03d BoundaryMessageManager socket open error: %s",
571  id_,
572  strerror(errno));
573 
574  break;
575  }
576 
577  int iOption{1};
578 
579  if(setsockopt(iSockFd,
580  SOL_SOCKET,
581  SO_REUSEADDR,
582  reinterpret_cast<void*>(&iOption),
583  sizeof(iOption)) < 0)
584  {
586  ERROR_LEVEL,
587  "NEM %03d BoundaryMessageManager socket SO_REUSEADDR error: %s",
588  id_,
589  strerror(errno));
590 
591  break;
592  }
593 
594  if(::bind(iSockFd,
595  localAddress_.getSockAddr(),
596  localAddress_.getAddrLength()) < 0)
597  {
599  ERROR_LEVEL,
600  "NEM %03d BoundaryMessageManager socket bind error: %s",
601  id_,
602  strerror(errno));
603  break;
604  }
605 
606  if(protocol_ == Protocol::PROTOCOL_TCP_SERVER)
607  {
608  if(listen(iSockFd,1) < 0)
609  {
611  ERROR_LEVEL,
612  "NEM %03d BoundaryMessageManager socket listen error: %s",
613  id_,
614  strerror(errno));
615  break;
616  }
617  }
618 
619  bLocalOpen = true;
620 
621  // store socket for proper shutdown on boundry close
622  std::lock_guard<std::mutex> m(mutex_);
623  iSockFd_ = iSockFd;
624  }
625 
626  int iConnectionSockFd{};
627 
628  while(!bLocalConnected)
629  {
630  if(protocol_ == Protocol::PROTOCOL_TCP_SERVER)
631  {
632  if((iConnectionSockFd = accept(iSockFd_,nullptr,nullptr)) > 0)
633  {
634  bLocalConnected = true;
635  }
636  else
637  {
638  if(errno == EINTR)
639  {
640  continue;
641  }
642  else
643  {
644  return;
645  }
646  }
647  }
648  else if(protocol_ == Protocol::PROTOCOL_TCP_CLIENT)
649  {
650  if(connect(iSockFd_,
651  remoteAddress_.getSockAddr(),
652  remoteAddress_.getAddrLength()))
653  {
654  // wait and try again
655  sleep(1);
656  }
657  else
658  {
659  bLocalConnected = true;
660  }
661  }
662  }
663 
664  // allow sending methods to transmit
665  mutex_.lock();
666 
667  bConnected_ = bLocalConnected;
668 
669  if(protocol_ == Protocol::PROTOCOL_TCP_SERVER)
670  {
671  iSessionSockFd_ = iConnectionSockFd;
672  }
673  else if(protocol_ == Protocol::PROTOCOL_TCP_CLIENT)
674  {
675  iSessionSockFd_ = iSockFd_;
676  iConnectionSockFd = iSockFd_;
677  }
678 
679  mutex_.unlock();
680 
682  INFO_LEVEL,
683  "NEM %03d BoundaryMessageManager connected",
684  id_);
685  while(bLocalConnected)
686  {
687  bool bDoDisconnect{};
688 
689  // process the session data
690  if(u32MessageSizeBytes == 0)
691  {
692  ssize_t length{}; // number of bytes received
693 
694  // read at most 6 bytes from peer to determine message length
695  length = recv(iConnectionSockFd,buf,6 - message.size(),0);
696 
697  if(length > 0)
698  {
699  // save the contents of the message header
700  message.insert(message.end(),&buf[0],&buf[length]);
701 
702  // is the entire header present
703  if(message.size() == 6)
704  {
705  u32MessageSizeBytes = ntohl(*reinterpret_cast<std::uint32_t *>(&message[2]));
706 
707  // a message length of 0 is not allowed
708  if(!u32MessageSizeBytes)
709  {
711  ERROR_LEVEL,
712  "NEM %03d BoundaryMessageManager Message Header read error",
713  id_);
714  bDoDisconnect = true;
715  }
716  }
717  }
718  else
719  {
721  ERROR_LEVEL,
722  "NEM %03d BoundaryMessageManager Message Header read error",
723  id_);
724  bDoDisconnect = true;
725  }
726  }
727  else
728  {
729  // attempt to read message length remaining or max buffer size
730  ssize_t length{};
731 
732  length = recv(iConnectionSockFd,
733  buf,
734  u32MessageSizeBytes - message.size() > sizeof(buf) ?
735  sizeof(buf) : u32MessageSizeBytes - message.size(),
736  0);
737 
738  if(length > 0)
739  {
740  message.insert(message.end(),&buf[0],&buf[length]);
741 
742  // process message when full message is read
743  if(message.size() == u32MessageSizeBytes)
744  {
746  DEBUG_LEVEL,
747  "NEM %03d BoundaryMessageManager Pkt Rcvd len: %zd",
748  id_,
749  message.size());
750 
751  handleNetworkMessage(&message[0],message.size());
752 
753  message.clear();
754  u32MessageSizeBytes = 0;
755  }
756  }
757  else
758  {
760  ERROR_LEVEL,
761  "NEM %03d BoundaryMessageManager Message Header read error",
762  id_);
763 
764  bDoDisconnect = true;
765  }
766  }
767 
768  if(bDoDisconnect)
769  {
770  message.clear();
771  u32MessageSizeBytes = 0;
772  bLocalConnected = false;
773  }
774  }
775 
776  std::lock_guard<std::mutex> m(mutex_);
777  bConnected_ = false;
778 
779  // iConnectionSockFd == iSocketFd for TCP_CLIENT
780  ::close(iConnectionSockFd);
781 
782  if(protocol_ == Protocol::PROTOCOL_TCP_CLIENT)
783  {
784  bLocalOpen = false;
785  }
786 
788  INFO_LEVEL,
789  "NEM %03d BoundaryMessageManager disconnected",
790  id_);
791 
792  }
793 }
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
socklen_t getAddrLength() const
Definition: inetaddr.cc:404
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
void open(const INETAddr &localAddress, const INETAddr &remoteAddress, Protocol protocol)
NEMId getDestination() const
Definition: packetinfo.inl:70
sockaddr * getSockAddr() const
Definition: inetaddr.cc:399
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
std::uint16_t NEMId
Definition: types.h:52
int getFamily() const
Definition: inetaddr.cc:394
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