[BUG 2150] Added a fixed number of retransmission attempts
This commit is contained in:
@@ -119,7 +119,7 @@ NscTcpSocketImpl::NscTcpSocketImpl(const NscTcpSocketImpl& sock)
|
||||
m_initialSsThresh (sock.m_initialSsThresh),
|
||||
m_lastMeasuredRtt (Seconds (0.0)),
|
||||
m_cnTimeout (sock.m_cnTimeout),
|
||||
m_cnCount (sock.m_cnCount),
|
||||
m_synRetries (sock.m_synRetries),
|
||||
m_rxAvailable (0),
|
||||
m_nscTcpSocket (0),
|
||||
m_sndBufSize (sock.m_sndBufSize)
|
||||
@@ -778,15 +778,15 @@ NscTcpSocketImpl::GetConnTimeout (void) const
|
||||
}
|
||||
|
||||
void
|
||||
NscTcpSocketImpl::SetConnCount (uint32_t count)
|
||||
NscTcpSocketImpl::SetSynRetries (uint32_t count)
|
||||
{
|
||||
m_cnCount = count;
|
||||
m_synRetries = count;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NscTcpSocketImpl::GetConnCount (void) const
|
||||
NscTcpSocketImpl::GetSynRetries (void) const
|
||||
{
|
||||
return m_cnCount;
|
||||
return m_synRetries;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -795,6 +795,20 @@ NscTcpSocketImpl::SetDelAckTimeout (Time timeout)
|
||||
m_delAckTimeout = timeout;
|
||||
}
|
||||
|
||||
void
|
||||
NscTcpSocketImpl::SetDataRetries (uint32_t retries)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << retries);
|
||||
m_dataRetries = retries;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NscTcpSocketImpl::GetDataRetries (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_dataRetries;
|
||||
}
|
||||
|
||||
Time
|
||||
NscTcpSocketImpl::GetDelAckTimeout (void) const
|
||||
{
|
||||
|
||||
@@ -193,8 +193,10 @@ private:
|
||||
virtual uint32_t GetInitialCwnd (void) const;
|
||||
virtual void SetConnTimeout (Time timeout);
|
||||
virtual Time GetConnTimeout (void) const;
|
||||
virtual void SetConnCount (uint32_t count);
|
||||
virtual uint32_t GetConnCount (void) const;
|
||||
virtual uint32_t GetSynRetries (void) const;
|
||||
virtual void SetSynRetries (uint32_t count);
|
||||
virtual void SetDataRetries (uint32_t retries);
|
||||
virtual uint32_t GetDataRetries (void) const;
|
||||
virtual void SetDelAckTimeout (Time timeout);
|
||||
virtual Time GetDelAckTimeout (void) const;
|
||||
virtual void SetDelAckMaxCount (uint32_t count);
|
||||
@@ -250,7 +252,8 @@ private:
|
||||
|
||||
// Timer-related members
|
||||
Time m_cnTimeout; //!< Timeout for connection retry
|
||||
uint32_t m_cnCount; //!< Count of remaining connection retries
|
||||
uint32_t m_synRetries; //!< Count of remaining connection retries
|
||||
uint32_t m_dataRetries; //!< Count of remaining data retransmission attempts
|
||||
Time m_persistTimeout; //!< Time between sending 1-byte probes
|
||||
|
||||
// Temporary queue for delivering data to application
|
||||
|
||||
@@ -296,7 +296,7 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
|
||||
m_delAckCount (0),
|
||||
m_delAckMaxCount (sock.m_delAckMaxCount),
|
||||
m_noDelay (sock.m_noDelay),
|
||||
m_cnRetries (sock.m_cnRetries),
|
||||
m_synRetries (sock.m_synRetries),
|
||||
m_delAckTimeout (sock.m_delAckTimeout),
|
||||
m_persistTimeout (sock.m_persistTimeout),
|
||||
m_cnTimeout (sock.m_cnTimeout),
|
||||
@@ -657,7 +657,8 @@ TcpSocketBase::Connect (const Address & address)
|
||||
|
||||
// Re-initialize parameters in case this socket is being reused after CLOSE
|
||||
m_rtt->Reset ();
|
||||
m_cnCount = m_cnRetries;
|
||||
m_synCount = m_synRetries;
|
||||
m_dataRetrCount = m_dataRetries;
|
||||
|
||||
// DoConnect() will do state-checking and send a SYN packet
|
||||
return DoConnect ();
|
||||
@@ -1514,6 +1515,9 @@ TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
||||
" ssTh: " << m_tcb->m_ssThresh);
|
||||
}
|
||||
|
||||
// Reset the data retransmission count. We got a new ACK!
|
||||
m_dataRetrCount = m_dataRetries;
|
||||
|
||||
if (m_isFirstPartialAck == false)
|
||||
{
|
||||
NS_ASSERT (m_tcb->m_ackState == TcpSocketState::RECOVERY);
|
||||
@@ -1528,7 +1532,6 @@ TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
||||
&TcpSocketBase::SendPendingData,
|
||||
this, m_connected);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If there is any data piggybacked, store it into m_rxBuffer
|
||||
@@ -1594,7 +1597,7 @@ TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader)
|
||||
{ // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
|
||||
NS_LOG_DEBUG ("SYN_SENT -> SYN_RCVD");
|
||||
m_state = SYN_RCVD;
|
||||
m_cnCount = m_cnRetries;
|
||||
m_synCount = m_synRetries;
|
||||
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
|
||||
SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
|
||||
}
|
||||
@@ -2046,7 +2049,7 @@ TcpSocketBase::SendEmptyPacket (uint8_t flags)
|
||||
bool isAck = flags == TcpHeader::ACK;
|
||||
if (hasSyn)
|
||||
{
|
||||
if (m_cnCount == 0)
|
||||
if (m_synCount == 0)
|
||||
{ // No more connection retries, give up
|
||||
NS_LOG_LOGIC ("Connection failed.");
|
||||
m_rtt->Reset (); //According to recommendation -> RFC 6298
|
||||
@@ -2055,9 +2058,9 @@ TcpSocketBase::SendEmptyPacket (uint8_t flags)
|
||||
}
|
||||
else
|
||||
{ // Exponential backoff of connection time out
|
||||
int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
|
||||
int backoffCount = 0x1 << (m_synRetries - m_synCount);
|
||||
m_rto = m_cnTimeout * backoffCount;
|
||||
m_cnCount--;
|
||||
m_synCount--;
|
||||
}
|
||||
}
|
||||
if (m_endPoint != 0)
|
||||
@@ -2209,7 +2212,8 @@ TcpSocketBase::CompleteFork (Ptr<Packet> p, const TcpHeader& h,
|
||||
// Change the cloned socket from LISTEN state to SYN_RCVD
|
||||
NS_LOG_DEBUG ("LISTEN -> SYN_RCVD");
|
||||
m_state = SYN_RCVD;
|
||||
m_cnCount = m_cnRetries;
|
||||
m_synCount = m_synRetries;
|
||||
m_dataRetrCount = m_dataRetries;
|
||||
SetupCallback ();
|
||||
// Set the sequence number and send SYN+ACK
|
||||
m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
|
||||
@@ -2799,7 +2803,7 @@ TcpSocketBase::DoRetransmit ()
|
||||
// Retransmit SYN packet
|
||||
if (m_state == SYN_SENT)
|
||||
{
|
||||
if (m_cnCount > 0)
|
||||
if (m_synCount > 0)
|
||||
{
|
||||
SendEmptyPacket (TcpHeader::SYN);
|
||||
}
|
||||
@@ -2809,6 +2813,19 @@ TcpSocketBase::DoRetransmit ()
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_dataRetrCount == 0)
|
||||
{
|
||||
NS_LOG_INFO ("No more data retries available. Dropping connection");
|
||||
NotifyErrorClose ();
|
||||
DeallocateEndPoint ();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
--m_dataRetrCount;
|
||||
}
|
||||
|
||||
// Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
|
||||
if (m_txBuffer->Size () == 0)
|
||||
{
|
||||
@@ -2908,16 +2925,30 @@ TcpSocketBase::GetConnTimeout (void) const
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketBase::SetConnCount (uint32_t count)
|
||||
TcpSocketBase::SetSynRetries (uint32_t count)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << count);
|
||||
m_cnRetries = count;
|
||||
m_synRetries = count;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TcpSocketBase::GetConnCount (void) const
|
||||
TcpSocketBase::GetSynRetries (void) const
|
||||
{
|
||||
return m_cnRetries;
|
||||
return m_synRetries;
|
||||
}
|
||||
|
||||
void
|
||||
TcpSocketBase::SetDataRetries (uint32_t retries)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << retries);
|
||||
m_dataRetries = retries;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TcpSocketBase::GetDataRetries (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_dataRetries;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -406,8 +406,10 @@ protected:
|
||||
virtual uint32_t GetInitialCwnd (void) const;
|
||||
virtual void SetConnTimeout (Time timeout);
|
||||
virtual Time GetConnTimeout (void) const;
|
||||
virtual void SetConnCount (uint32_t count);
|
||||
virtual uint32_t GetConnCount (void) const;
|
||||
virtual void SetSynRetries (uint32_t count);
|
||||
virtual uint32_t GetSynRetries (void) const;
|
||||
virtual void SetDataRetries (uint32_t retries);
|
||||
virtual uint32_t GetDataRetries (void) const;
|
||||
virtual void SetDelAckTimeout (Time timeout);
|
||||
virtual Time GetDelAckTimeout (void) const;
|
||||
virtual void SetDelAckMaxCount (uint32_t count);
|
||||
@@ -911,8 +913,10 @@ protected:
|
||||
uint32_t m_delAckCount; //!< Delayed ACK counter
|
||||
uint32_t m_delAckMaxCount; //!< Number of packet to fire an ACK before delay timeout
|
||||
bool m_noDelay; //!< Set to true to disable Nagle's algorithm
|
||||
uint32_t m_cnCount; //!< Count of remaining connection retries
|
||||
uint32_t m_cnRetries; //!< Number of connection retries before giving up
|
||||
uint32_t m_synCount; //!< Count of remaining connection retries
|
||||
uint32_t m_synRetries; //!< Number of connection attempts
|
||||
uint32_t m_dataRetrCount; //!< Count of remaining data retransmission attempts
|
||||
uint32_t m_dataRetries; //!< Number of data retransmission attempts
|
||||
TracedValue<Time> m_rto; //!< Retransmit timeout
|
||||
Time m_minRto; //!< minimum value of the Retransmit timeout
|
||||
Time m_clockGranularity; //!< Clock Granularity used in RTO calcs
|
||||
|
||||
@@ -82,10 +82,17 @@ TcpSocket::GetTypeId (void)
|
||||
&TcpSocket::SetConnTimeout),
|
||||
MakeTimeChecker ())
|
||||
.AddAttribute ("ConnCount",
|
||||
"Number of connection attempts (SYN retransmissions) before returning failure",
|
||||
"Number of connection attempts (SYN retransmissions) before "
|
||||
"returning failure",
|
||||
UintegerValue (6),
|
||||
MakeUintegerAccessor (&TcpSocket::GetConnCount,
|
||||
&TcpSocket::SetConnCount),
|
||||
MakeUintegerAccessor (&TcpSocket::GetSynRetries,
|
||||
&TcpSocket::SetSynRetries),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("DataRetries",
|
||||
"Number of data retransmission attempts",
|
||||
UintegerValue (6),
|
||||
MakeUintegerAccessor (&TcpSocket::GetDataRetries,
|
||||
&TcpSocket::SetDataRetries),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("DelAckTimeout",
|
||||
"Timeout value for TCP delayed acks, in seconds",
|
||||
|
||||
@@ -171,13 +171,25 @@ private:
|
||||
* \brief Set the number of connection retries before giving up.
|
||||
* \param count the number of connection retries
|
||||
*/
|
||||
virtual void SetConnCount (uint32_t count) = 0;
|
||||
virtual void SetSynRetries (uint32_t count) = 0;
|
||||
|
||||
/**
|
||||
* \brief Get the number of connection retries before giving up.
|
||||
* \returns the number of connection retries
|
||||
*/
|
||||
virtual uint32_t GetConnCount (void) const = 0;
|
||||
virtual uint32_t GetSynRetries (void) const = 0;
|
||||
|
||||
/**
|
||||
* \brief Set the number of data transmission retries before giving up.
|
||||
* \param count the number of data transmission retries
|
||||
*/
|
||||
virtual void SetDataRetries (uint32_t retries) = 0;
|
||||
|
||||
/**
|
||||
* \brief Get the number of data transmission retries before giving up.
|
||||
* \returns the number of data transmission retries
|
||||
*/
|
||||
virtual uint32_t GetDataRetries (void) const = 0;
|
||||
|
||||
/**
|
||||
* \brief Set the time to delay an ACK.
|
||||
|
||||
Reference in New Issue
Block a user