[BUG 2068] Timestamp option conforms to RFC 7323
This commit is contained in:
@@ -57,6 +57,7 @@ Bugs fixed
|
||||
- Bug 1999 - PointToPointRemoteChannel invokes PointToPointChannel constructor
|
||||
- Bug 2003 - Missing DSSS short PLCP preamble
|
||||
- Bug 2041 - TCP RTO needs unit tests
|
||||
- Bug 2068 - Timestamp option conforms to RFC 7323
|
||||
- Bug 2141 - TCP DataSent callback now correctly notifies sent data, without missing bytes in particular conditions
|
||||
- Bug 2150 - The TCP sender keeps retransmitting and does not terminate the connection after some retries.
|
||||
- Bug 2159 - TCP advertises wrong receive window
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -283,6 +283,7 @@ TcpSocketBase::TcpSocketBase (void)
|
||||
m_maxWinSize (0),
|
||||
m_rWnd (0),
|
||||
m_highRxMark (0),
|
||||
m_highTxAck (0),
|
||||
m_highRxAckMark (0),
|
||||
m_bytesAckedNotProcessed (0),
|
||||
m_winScalingEnabled (false),
|
||||
@@ -1175,11 +1176,42 @@ TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress,
|
||||
*/
|
||||
m_rWnd = tcpHeader.GetWindowSize ();
|
||||
|
||||
// When receiving a <SYN> or <SYN-ACK> we should adapt TS to the other end
|
||||
if (tcpHeader.HasOption (TcpOption::TS) && m_timestampEnabled)
|
||||
{
|
||||
ProcessOptionTimestamp (tcpHeader.GetOption (TcpOption::TS),
|
||||
tcpHeader.GetSequenceNumber ());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_timestampEnabled = false;
|
||||
}
|
||||
|
||||
// Initialize cWnd and ssThresh
|
||||
m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize ();
|
||||
m_tcb->m_ssThresh = GetInitialSSThresh ();
|
||||
}
|
||||
else if (tcpHeader.GetFlags () & TcpHeader::ACK)
|
||||
{
|
||||
NS_ASSERT (!(tcpHeader.GetFlags () & TcpHeader::SYN));
|
||||
if (m_timestampEnabled)
|
||||
{
|
||||
if (!tcpHeader.HasOption (TcpOption::TS))
|
||||
{
|
||||
// Ignoring segment without TS, RFC 7323
|
||||
NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
|
||||
" received packet of seq [" << seq <<
|
||||
":" << seq + packet->GetSize () <<
|
||||
") without TS option. Silently discard it");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessOptionTimestamp (tcpHeader.GetOption (TcpOption::TS),
|
||||
tcpHeader.GetSequenceNumber ());
|
||||
}
|
||||
}
|
||||
|
||||
EstimateRtt (tcpHeader);
|
||||
UpdateWindowSize (tcpHeader);
|
||||
}
|
||||
@@ -2121,6 +2153,10 @@ TcpSocketBase::SendEmptyPacket (uint8_t flags)
|
||||
{ // If sending an ACK, cancel the delay ACK as well
|
||||
m_delAckEvent.Cancel ();
|
||||
m_delAckCount = 0;
|
||||
if (m_highTxAck < header.GetAckNumber ())
|
||||
{
|
||||
m_highTxAck = header.GetAckNumber ();
|
||||
}
|
||||
}
|
||||
if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
|
||||
{ // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
|
||||
@@ -3086,15 +3122,6 @@ TcpSocketBase::ReadOptions (const TcpHeader& header)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool timestampAttribute = m_timestampEnabled;
|
||||
m_timestampEnabled = false;
|
||||
|
||||
if (header.HasOption (TcpOption::TS) && timestampAttribute)
|
||||
{
|
||||
m_timestampEnabled = true;
|
||||
ProcessOptionTimestamp (header.GetOption (TcpOption::TS));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3180,12 +3207,17 @@ TcpSocketBase::AddOptionWScale (TcpHeader &header)
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketBase::ProcessOptionTimestamp (const Ptr<const TcpOption> option)
|
||||
TcpSocketBase::ProcessOptionTimestamp (const Ptr<const TcpOption> option,
|
||||
const SequenceNumber32 &seq)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << option);
|
||||
|
||||
Ptr<const TcpOptionTS> ts = DynamicCast<const TcpOptionTS> (option);
|
||||
m_timestampToEcho = ts->GetTimestamp ();
|
||||
|
||||
if (seq == m_rxBuffer->NextRxSequence () && seq <= m_highTxAck)
|
||||
{
|
||||
m_timestampToEcho = ts->GetTimestamp ();
|
||||
}
|
||||
|
||||
NS_LOG_INFO (m_node->GetId () << " Got timestamp=" <<
|
||||
m_timestampToEcho << " and Echo=" << ts->GetEcho ());
|
||||
|
||||
@@ -882,9 +882,11 @@ protected:
|
||||
* to utilize later to calculate RTT.
|
||||
*
|
||||
* \see EstimateRtt
|
||||
* \param option Option from the packet
|
||||
* \param option Option from the segment
|
||||
* \param seq Sequence number of the segment
|
||||
*/
|
||||
void ProcessOptionTimestamp (const Ptr<const TcpOption> option);
|
||||
void ProcessOptionTimestamp (const Ptr<const TcpOption> option,
|
||||
const SequenceNumber32 &seq);
|
||||
/**
|
||||
* \brief Add the timestamp option to the header
|
||||
*
|
||||
@@ -949,6 +951,7 @@ protected:
|
||||
uint16_t m_maxWinSize; //!< Maximum window size to advertise
|
||||
TracedValue<uint32_t> m_rWnd; //!< Receiver window (RCV.WND in RFC793)
|
||||
TracedValue<SequenceNumber32> m_highRxMark; //!< Highest seqno received
|
||||
SequenceNumber32 m_highTxAck; //!< Highest ack sent
|
||||
TracedValue<SequenceNumber32> m_highRxAckMark; //!< Highest ack received
|
||||
uint32_t m_bytesAckedNotProcessed; //!< Bytes acked, but not processed
|
||||
|
||||
|
||||
Reference in New Issue
Block a user