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

TcpLwip send queue. More...

#include <TcpLwipQueues.h>

Inheritance diagram for inet::tcp::TcpLwipSendQueue:

Public Member Functions

 TcpLwipSendQueue ()
 
virtual ~TcpLwipSendQueue ()
 
virtual void setConnection (TcpLwipConnection *connP)
 set connection queue, and initialise queue variables. More...
 
virtual void enqueueAppData (Packet *msgP)
 Called on SEND app command, it inserts in the queue the data the user wants to send. More...
 
virtual unsigned int getBytesForTcpLayer (void *bufferP, unsigned int bufferLengthP) const
 Copy data to the buffer for send to LWIP. More...
 
virtual void dequeueTcpLayerMsg (unsigned int msgLengthP)
 This function should remove msgLengthP bytes from TCP layer queue. More...
 
virtual unsigned long getBytesAvailable () const
 Utility function: returns how many bytes are available in the queue. More...
 
virtual PacketcreateSegmentWithBytes (const void *tcpDataP, unsigned int tcpLengthP)
 Called when the TCP wants to send or retransmit data, it constructs a TCP segment which contains the data from the requested sequence number range. More...
 
virtual void discardAckedBytes (unsigned long bytesP)
 

Protected Attributes

TcpLwipConnectionconnM = nullptr
 
ChunkQueue dataBuffer
 

Detailed Description

TcpLwip send queue.

In fact a single object represents both the send queue and the retransmission queue (no need to separate them). The TcpConnection object knows which data in the queue have already been transmitted ("retransmission queue") and which not ("send queue"). This class is not interested in where's the boundary.

There is another particularity about this class: as a retransmission queue, it stores bytes and not segments. TCP is a bytestream oriented protocol (sequence numbers refer to bytes and not to TPDUs as e.g. in ISO TP4), and the protocol doesn't rely on retransmitted segments having the same segment boundaries as the original segments. Some implementations store segments on the retransmission queue, and others store only the data bytes; RFCs explicitly allow both. (See e.g. RFC1122 p90, section 4.2.2.15, "IMPLEMENTATION" note).

To simulate a TCP that retains segment boundaries in retransmissions, the appropriate TcpAlgorithm class should remember where the segment boundaries were at the original transmission, and it should form identical segments when retransmitting. The createSegmentWithBytes() send queue method makes this possible.

This class is polymorphic because depending on where and how you use the TCP model you might have different ideas about "sending data" on a simulated connection.

You might want to:

  • transmit a real bytes, especially if the application which uses TCP is a ported version of a real socket application.
  • simulate a "dummy" connection, that is, simulated TCP segments contain do not contain any real data, only the number of bytes they represent. You'll want to do this when the app is there solely as a traffic generator (e.g. simulated file transfer or telnet session), but actual data is unimportant.
  • transmit a sequence of cMessage objects, and you want exactly the same cMessage sequence to be reproduced on the receiver side. Here every cMessage maps to a sequence number range in the TCP stream, and the object is passed up to the application on the receiving side when its last byte has arrived on the simulated connection.

Different TcpLwipSendQueue subclasses can be written to accomodate different needs.

This class goes hand-in-hand with TcpLwipReceiveQueue.

See also
TcpLwipReceiveQueue

Constructor & Destructor Documentation

◆ TcpLwipSendQueue()

inet::tcp::TcpLwipSendQueue::TcpLwipSendQueue ( )
24 {
25 }

◆ ~TcpLwipSendQueue()

inet::tcp::TcpLwipSendQueue::~TcpLwipSendQueue ( )
virtual
28 {
29 }

Member Function Documentation

◆ createSegmentWithBytes()

Packet * inet::tcp::TcpLwipSendQueue::createSegmentWithBytes ( const void *  tcpDataP,
unsigned int  tcpLengthP 
)
virtual

Called when the TCP wants to send or retransmit data, it constructs a TCP segment which contains the data from the requested sequence number range.

The actually returned segment may contain less then maxNumBytes bytes if the subclass wants to reproduce the original segment boundaries when retransmitting.

called from inside of send_callback() called before called the send() to IP layer

69 {
70  ASSERT(tcpDataP);
71 
72  const auto& bytes = makeShared<BytesChunk>((const uint8_t *)tcpDataP, tcpLengthP);
73  auto packet = new Packet(nullptr, bytes);
74  auto tcpHdr = packet->removeAtFront<TcpHeader>();
75  int64_t numBytes = packet->getByteLength();
76  packet->insertAtFront(tcpHdr);
77 
78 // auto payload = makeShared<BytesChunk>((const uint8_t*)tcpDataP, tcpLengthP);
79 // const auto& tcpHdr = payload->Chunk::peek<TcpHeader>(byte(0));
80 // payload->removeFromBeginning(tcpHdr->getChunkLength());
81 
82  char msgname[80];
83  sprintf(msgname, "%.10s%s%s%s(l=%lu bytes)",
84  "tcpHdr",
85  tcpHdr->getSynBit() ? " SYN" : "",
86  tcpHdr->getFinBit() ? " FIN" : "",
87  (tcpHdr->getAckBit() && 0 == numBytes) ? " ACK" : "",
88  (unsigned long)numBytes);
89 
90  return packet;
91 }

Referenced by inet::tcp::TcpLwip::ip_output().

◆ dequeueTcpLayerMsg()

void inet::tcp::TcpLwipSendQueue::dequeueTcpLayerMsg ( unsigned int  msgLengthP)
virtual

This function should remove msgLengthP bytes from TCP layer queue.

59 {
60  dataBuffer.pop(B(msgLengthP));
61 }

Referenced by inet::tcp::TcpLwipConnection::do_SEND().

◆ discardAckedBytes()

void inet::tcp::TcpLwipSendQueue::discardAckedBytes ( unsigned long  bytesP)
virtual
94 {
95  // nothing to do here
96 }

◆ enqueueAppData()

void inet::tcp::TcpLwipSendQueue::enqueueAppData ( Packet msgP)
virtual

Called on SEND app command, it inserts in the queue the data the user wants to send.

Implementations of this abstract class will decide what this means: copying actual bytes, just increasing the "last byte queued" variable, or storing cMessage object(s). The msg object should not be referenced after this point (sendQueue may delete it.)

38 {
39  ASSERT(msg);
40  dataBuffer.push(msg->peekDataAt(B(0), B(msg->getByteLength())));
41  delete msg;
42 }

Referenced by inet::tcp::TcpLwipConnection::send().

◆ getBytesAvailable()

unsigned long inet::tcp::TcpLwipSendQueue::getBytesAvailable ( ) const
virtual

Utility function: returns how many bytes are available in the queue.

64 {
65  return B(dataBuffer.getLength()).get();
66 }

Referenced by inet::tcp::TcpLwipConnection::close(), and inet::tcp::TcpLwipConnection::do_SEND().

◆ getBytesForTcpLayer()

unsigned int inet::tcp::TcpLwipSendQueue::getBytesForTcpLayer ( void *  bufferP,
unsigned int  bufferLengthP 
) const
virtual

Copy data to the buffer for send to LWIP.

returns lengh of copied data. create msg for socket->send_data()

called before called socket->send_data()

45 {
46  ASSERT(bufferP);
47 
48  unsigned int length = B(dataBuffer.getLength()).get();
49  if (bufferLengthP < length)
50  length = bufferLengthP;
51  if (length == 0)
52  return 0;
53 
54  const auto& bytesChunk = dataBuffer.peek<BytesChunk>(B(length));
55  return bytesChunk->copyToBuffer(static_cast<uint8_t *>(bufferP), length);
56 }

Referenced by inet::tcp::TcpLwipConnection::do_SEND().

◆ setConnection()

void inet::tcp::TcpLwipSendQueue::setConnection ( TcpLwipConnection connP)
virtual

set connection queue, and initialise queue variables.

32 {
33  dataBuffer.clear();
34  connM = connP;
35 }

Referenced by inet::tcp::TcpLwipConnection::initConnection().

Member Data Documentation

◆ connM

TcpLwipConnection* inet::tcp::TcpLwipSendQueue::connM = nullptr
protected

Referenced by setConnection().

◆ dataBuffer

ChunkQueue inet::tcp::TcpLwipSendQueue::dataBuffer
protected

The documentation for this class was generated from the following files:
inet::tcp::TcpLwipSendQueue::connM
TcpLwipConnection * connM
Definition: TcpLwipQueues.h:130
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::ChunkQueue::getLength
b getLength() const
Returns the total length of data currently available in the queue.
Definition: ChunkQueue.h:74
inet::ChunkQueue::push
void push(const Ptr< const Chunk > &chunk)
Inserts the provided chunk at the tail of the queue.
Definition: ChunkQueue.cc:85
inet::ChunkQueue::peek
const Ptr< const Chunk > peek(b length=b(-1), int flags=0) const
Returns the designated data from the head of the queue as an immutable chunk in its current represent...
Definition: ChunkQueue.cc:56
inet::tcp::TcpLwipSendQueue::dataBuffer
ChunkQueue dataBuffer
Definition: TcpLwipQueues.h:131
inet::ChunkQueue::clear
void clear()
Erases all data from the queue.
Definition: ChunkQueue.cc:78
inet::ChunkQueue::pop
const Ptr< const Chunk > pop(b length=b(-1), int flags=0)
Pops the designated data and returns it as an immutable chunk in its current representation.
Definition: ChunkQueue.cc:69