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);
199  m_tcp->DeAllocate (m_endPoint);
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);
206  m_tcp->DeAllocate (m_endPoint6);
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);
275  m_endPoint6 = m_tcp->Allocate6 ();
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
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  {
324  m_endPoint6 = m_tcp->Allocate6 ();
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);
452  if (m_rxBuffer.Size () != 0)
453  {
454  NS_LOG_INFO ("Socket " << this << " << unread rx data during close. Sending reset");
455  SendRST ();
456  return 0;
457  }
458 
460  { // App close with pending data must wait until all data transmitted
461  if (m_closeOnEmpty == false)
462  {
463  m_closeOnEmpty = true;
464  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
465  }
466  return 0;
467  }
468  return DoClose ();
469 }
470 
472 int
474 {
475  NS_LOG_FUNCTION (this);
476 
477  //this prevents data from being added to the buffer
478  m_shutdownSend = true;
479  m_closeOnEmpty = true;
480  //if buffer is already empty, send a fin now
481  //otherwise fin will go when buffer empties.
482  if (m_txBuffer.Size () == 0)
483  {
484  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
485  {
486  NS_LOG_INFO("Emtpy tx buffer, send fin");
488 
489  if (m_state == ESTABLISHED)
490  { // On active close: I am the first one to send FIN
491  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
493  }
494  else
495  { // On passive close: Peer sent me FIN already
496  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
497  m_state = LAST_ACK;
498  }
499  }
500  }
501 
502  return 0;
503 }
504 
506 int
508 {
509  NS_LOG_FUNCTION (this);
510  m_shutdownRecv = true;
511  return 0;
512 }
513 
516 int
517 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
518 {
519  NS_LOG_FUNCTION (this << p);
520  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
522  {
523  // Store the packet into Tx buffer
524  if (!m_txBuffer.Add (p))
525  { // TxBuffer overflow, send failed
527  return -1;
528  }
529  if (m_shutdownSend)
530  {
532  return -1;
533  }
534  // Submit the data to lower layers
535  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
536  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
537  { // Try to send the data out
539  }
540  return p->GetSize ();
541  }
542  else
543  { // Connection not established yet
545  return -1; // Send failure
546  }
547 }
548 
550 int
552 {
553  return Send (p, flags); // SendTo() and Send() are the same
554 }
555 
559 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
560 {
561  NS_LOG_FUNCTION (this);
562  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
563  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
564  {
565  return Create<Packet> (); // Send EOF on connection close
566  }
567  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
568  if (outPacket != 0 && outPacket->GetSize () != 0)
569  {
570  SocketAddressTag tag;
571  if (m_endPoint != 0)
572  {
574  }
575  else if (m_endPoint6 != 0)
576  {
578  }
579  outPacket->AddPacketTag (tag);
580  }
581  return outPacket;
582 }
583 
586 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
587 {
588  NS_LOG_FUNCTION (this << maxSize << flags);
589  Ptr<Packet> packet = Recv (maxSize, flags);
590  // Null packet means no data to read, and an empty packet indicates EOF
591  if (packet != 0 && packet->GetSize () != 0)
592  {
593  if (m_endPoint != 0)
594  {
596  }
597  else if (m_endPoint6 != 0)
598  {
600  }
601  else
602  {
603  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
604  }
605  }
606  return packet;
607 }
608 
610 uint32_t
612 {
613  NS_LOG_FUNCTION (this);
614  return m_txBuffer.Available ();
615 }
616 
618 uint32_t
620 {
621  NS_LOG_FUNCTION (this);
622  return m_rxBuffer.Available ();
623 }
624 
626 int
628 {
629  NS_LOG_FUNCTION (this);
630  if (m_endPoint != 0)
631  {
633  }
634  else if (m_endPoint6 != 0)
635  {
637  }
638  else
639  { // It is possible to call this method on a socket without a name
640  // in which case, behavior is unspecified
641  // Should this return an InetSocketAddress or an Inet6SocketAddress?
642  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
643  }
644  return 0;
645 }
646 
648 void
650 {
651  NS_LOG_FUNCTION (netdevice);
652  Socket::BindToNetDevice (netdevice); // Includes sanity check
653  if (m_endPoint == 0 && m_endPoint6 == 0)
654  {
655  if (Bind () == -1)
656  {
657  NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
658  return;
659  }
660  NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
661  }
662 
663  if (m_endPoint != 0)
664  {
665  m_endPoint->BindToNetDevice (netdevice);
666  }
667  // No BindToNetDevice() for Ipv6EndPoint
668  return;
669 }
670 
672 int
674 {
675  NS_LOG_FUNCTION (this);
676 
677  if (m_endPoint == 0 && m_endPoint6 == 0)
678  {
679  return -1;
680  }
681  if (m_endPoint != 0)
682  {
686  }
687  if (m_endPoint6 != 0)
688  {
692  }
693 
694  return 0;
695 }
696 
698 int
700 {
701  NS_LOG_FUNCTION (this);
702 
703  // A new connection is allowed only if this socket does not have a connection
705  { // send a SYN packet and change state into SYN_SENT
707  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
708  m_state = SYN_SENT;
709  }
710  else if (m_state != TIME_WAIT)
711  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
712  // exists. We send RST, tear down everything, and close this socket.
713  SendRST ();
714  CloseAndNotify ();
715  }
716  return 0;
717 }
718 
721 int
723 {
724  NS_LOG_FUNCTION (this);
725  switch (m_state)
726  {
727  case SYN_RCVD:
728  case ESTABLISHED:
729  // send FIN to close the peer
731  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
733  break;
734  case CLOSE_WAIT:
735  // send FIN+ACK to close the peer
737  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
738  m_state = LAST_ACK;
739  break;
740  case SYN_SENT:
741  case CLOSING:
742  // Send RST if application closes in SYN_SENT and CLOSING
743  SendRST ();
744  CloseAndNotify ();
745  break;
746  case LISTEN:
747  case LAST_ACK:
748  // In these three states, move to CLOSED and tear down the end point
749  CloseAndNotify ();
750  break;
751  case CLOSED:
752  case FIN_WAIT_1:
753  case FIN_WAIT_2:
754  case TIME_WAIT:
755  default: /* mute compiler */
756  // Do nothing in these four states
757  break;
758  }
759  return 0;
760 }
761 
763 void
765 {
766  NS_LOG_FUNCTION (this);
767 
768  if (!m_closeNotified)
769  {
771  }
772  if (m_state != TIME_WAIT)
773  {
775  }
776  m_closeNotified = true;
777  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
778  CancelAllTimers ();
779  m_state = CLOSED;
780 }
781 
782 
785 bool
787 {
788  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
789  { // Rx buffer in these states are not initialized.
790  return false;
791  }
792  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
793  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
794  // sequence number must equals to m_rxBuffer.NextRxSequence ()
795  return (m_rxBuffer.NextRxSequence () != head);
796  }
797 
798  // In all other cases, check if the sequence number is in range
799  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
800 }
801 
805 void
807  Ptr<Ipv4Interface> incomingInterface)
808 {
809  DoForwardUp (packet, header, port, incomingInterface);
810 }
811 
812 void
814 {
815  DoForwardUp (packet, header, port);
816 }
817 
818 void
819 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
820  uint8_t icmpType, uint8_t icmpCode,
821  uint32_t icmpInfo)
822 {
823  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
824  (uint32_t)icmpCode << icmpInfo);
825  if (!m_icmpCallback.IsNull ())
826  {
827  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
828  }
829 }
830 
831 void
832 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
833  uint8_t icmpType, uint8_t icmpCode,
834  uint32_t icmpInfo)
835 {
836  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
837  (uint32_t)icmpCode << icmpInfo);
838  if (!m_icmpCallback6.IsNull ())
839  {
840  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
841  }
842 }
843 
847 void
849  Ptr<Ipv4Interface> incomingInterface)
850 {
851  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
853  ":" << m_endPoint->GetPeerPort () <<
854  " to " << m_endPoint->GetLocalAddress () <<
855  ":" << m_endPoint->GetLocalPort ());
856  Address fromAddress = InetSocketAddress (header.GetSource (), port);
857  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
858 
859  // Peel off TCP header and do validity checking
860  TcpHeader tcpHeader;
861  packet->RemoveHeader (tcpHeader);
862  if (tcpHeader.GetFlags () & TcpHeader::ACK)
863  {
864  EstimateRtt (tcpHeader);
865  }
866  ReadOptions (tcpHeader);
867 
868  // Update Rx window size, i.e. the flow control window
869  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
870  { // persist probes end
871  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
873  }
874  m_rWnd = tcpHeader.GetWindowSize ();
875 
876  // Discard fully out of range data packets
877  if (packet->GetSize ()
878  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
879  {
880  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
881  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
882  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
883  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
884  m_rxBuffer.MaxRxSequence () << ")");
885  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
886  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
887  {
889  }
890  return;
891  }
892 
893  // TCP state machine code in different process functions
894  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
895  switch (m_state)
896  {
897  case ESTABLISHED:
898  ProcessEstablished (packet, tcpHeader);
899  break;
900  case LISTEN:
901  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
902  break;
903  case TIME_WAIT:
904  // Do nothing
905  break;
906  case CLOSED:
907  // Send RST if the incoming packet is not a RST
908  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
909  { // Since m_endPoint is not configured yet, we cannot use SendRST here
910  TcpHeader h;
914  h.SetSourcePort (tcpHeader.GetDestinationPort ());
915  h.SetDestinationPort (tcpHeader.GetSourcePort ());
917  AddOptions (h);
918  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
919  }
920  break;
921  case SYN_SENT:
922  ProcessSynSent (packet, tcpHeader);
923  break;
924  case SYN_RCVD:
925  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
926  break;
927  case FIN_WAIT_1:
928  case FIN_WAIT_2:
929  case CLOSE_WAIT:
930  ProcessWait (packet, tcpHeader);
931  break;
932  case CLOSING:
933  ProcessClosing (packet, tcpHeader);
934  break;
935  case LAST_ACK:
936  ProcessLastAck (packet, tcpHeader);
937  break;
938  default: // mute compiler
939  break;
940  }
941 }
942 
943 void
945 {
946  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
948  ":" << m_endPoint6->GetPeerPort () <<
949  " to " << m_endPoint6->GetLocalAddress () <<
950  ":" << m_endPoint6->GetLocalPort ());
951  Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port);
953 
954  // Peel off TCP header and do validity checking
955  TcpHeader tcpHeader;
956  packet->RemoveHeader (tcpHeader);
957  if (tcpHeader.GetFlags () & TcpHeader::ACK)
958  {
959  EstimateRtt (tcpHeader);
960  }
961  ReadOptions (tcpHeader);
962 
963  // Update Rx window size, i.e. the flow control window
964  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
965  { // persist probes end
966  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
968  }
969  m_rWnd = tcpHeader.GetWindowSize ();
970 
971  // Discard fully out of range packets
972  if (packet->GetSize ()
973  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
974  {
975  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
976  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
977  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
978  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
979  m_rxBuffer.MaxRxSequence () << ")");
980  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
981  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
982  {
984  }
985  return;
986  }
987 
988  // TCP state machine code in different process functions
989  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
990  switch (m_state)
991  {
992  case ESTABLISHED:
993  ProcessEstablished (packet, tcpHeader);
994  break;
995  case LISTEN:
996  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
997  break;
998  case TIME_WAIT:
999  // Do nothing
1000  break;
1001  case CLOSED:
1002  // Send RST if the incoming packet is not a RST
1003  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
1004  { // Since m_endPoint is not configured yet, we cannot use SendRST here
1005  TcpHeader h;
1009  h.SetSourcePort (tcpHeader.GetDestinationPort ());
1010  h.SetDestinationPort (tcpHeader.GetSourcePort ());
1012  AddOptions (h);
1013  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestinationAddress (), header.GetSourceAddress (), m_boundnetdevice);
1014  }
1015  break;
1016  case SYN_SENT:
1017  ProcessSynSent (packet, tcpHeader);
1018  break;
1019  case SYN_RCVD:
1020  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
1021  break;
1022  case FIN_WAIT_1:
1023  case FIN_WAIT_2:
1024  case CLOSE_WAIT:
1025  ProcessWait (packet, tcpHeader);
1026  break;
1027  case CLOSING:
1028  ProcessClosing (packet, tcpHeader);
1029  break;
1030  case LAST_ACK:
1031  ProcessLastAck (packet, tcpHeader);
1032  break;
1033  default: // mute compiler
1034  break;
1035  }
1036 }
1037 
1040 void
1042 {
1043  NS_LOG_FUNCTION (this << tcpHeader);
1044 
1045  // Extract the flags. PSH and URG are not honoured.
1046  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1047 
1048  // Different flags are different events
1049  if (tcpflags == TcpHeader::ACK)
1050  {
1051  ReceivedAck (packet, tcpHeader);
1052  }
1053  else if (tcpflags == TcpHeader::SYN)
1054  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
1055  // respond with a SYN+ACK. But it is not a legal state transition as of
1056  // RFC793. Thus this is ignored.
1057  }
1058  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1059  { // No action for received SYN+ACK, it is probably a duplicated packet
1060  }
1061  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1062  { // Received FIN or FIN+ACK, bring down this socket nicely
1063  PeerClose (packet, tcpHeader);
1064  }
1065  else if (tcpflags == 0)
1066  { // No flags means there is only data
1067  ReceivedData (packet, tcpHeader);
1068  if (m_rxBuffer.Finished ())
1069  {
1070  PeerClose (packet, tcpHeader);
1071  }
1072  }
1073  else
1074  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1075  if (tcpflags != TcpHeader::RST)
1076  { // this must be an invalid flag, send reset
1077  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1078  SendRST ();
1079  }
1080  CloseAndNotify ();
1081  }
1082 }
1083 
1085 void
1087 {
1088  NS_LOG_FUNCTION (this << tcpHeader);
1089 
1090  // Received ACK. Compare the ACK number against highest unacked seqno
1091  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1092  { // Ignore if no ACK flag
1093  }
1094  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1095  { // Case 1: Old ACK, ignored.
1096  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1097  }
1098  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1099  { // Case 2: Potentially a duplicated ACK
1100  if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0)
1101  {
1102  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1103  DupAck (tcpHeader, ++m_dupAckCount);
1104  }
1105  // otherwise, the ACK is precisely equal to the nextTxSequence
1106  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1107  }
1108  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1109  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1110  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1111  NewAck (tcpHeader.GetAckNumber ());
1112  m_dupAckCount = 0;
1113  }
1114  // If there is any data piggybacked, store it into m_rxBuffer
1115  if (packet->GetSize () > 0)
1116  {
1117  ReceivedData (packet, tcpHeader);
1118  }
1119 }
1120 
1122 void
1124  const Address& fromAddress, const Address& toAddress)
1125 {
1126  NS_LOG_FUNCTION (this << tcpHeader);
1127 
1128  // Extract the flags. PSH and URG are not honoured.
1129  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1130 
1131  // Fork a socket if received a SYN. Do nothing otherwise.
1132  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1133  if (tcpflags != TcpHeader::SYN)
1134  {
1135  return;
1136  }
1137 
1138  // Call socket's notify function to let the server app know we got a SYN
1139  // If the server app refuses the connection, do nothing
1140  if (!NotifyConnectionRequest (fromAddress))
1141  {
1142  return;
1143  }
1144  // Clone the socket, simulate fork
1145  Ptr<TcpSocketBase> newSock = Fork ();
1146  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1148  packet, tcpHeader, fromAddress, toAddress);
1149 }
1150 
1152 void
1154 {
1155  NS_LOG_FUNCTION (this << tcpHeader);
1156 
1157  // Extract the flags. PSH and URG are not honoured.
1158  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1159 
1160  if (tcpflags == 0)
1161  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1162  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1163  m_state = ESTABLISHED;
1164  m_connected = true;
1165  m_retxEvent.Cancel ();
1167  ReceivedData (packet, tcpHeader);
1169  }
1170  else if (tcpflags == TcpHeader::ACK)
1171  { // Ignore ACK in SYN_SENT
1172  }
1173  else if (tcpflags == TcpHeader::SYN)
1174  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1175  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1176  m_state = SYN_RCVD;
1180  }
1181  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1182  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1183  { // Handshake completed
1184  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1185  m_state = ESTABLISHED;
1186  m_connected = true;
1187  m_retxEvent.Cancel ();
1194  // Always respond to first data packet to speed up the connection.
1195  // Remove to get the behaviour of old NS-3 code.
1197  }
1198  else
1199  { // Other in-sequence input
1200  if (tcpflags != TcpHeader::RST)
1201  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1202  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1203  SendRST ();
1204  }
1205  CloseAndNotify ();
1206  }
1207 }
1208 
1210 void
1212  const Address& fromAddress, const Address& toAddress)
1213 {
1214  NS_LOG_FUNCTION (this << tcpHeader);
1215 
1216  // Extract the flags. PSH and URG are not honoured.
1217  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1218 
1219  if (tcpflags == 0
1220  || (tcpflags == TcpHeader::ACK
1221  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1222  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1223  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1224  // handshake is completed nicely.
1225  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1226  m_state = ESTABLISHED;
1227  m_connected = true;
1228  m_retxEvent.Cancel ();
1231  if (m_endPoint)
1232  {
1233  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1234  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1235  }
1236  else if (m_endPoint6)
1237  {
1238  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1239  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1240  }
1241  // Always respond to first data packet to speed up the connection.
1242  // Remove to get the behaviour of old NS-3 code.
1244  ReceivedAck (packet, tcpHeader);
1245  NotifyNewConnectionCreated (this, fromAddress);
1246  // As this connection is established, the socket is available to send data now
1247  if (GetTxAvailable () > 0)
1248  {
1250  }
1251  }
1252  else if (tcpflags == TcpHeader::SYN)
1253  { // Probably the peer lost my SYN+ACK
1256  }
1257  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1258  {
1259  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1260  { // In-sequence FIN before connection complete. Set up connection and close.
1261  m_connected = true;
1262  m_retxEvent.Cancel ();
1265  if (m_endPoint)
1266  {
1267  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1268  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1269  }
1270  else if (m_endPoint6)
1271  {
1272  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1273  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1274  }
1275  PeerClose (packet, tcpHeader);
1276  }
1277  }
1278  else
1279  { // Other in-sequence input
1280  if (tcpflags != TcpHeader::RST)
1281  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1282  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1283  if (m_endPoint)
1284  {
1285  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1286  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1287  }
1288  else if (m_endPoint6)
1289  {
1290  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1291  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1292  }
1293  SendRST ();
1294  }
1295  CloseAndNotify ();
1296  }
1297 }
1298 
1300 void
1302 {
1303  NS_LOG_FUNCTION (this << tcpHeader);
1304 
1305  // Extract the flags. PSH and URG are not honoured.
1306  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1307 
1308  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1309  { // Bare data, accept it
1310  ReceivedData (packet, tcpHeader);
1311  }
1312  else if (tcpflags == TcpHeader::ACK)
1313  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1314  ReceivedAck (packet, tcpHeader);
1315  if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1316  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1317  { // This ACK corresponds to the FIN sent
1318  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1319  m_state = FIN_WAIT_2;
1320  }
1321  }
1322  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1323  { // Got FIN, respond with ACK and move to next state
1324  if (tcpflags & TcpHeader::ACK)
1325  { // Process the ACK first
1326  ReceivedAck (packet, tcpHeader);
1327  }
1329  }
1330  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1331  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1332  return;
1333  }
1334  else
1335  { // This is a RST or bad flags
1336  if (tcpflags != TcpHeader::RST)
1337  {
1338  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1339  SendRST ();
1340  }
1341  CloseAndNotify ();
1342  return;
1343  }
1344 
1345  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1346  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1347  {
1348  if (m_state == FIN_WAIT_1)
1349  {
1350  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1351  m_state = CLOSING;
1352  if (m_txBuffer.Size () == 0
1353  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1354  { // This ACK corresponds to the FIN sent
1355  TimeWait ();
1356  }
1357  }
1358  else if (m_state == FIN_WAIT_2)
1359  {
1360  TimeWait ();
1361  }
1363  if (!m_shutdownRecv)
1364  {
1365  NotifyDataRecv ();
1366  }
1367  }
1368 }
1369 
1371 void
1373 {
1374  NS_LOG_FUNCTION (this << tcpHeader);
1375 
1376  // Extract the flags. PSH and URG are not honoured.
1377  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1378 
1379  if (tcpflags == TcpHeader::ACK)
1380  {
1381  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1382  { // This ACK corresponds to the FIN sent
1383  TimeWait ();
1384  }
1385  }
1386  else
1387  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1388  // anyone. If anything other than ACK is received, respond with a reset.
1389  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1390  { // FIN from the peer as well. We can close immediately.
1392  }
1393  else if (tcpflags != TcpHeader::RST)
1394  { // Receive of SYN or SYN+ACK or bad flags or pure data
1395  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1396  SendRST ();
1397  }
1398  CloseAndNotify ();
1399  }
1400 }
1401 
1403 void
1405 {
1406  NS_LOG_FUNCTION (this << tcpHeader);
1407 
1408  // Extract the flags. PSH and URG are not honoured.
1409  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1410 
1411  if (tcpflags == 0)
1412  {
1413  ReceivedData (packet, tcpHeader);
1414  }
1415  else if (tcpflags == TcpHeader::ACK)
1416  {
1417  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1418  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1419  CloseAndNotify ();
1420  }
1421  }
1422  else if (tcpflags == TcpHeader::FIN)
1423  { // Received FIN again, the peer probably lost the FIN+ACK
1425  }
1426  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1427  {
1428  CloseAndNotify ();
1429  }
1430  else
1431  { // Received a SYN or SYN+ACK or bad flags
1432  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1433  SendRST ();
1434  CloseAndNotify ();
1435  }
1436 }
1437 
1439 void
1441 {
1442  NS_LOG_FUNCTION (this << tcpHeader);
1443 
1444  // Ignore all out of range packets
1445  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1446  || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1447  {
1448  return;
1449  }
1450  // For any case, remember the FIN position in rx buffer first
1452  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1453  // If there is any piggybacked data, process it
1454  if (p->GetSize ())
1455  {
1456  ReceivedData (p, tcpHeader);
1457  }
1458  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1459  if (!m_rxBuffer.Finished ())
1460  {
1461  return;
1462  }
1463 
1464  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1465  if (m_state == FIN_WAIT_1)
1466  {
1467  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1468  m_state = CLOSING;
1469  return;
1470  }
1471 
1472  DoPeerClose (); // Change state, respond with ACK
1473 }
1474 
1476 void
1478 {
1480 
1481  // Move the state to CLOSE_WAIT
1482  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1483  m_state = CLOSE_WAIT;
1484 
1485  if (!m_closeNotified)
1486  {
1487  // The normal behaviour for an application is that, when the peer sent a in-sequence
1488  // FIN, the app should prepare to close. The app has two choices at this point: either
1489  // respond with ShutdownSend() call to declare that it has nothing more to send and
1490  // the socket can be closed immediately; or remember the peer's close request, wait
1491  // until all its existing data are pushed into the TCP socket, then call Close()
1492  // explicitly.
1493  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1494  NotifyNormalClose ();
1495  m_closeNotified = true;
1496  }
1497  if (m_shutdownSend)
1498  { // The application declares that it would not sent any more, close this socket
1499  Close ();
1500  }
1501  else
1502  { // Need to ack, the application will close later
1504  }
1505  if (m_state == LAST_ACK)
1506  {
1507  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1508  m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
1510  }
1511 }
1512 
1515 void
1517 {
1518  NS_LOG_FUNCTION (this);
1519  m_endPoint = 0;
1520  if (m_tcp != 0)
1521  {
1522  std::vector<Ptr<TcpSocketBase> >::iterator it
1523  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1524  if (it != m_tcp->m_sockets.end ())
1525  {
1526  m_tcp->m_sockets.erase (it);
1527  }
1528  }
1529  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1530  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1531  CancelAllTimers ();
1532 }
1533 
1536 void
1538 {
1539  NS_LOG_FUNCTION (this);
1540  m_endPoint6 = 0;
1541  if (m_tcp != 0)
1542  {
1543  std::vector<Ptr<TcpSocketBase> >::iterator it
1544  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1545  if (it != m_tcp->m_sockets.end ())
1546  {
1547  m_tcp->m_sockets.erase (it);
1548  }
1549  }
1550  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1551  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1552  CancelAllTimers ();
1553 }
1554 
1556 void
1558 {
1559  NS_LOG_FUNCTION (this << (uint32_t)flags);
1560  Ptr<Packet> p = Create<Packet> ();
1561  TcpHeader header;
1563 
1564  /*
1565  * Add tags for each socket option.
1566  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1567  * if both options are set. Once the packet got to layer three, only
1568  * the corresponding tags will be read.
1569  */
1570  if (IsManualIpTos ())
1571  {
1572  SocketIpTosTag ipTosTag;
1573  ipTosTag.SetTos (GetIpTos ());
1574  p->AddPacketTag (ipTosTag);
1575  }
1576 
1577  if (IsManualIpv6Tclass ())
1578  {
1579  SocketIpv6TclassTag ipTclassTag;
1580  ipTclassTag.SetTclass (GetIpv6Tclass ());
1581  p->AddPacketTag (ipTclassTag);
1582  }
1583 
1584  if (IsManualIpTtl ())
1585  {
1586  SocketIpTtlTag ipTtlTag;
1587  ipTtlTag.SetTtl (GetIpTtl ());
1588  p->AddPacketTag (ipTtlTag);
1589  }
1590 
1591  if (IsManualIpv6HopLimit ())
1592  {
1593  SocketIpv6HopLimitTag ipHopLimitTag;
1594  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1595  p->AddPacketTag (ipHopLimitTag);
1596  }
1597 
1598  if (m_endPoint == 0 && m_endPoint6 == 0)
1599  {
1600  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1601  return;
1602  }
1603  if (flags & TcpHeader::FIN)
1604  {
1605  flags |= TcpHeader::ACK;
1606  }
1607  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1608  {
1609  ++s;
1610  }
1611 
1612  header.SetFlags (flags);
1613  header.SetSequenceNumber (s);
1614  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1615  if (m_endPoint != 0)
1616  {
1617  header.SetSourcePort (m_endPoint->GetLocalPort ());
1618  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1619  }
1620  else
1621  {
1622  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1623  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1624  }
1625  header.SetWindowSize (AdvertisedWindowSize ());
1626  AddOptions (header);
1627  m_rto = m_rtt->RetransmitTimeout ();
1628  bool hasSyn = flags & TcpHeader::SYN;
1629  bool hasFin = flags & TcpHeader::FIN;
1630  bool isAck = flags == TcpHeader::ACK;
1631  if (hasSyn)
1632  {
1633  if (m_cnCount == 0)
1634  { // No more connection retries, give up
1635  NS_LOG_LOGIC ("Connection failed.");
1636  CloseAndNotify ();
1637  return;
1638  }
1639  else
1640  { // Exponential backoff of connection time out
1641  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1642  m_rto = m_cnTimeout * backoffCount;
1643  m_cnCount--;
1644  }
1645  }
1646  if (m_endPoint != 0)
1647  {
1648  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1650  }
1651  else
1652  {
1653  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1655  }
1656  if (flags & TcpHeader::ACK)
1657  { // If sending an ACK, cancel the delay ACK as well
1658  m_delAckEvent.Cancel ();
1659  m_delAckCount = 0;
1660  }
1661  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1662  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1663  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1664  << Simulator::Now ().GetSeconds () << " to expire at time "
1665  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1667  }
1668 }
1669 
1671 void
1673 {
1674  NS_LOG_FUNCTION (this);
1676  NotifyErrorClose ();
1677  DeallocateEndPoint ();
1678 }
1679 
1681 void
1683 {
1684  if (m_endPoint != 0)
1685  {
1686  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1687  m_tcp->DeAllocate (m_endPoint);
1688  m_endPoint = 0;
1689  std::vector<Ptr<TcpSocketBase> >::iterator it
1690  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1691  if (it != m_tcp->m_sockets.end ())
1692  {
1693  m_tcp->m_sockets.erase (it);
1694  }
1695  CancelAllTimers ();
1696  }
1697  if (m_endPoint6 != 0)
1698  {
1699  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1700  m_tcp->DeAllocate (m_endPoint6);
1701  m_endPoint6 = 0;
1702  std::vector<Ptr<TcpSocketBase> >::iterator it
1703  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1704  if (it != m_tcp->m_sockets.end ())
1705  {
1706  m_tcp->m_sockets.erase (it);
1707  }
1708  CancelAllTimers ();
1709  }
1710 }
1711 
1713 int
1715 {
1716  NS_LOG_FUNCTION (this);
1717  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1718  NS_ASSERT (ipv4 != 0);
1719  if (ipv4->GetRoutingProtocol () == 0)
1720  {
1721  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1722  }
1723  // Create a dummy packet, then ask the routing function for the best output
1724  // interface's address
1725  Ipv4Header header;
1727  Socket::SocketErrno errno_;
1728  Ptr<Ipv4Route> route;
1730  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1731  if (route == 0)
1732  {
1733  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1734  NS_LOG_ERROR (errno_);
1735  m_errno = errno_;
1736  return -1;
1737  }
1738  NS_LOG_LOGIC ("Route exists");
1739  m_endPoint->SetLocalAddress (route->GetSource ());
1740  return 0;
1741 }
1742 
1743 int
1745 {
1746  NS_LOG_FUNCTION (this);
1748  NS_ASSERT (ipv6 != 0);
1749  if (ipv6->GetRoutingProtocol () == 0)
1750  {
1751  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1752  }
1753  // Create a dummy packet, then ask the routing function for the best output
1754  // interface's address
1755  Ipv6Header header;
1757  Socket::SocketErrno errno_;
1758  Ptr<Ipv6Route> route;
1760  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1761  if (route == 0)
1762  {
1763  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1764  NS_LOG_ERROR (errno_);
1765  m_errno = errno_;
1766  return -1;
1767  }
1768  NS_LOG_LOGIC ("Route exists");
1769  m_endPoint6->SetLocalAddress (route->GetSource ());
1770  return 0;
1771 }
1772 
1776 void
1778  const Address& fromAddress, const Address& toAddress)
1779 {
1780  // Get port and address from peer (connecting host)
1781  if (InetSocketAddress::IsMatchingType (toAddress))
1782  {
1783  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1784  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1785  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1786  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1787  m_endPoint6 = 0;
1788  }
1789  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1790  {
1791  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1792  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1793  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1794  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1795  m_endPoint = 0;
1796  }
1797  m_tcp->m_sockets.push_back (this);
1798 
1799  // Change the cloned socket from LISTEN state to SYN_RCVD
1800  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1801  m_state = SYN_RCVD;
1803  SetupCallback ();
1804  // Set the sequence number and send SYN+ACK
1807 }
1808 
1809 void
1811 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1812  // be called as a scheduled event
1814  // The if-block below was moved from ProcessSynSent() to here because we need
1815  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1816  // reflect the behaviour in the real world.
1817  if (GetTxAvailable () > 0)
1818  {
1820  }
1821 }
1822 
1825 uint32_t
1826 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1827 {
1828  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1829 
1830  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
1831  uint32_t sz = p->GetSize (); // Size of packet
1832  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1833  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
1834 
1835  /*
1836  * Add tags for each socket option.
1837  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1838  * if both options are set. Once the packet got to layer three, only
1839  * the corresponding tags will be read.
1840  */
1841  if (IsManualIpTos ())
1842  {
1843  SocketIpTosTag ipTosTag;
1844  ipTosTag.SetTos (GetIpTos ());
1845  p->AddPacketTag (ipTosTag);
1846  }
1847 
1848  if (IsManualIpv6Tclass ())
1849  {
1850  SocketIpv6TclassTag ipTclassTag;
1851  ipTclassTag.SetTclass (GetIpv6Tclass ());
1852  p->AddPacketTag (ipTclassTag);
1853  }
1854 
1855  if (IsManualIpTtl ())
1856  {
1857  SocketIpTtlTag ipTtlTag;
1858  ipTtlTag.SetTtl (GetIpTtl ());
1859  p->AddPacketTag (ipTtlTag);
1860  }
1861 
1862  if (IsManualIpv6HopLimit ())
1863  {
1864  SocketIpv6HopLimitTag ipHopLimitTag;
1865  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1866  p->AddPacketTag (ipHopLimitTag);
1867  }
1868 
1869  if (m_closeOnEmpty && (remainingData == 0))
1870  {
1871  flags |= TcpHeader::FIN;
1872  if (m_state == ESTABLISHED)
1873  { // On active close: I am the first one to send FIN
1874  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1875  m_state = FIN_WAIT_1;
1876  }
1877  else if (m_state == CLOSE_WAIT)
1878  { // On passive close: Peer sent me FIN already
1879  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1880  m_state = LAST_ACK;
1881  }
1882  }
1883  TcpHeader header;
1884  header.SetFlags (flags);
1885  header.SetSequenceNumber (seq);
1887  if (m_endPoint)
1888  {
1889  header.SetSourcePort (m_endPoint->GetLocalPort ());
1891  }
1892  else
1893  {
1894  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1896  }
1897  header.SetWindowSize (AdvertisedWindowSize ());
1898  AddOptions (header);
1899  if (m_retxEvent.IsExpired () )
1900  { // Schedule retransmit
1901  m_rto = m_rtt->RetransmitTimeout ();
1902  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
1903  Simulator::Now ().GetSeconds () << " to expire at time " <<
1904  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
1906  }
1907  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1908  if (m_endPoint)
1909  {
1910  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1912  }
1913  else
1914  {
1915  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1917  }
1918  m_rtt->SentSeq (seq, sz); // notify the RTT
1919  // Notify the application of the data being sent unless this is a retransmit
1920  if (seq == m_nextTxSequence)
1921  {
1923  }
1924  // Update highTxMark
1925  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1926  return sz;
1927 }
1928 
1932 bool
1934 {
1935  NS_LOG_FUNCTION (this << withAck);
1936  if (m_txBuffer.Size () == 0)
1937  {
1938  return false; // Nothing to send
1939 
1940  }
1941  if (m_endPoint == 0 && m_endPoint6 == 0)
1942  {
1943  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
1944  return false; // Is this the right way to handle this condition?
1945  }
1946  uint32_t nPacketsSent = 0;
1948  {
1949  uint32_t w = AvailableWindow (); // Get available window size
1950  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
1951  " w " << w <<
1952  " rxwin " << m_rWnd <<
1953  " segsize " << m_segmentSize <<
1954  " nextTxSeq " << m_nextTxSequence <<
1955  " highestRxAck " << m_txBuffer.HeadSequence () <<
1956  " pd->Size " << m_txBuffer.Size () <<
1957  " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
1958  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
1960  {
1961  break; // No more
1962  }
1963  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
1964  // in the buffer and the amount of data to send is less than one segment
1965  if (!m_noDelay && UnAckDataCount () > 0
1967  {
1968  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
1969  break;
1970  }
1971  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
1972  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
1973  nPacketsSent++; // Count sent this loop
1974  m_nextTxSequence += sz; // Advance next tx sequence
1975  }
1976  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
1977  return (nPacketsSent > 0);
1978 }
1979 
1980 uint32_t
1982 {
1983  NS_LOG_FUNCTION (this);
1985 }
1986 
1987 uint32_t
1989 {
1990  NS_LOG_FUNCTION (this);
1991  return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
1992 }
1993 
1994 uint32_t
1996 {
1997  NS_LOG_FUNCTION (this);
1998  return m_rWnd;
1999 }
2000 
2001 uint32_t
2003 {
2005  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
2006  uint32_t win = Window (); // Number of bytes allowed to be outstanding
2007  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
2008  return (win < unack) ? 0 : (win - unack);
2009 }
2010 
2011 uint16_t
2013 {
2014  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
2015 }
2016 
2017 // Receipt of new packet, put into Rx buffer
2018 void
2020 {
2021  NS_LOG_FUNCTION (this << tcpHeader);
2022  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
2023  " ack " << tcpHeader.GetAckNumber () <<
2024  " pkt size " << p->GetSize () );
2025 
2026  // Put into Rx buffer
2027  SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
2028  if (!m_rxBuffer.Add (p, tcpHeader))
2029  { // Insert failed: No data or RX buffer full
2031  return;
2032  }
2033  // Now send a new ACK packet acknowledging all received and delivered data
2034  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
2035  { // A gap exists in the buffer, or we filled a gap: Always ACK
2037  }
2038  else
2039  { // In-sequence packet: ACK if delayed ack count allows
2041  {
2042  m_delAckEvent.Cancel ();
2043  m_delAckCount = 0;
2045  }
2046  else if (m_delAckEvent.IsExpired ())
2047  {
2050  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
2051  }
2052  }
2053  // Notify app to receive if necessary
2054  if (expectedSeq < m_rxBuffer.NextRxSequence ())
2055  { // NextRxSeq advanced, we have something to send to the app
2056  if (!m_shutdownRecv)
2057  {
2058  NotifyDataRecv ();
2059  }
2060  // Handle exceptions
2061  if (m_closeNotified)
2062  {
2063  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
2064  }
2065  // If we received FIN before and now completed all "holes" in rx buffer,
2066  // invoke peer close procedure
2067  if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2068  {
2069  DoPeerClose ();
2070  }
2071  }
2072 }
2073 
2075 void
2077 {
2078  // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
2079  // (which should be ignored) is handled by m_rtt. Once timestamp option
2080  // is implemented, this function would be more elaborated.
2081  Time nextRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
2082 
2083  //nextRtt will be zero for dup acks. Don't want to update lastRtt in that case
2084  //but still needed to do list clearing that is done in AckSeq.
2085  if(nextRtt != 0)
2086  {
2087  m_lastRtt = nextRtt;
2088  NS_LOG_FUNCTION(this << m_lastRtt);
2089  }
2090 
2091 }
2092 
2093 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
2094 // when the three-way handshake completed. This cancels retransmission timer
2095 // and advances Tx window
2096 void
2098 {
2099  NS_LOG_FUNCTION (this << ack);
2100 
2101  if (m_state != SYN_RCVD)
2102  { // Set RTO unless the ACK is received in SYN_RCVD state
2103  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2104  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2105  m_retxEvent.Cancel ();
2106  // On recieving a "New" ack we restart retransmission timer .. RFC 2988
2107  m_rto = m_rtt->RetransmitTimeout ();
2108  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
2109  Simulator::Now ().GetSeconds () << " to expire at time " <<
2110  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2112  }
2113  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
2114  { // Zero window: Enter persist state to send 1 byte to probe
2115  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
2116  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
2117  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2118  m_retxEvent.Cancel ();
2119  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
2120  Simulator::Now ().GetSeconds () << " to expire at time " <<
2121  (Simulator::Now () + m_persistTimeout).GetSeconds ());
2124  }
2125  // Note the highest ACK and tell app to send more
2126  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2127  " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
2128  m_txBuffer.DiscardUpTo (ack);
2129  if (GetTxAvailable () > 0)
2130  {
2132  }
2133  if (ack > m_nextTxSequence)
2134  {
2135  m_nextTxSequence = ack; // If advanced
2136  }
2137  if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2138  { // No retransmit timer if no data to retransmit
2139  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2140  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2141  m_retxEvent.Cancel ();
2142  }
2143  // Try to send more data
2145 }
2146 
2147 // Retransmit timeout
2148 void
2150 {
2151  NS_LOG_FUNCTION (this);
2152  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2153  // If erroneous timeout in closed/timed-wait state, just return
2154  if (m_state == CLOSED || m_state == TIME_WAIT)
2155  {
2156  return;
2157  }
2158  // If all data are received (non-closing socket and nothing to send), just return
2160  {
2161  return;
2162  }
2163 
2164  Retransmit ();
2165 }
2166 
2167 void
2169 {
2170  m_delAckCount = 0;
2172 }
2173 
2174 void
2176 {
2177  NS_LOG_FUNCTION (this);
2178 
2180  if (m_state == LAST_ACK)
2181  {
2182  CloseAndNotify ();
2183  }
2184  if (!m_closeNotified)
2185  {
2186  m_closeNotified = true;
2187  }
2188 }
2189 
2190 // Send 1-byte data to probe for the window size at the receiver when
2191 // the local knowledge tells that the receiver has zero window size
2192 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2193 void
2195 {
2196  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2197  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2199  TcpHeader tcpHeader;
2200  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2201  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2202  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2203  if (m_endPoint != 0)
2204  {
2205  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2206  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2207  }
2208  else
2209  {
2210  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2211  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2212  }
2213  AddOptions (tcpHeader);
2214 
2215  if (m_endPoint != 0)
2216  {
2217  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2219  }
2220  else
2221  {
2222  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2224  }
2225  NS_LOG_LOGIC ("Schedule persist timeout at time "
2226  << Simulator::Now ().GetSeconds () << " to expire at time "
2227  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2229 }
2230 
2231 void
2233 {
2234  m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
2235  m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
2236  m_dupAckCount = 0;
2237  DoRetransmit (); // Retransmit the packet
2238 }
2239 
2240 void
2242 {
2243  NS_LOG_FUNCTION (this);
2244  // Retransmit SYN packet
2245  if (m_state == SYN_SENT)
2246  {
2247  if (m_cnCount > 0)
2248  {
2250  }
2251  else
2252  {
2254  }
2255  return;
2256  }
2257  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2258  if (m_txBuffer.Size () == 0)
2259  {
2260  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2261  { // Must have lost FIN, re-send
2263  }
2264  return;
2265  }
2266  // Retransmit a data packet: Call SendDataPacket
2267  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
2268  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
2269  // In case of RTO, advance m_nextTxSequence
2270  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
2271 
2272 }
2273 
2274 void
2276 {
2277  m_retxEvent.Cancel ();
2279  m_delAckEvent.Cancel ();
2282 }
2283 
2285 void
2287 {
2288  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2289  m_state = TIME_WAIT;
2290  CancelAllTimers ();
2291  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2292  // according to RFC793, p.28
2293  m_timewaitEvent = Simulator::Schedule (Seconds (2 * m_msl),
2295 }
2296 
2299 void
2301 {
2303 }
2304 
2305 uint32_t
2307 {
2308  return m_txBuffer.MaxBufferSize ();
2309 }
2310 
2311 void
2313 {
2315 }
2316 
2317 uint32_t
2319 {
2320  return m_rxBuffer.MaxBufferSize ();
2321 }
2322 
2323 void
2325 {
2326  m_segmentSize = size;
2327  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2328 }
2329 
2330 uint32_t
2332 {
2333  return m_segmentSize;
2334 }
2335 
2336 void
2338 {
2339  m_cnTimeout = timeout;
2340 }
2341 
2342 Time
2344 {
2345  return m_cnTimeout;
2346 }
2347 
2348 void
2350 {
2351  m_cnRetries = count;
2352 }
2353 
2354 uint32_t
2356 {
2357  return m_cnRetries;
2358 }
2359 
2360 void
2362 {
2364 }
2365 
2366 Time
2368 {
2369  return m_delAckTimeout;
2370 }
2371 
2372 void
2374 {
2375  m_delAckMaxCount = count;
2376 }
2377 
2378 uint32_t
2380 {
2381  return m_delAckMaxCount;
2382 }
2383 
2384 void
2386 {
2387  m_noDelay = noDelay;
2388 }
2389 
2390 bool
2392 {
2393  return m_noDelay;
2394 }
2395 
2396 void
2398 {
2400 }
2401 
2402 Time
2404 {
2405  return m_persistTimeout;
2406 }
2407 
2408 bool
2410 {
2411  // Broadcast is not implemented. Return true only if allowBroadcast==false
2412  return (!allowBroadcast);
2413 }
2414 
2415 bool
2417 {
2418  return false;
2419 }
2420 
2422 void
2424 {
2425 }
2426 
2428 void
2430 {
2431 }
2432 
2433 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Definition: simulator.cc:189
Ipv6Address GetLocalAddress()
Get the local address.
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:268
void SetTclass(uint8_t tclass)
Definition: socket.cc:816
virtual void DupAck(const TcpHeader &t, uint32_t count)=0
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
virtual int Listen(void)
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
bool IsManualIpTtl(void) const
Definition: socket.cc:382
Packet header for IPv6.
Definition: ipv6-header.h:33
an Inet address class
virtual int GetSockName(Address &address) const
Ipv4Address GetIpv4(void) const
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:297
static Ipv4Address GetAny(void)
uint32_t Size(void) const
virtual void EstimateRtt(const TcpHeader &)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
SequenceNumber32 GetSequenceNumber() const
Definition: tcp-header.cc:96
virtual void ReceivedAck(Ptr< Packet >, const TcpHeader &)
virtual uint8_t GetIpTtl(void) const
Definition: socket.cc:470
virtual uint16_t AdvertisedWindowSize(void)
Callback template class.
Definition: callback.h:920
bool Add(Ptr< Packet > p, TcpHeader const &tcph)
NS_LOG_COMPONENT_DEFINE("TcpSocketBase")
virtual uint32_t GetSegSize(void) const
uint8_t GetIpTos(void) const
Definition: socket.cc:403
uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck)
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:891
void DiscardUpTo(const SequenceNumber32 &seq)
(abstract) base class of all TcpSockets
Definition: tcp-socket.h:62
Ipv4EndPoint * m_endPoint
uint8_t GetFlags() const
Definition: tcp-header.cc:108
virtual ~TcpSocketBase(void)
TracedValue< Time > m_lastRtt
void NotifyDataRecv(void)
Definition: socket.cc:304
virtual int ShutdownRecv(void)
uint32_t SizeFromSequence(const SequenceNumber32 &seq) const
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
void ProcessClosing(Ptr< Packet >, const TcpHeader &)
SequenceNumber32 HeadSequence(void) const
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
IPv6 layer implementation.
void SetDestroyCallback(Callback< void > callback)
SequenceNumber32 GetAckNumber() const
Definition: tcp-header.cc:100
void PeerClose(Ptr< Packet >, const TcpHeader &)
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:841
void SetAddress(Address addr)
Definition: socket.cc:522
virtual void SetPersistTimeout(Time timeout)
virtual int Send(Ptr< Packet > p, uint32_t flags)
virtual bool GetAllowBroadcast(void) const
Query whether broadcast datagram transmissions are allowed.
void NotifyConnectionFailed(void)
Definition: socket.cc:226
static TypeId GetTypeId(void)
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
uint32_t Available() const
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t MaxBufferSize(void) const
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
virtual void AddOptions(TcpHeader &)
uint32_t GetSize(void) const
Definition: packet.h:650
bool IsManualIpTos(void) const
Definition: socket.cc:370
Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback
virtual void ReceivedData(Ptr< Packet >, const TcpHeader &)
void BindToNetDevice(Ptr< NetDevice > netdevice)
#define NS_LOG_INFO(msg)
Definition: log.h:264
virtual uint8_t GetIpv6HopLimit(void) const
Definition: socket.cc:495
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
void ConnectionSucceeded(void)
void SetFinSequence(const SequenceNumber32 &s)
void SetTos(uint8_t tos)
Definition: socket.cc:760
TracedValue< SequenceNumber32 > m_nextTxSequence
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:824
ns3::Time timeout
void CompleteFork(Ptr< Packet >, const TcpHeader &, const Address &fromAddress, const Address &toAdress)
T Get(void) const
Definition: traced-value.h:97
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:869
virtual Time GetPersistTimeout(void) const
bool NotifyConnectionRequest(const Address &from)
Definition: socket.cc:256
SequenceNumber32 NextRxSequence(void) const
virtual void PersistTimeout(void)
TracedValue< TcpStates_t > m_state
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if cond is false.
Definition: abort.h:131
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:86
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
uint16_t GetPeerPort()
Get the peer port.
virtual uint32_t GetRcvBufSize(void) const
virtual bool GetTcpNoDelay(void) const
void ForwardIcmp6(Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
virtual int Bind(void)
SequenceNumber< uint32_t, int32_t > SequenceNumber32
SequenceNumber32 MaxRxSequence(void) const
TcpTxBuffer m_txBuffer
virtual void Retransmit(void)
Packet header for IPv4.
Definition: ipv4-header.h:31
void SetLocalAddress(Ipv6Address addr)
Set the local address.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Definition: tcp-header.cc:63
virtual uint32_t UnAckDataCount(void)
void ForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
static const char *const TcpStateName[LAST_STATE]
Definition: tcp-socket.h:71
void SetTtl(uint8_t ttl)
Definition: socket.cc:582
virtual uint32_t GetSndBufSize(void) const
virtual enum SocketType GetSocketType(void) const
uint16_t GetLocalPort()
Get the local port.
Hold an unsigned integer type.
Definition: uinteger.h:46
Ipv6EndPoint * m_endPoint6
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Ptr< SampleEmitter > s
bool OutOfRange(SequenceNumber32 head, SequenceNumber32 tail) const
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
Ipv4Address GetLocalAddress(void)
An Inet6 address class.
virtual void SetTcpNoDelay(bool noDelay)
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:847
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
bool IsManualIpv6Tclass(void) const
Definition: socket.cc:376
void NotifyDataSent(uint32_t size)
Definition: socket.cc:284
virtual uint32_t GetConnCount(void) const
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
enum SocketErrno m_errno
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
void SetNextRxSequence(const SequenceNumber32 &s)
A base class for implementation of a stream socket using TCP.
Ptr< RttEstimator > m_rtt
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
virtual void SetTcp(Ptr< TcpL4Protocol > tcp)
Ptr< TcpL4Protocol > m_tcp
void SetHopLimit(uint8_t hopLimit)
Definition: socket.cc:642
void SetMaxBufferSize(uint32_t n)
virtual int ShutdownSend(void)
void SetDestinationPort(uint16_t port)
Definition: tcp-header.cc:59
void NotifyConnectionSucceeded(void)
Definition: socket.cc:216
uint32_t Available(void) const
void SetFlags(uint8_t flags)
Definition: tcp-header.cc:75
void ProcessListen(Ptr< Packet >, const TcpHeader &, const Address &, const Address &)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
void SetMaxBufferSize(uint32_t s)
bool IsManualIpv6HopLimit(void) const
Definition: socket.cc:388
virtual void SetDelAckMaxCount(uint32_t count)
void NotifyNormalClose(void)
Definition: socket.cc:236
Ptr< Packet > Extract(uint32_t maxSize)
static InetSocketAddress ConvertFrom(const Address &address)
void NotifyNewConnectionCreated(Ptr< Socket > socket, const Address &from)
Definition: socket.cc:274
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void ProcessEstablished(Ptr< Packet >, const TcpHeader &)
Header for the Transmission Control Protocol.
Definition: tcp-header.h:43
virtual void SetNode(Ptr< Node > node)
void SetIcmpCallback(Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
void SetSourcePort(uint16_t port)
Definition: tcp-header.cc:55
virtual uint32_t BytesInFlight(void)
uint8_t GetIpv6Tclass(void) const
Definition: socket.cc:445
bool Add(Ptr< Packet > p)
virtual int Connect(const Address &address)
void ProcessSynRcvd(Ptr< Packet >, const TcpHeader &, const Address &, const Address &)
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:985
virtual int Close(void)
static Ipv4Address GetZero(void)
void SetPeer(Ipv4Address address, uint16_t port)
static Time Now(void)
Definition: simulator.cc:180
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t > callback)
Set the reception callback.
virtual uint32_t AvailableWindow(void)
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
Definition: socket.cc:120
virtual Ptr< TcpSocketBase > Fork(void)=0
virtual void SetRtt(Ptr< RttEstimator > rtt)
virtual void ReTxTimeout(void)
TracedValue< SequenceNumber32 > m_highTxMark
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
void SendEmptyPacket(uint8_t flags)
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call) ...
Definition: socket.cc:113
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
void SetLocalAddress(Ipv4Address address)
virtual void SetSndBufSize(uint32_t size)
virtual void SetDelAckTimeout(Time timeout)
virtual void NewAck(SequenceNumber32 const &seq)
void DeallocateEndPoint(void)
TcpRxBuffer m_rxBuffer
Describes an IPv6 address.
Definition: ipv6-address.h:46
uint32_t MaxBufferSize(void) const
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Ptr< NetDevice > m_boundnetdevice
Definition: socket.h:810
TracedValue< Time > m_rto
uint16_t GetLocalPort(void)
#define NS_LOG_WARN(msg)
Definition: log.h:246
void SetAckNumber(SequenceNumber32 ackNumber)
Definition: tcp-header.cc:67
Ipv6Address GetPeerAddress()
Get the peer address.
virtual void SetConnCount(uint32_t count)
void ForwardUp6(Ptr< Packet > packet, Ipv6Header header, uint16_t port)
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Ipv4Address GetPeerAddress(void)
static bool IsMatchingType(const Address &addr)
If the address match.
uint16_t GetPeerPort(void)
uint16_t GetPort(void) const
Get the port.
void Cancel(void)
Definition: event-id.cc:47
virtual uint32_t Window(void)
void ProcessSynSent(Ptr< Packet >, const TcpHeader &)
virtual enum SocketErrno GetErrno(void) const
void ProcessWait(Ptr< Packet >, const TcpHeader &)
virtual void ReadOptions(const TcpHeader &)
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
virtual void SetSegSize(uint32_t size)
#define NS_LOG_ERROR(msg)
Definition: log.h:237
uint16_t GetPort(void) const
void ProcessLastAck(Ptr< Packet >, const TcpHeader &)
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:83
Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback6
tuple address
Definition: first.py:37
virtual Ptr< Node > GetNode(void) const
virtual void SetRcvBufSize(uint32_t size)
virtual Time GetDelAckTimeout(void) const
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
virtual void DelAckTimeout(void)
virtual void LastAckTimeout(void)
uint32_t Size(void) const
void SetWindowSize(uint16_t windowSize)
Definition: tcp-header.cc:79
Hold an floating point type.
Definition: double.h:41
virtual void DoForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
bool IsExpired(void) const
Definition: event-id.cc:53
Ptr< T > GetObject(void) const
Definition: object.h:360
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
a unique identifier for an interface.
Definition: type-id.h:49
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
void NotifySend(uint32_t spaceAvailable)
Definition: socket.cc:294
bool IsIpv4MappedAddress()
If the address is an IPv4-mapped address.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
bool SendPendingData(bool withAck=false)
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
TracedValue< uint32_t > m_rWnd
static bool IsMatchingType(const Address &address)
void NotifyErrorClose(void)
Definition: socket.cc:246
virtual void DoRetransmit(void)
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
virtual uint32_t GetDelAckMaxCount(void) const
virtual void SetConnTimeout(Time timeout)
void SetPeer(Ipv6Address addr, uint16_t port)
Set the peer informations (address and port).
virtual Time GetConnTimeout(void) const
bool Finished(void)
void SetHeadSequence(const SequenceNumber32 &seq)
virtual uint32_t GetTxAvailable(void) const
virtual uint32_t GetRxAvailable(void) const
Ptr< Packet > CopyFromSequence(uint32_t numBytes, const SequenceNumber32 &seq)