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