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

(-)a/src/internet/model/tcp-socket-base.cc (-31 / +50 lines)
 Lines 1196-1201    Link Here 
1196
      // Initialize cWnd and ssThresh
1196
      // Initialize cWnd and ssThresh
1197
      m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize ();
1197
      m_tcb->m_cWnd = GetInitialCwnd () * GetSegSize ();
1198
      m_tcb->m_ssThresh = GetInitialSSThresh ();
1198
      m_tcb->m_ssThresh = GetInitialSSThresh ();
1199
      
1200
      //Also estimate the RTT for SYN/ACK
1201
      if(tcpHeader.GetFlags () & TcpHeader::ACK)
1202
      {
1203
        EstimateRtt (tcpHeader);
1204
      }
1199
    }
1205
    }
1200
  else if (tcpHeader.GetFlags () & TcpHeader::ACK)
1206
  else if (tcpHeader.GetFlags () & TcpHeader::ACK)
1201
    {
1207
    {
 Lines 1419-1425    Link Here 
1419
            {
1425
            {
1420
              // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit
1426
              // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit
1421
              NS_LOG_INFO ("Limited transmit");
1427
              NS_LOG_INFO ("Limited transmit");
1422
              uint32_t sz = SendDataPacket (m_nextTxSequence, m_tcb->m_segmentSize, true);
1428
              uint32_t sz = SendDataPacket (m_nextTxSequence, m_tcb->m_segmentSize, true, false);
1423
              m_nextTxSequence += sz;
1429
              m_nextTxSequence += sz;
1424
            }
1430
            }
1425
1431
 Lines 1452-1458    Link Here 
1452
            {
1458
            {
1453
              // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit
1459
              // RFC3042 Limited transmit: Send a new packet for each duplicated ACK before fast retransmit
1454
              NS_LOG_INFO ("Limited transmit");
1460
              NS_LOG_INFO ("Limited transmit");
1455
              uint32_t sz = SendDataPacket (m_nextTxSequence, m_tcb->m_segmentSize, true);
1461
              uint32_t sz = SendDataPacket (m_nextTxSequence, m_tcb->m_segmentSize, true, false);
1456
              m_nextTxSequence += sz;
1462
              m_nextTxSequence += sz;
1457
            }
1463
            }
1458
        }
1464
        }
 Lines 2056-2062    Link Here 
2056
2062
2057
/* Send an empty packet with specified TCP flags */
2063
/* Send an empty packet with specified TCP flags */
2058
void
2064
void
2059
TcpSocketBase::SendEmptyPacket (uint8_t flags)
2065
TcpSocketBase::SendEmptyPacket (uint8_t flags, bool isRetransmission)
2060
{
2066
{
2061
  NS_LOG_FUNCTION (this << (uint32_t)flags);
2067
  NS_LOG_FUNCTION (this << (uint32_t)flags);
2062
  Ptr<Packet> p = Create<Packet> ();
2068
  Ptr<Packet> p = Create<Packet> ();
 Lines 2161-2166    Link Here 
2161
    }
2167
    }
2162
2168
2163
  m_txTrace (p, header, this);
2169
  m_txTrace (p, header, this);
2170
  
2171
  if(hasSyn)
2172
  {
2173
    UpdateRTTHistory(s, 0, isRetransmission);
2174
  }
2164
2175
2165
  if (flags & TcpHeader::ACK)
2176
  if (flags & TcpHeader::ACK)
2166
    { // If sending an ACK, cancel the delay ACK as well
2177
    { // If sending an ACK, cancel the delay ACK as well
 Lines 2176-2182    Link Here 
2176
      NS_LOG_LOGIC ("Schedule retransmission timeout at time "
2187
      NS_LOG_LOGIC ("Schedule retransmission timeout at time "
2177
                    << Simulator::Now ().GetSeconds () << " to expire at time "
2188
                    << Simulator::Now ().GetSeconds () << " to expire at time "
2178
                    << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2189
                    << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2179
      m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::SendEmptyPacket, this, flags);
2190
      m_retxEvent = Simulator::Schedule (m_rto, &TcpSocketBase::SendEmptyPacket, this, flags, true);
2180
    }
2191
    }
2181
}
2192
}
2182
2193
 Lines 2328-2343    Link Here 
2328
/* Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
2339
/* Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
2329
    TCP header, and send to TcpL4Protocol */
2340
    TCP header, and send to TcpL4Protocol */
2330
uint32_t
2341
uint32_t
2331
TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
2342
TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck, bool isRetransmission)
2332
{
2343
{
2333
  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
2344
  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
2334
2345
2335
  bool isRetransmission = false;
2336
  if ( seq == m_txBuffer->HeadSequence () )
2337
    {
2338
      isRetransmission = true;
2339
    }
2340
2341
  Ptr<Packet> p = m_txBuffer->CopyFromSequence (maxSize, seq);
2346
  Ptr<Packet> p = m_txBuffer->CopyFromSequence (maxSize, seq);
2342
  uint32_t sz = p->GetSize (); // Size of packet
2347
  uint32_t sz = p->GetSize (); // Size of packet
2343
  uint8_t flags = withAck ? TcpHeader::ACK : 0;
2348
  uint8_t flags = withAck ? TcpHeader::ACK : 0;
 Lines 2458-2479    Link Here 
2458
  m_txTrace (p, header, this);
2464
  m_txTrace (p, header, this);
2459
2465
2460
  // update the history of sequence numbers used to calculate the RTT
2466
  // update the history of sequence numbers used to calculate the RTT
2461
  if (isRetransmission == false)
2467
  UpdateRTTHistory(seq, sz, isRetransmission);
2462
    { // This is the next expected one, just log at end
2463
      m_history.push_back (RttHistory (seq, sz, Simulator::Now () ));
2464
    }
2465
  else
2466
    { // This is a retransmit, find in list and mark as re-tx
2467
      for (RttHistory_t::iterator i = m_history.begin (); i != m_history.end (); ++i)
2468
        {
2469
          if ((seq >= i->seq) && (seq < (i->seq + SequenceNumber32 (i->count))))
2470
            { // Found it
2471
              i->retx = true;
2472
              i->count = ((seq + SequenceNumber32 (sz)) - i->seq); // And update count in hist
2473
              break;
2474
            }
2475
        }
2476
    }
2477
2468
2478
  // Notify the application of the data being sent unless this is a retransmit
2469
  // Notify the application of the data being sent unless this is a retransmit
2479
  if (seq + sz > m_highTxMark)
2470
  if (seq + sz > m_highTxMark)
 Lines 2533-2539    Link Here 
2533
                    " unAck: " << UnAckDataCount ());
2524
                    " unAck: " << UnAckDataCount ());
2534
2525
2535
      uint32_t s = std::min (w, m_tcb->m_segmentSize);  // Send no more than window
2526
      uint32_t s = std::min (w, m_tcb->m_segmentSize);  // Send no more than window
2536
      uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
2527
      uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck, false);
2537
      nPacketsSent++;                             // Count sent this loop
2528
      nPacketsSent++;                             // Count sent this loop
2538
      m_nextTxSequence += sz;                     // Advance next tx sequence
2529
      m_nextTxSequence += sz;                     // Advance next tx sequence
2539
    }
2530
    }
 Lines 2650-2655    Link Here 
2650
}
2641
}
2651
2642
2652
/**
2643
/**
2644
 * \brief Update the RTT history, when we send TCP segments
2645
 * \param seq The sequence number of the TCP segment
2646
 * \param sz The segment's size
2647
 * \param isRetransmission Whether or not the segment is a retransmission
2648
 */
2649
2650
void
2651
TcpSocketBase::UpdateRTTHistory (SequenceNumber32 seq, uint32_t sz, bool isRetransmission)
2652
{
2653
  // update the history of sequence numbers used to calculate the RTT
2654
  if (isRetransmission == false)
2655
  { // This is the next expected one, just log at end
2656
    m_history.push_back (RttHistory (seq, sz, Simulator::Now () ));
2657
  }
2658
  else
2659
  { // This is a retransmit, find in list and mark as re-tx
2660
    for (RttHistory_t::iterator i = m_history.begin (); i != m_history.end (); ++i)
2661
    {
2662
      if ((seq >= i->seq) && (seq < (i->seq + SequenceNumber32 (i->count))))
2663
      { // Found it
2664
        i->retx = true;
2665
        i->count = ((seq + SequenceNumber32 (sz)) - i->seq); // And update count in hist
2666
        break;
2667
      }
2668
    }
2669
  }
2670
}
2671
2672
/**
2653
 * \brief Estimate the RTT
2673
 * \brief Estimate the RTT
2654
 *
2674
 *
2655
 * Called by ForwardUp() to estimate RTT.
2675
 * Called by ForwardUp() to estimate RTT.
 Lines 2907-2913    Link Here 
2907
    {
2927
    {
2908
      if (m_synCount > 0)
2928
      if (m_synCount > 0)
2909
        {
2929
        {
2910
          SendEmptyPacket (TcpHeader::SYN);
2930
          SendEmptyPacket (TcpHeader::SYN, true);
2911
        }
2931
        }
2912
      else
2932
      else
2913
        {
2933
        {
 Lines 2933-2945    Link Here 
2933
    {
2953
    {
2934
      if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2954
      if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2935
        { // Must have lost FIN, re-send
2955
        { // Must have lost FIN, re-send
2936
          SendEmptyPacket (TcpHeader::FIN);
2956
          SendEmptyPacket (TcpHeader::FIN, true);
2937
        }
2957
        }
2938
      return;
2958
      return;
2939
    }
2959
    }
2940
2960
2941
  // Retransmit a data packet: Call SendDataPacket
2961
  // Retransmit a data packet: Call SendDataPacket
2942
  uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true);
2962
  uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true, true);
2943
  // In case of RTO, advance m_nextTxSequence
2963
  // In case of RTO, advance m_nextTxSequence
2944
  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz);
2964
  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz);
2945
2965
(-)a/src/internet/model/tcp-socket-base.h (-2 / +12 lines)
 Lines 562-577    Link Here 
562
   * \param seq the sequence number
562
   * \param seq the sequence number
563
   * \param maxSize the maximum data block to be transmitted (in bytes)
563
   * \param maxSize the maximum data block to be transmitted (in bytes)
564
   * \param withAck forces an ACK to be sent
564
   * \param withAck forces an ACK to be sent
565
   * \param isRetransmission whether the segment is being retransmitted
565
   * \returns the number of bytes sent
566
   * \returns the number of bytes sent
566
   */
567
   */
567
  uint32_t SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck);
568
  uint32_t SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck, bool isRetransmission);
568
569
569
  /**
570
  /**
570
   * \brief Send a empty packet that carries a flag, e.g. ACK
571
   * \brief Send a empty packet that carries a flag, e.g. ACK
571
   *
572
   *
572
   * \param flags the packet's flags
573
   * \param flags the packet's flags
574
   * \param isRetransmission whether the segment is being retransmitted
573
   */
575
   */
574
  virtual void SendEmptyPacket (uint8_t flags);
576
  virtual void SendEmptyPacket (uint8_t flags, bool isRetransmission=false);
575
577
576
  /**
578
  /**
577
   * \brief Send reset and tear down this socket
579
   * \brief Send reset and tear down this socket
 Lines 786-791    Link Here 
786
   * \param tcpHeader the packet's TCP header
788
   * \param tcpHeader the packet's TCP header
787
   */
789
   */
788
  virtual void EstimateRtt (const TcpHeader& tcpHeader);
790
  virtual void EstimateRtt (const TcpHeader& tcpHeader);
791
  
792
  /**
793
   * \brief Update the RTT history, when we send TCP segments
794
   * \param seq The sequence number of the TCP segment
795
   * \param sz The segment's size
796
   * \param isRetransmission Whether or not the segment is a retransmission
797
   */
798
  virtual void UpdateRTTHistory (SequenceNumber32 seq, uint32_t sz, bool isRetransmission);
789
799
790
  /**
800
  /**
791
   * \brief Update buffers w.r.t. ACK
801
   * \brief Update buffers w.r.t. ACK

Return to bug 2302