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

(-)a/src/internet/model/tcp-socket-base.cc (-43 / +29 lines)
 Lines 285-292   TcpSocketBase::TcpSocketBase (void) Link Here 
285
  m_highRxAckMark (0),
285
  m_highRxAckMark (0),
286
  m_bytesAckedNotProcessed (0),
286
  m_bytesAckedNotProcessed (0),
287
  m_winScalingEnabled (false),
287
  m_winScalingEnabled (false),
288
  m_sndScaleFactor (0),
288
  m_rcvWindShift (0),
289
  m_rcvScaleFactor (0),
289
  m_sndWindShift (0),
290
  m_timestampEnabled (true),
290
  m_timestampEnabled (true),
291
  m_timestampToEcho (0),
291
  m_timestampToEcho (0),
292
  m_sendPendingDataEvent (),
292
  m_sendPendingDataEvent (),
 Lines 354-361   TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) Link Here 
354
  m_highRxAckMark (sock.m_highRxAckMark),
354
  m_highRxAckMark (sock.m_highRxAckMark),
355
  m_bytesAckedNotProcessed (sock.m_bytesAckedNotProcessed),
355
  m_bytesAckedNotProcessed (sock.m_bytesAckedNotProcessed),
356
  m_winScalingEnabled (sock.m_winScalingEnabled),
356
  m_winScalingEnabled (sock.m_winScalingEnabled),
357
  m_sndScaleFactor (sock.m_sndScaleFactor),
357
  m_rcvWindShift (sock.m_rcvWindShift),
358
  m_rcvScaleFactor (sock.m_rcvScaleFactor),
358
  m_sndWindShift (sock.m_sndWindShift),
359
  m_timestampEnabled (sock.m_timestampEnabled),
359
  m_timestampEnabled (sock.m_timestampEnabled),
360
  m_timestampToEcho (sock.m_timestampToEcho),
360
  m_timestampToEcho (sock.m_timestampToEcho),
361
  m_recover (sock.m_recover),
361
  m_recover (sock.m_recover),
 Lines 581-593   TcpSocketBase::Bind (const Address &address) Link Here 
581
}
581
}
582
582
583
void
583
void
584
TcpSocketBase::InitializeCwnd (void)
585
{
586
  m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize ();
587
  m_tcb->m_ssThresh = GetInitialSSThresh ();
588
}
589
590
void
591
TcpSocketBase::SetInitialSSThresh (uint32_t threshold)
584
TcpSocketBase::SetInitialSSThresh (uint32_t threshold)
592
{
585
{
593
  NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || threshold == m_tcb->m_initialSsThresh,
586
  NS_ABORT_MSG_UNLESS ( (m_state == CLOSED) || threshold == m_tcb->m_initialSsThresh,
 Lines 617-636   TcpSocketBase::GetInitialCwnd (void) const Link Here 
617
  return m_tcb->m_initialCWnd;
610
  return m_tcb->m_initialCWnd;
618
}
611
}
619
612
620
void
621
TcpSocketBase::ScaleSsThresh (uint8_t scaleFactor)
622
{
623
  m_tcb->m_ssThresh <<= scaleFactor;
624
}
625
626
/* Inherit from Socket class: Initiate connection to a remote address:port */
613
/* Inherit from Socket class: Initiate connection to a remote address:port */
627
int
614
int
628
TcpSocketBase::Connect (const Address & address)
615
TcpSocketBase::Connect (const Address & address)
629
{
616
{
630
  NS_LOG_FUNCTION (this << address);
617
  NS_LOG_FUNCTION (this << address);
631
618
632
  InitializeCwnd ();
633
634
  // If haven't do so, Bind() this socket first
619
  // If haven't do so, Bind() this socket first
635
  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
620
  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
636
    {
621
    {
 Lines 705-712   TcpSocketBase::Listen (void) Link Here 
705
{
690
{
706
  NS_LOG_FUNCTION (this);
691
  NS_LOG_FUNCTION (this);
707
692
708
  InitializeCwnd ();
709
710
  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
693
  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
711
  if (m_state != CLOSED)
694
  if (m_state != CLOSED)
712
    {
695
    {
 Lines 1183-1206   TcpSocketBase::DoForwardUp (Ptr<Packet> packet, const Address &fromAddress, Link Here 
1183
1166
1184
  ReadOptions (tcpHeader);
1167
  ReadOptions (tcpHeader);
1185
1168
1186
  if (tcpHeader.GetFlags () & TcpHeader::ACK)
1169
  if (tcpHeader.GetFlags () & TcpHeader::SYN)
1187
    {
1188
      EstimateRtt (tcpHeader);
1189
    }
1190
1191
  // Update Rx window size, i.e. the flow control window
1192
  if (tcpHeader.GetFlags () & TcpHeader::ACK)
1193
    {
1194
      UpdateWindowSize (tcpHeader);
1195
    }
1196
  else if (tcpHeader.GetFlags () & TcpHeader::SYN)
1197
    {
1170
    {
1198
      /* The window field in a segment where the SYN bit is set (i.e., a <SYN>
1171
      /* The window field in a segment where the SYN bit is set (i.e., a <SYN>
1199
       * or <SYN,ACK>) MUST NOT be scaled (from RFC 7323 page 9). But should be
1172
       * or <SYN,ACK>) MUST NOT be scaled (from RFC 7323 page 9). But should be
1200
       * saved anyway..
1173
       * saved anyway..
1201
       */
1174
       */
1202
      m_rWnd = tcpHeader.GetWindowSize ();
1175
      m_rWnd = tcpHeader.GetWindowSize ();
1176
1177
      if (m_tcb->m_initialSsThresh == UINT32_MAX)
1178
        {
1179
          m_tcb->m_initialSsThresh = m_rWnd << m_sndWindShift;
1180
        }
1181
1182
      m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize ();
1183
      m_tcb->m_ssThresh = GetInitialSSThresh ();
1203
    }
1184
    }
1185
  else if (tcpHeader.GetFlags () & TcpHeader::ACK)
1186
    {
1187
      EstimateRtt (tcpHeader);
1188
      UpdateWindowSize (tcpHeader);
1189
    }
1190
1204
1191
1205
  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
1192
  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
1206
    { // Zero window: Enter persist state to send 1 byte to probe
1193
    { // Zero window: Enter persist state to send 1 byte to probe
 Lines 2548-2554   TcpSocketBase::AdvertisedWindowSize () const Link Here 
2548
{
2535
{
2549
  uint32_t w = m_rxBuffer->MaxBufferSize ();
2536
  uint32_t w = m_rxBuffer->MaxBufferSize ();
2550
2537
2551
  w >>= m_sndScaleFactor;
2538
  w >>= m_rcvWindShift;
2552
2539
2553
  if (w > m_maxWinSize)
2540
  if (w > m_maxWinSize)
2554
    {
2541
    {
 Lines 3106-3112   TcpSocketBase::ReadOptions (const TcpHeader& header) Link Here 
3106
            {
3093
            {
3107
              m_winScalingEnabled = true;
3094
              m_winScalingEnabled = true;
3108
              ProcessOptionWScale (header.GetOption (TcpOption::WINSCALE));
3095
              ProcessOptionWScale (header.GetOption (TcpOption::WINSCALE));
3109
              ScaleSsThresh (m_sndScaleFactor);
3110
            }
3096
            }
3111
        }
3097
        }
3112
    }
3098
    }
 Lines 3147-3162   TcpSocketBase::ProcessOptionWScale (const Ptr<const TcpOption> option) Link Here 
3147
3133
3148
  // In naming, we do the contrary of RFC 1323. The received scaling factor
3134
  // In naming, we do the contrary of RFC 1323. The received scaling factor
3149
  // is Rcv.Wind.Scale (and not Snd.Wind.Scale)
3135
  // is Rcv.Wind.Scale (and not Snd.Wind.Scale)
3150
  m_rcvScaleFactor = ws->GetScale ();
3136
  m_sndWindShift = ws->GetScale ();
3151
3137
3152
  if (m_rcvScaleFactor > 14)
3138
  if (m_sndWindShift > 14)
3153
    {
3139
    {
3154
      NS_LOG_WARN ("Possible error; m_rcvScaleFactor exceeds 14: " << m_rcvScaleFactor);
3140
      NS_LOG_WARN ("Possible error; m_sndWindShift exceeds 14: " << m_sndWindShift);
3155
      m_rcvScaleFactor = 14;
3141
      m_sndWindShift = 14;
3156
    }
3142
    }
3157
3143
3158
  NS_LOG_INFO (m_node->GetId () << " Received a scale factor of " <<
3144
  NS_LOG_INFO (m_node->GetId () << " Received a scale factor of " <<
3159
               static_cast<int> (m_rcvScaleFactor));
3145
               static_cast<int> (m_sndWindShift));
3160
}
3146
}
3161
3147
3162
uint8_t
3148
uint8_t
 Lines 3194-3206   TcpSocketBase::AddOptionWScale (TcpHeader &header) Link Here 
3194
  // In naming, we do the contrary of RFC 1323. The sended scaling factor
3180
  // In naming, we do the contrary of RFC 1323. The sended scaling factor
3195
  // is Snd.Wind.Scale (and not Rcv.Wind.Scale)
3181
  // is Snd.Wind.Scale (and not Rcv.Wind.Scale)
3196
3182
3197
  m_sndScaleFactor = CalculateWScale ();
3183
  m_rcvWindShift = CalculateWScale ();
3198
  option->SetScale (m_sndScaleFactor);
3184
  option->SetScale (m_rcvWindShift);
3199
3185
3200
  header.AppendOption (option);
3186
  header.AppendOption (option);
3201
3187
3202
  NS_LOG_INFO (m_node->GetId () << " Send a scaling factor of " <<
3188
  NS_LOG_INFO (m_node->GetId () << " Send a scaling factor of " <<
3203
               static_cast<int> (m_sndScaleFactor));
3189
               static_cast<int> (m_rcvWindShift));
3204
}
3190
}
3205
3191
3206
void
3192
void
 Lines 3236-3242   void TcpSocketBase::UpdateWindowSize (const TcpHeader &header) Link Here 
3236
  //  If the connection is not established, the window size is always
3222
  //  If the connection is not established, the window size is always
3237
  //  updated
3223
  //  updated
3238
  uint32_t receivedWindow = header.GetWindowSize ();
3224
  uint32_t receivedWindow = header.GetWindowSize ();
3239
  receivedWindow <<= m_rcvScaleFactor;
3225
  receivedWindow <<= m_sndWindShift;
3240
  NS_LOG_INFO ("Received (scaled) window is " << receivedWindow << " bytes");
3226
  NS_LOG_INFO ("Received (scaled) window is " << receivedWindow << " bytes");
3241
  if (m_state < ESTABLISHED)
3227
  if (m_state < ESTABLISHED)
3242
    {
3228
    {
(-)a/src/internet/model/tcp-socket-base.h (-22 / +3 lines)
 Lines 895-919   protected: Link Here 
895
   */
895
   */
896
  void AddOptionTimestamp (TcpHeader& header);
896
  void AddOptionTimestamp (TcpHeader& header);
897
897
898
  /**
899
   * \brief Scale the initial SsThresh value to the correct one
900
   *
901
   * Set the initial SsThresh to the largest possible advertised window
902
   * according to the sender scale factor.
903
   *
904
   * \param scaleFactor the sender scale factor
905
   */
906
  virtual void ScaleSsThresh (uint8_t scaleFactor);
907
908
  /**
909
   * \brief Initialize congestion window
910
   *
911
   * Default cWnd to 1 MSS (RFC2001, sec.1) and must
912
   * not be larger than 2 MSS (RFC2581, sec.3.1). Both m_initiaCWnd and
913
   * m_segmentSize are set by the attribute system in ns3::TcpSocket.
914
   */
915
  virtual void InitializeCwnd ();
916
917
protected:
898
protected:
918
  // Counters and events
899
  // Counters and events
919
  EventId           m_retxEvent;       //!< Retransmission event
900
  EventId           m_retxEvent;       //!< Retransmission event
 Lines 972-980   protected: Link Here 
972
  uint32_t                      m_bytesAckedNotProcessed;  //!< Bytes acked, but not processed
953
  uint32_t                      m_bytesAckedNotProcessed;  //!< Bytes acked, but not processed
973
954
974
  // Options
955
  // Options
975
  bool    m_winScalingEnabled;    //!< Window Scale option enabled
956
  bool    m_winScalingEnabled; //!< Window Scale option enabled (RFC 7323)
976
  uint8_t m_sndScaleFactor;       //!< Sent Window Scale (i.e., the one of the node)
957
  uint8_t m_rcvWindShift;      //!< Window shift to apply to outgoing segments
977
  uint8_t m_rcvScaleFactor;       //!< Received Window Scale (i.e., the one of the peer)
958
  uint8_t m_sndWindShift;      //!< Window shift to apply to incoming segments
978
959
979
  bool     m_timestampEnabled;    //!< Timestamp option enabled
960
  bool     m_timestampEnabled;    //!< Timestamp option enabled
980
  uint32_t m_timestampToEcho;     //!< Timestamp to echo
961
  uint32_t m_timestampToEcho;     //!< Timestamp to echo
(-)a/src/internet/model/tcp-socket.cc (-1 / +1 lines)
 Lines 65-71   TcpSocket::GetTypeId (void) Link Here 
65
                   MakeUintegerChecker<uint32_t> ())
65
                   MakeUintegerChecker<uint32_t> ())
66
    .AddAttribute ("InitialSlowStartThreshold",
66
    .AddAttribute ("InitialSlowStartThreshold",
67
                   "TCP initial slow start threshold (bytes)",
67
                   "TCP initial slow start threshold (bytes)",
68
                   UintegerValue (0xffff),
68
                   UintegerValue (UINT32_MAX),
69
                   MakeUintegerAccessor (&TcpSocket::GetInitialSSThresh,
69
                   MakeUintegerAccessor (&TcpSocket::GetInitialSSThresh,
70
                                         &TcpSocket::SetInitialSSThresh),
70
                                         &TcpSocket::SetInitialSSThresh),
71
                   MakeUintegerChecker<uint32_t> ())
71
                   MakeUintegerChecker<uint32_t> ())

Return to bug 2262