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  NS_LOG_INFO ("Socket " << this << " << unread rx data during close. Sending reset");
454  SendRST ();
455  return 0;
456  }
457 
459  { // App close with pending data must wait until all data transmitted
460  if (m_closeOnEmpty == false)
461  {
462  m_closeOnEmpty = true;
463  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
464  }
465  return 0;
466  }
467  return DoClose ();
468 }
469 
471 int
473 {
474  NS_LOG_FUNCTION (this);
475 
476  //this prevents data from being added to the buffer
477  m_shutdownSend = true;
478  m_closeOnEmpty = true;
479  //if buffer is already empty, send a fin now
480  //otherwise fin will go when buffer empties.
481  if (m_txBuffer.Size () == 0)
482  {
483  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
484  {
485  NS_LOG_INFO("Emtpy tx buffer, send fin");
487 
488  if (m_state == ESTABLISHED)
489  { // On active close: I am the first one to send FIN
490  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
492  }
493  else
494  { // On passive close: Peer sent me FIN already
495  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
496  m_state = LAST_ACK;
497  }
498  }
499  }
500 
501  return 0;
502 }
503 
505 int
507 {
508  NS_LOG_FUNCTION (this);
509  m_shutdownRecv = true;
510  return 0;
511 }
512 
515 int
516 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
517 {
518  NS_LOG_FUNCTION (this << p);
519  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
521  {
522  // Store the packet into Tx buffer
523  if (!m_txBuffer.Add (p))
524  { // TxBuffer overflow, send failed
526  return -1;
527  }
528  if (m_shutdownSend)
529  {
531  return -1;
532  }
533  // Submit the data to lower layers
534  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
535  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
536  { // Try to send the data out
538  }
539  return p->GetSize ();
540  }
541  else
542  { // Connection not established yet
544  return -1; // Send failure
545  }
546 }
547 
549 int
550 TcpSocketBase::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
551 {
552  return Send (p, flags); // SendTo() and Send() are the same
553 }
554 
558 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
559 {
560  NS_LOG_FUNCTION (this);
561  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
562  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
563  {
564  return Create<Packet> (); // Send EOF on connection close
565  }
566  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
567  if (outPacket != 0 && outPacket->GetSize () != 0)
568  {
569  SocketAddressTag tag;
570  if (m_endPoint != 0)
571  {
573  }
574  else if (m_endPoint6 != 0)
575  {
577  }
578  outPacket->AddPacketTag (tag);
579  }
580  return outPacket;
581 }
582 
585 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
586 {
587  NS_LOG_FUNCTION (this << maxSize << flags);
588  Ptr<Packet> packet = Recv (maxSize, flags);
589  // Null packet means no data to read, and an empty packet indicates EOF
590  if (packet != 0 && packet->GetSize () != 0)
591  {
592  if (m_endPoint != 0)
593  {
595  }
596  else if (m_endPoint6 != 0)
597  {
599  }
600  else
601  {
602  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
603  }
604  }
605  return packet;
606 }
607 
609 uint32_t
611 {
612  NS_LOG_FUNCTION (this);
613  return m_txBuffer.Available ();
614 }
615 
617 uint32_t
619 {
620  NS_LOG_FUNCTION (this);
621  return m_rxBuffer.Available ();
622 }
623 
625 int
627 {
628  NS_LOG_FUNCTION (this);
629  if (m_endPoint != 0)
630  {
632  }
633  else if (m_endPoint6 != 0)
634  {
636  }
637  else
638  { // It is possible to call this method on a socket without a name
639  // in which case, behavior is unspecified
640  // Should this return an InetSocketAddress or an Inet6SocketAddress?
641  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
642  }
643  return 0;
644 }
645 
647 void
649 {
650  NS_LOG_FUNCTION (netdevice);
651  Socket::BindToNetDevice (netdevice); // Includes sanity check
652  if (m_endPoint == 0 && m_endPoint6 == 0)
653  {
654  if (Bind () == -1)
655  {
656  NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
657  return;
658  }
659  NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
660  }
661 
662  if (m_endPoint != 0)
663  {
664  m_endPoint->BindToNetDevice (netdevice);
665  }
666  // No BindToNetDevice() for Ipv6EndPoint
667  return;
668 }
669 
671 int
673 {
674  NS_LOG_FUNCTION (this);
675 
676  if (m_endPoint == 0 && m_endPoint6 == 0)
677  {
678  return -1;
679  }
680  if (m_endPoint != 0)
681  {
685  }
686  if (m_endPoint6 != 0)
687  {
691  }
692 
693  return 0;
694 }
695 
697 int
699 {
700  NS_LOG_FUNCTION (this);
701 
702  // A new connection is allowed only if this socket does not have a connection
704  { // send a SYN packet and change state into SYN_SENT
706  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
707  m_state = SYN_SENT;
708  }
709  else if (m_state != TIME_WAIT)
710  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
711  // exists. We send RST, tear down everything, and close this socket.
712  SendRST ();
713  CloseAndNotify ();
714  }
715  return 0;
716 }
717 
720 int
722 {
723  NS_LOG_FUNCTION (this);
724  switch (m_state)
725  {
726  case SYN_RCVD:
727  case ESTABLISHED:
728  // send FIN to close the peer
730  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
732  break;
733  case CLOSE_WAIT:
734  // send FIN+ACK to close the peer
736  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
737  m_state = LAST_ACK;
738  break;
739  case SYN_SENT:
740  case CLOSING:
741  // Send RST if application closes in SYN_SENT and CLOSING
742  SendRST ();
743  CloseAndNotify ();
744  break;
745  case LISTEN:
746  case LAST_ACK:
747  // In these three states, move to CLOSED and tear down the end point
748  CloseAndNotify ();
749  break;
750  case CLOSED:
751  case FIN_WAIT_1:
752  case FIN_WAIT_2:
753  case TIME_WAIT:
754  default: /* mute compiler */
755  // Do nothing in these four states
756  break;
757  }
758  return 0;
759 }
760 
762 void
764 {
765  NS_LOG_FUNCTION (this);
766 
767  if (!m_closeNotified)
768  {
770  }
771  if (m_state != TIME_WAIT)
772  {
774  }
775  m_closeNotified = true;
776  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
777  CancelAllTimers ();
778  m_state = CLOSED;
779 }
780 
781 
784 bool
786 {
787  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
788  { // Rx buffer in these states are not initialized.
789  return false;
790  }
791  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
792  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
793  // sequence number must equals to m_rxBuffer.NextRxSequence ()
794  return (m_rxBuffer.NextRxSequence () != head);
795  }
796 
797  // In all other cases, check if the sequence number is in range
798  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
799 }
800 
804 void
806  Ptr<Ipv4Interface> incomingInterface)
807 {
808  DoForwardUp (packet, header, port, incomingInterface);
809 }
810 
811 void
813 {
814  DoForwardUp (packet, header, port);
815 }
816 
817 void
818 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
819  uint8_t icmpType, uint8_t icmpCode,
820  uint32_t icmpInfo)
821 {
822  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
823  (uint32_t)icmpCode << icmpInfo);
824  if (!m_icmpCallback.IsNull ())
825  {
826  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
827  }
828 }
829 
830 void
831 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
832  uint8_t icmpType, uint8_t icmpCode,
833  uint32_t icmpInfo)
834 {
835  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
836  (uint32_t)icmpCode << icmpInfo);
837  if (!m_icmpCallback6.IsNull ())
838  {
839  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
840  }
841 }
842 
846 void
848  Ptr<Ipv4Interface> incomingInterface)
849 {
850  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
852  ":" << m_endPoint->GetPeerPort () <<
853  " to " << m_endPoint->GetLocalAddress () <<
854  ":" << m_endPoint->GetLocalPort ());
855  Address fromAddress = InetSocketAddress (header.GetSource (), port);
856  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
857 
858  // Peel off TCP header and do validity checking
859  TcpHeader tcpHeader;
860  packet->RemoveHeader (tcpHeader);
861  if (tcpHeader.GetFlags () & TcpHeader::ACK)
862  {
863  EstimateRtt (tcpHeader);
864  }
865  ReadOptions (tcpHeader);
866 
867  // Update Rx window size, i.e. the flow control window
868  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
869  { // persist probes end
870  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
872  }
873  m_rWnd = tcpHeader.GetWindowSize ();
874 
875  // Discard fully out of range data packets
876  if (packet->GetSize ()
877  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
878  {
879  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
880  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
881  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
882  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
883  m_rxBuffer.MaxRxSequence () << ")");
884  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
885  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
886  {
888  }
889  return;
890  }
891 
892  // TCP state machine code in different process functions
893  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
894  switch (m_state)
895  {
896  case ESTABLISHED:
897  ProcessEstablished (packet, tcpHeader);
898  break;
899  case LISTEN:
900  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
901  break;
902  case TIME_WAIT:
903  // Do nothing
904  break;
905  case CLOSED:
906  // Send RST if the incoming packet is not a RST
907  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
908  { // Since m_endPoint is not configured yet, we cannot use SendRST here
909  TcpHeader h;
913  h.SetSourcePort (tcpHeader.GetDestinationPort ());
914  h.SetDestinationPort (tcpHeader.GetSourcePort ());
916  AddOptions (h);
917  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
918  }
919  break;
920  case SYN_SENT:
921  ProcessSynSent (packet, tcpHeader);
922  break;
923  case SYN_RCVD:
924  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
925  break;
926  case FIN_WAIT_1:
927  case FIN_WAIT_2:
928  case CLOSE_WAIT:
929  ProcessWait (packet, tcpHeader);
930  break;
931  case CLOSING:
932  ProcessClosing (packet, tcpHeader);
933  break;
934  case LAST_ACK:
935  ProcessLastAck (packet, tcpHeader);
936  break;
937  default: // mute compiler
938  break;
939  }
940 }
941 
942 void
944 {
945  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
947  ":" << m_endPoint6->GetPeerPort () <<
948  " to " << m_endPoint6->GetLocalAddress () <<
949  ":" << m_endPoint6->GetLocalPort ());
950  Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port);
952 
953  // Peel off TCP header and do validity checking
954  TcpHeader tcpHeader;
955  packet->RemoveHeader (tcpHeader);
956  if (tcpHeader.GetFlags () & TcpHeader::ACK)
957  {
958  EstimateRtt (tcpHeader);
959  }
960  ReadOptions (tcpHeader);
961 
962  // Update Rx window size, i.e. the flow control window
963  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
964  { // persist probes end
965  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
967  }
968  m_rWnd = tcpHeader.GetWindowSize ();
969 
970  // Discard fully out of range packets
971  if (packet->GetSize ()
972  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
973  {
974  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
975  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
976  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
977  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
978  m_rxBuffer.MaxRxSequence () << ")");
979  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
980  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
981  {
983  }
984  return;
985  }
986 
987  // TCP state machine code in different process functions
988  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
989  switch (m_state)
990  {
991  case ESTABLISHED:
992  ProcessEstablished (packet, tcpHeader);
993  break;
994  case LISTEN:
995  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
996  break;
997  case TIME_WAIT:
998  // Do nothing
999  break;
1000  case CLOSED:
1001  // Send RST if the incoming packet is not a RST
1002  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
1003  { // Since m_endPoint is not configured yet, we cannot use SendRST here
1004  TcpHeader h;
1008  h.SetSourcePort (tcpHeader.GetDestinationPort ());
1009  h.SetDestinationPort (tcpHeader.GetSourcePort ());
1011  AddOptions (h);
1012  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestinationAddress (), header.GetSourceAddress (), m_boundnetdevice);
1013  }
1014  break;
1015  case SYN_SENT:
1016  ProcessSynSent (packet, tcpHeader);
1017  break;
1018  case SYN_RCVD:
1019  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
1020  break;
1021  case FIN_WAIT_1:
1022  case FIN_WAIT_2:
1023  case CLOSE_WAIT:
1024  ProcessWait (packet, tcpHeader);
1025  break;
1026  case CLOSING:
1027  ProcessClosing (packet, tcpHeader);
1028  break;
1029  case LAST_ACK:
1030  ProcessLastAck (packet, tcpHeader);
1031  break;
1032  default: // mute compiler
1033  break;
1034  }
1035 }
1036 
1039 void
1041 {
1042  NS_LOG_FUNCTION (this << tcpHeader);
1043 
1044  // Extract the flags. PSH and URG are not honoured.
1045  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1046 
1047  // Different flags are different events
1048  if (tcpflags == TcpHeader::ACK)
1049  {
1050  ReceivedAck (packet, tcpHeader);
1051  }
1052  else if (tcpflags == TcpHeader::SYN)
1053  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
1054  // respond with a SYN+ACK. But it is not a legal state transition as of
1055  // RFC793. Thus this is ignored.
1056  }
1057  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1058  { // No action for received SYN+ACK, it is probably a duplicated packet
1059  }
1060  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1061  { // Received FIN or FIN+ACK, bring down this socket nicely
1062  PeerClose (packet, tcpHeader);
1063  }
1064  else if (tcpflags == 0)
1065  { // No flags means there is only data
1066  ReceivedData (packet, tcpHeader);
1067  if (m_rxBuffer.Finished ())
1068  {
1069  PeerClose (packet, tcpHeader);
1070  }
1071  }
1072  else
1073  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1074  if (tcpflags != TcpHeader::RST)
1075  { // this must be an invalid flag, send reset
1076  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1077  SendRST ();
1078  }
1079  CloseAndNotify ();
1080  }
1081 }
1082 
1084 void
1086 {
1087  NS_LOG_FUNCTION (this << tcpHeader);
1088 
1089  // Received ACK. Compare the ACK number against highest unacked seqno
1090  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1091  { // Ignore if no ACK flag
1092  }
1093  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1094  { // Case 1: Old ACK, ignored.
1095  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1096  }
1097  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1098  { // Case 2: Potentially a duplicated ACK
1099  if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0)
1100  {
1101  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1102  DupAck (tcpHeader, ++m_dupAckCount);
1103  }
1104  // otherwise, the ACK is precisely equal to the nextTxSequence
1105  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1106  }
1107  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1108  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1109  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1110  NewAck (tcpHeader.GetAckNumber ());
1111  m_dupAckCount = 0;
1112  }
1113  // If there is any data piggybacked, store it into m_rxBuffer
1114  if (packet->GetSize () > 0)
1115  {
1116  ReceivedData (packet, tcpHeader);
1117  }
1118 }
1119 
1121 void
1123  const Address& fromAddress, const Address& toAddress)
1124 {
1125  NS_LOG_FUNCTION (this << tcpHeader);
1126 
1127  // Extract the flags. PSH and URG are not honoured.
1128  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1129 
1130  // Fork a socket if received a SYN. Do nothing otherwise.
1131  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1132  if (tcpflags != TcpHeader::SYN)
1133  {
1134  return;
1135  }
1136 
1137  // Call socket's notify function to let the server app know we got a SYN
1138  // If the server app refuses the connection, do nothing
1139  if (!NotifyConnectionRequest (fromAddress))
1140  {
1141  return;
1142  }
1143  // Clone the socket, simulate fork
1144  Ptr<TcpSocketBase> newSock = Fork ();
1145  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1147  packet, tcpHeader, fromAddress, toAddress);
1148 }
1149 
1151 void
1153 {
1154  NS_LOG_FUNCTION (this << tcpHeader);
1155 
1156  // Extract the flags. PSH and URG are not honoured.
1157  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1158 
1159  if (tcpflags == 0)
1160  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1161  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1162  m_state = ESTABLISHED;
1163  m_connected = true;
1164  m_retxEvent.Cancel ();
1166  ReceivedData (packet, tcpHeader);
1168  }
1169  else if (tcpflags == TcpHeader::ACK)
1170  { // Ignore ACK in SYN_SENT
1171  }
1172  else if (tcpflags == TcpHeader::SYN)
1173  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1174  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1175  m_state = SYN_RCVD;
1179  }
1180  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1181  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1182  { // Handshake completed
1183  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1184  m_state = ESTABLISHED;
1185  m_connected = true;
1186  m_retxEvent.Cancel ();
1193  // Always respond to first data packet to speed up the connection.
1194  // Remove to get the behaviour of old NS-3 code.
1196  }
1197  else
1198  { // Other in-sequence input
1199  if (tcpflags != TcpHeader::RST)
1200  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1201  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1202  SendRST ();
1203  }
1204  CloseAndNotify ();
1205  }
1206 }
1207 
1209 void
1211  const Address& fromAddress, const Address& toAddress)
1212 {
1213  NS_LOG_FUNCTION (this << tcpHeader);
1214 
1215  // Extract the flags. PSH and URG are not honoured.
1216  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1217 
1218  if (tcpflags == 0
1219  || (tcpflags == TcpHeader::ACK
1220  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1221  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1222  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1223  // handshake is completed nicely.
1224  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1225  m_state = ESTABLISHED;
1226  m_connected = true;
1227  m_retxEvent.Cancel ();
1230  if (m_endPoint)
1231  {
1232  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1233  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1234  }
1235  else if (m_endPoint6)
1236  {
1237  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1238  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1239  }
1240  // Always respond to first data packet to speed up the connection.
1241  // Remove to get the behaviour of old NS-3 code.
1243  ReceivedAck (packet, tcpHeader);
1244  NotifyNewConnectionCreated (this, fromAddress);
1245  // As this connection is established, the socket is available to send data now
1246  if (GetTxAvailable () > 0)
1247  {
1249  }
1250  }
1251  else if (tcpflags == TcpHeader::SYN)
1252  { // Probably the peer lost my SYN+ACK
1255  }
1256  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1257  {
1258  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1259  { // In-sequence FIN before connection complete. Set up connection and close.
1260  m_connected = true;
1261  m_retxEvent.Cancel ();
1264  if (m_endPoint)
1265  {
1266  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1267  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1268  }
1269  else if (m_endPoint6)
1270  {
1271  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1272  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1273  }
1274  PeerClose (packet, tcpHeader);
1275  }
1276  }
1277  else
1278  { // Other in-sequence input
1279  if (tcpflags != TcpHeader::RST)
1280  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1281  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1282  if (m_endPoint)
1283  {
1284  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1285  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1286  }
1287  else if (m_endPoint6)
1288  {
1289  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1290  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1291  }
1292  SendRST ();
1293  }
1294  CloseAndNotify ();
1295  }
1296 }
1297 
1299 void
1301 {
1302  NS_LOG_FUNCTION (this << tcpHeader);
1303 
1304  // Extract the flags. PSH and URG are not honoured.
1305  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1306 
1307  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1308  { // Bare data, accept it
1309  ReceivedData (packet, tcpHeader);
1310  }
1311  else if (tcpflags == TcpHeader::ACK)
1312  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1313  ReceivedAck (packet, tcpHeader);
1314  if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1315  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1316  { // This ACK corresponds to the FIN sent
1317  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1318  m_state = FIN_WAIT_2;
1319  }
1320  }
1321  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1322  { // Got FIN, respond with ACK and move to next state
1323  if (tcpflags & TcpHeader::ACK)
1324  { // Process the ACK first
1325  ReceivedAck (packet, tcpHeader);
1326  }
1328  }
1329  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1330  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1331  return;
1332  }
1333  else
1334  { // This is a RST or bad flags
1335  if (tcpflags != TcpHeader::RST)
1336  {
1337  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1338  SendRST ();
1339  }
1340  CloseAndNotify ();
1341  return;
1342  }
1343 
1344  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1345  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1346  {
1347  if (m_state == FIN_WAIT_1)
1348  {
1349  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1350  m_state = CLOSING;
1351  if (m_txBuffer.Size () == 0
1352  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1353  { // This ACK corresponds to the FIN sent
1354  TimeWait ();
1355  }
1356  }
1357  else if (m_state == FIN_WAIT_2)
1358  {
1359  TimeWait ();
1360  }
1362  if (!m_shutdownRecv)
1363  {
1364  NotifyDataRecv ();
1365  }
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 == TcpHeader::ACK)
1379  {
1380  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1381  { // This ACK corresponds to the FIN sent
1382  TimeWait ();
1383  }
1384  }
1385  else
1386  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1387  // anyone. If anything other than ACK is received, respond with a reset.
1388  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1389  { // FIN from the peer as well. We can close immediately.
1391  }
1392  else if (tcpflags != TcpHeader::RST)
1393  { // Receive of SYN or SYN+ACK or bad flags or pure data
1394  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1395  SendRST ();
1396  }
1397  CloseAndNotify ();
1398  }
1399 }
1400 
1402 void
1404 {
1405  NS_LOG_FUNCTION (this << tcpHeader);
1406 
1407  // Extract the flags. PSH and URG are not honoured.
1408  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1409 
1410  if (tcpflags == 0)
1411  {
1412  ReceivedData (packet, tcpHeader);
1413  }
1414  else if (tcpflags == TcpHeader::ACK)
1415  {
1416  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1417  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1418  CloseAndNotify ();
1419  }
1420  }
1421  else if (tcpflags == TcpHeader::FIN)
1422  { // Received FIN again, the peer probably lost the FIN+ACK
1424  }
1425  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1426  {
1427  CloseAndNotify ();
1428  }
1429  else
1430  { // Received a SYN or SYN+ACK or bad flags
1431  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1432  SendRST ();
1433  CloseAndNotify ();
1434  }
1435 }
1436 
1438 void
1440 {
1441  NS_LOG_FUNCTION (this << tcpHeader);
1442 
1443  // Ignore all out of range packets
1444  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1445  || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1446  {
1447  return;
1448  }
1449  // For any case, remember the FIN position in rx buffer first
1451  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1452  // If there is any piggybacked data, process it
1453  if (p->GetSize ())
1454  {
1455  ReceivedData (p, tcpHeader);
1456  }
1457  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1458  if (!m_rxBuffer.Finished ())
1459  {
1460  return;
1461  }
1462 
1463  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1464  if (m_state == FIN_WAIT_1)
1465  {
1466  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1467  m_state = CLOSING;
1468  return;
1469  }
1470 
1471  DoPeerClose (); // Change state, respond with ACK
1472 }
1473 
1475 void
1477 {
1479 
1480  // Move the state to CLOSE_WAIT
1481  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1482  m_state = CLOSE_WAIT;
1483 
1484  if (!m_closeNotified)
1485  {
1486  // The normal behaviour for an application is that, when the peer sent a in-sequence
1487  // FIN, the app should prepare to close. The app has two choices at this point: either
1488  // respond with ShutdownSend() call to declare that it has nothing more to send and
1489  // the socket can be closed immediately; or remember the peer's close request, wait
1490  // until all its existing data are pushed into the TCP socket, then call Close()
1491  // explicitly.
1492  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1493  NotifyNormalClose ();
1494  m_closeNotified = true;
1495  }
1496  if (m_shutdownSend)
1497  { // The application declares that it would not sent any more, close this socket
1498  Close ();
1499  }
1500  else
1501  { // Need to ack, the application will close later
1503  }
1504  if (m_state == LAST_ACK)
1505  {
1506  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1509  }
1510 }
1511 
1514 void
1516 {
1517  NS_LOG_FUNCTION (this);
1518  m_endPoint = 0;
1519  if (m_tcp != 0)
1520  {
1521  std::vector<Ptr<TcpSocketBase> >::iterator it
1522  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1523  if (it != m_tcp->m_sockets.end ())
1524  {
1525  m_tcp->m_sockets.erase (it);
1526  }
1527  }
1528  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1529  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1530  CancelAllTimers ();
1531 }
1532 
1535 void
1537 {
1538  NS_LOG_FUNCTION (this);
1539  m_endPoint6 = 0;
1540  if (m_tcp != 0)
1541  {
1542  std::vector<Ptr<TcpSocketBase> >::iterator it
1543  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1544  if (it != m_tcp->m_sockets.end ())
1545  {
1546  m_tcp->m_sockets.erase (it);
1547  }
1548  }
1549  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1550  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1551  CancelAllTimers ();
1552 }
1553 
1555 void
1557 {
1558  NS_LOG_FUNCTION (this << (uint32_t)flags);
1559  Ptr<Packet> p = Create<Packet> ();
1560  TcpHeader header;
1562 
1563  /*
1564  * Add tags for each socket option.
1565  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1566  * if both options are set. Once the packet got to layer three, only
1567  * the corresponding tags will be read.
1568  */
1569  if (IsManualIpTos ())
1570  {
1571  SocketIpTosTag ipTosTag;
1572  ipTosTag.SetTos (GetIpTos ());
1573  p->AddPacketTag (ipTosTag);
1574  }
1575 
1576  if (IsManualIpv6Tclass ())
1577  {
1578  SocketIpv6TclassTag ipTclassTag;
1579  ipTclassTag.SetTclass (GetIpv6Tclass ());
1580  p->AddPacketTag (ipTclassTag);
1581  }
1582 
1583  if (IsManualIpTtl ())
1584  {
1585  SocketIpTtlTag ipTtlTag;
1586  ipTtlTag.SetTtl (GetIpTtl ());
1587  p->AddPacketTag (ipTtlTag);
1588  }
1589 
1590  if (IsManualIpv6HopLimit ())
1591  {
1592  SocketIpv6HopLimitTag ipHopLimitTag;
1593  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1594  p->AddPacketTag (ipHopLimitTag);
1595  }
1596 
1597  if (m_endPoint == 0 && m_endPoint6 == 0)
1598  {
1599  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1600  return;
1601  }
1602  if (flags & TcpHeader::FIN)
1603  {
1604  flags |= TcpHeader::ACK;
1605  }
1606  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1607  {
1608  ++s;
1609  }
1610 
1611  header.SetFlags (flags);
1612  header.SetSequenceNumber (s);
1613  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1614  if (m_endPoint != 0)
1615  {
1616  header.SetSourcePort (m_endPoint->GetLocalPort ());
1617  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1618  }
1619  else
1620  {
1621  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1622  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1623  }
1624  header.SetWindowSize (AdvertisedWindowSize ());
1625  AddOptions (header);
1627  bool hasSyn = flags & TcpHeader::SYN;
1628  bool hasFin = flags & TcpHeader::FIN;
1629  bool isAck = flags == TcpHeader::ACK;
1630  if (hasSyn)
1631  {
1632  if (m_cnCount == 0)
1633  { // No more connection retries, give up
1634  NS_LOG_LOGIC ("Connection failed.");
1635  CloseAndNotify ();
1636  return;
1637  }
1638  else
1639  { // Exponential backoff of connection time out
1640  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1641  m_rto = m_cnTimeout * backoffCount;
1642  m_cnCount--;
1643  }
1644  }
1645  if (m_endPoint != 0)
1646  {
1647  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1649  }
1650  else
1651  {
1652  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1654  }
1655  if (flags & TcpHeader::ACK)
1656  { // If sending an ACK, cancel the delay ACK as well
1657  m_delAckEvent.Cancel ();
1658  m_delAckCount = 0;
1659  }
1660  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1661  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1662  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1663  << Simulator::Now ().GetSeconds () << " to expire at time "
1664  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1666  }
1667 }
1668 
1670 void
1672 {
1673  NS_LOG_FUNCTION (this);
1675  NotifyErrorClose ();
1676  DeallocateEndPoint ();
1677 }
1678 
1680 void
1682 {
1683  if (m_endPoint != 0)
1684  {
1685  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1687  m_endPoint = 0;
1688  std::vector<Ptr<TcpSocketBase> >::iterator it
1689  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1690  if (it != m_tcp->m_sockets.end ())
1691  {
1692  m_tcp->m_sockets.erase (it);
1693  }
1694  CancelAllTimers ();
1695  }
1696  if (m_endPoint6 != 0)
1697  {
1698  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1700  m_endPoint6 = 0;
1701  std::vector<Ptr<TcpSocketBase> >::iterator it
1702  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1703  if (it != m_tcp->m_sockets.end ())
1704  {
1705  m_tcp->m_sockets.erase (it);
1706  }
1707  CancelAllTimers ();
1708  }
1709 }
1710 
1712 int
1714 {
1715  NS_LOG_FUNCTION (this);
1716  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1717  NS_ASSERT (ipv4 != 0);
1718  if (ipv4->GetRoutingProtocol () == 0)
1719  {
1720  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1721  }
1722  // Create a dummy packet, then ask the routing function for the best output
1723  // interface's address
1724  Ipv4Header header;
1726  Socket::SocketErrno errno_;
1727  Ptr<Ipv4Route> route;
1729  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1730  if (route == 0)
1731  {
1732  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1733  NS_LOG_ERROR (errno_);
1734  m_errno = errno_;
1735  return -1;
1736  }
1737  NS_LOG_LOGIC ("Route exists");
1738  m_endPoint->SetLocalAddress (route->GetSource ());
1739  return 0;
1740 }
1741 
1742 int
1744 {
1745  NS_LOG_FUNCTION (this);
1747  NS_ASSERT (ipv6 != 0);
1748  if (ipv6->GetRoutingProtocol () == 0)
1749  {
1750  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1751  }
1752  // Create a dummy packet, then ask the routing function for the best output
1753  // interface's address
1754  Ipv6Header header;
1756  Socket::SocketErrno errno_;
1757  Ptr<Ipv6Route> route;
1759  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1760  if (route == 0)
1761  {
1762  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1763  NS_LOG_ERROR (errno_);
1764  m_errno = errno_;
1765  return -1;
1766  }
1767  NS_LOG_LOGIC ("Route exists");
1768  m_endPoint6->SetLocalAddress (route->GetSource ());
1769  return 0;
1770 }
1771 
1775 void
1777  const Address& fromAddress, const Address& toAddress)
1778 {
1779  // Get port and address from peer (connecting host)
1780  if (InetSocketAddress::IsMatchingType (toAddress))
1781  {
1782  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1783  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1784  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1785  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1786  m_endPoint6 = 0;
1787  }
1788  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1789  {
1790  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1791  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1792  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1793  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1794  m_endPoint = 0;
1795  }
1796  m_tcp->m_sockets.push_back (this);
1797 
1798  // Change the cloned socket from LISTEN state to SYN_RCVD
1799  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1800  m_state = SYN_RCVD;
1802  SetupCallback ();
1803  // Set the sequence number and send SYN+ACK
1806 }
1807 
1808 void
1810 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1811  // be called as a scheduled event
1813  // The if-block below was moved from ProcessSynSent() to here because we need
1814  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1815  // reflect the behaviour in the real world.
1816  if (GetTxAvailable () > 0)
1817  {
1819  }
1820 }
1821 
1824 uint32_t
1825 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1826 {
1827  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1828 
1829  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
1830  uint32_t sz = p->GetSize (); // Size of packet
1831  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1832  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
1833 
1834  /*
1835  * Add tags for each socket option.
1836  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1837  * if both options are set. Once the packet got to layer three, only
1838  * the corresponding tags will be read.
1839  */
1840  if (IsManualIpTos ())
1841  {
1842  SocketIpTosTag ipTosTag;
1843  ipTosTag.SetTos (GetIpTos ());
1844  p->AddPacketTag (ipTosTag);
1845  }
1846 
1847  if (IsManualIpv6Tclass ())
1848  {
1849  SocketIpv6TclassTag ipTclassTag;
1850  ipTclassTag.SetTclass (GetIpv6Tclass ());
1851  p->AddPacketTag (ipTclassTag);
1852  }
1853 
1854  if (IsManualIpTtl ())
1855  {
1856  SocketIpTtlTag ipTtlTag;
1857  ipTtlTag.SetTtl (GetIpTtl ());
1858  p->AddPacketTag (ipTtlTag);
1859  }
1860 
1861  if (IsManualIpv6HopLimit ())
1862  {
1863  SocketIpv6HopLimitTag ipHopLimitTag;
1864  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1865  p->AddPacketTag (ipHopLimitTag);
1866  }
1867 
1868  if (m_closeOnEmpty && (remainingData == 0))
1869  {
1870  flags |= TcpHeader::FIN;
1871  if (m_state == ESTABLISHED)
1872  { // On active close: I am the first one to send FIN
1873  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1874  m_state = FIN_WAIT_1;
1875  }
1876  else if (m_state == CLOSE_WAIT)
1877  { // On passive close: Peer sent me FIN already
1878  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1879  m_state = LAST_ACK;
1880  }
1881  }
1882  TcpHeader header;
1883  header.SetFlags (flags);
1884  header.SetSequenceNumber (seq);
1886  if (m_endPoint)
1887  {
1888  header.SetSourcePort (m_endPoint->GetLocalPort ());
1890  }
1891  else
1892  {
1893  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1895  }
1896  header.SetWindowSize (AdvertisedWindowSize ());
1897  AddOptions (header);
1898  if (m_retxEvent.IsExpired () )
1899  { // Schedule retransmit
1901  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
1902  Simulator::Now ().GetSeconds () << " to expire at time " <<
1903  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
1905  }
1906  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1907  if (m_endPoint)
1908  {
1909  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1911  }
1912  else
1913  {
1914  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1916  }
1917  m_rtt->SentSeq (seq, sz); // notify the RTT
1918  // Notify the application of the data being sent unless this is a retransmit
1919  if (seq == m_nextTxSequence)
1920  {
1922  }
1923  // Update highTxMark
1924  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1925  return sz;
1926 }
1927 
1931 bool
1933 {
1934  NS_LOG_FUNCTION (this << withAck);
1935  if (m_txBuffer.Size () == 0)
1936  {
1937  return false; // Nothing to send
1938 
1939  }
1940  if (m_endPoint == 0 && m_endPoint6 == 0)
1941  {
1942  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
1943  return false; // Is this the right way to handle this condition?
1944  }
1945  uint32_t nPacketsSent = 0;
1947  {
1948  uint32_t w = AvailableWindow (); // Get available window size
1949  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
1950  " w " << w <<
1951  " rxwin " << m_rWnd <<
1952  " segsize " << m_segmentSize <<
1953  " nextTxSeq " << m_nextTxSequence <<
1954  " highestRxAck " << m_txBuffer.HeadSequence () <<
1955  " pd->Size " << m_txBuffer.Size () <<
1956  " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
1957  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
1959  {
1960  break; // No more
1961  }
1962  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
1963  // in the buffer and the amount of data to send is less than one segment
1964  if (!m_noDelay && UnAckDataCount () > 0
1966  {
1967  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
1968  break;
1969  }
1970  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
1971  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
1972  nPacketsSent++; // Count sent this loop
1973  m_nextTxSequence += sz; // Advance next tx sequence
1974  }
1975  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
1976  return (nPacketsSent > 0);
1977 }
1978 
1979 uint32_t
1981 {
1982  NS_LOG_FUNCTION (this);
1984 }
1985 
1986 uint32_t
1988 {
1989  NS_LOG_FUNCTION (this);
1990  return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
1991 }
1992 
1993 uint32_t
1995 {
1996  NS_LOG_FUNCTION (this);
1997  return m_rWnd;
1998 }
1999 
2000 uint32_t
2002 {
2004  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
2005  uint32_t win = Window (); // Number of bytes allowed to be outstanding
2006  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
2007  return (win < unack) ? 0 : (win - unack);
2008 }
2009 
2010 uint16_t
2012 {
2013  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
2014 }
2015 
2016 // Receipt of new packet, put into Rx buffer
2017 void
2019 {
2020  NS_LOG_FUNCTION (this << tcpHeader);
2021  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
2022  " ack " << tcpHeader.GetAckNumber () <<
2023  " pkt size " << p->GetSize () );
2024 
2025  // Put into Rx buffer
2026  SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
2027  if (!m_rxBuffer.Add (p, tcpHeader))
2028  { // Insert failed: No data or RX buffer full
2030  return;
2031  }
2032  // Now send a new ACK packet acknowledging all received and delivered data
2033  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
2034  { // A gap exists in the buffer, or we filled a gap: Always ACK
2036  }
2037  else
2038  { // In-sequence packet: ACK if delayed ack count allows
2040  {
2041  m_delAckEvent.Cancel ();
2042  m_delAckCount = 0;
2044  }
2045  else if (m_delAckEvent.IsExpired ())
2046  {
2049  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
2050  }
2051  }
2052  // Notify app to receive if necessary
2053  if (expectedSeq < m_rxBuffer.NextRxSequence ())
2054  { // NextRxSeq advanced, we have something to send to the app
2055  if (!m_shutdownRecv)
2056  {
2057  NotifyDataRecv ();
2058  }
2059  // Handle exceptions
2060  if (m_closeNotified)
2061  {
2062  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
2063  }
2064  // If we received FIN before and now completed all "holes" in rx buffer,
2065  // invoke peer close procedure
2066  if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2067  {
2068  DoPeerClose ();
2069  }
2070  }
2071 }
2072 
2074 void
2076 {
2077  // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
2078  // (which should be ignored) is handled by m_rtt. Once timestamp option
2079  // is implemented, this function would be more elaborated.
2080  Time nextRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
2081 
2082  //nextRtt will be zero for dup acks. Don't want to update lastRtt in that case
2083  //but still needed to do list clearing that is done in AckSeq.
2084  if(nextRtt != 0)
2085  {
2086  m_lastRtt = nextRtt;
2087  NS_LOG_FUNCTION(this << m_lastRtt);
2088  }
2089 
2090 }
2091 
2092 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
2093 // when the three-way handshake completed. This cancels retransmission timer
2094 // and advances Tx window
2095 void
2097 {
2098  NS_LOG_FUNCTION (this << ack);
2099 
2100  if (m_state != SYN_RCVD)
2101  { // Set RTO unless the ACK is received in SYN_RCVD state
2102  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2103  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2104  m_retxEvent.Cancel ();
2105  // On recieving a "New" ack we restart retransmission timer .. RFC 2988
2107  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
2108  Simulator::Now ().GetSeconds () << " to expire at time " <<
2109  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2111  }
2112  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
2113  { // Zero window: Enter persist state to send 1 byte to probe
2114  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
2115  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
2116  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2117  m_retxEvent.Cancel ();
2118  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
2119  Simulator::Now ().GetSeconds () << " to expire at time " <<
2120  (Simulator::Now () + m_persistTimeout).GetSeconds ());
2123  }
2124  // Note the highest ACK and tell app to send more
2125  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2126  " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
2127  m_txBuffer.DiscardUpTo (ack);
2128  if (GetTxAvailable () > 0)
2129  {
2131  }
2132  if (ack > m_nextTxSequence)
2133  {
2134  m_nextTxSequence = ack; // If advanced
2135  }
2136  if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2137  { // No retransmit timer if no data to retransmit
2138  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2139  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2140  m_retxEvent.Cancel ();
2141  }
2142  // Try to send more data
2144 }
2145 
2146 // Retransmit timeout
2147 void
2149 {
2150  NS_LOG_FUNCTION (this);
2151  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2152  // If erroneous timeout in closed/timed-wait state, just return
2153  if (m_state == CLOSED || m_state == TIME_WAIT)
2154  {
2155  return;
2156  }
2157  // If all data are received (non-closing socket and nothing to send), just return
2159  {
2160  return;
2161  }
2162 
2163  Retransmit ();
2164 }
2165 
2166 void
2168 {
2169  m_delAckCount = 0;
2171 }
2172 
2173 void
2175 {
2176  NS_LOG_FUNCTION (this);
2177 
2179  if (m_state == LAST_ACK)
2180  {
2181  CloseAndNotify ();
2182  }
2183  if (!m_closeNotified)
2184  {
2185  m_closeNotified = true;
2186  }
2187 }
2188 
2189 // Send 1-byte data to probe for the window size at the receiver when
2190 // the local knowledge tells that the receiver has zero window size
2191 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2192 void
2194 {
2195  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2196  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2198  TcpHeader tcpHeader;
2199  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2200  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2201  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2202  if (m_endPoint != 0)
2203  {
2204  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2205  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2206  }
2207  else
2208  {
2209  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2210  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2211  }
2212  AddOptions (tcpHeader);
2213 
2214  if (m_endPoint != 0)
2215  {
2216  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2218  }
2219  else
2220  {
2221  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2223  }
2224  NS_LOG_LOGIC ("Schedule persist timeout at time "
2225  << Simulator::Now ().GetSeconds () << " to expire at time "
2226  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2228 }
2229 
2230 void
2232 {
2233  m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
2234  m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
2235  m_dupAckCount = 0;
2236  DoRetransmit (); // Retransmit the packet
2237 }
2238 
2239 void
2241 {
2242  NS_LOG_FUNCTION (this);
2243  // Retransmit SYN packet
2244  if (m_state == SYN_SENT)
2245  {
2246  if (m_cnCount > 0)
2247  {
2249  }
2250  else
2251  {
2253  }
2254  return;
2255  }
2256  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2257  if (m_txBuffer.Size () == 0)
2258  {
2259  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2260  { // Must have lost FIN, re-send
2262  }
2263  return;
2264  }
2265  // Retransmit a data packet: Call SendDataPacket
2266  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
2267  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
2268  // In case of RTO, advance m_nextTxSequence
2269  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
2270 
2271 }
2272 
2273 void
2275 {
2276  m_retxEvent.Cancel ();
2278  m_delAckEvent.Cancel ();
2281 }
2282 
2284 void
2286 {
2287  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2288  m_state = TIME_WAIT;
2289  CancelAllTimers ();
2290  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2291  // according to RFC793, p.28
2294 }
2295 
2298 void
2300 {
2302 }
2303 
2304 uint32_t
2306 {
2307  return m_txBuffer.MaxBufferSize ();
2308 }
2309 
2310 void
2312 {
2314 }
2315 
2316 uint32_t
2318 {
2319  return m_rxBuffer.MaxBufferSize ();
2320 }
2321 
2322 void
2324 {
2325  m_segmentSize = size;
2326  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2327 }
2328 
2329 uint32_t
2331 {
2332  return m_segmentSize;
2333 }
2334 
2335 void
2337 {
2338  m_cnTimeout = timeout;
2339 }
2340 
2341 Time
2343 {
2344  return m_cnTimeout;
2345 }
2346 
2347 void
2349 {
2350  m_cnRetries = count;
2351 }
2352 
2353 uint32_t
2355 {
2356  return m_cnRetries;
2357 }
2358 
2359 void
2361 {
2363 }
2364 
2365 Time
2367 {
2368  return m_delAckTimeout;
2369 }
2370 
2371 void
2373 {
2374  m_delAckMaxCount = count;
2375 }
2376 
2377 uint32_t
2379 {
2380  return m_delAckMaxCount;
2381 }
2382 
2383 void
2385 {
2386  m_noDelay = noDelay;
2387 }
2388 
2389 bool
2391 {
2392  return m_noDelay;
2393 }
2394 
2395 void
2397 {
2399 }
2400 
2401 Time
2403 {
2404  return m_persistTimeout;
2405 }
2406 
2407 bool
2409 {
2410  // Broadcast is not implemented. Return true only if allowBroadcast==false
2411  return (!allowBroadcast);
2412 }
2413 
2414 bool
2416 {
2417  return false;
2418 }
2419 
2421 void
2423 {
2424 }
2425 
2427 void
2429 {
2430 }
2431 
2432 } // namespace ns3