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

Implements the Tcp protocol. More...

#include <Tcp.h>

Inheritance diagram for inet::tcp::Tcp:
inet::TransportProtocolBase inet::LayeredProtocolBase inet::OperationalBase inet::OperationalMixin< cSimpleModule > inet::ILifecycle

Classes

struct  SockPair
 

Public Types

enum  PortRange { EPHEMERAL_PORTRANGE_START = 1024, EPHEMERAL_PORTRANGE_END = 5000 }
 

Public Member Functions

 Tcp ()
 
virtual ~Tcp ()
 
virtual void addSockPair (TcpConnection *conn, L3Address localAddr, L3Address remoteAddr, int localPort, int remotePort)
 To be called from TcpConnection when a new connection gets created, during processing of OPEN_ACTIVE or OPEN_PASSIVE. More...
 
virtual void removeConnection (TcpConnection *conn)
 
virtual void sendFromConn (cMessage *msg, const char *gatename, int gateindex=-1)
 
virtual void updateSockPair (TcpConnection *conn, L3Address localAddr, L3Address remoteAddr, int localPort, int remotePort)
 To be called from TcpConnection when socket pair (key for TcpConnMap) changes (e.g. More...
 
virtual void addForkedConnection (TcpConnection *conn, TcpConnection *newConn, L3Address localAddr, L3Address remoteAddr, int localPort, int remotePort)
 Update conn's socket pair, and register newConn (which'll keep LISTENing). More...
 
virtual ushort getEphemeralPort ()
 To be called from TcpConnection: reserves an ephemeral port for the connection. More...
 
virtual TcpSendQueuecreateSendQueue ()
 To be called from TcpConnection: create a new send queue. More...
 
virtual TcpReceiveQueuecreateReceiveQueue ()
 To be called from TcpConnection: create a new receive queue. More...
 
virtual void handleStartOperation (LifecycleOperation *operation) override
 
virtual void handleStopOperation (LifecycleOperation *operation) override
 
virtual void handleCrashOperation (LifecycleOperation *operation) override
 
virtual void reset ()
 
bool checkCrc (Packet *pk)
 
int getMsl ()
 
- Public Member Functions inherited from inet::TransportProtocolBase
 TransportProtocolBase ()
 
- Public Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual ~OperationalMixin ()
 }@ More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Public Attributes

bool useDataNotification = false
 
CrcMode crcMode = CRC_MODE_UNDEFINED
 
int msl
 

Static Public Attributes

static simsignal_t tcpConnectionAddedSignal = registerSignal("tcpConnectionAdded")
 
static simsignal_t tcpConnectionRemovedSignal = registerSignal("tcpConnectionRemoved")
 

Protected Types

typedef std::map< int, TcpConnection * > TcpAppConnMap
 
typedef std::map< SockPair, TcpConnection * > TcpConnMap
 
- Protected Types inherited from inet::OperationalMixin< cSimpleModule >
enum  State
 

Protected Member Functions

virtual TcpConnectioncreateConnection (int socketId)
 Factory method; may be overriden for customizing Tcp. More...
 
virtual TcpConnectionfindConnForSegment (const Ptr< const TcpHeader > &tcpHeader, L3Address srcAddr, L3Address destAddr)
 
virtual TcpConnectionfindConnForApp (int socketId)
 
virtual void segmentArrivalWhileClosed (Packet *tcpSegment, const Ptr< const TcpHeader > &tcpHeader, L3Address src, L3Address dest)
 
virtual void refreshDisplay () const override
 
virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void finish () override
 
virtual void handleSelfMessage (cMessage *message) override
 
virtual void handleUpperCommand (cMessage *message) override
 
virtual void handleUpperPacket (Packet *packet) override
 
virtual void handleLowerPacket (Packet *packet) override
 
- Protected Member Functions inherited from inet::TransportProtocolBase
virtual bool isUpperMessage (cMessage *message) const override
 
virtual bool isLowerMessage (cMessage *message) const override
 
virtual bool isInitializeStage (int stage) const override
 
virtual bool isModuleStartStage (int stage) const override
 
virtual bool isModuleStopStage (int stage) const override
 
- Protected Member Functions inherited from inet::LayeredProtocolBase
virtual void handleMessageWhenUp (cMessage *message) override
 
virtual void handleUpperMessage (cMessage *message)
 
virtual void handleLowerMessage (cMessage *message)
 
virtual void handleLowerCommand (cMessage *message)
 
- Protected Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual int numInitStages () const override
 
virtual void refreshDisplay () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void handleMessageWhenDown (cMessage *msg)
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual State getInitialOperationalState () const
 Returns initial operational state: OPERATING or NOT_OPERATING. More...
 
virtual void handleActiveOperationTimeout (cMessage *message)
 
virtual bool isUp () const
 utility functions More...
 
virtual bool isDown () const
 
virtual void setOperationalState (State newState)
 
virtual void scheduleOperationTimeout (simtime_t timeout)
 
virtual void setupActiveOperation (LifecycleOperation *operation, IDoneCallback *doneCallback, State)
 
virtual void delayActiveOperationFinish (simtime_t timeout)
 
virtual void startActiveOperationExtraTime (simtime_t delay=SIMTIME_ZERO)
 
virtual void startActiveOperationExtraTimeOrFinish (simtime_t extraTime)
 
virtual void finishActiveOperation ()
 

Protected Attributes

TcpAppConnMap tcpAppConnMap
 
TcpConnMap tcpConnMap
 
ushort lastEphemeralPort = static_cast<ushort>(-1)
 
std::multiset< ushortusedEphemeralPorts
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 

Detailed Description

Implements the Tcp protocol.

This section describes the internal architecture of the Tcp model.

Usage and compliance with various RFCs are discussed in the corresponding NED documentation for Tcp. Also, you may want to check the TcpSocket class which makes it easier to use Tcp from applications.

The Tcp protocol implementation is composed of several classes (discussion follows below):

Tcp subclassed from cSimpleModule. It manages socketpair-to-connection mapping, and dispatches segments and user commands to the appropriate TcpConnection object.

TcpConnection manages the connection, with the help of other objects. TcpConnection itself implements the basic Tcp "machinery": takes care of the state machine, stores the state variables (TCB), sends/receives SYN, FIN, RST, ACKs, etc.

TcpConnection internally relies on 3 objects. The first two are subclassed from TcpSendQueue and TcpReceiveQueue. They manage the actual data stream, so TcpConnection itself only works with sequence number variables. This makes it possible to easily accomodate need for various types of simulated data transfer: real byte stream, "virtual" bytes (byte counts only), and sequence of cMessage objects (where every message object is mapped to a Tcp sequence number range).

Currently implemented send queue and receive queue classes are TCPVirtualDataSendQueue and TCPVirtualDataRcvQueue which implement queues with "virtual" bytes (byte counts only).

The third object is subclassed from TcpAlgorithm. Control over retransmissions, congestion control and ACK sending are "outsourced" from TcpConnection into TcpAlgorithm: delayed acks, slow start, fast rexmit, etc. are all implemented in TcpAlgorithm subclasses. This simplifies the design of TcpConnection and makes it a lot easier to implement new Tcp variations such as NewReno, Vegas or LinuxTcp as TcpAlgorithm subclasses.

Currently implemented TcpAlgorithm classes are TcpReno, TcpTahoe, TcpNewReno, TcpNoCongestionControl and DumbTcp.

The concrete TcpAlgorithm class to use can be chosen per connection (in OPEN) or in a module parameter.

Member Typedef Documentation

◆ TcpAppConnMap

typedef std::map<int , TcpConnection *> inet::tcp::Tcp::TcpAppConnMap
protected

◆ TcpConnMap

typedef std::map<SockPair, TcpConnection *> inet::tcp::Tcp::TcpConnMap
protected

Member Enumeration Documentation

◆ PortRange

Enumerator
EPHEMERAL_PORTRANGE_START 
EPHEMERAL_PORTRANGE_END 
90  {
93  };

Constructor & Destructor Documentation

◆ Tcp()

inet::tcp::Tcp::Tcp ( )
inline
139 {}

◆ ~Tcp()

inet::tcp::Tcp::~Tcp ( )
virtual
46 {
47 }

Member Function Documentation

◆ addForkedConnection()

void inet::tcp::Tcp::addForkedConnection ( TcpConnection conn,
TcpConnection newConn,
L3Address  localAddr,
L3Address  remoteAddr,
int  localPort,
int  remotePort 
)
virtual

Update conn's socket pair, and register newConn (which'll keep LISTENing).

Also, conn will get a new socketId (and newConn will live on with its old socketId).

296 {
297  // update conn's socket pair, and register newConn
298  addSockPair(newConn, localAddr, remoteAddr, localPort, remotePort);
299 
300  // newConn will live on with the new socketId
301  tcpAppConnMap[newConn->socketId] = newConn;
302 }

Referenced by inet::tcp::TcpConnection::processSegmentInListen().

◆ addSockPair()

void inet::tcp::Tcp::addSockPair ( TcpConnection conn,
L3Address  localAddr,
L3Address  remoteAddr,
int  localPort,
int  remotePort 
)
virtual

To be called from TcpConnection when a new connection gets created, during processing of OPEN_ACTIVE or OPEN_PASSIVE.

305 {
306  // update addresses/ports in TcpConnection
307  SockPair key;
308  key.localAddr = conn->localAddr = localAddr;
309  key.remoteAddr = conn->remoteAddr = remoteAddr;
310  key.localPort = conn->localPort = localPort;
311  key.remotePort = conn->remotePort = remotePort;
312 
313  // make sure connection is unique
314  auto it = tcpConnMap.find(key);
315  if (it != tcpConnMap.end()) {
316  // throw "address already in use" error
317  if (remoteAddr.isUnspecified() && remotePort == -1)
318  throw cRuntimeError("Address already in use: there is already a connection listening on %s:%d",
319  localAddr.str().c_str(), localPort);
320  else
321  throw cRuntimeError("Address already in use: there is already a connection %s:%d to %s:%d",
322  localAddr.str().c_str(), localPort, remoteAddr.str().c_str(), remotePort);
323  }
324 
325  // then insert it into tcpConnMap
326  tcpConnMap[key] = conn;
327 
328  // mark port as used
329  if (localPort >= EPHEMERAL_PORTRANGE_START && localPort < EPHEMERAL_PORTRANGE_END)
330  usedEphemeralPorts.insert(localPort);
331 }

Referenced by addForkedConnection(), inet::tcp::TcpConnection::process_OPEN_ACTIVE(), and inet::tcp::TcpConnection::process_OPEN_PASSIVE().

◆ checkCrc()

bool inet::tcp::Tcp::checkCrc ( Packet pk)
398 {
399  auto tcpHeader = tcpSegment->peekAtFront<TcpHeader>();
400 
401  switch (tcpHeader->getCrcMode()) {
402  case CRC_COMPUTED: {
403  // check CRC:
404  auto networkProtocol = tcpSegment->getTag<NetworkProtocolInd>()->getProtocol();
405  const std::vector<uint8_t> tcpBytes = tcpSegment->peekDataAsBytes()->getBytes();
406  auto pseudoHeader = makeShared<TransportPseudoHeader>();
407  L3Address srcAddr = tcpSegment->getTag<L3AddressInd>()->getSrcAddress();
408  L3Address destAddr = tcpSegment->getTag<L3AddressInd>()->getDestAddress();
409  pseudoHeader->setSrcAddress(srcAddr);
410  pseudoHeader->setDestAddress(destAddr);
411  ASSERT(networkProtocol);
412  pseudoHeader->setNetworkProtocolId(networkProtocol->getId());
413  pseudoHeader->setProtocolId(IP_PROT_TCP);
414  pseudoHeader->setPacketLength(B(tcpBytes.size()));
415  // pseudoHeader length: ipv4: 12 bytes, ipv6: 40 bytes, generic: ???
416  if (networkProtocol == &Protocol::ipv4)
417  pseudoHeader->setChunkLength(B(12));
418  else if (networkProtocol == &Protocol::ipv6)
419  pseudoHeader->setChunkLength(B(40));
420  else
421  throw cRuntimeError("Unknown network protocol: %s", networkProtocol->getName());
422  MemoryOutputStream stream;
423  Chunk::serialize(stream, pseudoHeader);
424  Chunk::serialize(stream, tcpSegment->peekData());
425  uint16_t crc = TcpIpChecksum::checksum(stream.getData());
426  return crc == 0;
427  }
429  return true;
431  return false;
432  default:
433  break;
434  }
435  throw cRuntimeError("unknown CRC mode: %d", tcpHeader->getCrcMode());
436 }

Referenced by handleLowerPacket().

◆ createConnection()

TcpConnection * inet::tcp::Tcp::createConnection ( int  socketId)
protectedvirtual

Factory method; may be overriden for customizing Tcp.

189 {
190  auto moduleType = cModuleType::get("inet.transportlayer.tcp.TcpConnection");
191  char submoduleName[24];
192  sprintf(submoduleName, "conn-%d", socketId);
193  auto module = check_and_cast<TcpConnection *>(moduleType->createScheduleInit(submoduleName, this));
194  module->initConnection(this, socketId);
195  return module;
196 }

Referenced by handleUpperCommand().

◆ createReceiveQueue()

TcpReceiveQueue * inet::tcp::Tcp::createReceiveQueue ( )
virtual

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

364 {
365  return new TcpReceiveQueue();
366 }

Referenced by inet::tcp::TcpConnection::initConnection().

◆ createSendQueue()

TcpSendQueue * inet::tcp::Tcp::createSendQueue ( )
virtual

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

359 {
360  return new TcpSendQueue();
361 }

Referenced by inet::tcp::TcpConnection::initConnection().

◆ findConnForApp()

TcpConnection * inet::tcp::Tcp::findConnForApp ( int  socketId)
protectedvirtual
131 {
132  auto i = tcpAppConnMap.find(socketId);
133  return i == tcpAppConnMap.end() ? nullptr : i->second;
134 }

Referenced by handleUpperCommand().

◆ findConnForSegment()

TcpConnection * inet::tcp::Tcp::findConnForSegment ( const Ptr< const TcpHeader > &  tcpHeader,
L3Address  srcAddr,
L3Address  destAddr 
)
protectedvirtual
223 {
224  SockPair key;
225  key.localAddr = destAddr;
226  key.remoteAddr = srcAddr;
227  key.localPort = tcpHeader->getDestPort();
228  key.remotePort = tcpHeader->getSrcPort();
229  SockPair save = key;
230 
231  // try with fully qualified SockPair
232  auto i = tcpConnMap.find(key);
233  if (i != tcpConnMap.end())
234  return i->second;
235 
236  // try with localAddr missing (only localPort specified in passive/active open)
237  key.localAddr = L3Address();
238  i = tcpConnMap.find(key);
239 
240  if (i != tcpConnMap.end())
241  return i->second;
242 
243  // try fully qualified local socket + blank remote socket (for incoming SYN)
244  key = save;
245  key.remoteAddr = L3Address();
246  key.remotePort = -1;
247  i = tcpConnMap.find(key);
248 
249  if (i != tcpConnMap.end())
250  return i->second;
251 
252  // try with blank remote socket, and localAddr missing (for incoming SYN)
253  key.localAddr = L3Address();
254  i = tcpConnMap.find(key);
255 
256  if (i != tcpConnMap.end())
257  return i->second;
258 
259  // given up
260  return nullptr;
261 }

Referenced by handleLowerPacket().

◆ finish()

void inet::tcp::Tcp::finish ( )
overrideprotectedvirtual
90 {
91  EV_INFO << getFullPath() << ": finishing with " << tcpConnMap.size() << " connections open.\n";
92 }

◆ getEphemeralPort()

ushort inet::tcp::Tcp::getEphemeralPort ( )
virtual

To be called from TcpConnection: reserves an ephemeral port for the connection.

275 {
276  // start at the last allocated port number + 1, and search for an unused one
277  ushort searchUntil = lastEphemeralPort++;
280 
282  if (lastEphemeralPort == searchUntil) // got back to starting point?
283  throw cRuntimeError("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
284 
286 
289  }
290 
291  // found a free one, return it
292  return lastEphemeralPort;
293 }

Referenced by inet::tcp::TcpConnection::process_OPEN_ACTIVE().

◆ getMsl()

int inet::tcp::Tcp::getMsl ( )
inline

◆ handleCrashOperation()

void inet::tcp::Tcp::handleCrashOperation ( LifecycleOperation operation)
overridevirtual

Implements inet::OperationalMixin< cSimpleModule >.

382 {
383  reset();
384 }

◆ handleLowerPacket()

void inet::tcp::Tcp::handleLowerPacket ( Packet packet)
overrideprotectedvirtual

Reimplemented from inet::LayeredProtocolBase.

137 {
138  auto protocol = packet->getTag<PacketProtocolTag>()->getProtocol();
139  if (protocol == &Protocol::tcp) {
140  if (!checkCrc(packet)) {
141  EV_WARN << "Tcp segment has wrong CRC, dropped\n";
142  PacketDropDetails details;
143  details.setReason(INCORRECTLY_RECEIVED);
144  emit(packetDroppedSignal, packet, &details);
145  delete packet;
146  return;
147  }
148 
149  // must be a TcpHeader
150  auto tcpHeader = packet->peekAtFront<TcpHeader>();
151 
152  // get src/dest addresses
153  L3Address srcAddr, destAddr;
154  srcAddr = packet->getTag<L3AddressInd>()->getSrcAddress();
155  destAddr = packet->getTag<L3AddressInd>()->getDestAddress();
156  int ecn = 0;
157  if (auto ecnTag = packet->findTag<EcnInd>())
158  ecn = ecnTag->getExplicitCongestionNotification();
159  ASSERT(ecn != -1);
160 
161  // process segment
162  TcpConnection *conn = findConnForSegment(tcpHeader, srcAddr, destAddr);
163  if (conn) {
164  TcpStateVariables *state = conn->getState();
165  if (state && state->ect) {
166  // This may be true only in receiver side. According to RFC 3168, page 20:
167  // pure acknowledgement packets (e.g., packets that do not contain
168  // any accompanying data) MUST be sent with the not-ECT codepoint.
169  state->gotCeIndication = (ecn == 3);
170  }
171 
172  bool ret = conn->processTCPSegment(packet, tcpHeader, srcAddr, destAddr);
173  if (!ret)
174  removeConnection(conn);
175  }
176  else {
177  segmentArrivalWhileClosed(packet, tcpHeader, srcAddr, destAddr);
178  }
179  }
180  else if (protocol == &Protocol::icmpv4 || protocol == &Protocol::icmpv6) {
181  EV_DETAIL << "ICMP error received -- discarding\n"; // FIXME can ICMP packets really make it up to Tcp???
182  delete packet;
183  }
184  else
185  throw cRuntimeError("Unknown protocol: '%s'", (protocol != nullptr ? protocol->getName() : "<nullptr>"));
186 }

◆ handleSelfMessage()

void inet::tcp::Tcp::handleSelfMessage ( cMessage *  message)
overrideprotectedvirtual

Reimplemented from inet::LayeredProtocolBase.

95 {
96  throw cRuntimeError("model error: should schedule timers on connection");
97 }

◆ handleStartOperation()

void inet::tcp::Tcp::handleStartOperation ( LifecycleOperation operation)
overridevirtual

Implements inet::OperationalMixin< cSimpleModule >.

369 {
370  // FIXME implementation
371 }

◆ handleStopOperation()

void inet::tcp::Tcp::handleStopOperation ( LifecycleOperation operation)
overridevirtual

Implements inet::OperationalMixin< cSimpleModule >.

374 {
375  // FIXME close connections??? yes, because the applications may not close them!!!
376  reset();
377  delayActiveOperationFinish(par("stopOperationTimeout"));
378  startActiveOperationExtraTimeOrFinish(par("stopOperationExtraTime"));
379 }

◆ handleUpperCommand()

void inet::tcp::Tcp::handleUpperCommand ( cMessage *  message)
overrideprotectedvirtual

Reimplemented from inet::LayeredProtocolBase.

100 {
101  int socketId = check_and_cast<ITaggedObject *>(msg)->getTags().getTag<SocketReq>()->getSocketId();
102  TcpConnection *conn = findConnForApp(socketId);
103 
104  if (!conn) {
105  conn = createConnection(socketId);
106 
107  // add into appConnMap here; it'll be added to connMap during processing
108  // the OPEN command in TcpConnection's processAppCommand().
109  tcpAppConnMap[socketId] = conn;
110 
111  EV_INFO << "Tcp connection created for " << msg << "\n";
112  }
113 
114  if (!conn->processAppCommand(msg))
115  removeConnection(conn);
116 }

Referenced by handleUpperPacket().

◆ handleUpperPacket()

void inet::tcp::Tcp::handleUpperPacket ( Packet packet)
overrideprotectedvirtual

Reimplemented from inet::LayeredProtocolBase.

126 {
127  handleUpperCommand(packet);
128 }

◆ initialize()

void inet::tcp::Tcp::initialize ( int  stage)
overrideprotectedvirtual

Reimplemented from inet::OperationalMixin< cSimpleModule >.

50 {
52 
53  if (stage == INITSTAGE_LOCAL) {
54  const char *crcModeString = par("crcMode");
55  crcMode = parseCrcMode(crcModeString, false);
56 
58 
59  msl = par("msl");
60  useDataNotification = par("useDataNotification");
61 
62  WATCH(lastEphemeralPort);
63  WATCH_PTRMAP(tcpConnMap);
64  WATCH_PTRMAP(tcpAppConnMap);
65  }
66  else if (stage == INITSTAGE_TRANSPORT_LAYER) {
67  registerService(Protocol::tcp, gate("appIn"), gate("appOut"));
68  registerProtocol(Protocol::tcp, gate("ipOut"), gate("ipIn"));
69  if (crcMode == CRC_COMPUTED) {
70  cModuleType *moduleType = cModuleType::get("inet.transportlayer.tcp_common.TcpCrcInsertionHook");
71  auto crcInsertion = check_and_cast<TcpCrcInsertionHook *>(moduleType->create("crcInsertion", this));
72  crcInsertion->finalizeParameters();
73  crcInsertion->callInitialize();
74 
75 #ifdef INET_WITH_IPv4
76  auto ipv4 = dynamic_cast<INetfilter *>(findModuleByPath("^.ipv4.ip"));
77  if (ipv4 != nullptr)
78  ipv4->registerHook(0, crcInsertion);
79 #endif
80 #ifdef INET_WITH_IPv6
81  auto ipv6 = dynamic_cast<INetfilter *>(findModuleByPath("^.ipv6.ipv6"));
82  if (ipv6 != nullptr)
83  ipv6->registerHook(0, crcInsertion);
84 #endif
85  }
86  }
87 }

◆ numInitStages()

virtual int inet::tcp::Tcp::numInitStages ( ) const
inlineoverrideprotectedvirtual
144 { return NUM_INIT_STAGES; }

◆ refreshDisplay()

void inet::tcp::Tcp::refreshDisplay ( ) const
overrideprotectedvirtual
439 {
441 
442  if (getEnvir()->isExpressMode()) {
443  // in express mode, we don't bother to update the display
444  // (std::map's iteration is not very fast if map is large)
445  getDisplayString().setTagArg("t", 0, "");
446  return;
447  }
448 
449  int numINIT = 0, numCLOSED = 0, numLISTEN = 0, numSYN_SENT = 0, numSYN_RCVD = 0,
450  numESTABLISHED = 0, numCLOSE_WAIT = 0, numLAST_ACK = 0, numFIN_WAIT_1 = 0,
451  numFIN_WAIT_2 = 0, numCLOSING = 0, numTIME_WAIT = 0;
452 
453  for (auto& elem : tcpAppConnMap) {
454  int state = (elem).second->getFsmState();
455 
456  switch (state) {
457  case TCP_S_INIT:
458  numINIT++;
459  break;
460 
461  case TCP_S_CLOSED:
462  numCLOSED++;
463  break;
464 
465  case TCP_S_LISTEN:
466  numLISTEN++;
467  break;
468 
469  case TCP_S_SYN_SENT:
470  numSYN_SENT++;
471  break;
472 
473  case TCP_S_SYN_RCVD:
474  numSYN_RCVD++;
475  break;
476 
477  case TCP_S_ESTABLISHED:
478  numESTABLISHED++;
479  break;
480 
481  case TCP_S_CLOSE_WAIT:
482  numCLOSE_WAIT++;
483  break;
484 
485  case TCP_S_LAST_ACK:
486  numLAST_ACK++;
487  break;
488 
489  case TCP_S_FIN_WAIT_1:
490  numFIN_WAIT_1++;
491  break;
492 
493  case TCP_S_FIN_WAIT_2:
494  numFIN_WAIT_2++;
495  break;
496 
497  case TCP_S_CLOSING:
498  numCLOSING++;
499  break;
500 
501  case TCP_S_TIME_WAIT:
502  numTIME_WAIT++;
503  break;
504  }
505  }
506 
507  char buf2[200];
508  buf2[0] = '\0';
509 
510  if (numINIT > 0)
511  sprintf(buf2 + strlen(buf2), "init:%d ", numINIT);
512  if (numCLOSED > 0)
513  sprintf(buf2 + strlen(buf2), "closed:%d ", numCLOSED);
514  if (numLISTEN > 0)
515  sprintf(buf2 + strlen(buf2), "listen:%d ", numLISTEN);
516  if (numSYN_SENT > 0)
517  sprintf(buf2 + strlen(buf2), "syn_sent:%d ", numSYN_SENT);
518  if (numSYN_RCVD > 0)
519  sprintf(buf2 + strlen(buf2), "syn_rcvd:%d ", numSYN_RCVD);
520  if (numESTABLISHED > 0)
521  sprintf(buf2 + strlen(buf2), "estab:%d ", numESTABLISHED);
522  if (numCLOSE_WAIT > 0)
523  sprintf(buf2 + strlen(buf2), "close_wait:%d ", numCLOSE_WAIT);
524  if (numLAST_ACK > 0)
525  sprintf(buf2 + strlen(buf2), "last_ack:%d ", numLAST_ACK);
526  if (numFIN_WAIT_1 > 0)
527  sprintf(buf2 + strlen(buf2), "fin_wait_1:%d ", numFIN_WAIT_1);
528  if (numFIN_WAIT_2 > 0)
529  sprintf(buf2 + strlen(buf2), "fin_wait_2:%d ", numFIN_WAIT_2);
530  if (numCLOSING > 0)
531  sprintf(buf2 + strlen(buf2), "closing:%d ", numCLOSING);
532  if (numTIME_WAIT > 0)
533  sprintf(buf2 + strlen(buf2), "time_wait:%d ", numTIME_WAIT);
534 
535  getDisplayString().setTagArg("t", 0, buf2);
536 }

◆ removeConnection()

void inet::tcp::Tcp::removeConnection ( TcpConnection conn)
virtual
199 {
200  EV_INFO << "Deleting Tcp connection\n";
201 
202  tcpAppConnMap.erase(conn->socketId);
203 
204  SockPair key2;
205  key2.localAddr = conn->localAddr;
206  key2.remoteAddr = conn->remoteAddr;
207  key2.localPort = conn->localPort;
208  key2.remotePort = conn->remotePort;
209  tcpConnMap.erase(key2);
210 
211  // IMPORTANT: usedEphemeralPorts.erase(conn->localPort) is NOT GOOD because it
212  // deletes ALL occurrences of the port from the multiset.
213  auto it = usedEphemeralPorts.find(conn->localPort);
214 
215  if (it != usedEphemeralPorts.end())
216  usedEphemeralPorts.erase(it);
217 
218  emit(tcpConnectionRemovedSignal, conn);
219  conn->deleteModule();
220 }

Referenced by handleLowerPacket(), inet::tcp::TcpConnection::handleMessage(), and handleUpperCommand().

◆ reset()

void inet::tcp::Tcp::reset ( )
virtual
387 {
388  for (auto& elem : tcpAppConnMap)
389  elem.second->deleteModule();
390  tcpAppConnMap.clear();
391  tcpConnMap.clear();
392  usedEphemeralPorts.clear();
394 }

Referenced by handleCrashOperation(), and handleStopOperation().

◆ segmentArrivalWhileClosed()

void inet::tcp::Tcp::segmentArrivalWhileClosed ( Packet tcpSegment,
const Ptr< const TcpHeader > &  tcpHeader,
L3Address  src,
L3Address  dest 
)
protectedvirtual
264 {
265  auto moduleType = cModuleType::get("inet.transportlayer.tcp.TcpConnection");
266  const char *submoduleName = "conn-temp";
267  auto module = check_and_cast<TcpConnection *>(moduleType->createScheduleInit(submoduleName, this));
268  module->initConnection(this, -1);
269  module->segmentArrivalWhileClosed(tcpSegment, tcpHeader, srcAddr, destAddr);
270  module->deleteModule();
271  delete tcpSegment;
272 }

Referenced by handleLowerPacket().

◆ sendFromConn()

void inet::tcp::Tcp::sendFromConn ( cMessage *  msg,
const char *  gatename,
int  gateindex = -1 
)
virtual
119 {
120  Enter_Method("sendFromConn");
121  take(msg);
122  send(msg, gatename, gateindex);
123 }

Referenced by inet::tcp::TcpConnection::sendToApp(), and inet::tcp::TcpConnection::sendToIP().

◆ updateSockPair()

void inet::tcp::Tcp::updateSockPair ( TcpConnection conn,
L3Address  localAddr,
L3Address  remoteAddr,
int  localPort,
int  remotePort 
)
virtual

To be called from TcpConnection when socket pair (key for TcpConnMap) changes (e.g.

becomes fully qualified).

334 {
335  // find with existing address/port pair...
336  SockPair key;
337  key.localAddr = conn->localAddr;
338  key.remoteAddr = conn->remoteAddr;
339  key.localPort = conn->localPort;
340  key.remotePort = conn->remotePort;
341  auto it = tcpConnMap.find(key);
342 
343  ASSERT(it != tcpConnMap.end() && it->second == conn);
344 
345  // ...and remove from the old place in tcpConnMap
346  tcpConnMap.erase(it);
347 
348  // then update addresses/ports, and re-insert it with new key into tcpConnMap
349  key.localAddr = conn->localAddr = localAddr;
350  key.remoteAddr = conn->remoteAddr = remoteAddr;
351  ASSERT(conn->localPort == localPort);
352  key.remotePort = conn->remotePort = remotePort;
353  tcpConnMap[key] = conn;
354 
355  // localPort doesn't change (see ASSERT above), so there's no need to update usedEphemeralPorts[].
356 }

Referenced by inet::tcp::TcpConnection::processSegmentInListen(), and inet::tcp::TcpConnection::processSegmentInSynSent().

Member Data Documentation

◆ crcMode

◆ lastEphemeralPort

ushort inet::tcp::Tcp::lastEphemeralPort = static_cast<ushort>(-1)
protected

Referenced by getEphemeralPort(), initialize(), and reset().

◆ msl

int inet::tcp::Tcp::msl

Referenced by initialize().

◆ tcpAppConnMap

◆ tcpConnectionAddedSignal

◆ tcpConnectionRemovedSignal

simsignal_t inet::tcp::Tcp::tcpConnectionRemovedSignal = registerSignal("tcpConnectionRemoved")
static

Referenced by removeConnection().

◆ tcpConnMap

TcpConnMap inet::tcp::Tcp::tcpConnMap
protected

◆ useDataNotification

bool inet::tcp::Tcp::useDataNotification = false

◆ usedEphemeralPorts

std::multiset<ushort> inet::tcp::Tcp::usedEphemeralPorts
protected

The documentation for this class was generated from the following files:
inet::tcp::Tcp::msl
int msl
Definition: Tcp.h:136
inet::tcp::Tcp::segmentArrivalWhileClosed
virtual void segmentArrivalWhileClosed(Packet *tcpSegment, const Ptr< const TcpHeader > &tcpHeader, L3Address src, L3Address dest)
Definition: Tcp.cc:263
inet::tcp::Tcp::EPHEMERAL_PORTRANGE_START
@ EPHEMERAL_PORTRANGE_START
Definition: Tcp.h:91
protocol
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down protocol
Definition: IUdp-gates.txt:25
inet::Protocol::tcp
static const Protocol tcp
Definition: Protocol.h:112
inet::INCORRECTLY_RECEIVED
@ INCORRECTLY_RECEIVED
Definition: Simsignals_m.h:71
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::Protocol::ipv6
static const Protocol ipv6
Definition: Protocol.h:94
inet::OperationalMixin< cSimpleModule >::initialize
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
inet::Protocol::icmpv4
static const Protocol icmpv4
Definition: Protocol.h:71
inet::tcp::Tcp::removeConnection
virtual void removeConnection(TcpConnection *conn)
Definition: Tcp.cc:198
inet::CRC_COMPUTED
@ CRC_COMPUTED
Definition: CrcMode_m.h:59
inet::tcp::Tcp::tcpAppConnMap
TcpAppConnMap tcpAppConnMap
Definition: Tcp.h:117
inet::Chunk::serialize
static void serialize(MemoryOutputStream &stream, const Ptr< const Chunk > &chunk, b offset=b(0), b length=b(-1))
Serializes a chunk into the given stream.
Definition: Chunk.cc:175
inet::tcp::Tcp::crcMode
CrcMode crcMode
Definition: Tcp.h:135
inet::tcp::Tcp::tcpConnMap
TcpConnMap tcpConnMap
Definition: Tcp.h:118
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::tcp::Tcp::checkCrc
bool checkCrc(Packet *pk)
Definition: Tcp.cc:397
inet::parseCrcMode
CrcMode parseCrcMode(const char *crcModeString, bool allowDisable)
Definition: CrcMode.cc:14
inet::tcp::TCP_S_INIT
@ TCP_S_INIT
Definition: TcpConnection.h:47
inet::registerService
void registerService(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a service primitive (SDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:14
inet::tcp::TCP_S_FIN_WAIT_1
@ TCP_S_FIN_WAIT_1
Definition: TcpConnection.h:55
inet::packetDroppedSignal
simsignal_t packetDroppedSignal
Definition: Simsignals.cc:85
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::tcp::TCP_S_LISTEN
@ TCP_S_LISTEN
Definition: TcpConnection.h:49
inet::tcp::Tcp::useDataNotification
bool useDataNotification
Definition: Tcp.h:134
inet::tcp::TCP_S_CLOSED
@ TCP_S_CLOSED
Definition: TcpConnection.h:48
inet::tcp::TCP_S_ESTABLISHED
@ TCP_S_ESTABLISHED
Definition: TcpConnection.h:52
inet::tcp::TCP_S_SYN_RCVD
@ TCP_S_SYN_RCVD
Definition: TcpConnection.h:51
inet::INITSTAGE_TRANSPORT_LAYER
INET_API InitStage INITSTAGE_TRANSPORT_LAYER
Initialization of transport-layer protocols.
inet::tcp::Tcp::tcpConnectionRemovedSignal
static simsignal_t tcpConnectionRemovedSignal
Definition: Tcp.h:88
inet::tcp::TCP_S_CLOSE_WAIT
@ TCP_S_CLOSE_WAIT
Definition: TcpConnection.h:53
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::tcp::TCP_S_TIME_WAIT
@ TCP_S_TIME_WAIT
Definition: TcpConnection.h:58
inet::tcp::Tcp::findConnForSegment
virtual TcpConnection * findConnForSegment(const Ptr< const TcpHeader > &tcpHeader, L3Address srcAddr, L3Address destAddr)
Definition: Tcp.cc:222
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::TcpIpChecksum::checksum
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TcpIpChecksum.h:33
inet::CRC_DECLARED_CORRECT
@ CRC_DECLARED_CORRECT
Definition: CrcMode_m.h:57
inet::Protocol::icmpv6
static const Protocol icmpv6
Definition: Protocol.h:72
inet::IP_PROT_TCP
@ IP_PROT_TCP
Definition: IpProtocolId_m.h:94
inet::CRC_DECLARED_INCORRECT
@ CRC_DECLARED_INCORRECT
Definition: CrcMode_m.h:58
inet::OperationalMixin< cSimpleModule >::delayActiveOperationFinish
virtual void delayActiveOperationFinish(simtime_t timeout)
Definition: OperationalMixinImpl.h:161
inet::OperationalMixin< cSimpleModule >::startActiveOperationExtraTimeOrFinish
virtual void startActiveOperationExtraTimeOrFinish(simtime_t extraTime)
Definition: OperationalMixinImpl.h:179
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::ushort
unsigned short ushort
Definition: INETDefs.h:54
inet::tcp::Tcp::reset
virtual void reset()
Definition: Tcp.cc:386
inet::tcp::Tcp::handleUpperCommand
virtual void handleUpperCommand(cMessage *message) override
Definition: Tcp.cc:99
inet::tcp::Tcp::findConnForApp
virtual TcpConnection * findConnForApp(int socketId)
Definition: Tcp.cc:130
inet::tcp::TCP_S_LAST_ACK
@ TCP_S_LAST_ACK
Definition: TcpConnection.h:54
inet::tcp::TCP_S_CLOSING
@ TCP_S_CLOSING
Definition: TcpConnection.h:57
inet::OperationalMixin< cSimpleModule >::refreshDisplay
virtual void refreshDisplay() const override
Definition: OperationalMixinImpl.h:200
inet::registerProtocol
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
inet::tcp::TCP_S_SYN_SENT
@ TCP_S_SYN_SENT
Definition: TcpConnection.h:50
inet::tcp::Tcp::createConnection
virtual TcpConnection * createConnection(int socketId)
Factory method; may be overriden for customizing Tcp.
Definition: Tcp.cc:188
inet::tcp::Tcp::usedEphemeralPorts
std::multiset< ushort > usedEphemeralPorts
Definition: Tcp.h:121
inet::tcp::Tcp::EPHEMERAL_PORTRANGE_END
@ EPHEMERAL_PORTRANGE_END
Definition: Tcp.h:92
inet::tcp::TCP_S_FIN_WAIT_2
@ TCP_S_FIN_WAIT_2
Definition: TcpConnection.h:56
inet::tcp::Tcp::lastEphemeralPort
ushort lastEphemeralPort
Definition: Tcp.h:120
inet::tcp::Tcp::addSockPair
virtual void addSockPair(TcpConnection *conn, L3Address localAddr, L3Address remoteAddr, int localPort, int remotePort)
To be called from TcpConnection when a new connection gets created, during processing of OPEN_ACTIVE ...
Definition: Tcp.cc:304