A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-tx-buffer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015 Adrian Sai-wah Tam
3 * Copyright (c) 2016 Natale Patriciello <natale.patriciello@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Original author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
8 */
9
10#ifndef TCP_TX_BUFFER_H
11#define TCP_TX_BUFFER_H
12
13#include "tcp-option-sack.h"
14#include "tcp-tx-item.h"
15
16#include "ns3/internet-export.h"
17#include "ns3/object.h"
18#include "ns3/sequence-number.h"
19#include "ns3/traced-value.h"
20
21namespace ns3
22{
23class Packet;
24
25/**
26 * @ingroup tcp
27 *
28 * @brief Tcp sender buffer
29 *
30 * The class keeps track of all data that the application wishes to transmit to
31 * the other end. When the data is acknowledged, it is removed from the buffer.
32 * The buffer has a maximum size, and data is not saved if the amount exceeds
33 * the limit. Packets can be added to the class through the method Add(). An
34 * important thing to remember is that all the data managed is strictly
35 * sequential. It can be divided into blocks, but all the data follow a strict
36 * ordering. That order is managed through SequenceNumber.
37 *
38 * In other words, this buffer contains numbered bytes (e.g., 1,2,3), and the
39 * class is allowed to return only ordered (using "<" as operator) subsets
40 * (e.g. 1,2 or 2,3 or 1,2,3).
41 *
42 * The data structure underlying this is composed by two distinct packet lists.
43 * The first (SentList) is initially empty, and it contains the packets
44 * returned by the method CopyFromSequence. The second (AppList) is initially
45 * empty, and it contains the packets coming from the applications, but that
46 * are not transmitted yet as segments. To discover how the chunks are managed
47 * and retrieved from these lists, check CopyFromSequence documentation.
48 *
49 * The head of the data is represented by m_firstByteSeq, and it is returned by
50 * HeadSequence(). The last byte is returned by TailSequence(). In this class,
51 * we also store the size (in bytes) of the packets inside the SentList in the
52 * variable m_sentSize.
53 *
54 * SACK management
55 * ---------------
56 *
57 * The SACK information is usually saved in a data structure referred as
58 * scoreboard. In this implementation, the scoreboard is developed on top of
59 * the existing classes. In particular, instead of keeping raw pointers to
60 * packets in TcpTxBuffer we added the capability to store some flags
61 * associated with every segment sent. This is done through the use of the
62 * class TcpTxItem: instead of storing a list of packets, we store a list of
63 * TcpTxItem. Each item has different flags (check the corresponding
64 * documentation) and maintaining the scoreboard is a matter of travelling the
65 * list and set the SACK flag on the corresponding segment sent.
66 *
67 * Item properties
68 * ---------------
69 *
70 * An item (that represent a segment in flight) is not considered in flight
71 * anymore when it is marked lost or sacked. A sacked item represents an
72 * item which is received by the other end, but it is still impossible
73 * to delete from the list because other pieces are missing at the other
74 * end. A lost item never reached the other end, and retransmission is probably
75 * needed. Other properties are retransmitted, that indicates if an item was
76 * retransmitted, and the sequence number of the first byte of the packet. When
77 * a segment is sent for the first time, only the sequence number is set, and
78 * all the remaining properties are set to false. If an item is explicitly
79 * sacked by the receiver, we mark it as such. Each time we receive updated
80 * sack information from the other end, we perform a check to evaluate the
81 * segments that can be lost (\see UpdateLostCount), and we set the flags
82 * accordingly.
83 *
84 * Management of bytes in flight
85 * -----------------------------
86 *
87 * Since this class manages all the output segments and the scoreboard, we can
88 * do calculations about the number of bytes in flights. Earlier versions of
89 * this class used algorithms copied from RFC 6675. They were inefficient
90 * because they required a complete walk into the list of sent segments each
91 * time a simple question, such as "Is this sequence lost?" or "How many bytes
92 * are in flight?". Therefore, the class has been updated keeping in
93 * consideration the RFCs (including RFC 4898) and the Linux operating
94 * system. As a reference, we kept the older methods for calculating the
95 * bytes in flight and if a segment is lost, renaming them as "RFC" version
96 * of the methods. To have a look how the calculations are made, please see
97 * BytesInFlight method.
98 *
99 * Lost segments
100 * -------------
101 *
102 * After the sender receives a new SACK block, it updates the amount of segment
103 * that it considers as lost, following the specifications made in RFC 6675
104 * (for more detail please see the method UpdateLostCount). In case of SACKless
105 * connection, the TcpSocketImplementation should provide hints through
106 * the MarkHeadAsLost and AddRenoSack methods.
107 *
108 * @see BytesInFlight
109 * @see Size
110 * @see SizeFromSequence
111 * @see CopyFromSequence
112 */
113class TcpTxBuffer : public Object
114{
115 public:
116 /**
117 * @brief Get the type ID.
118 * @return the object TypeId
119 */
120 static TypeId GetTypeId();
121 /**
122 * @brief Constructor
123 * @param n initial Sequence number to be transmitted
124 */
125 TcpTxBuffer(uint32_t n = 0);
126 ~TcpTxBuffer() override;
127
128 // Accessors
129
130 /**
131 * @brief Get the sequence number of the buffer head
132 * @returns the first byte's sequence number
133 */
135
136 /**
137 * @brief Get the sequence number of the buffer tail (plus one)
138 * @returns the last byte's sequence number + 1
139 */
141
142 /**
143 * @brief Returns total number of bytes in this buffer
144 * @returns total number of bytes in this Tx buffer
145 */
146 uint32_t Size() const;
147
148 /**
149 * @brief Get the maximum buffer size
150 * @returns the Tx window size (in bytes)
151 */
152 uint32_t MaxBufferSize() const;
153
154 /**
155 * @brief Set the maximum buffer size
156 * @param n Tx window size (in bytes)
157 */
159
160 /**
161 * @brief check whether SACK is used on the corresponding TCP socket
162 * @return true if SACK is used
163 */
164 bool IsSackEnabled() const;
165
166 /**
167 * @brief tell tx-buffer whether SACK is used on this TCP socket
168 *
169 * @param enabled whether sack is used
170 */
171 void SetSackEnabled(bool enabled);
172
173 /**
174 * @brief Returns the available capacity of this buffer
175 * @returns available capacity in this Tx window
176 */
177 uint32_t Available() const;
178
179 /**
180 * @brief Set the DupAckThresh
181 * @param dupAckThresh the threshold
182 */
183 void SetDupAckThresh(uint32_t dupAckThresh);
184
185 /**
186 * @brief Set the segment size
187 * @param segmentSize the segment size
188 */
190
191 /**
192 * @brief Return the number of segments in the sent list that
193 * have been transmitted more than once, without acknowledgment.
194 *
195 * This method is to support the retransmits count for determining PipeSize
196 * in NewReno-style TCP.
197 *
198 * @returns number of segments that have been transmitted more than once, without acknowledgment
199 */
201
202 /**
203 * @brief Get the number of segments that we believe are lost in the network
204 *
205 * It is calculated in UpdateLostCount.
206 * @return the number of lost segment
207 */
208 uint32_t GetLost() const;
209
210 /**
211 * @brief Get the number of segments that have been explicitly sacked by the receiver.
212 * @return the number of sacked segment.
213 */
214 uint32_t GetSacked() const;
215
216 /**
217 * @brief Append a data packet to the end of the buffer
218 *
219 * @param p The packet to be appended to the Tx buffer
220 * @return Boolean to indicate success
221 */
222 bool Add(Ptr<Packet> p);
223
224 /**
225 * @brief Returns the number of bytes from the buffer in the range [seq, tailSequence)
226 *
227 * @param seq initial sequence number
228 * @returns the number of bytes from the buffer in the range
229 */
231
232 /**
233 * @brief Copy data from the range [seq, seq+numBytes) into a packet
234 *
235 * In the following, we refer to the block [seq, seq+numBytes) simply as "block".
236 * We check the boundary of the block, and divide the possibilities in three
237 * cases:
238 *
239 * - the block have already been transmitted (managed in GetTransmittedSegment)
240 * - the block have not been transmitted yet (managed in GetNewSegment)
241 *
242 * The last case is when the block is partially transmitted and partially
243 * not transmitted. We trick this case by requesting the portion not transmitted
244 * from GetNewSegment, and then calling GetTransmittedSegment with the full
245 * block range.
246 *
247 * @param numBytes number of bytes to copy
248 * @param seq start sequence number to extract
249 * @returns a pointer to the TcpTxItem that corresponds to what requested.
250 * Please do not delete the pointer, nor modify Packet data or sequence numbers.
251 */
253
254 /**
255 * @brief Set the head sequence of the buffer
256 *
257 * Set the head (m_firstByteSeq) to seq. Supposed to be called only when the
258 * connection is just set up and we did not send any data out yet.
259 * @param seq The sequence number of the head byte
260 */
261 void SetHeadSequence(const SequenceNumber32& seq);
262
263 /**
264 * @brief Checks whether the ack corresponds to retransmitted data
265 *
266 * @param ack ACK number received
267 * @return true if retransmitted data was acked
268 */
269 bool IsRetransmittedDataAcked(const SequenceNumber32& ack) const;
270
271 /**
272 * @brief Discard data up to but not including this sequence number.
273 *
274 * @param seq The first sequence number to maintain after discarding all the
275 * previous sequences.
276 * @param beforeDelCb Callback invoked, if it is not null, before the deletion
277 * of an Item (because it was, probably, ACKed)
278 */
279 void DiscardUpTo(const SequenceNumber32& seq,
280 const Callback<void, TcpTxItem*>& beforeDelCb = m_nullCb);
281
282 /**
283 * @brief Update the scoreboard
284 * @param list list of SACKed blocks
285 * @param sackedCb Callback invoked, if it is not null, when a segment has been
286 * SACKed by the receiver.
287 * @returns the number of bytes newly sacked by the list of blocks
288 */
290 const Callback<void, TcpTxItem*>& sackedCb = m_nullCb);
291
292 /**
293 * @brief Check if a segment is lost
294 *
295 * It does a check on the flags to determine if the segment has to be considered
296 * as lost for an external class
297 *
298 * @param seq sequence to check
299 * @return true if the sequence is supposed to be lost, false otherwise
300 */
301 bool IsLost(const SequenceNumber32& seq) const;
302
303 /**
304 * @brief Get the next sequence number to transmit, according to RFC 6675
305 *
306 * @param seq Next sequence number to transmit, based on the scoreboard information
307 * @param seqHigh Maximum sequence number to transmit, based on SMSS and/or receiver window
308 * @param isRecovery true if the socket congestion state is in recovery mode
309 * @return true is seq is updated, false otherwise
310 */
311 bool NextSeg(SequenceNumber32* seq, SequenceNumber32* seqHigh, bool isRecovery) const;
312
313 /**
314 * @brief Return total bytes in flight
315 *
316 * Counting packets in flight is pretty simple:
317 *
318 * \f$in_flight = sentSize - leftOut + retrans\f$
319 *
320 * sentsize is SND.NXT-SND.UNA, retrans is the number of retransmitted segments.
321 * leftOut is the number of segment that left the network without being ACKed:
322 *
323 * \f$leftOut = sacked_out + lost_out\f$
324 *
325 * To see how we define the lost packets, look at the method UpdateLostCount.
326 *
327 * @returns total bytes in flight
328 */
329 uint32_t BytesInFlight() const;
330
331 /**
332 * @brief Set the entire sent list as lost (typically after an RTO)
333 *
334 * Used to set all the sent list as lost, so the bytes in flight is not counting
335 * them as in flight, but we will continue to use SACK information for
336 * recovering the timeout.
337 *
338 * Moreover, reset the retransmit flag for every item.
339 * @param resetSack True if the function should reset the SACK flags.
340 */
341 void SetSentListLost(bool resetSack = false);
342
343 /**
344 * @brief Check if the head is retransmitted
345 *
346 * @return true if the head is retransmitted, false in all other cases
347 * (including no segment sent)
348 */
349 bool IsHeadRetransmitted() const;
350
351 /**
352 * @brief DeleteRetransmittedFlagFromHead
353 */
355
356 /**
357 * @brief Reset the sent list
358 *
359 */
360 void ResetSentList();
361
362 /**
363 * @brief Take the last segment sent and put it back into the un-sent list
364 * (at the beginning)
365 */
367
368 /**
369 * @brief Mark the head of the sent list as lost.
370 */
371 void MarkHeadAsLost();
372
373 /**
374 * @brief Emulate SACKs for SACKless connection: account for a new dupack.
375 *
376 * The method walk the list of the sent segment until it finds a segment
377 * that was not accounted in the sackedOut count. The head will never
378 * be included. To reset the information added with this function (e.g.,
379 * after an RTO) please use ResetRenoSack.
380 *
381 * The method DiscardUpTo, when invoked, will make sure to properly clean any
382 * flag on the discarded item. As example, if the implementation discard an item
383 * that is marked as sacked, the sackedOut count is decreased accordingly.
384 */
385 void AddRenoSack();
386
387 /**
388 * @brief Reset the SACKs.
389 *
390 * Reset the Scoreboard from all SACK information. This method also works in
391 * case the SACKs are set by the Update method.
392 */
393 void ResetRenoSack();
394
395 /**
396 * @brief Set callback to obtain receiver window value
397 * @param rWndCallback receiver window callback
398 */
399 void SetRWndCallback(Callback<uint32_t> rWndCallback);
400
401 private:
402 friend std::ostream& operator<<(std::ostream& os, const TcpTxBuffer& tcpTxBuf);
403
404 typedef std::list<TcpTxItem*> PacketList; //!< container for data stored in the buffer
405
406 /**
407 * @brief Update the lost count
408 *
409 * Reset lost to 0, then walk the sent list looking for lost segments.
410 * We have two possible algorithms for detecting lost packets:
411 *
412 * - RFC 6675 algorithm, which says that if more than "Dupack thresh" (e.g., 3)
413 * sacked segments above the sequence, then we can consider the sequence lost;
414 * - NewReno (RFC6582): in Recovery we assume that one segment is lost
415 * (classic Reno). While we are in Recovery and a partial ACK arrives,
416 * we assume that one more packet is lost (NewReno).
417 *
418 * The {New}Reno cases, for now, are managed in TcpSocketBase through the
419 * call to MarkHeadAsLost.
420 * This function is, therefore, called after a SACK option has been received,
421 * and updates the lost count. It can be probably optimized by not walking
422 * the entire list, but a subset.
423 *
424 */
425 void UpdateLostCount();
426
427 /**
428 * @brief Remove the size specified from the lostOut, retrans, sacked count
429 *
430 * Used only in DiscardUpTo
431 *
432 * @param item Item that will be discarded
433 * @param size size to remove (can be different from pktSize because of fragmentation)
434 */
435 void RemoveFromCounts(TcpTxItem* item, uint32_t size);
436
437 /**
438 * @brief Decide if a segment is lost based on RFC 6675 algorithm.
439 * @param seq Sequence
440 * @param segment Iterator to the sequence
441 * @return true if seq is lost per RFC 6675, false otherwise
442 */
443 bool IsLostRFC(const SequenceNumber32& seq, const PacketList::const_iterator& segment) const;
444
445 /**
446 * @brief Calculate the number of bytes in flight per RFC 6675
447 * @return the number of bytes in flight
448 */
450
451 /**
452 * @brief Get a block of data not transmitted yet and move it into SentList
453 *
454 * If the block is not yet transmitted, hopefully, seq is exactly the sequence
455 * number of the first byte of the first packet inside AppList. We extract
456 * the block from AppList and move it into the SentList, before returning the
457 * block itself. We manage possible fragmentation (or merges) inside AppList
458 * through GetPacketFromList.
459 *
460 * @see GetPacketFromList
461 * @param numBytes number of bytes to copy
462 *
463 * @return the item that contains the right packet
464 */
466
467 /**
468 * @brief Get a block of data previously transmitted
469 *
470 * This is clearly a retransmission, and if everything is going well,
471 * the block requested is matching perfectly with another one requested
472 * in the past. If not, fragmentation or merge are required. We manage
473 * both inside GetPacketFromList.
474 *
475 * @see GetPacketFromList
476 *
477 * @param numBytes number of bytes to copy
478 * @param seq sequence requested
479 * @returns the item that contains the right packet
480 */
482
483 /**
484 * @brief Get a block (which is returned as Packet) from a list
485 *
486 * This function extract a block [requestedSeq,numBytes) from the list, which
487 * starts at startingSeq.
488 *
489 * The cases we need to manage are two, and they are depicted in the following
490 * image:
491 *
492 * @verbatim
493 |------| |----| |----|
494 list = | | --> | | --> | |
495 |------| |----| |----|
496
497 ^ ^
498 | ^ ^ | (1)
499 seq | | seq + numBytes
500 | |
501 | |
502 seq seq + numBytes (2)
503 \endverbatim
504 *
505 * The case 1 is easy to manage: the requested block is exactly a packet
506 * already stored. If one value (seq or seq + numBytes) does not align
507 * to a packet boundary, or when both values does not align (case 2), it is
508 * a bit more complex.
509 *
510 * Basically, we have two possible operations:
511 *
512 * - fragment : split an existing packet in two
513 * - merge : merge two existing packets in one
514 *
515 * and we reduce case (2) to case (1) through sequentially applying fragment
516 * or merge. For instance:
517 *
518 * @verbatim
519 |------|
520 | |
521 |------|
522
523 ^ ^ ^ ^
524 | | | |
525 start | | |
526 | | end
527 seq |
528 seq + numBytes
529 \endverbatim
530 *
531 * To reduce to case (1), we need to perform two fragment operations:
532 *
533 * - fragment (start, seq)
534 * - fragment (seq + numBytes, end)
535 *
536 * After these operations, the requested block is exactly the resulting packet.
537 * Merge operation is required when the requested block span over two (or more)
538 * existing packets.
539 *
540 * While this could be extremely slow in the worst possible scenario (one big
541 * packet which is split in small packets for transmission, and merged for
542 * re-transmission) that scenario is unlikely during a TCP transmission (since
543 * MSS can change, but it is stable, and retransmissions do not happen for
544 * each segment).
545 *
546 * @param list List to extract block from
547 * @param startingSeq Starting sequence of the list
548 * @param numBytes Bytes to extract, starting from requestedSeq
549 * @param requestedSeq Requested sequence
550 * @param listEdited output parameter which indicates if the list has been edited
551 * @return the item that contains the right packet
552 */
554 const SequenceNumber32& startingSeq,
555 uint32_t numBytes,
556 const SequenceNumber32& requestedSeq,
557 bool* listEdited = nullptr) const;
558
559 /**
560 * @brief Merge two TcpTxItem
561 *
562 * Merge t2 in t1. It consists in copying the lastSent field if t2 is more
563 * recent than t1. Retransmitted field is copied only if it set in t2 but not
564 * in t1. Sacked is copied only if it is true in both items.
565 *
566 * @param t1 first item
567 * @param t2 second item
568 */
569 void MergeItems(TcpTxItem* t1, TcpTxItem* t2) const;
570
571 /**
572 * @brief Split one TcpTxItem
573 *
574 * Move "size" bytes from t2 into t1, copying all the fields.
575 * Adjust the starting sequence of each item.
576 *
577 * @param t1 first item
578 * @param t2 second item
579 * @param size Size to split
580 */
581 void SplitItems(TcpTxItem* t1, TcpTxItem* t2, uint32_t size) const;
582
583 /**
584 * @brief Check if the values of sacked, lost, retrans, are in sync
585 * with the sent list.
586 */
587 void ConsistencyCheck() const;
588
589 /**
590 * @brief Find the highest SACK byte
591 * @return a pair with the highest byte and an iterator inside m_sentList
592 */
593 std::pair<TcpTxBuffer::PacketList::const_iterator, SequenceNumber32> FindHighestSacked() const;
594
595 PacketList m_appList; //!< Buffer for application data
596 PacketList m_sentList; //!< Buffer for sent (but not acked) data
597 uint32_t m_maxBuffer; //!< Max number of data bytes in buffer (SND.WND)
598 uint32_t m_size; //!< Size of all data in this buffer
599 uint32_t m_sentSize; //!< Size of sent (and not discarded) segments
600 Callback<uint32_t> m_rWndCallback; //!< Callback to obtain RCV.WND value
601
603 m_firstByteSeq; //!< Sequence number of the first byte in data (SND.UNA)
604 std::pair<PacketList::const_iterator, SequenceNumber32> m_highestSack; //!< Highest SACK byte
605
606 uint32_t m_lostOut{0}; //!< Number of lost bytes
607 uint32_t m_sackedOut{0}; //!< Number of sacked bytes
608 uint32_t m_retrans{0}; //!< Number of retransmitted bytes
609
610 uint32_t m_dupAckThresh{0}; //!< Duplicate Ack threshold from TcpSocketBase
611 uint32_t m_segmentSize{0}; //!< Segment size from TcpSocketBase
612 bool m_renoSack{false}; //!< Indicates if AddRenoSack was called
613 bool m_sackEnabled{true}; //!< Indicates if SACK is enabled on this connection
614 bool m_sackSeen{false}; //!< Indicates if a SACK was received
615
616 INTERNET_EXPORT static inline Callback<void, TcpTxItem*> m_nullCb =
617 MakeNullCallback<void, TcpTxItem*>(); //!< Null callback for an item
618};
619
620/**
621 * @brief Output operator.
622 * @param os The output stream.
623 * @param tcpTxBuf the TcpTxBuffer to print.
624 * @returns The output stream.
625 */
626std::ostream& operator<<(std::ostream& os, const TcpTxBuffer& tcpTxBuf);
627
628/**
629 * @brief Output operator.
630 * @param os The output stream.
631 * @param item the item to print.
632 * @returns The output stream.
633 */
634std::ostream& operator<<(std::ostream& os, const TcpTxItem& item);
635
636} // namespace ns3
637
638#endif /* TCP_TX_BUFFER_H */
Callback template class.
Definition callback.h:422
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
std::list< SackBlock > SackList
SACK list definition.
Tcp sender buffer.
uint32_t m_retrans
Number of retransmitted bytes.
void ResetRenoSack()
Reset the SACKs.
void ConsistencyCheck() const
Check if the values of sacked, lost, retrans, are in sync with the sent list.
bool m_sackEnabled
Indicates if SACK is enabled on this connection.
uint32_t m_lostOut
Number of lost bytes.
bool IsLostRFC(const SequenceNumber32 &seq, const PacketList::const_iterator &segment) const
Decide if a segment is lost based on RFC 6675 algorithm.
std::pair< TcpTxBuffer::PacketList::const_iterator, SequenceNumber32 > FindHighestSacked() const
Find the highest SACK byte.
SequenceNumber32 HeadSequence() const
Get the sequence number of the buffer head.
std::pair< PacketList::const_iterator, SequenceNumber32 > m_highestSack
Highest SACK byte.
bool IsHeadRetransmitted() const
Check if the head is retransmitted.
bool Add(Ptr< Packet > p)
Append a data packet to the end of the buffer.
void SetSegmentSize(uint32_t segmentSize)
Set the segment size.
uint32_t GetRetransmitsCount() const
Return the number of segments in the sent list that have been transmitted more than once,...
bool IsRetransmittedDataAcked(const SequenceNumber32 &ack) const
Checks whether the ack corresponds to retransmitted data.
static TypeId GetTypeId()
Get the type ID.
TcpTxItem * GetPacketFromList(PacketList &list, const SequenceNumber32 &startingSeq, uint32_t numBytes, const SequenceNumber32 &requestedSeq, bool *listEdited=nullptr) const
Get a block (which is returned as Packet) from a list.
uint32_t SizeFromSequence(const SequenceNumber32 &seq) const
Returns the number of bytes from the buffer in the range [seq, tailSequence)
TracedValue< SequenceNumber32 > m_firstByteSeq
Sequence number of the first byte in data (SND.UNA)
std::list< TcpTxItem * > PacketList
container for data stored in the buffer
uint32_t MaxBufferSize() const
Get the maximum buffer size.
TcpTxItem * GetTransmittedSegment(uint32_t numBytes, const SequenceNumber32 &seq)
Get a block of data previously transmitted.
uint32_t m_maxBuffer
Max number of data bytes in buffer (SND.WND)
bool m_renoSack
Indicates if AddRenoSack was called.
bool m_sackSeen
Indicates if a SACK was received.
uint32_t m_dupAckThresh
Duplicate Ack threshold from TcpSocketBase.
uint32_t Size() const
Returns total number of bytes in this buffer.
void SetSackEnabled(bool enabled)
tell tx-buffer whether SACK is used on this TCP socket
uint32_t m_sackedOut
Number of sacked bytes.
void ResetLastSegmentSent()
Take the last segment sent and put it back into the un-sent list (at the beginning)
bool IsLost(const SequenceNumber32 &seq) const
Check if a segment is lost.
bool NextSeg(SequenceNumber32 *seq, SequenceNumber32 *seqHigh, bool isRecovery) const
Get the next sequence number to transmit, according to RFC 6675.
void SetDupAckThresh(uint32_t dupAckThresh)
Set the DupAckThresh.
TcpTxItem * CopyFromSequence(uint32_t numBytes, const SequenceNumber32 &seq)
Copy data from the range [seq, seq+numBytes) into a packet.
bool IsSackEnabled() const
check whether SACK is used on the corresponding TCP socket
TcpTxItem * GetNewSegment(uint32_t numBytes)
Get a block of data not transmitted yet and move it into SentList.
uint32_t Available() const
Returns the available capacity of this buffer.
uint32_t m_segmentSize
Segment size from TcpSocketBase.
uint32_t Update(const TcpOptionSack::SackList &list, const Callback< void, TcpTxItem * > &sackedCb=m_nullCb)
Update the scoreboard.
uint32_t GetLost() const
Get the number of segments that we believe are lost in the network.
void AddRenoSack()
Emulate SACKs for SACKless connection: account for a new dupack.
void MarkHeadAsLost()
Mark the head of the sent list as lost.
void UpdateLostCount()
Update the lost count.
SequenceNumber32 TailSequence() const
Get the sequence number of the buffer tail (plus one)
Callback< uint32_t > m_rWndCallback
Callback to obtain RCV.WND value.
void SetRWndCallback(Callback< uint32_t > rWndCallback)
Set callback to obtain receiver window value.
uint32_t BytesInFlight() const
Return total bytes in flight.
void SetSentListLost(bool resetSack=false)
Set the entire sent list as lost (typically after an RTO)
void SplitItems(TcpTxItem *t1, TcpTxItem *t2, uint32_t size) const
Split one TcpTxItem.
void DiscardUpTo(const SequenceNumber32 &seq, const Callback< void, TcpTxItem * > &beforeDelCb=m_nullCb)
Discard data up to but not including this sequence number.
uint32_t BytesInFlightRFC() const
Calculate the number of bytes in flight per RFC 6675.
~TcpTxBuffer() override
PacketList m_appList
Buffer for application data.
uint32_t GetSacked() const
Get the number of segments that have been explicitly sacked by the receiver.
void MergeItems(TcpTxItem *t1, TcpTxItem *t2) const
Merge two TcpTxItem.
uint32_t m_size
Size of all data in this buffer.
void ResetSentList()
Reset the sent list.
void DeleteRetransmittedFlagFromHead()
DeleteRetransmittedFlagFromHead.
void SetMaxBufferSize(uint32_t n)
Set the maximum buffer size.
PacketList m_sentList
Buffer for sent (but not acked) data.
uint32_t m_sentSize
Size of sent (and not discarded) segments.
void RemoveFromCounts(TcpTxItem *item, uint32_t size)
Remove the size specified from the lostOut, retrans, sacked count.
static INTERNET_EXPORT Callback< void, TcpTxItem * > m_nullCb
Null callback for an item.
friend std::ostream & operator<<(std::ostream &os, const TcpTxBuffer &tcpTxBuf)
Output operator.
void SetHeadSequence(const SequenceNumber32 &seq)
Set the head sequence of the buffer.
TcpTxBuffer(uint32_t n=0)
Constructor.
Item that encloses the application packet and some flags for it.
Definition tcp-tx-item.h:22
Trace classes with value semantics.
a unique identifier for an interface.
Definition type-id.h:49
uint32_t segmentSize
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148