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