View | Details | Raw Unified | Return to bug 2058
Collapse All | Expand All

(-)a/src/internet/model/tcp-socket-base.cc (-18 / +79 lines)
 Lines 142-147    Link Here 
142
                     "Remote side's flow control window",
142
                     "Remote side's flow control window",
143
                     MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd),
143
                     MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd),
144
                     "ns3::TracedValue::Uint32Callback")
144
                     "ns3::TracedValue::Uint32Callback")
145
    .AddTraceSource ("HighestRxSequence",
146
                     "Highest sequence number received from peer",
147
                     MakeTraceSourceAccessor (&TcpSocketBase::m_highRxMark),
148
                     "ns3::SequenceNumber32TracedValueCallback")
149
    .AddTraceSource ("HighestRxAck",
150
                     "Highest ack received from peer",
151
                     MakeTraceSourceAccessor (&TcpSocketBase::m_highRxAckMark),
152
                     "ns3::SequenceNumber32TracedValueCallback")
145
  ;
153
  ;
146
  return tid;
154
  return tid;
147
}
155
}
 Lines 169-174    Link Here 
169
    m_segmentSize (0),
177
    m_segmentSize (0),
170
    // For attribute initialization consistency (quiet valgrind)
178
    // For attribute initialization consistency (quiet valgrind)
171
    m_rWnd (0),
179
    m_rWnd (0),
180
    m_highRxMark (0),
181
    m_highRxAckMark (0),
172
    m_sndScaleFactor (0),
182
    m_sndScaleFactor (0),
173
    m_rcvScaleFactor (0),
183
    m_rcvScaleFactor (0),
174
    m_timestampEnabled (true),
184
    m_timestampEnabled (true),
 Lines 209-214    Link Here 
209
    m_segmentSize (sock.m_segmentSize),
219
    m_segmentSize (sock.m_segmentSize),
210
    m_maxWinSize (sock.m_maxWinSize),
220
    m_maxWinSize (sock.m_maxWinSize),
211
    m_rWnd (sock.m_rWnd),
221
    m_rWnd (sock.m_rWnd),
222
    m_highRxMark (sock.m_highRxMark),
223
    m_highRxAckMark (sock.m_highRxAckMark),
212
    m_winScalingEnabled (sock.m_winScalingEnabled),
224
    m_winScalingEnabled (sock.m_winScalingEnabled),
213
    m_sndScaleFactor (sock.m_sndScaleFactor),
225
    m_sndScaleFactor (sock.m_sndScaleFactor),
214
    m_rcvScaleFactor (sock.m_rcvScaleFactor),
226
    m_rcvScaleFactor (sock.m_rcvScaleFactor),
 Lines 942-956    Link Here 
942
      EstimateRtt (tcpHeader);
954
      EstimateRtt (tcpHeader);
943
    }
955
    }
944
956
945
  // Update Rx window size, i.e. the flow control window
946
  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
947
    { // persist probes end
948
      NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
949
      m_persistEvent.Cancel ();
950
    }
951
  m_rWnd = tcpHeader.GetWindowSize ();
952
  m_rWnd <<= m_rcvScaleFactor;
953
954
  // Discard fully out of range data packets
957
  // Discard fully out of range data packets
955
  if (packet->GetSize ()
958
  if (packet->GetSize ()
956
      && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
959
      && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
 Lines 968-973    Link Here 
968
      return;
971
      return;
969
    }
972
    }
970
973
974
  // Update Rx window size, i.e. the flow control window
975
  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0 && m_persistEvent.IsRunning ())
976
    { // persist probes end
977
      NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
978
      m_persistEvent.Cancel ();
979
    }
980
  if (tcpHeader.GetFlags () & TcpHeader::ACK)
981
    {
982
      UpdateWindowSize (tcpHeader);
983
    }
984
971
  // TCP state machine code in different process functions
985
  // TCP state machine code in different process functions
972
  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
986
  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
973
  switch (m_state)
987
  switch (m_state)
 Lines 1046-1060    Link Here 
1046
      EstimateRtt (tcpHeader);
1060
      EstimateRtt (tcpHeader);
1047
    }
1061
    }
1048
1062
1049
  // Update Rx window size, i.e. the flow control window
1050
  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
1051
    { // persist probes end
1052
      NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
1053
      m_persistEvent.Cancel ();
1054
    }
1055
  m_rWnd = tcpHeader.GetWindowSize ();
1056
  m_rWnd <<= m_rcvScaleFactor;
1057
1058
  // Discard fully out of range packets
1063
  // Discard fully out of range packets
1059
  if (packet->GetSize ()
1064
  if (packet->GetSize ()
1060
      && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
1065
      && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
 Lines 1072-1077    Link Here 
1072
      return;
1077
      return;
1073
    }
1078
    }
1074
1079
1080
  // Update Rx window size, i.e. the flow control window
1081
  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0 && m_persistEvent.IsRunning ())
1082
    { // persist probes end
1083
      NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
1084
      m_persistEvent.Cancel ();
1085
    }
1086
1087
  if (tcpHeader.GetFlags () & TcpHeader::ACK)
1088
    {
1089
      UpdateWindowSize (tcpHeader);
1090
    }
1091
1075
  // TCP state machine code in different process functions
1092
  // TCP state machine code in different process functions
1076
  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
1093
  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
1077
  switch (m_state)
1094
  switch (m_state)
 Lines 2727-2732    Link Here 
2727
               option->GetTimestamp () << " echo=" << m_timestampToEcho);
2744
               option->GetTimestamp () << " echo=" << m_timestampToEcho);
2728
}
2745
}
2729
2746
2747
void TcpSocketBase::UpdateWindowSize (const TcpHeader &header)
2748
{
2749
  NS_LOG_FUNCTION (this << header);
2750
  //  If the connection is not established, the window size is always
2751
  //  updated
2752
  uint32_t receivedWindow = header.GetWindowSize ();
2753
  receivedWindow <<= m_rcvScaleFactor;
2754
  NS_LOG_DEBUG ("Received (scaled) window is " << receivedWindow << " bytes");
2755
  if (m_state < ESTABLISHED)
2756
    {
2757
      m_rWnd = receivedWindow;
2758
      NS_LOG_DEBUG ("State less than ESTABLISHED; updating rWnd to " << m_rWnd);
2759
      return;
2760
    }
2761
2762
  // Test for conditions that allow updating of the window
2763
  // 1) segment contains new data (advancing the right edge of the receive 
2764
  // buffer), 
2765
  // 2) segment does not contain new data but the segment acks new data 
2766
  // (highest sequence number acked advances), or
2767
  // 3) the advertised window is larger than the current send window
2768
  bool update = false;
2769
  if (header.GetAckNumber () == m_highRxAckMark && receivedWindow > m_rWnd)
2770
    {
2771
      // right edge of the send window is increased (window update)
2772
      update = true;
2773
    }
2774
  if (header.GetAckNumber () > m_highRxAckMark)
2775
    {
2776
      m_highRxAckMark = header.GetAckNumber ();
2777
      update = true;
2778
    }
2779
  if (header.GetSequenceNumber () > m_highRxMark)
2780
    {
2781
      m_highRxMark = header.GetSequenceNumber ();
2782
      update = true;
2783
    }
2784
  if (update == true)
2785
    {
2786
      m_rWnd = receivedWindow;
2787
      NS_LOG_DEBUG ("updating rWnd to " << m_rWnd);
2788
    }
2789
}
2790
2730
void
2791
void
2731
TcpSocketBase::SetMinRto (Time minRto)
2792
TcpSocketBase::SetMinRto (Time minRto)
2732
{
2793
{
(-)a/src/internet/model/tcp-socket-base.h (-1 / +17 lines)
 Lines 675-680    Link Here 
675
   */
675
   */
676
  void AddOptionTimestamp (TcpHeader& header);
676
  void AddOptionTimestamp (TcpHeader& header);
677
677
678
  /**
679
   * \brief Update the receiver window (RWND) based on the value of the 
680
   * window field in the header.
681
   *
682
   * This method suppresses updates unless one of the following three 
683
   * conditions holds:  1) segment contains new data (advancing the right
684
   * edge of the receive buffer), 2) segment does not contain new data
685
   * but the segment acks new data (highest sequence number acked advances),
686
   * or 3) the advertised window is larger than the current send window
687
   *
688
   * \param header TcpHeader from which to extract the new window value
689
   */
690
  void UpdateWindowSize (const TcpHeader& header);
691
678
692
679
protected:
693
protected:
680
  // Counters and events
694
  // Counters and events
 Lines 727-733    Link Here 
727
  // Window management
741
  // Window management
728
  uint32_t              m_segmentSize; //!< Segment size
742
  uint32_t              m_segmentSize; //!< Segment size
729
  uint16_t              m_maxWinSize;  //!< Maximum window size to advertise
743
  uint16_t              m_maxWinSize;  //!< Maximum window size to advertise
730
  TracedValue<uint32_t> m_rWnd;        //!< Flow control window at remote side
744
  TracedValue<uint32_t> m_rWnd;        //!< Receiver window (RCV.WND in RFC793)
745
  TracedValue<SequenceNumber32> m_highRxMark;     //!< Highest seqno received
746
  TracedValue<SequenceNumber32> m_highRxAckMark;  //!< Highest ack received
731
747
732
  // Options
748
  // Options
733
  bool    m_winScalingEnabled;    //!< Window Scale option enabled
749
  bool    m_winScalingEnabled;    //!< Window Scale option enabled

Return to bug 2058