INET Framework for OMNeT++/OMNEST
inet::tcp::TCP_NSC Class Reference

Encapsulates a Network Simulation Cradle (NSC) instance. More...

#include <TCP_NSC.h>

Inheritance diagram for inet::tcp::TCP_NSC:
inet::ILifecycle

Public Member Functions

 TCP_NSC ()
 
virtual ~TCP_NSC ()
 
virtual void send_callback (const void *, int) override
 Called from the stack when a packet needs to be output to the wire. More...
 
virtual void wakeup () override
 This is called when something interesting happened to a socket. More...
 
virtual void gettime (unsigned int *, unsigned int *) override
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Types

enum  { MAX_SEND_BYTES = 500000 }
 
typedef std::map< int, TCP_NSC_ConnectionTcpAppConnMap
 
typedef std::map< u_int32_t, L3AddressNsc2RemoteMap
 
typedef std::map< L3Address, u_int32_tRemote2NscMap
 
typedef std::map< TCP_NSC_Connection::SockPair, int > SockPair2ConnIdMap
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msgP) override
 
virtual void finish () override
 
void changeAddresses (TCP_NSC_Connection &connP, const TCP_NSC_Connection::SockPair &inetSockPairP, const TCP_NSC_Connection::SockPair &nscSockPairP)
 
TCP_NSC_ConnectionfindAppConn (int connIdP)
 
TCP_NSC_ConnectionfindConnByInetSockPair (TCP_NSC_Connection::SockPair const &sockPairP)
 
TCP_NSC_ConnectionfindConnByNscSockPair (TCP_NSC_Connection::SockPair const &sockPairP)
 
virtual void refreshDisplay () const override
 
void removeConnection (int connIdP)
 
void printConnBrief (TCP_NSC_Connection &connP)
 
void loadStack (const char *stacknameP, int bufferSizeP)
 
void handleAppMessage (cMessage *msgP)
 
void handleIpInputMessage (TCPSegment *tcpsegP)
 
void sendDataToApp (TCP_NSC_Connection &c)
 
void sendErrorNotificationToApp (TCP_NSC_Connection &c, int err)
 
void sendToIP (const void *dataP, int lenP)
 
void processAppCommand (TCP_NSC_Connection &connP, cMessage *msgP)
 
void process_OPEN_ACTIVE (TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void process_OPEN_PASSIVE (TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void process_SEND (TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cPacket *msgP)
 
void process_CLOSE (TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void process_ABORT (TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void process_STATUS (TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void do_SEND (TCP_NSC_Connection &connP)
 
void do_SEND_all ()
 
u_int32_t mapRemote2Nsc (L3Address const &addrP)
 
L3Address const & mapNsc2Remote (u_int32_t nscAddrP)
 
void sendEstablishedMsg (TCP_NSC_Connection &connP)
 
virtual TCP_NSC_SendQueuecreateSendQueue (TCPDataTransferMode transferModeP)
 To be called from TCPConnection: create a new send queue. More...
 
virtual TCP_NSC_ReceiveQueuecreateReceiveQueue (TCPDataTransferMode transferModeP)
 To be called from TCPConnection: create a new receive queue. More...
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 

Protected Attributes

TcpAppConnMap tcpAppConnMapM
 
SockPair2ConnIdMap inetSockPair2ConnIdMapM
 
SockPair2ConnIdMap nscSockPair2ConnIdMapM
 
Nsc2RemoteMap nsc2RemoteMapM
 
Remote2NscMap remote2NscMapM
 
INetStack * pStackM
 
cMessage * pNsiTimerM
 
bool isAliveM
 
int curAddrCounterM
 
TCP_NSC_ConnectioncurConnM
 
cOutVector * sndNxtVector
 
cOutVector * sndAckVector
 
cOutVector * rcvSeqVector
 
cOutVector * rcvAckVector
 

Static Protected Attributes

static const L3Address localInnerIpS
 
static const L3Address localInnerGwS
 
static const L3Address localInnerMaskS
 
static const L3Address remoteFirstInnerIpS
 
static const char * stackNameParamNameS = "stackName"
 
static const char * bufferSizeParamNameS = "stackBufferSize"
 

Detailed Description

Encapsulates a Network Simulation Cradle (NSC) instance.

Member Typedef Documentation

typedef std::map<int, TCP_NSC_Connection> inet::tcp::TCP_NSC::TcpAppConnMap
protected

Member Enumeration Documentation

anonymous enum
protected
Enumerator
MAX_SEND_BYTES 
52 { MAX_SEND_BYTES = 500000 };
Definition: TCP_NSC.h:52

Constructor & Destructor Documentation

inet::tcp::TCP_NSC::TCP_NSC ( )
147  : pStackM(nullptr),
148  pNsiTimerM(nullptr),
149  isAliveM(false),
150  curAddrCounterM(0),
151  curConnM(nullptr),
152 
153  // statistics:
154  sndNxtVector(nullptr),
155  sndAckVector(nullptr),
156  rcvSeqVector(nullptr),
157  rcvAckVector(nullptr)
158 {
159  // statistics:
160  if (true) { // (getTcpMain()->recordStatistics)
161  sndNxtVector = new cOutVector("sent seq");
162  sndAckVector = new cOutVector("sent ack");
163  rcvSeqVector = new cOutVector("rcvd seq");
164  rcvAckVector = new cOutVector("rcvd ack");
165  }
166 }
INetStack * pStackM
Definition: TCP_NSC.h:161
cOutVector * sndAckVector
Definition: TCP_NSC.h:181
cOutVector * rcvSeqVector
Definition: TCP_NSC.h:182
bool isAliveM
Definition: TCP_NSC.h:166
int curAddrCounterM
Definition: TCP_NSC.h:168
TCP_NSC_Connection * curConnM
Definition: TCP_NSC.h:169
cOutVector * rcvAckVector
Definition: TCP_NSC.h:183
cOutVector * sndNxtVector
Definition: TCP_NSC.h:180
cMessage * pNsiTimerM
Definition: TCP_NSC.h:163
inet::tcp::TCP_NSC::~TCP_NSC ( )
virtual
251 {
252  EV_TRACE << this << ": destructor\n";
253  isAliveM = false;
254 
255  while (!tcpAppConnMapM.empty()) {
256  auto i = tcpAppConnMapM.begin();
257  delete (*i).second.pNscSocketM;
258  tcpAppConnMapM.erase(i);
259  }
260 
261  // statistics
262  delete sndNxtVector;
263  delete sndAckVector;
264  delete rcvSeqVector;
265  delete rcvAckVector;
266 }
cOutVector * sndAckVector
Definition: TCP_NSC.h:181
cOutVector * rcvSeqVector
Definition: TCP_NSC.h:182
bool isAliveM
Definition: TCP_NSC.h:166
cOutVector * rcvAckVector
Definition: TCP_NSC.h:183
cOutVector * sndNxtVector
Definition: TCP_NSC.h:180
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154

Member Function Documentation

void inet::tcp::TCP_NSC::changeAddresses ( TCP_NSC_Connection connP,
const TCP_NSC_Connection::SockPair inetSockPairP,
const TCP_NSC_Connection::SockPair nscSockPairP 
)
protected

Referenced by handleIpInputMessage(), process_OPEN_ACTIVE(), process_OPEN_PASSIVE(), and sendToIP().

290 {
291  if (!(connP.inetSockPairM == inetSockPairP)) {
292  EV_DEBUG << "conn:" << connP << " change inetMap from " << connP.inetSockPairM << " to " << inetSockPairP << "\n";
293  inetSockPair2ConnIdMapM.erase(connP.inetSockPairM);
294  connP.inetSockPairM = inetSockPairP;
295  inetSockPair2ConnIdMapM[connP.inetSockPairM] = connP.connIdM;
296  }
297 
298  if (!(connP.nscSockPairM == nscSockPairP)) {
299  EV_DEBUG << "conn:" << connP << " change nscMap from " << connP.nscSockPairM << " to " << nscSockPairP << "\n";
300  // remove old from map:
301  nscSockPair2ConnIdMapM.erase(connP.nscSockPairM);
302  // change addresses:
303  connP.nscSockPairM = nscSockPairP;
304  // and add to map:
305  nscSockPair2ConnIdMapM[connP.nscSockPairM] = connP.connIdM;
306  }
307 }
SockPair2ConnIdMap inetSockPair2ConnIdMapM
Definition: TCP_NSC.h:155
SockPair2ConnIdMap nscSockPair2ConnIdMapM
Definition: TCP_NSC.h:156
TCP_NSC_ReceiveQueue * inet::tcp::TCP_NSC::createReceiveQueue ( TCPDataTransferMode  transferModeP)
protectedvirtual

To be called from TCPConnection: create a new receive queue.

Referenced by handleAppMessage().

598 {
599  switch (transferModeP) {
601  return new TCP_NSC_VirtualDataReceiveQueue();
602 
604  return new TCP_NSC_ByteStreamReceiveQueue();
605 
606  case TCP_TRANSFER_OBJECT: //return new TCP_NSC_MsgBasedReceiveQueue();
607  default:
608  throw cRuntimeError("Invalid TCP data transfer mode: %d at %s", transferModeP, this->getFullPath().c_str());
609  }
610 }
Definition: TCPCommand_m.h:255
Definition: TCPCommand_m.h:257
Definition: TCPCommand_m.h:256
TCP_NSC_SendQueue * inet::tcp::TCP_NSC::createSendQueue ( TCPDataTransferMode  transferModeP)
protectedvirtual

To be called from TCPConnection: create a new send queue.

Referenced by handleAppMessage().

583 {
584  switch (transferModeP) {
586  return new TCP_NSC_VirtualDataSendQueue();
587 
589  return new TCP_NSC_ByteStreamSendQueue();
590 
591  case TCP_TRANSFER_OBJECT: //return new TCP_NSC_MsgBasedSendQueue();
592  default:
593  throw cRuntimeError("Invalid TCP data transfer mode: %d at %s", transferModeP, this->getFullPath().c_str());
594  }
595 }
Definition: TCPCommand_m.h:255
Definition: TCPCommand_m.h:257
Definition: TCPCommand_m.h:256
void inet::tcp::TCP_NSC::do_SEND ( TCP_NSC_Connection connP)
protected
void inet::tcp::TCP_NSC::do_SEND_all ( )
protected

Referenced by handleMessage().

1067 {
1068  for (auto & elem : tcpAppConnMapM) {
1069  TCP_NSC_Connection& conn = elem.second;
1070  conn.do_SEND();
1071  }
1072 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154
TCP_NSC_Connection * inet::tcp::TCP_NSC::findAppConn ( int  connIdP)
protected

Referenced by findConnByInetSockPair(), findConnByNscSockPair(), and handleAppMessage().

699 {
700  auto i = tcpAppConnMapM.find(connIdP);
701  return i == tcpAppConnMapM.end() ? nullptr : &(i->second);
702 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154
TCP_NSC_Connection * inet::tcp::TCP_NSC::findConnByInetSockPair ( TCP_NSC_Connection::SockPair const &  sockPairP)
protected

Referenced by handleIpInputMessage().

705 {
706  auto i = inetSockPair2ConnIdMapM.find(sockPairP);
707  return i == inetSockPair2ConnIdMapM.end() ? nullptr : findAppConn(i->second);
708 }
TCP_NSC_Connection * findAppConn(int connIdP)
Definition: TCP_NSC.cc:698
SockPair2ConnIdMap inetSockPair2ConnIdMapM
Definition: TCP_NSC.h:155
TCP_NSC_Connection * inet::tcp::TCP_NSC::findConnByNscSockPair ( TCP_NSC_Connection::SockPair const &  sockPairP)
protected

Referenced by sendToIP().

711 {
712  auto i = nscSockPair2ConnIdMapM.find(sockPairP);
713  return i == nscSockPair2ConnIdMapM.end() ? nullptr : findAppConn(i->second);
714 }
TCP_NSC_Connection * findAppConn(int connIdP)
Definition: TCP_NSC.cc:698
SockPair2ConnIdMap nscSockPair2ConnIdMapM
Definition: TCP_NSC.h:156
void inet::tcp::TCP_NSC::finish ( )
overrideprotectedvirtual
717 {
718  isAliveM = false;
719 }
bool isAliveM
Definition: TCP_NSC.h:166
void inet::tcp::TCP_NSC::gettime ( unsigned int *  secP,
unsigned int *  usecP 
)
overridevirtual
815 {
816 #ifdef USE_DOUBLE_SIMTIME
817  double t = simTime().dbl();
818  *sec = (unsigned int)(t);
819  *usec = (unsigned int)((t - *sec) * 1000000 + 0.5);
820 #else // ifdef USE_DOUBLE_SIMTIME
821  simtime_t t = simTime();
822  int64 raw = t.raw();
823  int64 scale = t.getScale();
824  int64 secs = raw / scale;
825  int64 usecs = (raw - (secs * scale));
826 
827  //usecs = usecs * 1000000 / scale;
828  if (scale > 1000000) // scale always 10^n
829  usecs /= (scale / 1000000);
830  else
831  usecs *= (1000000 / scale);
832 
833  *secP = secs;
834  *usecP = usecs;
835 #endif // ifdef USE_DOUBLE_SIMTIME
836 
837  EV_TRACE << this << ": gettime(" << *secP << "," << *usecP << ") called\n";
838 }
int64_t int64
Definition: Compat.h:29
void inet::tcp::TCP_NSC::handleAppMessage ( cMessage *  msgP)
protected

Referenced by handleMessage().

613 {
614  TCPCommand *controlInfo = check_and_cast<TCPCommand *>(msgP->getControlInfo());
615  int connId = controlInfo->getConnId();
616 
617  TCP_NSC_Connection *conn = findAppConn(connId);
618 
619  if (!conn) {
620  TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(controlInfo);
621 
622  // add into appConnMap
623  conn = &tcpAppConnMapM[connId];
624  conn->tcpNscM = this;
625  conn->connIdM = connId;
626  conn->appGateIndexM = msgP->getArrivalGate()->getIndex();
627  conn->pNscSocketM = nullptr; // will be filled in within processAppCommand()
628 
629  TCPDataTransferMode transferMode = (TCPDataTransferMode)(openCmd->getDataTransferMode());
630  // create send queue
631  conn->sendQueueM = createSendQueue(transferMode);
632  conn->sendQueueM->setConnection(conn);
633 
634  // create receive queue
635  conn->receiveQueueM = createReceiveQueue(transferMode);
636  conn->receiveQueueM->setConnection(conn);
637 
638  EV_INFO << this << ": TCP connection created for " << msgP << "\n";
639  }
640 
641  processAppCommand(*conn, msgP);
642 }
az accept haszálja pcb új connId
Definition: lwip_tcp.txt:38
TCPDataTransferMode
Enum generated from inet/transportlayer/contract/tcp/TCPCommand.msg:120 by nedtool.
Definition: TCPCommand_m.h:253
TCP_NSC_Connection * findAppConn(int connIdP)
Definition: TCP_NSC.cc:698
virtual TCP_NSC_SendQueue * createSendQueue(TCPDataTransferMode transferModeP)
To be called from TCPConnection: create a new send queue.
Definition: TCP_NSC.cc:582
virtual TCP_NSC_ReceiveQueue * createReceiveQueue(TCPDataTransferMode transferModeP)
To be called from TCPConnection: create a new receive queue.
Definition: TCP_NSC.cc:597
void processAppCommand(TCP_NSC_Connection &connP, cMessage *msgP)
Definition: TCP_NSC.cc:924
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154
void inet::tcp::TCP_NSC::handleIpInputMessage ( TCPSegment tcpsegP)
protected

Referenced by handleMessage().

310 {
311  // get src/dest addresses
312  TCP_NSC_Connection::SockPair nscSockPair, inetSockPair, inetSockPairAny;
313 
314  cObject *ctrl = tcpsegP->removeControlInfo();
315  if (!ctrl)
316  throw cRuntimeError("(%s)%s arrived without control info", tcpsegP->getClassName(), tcpsegP->getName());
317 
318  INetworkProtocolControlInfo *controlInfo = check_and_cast<INetworkProtocolControlInfo *>(ctrl);
319  inetSockPair.remoteM.ipAddrM = controlInfo->getSourceAddress();
320  inetSockPair.localM.ipAddrM = controlInfo->getDestinationAddress();
321  //int interfaceId = controlInfo->getInterfaceId();
322 
323  if (dynamic_cast<IPv6ControlInfo *>(ctrl) != nullptr) {
324  {
325  // HACK: when IPv6, then correcting the TCPOPTION_MAXIMUM_SEGMENT_SIZE option
326  // with IP header size difference
327  unsigned short numOptions = tcpsegP->getHeaderOptionArraySize();
328  for (unsigned short i = 0; i < numOptions; i++) {
329  TCPOption* option = tcpsegP->getHeaderOption(i);
330  if (option->getKind() == TCPOPTION_MAXIMUM_SEGMENT_SIZE) {
331  TCPOptionMaxSegmentSize *mssOption = dynamic_cast<TCPOptionMaxSegmentSize *>(option);
332  if (mssOption) {
333  unsigned int value = mssOption->getMaxSegmentSize();
334  value -= sizeof(struct nsc_ipv6hdr) - sizeof(struct nsc_iphdr);
335  mssOption->setMaxSegmentSize(value);
336  }
337  }
338  }
339  }
340  }
341  delete ctrl;
342 
343  // statistics:
344  if (rcvSeqVector)
345  rcvSeqVector->record(tcpsegP->getSequenceNo());
346 
347  if (rcvAckVector)
348  rcvAckVector->record(tcpsegP->getAckNo());
349 
350  inetSockPair.remoteM.portM = tcpsegP->getSrcPort();
351  inetSockPair.localM.portM = tcpsegP->getDestPort();
352  nscSockPair.remoteM.portM = tcpsegP->getSrcPort();
353  nscSockPair.localM.portM = tcpsegP->getDestPort();
354  inetSockPairAny.localM = inetSockPair.localM;
355 
356  // process segment
357  size_t ipHdrLen = sizeof(nsc_iphdr);
358  size_t const maxBufferSize = 4096;
359  char *data = new char[maxBufferSize];
360  memset(data, 0, maxBufferSize);
361  uint32_t nscSrcAddr = mapRemote2Nsc(inetSockPair.remoteM.ipAddrM);
362  nscSockPair.localM.ipAddrM = localInnerIpS;
363  nscSockPair.remoteM.ipAddrM.set(IPv4Address(nscSrcAddr));
364 
365  EV_DETAIL << this << ": data arrived for interface of stack " << pStackM << "\n"
366  << " src:" << inetSockPair.remoteM.ipAddrM << ",dest:" << inetSockPair.localM.ipAddrM << "\n";
367 
368  nsc_iphdr *ih = (nsc_iphdr *)data;
369  tcphdr *tcph = (tcphdr *)(data + ipHdrLen);
370  // set IP header:
371  ih->version = 4;
372  ih->ihl = ipHdrLen / 4;
373  ih->tos = 0;
374  ih->id = htons(tcpsegP->getSequenceNo());
375  ih->frag_off = htons(0x4000); // don't fragment, offset = 0;
376  ih->ttl = 64;
377  ih->protocol = 6; // TCP
378  ih->check = 0;
379  ih->saddr = htonl(nscSrcAddr);
380  ih->daddr = htonl(localInnerIpS.toIPv4().getInt());
381 
382  EV_DEBUG << this << ": modified to: IP " << ih->version << " len " << ih->ihl
383  << " protocol " << (unsigned int)(ih->protocol)
384  << " saddr " << (ih->saddr)
385  << " daddr " << (ih->daddr)
386  << "\n";
387 
388  size_t totalTcpLen = maxBufferSize - ipHdrLen;
389  TCP_NSC_Connection *conn;
390  conn = findConnByInetSockPair(inetSockPair);
391 
392  if (!conn) {
393  conn = findConnByInetSockPair(inetSockPairAny);
394  }
395 
396  { // local scope for 'b' and 'c'
397  Buffer b(tcph, totalTcpLen);
398  Context c;
399  c.l3AddressesPtr = &ih->saddr;
400  c.l3AddressesLength = 8;
401  TCPSerializer().serializePacket(tcpsegP, b, c);
402  totalTcpLen = b.getPos();
403  }
404 
405  if (conn) {
406  conn->receiveQueueM->notifyAboutIncomingSegmentProcessing(tcpsegP);
407  }
408 
409  size_t totalIpLen = ipHdrLen + totalTcpLen;
410  ih->tot_len = htons(totalIpLen);
411  ih->check = 0;
412  ih->check = htons(TCPIPchecksum::checksum(ih, ipHdrLen));
413 
414  // receive msg from network
415 
416  pStackM->if_receive_packet(0, data, totalIpLen);
417 
418  // Attempt to read from sockets
419  int changes = 0;
420 
421  for (auto & elem : tcpAppConnMapM) {
422  TCP_NSC_Connection& c = elem.second;
423 
424  if (c.pNscSocketM && c.isListenerM) {
425  // accepting socket
426  EV_DETAIL << this << ": NSC: attempting to accept:\n";
427 
428  INetStreamSocket *sock = nullptr;
429  int err;
430 
431  err = c.pNscSocketM->accept(&sock);
432 
433  EV_DETAIL << this << ": accept returned " << err << " , sock is " << sock
434  << " socket" << c.pNscSocketM << "\n";
435 
436  if (sock) {
437  ASSERT(changes == 0);
438  ASSERT(c.inetSockPairM.localM.portM == inetSockPair.localM.portM);
439  ++changes;
440 
441  int newConnId = getEnvir()->getUniqueNumber();
442  // add into appConnMap
443  TCP_NSC_Connection *conn = &tcpAppConnMapM[newConnId];
444  conn->tcpNscM = this;
445  conn->connIdM = newConnId;
446  conn->appGateIndexM = c.appGateIndexM;
447  conn->pNscSocketM = sock;
448 
449  // set sockPairs:
450  changeAddresses(*conn, inetSockPair, nscSockPair);
451 
452  // following code to be kept consistent with initConnection()
453  const char *sendQueueClass = c.sendQueueM->getClassName();
454  conn->sendQueueM = check_and_cast<TCP_NSC_SendQueue *>(inet::utils::createOne(sendQueueClass));
455  conn->sendQueueM->setConnection(conn);
456 
457  const char *receiveQueueClass = c.receiveQueueM->getClassName();
458  conn->receiveQueueM = check_and_cast<TCP_NSC_ReceiveQueue *>(inet::utils::createOne(receiveQueueClass));
459  conn->receiveQueueM->setConnection(conn);
460  EV_DETAIL << this << ": NSC: got accept!\n";
461 
462  sendEstablishedMsg(*conn);
463  }
464  }
465  else if (c.pNscSocketM && !c.disconnectCalledM && c.pNscSocketM->is_connected()) { // not listener
466  bool hasData = false;
467  int err = NSC_EAGAIN;
468  EV_DEBUG << this << ": NSC: attempting to read from socket " << c.pNscSocketM << "\n";
469 
470  if ((!c.sentEstablishedM) && c.pNscSocketM->is_connected()) {
471  ASSERT(changes == 0);
472  hasData = true;
473  changeAddresses(c, inetSockPair, nscSockPair);
475  }
476 
477  while (true) {
478  static char buf[4096];
479 
480  int buflen = sizeof(buf);
481 
482  err = c.pNscSocketM->read_data(buf, &buflen);
483 
484  EV_DEBUG << this << ": NSC: read: err " << err << " , buflen " << buflen << "\n";
485 
486  if (err == 0 && buflen > 0) {
487  ASSERT(changes == 0);
488  if (!hasData)
489  changeAddresses(c, inetSockPair, nscSockPair);
490 
491  hasData = true;
492  c.receiveQueueM->enqueueNscData(buf, buflen);
493  err = NSC_EAGAIN;
494  }
495  else
496  break;
497  }
498 
499  if (hasData) {
500  sendDataToApp(c);
501  ++changes;
502  changeAddresses(c, inetSockPair, nscSockPair);
503  }
505  }
506  }
507 
508  /*
509  ...
510  NSC: process segment (data,len); should call removeConnection() if socket has
511  closed and completely done
512 
513  XXX: probably need to poll sockets to see if they are closed.
514  ...
515  */
516 
517  delete[] data;
518  delete tcpsegP;
519 }
Definition: TCPSegment_m.h:114
TCP_NSC_Connection * findConnByInetSockPair(TCP_NSC_Connection::SockPair const &sockPairP)
Definition: TCP_NSC.cc:704
INetStack * pStackM
Definition: TCP_NSC.h:161
cOutVector * rcvSeqVector
Definition: TCP_NSC.h:182
static const L3Address localInnerIpS
Definition: TCP_NSC.h:171
void set(AddressType type, uint64 lo)
Definition: L3Address.cc:37
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TCPIPchecksum.h:44
void changeAddresses(TCP_NSC_Connection &connP, const TCP_NSC_Connection::SockPair &inetSockPairP, const TCP_NSC_Connection::SockPair &nscSockPairP)
Definition: TCP_NSC.cc:287
cObject * createOne(const char *className, const char *defaultNamespace)
Like cObjectFactory::createOne(), except it starts searching for the class in the given namespace...
Definition: INETUtils.cc:105
u16_t htons(u16_t n)
void sendDataToApp(TCP_NSC_Connection &c)
Definition: TCP_NSC.cc:521
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
cOutVector * rcvAckVector
Definition: TCP_NSC.h:183
void sendErrorNotificationToApp(TCP_NSC_Connection &c, int err)
Definition: TCP_NSC.cc:538
u32_t htonl(u32_t n)
u_int32_t mapRemote2Nsc(L3Address const &addrP)
Definition: TCP_NSC.cc:170
uint32 getInt() const
Returns the address as an int.
Definition: IPv4Address.h:197
IPv4Address toIPv4() const
Definition: L3Address.h:76
value< double, units::m > b
Definition: Units.h:1054
void sendEstablishedMsg(TCP_NSC_Connection &connP)
Definition: TCP_NSC.cc:269
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154
void inet::tcp::TCP_NSC::handleMessage ( cMessage *  msgP)
overrideprotectedvirtual
645 {
646  if (msgP->isSelfMessage()) {
647  // timer expired
648  /*
649  ...
650  NSC timer processing
651  ...
652  Timers are ordinary cMessage objects that are started by
653  scheduleAt(simTime()+timeout, msg), and can be cancelled
654  via cancelEvent(msg); when they expire (fire) they are delivered
655  to the module via handleMessage(), i.e. they end up here.
656  */
657  if (msgP == pNsiTimerM) { // nsc_nsi_timer
658  do_SEND_all();
659 
660  pStackM->increment_ticks();
661 
662  pStackM->timer_interrupt();
663 
664  scheduleAt(msgP->getArrivalTime() + 1.0 / (double)pStackM->get_hz(), msgP);
665  }
666  }
667  else if (msgP->arrivedOn("ipIn")) {
668  if (false
669 #ifdef WITH_IPv4
670  || dynamic_cast<ICMPMessage *>(msgP)
671 #endif // ifdef WITH_IPv4
672 #ifdef WITH_IPv6
673  || dynamic_cast<ICMPv6Message *>(msgP)
674 #endif // ifdef WITH_IPv6
675  )
676  {
677  EV_WARN << "ICMP error received -- discarding\n"; // FIXME can ICMP packets really make it up to TCP???
678  delete msgP;
679  }
680  else {
681  EV_DEBUG << this << ": handle msg: " << msgP->getName() << "\n";
682  // must be a TCPSegment
683  TCPSegment *tcpseg = check_and_cast<TCPSegment *>(msgP);
684  handleIpInputMessage(tcpseg);
685  }
686  }
687  else { // must be from app
688  EV_DEBUG << this << ": handle msg: " << msgP->getName() << "\n";
689  handleAppMessage(msgP);
690  }
691 }
INetStack * pStackM
Definition: TCP_NSC.h:161
void handleIpInputMessage(TCPSegment *tcpsegP)
Definition: TCP_NSC.cc:309
void do_SEND_all()
Definition: TCP_NSC.cc:1066
void handleAppMessage(cMessage *msgP)
Definition: TCP_NSC.cc:612
cMessage * pNsiTimerM
Definition: TCP_NSC.h:163
bool inet::tcp::TCP_NSC::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

1151 {
1152  Enter_Method_Silent();
1153 
1154  throw cRuntimeError("Unsupported lifecycle operation '%s'", operation->getClassName());
1155  return true;
1156 }
void inet::tcp::TCP_NSC::initialize ( int  stage)
overrideprotectedvirtual
210 {
211  cSimpleModule::initialize(stage);
212 
213  EV_TRACE << this << ": initialize stage " << stage << endl;
214 
215  if (stage == INITSTAGE_LOCAL) {
216  const char *q;
217  q = par("sendQueueClass");
218 
219  if (*q != '\0')
220  throw cRuntimeError("Don't use obsolete sendQueueClass = \"%s\" parameter", q);
221 
222  q = par("receiveQueueClass");
223 
224  if (*q != '\0')
225  throw cRuntimeError("Don't use obsolete receiveQueueClass = \"%s\" parameter", q);
226 
227  WATCH_MAP(tcpAppConnMapM);
228 
229  // load the stack
230  const char *stackName = this->par(stackNameParamNameS).stringValue();
231  int bufferSize = (int)(this->par(bufferSizeParamNameS).longValue());
232  loadStack(stackName, bufferSize);
233  pStackM->if_attach(localInnerIpS.str().c_str(), localInnerMaskS.str().c_str(), 1500);
234  pStackM->add_default_gateway(localInnerGwS.str().c_str());
235  }
236  else if (stage == INITSTAGE_TRANSPORT_LAYER) {
237  bool isOperational;
238  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
239  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
240  if (!isOperational)
241  throw cRuntimeError("This module doesn't support starting in node DOWN state");
242  IPSocket ipSocket(gate("ipOut"));
243  ipSocket.registerProtocol(IP_PROT_TCP);
244  }
245  else if (stage == INITSTAGE_LAST) {
246  isAliveM = true;
247  }
248 }
Initialization of transport-layer protocols.
Definition: InitStages.h:90
INetStack * pStackM
Definition: TCP_NSC.h:161
static const char * bufferSizeParamNameS
Definition: TCP_NSC.h:177
bool isAliveM
Definition: TCP_NSC.h:166
static const L3Address localInnerMaskS
Definition: TCP_NSC.h:173
static const L3Address localInnerIpS
Definition: TCP_NSC.h:171
std::string str() const
Definition: L3Address.cc:86
Operations that no other initializations can depend on, e.g.
Definition: InitStages.h:111
static const L3Address localInnerGwS
Definition: TCP_NSC.h:172
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
static const char * stackNameParamNameS
Definition: TCP_NSC.h:176
void loadStack(const char *stacknameP, int bufferSizeP)
Definition: TCP_NSC.cc:734
Definition: IPProtocolId_m.h:80
Definition: NodeStatus.h:40
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154
void inet::tcp::TCP_NSC::loadStack ( const char *  stacknameP,
int  bufferSizeP 
)
protected

Referenced by initialize().

735 {
736  void *handle = nullptr;
737  FCreateStack create = nullptr;
738 
739  EV_DETAIL << this << ": Loading stack " << stacknameP << "\n";
740 
741  handle = dlopen(stacknameP, RTLD_NOW);
742 
743  if (!handle) {
744  throw cRuntimeError("The loading of '%s' NSC stack is unsuccessful: %s. Check the LD_LIBRARY_PATH or stackname!", stacknameP, dlerror());
745  }
746 
747  create = (FCreateStack)dlsym(handle, "nsc_create_stack");
748 
749  if (!create) {
750  throw cRuntimeError("The '%s' NSC stack creation unsuccessful: %s", stacknameP, dlerror());
751  }
752 
753  pStackM = create(this, this, nullptr);
754 
755  EV_DETAIL << "TCP_NSC " << this << " has stack " << pStackM << "\n";
756 
757  EV_DETAIL << "TCP_NSC " << this << "Initializing stack, name=" << pStackM->get_name() << endl;
758 
759  pStackM->init(pStackM->get_hz());
760 
761  pStackM->buffer_size(bufferSizeP);
762 
763  EV_INFO << "TCP_NSC " << this << "Stack initialized, name=" << pStackM->get_name() << endl;
764 
765  // set timer for 1.0 / pStackM->get_hz()
766  pNsiTimerM = new cMessage("nsc_nsi_timer");
767  scheduleAt(1.0 / (double)pStackM->get_hz(), pNsiTimerM);
768 }
INetStack * pStackM
Definition: TCP_NSC.h:161
cMessage * pNsiTimerM
Definition: TCP_NSC.h:163
L3Address const & inet::tcp::TCP_NSC::mapNsc2Remote ( u_int32_t  nscAddrP)
protected

Referenced by sendToIP().

197 {
198  auto i = nsc2RemoteMapM.find(nscAddrP);
199 
200  if (i != nsc2RemoteMapM.end())
201  return i->second;
202 
203  ASSERT(0);
204  exit(1);
205 }
Nsc2RemoteMap nsc2RemoteMapM
Definition: TCP_NSC.h:158
uint32_t inet::tcp::TCP_NSC::mapRemote2Nsc ( L3Address const &  addrP)
protected

Referenced by handleIpInputMessage(), process_OPEN_ACTIVE(), and process_OPEN_PASSIVE().

171 {
172  auto i = remote2NscMapM.find(addrP);
173  if (i != remote2NscMapM.end()) {
174  return i->second;
175  }
176 
177  // get first free remote NSC IP
178  uint32_t ret = remoteFirstInnerIpS.toIPv4().getInt();
179  for (auto & elem : nsc2RemoteMapM) {
180  if (elem.first > ret)
181  break;
182  ret = elem.first + 1;
183  }
184 
185  // add new pair to maps
186  remote2NscMapM[addrP] = ret;
187  nsc2RemoteMapM[ret] = addrP;
188  ASSERT(remote2NscMapM.find(addrP) != remote2NscMapM.end());
189  ASSERT(nsc2RemoteMapM.find(ret) != nsc2RemoteMapM.end());
190  return ret;
191 }
Nsc2RemoteMap nsc2RemoteMapM
Definition: TCP_NSC.h:158
Remote2NscMap remote2NscMapM
Definition: TCP_NSC.h:159
static const L3Address remoteFirstInnerIpS
Definition: TCP_NSC.h:174
uint32 getInt() const
Returns the address as an int.
Definition: IPv4Address.h:197
IPv4Address toIPv4() const
Definition: L3Address.h:76
virtual int inet::tcp::TCP_NSC::numInitStages ( ) const
inlineoverrideprotectedvirtual
71 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::tcp::TCP_NSC::printConnBrief ( TCP_NSC_Connection connP)
protected

Referenced by processAppCommand().

729 {
730  EV_DEBUG << this << ": connId=" << connP.connIdM << " appGateIndex=" << connP.appGateIndexM
731  << " nscsocket=" << connP.pNscSocketM << "\n";
732 }
void inet::tcp::TCP_NSC::process_ABORT ( TCP_NSC_Connection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

1085 {
1086  EV_INFO << this << ": process_ABORT()\n";
1087 
1088  delete tcpCommandP;
1089  delete msgP;
1090 
1091  connP.abort();
1092 }
void inet::tcp::TCP_NSC::process_CLOSE ( TCP_NSC_Connection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

1075 {
1076  EV_INFO << this << ": process_CLOSE()\n";
1077 
1078  delete tcpCommandP;
1079  delete msgP;
1080 
1081  connP.close();
1082 }
void inet::tcp::TCP_NSC::process_OPEN_ACTIVE ( TCP_NSC_Connection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

968 {
969  TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(tcpCommandP);
970 
971  TCP_NSC_Connection::SockPair inetSockPair, nscSockPair;
972  inetSockPair.localM.ipAddrM = openCmd->getLocalAddr();
973  inetSockPair.remoteM.ipAddrM = openCmd->getRemoteAddr();
974  inetSockPair.localM.portM = openCmd->getLocalPort();
975  inetSockPair.remoteM.portM = openCmd->getRemotePort();
976 
977  if (inetSockPair.remoteM.ipAddrM.isUnspecified() || inetSockPair.remoteM.portM == PORT_UNDEF)
978  throw cRuntimeError("Error processing command OPEN_ACTIVE: remote address and port must be specified");
979 
980  EV_INFO << this << ": OPEN: "
981  << inetSockPair.localM.ipAddrM << ":" << inetSockPair.localM.portM << " --> "
982  << inetSockPair.remoteM.ipAddrM << ":" << inetSockPair.remoteM.portM << "\n";
983 
984  // insert to map:
985  uint32_t nscRemoteAddr = mapRemote2Nsc(inetSockPair.remoteM.ipAddrM);
986 
987  ASSERT(pStackM);
988 
989  nscSockPair.localM.portM = inetSockPair.localM.portM;
990  if (nscSockPair.localM.portM == PORT_UNDEF)
991  nscSockPair.localM.portM = 0; // NSC uses 0 to mean "not specified"
992  nscSockPair.remoteM.ipAddrM.set(IPv4Address(nscRemoteAddr));
993  nscSockPair.remoteM.portM = inetSockPair.remoteM.portM;
994 
995  changeAddresses(connP, inetSockPair, nscSockPair);
996 
997  ASSERT(!curConnM);
998  curConnM = &connP;
999  connP.connect(*pStackM, inetSockPair, nscSockPair);
1000  curConnM = nullptr;
1001 
1002  // and add to map:
1003  // TODO sendToIp already set the addresses.
1004  //changeAddresses(connP, inetSockPair, nscSockPair);
1005 
1006  delete tcpCommandP;
1007  delete msgP;
1008 }
INetStack * pStackM
Definition: TCP_NSC.h:161
TCP_NSC_Connection * curConnM
Definition: TCP_NSC.h:169
void changeAddresses(TCP_NSC_Connection &connP, const TCP_NSC_Connection::SockPair &inetSockPairP, const TCP_NSC_Connection::SockPair &nscSockPairP)
Definition: TCP_NSC.cc:287
const short PORT_UNDEF
TCP/UDP port numbers.
Definition: IPv4Address.h:39
void connect(INetStack &stackP, SockPair &inetSockPairP, SockPair &nscSockPairP)
Definition: TCP_NSC_Connection.cc:86
u_int32_t mapRemote2Nsc(L3Address const &addrP)
Definition: TCP_NSC.cc:170
void inet::tcp::TCP_NSC::process_OPEN_PASSIVE ( TCP_NSC_Connection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

1011 {
1012  ASSERT(pStackM);
1013 
1014  TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(tcpCommandP);
1015 
1016  if (!openCmd->getFork())
1017  throw cRuntimeError("TCP_NSC supports Forking mode only");
1018 
1019  TCP_NSC_Connection::SockPair inetSockPair, nscSockPair;
1020  inetSockPair.localM.ipAddrM = openCmd->getLocalAddr();
1021  inetSockPair.remoteM.ipAddrM = openCmd->getRemoteAddr();
1022  inetSockPair.localM.portM = openCmd->getLocalPort();
1023  inetSockPair.remoteM.portM = openCmd->getRemotePort();
1024 
1025  uint32_t nscRemoteAddr = inetSockPair.remoteM.ipAddrM.isUnspecified()
1026  ? ntohl(INADDR_ANY)
1027  : mapRemote2Nsc(inetSockPair.remoteM.ipAddrM); // Don't remove! It's insert remoteAddr into MAP.
1028 
1029  (void)nscRemoteAddr; // Eliminate "unused variable" warning.
1030 
1031  if (inetSockPair.localM.portM == PORT_UNDEF)
1032  throw cRuntimeError("Error processing command OPEN_PASSIVE: local port must be specified");
1033 
1034  EV_INFO << this << "Starting to listen on: " << inetSockPair.localM.ipAddrM << ":" << inetSockPair.localM.portM << "\n";
1035 
1036  /*
1037  ...
1038  NSC: process passive open request
1039  ...
1040  */
1041  nscSockPair.localM.portM = inetSockPair.localM.portM;
1042 
1043  changeAddresses(connP, inetSockPair, nscSockPair);
1044 
1045  ASSERT(!curConnM);
1046  curConnM = &connP;
1047  connP.listen(*pStackM, inetSockPair, nscSockPair);
1048  curConnM = nullptr;
1049 
1050  changeAddresses(connP, inetSockPair, nscSockPair);
1051 
1052  delete openCmd;
1053  delete msgP;
1054 }
#define INADDR_ANY
Definition: inet.h:66
INetStack * pStackM
Definition: TCP_NSC.h:161
u32_t ntohl(u32_t n)
TCP_NSC_Connection * curConnM
Definition: TCP_NSC.h:169
void changeAddresses(TCP_NSC_Connection &connP, const TCP_NSC_Connection::SockPair &inetSockPairP, const TCP_NSC_Connection::SockPair &nscSockPairP)
Definition: TCP_NSC.cc:287
u_int32_t mapRemote2Nsc(L3Address const &addrP)
Definition: TCP_NSC.cc:170
void listen(INetStack &stackP, SockPair &inetSockPairP, SockPair &nscSockPairP)
Definition: TCP_NSC_Connection.cc:117
void inet::tcp::TCP_NSC::process_SEND ( TCP_NSC_Connection connP,
TCPCommand tcpCommandP,
cPacket *  msgP 
)
protected

Referenced by processAppCommand().

1057 {
1058  TCPSendCommand *sendCommand = check_and_cast<TCPSendCommand *>(tcpCommandP);
1059  delete sendCommand;
1060 
1061  connP.send(msgP);
1062 
1063  connP.do_SEND();
1064 }
void inet::tcp::TCP_NSC::process_STATUS ( TCP_NSC_Connection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

1095 {
1096  delete tcpCommandP; // but we'll reuse msg for reply
1097 
1098  TCPStatusInfo *statusInfo = new TCPStatusInfo();
1099 
1100  /*
1101  ...
1102  NSC: fill in status if possible
1103 
1104  Still more work to do here. Some of this needs to be implemented on
1105  the NSC side, which is fairly trivial, just updating the get_var
1106  function for each stack.
1107  ...
1108  */
1109 
1110  char result[512];
1111 
1112  ASSERT(connP.pNscSocketM);
1113 
1114  connP.pNscSocketM->get_var("cwnd_", result, sizeof(result));
1115  statusInfo->setSnd_wnd(atoi(result));
1116 
1117  statusInfo->setLocalAddr(connP.inetSockPairM.localM.ipAddrM);
1118  statusInfo->setRemoteAddr(connP.inetSockPairM.remoteM.ipAddrM);
1119  statusInfo->setLocalPort(connP.inetSockPairM.localM.portM);
1120  statusInfo->setRemotePort(connP.inetSockPairM.remoteM.portM);
1121  //connP.pNscSocketM->get_var("ssthresh_", result, sizeof(result));
1122  //connP.pNscSocketM->get_var("rxtcur_", result, sizeof(result));
1123 
1124 /* other TCP model:
1125  statusInfo->setState(fsm.getState());
1126  statusInfo->setStateName(stateName(fsm.getState()));
1127 
1128 
1129  statusInfo->setSnd_mss(state->snd_mss);
1130  statusInfo->setSnd_una(state->snd_una);
1131  statusInfo->setSnd_nxt(state->snd_nxt);
1132  statusInfo->setSnd_max(state->snd_max);
1133  statusInfo->setSnd_wnd(state->snd_wnd);
1134  statusInfo->setSnd_up(state->snd_up);
1135  statusInfo->setSnd_wl1(state->snd_wl1);
1136  statusInfo->setSnd_wl2(state->snd_wl2);
1137  statusInfo->setIss(state->iss);
1138  statusInfo->setRcv_nxt(state->rcv_nxt);
1139  statusInfo->setRcv_wnd(state->rcv_wnd);
1140  statusInfo->setRcv_up(state->rcv_up);
1141  statusInfo->setIrs(state->irs);
1142  statusInfo->setFin_ack_rcvd(state->fin_ack_rcvd);
1143  */
1144 
1145  msgP->setControlInfo(statusInfo);
1146  msgP->setKind(TCP_I_STATUS);
1147  send(msgP, "appOut", connP.appGateIndexM);
1148 }
Definition: TCPCommand_m.h:106
void inet::tcp::TCP_NSC::processAppCommand ( TCP_NSC_Connection connP,
cMessage *  msgP 
)
protected

Referenced by handleAppMessage().

925 {
926  printConnBrief(connP);
927 
928  // first do actions
929  TCPCommand *tcpCommand = (TCPCommand *)(msgP->removeControlInfo());
930 
931  switch (msgP->getKind()) {
932  case TCP_C_OPEN_ACTIVE:
933  process_OPEN_ACTIVE(connP, tcpCommand, msgP);
934  break;
935 
936  case TCP_C_OPEN_PASSIVE:
937  process_OPEN_PASSIVE(connP, tcpCommand, msgP);
938  break;
939 
940  case TCP_C_SEND:
941  process_SEND(connP, tcpCommand, check_and_cast<cPacket *>(msgP));
942  break;
943 
944  case TCP_C_CLOSE:
945  process_CLOSE(connP, tcpCommand, msgP);
946  break;
947 
948  case TCP_C_ABORT:
949  process_ABORT(connP, tcpCommand, msgP);
950  break;
951 
952  case TCP_C_STATUS:
953  process_STATUS(connP, tcpCommand, msgP);
954  break;
955 
956  default:
957  throw cRuntimeError("Wrong command from app: %d", msgP->getKind());
958  }
959 
960  /*
961  ...
962  NSC: should call removeConnection(connP.connIdM) if socket has been destroyed
963  ...
964  */
965 }
Definition: TCPCommand_m.h:61
void process_STATUS(TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_NSC.cc:1094
void process_OPEN_PASSIVE(TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_NSC.cc:1010
void process_ABORT(TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_NSC.cc:1084
void process_SEND(TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cPacket *msgP)
Definition: TCP_NSC.cc:1056
void process_CLOSE(TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_NSC.cc:1074
Definition: TCPCommand_m.h:63
void printConnBrief(TCP_NSC_Connection &connP)
Definition: TCP_NSC.cc:728
Definition: TCPCommand_m.h:66
void process_OPEN_ACTIVE(TCP_NSC_Connection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_NSC.cc:967
Definition: TCPCommand_m.h:62
Definition: TCPCommand_m.h:64
Definition: TCPCommand_m.h:65
void inet::tcp::TCP_NSC::refreshDisplay ( ) const
overrideprotectedvirtual
694 {
695  //...
696 }
void inet::tcp::TCP_NSC::removeConnection ( int  connIdP)
protected
722 {
723  auto i = tcpAppConnMapM.find(connIdP);
724  if (i != tcpAppConnMapM.end())
725  tcpAppConnMapM.erase(i);
726 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_NSC.h:154
void inet::tcp::TCP_NSC::send_callback ( const void *  dataP,
int  datalenP 
)
overridevirtual

Called from the stack when a packet needs to be output to the wire.

772 {
773  if (!isAliveM)
774  return;
775 
776  EV_DETAIL << this << ": NSC: send_callback(" << dataP << ", " << datalenP << ") called\n";
777 
778  sendToIP(dataP, datalenP);
779 
780  // comment from nsc.cc:
781  // New method: if_send_finish. This should be called by the nic
782  // driver code when there is space in it's queue. Unfortunately
783  // we don't know whether that is the case from here, so we just
784  // call it immediately for now. **THIS IS INCORRECT**. It should
785  // only be called when a space becomes free in the nic queue.
786  pStackM->if_send_finish(0); // XXX: hardcoded inerface id
787 }
INetStack * pStackM
Definition: TCP_NSC.h:161
bool isAliveM
Definition: TCP_NSC.h:166
void sendToIP(const void *dataP, int lenP)
Definition: TCP_NSC.cc:840
void inet::tcp::TCP_NSC::sendDataToApp ( TCP_NSC_Connection c)
protected

Referenced by handleIpInputMessage().

522 {
523  cPacket *dataMsg;
524 
525  while (nullptr != (dataMsg = c.receiveQueueM->extractBytesUpTo())) {
526  TCPConnectInfo *tcpConnectInfo = new TCPConnectInfo();
527  tcpConnectInfo->setConnId(c.connIdM);
528  tcpConnectInfo->setLocalAddr(c.inetSockPairM.localM.ipAddrM);
529  tcpConnectInfo->setRemoteAddr(c.inetSockPairM.remoteM.ipAddrM);
530  tcpConnectInfo->setLocalPort(c.inetSockPairM.localM.portM);
531  tcpConnectInfo->setRemotePort(c.inetSockPairM.remoteM.portM);
532  dataMsg->setControlInfo(tcpConnectInfo);
533  // send Msg to Application layer:
534  send(dataMsg, "appOut", c.appGateIndexM);
535  }
536 }
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
void inet::tcp::TCP_NSC::sendErrorNotificationToApp ( TCP_NSC_Connection c,
int  err 
)
protected

Referenced by handleIpInputMessage().

539 {
540  int code = -1;
541  const char *name;
542  switch (err) {
543  case 0:
544  code = TCP_I_PEER_CLOSED;
545  name = "PEER_CLOSED";
546  break;
547 
548  case NSC_ECONNREFUSED:
550  name = "CONNECTION_REFUSED";
551  break;
552 
553  case NSC_ECONNRESET:
554  code = TCP_I_CONNECTION_RESET;
555  name = "CONNECTION_RESET";
556  break;
557 
558  case NSC_ETIMEDOUT:
559  code = TCP_I_TIMED_OUT;
560  name = "TIMED_OUT";
561  break;
562 
563  case NSC_EAGAIN:
564  code = -1;
565  name = "";
566  break;
567 
568  default:
569  throw cRuntimeError("Unknown NSC error returned by read_data(): %d", err);
570  break;
571  }
572  if (code != -1) {
573  cMessage *msg = new cMessage(name);
574  msg->setKind(code);
575  TCPCommand *ind = new TCPCommand();
576  ind->setConnId(c.connIdM);
577  msg->setControlInfo(ind);
578  send(msg, "appOut", c.appGateIndexM);
579  }
580 }
Definition: TCPCommand_m.h:101
Definition: TCPCommand_m.h:104
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
Definition: TCPCommand_m.h:103
Definition: TCPCommand_m.h:105
void inet::tcp::TCP_NSC::sendEstablishedMsg ( TCP_NSC_Connection connP)
protected

Referenced by handleIpInputMessage().

270 {
271  if (connP.sentEstablishedM)
272  return;
273 
274  cMessage *msg = new cMessage("TCP_I_ESTABLISHED");
275  msg->setKind(TCP_I_ESTABLISHED);
276  TCPConnectInfo *tcpConnectInfo = new TCPConnectInfo();
277  tcpConnectInfo->setConnId(connP.connIdM);
278  tcpConnectInfo->setLocalAddr(connP.inetSockPairM.localM.ipAddrM);
279  tcpConnectInfo->setRemoteAddr(connP.inetSockPairM.remoteM.ipAddrM);
280  tcpConnectInfo->setLocalPort(connP.inetSockPairM.localM.portM);
281  tcpConnectInfo->setRemotePort(connP.inetSockPairM.remoteM.portM);
282  msg->setControlInfo(tcpConnectInfo);
283  send(msg, "appOut", connP.appGateIndexM);
284  connP.sentEstablishedM = true;
285 }
Definition: TCPCommand_m.h:100
void inet::tcp::TCP_NSC::sendToIP ( const void *  dataP,
int  lenP 
)
protected

Referenced by send_callback().

841 {
842  L3Address src, dest;
843  const nsc_iphdr *iph = (const nsc_iphdr *)dataP;
844 
845  int ipHdrLen = 4 * iph->ihl;
846  ASSERT(ipHdrLen <= lenP);
847  int totalLen = ntohs(iph->tot_len);
848  ASSERT(totalLen == lenP);
849  tcphdr const *tcph = (tcphdr const *)(((const char *)(iph)) + ipHdrLen);
850 
851  // XXX add some info (seqNo, len, etc)
852 
853  TCP_NSC_Connection::SockPair nscSockPair;
854  TCP_NSC_Connection *conn;
855 
856  nscSockPair.localM.ipAddrM.set(IPv4Address(ntohl(iph->saddr)));
857  nscSockPair.localM.portM = ntohs(tcph->th_sport);
858  nscSockPair.remoteM.ipAddrM.set(IPv4Address(ntohl(iph->daddr)));
859  nscSockPair.remoteM.portM = ntohs(tcph->th_dport);
860 
861  if (curConnM) {
863  conn = curConnM;
864  }
865  else {
866  conn = findConnByNscSockPair(nscSockPair);
867  }
868 
869  TCPSegment *tcpseg;
870 
871  if (conn) {
872  tcpseg = conn->sendQueueM->createSegmentWithBytes(tcph, totalLen - ipHdrLen);
873  src = conn->inetSockPairM.localM.ipAddrM;
874  dest = conn->inetSockPairM.remoteM.ipAddrM;
875  }
876  else {
877  tcpseg = TCPSerializer().deserialize((const unsigned char *)tcph, totalLen - ipHdrLen, true);
878  dest = mapNsc2Remote(ntohl(iph->daddr));
879  }
880 
881  ASSERT(tcpseg);
882 
883  EV_TRACE << this << ": Sending: conn=" << conn << ", data: " << dataP << " of len " << lenP << " from " << src
884  << " to " << dest << "\n";
885 
886  IL3AddressType *addressType = dest.getAddressType();
887  INetworkProtocolControlInfo *controlInfo = addressType->createNetworkProtocolControlInfo();
888  controlInfo->setTransportProtocol(IP_PROT_TCP);
889  controlInfo->setSourceAddress(src);
890  controlInfo->setDestinationAddress(dest);
891  tcpseg->setControlInfo(check_and_cast<cObject *>(controlInfo));
892 
893  if (conn) {
894  conn->receiveQueueM->notifyAboutSending(tcpseg);
895  }
896 
897  // record seq (only if we do send data) and ackno
898  if (sndNxtVector && tcpseg->getPayloadLength() != 0)
899  sndNxtVector->record(tcpseg->getSequenceNo());
900 
901  if (sndAckVector)
902  sndAckVector->record(tcpseg->getAckNo());
903 
904  int connId = conn ? conn->connIdM : -1;
905  EV_INFO << this << ": Send segment: conn ID=" << connId << " from " << src
906  << " to " << dest << " SEQ=" << tcpseg->getSequenceNo();
907  if (tcpseg->getSynBit())
908  EV_INFO << " SYN";
909  if (tcpseg->getAckBit())
910  EV_INFO << " ACK=" << tcpseg->getAckNo();
911  if (tcpseg->getFinBit())
912  EV_INFO << " FIN";
913  if (tcpseg->getRstBit())
914  EV_INFO << " RST";
915  if (tcpseg->getPshBit())
916  EV_INFO << " PSH";
917  if (tcpseg->getUrgBit())
918  EV_INFO << " URG";
919  EV_INFO << " len=" << tcpseg->getPayloadLength() << "\n";
920 
921  send(tcpseg, "ipOut");
922 }
az accept haszálja pcb új connId
Definition: lwip_tcp.txt:38
u16_t ntohs(u16_t n)
cOutVector * sndAckVector
Definition: TCP_NSC.h:181
u32_t ntohl(u32_t n)
TCP_NSC_Connection * curConnM
Definition: TCP_NSC.h:169
void changeAddresses(TCP_NSC_Connection &connP, const TCP_NSC_Connection::SockPair &inetSockPairP, const TCP_NSC_Connection::SockPair &nscSockPairP)
Definition: TCP_NSC.cc:287
L3Address const & mapNsc2Remote(u_int32_t nscAddrP)
Definition: TCP_NSC.cc:196
cOutVector * sndNxtVector
Definition: TCP_NSC.h:180
TCP_NSC_Connection * findConnByNscSockPair(TCP_NSC_Connection::SockPair const &sockPairP)
Definition: TCP_NSC.cc:710
Definition: IPProtocolId_m.h:80
SockPair inetSockPairM
Definition: TCP_NSC_Connection.h:99
void inet::tcp::TCP_NSC::wakeup ( )
overridevirtual

This is called when something interesting happened to a socket.

Perhaps a socket can now be written to or read from or something. We cannot directly do things like read or write from the socket, because this is not what happens in the real FreeBSD: it normally puts the application or thread blocking on the socket in question on the run queue.

To simulate this behaviour we wait a very small amount of time (this is sort of simulating processing delay) then call wakeup_expire. The important thing is that we return here and actually do the reading/writing at a later time.

807 {
808  if (!isAliveM)
809  return;
810 
811  EV_TRACE << this << ": wakeup() called\n";
812 }
bool isAliveM
Definition: TCP_NSC.h:166

Member Data Documentation

const char * inet::tcp::TCP_NSC::bufferSizeParamNameS = "stackBufferSize"
staticprotected

Referenced by initialize().

int inet::tcp::TCP_NSC::curAddrCounterM
protected
TCP_NSC_Connection* inet::tcp::TCP_NSC::curConnM
protected
SockPair2ConnIdMap inet::tcp::TCP_NSC::inetSockPair2ConnIdMapM
protected
bool inet::tcp::TCP_NSC::isAliveM
protected
const L3Address inet::tcp::TCP_NSC::localInnerGwS
staticprotected

Referenced by initialize().

const L3Address inet::tcp::TCP_NSC::localInnerIpS
staticprotected

Referenced by handleIpInputMessage(), and initialize().

const L3Address inet::tcp::TCP_NSC::localInnerMaskS
staticprotected

Referenced by initialize().

Nsc2RemoteMap inet::tcp::TCP_NSC::nsc2RemoteMapM
protected

Referenced by mapNsc2Remote(), and mapRemote2Nsc().

SockPair2ConnIdMap inet::tcp::TCP_NSC::nscSockPair2ConnIdMapM
protected
cMessage* inet::tcp::TCP_NSC::pNsiTimerM
protected

Referenced by handleMessage(), and loadStack().

INetStack* inet::tcp::TCP_NSC::pStackM
protected
cOutVector* inet::tcp::TCP_NSC::rcvAckVector
protected
cOutVector* inet::tcp::TCP_NSC::rcvSeqVector
protected
Remote2NscMap inet::tcp::TCP_NSC::remote2NscMapM
protected

Referenced by mapRemote2Nsc().

const L3Address inet::tcp::TCP_NSC::remoteFirstInnerIpS
staticprotected

Referenced by mapRemote2Nsc().

cOutVector* inet::tcp::TCP_NSC::sndAckVector
protected

Referenced by sendToIP(), TCP_NSC(), and ~TCP_NSC().

cOutVector* inet::tcp::TCP_NSC::sndNxtVector
protected

Referenced by sendToIP(), TCP_NSC(), and ~TCP_NSC().

const char * inet::tcp::TCP_NSC::stackNameParamNameS = "stackName"
staticprotected

Referenced by initialize().


The documentation for this class was generated from the following files: