src/internet-stack/tcp-socket-impl.cc
changeset 5100 d0cafb0ebeeb
parent 5050 5c2002bda934
parent 4627 d132345b3e10
child 5166 9d48acef10b3
equal deleted inserted replaced
5099:bb2373a0cece 5100:d0cafb0ebeeb
    17  *
    17  *
    18  * Author: Raj Bhattacharjea <raj.b@gatech.edu>
    18  * Author: Raj Bhattacharjea <raj.b@gatech.edu>
    19  */
    19  */
    20 
    20 
    21 
    21 
       
    22 #include "ns3/abort.h"
    22 #include "ns3/node.h"
    23 #include "ns3/node.h"
    23 #include "ns3/inet-socket-address.h"
    24 #include "ns3/inet-socket-address.h"
    24 #include "ns3/log.h"
    25 #include "ns3/log.h"
    25 #include "ns3/ipv4.h"
    26 #include "ns3/ipv4.h"
    26 #include "ns3/ipv4-interface-address.h"
    27 #include "ns3/ipv4-interface-address.h"
    27 #include "ns3/ipv4-route.h"
    28 #include "ns3/ipv4-route.h"
    28 #include "tcp-socket-impl.h"
    29 #include "ns3/ipv4-routing-protocol.h"
    29 #include "tcp-l4-protocol.h"
       
    30 #include "ipv4-end-point.h"
       
    31 #include "ns3/simulation-singleton.h"
    30 #include "ns3/simulation-singleton.h"
    32 #include "tcp-typedefs.h"
       
    33 #include "ns3/simulator.h"
    31 #include "ns3/simulator.h"
    34 #include "ns3/packet.h"
    32 #include "ns3/packet.h"
    35 #include "ns3/uinteger.h"
    33 #include "ns3/uinteger.h"
    36 #include "ns3/trace-source-accessor.h"
    34 #include "ns3/trace-source-accessor.h"
       
    35 #include "tcp-typedefs.h"
       
    36 #include "tcp-socket-impl.h"
       
    37 #include "tcp-l4-protocol.h"
       
    38 #include "ipv4-end-point.h"
    37 
    39 
    38 #include <algorithm>
    40 #include <algorithm>
    39 
    41 
    40 NS_LOG_COMPONENT_DEFINE ("TcpSocketImpl");
    42 NS_LOG_COMPONENT_DEFINE ("TcpSocketImpl");
    41 
    43 
    81     m_lastRxAck (0),
    83     m_lastRxAck (0),
    82     m_nextRxSequence (0),
    84     m_nextRxSequence (0),
    83     m_rxAvailable (0),
    85     m_rxAvailable (0),
    84     m_rxBufSize (0),
    86     m_rxBufSize (0),
    85     m_pendingData (0),
    87     m_pendingData (0),
       
    88     m_segmentSize (0),          // For attribute initialization consistency (quiet valgrind)
    86     m_rxWindowSize (0),
    89     m_rxWindowSize (0),
       
    90     m_initialCWnd (0),          // For attribute initialization consistency (quiet valgrind)
    87     m_persistTime (Seconds(6)), //XXX hook this into attributes?
    91     m_persistTime (Seconds(6)), //XXX hook this into attributes?
    88     m_rtt (0),
    92     m_rtt (0),
    89     m_lastMeasuredRtt (Seconds(0.0))
    93     m_lastMeasuredRtt (Seconds(0.0))
    90 {
    94 {
    91   NS_LOG_FUNCTION (this);
    95   NS_LOG_FUNCTION (this);
   169   NS_LOG_FUNCTION(this);
   173   NS_LOG_FUNCTION(this);
   170   m_node = 0;
   174   m_node = 0;
   171   if (m_endPoint != 0)
   175   if (m_endPoint != 0)
   172     {
   176     {
   173       NS_ASSERT (m_tcp != 0);
   177       NS_ASSERT (m_tcp != 0);
   174       /**
   178       /*
   175        * Note that this piece of code is a bit tricky:
   179        * Note that this piece of code is seriously convoluted: When we do a 
   176        * when DeAllocate is called, it will call into
   180        * Bind we allocate an Ipv4Endpoint.  Immediately thereafter we always do
   177        * Ipv4EndPointDemux::Deallocate which triggers
   181        * a FinishBind which sets the DestroyCallback of that endpoint to be
   178        * a delete of the associated endPoint which triggers
   182        * TcpSocketImpl::Destroy, below.  When m_tcp->DeAllocate is called, it 
   179        * in turn a call to the method ::Destroy below
   183        * will in turn call into Ipv4EndpointDemux::DeAllocate with the endpoint
   180        * will will zero the m_endPoint field.
   184        * (m_endPoint).  The demux will look up the endpoint and destroy it (the
       
   185        * corollary is that we don't own the object pointed to by m_endpoint, we
       
   186        * just borrowed it).  The destructor for the endpoint will call the 
       
   187        * DestroyCallback which will then invoke TcpSocketImpl::Destroy below. 
       
   188        * Destroy will zero m_node, m_tcp and m_endpoint.  The zero of m_node and
       
   189        * m_tcp need to be here also in case the endpoint is deallocated before 
       
   190        * shutdown.
   181        */
   191        */
   182       NS_ASSERT (m_endPoint != 0);
   192       NS_ASSERT (m_endPoint != 0);
   183       m_tcp->DeAllocate (m_endPoint);
   193       m_tcp->DeAllocate (m_endPoint);
   184       NS_ASSERT (m_endPoint == 0);
   194       NS_ASSERT (m_endPoint == 0);
   185     }
   195     }
   190 
   200 
   191 void
   201 void
   192 TcpSocketImpl::SetNode (Ptr<Node> node)
   202 TcpSocketImpl::SetNode (Ptr<Node> node)
   193 {
   203 {
   194   m_node = node;
   204   m_node = node;
   195   // Initialize some variables 
   205   /*
       
   206    * Set the congestion window to IW.  This method is called from the L4 
       
   207    * Protocol after it creates the socket.  The Attribute system takes
       
   208    * care of setting m_initialCWnd and m_segmentSize to their default
       
   209    * values.  m_cWnd depends on m_initialCwnd and m_segmentSize so it
       
   210    * also needs to be updated in SetInitialCwnd and SetSegSize.
       
   211    */
   196   m_cWnd = m_initialCWnd * m_segmentSize;
   212   m_cWnd = m_initialCWnd * m_segmentSize;
   197 }
   213 }
   198 
   214 
   199 void 
   215 void 
   200 TcpSocketImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
   216 TcpSocketImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
   319       return 0;
   335       return 0;
   320     }
   336     }
   321 
   337 
   322   Actions_t action  = ProcessEvent (APP_CLOSE);
   338   Actions_t action  = ProcessEvent (APP_CLOSE);
   323   ProcessAction (action);
   339   ProcessAction (action);
   324   ShutdownSend ();
       
   325   return 0;
   340   return 0;
   326 }
   341 }
   327 
   342 
   328 int
   343 int
   329 TcpSocketImpl::Connect (const Address & address)
   344 TcpSocketImpl::Connect (const Address & address)
   347   
   362   
   348   if (ipv4->GetRoutingProtocol () != 0)
   363   if (ipv4->GetRoutingProtocol () != 0)
   349     {
   364     {
   350       Ipv4Header header;
   365       Ipv4Header header;
   351       header.SetDestination (m_remoteAddress);
   366       header.SetDestination (m_remoteAddress);
   352       Socket::SocketErrno errno;
   367       Socket::SocketErrno errno_;
   353       Ptr<Ipv4Route> route;
   368       Ptr<Ipv4Route> route;
   354       uint32_t oif = 0; //specify non-zero if bound to a source address
   369       uint32_t oif = 0; //specify non-zero if bound to a source address
   355       // XXX here, cache the route in the endpoint?
   370       // XXX here, cache the route in the endpoint?
   356       route = ipv4->GetRoutingProtocol ()->RouteOutput (header, oif, errno);
   371       route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
   357       if (route != 0)
   372       if (route != 0)
   358         {
   373         {
   359           NS_LOG_LOGIC ("Route exists");
   374           NS_LOG_LOGIC ("Route exists");
   360           m_endPoint->SetLocalAddress (route->GetSource ());
   375           m_endPoint->SetLocalAddress (route->GetSource ());
   361         }
   376         }
   362       else
   377       else
   363         {
   378         {
   364           NS_LOG_LOGIC ("TcpSocketImpl::Connect():  Route to " << m_remoteAddress << " does not exist");
   379           NS_LOG_LOGIC ("TcpSocketImpl::Connect():  Route to " << m_remoteAddress << " does not exist");
   365           NS_LOG_ERROR (errno);
   380           NS_LOG_ERROR (errno_);
   366           m_errno = errno;
   381           m_errno = errno_;
   367           return -1;
   382           return -1;
   368         }
   383         }
   369     }
   384     }
   370   else
   385   else
   371     {
   386     {
   652   States_t saveState = m_state;
   667   States_t saveState = m_state;
   653   NS_LOG_LOGIC ("TcpSocketImpl " << this << " processing event " << e);
   668   NS_LOG_LOGIC ("TcpSocketImpl " << this << " processing event " << e);
   654   // simulation singleton is a way to get a single global static instance of a
   669   // simulation singleton is a way to get a single global static instance of a
   655   // class intended to be a singleton; see simulation-singleton.h
   670   // class intended to be a singleton; see simulation-singleton.h
   656   SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
   671   SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
       
   672   NS_LOG_LOGIC ("TcpSocketImpl::ProcessEvent stateAction " << stateAction.action);
   657   // debug
   673   // debug
   658   if (stateAction.action == RST_TX)
   674   if (stateAction.action == RST_TX)
   659     {
   675     {
   660       NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state "
   676       NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state "
   661               << saveState << " event " << e);
   677               << saveState << " event " << e);
   676       Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
   692       Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
   677       //NotifyConnectionSucceeded ();
   693       //NotifyConnectionSucceeded ();
   678       m_connected = true;
   694       m_connected = true;
   679       m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
   695       m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
   680       NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
   696       NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
       
   697     }
       
   698   if (saveState < CLOSING && (m_state == CLOSING || m_state == TIMED_WAIT) )
       
   699     {
       
   700       NS_LOG_LOGIC ("TcpSocketImpl peer closing, send EOF to application");
       
   701       NotifyDataRecv ();
   681     }
   702     }
   682 
   703 
   683   if (needCloseNotify && !m_closeNotified)
   704   if (needCloseNotify && !m_closeNotified)
   684     {
   705     {
   685       NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from " 
   706       NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from " 
   691               << " event " << e);
   712               << " event " << e);
   692       NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from "
   713       NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from "
   693           << m_state << " event " << e
   714           << m_state << " event " << e
   694           << " set CloseNotif ");
   715           << " set CloseNotif ");
   695     }
   716     }
       
   717 
       
   718   if (m_state == CLOSED && saveState != CLOSED && m_endPoint != 0)
       
   719     {
       
   720       NS_ASSERT (m_tcp != 0);
       
   721       /*
       
   722        * We want to deallocate the endpoint now.  We can't just naively call
       
   723        * Deallocate (see the comment in TcpSocketImpl::~TcpSocketImpl), we 
       
   724        * have to turn off the DestroyCallback to keep it from calling back 
       
   725        * into TcpSocketImpl::Destroy and closing pretty much everything down.
       
   726        * Once we have the callback disconnected, we can DeAllocate the
       
   727        * endpoint which actually deals with destroying the actual endpoint,
       
   728        * and then zero our member varible on general principles.
       
   729        */
       
   730       m_endPoint->SetDestroyCallback(MakeNullCallback<void>());
       
   731       m_tcp->DeAllocate (m_endPoint);
       
   732       m_endPoint = 0;
       
   733     }
       
   734     
   696   return stateAction.action;
   735   return stateAction.action;
   697 }
   736 }
   698 
   737 
   699 void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
   738 void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
   700 {
   739 {
   819   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   858   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   820 
   859 
   821   switch (a)
   860   switch (a)
   822   {
   861   {
   823     case ACK_TX:
   862     case ACK_TX:
       
   863       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX");
   824       if(tcpHeader.GetFlags() & TcpHeader::FIN)
   864       if(tcpHeader.GetFlags() & TcpHeader::FIN)
   825       {
   865       {
   826         ++m_nextRxSequence; //bump this to account for the FIN
   866         ++m_nextRxSequence; //bump this to account for the FIN
   827       }
   867       }
   828       SendEmptyPacket (TcpHeader::ACK);
   868       SendEmptyPacket (TcpHeader::ACK);
   848 
   888 
   849         // Look up the source address
   889         // Look up the source address
   850         if (ipv4->GetRoutingProtocol () != 0)
   890         if (ipv4->GetRoutingProtocol () != 0)
   851           {
   891           {
   852             Ipv4Header header;
   892             Ipv4Header header;
   853             Socket::SocketErrno errno;
   893             Socket::SocketErrno errno_;
   854             Ptr<Ipv4Route> route;
   894             Ptr<Ipv4Route> route;
   855             uint32_t oif = 0; //specify non-zero if bound to a source address
   895             uint32_t oif = 0; //specify non-zero if bound to a source address
   856             header.SetDestination (m_remoteAddress);
   896             header.SetDestination (m_remoteAddress);
   857             route = ipv4->GetRoutingProtocol ()->RouteOutput (header, oif, errno);
   897             route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
   858             if (route != 0)
   898             if (route != 0)
   859               {
   899               {
   860                 NS_LOG_LOGIC ("Route exists");
   900                 NS_LOG_LOGIC ("Route exists");
   861                 m_endPoint->SetLocalAddress (route->GetSource ());
   901                 m_endPoint->SetLocalAddress (route->GetSource ());
   862               }
   902               }
   863             else
   903             else
   864               {
   904               {
   865                 NS_LOG_ERROR (errno);
   905                 NS_LOG_ERROR (errno_);
   866                 m_errno = errno;
   906                 m_errno = errno_;
   867                 return -1;
   907                 return -1;
   868               }
   908               }
   869           }
   909           }
   870         else
   910         else
   871           {
   911           {
  1151   NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
  1191   NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
  1152   NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
  1192   NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
  1153                 << " seq " << tcpHeader.GetSequenceNumber()
  1193                 << " seq " << tcpHeader.GetSequenceNumber()
  1154                 << " ack " << tcpHeader.GetAckNumber()
  1194                 << " ack " << tcpHeader.GetAckNumber()
  1155                 << " p.size is " << p->GetSize () );
  1195                 << " p.size is " << p->GetSize () );
  1156   NS_LOG_DEBUG ("TcpSocketImpl " << this <<
       
  1157                 " NewRx," <<
       
  1158                 " seq " << tcpHeader.GetSequenceNumber() <<
       
  1159                 " ack " << tcpHeader.GetAckNumber() <<
       
  1160                 " p.size is " << p->GetSize());
       
  1161   States_t origState = m_state;
  1196   States_t origState = m_state;
  1162   if (RxBufferFreeSpace() < p->GetSize()) 
  1197   if (RxBufferFreeSpace() < p->GetSize()) 
  1163     { //if not enough room, fragment
  1198     { //if not enough room, fragment
  1164       p = p->CreateFragment(0, RxBufferFreeSpace());
  1199       p = p->CreateFragment(0, RxBufferFreeSpace());
  1165     }
  1200     }
  1623 
  1658 
  1624 void
  1659 void
  1625 TcpSocketImpl::SetSegSize (uint32_t size)
  1660 TcpSocketImpl::SetSegSize (uint32_t size)
  1626 {
  1661 {
  1627   m_segmentSize = size;
  1662   m_segmentSize = size;
       
  1663   /*
       
  1664    * Make sure that the congestion window is initialized for IW properly.  We
       
  1665    * can't do this after the connection starts up or would would most likely 
       
  1666    * change m_cWnd out from under the protocol.  That would be Bad (TM).
       
  1667    */
       
  1668   NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpSocketImpl::SetSegSize(): Cannot change segment size dynamically.");
       
  1669   m_cWnd = m_initialCWnd * m_segmentSize;
  1628 }
  1670 }
  1629 
  1671 
  1630 uint32_t
  1672 uint32_t
  1631 TcpSocketImpl::GetSegSize (void) const
  1673 TcpSocketImpl::GetSegSize (void) const
  1632 {
  1674 {
  1647 
  1689 
  1648 void
  1690 void
  1649 TcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
  1691 TcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
  1650 {
  1692 {
  1651   m_initialCWnd = cwnd;
  1693   m_initialCWnd = cwnd;
       
  1694   /*
       
  1695    * Make sure that the congestion window is initialized for IW properly.  We
       
  1696    * can't do this after the connection starts up or would would most likely 
       
  1697    * change m_cWnd out from under the protocol.  That would be Bad (TM).
       
  1698    */
       
  1699   NS_ABORT_MSG_UNLESS (m_state == CLOSED, "TcpSocketImpl::SetInitialCwnd(): Cannot change initial cwnd dynamically.");
       
  1700   m_cWnd = m_initialCWnd * m_segmentSize;
  1652 }
  1701 }
  1653 
  1702 
  1654 uint32_t
  1703 uint32_t
  1655 TcpSocketImpl::GetInitialCwnd (void) const
  1704 TcpSocketImpl::GetInitialCwnd (void) const
  1656 {
  1705 {