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

(-)a/src/internet-stack/pending-data.cc (-1 / +1 lines)
 Lines 131-137   Ptr<Packet> PendingData::CopyFromOffset Link Here 
131
  uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
131
  uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
132
  if (s1 == 0)
132
  if (s1 == 0)
133
    {
133
    {
134
      return 0;   // No data requested
134
      return Create<Packet> ();   // No data requested
135
    }
135
    }
136
  if (data.size() != 0)
136
  if (data.size() != 0)
137
    { // Actual data exists, make copy and return it
137
    { // Actual data exists, make copy and return it
(-)a/src/internet-stack/tcp-socket-impl.cc (-44 / +121 lines)
 Lines 76-85   TcpSocketImpl::GetTypeId () Link Here 
76
    m_highestRxAck (0),
76
    m_highestRxAck (0),
77
    m_lastRxAck (0),
77
    m_lastRxAck (0),
78
    m_nextRxSequence (0),
78
    m_nextRxSequence (0),
79
    m_rxAvailable (0),
80
    m_rxBufSize (0),
79
    m_pendingData (0),
81
    m_pendingData (0),
82
    m_rxWindowSize (0),
83
    m_persistTime (Seconds(6)), //XXX hook this into attributes?
80
    m_rtt (0),
84
    m_rtt (0),
81
    m_lastMeasuredRtt (Seconds(0.0)),
85
    m_lastMeasuredRtt (Seconds(0.0))
82
    m_rxAvailable (0)
83
{
86
{
84
  NS_LOG_FUNCTION (this);
87
  NS_LOG_FUNCTION (this);
85
}
88
}
 Lines 112-131   TcpSocketImpl::TcpSocketImpl(const TcpSo Link Here 
112
    m_highestRxAck (sock.m_highestRxAck),
115
    m_highestRxAck (sock.m_highestRxAck),
113
    m_lastRxAck (sock.m_lastRxAck),
116
    m_lastRxAck (sock.m_lastRxAck),
114
    m_nextRxSequence (sock.m_nextRxSequence),
117
    m_nextRxSequence (sock.m_nextRxSequence),
118
    m_rxAvailable (0),
119
    m_rxBufSize (0),
115
    m_pendingData (0),
120
    m_pendingData (0),
116
    m_segmentSize (sock.m_segmentSize),
121
    m_segmentSize (sock.m_segmentSize),
117
    m_rxWindowSize (sock.m_rxWindowSize),
122
    m_rxWindowSize (sock.m_rxWindowSize),
118
    m_advertisedWindowSize (sock.m_advertisedWindowSize),
119
    m_cWnd (sock.m_cWnd),
123
    m_cWnd (sock.m_cWnd),
120
    m_ssThresh (sock.m_ssThresh),
124
    m_ssThresh (sock.m_ssThresh),
121
    m_initialCWnd (sock.m_initialCWnd),
125
    m_initialCWnd (sock.m_initialCWnd),
126
    m_persistTime (sock.m_persistTime),
122
    m_rtt (0),
127
    m_rtt (0),
123
    m_lastMeasuredRtt (Seconds(0.0)),
128
    m_lastMeasuredRtt (Seconds(0.0)),
124
    m_cnTimeout (sock.m_cnTimeout),
129
    m_cnTimeout (sock.m_cnTimeout),
125
    m_cnCount (sock.m_cnCount),
130
    m_cnCount (sock.m_cnCount),
126
    m_rxAvailable (0),
127
    m_sndBufSize (sock.m_sndBufSize),
131
    m_sndBufSize (sock.m_sndBufSize),
128
    m_rcvBufSize(sock.m_rcvBufSize)
132
    m_rxBufMaxSize(sock.m_rxBufMaxSize)
129
{
133
{
130
  NS_LOG_FUNCTION_NOARGS ();
134
  NS_LOG_FUNCTION_NOARGS ();
131
  NS_LOG_LOGIC("Invoked the copy constructor");
135
  NS_LOG_LOGIC("Invoked the copy constructor");
 Lines 176-182   TcpSocketImpl::SetNode (Ptr<Node> node) Link Here 
176
  m_node = node;
180
  m_node = node;
177
  // Initialize some variables 
181
  // Initialize some variables 
178
  m_cWnd = m_initialCWnd * m_segmentSize;
182
  m_cWnd = m_initialCWnd * m_segmentSize;
179
  m_rxWindowSize = m_advertisedWindowSize;
180
}
183
}
181
184
182
void 
185
void 
 Lines 212-217   TcpSocketImpl::Destroy (void) Link Here 
212
  m_node = 0;
215
  m_node = 0;
213
  m_endPoint = 0;
216
  m_endPoint = 0;
214
  m_tcp = 0;
217
  m_tcp = 0;
218
  NS_LOG_LOGIC (this<<" Cancelled ReTxTimeout event which was set to expire at "
219
                << (Simulator::Now () + 
220
                Simulator::GetDelayLeft (m_retxEvent)).GetSeconds());
215
  m_retxEvent.Cancel ();
221
  m_retxEvent.Cancel ();
216
}
222
}
217
int
223
int
 Lines 492-497   TcpSocketImpl::Recv (uint32_t maxSize, u Link Here 
492
          out[i->first]  = i->second;
498
          out[i->first]  = i->second;
493
        }
499
        }
494
      m_rxAvailable -= i->second->GetSize ();
500
      m_rxAvailable -= i->second->GetSize ();
501
      m_rxBufSize -= i->second->GetSize ();
495
      m_bufferedData.erase (i);     // Remove from list
502
      m_bufferedData.erase (i);     // Remove from list
496
    }
503
    }
497
  if (out.size() == 0)
504
  if (out.size() == 0)
 Lines 514-519   TcpSocketImpl::Recv (uint32_t maxSize, u Link Here 
514
      m_bufferedData[i->first+SequenceNumber(avail)] 
521
      m_bufferedData[i->first+SequenceNumber(avail)] 
515
          = i->second->CreateFragment(avail,i->second->GetSize()-avail);
522
          = i->second->CreateFragment(avail,i->second->GetSize()-avail);
516
      m_rxAvailable += i->second->GetSize()-avail;
523
      m_rxAvailable += i->second->GetSize()-avail;
524
      m_rxBufSize += i->second->GetSize()-avail;
517
    }
525
    }
518
  }
526
  }
519
  return outPacket;
527
  return outPacket;
 Lines 570-575   TcpSocketImpl::ForwardUp (Ptr<Packet> pa Link Here 
570
          m_lastMeasuredRtt = m;
578
          m_lastMeasuredRtt = m;
571
        }
579
        }
572
    }
580
    }
581
582
  if (m_rxWindowSize == 0 && tcpHeader.GetWindowSize () != 0) 
583
    { //persist probes end
584
      NS_LOG_LOGIC (this<<" Leaving zerowindow persist state");
585
      m_persistEvent.Cancel ();
586
    }
587
  m_rxWindowSize = tcpHeader.GetWindowSize (); //update the flow control window
573
588
574
  Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
589
  Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
575
  Actions_t action = ProcessEvent (event); //updates the state
590
  Actions_t action = ProcessEvent (event); //updates the state
 Lines 632-638   Actions_t TcpSocketImpl::ProcessEvent (E Link Here 
632
647
633
void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
648
void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
634
{
649
{
635
  NS_LOG_FUNCTION (this << flags);
650
  NS_LOG_FUNCTION (this << (uint32_t)flags);
636
  Ptr<Packet> p = Create<Packet> ();
651
  Ptr<Packet> p = Create<Packet> ();
637
  TcpHeader header;
652
  TcpHeader header;
638
653
 Lines 641-647   void TcpSocketImpl::SendEmptyPacket (uin Link Here 
641
  header.SetAckNumber (m_nextRxSequence);
656
  header.SetAckNumber (m_nextRxSequence);
642
  header.SetSourcePort (m_endPoint->GetLocalPort ());
657
  header.SetSourcePort (m_endPoint->GetLocalPort ());
643
  header.SetDestinationPort (m_remotePort);
658
  header.SetDestinationPort (m_remotePort);
644
  header.SetWindowSize (m_advertisedWindowSize);
659
  header.SetWindowSize (AdvertisedWindowSize());
645
  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), 
660
  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), 
646
    m_remoteAddress);
661
    m_remoteAddress);
647
  Time rto = m_rtt->RetransmitTimeout ();
662
  Time rto = m_rtt->RetransmitTimeout ();
 Lines 651-659   void TcpSocketImpl::SendEmptyPacket (uin Link Here 
651
      m_cnTimeout = m_cnTimeout + m_cnTimeout;
666
      m_cnTimeout = m_cnTimeout + m_cnTimeout;
652
      m_cnCount--;
667
      m_cnCount--;
653
    }
668
    }
654
  if (m_retxEvent.IsExpired () ) //no outstanding timer
669
  bool isAck =  (flags == TcpHeader::ACK);
670
  if (m_retxEvent.IsExpired () && !isAck) //no outstanding timer
655
  {
671
  {
656
    NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
672
    NS_LOG_LOGIC (this<<" Schedule ReTxTimeout at time " 
657
          << Simulator::Now ().GetSeconds () << " to expire at time " 
673
          << Simulator::Now ().GetSeconds () << " to expire at time " 
658
          << (Simulator::Now () + rto).GetSeconds ());
674
          << (Simulator::Now () + rto).GetSeconds ());
659
    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
675
    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
 Lines 790-796   bool TcpSocketImpl::ProcessPacketAction Link Here 
790
      NS_LOG_DEBUG ("TcpSocketImpl " << this << " ACK_TX_1" <<
806
      NS_LOG_DEBUG ("TcpSocketImpl " << this << " ACK_TX_1" <<
791
                    " nextRxSeq " << m_nextRxSequence);
807
                    " nextRxSeq " << m_nextRxSequence);
792
      SendEmptyPacket (TcpHeader::ACK);
808
      SendEmptyPacket (TcpHeader::ACK);
793
      m_rxWindowSize = tcpHeader.GetWindowSize ();
794
      if (tcpHeader.GetAckNumber () > m_highestRxAck)
809
      if (tcpHeader.GetAckNumber () > m_highestRxAck)
795
      {
810
      {
796
        m_highestRxAck = tcpHeader.GetAckNumber ();
811
        m_highestRxAck = tcpHeader.GetAckNumber ();
 Lines 808-820   bool TcpSocketImpl::ProcessPacketAction Link Here 
808
      {
823
      {
809
        break;
824
        break;
810
      }
825
      }
811
      if (tcpHeader.GetAckNumber () == m_highestRxAck && 
826
      if (tcpHeader.GetAckNumber () == m_highestRxAck)
812
         tcpHeader.GetAckNumber ()  < m_nextTxSequence)
813
      {
827
      {
814
        DupAck (tcpHeader, ++m_dupAckCount);
828
        if (tcpHeader.GetAckNumber ()  < m_nextTxSequence)
829
        {
830
          DupAck (tcpHeader, ++m_dupAckCount);
831
        }
832
        NS_ASSERT(tcpHeader.GetAckNumber ()  <= m_nextTxSequence);
833
        //if the ack is precisely equal to the nextTxSequence
815
        break;
834
        break;
816
      }
835
      }
817
      if (tcpHeader.GetAckNumber () > m_highestRxAck)  
836
      if (tcpHeader.GetAckNumber () > m_highestRxAck)
818
        {
837
        {
819
          m_dupAckCount = 0;
838
          m_dupAckCount = 0;
820
        }
839
        }
 Lines 928-934   bool TcpSocketImpl::SendPendingData (boo Link Here 
928
           << " highestRxAck " << m_highestRxAck 
947
           << " highestRxAck " << m_highestRxAck 
929
           << " pd->Size " << m_pendingData->Size ()
948
           << " pd->Size " << m_pendingData->Size ()
930
           << " pd->SFS " << m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence));
949
           << " pd->SFS " << m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence));
931
950
//XXX pd->Size is probably a bug, should be SizeFromSeq(...)
932
      if (w < m_segmentSize && m_pendingData->Size () > w)
951
      if (w < m_segmentSize && m_pendingData->Size () > w)
933
        {
952
        {
934
          break; // No more
953
          break; // No more
 Lines 961-966   bool TcpSocketImpl::SendPendingData (boo Link Here 
961
      header.SetAckNumber (m_nextRxSequence);
980
      header.SetAckNumber (m_nextRxSequence);
962
      header.SetSourcePort (m_endPoint->GetLocalPort());
981
      header.SetSourcePort (m_endPoint->GetLocalPort());
963
      header.SetDestinationPort (m_remotePort);
982
      header.SetDestinationPort (m_remotePort);
983
      header.SetWindowSize (AdvertisedWindowSize());
964
      if (m_shutdownSend)
984
      if (m_shutdownSend)
965
        {
985
        {
966
          m_errno = ERROR_SHUTDOWN;
986
          m_errno = ERROR_SHUTDOWN;
 Lines 971-977   bool TcpSocketImpl::SendPendingData (boo Link Here 
971
      if (m_retxEvent.IsExpired () ) //go ahead and schedule the retransmit
991
      if (m_retxEvent.IsExpired () ) //go ahead and schedule the retransmit
972
        {
992
        {
973
            Time rto = m_rtt->RetransmitTimeout (); 
993
            Time rto = m_rtt->RetransmitTimeout (); 
974
            NS_LOG_LOGIC ("SendPendingData Schedule retransmission timeout at time " << 
994
            NS_LOG_LOGIC (this<<" SendPendingData Schedule ReTxTimeout at time " << 
975
              Simulator::Now ().GetSeconds () << " to expire at time " <<
995
              Simulator::Now ().GetSeconds () << " to expire at time " <<
976
              (Simulator::Now () + rto).GetSeconds () );
996
              (Simulator::Now () + rto).GetSeconds () );
977
          m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
997
          m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
 Lines 1024-1029   uint32_t TcpSocketImpl::AvailableWindow Link Here 
1024
  return (win - unack);       // Amount of window space available
1044
  return (win - unack);       // Amount of window space available
1025
}
1045
}
1026
1046
1047
uint32_t TcpSocketImpl::RxBufferFreeSpace()
1048
{
1049
  return m_rxBufMaxSize - m_rxBufSize;
1050
}
1051
1052
uint16_t TcpSocketImpl::AdvertisedWindowSize()
1053
{
1054
  uint32_t max = 0xffff;
1055
  return std::min(RxBufferFreeSpace(), max);
1056
}
1057
1027
void TcpSocketImpl::NewRx (Ptr<Packet> p,
1058
void TcpSocketImpl::NewRx (Ptr<Packet> p,
1028
                        const TcpHeader& tcpHeader, 
1059
                        const TcpHeader& tcpHeader, 
1029
                        const Address& fromAddress)
1060
                        const Address& fromAddress)
 Lines 1039-1047   void TcpSocketImpl::NewRx (Ptr<Packet> p Link Here 
1039
                " ack " << tcpHeader.GetAckNumber() <<
1070
                " ack " << tcpHeader.GetAckNumber() <<
1040
                " p.size is " << p->GetSize());
1071
                " p.size is " << p->GetSize());
1041
  States_t origState = m_state;
1072
  States_t origState = m_state;
1073
  if (RxBufferFreeSpace() < p->GetSize()) 
1074
    { //if not enough room, fragment
1075
      p = p->CreateFragment(0, RxBufferFreeSpace());
1076
    }
1077
  //XXX
1078
  //fragmenting here MIGHT not be the right thing to do, since possibly we trim
1079
  //the front and back off the packet below if it isn't all new data, so the 
1080
  //check against RxBufferFreeSpace and fragmentation should ideally occur
1081
  //just before insertion into m_bufferedData, but this strategy is more
1082
  //agressive in rejecting oversized packets and still gives acceptable TCP
1042
  uint32_t s = p->GetSize ();  // Size of associated data
1083
  uint32_t s = p->GetSize ();  // Size of associated data
1043
  if (s == 0)
1084
  if (s == 0)
1044
    {// Nothing to do if no associated data
1085
    {//if there is no data or no rx buffer space, just ack anyway
1086
      SendEmptyPacket (TcpHeader::ACK);
1045
      return;
1087
      return;
1046
    }
1088
    }
1047
  // Log sequence received if enabled
1089
  // Log sequence received if enabled
 Lines 1074-1087   void TcpSocketImpl::NewRx (Ptr<Packet> p Link Here 
1074
      //buffer this, it'll be read by call to Recv
1116
      //buffer this, it'll be read by call to Recv
1075
      UnAckData_t::iterator i = 
1117
      UnAckData_t::iterator i = 
1076
          m_bufferedData.find (tcpHeader.GetSequenceNumber () );
1118
          m_bufferedData.find (tcpHeader.GetSequenceNumber () );
1077
      if (i != m_bufferedData.end () ) //we found it already in the buffer
1119
      NS_ASSERT(i == m_bufferedData.end ()); //no way it should have been found
1078
      {
1120
      // Save for later delivery if there is room
1079
        i->second = 0; // relase reference to already buffered
1121
      m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;
1080
      }
1081
      // Save for later delivery
1082
      m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;  
1083
      m_rxAvailable += p->GetSize ();
1122
      m_rxAvailable += p->GetSize ();
1084
      RxBufFinishInsert (tcpHeader.GetSequenceNumber ());
1123
      RxBufFinishInsert (tcpHeader.GetSequenceNumber ());
1124
      m_rxBufSize += p->GetSize ();
1085
      NotifyDataRecv ();
1125
      NotifyDataRecv ();
1086
      if (m_closeNotified)
1126
      if (m_closeNotified)
1087
        {
1127
        {
 Lines 1181-1186   void TcpSocketImpl::NewRx (Ptr<Packet> p Link Here 
1181
      // Save for later delivery
1221
      // Save for later delivery
1182
      m_bufferedData[start] = p;
1222
      m_bufferedData[start] = p;
1183
      m_rxAvailable += p->GetSize ();
1223
      m_rxAvailable += p->GetSize ();
1224
      m_rxBufSize += p->GetSize();
1184
      RxBufFinishInsert(start);
1225
      RxBufFinishInsert(start);
1185
      NotifyDataRecv ();
1226
      NotifyDataRecv ();
1186
    }
1227
    }
 Lines 1248-1260   void TcpSocketImpl::CommonNewAck (Sequen Link Here 
1248
  //DEBUG(1,(cout << "TCP " << this << "Cancelling retx timer " << endl));
1289
  //DEBUG(1,(cout << "TCP " << this << "Cancelling retx timer " << endl));
1249
  if (!skipTimer)
1290
  if (!skipTimer)
1250
    {
1291
    {
1251
      m_retxEvent.Cancel ();  
1292
      NS_LOG_LOGIC (this<<" Cancelled ReTxTimeout event which was set to expire at "
1293
                    << (Simulator::Now () + 
1294
                        Simulator::GetDelayLeft (m_retxEvent)).GetSeconds());
1295
      m_retxEvent.Cancel ();
1252
      //On recieving a "New" ack we restart retransmission timer .. RFC 2988
1296
      //On recieving a "New" ack we restart retransmission timer .. RFC 2988
1253
      Time rto = m_rtt->RetransmitTimeout ();
1297
      Time rto = m_rtt->RetransmitTimeout ();
1254
      NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
1298
      NS_LOG_LOGIC (this<<" Schedule ReTxTimeout at time " 
1255
          << Simulator::Now ().GetSeconds () << " to expire at time " 
1299
          << Simulator::Now ().GetSeconds () << " to expire at time " 
1256
          << (Simulator::Now () + rto).GetSeconds ());
1300
          << (Simulator::Now () + rto).GetSeconds ());
1257
    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
1301
      m_retxEvent = 
1302
          Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
1303
    }
1304
  if (m_rxWindowSize == 0 && m_persistEvent.IsExpired ()) //zerowindow
1305
    {
1306
      NS_LOG_LOGIC (this<<"Enter zerowindow persist state");
1307
      NS_LOG_LOGIC (this<<" Cancelled ReTxTimeout event which was set to expire at "
1308
                    << (Simulator::Now () + 
1309
                        Simulator::GetDelayLeft (m_retxEvent)).GetSeconds());
1310
      m_retxEvent.Cancel ();
1311
      NS_LOG_LOGIC ("Schedule persist timeout at time " 
1312
                    <<Simulator::Now ().GetSeconds () << " to expire at time "
1313
                    << (Simulator::Now () + m_persistTime).GetSeconds());
1314
      m_persistEvent = 
1315
      Simulator::Schedule (m_persistTime, &TcpSocketImpl::PersistTimeout, this);
1316
      NS_ASSERT (m_persistTime == Simulator::GetDelayLeft (m_persistEvent));
1258
    }
1317
    }
1259
  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack 
1318
  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack 
1260
           << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
1319
           << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
 Lines 1276-1281   void TcpSocketImpl::CommonNewAck (Sequen Link Here 
1276
          delete m_pendingData;
1335
          delete m_pendingData;
1277
          m_pendingData = 0;
1336
          m_pendingData = 0;
1278
          // Insure no re-tx timer
1337
          // Insure no re-tx timer
1338
          NS_LOG_LOGIC (this<<" Cancelled ReTxTimeout event which was set to expire at "
1339
                    << (Simulator::Now () + 
1340
                        Simulator::GetDelayLeft (m_retxEvent)).GetSeconds());
1279
          m_retxEvent.Cancel ();
1341
          m_retxEvent.Cancel ();
1280
        }
1342
        }
1281
    }
1343
    }
 Lines 1341-1346   void TcpSocketImpl::ReTxTimeout () Link Here 
1341
void TcpSocketImpl::ReTxTimeout ()
1403
void TcpSocketImpl::ReTxTimeout ()
1342
{ // Retransmit timeout
1404
{ // Retransmit timeout
1343
  NS_LOG_FUNCTION (this);
1405
  NS_LOG_FUNCTION (this);
1406
  NS_LOG_LOGIC (this<<" ReTxTimeout Expired at time "<<Simulator::Now ().GetSeconds());
1344
  m_ssThresh = Window () / 2; // Per RFC2581
1407
  m_ssThresh = Window () / 2; // Per RFC2581
1345
  m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
1408
  m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
1346
  // Set cWnd to segSize on timeout,  per rfc2581
1409
  // Set cWnd to segSize on timeout,  per rfc2581
 Lines 1363-1368   void TcpSocketImpl::LastAckTimeout () Link Here 
1363
    {
1426
    {
1364
      m_closeNotified = true;
1427
      m_closeNotified = true;
1365
    }
1428
    }
1429
}
1430
1431
void TcpSocketImpl::PersistTimeout ()
1432
{
1433
  NS_LOG_LOGIC ("PersistTimeout expired at "<<Simulator::Now ().GetSeconds ());
1434
  m_persistTime = Scalar(2)*m_persistTime;
1435
  m_persistTime = std::min(Seconds(60),m_persistTime); //maxes out at 60
1436
  //the persist timeout sends exactly one byte probes
1437
  //this is explicit in stevens, and kind of in rfc793 p42, rfc1122 sec4.2.2.17
1438
  Ptr<Packet> p =
1439
    m_pendingData->CopyFromSeq(1,m_firstPendingSequence,m_nextTxSequence);
1440
  TcpHeader tcpHeader;
1441
  tcpHeader.SetSequenceNumber (m_nextTxSequence);
1442
  tcpHeader.SetAckNumber (m_nextRxSequence);
1443
  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
1444
  tcpHeader.SetDestinationPort (m_remotePort);
1445
  tcpHeader.SetWindowSize (AdvertisedWindowSize());
1446
1447
  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
1448
    m_remoteAddress);
1449
  NS_LOG_LOGIC ("Schedule persist timeout at time " 
1450
                    <<Simulator::Now ().GetSeconds () << " to expire at time "
1451
                    << (Simulator::Now () + m_persistTime).GetSeconds());
1452
  m_persistEvent = 
1453
    Simulator::Schedule (m_persistTime, &TcpSocketImpl::PersistTimeout, this);
1366
}
1454
}
1367
1455
1368
void TcpSocketImpl::Retransmit ()
1456
void TcpSocketImpl::Retransmit ()
 Lines 1390-1398   void TcpSocketImpl::Retransmit () Link Here 
1390
        }
1478
        }
1391
      return;
1479
      return;
1392
    }
1480
    }
1481
  NS_ASSERT(m_nextTxSequence == m_highestRxAck);
1393
  Ptr<Packet> p = m_pendingData->CopyFromSeq (m_segmentSize,
1482
  Ptr<Packet> p = m_pendingData->CopyFromSeq (m_segmentSize,
1394
                                            m_firstPendingSequence,
1483
                                            m_firstPendingSequence,
1395
                                            m_highestRxAck);
1484
                                            m_nextTxSequence);
1396
  // Calculate remaining data for COE check
1485
  // Calculate remaining data for COE check
1397
  uint32_t remainingData = m_pendingData->SizeFromSeq (
1486
  uint32_t remainingData = m_pendingData->SizeFromSeq (
1398
      m_firstPendingSequence,
1487
      m_firstPendingSequence,
 Lines 1406-1412   void TcpSocketImpl::Retransmit () Link Here 
1406
  if (m_retxEvent.IsExpired () )
1495
  if (m_retxEvent.IsExpired () )
1407
    {
1496
    {
1408
      Time rto = m_rtt->RetransmitTimeout ();
1497
      Time rto = m_rtt->RetransmitTimeout ();
1409
      NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1498
      NS_LOG_LOGIC (this<<" Schedule ReTxTimeout at time "
1410
          << Simulator::Now ().GetSeconds () << " to expire at time "
1499
          << Simulator::Now ().GetSeconds () << " to expire at time "
1411
          << (Simulator::Now () + rto).GetSeconds ());
1500
          << (Simulator::Now () + rto).GetSeconds ());
1412
      m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
1501
      m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
 Lines 1419-1425   void TcpSocketImpl::Retransmit () Link Here 
1419
  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
1508
  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
1420
  tcpHeader.SetDestinationPort (m_remotePort);
1509
  tcpHeader.SetDestinationPort (m_remotePort);
1421
  tcpHeader.SetFlags (flags);
1510
  tcpHeader.SetFlags (flags);
1422
  tcpHeader.SetWindowSize (m_advertisedWindowSize);
1511
  tcpHeader.SetWindowSize (AdvertisedWindowSize());
1423
1512
1424
  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
1513
  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
1425
    m_remoteAddress);
1514
    m_remoteAddress);
 Lines 1440-1452   void Link Here 
1440
void
1529
void
1441
TcpSocketImpl::SetRcvBufSize (uint32_t size)
1530
TcpSocketImpl::SetRcvBufSize (uint32_t size)
1442
{
1531
{
1443
  m_rcvBufSize = size;
1532
  m_rxBufMaxSize = size;
1444
}
1533
}
1445
1534
1446
uint32_t
1535
uint32_t
1447
TcpSocketImpl::GetRcvBufSize (void) const
1536
TcpSocketImpl::GetRcvBufSize (void) const
1448
{
1537
{
1449
  return m_rcvBufSize;
1538
  return m_rxBufMaxSize;
1450
}
1539
}
1451
1540
1452
void
1541
void
 Lines 1459-1476   TcpSocketImpl::GetSegSize (void) const Link Here 
1459
TcpSocketImpl::GetSegSize (void) const
1548
TcpSocketImpl::GetSegSize (void) const
1460
{
1549
{
1461
  return m_segmentSize;
1550
  return m_segmentSize;
1462
}
1463
1464
void
1465
TcpSocketImpl::SetAdvWin (uint32_t window)
1466
{
1467
  m_advertisedWindowSize = window;
1468
}
1469
1470
uint32_t
1471
TcpSocketImpl::GetAdvWin (void) const
1472
{
1473
  return m_advertisedWindowSize;
1474
}
1551
}
1475
1552
1476
void
1553
void
(-)a/src/internet-stack/tcp-socket-impl.h (-12 / +22 lines)
 Lines 121-126   private: Link Here 
121
  virtual uint32_t  Window();         // Return window size (integer)
121
  virtual uint32_t  Window();         // Return window size (integer)
122
  virtual uint32_t  AvailableWindow();// Return unfilled portion of window
122
  virtual uint32_t  AvailableWindow();// Return unfilled portion of window
123
123
124
  //methods for Rx buffer management
125
  uint32_t RxBufferFreeSpace();
126
  uint16_t AdvertisedWindowSize();
127
124
  // Manage data tx/rx
128
  // Manage data tx/rx
125
  void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
129
  void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
126
  void RxBufFinishInsert (SequenceNumber);
130
  void RxBufFinishInsert (SequenceNumber);
 Lines 132-137   private: Link Here 
132
  void ReTxTimeout ();
136
  void ReTxTimeout ();
133
  void DelAckTimeout ();
137
  void DelAckTimeout ();
134
  void LastAckTimeout ();
138
  void LastAckTimeout ();
139
  void PersistTimeout ();
135
  void Retransmit ();
140
  void Retransmit ();
136
  void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
141
  void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
137
142
 Lines 142-149   private: Link Here 
142
  virtual uint32_t GetRcvBufSize (void) const;
147
  virtual uint32_t GetRcvBufSize (void) const;
143
  virtual void SetSegSize (uint32_t size);
148
  virtual void SetSegSize (uint32_t size);
144
  virtual uint32_t GetSegSize (void) const;
149
  virtual uint32_t GetSegSize (void) const;
145
  virtual void SetAdvWin (uint32_t window);
146
  virtual uint32_t GetAdvWin (void) const;
147
  virtual void SetSSThresh (uint32_t threshold);
150
  virtual void SetSSThresh (uint32_t threshold);
148
  virtual uint32_t GetSSThresh (void) const;
151
  virtual uint32_t GetSSThresh (void) const;
149
  virtual void SetInitialCwnd (uint32_t cwnd);
152
  virtual void SetInitialCwnd (uint32_t cwnd);
 Lines 195-216   private: Link Here 
195
  SequenceNumber m_lastRxAck;
198
  SequenceNumber m_lastRxAck;
196
  
199
  
197
  //sequence info, reciever side
200
  //sequence info, reciever side
198
  SequenceNumber m_nextRxSequence;
201
  SequenceNumber m_nextRxSequence; //next expected sequence
199
202
200
  //history data
203
  //Rx buffer
201
  //this is the incoming data buffer which sorts out of sequence data
204
  UnAckData_t m_bufferedData; //buffer which sorts out of sequence data
202
  UnAckData_t m_bufferedData;
205
  //Rx buffer state
206
  uint32_t m_rxAvailable; // amount of data available for reading through Recv
207
  uint32_t m_rxBufSize; //size in bytes of the data in the rx buf
208
  //note that these two are not the same: rxAvailbale is the number of
209
  //contiguous sequenced bytes that can be read, rxBufSize is the TOTAL size
210
  //including out of sequence data, such that m_rxAvailable <= m_rxBufSize
211
203
  //this is kind of the tx buffer
212
  //this is kind of the tx buffer
204
  PendingData* m_pendingData;
213
  PendingData* m_pendingData;
205
  SequenceNumber m_firstPendingSequence;
214
  SequenceNumber m_firstPendingSequence;
206
215
207
  // Window management
216
  // Window management
208
  uint32_t                       m_segmentSize;          //SegmentSize
217
  uint32_t                       m_segmentSize;          //SegmentSize
209
  uint32_t                       m_rxWindowSize;
218
  uint32_t                       m_rxWindowSize;         //Flow control window
210
  uint32_t                       m_advertisedWindowSize; //Window to advertise
211
  TracedValue<uint32_t>          m_cWnd;                 //Congestion window
219
  TracedValue<uint32_t>          m_cWnd;                 //Congestion window
212
  uint32_t                       m_ssThresh;             //Slow Start Threshold
220
  uint32_t                       m_ssThresh;             //Slow Start Threshold
213
  uint32_t                       m_initialCWnd;          //Initial cWnd value
221
  uint32_t                       m_initialCWnd;          //Initial cWnd value
222
223
  //persist timer management
224
  Time                           m_persistTime;
225
  EventId                        m_persistEvent;
226
  
214
227
215
  // Round trip time estimation
228
  // Round trip time estimation
216
  Ptr<RttEstimator> m_rtt;
229
  Ptr<RttEstimator> m_rtt;
 Lines 220-231   private: Link Here 
220
  Time              m_cnTimeout; 
233
  Time              m_cnTimeout; 
221
  uint32_t          m_cnCount;
234
  uint32_t          m_cnCount;
222
235
223
  // Temporary queue for delivering data to application
224
  uint32_t m_rxAvailable;
225
226
  // Attributes
236
  // Attributes
227
  uint32_t m_sndBufSize;   // buffer limit for the outgoing queue
237
  uint32_t m_sndBufSize;   // buffer limit for the outgoing queue
228
  uint32_t m_rcvBufSize;   // maximum receive socket buffer size
238
  uint32_t m_rxBufMaxSize;   // maximum receive socket buffer size
229
};
239
};
230
240
231
}//namespace ns3
241
}//namespace ns3
(-)a/src/node/tcp-socket.cc (-6 lines)
 Lines 55-66   TcpSocket::GetTypeId (void) Link Here 
55
                   MakeUintegerAccessor (&TcpSocket::GetSegSize,
55
                   MakeUintegerAccessor (&TcpSocket::GetSegSize,
56
                                         &TcpSocket::SetSegSize),
56
                                         &TcpSocket::SetSegSize),
57
                   MakeUintegerChecker<uint32_t> ())
57
                   MakeUintegerChecker<uint32_t> ())
58
    .AddAttribute ("AdvertisedWindowSize",
59
                   "TCP advertised window size (bytes)",
60
                   UintegerValue (0xffff),
61
                   MakeUintegerAccessor (&TcpSocket::GetAdvWin,
62
                                         &TcpSocket::SetAdvWin),
63
                   MakeUintegerChecker<uint32_t> ())
64
    .AddAttribute ("SlowStartThreshold",
58
    .AddAttribute ("SlowStartThreshold",
65
                   "TCP slow start threshold (bytes)",
59
                   "TCP slow start threshold (bytes)",
66
                   UintegerValue (0xffff),
60
                   UintegerValue (0xffff),
(-)a/src/node/tcp-socket.h (-2 lines)
 Lines 59-66   private: Link Here 
59
  virtual uint32_t GetRcvBufSize (void) const = 0;
59
  virtual uint32_t GetRcvBufSize (void) const = 0;
60
  virtual void SetSegSize (uint32_t size) = 0;
60
  virtual void SetSegSize (uint32_t size) = 0;
61
  virtual uint32_t GetSegSize (void) const = 0;
61
  virtual uint32_t GetSegSize (void) const = 0;
62
  virtual void SetAdvWin (uint32_t window) = 0;
63
  virtual uint32_t GetAdvWin (void) const = 0;
64
  virtual void SetSSThresh (uint32_t threshold) = 0;
62
  virtual void SetSSThresh (uint32_t threshold) = 0;
65
  virtual uint32_t GetSSThresh (void) const = 0;
63
  virtual uint32_t GetSSThresh (void) const = 0;
66
  virtual void SetInitialCwnd (uint32_t count) = 0;
64
  virtual void SetInitialCwnd (uint32_t count) = 0;

Return to bug 239