diff --git a/src/internet/model/nsc-tcp-socket-impl.cc b/src/internet/model/nsc-tcp-socket-impl.cc index 5f650bdc5..69a816917 100644 --- a/src/internet/model/nsc-tcp-socket-impl.cc +++ b/src/internet/model/nsc-tcp-socket-impl.cc @@ -85,6 +85,7 @@ NscTcpSocketImpl::NscTcpSocketImpl(const NscTcpSocketImpl& sock) : TcpSocket (sock), //copy the base class callbacks m_delAckMaxCount (sock.m_delAckMaxCount), m_delAckTimeout (sock.m_delAckTimeout), + m_noDelay (sock.m_noDelay), m_endPoint (0), m_node (sock.m_node), m_tcp (sock.m_tcp), @@ -797,6 +798,18 @@ NscTcpSocketImpl::GetDelAckMaxCount (void) const return m_delAckMaxCount; } +void +NscTcpSocketImpl::SetTcpNoDelay (bool noDelay) +{ + m_noDelay = noDelay; +} + +bool +NscTcpSocketImpl::GetTcpNoDelay (void) const +{ + return m_noDelay; +} + void NscTcpSocketImpl::SetPersistTimeout (Time timeout) { diff --git a/src/internet/model/nsc-tcp-socket-impl.h b/src/internet/model/nsc-tcp-socket-impl.h index 7d645ed37..69757d69b 100644 --- a/src/internet/model/nsc-tcp-socket-impl.h +++ b/src/internet/model/nsc-tcp-socket-impl.h @@ -125,12 +125,15 @@ private: virtual Time GetDelAckTimeout (void) const; virtual void SetDelAckMaxCount (uint32_t count); virtual uint32_t GetDelAckMaxCount (void) const; + virtual void SetTcpNoDelay (bool noDelay); + virtual bool GetTcpNoDelay (void) const; virtual void SetPersistTimeout (Time timeout); virtual Time GetPersistTimeout (void) const; enum Socket::SocketErrno GetNativeNs3Errno (int err) const; uint32_t m_delAckMaxCount; Time m_delAckTimeout; + bool m_noDelay; Ipv4EndPoint *m_endPoint; Ptr m_node; diff --git a/src/internet/model/rtt-estimator.cc b/src/internet/model/rtt-estimator.cc index 542451c06..b5ae0410d 100644 --- a/src/internet/model/rtt-estimator.cc +++ b/src/internet/model/rtt-estimator.cc @@ -54,7 +54,7 @@ RttEstimator::GetTypeId (void) MakeTimeChecker ()) .AddAttribute ("MinRTO", "Minimum retransmit timeout value", - TimeValue (Seconds (0.2)), + TimeValue (Seconds (0.2)), // RFC2988 says min RTO=1 sec, but Linux uses 200ms. See http://www.postel.org/pipermail/end2end-interest/2004-November/004402.html MakeTimeAccessor (&RttEstimator::SetMinRto, &RttEstimator::GetMinRto), MakeTimeChecker ()) diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index 6817ffcc2..f4322eaa8 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -120,6 +120,7 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) m_dupAckCount (sock.m_dupAckCount), m_delAckCount (0), m_delAckMaxCount (sock.m_delAckMaxCount), + m_noDelay (sock.m_noDelay), m_cnRetries (sock.m_cnRetries), m_delAckTimeout (sock.m_delAckTimeout), m_persistTimeout (sock.m_persistTimeout), @@ -1456,6 +1457,14 @@ TcpSocketBase::SendPendingData (bool withAck) { break; // No more } + // Nagle's algorithm (RFC896): Hold off sending if there is unacked data + // in the buffer and the amount of data to send is less than one segment + if (!m_noDelay && UnAckDataCount () > 0 && + m_txBuffer.SizeFromSequence (m_nextTxSequence) < m_segmentSize) + { + NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send."); + break; + } uint32_t s = std::min (w, m_segmentSize); // Send no more than window uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck); nPacketsSent++; // Count sent this loop @@ -1835,6 +1844,18 @@ TcpSocketBase::GetDelAckMaxCount (void) const return m_delAckMaxCount; } +void +TcpSocketBase::SetTcpNoDelay (bool noDelay) +{ + m_noDelay = noDelay; +} + +bool +TcpSocketBase::GetTcpNoDelay (void) const +{ + return m_noDelay; +} + void TcpSocketBase::SetPersistTimeout (Time timeout) { diff --git a/src/internet/model/tcp-socket-base.h b/src/internet/model/tcp-socket-base.h index cb824636e..40716e7c3 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -116,6 +116,8 @@ protected: virtual Time GetDelAckTimeout (void) const; virtual void SetDelAckMaxCount (uint32_t count); virtual uint32_t GetDelAckMaxCount (void) const; + virtual void SetTcpNoDelay (bool noDelay); + virtual bool GetTcpNoDelay (void) const; virtual void SetPersistTimeout (Time timeout); virtual Time GetPersistTimeout (void) const; virtual bool SetAllowBroadcast (bool allowBroadcast); @@ -189,6 +191,7 @@ protected: uint32_t m_dupAckCount; //< Dupack counter 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 TracedValue