|
INET Framework for OMNeT++/OMNEST
|
Implements the Tcp protocol.
More...
#include <Tcp.h>
|
| | 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 TcpSendQueue * | createSendQueue () |
| | To be called from TcpConnection: create a new send queue. More...
|
| |
| virtual TcpReceiveQueue * | createReceiveQueue () |
| | 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 () |
| |
| | TransportProtocolBase () |
| |
| virtual | ~OperationalMixin () |
| | }@ More...
|
| |
| virtual | ~ILifecycle () |
| |
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.
◆ TcpAppConnMap
◆ TcpConnMap
◆ PortRange
| Enumerator |
|---|
| EPHEMERAL_PORTRANGE_START | |
| EPHEMERAL_PORTRANGE_END | |
◆ Tcp()
◆ ~Tcp()
◆ addForkedConnection()
◆ addSockPair()
To be called from TcpConnection when a new connection gets created, during processing of OPEN_ACTIVE or OPEN_PASSIVE.
308 key.localAddr = conn->localAddr = localAddr;
309 key.remoteAddr = conn->remoteAddr = remoteAddr;
310 key.localPort = conn->localPort = localPort;
311 key.remotePort = conn->remotePort = remotePort;
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);
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);
Referenced by addForkedConnection(), inet::tcp::TcpConnection::process_OPEN_ACTIVE(), and inet::tcp::TcpConnection::process_OPEN_PASSIVE().
◆ checkCrc()
| bool inet::tcp::Tcp::checkCrc |
( |
Packet * |
pk | ) |
|
399 auto tcpHeader = tcpSegment->peekAtFront<TcpHeader>();
401 switch (tcpHeader->getCrcMode()) {
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());
414 pseudoHeader->setPacketLength(
B(tcpBytes.size()));
417 pseudoHeader->setChunkLength(
B(12));
419 pseudoHeader->setChunkLength(
B(40));
421 throw cRuntimeError(
"Unknown network protocol: %s", networkProtocol->getName());
422 MemoryOutputStream stream;
435 throw cRuntimeError(
"unknown CRC mode: %d", tcpHeader->getCrcMode());
Referenced by handleLowerPacket().
◆ createConnection()
Factory method; may be overriden for customizing Tcp.
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);
Referenced by handleUpperCommand().
◆ createReceiveQueue()
◆ createSendQueue()
◆ findConnForApp()
◆ findConnForSegment()
225 key.localAddr = destAddr;
226 key.remoteAddr = srcAddr;
227 key.localPort = tcpHeader->getDestPort();
228 key.remotePort = tcpHeader->getSrcPort();
237 key.localAddr = L3Address();
245 key.remoteAddr = L3Address();
253 key.localAddr = L3Address();
Referenced by handleLowerPacket().
◆ finish()
| void inet::tcp::Tcp::finish |
( |
| ) |
|
|
overrideprotectedvirtual |
91 EV_INFO << getFullPath() <<
": finishing with " <<
tcpConnMap.size() <<
" connections open.\n";
◆ getEphemeralPort()
| ushort inet::tcp::Tcp::getEphemeralPort |
( |
| ) |
|
|
virtual |
◆ getMsl()
| int inet::tcp::Tcp::getMsl |
( |
| ) |
|
|
inline |
◆ handleCrashOperation()
◆ handleLowerPacket()
| void inet::tcp::Tcp::handleLowerPacket |
( |
Packet * |
packet | ) |
|
|
overrideprotectedvirtual |
Reimplemented from inet::LayeredProtocolBase.
141 EV_WARN <<
"Tcp segment has wrong CRC, dropped\n";
142 PacketDropDetails details;
150 auto tcpHeader = packet->peekAtFront<TcpHeader>();
153 L3Address srcAddr, destAddr;
154 srcAddr = packet->getTag<
L3AddressInd>()->getSrcAddress();
155 destAddr = packet->getTag<
L3AddressInd>()->getDestAddress();
157 if (
auto ecnTag = packet->findTag<EcnInd>())
158 ecn = ecnTag->getExplicitCongestionNotification();
164 TcpStateVariables *state = conn->getState();
165 if (state && state->ect) {
169 state->gotCeIndication = (ecn == 3);
172 bool ret = conn->processTCPSegment(packet, tcpHeader, srcAddr, destAddr);
181 EV_DETAIL <<
"ICMP error received -- discarding\n";
185 throw cRuntimeError(
"Unknown protocol: '%s'", (
protocol !=
nullptr ?
protocol->getName() :
"<nullptr>"));
◆ handleSelfMessage()
| void inet::tcp::Tcp::handleSelfMessage |
( |
cMessage * |
message | ) |
|
|
overrideprotectedvirtual |
◆ handleStartOperation()
◆ handleStopOperation()
◆ handleUpperCommand()
| void inet::tcp::Tcp::handleUpperCommand |
( |
cMessage * |
message | ) |
|
|
overrideprotectedvirtual |
Reimplemented from inet::LayeredProtocolBase.
101 int socketId = check_and_cast<ITaggedObject *>(msg)->getTags().getTag<SocketReq>()->getSocketId();
111 EV_INFO <<
"Tcp connection created for " << msg <<
"\n";
114 if (!conn->processAppCommand(msg))
Referenced by handleUpperPacket().
◆ handleUpperPacket()
| void inet::tcp::Tcp::handleUpperPacket |
( |
Packet * |
packet | ) |
|
|
overrideprotectedvirtual |
◆ initialize()
| void inet::tcp::Tcp::initialize |
( |
int |
stage | ) |
|
|
overrideprotectedvirtual |
Reimplemented from inet::OperationalMixin< cSimpleModule >.
54 const char *crcModeString = par(
"crcMode");
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();
76 auto ipv4 =
dynamic_cast<INetfilter *
>(findModuleByPath(
"^.ipv4.ip"));
78 ipv4->registerHook(0, crcInsertion);
81 auto ipv6 =
dynamic_cast<INetfilter *
>(findModuleByPath(
"^.ipv6.ipv6"));
83 ipv6->registerHook(0, crcInsertion);
◆ numInitStages()
| virtual int inet::tcp::Tcp::numInitStages |
( |
| ) |
const |
|
inlineoverrideprotectedvirtual |
◆ refreshDisplay()
| void inet::tcp::Tcp::refreshDisplay |
( |
| ) |
const |
|
overrideprotectedvirtual |
442 if (getEnvir()->isExpressMode()) {
445 getDisplayString().setTagArg(
"t", 0,
"");
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;
454 int state = (elem).second->getFsmState();
511 sprintf(buf2 + strlen(buf2),
"init:%d ", numINIT);
513 sprintf(buf2 + strlen(buf2),
"closed:%d ", numCLOSED);
515 sprintf(buf2 + strlen(buf2),
"listen:%d ", numLISTEN);
517 sprintf(buf2 + strlen(buf2),
"syn_sent:%d ", numSYN_SENT);
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);
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);
531 sprintf(buf2 + strlen(buf2),
"closing:%d ", numCLOSING);
532 if (numTIME_WAIT > 0)
533 sprintf(buf2 + strlen(buf2),
"time_wait:%d ", numTIME_WAIT);
535 getDisplayString().setTagArg(
"t", 0, buf2);
◆ removeConnection()
◆ reset()
| void inet::tcp::Tcp::reset |
( |
| ) |
|
|
virtual |
◆ segmentArrivalWhileClosed()
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();
Referenced by handleLowerPacket().
◆ sendFromConn()
| void inet::tcp::Tcp::sendFromConn |
( |
cMessage * |
msg, |
|
|
const char * |
gatename, |
|
|
int |
gateindex = -1 |
|
) |
| |
|
virtual |
◆ updateSockPair()
To be called from TcpConnection when socket pair (key for TcpConnMap) changes (e.g.
becomes fully qualified).
337 key.localAddr = conn->localAddr;
338 key.remoteAddr = conn->remoteAddr;
339 key.localPort = conn->localPort;
340 key.remotePort = conn->remotePort;
343 ASSERT(it !=
tcpConnMap.end() && it->second == conn);
349 key.localAddr = conn->localAddr = localAddr;
350 key.remoteAddr = conn->remoteAddr = remoteAddr;
351 ASSERT(conn->localPort == localPort);
352 key.remotePort = conn->remotePort = remotePort;
Referenced by inet::tcp::TcpConnection::processSegmentInListen(), and inet::tcp::TcpConnection::processSegmentInSynSent().
◆ crcMode
◆ lastEphemeralPort
| ushort inet::tcp::Tcp::lastEphemeralPort = static_cast<ushort>(-1) |
|
protected |
◆ msl
◆ tcpAppConnMap
◆ tcpConnectionAddedSignal
| simsignal_t inet::tcp::Tcp::tcpConnectionAddedSignal = registerSignal("tcpConnectionAdded") |
|
static |
◆ tcpConnectionRemovedSignal
| simsignal_t inet::tcp::Tcp::tcpConnectionRemovedSignal = registerSignal("tcpConnectionRemoved") |
|
static |
◆ tcpConnMap
◆ 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:
int msl
Definition: Tcp.h:136
virtual void segmentArrivalWhileClosed(Packet *tcpSegment, const Ptr< const TcpHeader > &tcpHeader, L3Address src, L3Address dest)
Definition: Tcp.cc:263
@ EPHEMERAL_PORTRANGE_START
Definition: Tcp.h:91
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down protocol
Definition: IUdp-gates.txt:25
static const Protocol tcp
Definition: Protocol.h:112
@ INCORRECTLY_RECEIVED
Definition: Simsignals_m.h:71
static const Protocol ipv4
Definition: Protocol.h:93
static const Protocol ipv6
Definition: Protocol.h:94
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
static const Protocol icmpv4
Definition: Protocol.h:71
virtual void removeConnection(TcpConnection *conn)
Definition: Tcp.cc:198
@ CRC_COMPUTED
Definition: CrcMode_m.h:59
TcpAppConnMap tcpAppConnMap
Definition: Tcp.h:117
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
CrcMode crcMode
Definition: Tcp.h:135
TcpConnMap tcpConnMap
Definition: Tcp.h:118
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
bool checkCrc(Packet *pk)
Definition: Tcp.cc:397
CrcMode parseCrcMode(const char *crcModeString, bool allowDisable)
Definition: CrcMode.cc:14
@ TCP_S_INIT
Definition: TcpConnection.h:47
void registerService(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a service primitive (SDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:14
@ TCP_S_FIN_WAIT_1
Definition: TcpConnection.h:55
simsignal_t packetDroppedSignal
Definition: Simsignals.cc:85
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
intscale< b, 1, 8 > B
Definition: Units.h:1168
@ TCP_S_LISTEN
Definition: TcpConnection.h:49
bool useDataNotification
Definition: Tcp.h:134
@ TCP_S_CLOSED
Definition: TcpConnection.h:48
@ TCP_S_ESTABLISHED
Definition: TcpConnection.h:52
@ TCP_S_SYN_RCVD
Definition: TcpConnection.h:51
INET_API InitStage INITSTAGE_TRANSPORT_LAYER
Initialization of transport-layer protocols.
static simsignal_t tcpConnectionRemovedSignal
Definition: Tcp.h:88
@ TCP_S_CLOSE_WAIT
Definition: TcpConnection.h:53
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
@ TCP_S_TIME_WAIT
Definition: TcpConnection.h:58
virtual TcpConnection * findConnForSegment(const Ptr< const TcpHeader > &tcpHeader, L3Address srcAddr, L3Address destAddr)
Definition: Tcp.cc:222
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TcpIpChecksum.h:33
@ CRC_DECLARED_CORRECT
Definition: CrcMode_m.h:57
static const Protocol icmpv6
Definition: Protocol.h:72
@ IP_PROT_TCP
Definition: IpProtocolId_m.h:94
@ CRC_DECLARED_INCORRECT
Definition: CrcMode_m.h:58
virtual void delayActiveOperationFinish(simtime_t timeout)
Definition: OperationalMixinImpl.h:161
virtual void startActiveOperationExtraTimeOrFinish(simtime_t extraTime)
Definition: OperationalMixinImpl.h:179
#define Enter_Method(...)
Definition: SelfDoc.h:71
unsigned short ushort
Definition: INETDefs.h:54
virtual void reset()
Definition: Tcp.cc:386
virtual void handleUpperCommand(cMessage *message) override
Definition: Tcp.cc:99
virtual TcpConnection * findConnForApp(int socketId)
Definition: Tcp.cc:130
@ TCP_S_LAST_ACK
Definition: TcpConnection.h:54
@ TCP_S_CLOSING
Definition: TcpConnection.h:57
virtual void refreshDisplay() const override
Definition: OperationalMixinImpl.h:200
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
@ TCP_S_SYN_SENT
Definition: TcpConnection.h:50
virtual TcpConnection * createConnection(int socketId)
Factory method; may be overriden for customizing Tcp.
Definition: Tcp.cc:188
std::multiset< ushort > usedEphemeralPorts
Definition: Tcp.h:121
@ EPHEMERAL_PORTRANGE_END
Definition: Tcp.h:92
@ TCP_S_FIN_WAIT_2
Definition: TcpConnection.h:56
ushort lastEphemeralPort
Definition: Tcp.h:120
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