2010-12-17 13:57:22 -05:00
|
|
|
/*
|
Mixed bugfixes on TCP, closes bug 1166, 1227, 1242.
1. Make connection count (m_cnCount) a separate variable from the number of
connection retries (m_cnRetries), so that the number of connection retries
can be cloned without affecting the number of connections to be made in the
cloned sockets.
2. There was a case that the m_highTxMark was mistaken as m_nextTxSequence
3. Update m_lastRtt correctly, fixes bug 1242
4. The endpoint allocation/deallocation is rewritten so that the endpoint
remembers the correct peer's address and it is deleted upon close.
RecvFrom() call now use the data in endpoint to return the peer's address,
and the socket closes nicely.
5. TcpL4Protocol::m_sockets now holds a complete list of all existing sockets
6. RST packet is sent before CloseAndNotify() is called, so that m_endPoint is
not yet destroyed, fixes bug 1166
7. Fix cwnd deflation bug in partial ACK handling in TcpNewReno
8. Created attributes for fast retransmit threshold (m_retxThresh) and max
advertised window size (m_maxWinSize)
9. Refactor SendPendingData() and DoRetransmit(), created SendDataPacket()
10. Call NotifySend() after connection established in ProcessSynSent() and
ProcessSynRcvd()
11. Defines new flags in TcpHeader: ECE and CWR (see RFC3168)
12. Prepared hooks for TCP option handling
13. Code tidy up
14. Fix the definition of out-of-order packets
15. TCP can now move from TIME_WAIT state to CLOSED state after 2*MSL
16. Implemented limited transmit (RFC3042) in TcpNewReno, c.f. bug 1227
17. Added Raj's email to the preamble, as TcpSocketBase was modified from
TcpSocketImpl.
2011-12-01 04:53:20 -05:00
|
|
|
* Copyright (c) 2007 Georgia Tech Research Corporation
|
2010-12-17 13:57:22 -05:00
|
|
|
* Copyright (c) 2010 Adrian Sai-wah Tam
|
|
|
|
|
*
|
2024-06-17 16:17:10 +02:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
2010-12-17 13:57:22 -05:00
|
|
|
*
|
|
|
|
|
* Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
|
|
|
|
|
*/
|
|
|
|
|
#ifndef TCP_SOCKET_BASE_H
|
|
|
|
|
#define TCP_SOCKET_BASE_H
|
|
|
|
|
|
2023-09-12 16:55:35 +01:00
|
|
|
#include "ipv4-header.h"
|
|
|
|
|
#include "ipv6-header.h"
|
|
|
|
|
#include "tcp-socket-state.h"
|
|
|
|
|
#include "tcp-socket.h"
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
#include "ns3/data-rate.h"
|
2018-02-25 11:32:43 +01:00
|
|
|
#include "ns3/node.h"
|
2022-10-07 20:08:35 +00:00
|
|
|
#include "ns3/sequence-number.h"
|
|
|
|
|
#include "ns3/timer.h"
|
|
|
|
|
#include "ns3/traced-value.h"
|
|
|
|
|
|
|
|
|
|
#include <queue>
|
|
|
|
|
#include <stdint.h>
|
2010-12-17 13:57:22 -05:00
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
namespace ns3
|
|
|
|
|
{
|
2010-12-17 13:57:22 -05:00
|
|
|
|
|
|
|
|
class Ipv4EndPoint;
|
2012-02-20 14:05:07 +01:00
|
|
|
class Ipv6EndPoint;
|
2010-12-17 13:57:22 -05:00
|
|
|
class Node;
|
|
|
|
|
class Packet;
|
|
|
|
|
class TcpL4Protocol;
|
|
|
|
|
class TcpHeader;
|
2016-04-18 17:04:13 +02:00
|
|
|
class TcpCongestionOps;
|
2018-05-11 19:30:43 +02:00
|
|
|
class TcpRecoveryOps;
|
2018-02-25 11:32:43 +01:00
|
|
|
class RttEstimator;
|
|
|
|
|
class TcpRxBuffer;
|
|
|
|
|
class TcpTxBuffer;
|
|
|
|
|
class TcpOption;
|
|
|
|
|
class Ipv4Interface;
|
|
|
|
|
class Ipv6Interface;
|
2018-06-18 23:31:09 +02:00
|
|
|
class TcpRateOps;
|
2010-12-17 13:57:22 -05:00
|
|
|
|
2015-01-30 22:29:30 +01:00
|
|
|
/**
|
|
|
|
|
* \ingroup tcp
|
|
|
|
|
*
|
|
|
|
|
* \brief Helper class to store RTT measurements
|
|
|
|
|
*/
|
2016-01-22 14:29:07 +01:00
|
|
|
class RttHistory
|
|
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* \brief Constructor - builds an RttHistory with the given parameters
|
|
|
|
|
* \param s First sequence number in packet sent
|
|
|
|
|
* \param c Number of bytes sent
|
|
|
|
|
* \param t Time this one was sent
|
|
|
|
|
*/
|
|
|
|
|
RttHistory(SequenceNumber32 s, uint32_t c, Time t);
|
|
|
|
|
/**
|
|
|
|
|
* \brief Copy constructor
|
|
|
|
|
* \param h the object to copy
|
|
|
|
|
*/
|
|
|
|
|
RttHistory(const RttHistory& h); // Copy constructor
|
|
|
|
|
public:
|
|
|
|
|
SequenceNumber32 seq; //!< First sequence number in packet sent
|
|
|
|
|
uint32_t count; //!< Number of bytes sent
|
|
|
|
|
Time time; //!< Time this one was sent
|
|
|
|
|
bool retx; //!< True if this has been retransmitted
|
2015-01-30 22:29:30 +01:00
|
|
|
};
|
|
|
|
|
|
2010-12-17 13:57:22 -05:00
|
|
|
/**
|
|
|
|
|
* \ingroup socket
|
|
|
|
|
* \ingroup tcp
|
|
|
|
|
*
|
|
|
|
|
* \brief A base class for implementation of a stream socket using TCP.
|
|
|
|
|
*
|
|
|
|
|
* This class contains the essential components of TCP, as well as a sockets
|
2017-02-03 14:03:01 +01:00
|
|
|
* interface for upper layers to call. This class provides connection orientation
|
|
|
|
|
* and sliding window flow control; congestion control is delegated to subclasses
|
|
|
|
|
* of TcpCongestionOps. Part of TcpSocketBase is modified from the original
|
|
|
|
|
* NS-3 TCP socket implementation (TcpSocketImpl) by
|
|
|
|
|
* Raj Bhattacharjea <raj.b@gatech.edu> of Georgia Tech.
|
2015-10-16 10:38:51 -07:00
|
|
|
*
|
2016-07-14 15:59:55 +02:00
|
|
|
* For IPv4 packets, the TOS set for the socket is used. The Bind and Connect
|
|
|
|
|
* operations set the TOS for the socket to the value specified in the provided
|
|
|
|
|
* address. A SocketIpTos tag is only added to the packet if the resulting
|
|
|
|
|
* TOS is non-null.
|
2016-07-14 15:59:55 +02:00
|
|
|
* Each packet is assigned the priority set for the socket. Setting a TOS
|
|
|
|
|
* for a socket also sets a priority for the socket (according to the
|
|
|
|
|
* Socket::IpTos2Priority function). A SocketPriority tag is only added to the
|
|
|
|
|
* packet if the priority is non-null.
|
2016-07-14 15:59:55 +02:00
|
|
|
*
|
2015-10-16 10:44:38 -07:00
|
|
|
* Congestion state machine
|
2015-10-16 10:39:02 -07:00
|
|
|
* ---------------------------
|
|
|
|
|
*
|
|
|
|
|
* The socket maintains two state machines; the TCP one, and another called
|
2015-10-16 10:44:38 -07:00
|
|
|
* "Congestion state machine", which keeps track of the phase we are in. Currently,
|
2015-10-16 10:39:02 -07:00
|
|
|
* ns-3 manages the states:
|
|
|
|
|
*
|
2015-10-16 10:44:38 -07:00
|
|
|
* - CA_OPEN
|
|
|
|
|
* - CA_DISORDER
|
|
|
|
|
* - CA_RECOVERY
|
|
|
|
|
* - CA_LOSS
|
2020-12-13 20:01:03 -08:00
|
|
|
* - CA_CWR
|
2015-10-16 10:39:02 -07:00
|
|
|
*
|
2020-12-13 20:01:03 -08:00
|
|
|
* For more information, see the TcpCongState_t documentation.
|
2015-10-16 10:39:02 -07:00
|
|
|
*
|
2015-10-16 10:42:14 -07:00
|
|
|
* Congestion control interface
|
|
|
|
|
* ---------------------------
|
|
|
|
|
*
|
2017-02-03 14:03:01 +01:00
|
|
|
* Congestion control, unlike older releases of ns-3, has been split from
|
2015-10-16 10:42:30 -07:00
|
|
|
* TcpSocketBase. In particular, each congestion control is now a subclass of
|
|
|
|
|
* the main TcpCongestionOps class. Switching between congestion algorithm is
|
2017-02-03 14:03:01 +01:00
|
|
|
* now a matter of setting a pointer into the TcpSocketBase class. The idea
|
|
|
|
|
* and the interfaces are inspired by the Linux operating system, and in
|
2018-08-26 06:33:14 -07:00
|
|
|
* particular from the structure tcp_congestion_ops. The reference paper is
|
2022-06-06 01:24:09 -03:00
|
|
|
* https://www.sciencedirect.com/science/article/abs/pii/S1569190X15300939.
|
2017-02-03 14:03:01 +01:00
|
|
|
*
|
|
|
|
|
* Transmission Control Block (TCB)
|
|
|
|
|
* --------------------------------
|
2015-10-16 10:42:30 -07:00
|
|
|
*
|
|
|
|
|
* The variables needed to congestion control classes to operate correctly have
|
|
|
|
|
* been moved inside the TcpSocketState class. It contains information on the
|
|
|
|
|
* congestion window, slow start threshold, segment size and the state of the
|
2015-10-16 10:44:38 -07:00
|
|
|
* Congestion state machine.
|
2015-10-16 10:42:30 -07:00
|
|
|
*
|
|
|
|
|
* To track the trace inside the TcpSocketState class, a "forward" technique is
|
|
|
|
|
* used, which consists in chaining callbacks from TcpSocketState to TcpSocketBase
|
|
|
|
|
* (see for example cWnd trace source).
|
2015-10-16 10:42:14 -07:00
|
|
|
*
|
2015-10-16 10:38:51 -07:00
|
|
|
* Fast retransmit
|
2017-02-03 14:03:01 +01:00
|
|
|
* ----------------
|
2015-10-16 10:38:51 -07:00
|
|
|
*
|
2018-03-03 12:00:13 +01:00
|
|
|
* The fast retransmit enhancement is introduced in RFC 2581 and updated in RFC
|
|
|
|
|
* 5681. It reduces the time a sender waits before retransmitting a lost segment,
|
|
|
|
|
* through the assumption that if it receives a certain number of duplicate ACKs,
|
|
|
|
|
* a segment has been lost and it can be retransmitted. Usually, it is coupled
|
|
|
|
|
* with the Limited Transmit algorithm, defined in RFC 3042. These algorithms
|
|
|
|
|
* are included in this class, and they are implemented inside the ProcessAck
|
|
|
|
|
* method. With the SACK option enabled, the LimitedTransmit algorithm will be
|
|
|
|
|
* always on, as a consequence of how the information in the received SACK block
|
|
|
|
|
* is managed.
|
2015-10-16 10:38:51 -07:00
|
|
|
*
|
2018-03-03 12:00:13 +01:00
|
|
|
* The attribute which manages the number of dup ACKs necessary to start the
|
|
|
|
|
* fast retransmit algorithm is named "ReTxThreshold", and by default is 3.
|
|
|
|
|
* The parameter is also used in TcpTxBuffer to determine if a packet is lost
|
|
|
|
|
* (please take a look at TcpTxBuffer documentation to see details) but,
|
|
|
|
|
* right now, it is assumed to be fixed. In future releases this parameter can
|
|
|
|
|
* be made dynamic, to reflect the reordering degree of the network. With SACK,
|
|
|
|
|
* the next sequence to transmit is given by the RFC 6675 algorithm. Without
|
|
|
|
|
* SACK option, the implementation adds "hints" to TcpTxBuffer to make sure it
|
|
|
|
|
* returns, as next transmittable sequence, the first lost (or presumed lost)
|
|
|
|
|
* segment.
|
2015-10-16 10:38:51 -07:00
|
|
|
*
|
|
|
|
|
* Fast recovery
|
2017-02-03 14:03:01 +01:00
|
|
|
* -------------
|
2015-10-16 10:38:51 -07:00
|
|
|
*
|
2018-03-03 12:00:13 +01:00
|
|
|
* The fast recovery algorithm is introduced RFC 2001, and it avoids to reset
|
|
|
|
|
* cWnd to 1 segment after sensing a loss on the channel. Instead, a new slow
|
|
|
|
|
* start threshold value is asked to the congestion control (for instance,
|
|
|
|
|
* with NewReno the returned amount is half of the previous), and the cWnd is
|
|
|
|
|
* set equal to such value. Ns-3 does not implement any inflation/deflation to
|
|
|
|
|
* the congestion window since it uses an evolved method (borrowed from Linux
|
|
|
|
|
* operating system) to calculate the number of bytes in flight. The fundamental
|
|
|
|
|
* idea is to subtract from the total bytes in flight the lost/sacked amount
|
|
|
|
|
* (the segments that have left the network) and to add the retransmitted count.
|
|
|
|
|
* In this way, congestion window represents the exact number of bytes that
|
|
|
|
|
* should be in flight. The implementation then decides what to transmit, it
|
|
|
|
|
* there is space, between new or already transmitted data portion. If a value
|
|
|
|
|
* of the congestion window with inflation and deflation is needed, there is a
|
|
|
|
|
* traced source named "CongestionWindowInflated". However, the variable behind
|
|
|
|
|
* it is not used in the code, but maintained for backward compatibility.
|
2015-10-16 10:38:51 -07:00
|
|
|
*
|
2017-02-03 14:03:01 +01:00
|
|
|
* RTO expiration
|
|
|
|
|
* --------------
|
|
|
|
|
*
|
2018-03-03 12:00:13 +01:00
|
|
|
* When the Retransmission Time Out expires, the TCP faces a significant
|
|
|
|
|
* performance drop. The expiration event is managed in the ReTxTimeout method,
|
|
|
|
|
* which set the cWnd to 1 segment and starts "from scratch" again. The list
|
|
|
|
|
* of sent packet is set as lost entirely, and the transmission is re-started
|
|
|
|
|
* from the SND.UNA sequence number.
|
2017-02-03 14:03:01 +01:00
|
|
|
*
|
|
|
|
|
* Options management
|
|
|
|
|
* ------------------
|
|
|
|
|
*
|
|
|
|
|
* SYN and SYN-ACK options, which are allowed only at the beginning of the
|
|
|
|
|
* connection, are managed in the DoForwardUp and SendEmptyPacket methods.
|
|
|
|
|
* To read all others, we have set up a cycle inside ReadOptions. For adding
|
|
|
|
|
* them, there is no a unique place, since the options (and the information
|
|
|
|
|
* available to build them) are scattered around the code. For instance,
|
|
|
|
|
* the SACK option is built in SendEmptyPacket only under certain conditions.
|
|
|
|
|
*
|
|
|
|
|
* SACK
|
|
|
|
|
* ----
|
|
|
|
|
*
|
|
|
|
|
* The SACK generation/management is delegated to the buffer classes, namely
|
2018-03-03 12:00:13 +01:00
|
|
|
* TcpTxBuffer and TcpRxBuffer. In TcpRxBuffer it is managed the creation
|
|
|
|
|
* of the SACK option from the receiver point of view. It must provide an
|
|
|
|
|
* accurate (and efficient) representation of the status of the receiver buffer.
|
|
|
|
|
* On the other side, inside TcpTxBuffer the received options (that contain
|
|
|
|
|
* the SACK block) are processed and a particular data structure, called Scoreboard,
|
|
|
|
|
* is filled. Please take a look at TcpTxBuffer and TcpRxBuffer documentation if
|
2018-08-26 06:33:14 -07:00
|
|
|
* you need more information. The reference paper is
|
|
|
|
|
* https://dl.acm.org/citation.cfm?id=3067666.
|
2017-02-03 14:03:01 +01:00
|
|
|
*
|
2010-12-17 13:57:22 -05:00
|
|
|
*/
|
|
|
|
|
class TcpSocketBase : public TcpSocket
|
|
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* Get the type ID.
|
|
|
|
|
* \brief Get the type ID.
|
|
|
|
|
* \return the object TypeId
|
|
|
|
|
*/
|
|
|
|
|
static TypeId GetTypeId();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get the instance TypeId
|
|
|
|
|
* \return the instance TypeId
|
|
|
|
|
*/
|
|
|
|
|
TypeId GetInstanceTypeId() const override;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief TcpGeneralTest friend class (for tests).
|
|
|
|
|
* \relates TcpGeneralTest
|
|
|
|
|
*/
|
|
|
|
|
friend class TcpGeneralTest;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create an unbound TCP socket
|
|
|
|
|
*/
|
|
|
|
|
TcpSocketBase();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Clone a TCP socket, for use upon receiving a connection request in LISTEN state
|
|
|
|
|
*
|
|
|
|
|
* \param sock the original Tcp Socket
|
|
|
|
|
*/
|
|
|
|
|
TcpSocketBase(const TcpSocketBase& sock);
|
|
|
|
|
~TcpSocketBase() override;
|
|
|
|
|
|
2024-09-04 14:38:52 +05:30
|
|
|
/**
|
|
|
|
|
* \brief Tcp Packet Types
|
|
|
|
|
*
|
|
|
|
|
* Taxonomy referred from Table 1 of
|
|
|
|
|
* https://www.ietf.org/archive/id/draft-ietf-tcpm-generalized-ecn-15.txt
|
|
|
|
|
*/
|
|
|
|
|
enum TcpPacketType_t
|
|
|
|
|
{
|
|
|
|
|
SYN,
|
|
|
|
|
SYN_ACK,
|
|
|
|
|
PURE_ACK,
|
|
|
|
|
WINDOW_PROBE,
|
|
|
|
|
FIN,
|
|
|
|
|
RST,
|
|
|
|
|
RE_XMT,
|
2024-10-05 17:24:01 +00:00
|
|
|
DATA,
|
|
|
|
|
INVALID
|
2024-09-04 14:38:52 +05:30
|
|
|
};
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
// Set associated Node, TcpL4Protocol, RttEstimator to this socket
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Set the associated node.
|
|
|
|
|
* \param node the node
|
|
|
|
|
*/
|
|
|
|
|
virtual void SetNode(Ptr<Node> node);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Set the associated TCP L4 protocol.
|
|
|
|
|
* \param tcp the TCP L4 protocol
|
|
|
|
|
*/
|
|
|
|
|
virtual void SetTcp(Ptr<TcpL4Protocol> tcp);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Set the associated RTT estimator.
|
|
|
|
|
* \param rtt the RTT estimator
|
|
|
|
|
*/
|
|
|
|
|
virtual void SetRtt(Ptr<RttEstimator> rtt);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Sets the Minimum RTO.
|
|
|
|
|
* \param minRto The minimum RTO.
|
|
|
|
|
*/
|
|
|
|
|
void SetMinRto(Time minRto);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get the Minimum RTO.
|
|
|
|
|
* \return The minimum RTO.
|
|
|
|
|
*/
|
|
|
|
|
Time GetMinRto() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Sets the Clock Granularity (used in RTO calcs).
|
|
|
|
|
* \param clockGranularity The Clock Granularity
|
|
|
|
|
*/
|
|
|
|
|
void SetClockGranularity(Time clockGranularity);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get the Clock Granularity (used in RTO calcs).
|
|
|
|
|
* \return The Clock Granularity.
|
|
|
|
|
*/
|
|
|
|
|
Time GetClockGranularity() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get a pointer to the Tx buffer
|
|
|
|
|
* \return a pointer to the tx buffer
|
|
|
|
|
*/
|
|
|
|
|
Ptr<TcpTxBuffer> GetTxBuffer() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get a pointer to the Rx buffer
|
|
|
|
|
* \return a pointer to the rx buffer
|
|
|
|
|
*/
|
|
|
|
|
Ptr<TcpRxBuffer> GetRxBuffer() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Set the retransmission threshold (dup ack threshold for a fast retransmit)
|
|
|
|
|
* \param retxThresh the threshold
|
|
|
|
|
*/
|
|
|
|
|
void SetRetxThresh(uint32_t retxThresh);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Get the retransmission threshold (dup ack threshold for a fast retransmit)
|
|
|
|
|
* \return the threshold
|
|
|
|
|
*/
|
|
|
|
|
uint32_t GetRetxThresh() const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return m_retxThresh;
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for pacing rate trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<DataRate, DataRate> m_pacingRateTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for cWnd trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<uint32_t, uint32_t> m_cWndTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for cWndInfl trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<uint32_t, uint32_t> m_cWndInflTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for ssTh trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<uint32_t, uint32_t> m_ssThTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for congestion state trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<TcpSocketState::TcpCongState_t, TcpSocketState::TcpCongState_t> m_congStateTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for ECN state trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<TcpSocketState::EcnState_t, TcpSocketState::EcnState_t> m_ecnStateTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for high tx mark chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<SequenceNumber32, SequenceNumber32> m_highTxMarkTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for next tx sequence chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<SequenceNumber32, SequenceNumber32> m_nextTxSequenceTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for bytesInFlight trace chaining
|
|
|
|
|
*/
|
|
|
|
|
TracedCallback<uint32_t, uint32_t> m_bytesInFlightTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for RTT trace chaining
|
|
|
|
|
*/
|
2024-06-05 15:57:37 +05:30
|
|
|
TracedCallback<Time, Time> m_srttTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback pointer for Last RTT trace chaining
|
|
|
|
|
*/
|
2022-10-07 20:08:35 +00:00
|
|
|
TracedCallback<Time, Time> m_lastRttTrace;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState pacing rate
|
|
|
|
|
* \param oldValue old pacing rate value
|
|
|
|
|
* \param newValue new pacing rate value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdatePacingRateTrace(DataRate oldValue, DataRate newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState congestion window
|
|
|
|
|
* \param oldValue old cWnd value
|
|
|
|
|
* \param newValue new cWnd value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateCwnd(uint32_t oldValue, uint32_t newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState inflated congestion window
|
|
|
|
|
* \param oldValue old cWndInfl value
|
|
|
|
|
* \param newValue new cWndInfl value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateCwndInfl(uint32_t oldValue, uint32_t newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState slow start threshold
|
|
|
|
|
* \param oldValue old ssTh value
|
|
|
|
|
* \param newValue new ssTh value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateSsThresh(uint32_t oldValue, uint32_t newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState congestion state
|
|
|
|
|
* \param oldValue old congestion state value
|
|
|
|
|
* \param newValue new congestion state value
|
|
|
|
|
*/
|
|
|
|
|
void UpdateCongState(TcpSocketState::TcpCongState_t oldValue,
|
2022-12-16 19:36:31 +00:00
|
|
|
TcpSocketState::TcpCongState_t newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to EcnState state
|
|
|
|
|
* \param oldValue old ecn state value
|
|
|
|
|
* \param newValue new ecn state value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateEcnState(TcpSocketState::EcnState_t oldValue,
|
|
|
|
|
TcpSocketState::EcnState_t newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState high tx mark
|
|
|
|
|
* \param oldValue old high tx mark
|
|
|
|
|
* \param newValue new high tx mark
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateHighTxMark(SequenceNumber32 oldValue, SequenceNumber32 newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState next tx sequence
|
|
|
|
|
* \param oldValue old nextTxSeq value
|
|
|
|
|
* \param newValue new nextTxSeq value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateNextTxSequence(SequenceNumber32 oldValue, SequenceNumber32 newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState bytes inflight
|
|
|
|
|
* \param oldValue old bytesInFlight value
|
|
|
|
|
* \param newValue new bytesInFlight value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateBytesInFlight(uint32_t oldValue, uint32_t newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState rtt
|
|
|
|
|
* \param oldValue old rtt value
|
|
|
|
|
* \param newValue new rtt value
|
|
|
|
|
*/
|
2022-12-16 19:36:31 +00:00
|
|
|
void UpdateRtt(Time oldValue, Time newValue) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
2024-06-05 15:57:37 +05:30
|
|
|
/**
|
|
|
|
|
* \brief Callback function to hook to TcpSocketState lastRtt
|
|
|
|
|
* \param oldValue old lastRtt value
|
|
|
|
|
* \param newValue new lastRtt value
|
|
|
|
|
*/
|
|
|
|
|
void UpdateLastRtt(Time oldValue, Time newValue) const;
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Install a congestion control algorithm on this socket
|
|
|
|
|
*
|
|
|
|
|
* \param algo Algorithm to be installed
|
|
|
|
|
*/
|
|
|
|
|
void SetCongestionControlAlgorithm(Ptr<TcpCongestionOps> algo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Install a recovery algorithm on this socket
|
|
|
|
|
*
|
|
|
|
|
* \param recovery Algorithm to be installed
|
|
|
|
|
*/
|
|
|
|
|
void SetRecoveryAlgorithm(Ptr<TcpRecoveryOps> recovery);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Mark ECT(0) codepoint
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to modify
|
|
|
|
|
* \return TOS with ECT(0) codepoint set
|
|
|
|
|
*/
|
|
|
|
|
inline uint8_t MarkEcnEct0(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0xfc) | 0x02);
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Mark ECT(1) codepoint
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to modify
|
|
|
|
|
* \return TOS with ECT(1) codepoint set
|
|
|
|
|
*/
|
|
|
|
|
inline uint8_t MarkEcnEct1(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0xfc) | 0x01);
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Mark CE codepoint
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to modify
|
|
|
|
|
* \return TOS with CE codepoint set
|
|
|
|
|
*/
|
|
|
|
|
inline uint8_t MarkEcnCe(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0xfc) | 0x03);
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Clears ECN bits from TOS
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to modify
|
|
|
|
|
* \return TOS without ECN bits
|
|
|
|
|
*/
|
|
|
|
|
inline uint8_t ClearEcnBits(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return tos & 0xfc;
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Checks if TOS has no ECN codepoints
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to check
|
|
|
|
|
* \return true if TOS does not have any ECN codepoints set; otherwise false
|
|
|
|
|
*/
|
|
|
|
|
inline bool CheckNoEcn(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0x03) == 0x00);
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Checks for ECT(0) codepoint
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to check
|
|
|
|
|
* \return true if TOS has ECT(0) codepoint set; otherwise false
|
|
|
|
|
*/
|
|
|
|
|
inline bool CheckEcnEct0(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0x03) == 0x02);
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Checks for ECT(1) codepoint
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to check
|
|
|
|
|
* \return true if TOS has ECT(1) codepoint set; otherwise false
|
|
|
|
|
*/
|
|
|
|
|
inline bool CheckEcnEct1(uint8_t tos) const
|
2018-06-09 12:00:54 -07:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0x03) == 0x01);
|
2018-06-09 12:00:54 -07:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Checks for CE codepoint
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to check
|
|
|
|
|
* \return true if TOS has CE codepoint set; otherwise false
|
|
|
|
|
*/
|
|
|
|
|
inline bool CheckEcnCe(uint8_t tos) const
|
2019-11-15 23:59:22 -06:00
|
|
|
{
|
2022-10-07 20:08:35 +00:00
|
|
|
return ((tos & 0x03) == 0x03);
|
2019-11-15 23:59:22 -06:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief mark ECN code point
|
|
|
|
|
*
|
|
|
|
|
* \param tos the TOS byte to modify
|
|
|
|
|
* \param codePoint the codepoint to use
|
|
|
|
|
* \return TOS with specified ECN code point
|
|
|
|
|
*/
|
|
|
|
|
inline uint8_t MarkEcnCodePoint(const uint8_t tos,
|
|
|
|
|
const TcpSocketState::EcnCodePoint_t codePoint) const
|
|
|
|
|
{
|
|
|
|
|
return ((tos & 0xfc) | codePoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Set ECN mode of use on the socket
|
|
|
|
|
*
|
|
|
|
|
* \param useEcn Mode of ECN to use.
|
|
|
|
|
*/
|
|
|
|
|
void SetUseEcn(TcpSocketState::UseEcn_t useEcn);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Enable or disable pacing
|
|
|
|
|
* \param pacing Boolean to enable or disable pacing
|
|
|
|
|
*/
|
|
|
|
|
void SetPacingStatus(bool pacing);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Enable or disable pacing of the initial window
|
|
|
|
|
* \param paceWindow Boolean to enable or disable pacing of the initial window
|
|
|
|
|
*/
|
|
|
|
|
void SetPaceInitialWindow(bool paceWindow);
|
|
|
|
|
|
2024-09-04 14:38:52 +05:30
|
|
|
/**
|
|
|
|
|
* \brief Checks if a TCP packet should be ECN-capable (ECT) according to the TcpPacketType and
|
|
|
|
|
* ECN mode.
|
|
|
|
|
*
|
|
|
|
|
* Currently, only Classic ECN and DCTCP ECN modes are supported, with
|
|
|
|
|
* potential extensions for future modes (Ecnpp).
|
|
|
|
|
*
|
|
|
|
|
* \param packetType The type of the TCP packet, represented by an enum TcpPacketType.
|
|
|
|
|
* \return true if the packet is ECN-capable (ECT), false otherwise.
|
|
|
|
|
*
|
|
|
|
|
* Reference: https://www.ietf.org/archive/id/draft-ietf-tcpm-generalized-ecn-15.txt (Table 1)
|
|
|
|
|
*/
|
|
|
|
|
bool IsEct(TcpPacketType_t packetType) const;
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
// Necessary implementations of null functions from ns3::Socket
|
2022-12-05 18:49:22 +00:00
|
|
|
SocketErrno GetErrno() const override; // returns m_errno
|
|
|
|
|
SocketType GetSocketType() const override; // returns socket type
|
|
|
|
|
Ptr<Node> GetNode() const override; // returns m_node
|
2022-10-07 20:08:35 +00:00
|
|
|
int Bind() override; // Bind a socket by setting up endpoint in TcpL4Protocol
|
|
|
|
|
int Bind6() override; // Bind a socket by setting up endpoint in TcpL4Protocol
|
|
|
|
|
int Bind(const Address& address) override; // ... endpoint of specific addr or port
|
|
|
|
|
int Connect(
|
|
|
|
|
const Address& address) override; // Setup endpoint and call ProcessAction() to connect
|
|
|
|
|
int Listen()
|
|
|
|
|
override; // Verify the socket is in a correct state and call ProcessAction() to listen
|
|
|
|
|
int Close() override; // Close by app: Kill socket upon tx buffer emptied
|
|
|
|
|
int ShutdownSend() override; // Assert the m_shutdownSend flag to prevent send to network
|
|
|
|
|
int ShutdownRecv() override; // Assert the m_shutdownRecv flag to prevent forward to app
|
|
|
|
|
int Send(Ptr<Packet> p, uint32_t flags) override; // Call by app to send data to network
|
|
|
|
|
int SendTo(Ptr<Packet> p,
|
|
|
|
|
uint32_t flags,
|
|
|
|
|
const Address& toAddress) override; // Same as Send(), toAddress is insignificant
|
|
|
|
|
Ptr<Packet> Recv(uint32_t maxSize,
|
|
|
|
|
uint32_t flags) override; // Return a packet to be forwarded to app
|
|
|
|
|
Ptr<Packet> RecvFrom(uint32_t maxSize, uint32_t flags, Address& fromAddress)
|
|
|
|
|
override; // ... and write the remote address at fromAddress
|
|
|
|
|
uint32_t GetTxAvailable() const override; // Available Tx buffer size
|
|
|
|
|
uint32_t GetRxAvailable()
|
|
|
|
|
const override; // Available-to-read data size, i.e. value of m_rxAvailable
|
|
|
|
|
int GetSockName(Address& address) const override; // Return local addr:port in address
|
|
|
|
|
int GetPeerName(Address& address) const override;
|
|
|
|
|
void BindToNetDevice(Ptr<NetDevice> netdevice) override; // NetDevice with my m_endPoint
|
|
|
|
|
|
|
|
|
|
/**
|
2024-09-03 14:30:07 +00:00
|
|
|
* TracedCallback signature for TCP packet transmission or reception events.
|
2022-10-07 20:08:35 +00:00
|
|
|
*
|
|
|
|
|
* \param [in] packet The packet.
|
|
|
|
|
* \param [in] header The TcpHeader
|
|
|
|
|
* \param [in] socket This socket
|
|
|
|
|
*/
|
|
|
|
|
typedef void (*TcpTxRxTracedCallback)(const Ptr<const Packet> packet,
|
|
|
|
|
const TcpHeader& header,
|
|
|
|
|
const Ptr<const TcpSocketBase> socket);
|
|
|
|
|
|
2024-09-03 14:30:07 +00:00
|
|
|
/**
|
|
|
|
|
* TracedCallback signature for TCP packet retransmission events.
|
|
|
|
|
*
|
|
|
|
|
* \param [in] packet The packet.
|
|
|
|
|
* \param [in] header The TcpHeader
|
|
|
|
|
* \param [in] localAddr The local address
|
|
|
|
|
* \param [in] peerAddr The peer/remote address
|
|
|
|
|
* \param [in] socket This socket
|
|
|
|
|
*/
|
|
|
|
|
typedef void (*RetransmissionCallback)(const Ptr<const Packet> packet,
|
|
|
|
|
const TcpHeader& header,
|
|
|
|
|
const Address& localAddr,
|
|
|
|
|
const Address& peerAddr,
|
|
|
|
|
const Ptr<const TcpSocketBase> socket);
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
protected:
|
|
|
|
|
// Implementing ns3::TcpSocket -- Attribute get/set
|
|
|
|
|
// inherited, no need to doc
|
|
|
|
|
|
|
|
|
|
void SetSndBufSize(uint32_t size) override;
|
|
|
|
|
uint32_t GetSndBufSize() const override;
|
|
|
|
|
void SetRcvBufSize(uint32_t size) override;
|
|
|
|
|
uint32_t GetRcvBufSize() const override;
|
|
|
|
|
void SetSegSize(uint32_t size) override;
|
|
|
|
|
uint32_t GetSegSize() const override;
|
|
|
|
|
void SetInitialSSThresh(uint32_t threshold) override;
|
|
|
|
|
uint32_t GetInitialSSThresh() const override;
|
|
|
|
|
void SetInitialCwnd(uint32_t cwnd) override;
|
|
|
|
|
uint32_t GetInitialCwnd() const override;
|
|
|
|
|
void SetConnTimeout(Time timeout) override;
|
|
|
|
|
Time GetConnTimeout() const override;
|
|
|
|
|
void SetSynRetries(uint32_t count) override;
|
|
|
|
|
uint32_t GetSynRetries() const override;
|
|
|
|
|
void SetDataRetries(uint32_t retries) override;
|
|
|
|
|
uint32_t GetDataRetries() const override;
|
|
|
|
|
void SetDelAckTimeout(Time timeout) override;
|
|
|
|
|
Time GetDelAckTimeout() const override;
|
|
|
|
|
void SetDelAckMaxCount(uint32_t count) override;
|
|
|
|
|
uint32_t GetDelAckMaxCount() const override;
|
|
|
|
|
void SetTcpNoDelay(bool noDelay) override;
|
|
|
|
|
bool GetTcpNoDelay() const override;
|
|
|
|
|
void SetPersistTimeout(Time timeout) override;
|
|
|
|
|
Time GetPersistTimeout() const override;
|
|
|
|
|
bool SetAllowBroadcast(bool allowBroadcast) override;
|
|
|
|
|
bool GetAllowBroadcast() const override;
|
|
|
|
|
|
|
|
|
|
// Helper functions: Connection set up
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Common part of the two Bind(), i.e. set callback and remembering local addr:port
|
|
|
|
|
*
|
|
|
|
|
* \returns 0 on success, -1 on failure
|
|
|
|
|
*/
|
|
|
|
|
int SetupCallback();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Perform the real connection tasks: Send SYN if allowed, RST if invalid
|
|
|
|
|
*
|
|
|
|
|
* \returns 0 on success
|
|
|
|
|
*/
|
|
|
|
|
int DoConnect();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Schedule-friendly wrapper for Socket::NotifyConnectionSucceeded()
|
|
|
|
|
*/
|
|
|
|
|
void ConnectionSucceeded();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Configure the endpoint to a local address. Called by Connect() if Bind() didn't
|
|
|
|
|
* specify one.
|
|
|
|
|
*
|
|
|
|
|
* \returns 0 on success
|
|
|
|
|
*/
|
|
|
|
|
int SetupEndpoint();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Configure the endpoint v6 to a local address. Called by Connect() if Bind() didn't
|
|
|
|
|
* specify one.
|
|
|
|
|
*
|
|
|
|
|
* \returns 0 on success
|
|
|
|
|
*/
|
|
|
|
|
int SetupEndpoint6();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Complete a connection by forking the socket
|
|
|
|
|
*
|
|
|
|
|
* This function is called only if a SYN received in LISTEN state. After
|
|
|
|
|
* TcpSocketBase cloned, allocate a new end point to handle the incoming
|
|
|
|
|
* connection and send a SYN+ACK to complete the handshake.
|
|
|
|
|
*
|
|
|
|
|
* \param p the packet triggering the fork
|
|
|
|
|
* \param tcpHeader the TCP header of the triggering packet
|
|
|
|
|
* \param fromAddress the address of the remote host
|
|
|
|
|
* \param toAddress the address the connection is directed to
|
|
|
|
|
*/
|
|
|
|
|
virtual void CompleteFork(Ptr<Packet> p,
|
|
|
|
|
const TcpHeader& tcpHeader,
|
|
|
|
|
const Address& fromAddress,
|
|
|
|
|
const Address& toAddress);
|
|
|
|
|
|
|
|
|
|
// Helper functions: Transfer operation
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Checks whether the given TCP segment is valid or not.
|
|
|
|
|
*
|
|
|
|
|
* \param seq the sequence number of packet's TCP header
|
|
|
|
|
* \param tcpHeaderSize the size of packet's TCP header
|
|
|
|
|
* \param tcpPayloadSize the size of TCP payload
|
|
|
|
|
* \return true if the TCP segment is valid
|
|
|
|
|
*/
|
|
|
|
|
bool IsValidTcpSegment(const SequenceNumber32 seq,
|
|
|
|
|
const uint32_t tcpHeaderSize,
|
|
|
|
|
const uint32_t tcpPayloadSize);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Called by the L3 protocol when it received a packet to pass on to TCP.
|
|
|
|
|
*
|
|
|
|
|
* \param packet the incoming packet
|
|
|
|
|
* \param header the packet's IPv4 header
|
|
|
|
|
* \param port the remote port
|
|
|
|
|
* \param incomingInterface the incoming interface
|
|
|
|
|
*/
|
|
|
|
|
void ForwardUp(Ptr<Packet> packet,
|
|
|
|
|
Ipv4Header header,
|
|
|
|
|
uint16_t port,
|
|
|
|
|
Ptr<Ipv4Interface> incomingInterface);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Called by the L3 protocol when it received a packet to pass on to TCP.
|
|
|
|
|
*
|
|
|
|
|
* \param packet the incoming packet
|
|
|
|
|
* \param header the packet's IPv6 header
|
|
|
|
|
* \param port the remote port
|
|
|
|
|
* \param incomingInterface the incoming interface
|
|
|
|
|
*/
|
|
|
|
|
void ForwardUp6(Ptr<Packet> packet,
|
|
|
|
|
Ipv6Header header,
|
|
|
|
|
uint16_t port,
|
|
|
|
|
Ptr<Ipv6Interface> incomingInterface);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Called by TcpSocketBase::ForwardUp{,6}().
|
|
|
|
|
*
|
|
|
|
|
* Get a packet from L3. This is the real function to handle the
|
|
|
|
|
* incoming packet from lower layers. This is
|
|
|
|
|
* wrapped by ForwardUp() so that this function can be overloaded by daughter
|
|
|
|
|
* classes.
|
|
|
|
|
*
|
|
|
|
|
* \param packet the incoming packet
|
|
|
|
|
* \param fromAddress the address of the sender of packet
|
|
|
|
|
* \param toAddress the address of the receiver of packet (hopefully, us)
|
|
|
|
|
*/
|
|
|
|
|
virtual void DoForwardUp(Ptr<Packet> packet,
|
|
|
|
|
const Address& fromAddress,
|
|
|
|
|
const Address& toAddress);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Called by the L3 protocol when it received an ICMP packet to pass on to TCP.
|
|
|
|
|
*
|
|
|
|
|
* \param icmpSource the ICMP source address
|
|
|
|
|
* \param icmpTtl the ICMP Time to Live
|
|
|
|
|
* \param icmpType the ICMP Type
|
|
|
|
|
* \param icmpCode the ICMP Code
|
|
|
|
|
* \param icmpInfo the ICMP Info
|
|
|
|
|
*/
|
|
|
|
|
void ForwardIcmp(Ipv4Address icmpSource,
|
|
|
|
|
uint8_t icmpTtl,
|
|
|
|
|
uint8_t icmpType,
|
|
|
|
|
uint8_t icmpCode,
|
|
|
|
|
uint32_t icmpInfo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Called by the L3 protocol when it received an ICMPv6 packet to pass on to TCP.
|
|
|
|
|
*
|
|
|
|
|
* \param icmpSource the ICMP source address
|
|
|
|
|
* \param icmpTtl the ICMP Time to Live
|
|
|
|
|
* \param icmpType the ICMP Type
|
|
|
|
|
* \param icmpCode the ICMP Code
|
|
|
|
|
* \param icmpInfo the ICMP Info
|
|
|
|
|
*/
|
|
|
|
|
void ForwardIcmp6(Ipv6Address icmpSource,
|
|
|
|
|
uint8_t icmpTtl,
|
|
|
|
|
uint8_t icmpType,
|
|
|
|
|
uint8_t icmpCode,
|
|
|
|
|
uint32_t icmpInfo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Send as much pending data as possible according to the Tx window.
|
|
|
|
|
*
|
|
|
|
|
* Note that this function did not implement the PSH flag.
|
|
|
|
|
*
|
|
|
|
|
* \param withAck forces an ACK to be sent
|
|
|
|
|
* \returns the number of packets sent
|
|
|
|
|
*/
|
|
|
|
|
uint32_t SendPendingData(bool withAck = false);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
|
|
|
|
|
* TCP header, and send to TcpL4Protocol
|
|
|
|
|
*
|
|
|
|
|
* \param seq the sequence number
|
|
|
|
|
* \param maxSize the maximum data block to be transmitted (in bytes)
|
|
|
|
|
* \param withAck forces an ACK to be sent
|
|
|
|
|
* \returns the number of bytes sent
|
|
|
|
|
*/
|
|
|
|
|
virtual uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Send a empty packet that carries a flag, e.g., ACK
|
|
|
|
|
*
|
|
|
|
|
* \param flags the packet's flags
|
|
|
|
|
*/
|
|
|
|
|
virtual void SendEmptyPacket(uint8_t flags);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Send reset and tear down this socket
|
|
|
|
|
*/
|
|
|
|
|
void SendRST();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Check if a sequence number range is within the rx window
|
|
|
|
|
*
|
|
|
|
|
* \param head start of the Sequence window
|
|
|
|
|
* \param tail end of the Sequence window
|
|
|
|
|
* \returns true if it is in range
|
|
|
|
|
*/
|
|
|
|
|
bool OutOfRange(SequenceNumber32 head, SequenceNumber32 tail) const;
|
|
|
|
|
|
|
|
|
|
// Helper functions: Connection close
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Close a socket by sending RST, FIN, or FIN+ACK, depend on the current state
|
|
|
|
|
*
|
|
|
|
|
* \returns 0 on success
|
|
|
|
|
*/
|
|
|
|
|
int DoClose();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Peacefully close the socket by notifying the upper layer and deallocate end point
|
|
|
|
|
*/
|
|
|
|
|
void CloseAndNotify();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Kill this socket by zeroing its attributes (IPv4)
|
|
|
|
|
*
|
|
|
|
|
* This is a callback function configured to m_endpoint in
|
|
|
|
|
* SetupCallback(), invoked when the endpoint is destroyed.
|
|
|
|
|
*/
|
|
|
|
|
void Destroy();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Kill this socket by zeroing its attributes (IPv6)
|
|
|
|
|
*
|
|
|
|
|
* This is a callback function configured to m_endpoint in
|
|
|
|
|
* SetupCallback(), invoked when the endpoint is destroyed.
|
|
|
|
|
*/
|
|
|
|
|
void Destroy6();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Deallocate m_endPoint and m_endPoint6
|
|
|
|
|
*/
|
|
|
|
|
void DeallocateEndPoint();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a FIN from peer, notify rx buffer
|
|
|
|
|
*
|
|
|
|
|
* \param p the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
void PeerClose(Ptr<Packet> p, const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief FIN is in sequence, notify app and respond with a FIN
|
|
|
|
|
*/
|
|
|
|
|
void DoPeerClose();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Cancel all timer when endpoint is deleted
|
|
|
|
|
*/
|
|
|
|
|
void CancelAllTimers();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Move from CLOSING or FIN_WAIT_2 to TIME_WAIT state
|
|
|
|
|
*/
|
|
|
|
|
void TimeWait();
|
|
|
|
|
|
|
|
|
|
// State transition functions
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon ESTABLISHED state.
|
|
|
|
|
*
|
|
|
|
|
* This function is mimicking the role of tcp_rcv_established() in tcp_input.c in Linux kernel.
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessEstablished(Ptr<Packet> packet,
|
|
|
|
|
const TcpHeader& tcpHeader); // Received a packet upon ESTABLISHED state
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon LISTEN state.
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
* \param fromAddress the source address
|
|
|
|
|
* \param toAddress the destination address
|
|
|
|
|
*/
|
|
|
|
|
void ProcessListen(Ptr<Packet> packet,
|
|
|
|
|
const TcpHeader& tcpHeader,
|
|
|
|
|
const Address& fromAddress,
|
|
|
|
|
const Address& toAddress);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon SYN_SENT
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessSynSent(Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon SYN_RCVD.
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
* \param fromAddress the source address
|
|
|
|
|
* \param toAddress the destination address
|
|
|
|
|
*/
|
|
|
|
|
void ProcessSynRcvd(Ptr<Packet> packet,
|
|
|
|
|
const TcpHeader& tcpHeader,
|
|
|
|
|
const Address& fromAddress,
|
|
|
|
|
const Address& toAddress);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon CLOSE_WAIT, FIN_WAIT_1, FIN_WAIT_2
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessWait(Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon CLOSING
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessClosing(Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received a packet upon LAST_ACK
|
|
|
|
|
*
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessLastAck(Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
// Window management
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Return count of number of unacked bytes
|
|
|
|
|
*
|
|
|
|
|
* The difference between SND.UNA and HighTx
|
|
|
|
|
*
|
|
|
|
|
* \returns count of number of unacked bytes
|
|
|
|
|
*/
|
|
|
|
|
virtual uint32_t UnAckDataCount() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Return total bytes in flight
|
|
|
|
|
*
|
|
|
|
|
* Does not count segments lost and SACKed (or dupACKed)
|
|
|
|
|
*
|
|
|
|
|
* \returns total bytes in flight
|
|
|
|
|
*/
|
|
|
|
|
virtual uint32_t BytesInFlight() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Return the max possible number of unacked bytes
|
|
|
|
|
* \returns the max possible number of unacked bytes
|
|
|
|
|
*/
|
|
|
|
|
virtual uint32_t Window() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Return unfilled portion of window
|
|
|
|
|
* \return unfilled portion of window
|
|
|
|
|
*/
|
|
|
|
|
virtual uint32_t AvailableWindow() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief The amount of Rx window announced to the peer
|
|
|
|
|
* \param scale indicate if the window should be scaled. True for
|
|
|
|
|
* almost all cases, except when we are sending a SYN
|
|
|
|
|
* \returns size of Rx window announced to the peer
|
|
|
|
|
*/
|
|
|
|
|
virtual uint16_t AdvertisedWindowSize(bool scale = true) const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Update the receiver window (RWND) based on the value of the
|
|
|
|
|
* window field in the header.
|
|
|
|
|
*
|
|
|
|
|
* This method suppresses updates unless one of the following three
|
|
|
|
|
* conditions holds: 1) segment contains new data (advancing the right
|
|
|
|
|
* edge of the receive buffer), 2) segment does not contain new data
|
|
|
|
|
* but the segment acks new data (highest sequence number acked advances),
|
|
|
|
|
* or 3) the advertised window is larger than the current send window
|
|
|
|
|
*
|
|
|
|
|
* \param header TcpHeader from which to extract the new window value
|
|
|
|
|
*/
|
|
|
|
|
void UpdateWindowSize(const TcpHeader& header);
|
|
|
|
|
|
|
|
|
|
// Manage data tx/rx
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Call CopyObject<> to clone me
|
|
|
|
|
* \returns a copy of the socket
|
|
|
|
|
*/
|
|
|
|
|
virtual Ptr<TcpSocketBase> Fork();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Received an ACK packet
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
virtual void ReceivedAck(Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Process a received ack
|
|
|
|
|
* \param ackNumber ack number
|
|
|
|
|
* \param scoreboardUpdated if true indicates that the scoreboard has been
|
|
|
|
|
* \param oldHeadSequence value of HeadSequence before ack
|
|
|
|
|
* updated with SACK information
|
|
|
|
|
* \param currentDelivered The number of bytes (S)ACKed
|
2024-09-12 11:42:15 +05:30
|
|
|
* \param receivedData if true indicates that data is piggybacked with ACK
|
2022-10-07 20:08:35 +00:00
|
|
|
*/
|
|
|
|
|
virtual void ProcessAck(const SequenceNumber32& ackNumber,
|
|
|
|
|
bool scoreboardUpdated,
|
|
|
|
|
uint32_t currentDelivered,
|
2024-09-12 11:42:15 +05:30
|
|
|
const SequenceNumber32& oldHeadSequence,
|
|
|
|
|
bool receivedData);
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Recv of a data, put into buffer, call L7 to get it if necessary
|
|
|
|
|
* \param packet the packet
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
virtual void ReceivedData(Ptr<Packet> packet, const TcpHeader& tcpHeader);
|
|
|
|
|
|
2024-06-05 15:57:37 +05:30
|
|
|
/**
|
|
|
|
|
* \brief Calculate RTT sample for the ACKed packet
|
|
|
|
|
*
|
|
|
|
|
* Per RFC 6298 (Section 3),
|
|
|
|
|
* If `m_timestampsEnabled` is true, calculate RTT using timestamps option.
|
|
|
|
|
* Otherwise, return RTT as the elapsed time since the packet was transmitted.
|
|
|
|
|
* If ACKed packed was a retrasmitted packet, return zero time.
|
|
|
|
|
*
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
* \param rttHistory the ACKed packet's RTT History
|
|
|
|
|
* \returns the RTT sample
|
|
|
|
|
*/
|
|
|
|
|
virtual Time CalculateRttSample(const TcpHeader& tcpHeader, const RttHistory& rttHistory);
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
/**
|
|
|
|
|
* \brief Take into account the packet for RTT estimation
|
|
|
|
|
* \param tcpHeader the packet's TCP header
|
|
|
|
|
*/
|
|
|
|
|
virtual void EstimateRtt(const TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Update the RTT history, when we send TCP segments
|
|
|
|
|
*
|
|
|
|
|
* \param seq The sequence number of the TCP segment
|
|
|
|
|
* \param sz The segment's size
|
|
|
|
|
* \param isRetransmission Whether or not the segment is a retransmission
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
virtual void UpdateRttHistory(const SequenceNumber32& seq, uint32_t sz, bool isRetransmission);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Update buffers w.r.t. ACK
|
|
|
|
|
* \param seq the sequence number
|
|
|
|
|
* \param resetRTO indicates if RTO should be reset
|
|
|
|
|
*/
|
|
|
|
|
virtual void NewAck(const SequenceNumber32& seq, bool resetRTO);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Dupack management
|
|
|
|
|
*
|
|
|
|
|
* \param currentDelivered Current (S)ACKed bytes
|
|
|
|
|
*/
|
|
|
|
|
void DupAck(uint32_t currentDelivered);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Enter CA_CWR state upon receipt of an ECN Echo
|
|
|
|
|
*
|
|
|
|
|
* \param currentDelivered Currently (S)ACKed bytes
|
|
|
|
|
*/
|
|
|
|
|
void EnterCwr(uint32_t currentDelivered);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Enter the CA_RECOVERY, and retransmit the head
|
|
|
|
|
*
|
|
|
|
|
* \param currentDelivered Currently (S)ACKed bytes
|
|
|
|
|
*/
|
|
|
|
|
void EnterRecovery(uint32_t currentDelivered);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief An RTO event happened
|
|
|
|
|
*/
|
|
|
|
|
virtual void ReTxTimeout();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Action upon delay ACK timeout, i.e. send an ACK
|
|
|
|
|
*/
|
|
|
|
|
virtual void DelAckTimeout();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Timeout at LAST_ACK, close the connection
|
|
|
|
|
*/
|
|
|
|
|
virtual void LastAckTimeout();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Send 1 byte probe to get an updated window size
|
|
|
|
|
*/
|
|
|
|
|
virtual void PersistTimeout();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Retransmit the first segment marked as lost, without considering
|
|
|
|
|
* available window nor pacing.
|
|
|
|
|
*/
|
|
|
|
|
void DoRetransmit();
|
|
|
|
|
|
2024-08-20 14:44:36 +01:00
|
|
|
/**
|
|
|
|
|
* \brief Add options to TcpHeader
|
2022-10-07 20:08:35 +00:00
|
|
|
*
|
|
|
|
|
* Test each option, and if it is enabled on our side, add it
|
|
|
|
|
* to the header
|
|
|
|
|
*
|
|
|
|
|
* \param tcpHeader TcpHeader to add options to
|
|
|
|
|
*/
|
|
|
|
|
void AddOptions(TcpHeader& tcpHeader);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Read TCP options before Ack processing
|
|
|
|
|
*
|
|
|
|
|
* Timestamp and Window scale are managed in other pieces of code.
|
|
|
|
|
*
|
|
|
|
|
* \param tcpHeader Header of the segment
|
|
|
|
|
* \param [out] bytesSacked Number of bytes SACKed, or 0
|
|
|
|
|
*/
|
|
|
|
|
void ReadOptions(const TcpHeader& tcpHeader, uint32_t* bytesSacked);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Return true if the specified option is enabled
|
|
|
|
|
*
|
|
|
|
|
* \param kind kind of TCP option
|
|
|
|
|
* \return true if the option is enabled
|
|
|
|
|
*/
|
|
|
|
|
bool IsTcpOptionEnabled(uint8_t kind) const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Read and parse the Window scale option
|
|
|
|
|
*
|
|
|
|
|
* Read the window scale option (encoded logarithmically) and save it.
|
|
|
|
|
* Per RFC 1323, the value can't exceed 14.
|
|
|
|
|
*
|
|
|
|
|
* \param option Window scale option read from the header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessOptionWScale(const Ptr<const TcpOption> option);
|
|
|
|
|
/**
|
|
|
|
|
* \brief Add the window scale option to the header
|
|
|
|
|
*
|
|
|
|
|
* Calculate our factor from the rxBuffer max size, and add it
|
|
|
|
|
* to the header.
|
|
|
|
|
*
|
|
|
|
|
* \param header TcpHeader where the method should add the window scale option
|
|
|
|
|
*/
|
|
|
|
|
void AddOptionWScale(TcpHeader& header);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Calculate window scale value based on receive buffer space
|
|
|
|
|
*
|
|
|
|
|
* Calculate our factor from the rxBuffer max size
|
|
|
|
|
*
|
|
|
|
|
* \returns the Window Scale factor
|
|
|
|
|
*/
|
|
|
|
|
uint8_t CalculateWScale() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Read the SACK PERMITTED option
|
|
|
|
|
*
|
|
|
|
|
* Currently this is a placeholder, since no operations should be done
|
|
|
|
|
* on such option.
|
|
|
|
|
*
|
|
|
|
|
* \param option SACK PERMITTED option from the header
|
|
|
|
|
*/
|
|
|
|
|
void ProcessOptionSackPermitted(const Ptr<const TcpOption> option);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Read the SACK option
|
|
|
|
|
*
|
|
|
|
|
* \param option SACK option from the header
|
|
|
|
|
* \returns the number of bytes sacked by this option
|
|
|
|
|
*/
|
|
|
|
|
uint32_t ProcessOptionSack(const Ptr<const TcpOption> option);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Add the SACK PERMITTED option to the header
|
|
|
|
|
*
|
|
|
|
|
* \param header TcpHeader where the method should add the option
|
|
|
|
|
*/
|
|
|
|
|
void AddOptionSackPermitted(TcpHeader& header);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Add the SACK option to the header
|
|
|
|
|
*
|
|
|
|
|
* \param header TcpHeader where the method should add the option
|
|
|
|
|
*/
|
|
|
|
|
void AddOptionSack(TcpHeader& header);
|
|
|
|
|
|
2024-08-20 14:44:36 +01:00
|
|
|
/**
|
|
|
|
|
* \brief Process the timestamp option from other side
|
2022-10-07 20:08:35 +00:00
|
|
|
*
|
|
|
|
|
* Get the timestamp and the echo, then save timestamp (which will
|
|
|
|
|
* be the echo value in our out-packets) and save the echoed timestamp,
|
|
|
|
|
* to utilize later to calculate RTT.
|
|
|
|
|
*
|
|
|
|
|
* \see EstimateRtt
|
|
|
|
|
* \param option Option from the segment
|
|
|
|
|
* \param seq Sequence number of the segment
|
|
|
|
|
*/
|
|
|
|
|
void ProcessOptionTimestamp(const Ptr<const TcpOption> option, const SequenceNumber32& seq);
|
|
|
|
|
/**
|
|
|
|
|
* \brief Add the timestamp option to the header
|
|
|
|
|
*
|
|
|
|
|
* Set the timestamp as the lower bits of the Simulator::Now time,
|
|
|
|
|
* and the echo value as the last seen timestamp from the other part.
|
|
|
|
|
*
|
|
|
|
|
* \param header TcpHeader to which add the option to
|
|
|
|
|
*/
|
|
|
|
|
void AddOptionTimestamp(TcpHeader& header);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Performs a safe subtraction between a and b (a-b)
|
|
|
|
|
*
|
|
|
|
|
* Safe is used to indicate that, if b>a, the results returned is 0.
|
|
|
|
|
*
|
|
|
|
|
* \param a first number
|
|
|
|
|
* \param b second number
|
|
|
|
|
* \return 0 if b>0, (a-b) otherwise
|
|
|
|
|
*/
|
|
|
|
|
static uint32_t SafeSubtraction(uint32_t a, uint32_t b);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Notify Pacing
|
|
|
|
|
*/
|
|
|
|
|
void NotifyPacingPerformed();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Return true if packets in the current window should be paced
|
|
|
|
|
* \return true if pacing is currently enabled
|
|
|
|
|
*/
|
|
|
|
|
bool IsPacingEnabled() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Dynamically update the pacing rate
|
|
|
|
|
*/
|
|
|
|
|
void UpdatePacingRate();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Add Tags for the Socket
|
|
|
|
|
* \param p Packet
|
2024-09-04 14:38:52 +05:30
|
|
|
* \param isEct Whether the packet is allowed to be ECT capable
|
2022-10-07 20:08:35 +00:00
|
|
|
*/
|
2024-09-04 14:38:52 +05:30
|
|
|
void AddSocketTags(const Ptr<Packet>& p, bool isEct) const;
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the current value of the receiver's offered window (RCV.WND)
|
|
|
|
|
* \note This method exists to expose the value to the TcpTxBuffer
|
|
|
|
|
* \return value of receiver's offered window
|
|
|
|
|
*/
|
|
|
|
|
uint32_t GetRWnd() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the current value of the receiver's highest (in-sequence) sequence number acked.
|
|
|
|
|
* \note This method exists to expose the value to the TcpTxBuffer
|
|
|
|
|
* \return value of receiver's highest sequence number acked.
|
|
|
|
|
*/
|
|
|
|
|
SequenceNumber32 GetHighRxAck() const;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
// Counters and events
|
|
|
|
|
EventId m_retxEvent{}; //!< Retransmission event
|
|
|
|
|
EventId m_lastAckEvent{}; //!< Last ACK timeout event
|
|
|
|
|
EventId m_delAckEvent{}; //!< Delayed ACK timeout event
|
|
|
|
|
EventId m_persistEvent{}; //!< Persist event: Send 1 byte to probe for a non-zero Rx window
|
|
|
|
|
EventId m_timewaitEvent{}; //!< TIME_WAIT expiration event: Move this socket to CLOSED state
|
|
|
|
|
|
|
|
|
|
// ACK management
|
|
|
|
|
uint32_t m_dupAckCount{0}; //!< Dupack counter
|
|
|
|
|
uint32_t m_delAckCount{0}; //!< Delayed ACK counter
|
|
|
|
|
uint32_t m_delAckMaxCount{0}; //!< Number of packet to fire an ACK before delay timeout
|
|
|
|
|
|
|
|
|
|
// Nagle algorithm
|
|
|
|
|
bool m_noDelay{false}; //!< Set to true to disable Nagle's algorithm
|
|
|
|
|
|
|
|
|
|
// Retries
|
|
|
|
|
uint32_t m_synCount{0}; //!< Count of remaining connection retries
|
|
|
|
|
uint32_t m_synRetries{0}; //!< Number of connection attempts
|
|
|
|
|
uint32_t m_dataRetrCount{0}; //!< Count of remaining data retransmission attempts
|
|
|
|
|
uint32_t m_dataRetries{0}; //!< Number of data retransmission attempts
|
|
|
|
|
|
|
|
|
|
// Timeouts
|
|
|
|
|
TracedValue<Time> m_rto{Seconds(0.0)}; //!< Retransmit timeout
|
|
|
|
|
Time m_minRto{Time::Max()}; //!< minimum value of the Retransmit timeout
|
|
|
|
|
Time m_clockGranularity{Seconds(0.001)}; //!< Clock Granularity used in RTO calcs
|
|
|
|
|
Time m_delAckTimeout{Seconds(0.0)}; //!< Time to delay an ACK
|
|
|
|
|
Time m_persistTimeout{Seconds(0.0)}; //!< Time between sending 1-byte probes
|
|
|
|
|
Time m_cnTimeout{Seconds(0.0)}; //!< Timeout for connection retry
|
|
|
|
|
|
|
|
|
|
// History of RTT
|
|
|
|
|
std::deque<RttHistory> m_history; //!< List of sent packet
|
|
|
|
|
|
|
|
|
|
// Connections to other layers of TCP/IP
|
|
|
|
|
Ipv4EndPoint* m_endPoint{nullptr}; //!< the IPv4 endpoint
|
|
|
|
|
Ipv6EndPoint* m_endPoint6{nullptr}; //!< the IPv6 endpoint
|
|
|
|
|
Ptr<Node> m_node; //!< the associated node
|
|
|
|
|
Ptr<TcpL4Protocol> m_tcp; //!< the associated TCP L4 protocol
|
|
|
|
|
Callback<void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t>
|
|
|
|
|
m_icmpCallback; //!< ICMP callback
|
|
|
|
|
Callback<void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t>
|
|
|
|
|
m_icmpCallback6; //!< ICMPv6 callback
|
|
|
|
|
|
|
|
|
|
Ptr<RttEstimator> m_rtt; //!< Round trip time estimator
|
|
|
|
|
|
|
|
|
|
// Tx buffer management
|
|
|
|
|
Ptr<TcpTxBuffer> m_txBuffer; //!< Tx buffer
|
|
|
|
|
|
|
|
|
|
// State-related attributes
|
|
|
|
|
TracedValue<TcpStates_t> m_state{CLOSED}; //!< TCP state
|
|
|
|
|
|
2022-12-05 18:49:22 +00:00
|
|
|
mutable SocketErrno m_errno{ERROR_NOTERROR}; //!< Socket error code
|
2022-10-07 20:08:35 +00:00
|
|
|
|
|
|
|
|
bool m_closeNotified{false}; //!< Told app to close socket
|
|
|
|
|
bool m_closeOnEmpty{false}; //!< Close socket upon tx buffer emptied
|
|
|
|
|
bool m_shutdownSend{false}; //!< Send no longer allowed
|
|
|
|
|
bool m_shutdownRecv{false}; //!< Receive no longer allowed
|
|
|
|
|
bool m_connected{false}; //!< Connection established
|
|
|
|
|
double m_msl{0.0}; //!< Max segment lifetime
|
|
|
|
|
|
|
|
|
|
// Window management
|
|
|
|
|
uint16_t m_maxWinSize{0}; //!< Maximum window size to advertise
|
|
|
|
|
uint32_t m_bytesAckedNotProcessed{0}; //!< Bytes acked, but not processed
|
|
|
|
|
SequenceNumber32 m_highTxAck{0}; //!< Highest ack sent
|
|
|
|
|
TracedValue<uint32_t> m_rWnd{0}; //!< Receiver window (RCV.WND in RFC793)
|
|
|
|
|
TracedValue<uint32_t> m_advWnd{0}; //!< Advertised Window size
|
|
|
|
|
TracedValue<SequenceNumber32> m_highRxMark{0}; //!< Highest seqno received
|
|
|
|
|
TracedValue<SequenceNumber32> m_highRxAckMark{0}; //!< Highest ack received
|
|
|
|
|
|
|
|
|
|
// Options
|
|
|
|
|
bool m_sackEnabled{true}; //!< RFC SACK option enabled
|
|
|
|
|
bool m_winScalingEnabled{true}; //!< Window Scale option enabled (RFC 7323)
|
|
|
|
|
uint8_t m_rcvWindShift{0}; //!< Window shift to apply to outgoing segments
|
|
|
|
|
uint8_t m_sndWindShift{0}; //!< Window shift to apply to incoming segments
|
|
|
|
|
bool m_timestampEnabled{true}; //!< Timestamp option enabled
|
|
|
|
|
uint32_t m_timestampToEcho{0}; //!< Timestamp to echo
|
|
|
|
|
|
|
|
|
|
EventId m_sendPendingDataEvent{}; //!< micro-delay event to send pending data
|
|
|
|
|
|
|
|
|
|
// Fast Retransmit and Recovery
|
|
|
|
|
SequenceNumber32 m_recover{
|
|
|
|
|
0}; //!< Previous highest Tx seqnum for fast recovery (set it to initial seq number)
|
|
|
|
|
bool m_recoverActive{false}; //!< Whether "m_recover" has been set/activated
|
|
|
|
|
//!< It is used to avoid comparing with the old m_recover value
|
|
|
|
|
//!< which was set for handling previous congestion event.
|
|
|
|
|
uint32_t m_retxThresh{3}; //!< Fast Retransmit threshold
|
|
|
|
|
bool m_limitedTx{true}; //!< perform limited transmit
|
|
|
|
|
|
|
|
|
|
// Transmission Control Block
|
|
|
|
|
Ptr<TcpSocketState> m_tcb; //!< Congestion control information
|
|
|
|
|
Ptr<TcpCongestionOps> m_congestionControl; //!< Congestion control
|
|
|
|
|
Ptr<TcpRecoveryOps> m_recoveryOps; //!< Recovery Algorithm
|
|
|
|
|
Ptr<TcpRateOps> m_rateOps; //!< Rate operations
|
|
|
|
|
|
|
|
|
|
// Guesses over the other connection end
|
|
|
|
|
bool m_isFirstPartialAck{true}; //!< First partial ACK during RECOVERY
|
|
|
|
|
|
2024-09-03 14:30:07 +00:00
|
|
|
// The following three traces pass a packet with a TCP header
|
2022-10-07 20:08:35 +00:00
|
|
|
TracedCallback<Ptr<const Packet>,
|
|
|
|
|
const TcpHeader&,
|
|
|
|
|
Ptr<const TcpSocketBase>>
|
|
|
|
|
m_txTrace; //!< Trace of transmitted packets
|
|
|
|
|
|
2024-09-03 14:30:07 +00:00
|
|
|
TracedCallback<Ptr<const Packet>,
|
|
|
|
|
const TcpHeader&,
|
|
|
|
|
const Address&,
|
|
|
|
|
const Address&,
|
|
|
|
|
Ptr<const TcpSocketBase>>
|
|
|
|
|
m_retransmissionTrace; //!< Trace of retransmitted packets
|
|
|
|
|
|
2022-10-07 20:08:35 +00:00
|
|
|
TracedCallback<Ptr<const Packet>,
|
|
|
|
|
const TcpHeader&,
|
|
|
|
|
Ptr<const TcpSocketBase>>
|
|
|
|
|
m_rxTrace; //!< Trace of received packets
|
|
|
|
|
|
|
|
|
|
// Pacing related variable
|
|
|
|
|
Timer m_pacingTimer{Timer::CANCEL_ON_DESTROY}; //!< Pacing Event
|
|
|
|
|
|
|
|
|
|
// Parameters related to Explicit Congestion Notification
|
|
|
|
|
TracedValue<SequenceNumber32> m_ecnEchoSeq{
|
|
|
|
|
0}; //!< Sequence number of the last received ECN Echo
|
|
|
|
|
TracedValue<SequenceNumber32> m_ecnCESeq{
|
|
|
|
|
0}; //!< Sequence number of the last received Congestion Experienced
|
|
|
|
|
TracedValue<SequenceNumber32> m_ecnCWRSeq{0}; //!< Sequence number of the last sent CWR
|
2010-12-17 13:57:22 -05:00
|
|
|
};
|
|
|
|
|
|
2015-10-16 10:38:30 -07:00
|
|
|
/**
|
|
|
|
|
* \ingroup tcp
|
2015-10-16 10:44:38 -07:00
|
|
|
* TracedValue Callback signature for TcpCongState_t
|
2015-10-16 10:38:30 -07:00
|
|
|
*
|
|
|
|
|
* \param [in] oldValue original value of the traced variable
|
|
|
|
|
* \param [in] newValue new value of the traced variable
|
|
|
|
|
*/
|
2022-10-07 20:08:35 +00:00
|
|
|
typedef void (*TcpCongStatesTracedValueCallback)(const TcpSocketState::TcpCongState_t oldValue,
|
|
|
|
|
const TcpSocketState::TcpCongState_t newValue);
|
2015-10-16 10:38:30 -07:00
|
|
|
|
2018-06-09 12:00:54 -07:00
|
|
|
/**
|
|
|
|
|
* \ingroup tcp
|
|
|
|
|
* TracedValue Callback signature for ECN state trace
|
|
|
|
|
*
|
|
|
|
|
* \param [in] oldValue original value of the traced variable
|
|
|
|
|
* \param [in] newValue new value of the traced variable
|
|
|
|
|
*/
|
2022-10-07 20:08:35 +00:00
|
|
|
typedef void (*EcnStatesTracedValueCallback)(const TcpSocketState::EcnState_t oldValue,
|
|
|
|
|
const TcpSocketState::EcnState_t newValue);
|
2018-06-09 12:00:54 -07:00
|
|
|
|
2010-12-17 13:57:22 -05:00
|
|
|
} // namespace ns3
|
|
|
|
|
|
|
|
|
|
#endif /* TCP_SOCKET_BASE_H */
|