INET Framework for OMNeT++/OMNEST
|
#include <SCTPQueue.h>
Public Types | |
typedef std::map< uint32, SCTPDataVariables * > | PayloadQueue |
Public Member Functions | |
SCTPQueue () | |
~SCTPQueue () | |
bool | checkAndInsertChunk (const uint32 key, SCTPDataVariables *chunk) |
SCTPDataVariables * | getAndExtractChunk (const uint32 tsn) |
SCTPDataVariables * | extractMessage () |
void | printQueue () const |
uint32 | getQueueSize () const |
SCTPDataVariables * | getFirstChunk () const |
cMessage * | getMsg (const uint32 key) const |
SCTPDataVariables * | getChunk (const uint32 key) const |
SCTPDataVariables * | getChunkFast (const uint32 tsn, bool &firstTime) |
void | removeMsg (const uint32 key) |
bool | deleteMsg (const uint32 tsn) |
int32 | getNumBytes () const |
SCTPDataVariables * | dequeueChunkBySSN (const uint16 ssn) |
Public Attributes | |
PayloadQueue | payloadQueue |
Protected Attributes | |
SCTPAssociation * | assoc |
Private Attributes | |
PayloadQueue::iterator | GetChunkFastIterator |
Abstract base class for SCTP receive queues. This class represents data received by SCTP but not yet passed up to the application. The class also accomodates for selective retransmission, i.e. also acts as a segment buffer.
This class goes hand-in-hand with SCTPSendQueue.
This class is polymorphic because depending on where and how you use the SCTP model you might have different ideas about "sending data" on a simulated connection: you might want to transmit real bytes, "dummy" (byte count only), cMessage objects, etc; see discussion at SCTPSendQueue. Different subclasses can be written to accomodate different needs.
typedef std::map<uint32, SCTPDataVariables*> SCTPQueue::PayloadQueue |
SCTPQueue::SCTPQueue | ( | ) |
Constructor.
{ assoc = NULL; }
SCTPQueue::~SCTPQueue | ( | ) |
Virtual destructor.
{ for (PayloadQueue::iterator iterator = payloadQueue.begin(); iterator != payloadQueue.end(); iterator++) { SCTPDataVariables* chunk = iterator->second; delete chunk->userData; } if (!payloadQueue.empty()) { payloadQueue.clear(); } }
bool SCTPQueue::checkAndInsertChunk | ( | const uint32 | key, |
SCTPDataVariables * | chunk | ||
) |
Referenced by SCTPReceiveStream::enqueueNewDataChunk(), SCTPAssociation::handleChunkReportedAsMissing(), SCTPAssociation::moveChunkToOtherPath(), SCTPAssociation::putInDeliveryQ(), SCTPAssociation::sendOnPath(), and SCTPAssociation::tsnWasReneged().
{ PayloadQueue::iterator found = payloadQueue.find(key); if (found != payloadQueue.end()) { return false; } payloadQueue[key] = chunk; return true; }
bool SCTPQueue::deleteMsg | ( | const uint32 | tsn | ) |
Referenced by SCTPAssociation::makeRoomForTsn().
{ PayloadQueue::iterator iterator = payloadQueue.find(tsn); if (iterator != payloadQueue.end()) { SCTPDataVariables* chunk = iterator->second; cMessage* msg = check_and_cast<cMessage*>(chunk->userData); delete msg; payloadQueue.erase(iterator); return true; } return false; }
SCTPDataVariables * SCTPQueue::dequeueChunkBySSN | ( | const uint16 | ssn | ) |
Referenced by SCTPReceiveStream::enqueueNewDataChunk().
{ for (PayloadQueue::iterator iterator = payloadQueue.begin(); iterator != payloadQueue.end(); iterator++) { SCTPDataVariables* chunk = iterator->second; if ((iterator->second->ssn == ssn) && (iterator->second->bbit) && (iterator->second->ebit) ) { payloadQueue.erase(iterator); return chunk; } } return NULL; }
SCTPDataVariables * SCTPQueue::extractMessage | ( | ) |
Referenced by SCTPAssociation::pushUlp().
{ if (!payloadQueue.empty()) { PayloadQueue::iterator iterator = payloadQueue.begin(); SCTPDataVariables* chunk = iterator->second; payloadQueue.erase(iterator); return chunk; } return NULL; }
SCTPDataVariables * SCTPQueue::getAndExtractChunk | ( | const uint32 | tsn | ) |
Referenced by SCTPAssociation::dequeueAckedChunks(), SCTPReceiveStream::enqueueNewDataChunk(), and SCTPReceiveStream::reassemble().
{ if (!payloadQueue.empty()) { PayloadQueue::iterator iterator = payloadQueue.find(tsn); SCTPDataVariables* chunk = iterator->second; payloadQueue.erase(iterator); return chunk; } return NULL; }
SCTPDataVariables * SCTPQueue::getChunk | ( | const uint32 | key | ) | const |
Referenced by SCTPAssociation::dequeueAckedChunks(), SCTPReceiveStream::enqueueNewDataChunk(), SCTPAssociation::handleChunkReportedAsAcked(), SCTPAssociation::handleChunkReportedAsMissing(), SCTPAssociation::makeRoomForTsn(), SCTPAssociation::processSackArrived(), and SCTPReceiveStream::reassemble().
{ PayloadQueue::const_iterator iterator = payloadQueue.find(tsn); if (iterator != payloadQueue.end()) { SCTPDataVariables* chunk = iterator->second; return chunk; } return NULL; }
SCTPDataVariables * SCTPQueue::getChunkFast | ( | const uint32 | tsn, |
bool & | firstTime | ||
) |
Referenced by SCTPAssociation::processSackArrived().
{ if(!firstTime) { if(GetChunkFastIterator != payloadQueue.end()) { SCTPDataVariables* chunk = GetChunkFastIterator->second; if(chunk->tsn == tsn) { GetChunkFastIterator++; return(chunk); // Found the right TSN! } } // TSN not found -> needs regular TSN lookup. } GetChunkFastIterator = payloadQueue.find(tsn); if(GetChunkFastIterator != payloadQueue.end()) { SCTPDataVariables* chunk = GetChunkFastIterator->second; GetChunkFastIterator++; firstTime = false; return(chunk); } return(NULL); }
SCTPDataVariables * SCTPQueue::getFirstChunk | ( | ) | const |
{ PayloadQueue::const_iterator iterator = payloadQueue.begin(); SCTPDataVariables* chunk = iterator->second; return chunk; }
cMessage * SCTPQueue::getMsg | ( | const uint32 | key | ) | const |
{ PayloadQueue::const_iterator iterator = payloadQueue.find(tsn); if (iterator != payloadQueue.end()) { SCTPDataVariables* chunk = iterator->second; cMessage* msg = check_and_cast<cMessage*>(chunk->userData); return msg; } return NULL; }
int32 SCTPQueue::getNumBytes | ( | ) | const |
{ int32 qb = 0; for (PayloadQueue::const_iterator iterator = payloadQueue.begin(); iterator != payloadQueue.end(); iterator++) { qb += (iterator->second->len / 8); } return qb; }
uint32 SCTPQueue::getQueueSize | ( | ) | const |
void SCTPQueue::printQueue | ( | ) | const |
{ sctpEV3 << "Queue contents:\n"; for (PayloadQueue::const_iterator iterator = payloadQueue.begin(); iterator != payloadQueue.end(); ++iterator) { const uint32 key = iterator->first; const SCTPDataVariables* chunk = iterator->second; sctpEV3 << key << ":\t" << "lastDestination=" << chunk->getLastDestination() << " nextDestination=" << chunk->getNextDestination() << " hasBeenAcked=" << chunk->hasBeenAcked << " countsAsOutstanding=" << chunk->countsAsOutstanding << " numberOfRetransmissions=" << chunk->numberOfRetransmissions << endl; } sctpEV3 << endl; }
void SCTPQueue::removeMsg | ( | const uint32 | key | ) |
Referenced by SCTPAssociation::dequeueAckedChunks(), and SCTPAssociation::handleChunkReportedAsAcked().
{ PayloadQueue::iterator iterator = payloadQueue.find(tsn); payloadQueue.erase(iterator); }
SCTPAssociation* SCTPQueue::assoc [protected] |
Referenced by SCTPQueue().
PayloadQueue::iterator SCTPQueue::GetChunkFastIterator [private] |
Referenced by getChunkFast().
Referenced by checkAndInsertChunk(), SCTPAssociation::cwndUpdateAfterSack(), deleteMsg(), SCTPAssociation::dequeueAckedChunks(), dequeueChunkBySSN(), extractMessage(), getAndExtractChunk(), getChunk(), getChunkFast(), getFirstChunk(), getMsg(), getNumBytes(), SCTPAssociation::getOutboundDataChunk(), getQueueSize(), SCTPAssociation::handleChunkReportedAsMissing(), SCTPAssociation::loadPacket(), SCTPAssociation::peekAbandonedChunk(), printQueue(), SCTPAssociation::process_TIMEOUT_RTX(), SCTPAssociation::processSackArrived(), SCTPAssociation::pushUlp(), SCTP::removeAssociation(), removeMsg(), SCTPAssociation::storePacket(), SCTPAssociation::tsnWasReneged(), and ~SCTPQueue().