diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 1f14f8d68..3829946e0 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -33,6 +33,7 @@ Bugs fixed - Bug 2248 - tcp: TCP SACK added after reviews - Bug 2256 - tcp: bytes in flight now updated in TcpTxBuffer - Bug 2263 - Support processing of multiple TCP options +- Bug 2367 - BlockAckManager does not remove iterators to freed items - Bug 2450 - LogDistancePropagationLossModel is not continuous - Bug 2463 - create trace source to trace the TXOP time that is actually used - Bug 2471 - unable to disable Block Ack agreement for 802.11n diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index 0b53d1451..111b3adeb 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -613,6 +613,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 (*queueIt).hdr.GetFragmentNumber ())) { nSuccessfulMpdus++; + RemoveFromRetryQueue (recipient, tid, (*queueIt).hdr.GetSequenceNumber ()); queueIt = it->second.second.erase (queueIt); } else @@ -636,9 +637,9 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 { for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; ) { - if (blockAck->IsPacketReceived ((*queueIt).hdr.GetSequenceNumber ())) + uint16_t currentSeq = (*queueIt).hdr.GetSequenceNumber (); + if (blockAck->IsPacketReceived (currentSeq)) { - uint16_t currentSeq = (*queueIt).hdr.GetSequenceNumber (); while (queueIt != queueEnd && (*queueIt).hdr.GetSequenceNumber () == currentSeq) { @@ -647,6 +648,7 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 { m_txOkCallback ((*queueIt).hdr); } + RemoveFromRetryQueue (recipient, tid, currentSeq); queueIt = it->second.second.erase (queueIt); } } @@ -871,6 +873,26 @@ bool BlockAckManager::NeedBarRetransmission (uint8_t tid, uint16_t seqNumber, Ma } } +void +BlockAckManager::RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16_t seq) +{ + /* remove retry packet iterator if it's present in retry queue */ + std::list::iterator it = m_retryPackets.begin (); + while (it != m_retryPackets.end ()) + { + if ((*it)->hdr.GetAddr1 () == address + && (*it)->hdr.GetQosTid () == tid + && (*it)->hdr.GetSequenceNumber () == seq) + { + it = m_retryPackets.erase (it); + } + else + { + it++; + } + } +} + void BlockAckManager::CleanupBuffers (void) { @@ -892,20 +914,9 @@ BlockAckManager::CleanupBuffers (void) } else { - /* remove retry packet iterator if it's present in retry queue */ - for (std::list::iterator it = m_retryPackets.begin (); it != m_retryPackets.end (); ) - { - if ((*it)->hdr.GetAddr1 () == j->second.first.GetPeer () - && (*it)->hdr.GetQosTid () == j->second.first.GetTid () - && (*it)->hdr.GetSequenceNumber () == i->hdr.GetSequenceNumber ()) - { - it = m_retryPackets.erase (it); - } - else - { - it++; - } - } + RemoveFromRetryQueue (j->second.first.GetPeer (), + j->second.first.GetTid (), + i->hdr.GetSequenceNumber ()); } } j->second.second.erase (j->second.second.begin (), end); diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 80f2392c7..69a94503a 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -478,6 +478,16 @@ private: */ void InsertInRetryQueue (PacketQueueI item); + /** + * Remove items from retransmission queue. + * This method should be called when packets are acknowledged. + * + * \param address recipient mac address of the packet to be removed + * \param tid Traffic ID of the packet to be removed + * \param seq sequence number of the packet to be removed + */ + void RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16_t seq); + /** * This data structure contains, for each block ack agreement (recipient, tid), a set of packets * for which an ack by block ack is requested.