Bug 1831 - TcpSocket SlowStartThreshold is not a TraceSource
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Wed, 13 Aug 2014 23:46:16 +0200
changeset 10855 7ef081ddfc7f
parent 10854 e6e590450831
child 10856 d45187afb01a
Bug 1831 - TcpSocket SlowStartThreshold is not a TraceSource
CHANGES.html
RELEASE_NOTES
src/internet/model/nsc-tcp-socket-impl.cc
src/internet/model/nsc-tcp-socket-impl.h
src/internet/model/tcp-newreno.cc
src/internet/model/tcp-newreno.h
src/internet/model/tcp-reno.cc
src/internet/model/tcp-reno.h
src/internet/model/tcp-rfc793.cc
src/internet/model/tcp-rfc793.h
src/internet/model/tcp-socket-base.h
src/internet/model/tcp-socket.cc
src/internet/model/tcp-socket.h
src/internet/model/tcp-tahoe.cc
src/internet/model/tcp-tahoe.h
src/internet/model/tcp-westwood.cc
src/internet/model/tcp-westwood.h
--- a/CHANGES.html	Wed Aug 06 11:00:06 2014 +0200
+++ b/CHANGES.html	Wed Aug 13 23:46:16 2014 +0200
@@ -56,12 +56,17 @@
 <ul>
   <li> New "const double& SpectrumValue:: operator[] (size_t index) const".
   </li>
+  <li> A new TraceSource has been added to TCP sockets: SlowStartThreshold.
+  </li>
 </ul>
 
 <h2>Changes to existing API:</h2>
 <ul>
   <li> "Icmpv6L4Protocol::ForgeEchoRequest" is now returning a packet with the proper IPv6 header.
   </li>
+  <li> The TCP socket Attribute "SlowStartThreshold" has been renamed "InitialSlowStartThreshold" to
+       clarify that the effect is only on the initial value.
+  </li>
 </ul>
 
 <h2>Changes to build system:</h2>
--- a/RELEASE_NOTES	Wed Aug 06 11:00:06 2014 +0200
+++ b/RELEASE_NOTES	Wed Aug 13 23:46:16 2014 +0200
@@ -29,6 +29,7 @@
 ----------
 
 - Bug 1762 - UE stuck in IDLE_CONNECTING because RRC CONN REQ is not transmitted
+- Bug 1831 - TcpSocket SlowStartThreshold is not a TraceSource
 - Bug 1921 - Icmpv6L4Protocol::ForgeEchoRequest returns a malformed packet
 - Bug 1930 - Use of invalid reference in OLSR RemoveLinkTuple
 - Bug 1932 - NdiscCache entry is not failsafe on double neighbor probing.
--- a/src/internet/model/nsc-tcp-socket-impl.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/nsc-tcp-socket-impl.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -57,6 +57,9 @@
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&NscTcpSocketImpl::m_cWnd))
+    .AddTraceSource ("SlowStartThreshold",
+                     "TCP slow start threshold (bytes)",
+                     MakeTraceSourceAccessor (&NscTcpSocketImpl::m_ssThresh))
   ;
   return tid;
 }
@@ -106,6 +109,7 @@
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
     m_initialCWnd (sock.m_initialCWnd),
+    m_initialSsThresh (sock.m_initialSsThresh),
     m_lastMeasuredRtt (Seconds (0.0)),
     m_cnTimeout (sock.m_cnTimeout),
     m_cnCount (sock.m_cnCount),
@@ -152,6 +156,7 @@
   m_node = node;
   // Initialize some variables 
   m_cWnd = m_initialCWnd * m_segmentSize;
+  m_ssThresh = m_initialSsThresh;
   m_rxWindowSize = m_advertisedWindowSize;
 }
 
@@ -730,15 +735,15 @@
 }
 
 void
-NscTcpSocketImpl::SetSSThresh (uint32_t threshold)
+NscTcpSocketImpl::SetInitialSSThresh (uint32_t threshold)
 {
-  m_ssThresh = threshold;
+  m_initialSsThresh = threshold;
 }
 
 uint32_t
-NscTcpSocketImpl::GetSSThresh (void) const
+NscTcpSocketImpl::GetInitialSSThresh (void) const
 {
-  return m_ssThresh;
+  return m_initialSsThresh;
 }
 
 void
--- a/src/internet/model/nsc-tcp-socket-impl.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/nsc-tcp-socket-impl.h	Wed Aug 13 23:46:16 2014 +0200
@@ -187,8 +187,8 @@
    * \returns the window size
    */
   virtual uint32_t GetAdvWin (void) const;
-  virtual void SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
+  virtual void SetInitialSSThresh (uint32_t threshold);
+  virtual uint32_t GetInitialSSThresh (void) const;
   virtual void SetInitialCwnd (uint32_t cwnd);
   virtual uint32_t GetInitialCwnd (void) const;
   virtual void SetConnTimeout (Time timeout);
@@ -240,9 +240,10 @@
   uint32_t                       m_segmentSize;          //!< SegmentSize
   uint32_t                       m_rxWindowSize;         //!< Receive window size
   uint32_t                       m_advertisedWindowSize; //!< Window to advertise
+  TracedValue<uint32_t>          m_ssThresh;             //!< Slow Start Threshold
   TracedValue<uint32_t>          m_cWnd;                 //!< Congestion window
-  uint32_t                       m_ssThresh;             //!< Slow Start Threshold
   uint32_t                       m_initialCWnd;          //!< Initial cWnd value
+  uint32_t                       m_initialSsThresh;      //!< Initial Slow Start Threshold
 
   // Round trip time estimation
   Time m_lastMeasuredRtt; //!< Last measured RTT
--- a/src/internet/model/tcp-newreno.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-newreno.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -45,13 +45,16 @@
                     MakeUintegerAccessor (&TcpNewReno::m_retxThresh),
                     MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("LimitedTransmit", "Enable limited transmit",
-		    BooleanValue (false),
-		    MakeBooleanAccessor (&TcpNewReno::m_limitedTx),
-		    MakeBooleanChecker ())
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&TcpNewReno::m_limitedTx),
+                   MakeBooleanChecker ())
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&TcpNewReno::m_cWnd))
-  ;
+    .AddTraceSource ("SlowStartThreshold",
+                     "TCP slow start threshold (bytes)",
+                     MakeTraceSourceAccessor (&TcpNewReno::m_ssThresh))
+ ;
   return tid;
 }
 
@@ -68,6 +71,7 @@
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
     m_initialCWnd (sock.m_initialCWnd),
+    m_initialSsThresh (sock.m_initialSsThresh),
     m_retxThresh (sock.m_retxThresh),
     m_inFastRec (false),
     m_limitedTx (sock.m_limitedTx)
@@ -124,8 +128,7 @@
   // Check for exit condition of fast recovery
   if (m_inFastRec && seq < m_recover)
     { // Partial ACK, partial window deflation (RFC2582 sec.3 bullet #5 paragraph 3)
-      m_cWnd -= seq - m_txBuffer.HeadSequence ();
-      m_cWnd += m_segmentSize;  // increase cwnd
+      m_cWnd += m_segmentSize - (seq - m_txBuffer.HeadSequence ());
       NS_LOG_INFO ("Partial ACK in fast recovery: cwnd set to " << m_cWnd);
       m_txBuffer.DiscardUpTo(seq);  //Bug 1850:  retransmit before newack
       DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet
@@ -134,7 +137,7 @@
     }
   else if (m_inFastRec && seq >= m_recover)
     { // Full ACK (RFC2582 sec.3 bullet #5 paragraph 2, option 1)
-      m_cWnd = std::min (m_ssThresh, BytesInFlight () + m_segmentSize);
+      m_cWnd = std::min (m_ssThresh.Get (), BytesInFlight () + m_segmentSize);
       m_inFastRec = false;
       NS_LOG_INFO ("Received full ACK. Leaving fast recovery with cwnd set to " << m_cWnd);
     }
@@ -220,15 +223,16 @@
 }
 
 void
-TcpNewReno::SetSSThresh (uint32_t threshold)
+TcpNewReno::SetInitialSSThresh (uint32_t threshold)
 {
-  m_ssThresh = threshold;
+  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpNewReno::SetSSThresh() cannot change initial ssThresh after connection started.");
+  m_initialSsThresh = threshold;
 }
 
 uint32_t
-TcpNewReno::GetSSThresh (void) const
+TcpNewReno::GetInitialSSThresh (void) const
 {
-  return m_ssThresh;
+  return m_initialSsThresh;
 }
 
 void
@@ -253,6 +257,7 @@
    * m_segmentSize are set by the attribute system in ns3::TcpSocket.
    */
   m_cWnd = m_initialCWnd * m_segmentSize;
+  m_ssThresh = m_initialSsThresh;
 }
 
 } // namespace ns3
--- a/src/internet/model/tcp-newreno.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-newreno.h	Wed Aug 13 23:46:16 2014 +0200
@@ -65,8 +65,8 @@
 
   // Implementing ns3::TcpSocket -- Attribute get/set
   virtual void     SetSegSize (uint32_t size);
-  virtual void     SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
+  virtual void     SetInitialSSThresh (uint32_t threshold);
+  virtual uint32_t GetInitialSSThresh (void) const;
   virtual void     SetInitialCwnd (uint32_t cwnd);
   virtual uint32_t GetInitialCwnd (void) const;
 private:
@@ -77,8 +77,9 @@
 
 protected:
   TracedValue<uint32_t>  m_cWnd;         //!< Congestion window
-  uint32_t               m_ssThresh;     //!< Slow Start Threshold
+  TracedValue<uint32_t>  m_ssThresh;     //!< Slow Start Threshold
   uint32_t               m_initialCWnd;  //!< Initial cWnd value
+  uint32_t               m_initialSsThresh;  //!< Initial Slow Start Threshold value
   SequenceNumber32       m_recover;      //!< Previous highest Tx seqnum for fast recovery
   uint32_t               m_retxThresh;   //!< Fast Retransmit threshold
   bool                   m_inFastRec;    //!< currently in fast recovery
--- a/src/internet/model/tcp-reno.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-reno.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -47,6 +47,9 @@
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&TcpReno::m_cWnd))
+    .AddTraceSource ("SlowStartThreshold",
+                     "TCP slow start threshold (bytes)",
+                     MakeTraceSourceAccessor (&TcpReno::m_ssThresh))
   ;
   return tid;
 }
@@ -61,6 +64,7 @@
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
     m_initialCWnd (sock.m_initialCWnd),
+    m_initialSsThresh (sock.m_initialSsThresh),
     m_retxThresh (sock.m_retxThresh),
     m_inFastRec (false)
 {
@@ -194,15 +198,16 @@
 }
 
 void
-TcpReno::SetSSThresh (uint32_t threshold)
+TcpReno::SetInitialSSThresh (uint32_t threshold)
 {
-  m_ssThresh = threshold;
+  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpReno::SetSSThresh() cannot change initial ssThresh after connection started.");
+  m_initialSsThresh = threshold;
 }
 
 uint32_t
-TcpReno::GetSSThresh (void) const
+TcpReno::GetInitialSSThresh (void) const
 {
-  return m_ssThresh;
+  return m_initialSsThresh;
 }
 
 void
@@ -227,6 +232,7 @@
    * m_segmentSize are set by the attribute system in ns3::TcpSocket.
    */
   m_cWnd = m_initialCWnd * m_segmentSize;
+  m_ssThresh = m_initialSsThresh;
 }
 
 } // namespace ns3
--- a/src/internet/model/tcp-reno.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-reno.h	Wed Aug 13 23:46:16 2014 +0200
@@ -67,8 +67,8 @@
 
   // Implementing ns3::TcpSocket -- Attribute get/set
   virtual void     SetSegSize (uint32_t size);
-  virtual void     SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
+  virtual void     SetInitialSSThresh (uint32_t threshold);
+  virtual uint32_t GetInitialSSThresh (void) const;
   virtual void     SetInitialCwnd (uint32_t cwnd);
   virtual uint32_t GetInitialCwnd (void) const;
 private:
@@ -79,8 +79,9 @@
 
 protected:
   TracedValue<uint32_t>  m_cWnd;         //!< Congestion window
-  uint32_t               m_ssThresh;     //!< Slow Start Threshold
+  TracedValue<uint32_t>  m_ssThresh;     //!< Slow Start Threshold
   uint32_t               m_initialCWnd;  //!< Initial cWnd value
+  uint32_t               m_initialSsThresh;  //!< Initial Slow Start Threshold value
   uint32_t               m_retxThresh;   //!< Fast Retransmit threshold
   bool                   m_inFastRec;    //!< currently in fast recovery
 };
--- a/src/internet/model/tcp-rfc793.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-rfc793.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -63,13 +63,13 @@
 }
 
 void
-TcpRfc793::SetSSThresh (uint32_t threshold)
+TcpRfc793::SetInitialSSThresh (uint32_t threshold)
 {
   NS_LOG_WARN ("DoD TCP does not perform slow start");
 }
 
 uint32_t
-TcpRfc793::GetSSThresh (void) const
+TcpRfc793::GetInitialSSThresh (void) const
 {
   NS_LOG_WARN ("DoD TCP does not perform slow start");
   return 0;
--- a/src/internet/model/tcp-rfc793.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-rfc793.h	Wed Aug 13 23:46:16 2014 +0200
@@ -58,8 +58,8 @@
 protected:
   virtual Ptr<TcpSocketBase> Fork (); // Call CopyObject<TcpRfc793> to clone me
   virtual void DupAck (const TcpHeader& t, uint32_t count);
-  virtual void     SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
+  virtual void     SetInitialSSThresh (uint32_t threshold);
+  virtual uint32_t GetInitialSSThresh (void) const;
   virtual void     SetInitialCwnd (uint32_t cwnd);
   virtual uint32_t GetInitialCwnd (void) const;
 };
--- a/src/internet/model/tcp-socket-base.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-socket-base.h	Wed Aug 13 23:46:16 2014 +0200
@@ -132,8 +132,8 @@
   virtual uint32_t GetRcvBufSize (void) const;
   virtual void     SetSegSize (uint32_t size);
   virtual uint32_t GetSegSize (void) const;
-  virtual void     SetSSThresh (uint32_t threshold) = 0;
-  virtual uint32_t GetSSThresh (void) const = 0;
+  virtual void     SetInitialSSThresh (uint32_t threshold) = 0;
+  virtual uint32_t GetInitialSSThresh (void) const = 0;
   virtual void     SetInitialCwnd (uint32_t cwnd) = 0;
   virtual uint32_t GetInitialCwnd (void) const = 0;
   virtual void     SetConnTimeout (Time timeout);
--- a/src/internet/model/tcp-socket.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-socket.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -58,11 +58,11 @@
                    MakeUintegerAccessor (&TcpSocket::GetSegSize,
                                          &TcpSocket::SetSegSize),
                    MakeUintegerChecker<uint32_t> ())
-    .AddAttribute ("SlowStartThreshold",
-                   "TCP slow start threshold (bytes)",
+    .AddAttribute ("InitialSlowStartThreshold",
+                   "TCP initial slow start threshold (bytes)",
                    UintegerValue (0xffff),
-                   MakeUintegerAccessor (&TcpSocket::GetSSThresh,
-                                         &TcpSocket::SetSSThresh),
+                   MakeUintegerAccessor (&TcpSocket::GetInitialSSThresh,
+                                         &TcpSocket::SetInitialSSThresh),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("InitialCwnd",
                    "TCP initial congestion window size (segments)",
--- a/src/internet/model/tcp-socket.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-socket.h	Wed Aug 13 23:46:16 2014 +0200
@@ -119,16 +119,16 @@
   virtual uint32_t GetSegSize (void) const = 0;
 
   /**
-   * \brief Set the Slow Start Threshold.
+   * \brief Set the initial Slow Start Threshold.
    * \param threshold the Slow Start Threshold (in bytes)
    */
-  virtual void SetSSThresh (uint32_t threshold) = 0;
+  virtual void SetInitialSSThresh (uint32_t threshold) = 0;
 
   /**
-   * \brief Get the Slow Start Threshold.
+   * \brief Get the initial Slow Start Threshold.
    * \returns the Slow Start Threshold (in bytes)
    */
-  virtual uint32_t GetSSThresh (void) const = 0;
+  virtual uint32_t GetInitialSSThresh (void) const = 0;
 
   /**
    * \brief Set the initial Congestion Window.
--- a/src/internet/model/tcp-tahoe.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-tahoe.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -47,6 +47,9 @@
     .AddTraceSource ("CongestionWindow",
                      "The TCP connection's congestion window",
                      MakeTraceSourceAccessor (&TcpTahoe::m_cWnd))
+    .AddTraceSource ("SlowStartThreshold",
+                     "TCP slow start threshold (bytes)",
+                     MakeTraceSourceAccessor (&TcpTahoe::m_ssThresh))
   ;
   return tid;
 }
@@ -61,6 +64,7 @@
     m_cWnd (sock.m_cWnd),
     m_ssThresh (sock.m_ssThresh),
     m_initialCWnd (sock.m_initialCWnd),
+    m_initialSsThresh (sock.m_initialSsThresh),
     m_retxThresh (sock.m_retxThresh)
 {
   NS_LOG_FUNCTION (this);
@@ -108,7 +112,7 @@
 TcpTahoe::NewAck (SequenceNumber32 const& seq)
 {
   NS_LOG_FUNCTION (this << seq);
-  NS_LOG_LOGIC ("TcpTahoe receieved ACK for seq " << seq <<
+  NS_LOG_LOGIC ("TcpTahoe received ACK for seq " << seq <<
                 " cwnd " << m_cWnd <<
                 " ssthresh " << m_ssThresh);
   if (m_cWnd < m_ssThresh)
@@ -172,15 +176,16 @@
 }
 
 void
-TcpTahoe::SetSSThresh (uint32_t threshold)
+TcpTahoe::SetInitialSSThresh (uint32_t threshold)
 {
-  m_ssThresh = threshold;
+  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpTahoe::SetSSThresh() cannot change initial ssThresh after connection started.");
+  m_initialSsThresh = threshold;
 }
 
 uint32_t
-TcpTahoe::GetSSThresh (void) const
+TcpTahoe::GetInitialSSThresh (void) const
 {
-  return m_ssThresh;
+  return m_initialSsThresh;
 }
 
 void
@@ -205,6 +210,7 @@
    * m_segmentSize are set by the attribute system in ns3::TcpSocket.
    */
   m_cWnd = m_initialCWnd * m_segmentSize;
+  m_ssThresh = m_initialSsThresh;
 }
 
 } // namespace ns3
--- a/src/internet/model/tcp-tahoe.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-tahoe.h	Wed Aug 13 23:46:16 2014 +0200
@@ -71,8 +71,8 @@
 
   // Implementing ns3::TcpSocket -- Attribute get/set
   virtual void     SetSegSize (uint32_t size);
-  virtual void     SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
+  virtual void     SetInitialSSThresh (uint32_t threshold);
+  virtual uint32_t GetInitialSSThresh (void) const;
   virtual void     SetInitialCwnd (uint32_t cwnd);
   virtual uint32_t GetInitialCwnd (void) const;
 private:
@@ -83,8 +83,9 @@
 
 protected:
   TracedValue<uint32_t>  m_cWnd;         //!< Congestion window
-  uint32_t               m_ssThresh;     //!< Slow Start Threshold
+  TracedValue<uint32_t>  m_ssThresh;     //!< Slow Start Threshold
   uint32_t               m_initialCWnd;  //!< Initial cWnd value
+  uint32_t               m_initialSsThresh;  //!< Initial Slow Start Threshold value
   uint32_t               m_retxThresh;   //!< Fast Retransmit threshold
 };
 
--- a/src/internet/model/tcp-westwood.cc	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-westwood.cc	Wed Aug 13 23:46:16 2014 +0200
@@ -56,6 +56,9 @@
       .AddConstructor<TcpWestwood>()
       .AddTraceSource("CongestionWindow", "The TCP connection's congestion window",
                       MakeTraceSourceAccessor(&TcpWestwood::m_cWnd))
+      .AddTraceSource ("SlowStartThreshold",
+                       "TCP slow start threshold (bytes)",
+                       MakeTraceSourceAccessor (&TcpWestwood::m_ssThresh))
       .AddAttribute("FilterType", "Use this to choose no filter or Tustin's approximation filter",
                     EnumValue(TcpWestwood::TUSTIN), MakeEnumAccessor(&TcpWestwood::m_fType),
                     MakeEnumChecker(TcpWestwood::NONE, "None", TcpWestwood::TUSTIN, "Tustin"))
@@ -88,6 +91,7 @@
   m_cWnd(sock.m_cWnd),
   m_ssThresh(sock.m_ssThresh),
   m_initialCWnd(sock.m_initialCWnd),
+  m_initialSsThresh (sock.m_initialSsThresh),
   m_inFastRec(false),
   m_currentBW(sock.m_currentBW),
   m_lastSampleBW(sock.m_lastSampleBW),
@@ -272,7 +276,7 @@
   if (count == 3 && !m_inFastRec)
     {// Triple duplicate ACK triggers fast retransmit
      // Adjust cwnd and ssthresh based on the estimated BW
-      m_ssThresh = m_currentBW * static_cast<double> (m_minRtt.GetSeconds());
+      m_ssThresh = uint32_t(m_currentBW * static_cast<double> (m_minRtt.GetSeconds()));
       if (m_cWnd > m_ssThresh)
         {
           m_cWnd = m_ssThresh;
@@ -380,17 +384,18 @@
 }
 
 void
-TcpWestwood::SetSSThresh (uint32_t threshold)
+TcpWestwood::SetInitialSSThresh (uint32_t threshold)
 {
   NS_LOG_FUNCTION (this);
-  m_ssThresh = threshold;
+  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpWestwood::SetSSThresh() cannot change initial ssThresh after connection started.");
+  m_initialSsThresh = threshold;
 }
 
 uint32_t
-TcpWestwood::GetSSThresh (void) const
+TcpWestwood::GetInitialSSThresh (void) const
 {
   NS_LOG_FUNCTION (this);
-  return m_ssThresh;
+  return m_initialSsThresh;
 }
 
 void
@@ -417,6 +422,7 @@
    * m_segmentSize are set by the attribute system in ns3::TcpSocket.
    */
   m_cWnd = m_initialCWnd * m_segmentSize;
+  m_ssThresh = m_initialSsThresh;
 }
 
 } // namespace ns3
--- a/src/internet/model/tcp-westwood.h	Wed Aug 06 11:00:06 2014 +0200
+++ b/src/internet/model/tcp-westwood.h	Wed Aug 13 23:46:16 2014 +0200
@@ -122,8 +122,8 @@
 
   // Implementing ns3::TcpSocket -- Attribute get/set
   virtual void     SetSegSize (uint32_t size);
-  virtual void     SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
+  virtual void     SetInitialSSThresh (uint32_t threshold);
+  virtual uint32_t GetInitialSSThresh (void) const;
   virtual void     SetInitialCwnd (uint32_t cwnd);
   virtual uint32_t GetInitialCwnd (void) const;
 
@@ -164,8 +164,9 @@
 
 protected:
   TracedValue<uint32_t>  m_cWnd;                   //!< Congestion window
-  uint32_t               m_ssThresh;               //!< Slow Start Threshold
+  TracedValue<uint32_t>  m_ssThresh;               //!< Slow Start Threshold
   uint32_t               m_initialCWnd;            //!< Initial cWnd value
+  uint32_t               m_initialSsThresh;        //!< Initial Slow Start Threshold value
   bool                   m_inFastRec;              //!< Currently in fast recovery if TRUE
 
   TracedValue<double>    m_currentBW;              //!< Current value of the estimated BW