PageRenderTime 192ms CodeModel.GetById 77ms app.highlight 103ms RepoModel.GetById 0ms app.codeStats 1ms

/src/internet/model/tcp-socket-base.cc

https://github.com/scarletttu/ns-3-codel-dev
C++ | 2293 lines | 1904 code | 157 blank | 232 comment | 491 complexity | 36f750ef4f764a953e53febbbcc2be36 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
   2/*
   3 * Copyright (c) 2007 Georgia Tech Research Corporation
   4 * Copyright (c) 2010 Adrian Sai-wah Tam
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation;
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 *
  19 * Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
  20 */
  21
  22#define NS_LOG_APPEND_CONTEXT \
  23  if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
  24
  25#include <cstdlib>
  26#include "ns3/abort.h"
  27#include "ns3/node.h"
  28#include "ns3/inet-socket-address.h"
  29#include "ns3/inet6-socket-address.h"
  30#include "ns3/log.h"
  31#include "ns3/ipv4.h"
  32#include "ns3/ipv6.h"
  33#include "ns3/ipv4-interface-address.h"
  34#include "ns3/ipv4-route.h"
  35#include "ns3/ipv6-route.h"
  36#include "ns3/ipv4-routing-protocol.h"
  37#include "ns3/ipv6-routing-protocol.h"
  38#include "ns3/simulation-singleton.h"
  39#include "ns3/simulator.h"
  40#include "ns3/packet.h"
  41#include "ns3/uinteger.h"
  42#include "ns3/double.h"
  43#include "ns3/trace-source-accessor.h"
  44#include "tcp-socket-base.h"
  45#include "tcp-l4-protocol.h"
  46#include "ipv4-end-point.h"
  47#include "ipv6-end-point.h"
  48#include "ipv6-l3-protocol.h"
  49#include "tcp-header.h"
  50#include "rtt-estimator.h"
  51
  52#include <algorithm>
  53
  54NS_LOG_COMPONENT_DEFINE ("TcpSocketBase");
  55
  56namespace ns3 {
  57
  58NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase);
  59
  60TypeId
  61TcpSocketBase::GetTypeId (void)
  62{
  63  static TypeId tid = TypeId ("ns3::TcpSocketBase")
  64    .SetParent<TcpSocket> ()
  65//    .AddAttribute ("TcpState", "State in TCP state machine",
  66//                   TypeId::ATTR_GET,
  67//                   EnumValue (CLOSED),
  68//                   MakeEnumAccessor (&TcpSocketBase::m_state),
  69//                   MakeEnumChecker (CLOSED, "Closed"))
  70    .AddAttribute ("MaxSegLifetime",
  71                   "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
  72                   DoubleValue (120), /* RFC793 says MSL=2 minutes*/
  73                   MakeDoubleAccessor (&TcpSocketBase::m_msl),
  74                   MakeDoubleChecker<double> (0))
  75    .AddAttribute ("MaxWindowSize", "Max size of advertised window",
  76                   UintegerValue (65535),
  77                   MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
  78                   MakeUintegerChecker<uint16_t> ())
  79    .AddTraceSource ("RTO",
  80                     "Retransmission timeout",
  81                     MakeTraceSourceAccessor (&TcpSocketBase::m_rto))
  82    .AddTraceSource ("RTT",
  83                     "Last RTT sample",
  84                     MakeTraceSourceAccessor (&TcpSocketBase::m_lastRtt))
  85    .AddTraceSource ("NextTxSequence",
  86                     "Next sequence number to send (SND.NXT)",
  87                     MakeTraceSourceAccessor (&TcpSocketBase::m_nextTxSequence))
  88    .AddTraceSource ("HighestSequence",
  89                     "Highest sequence number ever sent in socket's life time",
  90                     MakeTraceSourceAccessor (&TcpSocketBase::m_highTxMark))
  91    .AddTraceSource ("State",
  92                     "TCP state",
  93                     MakeTraceSourceAccessor (&TcpSocketBase::m_state))
  94    .AddTraceSource ("RWND",
  95                     "Remote side's flow control window",
  96                     MakeTraceSourceAccessor (&TcpSocketBase::m_rWnd))
  97  ;
  98  return tid;
  99}
 100
 101TcpSocketBase::TcpSocketBase (void)
 102  : m_dupAckCount (0),
 103    m_delAckCount (0),
 104    m_endPoint (0),
 105    m_endPoint6 (0),
 106    m_node (0),
 107    m_tcp (0),
 108    m_rtt (0),
 109    m_nextTxSequence (std::rand ()),
 110    // Change this for non-zero initial sequence number
 111    m_highTxMark (0),
 112    m_rxBuffer (0),
 113    m_txBuffer (0),
 114    m_state (CLOSED),
 115    m_errno (ERROR_NOTERROR),
 116    m_closeNotified (false),
 117    m_closeOnEmpty (false),
 118    m_shutdownSend (false),
 119    m_shutdownRecv (false),
 120    m_connected (false),
 121    m_segmentSize (0),
 122    // For attribute initialization consistency (quiet valgrind)
 123    m_rWnd (0)
 124{
 125  NS_LOG_FUNCTION (this);
 126}
 127
 128TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock)
 129  : TcpSocket (sock),
 130    //copy object::m_tid and socket::callbacks
 131    m_dupAckCount (sock.m_dupAckCount),
 132    m_delAckCount (0),
 133    m_delAckMaxCount (sock.m_delAckMaxCount),
 134    m_noDelay (sock.m_noDelay),
 135    m_cnRetries (sock.m_cnRetries),
 136    m_delAckTimeout (sock.m_delAckTimeout),
 137    m_persistTimeout (sock.m_persistTimeout),
 138    m_cnTimeout (sock.m_cnTimeout),
 139    m_endPoint (0),
 140    m_endPoint6 (0),
 141    m_node (sock.m_node),
 142    m_tcp (sock.m_tcp),
 143    m_rtt (0),
 144    m_nextTxSequence (sock.m_nextTxSequence),
 145    m_highTxMark (sock.m_highTxMark),
 146    m_rxBuffer (sock.m_rxBuffer),
 147    m_txBuffer (sock.m_txBuffer),
 148    m_state (sock.m_state),
 149    m_errno (sock.m_errno),
 150    m_closeNotified (sock.m_closeNotified),
 151    m_closeOnEmpty (sock.m_closeOnEmpty),
 152    m_shutdownSend (sock.m_shutdownSend),
 153    m_shutdownRecv (sock.m_shutdownRecv),
 154    m_connected (sock.m_connected),
 155    m_msl (sock.m_msl),
 156    m_segmentSize (sock.m_segmentSize),
 157    m_maxWinSize (sock.m_maxWinSize),
 158    m_rWnd (sock.m_rWnd)
 159{
 160  NS_LOG_FUNCTION (this);
 161  NS_LOG_LOGIC ("Invoked the copy constructor");
 162  // Copy the rtt estimator if it is set
 163  if (sock.m_rtt)
 164    {
 165      m_rtt = sock.m_rtt->Copy ();
 166    }
 167  // Reset all callbacks to null
 168  Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
 169  Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
 170  Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
 171  SetConnectCallback (vPS, vPS);
 172  SetDataSentCallback (vPSUI);
 173  SetSendCallback (vPSUI);
 174  SetRecvCallback (vPS);
 175}
 176
 177TcpSocketBase::~TcpSocketBase (void)
 178{
 179  NS_LOG_FUNCTION (this);
 180  m_node = 0;
 181  if (m_endPoint != 0)
 182    {
 183      NS_ASSERT (m_tcp != 0);
 184      /*
 185       * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
 186       * DestroyCallback is set to TcpSocketBase::Destroy. If we called
 187       * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
 188       * which in turn destroys my m_endPoint, and in turn invokes
 189       * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
 190       */
 191      NS_ASSERT (m_endPoint != 0);
 192      m_tcp->DeAllocate (m_endPoint);
 193      NS_ASSERT (m_endPoint == 0);
 194    }
 195  if (m_endPoint6 != 0)
 196    {
 197      NS_ASSERT (m_tcp != 0);
 198      NS_ASSERT (m_endPoint6 != 0);
 199      m_tcp->DeAllocate (m_endPoint6);
 200      NS_ASSERT (m_endPoint6 == 0);
 201    }
 202  m_tcp = 0;
 203  CancelAllTimers ();
 204}
 205
 206/** Associate a node with this TCP socket */
 207void
 208TcpSocketBase::SetNode (Ptr<Node> node)
 209{
 210  m_node = node;
 211}
 212
 213/** Associate the L4 protocol (e.g. mux/demux) with this socket */
 214void
 215TcpSocketBase::SetTcp (Ptr<TcpL4Protocol> tcp)
 216{
 217  m_tcp = tcp;
 218}
 219
 220/** Set an RTT estimator with this socket */
 221void
 222TcpSocketBase::SetRtt (Ptr<RttEstimator> rtt)
 223{
 224  m_rtt = rtt;
 225}
 226
 227/** Inherit from Socket class: Returns error code */
 228enum Socket::SocketErrno
 229TcpSocketBase::GetErrno (void) const
 230{
 231  return m_errno;
 232}
 233
 234/** Inherit from Socket class: Returns socket type, NS3_SOCK_STREAM */
 235enum Socket::SocketType
 236TcpSocketBase::GetSocketType (void) const
 237{
 238  return NS3_SOCK_STREAM;
 239}
 240
 241/** Inherit from Socket class: Returns associated node */
 242Ptr<Node>
 243TcpSocketBase::GetNode (void) const
 244{
 245  NS_LOG_FUNCTION_NOARGS ();
 246  return m_node;
 247}
 248
 249/** Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */
 250int
 251TcpSocketBase::Bind (void)
 252{
 253  NS_LOG_FUNCTION (this);
 254  m_endPoint = m_tcp->Allocate ();
 255  if (0 == m_endPoint)
 256    {
 257      m_errno = ERROR_ADDRNOTAVAIL;
 258      return -1;
 259    }
 260  m_tcp->m_sockets.push_back (this);
 261  return SetupCallback ();
 262}
 263
 264int
 265TcpSocketBase::Bind6 (void)
 266{
 267  NS_LOG_FUNCTION (this);
 268  m_endPoint6 = m_tcp->Allocate6 ();
 269  if (0 == m_endPoint6)
 270    {
 271      m_errno = ERROR_ADDRNOTAVAIL;
 272      return -1;
 273    }
 274  m_tcp->m_sockets.push_back (this);
 275  return SetupCallback ();
 276}
 277
 278/** Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
 279int
 280TcpSocketBase::Bind (const Address &address)
 281{
 282  NS_LOG_FUNCTION (this << address);
 283  if (InetSocketAddress::IsMatchingType (address))
 284    {
 285      InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
 286      Ipv4Address ipv4 = transport.GetIpv4 ();
 287      uint16_t port = transport.GetPort ();
 288      if (ipv4 == Ipv4Address::GetAny () && port == 0)
 289        {
 290          m_endPoint = m_tcp->Allocate ();
 291        }
 292      else if (ipv4 == Ipv4Address::GetAny () && port != 0)
 293        {
 294          m_endPoint = m_tcp->Allocate (port);
 295        }
 296      else if (ipv4 != Ipv4Address::GetAny () && port == 0)
 297        {
 298          m_endPoint = m_tcp->Allocate (ipv4);
 299        }
 300      else if (ipv4 != Ipv4Address::GetAny () && port != 0)
 301        {
 302          m_endPoint = m_tcp->Allocate (ipv4, port);
 303        }
 304      if (0 == m_endPoint)
 305        {
 306          m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
 307          return -1;
 308        }
 309    }
 310  else if (Inet6SocketAddress::IsMatchingType (address))
 311    {
 312      Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
 313      Ipv6Address ipv6 = transport.GetIpv6 ();
 314      uint16_t port = transport.GetPort ();
 315      if (ipv6 == Ipv6Address::GetAny () && port == 0)
 316        {
 317          m_endPoint6 = m_tcp->Allocate6 ();
 318        }
 319      else if (ipv6 == Ipv6Address::GetAny () && port != 0)
 320        {
 321          m_endPoint6 = m_tcp->Allocate6 (port);
 322        }
 323      else if (ipv6 != Ipv6Address::GetAny () && port == 0)
 324        {
 325          m_endPoint6 = m_tcp->Allocate6 (ipv6);
 326        }
 327      else if (ipv6 != Ipv6Address::GetAny () && port != 0)
 328        {
 329          m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
 330        }
 331      if (0 == m_endPoint6)
 332        {
 333          m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
 334          return -1;
 335        }
 336    }
 337  else
 338    {
 339      m_errno = ERROR_INVAL;
 340      return -1;
 341    }
 342  m_tcp->m_sockets.push_back (this);
 343  NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
 344
 345  return SetupCallback ();
 346}
 347
 348/** Inherit from Socket class: Initiate connection to a remote address:port */
 349int
 350TcpSocketBase::Connect (const Address & address)
 351{
 352  NS_LOG_FUNCTION (this << address);
 353
 354  // If haven't do so, Bind() this socket first
 355  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
 356    {
 357      if (m_endPoint == 0)
 358        {
 359          if (Bind () == -1)
 360            {
 361              NS_ASSERT (m_endPoint == 0);
 362              return -1; // Bind() failed
 363            }
 364          NS_ASSERT (m_endPoint != 0);
 365        }
 366      InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
 367      m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
 368      m_endPoint6 = 0;
 369
 370      // Get the appropriate local address and port number from the routing protocol and set up endpoint
 371      if (SetupEndpoint () != 0)
 372        { // Route to destination does not exist
 373          return -1;
 374        }
 375    }
 376  else if (Inet6SocketAddress::IsMatchingType (address)  && m_endPoint == 0)
 377    {
 378      // If we are operating on a v4-mapped address, translate the address to
 379      // a v4 address and re-call this function
 380      Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
 381      Ipv6Address v6Addr = transport.GetIpv6 ();
 382      if (v6Addr.IsIpv4MappedAddress () == true)
 383        {
 384          Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
 385          return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
 386        }
 387
 388      if (m_endPoint6 == 0)
 389        {
 390          if (Bind6 () == -1)
 391            {
 392              NS_ASSERT (m_endPoint6 == 0);
 393              return -1; // Bind() failed
 394            }
 395          NS_ASSERT (m_endPoint6 != 0);
 396        }
 397      m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
 398      m_endPoint = 0;
 399
 400      // Get the appropriate local address and port number from the routing protocol and set up endpoint
 401      if (SetupEndpoint6 () != 0)
 402        { // Route to destination does not exist
 403          return -1;
 404        }
 405    }
 406  else
 407    {
 408      m_errno = ERROR_INVAL;
 409      return -1;
 410    }
 411
 412  // Re-initialize parameters in case this socket is being reused after CLOSE
 413  m_rtt->Reset ();
 414  m_cnCount = m_cnRetries;
 415
 416  // DoConnect() will do state-checking and send a SYN packet
 417  return DoConnect ();
 418}
 419
 420/** Inherit from Socket class: Listen on the endpoint for an incoming connection */
 421int
 422TcpSocketBase::Listen (void)
 423{
 424  NS_LOG_FUNCTION (this);
 425  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
 426  if (m_state != CLOSED)
 427    {
 428      m_errno = ERROR_INVAL;
 429      return -1;
 430    }
 431  // In other cases, set the state to LISTEN and done
 432  NS_LOG_INFO ("CLOSED -> LISTEN");
 433  m_state = LISTEN;
 434  return 0;
 435}
 436
 437/** Inherit from Socket class: Kill this socket and signal the peer (if any) */
 438int
 439TcpSocketBase::Close (void)
 440{
 441  NS_LOG_FUNCTION (this);
 442  // First we check to see if there is any unread rx data
 443  // Bug number 426 claims we should send reset in this case.
 444  if (m_rxBuffer.Size () != 0)
 445    {
 446      SendRST ();
 447      return 0;
 448    }
 449  if (m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0)
 450    { // App close with pending data must wait until all data transmitted
 451      if (m_closeOnEmpty == false)
 452        {
 453          m_closeOnEmpty = true;
 454          NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
 455        }
 456      return 0;
 457    }
 458  return DoClose ();
 459}
 460
 461/** Inherit from Socket class: Signal a termination of send */
 462int
 463TcpSocketBase::ShutdownSend (void)
 464{
 465  NS_LOG_FUNCTION (this);
 466  m_shutdownSend = true;
 467  return 0;
 468}
 469
 470/** Inherit from Socket class: Signal a termination of receive */
 471int
 472TcpSocketBase::ShutdownRecv (void)
 473{
 474  NS_LOG_FUNCTION (this);
 475  m_shutdownRecv = true;
 476  return 0;
 477}
 478
 479/** Inherit from Socket class: Send a packet. Parameter flags is not used.
 480    Packet has no TCP header. Invoked by upper-layer application */
 481int
 482TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
 483{
 484  NS_LOG_FUNCTION (this << p);
 485  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
 486  if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
 487    {
 488      // Store the packet into Tx buffer
 489      if (!m_txBuffer.Add (p))
 490        { // TxBuffer overflow, send failed
 491          m_errno = ERROR_MSGSIZE;
 492          return -1;
 493        }
 494      // Submit the data to lower layers
 495      NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
 496      if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
 497        { // Try to send the data out
 498          SendPendingData (m_connected);
 499        }
 500      return p->GetSize ();
 501    }
 502  else
 503    { // Connection not established yet
 504      m_errno = ERROR_NOTCONN;
 505      return -1; // Send failure
 506    }
 507}
 508
 509/** Inherit from Socket class: In TcpSocketBase, it is same as Send() call */
 510int
 511TcpSocketBase::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
 512{
 513  return Send (p, flags); // SendTo() and Send() are the same
 514}
 515
 516/** Inherit from Socket class: Return data to upper-layer application. Parameter flags
 517    is not used. Data is returned as a packet of size no larger than maxSize */
 518Ptr<Packet>
 519TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
 520{
 521  NS_LOG_FUNCTION (this);
 522  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
 523  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
 524    {
 525      return Create<Packet> (); // Send EOF on connection close
 526    }
 527  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
 528  if (outPacket != 0 && outPacket->GetSize () != 0)
 529    {
 530      SocketAddressTag tag;
 531      if (m_endPoint != 0)
 532        {
 533          tag.SetAddress (InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ()));
 534        }
 535      else if (m_endPoint6 != 0)
 536        {
 537          tag.SetAddress (Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ()));
 538        }
 539      outPacket->AddPacketTag (tag);
 540    }
 541  return outPacket;
 542}
 543
 544/** Inherit from Socket class: Recv and return the remote's address */
 545Ptr<Packet>
 546TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
 547{
 548  NS_LOG_FUNCTION (this << maxSize << flags);
 549  Ptr<Packet> packet = Recv (maxSize, flags);
 550  // Null packet means no data to read, and an empty packet indicates EOF
 551  if (packet != 0 && packet->GetSize () != 0)
 552    {
 553      if (m_endPoint != 0)
 554        {
 555          fromAddress = InetSocketAddress (m_endPoint->GetPeerAddress (), m_endPoint->GetPeerPort ());
 556        }
 557      else if (m_endPoint6 != 0)
 558        {
 559          fromAddress = Inet6SocketAddress (m_endPoint6->GetPeerAddress (), m_endPoint6->GetPeerPort ());
 560        }
 561      else
 562        {
 563          fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
 564        }
 565    }
 566  return packet;
 567}
 568
 569/** Inherit from Socket class: Get the max number of bytes an app can send */
 570uint32_t
 571TcpSocketBase::GetTxAvailable (void) const
 572{
 573  NS_LOG_FUNCTION (this);
 574  return m_txBuffer.Available ();
 575}
 576
 577/** Inherit from Socket class: Get the max number of bytes an app can read */
 578uint32_t
 579TcpSocketBase::GetRxAvailable (void) const
 580{
 581  NS_LOG_FUNCTION (this);
 582  return m_rxBuffer.Available ();
 583}
 584
 585/** Inherit from Socket class: Return local address:port */
 586int
 587TcpSocketBase::GetSockName (Address &address) const
 588{
 589  NS_LOG_FUNCTION (this);
 590  if (m_endPoint != 0)
 591    {
 592      address = InetSocketAddress (m_endPoint->GetLocalAddress (), m_endPoint->GetLocalPort ());
 593    }
 594  else if (m_endPoint6 != 0)
 595    {
 596      address = Inet6SocketAddress (m_endPoint6->GetLocalAddress (), m_endPoint6->GetLocalPort ());
 597    }
 598  else
 599    { // It is possible to call this method on a socket without a name
 600      // in which case, behavior is unspecified
 601      // Should this return an InetSocketAddress or an Inet6SocketAddress?
 602      address = InetSocketAddress (Ipv4Address::GetZero (), 0);
 603    }
 604  return 0;
 605}
 606
 607/** Inherit from Socket class: Bind this socket to the specified NetDevice */
 608void
 609TcpSocketBase::BindToNetDevice (Ptr<NetDevice> netdevice)
 610{
 611  NS_LOG_FUNCTION (netdevice);
 612  Socket::BindToNetDevice (netdevice); // Includes sanity check
 613  if (m_endPoint == 0 && m_endPoint6 == 0)
 614    {
 615      if (Bind () == -1)
 616        {
 617          NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
 618          return;
 619        }
 620      NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
 621    }
 622
 623  if (m_endPoint != 0)
 624    {
 625      m_endPoint->BindToNetDevice (netdevice);
 626    }
 627  // No BindToNetDevice() for Ipv6EndPoint
 628  return;
 629}
 630
 631/** Clean up after Bind. Set up callback functions in the end-point. */
 632int
 633TcpSocketBase::SetupCallback (void)
 634{
 635  NS_LOG_FUNCTION (this);
 636
 637  if (m_endPoint == 0 && m_endPoint6 == 0)
 638    {
 639      return -1;
 640    }
 641  if (m_endPoint != 0)
 642    {
 643      m_endPoint->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp, Ptr<TcpSocketBase> (this)));
 644      m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
 645    }
 646  if (m_endPoint6 != 0)
 647    {
 648      m_endPoint6->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp6, Ptr<TcpSocketBase> (this)));
 649      m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy6, Ptr<TcpSocketBase> (this)));
 650    }
 651
 652  return 0;
 653}
 654
 655/** Perform the real connection tasks: Send SYN if allowed, RST if invalid */
 656int
 657TcpSocketBase::DoConnect (void)
 658{
 659  NS_LOG_FUNCTION (this);
 660
 661  // A new connection is allowed only if this socket does not have a connection
 662  if (m_state == CLOSED || m_state == LISTEN || m_state == SYN_SENT || m_state == LAST_ACK || m_state == CLOSE_WAIT)
 663    { // send a SYN packet and change state into SYN_SENT
 664      SendEmptyPacket (TcpHeader::SYN);
 665      NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
 666      m_state = SYN_SENT;
 667    }
 668  else if (m_state != TIME_WAIT)
 669    { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
 670      // exists. We send RST, tear down everything, and close this socket.
 671      SendRST ();
 672      CloseAndNotify ();
 673    }
 674  return 0;
 675}
 676
 677/** Do the action to close the socket. Usually send a packet with appropriate
 678    flags depended on the current m_state. */
 679int
 680TcpSocketBase::DoClose (void)
 681{
 682  NS_LOG_FUNCTION (this);
 683  switch (m_state)
 684    {
 685    case SYN_RCVD:
 686    case ESTABLISHED:
 687      // send FIN to close the peer
 688      SendEmptyPacket (TcpHeader::FIN);
 689      NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
 690      m_state = FIN_WAIT_1;
 691      break;
 692    case CLOSE_WAIT:
 693      // send FIN+ACK to close the peer
 694      SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
 695      NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
 696      m_state = LAST_ACK;
 697      break;
 698    case SYN_SENT:
 699    case CLOSING:
 700      // Send RST if application closes in SYN_SENT and CLOSING
 701      SendRST ();
 702      CloseAndNotify ();
 703      break;
 704    case LISTEN:
 705    case LAST_ACK:
 706      // In these three states, move to CLOSED and tear down the end point
 707      CloseAndNotify ();
 708      break;
 709    case CLOSED:
 710    case FIN_WAIT_1:
 711    case FIN_WAIT_2:
 712    case TIME_WAIT:
 713    default: /* mute compiler */
 714      // Do nothing in these four states
 715      break;
 716    }
 717  return 0;
 718}
 719
 720/** Peacefully close the socket by notifying the upper layer and deallocate end point */
 721void
 722TcpSocketBase::CloseAndNotify (void)
 723{
 724  NS_LOG_FUNCTION (this);
 725
 726  if (!m_closeNotified)
 727    {
 728      NotifyNormalClose ();
 729    }
 730  if (m_state != TIME_WAIT)
 731    {
 732      DeallocateEndPoint ();
 733    }
 734  m_closeNotified = true;
 735  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
 736  CancelAllTimers ();
 737  m_state = CLOSED;
 738}
 739
 740
 741/** Tell if a sequence number range is out side the range that my rx buffer can
 742    accpet */
 743bool
 744TcpSocketBase::OutOfRange (SequenceNumber32 head, SequenceNumber32 tail) const
 745{
 746  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
 747    { // Rx buffer in these states are not initialized.
 748      return false;
 749    }
 750  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
 751    { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
 752      // sequence number must equals to m_rxBuffer.NextRxSequence ()
 753      return (m_rxBuffer.NextRxSequence () != head);
 754    }
 755
 756  // In all other cases, check if the sequence number is in range
 757  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
 758}
 759
 760/** Function called by the L3 protocol when it received a packet to pass on to
 761    the TCP. This function is registered as the "RxCallback" function in
 762    SetupCallback(), which invoked by Bind(), and CompleteFork() */
 763void
 764TcpSocketBase::ForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
 765                          Ptr<Ipv4Interface> incomingInterface)
 766{
 767  DoForwardUp (packet, header, port, incomingInterface);
 768}
 769
 770void
 771TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
 772{
 773  DoForwardUp (packet, saddr, daddr, port);
 774}
 775
 776/** The real function to handle the incoming packet from lower layers. This is
 777    wrapped by ForwardUp() so that this function can be overloaded by daughter
 778    classes. */
 779void
 780TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv4Header header, uint16_t port,
 781                            Ptr<Ipv4Interface> incomingInterface)
 782{
 783  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
 784                m_endPoint->GetPeerAddress () <<
 785                ":" << m_endPoint->GetPeerPort () <<
 786                " to " << m_endPoint->GetLocalAddress () <<
 787                ":" << m_endPoint->GetLocalPort ());
 788  Address fromAddress = InetSocketAddress (header.GetSource (), port);
 789  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
 790
 791  // Peel off TCP header and do validity checking
 792  TcpHeader tcpHeader;
 793  packet->RemoveHeader (tcpHeader);
 794  if (tcpHeader.GetFlags () & TcpHeader::ACK)
 795    {
 796      EstimateRtt (tcpHeader);
 797    }
 798  ReadOptions (tcpHeader);
 799
 800  // Update Rx window size, i.e. the flow control window
 801  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
 802    { // persist probes end
 803      NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
 804      m_persistEvent.Cancel ();
 805    }
 806  m_rWnd = tcpHeader.GetWindowSize ();
 807
 808  // Discard fully out of range data packets
 809  if (packet->GetSize ()
 810      && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
 811    {
 812      NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
 813                    " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
 814                    ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
 815                    ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
 816                    m_rxBuffer.MaxRxSequence () << ")");
 817      // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
 818      if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
 819        {
 820          SendEmptyPacket (TcpHeader::ACK);
 821        }
 822      return;
 823    }
 824
 825  // TCP state machine code in different process functions
 826  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
 827  switch (m_state)
 828    {
 829    case ESTABLISHED:
 830      ProcessEstablished (packet, tcpHeader);
 831      break;
 832    case LISTEN:
 833      ProcessListen (packet, tcpHeader, fromAddress, toAddress);
 834      break;
 835    case TIME_WAIT:
 836      // Do nothing
 837      break;
 838    case CLOSED:
 839      // Send RST if the incoming packet is not a RST
 840      if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
 841        { // Since m_endPoint is not configured yet, we cannot use SendRST here
 842          TcpHeader h;
 843          h.SetFlags (TcpHeader::RST);
 844          h.SetSequenceNumber (m_nextTxSequence);
 845          h.SetAckNumber (m_rxBuffer.NextRxSequence ());
 846          h.SetSourcePort (tcpHeader.GetDestinationPort ());
 847          h.SetDestinationPort (tcpHeader.GetSourcePort ());
 848          h.SetWindowSize (AdvertisedWindowSize ());
 849          AddOptions (h);
 850          m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
 851        }
 852      break;
 853    case SYN_SENT:
 854      ProcessSynSent (packet, tcpHeader);
 855      break;
 856    case SYN_RCVD:
 857      ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
 858      break;
 859    case FIN_WAIT_1:
 860    case FIN_WAIT_2:
 861    case CLOSE_WAIT:
 862      ProcessWait (packet, tcpHeader);
 863      break;
 864    case CLOSING:
 865      ProcessClosing (packet, tcpHeader);
 866      break;
 867    case LAST_ACK:
 868      ProcessLastAck (packet, tcpHeader);
 869      break;
 870    default: // mute compiler
 871      break;
 872    }
 873}
 874
 875void
 876TcpSocketBase::DoForwardUp (Ptr<Packet> packet, Ipv6Address saddr, Ipv6Address daddr, uint16_t port)
 877{
 878  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
 879                m_endPoint6->GetPeerAddress () <<
 880                ":" << m_endPoint6->GetPeerPort () <<
 881                " to " << m_endPoint6->GetLocalAddress () <<
 882                ":" << m_endPoint6->GetLocalPort ());
 883  Address fromAddress = Inet6SocketAddress (saddr, port);
 884  Address toAddress = Inet6SocketAddress (daddr, m_endPoint6->GetLocalPort ());
 885
 886  // Peel off TCP header and do validity checking
 887  TcpHeader tcpHeader;
 888  packet->RemoveHeader (tcpHeader);
 889  if (tcpHeader.GetFlags () & TcpHeader::ACK)
 890    {
 891      EstimateRtt (tcpHeader);
 892    }
 893  ReadOptions (tcpHeader);
 894
 895  // Update Rx window size, i.e. the flow control window
 896  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
 897    { // persist probes end
 898      NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
 899      m_persistEvent.Cancel ();
 900    }
 901  m_rWnd = tcpHeader.GetWindowSize ();
 902
 903  // Discard fully out of range packets
 904  if (packet->GetSize ()
 905      && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
 906    {
 907      NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
 908                    " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
 909                    ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
 910                    ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
 911                    m_rxBuffer.MaxRxSequence () << ")");
 912      // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
 913      if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
 914        {
 915          SendEmptyPacket (TcpHeader::ACK);
 916        }
 917      return;
 918    }
 919
 920  // TCP state machine code in different process functions
 921  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
 922  switch (m_state)
 923    {
 924    case ESTABLISHED:
 925      ProcessEstablished (packet, tcpHeader);
 926      break;
 927    case LISTEN:
 928      ProcessListen (packet, tcpHeader, fromAddress, toAddress);
 929      break;
 930    case TIME_WAIT:
 931      // Do nothing
 932      break;
 933    case CLOSED:
 934      // Send RST if the incoming packet is not a RST
 935      if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
 936        { // Since m_endPoint is not configured yet, we cannot use SendRST here
 937          TcpHeader h;
 938          h.SetFlags (TcpHeader::RST);
 939          h.SetSequenceNumber (m_nextTxSequence);
 940          h.SetAckNumber (m_rxBuffer.NextRxSequence ());
 941          h.SetSourcePort (tcpHeader.GetDestinationPort ());
 942          h.SetDestinationPort (tcpHeader.GetSourcePort ());
 943          h.SetWindowSize (AdvertisedWindowSize ());
 944          AddOptions (h);
 945          m_tcp->SendPacket (Create<Packet> (), h, daddr, saddr, m_boundnetdevice);
 946        }
 947      break;
 948    case SYN_SENT:
 949      ProcessSynSent (packet, tcpHeader);
 950      break;
 951    case SYN_RCVD:
 952      ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
 953      break;
 954    case FIN_WAIT_1:
 955    case FIN_WAIT_2:
 956    case CLOSE_WAIT:
 957      ProcessWait (packet, tcpHeader);
 958      break;
 959    case CLOSING:
 960      ProcessClosing (packet, tcpHeader);
 961      break;
 962    case LAST_ACK:
 963      ProcessLastAck (packet, tcpHeader);
 964      break;
 965    default: // mute compiler
 966      break;
 967    }
 968}
 969
 970/** Received a packet upon ESTABLISHED state. This function is mimicking the
 971    role of tcp_rcv_established() in tcp_input.c in Linux kernel. */
 972void
 973TcpSocketBase::ProcessEstablished (Ptr<Packet> packet, const TcpHeader& tcpHeader)
 974{
 975  NS_LOG_FUNCTION (this << tcpHeader);
 976
 977  // Extract the flags. PSH and URG are not honoured.
 978  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
 979
 980  // Different flags are different events
 981  if (tcpflags == TcpHeader::ACK)
 982    {
 983      ReceivedAck (packet, tcpHeader);
 984    }
 985  else if (tcpflags == TcpHeader::SYN)
 986    { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
 987      // respond with a SYN+ACK. But it is not a legal state transition as of
 988      // RFC793. Thus this is ignored.
 989    }
 990  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
 991    { // No action for received SYN+ACK, it is probably a duplicated packet
 992    }
 993  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
 994    { // Received FIN or FIN+ACK, bring down this socket nicely
 995      PeerClose (packet, tcpHeader);
 996    }
 997  else if (tcpflags == 0)
 998    { // No flags means there is only data
 999      ReceivedData (packet, tcpHeader);
1000      if (m_rxBuffer.Finished ())
1001        {
1002          PeerClose (packet, tcpHeader);
1003        }
1004    }
1005  else
1006    { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1007      if (tcpflags != TcpHeader::RST)
1008        { // this must be an invalid flag, send reset
1009          NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1010          SendRST ();
1011        }
1012      CloseAndNotify ();
1013    }
1014}
1015
1016/** Process the newly received ACK */
1017void
1018TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
1019{
1020  NS_LOG_FUNCTION (this << tcpHeader);
1021
1022  // Received ACK. Compare the ACK number against highest unacked seqno
1023  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1024    { // Ignore if no ACK flag
1025    }
1026  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1027    { // Case 1: Old ACK, ignored.
1028      NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1029    }
1030  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1031    { // Case 2: Potentially a duplicated ACK
1032      if (tcpHeader.GetAckNumber () < m_nextTxSequence)
1033        {
1034          NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1035          DupAck (tcpHeader, ++m_dupAckCount);
1036        }
1037      // otherwise, the ACK is precisely equal to the nextTxSequence
1038      NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1039    }
1040  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1041    { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1042      NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1043      NewAck (tcpHeader.GetAckNumber ());
1044      m_dupAckCount = 0;
1045    }
1046  // If there is any data piggybacked, store it into m_rxBuffer
1047  if (packet->GetSize () > 0)
1048    {
1049      ReceivedData (packet, tcpHeader);
1050    }
1051}
1052
1053/** Received a packet upon LISTEN state. */
1054void
1055TcpSocketBase::ProcessListen (Ptr<Packet> packet, const TcpHeader& tcpHeader,
1056                              const Address& fromAddress, const Address& toAddress)
1057{
1058  NS_LOG_FUNCTION (this << tcpHeader);
1059
1060  // Extract the flags. PSH and URG are not honoured.
1061  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1062
1063  // Fork a socket if received a SYN. Do nothing otherwise.
1064  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1065  if (tcpflags != TcpHeader::SYN)
1066    {
1067      return;
1068    }
1069
1070  // Call socket's notify function to let the server app know we got a SYN
1071  // If the server app refuses the connection, do nothing
1072  if (!NotifyConnectionRequest (fromAddress))
1073    {
1074      return;
1075    }
1076  // Clone the socket, simulate fork
1077  Ptr<TcpSocketBase> newSock = Fork ();
1078  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1079  Simulator::ScheduleNow (&TcpSocketBase::CompleteFork, newSock,
1080                          packet, tcpHeader, fromAddress, toAddress);
1081}
1082
1083/** Received a packet upon SYN_SENT */
1084void
1085TcpSocketBase::ProcessSynSent (Ptr<Packet> packet, const TcpHeader& tcpHeader)
1086{
1087  NS_LOG_FUNCTION (this << tcpHeader);
1088
1089  // Extract the flags. PSH and URG are not honoured.
1090  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1091
1092  if (tcpflags == 0)
1093    { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1094      NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1095      m_state = ESTABLISHED;
1096      m_connected = true;
1097      m_retxEvent.Cancel ();
1098      m_delAckCount = m_delAckMaxCount;
1099      ReceivedData (packet, tcpHeader);
1100      Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
1101    }
1102  else if (tcpflags == TcpHeader::ACK)
1103    { // Ignore ACK in SYN_SENT
1104    }
1105  else if (tcpflags == TcpHeader::SYN)
1106    { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1107      NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1108      m_state = SYN_RCVD;
1109      m_cnCount = m_cnRetries;
1110      m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
1111      SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
1112    }
1113  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1114           && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1115    { // Handshake completed
1116      NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1117      m_state = ESTABLISHED;
1118      m_connected = true;
1119      m_retxEvent.Cancel ();
1120      m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
1121      m_highTxMark = ++m_nextTxSequence;
1122      m_txBuffer.SetHeadSequence (m_nextTxSequence);
1123      SendEmptyPacket (TcpHeader::ACK);
1124      SendPendingData (m_connected);
1125      Simulator::ScheduleNow (&TcpSocketBase::ConnectionSucceeded, this);
1126      // Always respond to first data packet to speed up the connection.
1127      // Remove to get the behaviour of old NS-3 code.
1128      m_delAckCount = m_delAckMaxCount;
1129    }
1130  else
1131    { // Other in-sequence input
1132      if (tcpflags != TcpHeader::RST)
1133        { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1134          NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1135          SendRST ();
1136        }
1137      CloseAndNotify ();
1138    }
1139}
1140
1141/** Received a packet upon SYN_RCVD */
1142void
1143TcpSocketBase::ProcessSynRcvd (Ptr<Packet> packet, const TcpHeader& tcpHeader,
1144                               const Address& fromAddress, const Address& toAddress)
1145{
1146  NS_LOG_FUNCTION (this << tcpHeader);
1147
1148  // Extract the flags. PSH and URG are not honoured.
1149  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1150
1151  if (tcpflags == 0
1152      || (tcpflags == TcpHeader::ACK
1153          && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1154    { // If it is bare data, accept it and move to ESTABLISHED state. This is
1155      // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1156      // handshake is completed nicely.
1157      NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1158      m_state = ESTABLISHED;
1159      m_connected = true;
1160      m_retxEvent.Cancel ();
1161      m_highTxMark = ++m_nextTxSequence;
1162      m_txBuffer.SetHeadSequence (m_nextTxSequence);
1163      if (m_endPoint)
1164        {
1165          m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1166                               InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1167        }
1168      else if (m_endPoint6)
1169        {
1170          m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1171                                Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1172        }
1173      // Always respond to first data packet to speed up the connection.
1174      // Remove to get the behaviour of old NS-3 code.
1175      m_delAckCount = m_delAckMaxCount;
1176      ReceivedAck (packet, tcpHeader);
1177      NotifyNewConnectionCreated (this, fromAddress);
1178      // As this connection is established, the socket is available to send data now
1179      if (GetTxAvailable () > 0)
1180        {
1181          NotifySend (GetTxAvailable ());
1182        }
1183    }
1184  else if (tcpflags == TcpHeader::SYN)
1185    { // Probably the peer lost my SYN+ACK
1186      m_rxBuffer.SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
1187      SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
1188    }
1189  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1190    {
1191      if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1192        { // In-sequence FIN before connection complete. Set up connection and close.
1193          m_connected = true;
1194          m_retxEvent.Cancel ();
1195          m_highTxMark = ++m_nextTxSequence;
1196          m_txBuffer.SetHeadSequence (m_nextTxSequence);
1197          if (m_endPoint)
1198            {
1199              m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1200                                   InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1201            }
1202          else if (m_endPoint6)
1203            {
1204              m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1205                                    Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1206            }
1207          PeerClose (packet, tcpHeader);
1208        }
1209    }
1210  else
1211    { // Other in-sequence input
1212      if (tcpflags != TcpHeader::RST)
1213        { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1214          NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1215          if (m_endPoint)
1216            {
1217              m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1218                                   InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1219            }
1220          else if (m_endPoint6)
1221            {
1222              m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1223                                    Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1224            }
1225          SendRST ();
1226        }
1227      CloseAndNotify ();
1228    }
1229}
1230
1231/** Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */
1232void
1233TcpSocketBase::ProcessWait (Ptr<Packet> packet, const TcpHeader& tcpHeader)
1234{
1235  NS_LOG_FUNCTION (this << tcpHeader);
1236
1237  // Extract the flags. PSH and URG are not honoured.
1238  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1239
1240  if (packet->GetSize () > 0)
1241    { // Bare data, accept it
1242      ReceivedData (packet, tcpHeader);
1243    }
1244  else if (tcpflags == TcpHeader::ACK)
1245    { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1246      ReceivedAck (packet, tcpHeader);
1247      if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1248          && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1249        { // This ACK corresponds to the FIN sent
1250          NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1251          m_state = FIN_WAIT_2;
1252        }
1253    }
1254  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1255    { // Got FIN, respond with ACK and move to next state
1256      if (tcpflags & TcpHeader::ACK)
1257        { // Process the ACK first
1258          ReceivedAck (packet, tcpHeader);
1259        }
1260      m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber ());
1261    }
1262  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1263    { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1264      return;
1265    }
1266  else
1267    { // This is a RST or bad flags
1268      if (tcpflags != TcpHeader::RST)
1269        {
1270          NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1271          SendRST ();
1272        }
1273      CloseAndNotify ();
1274      return;
1275    }
1276
1277  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1278  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1279    {
1280      if (m_state == FIN_WAIT_1)
1281        {
1282          NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1283          m_state = CLOSING;
1284          if (m_txBuffer.Size () == 0
1285              && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1286            { // This ACK corresponds to the FIN sent
1287              TimeWait ();
1288            }
1289        }
1290      else if (m_state == FIN_WAIT_2)
1291        {
1292          TimeWait ();
1293        }
1294      SendEmptyPacket (TcpHeader::ACK);
1295      if (!m_shutdownRecv)
1296        {
1297          NotifyDataRecv ();
1298        }
1299    }
1300}
1301
1302/** Received a packet upon CLOSING */
1303void
1304TcpSocketBase::ProcessClosing (Ptr<Packet> packet, const TcpHeader& tcpHeader)
1305{
1306  NS_LOG_FUNCTION (this << tcpHeader);
1307
1308  // Extract the flags. PSH and URG are not honoured.
1309  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1310
1311  if (tcpflags == TcpHeader::ACK)
1312    {
1313      if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1314        { // This ACK corresponds to the FIN sent
1315          TimeWait ();
1316        }
1317    }
1318  else
1319    { // CLOSING state means simultaneous close, i.e. no one is sending data to
1320      // anyone. If anything other than ACK is received, respond with a reset.
1321      if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1322        { // FIN from the peer as well. We can close immediately.
1323          SendEmptyPacket (TcpHeader::ACK);
1324        }
1325      else if (tcpflags != TcpHeader::RST)
1326        { // Receive of SYN or SYN+ACK or bad flags or pure data
1327          NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1328          SendRST ();
1329        }
1330      CloseAndNotify ();
1331    }
1332}
1333
1334/** Received a packet upon LAST_ACK */
1335void
1336TcpSocketBase::ProcessLastAck (Ptr<Packet> packet, const TcpHeader& tcpHeader)
1337{
1338  NS_LOG_FUNCTION (this << tcpHeader);
1339
1340  // Extract the flags. PSH and URG are not honoured.
1341  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1342
1343  if (tcpflags == 0)
1344    {
1345      ReceivedData (packet, tcpHeader);
1346    }
1347  else if (tcpflags == TcpHeader::ACK)
1348    {
1349      if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1350        { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1351          CloseAndNotify ();
1352        }
1353    }
1354  else if (tcpflags == TcpHeader::FIN)
1355    { // Received FIN again, the peer probably lost the FIN+ACK
1356      SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
1357    }
1358  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1359    {
1360      CloseAndNotify ();
1361    }
1362  else
1363    { // Received a SYN or SYN+ACK or bad flags
1364      NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1365      SendRST ();
1366      CloseAndNotify ();
1367    }
1368}
1369
1370/** Peer sent me a FIN. Remember its sequence in rx buffer. */
1371void
1372TcpSocketBase::PeerClose (Ptr<Packet> p, const TcpHeader& tcpHeader)
1373{
1374  NS_LOG_FUNCTION (this << tcpHeader);
1375
1376  // Ignore all out of range packets
1377  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1378      || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1379    {
1380      return;
1381    }
1382  // For any case, remember the FIN position in rx buffer first
1383  m_rxBuffer.SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1384  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1385  // If there is any piggybacked data, process it
1386  if (p->GetSize ())
1387    {
1388      ReceivedData (p, tcpHeader);
1389    }
1390  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1391  if (!m_rxBuffer.Finished ())
1392    {
1393      return;
1394    }
1395
1396  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1397  if (m_state == FIN_WAIT_1)
1398    {
1399      NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1400      m_state = CLOSING;
1401      return;
1402    }
1403
1404  DoPeerClose (); // Change state, respond with ACK
1405}
1406
1407/** Received a in-sequence FIN. Close down this socket. */
1408void
1409TcpSocketBase::DoPeerClose (void)
1410{
1411  NS_ASSERT (m_state == ESTABLISHED || m_state == SYN_RCVD);
1412
1413  // Move the state to CLOSE_WAIT
1414  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1415  m_state = CLOSE_WAIT;
1416
1417  if (!m_closeNotified)
1418    {
1419      // The normal behaviour for an application is that, when the peer sent a in-sequence
1420      // FIN, the app should prepare to close. The app has two choices at this point: either
1421      // respond with ShutdownSend() call to declare that it has nothing more to send and
1422      // the socket can be closed immediately; or remember the peer's close request, wait
1423      // until all its existing data are pushed into the TCP socket, then call Close()
1424      // explicitly.
1425      NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1426      NotifyNormalClose ();
1427      m_closeNotified = true;
1428    }
1429  if (m_shutdownSend)
1430    { // The application declares that it would not sent any more, close this socket
1431      Close ();
1432    }
1433  else
1434    { // Need to ack, the application will close later
1435      SendEmptyPacket (TcpHeader::ACK);
1436    }
1437  if (m_state == LAST_ACK)
1438    {
1439      NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1440      m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
1441                                            &TcpSocketBase::LastAckTimeout, this);
1442    }
1443}
1444
1445/** Kill this socket. This is a callback function configured to m_endpoint in
1446   SetupCallback(), invoked when the endpoint is destroyed. */
1447void
1448TcpSocketBase::Destroy (void)
1449{
1450  NS_LOG_FUNCTION (this);
1451  m_endPoint = 0;
1452  if (m_tcp != 0)
1453    {
1454      std::vector<Ptr<TcpSocketBase> >::iterator it
1455        = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1456      if (it != m_tcp->m_sockets.end ())
1457        {
1458          m_tcp->m_sockets.erase (it);
1459        }
1460    }
1461  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1462                (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1463  CancelAllTimers ();
1464}
1465
1466/** Kill this socket. This is a callback function configured to m_endpoint in
1467   SetupCallback(), invoked when the endpoint is destroyed. */
1468void
1469TcpSocketBase::Destroy6 (void)
1470{
1471  NS_LOG_FUNCTION (this);
1472  m_endPoint6 = 0;
1473  if (m_tcp != 0)
1474    {
1475      std::vector<Ptr<TcpSocketBase> >::iterator it
1476        = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1477      if (it != m_tcp->m_sockets.end ())
1478        {
1479          m_tcp->m_sockets.erase (it);
1480        }
1481    }
1482  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1483                (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1484  CancelAllTimers ();
1485}
1486
1487/** Send an empty packet with specified TCP flags */
1488void
1489TcpSocketBase::SendEmptyPacket (uint8_t flags)
1490{
1491  NS_LOG_FUNCTION (this << (uint32_t)flags);
1492  Ptr<Packet> p = Create<Packet> ();
1493  TcpHeader header;
1494  SequenceNumber32 s = m_nextTxSequence;
1495
1496  if (m_endPoint == 0 && m_endPoint6 == 0)
1497    {
1498      NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1499      return;
1500    }
1501  if (flags & TcpHeader::FIN)
1502    {
1503      flags |= TcpHeader::ACK;
1504    }
1505  else if (m_stat

Large files files are truncated, but you can click here to view the full file