A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-rx-buffer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Adrian Sai-wah Tam
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
7 */
8
9#ifndef TCP_RX_BUFFER_H
10#define TCP_RX_BUFFER_H
11
12#include "tcp-header.h"
13#include "tcp-option-sack.h"
14
15#include "ns3/ptr.h"
16#include "ns3/sequence-number.h"
17#include "ns3/trace-source-accessor.h"
18#include "ns3/traced-value.h"
19
20#include <map>
21
22namespace ns3
23{
24class Packet;
25
26/**
27 * \ingroup tcp
28 *
29 * \brief Rx reordering buffer for TCP
30 *
31 * The class is responsible to safely store the segments, and then
32 * returning them in-order to the application, where "in-order" does not means
33 * "network-order", but "sender-order" : the bytes should be returned in the
34 * same order that the sender application used to push them down on wire.
35 *
36 * The first useful sequence that this class is waiting is returned by the method
37 * NextRxSequence, and could be set at the beginning through MaxRxSequence.
38 *
39 * The max. size of this buffer is managed through SetMaxBufferSize, and could be
40 * retrieved using MaxBufferSize. The current size instead is returned by
41 * Size, while the amount of in-order data that could be extracted is returned
42 * by the method Available.
43 *
44 * To store data, use Add; for retrieving a certain amount of ordered data, use
45 * the method Extract.
46 *
47 * SACK list
48 * ---------
49 *
50 * An interesting feature of this class is the ability to maintain an ordered
51 * SACK list, under the definition of RFC 2018. When a out-of-order segment
52 * reaches this buffer, an ACK will be sent out, and the SACK list is
53 * generated or updated. From RFC 2018:
54 *
55 * > If sent at all, SACK options SHOULD be included in all ACKs which do
56 * > not ACK the highest sequence number in the data receiver's queue.
57 *
58 * For more information about the SACK list, please check the documentation of
59 * the method GetSackList.
60 *
61 * \see GetSackList
62 * \see UpdateSackList
63 */
64class TcpRxBuffer : public Object
65{
66 public:
67 /**
68 * \brief Get the type ID.
69 * \return the object TypeId
70 */
71 static TypeId GetTypeId();
72 /**
73 * \brief Constructor
74 * \param n initial Sequence number to be received
75 */
76 TcpRxBuffer(uint32_t n = 0);
77 ~TcpRxBuffer() override;
78
79 // Accessors
80 /**
81 * \brief Get Next Rx Sequence number
82 * \returns Next Rx Sequence number
83 */
85 /**
86 * \brief Get the lowest sequence number that this TcpRxBuffer cannot accept
87 * \returns the lowest sequence number that this TcpRxBuffer cannot accept
88 */
90 /**
91 * \brief Increment the Next Sequence number
92 */
93 void IncNextRxSequence();
94 /**
95 * \brief Set the Next Sequence number
96 * \param s the Sequence number
97 */
99 /**
100 * \brief Set the FIN Sequence number (i.e., the one closing the connection)
101 * \param s the Sequence number
102 */
103 void SetFinSequence(const SequenceNumber32& s);
104 /**
105 * \brief Get the Maximum buffer size
106 * \returns the Maximum buffer size
107 */
108 uint32_t MaxBufferSize() const;
109 /**
110 * \brief Set the Maximum buffer size
111 * \param s the Maximum buffer size
112 */
114 /**
115 * \brief Get the actual buffer occupancy
116 * \returns buffer occupancy (in bytes)
117 */
118 uint32_t Size() const;
119 /**
120 * \brief Get the actual number of bytes available to be read
121 * \returns size of available data (in bytes)
122 */
123 uint32_t Available() const;
124 /**
125 * \brief Check if the buffer did receive all the data (and the connection is closed)
126 * \returns true if all data have been received
127 */
128 bool Finished();
129
130 /**
131 * Insert a packet into the buffer and update the availBytes counter to
132 * reflect the number of bytes ready to send to the application. This
133 * function handles overlap by trimming the head of the inputted packet and
134 * removing data from the buffer that overlaps the tail of the inputted
135 * packet
136 *
137 * \param p packet
138 * \param tcph packet's TCP header
139 * \return True when success, false otherwise.
140 */
141 bool Add(Ptr<Packet> p, const TcpHeader& tcph);
142
143 /**
144 * Extract data from the head of the buffer as indicated by nextRxSeq.
145 * The extracted data is going to be forwarded to the application.
146 *
147 * \param maxSize maximum number of bytes to extract
148 * \returns a packet
149 */
151
152 /**
153 * \brief Get the sack list
154 *
155 * The sack list can be empty, and it is updated each time Add or Extract
156 * are called through the private method UpdateSackList.
157 *
158 * \return a list of isolated blocks
159 */
161
162 /**
163 * \brief Get the size of Sack list
164 *
165 * \return the size of the sack block list; can be empty
166 */
168
169 /**
170 * \brief Says if a FIN bit has been received
171 * \return true if we received a FIN bit
172 */
173 bool GotFin() const
174 {
175 return m_gotFin;
176 }
177
178 private:
179 /**
180 * \brief Update the sack list, with the block seq starting at the beginning
181 *
182 * Note: the maximum size of the block list is 4. Caller is free to
183 * drop blocks at the end to accommodate header size; from RFC 2018:
184 *
185 * > The data receiver SHOULD include as many distinct SACK blocks as
186 * > possible in the SACK option. Note that the maximum available
187 * > option space may not be sufficient to report all blocks present in
188 * > the receiver's queue.
189 *
190 * In fact, the maximum amount of blocks is 4, and if we consider the timestamp
191 * (or other) options, it is even less. For more detail about this function,
192 * please see the source code and in-line comments.
193 *
194 * \param head sequence number of the block at the beginning
195 * \param tail sequence number of the block at the end
196 */
197 void UpdateSackList(const SequenceNumber32& head, const SequenceNumber32& tail);
198
199 /**
200 * \brief Remove old blocks from the sack list
201 *
202 * Used to remove blocks already delivered to the application.
203 *
204 * After this call, in the SACK list there will be only blocks with
205 * sequence numbers greater than seq; it is perfectly safe to call this
206 * function with an empty sack list.
207 *
208 * \param seq Last sequence to remove
209 */
210 void ClearSackList(const SequenceNumber32& seq);
211
212 TcpOptionSack::SackList m_sackList; //!< Sack list (updated constantly)
213
214 /// container for data stored in the buffer
215 typedef std::map<SequenceNumber32, Ptr<Packet>>::iterator BufIterator;
217 m_nextRxSeq; //!< Seqnum of the first missing byte in data (RCV.NXT)
218 SequenceNumber32 m_finSeq; //!< Seqnum of the FIN packet
219 bool m_gotFin; //!< Did I received FIN packet?
220 uint32_t m_size; //!< Number of total data bytes in the buffer, not necessarily contiguous
221 uint32_t m_maxBuffer; //!< Upper bound of the number of data bytes in buffer (RCV.WND)
222 uint32_t m_availBytes; //!< Number of bytes available to read, i.e. contiguous block at head
223 std::map<SequenceNumber32, Ptr<Packet>> m_data; //!< Corresponding data (may be null)
224};
225
226} // namespace ns3
227
228#endif /* TCP_RX_BUFFER_H */
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
Header for the Transmission Control Protocol.
Definition tcp-header.h:36
std::list< SackBlock > SackList
SACK list definition.
Rx reordering buffer for TCP.
~TcpRxBuffer() override
uint32_t GetSackListSize() const
Get the size of Sack list.
Ptr< Packet > Extract(uint32_t maxSize)
Extract data from the head of the buffer as indicated by nextRxSeq.
bool Finished()
Check if the buffer did receive all the data (and the connection is closed)
static TypeId GetTypeId()
Get the type ID.
void SetFinSequence(const SequenceNumber32 &s)
Set the FIN Sequence number (i.e., the one closing the connection)
void SetMaxBufferSize(uint32_t s)
Set the Maximum buffer size.
SequenceNumber32 NextRxSequence() const
Get Next Rx Sequence number.
std::map< SequenceNumber32, Ptr< Packet > > m_data
Corresponding data (may be null)
void SetNextRxSequence(const SequenceNumber32 &s)
Set the Next Sequence number.
SequenceNumber32 m_finSeq
Seqnum of the FIN packet.
uint32_t m_availBytes
Number of bytes available to read, i.e.
void IncNextRxSequence()
Increment the Next Sequence number.
uint32_t MaxBufferSize() const
Get the Maximum buffer size.
uint32_t Size() const
Get the actual buffer occupancy.
bool Add(Ptr< Packet > p, const TcpHeader &tcph)
Insert a packet into the buffer and update the availBytes counter to reflect the number of bytes read...
uint32_t m_maxBuffer
Upper bound of the number of data bytes in buffer (RCV.WND)
std::map< SequenceNumber32, Ptr< Packet > >::iterator BufIterator
container for data stored in the buffer
SequenceNumber32 MaxRxSequence() const
Get the lowest sequence number that this TcpRxBuffer cannot accept.
bool GotFin() const
Says if a FIN bit has been received.
TracedValue< SequenceNumber32 > m_nextRxSeq
Seqnum of the first missing byte in data (RCV.NXT)
TcpRxBuffer(uint32_t n=0)
Constructor.
void UpdateSackList(const SequenceNumber32 &head, const SequenceNumber32 &tail)
Update the sack list, with the block seq starting at the beginning.
uint32_t Available() const
Get the actual number of bytes available to be read.
TcpOptionSack::SackList GetSackList() const
Get the sack list.
uint32_t m_size
Number of total data bytes in the buffer, not necessarily contiguous.
void ClearSackList(const SequenceNumber32 &seq)
Remove old blocks from the sack list.
bool m_gotFin
Did I received FIN packet?
TcpOptionSack::SackList m_sackList
Sack list (updated constantly)
Trace classes with value semantics.
a unique identifier for an interface.
Definition type-id.h:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.