A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
tcp-socket-base.cc
Go to the documentation of this 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 "ns3/abort.h"
26 #include "ns3/node.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/inet6-socket-address.h"
29 #include "ns3/log.h"
30 #include "ns3/ipv4.h"
31 #include "ns3/ipv6.h"
32 #include "ns3/ipv4-interface-address.h"
33 #include "ns3/ipv4-route.h"
34 #include "ns3/ipv6-route.h"
35 #include "ns3/ipv4-routing-protocol.h"
36 #include "ns3/ipv6-routing-protocol.h"
37 #include "ns3/simulation-singleton.h"
38 #include "ns3/simulator.h"
39 #include "ns3/packet.h"
40 #include "ns3/uinteger.h"
41 #include "ns3/double.h"
42 #include "ns3/trace-source-accessor.h"
43 #include "tcp-socket-base.h"
44 #include "tcp-l4-protocol.h"
45 #include "ipv4-end-point.h"
46 #include "ipv6-end-point.h"
47 #include "ipv6-l3-protocol.h"
48 #include "tcp-header.h"
49 #include "rtt-estimator.h"
50 
51 #include <algorithm>
52 
53 NS_LOG_COMPONENT_DEFINE ("TcpSocketBase");
54 
55 namespace ns3 {
56 
57 NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase);
58 
59 TypeId
61 {
62  static TypeId tid = TypeId ("ns3::TcpSocketBase")
63  .SetParent<TcpSocket> ()
64 // .AddAttribute ("TcpState", "State in TCP state machine",
65 // TypeId::ATTR_GET,
66 // EnumValue (CLOSED),
67 // MakeEnumAccessor (&TcpSocketBase::m_state),
68 // MakeEnumChecker (CLOSED, "Closed"))
69  .AddAttribute ("MaxSegLifetime",
70  "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
71  DoubleValue (120), /* RFC793 says MSL=2 minutes*/
72  MakeDoubleAccessor (&TcpSocketBase::m_msl),
73  MakeDoubleChecker<double> (0))
74  .AddAttribute ("MaxWindowSize", "Max size of advertised window",
75  UintegerValue (65535),
76  MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
77  MakeUintegerChecker<uint16_t> ())
78  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
79  CallbackValue (),
80  MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback),
81  MakeCallbackChecker ())
82  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
83  CallbackValue (),
84  MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback6),
85  MakeCallbackChecker ())
86  .AddTraceSource ("RTO",
87  "Retransmission timeout",
89  .AddTraceSource ("RTT",
90  "Last RTT sample",
92  .AddTraceSource ("NextTxSequence",
93  "Next sequence number to send (SND.NXT)",
95  .AddTraceSource ("HighestSequence",
96  "Highest sequence number ever sent in socket's life time",
98  .AddTraceSource ("State",
99  "TCP state",
101  .AddTraceSource ("RWND",
102  "Remote side's flow control window",
104  ;
105  return tid;
106 }
107 
109  : m_dupAckCount (0),
110  m_delAckCount (0),
111  m_endPoint (0),
112  m_endPoint6 (0),
113  m_node (0),
114  m_tcp (0),
115  m_rtt (0),
116  m_nextTxSequence (0),
117  // Change this for non-zero initial sequence number
118  m_highTxMark (0),
119  m_rxBuffer (0),
120  m_txBuffer (0),
121  m_state (CLOSED),
122  m_errno (ERROR_NOTERROR),
123  m_closeNotified (false),
124  m_closeOnEmpty (false),
125  m_shutdownSend (false),
126  m_shutdownRecv (false),
127  m_connected (false),
128  m_segmentSize (0),
129  // For attribute initialization consistency (quiet valgrind)
130  m_rWnd (0)
131 {
132  NS_LOG_FUNCTION (this);
133 }
134 
136  : TcpSocket (sock),
137  //copy object::m_tid and socket::callbacks
138  m_dupAckCount (sock.m_dupAckCount),
139  m_delAckCount (0),
140  m_delAckMaxCount (sock.m_delAckMaxCount),
141  m_noDelay (sock.m_noDelay),
142  m_cnRetries (sock.m_cnRetries),
143  m_delAckTimeout (sock.m_delAckTimeout),
144  m_persistTimeout (sock.m_persistTimeout),
145  m_cnTimeout (sock.m_cnTimeout),
146  m_endPoint (0),
147  m_endPoint6 (0),
148  m_node (sock.m_node),
149  m_tcp (sock.m_tcp),
150  m_rtt (0),
151  m_nextTxSequence (sock.m_nextTxSequence),
152  m_highTxMark (sock.m_highTxMark),
153  m_rxBuffer (sock.m_rxBuffer),
154  m_txBuffer (sock.m_txBuffer),
155  m_state (sock.m_state),
156  m_errno (sock.m_errno),
157  m_closeNotified (sock.m_closeNotified),
158  m_closeOnEmpty (sock.m_closeOnEmpty),
159  m_shutdownSend (sock.m_shutdownSend),
160  m_shutdownRecv (sock.m_shutdownRecv),
161  m_connected (sock.m_connected),
162  m_msl (sock.m_msl),
163  m_segmentSize (sock.m_segmentSize),
164  m_maxWinSize (sock.m_maxWinSize),
165  m_rWnd (sock.m_rWnd)
166 {
167  NS_LOG_FUNCTION (this);
168  NS_LOG_LOGIC ("Invoked the copy constructor");
169  // Copy the rtt estimator if it is set
170  if (sock.m_rtt)
171  {
172  m_rtt = sock.m_rtt->Copy ();
173  }
174  // Reset all callbacks to null
175  Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
176  Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
177  Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
178  SetConnectCallback (vPS, vPS);
179  SetDataSentCallback (vPSUI);
180  SetSendCallback (vPSUI);
181  SetRecvCallback (vPS);
182 }
183 
185 {
186  NS_LOG_FUNCTION (this);
187  m_node = 0;
188  if (m_endPoint != 0)
189  {
190  NS_ASSERT (m_tcp != 0);
191  /*
192  * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
193  * DestroyCallback is set to TcpSocketBase::Destroy. If we called
194  * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
195  * which in turn destroys my m_endPoint, and in turn invokes
196  * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
197  */
198  NS_ASSERT (m_endPoint != 0);
200  NS_ASSERT (m_endPoint == 0);
201  }
202  if (m_endPoint6 != 0)
203  {
204  NS_ASSERT (m_tcp != 0);
205  NS_ASSERT (m_endPoint6 != 0);
207  NS_ASSERT (m_endPoint6 == 0);
208  }
209  m_tcp = 0;
210  CancelAllTimers ();
211 }
212 
214 void
216 {
217  m_node = node;
218 }
219 
221 void
223 {
224  m_tcp = tcp;
225 }
226 
228 void
230 {
231  m_rtt = rtt;
232 }
233 
237 {
238  return m_errno;
239 }
240 
244 {
245  return NS3_SOCK_STREAM;
246 }
247 
249 Ptr<Node>
251 {
253  return m_node;
254 }
255 
257 int
259 {
260  NS_LOG_FUNCTION (this);
261  m_endPoint = m_tcp->Allocate ();
262  if (0 == m_endPoint)
263  {
265  return -1;
266  }
267  m_tcp->m_sockets.push_back (this);
268  return SetupCallback ();
269 }
270 
271 int
273 {
274  NS_LOG_FUNCTION (this);
276  if (0 == m_endPoint6)
277  {
279  return -1;
280  }
281  m_tcp->m_sockets.push_back (this);
282  return SetupCallback ();
283 }
284 
286 int
287 TcpSocketBase::Bind (const Address &address)
288 {
289  NS_LOG_FUNCTION (this << address);
290  if (InetSocketAddress::IsMatchingType (address))
291  {
293  Ipv4Address ipv4 = transport.GetIpv4 ();
294  uint16_t port = transport.GetPort ();
295  if (ipv4 == Ipv4Address::GetAny () && port == 0)
296  {
297  m_endPoint = m_tcp->Allocate ();
298  }
299  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
300  {
301  m_endPoint = m_tcp->Allocate (port);
302  }
303  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
304  {
305  m_endPoint = m_tcp->Allocate (ipv4);
306  }
307  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
308  {
309  m_endPoint = m_tcp->Allocate (ipv4, port);
310  }
311  if (0 == m_endPoint)
312  {
314  return -1;
315  }
316  }
317  else if (Inet6SocketAddress::IsMatchingType (address))
318  {
320  Ipv6Address ipv6 = transport.GetIpv6 ();
321  uint16_t port = transport.GetPort ();
322  if (ipv6 == Ipv6Address::GetAny () && port == 0)
323  {
325  }
326  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
327  {
328  m_endPoint6 = m_tcp->Allocate6 (port);
329  }
330  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
331  {
332  m_endPoint6 = m_tcp->Allocate6 (ipv6);
333  }
334  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
335  {
336  m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
337  }
338  if (0 == m_endPoint6)
339  {
341  return -1;
342  }
343  }
344  else
345  {
347  return -1;
348  }
349  m_tcp->m_sockets.push_back (this);
350  NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
351 
352  return SetupCallback ();
353 }
354 
356 int
358 {
359  NS_LOG_FUNCTION (this << address);
360 
361  // If haven't do so, Bind() this socket first
362  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
363  {
364  if (m_endPoint == 0)
365  {
366  if (Bind () == -1)
367  {
368  NS_ASSERT (m_endPoint == 0);
369  return -1; // Bind() failed
370  }
371  NS_ASSERT (m_endPoint != 0);
372  }
374  m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
375  m_endPoint6 = 0;
376 
377  // Get the appropriate local address and port number from the routing protocol and set up endpoint
378  if (SetupEndpoint () != 0)
379  { // Route to destination does not exist
380  return -1;
381  }
382  }
383  else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
384  {
385  // If we are operating on a v4-mapped address, translate the address to
386  // a v4 address and re-call this function
388  Ipv6Address v6Addr = transport.GetIpv6 ();
389  if (v6Addr.IsIpv4MappedAddress () == true)
390  {
391  Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
392  return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
393  }
394 
395  if (m_endPoint6 == 0)
396  {
397  if (Bind6 () == -1)
398  {
399  NS_ASSERT (m_endPoint6 == 0);
400  return -1; // Bind() failed
401  }
402  NS_ASSERT (m_endPoint6 != 0);
403  }
404  m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
405  m_endPoint = 0;
406 
407  // Get the appropriate local address and port number from the routing protocol and set up endpoint
408  if (SetupEndpoint6 () != 0)
409  { // Route to destination does not exist
410  return -1;
411  }
412  }
413  else
414  {
416  return -1;
417  }
418 
419  // Re-initialize parameters in case this socket is being reused after CLOSE
420  m_rtt->Reset ();
422 
423  // DoConnect() will do state-checking and send a SYN packet
424  return DoConnect ();
425 }
426 
428 int
430 {
431  NS_LOG_FUNCTION (this);
432  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
433  if (m_state != CLOSED)
434  {
436  return -1;
437  }
438  // In other cases, set the state to LISTEN and done
439  NS_LOG_INFO ("CLOSED -> LISTEN");
440  m_state = LISTEN;
441  return 0;
442 }
443 
445 int
447 {
448  NS_LOG_FUNCTION (this);
449  // First we check to see if there is any unread rx data
450  // Bug number 426 claims we should send reset in this case.
451  if (m_rxBuffer.Size () != 0)
452  {
453  SendRST ();
454  return 0;
455  }
457  { // App close with pending data must wait until all data transmitted
458  if (m_closeOnEmpty == false)
459  {
460  m_closeOnEmpty = true;
461  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
462  }
463  return 0;
464  }
465  return DoClose ();
466 }
467 
469 int
471 {
472  NS_LOG_FUNCTION (this);
473  m_shutdownSend = true;
474  return 0;
475 }
476 
478 int
480 {
481  NS_LOG_FUNCTION (this);
482  m_shutdownRecv = true;
483  return 0;
484 }
485 
488 int
489 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
490 {
491  NS_LOG_FUNCTION (this << p);
492  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
494  {
495  // Store the packet into Tx buffer
496  if (!m_txBuffer.Add (p))
497  { // TxBuffer overflow, send failed
499  return -1;
500  }
501  // Submit the data to lower layers
502  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
503  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
504  { // Try to send the data out
506  }
507  return p->GetSize ();
508  }
509  else
510  { // Connection not established yet
512  return -1; // Send failure
513  }
514 }
515 
517 int
518 TcpSocketBase::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
519 {
520  return Send (p, flags); // SendTo() and Send() are the same
521 }
522 
526 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
527 {
528  NS_LOG_FUNCTION (this);
529  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
530  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
531  {
532  return Create<Packet> (); // Send EOF on connection close
533  }
534  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
535  if (outPacket != 0 && outPacket->GetSize () != 0)
536  {
537  SocketAddressTag tag;
538  if (m_endPoint != 0)
539  {
541  }
542  else if (m_endPoint6 != 0)
543  {
545  }
546  outPacket->AddPacketTag (tag);
547  }
548  return outPacket;
549 }
550 
553 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
554 {
555  NS_LOG_FUNCTION (this << maxSize << flags);
556  Ptr<Packet> packet = Recv (maxSize, flags);
557  // Null packet means no data to read, and an empty packet indicates EOF
558  if (packet != 0 && packet->GetSize () != 0)
559  {
560  if (m_endPoint != 0)
561  {
563  }
564  else if (m_endPoint6 != 0)
565  {
567  }
568  else
569  {
570  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
571  }
572  }
573  return packet;
574 }
575 
577 uint32_t
579 {
580  NS_LOG_FUNCTION (this);
581  return m_txBuffer.Available ();
582 }
583 
585 uint32_t
587 {
588  NS_LOG_FUNCTION (this);
589  return m_rxBuffer.Available ();
590 }
591 
593 int
595 {
596  NS_LOG_FUNCTION (this);
597  if (m_endPoint != 0)
598  {
600  }
601  else if (m_endPoint6 != 0)
602  {
604  }
605  else
606  { // It is possible to call this method on a socket without a name
607  // in which case, behavior is unspecified
608  // Should this return an InetSocketAddress or an Inet6SocketAddress?
609  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
610  }
611  return 0;
612 }
613 
615 void
617 {
618  NS_LOG_FUNCTION (netdevice);
619  Socket::BindToNetDevice (netdevice); // Includes sanity check
620  if (m_endPoint == 0 && m_endPoint6 == 0)
621  {
622  if (Bind () == -1)
623  {
624  NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
625  return;
626  }
627  NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
628  }
629 
630  if (m_endPoint != 0)
631  {
632  m_endPoint->BindToNetDevice (netdevice);
633  }
634  // No BindToNetDevice() for Ipv6EndPoint
635  return;
636 }
637 
639 int
641 {
642  NS_LOG_FUNCTION (this);
643 
644  if (m_endPoint == 0 && m_endPoint6 == 0)
645  {
646  return -1;
647  }
648  if (m_endPoint != 0)
649  {
653  }
654  if (m_endPoint6 != 0)
655  {
659  }
660 
661  return 0;
662 }
663 
665 int
667 {
668  NS_LOG_FUNCTION (this);
669 
670  // A new connection is allowed only if this socket does not have a connection
672  { // send a SYN packet and change state into SYN_SENT
674  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
675  m_state = SYN_SENT;
676  }
677  else if (m_state != TIME_WAIT)
678  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
679  // exists. We send RST, tear down everything, and close this socket.
680  SendRST ();
681  CloseAndNotify ();
682  }
683  return 0;
684 }
685 
688 int
690 {
691  NS_LOG_FUNCTION (this);
692  switch (m_state)
693  {
694  case SYN_RCVD:
695  case ESTABLISHED:
696  // send FIN to close the peer
698  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
700  break;
701  case CLOSE_WAIT:
702  // send FIN+ACK to close the peer
704  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
705  m_state = LAST_ACK;
706  break;
707  case SYN_SENT:
708  case CLOSING:
709  // Send RST if application closes in SYN_SENT and CLOSING
710  SendRST ();
711  CloseAndNotify ();
712  break;
713  case LISTEN:
714  case LAST_ACK:
715  // In these three states, move to CLOSED and tear down the end point
716  CloseAndNotify ();
717  break;
718  case CLOSED:
719  case FIN_WAIT_1:
720  case FIN_WAIT_2:
721  case TIME_WAIT:
722  default: /* mute compiler */
723  // Do nothing in these four states
724  break;
725  }
726  return 0;
727 }
728 
730 void
732 {
733  NS_LOG_FUNCTION (this);
734 
735  if (!m_closeNotified)
736  {
738  }
739  if (m_state != TIME_WAIT)
740  {
742  }
743  m_closeNotified = true;
744  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
745  CancelAllTimers ();
746  m_state = CLOSED;
747 }
748 
749 
752 bool
754 {
755  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
756  { // Rx buffer in these states are not initialized.
757  return false;
758  }
759  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
760  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
761  // sequence number must equals to m_rxBuffer.NextRxSequence ()
762  return (m_rxBuffer.NextRxSequence () != head);
763  }
764 
765  // In all other cases, check if the sequence number is in range
766  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
767 }
768 
772 void
774  Ptr<Ipv4Interface> incomingInterface)
775 {
776  DoForwardUp (packet, header, port, incomingInterface);
777 }
778 
779 void
781 {
782  DoForwardUp (packet, header, port);
783 }
784 
785 void
786 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
787  uint8_t icmpType, uint8_t icmpCode,
788  uint32_t icmpInfo)
789 {
790  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
791  (uint32_t)icmpCode << icmpInfo);
792  if (!m_icmpCallback.IsNull ())
793  {
794  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
795  }
796 }
797 
798 void
799 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
800  uint8_t icmpType, uint8_t icmpCode,
801  uint32_t icmpInfo)
802 {
803  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
804  (uint32_t)icmpCode << icmpInfo);
805  if (!m_icmpCallback6.IsNull ())
806  {
807  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
808  }
809 }
810 
814 void
816  Ptr<Ipv4Interface> incomingInterface)
817 {
818  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
820  ":" << m_endPoint->GetPeerPort () <<
821  " to " << m_endPoint->GetLocalAddress () <<
822  ":" << m_endPoint->GetLocalPort ());
823  Address fromAddress = InetSocketAddress (header.GetSource (), port);
824  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
825 
826  // Peel off TCP header and do validity checking
827  TcpHeader tcpHeader;
828  packet->RemoveHeader (tcpHeader);
829  if (tcpHeader.GetFlags () & TcpHeader::ACK)
830  {
831  EstimateRtt (tcpHeader);
832  }
833  ReadOptions (tcpHeader);
834 
835  // Update Rx window size, i.e. the flow control window
836  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
837  { // persist probes end
838  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
840  }
841  m_rWnd = tcpHeader.GetWindowSize ();
842 
843  // Discard fully out of range data packets
844  if (packet->GetSize ()
845  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
846  {
847  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
848  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
849  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
850  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
851  m_rxBuffer.MaxRxSequence () << ")");
852  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
853  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
854  {
856  }
857  return;
858  }
859 
860  // TCP state machine code in different process functions
861  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
862  switch (m_state)
863  {
864  case ESTABLISHED:
865  ProcessEstablished (packet, tcpHeader);
866  break;
867  case LISTEN:
868  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
869  break;
870  case TIME_WAIT:
871  // Do nothing
872  break;
873  case CLOSED:
874  // Send RST if the incoming packet is not a RST
875  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
876  { // Since m_endPoint is not configured yet, we cannot use SendRST here
877  TcpHeader h;
881  h.SetSourcePort (tcpHeader.GetDestinationPort ());
882  h.SetDestinationPort (tcpHeader.GetSourcePort ());
884  AddOptions (h);
885  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
886  }
887  break;
888  case SYN_SENT:
889  ProcessSynSent (packet, tcpHeader);
890  break;
891  case SYN_RCVD:
892  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
893  break;
894  case FIN_WAIT_1:
895  case FIN_WAIT_2:
896  case CLOSE_WAIT:
897  ProcessWait (packet, tcpHeader);
898  break;
899  case CLOSING:
900  ProcessClosing (packet, tcpHeader);
901  break;
902  case LAST_ACK:
903  ProcessLastAck (packet, tcpHeader);
904  break;
905  default: // mute compiler
906  break;
907  }
908 }
909 
910 void
912 {
913  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
915  ":" << m_endPoint6->GetPeerPort () <<
916  " to " << m_endPoint6->GetLocalAddress () <<
917  ":" << m_endPoint6->GetLocalPort ());
918  Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port);
920 
921  // Peel off TCP header and do validity checking
922  TcpHeader tcpHeader;
923  packet->RemoveHeader (tcpHeader);
924  if (tcpHeader.GetFlags () & TcpHeader::ACK)
925  {
926  EstimateRtt (tcpHeader);
927  }
928  ReadOptions (tcpHeader);
929 
930  // Update Rx window size, i.e. the flow control window
931  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
932  { // persist probes end
933  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
935  }
936  m_rWnd = tcpHeader.GetWindowSize ();
937 
938  // Discard fully out of range packets
939  if (packet->GetSize ()
940  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
941  {
942  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
943  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
944  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
945  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
946  m_rxBuffer.MaxRxSequence () << ")");
947  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
948  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
949  {
951  }
952  return;
953  }
954 
955  // TCP state machine code in different process functions
956  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
957  switch (m_state)
958  {
959  case ESTABLISHED:
960  ProcessEstablished (packet, tcpHeader);
961  break;
962  case LISTEN:
963  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
964  break;
965  case TIME_WAIT:
966  // Do nothing
967  break;
968  case CLOSED:
969  // Send RST if the incoming packet is not a RST
970  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
971  { // Since m_endPoint is not configured yet, we cannot use SendRST here
972  TcpHeader h;
976  h.SetSourcePort (tcpHeader.GetDestinationPort ());
977  h.SetDestinationPort (tcpHeader.GetSourcePort ());
979  AddOptions (h);
980  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestinationAddress (), header.GetSourceAddress (), m_boundnetdevice);
981  }
982  break;
983  case SYN_SENT:
984  ProcessSynSent (packet, tcpHeader);
985  break;
986  case SYN_RCVD:
987  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
988  break;
989  case FIN_WAIT_1:
990  case FIN_WAIT_2:
991  case CLOSE_WAIT:
992  ProcessWait (packet, tcpHeader);
993  break;
994  case CLOSING:
995  ProcessClosing (packet, tcpHeader);
996  break;
997  case LAST_ACK:
998  ProcessLastAck (packet, tcpHeader);
999  break;
1000  default: // mute compiler
1001  break;
1002  }
1003 }
1004 
1007 void
1009 {
1010  NS_LOG_FUNCTION (this << tcpHeader);
1011 
1012  // Extract the flags. PSH and URG are not honoured.
1013  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1014 
1015  // Different flags are different events
1016  if (tcpflags == TcpHeader::ACK)
1017  {
1018  ReceivedAck (packet, tcpHeader);
1019  }
1020  else if (tcpflags == TcpHeader::SYN)
1021  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
1022  // respond with a SYN+ACK. But it is not a legal state transition as of
1023  // RFC793. Thus this is ignored.
1024  }
1025  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1026  { // No action for received SYN+ACK, it is probably a duplicated packet
1027  }
1028  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1029  { // Received FIN or FIN+ACK, bring down this socket nicely
1030  PeerClose (packet, tcpHeader);
1031  }
1032  else if (tcpflags == 0)
1033  { // No flags means there is only data
1034  ReceivedData (packet, tcpHeader);
1035  if (m_rxBuffer.Finished ())
1036  {
1037  PeerClose (packet, tcpHeader);
1038  }
1039  }
1040  else
1041  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1042  if (tcpflags != TcpHeader::RST)
1043  { // this must be an invalid flag, send reset
1044  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1045  SendRST ();
1046  }
1047  CloseAndNotify ();
1048  }
1049 }
1050 
1052 void
1054 {
1055  NS_LOG_FUNCTION (this << tcpHeader);
1056 
1057  // Received ACK. Compare the ACK number against highest unacked seqno
1058  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1059  { // Ignore if no ACK flag
1060  }
1061  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1062  { // Case 1: Old ACK, ignored.
1063  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1064  }
1065  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1066  { // Case 2: Potentially a duplicated ACK
1067  if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0)
1068  {
1069  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1070  DupAck (tcpHeader, ++m_dupAckCount);
1071  }
1072  // otherwise, the ACK is precisely equal to the nextTxSequence
1073  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1074  }
1075  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1076  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1077  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1078  NewAck (tcpHeader.GetAckNumber ());
1079  m_dupAckCount = 0;
1080  }
1081  // If there is any data piggybacked, store it into m_rxBuffer
1082  if (packet->GetSize () > 0)
1083  {
1084  ReceivedData (packet, tcpHeader);
1085  }
1086 }
1087 
1089 void
1091  const Address& fromAddress, const Address& toAddress)
1092 {
1093  NS_LOG_FUNCTION (this << tcpHeader);
1094 
1095  // Extract the flags. PSH and URG are not honoured.
1096  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1097 
1098  // Fork a socket if received a SYN. Do nothing otherwise.
1099  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1100  if (tcpflags != TcpHeader::SYN)
1101  {
1102  return;
1103  }
1104 
1105  // Call socket's notify function to let the server app know we got a SYN
1106  // If the server app refuses the connection, do nothing
1107  if (!NotifyConnectionRequest (fromAddress))
1108  {
1109  return;
1110  }
1111  // Clone the socket, simulate fork
1112  Ptr<TcpSocketBase> newSock = Fork ();
1113  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1115  packet, tcpHeader, fromAddress, toAddress);
1116 }
1117 
1119 void
1121 {
1122  NS_LOG_FUNCTION (this << tcpHeader);
1123 
1124  // Extract the flags. PSH and URG are not honoured.
1125  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1126 
1127  if (tcpflags == 0)
1128  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1129  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1130  m_state = ESTABLISHED;
1131  m_connected = true;
1132  m_retxEvent.Cancel ();
1134  ReceivedData (packet, tcpHeader);
1136  }
1137  else if (tcpflags == TcpHeader::ACK)
1138  { // Ignore ACK in SYN_SENT
1139  }
1140  else if (tcpflags == TcpHeader::SYN)
1141  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1142  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1143  m_state = SYN_RCVD;
1147  }
1148  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1149  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1150  { // Handshake completed
1151  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1152  m_state = ESTABLISHED;
1153  m_connected = true;
1154  m_retxEvent.Cancel ();
1161  // Always respond to first data packet to speed up the connection.
1162  // Remove to get the behaviour of old NS-3 code.
1164  }
1165  else
1166  { // Other in-sequence input
1167  if (tcpflags != TcpHeader::RST)
1168  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1169  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1170  SendRST ();
1171  }
1172  CloseAndNotify ();
1173  }
1174 }
1175 
1177 void
1179  const Address& fromAddress, const Address& toAddress)
1180 {
1181  NS_LOG_FUNCTION (this << tcpHeader);
1182 
1183  // Extract the flags. PSH and URG are not honoured.
1184  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1185 
1186  if (tcpflags == 0
1187  || (tcpflags == TcpHeader::ACK
1188  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1189  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1190  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1191  // handshake is completed nicely.
1192  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1193  m_state = ESTABLISHED;
1194  m_connected = true;
1195  m_retxEvent.Cancel ();
1198  if (m_endPoint)
1199  {
1200  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1201  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1202  }
1203  else if (m_endPoint6)
1204  {
1205  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1206  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1207  }
1208  // Always respond to first data packet to speed up the connection.
1209  // Remove to get the behaviour of old NS-3 code.
1211  ReceivedAck (packet, tcpHeader);
1212  NotifyNewConnectionCreated (this, fromAddress);
1213  // As this connection is established, the socket is available to send data now
1214  if (GetTxAvailable () > 0)
1215  {
1217  }
1218  }
1219  else if (tcpflags == TcpHeader::SYN)
1220  { // Probably the peer lost my SYN+ACK
1223  }
1224  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1225  {
1226  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1227  { // In-sequence FIN before connection complete. Set up connection and close.
1228  m_connected = true;
1229  m_retxEvent.Cancel ();
1232  if (m_endPoint)
1233  {
1234  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1235  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1236  }
1237  else if (m_endPoint6)
1238  {
1239  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1240  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1241  }
1242  PeerClose (packet, tcpHeader);
1243  }
1244  }
1245  else
1246  { // Other in-sequence input
1247  if (tcpflags != TcpHeader::RST)
1248  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1249  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1250  if (m_endPoint)
1251  {
1252  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1253  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1254  }
1255  else if (m_endPoint6)
1256  {
1257  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1258  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1259  }
1260  SendRST ();
1261  }
1262  CloseAndNotify ();
1263  }
1264 }
1265 
1267 void
1269 {
1270  NS_LOG_FUNCTION (this << tcpHeader);
1271 
1272  // Extract the flags. PSH and URG are not honoured.
1273  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1274 
1275  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1276  { // Bare data, accept it
1277  ReceivedData (packet, tcpHeader);
1278  }
1279  else if (tcpflags == TcpHeader::ACK)
1280  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1281  ReceivedAck (packet, tcpHeader);
1282  if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1283  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1284  { // This ACK corresponds to the FIN sent
1285  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1286  m_state = FIN_WAIT_2;
1287  }
1288  }
1289  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1290  { // Got FIN, respond with ACK and move to next state
1291  if (tcpflags & TcpHeader::ACK)
1292  { // Process the ACK first
1293  ReceivedAck (packet, tcpHeader);
1294  }
1296  }
1297  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1298  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1299  return;
1300  }
1301  else
1302  { // This is a RST or bad flags
1303  if (tcpflags != TcpHeader::RST)
1304  {
1305  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1306  SendRST ();
1307  }
1308  CloseAndNotify ();
1309  return;
1310  }
1311 
1312  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1313  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1314  {
1315  if (m_state == FIN_WAIT_1)
1316  {
1317  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1318  m_state = CLOSING;
1319  if (m_txBuffer.Size () == 0
1320  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1321  { // This ACK corresponds to the FIN sent
1322  TimeWait ();
1323  }
1324  }
1325  else if (m_state == FIN_WAIT_2)
1326  {
1327  TimeWait ();
1328  }
1330  if (!m_shutdownRecv)
1331  {
1332  NotifyDataRecv ();
1333  }
1334  }
1335 }
1336 
1338 void
1340 {
1341  NS_LOG_FUNCTION (this << tcpHeader);
1342 
1343  // Extract the flags. PSH and URG are not honoured.
1344  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1345 
1346  if (tcpflags == TcpHeader::ACK)
1347  {
1348  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1349  { // This ACK corresponds to the FIN sent
1350  TimeWait ();
1351  }
1352  }
1353  else
1354  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1355  // anyone. If anything other than ACK is received, respond with a reset.
1356  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1357  { // FIN from the peer as well. We can close immediately.
1359  }
1360  else if (tcpflags != TcpHeader::RST)
1361  { // Receive of SYN or SYN+ACK or bad flags or pure data
1362  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1363  SendRST ();
1364  }
1365  CloseAndNotify ();
1366  }
1367 }
1368 
1370 void
1372 {
1373  NS_LOG_FUNCTION (this << tcpHeader);
1374 
1375  // Extract the flags. PSH and URG are not honoured.
1376  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1377 
1378  if (tcpflags == 0)
1379  {
1380  ReceivedData (packet, tcpHeader);
1381  }
1382  else if (tcpflags == TcpHeader::ACK)
1383  {
1384  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1385  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1386  CloseAndNotify ();
1387  }
1388  }
1389  else if (tcpflags == TcpHeader::FIN)
1390  { // Received FIN again, the peer probably lost the FIN+ACK
1392  }
1393  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1394  {
1395  CloseAndNotify ();
1396  }
1397  else
1398  { // Received a SYN or SYN+ACK or bad flags
1399  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1400  SendRST ();
1401  CloseAndNotify ();
1402  }
1403 }
1404 
1406 void
1408 {
1409  NS_LOG_FUNCTION (this << tcpHeader);
1410 
1411  // Ignore all out of range packets
1412  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1413  || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1414  {
1415  return;
1416  }
1417  // For any case, remember the FIN position in rx buffer first
1419  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1420  // If there is any piggybacked data, process it
1421  if (p->GetSize ())
1422  {
1423  ReceivedData (p, tcpHeader);
1424  }
1425  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1426  if (!m_rxBuffer.Finished ())
1427  {
1428  return;
1429  }
1430 
1431  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1432  if (m_state == FIN_WAIT_1)
1433  {
1434  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1435  m_state = CLOSING;
1436  return;
1437  }
1438 
1439  DoPeerClose (); // Change state, respond with ACK
1440 }
1441 
1443 void
1445 {
1447 
1448  // Move the state to CLOSE_WAIT
1449  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1450  m_state = CLOSE_WAIT;
1451 
1452  if (!m_closeNotified)
1453  {
1454  // The normal behaviour for an application is that, when the peer sent a in-sequence
1455  // FIN, the app should prepare to close. The app has two choices at this point: either
1456  // respond with ShutdownSend() call to declare that it has nothing more to send and
1457  // the socket can be closed immediately; or remember the peer's close request, wait
1458  // until all its existing data are pushed into the TCP socket, then call Close()
1459  // explicitly.
1460  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1461  NotifyNormalClose ();
1462  m_closeNotified = true;
1463  }
1464  if (m_shutdownSend)
1465  { // The application declares that it would not sent any more, close this socket
1466  Close ();
1467  }
1468  else
1469  { // Need to ack, the application will close later
1471  }
1472  if (m_state == LAST_ACK)
1473  {
1474  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1477  }
1478 }
1479 
1482 void
1484 {
1485  NS_LOG_FUNCTION (this);
1486  m_endPoint = 0;
1487  if (m_tcp != 0)
1488  {
1489  std::vector<Ptr<TcpSocketBase> >::iterator it
1490  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1491  if (it != m_tcp->m_sockets.end ())
1492  {
1493  m_tcp->m_sockets.erase (it);
1494  }
1495  }
1496  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1497  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1498  CancelAllTimers ();
1499 }
1500 
1503 void
1505 {
1506  NS_LOG_FUNCTION (this);
1507  m_endPoint6 = 0;
1508  if (m_tcp != 0)
1509  {
1510  std::vector<Ptr<TcpSocketBase> >::iterator it
1511  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1512  if (it != m_tcp->m_sockets.end ())
1513  {
1514  m_tcp->m_sockets.erase (it);
1515  }
1516  }
1517  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1518  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1519  CancelAllTimers ();
1520 }
1521 
1523 void
1525 {
1526  NS_LOG_FUNCTION (this << (uint32_t)flags);
1527  Ptr<Packet> p = Create<Packet> ();
1528  TcpHeader header;
1530 
1531  /*
1532  * Add tags for each socket option.
1533  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1534  * if both options are set. Once the packet got to layer three, only
1535  * the corresponding tags will be read.
1536  */
1537  if (IsManualIpTos ())
1538  {
1539  SocketIpTosTag ipTosTag;
1540  ipTosTag.SetTos (GetIpTos ());
1541  p->AddPacketTag (ipTosTag);
1542  }
1543 
1544  if (IsManualIpv6Tclass ())
1545  {
1546  SocketIpv6TclassTag ipTclassTag;
1547  ipTclassTag.SetTclass (GetIpv6Tclass ());
1548  p->AddPacketTag (ipTclassTag);
1549  }
1550 
1551  if (IsManualIpTtl ())
1552  {
1553  SocketIpTtlTag ipTtlTag;
1554  ipTtlTag.SetTtl (GetIpTtl ());
1555  p->AddPacketTag (ipTtlTag);
1556  }
1557 
1558  if (IsManualIpv6HopLimit ())
1559  {
1560  SocketIpv6HopLimitTag ipHopLimitTag;
1561  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1562  p->AddPacketTag (ipHopLimitTag);
1563  }
1564 
1565  if (m_endPoint == 0 && m_endPoint6 == 0)
1566  {
1567  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1568  return;
1569  }
1570  if (flags & TcpHeader::FIN)
1571  {
1572  flags |= TcpHeader::ACK;
1573  }
1574  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1575  {
1576  ++s;
1577  }
1578 
1579  header.SetFlags (flags);
1580  header.SetSequenceNumber (s);
1581  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1582  if (m_endPoint != 0)
1583  {
1584  header.SetSourcePort (m_endPoint->GetLocalPort ());
1585  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1586  }
1587  else
1588  {
1589  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1590  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1591  }
1592  header.SetWindowSize (AdvertisedWindowSize ());
1593  AddOptions (header);
1595  bool hasSyn = flags & TcpHeader::SYN;
1596  bool hasFin = flags & TcpHeader::FIN;
1597  bool isAck = flags == TcpHeader::ACK;
1598  if (hasSyn)
1599  {
1600  if (m_cnCount == 0)
1601  { // No more connection retries, give up
1602  NS_LOG_LOGIC ("Connection failed.");
1603  CloseAndNotify ();
1604  return;
1605  }
1606  else
1607  { // Exponential backoff of connection time out
1608  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1609  m_rto = m_cnTimeout * backoffCount;
1610  m_cnCount--;
1611  }
1612  }
1613  if (m_endPoint != 0)
1614  {
1615  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1617  }
1618  else
1619  {
1620  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1622  }
1623  if (flags & TcpHeader::ACK)
1624  { // If sending an ACK, cancel the delay ACK as well
1625  m_delAckEvent.Cancel ();
1626  m_delAckCount = 0;
1627  }
1628  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1629  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1630  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1631  << Simulator::Now ().GetSeconds () << " to expire at time "
1632  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1634  }
1635 }
1636 
1638 void
1640 {
1641  NS_LOG_FUNCTION (this);
1643  NotifyErrorClose ();
1644  DeallocateEndPoint ();
1645 }
1646 
1648 void
1650 {
1651  if (m_endPoint != 0)
1652  {
1653  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1655  m_endPoint = 0;
1656  std::vector<Ptr<TcpSocketBase> >::iterator it
1657  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1658  if (it != m_tcp->m_sockets.end ())
1659  {
1660  m_tcp->m_sockets.erase (it);
1661  }
1662  CancelAllTimers ();
1663  }
1664  if (m_endPoint6 != 0)
1665  {
1666  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1668  m_endPoint6 = 0;
1669  std::vector<Ptr<TcpSocketBase> >::iterator it
1670  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1671  if (it != m_tcp->m_sockets.end ())
1672  {
1673  m_tcp->m_sockets.erase (it);
1674  }
1675  CancelAllTimers ();
1676  }
1677 }
1678 
1680 int
1682 {
1683  NS_LOG_FUNCTION (this);
1684  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1685  NS_ASSERT (ipv4 != 0);
1686  if (ipv4->GetRoutingProtocol () == 0)
1687  {
1688  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1689  }
1690  // Create a dummy packet, then ask the routing function for the best output
1691  // interface's address
1692  Ipv4Header header;
1694  Socket::SocketErrno errno_;
1695  Ptr<Ipv4Route> route;
1697  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1698  if (route == 0)
1699  {
1700  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1701  NS_LOG_ERROR (errno_);
1702  m_errno = errno_;
1703  return -1;
1704  }
1705  NS_LOG_LOGIC ("Route exists");
1706  m_endPoint->SetLocalAddress (route->GetSource ());
1707  return 0;
1708 }
1709 
1710 int
1712 {
1713  NS_LOG_FUNCTION (this);
1715  NS_ASSERT (ipv6 != 0);
1716  if (ipv6->GetRoutingProtocol () == 0)
1717  {
1718  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1719  }
1720  // Create a dummy packet, then ask the routing function for the best output
1721  // interface's address
1722  Ipv6Header header;
1724  Socket::SocketErrno errno_;
1725  Ptr<Ipv6Route> route;
1727  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1728  if (route == 0)
1729  {
1730  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1731  NS_LOG_ERROR (errno_);
1732  m_errno = errno_;
1733  return -1;
1734  }
1735  NS_LOG_LOGIC ("Route exists");
1736  m_endPoint6->SetLocalAddress (route->GetSource ());
1737  return 0;
1738 }
1739 
1743 void
1745  const Address& fromAddress, const Address& toAddress)
1746 {
1747  // Get port and address from peer (connecting host)
1748  if (InetSocketAddress::IsMatchingType (toAddress))
1749  {
1750  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1751  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1752  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1753  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1754  m_endPoint6 = 0;
1755  }
1756  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1757  {
1758  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1759  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1760  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1761  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1762  m_endPoint = 0;
1763  }
1764  m_tcp->m_sockets.push_back (this);
1765 
1766  // Change the cloned socket from LISTEN state to SYN_RCVD
1767  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1768  m_state = SYN_RCVD;
1770  SetupCallback ();
1771  // Set the sequence number and send SYN+ACK
1774 }
1775 
1776 void
1778 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1779  // be called as a scheduled event
1781  // The if-block below was moved from ProcessSynSent() to here because we need
1782  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1783  // reflect the behaviour in the real world.
1784  if (GetTxAvailable () > 0)
1785  {
1787  }
1788 }
1789 
1792 uint32_t
1793 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1794 {
1795  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1796 
1797  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
1798  uint32_t sz = p->GetSize (); // Size of packet
1799  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1800  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
1801 
1802  /*
1803  * Add tags for each socket option.
1804  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1805  * if both options are set. Once the packet got to layer three, only
1806  * the corresponding tags will be read.
1807  */
1808  if (IsManualIpTos ())
1809  {
1810  SocketIpTosTag ipTosTag;
1811  ipTosTag.SetTos (GetIpTos ());
1812  p->AddPacketTag (ipTosTag);
1813  }
1814 
1815  if (IsManualIpv6Tclass ())
1816  {
1817  SocketIpv6TclassTag ipTclassTag;
1818  ipTclassTag.SetTclass (GetIpv6Tclass ());
1819  p->AddPacketTag (ipTclassTag);
1820  }
1821 
1822  if (IsManualIpTtl ())
1823  {
1824  SocketIpTtlTag ipTtlTag;
1825  ipTtlTag.SetTtl (GetIpTtl ());
1826  p->AddPacketTag (ipTtlTag);
1827  }
1828 
1829  if (IsManualIpv6HopLimit ())
1830  {
1831  SocketIpv6HopLimitTag ipHopLimitTag;
1832  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1833  p->AddPacketTag (ipHopLimitTag);
1834  }
1835 
1836  if (m_closeOnEmpty && (remainingData == 0))
1837  {
1838  flags |= TcpHeader::FIN;
1839  if (m_state == ESTABLISHED)
1840  { // On active close: I am the first one to send FIN
1841  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1842  m_state = FIN_WAIT_1;
1843  }
1844  else if (m_state == CLOSE_WAIT)
1845  { // On passive close: Peer sent me FIN already
1846  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1847  m_state = LAST_ACK;
1848  }
1849  }
1850  TcpHeader header;
1851  header.SetFlags (flags);
1852  header.SetSequenceNumber (seq);
1854  if (m_endPoint)
1855  {
1856  header.SetSourcePort (m_endPoint->GetLocalPort ());
1858  }
1859  else
1860  {
1861  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1863  }
1864  header.SetWindowSize (AdvertisedWindowSize ());
1865  AddOptions (header);
1866  if (m_retxEvent.IsExpired () )
1867  { // Schedule retransmit
1869  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
1870  Simulator::Now ().GetSeconds () << " to expire at time " <<
1871  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
1873  }
1874  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1875  if (m_endPoint)
1876  {
1877  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1879  }
1880  else
1881  {
1882  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1884  }
1885  m_rtt->SentSeq (seq, sz); // notify the RTT
1886  // Notify the application of the data being sent unless this is a retransmit
1887  if (seq == m_nextTxSequence)
1888  {
1890  }
1891  // Update highTxMark
1892  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1893  return sz;
1894 }
1895 
1899 bool
1901 {
1902  NS_LOG_FUNCTION (this << withAck);
1903  if (m_txBuffer.Size () == 0)
1904  {
1905  return false; // Nothing to send
1906 
1907  }
1908  if (m_endPoint == 0 && m_endPoint6 == 0)
1909  {
1910  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
1911  return false; // Is this the right way to handle this condition?
1912  }
1913  uint32_t nPacketsSent = 0;
1915  {
1916  uint32_t w = AvailableWindow (); // Get available window size
1917  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
1918  " w " << w <<
1919  " rxwin " << m_rWnd <<
1920  " segsize " << m_segmentSize <<
1921  " nextTxSeq " << m_nextTxSequence <<
1922  " highestRxAck " << m_txBuffer.HeadSequence () <<
1923  " pd->Size " << m_txBuffer.Size () <<
1924  " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
1925  // Quit if send disallowed
1926  if (m_shutdownSend)
1927  {
1929  return false;
1930  }
1931  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
1933  {
1934  break; // No more
1935  }
1936  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
1937  // in the buffer and the amount of data to send is less than one segment
1938  if (!m_noDelay && UnAckDataCount () > 0
1940  {
1941  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
1942  break;
1943  }
1944  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
1945  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
1946  nPacketsSent++; // Count sent this loop
1947  m_nextTxSequence += sz; // Advance next tx sequence
1948  }
1949  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
1950  return (nPacketsSent > 0);
1951 }
1952 
1953 uint32_t
1955 {
1956  NS_LOG_FUNCTION (this);
1958 }
1959 
1960 uint32_t
1962 {
1963  NS_LOG_FUNCTION (this);
1964  return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
1965 }
1966 
1967 uint32_t
1969 {
1970  NS_LOG_FUNCTION (this);
1971  return m_rWnd;
1972 }
1973 
1974 uint32_t
1976 {
1978  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
1979  uint32_t win = Window (); // Number of bytes allowed to be outstanding
1980  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
1981  return (win < unack) ? 0 : (win - unack);
1982 }
1983 
1984 uint16_t
1986 {
1987  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
1988 }
1989 
1990 // Receipt of new packet, put into Rx buffer
1991 void
1993 {
1994  NS_LOG_FUNCTION (this << tcpHeader);
1995  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
1996  " ack " << tcpHeader.GetAckNumber () <<
1997  " pkt size " << p->GetSize () );
1998 
1999  // Put into Rx buffer
2000  SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
2001  if (!m_rxBuffer.Add (p, tcpHeader))
2002  { // Insert failed: No data or RX buffer full
2004  return;
2005  }
2006  // Now send a new ACK packet acknowledging all received and delivered data
2007  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
2008  { // A gap exists in the buffer, or we filled a gap: Always ACK
2010  }
2011  else
2012  { // In-sequence packet: ACK if delayed ack count allows
2014  {
2015  m_delAckEvent.Cancel ();
2016  m_delAckCount = 0;
2018  }
2019  else if (m_delAckEvent.IsExpired ())
2020  {
2023  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
2024  }
2025  }
2026  // Notify app to receive if necessary
2027  if (expectedSeq < m_rxBuffer.NextRxSequence ())
2028  { // NextRxSeq advanced, we have something to send to the app
2029  if (!m_shutdownRecv)
2030  {
2031  NotifyDataRecv ();
2032  }
2033  // Handle exceptions
2034  if (m_closeNotified)
2035  {
2036  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
2037  }
2038  // If we received FIN before and now completed all "holes" in rx buffer,
2039  // invoke peer close procedure
2040  if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2041  {
2042  DoPeerClose ();
2043  }
2044  }
2045 }
2046 
2048 void
2050 {
2051  // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
2052  // (which should be ignored) is handled by m_rtt. Once timestamp option
2053  // is implemented, this function would be more elaborated.
2054  Time nextRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
2055 
2056  //nextRtt will be zero for dup acks. Don't want to update lastRtt in that case
2057  //but still needed to do list clearing that is done in AckSeq.
2058  if(nextRtt != 0)
2059  {
2060  m_lastRtt = nextRtt;
2061  NS_LOG_FUNCTION(this << m_lastRtt);
2062  }
2063 
2064 }
2065 
2066 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
2067 // when the three-way handshake completed. This cancels retransmission timer
2068 // and advances Tx window
2069 void
2071 {
2072  NS_LOG_FUNCTION (this << ack);
2073 
2074  if (m_state != SYN_RCVD)
2075  { // Set RTO unless the ACK is received in SYN_RCVD state
2076  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2077  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2078  m_retxEvent.Cancel ();
2079  // On recieving a "New" ack we restart retransmission timer .. RFC 2988
2081  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
2082  Simulator::Now ().GetSeconds () << " to expire at time " <<
2083  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2085  }
2086  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
2087  { // Zero window: Enter persist state to send 1 byte to probe
2088  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
2089  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
2090  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2091  m_retxEvent.Cancel ();
2092  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
2093  Simulator::Now ().GetSeconds () << " to expire at time " <<
2094  (Simulator::Now () + m_persistTimeout).GetSeconds ());
2097  }
2098  // Note the highest ACK and tell app to send more
2099  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2100  " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
2101  m_txBuffer.DiscardUpTo (ack);
2102  if (GetTxAvailable () > 0)
2103  {
2105  }
2106  if (ack > m_nextTxSequence)
2107  {
2108  m_nextTxSequence = ack; // If advanced
2109  }
2110  if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2111  { // No retransmit timer if no data to retransmit
2112  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2113  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2114  m_retxEvent.Cancel ();
2115  }
2116  // Try to send more data
2118 }
2119 
2120 // Retransmit timeout
2121 void
2123 {
2124  NS_LOG_FUNCTION (this);
2125  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2126  // If erroneous timeout in closed/timed-wait state, just return
2127  if (m_state == CLOSED || m_state == TIME_WAIT)
2128  {
2129  return;
2130  }
2131  // If all data are received (non-closing socket and nothing to send), just return
2133  {
2134  return;
2135  }
2136 
2137  Retransmit ();
2138 }
2139 
2140 void
2142 {
2143  m_delAckCount = 0;
2145 }
2146 
2147 void
2149 {
2150  NS_LOG_FUNCTION (this);
2151 
2153  if (m_state == LAST_ACK)
2154  {
2155  CloseAndNotify ();
2156  }
2157  if (!m_closeNotified)
2158  {
2159  m_closeNotified = true;
2160  }
2161 }
2162 
2163 // Send 1-byte data to probe for the window size at the receiver when
2164 // the local knowledge tells that the receiver has zero window size
2165 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2166 void
2168 {
2169  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2170  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2172  TcpHeader tcpHeader;
2173  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2174  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2175  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2176  if (m_endPoint != 0)
2177  {
2178  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2179  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2180  }
2181  else
2182  {
2183  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2184  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2185  }
2186  AddOptions (tcpHeader);
2187 
2188  if (m_endPoint != 0)
2189  {
2190  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2192  }
2193  else
2194  {
2195  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2197  }
2198  NS_LOG_LOGIC ("Schedule persist timeout at time "
2199  << Simulator::Now ().GetSeconds () << " to expire at time "
2200  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2202 }
2203 
2204 void
2206 {
2207  m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
2208  m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
2209  m_dupAckCount = 0;
2210  DoRetransmit (); // Retransmit the packet
2211 }
2212 
2213 void
2215 {
2216  NS_LOG_FUNCTION (this);
2217  // Retransmit SYN packet
2218  if (m_state == SYN_SENT)
2219  {
2220  if (m_cnCount > 0)
2221  {
2223  }
2224  else
2225  {
2227  }
2228  return;
2229  }
2230  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2231  if (m_txBuffer.Size () == 0)
2232  {
2233  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2234  { // Must have lost FIN, re-send
2236  }
2237  return;
2238  }
2239  // Retransmit a data packet: Call SendDataPacket
2240  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
2241  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
2242  // In case of RTO, advance m_nextTxSequence
2243  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
2244 
2245 }
2246 
2247 void
2249 {
2250  m_retxEvent.Cancel ();
2252  m_delAckEvent.Cancel ();
2255 }
2256 
2258 void
2260 {
2261  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2262  m_state = TIME_WAIT;
2263  CancelAllTimers ();
2264  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2265  // according to RFC793, p.28
2268 }
2269 
2272 void
2274 {
2276 }
2277 
2278 uint32_t
2280 {
2281  return m_txBuffer.MaxBufferSize ();
2282 }
2283 
2284 void
2286 {
2288 }
2289 
2290 uint32_t
2292 {
2293  return m_rxBuffer.MaxBufferSize ();
2294 }
2295 
2296 void
2298 {
2299  m_segmentSize = size;
2300  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2301 }
2302 
2303 uint32_t
2305 {
2306  return m_segmentSize;
2307 }
2308 
2309 void
2311 {
2312  m_cnTimeout = timeout;
2313 }
2314 
2315 Time
2317 {
2318  return m_cnTimeout;
2319 }
2320 
2321 void
2323 {
2324  m_cnRetries = count;
2325 }
2326 
2327 uint32_t
2329 {
2330  return m_cnRetries;
2331 }
2332 
2333 void
2335 {
2337 }
2338 
2339 Time
2341 {
2342  return m_delAckTimeout;
2343 }
2344 
2345 void
2347 {
2348  m_delAckMaxCount = count;
2349 }
2350 
2351 uint32_t
2353 {
2354  return m_delAckMaxCount;
2355 }
2356 
2357 void
2359 {
2360  m_noDelay = noDelay;
2361 }
2362 
2363 bool
2365 {
2366  return m_noDelay;
2367 }
2368 
2369 void
2371 {
2373 }
2374 
2375 Time
2377 {
2378  return m_persistTimeout;
2379 }
2380 
2381 bool
2383 {
2384  // Broadcast is not implemented. Return true only if allowBroadcast==false
2385  return (!allowBroadcast);
2386 }
2387 
2388 bool
2390 {
2391  return false;
2392 }
2393 
2395 void
2397 {
2398 }
2399 
2401 void
2403 {
2404 }
2405 
2406 } // namespace ns3