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

(-)i/src/internet/model/tcp-socket-base.cc (-20 / +70 lines)
 Lines 172-177   TcpSocketBase::GetTypeId (void) Link Here 
172
                     "TCP slow start threshold (bytes)",
172
                     "TCP slow start threshold (bytes)",
173
                     MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace),
173
                     MakeTraceSourceAccessor (&TcpSocketBase::m_ssThTrace),
174
                     "ns3::TracedValueCallback::Uint32")
174
                     "ns3::TracedValueCallback::Uint32")
175
    .AddTraceSource ("NextRxSequence",
176
                     "Next sequence number expected (RCV.NXT)",
177
                     MakeTraceSourceAccessor (&TcpSocketBase::m_rcvNXTTrace),
178
                     "ns3::SequenceNumber32TracedValueCallback")
179
    .AddTraceSource ("UnackSequence",
180
                     "First unacknowledged sequence number (SND.UNA)",
181
                     MakeTraceSourceAccessor (&TcpSocketBase::m_sndUNATrace),
182
                     "ns3::SequenceNumber32TracedValueCallback")
175
    .AddTraceSource ("Tx",
183
    .AddTraceSource ("Tx",
176
                     "Send tcp packet to IP protocol",
184
                     "Send tcp packet to IP protocol",
177
                     MakeTraceSourceAccessor (&TcpSocketBase::m_txTrace),
185
                     MakeTraceSourceAccessor (&TcpSocketBase::m_txTrace),
 Lines 308-313   TcpSocketBase::TcpSocketBase (void) Link Here 
308
  ok = m_tcb->TraceConnectWithoutContext ("CongState",
316
  ok = m_tcb->TraceConnectWithoutContext ("CongState",
309
                                          MakeCallback (&TcpSocketBase::UpdateCongState, this));
317
                                          MakeCallback (&TcpSocketBase::UpdateCongState, this));
310
  NS_ASSERT (ok == true);
318
  NS_ASSERT (ok == true);
319
320
  ok = m_txBuffer->TraceConnectWithoutContext ("UnackSequence",
321
                                               MakeCallback (&TcpSocketBase::UpdateSNDUNA, this));
322
  NS_ASSERT (ok == true);
323
324
  ok = m_rxBuffer->TraceConnectWithoutContext("NextRxSequence",
325
                                              MakeCallback (&TcpSocketBase::UpdateRCVNXT, this));
326
  NS_ASSERT (ok == true);
311
}
327
}
312
328
313
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
329
TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
 Lines 395-400   TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) Link Here 
395
  ok = m_tcb->TraceConnectWithoutContext ("CongState",
411
  ok = m_tcb->TraceConnectWithoutContext ("CongState",
396
                                          MakeCallback (&TcpSocketBase::UpdateCongState, this));
412
                                          MakeCallback (&TcpSocketBase::UpdateCongState, this));
397
  NS_ASSERT (ok == true);
413
  NS_ASSERT (ok == true);
414
415
  ok = m_txBuffer->TraceConnectWithoutContext ("UnackSequence",
416
                                               MakeCallback (&TcpSocketBase::UpdateSNDUNA, this));
417
  NS_ASSERT (ok == true);
418
419
  ok = m_rxBuffer->TraceConnectWithoutContext("NextRxSequence",
420
                                              MakeCallback (&TcpSocketBase::UpdateRCVNXT, this));
421
  NS_ASSERT (ok == true);
398
}
422
}
399
423
400
TcpSocketBase::~TcpSocketBase (void)
424
TcpSocketBase::~TcpSocketBase (void)
 Lines 1289-1300   TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeade Link Here 
1289
  // Different flags are different events
1313
  // Different flags are different events
1290
  if (tcpflags == TcpHeader::ACK)
1314
  if (tcpflags == TcpHeader::ACK)
1291
    {
1315
    {
1292
      if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ())
1316
      if (tcpHeader.GetAckNumber () < GetFirstUnackedSeq ())
1293
        {
1317
        {
1294
          // Case 1:  If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored.
1318
          // Case 1:  If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored.
1295
          // Pag. 72 RFC 793
1319
          // Pag. 72 RFC 793
1296
          NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () <<
1320
          NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () <<
1297
                        " SND.UNA = " << m_txBuffer->HeadSequence ());
1321
                        " SND.UNA = " << GetFirstUnackedSeq ());
1298
1322
1299
          // TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation]
1323
          // TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation]
1300
        }
1324
        }
 Lines 1355-1361   TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) Link Here 
1355
  NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK));
1379
  NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK));
1356
  NS_ASSERT (m_tcb->m_segmentSize > 0);
1380
  NS_ASSERT (m_tcb->m_segmentSize > 0);
1357
1381
1358
  uint32_t bytesAcked = tcpHeader.GetAckNumber () - m_txBuffer->HeadSequence ();
1382
  uint32_t bytesAcked = tcpHeader.GetAckNumber () - GetFirstUnackedSeq ();
1359
  uint32_t segsAcked  = bytesAcked / m_tcb->m_segmentSize;
1383
  uint32_t segsAcked  = bytesAcked / m_tcb->m_segmentSize;
1360
  m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize;
1384
  m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize;
1361
1385
 Lines 1370-1379   TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) Link Here 
1370
                " bytes left: " << m_bytesAckedNotProcessed);
1394
                " bytes left: " << m_bytesAckedNotProcessed);
1371
1395
1372
  NS_LOG_DEBUG ("ACK of " << tcpHeader.GetAckNumber () <<
1396
  NS_LOG_DEBUG ("ACK of " << tcpHeader.GetAckNumber () <<
1373
                " SND.UNA=" << m_txBuffer->HeadSequence () <<
1397
                " SND.UNA=" << GetFirstUnackedSeq () <<
1374
                " SND.NXT=" << m_nextTxSequence);
1398
                " SND.NXT=" << m_nextTxSequence);
1375
1399
1376
  if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence () &&
1400
  if (tcpHeader.GetAckNumber () == GetFirstUnackedSeq () &&
1377
      tcpHeader.GetAckNumber () < m_nextTxSequence &&
1401
      tcpHeader.GetAckNumber () < m_nextTxSequence &&
1378
      packet->GetSize () == 0)
1402
      packet->GetSize () == 0)
1379
    {
1403
    {
 Lines 1432-1443   TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) Link Here 
1432
      // Artificially call PktsAcked. After all, one segment has been ACKed.
1456
      // Artificially call PktsAcked. After all, one segment has been ACKed.
1433
      m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt);
1457
      m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt);
1434
    }
1458
    }
1435
  else if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence () &&
1459
  else if (tcpHeader.GetAckNumber () == GetFirstUnackedSeq () &&
1436
           tcpHeader.GetAckNumber () == m_nextTxSequence)
1460
           tcpHeader.GetAckNumber () == m_nextTxSequence)
1437
    {
1461
    {
1438
      // Dupack, but the ACK is precisely equal to the nextTxSequence
1462
      // Dupack, but the ACK is precisely equal to the nextTxSequence
1439
    }
1463
    }
1440
  else if (tcpHeader.GetAckNumber () > m_txBuffer->HeadSequence ())
1464
  else if (tcpHeader.GetAckNumber () > GetFirstUnackedSeq ())
1441
    { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1465
    { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1442
      bool callCongestionControl = true;
1466
      bool callCongestionControl = true;
1443
      bool resetRTO = true;
1467
      bool resetRTO = true;
 Lines 1503-1509   TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) Link Here 
1503
1527
1504
              callCongestionControl = false; // No congestion control on cWnd show be invoked
1528
              callCongestionControl = false; // No congestion control on cWnd show be invoked
1505
              m_dupAckCount -= segsAcked;    // Update the dupAckCount
1529
              m_dupAckCount -= segsAcked;    // Update the dupAckCount
1506
              m_txBuffer->DiscardUpTo (tcpHeader.GetAckNumber ());  //Bug 1850:  retransmit before newack
1530
              UpdateTxBuffer (tcpHeader.GetAckNumber ());  //Bug 1850:  retransmit before newack
1507
              DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet
1531
              DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet
1508
1532
1509
              if (m_isFirstPartialAck)
1533
              if (m_isFirstPartialAck)
 Lines 2294-2300   TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with Link Here 
2294
  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
2318
  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
2295
2319
2296
  bool isRetransmission = false;
2320
  bool isRetransmission = false;
2297
  if ( seq == m_txBuffer->HeadSequence () )
2321
  if ( seq == GetFirstUnackedSeq () )
2298
    {
2322
    {
2299
      isRetransmission = true;
2323
      isRetransmission = true;
2300
    }
2324
    }
 Lines 2478-2484   TcpSocketBase::SendPendingData (bool withAck) Link Here 
2478
                    " rxwin " << m_rWnd <<
2502
                    " rxwin " << m_rWnd <<
2479
                    " segsize " << m_tcb->m_segmentSize <<
2503
                    " segsize " << m_tcb->m_segmentSize <<
2480
                    " nextTxSeq " << m_nextTxSequence <<
2504
                    " nextTxSeq " << m_nextTxSequence <<
2481
                    " highestRxAck " << m_txBuffer->HeadSequence () <<
2505
                    " highestRxAck " << GetFirstUnackedSeq () <<
2482
                    " pd->Size " << m_txBuffer->Size () <<
2506
                    " pd->Size " << m_txBuffer->Size () <<
2483
                    " pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence));
2507
                    " pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence));
2484
2508
 Lines 2502-2515   uint32_t Link Here 
2502
TcpSocketBase::UnAckDataCount () const
2526
TcpSocketBase::UnAckDataCount () const
2503
{
2527
{
2504
  NS_LOG_FUNCTION (this);
2528
  NS_LOG_FUNCTION (this);
2505
  return m_nextTxSequence.Get () - m_txBuffer->HeadSequence ();
2529
  return m_nextTxSequence.Get () - GetFirstUnackedSeq ();
2506
}
2530
}
2507
2531
2508
uint32_t
2532
uint32_t
2509
TcpSocketBase::BytesInFlight () const
2533
TcpSocketBase::BytesInFlight () const
2510
{
2534
{
2511
  NS_LOG_FUNCTION (this);
2535
  NS_LOG_FUNCTION (this);
2512
  return m_highTxMark.Get () - m_txBuffer->HeadSequence ();
2536
  return m_highTxMark.Get () - GetFirstUnackedSeq ();
2513
}
2537
}
2514
2538
2515
uint32_t
2539
uint32_t
 Lines 2680-2687   TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO) Link Here 
2680
2704
2681
  // Note the highest ACK and tell app to send more
2705
  // Note the highest ACK and tell app to send more
2682
  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2706
  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2683
                " numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed
2707
                " numberAck " << (ack - GetFirstUnackedSeq ())); // Number bytes ack'ed
2684
  m_txBuffer->DiscardUpTo (ack);
2708
  UpdateTxBuffer (ack);
2685
  if (GetTxAvailable () > 0)
2709
  if (GetTxAvailable () > 0)
2686
    {
2710
    {
2687
      NotifySend (GetTxAvailable ());
2711
      NotifySend (GetTxAvailable ());
 Lines 2710-2716   TcpSocketBase::ReTxTimeout () Link Here 
2710
      return;
2734
      return;
2711
    }
2735
    }
2712
  // If all data are received (non-closing socket and nothing to send), just return
2736
  // If all data are received (non-closing socket and nothing to send), just return
2713
  if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence () >= m_highTxMark)
2737
  if (m_state <= ESTABLISHED && GetFirstUnackedSeq () >= m_highTxMark)
2714
    {
2738
    {
2715
      return;
2739
      return;
2716
    }
2740
    }
 Lines 2791-2797   TcpSocketBase::Retransmit () Link Here 
2791
  // If erroneous timeout in closed/timed-wait state, just return
2815
  // If erroneous timeout in closed/timed-wait state, just return
2792
  if (m_state == CLOSED || m_state == TIME_WAIT) return;
2816
  if (m_state == CLOSED || m_state == TIME_WAIT) return;
2793
  // If all data are received (non-closing socket and nothing to send), just return
2817
  // If all data are received (non-closing socket and nothing to send), just return
2794
  if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence () >= m_highTxMark) return;
2818
  if (m_state <= ESTABLISHED && GetFirstUnackedSeq () >= m_highTxMark) return;
2795
2819
2796
  /*
2820
  /*
2797
   * When a TCP sender detects segment loss using the retransmission timer
2821
   * When a TCP sender detects segment loss using the retransmission timer
 Lines 2824-2830   TcpSocketBase::Retransmit () Link Here 
2824
   * are not able to retransmit anything because of local congestion.
2848
   * are not able to retransmit anything because of local congestion.
2825
   */
2849
   */
2826
2850
2827
  m_nextTxSequence = m_txBuffer->HeadSequence (); // Restart from highest Ack
2851
  m_nextTxSequence = GetFirstUnackedSeq (); // Restart from highest Ack
2828
  m_dupAckCount = 0;
2852
  m_dupAckCount = 0;
2829
2853
2830
  if (m_tcb->m_congState != TcpSocketState::CA_LOSS)
2854
  if (m_tcb->m_congState != TcpSocketState::CA_LOSS)
 Lines 2880-2890   TcpSocketBase::DoRetransmit () Link Here 
2880
    }
2904
    }
2881
2905
2882
  // Retransmit a data packet: Call SendDataPacket
2906
  // Retransmit a data packet: Call SendDataPacket
2883
  uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true);
2907
  uint32_t sz = SendDataPacket (GetFirstUnackedSeq (), m_tcb->m_segmentSize, true);
2884
  // In case of RTO, advance m_nextTxSequence
2908
  // In case of RTO, advance m_nextTxSequence
2885
  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz);
2909
  m_nextTxSequence = std::max (m_nextTxSequence.Get (), GetFirstUnackedSeq () + sz);
2886
2910
2887
  NS_LOG_DEBUG ("retxing seq " << m_txBuffer->HeadSequence ());
2911
  NS_LOG_DEBUG ("retxing seq " << GetFirstUnackedSeq ());
2888
}
2912
}
2889
2913
2890
void
2914
void
 Lines 3310-3321   TcpSocketBase::UpdateCongState (TcpSocketState::TcpCongState_t oldValue, Link Here 
3310
}
3334
}
3311
3335
3312
void
3336
void
3337
TcpSocketBase::UpdateRCVNXT (SequenceNumber32 oldValue, SequenceNumber32 newValue)
3338
{
3339
  m_rcvNXTTrace (oldValue, newValue);
3340
}
3341
3342
void
3343
TcpSocketBase::UpdateSNDUNA (SequenceNumber32 oldValue, SequenceNumber32 newValue)
3344
{
3345
  m_sndUNATrace (oldValue, newValue);
3346
}
3347
3348
void
3313
TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo)
3349
TcpSocketBase::SetCongestionControlAlgorithm (Ptr<TcpCongestionOps> algo)
3314
{
3350
{
3315
  NS_LOG_FUNCTION (this << algo);
3351
  NS_LOG_FUNCTION (this << algo);
3316
  m_congestionControl = algo;
3352
  m_congestionControl = algo;
3317
}
3353
}
3318
3354
3355
void
3356
TcpSocketBase::UpdateTxBuffer (SequenceNumber32 seq)
3357
{
3358
  NS_LOG_FUNCTION (this << seq);
3359
  m_txBuffer->DiscardUpTo (seq);
3360
}
3361
3362
SequenceNumber32
3363
TcpSocketBase::GetFirstUnackedSeq () const
3364
{
3365
  NS_LOG_FUNCTION (this);
3366
  return m_txBuffer->HeadSequence ();
3367
}
3368
3319
Ptr<TcpSocketBase>
3369
Ptr<TcpSocketBase>
3320
TcpSocketBase::Fork (void)
3370
TcpSocketBase::Fork (void)
3321
{
3371
{
(-)i/src/internet/model/tcp-socket-base.h (+36 lines)
 Lines 317-322   public: Link Here 
317
  Ptr<TcpRxBuffer> GetRxBuffer (void) const;
317
  Ptr<TcpRxBuffer> GetRxBuffer (void) const;
318
318
319
  /**
319
  /**
320
   * \brief Get the first unacked sequence
321
   * \return sequence number indicating the first unacked seq
322
   */
323
  virtual SequenceNumber32 GetFirstUnackedSeq () const;
324
325
  /**
320
   * \brief Callback pointer for cWnd trace chaining
326
   * \brief Callback pointer for cWnd trace chaining
321
   */
327
   */
322
  TracedCallback<uint32_t, uint32_t> m_cWndTrace;
328
  TracedCallback<uint32_t, uint32_t> m_cWndTrace;
 Lines 327-332   public: Link Here 
327
  TracedCallback<uint32_t, uint32_t> m_ssThTrace;
333
  TracedCallback<uint32_t, uint32_t> m_ssThTrace;
328
334
329
  /**
335
  /**
336
   * \brief Callback pointer for SND.UNA trace chaining
337
   */
338
  TracedCallback<SequenceNumber32, SequenceNumber32> m_sndUNATrace;
339
340
  /**
341
   * \brief Callback pointer for RCV.NXT trace chaining
342
   */
343
  TracedCallback<SequenceNumber32, SequenceNumber32> m_rcvNXTTrace;
344
345
  /**
330
   * \brief Callback pointer for congestion state trace chaining
346
   * \brief Callback pointer for congestion state trace chaining
331
   */
347
   */
332
  TracedCallback<TcpSocketState::TcpCongState_t, TcpSocketState::TcpCongState_t> m_congStateTrace;
348
  TracedCallback<TcpSocketState::TcpCongState_t, TcpSocketState::TcpCongState_t> m_congStateTrace;
 Lines 354-359   public: Link Here 
354
                       TcpSocketState::TcpCongState_t newValue);
370
                       TcpSocketState::TcpCongState_t newValue);
355
371
356
  /**
372
  /**
373
   * \brief Callback function to hook to TcpTxBuffer SND.UNA
374
   * \param oldValue old congestion state value
375
   * \param newValue new congestion state value
376
   */
377
  void UpdateSNDUNA (SequenceNumber32 oldValue, SequenceNumber32 newValue);
378
379
  /**
380
   * \brief Callback function to hook to TcpRxBuffer RCV.NXT
381
   * \param oldValue old congestion state value
382
   * \param newValue new congestion state value
383
   */
384
  void UpdateRCVNXT (SequenceNumber32 oldValue, SequenceNumber32 newValue);
385
386
  /**
357
   * \brief Install a congestion control algorithm on this socket
387
   * \brief Install a congestion control algorithm on this socket
358
   *
388
   *
359
   * \param algo Algorithm to be installed
389
   * \param algo Algorithm to be installed
 Lines 905-910   protected: Link Here 
905
   */
935
   */
906
  virtual void InitializeCwnd ();
936
  virtual void InitializeCwnd ();
907
937
938
  /**
939
   * \brief Discard data in transmission buffer up to seq
940
   * \param seq sequence number correctly acknowledged
941
   */
942
  void UpdateTxBuffer (SequenceNumber32 seq);
943
908
protected:
944
protected:
909
  // Counters and events
945
  // Counters and events
910
  EventId           m_retxEvent;       //!< Retransmission event
946
  EventId           m_retxEvent;       //!< Retransmission event

Return to bug 2112