#include <TCPMsgBasedSendQueue.h>
Public Member Functions | |
TCPMsgBasedSendQueue () | |
virtual | ~TCPMsgBasedSendQueue () |
virtual void | init (uint32 startSeq) |
virtual std::string | info () const |
virtual void | enqueueAppData (cPacket *msg) |
virtual uint32 | getBufferEndSeq () |
virtual TCPSegment * | createSegmentWithBytes (uint32 fromSeq, ulong numBytes) |
virtual void | discardUpTo (uint32 seqNum) |
Protected Types | |
typedef std::list< Payload > | PayloadQueue |
Protected Attributes | |
PayloadQueue | payloadQueue |
uint32 | begin |
uint32 | end |
Classes | |
struct | Payload |
typedef std::list<Payload> TCPMsgBasedSendQueue::PayloadQueue [protected] |
TCPMsgBasedSendQueue::TCPMsgBasedSendQueue | ( | ) |
TCPMsgBasedSendQueue::~TCPMsgBasedSendQueue | ( | ) | [virtual] |
Virtual dtor.
00029 { 00030 for (PayloadQueue::iterator it=payloadQueue.begin(); it!=payloadQueue.end(); ++it) 00031 delete it->msg; 00032 }
void TCPMsgBasedSendQueue::init | ( | uint32 | startSeq | ) | [virtual] |
Initialize the object. The startSeq parameter tells what sequence number the first byte of app data should get. This is usually ISS+1 because SYN consumes one byte in the sequence number space.
init() may be called more than once; every call flushes the existing contents of the queue.
Implements TCPSendQueue.
std::string TCPMsgBasedSendQueue::info | ( | ) | const [virtual] |
Returns a string with the region stored.
00041 { 00042 std::stringstream out; 00043 out << "[" << begin << ".." << end << "), " << payloadQueue.size() << " packets"; 00044 return out.str(); 00045 }
void TCPMsgBasedSendQueue::enqueueAppData | ( | cPacket * | msg | ) | [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.)
Implements TCPSendQueue.
00048 { 00049 //tcpEV << "sendQ: " << info() << " enqueueAppData(bytes=" << msg->getByteLength() << ")\n"; 00050 end += msg->getByteLength(); 00051 00052 Payload payload; 00053 payload.endSequenceNo = end; 00054 payload.msg = msg; 00055 payloadQueue.push_back(payload); 00056 }
uint32 TCPMsgBasedSendQueue::getBufferEndSeq | ( | ) | [virtual] |
Returns the sequence number of the last byte stored in the buffer plus one. (The first byte of the next send operation would get this sequence number.)
Implements TCPSendQueue.
00059 { 00060 return end; 00061 }
TCPSegment * TCPMsgBasedSendQueue::createSegmentWithBytes | ( | uint32 | fromSeq, | |
ulong | maxNumBytes | |||
) | [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.
Implements TCPSendQueue.
00064 { 00065 //tcpEV << "sendQ: " << info() << " createSeg(seq=" << fromSeq << " len=" << numBytes << ")\n"; 00066 ASSERT(seqLE(begin,fromSeq) && seqLE(fromSeq+numBytes,end)); 00067 00068 TCPSegment *tcpseg = conn->createTCPSegment(NULL); 00069 tcpseg->setSequenceNo(fromSeq); 00070 tcpseg->setPayloadLength(numBytes); 00071 00072 // add payload messages whose endSequenceNo is between fromSeq and fromSeq+numBytes 00073 PayloadQueue::iterator i = payloadQueue.begin(); 00074 while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, fromSeq)) 00075 ++i; 00076 uint32 toSeq = fromSeq+numBytes; 00077 const char *payloadName = NULL; 00078 while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, toSeq)) 00079 { 00080 if (!payloadName) payloadName = i->msg->getName(); 00081 tcpseg->addPayloadMessage(i->msg->dup(), i->endSequenceNo); 00082 ++i; 00083 } 00084 00085 // give segment a name 00086 char msgname[80]; 00087 if (!payloadName) 00088 sprintf(msgname, "tcpseg(l=%lu,%dmsg)", numBytes, tcpseg->getPayloadArraySize()); 00089 else 00090 sprintf(msgname, "%.10s(l=%lu,%dmsg)", payloadName, numBytes, tcpseg->getPayloadArraySize()); 00091 tcpseg->setName(msgname); 00092 00093 return tcpseg; 00094 }
void TCPMsgBasedSendQueue::discardUpTo | ( | uint32 | seqNum | ) | [virtual] |
Tells the queue that bytes up to (but NOT including) seqNum have been transmitted and ACKed, so they can be removed from the queue.
Implements TCPSendQueue.
00097 { 00098 //tcpEV << "sendQ: " << info() << " discardUpTo(seq=" << seqNum << ")\n"; 00099 ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end)); 00100 begin = seqNum; 00101 00102 // remove payload messages whose endSequenceNo is below seqNum 00103 while (!payloadQueue.empty() && seqLE(payloadQueue.front().endSequenceNo, seqNum)) 00104 { 00105 delete payloadQueue.front().msg; 00106 payloadQueue.pop_front(); 00107 } 00108 }
PayloadQueue TCPMsgBasedSendQueue::payloadQueue [protected] |
Referenced by createSegmentWithBytes(), discardUpTo(), enqueueAppData(), info(), and ~TCPMsgBasedSendQueue().
uint32 TCPMsgBasedSendQueue::begin [protected] |
Referenced by createSegmentWithBytes(), discardUpTo(), info(), init(), and TCPMsgBasedSendQueue().
uint32 TCPMsgBasedSendQueue::end [protected] |
Referenced by createSegmentWithBytes(), discardUpTo(), enqueueAppData(), getBufferEndSeq(), info(), init(), and TCPMsgBasedSendQueue().