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