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  .AddTraceSource ("RTO",
79  "Retransmission timeout",
81  .AddTraceSource ("RTT",
82  "Last RTT sample",
84  .AddTraceSource ("NextTxSequence",
85  "Next sequence number to send (SND.NXT)",
87  .AddTraceSource ("HighestSequence",
88  "Highest sequence number ever sent in socket's life time",
90  .AddTraceSource ("State",
91  "TCP state",
93  .AddTraceSource ("RWND",
94  "Remote side's flow control window",
96  ;
97  return tid;
98 }
99 
101  : m_dupAckCount (0),
102  m_delAckCount (0),
103  m_endPoint (0),
104  m_endPoint6 (0),
105  m_node (0),
106  m_tcp (0),
107  m_rtt (0),
108  m_nextTxSequence (0),
109  // Change this for non-zero initial sequence number
110  m_highTxMark (0),
111  m_rxBuffer (0),
112  m_txBuffer (0),
113  m_state (CLOSED),
114  m_errno (ERROR_NOTERROR),
115  m_closeNotified (false),
116  m_closeOnEmpty (false),
117  m_shutdownSend (false),
118  m_shutdownRecv (false),
119  m_connected (false),
120  m_segmentSize (0),
121  // For attribute initialization consistency (quiet valgrind)
122  m_rWnd (0)
123 {
124  NS_LOG_FUNCTION (this);
125 }
126 
128  : TcpSocket (sock),
129  //copy object::m_tid and socket::callbacks
130  m_dupAckCount (sock.m_dupAckCount),
131  m_delAckCount (0),
132  m_delAckMaxCount (sock.m_delAckMaxCount),
133  m_noDelay (sock.m_noDelay),
134  m_cnRetries (sock.m_cnRetries),
135  m_delAckTimeout (sock.m_delAckTimeout),
136  m_persistTimeout (sock.m_persistTimeout),
137  m_cnTimeout (sock.m_cnTimeout),
138  m_endPoint (0),
139  m_endPoint6 (0),
140  m_node (sock.m_node),
141  m_tcp (sock.m_tcp),
142  m_rtt (0),
143  m_nextTxSequence (sock.m_nextTxSequence),
144  m_highTxMark (sock.m_highTxMark),
145  m_rxBuffer (sock.m_rxBuffer),
146  m_txBuffer (sock.m_txBuffer),
147  m_state (sock.m_state),
148  m_errno (sock.m_errno),
149  m_closeNotified (sock.m_closeNotified),
150  m_closeOnEmpty (sock.m_closeOnEmpty),
151  m_shutdownSend (sock.m_shutdownSend),
152  m_shutdownRecv (sock.m_shutdownRecv),
153  m_connected (sock.m_connected),
154  m_msl (sock.m_msl),
155  m_segmentSize (sock.m_segmentSize),
156  m_maxWinSize (sock.m_maxWinSize),
157  m_rWnd (sock.m_rWnd)
158 {
159  NS_LOG_FUNCTION (this);
160  NS_LOG_LOGIC ("Invoked the copy constructor");
161  // Copy the rtt estimator if it is set
162  if (sock.m_rtt)
163  {
164  m_rtt = sock.m_rtt->Copy ();
165  }
166  // Reset all callbacks to null
167  Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
168  Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
169  Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
170  SetConnectCallback (vPS, vPS);
171  SetDataSentCallback (vPSUI);
172  SetSendCallback (vPSUI);
173  SetRecvCallback (vPS);
174 }
175 
177 {
178  NS_LOG_FUNCTION (this);
179  m_node = 0;
180  if (m_endPoint != 0)
181  {
182  NS_ASSERT (m_tcp != 0);
183  /*
184  * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
185  * DestroyCallback is set to TcpSocketBase::Destroy. If we called
186  * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
187  * which in turn destroys my m_endPoint, and in turn invokes
188  * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
189  */
190  NS_ASSERT (m_endPoint != 0);
192  NS_ASSERT (m_endPoint == 0);
193  }
194  if (m_endPoint6 != 0)
195  {
196  NS_ASSERT (m_tcp != 0);
197  NS_ASSERT (m_endPoint6 != 0);
199  NS_ASSERT (m_endPoint6 == 0);
200  }
201  m_tcp = 0;
202  CancelAllTimers ();
203 }
204 
206 void
208 {
209  m_node = node;
210 }
211 
213 void
215 {
216  m_tcp = tcp;
217 }
218 
220 void
222 {
223  m_rtt = rtt;
224 }
225 
229 {
230  return m_errno;
231 }
232 
236 {
237  return NS3_SOCK_STREAM;
238 }
239 
241 Ptr<Node>
243 {
245  return m_node;
246 }
247 
249 int
251 {
252  NS_LOG_FUNCTION (this);
253  m_endPoint = m_tcp->Allocate ();
254  if (0 == m_endPoint)
255  {
257  return -1;
258  }
259  m_tcp->m_sockets.push_back (this);
260  return SetupCallback ();
261 }
262 
263 int
265 {
266  NS_LOG_FUNCTION (this);
268  if (0 == m_endPoint6)
269  {
271  return -1;
272  }
273  m_tcp->m_sockets.push_back (this);
274  return SetupCallback ();
275 }
276 
278 int
279 TcpSocketBase::Bind (const Address &address)
280 {
281  NS_LOG_FUNCTION (this << address);
282  if (InetSocketAddress::IsMatchingType (address))
283  {
285  Ipv4Address ipv4 = transport.GetIpv4 ();
286  uint16_t port = transport.GetPort ();
287  if (ipv4 == Ipv4Address::GetAny () && port == 0)
288  {
289  m_endPoint = m_tcp->Allocate ();
290  }
291  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
292  {
293  m_endPoint = m_tcp->Allocate (port);
294  }
295  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
296  {
297  m_endPoint = m_tcp->Allocate (ipv4);
298  }
299  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
300  {
301  m_endPoint = m_tcp->Allocate (ipv4, port);
302  }
303  if (0 == m_endPoint)
304  {
306  return -1;
307  }
308  }
309  else if (Inet6SocketAddress::IsMatchingType (address))
310  {
312  Ipv6Address ipv6 = transport.GetIpv6 ();
313  uint16_t port = transport.GetPort ();
314  if (ipv6 == Ipv6Address::GetAny () && port == 0)
315  {
317  }
318  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
319  {
320  m_endPoint6 = m_tcp->Allocate6 (port);
321  }
322  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
323  {
324  m_endPoint6 = m_tcp->Allocate6 (ipv6);
325  }
326  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
327  {
328  m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
329  }
330  if (0 == m_endPoint6)
331  {
333  return -1;
334  }
335  }
336  else
337  {
339  return -1;
340  }
341  m_tcp->m_sockets.push_back (this);
342  NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
343 
344  return SetupCallback ();
345 }
346 
348 int
350 {
351  NS_LOG_FUNCTION (this << address);
352 
353  // If haven't do so, Bind() this socket first
354  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
355  {
356  if (m_endPoint == 0)
357  {
358  if (Bind () == -1)
359  {
360  NS_ASSERT (m_endPoint == 0);
361  return -1; // Bind() failed
362  }
363  NS_ASSERT (m_endPoint != 0);
364  }
366  m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
367  m_endPoint6 = 0;
368 
369  // Get the appropriate local address and port number from the routing protocol and set up endpoint
370  if (SetupEndpoint () != 0)
371  { // Route to destination does not exist
372  return -1;
373  }
374  }
375  else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
376  {
377  // If we are operating on a v4-mapped address, translate the address to
378  // a v4 address and re-call this function
380  Ipv6Address v6Addr = transport.GetIpv6 ();
381  if (v6Addr.IsIpv4MappedAddress () == true)
382  {
383  Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
384  return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
385  }
386 
387  if (m_endPoint6 == 0)
388  {
389  if (Bind6 () == -1)
390  {
391  NS_ASSERT (m_endPoint6 == 0);
392  return -1; // Bind() failed
393  }
394  NS_ASSERT (m_endPoint6 != 0);
395  }
396  m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
397  m_endPoint = 0;
398 
399  // Get the appropriate local address and port number from the routing protocol and set up endpoint
400  if (SetupEndpoint6 () != 0)
401  { // Route to destination does not exist
402  return -1;
403  }
404  }
405  else
406  {
408  return -1;
409  }
410 
411  // Re-initialize parameters in case this socket is being reused after CLOSE
412  m_rtt->Reset ();
414 
415  // DoConnect() will do state-checking and send a SYN packet
416  return DoConnect ();
417 }
418 
420 int
422 {
423  NS_LOG_FUNCTION (this);
424  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
425  if (m_state != CLOSED)
426  {
428  return -1;
429  }
430  // In other cases, set the state to LISTEN and done
431  NS_LOG_INFO ("CLOSED -> LISTEN");
432  m_state = LISTEN;
433  return 0;
434 }
435 
437 int
439 {
440  NS_LOG_FUNCTION (this);
441  // First we check to see if there is any unread rx data
442  // Bug number 426 claims we should send reset in this case.
443  if (m_rxBuffer.Size () != 0)
444  {
445  SendRST ();
446  return 0;
447  }
449  { // App close with pending data must wait until all data transmitted
450  if (m_closeOnEmpty == false)
451  {
452  m_closeOnEmpty = true;
453  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
454  }
455  return 0;
456  }
457  return DoClose ();
458 }
459 
461 int
463 {
464  NS_LOG_FUNCTION (this);
465  m_shutdownSend = true;
466  return 0;
467 }
468 
470 int
472 {
473  NS_LOG_FUNCTION (this);
474  m_shutdownRecv = true;
475  return 0;
476 }
477 
480 int
481 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
482 {
483  NS_LOG_FUNCTION (this << p);
484  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
486  {
487  // Store the packet into Tx buffer
488  if (!m_txBuffer.Add (p))
489  { // TxBuffer overflow, send failed
491  return -1;
492  }
493  // Submit the data to lower layers
494  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
495  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
496  { // Try to send the data out
498  }
499  return p->GetSize ();
500  }
501  else
502  { // Connection not established yet
504  return -1; // Send failure
505  }
506 }
507 
509 int
510 TcpSocketBase::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
511 {
512  return Send (p, flags); // SendTo() and Send() are the same
513 }
514 
518 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
519 {
520  NS_LOG_FUNCTION (this);
521  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
522  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
523  {
524  return Create<Packet> (); // Send EOF on connection close
525  }
526  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
527  if (outPacket != 0 && outPacket->GetSize () != 0)
528  {
529  SocketAddressTag tag;
530  if (m_endPoint != 0)
531  {
533  }
534  else if (m_endPoint6 != 0)
535  {
537  }
538  outPacket->AddPacketTag (tag);
539  }
540  return outPacket;
541 }
542 
545 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
546 {
547  NS_LOG_FUNCTION (this << maxSize << flags);
548  Ptr<Packet> packet = Recv (maxSize, flags);
549  // Null packet means no data to read, and an empty packet indicates EOF
550  if (packet != 0 && packet->GetSize () != 0)
551  {
552  if (m_endPoint != 0)
553  {
555  }
556  else if (m_endPoint6 != 0)
557  {
559  }
560  else
561  {
562  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
563  }
564  }
565  return packet;
566 }
567 
569 uint32_t
571 {
572  NS_LOG_FUNCTION (this);
573  return m_txBuffer.Available ();
574 }
575 
577 uint32_t
579 {
580  NS_LOG_FUNCTION (this);
581  return m_rxBuffer.Available ();
582 }
583 
585 int
587 {
588  NS_LOG_FUNCTION (this);
589  if (m_endPoint != 0)
590  {
592  }
593  else if (m_endPoint6 != 0)
594  {
596  }
597  else
598  { // It is possible to call this method on a socket without a name
599  // in which case, behavior is unspecified
600  // Should this return an InetSocketAddress or an Inet6SocketAddress?
601  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
602  }
603  return 0;
604 }
605 
607 void
609 {
610  NS_LOG_FUNCTION (netdevice);
611  Socket::BindToNetDevice (netdevice); // Includes sanity check
612  if (m_endPoint == 0 && m_endPoint6 == 0)
613  {
614  if (Bind () == -1)
615  {
616  NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
617  return;
618  }
619  NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
620  }
621 
622  if (m_endPoint != 0)
623  {
624  m_endPoint->BindToNetDevice (netdevice);
625  }
626  // No BindToNetDevice() for Ipv6EndPoint
627  return;
628 }
629 
631 int
633 {
634  NS_LOG_FUNCTION (this);
635 
636  if (m_endPoint == 0 && m_endPoint6 == 0)
637  {
638  return -1;
639  }
640  if (m_endPoint != 0)
641  {
644  }
645  if (m_endPoint6 != 0)
646  {
649  }
650 
651  return 0;
652 }
653 
655 int
657 {
658  NS_LOG_FUNCTION (this);
659 
660  // A new connection is allowed only if this socket does not have a connection
662  { // send a SYN packet and change state into SYN_SENT
664  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
665  m_state = SYN_SENT;
666  }
667  else if (m_state != TIME_WAIT)
668  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
669  // exists. We send RST, tear down everything, and close this socket.
670  SendRST ();
671  CloseAndNotify ();
672  }
673  return 0;
674 }
675 
678 int
680 {
681  NS_LOG_FUNCTION (this);
682  switch (m_state)
683  {
684  case SYN_RCVD:
685  case ESTABLISHED:
686  // send FIN to close the peer
688  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
690  break;
691  case CLOSE_WAIT:
692  // send FIN+ACK to close the peer
694  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
695  m_state = LAST_ACK;
696  break;
697  case SYN_SENT:
698  case CLOSING:
699  // Send RST if application closes in SYN_SENT and CLOSING
700  SendRST ();
701  CloseAndNotify ();
702  break;
703  case LISTEN:
704  case LAST_ACK:
705  // In these three states, move to CLOSED and tear down the end point
706  CloseAndNotify ();
707  break;
708  case CLOSED:
709  case FIN_WAIT_1:
710  case FIN_WAIT_2:
711  case TIME_WAIT:
712  default: /* mute compiler */
713  // Do nothing in these four states
714  break;
715  }
716  return 0;
717 }
718 
720 void
722 {
723  NS_LOG_FUNCTION (this);
724 
725  if (!m_closeNotified)
726  {
728  }
729  if (m_state != TIME_WAIT)
730  {
732  }
733  m_closeNotified = true;
734  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
735  CancelAllTimers ();
736  m_state = CLOSED;
737 }
738 
739 
742 bool
744 {
745  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
746  { // Rx buffer in these states are not initialized.
747  return false;
748  }
749  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
750  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
751  // sequence number must equals to m_rxBuffer.NextRxSequence ()
752  return (m_rxBuffer.NextRxSequence () != head);
753  }
754 
755  // In all other cases, check if the sequence number is in range
756  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
757 }
758 
762 void
764  Ptr<Ipv4Interface> incomingInterface)
765 {
766  DoForwardUp (packet, header, port, incomingInterface);
767 }
768 
769 void
771 {
772  DoForwardUp (packet, saddr, daddr, port);
773 }
774 
778 void
780  Ptr<Ipv4Interface> incomingInterface)
781 {
782  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
784  ":" << m_endPoint->GetPeerPort () <<
785  " to " << m_endPoint->GetLocalAddress () <<
786  ":" << m_endPoint->GetLocalPort ());
787  Address fromAddress = InetSocketAddress (header.GetSource (), port);
788  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
789 
790  // Peel off TCP header and do validity checking
791  TcpHeader tcpHeader;
792  packet->RemoveHeader (tcpHeader);
793  if (tcpHeader.GetFlags () & TcpHeader::ACK)
794  {
795  EstimateRtt (tcpHeader);
796  }
797  ReadOptions (tcpHeader);
798 
799  // Update Rx window size, i.e. the flow control window
800  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
801  { // persist probes end
802  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
804  }
805  m_rWnd = tcpHeader.GetWindowSize ();
806 
807  // Discard fully out of range data packets
808  if (packet->GetSize ()
809  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
810  {
811  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
812  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
813  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
814  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
815  m_rxBuffer.MaxRxSequence () << ")");
816  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
817  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
818  {
820  }
821  return;
822  }
823 
824  // TCP state machine code in different process functions
825  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
826  switch (m_state)
827  {
828  case ESTABLISHED:
829  ProcessEstablished (packet, tcpHeader);
830  break;
831  case LISTEN:
832  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
833  break;
834  case TIME_WAIT:
835  // Do nothing
836  break;
837  case CLOSED:
838  // Send RST if the incoming packet is not a RST
839  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
840  { // Since m_endPoint is not configured yet, we cannot use SendRST here
841  TcpHeader h;
845  h.SetSourcePort (tcpHeader.GetDestinationPort ());
846  h.SetDestinationPort (tcpHeader.GetSourcePort ());
848  AddOptions (h);
849  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
850  }
851  break;
852  case SYN_SENT:
853  ProcessSynSent (packet, tcpHeader);
854  break;
855  case SYN_RCVD:
856  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
857  break;
858  case FIN_WAIT_1:
859  case FIN_WAIT_2:
860  case CLOSE_WAIT:
861  ProcessWait (packet, tcpHeader);
862  break;
863  case CLOSING:
864  ProcessClosing (packet, tcpHeader);
865  break;
866  case LAST_ACK:
867  ProcessLastAck (packet, tcpHeader);
868  break;
869  default: // mute compiler
870  break;
871  }
872 }
873 
874 void
876 {
877  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
879  ":" << m_endPoint6->GetPeerPort () <<
880  " to " << m_endPoint6->GetLocalAddress () <<
881  ":" << m_endPoint6->GetLocalPort ());
882  Address fromAddress = Inet6SocketAddress (saddr, port);
883  Address toAddress = Inet6SocketAddress (daddr, m_endPoint6->GetLocalPort ());
884 
885  // Peel off TCP header and do validity checking
886  TcpHeader tcpHeader;
887  packet->RemoveHeader (tcpHeader);
888  if (tcpHeader.GetFlags () & TcpHeader::ACK)
889  {
890  EstimateRtt (tcpHeader);
891  }
892  ReadOptions (tcpHeader);
893 
894  // Update Rx window size, i.e. the flow control window
895  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
896  { // persist probes end
897  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
899  }
900  m_rWnd = tcpHeader.GetWindowSize ();
901 
902  // Discard fully out of range packets
903  if (packet->GetSize ()
904  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
905  {
906  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
907  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
908  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
909  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
910  m_rxBuffer.MaxRxSequence () << ")");
911  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
912  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
913  {
915  }
916  return;
917  }
918 
919  // TCP state machine code in different process functions
920  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
921  switch (m_state)
922  {
923  case ESTABLISHED:
924  ProcessEstablished (packet, tcpHeader);
925  break;
926  case LISTEN:
927  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
928  break;
929  case TIME_WAIT:
930  // Do nothing
931  break;
932  case CLOSED:
933  // Send RST if the incoming packet is not a RST
934  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
935  { // Since m_endPoint is not configured yet, we cannot use SendRST here
936  TcpHeader h;
940  h.SetSourcePort (tcpHeader.GetDestinationPort ());
941  h.SetDestinationPort (tcpHeader.GetSourcePort ());
943  AddOptions (h);
944  m_tcp->SendPacket (Create<Packet> (), h, daddr, saddr, m_boundnetdevice);
945  }
946  break;
947  case SYN_SENT:
948  ProcessSynSent (packet, tcpHeader);
949  break;
950  case SYN_RCVD:
951  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
952  break;
953  case FIN_WAIT_1:
954  case FIN_WAIT_2:
955  case CLOSE_WAIT:
956  ProcessWait (packet, tcpHeader);
957  break;
958  case CLOSING:
959  ProcessClosing (packet, tcpHeader);
960  break;
961  case LAST_ACK:
962  ProcessLastAck (packet, tcpHeader);
963  break;
964  default: // mute compiler
965  break;
966  }
967 }
968 
971 void
973 {
974  NS_LOG_FUNCTION (this << tcpHeader);
975 
976  // Extract the flags. PSH and URG are not honoured.
977  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
978 
979  // Different flags are different events
980  if (tcpflags == TcpHeader::ACK)
981  {
982  ReceivedAck (packet, tcpHeader);
983  }
984  else if (tcpflags == TcpHeader::SYN)
985  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
986  // respond with a SYN+ACK. But it is not a legal state transition as of
987  // RFC793. Thus this is ignored.
988  }
989  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
990  { // No action for received SYN+ACK, it is probably a duplicated packet
991  }
992  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
993  { // Received FIN or FIN+ACK, bring down this socket nicely
994  PeerClose (packet, tcpHeader);
995  }
996  else if (tcpflags == 0)
997  { // No flags means there is only data
998  ReceivedData (packet, tcpHeader);
999  if (m_rxBuffer.Finished ())
1000  {
1001  PeerClose (packet, tcpHeader);
1002  }
1003  }
1004  else
1005  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1006  if (tcpflags != TcpHeader::RST)
1007  { // this must be an invalid flag, send reset
1008  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1009  SendRST ();
1010  }
1011  CloseAndNotify ();
1012  }
1013 }
1014 
1016 void
1018 {
1019  NS_LOG_FUNCTION (this << tcpHeader);
1020 
1021  // Received ACK. Compare the ACK number against highest unacked seqno
1022  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1023  { // Ignore if no ACK flag
1024  }
1025  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1026  { // Case 1: Old ACK, ignored.
1027  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1028  }
1029  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1030  { // Case 2: Potentially a duplicated ACK
1031  if (tcpHeader.GetAckNumber () < m_nextTxSequence)
1032  {
1033  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1034  DupAck (tcpHeader, ++m_dupAckCount);
1035  }
1036  // otherwise, the ACK is precisely equal to the nextTxSequence
1037  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1038  }
1039  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1040  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1041  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1042  NewAck (tcpHeader.GetAckNumber ());
1043  m_dupAckCount = 0;
1044  }
1045  // If there is any data piggybacked, store it into m_rxBuffer
1046  if (packet->GetSize () > 0)
1047  {
1048  ReceivedData (packet, tcpHeader);
1049  }
1050 }
1051 
1053 void
1055  const Address& fromAddress, const Address& toAddress)
1056 {
1057  NS_LOG_FUNCTION (this << tcpHeader);
1058 
1059  // Extract the flags. PSH and URG are not honoured.
1060  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1061 
1062  // Fork a socket if received a SYN. Do nothing otherwise.
1063  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1064  if (tcpflags != TcpHeader::SYN)
1065  {
1066  return;
1067  }
1068 
1069  // Call socket's notify function to let the server app know we got a SYN
1070  // If the server app refuses the connection, do nothing
1071  if (!NotifyConnectionRequest (fromAddress))
1072  {
1073  return;
1074  }
1075  // Clone the socket, simulate fork
1076  Ptr<TcpSocketBase> newSock = Fork ();
1077  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1079  packet, tcpHeader, fromAddress, toAddress);
1080 }
1081 
1083 void
1085 {
1086  NS_LOG_FUNCTION (this << tcpHeader);
1087 
1088  // Extract the flags. PSH and URG are not honoured.
1089  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1090 
1091  if (tcpflags == 0)
1092  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1093  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1094  m_state = ESTABLISHED;
1095  m_connected = true;
1096  m_retxEvent.Cancel ();
1098  ReceivedData (packet, tcpHeader);
1100  }
1101  else if (tcpflags == TcpHeader::ACK)
1102  { // Ignore ACK in SYN_SENT
1103  }
1104  else if (tcpflags == TcpHeader::SYN)
1105  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1106  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1107  m_state = SYN_RCVD;
1111  }
1112  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1113  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1114  { // Handshake completed
1115  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1116  m_state = ESTABLISHED;
1117  m_connected = true;
1118  m_retxEvent.Cancel ();
1125  // Always respond to first data packet to speed up the connection.
1126  // Remove to get the behaviour of old NS-3 code.
1128  }
1129  else
1130  { // Other in-sequence input
1131  if (tcpflags != TcpHeader::RST)
1132  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1133  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1134  SendRST ();
1135  }
1136  CloseAndNotify ();
1137  }
1138 }
1139 
1141 void
1143  const Address& fromAddress, const Address& toAddress)
1144 {
1145  NS_LOG_FUNCTION (this << tcpHeader);
1146 
1147  // Extract the flags. PSH and URG are not honoured.
1148  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1149 
1150  if (tcpflags == 0
1151  || (tcpflags == TcpHeader::ACK
1152  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1153  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1154  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1155  // handshake is completed nicely.
1156  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1157  m_state = ESTABLISHED;
1158  m_connected = true;
1159  m_retxEvent.Cancel ();
1162  if (m_endPoint)
1163  {
1164  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1165  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1166  }
1167  else if (m_endPoint6)
1168  {
1169  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1170  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1171  }
1172  // Always respond to first data packet to speed up the connection.
1173  // Remove to get the behaviour of old NS-3 code.
1175  ReceivedAck (packet, tcpHeader);
1176  NotifyNewConnectionCreated (this, fromAddress);
1177  // As this connection is established, the socket is available to send data now
1178  if (GetTxAvailable () > 0)
1179  {
1181  }
1182  }
1183  else if (tcpflags == TcpHeader::SYN)
1184  { // Probably the peer lost my SYN+ACK
1187  }
1188  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1189  {
1190  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1191  { // In-sequence FIN before connection complete. Set up connection and close.
1192  m_connected = true;
1193  m_retxEvent.Cancel ();
1196  if (m_endPoint)
1197  {
1198  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1199  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1200  }
1201  else if (m_endPoint6)
1202  {
1203  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1204  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1205  }
1206  PeerClose (packet, tcpHeader);
1207  }
1208  }
1209  else
1210  { // Other in-sequence input
1211  if (tcpflags != TcpHeader::RST)
1212  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1213  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1214  if (m_endPoint)
1215  {
1216  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1217  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1218  }
1219  else if (m_endPoint6)
1220  {
1221  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1222  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1223  }
1224  SendRST ();
1225  }
1226  CloseAndNotify ();
1227  }
1228 }
1229 
1231 void
1233 {
1234  NS_LOG_FUNCTION (this << tcpHeader);
1235 
1236  // Extract the flags. PSH and URG are not honoured.
1237  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1238 
1239  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1240  { // Bare data, accept it
1241  ReceivedData (packet, tcpHeader);
1242  }
1243  else if (tcpflags == TcpHeader::ACK)
1244  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1245  ReceivedAck (packet, tcpHeader);
1246  if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1247  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1248  { // This ACK corresponds to the FIN sent
1249  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1250  m_state = FIN_WAIT_2;
1251  }
1252  }
1253  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1254  { // Got FIN, respond with ACK and move to next state
1255  if (tcpflags & TcpHeader::ACK)
1256  { // Process the ACK first
1257  ReceivedAck (packet, tcpHeader);
1258  }
1260  }
1261  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1262  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1263  return;
1264  }
1265  else
1266  { // This is a RST or bad flags
1267  if (tcpflags != TcpHeader::RST)
1268  {
1269  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1270  SendRST ();
1271  }
1272  CloseAndNotify ();
1273  return;
1274  }
1275 
1276  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1277  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1278  {
1279  if (m_state == FIN_WAIT_1)
1280  {
1281  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1282  m_state = CLOSING;
1283  if (m_txBuffer.Size () == 0
1284  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1285  { // This ACK corresponds to the FIN sent
1286  TimeWait ();
1287  }
1288  }
1289  else if (m_state == FIN_WAIT_2)
1290  {
1291  TimeWait ();
1292  }
1294  if (!m_shutdownRecv)
1295  {
1296  NotifyDataRecv ();
1297  }
1298  }
1299 }
1300 
1302 void
1304 {
1305  NS_LOG_FUNCTION (this << tcpHeader);
1306 
1307  // Extract the flags. PSH and URG are not honoured.
1308  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1309 
1310  if (tcpflags == TcpHeader::ACK)
1311  {
1312  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1313  { // This ACK corresponds to the FIN sent
1314  TimeWait ();
1315  }
1316  }
1317  else
1318  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1319  // anyone. If anything other than ACK is received, respond with a reset.
1320  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1321  { // FIN from the peer as well. We can close immediately.
1323  }
1324  else if (tcpflags != TcpHeader::RST)
1325  { // Receive of SYN or SYN+ACK or bad flags or pure data
1326  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1327  SendRST ();
1328  }
1329  CloseAndNotify ();
1330  }
1331 }
1332 
1334 void
1336 {
1337  NS_LOG_FUNCTION (this << tcpHeader);
1338 
1339  // Extract the flags. PSH and URG are not honoured.
1340  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1341 
1342  if (tcpflags == 0)
1343  {
1344  ReceivedData (packet, tcpHeader);
1345  }
1346  else if (tcpflags == TcpHeader::ACK)
1347  {
1348  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1349  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1350  CloseAndNotify ();
1351  }
1352  }
1353  else if (tcpflags == TcpHeader::FIN)
1354  { // Received FIN again, the peer probably lost the FIN+ACK
1356  }
1357  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1358  {
1359  CloseAndNotify ();
1360  }
1361  else
1362  { // Received a SYN or SYN+ACK or bad flags
1363  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1364  SendRST ();
1365  CloseAndNotify ();
1366  }
1367 }
1368 
1370 void
1372 {
1373  NS_LOG_FUNCTION (this << tcpHeader);
1374 
1375  // Ignore all out of range packets
1376  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1377  || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1378  {
1379  return;
1380  }
1381  // For any case, remember the FIN position in rx buffer first
1383  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1384  // If there is any piggybacked data, process it
1385  if (p->GetSize ())
1386  {
1387  ReceivedData (p, tcpHeader);
1388  }
1389  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1390  if (!m_rxBuffer.Finished ())
1391  {
1392  return;
1393  }
1394 
1395  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1396  if (m_state == FIN_WAIT_1)
1397  {
1398  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1399  m_state = CLOSING;
1400  return;
1401  }
1402 
1403  DoPeerClose (); // Change state, respond with ACK
1404 }
1405 
1407 void
1409 {
1411 
1412  // Move the state to CLOSE_WAIT
1413  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1414  m_state = CLOSE_WAIT;
1415 
1416  if (!m_closeNotified)
1417  {
1418  // The normal behaviour for an application is that, when the peer sent a in-sequence
1419  // FIN, the app should prepare to close. The app has two choices at this point: either
1420  // respond with ShutdownSend() call to declare that it has nothing more to send and
1421  // the socket can be closed immediately; or remember the peer's close request, wait
1422  // until all its existing data are pushed into the TCP socket, then call Close()
1423  // explicitly.
1424  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1425  NotifyNormalClose ();
1426  m_closeNotified = true;
1427  }
1428  if (m_shutdownSend)
1429  { // The application declares that it would not sent any more, close this socket
1430  Close ();
1431  }
1432  else
1433  { // Need to ack, the application will close later
1435  }
1436  if (m_state == LAST_ACK)
1437  {
1438  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1441  }
1442 }
1443 
1446 void
1448 {
1449  NS_LOG_FUNCTION (this);
1450  m_endPoint = 0;
1451  if (m_tcp != 0)
1452  {
1453  std::vector<Ptr<TcpSocketBase> >::iterator it
1454  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1455  if (it != m_tcp->m_sockets.end ())
1456  {
1457  m_tcp->m_sockets.erase (it);
1458  }
1459  }
1460  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1461  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1462  CancelAllTimers ();
1463 }
1464 
1467 void
1469 {
1470  NS_LOG_FUNCTION (this);
1471  m_endPoint6 = 0;
1472  if (m_tcp != 0)
1473  {
1474  std::vector<Ptr<TcpSocketBase> >::iterator it
1475  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1476  if (it != m_tcp->m_sockets.end ())
1477  {
1478  m_tcp->m_sockets.erase (it);
1479  }
1480  }
1481  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1482  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1483  CancelAllTimers ();
1484 }
1485 
1487 void
1489 {
1490  NS_LOG_FUNCTION (this << (uint32_t)flags);
1491  Ptr<Packet> p = Create<Packet> ();
1492  TcpHeader header;
1494 
1495  if (m_endPoint == 0 && m_endPoint6 == 0)
1496  {
1497  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1498  return;
1499  }
1500  if (flags & TcpHeader::FIN)
1501  {
1502  flags |= TcpHeader::ACK;
1503  }
1504  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1505  {
1506  ++s;
1507  }
1508 
1509  header.SetFlags (flags);
1510  header.SetSequenceNumber (s);
1511  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1512  if (m_endPoint != 0)
1513  {
1514  header.SetSourcePort (m_endPoint->GetLocalPort ());
1515  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1516  }
1517  else
1518  {
1519  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1520  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1521  }
1522  header.SetWindowSize (AdvertisedWindowSize ());
1523  AddOptions (header);
1525  bool hasSyn = flags & TcpHeader::SYN;
1526  bool hasFin = flags & TcpHeader::FIN;
1527  bool isAck = flags == TcpHeader::ACK;
1528  if (hasSyn)
1529  {
1530  if (m_cnCount == 0)
1531  { // No more connection retries, give up
1532  NS_LOG_LOGIC ("Connection failed.");
1533  CloseAndNotify ();
1534  return;
1535  }
1536  else
1537  { // Exponential backoff of connection time out
1538  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1539  m_rto = m_cnTimeout * backoffCount;
1540  m_cnCount--;
1541  }
1542  }
1543  if (m_endPoint != 0)
1544  {
1545  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1547  }
1548  else
1549  {
1550  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1552  }
1553  if (flags & TcpHeader::ACK)
1554  { // If sending an ACK, cancel the delay ACK as well
1555  m_delAckEvent.Cancel ();
1556  m_delAckCount = 0;
1557  }
1558  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1559  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1560  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1561  << Simulator::Now ().GetSeconds () << " to expire at time "
1562  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1564  }
1565 }
1566 
1568 void
1570 {
1571  NS_LOG_FUNCTION (this);
1573  NotifyErrorClose ();
1574  DeallocateEndPoint ();
1575 }
1576 
1578 void
1580 {
1581  if (m_endPoint != 0)
1582  {
1583  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1585  m_endPoint = 0;
1586  std::vector<Ptr<TcpSocketBase> >::iterator it
1587  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1588  if (it != m_tcp->m_sockets.end ())
1589  {
1590  m_tcp->m_sockets.erase (it);
1591  }
1592  CancelAllTimers ();
1593  }
1594  if (m_endPoint6 != 0)
1595  {
1596  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1598  m_endPoint6 = 0;
1599  std::vector<Ptr<TcpSocketBase> >::iterator it
1600  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1601  if (it != m_tcp->m_sockets.end ())
1602  {
1603  m_tcp->m_sockets.erase (it);
1604  }
1605  CancelAllTimers ();
1606  }
1607 }
1608 
1610 int
1612 {
1613  NS_LOG_FUNCTION (this);
1614  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1615  NS_ASSERT (ipv4 != 0);
1616  if (ipv4->GetRoutingProtocol () == 0)
1617  {
1618  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1619  }
1620  // Create a dummy packet, then ask the routing function for the best output
1621  // interface's address
1622  Ipv4Header header;
1624  Socket::SocketErrno errno_;
1625  Ptr<Ipv4Route> route;
1627  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1628  if (route == 0)
1629  {
1630  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1631  NS_LOG_ERROR (errno_);
1632  m_errno = errno_;
1633  return -1;
1634  }
1635  NS_LOG_LOGIC ("Route exists");
1636  m_endPoint->SetLocalAddress (route->GetSource ());
1637  return 0;
1638 }
1639 
1640 int
1642 {
1643  NS_LOG_FUNCTION (this);
1645  NS_ASSERT (ipv6 != 0);
1646  if (ipv6->GetRoutingProtocol () == 0)
1647  {
1648  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1649  }
1650  // Create a dummy packet, then ask the routing function for the best output
1651  // interface's address
1652  Ipv6Header header;
1654  Socket::SocketErrno errno_;
1655  Ptr<Ipv6Route> route;
1657  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1658  if (route == 0)
1659  {
1660  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1661  NS_LOG_ERROR (errno_);
1662  m_errno = errno_;
1663  return -1;
1664  }
1665  NS_LOG_LOGIC ("Route exists");
1666  m_endPoint6->SetLocalAddress (route->GetSource ());
1667  return 0;
1668 }
1669 
1673 void
1675  const Address& fromAddress, const Address& toAddress)
1676 {
1677  // Get port and address from peer (connecting host)
1678  if (InetSocketAddress::IsMatchingType (toAddress))
1679  {
1680  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1681  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1682  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1683  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1684  m_endPoint6 = 0;
1685  }
1686  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1687  {
1688  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1689  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1690  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1691  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1692  m_endPoint = 0;
1693  }
1694  m_tcp->m_sockets.push_back (this);
1695 
1696  // Change the cloned socket from LISTEN state to SYN_RCVD
1697  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1698  m_state = SYN_RCVD;
1700  SetupCallback ();
1701  // Set the sequence number and send SYN+ACK
1704 }
1705 
1706 void
1708 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1709  // be called as a scheduled event
1711  // The if-block below was moved from ProcessSynSent() to here because we need
1712  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1713  // reflect the behaviour in the real world.
1714  if (GetTxAvailable () > 0)
1715  {
1717  }
1718 }
1719 
1722 uint32_t
1723 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1724 {
1725  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1726 
1727  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
1728  uint32_t sz = p->GetSize (); // Size of packet
1729  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1730  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
1731  if (m_closeOnEmpty && (remainingData == 0))
1732  {
1733  flags |= TcpHeader::FIN;
1734  if (m_state == ESTABLISHED)
1735  { // On active close: I am the first one to send FIN
1736  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1737  m_state = FIN_WAIT_1;
1738  }
1739  else if (m_state == CLOSE_WAIT)
1740  { // On passive close: Peer sent me FIN already
1741  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1742  m_state = LAST_ACK;
1743  }
1744  }
1745  TcpHeader header;
1746  header.SetFlags (flags);
1747  header.SetSequenceNumber (seq);
1749  if (m_endPoint)
1750  {
1751  header.SetSourcePort (m_endPoint->GetLocalPort ());
1753  }
1754  else
1755  {
1756  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1758  }
1759  header.SetWindowSize (AdvertisedWindowSize ());
1760  AddOptions (header);
1761  if (m_retxEvent.IsExpired () )
1762  { // Schedule retransmit
1764  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
1765  Simulator::Now ().GetSeconds () << " to expire at time " <<
1766  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
1768  }
1769  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1770  if (m_endPoint)
1771  {
1772  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1774  }
1775  else
1776  {
1777  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1779  }
1780  m_rtt->SentSeq (seq, sz); // notify the RTT
1781  // Notify the application of the data being sent unless this is a retransmit
1782  if (seq == m_nextTxSequence)
1783  {
1785  }
1786  // Update highTxMark
1787  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1788  return sz;
1789 }
1790 
1794 bool
1796 {
1797  NS_LOG_FUNCTION (this << withAck);
1798  if (m_txBuffer.Size () == 0)
1799  {
1800  return false; // Nothing to send
1801 
1802  }
1803  if (m_endPoint == 0 && m_endPoint6 == 0)
1804  {
1805  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
1806  return false; // Is this the right way to handle this condition?
1807  }
1808  uint32_t nPacketsSent = 0;
1810  {
1811  uint32_t w = AvailableWindow (); // Get available window size
1812  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
1813  " w " << w <<
1814  " rxwin " << m_rWnd <<
1815  " segsize " << m_segmentSize <<
1816  " nextTxSeq " << m_nextTxSequence <<
1817  " highestRxAck " << m_txBuffer.HeadSequence () <<
1818  " pd->Size " << m_txBuffer.Size () <<
1819  " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
1820  // Quit if send disallowed
1821  if (m_shutdownSend)
1822  {
1824  return false;
1825  }
1826  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
1828  {
1829  break; // No more
1830  }
1831  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
1832  // in the buffer and the amount of data to send is less than one segment
1833  if (!m_noDelay && UnAckDataCount () > 0
1835  {
1836  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
1837  break;
1838  }
1839  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
1840  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
1841  nPacketsSent++; // Count sent this loop
1842  m_nextTxSequence += sz; // Advance next tx sequence
1843  }
1844  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
1845  return (nPacketsSent > 0);
1846 }
1847 
1848 uint32_t
1850 {
1851  NS_LOG_FUNCTION (this);
1853 }
1854 
1855 uint32_t
1857 {
1858  NS_LOG_FUNCTION (this);
1859  return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
1860 }
1861 
1862 uint32_t
1864 {
1865  NS_LOG_FUNCTION (this);
1866  return m_rWnd;
1867 }
1868 
1869 uint32_t
1871 {
1873  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
1874  uint32_t win = Window (); // Number of bytes allowed to be outstanding
1875  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
1876  return (win < unack) ? 0 : (win - unack);
1877 }
1878 
1879 uint16_t
1881 {
1882  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
1883 }
1884 
1885 // Receipt of new packet, put into Rx buffer
1886 void
1888 {
1889  NS_LOG_FUNCTION (this << tcpHeader);
1890  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
1891  " ack " << tcpHeader.GetAckNumber () <<
1892  " pkt size " << p->GetSize () );
1893 
1894  // Put into Rx buffer
1895  SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
1896  if (!m_rxBuffer.Add (p, tcpHeader))
1897  { // Insert failed: No data or RX buffer full
1899  return;
1900  }
1901  // Now send a new ACK packet acknowledging all received and delivered data
1902  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
1903  { // A gap exists in the buffer, or we filled a gap: Always ACK
1905  }
1906  else
1907  { // In-sequence packet: ACK if delayed ack count allows
1909  {
1910  m_delAckEvent.Cancel ();
1911  m_delAckCount = 0;
1913  }
1914  else if (m_delAckEvent.IsExpired ())
1915  {
1918  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
1919  }
1920  }
1921  // Notify app to receive if necessary
1922  if (expectedSeq < m_rxBuffer.NextRxSequence ())
1923  { // NextRxSeq advanced, we have something to send to the app
1924  if (!m_shutdownRecv)
1925  {
1926  NotifyDataRecv ();
1927  }
1928  // Handle exceptions
1929  if (m_closeNotified)
1930  {
1931  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
1932  }
1933  // If we received FIN before and now completed all "holes" in rx buffer,
1934  // invoke peer close procedure
1935  if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
1936  {
1937  DoPeerClose ();
1938  }
1939  }
1940 }
1941 
1943 void
1945 {
1946  // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
1947  // (which should be ignored) is handled by m_rtt. Once timestamp option
1948  // is implemented, this function would be more elaborated.
1949  m_lastRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
1950 }
1951 
1952 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
1953 // when the three-way handshake completed. This cancels retransmission timer
1954 // and advances Tx window
1955 void
1957 {
1958  NS_LOG_FUNCTION (this << ack);
1959 
1960  if (m_state != SYN_RCVD)
1961  { // Set RTO unless the ACK is received in SYN_RCVD state
1962  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1963  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1964  m_retxEvent.Cancel ();
1965  // On recieving a "New" ack we restart retransmission timer .. RFC 2988
1967  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
1968  Simulator::Now ().GetSeconds () << " to expire at time " <<
1969  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1971  }
1972  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
1973  { // Zero window: Enter persist state to send 1 byte to probe
1974  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
1975  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
1976  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1977  m_retxEvent.Cancel ();
1978  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
1979  Simulator::Now ().GetSeconds () << " to expire at time " <<
1980  (Simulator::Now () + m_persistTimeout).GetSeconds ());
1983  }
1984  // Note the highest ACK and tell app to send more
1985  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
1986  " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
1987  m_txBuffer.DiscardUpTo (ack);
1988  if (GetTxAvailable () > 0)
1989  {
1991  }
1992  if (ack > m_nextTxSequence)
1993  {
1994  m_nextTxSequence = ack; // If advanced
1995  }
1996  if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
1997  { // No retransmit timer if no data to retransmit
1998  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1999  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2000  m_retxEvent.Cancel ();
2001  }
2002  // Try to send more data
2004 }
2005 
2006 // Retransmit timeout
2007 void
2009 {
2010  NS_LOG_FUNCTION (this);
2011  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2012  // If erroneous timeout in closed/timed-wait state, just return
2013  if (m_state == CLOSED || m_state == TIME_WAIT)
2014  {
2015  return;
2016  }
2017  // If all data are received (non-closing socket and nothing to send), just return
2019  {
2020  return;
2021  }
2022 
2023  Retransmit ();
2024 }
2025 
2026 void
2028 {
2029  m_delAckCount = 0;
2031 }
2032 
2033 void
2035 {
2036  NS_LOG_FUNCTION (this);
2037 
2039  if (m_state == LAST_ACK)
2040  {
2041  CloseAndNotify ();
2042  }
2043  if (!m_closeNotified)
2044  {
2045  m_closeNotified = true;
2046  }
2047 }
2048 
2049 // Send 1-byte data to probe for the window size at the receiver when
2050 // the local knowledge tells that the receiver has zero window size
2051 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2052 void
2054 {
2055  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2056  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2058  TcpHeader tcpHeader;
2059  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2060  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2061  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2062  if (m_endPoint != 0)
2063  {
2064  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2065  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2066  }
2067  else
2068  {
2069  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2070  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2071  }
2072  AddOptions (tcpHeader);
2073 
2074  if (m_endPoint != 0)
2075  {
2076  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2078  }
2079  else
2080  {
2081  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2083  }
2084  NS_LOG_LOGIC ("Schedule persist timeout at time "
2085  << Simulator::Now ().GetSeconds () << " to expire at time "
2086  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2088 }
2089 
2090 void
2092 {
2093  m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
2094  m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
2095  m_dupAckCount = 0;
2096  DoRetransmit (); // Retransmit the packet
2097 }
2098 
2099 void
2101 {
2102  NS_LOG_FUNCTION (this);
2103  // Retransmit SYN packet
2104  if (m_state == SYN_SENT)
2105  {
2106  if (m_cnCount > 0)
2107  {
2109  }
2110  else
2111  {
2113  }
2114  return;
2115  }
2116  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2117  if (m_txBuffer.Size () == 0)
2118  {
2119  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2120  { // Must have lost FIN, re-send
2122  }
2123  return;
2124  }
2125  // Retransmit a data packet: Call SendDataPacket
2126  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
2127  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
2128  // In case of RTO, advance m_nextTxSequence
2129  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
2130 
2131 }
2132 
2133 void
2135 {
2136  m_retxEvent.Cancel ();
2138  m_delAckEvent.Cancel ();
2141 }
2142 
2144 void
2146 {
2147  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2148  m_state = TIME_WAIT;
2149  CancelAllTimers ();
2150  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2151  // according to RFC793, p.28
2154 }
2155 
2158 void
2160 {
2162 }
2163 
2164 uint32_t
2166 {
2167  return m_txBuffer.MaxBufferSize ();
2168 }
2169 
2170 void
2172 {
2174 }
2175 
2176 uint32_t
2178 {
2179  return m_rxBuffer.MaxBufferSize ();
2180 }
2181 
2182 void
2184 {
2185  m_segmentSize = size;
2186  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2187 }
2188 
2189 uint32_t
2191 {
2192  return m_segmentSize;
2193 }
2194 
2195 void
2197 {
2198  m_cnTimeout = timeout;
2199 }
2200 
2201 Time
2203 {
2204  return m_cnTimeout;
2205 }
2206 
2207 void
2209 {
2210  m_cnRetries = count;
2211 }
2212 
2213 uint32_t
2215 {
2216  return m_cnRetries;
2217 }
2218 
2219 void
2221 {
2223 }
2224 
2225 Time
2227 {
2228  return m_delAckTimeout;
2229 }
2230 
2231 void
2233 {
2234  m_delAckMaxCount = count;
2235 }
2236 
2237 uint32_t
2239 {
2240  return m_delAckMaxCount;
2241 }
2242 
2243 void
2245 {
2246  m_noDelay = noDelay;
2247 }
2248 
2249 bool
2251 {
2252  return m_noDelay;
2253 }
2254 
2255 void
2257 {
2259 }
2260 
2261 Time
2263 {
2264  return m_persistTimeout;
2265 }
2266 
2267 bool
2269 {
2270  // Broadcast is not implemented. Return true only if allowBroadcast==false
2271  return (!allowBroadcast);
2272 }
2273 
2274 bool
2276 {
2277  return false;
2278 }
2279 
2281 void
2283 {
2284 }
2285 
2287 void
2289 {
2290 }
2291 
2292 } // namespace ns3