diff --git a/doc/src/developers-guide/ch-tcp.rst b/doc/src/developers-guide/ch-tcp.rst index 2c35806ae36..2d54d8b5498 100644 --- a/doc/src/developers-guide/ch-tcp.rst +++ b/doc/src/developers-guide/ch-tcp.rst @@ -111,10 +111,9 @@ The :ned:`Tcp` module has the following parameters: receiver buffer capacity (Note: normally, NIC queues should be at least this size, default is 14*mss) -- :par:`delayedAcksEnabled` delayed ACK algorithm (RFC 1122) - enabled/disabled +- :par:`delayedAcksEnabled` delayed ACK algorithm (RFC 1122) enabled/disabled -- :par:`nagleEnabled` Nagle’s algorithm (RFC 896) enabled/disabled +- :par:`nagleEnabled` Nagle's algorithm (RFC 1122) enabled/disabled - :par:`limitedTransmitEnabled` Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for @@ -123,18 +122,18 @@ The :ned:`Tcp` module has the following parameters: - :par:`increasedIWEnabled` Increased Initial Window (RFC 3390) enabled/disabled -- :par:`sackSupport` Selective Acknowledgment (RFC 2018, 2883, 3517) +- :par:`sackSupport` Selective Acknowledgment (RFC 2018, 2883, 6675) support (header option) (SACK will be enabled for a connection if both endpoints support it) -- :par:`windowScalingSupport` Window Scale (RFC 1323) support (header +- :par:`windowScalingSupport` Window Scale (RFC 7323) support (header option) (WS will be enabled for a connection if both endpoints support it) -- :par:`timestampSupport` Timestamps (RFC 1323) support (header option) +- :par:`timestampSupport` Timestamps (RFC 7323) support (header option) (TS will be enabled for a connection if both endpoints support it) -- :par:`mss` Maximum Segment Size (RFC 793) (header option, default is +- :par:`mss` Maximum Segment Size (RFC 9293) (header option, default is 536) - :par:`tcpAlgorithmClass` the name of the TCP flavour @@ -244,7 +243,7 @@ receives a TCP_I_CONNECTION_REFUSED message. If you do an active OPEN, then send data and close before the connection has reached ESTABLISHED, the connection will go from SYN_SENT to CLOSED without actually sending the buffered data. This is consistent with - RFC 793 but may not be what you would expect. + RFC 9293 but may not be what you would expect. @@ -403,10 +402,10 @@ etc. Because this algorithm does not send duplicate ACKs when it receives out-of-order segments, it does not work well together with other algorithms. -TcpBaseAlg +TcpAlgorithmBase ~~~~~~~~~~ -The :cpp:`TcpBaseAlg` is the base class of the INET implementation of +The :cpp:`TcpAlgorithmBase` is the base class of the INET implementation of Tahoe, Reno, and NewReno. It implements basic TCP algorithms for adaptive retransmissions, persistence timers, delayed ACKs, Nagle’s algorithm, Increased Initial Window – EXCLUDING congestion control. @@ -416,7 +415,7 @@ Delayed ACK ^^^^^^^^^^^ When the :par:`delayedAcksEnabled` parameter is set to true, the -:cpp:`TcpBaseAlg` applies a 200ms delay before sending ACKs. +:cpp:`TcpAlgorithmBase` applies a 200ms delay before sending ACKs. Nagle’s algorithm ^^^^^^^^^^^^^^^^^ @@ -443,7 +442,7 @@ If the :par:`increasedIWEnabled` parameter is true, then the initial window is increased to 4380 bytes, but at least 2 SMSS and at most 4 SMSS. The congestion window is not updated afterwards; subclasses can add congestion control by redefining virtual methods of the -:cpp:`TcpBaseAlg` class in their own class implementation. +:cpp:`TcpAlgorithmBase` class in their own class implementation. Duplicate ACKs ^^^^^^^^^^^^^^ @@ -469,7 +468,7 @@ Can be used to demonstrate the effect of lack of congestion control. TcpTahoe ~~~~~~~~ -The :cpp:`TcpTahoe` algorithm class extends :cpp:`TcpBaseAlg` with *Slow +The :cpp:`TcpTahoe` algorithm class extends :cpp:`TcpAlgorithmBase` with *Slow Start*, *Congestion Avoidance*, and *Fast Retransmit* congestion control algorithms. This algorithm initiates a *Slow Start* when a packet loss is detected. diff --git a/doc/src/msgtags.xml b/doc/src/msgtags.xml index fbde38f8a8f..c64416e9b18 100644 --- a/doc/src/msgtags.xml +++ b/doc/src/msgtags.xml @@ -57,6 +57,8 @@ types/msg-inet--aodv--Rreq.html + TcpAlgorithmBaseStateVariables + inet-tcp-TcpAlgorithmBaseStateVariables.html UnreachableNode types/msg-inet--aodv--UnreachableNode.html diff --git a/doc/src/users-guide/ch-transport.rst b/doc/src/users-guide/ch-transport.rst index a06d825bd3e..05b1cb8c81b 100644 --- a/doc/src/users-guide/ch-transport.rst +++ b/doc/src/users-guide/ch-transport.rst @@ -41,7 +41,7 @@ Overview The TCP protocol is the most widely used protocol of the Internet. It provides reliable, ordered delivery of a stream of bytes from one application on one computer to another application on another computer. -The baseline TCP protocol is described in RFC793, but other tens of RFCs +The baseline TCP protocol is described in RFC 9293, but other tens of RFCs contain modifications and extensions to TCP. As a result, TCP is a complex protocol and sometimes it is hard to see how the different requirements interact with each other. diff --git a/examples/emulation/extserver/omnetpp.ini b/examples/emulation/extserver/omnetpp.ini index dddd0d9c4b7..e5666bcf333 100644 --- a/examples/emulation/extserver/omnetpp.ini +++ b/examples/emulation/extserver/omnetpp.ini @@ -53,13 +53,13 @@ abstract = true **.tcp.typename = "Tcp" **.tcp.advertisedWindow = 65535 # in bytes, corresponds with the maximal receiver buffer capacity (Note: normally, NIC queues should be at least this size) **.tcp.delayedAcksEnabled = false # delayed ACK algorithm (RFC 1122) enabled/disabled -**.tcp.nagleEnabled = true # Nagle's algorithm (RFC 896) enabled/disabled +**.tcp.nagleEnabled = true # Nagle's algorithm (RFC 1122) enabled/disabled **.tcp.limitedTransmitEnabled = false # Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl) **.tcp.increasedIWEnabled = false # Increased Initial Window (RFC 3390) enabled/disabled -**.tcp.sackSupport = true # Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) -**.tcp.windowScalingSupport = false # Window Scale (RFC 1323) support (header option) (WS will be enabled for a connection if both endpoints support it) -**.tcp.timestampSupport = false # Timestamps (RFC 1323) support (header option) (TS will be enabled for a connection if both endpoints support it) -**.tcp.mss = 1452 # Maximum Segment Size (RFC 793) (header option) +**.tcp.sackSupport = true # Selective Acknowledgment (RFC 2018, 2883, 6675) support (header option) (SACK will be enabled for a connection if both endpoints support it) +**.tcp.windowScalingSupport = false # Window Scale (RFC 7323) support (header option) (WS will be enabled for a connection if both endpoints support it) +**.tcp.timestampSupport = false # Timestamps (RFC 7323) support (header option) (TS will be enabled for a connection if both endpoints support it) +**.tcp.mss = 1452 # Maximum Segment Size (RFC 9293) (header option) **.tcp.tcpAlgorithmClass = "TcpReno" # TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl/DumbTcp # pcapRecorder settings diff --git a/examples/inet/ber/omnetpp.ini b/examples/inet/ber/omnetpp.ini index 365e55788f4..58e363c79d0 100644 --- a/examples/inet/ber/omnetpp.ini +++ b/examples/inet/ber/omnetpp.ini @@ -49,13 +49,13 @@ abstract = true **.tcp.typename = "Tcp" **.tcp.advertisedWindow = 65535 # in bytes, corresponds with the maximal receiver buffer capacity (Note: normally, NIC queues should be at least this size) **.tcp.delayedAcksEnabled = false # delayed ACK algorithm (RFC 1122) enabled/disabled -**.tcp.nagleEnabled = true # Nagle's algorithm (RFC 896) enabled/disabled +**.tcp.nagleEnabled = true # Nagle's algorithm (RFC 1122) enabled/disabled **.tcp.limitedTransmitEnabled = false # Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl) **.tcp.increasedIWEnabled = false # Increased Initial Window (RFC 3390) enabled/disabled -**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) -**.tcp.windowScalingSupport = false # Window Scale (RFC 1323) support (header option) (WS will be enabled for a connection if both endpoints support it) -**.tcp.timestampSupport = false # Timestamps (RFC 1323) support (header option) (TS will be enabled for a connection if both endpoints support it) -**.tcp.mss = 1452 # Maximum Segment Size (RFC 793) (header option) +**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 6675) support (header option) (SACK will be enabled for a connection if both endpoints support it) +**.tcp.windowScalingSupport = false # Window Scale (RFC 7323) support (header option) (WS will be enabled for a connection if both endpoints support it) +**.tcp.timestampSupport = false # Timestamps (RFC 7323) support (header option) (TS will be enabled for a connection if both endpoints support it) +**.tcp.mss = 1452 # Maximum Segment Size (RFC 9293) (header option) **.tcp.tcpAlgorithmClass = "TcpReno" # TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl/DumbTcp # RNG/seed settings diff --git a/examples/inet/dctcp/omnetpp.ini b/examples/inet/dctcp/omnetpp.ini index 5d4c1960bcf..38b5fa9b75f 100644 --- a/examples/inet/dctcp/omnetpp.ini +++ b/examples/inet/dctcp/omnetpp.ini @@ -22,12 +22,12 @@ cmdenv-event-banners = true # for normal (non-express) mode only **.tcp.delayedAcksEnabled = false # delayed ACK algorithm (RFC 1122) enabled/disabled -**.tcp.nagleEnabled = false # Nagle's algorithm (RFC 896) enabled/disabled +**.tcp.nagleEnabled = false # Nagle's algorithm (RFC 1122) enabled/disabled **.tcp.limitedTransmitEnabled = false # Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TCPReno/TCPTahoe/TCPNewReno/TCPNoCongestionControl) **.tcp.increasedIWEnabled = false # Increased Initial Window (RFC 3390) enabled/disabled -**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) -**.tcp.windowScalingSupport = true # Window Scale (RFC 1323) support (header option) (WS will be enabled for a connection if both endpoints support it) -**.tcp.timestampSupport = false # Timestamps (RFC 1323) support (header option) (TS will be enabled for a connection if both endpoints support it) +**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 6675) support (header option) (SACK will be enabled for a connection if both endpoints support it) +**.tcp.windowScalingSupport = true # Window Scale (RFC 7323) support (header option) (WS will be enabled for a connection if both endpoints support it) +**.tcp.timestampSupport = false # Timestamps (RFC 7323) support (header option) (TS will be enabled for a connection if both endpoints support it) **.tcp.tcpAlgorithmClass = "DcTcp" # TCPReno/TCPTahoe/TCPNewReno/TCPNoCongestionControl/DumbTCP **.tcp.advertisedWindow = 350000 **.tcp.mss = 1460 diff --git a/examples/inet/redmarker/omnetpp.ini b/examples/inet/redmarker/omnetpp.ini index 037173a8f13..d6809dd3d6c 100644 --- a/examples/inet/redmarker/omnetpp.ini +++ b/examples/inet/redmarker/omnetpp.ini @@ -22,12 +22,12 @@ sim-time-limit = 100s **.tcp.typename = "Tcp" **.tcp.delayedAcksEnabled = false # delayed ACK algorithm (RFC 1122) enabled/disabled -**.tcp.nagleEnabled = false # Nagle's algorithm (RFC 896) enabled/disabled +**.tcp.nagleEnabled = false # Nagle's algorithm (RFC 1122) enabled/disabled **.tcp.limitedTransmitEnabled = false # Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TCPReno/TCPTahoe/TCPNewReno/TCPNoCongestionControl) **.tcp.increasedIWEnabled = false # Increased Initial Window (RFC 3390) enabled/disabled -**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) -**.tcp.windowScalingSupport = true # Window Scale (RFC 1323) support (header option) (WS will be enabled for a connection if both endpoints support it) -**.tcp.timestampSupport = false # Timestamps (RFC 1323) support (header option) (TS will be enabled for a connection if both endpoints support it) +**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 6675) support (header option) (SACK will be enabled for a connection if both endpoints support it) +**.tcp.windowScalingSupport = true # Window Scale (RFC 7323) support (header option) (WS will be enabled for a connection if both endpoints support it) +**.tcp.timestampSupport = false # Timestamps (RFC 7323) support (header option) (TS will be enabled for a connection if both endpoints support it) **.tcp.tcpAlgorithmClass = "TcpReno" # TCPReno/TCPTahoe/TCPNewReno/TCPNoCongestionControl/DumbTCP **.tcp.advertisedWindow = 5000000 **.tcp.mss = 1460 diff --git a/examples/inet/tcpwindowscale/omnetpp.ini b/examples/inet/tcpwindowscale/omnetpp.ini index 2d32a7b3320..5a5c11a4efd 100644 --- a/examples/inet/tcpwindowscale/omnetpp.ini +++ b/examples/inet/tcpwindowscale/omnetpp.ini @@ -44,13 +44,13 @@ sim-time-limit = 600.0s **.tcp.typename = "Tcp" **.tcp.advertisedWindow = 65535 # in bytes, corresponds with the maximal receiver buffer capacity (Note: normally, NIC queues should be at least this size) **.tcp.delayedAcksEnabled = false # delayed ACK algorithm (RFC 1122) enabled/disabled -**.tcp.nagleEnabled = true # Nagle's algorithm (RFC 896) enabled/disabled +**.tcp.nagleEnabled = true # Nagle's algorithm (RFC 1122) enabled/disabled **.tcp.limitedTransmitEnabled = false # Limited Transmit algorithm (RFC 3042) enabled/disabled (can be used for TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl) **.tcp.increasedIWEnabled = false # Increased Initial Window (RFC 3390) enabled/disabled -**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 3517) support (header option) (SACK will be enabled for a connection if both endpoints support it) -**.tcp.windowScalingSupport = false # Window Scale (RFC 1323) support (header option) (WS will be enabled for a connection if both endpoints support it) -**.tcp.timestampSupport = false # Timestamps (RFC 1323) support (header option) (TS will be enabled for a connection if both endpoints support it) -**.tcp.mss = 1452 # Maximum Segment Size (RFC 793) (header option) +**.tcp.sackSupport = false # Selective Acknowledgment (RFC 2018, 2883, 6675) support (header option) (SACK will be enabled for a connection if both endpoints support it) +**.tcp.windowScalingSupport = false # Window Scale (RFC 7323) support (header option) (WS will be enabled for a connection if both endpoints support it) +**.tcp.timestampSupport = false # Timestamps (RFC 7323) support (header option) (TS will be enabled for a connection if both endpoints support it) +**.tcp.mss = 1452 # Maximum Segment Size (RFC 9293) (header option) **.tcp.tcpAlgorithmClass = "TcpReno" # TcpReno/TcpTahoe/TcpNewReno/TcpNoCongestionControl/DumbTcp # diff --git a/src/inet/applications/tcpapp/TcpAppBase.cc b/src/inet/applications/tcpapp/TcpAppBase.cc index 027424498da..6cc08b87b79 100644 --- a/src/inet/applications/tcpapp/TcpAppBase.cc +++ b/src/inet/applications/tcpapp/TcpAppBase.cc @@ -97,11 +97,11 @@ void TcpAppBase::close() emit(connectSignal, -1L); } -void TcpAppBase::sendPacket(Packet *msg) +void TcpAppBase::sendPacket(Packet *msg, bool eor) { int numBytes = msg->getByteLength(); emit(packetSentSignal, msg); - socket.send(msg); + socket.send(msg, eor); packetsSent++; bytesSent += numBytes; diff --git a/src/inet/applications/tcpapp/TcpAppBase.h b/src/inet/applications/tcpapp/TcpAppBase.h index 213ae952b7f..ddbc850dd8d 100644 --- a/src/inet/applications/tcpapp/TcpAppBase.h +++ b/src/inet/applications/tcpapp/TcpAppBase.h @@ -45,7 +45,7 @@ class INET_API TcpAppBase : public ApplicationBase, public TcpSocket::ICallback /* Utility functions */ virtual void connect(); virtual void close(); - virtual void sendPacket(Packet *pkt); + virtual void sendPacket(Packet *pkt, bool eor = false); virtual void handleTimer(cMessage *msg) = 0; diff --git a/src/inet/applications/tcpapp/TcpSessionApp.cc b/src/inet/applications/tcpapp/TcpSessionApp.cc index 4df7141be6d..dbb9fefeef0 100644 --- a/src/inet/applications/tcpapp/TcpSessionApp.cc +++ b/src/inet/applications/tcpapp/TcpSessionApp.cc @@ -124,8 +124,9 @@ void TcpSessionApp::handleTimer(cMessage *msg) void TcpSessionApp::sendData() { long numBytes = commands[commandIndex].numBytes; - EV_INFO << "sending data with " << numBytes << " bytes\n"; - sendPacket(createDataPacket(numBytes)); + bool eor = commands[commandIndex].eor; + EV_INFO << "sending data with " << numBytes << " bytes" << (eor ? " (eor)" : "") << "\n"; + sendPacket(createDataPacket(numBytes), eor); if (++commandIndex < (int)commands.size()) { simtime_t tSend = commands[commandIndex].tSend; @@ -148,7 +149,8 @@ Packet *TcpSessionApp::createDataPacket(long sendBytes) const char *dataTransferMode = par("dataTransferMode"); Ptr payload; if (!strcmp(dataTransferMode, "bytecount")) { - payload = makeShared(B(sendBytes)); + int packetData = par("packetData"); + payload = packetData == -1 ? makeShared(B(sendBytes)) : makeShared(B(sendBytes), packetData); } else if (!strcmp(dataTransferMode, "object")) { const auto& applicationPacket = makeShared(); @@ -159,8 +161,9 @@ Packet *TcpSessionApp::createDataPacket(long sendBytes) const auto& bytesChunk = makeShared(); std::vector vec; vec.resize(sendBytes); + int packetData = par("packetData"); for (int i = 0; i < sendBytes; i++) - vec[i] = (bytesSent + i) & 0xFF; + vec[i] = packetData == -1 ? (bytesSent + i) & 0xFF : packetData; bytesChunk->setBytes(vec); payload = bytesChunk; } @@ -236,9 +239,20 @@ void TcpSessionApp::parseScript(const char *script) while (isdigit(*s)) s++; + // MSG_EOR: optional "eor" keyword right after the byte + // count marks this command's SEND as a record boundary. + while (isspace(*s)) + s++; + + bool eor = false; + if (strncmp(s, "eor", 3) == 0 && !isalnum(s[3])) { + eor = true; + s += 3; + } + // add command - EV_DEBUG << " add command (" << tSend << "s, " << numBytes << "B)\n"; - commands.push_back(Command(tSend, numBytes)); + EV_DEBUG << " add command (" << tSend << "s, " << numBytes << "B" << (eor ? ", eor" : "") << ")\n"; + commands.push_back(Command(tSend, numBytes, eor)); // skip delimiter while (isspace(*s)) diff --git a/src/inet/applications/tcpapp/TcpSessionApp.h b/src/inet/applications/tcpapp/TcpSessionApp.h index 9b9fa6b4fdf..d2b91e582e3 100644 --- a/src/inet/applications/tcpapp/TcpSessionApp.h +++ b/src/inet/applications/tcpapp/TcpSessionApp.h @@ -25,7 +25,8 @@ class INET_API TcpSessionApp : public TcpAppBase struct Command { simtime_t tSend; long numBytes = 0; - Command(simtime_t t, long n) { tSend = t; numBytes = n; } + bool eor = false; // MSG_EOR: "eor" keyword after the byte count in sendScript + Command(simtime_t t, long n, bool e = false) { tSend = t; numBytes = n; eor = e; } }; typedef std::vector CommandVector; CommandVector commands; diff --git a/src/inet/applications/tcpapp/TcpSessionApp.ned b/src/inet/applications/tcpapp/TcpSessionApp.ned index a7524dfc2b6..d96b81ec483 100644 --- a/src/inet/applications/tcpapp/TcpSessionApp.ned +++ b/src/inet/applications/tcpapp/TcpSessionApp.ned @@ -38,7 +38,10 @@ import inet.applications.contract.IApp; // data. One way of specifying sending is via the `tSend`, `sendBytes` // parameters, the other way is with `sendScript`. With the former, `sendBytes` // bytes will be sent at `tSend`. With `sendScript`, the format is -// "