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::ILifecycle

Classes

struct  AppConnKey
 
struct  SockPair
 

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 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 (TCPDataTransferMode transferModeP)
 To be called from TCPConnection: create a new send queue. More...
 
virtual TCPReceiveQueuecreateReceiveQueue (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...
 
virtual void reset ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Public Attributes

bool recordStatistics = false
 
bool isOperational = false
 
bool useDataNotification = false
 

Static Public Attributes

static simsignal_t tcpConnectionAddedSignal = registerSignal("tcpConnectionAdded")
 
static simsignal_t tcpConnectionRemovedSignal = registerSignal("tcpConnectionRemoved")
 
static bool testing
 
static bool logverbose
 

Protected Types

typedef std::map< AppConnKey, TCPConnection * > TcpAppConnMap
 
typedef std::map< SockPair, TCPConnection * > TcpConnMap
 

Protected Member Functions

virtual TCPConnectioncreateConnection (int appGateIndex, int connId)
 Factory method; may be overriden for customizing TCP. More...
 
virtual TCPConnectionfindConnForSegment (TCPSegment *tcpseg, L3Address srcAddr, L3Address destAddr)
 
virtual TCPConnectionfindConnForApp (int appGateIndex, int connId)
 
virtual void segmentArrivalWhileClosed (TCPSegment *tcpseg, L3Address src, L3Address dest)
 
virtual void removeConnection (TCPConnection *conn)
 
virtual void refreshDisplay () const override
 
virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void finish () override
 

Protected Attributes

TcpAppConnMap tcpAppConnMap
 
TcpConnMap tcpConnMap
 
ushort lastEphemeralPort = (ushort)-1
 
std::multiset< ushortusedEphemeralPorts
 

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

typedef std::map<AppConnKey, TCPConnection *> inet::tcp::TCP::TcpAppConnMap
protected
typedef std::map<SockPair, TCPConnection *> inet::tcp::TCP::TcpConnMap
protected

Constructor & Destructor Documentation

inet::tcp::TCP::TCP ( )
inline
164 {}
inet::tcp::TCP::~TCP ( )
virtual
111 {
112  while (!tcpAppConnMap.empty()) {
113  auto i = tcpAppConnMap.begin();
114  delete i->second;
115  tcpAppConnMap.erase(i);
116  }
117 }
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137

Member Function Documentation

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 connId (and newConn will live on with its old connId).

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

446 {
447  // update conn's socket pair, and register newConn (which'll keep LISTENing)
448  updateSockPair(conn, localAddr, remoteAddr, localPort, remotePort);
449  addSockPair(newConn, newConn->localAddr, newConn->remoteAddr, newConn->localPort, newConn->remotePort);
450 
451  // conn will get a new connId...
452  AppConnKey key;
453  key.appGateIndex = conn->appGateIndex;
454  key.connId = conn->connId;
455  tcpAppConnMap.erase(key);
456  key.connId = conn->connId = getEnvir()->getUniqueNumber();
457  tcpAppConnMap[key] = conn;
458 
459  // ...and newConn will live on with the old connId
460  key.appGateIndex = newConn->appGateIndex;
461  key.connId = newConn->connId;
462  tcpAppConnMap[key] = newConn;
463 }
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
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.
Definition: TCP.cc:420
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:391
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.

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

392 {
393  // update addresses/ports in TCPConnection
394  SockPair key;
395  key.localAddr = conn->localAddr = localAddr;
396  key.remoteAddr = conn->remoteAddr = remoteAddr;
397  key.localPort = conn->localPort = localPort;
398  key.remotePort = conn->remotePort = remotePort;
399 
400  // make sure connection is unique
401  auto it = tcpConnMap.find(key);
402  if (it != tcpConnMap.end()) {
403  // throw "address already in use" error
404  if (remoteAddr.isUnspecified() && remotePort == -1)
405  throw cRuntimeError("Address already in use: there is already a connection listening on %s:%d",
406  localAddr.str().c_str(), localPort);
407  else
408  throw cRuntimeError("Address already in use: there is already a connection %s:%d to %s:%d",
409  localAddr.str().c_str(), localPort, remoteAddr.str().c_str(), remotePort);
410  }
411 
412  // then insert it into tcpConnMap
413  tcpConnMap[key] = conn;
414 
415  // mark port as used
416  if (localPort >= EPHEMERAL_PORTRANGE_START && localPort < EPHEMERAL_PORTRANGE_END)
417  usedEphemeralPorts.insert(localPort);
418 }
TcpConnMap tcpConnMap
Definition: TCP.h:138
#define EPHEMERAL_PORTRANGE_END
Definition: TCP.cc:56
#define EPHEMERAL_PORTRANGE_START
Definition: TCP.cc:55
std::multiset< ushort > usedEphemeralPorts
Definition: TCP.h:141
TCPConnection * inet::tcp::TCP::createConnection ( int  appGateIndex,
int  connId 
)
protectedvirtual

Factory method; may be overriden for customizing TCP.

Referenced by handleMessage().

201 {
202  return new TCPConnection(this, appGateIndex, connId);
203 }
az accept haszálja pcb új connId
Definition: lwip_tcp.txt:38
TCPReceiveQueue * inet::tcp::TCP::createReceiveQueue ( TCPDataTransferMode  transferModeP)
virtual

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

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

515 {
516  switch (transferModeP) {
518  return new TCPVirtualDataRcvQueue();
519 
520  case TCP_TRANSFER_OBJECT:
521  return new TCPMsgBasedRcvQueue();
522 
524  return new TCPByteStreamRcvQueue();
525 
526  default:
527  throw cRuntimeError("Invalid TCP data transfer mode: %d", transferModeP);
528  }
529 }
Definition: TCPCommand_m.h:255
Definition: TCPCommand_m.h:257
Definition: TCPCommand_m.h:256
TCPSendQueue * inet::tcp::TCP::createSendQueue ( TCPDataTransferMode  transferModeP)
virtual

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

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

498 {
499  switch (transferModeP) {
501  return new TCPVirtualDataSendQueue();
502 
503  case TCP_TRANSFER_OBJECT:
504  return new TCPMsgBasedSendQueue();
505 
507  return new TCPByteStreamSendQueue();
508 
509  default:
510  throw cRuntimeError("Invalid TCP data transfer mode: %d", transferModeP);
511  }
512 }
Definition: TCPCommand_m.h:255
Definition: TCPCommand_m.h:257
Definition: TCPCommand_m.h:256
TCPConnection * inet::tcp::TCP::findConnForApp ( int  appGateIndex,
int  connId 
)
protectedvirtual

Referenced by handleMessage().

361 {
362  AppConnKey key;
363  key.appGateIndex = appGateIndex;
364  key.connId = connId;
365 
366  auto i = tcpAppConnMap.find(key);
367  return i == tcpAppConnMap.end() ? nullptr : i->second;
368 }
az accept haszálja pcb új connId
Definition: lwip_tcp.txt:38
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
TCPConnection * inet::tcp::TCP::findConnForSegment ( TCPSegment tcpseg,
L3Address  srcAddr,
L3Address  destAddr 
)
protectedvirtual

Referenced by handleMessage().

320 {
321  SockPair key;
322  key.localAddr = destAddr;
323  key.remoteAddr = srcAddr;
324  key.localPort = tcpseg->getDestPort();
325  key.remotePort = tcpseg->getSrcPort();
326  SockPair save = key;
327 
328  // try with fully qualified SockPair
329  auto i = tcpConnMap.find(key);
330  if (i != tcpConnMap.end())
331  return i->second;
332 
333  // try with localAddr missing (only localPort specified in passive/active open)
334  key.localAddr = L3Address();
335  i = tcpConnMap.find(key);
336 
337  if (i != tcpConnMap.end())
338  return i->second;
339 
340  // try fully qualified local socket + blank remote socket (for incoming SYN)
341  key = save;
342  key.remoteAddr = L3Address();
343  key.remotePort = -1;
344  i = tcpConnMap.find(key);
345 
346  if (i != tcpConnMap.end())
347  return i->second;
348 
349  // try with blank remote socket, and localAddr missing (for incoming SYN)
350  key.localAddr = L3Address();
351  i = tcpConnMap.find(key);
352 
353  if (i != tcpConnMap.end())
354  return i->second;
355 
356  // given up
357  return nullptr;
358 }
TcpConnMap tcpConnMap
Definition: TCP.h:138
void inet::tcp::TCP::finish ( )
overrideprotectedvirtual
493 {
494  EV_INFO << getFullPath() << ": finishing with " << tcpConnMap.size() << " connections open.\n";
495 }
TcpConnMap tcpConnMap
Definition: TCP.h:138
ushort inet::tcp::TCP::getEphemeralPort ( )
virtual

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

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

371 {
372  // start at the last allocated port number + 1, and search for an unused one
373  ushort searchUntil = lastEphemeralPort++;
376 
378  if (lastEphemeralPort == searchUntil) // got back to starting point?
379  throw cRuntimeError("Ephemeral port range %d..%d exhausted, all ports occupied", EPHEMERAL_PORTRANGE_START, EPHEMERAL_PORTRANGE_END);
380 
382 
385  }
386 
387  // found a free one, return it
388  return lastEphemeralPort;
389 }
ushort lastEphemeralPort
Definition: TCP.h:140
#define EPHEMERAL_PORTRANGE_END
Definition: TCP.cc:56
unsigned short ushort
Definition: INETDefs.h:62
#define EPHEMERAL_PORTRANGE_START
Definition: TCP.cc:55
std::multiset< ushort > usedEphemeralPorts
Definition: TCP.h:141
void inet::tcp::TCP::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
120 {
121  if (!isOperational) {
122  if (msg->isSelfMessage())
123  throw cRuntimeError("Model error: self msg '%s' received when isOperational is false", msg->getName());
124  EV_ERROR << "TCP is turned off, dropping '" << msg->getName() << "' message\n";
125  delete msg;
126  }
127  else if (msg->isSelfMessage()) {
128  TCPConnection *conn = (TCPConnection *)msg->getContextPointer();
129  bool ret = conn->processTimer(msg);
130  if (!ret)
131  removeConnection(conn);
132  }
133  else if (msg->arrivedOn("ipIn")) {
134  if (false
135 #ifdef WITH_IPv4
136  || dynamic_cast<ICMPMessage *>(msg)
137 #endif // ifdef WITH_IPv4
138 #ifdef WITH_IPv6
139  || dynamic_cast<ICMPv6Message *>(msg)
140 #endif // ifdef WITH_IPv6
141  )
142  {
143  EV_DETAIL << "ICMP error received -- discarding\n"; // FIXME can ICMP packets really make it up to TCP???
144  delete msg;
145  }
146  else {
147  // must be a TCPSegment
148  TCPSegment *tcpseg = check_and_cast<TCPSegment *>(msg);
149 
150  // get src/dest addresses
151  L3Address srcAddr, destAddr;
152 
153  cObject *ctrl = tcpseg->removeControlInfo();
154  if (!ctrl)
155  throw cRuntimeError("(%s)%s arrived without control info", tcpseg->getClassName(), tcpseg->getName());
156 
157  INetworkProtocolControlInfo *controlInfo = check_and_cast<INetworkProtocolControlInfo *>(ctrl);
158  srcAddr = controlInfo->getSourceAddress();
159  destAddr = controlInfo->getDestinationAddress();
160  //interfaceId = controlInfo->getInterfaceId();
161  delete ctrl;
162 
163  // process segment
164  TCPConnection *conn = findConnForSegment(tcpseg, srcAddr, destAddr);
165  if (conn) {
166  bool ret = conn->processTCPSegment(tcpseg, srcAddr, destAddr);
167  if (!ret)
168  removeConnection(conn);
169  }
170  else {
171  segmentArrivalWhileClosed(tcpseg, srcAddr, destAddr);
172  }
173  }
174  }
175  else { // must be from app
176  TCPCommand *controlInfo = check_and_cast<TCPCommand *>(msg->getControlInfo());
177  int appGateIndex = msg->getArrivalGate()->getIndex();
178  int connId = controlInfo->getConnId();
179 
180  TCPConnection *conn = findConnForApp(appGateIndex, connId);
181 
182  if (!conn) {
183  conn = createConnection(appGateIndex, connId);
184 
185  // add into appConnMap here; it'll be added to connMap during processing
186  // the OPEN command in TCPConnection's processAppCommand().
187  AppConnKey key;
188  key.appGateIndex = appGateIndex;
189  key.connId = connId;
190  tcpAppConnMap[key] = conn;
191 
192  EV_INFO << "TCP connection created for " << msg << "\n";
193  }
194  bool ret = conn->processAppCommand(msg);
195  if (!ret)
196  removeConnection(conn);
197  }
198 }
az accept haszálja pcb új connId
Definition: lwip_tcp.txt:38
virtual TCPConnection * findConnForApp(int appGateIndex, int connId)
Definition: TCP.cc:360
virtual TCPConnection * createConnection(int appGateIndex, int connId)
Factory method; may be overriden for customizing TCP.
Definition: TCP.cc:200
bool isOperational
Definition: TCP.h:159
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
virtual TCPConnection * findConnForSegment(TCPSegment *tcpseg, L3Address srcAddr, L3Address destAddr)
Definition: TCP.cc:319
virtual void removeConnection(TCPConnection *conn)
Definition: TCP.cc:465
virtual void segmentArrivalWhileClosed(TCPSegment *tcpseg, L3Address src, L3Address dest)
Definition: TCP.cc:205
bool inet::tcp::TCP::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overridevirtual

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.

532 {
533  Enter_Method_Silent();
534 
535  if (dynamic_cast<NodeStartOperation *>(operation)) {
537  //FIXME implementation
538  isOperational = true;
539  }
540  }
541  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
543  //FIXME close connections???
544  reset();
545  isOperational = false;
546  }
547  }
548  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
550  //FIXME implementation
551  reset();
552  isOperational = false;
553  }
554  }
555  else {
556  throw cRuntimeError("Unsupported operation '%s'", operation->getClassName());
557  }
558 
559  return true;
560 }
bool isOperational
Definition: TCP.h:159
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
Stage
Definition: NodeOperations.h:46
virtual void reset()
Definition: TCP.cc:562
Definition: NodeOperations.h:127
void inet::tcp::TCP::initialize ( int  stage)
overrideprotectedvirtual
79 {
80  cSimpleModule::initialize(stage);
81 
82  if (stage == INITSTAGE_LOCAL) {
83  const char *q;
84  q = par("sendQueueClass");
85  if (*q != '\0')
86  throw cRuntimeError("Don't use obsolete sendQueueClass = \"%s\" parameter", q);
87 
88  q = par("receiveQueueClass");
89  if (*q != '\0')
90  throw cRuntimeError("Don't use obsolete receiveQueueClass = \"%s\" parameter", q);
91 
93  WATCH(lastEphemeralPort);
94 
95  WATCH_PTRMAP(tcpConnMap);
96  WATCH_PTRMAP(tcpAppConnMap);
97 
98  recordStatistics = par("recordStats");
99  useDataNotification = par("useDataNotification");
100  }
101  else if (stage == INITSTAGE_TRANSPORT_LAYER) {
102  cModule *host = findContainingNode(this);
103  NodeStatus *nodeStatus = check_and_cast_nullable<NodeStatus *>(host ? host->getSubmodule("status") : nullptr);
104  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
105  IPSocket ipSocket(gate("ipOut"));
106  ipSocket.registerProtocol(IP_PROT_TCP);
107  }
108 }
Initialization of transport-layer protocols.
Definition: InitStages.h:90
TcpConnMap tcpConnMap
Definition: TCP.h:138
bool useDataNotification
Definition: TCP.h:161
bool isOperational
Definition: TCP.h:159
bool recordStatistics
Definition: TCP.h:158
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
ushort lastEphemeralPort
Definition: TCP.h:140
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
Definition: IPProtocolId_m.h:80
#define EPHEMERAL_PORTRANGE_START
Definition: TCP.cc:55
Definition: NodeStatus.h:40
virtual int inet::tcp::TCP::numInitStages ( ) const
inlineoverrideprotectedvirtual
169 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::tcp::TCP::refreshDisplay ( ) const
overrideprotectedvirtual
214 {
215  if (getEnvir()->isExpressMode()) {
216  // in express mode, we don't bother to update the display
217  // (std::map's iteration is not very fast if map is large)
218  getDisplayString().setTagArg("t", 0, "");
219  return;
220  }
221 
222  //char buf[40];
223  //sprintf(buf,"%d conns", tcpAppConnMap.size());
224  //getDisplayString().setTagArg("t",0,buf);
225  if (isOperational)
226  getDisplayString().removeTag("i2");
227  else
228  getDisplayString().setTagArg("i2", 0, "status/cross");
229 
230  int numINIT = 0, numCLOSED = 0, numLISTEN = 0, numSYN_SENT = 0, numSYN_RCVD = 0,
231  numESTABLISHED = 0, numCLOSE_WAIT = 0, numLAST_ACK = 0, numFIN_WAIT_1 = 0,
232  numFIN_WAIT_2 = 0, numCLOSING = 0, numTIME_WAIT = 0;
233 
234  for (auto & elem : tcpAppConnMap) {
235  int state = (elem).second->getFsmState();
236 
237  switch (state) {
238  case TCP_S_INIT:
239  numINIT++;
240  break;
241 
242  case TCP_S_CLOSED:
243  numCLOSED++;
244  break;
245 
246  case TCP_S_LISTEN:
247  numLISTEN++;
248  break;
249 
250  case TCP_S_SYN_SENT:
251  numSYN_SENT++;
252  break;
253 
254  case TCP_S_SYN_RCVD:
255  numSYN_RCVD++;
256  break;
257 
258  case TCP_S_ESTABLISHED:
259  numESTABLISHED++;
260  break;
261 
262  case TCP_S_CLOSE_WAIT:
263  numCLOSE_WAIT++;
264  break;
265 
266  case TCP_S_LAST_ACK:
267  numLAST_ACK++;
268  break;
269 
270  case TCP_S_FIN_WAIT_1:
271  numFIN_WAIT_1++;
272  break;
273 
274  case TCP_S_FIN_WAIT_2:
275  numFIN_WAIT_2++;
276  break;
277 
278  case TCP_S_CLOSING:
279  numCLOSING++;
280  break;
281 
282  case TCP_S_TIME_WAIT:
283  numTIME_WAIT++;
284  break;
285  }
286  }
287 
288  char buf2[200];
289  buf2[0] = '\0';
290 
291  if (numINIT > 0)
292  sprintf(buf2 + strlen(buf2), "init:%d ", numINIT);
293  if (numCLOSED > 0)
294  sprintf(buf2 + strlen(buf2), "closed:%d ", numCLOSED);
295  if (numLISTEN > 0)
296  sprintf(buf2 + strlen(buf2), "listen:%d ", numLISTEN);
297  if (numSYN_SENT > 0)
298  sprintf(buf2 + strlen(buf2), "syn_sent:%d ", numSYN_SENT);
299  if (numSYN_RCVD > 0)
300  sprintf(buf2 + strlen(buf2), "syn_rcvd:%d ", numSYN_RCVD);
301  if (numESTABLISHED > 0)
302  sprintf(buf2 + strlen(buf2), "estab:%d ", numESTABLISHED);
303  if (numCLOSE_WAIT > 0)
304  sprintf(buf2 + strlen(buf2), "close_wait:%d ", numCLOSE_WAIT);
305  if (numLAST_ACK > 0)
306  sprintf(buf2 + strlen(buf2), "last_ack:%d ", numLAST_ACK);
307  if (numFIN_WAIT_1 > 0)
308  sprintf(buf2 + strlen(buf2), "fin_wait_1:%d ", numFIN_WAIT_1);
309  if (numFIN_WAIT_2 > 0)
310  sprintf(buf2 + strlen(buf2), "fin_wait_2:%d ", numFIN_WAIT_2);
311  if (numCLOSING > 0)
312  sprintf(buf2 + strlen(buf2), "closing:%d ", numCLOSING);
313  if (numTIME_WAIT > 0)
314  sprintf(buf2 + strlen(buf2), "time_wait:%d ", numTIME_WAIT);
315 
316  getDisplayString().setTagArg("t", 0, buf2);
317 }
Definition: TCPConnection.h:68
Definition: TCPConnection.h:69
Definition: TCPConnection.h:70
Definition: TCPConnection.h:74
Definition: TCPConnection.h:66
bool isOperational
Definition: TCP.h:159
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
Definition: TCPConnection.h:72
Definition: TCPConnection.h:63
Definition: TCPConnection.h:71
Definition: TCPConnection.h:65
Definition: TCPConnection.h:67
Definition: TCPConnection.h:64
Definition: TCPConnection.h:73
void inet::tcp::TCP::removeConnection ( TCPConnection conn)
protectedvirtual

Referenced by handleMessage().

466 {
467  EV_INFO << "Deleting TCP connection\n";
468 
469  AppConnKey key;
470  key.appGateIndex = conn->appGateIndex;
471  key.connId = conn->connId;
472  tcpAppConnMap.erase(key);
473 
474  SockPair key2;
475  key2.localAddr = conn->localAddr;
476  key2.remoteAddr = conn->remoteAddr;
477  key2.localPort = conn->localPort;
478  key2.remotePort = conn->remotePort;
479  tcpConnMap.erase(key2);
480 
481  // IMPORTANT: usedEphemeralPorts.erase(conn->localPort) is NOT GOOD because it
482  // deletes ALL occurrences of the port from the multiset.
483  auto it = usedEphemeralPorts.find(conn->localPort);
484 
485  if (it != usedEphemeralPorts.end())
486  usedEphemeralPorts.erase(it);
487 
488  emit(tcpConnectionRemovedSignal, conn);
489  delete conn;
490 }
TcpConnMap tcpConnMap
Definition: TCP.h:138
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
static simsignal_t tcpConnectionRemovedSignal
Definition: TCP.h:98
std::multiset< ushort > usedEphemeralPorts
Definition: TCP.h:141
void inet::tcp::TCP::reset ( )
virtual

Referenced by handleOperationStage().

563 {
564  for (auto & elem : tcpAppConnMap)
565  delete elem.second;
566  tcpAppConnMap.clear();
567  tcpConnMap.clear();
568  usedEphemeralPorts.clear();
570 }
TcpConnMap tcpConnMap
Definition: TCP.h:138
TcpAppConnMap tcpAppConnMap
Definition: TCP.h:137
ushort lastEphemeralPort
Definition: TCP.h:140
#define EPHEMERAL_PORTRANGE_START
Definition: TCP.cc:55
std::multiset< ushort > usedEphemeralPorts
Definition: TCP.h:141
void inet::tcp::TCP::segmentArrivalWhileClosed ( TCPSegment tcpseg,
L3Address  src,
L3Address  dest 
)
protectedvirtual

Referenced by handleMessage().

206 {
207  TCPConnection *tmp = new TCPConnection();
208  tmp->segmentArrivalWhileClosed(tcpseg, srcAddr, destAddr);
209  delete tmp;
210  delete tcpseg;
211 }
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).

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

421 {
422  // find with existing address/port pair...
423  SockPair key;
424  key.localAddr = conn->localAddr;
425  key.remoteAddr = conn->remoteAddr;
426  key.localPort = conn->localPort;
427  key.remotePort = conn->remotePort;
428  auto it = tcpConnMap.find(key);
429 
430  ASSERT(it != tcpConnMap.end() && it->second == conn);
431 
432  // ...and remove from the old place in tcpConnMap
433  tcpConnMap.erase(it);
434 
435  // then update addresses/ports, and re-insert it with new key into tcpConnMap
436  key.localAddr = conn->localAddr = localAddr;
437  key.remoteAddr = conn->remoteAddr = remoteAddr;
438  ASSERT(conn->localPort == localPort);
439  key.remotePort = conn->remotePort = remotePort;
440  tcpConnMap[key] = conn;
441 
442  // localPort doesn't change (see ASSERT above), so there's no need to update usedEphemeralPorts[].
443 }
TcpConnMap tcpConnMap
Definition: TCP.h:138

Member Data Documentation

bool inet::tcp::TCP::isOperational = false
ushort inet::tcp::TCP::lastEphemeralPort = (ushort)-1
protected

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

bool inet::tcp::TCP::logverbose
static
bool inet::tcp::TCP::recordStatistics = false
simsignal_t inet::tcp::TCP::tcpConnectionRemovedSignal = registerSignal("tcpConnectionRemoved")
static

Referenced by removeConnection().

TcpConnMap inet::tcp::TCP::tcpConnMap
protected
bool inet::tcp::TCP::testing
static
bool inet::tcp::TCP::useDataNotification = false
std::multiset<ushort> inet::tcp::TCP::usedEphemeralPorts
protected

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