|
Lines 1583-1592
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
|---|
|
| 1583 |
ReadOptions (tcpHeader, scoreboardUpdated); |
1583 |
ReadOptions (tcpHeader, scoreboardUpdated); |
| 1584 |
|
1584 |
|
| 1585 |
SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); |
1585 |
SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); |
|
|
1586 |
SequenceNumber32 oldHeadSequence = m_txBuffer->HeadSequence (); |
| 1587 |
m_txBuffer->DiscardUpTo (ackNumber); |
| 1586 |
|
1588 |
|
| 1587 |
// RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation |
1589 |
// RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation |
| 1588 |
// are inside the function ProcessAck |
1590 |
// are inside the function ProcessAck |
| 1589 |
ProcessAck (ackNumber, scoreboardUpdated); |
1591 |
ProcessAck (ackNumber, scoreboardUpdated, oldHeadSequence); |
| 1590 |
|
1592 |
|
| 1591 |
// If there is any data piggybacked, store it into m_rxBuffer |
1593 |
// If there is any data piggybacked, store it into m_rxBuffer |
| 1592 |
if (packet->GetSize () > 0) |
1594 |
if (packet->GetSize () > 0) |
|
Lines 1600-1606
TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
Link Here
|
|---|
|
| 1600 |
} |
1602 |
} |
| 1601 |
|
1603 |
|
| 1602 |
void |
1604 |
void |
| 1603 |
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated) |
1605 |
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated, |
|
|
1606 |
const SequenceNumber32 &oldHeadSequence) |
| 1604 |
{ |
1607 |
{ |
| 1605 |
NS_LOG_FUNCTION (this << ackNumber << scoreboardUpdated); |
1608 |
NS_LOG_FUNCTION (this << ackNumber << scoreboardUpdated); |
| 1606 |
// RFC 6675, Section 5, 2nd paragraph: |
1609 |
// RFC 6675, Section 5, 2nd paragraph: |
|
Lines 1629-1635
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
Link Here
|
|---|
|
| 1629 |
|
1632 |
|
| 1630 |
bool isDupack = m_sackEnabled ? |
1633 |
bool isDupack = m_sackEnabled ? |
| 1631 |
scoreboardUpdated |
1634 |
scoreboardUpdated |
| 1632 |
: ackNumber == m_txBuffer->HeadSequence () && |
1635 |
: ackNumber == oldHeadSequence && |
| 1633 |
ackNumber < m_tcb->m_highTxMark; |
1636 |
ackNumber < m_tcb->m_highTxMark; |
| 1634 |
|
1637 |
|
| 1635 |
// RFC 6675, Section 5, 3rd paragraph: |
1638 |
// RFC 6675, Section 5, 3rd paragraph: |
|
Lines 1639-1645
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
Link Here
|
|---|
|
| 1639 |
if (isDupack) |
1642 |
if (isDupack) |
| 1640 |
{ |
1643 |
{ |
| 1641 |
NS_LOG_DEBUG ("ACK of " << ackNumber << |
1644 |
NS_LOG_DEBUG ("ACK of " << ackNumber << |
| 1642 |
" SND.UNA=" << m_txBuffer->HeadSequence () << |
1645 |
" SND.UNA=" << oldHeadSequence << |
| 1643 |
" SND.NXT=" << m_tcb->m_nextTxSequence << |
1646 |
" SND.NXT=" << m_tcb->m_nextTxSequence << |
| 1644 |
" in state: " << TcpSocketState::TcpCongStateName[m_tcb->m_congState] << |
1647 |
" in state: " << TcpSocketState::TcpCongStateName[m_tcb->m_congState] << |
| 1645 |
" with m_recover: " << m_recover); |
1648 |
" with m_recover: " << m_recover); |
|
Lines 1648-1660
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
Link Here
|
|---|
|
| 1648 |
DupAck (); |
1651 |
DupAck (); |
| 1649 |
} |
1652 |
} |
| 1650 |
|
1653 |
|
| 1651 |
if (ackNumber == m_txBuffer->HeadSequence () |
1654 |
if (ackNumber == oldHeadSequence |
| 1652 |
&& ackNumber == m_tcb->m_highTxMark) |
1655 |
&& ackNumber == m_tcb->m_highTxMark) |
| 1653 |
{ |
1656 |
{ |
| 1654 |
// Dupack, but the ACK is precisely equal to the nextTxSequence |
1657 |
// Dupack, but the ACK is precisely equal to the nextTxSequence |
| 1655 |
return; |
1658 |
return; |
| 1656 |
} |
1659 |
} |
| 1657 |
else if (ackNumber == m_txBuffer->HeadSequence () |
1660 |
else if (ackNumber == oldHeadSequence |
| 1658 |
&& ackNumber > m_tcb->m_highTxMark) |
1661 |
&& ackNumber > m_tcb->m_highTxMark) |
| 1659 |
{ |
1662 |
{ |
| 1660 |
// ACK of the FIN bit ... nextTxSequence is not updated since we |
1663 |
// ACK of the FIN bit ... nextTxSequence is not updated since we |
|
Lines 1662-1677
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
Link Here
|
|---|
|
| 1662 |
NS_LOG_DEBUG ("Update nextTxSequence manually to " << ackNumber); |
1665 |
NS_LOG_DEBUG ("Update nextTxSequence manually to " << ackNumber); |
| 1663 |
m_tcb->m_nextTxSequence = ackNumber; |
1666 |
m_tcb->m_nextTxSequence = ackNumber; |
| 1664 |
} |
1667 |
} |
| 1665 |
else if (ackNumber == m_txBuffer->HeadSequence ()) |
1668 |
else if (ackNumber == oldHeadSequence) |
| 1666 |
{ |
1669 |
{ |
| 1667 |
// DupAck. Artificially call PktsAcked: after all, one segment has been ACKed. |
1670 |
// DupAck. Artificially call PktsAcked: after all, one segment has been ACKed. |
| 1668 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
1671 |
m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt); |
| 1669 |
} |
1672 |
} |
| 1670 |
else if (ackNumber > m_txBuffer->HeadSequence ()) |
1673 |
else if (ackNumber > oldHeadSequence) |
| 1671 |
{ |
1674 |
{ |
| 1672 |
// Please remember that, with SACK, we can enter here even if we |
1675 |
// Please remember that, with SACK, we can enter here even if we |
| 1673 |
// received a dupack. |
1676 |
// received a dupack. |
| 1674 |
uint32_t bytesAcked = ackNumber - m_txBuffer->HeadSequence (); |
1677 |
uint32_t bytesAcked = ackNumber - oldHeadSequence; |
| 1675 |
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
1678 |
uint32_t segsAcked = bytesAcked / m_tcb->m_segmentSize; |
| 1676 |
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
1679 |
m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize; |
| 1677 |
|
1680 |
|
|
Lines 1702-1708
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
|
Link Here
|
|---|
|
| 1702 |
// the CA_RECOVERY phase. Just process this partial ack (RFC 5681) |
1705 |
// the CA_RECOVERY phase. Just process this partial ack (RFC 5681) |
| 1703 |
if (ackNumber < m_recover && m_tcb->m_congState == TcpSocketState::CA_RECOVERY) |
1706 |
if (ackNumber < m_recover && m_tcb->m_congState == TcpSocketState::CA_RECOVERY) |
| 1704 |
{ |
1707 |
{ |
| 1705 |
m_txBuffer->DiscardUpTo (ackNumber); |
|
|
| 1706 |
if (!m_sackEnabled) |
1708 |
if (!m_sackEnabled) |
| 1707 |
{ |
1709 |
{ |
| 1708 |
// Manually set the head as lost, it will be retransmitted. |
1710 |
// Manually set the head as lost, it will be retransmitted. |
|
Lines 3111-3117
TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO)
|
Link Here
|
|---|
|
| 3111 |
// Note the highest ACK and tell app to send more |
3113 |
// Note the highest ACK and tell app to send more |
| 3112 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
3114 |
NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack << |
| 3113 |
" numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed |
3115 |
" numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed |
| 3114 |
m_txBuffer->DiscardUpTo (ack); |
3116 |
|
| 3115 |
if (GetTxAvailable () > 0) |
3117 |
if (GetTxAvailable () > 0) |
| 3116 |
{ |
3118 |
{ |
| 3117 |
NotifySend (GetTxAvailable ()); |
3119 |
NotifySend (GetTxAvailable ()); |