INET Framework for OMNeT++/OMNEST
inet::tcp::TcpReceiveQueue Class Reference

Receive queue that manages Chunks. More...

#include <TcpReceiveQueue.h>

Inheritance diagram for inet::tcp::TcpReceiveQueue:

Public Member Functions

 TcpReceiveQueue ()
 Ctor. More...
 
virtual ~TcpReceiveQueue ()
 Virtual dtor. More...
 
virtual ReorderBuffergetReorderBuffer ()
 
virtual void setConnection (TcpConnection *_conn)
 Set the connection that owns this queue. More...
 
virtual void init (uint32_t startSeq)
 Set initial receive sequence number. More...
 
virtual std::string str () const override
 
virtual uint32_t insertBytesFromSegment (Packet *tcpSegment, const Ptr< const TcpHeader > &tcpHeader)
 Called when a TCP segment arrives, it should extract the payload from the segment and store it in the receive queue. More...
 
virtual PacketextractBytesUpTo (uint32_t seq)
 Should create a packet to be passed up to the app, up to (but NOT including) the given sequence no (usually rcv_nxt). More...
 
virtual uint32_t getAmountOfBufferedBytes ()
 Returns the number of bytes (out-of-order-segments) currently buffered in queue. More...
 
virtual uint32_t getAmountOfFreeBytes (uint32_t maxRcvBuffer)
 Returns the number of bytes currently free (=available) in queue. More...
 
virtual uint32_t getQueueLength ()
 Returns the number of blocks currently buffered in queue. More...
 
virtual void getQueueStatus ()
 Shows current queue status. More...
 
virtual uint32_t getLE (uint32_t fromSeqNum)
 Returns left edge of enqueued region. More...
 
virtual uint32_t getRE (uint32_t toSeqNum)
 Returns right edge of enqueued region. More...
 
virtual uint32_t getFirstSeqNo ()
 Returns the minimum of first byte seq.no. More...
 

Protected Member Functions

uint32_t offsetToSeq (B offs) const
 
B seqToOffset (uint32_t seq) const
 

Protected Attributes

TcpConnectionconn = nullptr
 
uint32_t rcv_nxt = 0
 
ReorderBuffer reorderBuffer
 

Detailed Description

Receive queue that manages Chunks.

See also
TcpSendQueue

Constructor & Destructor Documentation

◆ TcpReceiveQueue()

inet::tcp::TcpReceiveQueue::TcpReceiveQueue ( )

Ctor.

16  :
17  rcv_nxt(-1)
18 {
19 }

◆ ~TcpReceiveQueue()

inet::tcp::TcpReceiveQueue::~TcpReceiveQueue ( )
virtual

Virtual dtor.

22 {
23 }

Member Function Documentation

◆ extractBytesUpTo()

Packet * inet::tcp::TcpReceiveQueue::extractBytesUpTo ( uint32_t  seq)
virtual

Should create a packet to be passed up to the app, up to (but NOT including) the given sequence no (usually rcv_nxt).

It should return nullptr if there's no more data to be passed up – this method is called several times until it returns nullptr.

81 {
82  ASSERT(seqLE(seq, rcv_nxt));
83 
84  if (reorderBuffer.isEmpty())
85  return nullptr;
86 
87  auto seqOffs = seqToOffset(seq);
88  auto maxLength = seqOffs - reorderBuffer.getExpectedOffset();
89  if (maxLength <= b(0))
90  return nullptr;
91  auto chunk = reorderBuffer.popAvailableData(maxLength);
93 
94  if (chunk) {
95  Packet *msg = new Packet("data");
96  msg->insertAtBack(chunk);
97  return msg;
98  }
99 
100  return nullptr;
101 }

Referenced by inet::tcp::TcpConnection::process_READ_REQUEST(), and inet::tcp::TcpConnection::sendAvailableDataToApp().

◆ getAmountOfBufferedBytes()

uint32_t inet::tcp::TcpReceiveQueue::getAmountOfBufferedBytes ( )
virtual

Returns the number of bytes (out-of-order-segments) currently buffered in queue.

104 {
105  uint32_t bytes = 0;
106 
107  for (int i = 0; i < reorderBuffer.getNumRegions(); i++)
108  bytes += B(reorderBuffer.getRegionLength(i)).get();
109 
110  return bytes;
111 }

Referenced by getAmountOfFreeBytes(), inet::tcp::TcpConnection::processSegment1stThru8th(), and inet::tcp::TcpConnection::sendAvailableDataToApp().

◆ getAmountOfFreeBytes()

uint32_t inet::tcp::TcpReceiveQueue::getAmountOfFreeBytes ( uint32_t  maxRcvBuffer)
virtual

Returns the number of bytes currently free (=available) in queue.

freeRcvBuffer = maxRcvBuffer - usedRcvBuffer

114 {
115  uint32_t usedRcvBuffer = getAmountOfBufferedBytes();
116  uint32_t freeRcvBuffer = maxRcvBuffer - usedRcvBuffer;
117  return (maxRcvBuffer > usedRcvBuffer) ? freeRcvBuffer : 0;
118 }

Referenced by inet::tcp::TcpConnection::updateRcvQueueVars().

◆ getFirstSeqNo()

uint32_t inet::tcp::TcpReceiveQueue::getFirstSeqNo ( )
virtual

Returns the minimum of first byte seq.no.

in queue and rcv_nxt

155 {
156  if (reorderBuffer.getNumRegions() == 0)
157  return rcv_nxt;
159 }

Referenced by inet::tcp::TcpConnection::hasEnoughSpaceForSegmentInReceiveQueue(), and inet::tcp::TcpConnection::writeHeaderOptions().

◆ getLE()

uint32_t inet::tcp::TcpReceiveQueue::getLE ( uint32_t  fromSeqNum)
virtual

Returns left edge of enqueued region.

131 {
132  B fs = seqToOffset(fromSeqNum);
133 
134  for (int i = 0; i < reorderBuffer.getNumRegions(); i++) {
137  }
138 
139  return fromSeqNum;
140 }

Referenced by inet::tcp::TcpConnection::addSacks().

◆ getQueueLength()

uint32_t inet::tcp::TcpReceiveQueue::getQueueLength ( )
virtual

Returns the number of blocks currently buffered in queue.

121 {
122  return reorderBuffer.getNumRegions();
123 }

Referenced by inet::tcp::TcpConnection::processSegment1stThru8th().

◆ getQueueStatus()

void inet::tcp::TcpReceiveQueue::getQueueStatus ( )
virtual

Shows current queue status.

126 {
127  EV_DEBUG << "receiveQLength=" << reorderBuffer.getNumRegions() << " " << str() << "\n";
128 }

◆ getRE()

uint32_t inet::tcp::TcpReceiveQueue::getRE ( uint32_t  toSeqNum)
virtual

Returns right edge of enqueued region.

143 {
144  B fs = seqToOffset(toSeqNum);
145 
146  for (int i = 0; i < reorderBuffer.getNumRegions(); i++) {
149  }
150 
151  return toSeqNum;
152 }

Referenced by inet::tcp::TcpConnection::addSacks().

◆ getReorderBuffer()

virtual ReorderBuffer& inet::tcp::TcpReceiveQueue::getReorderBuffer ( )
inlinevirtual
62 { return reorderBuffer; }

◆ init()

void inet::tcp::TcpReceiveQueue::init ( uint32_t  startSeq)
virtual

Set initial receive sequence number.

26 {
27  rcv_nxt = startSeq;
28 
31 }

Referenced by inet::tcp::TcpConnection::processSegmentInSynSent(), and inet::tcp::TcpConnection::processSynInListen().

◆ insertBytesFromSegment()

uint32_t inet::tcp::TcpReceiveQueue::insertBytesFromSegment ( Packet tcpSegment,
const Ptr< const TcpHeader > &  tcpHeader 
)
virtual

Called when a TCP segment arrives, it should extract the payload from the segment and store it in the receive queue.

The segment object should not be deleted.

The method should return the sequence number to be ACKed.

45 {
46  B tcpHeaderLength = tcpHeader->getHeaderLength();
47  B tcpPayloadLength = tcpSegment->getDataLength() - tcpHeaderLength;
48  uint32_t seq = tcpHeader->getSequenceNo();
49  uint32_t offs = 0;
50  uint32_t buffSeq = offsetToSeq(reorderBuffer.getExpectedOffset());
51 
52 #ifndef NDEBUG
53  if (!reorderBuffer.isEmpty()) {
56  uint32_t nb = seq;
57  uint32_t ne = seq + tcpPayloadLength.get();
58  uint32_t minb = seqMin(ob, nb);
59  uint32_t maxe = seqMax(oe, ne);
60  if (seqGE(minb, oe) || seqGE(minb, ne) || seqGE(ob, maxe) || seqGE(nb, maxe))
61  throw cRuntimeError("The new segment is [%u, %u) out of the acceptable range at the queue %s",
62  nb, ne, str().c_str());
63  }
64 #endif // ifndef NDEBUG
65 
66  if (seqLess(seq, buffSeq)) {
67  offs = buffSeq - seq;
68  seq = buffSeq;
69  tcpPayloadLength -= B(offs);
70  }
71  const auto& payload = tcpSegment->peekDataAt(tcpHeaderLength + B(offs), tcpPayloadLength);
72  reorderBuffer.replace(seqToOffset(seq), payload);
73 
76 
77  return rcv_nxt;
78 }

Referenced by inet::tcp::TcpConnection::processSegment1stThru8th(), inet::tcp::TcpConnection::processSegmentInSynSent(), and inet::tcp::TcpConnection::processSynInListen().

◆ offsetToSeq()

uint32_t inet::tcp::TcpReceiveQueue::offsetToSeq ( B  offs) const
inlineprotected
42 { return (uint32_t)offs.get(); }

Referenced by getFirstSeqNo(), getLE(), getRE(), insertBytesFromSegment(), and str().

◆ seqToOffset()

B inet::tcp::TcpReceiveQueue::seqToOffset ( uint32_t  seq) const
inlineprotected
45  {
46  B expOffs = reorderBuffer.getExpectedOffset();
47  uint32_t expSeq = offsetToSeq(expOffs);
48  return B((seqGE(seq, expSeq)) ? B(expOffs).get() + (seq - expSeq) : B(expOffs).get() - (expSeq - seq));
49  }

Referenced by extractBytesUpTo(), getLE(), getRE(), and insertBytesFromSegment().

◆ setConnection()

virtual void inet::tcp::TcpReceiveQueue::setConnection ( TcpConnection _conn)
inlinevirtual

Set the connection that owns this queue.

67 { conn = _conn; }

Referenced by inet::tcp::TcpConnection::initClonedConnection(), and inet::tcp::TcpConnection::initConnection().

◆ str()

std::string inet::tcp::TcpReceiveQueue::str ( ) const
overridevirtual
34 {
35  std::ostringstream buf;
36  buf << "rcv_nxt=" << rcv_nxt;
37 
38  for (int i = 0; i < reorderBuffer.getNumRegions(); i++) {
40  }
41  return buf.str();
42 }

Referenced by getQueueStatus(), and insertBytesFromSegment().

Member Data Documentation

◆ conn

TcpConnection* inet::tcp::TcpReceiveQueue::conn = nullptr
protected

◆ rcv_nxt

uint32_t inet::tcp::TcpReceiveQueue::rcv_nxt = 0
protected

◆ reorderBuffer


The documentation for this class was generated from the following files:
inet::ChunkBuffer::replace
void replace(b offset, const Ptr< const Chunk > &chunk)
Replaces the stored data at the provided offset with the data in the chunk.
Definition: ChunkBuffer.cc:115
inet::ReorderBuffer::getExpectedOffset
b getExpectedOffset() const
Returns the offset of the next expected data chunk.
Definition: ReorderBuffer.h:36
inet::tcp::TcpReceiveQueue::str
virtual std::string str() const override
Definition: TcpReceiveQueue.cc:33
inet::ChunkBuffer::getNumRegions
int getNumRegions() const
Returns the number non-overlapping, non-connecting but continuous regions.
Definition: ChunkBuffer.h:94
inet::tcp::seqLess
bool seqLess(uint32_t a, uint32_t b)
Definition: TcpHeader.h:21
inet::tcp::seqLE
bool seqLE(uint32_t a, uint32_t b)
Definition: TcpHeader.h:22
inet::ChunkBuffer::getRegionEndOffset
b getRegionEndOffset(int index) const
Returns the end offset of the given region.
Definition: ChunkBuffer.h:109
inet::tcp::TcpReceiveQueue::rcv_nxt
uint32_t rcv_nxt
Definition: TcpReceiveQueue.h:38
inet::tcp::TcpReceiveQueue::reorderBuffer
ReorderBuffer reorderBuffer
Definition: TcpReceiveQueue.h:39
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::tcp::seqGE
bool seqGE(uint32_t a, uint32_t b)
Definition: TcpHeader.h:24
inet::tcp::TcpReceiveQueue::offsetToSeq
uint32_t offsetToSeq(B offs) const
Definition: TcpReceiveQueue.h:42
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::tcp::seqMax
uint32_t seqMax(uint32_t a, uint32_t b)
Definition: TcpHeader.h:26
inet::ChunkBuffer::getRegionStartOffset
b getRegionStartOffset(int index) const
Returns the start offset of the given region.
Definition: ChunkBuffer.h:104
inet::tcp::TcpReceiveQueue::conn
TcpConnection * conn
Definition: TcpReceiveQueue.h:37
inet::ReorderBuffer::setExpectedOffset
void setExpectedOffset(b expectedOffset)
Changes the offset of the next expected data chunk.
Definition: ReorderBuffer.h:41
inet::tcp::TcpReceiveQueue::seqToOffset
B seqToOffset(uint32_t seq) const
Definition: TcpReceiveQueue.h:44
inet::ReorderBuffer::popAvailableData
const Ptr< const Chunk > popAvailableData(b length=b(-1))
Returns the largest next available data chunk starting at the expected offset.
Definition: ReorderBuffer.cc:20
inet::tcp::TcpReceiveQueue::getAmountOfBufferedBytes
virtual uint32_t getAmountOfBufferedBytes()
Returns the number of bytes (out-of-order-segments) currently buffered in queue.
Definition: TcpReceiveQueue.cc:103
inet::tcp::seqMin
uint32_t seqMin(uint32_t a, uint32_t b)
Definition: TcpHeader.h:25
inet::ChunkBuffer::isEmpty
bool isEmpty() const
Returns true if the buffer is completely empty.
Definition: ChunkBuffer.h:89
inet::ChunkBuffer::getRegionLength
b getRegionLength(int index) const
Returns the length of the given region.
Definition: ChunkBuffer.h:99
inet::ChunkBuffer::clear
void clear(b offset, b length)
Erases the stored data at the provided offset and length.
Definition: ChunkBuffer.cc:149