src/internet-node/tcp-socket.cc
author Raj Bhattacharjea <raj.b@gatech.edu>
Thu Mar 20 14:04:24 2008 -0400 (2008-03-20)
changeset 2668 4956586bd798
parent 2608 408589d1dfff
child 2669 43ec4c995363
permissions -rw-r--r--
Pass TcpSockets as smart pointers into demux callbacks
fixes TcpSocket memory leaks
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2007 Georgia Tech Research Corporation
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Raj Bhattacharjea <raj.b@gatech.edu>
    19  */
    20 
    21 
    22 #include "ns3/node.h"
    23 #include "ns3/inet-socket-address.h"
    24 #include "ns3/log.h"
    25 #include "ns3/ipv4.h"
    26 #include "tcp-socket.h"
    27 #include "tcp-l4-protocol.h"
    28 #include "ipv4-end-point.h"
    29 #include "ipv4-l4-demux.h"
    30 #include "ns3/simulation-singleton.h"
    31 #include "tcp-typedefs.h"
    32 #include "ns3/simulator.h"
    33 #include "ns3/packet.h"
    34 
    35 #include <algorithm>
    36 
    37 NS_LOG_COMPONENT_DEFINE ("TcpSocket");
    38 
    39 using namespace std;
    40 
    41 namespace ns3 {
    42 
    43   TcpSocket::TcpSocket ()
    44   : m_skipRetxResched (false),
    45     m_dupAckCount (0),
    46     m_endPoint (0),
    47     m_node (0),
    48     m_tcp (0),
    49     m_errno (ERROR_NOTERROR),
    50     m_shutdownSend (false),
    51     m_shutdownRecv (false),
    52     m_connected (false),
    53     m_state (CLOSED),
    54     m_closeNotified (false),
    55     m_closeRequestNotified (false),
    56     m_closeOnEmpty (false),
    57     m_pendingClose (false),
    58     m_nextTxSequence (0),
    59     m_highTxMark (0),
    60     m_highestRxAck (0),
    61     m_lastRxAck (0),
    62     m_nextRxSequence (0),
    63     m_pendingData (0),
    64     m_rtt (0),
    65     m_lastMeasuredRtt (Seconds(0.0))
    66 {
    67   NS_LOG_FUNCTION;
    68   NS_LOG_PARAMS (this);
    69   
    70 }
    71 
    72 TcpSocket::TcpSocket(const TcpSocket& sock)
    73   : Socket(sock), //copy the base class callbacks
    74     m_skipRetxResched (sock.m_skipRetxResched),
    75     m_dupAckCount (sock.m_dupAckCount),
    76     m_endPoint (0),
    77     m_node (sock.m_node),
    78     m_tcp (sock.m_tcp),
    79     m_remoteAddress (sock.m_remoteAddress),
    80     m_remotePort (sock.m_remotePort),
    81     m_localAddress (sock.m_localAddress),
    82     m_localPort (sock.m_localPort),
    83     m_errno (sock.m_errno),
    84     m_shutdownSend (sock.m_shutdownSend),
    85     m_shutdownRecv (sock.m_shutdownRecv),
    86     m_connected (sock.m_connected),
    87     m_state (sock.m_state),
    88     m_closeNotified (sock.m_closeNotified),
    89     m_closeRequestNotified (sock.m_closeRequestNotified),
    90     m_closeOnEmpty (sock.m_closeOnEmpty),
    91     m_pendingClose (sock.m_pendingClose),
    92     m_nextTxSequence (sock.m_nextTxSequence),
    93     m_highTxMark (sock.m_highTxMark),
    94     m_highestRxAck (sock.m_highestRxAck),
    95     m_lastRxAck (sock.m_lastRxAck),
    96     m_nextRxSequence (sock.m_nextRxSequence),
    97     m_pendingData (0),
    98     m_segmentSize (sock.m_segmentSize),
    99     m_rxWindowSize (sock.m_rxWindowSize),
   100     m_advertisedWindowSize (sock.m_advertisedWindowSize),
   101     m_cWnd (sock.m_cWnd),
   102     m_ssThresh (sock.m_ssThresh),
   103     m_initialCWnd (sock.m_initialCWnd),
   104     m_rtt (0),
   105     m_lastMeasuredRtt (Seconds(0.0)),
   106     m_cnTimeout (sock.m_cnTimeout),
   107     m_cnCount (sock.m_cnCount)
   108 {
   109   NS_LOG_FUNCTION;
   110   NS_LOG_LOGIC("Invoked the copy constructor");
   111   //copy the pending data if necessary
   112   if(sock.m_pendingData)
   113     {
   114       m_pendingData = sock.m_pendingData->Copy();
   115     }
   116   //copy the rtt if necessary
   117   if (sock.m_rtt)
   118     {
   119       m_rtt = sock.m_rtt->Copy();
   120     }
   121   //can't "copy" the endpoint just yes, must do this when we know the peer info
   122   //too; this is in SYN_ACK_TX
   123 }
   124 
   125 TcpSocket::~TcpSocket ()
   126 {
   127   NS_LOG_FUNCTION;
   128   NS_LOG_PARAMS(this);
   129   m_node = 0;
   130   if (m_endPoint != 0)
   131     {
   132       NS_ASSERT (m_tcp != 0);
   133       /**
   134        * Note that this piece of code is a bit tricky:
   135        * when DeAllocate is called, it will call into
   136        * Ipv4EndPointDemux::Deallocate which triggers
   137        * a delete of the associated endPoint which triggers
   138        * in turn a call to the method ::Destroy below
   139        * will will zero the m_endPoint field.
   140        */
   141       NS_ASSERT (m_endPoint != 0);
   142       m_tcp->DeAllocate (m_endPoint);
   143       NS_ASSERT (m_endPoint == 0);
   144     }
   145   m_tcp = 0;
   146   delete m_pendingData; //prevents leak
   147   m_pendingData = 0;
   148 }
   149 
   150 void
   151 TcpSocket::SetNode (Ptr<Node> node)
   152 {
   153   m_node = node;
   154   Ptr<Tcp> t = node->GetObject<Tcp> ();
   155   m_segmentSize = t->GetDefaultSegSize ();
   156   m_rxWindowSize = t->GetDefaultAdvWin ();
   157   m_advertisedWindowSize = t->GetDefaultAdvWin ();
   158   m_cWnd = t->GetDefaultInitialCwnd () * m_segmentSize;
   159   m_ssThresh = t->GetDefaultSsThresh ();
   160   m_initialCWnd = t->GetDefaultInitialCwnd ();
   161   m_cnTimeout = Seconds (t->GetDefaultConnTimeout ());
   162   m_cnCount = t->GetDefaultConnCount ();
   163 }
   164 
   165 void 
   166 TcpSocket::SetTcp (Ptr<TcpL4Protocol> tcp)
   167 {
   168   m_tcp = tcp;
   169 }
   170 void 
   171 TcpSocket::SetRtt (Ptr<RttEstimator> rtt)
   172 {
   173   m_rtt = rtt;
   174 }
   175 
   176 
   177 enum Socket::SocketErrno
   178 TcpSocket::GetErrno (void) const
   179 {
   180   NS_LOG_FUNCTION;
   181   return m_errno;
   182 }
   183 
   184 Ptr<Node>
   185 TcpSocket::GetNode (void) const
   186 {
   187   NS_LOG_FUNCTION;
   188   return m_node;
   189 }
   190 
   191 void 
   192 TcpSocket::Destroy (void)
   193 {
   194   NS_LOG_FUNCTION;
   195   m_node = 0;
   196   m_endPoint = 0;
   197   m_tcp = 0;
   198   m_retxEvent.Cancel ();
   199 }
   200 int
   201 TcpSocket::FinishBind (void)
   202 {
   203   NS_LOG_FUNCTION;
   204   if (m_endPoint == 0)
   205     {
   206       return -1;
   207     }
   208   m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, Ptr<TcpSocket>(this)));
   209   m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, Ptr<TcpSocket>(this)));
   210   m_localAddress = m_endPoint->GetLocalAddress ();
   211   m_localPort = m_endPoint->GetLocalPort ();
   212   return 0;
   213 }
   214 
   215 int
   216 TcpSocket::Bind (void)
   217 {
   218   NS_LOG_FUNCTION;
   219   m_endPoint = m_tcp->Allocate ();
   220   return FinishBind ();
   221 }
   222 int 
   223 TcpSocket::Bind (const Address &address)
   224 {
   225   NS_LOG_FUNCTION;
   226   NS_LOG_PARAMS (this<<address);
   227   if (!InetSocketAddress::IsMatchingType (address))
   228     {
   229       return ERROR_INVAL;
   230     }
   231   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   232   Ipv4Address ipv4 = transport.GetIpv4 ();
   233   uint16_t port = transport.GetPort ();
   234   if (ipv4 == Ipv4Address::GetAny () && port == 0)
   235     {
   236       m_endPoint = m_tcp->Allocate ();
   237       NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
   238     }
   239   else if (ipv4 == Ipv4Address::GetAny () && port != 0)
   240     {
   241       m_endPoint = m_tcp->Allocate (port);
   242       NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
   243     }
   244   else if (ipv4 != Ipv4Address::GetAny () && port == 0)
   245     {
   246       m_endPoint = m_tcp->Allocate (ipv4);
   247       NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
   248     }
   249   else if (ipv4 != Ipv4Address::GetAny () && port != 0)
   250     {
   251       m_endPoint = m_tcp->Allocate (ipv4, port);
   252       NS_LOG_LOGIC ("TcpSocket "<<this<<" got an endpoint: "<<m_endPoint);
   253     }
   254 
   255   return FinishBind ();
   256 }
   257 
   258 int 
   259 TcpSocket::ShutdownSend (void)
   260 {
   261   NS_LOG_FUNCTION;
   262   m_shutdownSend = true;
   263   return 0;
   264 }
   265 int 
   266 TcpSocket::ShutdownRecv (void)
   267 {
   268   NS_LOG_FUNCTION;
   269   m_shutdownRecv = false;
   270   return 0;
   271 }
   272 
   273 int
   274 TcpSocket::Close (void)
   275 {
   276   NS_LOG_FUNCTION;
   277   if (m_state == CLOSED) 
   278     {
   279       return -1;
   280     }
   281   if (m_pendingData && m_pendingData->Size() != 0)
   282     { // App close with pending data must wait until all data transmitted
   283       m_closeOnEmpty = true;
   284       NS_LOG_LOGIC("Socket " << this << 
   285                    " deferring close, state " << m_state);
   286       return 0;
   287     }
   288 
   289   Actions_t action  = ProcessEvent (APP_CLOSE);
   290   ProcessAction (action);
   291   ShutdownSend ();
   292   return 0;
   293 }
   294 
   295 int
   296 TcpSocket::Connect (const Address & address)
   297 {
   298   NS_LOG_FUNCTION;
   299   NS_LOG_PARAMS (this << address);
   300   if (m_endPoint == 0)
   301     {
   302       if (Bind () == -1)
   303         {
   304           NS_ASSERT (m_endPoint == 0);
   305           return -1;
   306         }
   307       NS_ASSERT (m_endPoint != 0);
   308     }
   309   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   310   m_remoteAddress = transport.GetIpv4 ();
   311   m_remotePort = transport.GetPort ();
   312   
   313   uint32_t localIfIndex;
   314   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   315 
   316   if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
   317     {
   318       m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
   319     }
   320   else
   321     {
   322       m_errno = ERROR_NOROUTETOHOST;
   323       return -1;
   324     }
   325 
   326   Actions_t action = ProcessEvent (APP_CONNECT);
   327   bool success = ProcessAction (action);
   328   if (success) 
   329     {
   330       return 0;
   331     }
   332   return -1;
   333 }
   334 int 
   335 TcpSocket::Send (const Ptr<Packet> p) //p here is just data, no headers
   336 { // TCP Does not deal with packets from app, just data
   337   return Send(p->PeekData(), p->GetSize());
   338 }
   339 
   340 int TcpSocket::Send (const uint8_t* buf, uint32_t size)
   341 {
   342   NS_LOG_FUNCTION;
   343   NS_LOG_PARAMS (this << buf << size);
   344   if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
   345     { // Ok to buffer some data to send
   346       if (!m_pendingData)
   347       {
   348         m_pendingData = new PendingData ();   // Create if non-existent
   349         m_firstPendingSequence = m_nextTxSequence; // Note seq of first
   350       }
   351       //PendingData::Add always copies the data buffer, never modifies
   352       m_pendingData->Add (size,buf);
   353       NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << 
   354                    " state " << m_state);
   355       Actions_t action = ProcessEvent (APP_SEND);
   356       NS_LOG_DEBUG(" action " << action);
   357       if (!ProcessAction (action)) 
   358         {
   359           return -1; // Failed, return zero
   360         }
   361       return size;
   362     }
   363   else
   364   {
   365     m_errno = ERROR_NOTCONN;
   366     return -1;
   367   }
   368 }
   369 
   370 int TcpSocket::DoSendTo (Ptr<Packet> p, const Address &address)
   371 {
   372   NS_LOG_FUNCTION;
   373   NS_LOG_PARAMS (this << p << address);
   374   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   375   Ipv4Address ipv4 = transport.GetIpv4 ();
   376   uint16_t port = transport.GetPort ();
   377   return DoSendTo (p, ipv4, port);
   378 }
   379 
   380 int TcpSocket::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
   381 {
   382   NS_LOG_FUNCTION;
   383   NS_LOG_PARAMS (this << p << ipv4 << port);
   384   if (m_endPoint == 0)
   385     {
   386       if (Bind () == -1)
   387 	{
   388           NS_ASSERT (m_endPoint == 0);
   389 	  return -1;
   390 	}
   391       NS_ASSERT (m_endPoint != 0);
   392     }
   393   if (m_shutdownSend)
   394     {
   395       m_errno = ERROR_SHUTDOWN;
   396       return -1;
   397     }
   398   m_tcp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
   399                   m_endPoint->GetLocalPort (), port);
   400   NotifyDataSent (p->GetSize ());
   401   return 0;
   402 }
   403 
   404 int 
   405 TcpSocket::SendTo (const Address &address, Ptr<Packet> p)
   406 {
   407   NS_LOG_FUNCTION;
   408   NS_LOG_PARAMS (this << address << p);
   409   if (!m_connected)
   410     {
   411       m_errno = ERROR_NOTCONN;
   412       return -1;
   413     }
   414   else
   415     {
   416       return Send (p); //drop the address according to BSD manpages
   417     }
   418 }
   419 
   420 int
   421 TcpSocket::Listen (uint32_t q)
   422 {
   423   NS_LOG_FUNCTION;
   424   NS_LOG_PARAMS (this << q);
   425   Actions_t action = ProcessEvent (APP_LISTEN);
   426   ProcessAction (action);
   427   return 0;
   428 }
   429 
   430 void
   431 TcpSocket::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
   432 {
   433   NS_LOG_DEBUG("Socket " << this << " got forward up" <<
   434                " dport " << m_endPoint->GetLocalPort() <<
   435                " daddr " << m_endPoint->GetLocalAddress() <<
   436                " sport " << m_endPoint->GetPeerPort() <<
   437                " saddr " << m_endPoint->GetPeerAddress());
   438 
   439   NS_LOG_FUNCTION;
   440   NS_LOG_PARAMS (this << packet << ipv4 << port);
   441   if (m_shutdownRecv)
   442     {
   443       return;
   444     }
   445   TcpHeader tcpHeader;
   446   packet->RemoveHeader (tcpHeader);
   447 
   448   if (tcpHeader.GetFlags () & TcpHeader::ACK)
   449     {
   450       Time m = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
   451       if (m != Seconds (0.0))
   452         {
   453           m_lastMeasuredRtt = m;
   454         }
   455     }
   456 
   457   Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
   458   Actions_t action = ProcessEvent (event); //updates the state
   459   Address address = InetSocketAddress (ipv4, port);
   460   NS_LOG_DEBUG("Socket " << this << 
   461                " processing pkt action, " << action <<
   462                " current state " << m_state);
   463   ProcessPacketAction (action, packet, tcpHeader, address);
   464 }
   465 
   466 Actions_t TcpSocket::ProcessEvent (Events_t e)
   467 {
   468   NS_LOG_FUNCTION;
   469   NS_LOG_PARAMS (this << e);
   470   States_t saveState = m_state;
   471   NS_LOG_LOGIC ("TcpSocket " << this << " processing event " << e);
   472   // simulation singleton is a way to get a single global static instance of a
   473   // class intended to be a singleton; see simulation-singleton.h
   474   SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
   475   // debug
   476   if (stateAction.action == RST_TX)
   477     {
   478       NS_LOG_LOGIC ("TcpSocket " << this << " sending RST from state "
   479               << saveState << " event " << e);
   480     }
   481   bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED 
   482     && e != TIMEOUT);
   483   m_state = stateAction.state;
   484   NS_LOG_LOGIC ("TcpSocket " << this << " moved from state " << saveState 
   485     << " to state " <<m_state);
   486   NS_LOG_LOGIC ("TcpSocket " << this << " pendingData " << m_pendingData);
   487 
   488   //extra event logic is here for RX events
   489   //e = SYN_ACK_RX
   490   if (saveState == SYN_SENT && m_state == ESTABLISHED)
   491     // this means the application side has completed its portion of 
   492     // the handshaking
   493     {
   494       Simulator::ScheduleNow(&TcpSocket::ConnectionSucceeded, this);
   495       //NotifyConnectionSucceeded ();
   496       m_connected = true;
   497       m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
   498       NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
   499     }
   500 
   501   if (needCloseNotify && !m_closeNotified)
   502     {
   503       NS_LOG_LOGIC ("TcpSocket " << this << " transition to CLOSED from " 
   504                << m_state << " event " << e << " closeNot " << m_closeNotified
   505                << " action " << stateAction.action);
   506       NotifyCloseCompleted ();
   507       m_closeNotified = true;
   508       NS_LOG_LOGIC ("TcpSocket " << this << " calling Closed from PE"
   509               << " origState " << saveState
   510               << " event " << e);
   511       NS_LOG_LOGIC ("TcpSocket " << this << " transition to CLOSED from "
   512           << m_state << " event " << e
   513           << " set CloseNotif ");
   514     }
   515   return stateAction.action;
   516 }
   517 
   518 void TcpSocket::SendEmptyPacket (uint8_t flags)
   519 {
   520   NS_LOG_FUNCTION;
   521   NS_LOG_PARAMS (this << flags);
   522   Ptr<Packet> p = Create<Packet> ();
   523   TcpHeader header;
   524 
   525   header.SetFlags (flags);
   526   header.SetSequenceNumber (m_nextTxSequence);
   527   header.SetAckNumber (m_nextRxSequence);
   528   header.SetSourcePort (m_endPoint->GetLocalPort ());
   529   header.SetDestinationPort (m_remotePort);
   530   header.SetWindowSize (m_advertisedWindowSize);
   531   m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), 
   532     m_remoteAddress);
   533   Time rto = m_rtt->RetransmitTimeout ();
   534   if (flags & TcpHeader::SYN)
   535     {
   536       rto = m_cnTimeout;
   537       m_cnTimeout = m_cnTimeout + m_cnTimeout;
   538       m_cnCount--;
   539     }
   540   if (m_retxEvent.IsExpired () ) //no outstanding timer
   541   {
   542     NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
   543           << Simulator::Now ().GetSeconds () << " to expire at time " 
   544           << (Simulator::Now () + rto).GetSeconds ());
   545     m_retxEvent = Simulator::Schedule (rto, &TcpSocket::ReTxTimeout, this);
   546   }
   547 }
   548 
   549 bool TcpSocket::ProcessAction (Actions_t a)
   550 { // These actions do not require a packet or any TCP Headers
   551   NS_LOG_FUNCTION;
   552   NS_LOG_PARAMS (this << a);
   553   switch (a)
   554   {
   555     case NO_ACT:
   556       NS_LOG_LOGIC ("TcpSocket " << this <<" Action: NO_ACT");
   557       break;
   558     case ACK_TX:
   559       SendEmptyPacket (TcpHeader::ACK);
   560       break;
   561     case ACK_TX_1:
   562       NS_ASSERT (false); // This should be processed in ProcessPacketAction
   563       break;
   564     case RST_TX:
   565       NS_LOG_LOGIC ("TcpSocket " << this <<" Action RST_TX");
   566       SendEmptyPacket (TcpHeader::RST);
   567       break;
   568     case SYN_TX:
   569       NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_TX");
   570       // TCP SYN Flag consumes one byte
   571       // is the above correct? we're SENDING a syn, not acking back -- Raj
   572       // commented out for now
   573       // m_nextTxSequence+= 1;
   574       SendEmptyPacket (TcpHeader::SYN);
   575       break;
   576     case SYN_ACK_TX:
   577       NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
   578       // TCP SYN Flag consumes one byte
   579       ++m_nextRxSequence;
   580       SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
   581       break;
   582     case FIN_TX:
   583       NS_LOG_LOGIC ("TcpSocket " << this <<" Action FIN_TX");
   584       SendEmptyPacket (TcpHeader::FIN);
   585       break;
   586     case FIN_ACK_TX:
   587       NS_LOG_LOGIC ("TcpSocket " << this <<" Action FIN_ACK_TX");
   588       SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
   589       break;
   590     case NEW_ACK:
   591       NS_ASSERT (false); // This should be processed in ProcessPacketAction
   592       break;
   593     case NEW_SEQ_RX:
   594       NS_ASSERT (false); // This should be processed in ProcessPacketAction
   595       break;
   596     case RETX:
   597       NS_LOG_LOGIC ("TcpSocket " << this <<" Action RETX");
   598       break;
   599     case TX_DATA:
   600       NS_LOG_LOGIC ("TcpSocket " << this <<" Action TX_DATA");
   601       SendPendingData ();
   602       break;
   603     case PEER_CLOSE:
   604       NS_ASSERT (false); // This should be processed in ProcessPacketAction
   605       NS_LOG_LOGIC ("TcpSocket " << this <<" Action PEER_CLOSE");
   606       break;
   607     case APP_CLOSED:
   608       NS_LOG_LOGIC ("TcpSocket " << this <<" Action APP_CLOSED");
   609       break;
   610     case CANCEL_TM:
   611       NS_LOG_LOGIC ("TcpSocket " << this <<" Action CANCEL_TM");
   612       break;
   613     case APP_NOTIFY:
   614       NS_LOG_LOGIC ("TcpSocket " << this <<" Action APP_NOTIFY");
   615       break;
   616     case SERV_NOTIFY:
   617       NS_ASSERT (false); // This should be processed in ProcessPacketAction
   618       break;
   619     case LAST_ACTION:
   620       NS_LOG_LOGIC ("TcpSocket " << this <<" Action LAST_ACTION");
   621       break;
   622   }
   623   return true;
   624 }
   625 
   626 bool TcpSocket::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
   627                                      const TcpHeader& tcpHeader,
   628                                      const Address& fromAddress)
   629 {
   630   NS_LOG_FUNCTION;
   631   NS_LOG_PARAMS (this << a << p  << fromAddress);
   632   uint32_t localIfIndex;
   633   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   634   switch (a)
   635   {
   636     case SYN_ACK_TX:
   637       NS_LOG_LOGIC ("TcpSocket " << this <<" Action SYN_ACK_TX");
   638 //      m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
   639 //      m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
   640 //       if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
   641 //         {
   642 //           m_localAddress = ipv4->GetAddress (localIfIndex);
   643 //         }
   644       if (m_state == LISTEN) //this means we should fork a new TcpSocket
   645         {
   646           NS_LOG_DEBUG("In SYN_ACK_TX, m_state is LISTEN, this " << this);
   647           //notify the server that we got a SYN
   648           // If server refuses connection do nothing
   649           if (!NotifyConnectionRequest(fromAddress)) return true;
   650           // Clone the socket
   651           Ptr<TcpSocket> newSock = Copy ();
   652           NS_LOG_LOGIC ("Cloned a TcpSocket " << newSock);
   653           //this listening socket should do nothing more
   654           Simulator::ScheduleNow (&TcpSocket::CompleteFork, newSock,
   655                                   p, tcpHeader,fromAddress);
   656           return true;
   657         }
   658         // This is the cloned endpoint
   659         m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
   660         if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
   661           {
   662             m_localAddress = ipv4->GetAddress (localIfIndex);
   663             m_endPoint->SetLocalAddress (m_localAddress);
   664             // Leave local addr in the portmap to any, as the path from
   665             // remote can change and packets can arrive on different interfaces
   666             //m_endPoint->SetLocalAddress (Ipv4Address::GetAny());
   667           }
   668         // TCP SYN consumes one byte
   669         m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
   670         SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
   671       break;
   672     case ACK_TX_1:
   673       NS_LOG_LOGIC ("TcpSocket " << this <<" Action ACK_TX_1");
   674       // TCP SYN consumes one byte
   675       m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
   676       NS_LOG_DEBUG ("TcpSocket " << this << " ACK_TX_1" <<
   677                     " nextRxSeq " << m_nextRxSequence);
   678       SendEmptyPacket (TcpHeader::ACK);
   679       m_rxWindowSize = tcpHeader.GetWindowSize ();
   680       m_nextTxSequence = tcpHeader.GetAckNumber ();
   681       if (tcpHeader.GetAckNumber () > m_highestRxAck)
   682       {
   683         m_highestRxAck = tcpHeader.GetAckNumber ();
   684       }
   685       SendPendingData ();
   686       break;
   687     case NEW_ACK:
   688       NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_ACK_TX");
   689       if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
   690       {
   691         break;
   692       }
   693       if (tcpHeader.GetAckNumber () == m_highestRxAck && 
   694          tcpHeader.GetAckNumber ()  < m_nextTxSequence)
   695       {
   696         DupAck (tcpHeader, ++m_dupAckCount);
   697         break;
   698       }
   699       if (tcpHeader.GetAckNumber () > m_highestRxAck)  
   700         {
   701           m_dupAckCount = 0;
   702         }
   703       NewAck (tcpHeader.GetAckNumber ());
   704       break;
   705     case NEW_SEQ_RX:
   706       NS_LOG_LOGIC ("TcpSocket " << this <<" Action NEW_SEQ_RX");
   707       NewRx (p, tcpHeader, fromAddress); // Process new data received
   708       break;
   709     case PEER_CLOSE:
   710     {
   711       // First we have to be sure the FIN packet was not received
   712       // out of sequence.  If so, note pending close and process
   713       // new sequence rx
   714       if (tcpHeader.GetSequenceNumber () != m_nextRxSequence)
   715         { // process close later
   716           m_pendingClose = true;
   717           NS_LOG_LOGIC ("TcpSocket " << this << " setting pendingClose" 
   718             << " rxseq " << tcpHeader.GetSequenceNumber () 
   719             << " nextRxSeq " << m_nextRxSequence);
   720           NewRx (p, tcpHeader, fromAddress);
   721           return true;
   722         }
   723       // Now we need to see if any data came with the FIN
   724       // if so, call NewRx
   725       if (p->GetSize () != 0)
   726         {
   727           NewRx (p, tcpHeader, fromAddress);
   728         }
   729       States_t saveState = m_state; // Used to see if app responds
   730       NS_LOG_LOGIC ("TcpSocket " << this 
   731           << " peer close, state " << m_state);
   732       if (!m_closeRequestNotified)
   733         {
   734           NS_LOG_LOGIC ("TCP " << this 
   735               << " calling AppCloseRequest");
   736           NotifyHalfClose ();
   737           m_closeRequestNotified = true;
   738         }
   739       NS_LOG_LOGIC ("TcpSocket " << this 
   740           << " peer close, state after " << m_state);
   741       if (m_state == saveState)
   742         { // Need to ack, the application will close later
   743           SendEmptyPacket (TcpHeader::ACK);
   744               // Also need to re-tx the ack if we
   745         }
   746       if (m_state == LAST_ACK)
   747         {
   748           NS_LOG_LOGIC ("TcpSocket " << this << " scheduling LATO1");
   749           m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
   750                                                 &TcpSocket::LastAckTimeout,this);
   751         }
   752       break;
   753     }
   754     case SERV_NOTIFY:
   755       NS_LOG_LOGIC ("TcpSocket " << this <<" Action SERV_NOTIFY");
   756       NS_LOG_LOGIC ("TcpSocket " << this << " Connected!");
   757       NotifyNewConnectionCreated (this, fromAddress);
   758       m_connected = true; // ! This is bogus; fix when we clone the tcp
   759       m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
   760       //treat the connection orientation final ack as a newack
   761       CommonNewAck (tcpHeader.GetAckNumber (), true);
   762       break;
   763     default:
   764       break;
   765   }
   766   return true;
   767 }
   768 
   769 void TcpSocket::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
   770 {
   771   // Get port and address from peer (connecting host)
   772   m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
   773   m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
   774   m_endPoint = m_tcp->Allocate (m_localAddress,
   775                                 m_localPort,
   776                                 m_remoteAddress,
   777                                 m_remotePort);
   778   //the cloned socket with be in listen state, so manually change state
   779   m_state = SYN_RCVD;
   780   //equivalent to FinishBind
   781   m_endPoint->SetRxCallback (MakeCallback (&TcpSocket::ForwardUp, Ptr<TcpSocket>(this)));
   782   m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocket::Destroy, Ptr<TcpSocket>(this)));
   783   ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
   784  }
   785 
   786 void TcpSocket::ConnectionSucceeded()
   787 { // We would preferred to have scheduled an event directly to
   788   // NotifyConnectionSucceeded, but (sigh) these are protected
   789   // and we can get the address of it :(
   790   NotifyConnectionSucceeded();
   791 }
   792 
   793 bool TcpSocket::SendPendingData (bool withAck)
   794 {
   795   NS_LOG_FUNCTION;
   796   NS_LOG_PARAMS (this << withAck);
   797   NS_LOG_LOGIC ("ENTERING SendPendingData");
   798   if (!m_pendingData)
   799     {
   800       return false; // No data exists
   801     }
   802   uint32_t nPacketsSent = 0;
   803   while (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence))
   804     {
   805       uint32_t w = AvailableWindow ();// Get available window size
   806       NS_LOG_LOGIC ("TcpSocket " << this << " SendPendingData"
   807            << " w " << w 
   808            << " rxwin " << m_rxWindowSize
   809            << " cWnd " << m_cWnd
   810            << " segsize " << m_segmentSize
   811            << " nextTxSeq " << m_nextTxSequence
   812            << " highestRxAck " << m_highestRxAck 
   813            << " pd->Size " << m_pendingData->Size ()
   814            << " pd->SFS " << m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence));
   815 
   816       if (w < m_segmentSize && m_pendingData->Size () > w)
   817         {
   818           break; // No more
   819         }
   820       uint32_t s = std::min (w, m_segmentSize);  // Send no more than window
   821       Ptr<Packet> p = m_pendingData->CopyFromSeq (s, m_firstPendingSequence, 
   822         m_nextTxSequence);
   823       NS_LOG_LOGIC("TcpSocket " << this << " sendPendingData"
   824                    << " txseq " << m_nextTxSequence
   825                    << " s " << s 
   826                    << " datasize " << p->GetSize() );
   827       uint8_t flags = 0;
   828       if (withAck)
   829         {
   830           flags |= TcpHeader::ACK;
   831         }
   832       uint32_t sz = p->GetSize (); // Size of packet
   833       uint32_t remainingData = m_pendingData->SizeFromSeq(
   834           m_firstPendingSequence,
   835           m_nextTxSequence + SequenceNumber (sz));
   836       if (m_closeOnEmpty && (remainingData == 0))
   837         {
   838           flags = TcpHeader::FIN;
   839           m_state = FIN_WAIT_1;
   840         }
   841 
   842       TcpHeader header;
   843       header.SetFlags (flags);
   844       header.SetSequenceNumber (m_nextTxSequence);
   845       header.SetAckNumber (m_nextRxSequence);
   846       header.SetSourcePort (m_endPoint->GetLocalPort());
   847       header.SetDestinationPort (m_remotePort);
   848       if (m_shutdownSend)
   849         {
   850           m_errno = ERROR_SHUTDOWN;
   851           return -1;
   852         }
   853 
   854       Time rto = m_rtt->RetransmitTimeout ();
   855       if (m_retxEvent.IsExpired () ) //go ahead and schedule the retransmit
   856         {
   857           NS_LOG_LOGIC ("Schedule retransmission timeout at time " << 
   858               Simulator::Now ().GetSeconds () << " to expire at time " <<
   859               (Simulator::Now () + rto).GetSeconds () );
   860           m_retxEvent = Simulator::Schedule (rto,&TcpSocket::ReTxTimeout,this);
   861         }
   862       NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
   863       m_tcp->SendPacket (p, header,
   864                          m_endPoint->GetLocalAddress (),
   865                          m_remoteAddress);
   866       m_rtt->SentSeq(m_nextTxSequence, sz);       // notify the RTT
   867       // Notify the application
   868       Simulator::ScheduleNow(&TcpSocket::NotifyDataSent, this, p->GetSize ());
   869       nPacketsSent++;                             // Count sent this loop
   870       m_nextTxSequence += sz;                     // Advance next tx sequence
   871       // Note the high water mark
   872       m_highTxMark = std::max (m_nextTxSequence, m_highTxMark);
   873     }
   874   NS_LOG_LOGIC ("Sent "<<nPacketsSent<<" packets");
   875   NS_LOG_LOGIC("RETURN SendPendingData");
   876   return (nPacketsSent>0);
   877 }
   878 
   879 uint32_t  TcpSocket::UnAckDataCount ()
   880 {
   881   NS_LOG_FUNCTION;
   882   return m_nextTxSequence - m_highestRxAck;
   883 }
   884 
   885 uint32_t  TcpSocket::BytesInFlight ()
   886 {
   887   NS_LOG_FUNCTION;
   888   return m_highTxMark - m_highestRxAck;
   889 }
   890 
   891 uint32_t  TcpSocket::Window ()
   892 {
   893   NS_LOG_FUNCTION;
   894   NS_LOG_LOGIC ("TcpSocket::Window() "<<this);
   895   return std::min (m_rxWindowSize, m_cWnd);
   896 }
   897 
   898 uint32_t  TcpSocket::AvailableWindow ()
   899 {
   900   NS_LOG_FUNCTION;
   901   uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
   902   uint32_t win = Window ();
   903   if (win < unack) 
   904     {
   905       return 0;  // No space available
   906     }
   907   return (win - unack);       // Amount of window space available
   908 }
   909 
   910 void TcpSocket::NewRx (Ptr<Packet> p,
   911                         const TcpHeader& tcpHeader, 
   912                         const Address& fromAddress)
   913 {
   914   NS_LOG_FUNCTION;
   915   NS_LOG_PARAMS (this << p << "tcpHeader " << fromAddress);
   916   NS_LOG_LOGIC ("TcpSocket " << this << " NewRx,"
   917                 << " seq " << tcpHeader.GetSequenceNumber()
   918                 << " ack " << tcpHeader.GetAckNumber()
   919                 << " p.size is " << p->GetSize () );
   920   NS_LOG_DEBUG ("TcpSocket " << this <<
   921                 " NewRx," <<
   922                 " seq " << tcpHeader.GetSequenceNumber() <<
   923                 " ack " << tcpHeader.GetAckNumber() <<
   924                 " p.size is " << p->GetSize());
   925   States_t origState = m_state;
   926   uint32_t s = p->GetSize ();  // Size of associated data
   927   if (s == 0)
   928     {// Nothing to do if no associated data
   929       return;
   930     }
   931   // Log sequence received if enabled
   932   // NoteTimeSeq(LOG_SEQ_RX, h->sequenceNumber);
   933   // Three possibilities
   934   // 1) Received seq is expected, deliver this and any buffered data
   935   // 2) Received seq is < expected, just re-ack previous
   936   // 3) Received seq is > expected, just re-ack previous and buffer data
   937   if (tcpHeader.GetSequenceNumber () == m_nextRxSequence)
   938     { // If seq is expected seq
   939       // 1) Update nextRxSeq
   940       // 2) Deliver to application this packet
   941       // 3) See if any buffered can be delivered
   942       // 4) Send the ack
   943       m_nextRxSequence += s;           // Advance next expected sequence
   944       //bytesReceived += s;       // Statistics
   945       NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
   946       NotifyDataReceived (p, fromAddress);
   947       if (m_closeNotified)
   948         {
   949           NS_LOG_LOGIC ("Tcp " << this << " HuH?  Got data after closeNotif");
   950         }
   951       NS_LOG_LOGIC ("TcpSocket " << this << " adv rxseq by " << s);
   952       // Look for buffered data
   953       UnAckData_t::iterator i;
   954       // Note that the bufferedData list DOES contain the tcp header
   955       while (!m_bufferedData.empty ())
   956         { // Check the buffered data for delivery
   957           NS_LOG_LOGIC("TCP " << this << " bufferedData.size() " 
   958               << m_bufferedData.size () 
   959               << " time " << Simulator::Now ());
   960           i = m_bufferedData.begin ();
   961           Ptr<Packet> p1 = i->second;
   962           SequenceNumber s1 = 0;
   963           if (i->first > m_nextRxSequence) 
   964             {
   965               break;  // Not next expected
   966             }
   967           // already have the header as a param
   968           //TCPHeader* h = dynamic_cast<TCPHeader*>(p1->PopPDU());
   969           // Check non-null here...
   970           uint8_t flags = tcpHeader.GetFlags ();           // Flags (used below)
   971           if (i->first < m_nextRxSequence)
   972             { // remove already delivered data
   973               // Two cases here.
   974               // 1) seq + length <= nextRxSeq, just discard
   975               // 2) seq + length > nextRxSeq, can deliver partial
   976               s1 = p->GetSize ();
   977               if (i->first + s1 < m_nextRxSequence)
   978                 { // Just remove from list
   979                   //bufferedData.erase(i);
   980                   p1 = 0; // Nothing to deliver
   981                 }
   982               else
   983                 { // Remove partial data to prepare for delivery
   984                   uint32_t dup = m_nextRxSequence - i->first;
   985                   i->second = p1->CreateFragment (0, p1->GetSize () - dup);
   986                   p1 = i->second;
   987                 }
   988             }
   989           else
   990             { // At this point i->first must equal nextRxSeq
   991               if (i->first != m_nextRxSequence)
   992                 {
   993                   NS_FATAL_ERROR ("HuH?  NexRx failure, first " 
   994                       << i->first << " nextRxSeq " << m_nextRxSequence);
   995                 }
   996               s1 = p1->GetSize ();
   997             }
   998           NotifyDataReceived (p1, fromAddress);
   999 
  1000           NS_LOG_LOGIC ("TcpSocket " << this << " adv rxseq1 by " << s1 );
  1001           m_nextRxSequence += s1;           // Note data received
  1002           m_bufferedData.erase (i);     // Remove from list
  1003           if (flags & TcpHeader::FIN)
  1004             NS_LOG_LOGIC("TcpSocket " << this 
  1005                     << " found FIN in buffered");
  1006         }
  1007 
  1008       if (m_pendingClose || (origState > ESTABLISHED))
  1009         { // See if we can close now
  1010           if (m_bufferedData.empty())
  1011             {
  1012               ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress);
  1013             }
  1014         }
  1015     }
  1016   else if (SequenceNumber (tcpHeader.GetSequenceNumber ()) >= m_nextRxSequence)
  1017     { // Need to buffer this one
  1018       NS_LOG_LOGIC ("Case 2, buffering " << tcpHeader.GetSequenceNumber () );
  1019       UnAckData_t::iterator i = 
  1020         m_bufferedData.find (tcpHeader.GetSequenceNumber () );
  1021       if (i != m_bufferedData.end () )
  1022         {
  1023           i->second = 0; // relase reference to already buffered
  1024         }
  1025       // Save for later delivery
  1026       m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;  
  1027     }
  1028   else
  1029     { // debug
  1030       NS_LOG_LOGIC("TCP " << this 
  1031                << " got seq " << tcpHeader.GetSequenceNumber ()
  1032                << " expected " << m_nextRxSequence
  1033                << "       flags " << tcpHeader.GetFlags ());
  1034     }
  1035   // Now send a new ack packet acknowledging all received and delivered data
  1036   SendEmptyPacket (TcpHeader::ACK);
  1037 }
  1038 
  1039 
  1040 void TcpSocket::CommonNewAck (SequenceNumber ack, bool skipTimer)
  1041 { // CommonNewAck is called only for "New" (non-duplicate) acks
  1042   // and MUST be called by any subclass, from the NewAck function
  1043   // Always cancel any pending re-tx timer on new acknowledgement
  1044   NS_LOG_FUNCTION;
  1045   NS_LOG_PARAMS (this << ack << skipTimer);
  1046   //DEBUG(1,(cout << "TCP " << this << "Cancelling retx timer " << endl));
  1047   if (!skipTimer)
  1048     {
  1049       m_retxEvent.Cancel ();
  1050     }
  1051   NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack 
  1052            << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
  1053   m_highestRxAck = ack;         // Note the highest recieved Ack
  1054   if (ack > m_nextTxSequence) 
  1055     {
  1056       m_nextTxSequence = ack; // If advanced
  1057     }
  1058   // See if all pending ack'ed; if so we can delete the data
  1059   if (m_pendingData)
  1060     { // Data exists, see if can be deleted
  1061       if (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_highestRxAck) == 0)
  1062         { // All pending acked, can be deleted
  1063           m_pendingData->Clear ();
  1064           delete m_pendingData;
  1065           m_pendingData = 0;
  1066           // Insure no re-tx timer
  1067           m_retxEvent.Cancel ();
  1068         }
  1069     }
  1070   // Try to send more data
  1071   SendPendingData();
  1072 }
  1073 
  1074 Ptr<TcpSocket> TcpSocket::Copy ()
  1075 {
  1076   return CopyObject<TcpSocket> (this);
  1077 }
  1078 
  1079 void TcpSocket::NewAck (SequenceNumber seq)
  1080 { // New acknowledgement up to sequence number "seq"
  1081   // Adjust congestion window in response to new ack's received
  1082   NS_LOG_FUNCTION;
  1083   NS_LOG_PARAMS (this << seq);
  1084   NS_LOG_LOGIC ("TcpSocket " << this << " NewAck "
  1085            << " seq " << seq
  1086            << " cWnd " << m_cWnd
  1087            << " ssThresh " << m_ssThresh);
  1088   if (m_cWnd < m_ssThresh)
  1089     { // Slow start mode, add one segSize to cWnd
  1090       m_cWnd += m_segmentSize;
  1091       NS_LOG_LOGIC ("TcpSocket " << this << " NewCWnd SlowStart, cWnd " << m_cWnd 
  1092           << " sst " << m_ssThresh);
  1093     }
  1094   else
  1095     { // Congestion avoidance mode, adjust by (ackBytes*segSize) / cWnd
  1096       double adder =  ((double) m_segmentSize * m_segmentSize) / m_cWnd;
  1097       if (adder < 1.0) 
  1098         {
  1099           adder = 1.0;
  1100         }
  1101       m_cWnd += (uint32_t) adder;
  1102       NS_LOG_LOGIC ("NewCWnd CongAvoid, cWnd " << m_cWnd 
  1103            << " sst " << m_ssThresh);
  1104     }
  1105   CommonNewAck (seq, false);           // Complete newAck processing
  1106 }
  1107 
  1108 void TcpSocket::DupAck (const TcpHeader& t, uint32_t count)
  1109 {
  1110   NS_LOG_FUNCTION;
  1111   NS_LOG_PARAMS (this << "t " << count);
  1112   NS_LOG_LOGIC ("TcpSocket " << this << " DupAck " <<  t.GetAckNumber ()
  1113       << ", count " << count
  1114       << ", time " << Simulator::Now ());
  1115   if (count == 3)
  1116   { // Count of three indicates triple duplicate ack
  1117     m_ssThresh = Window () / 2; // Per RFC2581
  1118     m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
  1119     NS_LOG_LOGIC("TcpSocket " << this << "Tahoe TDA, time " << Simulator::Now ()
  1120         << " seq " << t.GetAckNumber ()
  1121         << " in flight " << BytesInFlight ()
  1122         << " new ssthresh " << m_ssThresh);
  1123 
  1124     m_cWnd = m_segmentSize; // Collapse cwnd (re-enter slowstart)
  1125     // For Tahoe, we also reset nextTxSeq
  1126     m_nextTxSequence = m_highestRxAck;
  1127     SendPendingData ();
  1128   }
  1129 }
  1130 
  1131 void TcpSocket::ReTxTimeout ()
  1132 { // Retransmit timeout
  1133   NS_LOG_FUNCTION;
  1134   NS_LOG_PARAMS (this);
  1135   m_ssThresh = Window () / 2; // Per RFC2581
  1136   m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
  1137   // Set cWnd to segSize on timeout,  per rfc2581
  1138   // Collapse congestion window (re-enter slowstart)
  1139   m_cWnd = m_segmentSize;           
  1140   m_nextTxSequence = m_highestRxAck; // Start from highest Ack
  1141   m_rtt->IncreaseMultiplier (); // Double timeout value for next retx timer
  1142   Retransmit ();             // Retransmit the packet
  1143 }
  1144 
  1145 void TcpSocket::LastAckTimeout ()
  1146 {
  1147   m_lastAckEvent.Cancel ();
  1148   if (m_state == LAST_ACK)
  1149     {
  1150       Actions_t action = ProcessEvent (TIMEOUT);
  1151       ProcessAction (action);
  1152     }
  1153   if (!m_closeNotified)
  1154     {
  1155       m_closeNotified = true;
  1156     }
  1157 }
  1158 
  1159 void TcpSocket::Retransmit ()
  1160 {
  1161   NS_LOG_FUNCTION;
  1162   NS_LOG_PARAMS (this);
  1163   uint8_t flags = TcpHeader::NONE;
  1164   if (m_state == SYN_SENT) 
  1165     {
  1166       if (m_cnCount > 0) 
  1167         {
  1168           SendEmptyPacket (TcpHeader::SYN);
  1169           return;
  1170         }
  1171       else
  1172         {
  1173           NotifyConnectionFailed ();
  1174           return;
  1175         }
  1176     } 
  1177   if (!m_pendingData)
  1178     {
  1179       if (m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2)
  1180         { // Must have lost FIN, re-send
  1181           SendEmptyPacket (TcpHeader::FIN);
  1182         }
  1183       return;
  1184     }
  1185   Ptr<Packet> p = m_pendingData->CopyFromSeq (m_segmentSize,
  1186                                             m_firstPendingSequence,
  1187                                             m_highestRxAck);
  1188   // Calculate remaining data for COE check
  1189   uint32_t remainingData = m_pendingData->SizeFromSeq (
  1190       m_firstPendingSequence,
  1191       m_nextTxSequence + SequenceNumber(p->GetSize ()));
  1192   if (m_closeOnEmpty && remainingData == 0)
  1193     { // Add the FIN flag
  1194       flags = flags | TcpHeader::FIN;
  1195     }
  1196 
  1197   NS_LOG_LOGIC ("TcpSocket " << this << " retxing seq " << m_highestRxAck);
  1198   if (m_retxEvent.IsExpired () )
  1199     {
  1200       Time rto = m_rtt->RetransmitTimeout ();
  1201       NS_LOG_LOGIC ("Schedule retransmission timeout at time "
  1202           << Simulator::Now ().GetSeconds () << " to expire at time "
  1203           << (Simulator::Now () + rto).GetSeconds ());
  1204       m_retxEvent = Simulator::Schedule (rto,&TcpSocket::ReTxTimeout,this);
  1205     }
  1206   m_rtt->SentSeq (m_highestRxAck,p->GetSize ());
  1207   // And send the packet
  1208   TcpHeader tcpHeader;
  1209   tcpHeader.SetSequenceNumber (m_nextTxSequence);
  1210   tcpHeader.SetAckNumber (m_nextRxSequence);
  1211   tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
  1212   tcpHeader.SetDestinationPort (m_remotePort);
  1213   tcpHeader.SetFlags (flags);
  1214   tcpHeader.SetWindowSize (m_advertisedWindowSize);
  1215 
  1216   m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
  1217     m_remoteAddress);
  1218 }
  1219 
  1220 }//namespace ns3