[BUG 2150] Added a fixed number of retransmission attempts

This commit is contained in:
Natale Patriciello
2015-10-16 10:43:03 -07:00
parent df353911fb
commit 519f422b72
6 changed files with 101 additions and 30 deletions

View File

@@ -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
{

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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",

View File

@@ -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.