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 
60 TypeId
62 {
63  static TypeId tid = TypeId ("ns3::TcpSocketBase")
64  .SetParent<TcpSocket> ()
65 // .AddAttribute ("TcpState", "State in TCP state machine",
66 // TypeId::ATTR_GET,
67 // EnumValue (CLOSED),
68 // MakeEnumAccessor (&TcpSocketBase::m_state),
69 // MakeEnumChecker (CLOSED, "Closed"))
70  .AddAttribute ("MaxSegLifetime",
71  "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
72  DoubleValue (120), /* RFC793 says MSL=2 minutes*/
73  MakeDoubleAccessor (&TcpSocketBase::m_msl),
74  MakeDoubleChecker<double> (0))
75  .AddAttribute ("MaxWindowSize", "Max size of advertised window",
76  UintegerValue (65535),
77  MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
78  MakeUintegerChecker<uint16_t> ())
79  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
80  CallbackValue (),
81  MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback),
82  MakeCallbackChecker ())
83  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
84  CallbackValue (),
85  MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback6),
86  MakeCallbackChecker ())
87  .AddTraceSource ("RTO",
88  "Retransmission timeout",
90  .AddTraceSource ("RTT",
91  "Last RTT sample",
93  .AddTraceSource ("NextTxSequence",
94  "Next sequence number to send (SND.NXT)",
96  .AddTraceSource ("HighestSequence",
97  "Highest sequence number ever sent in socket's life time",
99  .AddTraceSource ("State",
100  "TCP state",
102  .AddTraceSource ("RWND",
103  "Remote side's flow control window",
105  ;
106  return tid;
107 }
108 
110  : m_dupAckCount (0),
111  m_delAckCount (0),
112  m_endPoint (0),
113  m_endPoint6 (0),
114  m_node (0),
115  m_tcp (0),
116  m_rtt (0),
117  m_nextTxSequence (0),
118  // Change this for non-zero initial sequence number
119  m_highTxMark (0),
120  m_rxBuffer (0),
121  m_txBuffer (0),
122  m_state (CLOSED),
123  m_errno (ERROR_NOTERROR),
124  m_closeNotified (false),
125  m_closeOnEmpty (false),
126  m_shutdownSend (false),
127  m_shutdownRecv (false),
128  m_connected (false),
129  m_segmentSize (0),
130  // For attribute initialization consistency (quiet valgrind)
131  m_rWnd (0)
132 {
133  NS_LOG_FUNCTION (this);
134 }
135 
137  : TcpSocket (sock),
138  //copy object::m_tid and socket::callbacks
139  m_dupAckCount (sock.m_dupAckCount),
140  m_delAckCount (0),
141  m_delAckMaxCount (sock.m_delAckMaxCount),
142  m_noDelay (sock.m_noDelay),
143  m_cnRetries (sock.m_cnRetries),
144  m_delAckTimeout (sock.m_delAckTimeout),
145  m_persistTimeout (sock.m_persistTimeout),
146  m_cnTimeout (sock.m_cnTimeout),
147  m_endPoint (0),
148  m_endPoint6 (0),
149  m_node (sock.m_node),
150  m_tcp (sock.m_tcp),
151  m_rtt (0),
152  m_nextTxSequence (sock.m_nextTxSequence),
153  m_highTxMark (sock.m_highTxMark),
154  m_rxBuffer (sock.m_rxBuffer),
155  m_txBuffer (sock.m_txBuffer),
156  m_state (sock.m_state),
157  m_errno (sock.m_errno),
158  m_closeNotified (sock.m_closeNotified),
159  m_closeOnEmpty (sock.m_closeOnEmpty),
160  m_shutdownSend (sock.m_shutdownSend),
161  m_shutdownRecv (sock.m_shutdownRecv),
162  m_connected (sock.m_connected),
163  m_msl (sock.m_msl),
164  m_segmentSize (sock.m_segmentSize),
165  m_maxWinSize (sock.m_maxWinSize),
166  m_rWnd (sock.m_rWnd)
167 {
168  NS_LOG_FUNCTION (this);
169  NS_LOG_LOGIC ("Invoked the copy constructor");
170  // Copy the rtt estimator if it is set
171  if (sock.m_rtt)
172  {
173  m_rtt = sock.m_rtt->Copy ();
174  }
175  // Reset all callbacks to null
176  Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
177  Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
178  Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
179  SetConnectCallback (vPS, vPS);
180  SetDataSentCallback (vPSUI);
181  SetSendCallback (vPSUI);
182  SetRecvCallback (vPS);
183 }
184 
186 {
187  NS_LOG_FUNCTION (this);
188  m_node = 0;
189  if (m_endPoint != 0)
190  {
191  NS_ASSERT (m_tcp != 0);
192  /*
193  * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
194  * DestroyCallback is set to TcpSocketBase::Destroy. If we called
195  * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
196  * which in turn destroys my m_endPoint, and in turn invokes
197  * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
198  */
199  NS_ASSERT (m_endPoint != 0);
200  m_tcp->DeAllocate (m_endPoint);
201  NS_ASSERT (m_endPoint == 0);
202  }
203  if (m_endPoint6 != 0)
204  {
205  NS_ASSERT (m_tcp != 0);
206  NS_ASSERT (m_endPoint6 != 0);
207  m_tcp->DeAllocate (m_endPoint6);
208  NS_ASSERT (m_endPoint6 == 0);
209  }
210  m_tcp = 0;
211  CancelAllTimers ();
212 }
213 
214 /* Associate a node with this TCP socket */
215 void
217 {
218  m_node = node;
219 }
220 
221 /* Associate the L4 protocol (e.g. mux/demux) with this socket */
222 void
224 {
225  m_tcp = tcp;
226 }
227 
228 /* Set an RTT estimator with this socket */
229 void
231 {
232  m_rtt = rtt;
233 }
234 
235 /* Inherit from Socket class: Returns error code */
238 {
239  return m_errno;
240 }
241 
242 /* Inherit from Socket class: Returns socket type, NS3_SOCK_STREAM */
245 {
246  return NS3_SOCK_STREAM;
247 }
248 
249 /* Inherit from Socket class: Returns associated node */
250 Ptr<Node>
252 {
254  return m_node;
255 }
256 
257 /* Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */
258 int
260 {
261  NS_LOG_FUNCTION (this);
262  m_endPoint = m_tcp->Allocate ();
263  if (0 == m_endPoint)
264  {
266  return -1;
267  }
268  m_tcp->m_sockets.push_back (this);
269  return SetupCallback ();
270 }
271 
272 int
274 {
275  NS_LOG_FUNCTION (this);
276  m_endPoint6 = m_tcp->Allocate6 ();
277  if (0 == m_endPoint6)
278  {
280  return -1;
281  }
282  m_tcp->m_sockets.push_back (this);
283  return SetupCallback ();
284 }
285 
286 /* Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
287 int
289 {
290  NS_LOG_FUNCTION (this << address);
291  if (InetSocketAddress::IsMatchingType (address))
292  {
294  Ipv4Address ipv4 = transport.GetIpv4 ();
295  uint16_t port = transport.GetPort ();
296  if (ipv4 == Ipv4Address::GetAny () && port == 0)
297  {
298  m_endPoint = m_tcp->Allocate ();
299  }
300  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
301  {
302  m_endPoint = m_tcp->Allocate (port);
303  }
304  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
305  {
306  m_endPoint = m_tcp->Allocate (ipv4);
307  }
308  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
309  {
310  m_endPoint = m_tcp->Allocate (ipv4, port);
311  }
312  if (0 == m_endPoint)
313  {
315  return -1;
316  }
317  }
318  else if (Inet6SocketAddress::IsMatchingType (address))
319  {
321  Ipv6Address ipv6 = transport.GetIpv6 ();
322  uint16_t port = transport.GetPort ();
323  if (ipv6 == Ipv6Address::GetAny () && port == 0)
324  {
325  m_endPoint6 = m_tcp->Allocate6 ();
326  }
327  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
328  {
329  m_endPoint6 = m_tcp->Allocate6 (port);
330  }
331  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
332  {
333  m_endPoint6 = m_tcp->Allocate6 (ipv6);
334  }
335  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
336  {
337  m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
338  }
339  if (0 == m_endPoint6)
340  {
342  return -1;
343  }
344  }
345  else
346  {
348  return -1;
349  }
350  m_tcp->m_sockets.push_back (this);
351  NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
352 
353  return SetupCallback ();
354 }
355 
356 /* Inherit from Socket class: Initiate connection to a remote address:port */
357 int
359 {
360  NS_LOG_FUNCTION (this << address);
361 
362  // If haven't do so, Bind() this socket first
363  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
364  {
365  if (m_endPoint == 0)
366  {
367  if (Bind () == -1)
368  {
369  NS_ASSERT (m_endPoint == 0);
370  return -1; // Bind() failed
371  }
372  NS_ASSERT (m_endPoint != 0);
373  }
375  m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
376  m_endPoint6 = 0;
377 
378  // Get the appropriate local address and port number from the routing protocol and set up endpoint
379  if (SetupEndpoint () != 0)
380  { // Route to destination does not exist
381  return -1;
382  }
383  }
384  else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
385  {
386  // If we are operating on a v4-mapped address, translate the address to
387  // a v4 address and re-call this function
389  Ipv6Address v6Addr = transport.GetIpv6 ();
390  if (v6Addr.IsIpv4MappedAddress () == true)
391  {
392  Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
393  return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
394  }
395 
396  if (m_endPoint6 == 0)
397  {
398  if (Bind6 () == -1)
399  {
400  NS_ASSERT (m_endPoint6 == 0);
401  return -1; // Bind() failed
402  }
403  NS_ASSERT (m_endPoint6 != 0);
404  }
405  m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
406  m_endPoint = 0;
407 
408  // Get the appropriate local address and port number from the routing protocol and set up endpoint
409  if (SetupEndpoint6 () != 0)
410  { // Route to destination does not exist
411  return -1;
412  }
413  }
414  else
415  {
417  return -1;
418  }
419 
420  // Re-initialize parameters in case this socket is being reused after CLOSE
421  m_rtt->Reset ();
423 
424  // DoConnect() will do state-checking and send a SYN packet
425  return DoConnect ();
426 }
427 
428 /* Inherit from Socket class: Listen on the endpoint for an incoming connection */
429 int
431 {
432  NS_LOG_FUNCTION (this);
433  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
434  if (m_state != CLOSED)
435  {
437  return -1;
438  }
439  // In other cases, set the state to LISTEN and done
440  NS_LOG_INFO ("CLOSED -> LISTEN");
441  m_state = LISTEN;
442  return 0;
443 }
444 
445 /* Inherit from Socket class: Kill this socket and signal the peer (if any) */
446 int
448 {
449  NS_LOG_FUNCTION (this);
453  if (m_rxBuffer.Size () != 0)
454  {
455  NS_LOG_INFO ("Socket " << this << " << unread rx data during close. Sending reset");
456  SendRST ();
457  return 0;
458  }
459 
461  { // App close with pending data must wait until all data transmitted
462  if (m_closeOnEmpty == false)
463  {
464  m_closeOnEmpty = true;
465  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
466  }
467  return 0;
468  }
469  return DoClose ();
470 }
471 
472 /* Inherit from Socket class: Signal a termination of send */
473 int
475 {
476  NS_LOG_FUNCTION (this);
477 
478  //this prevents data from being added to the buffer
479  m_shutdownSend = true;
480  m_closeOnEmpty = true;
481  //if buffer is already empty, send a fin now
482  //otherwise fin will go when buffer empties.
483  if (m_txBuffer.Size () == 0)
484  {
485  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
486  {
487  NS_LOG_INFO("Emtpy tx buffer, send fin");
489 
490  if (m_state == ESTABLISHED)
491  { // On active close: I am the first one to send FIN
492  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
494  }
495  else
496  { // On passive close: Peer sent me FIN already
497  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
498  m_state = LAST_ACK;
499  }
500  }
501  }
502 
503  return 0;
504 }
505 
506 /* Inherit from Socket class: Signal a termination of receive */
507 int
509 {
510  NS_LOG_FUNCTION (this);
511  m_shutdownRecv = true;
512  return 0;
513 }
514 
515 /* Inherit from Socket class: Send a packet. Parameter flags is not used.
516  Packet has no TCP header. Invoked by upper-layer application */
517 int
518 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
519 {
520  NS_LOG_FUNCTION (this << p);
521  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
523  {
524  // Store the packet into Tx buffer
525  if (!m_txBuffer.Add (p))
526  { // TxBuffer overflow, send failed
528  return -1;
529  }
530  if (m_shutdownSend)
531  {
533  return -1;
534  }
535  // Submit the data to lower layers
536  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
537  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
538  { // Try to send the data out
540  }
541  return p->GetSize ();
542  }
543  else
544  { // Connection not established yet
546  return -1; // Send failure
547  }
548 }
549 
550 /* Inherit from Socket class: In TcpSocketBase, it is same as Send() call */
551 int
553 {
554  return Send (p, flags); // SendTo() and Send() are the same
555 }
556 
557 /* Inherit from Socket class: Return data to upper-layer application. Parameter flags
558  is not used. Data is returned as a packet of size no larger than maxSize */
560 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
561 {
562  NS_LOG_FUNCTION (this);
563  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
564  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
565  {
566  return Create<Packet> (); // Send EOF on connection close
567  }
568  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
569  if (outPacket != 0 && outPacket->GetSize () != 0)
570  {
571  SocketAddressTag tag;
572  if (m_endPoint != 0)
573  {
575  }
576  else if (m_endPoint6 != 0)
577  {
579  }
580  outPacket->AddPacketTag (tag);
581  }
582  return outPacket;
583 }
584 
585 /* Inherit from Socket class: Recv and return the remote's address */
587 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
588 {
589  NS_LOG_FUNCTION (this << maxSize << flags);
590  Ptr<Packet> packet = Recv (maxSize, flags);
591  // Null packet means no data to read, and an empty packet indicates EOF
592  if (packet != 0 && packet->GetSize () != 0)
593  {
594  if (m_endPoint != 0)
595  {
597  }
598  else if (m_endPoint6 != 0)
599  {
601  }
602  else
603  {
604  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
605  }
606  }
607  return packet;
608 }
609 
610 /* Inherit from Socket class: Get the max number of bytes an app can send */
611 uint32_t
613 {
614  NS_LOG_FUNCTION (this);
615  return m_txBuffer.Available ();
616 }
617 
618 /* Inherit from Socket class: Get the max number of bytes an app can read */
619 uint32_t
621 {
622  NS_LOG_FUNCTION (this);
623  return m_rxBuffer.Available ();
624 }
625 
626 /* Inherit from Socket class: Return local address:port */
627 int
629 {
630  NS_LOG_FUNCTION (this);
631  if (m_endPoint != 0)
632  {
634  }
635  else if (m_endPoint6 != 0)
636  {
638  }
639  else
640  { // It is possible to call this method on a socket without a name
641  // in which case, behavior is unspecified
642  // Should this return an InetSocketAddress or an Inet6SocketAddress?
643  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
644  }
645  return 0;
646 }
647 
648 /* Inherit from Socket class: Bind this socket to the specified NetDevice */
649 void
651 {
652  NS_LOG_FUNCTION (netdevice);
653  Socket::BindToNetDevice (netdevice); // Includes sanity check
654  if (m_endPoint == 0 && m_endPoint6 == 0)
655  {
656  if (Bind () == -1)
657  {
658  NS_ASSERT ((m_endPoint == 0 && m_endPoint6 == 0));
659  return;
660  }
661  NS_ASSERT ((m_endPoint != 0 && m_endPoint6 != 0));
662  }
663 
664  if (m_endPoint != 0)
665  {
666  m_endPoint->BindToNetDevice (netdevice);
667  }
668  // No BindToNetDevice() for Ipv6EndPoint
669  return;
670 }
671 
672 /* Clean up after Bind. Set up callback functions in the end-point. */
673 int
675 {
676  NS_LOG_FUNCTION (this);
677 
678  if (m_endPoint == 0 && m_endPoint6 == 0)
679  {
680  return -1;
681  }
682  if (m_endPoint != 0)
683  {
687  }
688  if (m_endPoint6 != 0)
689  {
693  }
694 
695  return 0;
696 }
697 
698 /* Perform the real connection tasks: Send SYN if allowed, RST if invalid */
699 int
701 {
702  NS_LOG_FUNCTION (this);
703 
704  // A new connection is allowed only if this socket does not have a connection
706  { // send a SYN packet and change state into SYN_SENT
708  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
709  m_state = SYN_SENT;
710  }
711  else if (m_state != TIME_WAIT)
712  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
713  // exists. We send RST, tear down everything, and close this socket.
714  SendRST ();
715  CloseAndNotify ();
716  }
717  return 0;
718 }
719 
720 /* Do the action to close the socket. Usually send a packet with appropriate
721  flags depended on the current m_state. */
722 int
724 {
725  NS_LOG_FUNCTION (this);
726  switch (m_state)
727  {
728  case SYN_RCVD:
729  case ESTABLISHED:
730  // send FIN to close the peer
732  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
734  break;
735  case CLOSE_WAIT:
736  // send FIN+ACK to close the peer
738  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
739  m_state = LAST_ACK;
740  break;
741  case SYN_SENT:
742  case CLOSING:
743  // Send RST if application closes in SYN_SENT and CLOSING
744  SendRST ();
745  CloseAndNotify ();
746  break;
747  case LISTEN:
748  case LAST_ACK:
749  // In these three states, move to CLOSED and tear down the end point
750  CloseAndNotify ();
751  break;
752  case CLOSED:
753  case FIN_WAIT_1:
754  case FIN_WAIT_2:
755  case TIME_WAIT:
756  default: /* mute compiler */
757  // Do nothing in these four states
758  break;
759  }
760  return 0;
761 }
762 
763 /* Peacefully close the socket by notifying the upper layer and deallocate end point */
764 void
766 {
767  NS_LOG_FUNCTION (this);
768 
769  if (!m_closeNotified)
770  {
772  }
773  if (m_state != TIME_WAIT)
774  {
776  }
777  m_closeNotified = true;
778  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
779  CancelAllTimers ();
780  m_state = CLOSED;
781 }
782 
783 
784 /* Tell if a sequence number range is out side the range that my rx buffer can
785  accpet */
786 bool
788 {
789  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
790  { // Rx buffer in these states are not initialized.
791  return false;
792  }
793  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
794  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
795  // sequence number must equals to m_rxBuffer.NextRxSequence ()
796  return (m_rxBuffer.NextRxSequence () != head);
797  }
798 
799  // In all other cases, check if the sequence number is in range
800  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
801 }
802 
803 /* Function called by the L3 protocol when it received a packet to pass on to
804  the TCP. This function is registered as the "RxCallback" function in
805  SetupCallback(), which invoked by Bind(), and CompleteFork() */
806 void
808  Ptr<Ipv4Interface> incomingInterface)
809 {
810  DoForwardUp (packet, header, port, incomingInterface);
811 }
812 
813 void
814 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, Ptr<Ipv6Interface> incomingInterface)
815 {
816  DoForwardUp (packet, header, port);
817 }
818 
819 void
820 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
821  uint8_t icmpType, uint8_t icmpCode,
822  uint32_t icmpInfo)
823 {
824  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
825  (uint32_t)icmpCode << icmpInfo);
826  if (!m_icmpCallback.IsNull ())
827  {
828  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
829  }
830 }
831 
832 void
833 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
834  uint8_t icmpType, uint8_t icmpCode,
835  uint32_t icmpInfo)
836 {
837  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
838  (uint32_t)icmpCode << icmpInfo);
839  if (!m_icmpCallback6.IsNull ())
840  {
841  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
842  }
843 }
844 
845 /* The real function to handle the incoming packet from lower layers. This is
846  wrapped by ForwardUp() so that this function can be overloaded by daughter
847  classes. */
848 void
850  Ptr<Ipv4Interface> incomingInterface)
851 {
852  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
854  ":" << m_endPoint->GetPeerPort () <<
855  " to " << m_endPoint->GetLocalAddress () <<
856  ":" << m_endPoint->GetLocalPort ());
857  Address fromAddress = InetSocketAddress (header.GetSource (), port);
858  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
859 
860  // Peel off TCP header and do validity checking
861  TcpHeader tcpHeader;
862  packet->RemoveHeader (tcpHeader);
863  if (tcpHeader.GetFlags () & TcpHeader::ACK)
864  {
865  EstimateRtt (tcpHeader);
866  }
867  ReadOptions (tcpHeader);
868 
869  // Update Rx window size, i.e. the flow control window
870  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
871  { // persist probes end
872  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
874  }
875  m_rWnd = tcpHeader.GetWindowSize ();
876 
877  // Discard fully out of range data packets
878  if (packet->GetSize ()
879  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
880  {
881  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
882  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
883  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
884  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
885  m_rxBuffer.MaxRxSequence () << ")");
886  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
887  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
888  {
890  }
891  return;
892  }
893 
894  // TCP state machine code in different process functions
895  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
896  switch (m_state)
897  {
898  case ESTABLISHED:
899  ProcessEstablished (packet, tcpHeader);
900  break;
901  case LISTEN:
902  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
903  break;
904  case TIME_WAIT:
905  // Do nothing
906  break;
907  case CLOSED:
908  // Send RST if the incoming packet is not a RST
909  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
910  { // Since m_endPoint is not configured yet, we cannot use SendRST here
911  TcpHeader h;
915  h.SetSourcePort (tcpHeader.GetDestinationPort ());
916  h.SetDestinationPort (tcpHeader.GetSourcePort ());
918  AddOptions (h);
919  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
920  }
921  break;
922  case SYN_SENT:
923  ProcessSynSent (packet, tcpHeader);
924  break;
925  case SYN_RCVD:
926  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
927  break;
928  case FIN_WAIT_1:
929  case FIN_WAIT_2:
930  case CLOSE_WAIT:
931  ProcessWait (packet, tcpHeader);
932  break;
933  case CLOSING:
934  ProcessClosing (packet, tcpHeader);
935  break;
936  case LAST_ACK:
937  ProcessLastAck (packet, tcpHeader);
938  break;
939  default: // mute compiler
940  break;
941  }
942 }
943 
944 void
946 {
947  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
949  ":" << m_endPoint6->GetPeerPort () <<
950  " to " << m_endPoint6->GetLocalAddress () <<
951  ":" << m_endPoint6->GetLocalPort ());
952  Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port);
954 
955  // Peel off TCP header and do validity checking
956  TcpHeader tcpHeader;
957  packet->RemoveHeader (tcpHeader);
958  if (tcpHeader.GetFlags () & TcpHeader::ACK)
959  {
960  EstimateRtt (tcpHeader);
961  }
962  ReadOptions (tcpHeader);
963 
964  // Update Rx window size, i.e. the flow control window
965  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
966  { // persist probes end
967  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
969  }
970  m_rWnd = tcpHeader.GetWindowSize ();
971 
972  // Discard fully out of range packets
973  if (packet->GetSize ()
974  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
975  {
976  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
977  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
978  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
979  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
980  m_rxBuffer.MaxRxSequence () << ")");
981  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
982  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
983  {
985  }
986  return;
987  }
988 
989  // TCP state machine code in different process functions
990  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
991  switch (m_state)
992  {
993  case ESTABLISHED:
994  ProcessEstablished (packet, tcpHeader);
995  break;
996  case LISTEN:
997  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
998  break;
999  case TIME_WAIT:
1000  // Do nothing
1001  break;
1002  case CLOSED:
1003  // Send RST if the incoming packet is not a RST
1004  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
1005  { // Since m_endPoint is not configured yet, we cannot use SendRST here
1006  TcpHeader h;
1010  h.SetSourcePort (tcpHeader.GetDestinationPort ());
1011  h.SetDestinationPort (tcpHeader.GetSourcePort ());
1013  AddOptions (h);
1014  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestinationAddress (), header.GetSourceAddress (), m_boundnetdevice);
1015  }
1016  break;
1017  case SYN_SENT:
1018  ProcessSynSent (packet, tcpHeader);
1019  break;
1020  case SYN_RCVD:
1021  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
1022  break;
1023  case FIN_WAIT_1:
1024  case FIN_WAIT_2:
1025  case CLOSE_WAIT:
1026  ProcessWait (packet, tcpHeader);
1027  break;
1028  case CLOSING:
1029  ProcessClosing (packet, tcpHeader);
1030  break;
1031  case LAST_ACK:
1032  ProcessLastAck (packet, tcpHeader);
1033  break;
1034  default: // mute compiler
1035  break;
1036  }
1037 }
1038 
1039 /* Received a packet upon ESTABLISHED state. This function is mimicking the
1040  role of tcp_rcv_established() in tcp_input.c in Linux kernel. */
1041 void
1043 {
1044  NS_LOG_FUNCTION (this << tcpHeader);
1045 
1046  // Extract the flags. PSH and URG are not honoured.
1047  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1048 
1049  // Different flags are different events
1050  if (tcpflags == TcpHeader::ACK)
1051  {
1052  ReceivedAck (packet, tcpHeader);
1053  }
1054  else if (tcpflags == TcpHeader::SYN)
1055  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
1056  // respond with a SYN+ACK. But it is not a legal state transition as of
1057  // RFC793. Thus this is ignored.
1058  }
1059  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1060  { // No action for received SYN+ACK, it is probably a duplicated packet
1061  }
1062  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1063  { // Received FIN or FIN+ACK, bring down this socket nicely
1064  PeerClose (packet, tcpHeader);
1065  }
1066  else if (tcpflags == 0)
1067  { // No flags means there is only data
1068  ReceivedData (packet, tcpHeader);
1069  if (m_rxBuffer.Finished ())
1070  {
1071  PeerClose (packet, tcpHeader);
1072  }
1073  }
1074  else
1075  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1076  if (tcpflags != TcpHeader::RST)
1077  { // this must be an invalid flag, send reset
1078  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1079  SendRST ();
1080  }
1081  CloseAndNotify ();
1082  }
1083 }
1084 
1085 /* Process the newly received ACK */
1086 void
1088 {
1089  NS_LOG_FUNCTION (this << tcpHeader);
1090 
1091  // Received ACK. Compare the ACK number against highest unacked seqno
1092  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1093  { // Ignore if no ACK flag
1094  }
1095  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1096  { // Case 1: Old ACK, ignored.
1097  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1098  }
1099  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1100  { // Case 2: Potentially a duplicated ACK
1101  if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0)
1102  {
1103  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1104  DupAck (tcpHeader, ++m_dupAckCount);
1105  }
1106  // otherwise, the ACK is precisely equal to the nextTxSequence
1107  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1108  }
1109  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1110  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1111  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1112  NewAck (tcpHeader.GetAckNumber ());
1113  m_dupAckCount = 0;
1114  }
1115  // If there is any data piggybacked, store it into m_rxBuffer
1116  if (packet->GetSize () > 0)
1117  {
1118  ReceivedData (packet, tcpHeader);
1119  }
1120 }
1121 
1122 /* Received a packet upon LISTEN state. */
1123 void
1125  const Address& fromAddress, const Address& toAddress)
1126 {
1127  NS_LOG_FUNCTION (this << tcpHeader);
1128 
1129  // Extract the flags. PSH and URG are not honoured.
1130  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1131 
1132  // Fork a socket if received a SYN. Do nothing otherwise.
1133  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1134  if (tcpflags != TcpHeader::SYN)
1135  {
1136  return;
1137  }
1138 
1139  // Call socket's notify function to let the server app know we got a SYN
1140  // If the server app refuses the connection, do nothing
1141  if (!NotifyConnectionRequest (fromAddress))
1142  {
1143  return;
1144  }
1145  // Clone the socket, simulate fork
1146  Ptr<TcpSocketBase> newSock = Fork ();
1147  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1149  packet, tcpHeader, fromAddress, toAddress);
1150 }
1151 
1152 /* Received a packet upon SYN_SENT */
1153 void
1155 {
1156  NS_LOG_FUNCTION (this << tcpHeader);
1157 
1158  // Extract the flags. PSH and URG are not honoured.
1159  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1160 
1161  if (tcpflags == 0)
1162  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1163  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1164  m_state = ESTABLISHED;
1165  m_connected = true;
1166  m_retxEvent.Cancel ();
1168  ReceivedData (packet, tcpHeader);
1170  }
1171  else if (tcpflags == TcpHeader::ACK)
1172  { // Ignore ACK in SYN_SENT
1173  }
1174  else if (tcpflags == TcpHeader::SYN)
1175  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1176  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1177  m_state = SYN_RCVD;
1181  }
1182  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1183  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1184  { // Handshake completed
1185  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1186  m_state = ESTABLISHED;
1187  m_connected = true;
1188  m_retxEvent.Cancel ();
1195  // Always respond to first data packet to speed up the connection.
1196  // Remove to get the behaviour of old NS-3 code.
1198  }
1199  else
1200  { // Other in-sequence input
1201  if (tcpflags != TcpHeader::RST)
1202  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1203  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1204  SendRST ();
1205  }
1206  CloseAndNotify ();
1207  }
1208 }
1209 
1210 /* Received a packet upon SYN_RCVD */
1211 void
1213  const Address& fromAddress, const Address& toAddress)
1214 {
1215  NS_LOG_FUNCTION (this << tcpHeader);
1216 
1217  // Extract the flags. PSH and URG are not honoured.
1218  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1219 
1220  if (tcpflags == 0
1221  || (tcpflags == TcpHeader::ACK
1222  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1223  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1224  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1225  // handshake is completed nicely.
1226  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1227  m_state = ESTABLISHED;
1228  m_connected = true;
1229  m_retxEvent.Cancel ();
1232  if (m_endPoint)
1233  {
1234  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1235  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1236  }
1237  else if (m_endPoint6)
1238  {
1239  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1240  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1241  }
1242  // Always respond to first data packet to speed up the connection.
1243  // Remove to get the behaviour of old NS-3 code.
1245  ReceivedAck (packet, tcpHeader);
1246  NotifyNewConnectionCreated (this, fromAddress);
1247  // As this connection is established, the socket is available to send data now
1248  if (GetTxAvailable () > 0)
1249  {
1251  }
1252  }
1253  else if (tcpflags == TcpHeader::SYN)
1254  { // Probably the peer lost my SYN+ACK
1257  }
1258  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1259  {
1260  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1261  { // In-sequence FIN before connection complete. Set up connection and close.
1262  m_connected = true;
1263  m_retxEvent.Cancel ();
1266  if (m_endPoint)
1267  {
1268  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1269  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1270  }
1271  else if (m_endPoint6)
1272  {
1273  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1274  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1275  }
1276  PeerClose (packet, tcpHeader);
1277  }
1278  }
1279  else
1280  { // Other in-sequence input
1281  if (tcpflags != TcpHeader::RST)
1282  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1283  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1284  if (m_endPoint)
1285  {
1286  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1287  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1288  }
1289  else if (m_endPoint6)
1290  {
1291  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1292  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1293  }
1294  SendRST ();
1295  }
1296  CloseAndNotify ();
1297  }
1298 }
1299 
1300 /* Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */
1301 void
1303 {
1304  NS_LOG_FUNCTION (this << tcpHeader);
1305 
1306  // Extract the flags. PSH and URG are not honoured.
1307  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1308 
1309  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1310  { // Bare data, accept it
1311  ReceivedData (packet, tcpHeader);
1312  }
1313  else if (tcpflags == TcpHeader::ACK)
1314  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1315  ReceivedAck (packet, tcpHeader);
1316  if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1317  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1318  { // This ACK corresponds to the FIN sent
1319  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1320  m_state = FIN_WAIT_2;
1321  }
1322  }
1323  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1324  { // Got FIN, respond with ACK and move to next state
1325  if (tcpflags & TcpHeader::ACK)
1326  { // Process the ACK first
1327  ReceivedAck (packet, tcpHeader);
1328  }
1330  }
1331  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1332  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1333  return;
1334  }
1335  else
1336  { // This is a RST or bad flags
1337  if (tcpflags != TcpHeader::RST)
1338  {
1339  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1340  SendRST ();
1341  }
1342  CloseAndNotify ();
1343  return;
1344  }
1345 
1346  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1347  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1348  {
1349  if (m_state == FIN_WAIT_1)
1350  {
1351  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1352  m_state = CLOSING;
1353  if (m_txBuffer.Size () == 0
1354  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1355  { // This ACK corresponds to the FIN sent
1356  TimeWait ();
1357  }
1358  }
1359  else if (m_state == FIN_WAIT_2)
1360  {
1361  TimeWait ();
1362  }
1364  if (!m_shutdownRecv)
1365  {
1366  NotifyDataRecv ();
1367  }
1368  }
1369 }
1370 
1371 /* Received a packet upon CLOSING */
1372 void
1374 {
1375  NS_LOG_FUNCTION (this << tcpHeader);
1376 
1377  // Extract the flags. PSH and URG are not honoured.
1378  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1379 
1380  if (tcpflags == TcpHeader::ACK)
1381  {
1382  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1383  { // This ACK corresponds to the FIN sent
1384  TimeWait ();
1385  }
1386  }
1387  else
1388  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1389  // anyone. If anything other than ACK is received, respond with a reset.
1390  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1391  { // FIN from the peer as well. We can close immediately.
1393  }
1394  else if (tcpflags != TcpHeader::RST)
1395  { // Receive of SYN or SYN+ACK or bad flags or pure data
1396  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1397  SendRST ();
1398  }
1399  CloseAndNotify ();
1400  }
1401 }
1402 
1403 /* Received a packet upon LAST_ACK */
1404 void
1406 {
1407  NS_LOG_FUNCTION (this << tcpHeader);
1408 
1409  // Extract the flags. PSH and URG are not honoured.
1410  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1411 
1412  if (tcpflags == 0)
1413  {
1414  ReceivedData (packet, tcpHeader);
1415  }
1416  else if (tcpflags == TcpHeader::ACK)
1417  {
1418  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1419  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1420  CloseAndNotify ();
1421  }
1422  }
1423  else if (tcpflags == TcpHeader::FIN)
1424  { // Received FIN again, the peer probably lost the FIN+ACK
1426  }
1427  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1428  {
1429  CloseAndNotify ();
1430  }
1431  else
1432  { // Received a SYN or SYN+ACK or bad flags
1433  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1434  SendRST ();
1435  CloseAndNotify ();
1436  }
1437 }
1438 
1439 /* Peer sent me a FIN. Remember its sequence in rx buffer. */
1440 void
1442 {
1443  NS_LOG_FUNCTION (this << tcpHeader);
1444 
1445  // Ignore all out of range packets
1446  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1447  || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1448  {
1449  return;
1450  }
1451  // For any case, remember the FIN position in rx buffer first
1453  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1454  // If there is any piggybacked data, process it
1455  if (p->GetSize ())
1456  {
1457  ReceivedData (p, tcpHeader);
1458  }
1459  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1460  if (!m_rxBuffer.Finished ())
1461  {
1462  return;
1463  }
1464 
1465  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1466  if (m_state == FIN_WAIT_1)
1467  {
1468  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1469  m_state = CLOSING;
1470  return;
1471  }
1472 
1473  DoPeerClose (); // Change state, respond with ACK
1474 }
1475 
1476 /* Received a in-sequence FIN. Close down this socket. */
1477 void
1479 {
1481 
1482  // Move the state to CLOSE_WAIT
1483  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1484  m_state = CLOSE_WAIT;
1485 
1486  if (!m_closeNotified)
1487  {
1488  // The normal behaviour for an application is that, when the peer sent a in-sequence
1489  // FIN, the app should prepare to close. The app has two choices at this point: either
1490  // respond with ShutdownSend() call to declare that it has nothing more to send and
1491  // the socket can be closed immediately; or remember the peer's close request, wait
1492  // until all its existing data are pushed into the TCP socket, then call Close()
1493  // explicitly.
1494  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1495  NotifyNormalClose ();
1496  m_closeNotified = true;
1497  }
1498  if (m_shutdownSend)
1499  { // The application declares that it would not sent any more, close this socket
1500  Close ();
1501  }
1502  else
1503  { // Need to ack, the application will close later
1505  }
1506  if (m_state == LAST_ACK)
1507  {
1508  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1509  m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
1511  }
1512 }
1513 
1514 /* Kill this socket. This is a callback function configured to m_endpoint in
1515  SetupCallback(), invoked when the endpoint is destroyed. */
1516 void
1518 {
1519  NS_LOG_FUNCTION (this);
1520  m_endPoint = 0;
1521  if (m_tcp != 0)
1522  {
1523  std::vector<Ptr<TcpSocketBase> >::iterator it
1524  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1525  if (it != m_tcp->m_sockets.end ())
1526  {
1527  m_tcp->m_sockets.erase (it);
1528  }
1529  }
1530  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1531  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1532  CancelAllTimers ();
1533 }
1534 
1535 /* Kill this socket. This is a callback function configured to m_endpoint in
1536  SetupCallback(), invoked when the endpoint is destroyed. */
1537 void
1539 {
1540  NS_LOG_FUNCTION (this);
1541  m_endPoint6 = 0;
1542  if (m_tcp != 0)
1543  {
1544  std::vector<Ptr<TcpSocketBase> >::iterator it
1545  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1546  if (it != m_tcp->m_sockets.end ())
1547  {
1548  m_tcp->m_sockets.erase (it);
1549  }
1550  }
1551  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1552  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1553  CancelAllTimers ();
1554 }
1555 
1556 /* Send an empty packet with specified TCP flags */
1557 void
1559 {
1560  NS_LOG_FUNCTION (this << (uint32_t)flags);
1561  Ptr<Packet> p = Create<Packet> ();
1562  TcpHeader header;
1564 
1565  /*
1566  * Add tags for each socket option.
1567  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1568  * if both options are set. Once the packet got to layer three, only
1569  * the corresponding tags will be read.
1570  */
1571  if (IsManualIpTos ())
1572  {
1573  SocketIpTosTag ipTosTag;
1574  ipTosTag.SetTos (GetIpTos ());
1575  p->AddPacketTag (ipTosTag);
1576  }
1577 
1578  if (IsManualIpv6Tclass ())
1579  {
1580  SocketIpv6TclassTag ipTclassTag;
1581  ipTclassTag.SetTclass (GetIpv6Tclass ());
1582  p->AddPacketTag (ipTclassTag);
1583  }
1584 
1585  if (IsManualIpTtl ())
1586  {
1587  SocketIpTtlTag ipTtlTag;
1588  ipTtlTag.SetTtl (GetIpTtl ());
1589  p->AddPacketTag (ipTtlTag);
1590  }
1591 
1592  if (IsManualIpv6HopLimit ())
1593  {
1594  SocketIpv6HopLimitTag ipHopLimitTag;
1595  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1596  p->AddPacketTag (ipHopLimitTag);
1597  }
1598 
1599  if (m_endPoint == 0 && m_endPoint6 == 0)
1600  {
1601  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1602  return;
1603  }
1604  if (flags & TcpHeader::FIN)
1605  {
1606  flags |= TcpHeader::ACK;
1607  }
1608  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1609  {
1610  ++s;
1611  }
1612 
1613  header.SetFlags (flags);
1614  header.SetSequenceNumber (s);
1615  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1616  if (m_endPoint != 0)
1617  {
1618  header.SetSourcePort (m_endPoint->GetLocalPort ());
1619  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1620  }
1621  else
1622  {
1623  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1624  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1625  }
1626  header.SetWindowSize (AdvertisedWindowSize ());
1627  AddOptions (header);
1628  m_rto = m_rtt->RetransmitTimeout ();
1629  bool hasSyn = flags & TcpHeader::SYN;
1630  bool hasFin = flags & TcpHeader::FIN;
1631  bool isAck = flags == TcpHeader::ACK;
1632  if (hasSyn)
1633  {
1634  if (m_cnCount == 0)
1635  { // No more connection retries, give up
1636  NS_LOG_LOGIC ("Connection failed.");
1637  CloseAndNotify ();
1638  return;
1639  }
1640  else
1641  { // Exponential backoff of connection time out
1642  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1643  m_rto = m_cnTimeout * backoffCount;
1644  m_cnCount--;
1645  }
1646  }
1647  if (m_endPoint != 0)
1648  {
1649  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1651  }
1652  else
1653  {
1654  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1656  }
1657  if (flags & TcpHeader::ACK)
1658  { // If sending an ACK, cancel the delay ACK as well
1659  m_delAckEvent.Cancel ();
1660  m_delAckCount = 0;
1661  }
1662  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1663  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1664  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1665  << Simulator::Now ().GetSeconds () << " to expire at time "
1666  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1668  }
1669 }
1670 
1671 /* This function closes the endpoint completely. Called upon RST_TX action. */
1672 void
1674 {
1675  NS_LOG_FUNCTION (this);
1677  NotifyErrorClose ();
1678  DeallocateEndPoint ();
1679 }
1680 
1681 /* Deallocate the end point and cancel all the timers */
1682 void
1684 {
1685  if (m_endPoint != 0)
1686  {
1687  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1688  m_tcp->DeAllocate (m_endPoint);
1689  m_endPoint = 0;
1690  std::vector<Ptr<TcpSocketBase> >::iterator it
1691  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1692  if (it != m_tcp->m_sockets.end ())
1693  {
1694  m_tcp->m_sockets.erase (it);
1695  }
1696  CancelAllTimers ();
1697  }
1698  if (m_endPoint6 != 0)
1699  {
1700  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1701  m_tcp->DeAllocate (m_endPoint6);
1702  m_endPoint6 = 0;
1703  std::vector<Ptr<TcpSocketBase> >::iterator it
1704  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1705  if (it != m_tcp->m_sockets.end ())
1706  {
1707  m_tcp->m_sockets.erase (it);
1708  }
1709  CancelAllTimers ();
1710  }
1711 }
1712 
1713 /* Configure the endpoint to a local address. Called by Connect() if Bind() didn't specify one. */
1714 int
1716 {
1717  NS_LOG_FUNCTION (this);
1718  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1719  NS_ASSERT (ipv4 != 0);
1720  if (ipv4->GetRoutingProtocol () == 0)
1721  {
1722  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1723  }
1724  // Create a dummy packet, then ask the routing function for the best output
1725  // interface's address
1726  Ipv4Header header;
1728  Socket::SocketErrno errno_;
1729  Ptr<Ipv4Route> route;
1731  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1732  if (route == 0)
1733  {
1734  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1735  NS_LOG_ERROR (errno_);
1736  m_errno = errno_;
1737  return -1;
1738  }
1739  NS_LOG_LOGIC ("Route exists");
1740  m_endPoint->SetLocalAddress (route->GetSource ());
1741  return 0;
1742 }
1743 
1744 int
1746 {
1747  NS_LOG_FUNCTION (this);
1749  NS_ASSERT (ipv6 != 0);
1750  if (ipv6->GetRoutingProtocol () == 0)
1751  {
1752  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1753  }
1754  // Create a dummy packet, then ask the routing function for the best output
1755  // interface's address
1756  Ipv6Header header;
1758  Socket::SocketErrno errno_;
1759  Ptr<Ipv6Route> route;
1761  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1762  if (route == 0)
1763  {
1764  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1765  NS_LOG_ERROR (errno_);
1766  m_errno = errno_;
1767  return -1;
1768  }
1769  NS_LOG_LOGIC ("Route exists");
1770  m_endPoint6->SetLocalAddress (route->GetSource ());
1771  return 0;
1772 }
1773 
1774 /* This function is called only if a SYN received in LISTEN state. After
1775  TcpSocketBase cloned, allocate a new end point to handle the incoming
1776  connection and send a SYN+ACK to complete the handshake. */
1777 void
1779  const Address& fromAddress, const Address& toAddress)
1780 {
1781  // Get port and address from peer (connecting host)
1782  if (InetSocketAddress::IsMatchingType (toAddress))
1783  {
1784  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1785  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1786  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1787  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1788  m_endPoint6 = 0;
1789  }
1790  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1791  {
1792  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1793  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1794  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1795  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1796  m_endPoint = 0;
1797  }
1798  m_tcp->m_sockets.push_back (this);
1799 
1800  // Change the cloned socket from LISTEN state to SYN_RCVD
1801  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1802  m_state = SYN_RCVD;
1804  SetupCallback ();
1805  // Set the sequence number and send SYN+ACK
1808 }
1809 
1810 void
1812 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1813  // be called as a scheduled event
1815  // The if-block below was moved from ProcessSynSent() to here because we need
1816  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1817  // reflect the behaviour in the real world.
1818  if (GetTxAvailable () > 0)
1819  {
1821  }
1822 }
1823 
1824 /* Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
1825  TCP header, and send to TcpL4Protocol */
1826 uint32_t
1827 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1828 {
1829  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1830 
1831  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
1832  uint32_t sz = p->GetSize (); // Size of packet
1833  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1834  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
1835 
1836  /*
1837  * Add tags for each socket option.
1838  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1839  * if both options are set. Once the packet got to layer three, only
1840  * the corresponding tags will be read.
1841  */
1842  if (IsManualIpTos ())
1843  {
1844  SocketIpTosTag ipTosTag;
1845  ipTosTag.SetTos (GetIpTos ());
1846  p->AddPacketTag (ipTosTag);
1847  }
1848 
1849  if (IsManualIpv6Tclass ())
1850  {
1851  SocketIpv6TclassTag ipTclassTag;
1852  ipTclassTag.SetTclass (GetIpv6Tclass ());
1853  p->AddPacketTag (ipTclassTag);
1854  }
1855 
1856  if (IsManualIpTtl ())
1857  {
1858  SocketIpTtlTag ipTtlTag;
1859  ipTtlTag.SetTtl (GetIpTtl ());
1860  p->AddPacketTag (ipTtlTag);
1861  }
1862 
1863  if (IsManualIpv6HopLimit ())
1864  {
1865  SocketIpv6HopLimitTag ipHopLimitTag;
1866  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1867  p->AddPacketTag (ipHopLimitTag);
1868  }
1869 
1870  if (m_closeOnEmpty && (remainingData == 0))
1871  {
1872  flags |= TcpHeader::FIN;
1873  if (m_state == ESTABLISHED)
1874  { // On active close: I am the first one to send FIN
1875  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1876  m_state = FIN_WAIT_1;
1877  }
1878  else if (m_state == CLOSE_WAIT)
1879  { // On passive close: Peer sent me FIN already
1880  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1881  m_state = LAST_ACK;
1882  }
1883  }
1884  TcpHeader header;
1885  header.SetFlags (flags);
1886  header.SetSequenceNumber (seq);
1888  if (m_endPoint)
1889  {
1890  header.SetSourcePort (m_endPoint->GetLocalPort ());
1892  }
1893  else
1894  {
1895  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1897  }
1898  header.SetWindowSize (AdvertisedWindowSize ());
1899  AddOptions (header);
1900  if (m_retxEvent.IsExpired () )
1901  { // Schedule retransmit
1902  m_rto = m_rtt->RetransmitTimeout ();
1903  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
1904  Simulator::Now ().GetSeconds () << " to expire at time " <<
1905  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
1907  }
1908  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1909  if (m_endPoint)
1910  {
1911  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1913  }
1914  else
1915  {
1916  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1918  }
1919  m_rtt->SentSeq (seq, sz); // notify the RTT
1920  // Notify the application of the data being sent unless this is a retransmit
1921  if (seq == m_nextTxSequence)
1922  {
1924  }
1925  // Update highTxMark
1926  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1927  return sz;
1928 }
1929 
1930 /* Send as much pending data as possible according to the Tx window. Note that
1931  * this function did not implement the PSH flag
1932  */
1933 bool
1935 {
1936  NS_LOG_FUNCTION (this << withAck);
1937  if (m_txBuffer.Size () == 0)
1938  {
1939  return false; // Nothing to send
1940 
1941  }
1942  if (m_endPoint == 0 && m_endPoint6 == 0)
1943  {
1944  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
1945  return false; // Is this the right way to handle this condition?
1946  }
1947  uint32_t nPacketsSent = 0;
1949  {
1950  uint32_t w = AvailableWindow (); // Get available window size
1951  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
1952  " w " << w <<
1953  " rxwin " << m_rWnd <<
1954  " segsize " << m_segmentSize <<
1955  " nextTxSeq " << m_nextTxSequence <<
1956  " highestRxAck " << m_txBuffer.HeadSequence () <<
1957  " pd->Size " << m_txBuffer.Size () <<
1958  " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
1959  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
1961  {
1962  break; // No more
1963  }
1964  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
1965  // in the buffer and the amount of data to send is less than one segment
1966  if (!m_noDelay && UnAckDataCount () > 0
1968  {
1969  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
1970  break;
1971  }
1972  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
1973  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
1974  nPacketsSent++; // Count sent this loop
1975  m_nextTxSequence += sz; // Advance next tx sequence
1976  }
1977  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
1978  return (nPacketsSent > 0);
1979 }
1980 
1981 uint32_t
1983 {
1984  NS_LOG_FUNCTION (this);
1986 }
1987 
1988 uint32_t
1990 {
1991  NS_LOG_FUNCTION (this);
1992  return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
1993 }
1994 
1995 uint32_t
1997 {
1998  NS_LOG_FUNCTION (this);
1999  return m_rWnd;
2000 }
2001 
2002 uint32_t
2004 {
2006  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
2007  uint32_t win = Window (); // Number of bytes allowed to be outstanding
2008  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
2009  return (win < unack) ? 0 : (win - unack);
2010 }
2011 
2012 uint16_t
2014 {
2015  return std::min (m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size (), (uint32_t)m_maxWinSize);
2016 }
2017 
2018 // Receipt of new packet, put into Rx buffer
2019 void
2021 {
2022  NS_LOG_FUNCTION (this << tcpHeader);
2023  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
2024  " ack " << tcpHeader.GetAckNumber () <<
2025  " pkt size " << p->GetSize () );
2026 
2027  // Put into Rx buffer
2028  SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
2029  if (!m_rxBuffer.Add (p, tcpHeader))
2030  { // Insert failed: No data or RX buffer full
2032  return;
2033  }
2034  // Now send a new ACK packet acknowledging all received and delivered data
2035  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
2036  { // A gap exists in the buffer, or we filled a gap: Always ACK
2038  }
2039  else
2040  { // In-sequence packet: ACK if delayed ack count allows
2042  {
2043  m_delAckEvent.Cancel ();
2044  m_delAckCount = 0;
2046  }
2047  else if (m_delAckEvent.IsExpired ())
2048  {
2051  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
2052  }
2053  }
2054  // Notify app to receive if necessary
2055  if (expectedSeq < m_rxBuffer.NextRxSequence ())
2056  { // NextRxSeq advanced, we have something to send to the app
2057  if (!m_shutdownRecv)
2058  {
2059  NotifyDataRecv ();
2060  }
2061  // Handle exceptions
2062  if (m_closeNotified)
2063  {
2064  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
2065  }
2066  // If we received FIN before and now completed all "holes" in rx buffer,
2067  // invoke peer close procedure
2068  if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2069  {
2070  DoPeerClose ();
2071  }
2072  }
2073 }
2074 
2075 /* Called by ForwardUp() to estimate RTT */
2076 void
2078 {
2079  // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
2080  // (which should be ignored) is handled by m_rtt. Once timestamp option
2081  // is implemented, this function would be more elaborated.
2082  Time nextRtt = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
2083 
2084  //nextRtt will be zero for dup acks. Don't want to update lastRtt in that case
2085  //but still needed to do list clearing that is done in AckSeq.
2086  if(nextRtt != 0)
2087  {
2088  m_lastRtt = nextRtt;
2089  NS_LOG_FUNCTION(this << m_lastRtt);
2090  }
2091 
2092 }
2093 
2094 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
2095 // when the three-way handshake completed. This cancels retransmission timer
2096 // and advances Tx window
2097 void
2099 {
2100  NS_LOG_FUNCTION (this << ack);
2101 
2102  if (m_state != SYN_RCVD)
2103  { // Set RTO unless the ACK is received in SYN_RCVD state
2104  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2105  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2106  m_retxEvent.Cancel ();
2107  // On recieving a "New" ack we restart retransmission timer .. RFC 2988
2108  m_rto = m_rtt->RetransmitTimeout ();
2109  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
2110  Simulator::Now ().GetSeconds () << " to expire at time " <<
2111  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2113  }
2114  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
2115  { // Zero window: Enter persist state to send 1 byte to probe
2116  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
2117  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
2118  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2119  m_retxEvent.Cancel ();
2120  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
2121  Simulator::Now ().GetSeconds () << " to expire at time " <<
2122  (Simulator::Now () + m_persistTimeout).GetSeconds ());
2125  }
2126  // Note the highest ACK and tell app to send more
2127  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2128  " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
2129  m_txBuffer.DiscardUpTo (ack);
2130  if (GetTxAvailable () > 0)
2131  {
2133  }
2134  if (ack > m_nextTxSequence)
2135  {
2136  m_nextTxSequence = ack; // If advanced
2137  }
2138  if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2139  { // No retransmit timer if no data to retransmit
2140  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2141  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2142  m_retxEvent.Cancel ();
2143  }
2144  // Try to send more data
2146 }
2147 
2148 // Retransmit timeout
2149 void
2151 {
2152  NS_LOG_FUNCTION (this);
2153  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2154  // If erroneous timeout in closed/timed-wait state, just return
2155  if (m_state == CLOSED || m_state == TIME_WAIT)
2156  {
2157  return;
2158  }
2159  // If all data are received (non-closing socket and nothing to send), just return
2161  {
2162  return;
2163  }
2164 
2165  Retransmit ();
2166 }
2167 
2168 void
2170 {
2171  m_delAckCount = 0;
2173 }
2174 
2175 void
2177 {
2178  NS_LOG_FUNCTION (this);
2179 
2181  if (m_state == LAST_ACK)
2182  {
2183  CloseAndNotify ();
2184  }
2185  if (!m_closeNotified)
2186  {
2187  m_closeNotified = true;
2188  }
2189 }
2190 
2191 // Send 1-byte data to probe for the window size at the receiver when
2192 // the local knowledge tells that the receiver has zero window size
2193 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2194 void
2196 {
2197  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2198  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2200  TcpHeader tcpHeader;
2201  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2202  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2203  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2204  if (m_endPoint != 0)
2205  {
2206  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2207  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2208  }
2209  else
2210  {
2211  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2212  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2213  }
2214  AddOptions (tcpHeader);
2215 
2216  if (m_endPoint != 0)
2217  {
2218  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2220  }
2221  else
2222  {
2223  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2225  }
2226  NS_LOG_LOGIC ("Schedule persist timeout at time "
2227  << Simulator::Now ().GetSeconds () << " to expire at time "
2228  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2230 }
2231 
2232 void
2234 {
2235  m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
2236  m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
2237  m_dupAckCount = 0;
2238  DoRetransmit (); // Retransmit the packet
2239 }
2240 
2241 void
2243 {
2244  NS_LOG_FUNCTION (this);
2245  // Retransmit SYN packet
2246  if (m_state == SYN_SENT)
2247  {
2248  if (m_cnCount > 0)
2249  {
2251  }
2252  else
2253  {
2255  }
2256  return;
2257  }
2258  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2259  if (m_txBuffer.Size () == 0)
2260  {
2261  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2262  { // Must have lost FIN, re-send
2264  }
2265  return;
2266  }
2267  // Retransmit a data packet: Call SendDataPacket
2268  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
2269  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
2270  // In case of RTO, advance m_nextTxSequence
2271  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
2272 
2273 }
2274 
2275 void
2277 {
2278  m_retxEvent.Cancel ();
2280  m_delAckEvent.Cancel ();
2283 }
2284 
2285 /* Move TCP to Time_Wait state and schedule a transition to Closed state */
2286 void
2288 {
2289  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2290  m_state = TIME_WAIT;
2291  CancelAllTimers ();
2292  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2293  // according to RFC793, p.28
2294  m_timewaitEvent = Simulator::Schedule (Seconds (2 * m_msl),
2296 }
2297 
2298 /* Below are the attribute get/set functions */
2299 
2300 void
2302 {
2304 }
2305 
2306 uint32_t
2308 {
2309  return m_txBuffer.MaxBufferSize ();
2310 }
2311 
2312 void
2314 {
2316 }
2317 
2318 uint32_t
2320 {
2321  return m_rxBuffer.MaxBufferSize ();
2322 }
2323 
2324 void
2326 {
2327  m_segmentSize = size;
2328  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2329 }
2330 
2331 uint32_t
2333 {
2334  return m_segmentSize;
2335 }
2336 
2337 void
2339 {
2340  m_cnTimeout = timeout;
2341 }
2342 
2343 Time
2345 {
2346  return m_cnTimeout;
2347 }
2348 
2349 void
2351 {
2352  m_cnRetries = count;
2353 }
2354 
2355 uint32_t
2357 {
2358  return m_cnRetries;
2359 }
2360 
2361 void
2363 {
2365 }
2366 
2367 Time
2369 {
2370  return m_delAckTimeout;
2371 }
2372 
2373 void
2375 {
2376  m_delAckMaxCount = count;
2377 }
2378 
2379 uint32_t
2381 {
2382  return m_delAckMaxCount;
2383 }
2384 
2385 void
2387 {
2388  m_noDelay = noDelay;
2389 }
2390 
2391 bool
2393 {
2394  return m_noDelay;
2395 }
2396 
2397 void
2399 {
2401 }
2402 
2403 Time
2405 {
2406  return m_persistTimeout;
2407 }
2408 
2409 bool
2411 {
2412  // Broadcast is not implemented. Return true only if allowBroadcast==false
2413  return (!allowBroadcast);
2414 }
2415 
2416 bool
2418 {
2419  return false;
2420 }
2421 
2422 /* Placeholder function for future extension that reads more from the TCP header */
2423 void
2425 {
2426 }
2427 
2428 /* Placeholder function for future extension that changes the TCP header */
2429 void
2431 {
2432 }
2433 
2434 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Definition: simulator.cc:189
Ipv6Address GetLocalAddress()
Get the local address.
void PeerClose(Ptr< Packet > p, const TcpHeader &tcpHeader)
Received a FIN from peer, notify rx buffer.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition: socket.cc:821
void ProcessListen(Ptr< Packet > packet, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Received a packet upon LISTEN state.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
virtual int Listen(void)
Listen for incoming connections.
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
bool IsManualIpTtl(void) const
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:383
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
an Inet address class
virtual int GetSockName(Address &address) const
Get socket address.
Ipv4Address GetIpv4(void) const
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
static Ipv4Address GetAny(void)
uint32_t Size(void) const
Returns total number of bytes in this Tx buffer.
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void ProcessWait(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon CLOSE_WAIT, FIN_WAIT_1, FIN_WAIT_2.
SequenceNumber32 GetSequenceNumber() const
Definition: tcp-header.cc:97
virtual uint8_t GetIpTtl(void) const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:471
virtual uint16_t AdvertisedWindowSize(void)
The amount of Rx window announced to the peer.
Callback template class.
Definition: callback.h:920
bool Add(Ptr< Packet > p, TcpHeader const &tcph)
Insert a packet into the buffer and update the availBytes counter to reflect the number of bytes read...
NS_LOG_COMPONENT_DEFINE("TcpSocketBase")
bool m_noDelay
Set to true to disable Nagle's algorithm.
virtual uint32_t GetSegSize(void) const
Get the segment size.
uint8_t GetIpTos(void) const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:404
uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck)
Extract at most maxSize bytes from the TxBuffer at sequence seq, add the TCP header, and send to TcpL4Protocol.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:1044
void DiscardUpTo(const SequenceNumber32 &seq)
Discard data up to but not including this sequence number.
(abstract) base class of all TcpSockets
Definition: tcp-socket.h:64
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
uint8_t GetFlags() const
Definition: tcp-header.cc:109
virtual ~TcpSocketBase(void)
TracedValue< Time > m_lastRtt
Last RTT sample collected.
void NotifyDataRecv(void)
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:305
virtual int ShutdownRecv(void)
uint32_t SizeFromSequence(const SequenceNumber32 &seq) const
Returns the number of bytes from the buffer in the range [seq, tailSequence)
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Set the reception callback.
TcpSocketBase(void)
Create an unbound TCP socket.
EventId m_retxEvent
Retransmission event.
SequenceNumber32 HeadSequence(void) const
Returns the first byte's sequence number.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:175
IPv6 layer implementation.
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
SequenceNumber32 GetAckNumber() const
Definition: tcp-header.cc:101
void ForwardUp6(Ptr< Packet > packet, Ipv6Header header, uint16_t port, Ptr< Ipv6Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
void SetAddress(Address addr)
Set the tag's address.
Definition: socket.cc:523
virtual void SetPersistTimeout(Time timeout)
Set the timout for persistent connection.
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
virtual bool GetAllowBroadcast(void) const
Query whether broadcast datagram transmissions are allowed.
EventId m_timewaitEvent
TIME_WAIT expiration event: Move this socket to CLOSED state.
void NotifyConnectionFailed(void)
Notify through the callback (if set) that the connection has not been established due to an error...
Definition: socket.cc:227
static TypeId GetTypeId(void)
Get the type ID.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
uint32_t Available() const
Get the actual number of bytes available to be read.
#define NS_ASSERT(condition)
Definition: assert.h:64
void SendRST(void)
Send reset and tear down this socket.
uint32_t MaxBufferSize(void) const
Returns the Tx window size.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
uint16_t m_maxWinSize
Maximum window size to advertise.
uint32_t GetSize(void) const
Definition: packet.h:650
bool IsManualIpTos(void) const
Checks if the socket has a specific IPv4 ToS set.
Definition: socket.cc:371
Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback
ICMP callback.
void CancelAllTimers(void)
Cancel all timer when endpoint is deleted.
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
#define NS_LOG_INFO(msg)
Definition: log.h:298
virtual uint8_t GetIpv6HopLimit(void) const
Query the value of IP Hop Limit field of this socket.
Definition: socket.cc:496
Time m_cnTimeout
Timeout for connection retry.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
uint32_t m_segmentSize
Segment size.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
EventId m_lastAckEvent
Last ACK timeout event.
void ConnectionSucceeded(void)
Schedule-friendly wrapper for Socket::NotifyConnectionSucceeded()
void SetFinSequence(const SequenceNumber32 &s)
Set the FIN Sequence number (i.e., the one closing the connection)
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:765
TracedValue< SequenceNumber32 > m_nextTxSequence
Next seqnum to be sent (SND.NXT), ReTx pushes it back.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
virtual void ReceivedAck(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received an ACK packet.
ns3::Time timeout
uint32_t m_cnCount
Count of remaining connection retries.
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:996
virtual Time GetPersistTimeout(void) const
Get the timout for persistent connection.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
void DoPeerClose(void)
FIN is in sequence, notify app and respond with a FIN.
bool NotifyConnectionRequest(const Address &from)
Notify through the callback (if set) that an incoming connection is being requested by a remote host...
Definition: socket.cc:257
SequenceNumber32 NextRxSequence(void) const
Get Next Rx Sequence number.
virtual void PersistTimeout(void)
Send 1 byte probe to get an updated window size.
TracedValue< TcpStates_t > m_state
TCP state.
uint32_t m_delAckMaxCount
Number of packet to fire an ACK before delay timeout.
#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.
AttributeValue form of a Callback.
Definition: callback.h:1658
uint32_t m_cnRetries
Number of connection retries before giving up.
virtual uint32_t GetRcvBufSize(void) const
Get the receive buffer size.
uint32_t m_delAckCount
Delayed ACK counter.
virtual bool GetTcpNoDelay(void) const
Check if Nagle's algorithm is enabled or not.
void ForwardIcmp6(Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMPv6 packet to pass on to TCP.
virtual int Bind(void)
Allocate a local IPv4 endpoint for this socket.
SequenceNumber< uint32_t, int32_t > SequenceNumber32
SequenceNumber32 MaxRxSequence(void) const
Get the lowest sequence number that this TcpRxBuffer cannot accept.
TcpTxBuffer m_txBuffer
Tx buffer.
virtual void Retransmit(void)
Halving cwnd and call DoRetransmit()
Packet header for IPv4.
Definition: ipv4-header.h:31
void SetLocalAddress(Ipv6Address addr)
Set the local address.
virtual void ReadOptions(const TcpHeader &tcpHeader)
Read option from incoming packets.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
Send data to a specified peer.
virtual void EstimateRtt(const TcpHeader &tcpHeader)
Take into account the packet for RTT estimation.
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Definition: tcp-header.cc:64
virtual uint32_t UnAckDataCount(void)
Return count of number of unacked bytes.
void ForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
static const char *const TcpStateName[LAST_STATE]
Literal names of TCP states for use in log messages.
Definition: tcp-socket.h:80
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:584
virtual uint32_t GetSndBufSize(void) const
Get the send buffer size.
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
the IPv6 endpoint
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Ptr< SampleEmitter > s
bool OutOfRange(SequenceNumber32 head, SequenceNumber32 tail) const
Check if a sequence number range is within the rx window.
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
Ipv4Address GetLocalAddress(void)
Get the local address.
An Inet6 address class.
virtual void SetTcpNoDelay(bool noDelay)
Enable/Disable Nagle's algorithm.
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:948
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
bool IsManualIpv6Tclass(void) const
Checks if the socket has a specific IPv6 Tclass set.
Definition: socket.cc:377
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:285
virtual uint32_t GetConnCount(void) const
Get the number of connection retries before giving up.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
enum SocketErrno m_errno
Socket error code.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
void SetNextRxSequence(const SequenceNumber32 &s)
Set the Next Sequence number.
A base class for implementation of a stream socket using TCP.
Ptr< RttEstimator > m_rtt
Round trip time estimator.
bool m_closeNotified
Told app to close socket.
void ProcessSynSent(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon SYN_SENT.
int SetupCallback(void)
Common part of the two Bind(), i.e.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
virtual void SetTcp(Ptr< TcpL4Protocol > tcp)
Set the associated TCP L4 protocol.
Ptr< TcpL4Protocol > m_tcp
the associated TCP L4 protocol
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition: socket.cc:645
void SetMaxBufferSize(uint32_t n)
Set the Tx window size.
void ProcessSynRcvd(Ptr< Packet > packet, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Received a packet upon SYN_RCVD.
virtual int ShutdownSend(void)
void SetDestinationPort(uint16_t port)
Definition: tcp-header.cc:60
void NotifyConnectionSucceeded(void)
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:217
uint32_t Available(void) const
Returns the available capacity in this Tx window.
void SetFlags(uint8_t flags)
Definition: tcp-header.cc:76
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
void SetMaxBufferSize(uint32_t s)
Set the Maximum buffer size.
bool IsManualIpv6HopLimit(void) const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition: socket.cc:389
virtual void SetDelAckMaxCount(uint32_t count)
Set the number of packet to fire an ACK before delay timeout.
void NotifyNormalClose(void)
Notify through the callback (if set) that the connection has been closed.
Definition: socket.cc:237
int DoConnect(void)
Perform the real connection tasks: Send SYN if allowed, RST if invalid.
void CompleteFork(Ptr< Packet > p, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Complete a connection by forking the socket.
virtual void AddOptions(TcpHeader &tcpHeader)
Add option to outgoing packets.
Ptr< Packet > Extract(uint32_t maxSize)
Extract data from the head of the buffer as indicated by nextRxSeq.
uint32_t m_dupAckCount
Dupack counter.
static InetSocketAddress ConvertFrom(const Address &address)
Ptr< Node > m_node
the associated node
void NotifyNewConnectionCreated(Ptr< Socket > socket, const Address &from)
Notify through the callback (if set) that a new connection has been created.
Definition: socket.cc:275
void TimeWait(void)
Move from CLOSING or FIN_WAIT_2 to TIME_WAIT state.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Header for the Transmission Control Protocol.
Definition: tcp-header.h:43
virtual void SetNode(Ptr< Node > node)
Set the associated 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:56
virtual uint32_t BytesInFlight(void)
Return total bytes in flight.
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1189
uint8_t GetIpv6Tclass(void) const
Query the value of IPv6 Traffic Class field of this socket.
Definition: socket.cc:446
void Destroy(void)
Kill this socket by zeroing its attributes (IPv4)
bool Add(Ptr< Packet > p)
Append a data packet to the end of the buffer.
virtual int Connect(const Address &address)
Initiate a connection to a remote host.
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:985
virtual int Close(void)
Close a socket.
static Ipv4Address GetZero(void)
void SetPeer(Ipv4Address address, uint16_t port)
Set the peer informations (address and port).
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
virtual uint32_t AvailableWindow(void)
Return unfilled portion of window.
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
Definition: socket.cc:121
virtual Ptr< TcpSocketBase > Fork(void)=0
Call CopyObject<> to clone me.
virtual void DupAck(const TcpHeader &tcpHeader, uint32_t count)=0
Received dupack (duplicate ACK)
virtual void SetRtt(Ptr< RttEstimator > rtt)
Set the associated RTT estimator.
double m_msl
Max segment lifetime.
virtual void ReTxTimeout(void)
Call Retransmit() upon RTO event.
TracedValue< SequenceNumber32 > m_highTxMark
Highest seqno ever sent, regardless of ReTx.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
void SendEmptyPacket(uint8_t flags)
Send a empty packet that carries a flag, e.g.
Time m_delAckTimeout
Time to delay an ACK.
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:114
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
void SetLocalAddress(Ipv4Address address)
Set the local address.
virtual void SetSndBufSize(uint32_t size)
Set the send buffer size.
virtual void SetDelAckTimeout(Time timeout)
Set the time to delay an ACK.
virtual void NewAck(SequenceNumber32 const &seq)
Update buffers w.r.t.
void DeallocateEndPoint(void)
Deallocate m_endPoint.
TcpRxBuffer m_rxBuffer
Rx buffer (reordering buffer)
Describes an IPv6 address.
Definition: ipv6-address.h:46
uint32_t MaxBufferSize(void) const
Get the Maximum buffer size.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
void ProcessEstablished(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon ESTABLISHED state.
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:911
bool m_connected
Connection established.
TracedValue< Time > m_rto
Retransmit timeout.
uint16_t GetLocalPort(void)
Get the local port.
#define NS_LOG_WARN(msg)
Definition: log.h:280
void SetAckNumber(SequenceNumber32 ackNumber)
Definition: tcp-header.cc:68
Ipv6Address GetPeerAddress()
Get the peer address.
int DoClose(void)
Close a socket by sending RST, FIN, or FIN+ACK, depend on the current state.
virtual void SetConnCount(uint32_t count)
Set the number of connection retries before giving up.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:102
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Ipv4Address GetPeerAddress(void)
Get the peer address.
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t, Ptr< Ipv6Interface > > callback)
Set the reception callback.
static bool IsMatchingType(const Address &addr)
If the address match.
uint16_t GetPeerPort(void)
Get the peer port.
uint16_t GetPort(void) const
Get the port.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
virtual uint32_t Window(void)
Return the max possible number of unacked bytes.
virtual enum SocketErrno GetErrno(void) const
Get last error number.
void ProcessLastAck(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon LAST_ACK.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
virtual void SetSegSize(uint32_t size)
Set the segment size.
void ProcessClosing(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon CLOSING.
#define NS_LOG_ERROR(msg)
Definition: log.h:271
uint16_t GetPort(void) const
virtual void ReceivedData(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Recv of a data, put into buffer, call L7 to get it if necessary.
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:84
void CloseAndNotify(void)
Peacefully close the socket by notifying the upper layer and deallocate end point.
Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback6
ICMPv6 callback.
tuple address
Definition: first.py:37
virtual Ptr< Node > GetNode(void) const
Return the node this socket is associated with.
virtual void SetRcvBufSize(uint32_t size)
Set the receive buffer size.
bool m_shutdownRecv
Receive no longer allowed.
virtual Time GetDelAckTimeout(void) const
Get the time to delay an ACK.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
virtual void DelAckTimeout(void)
Action upon delay ACK timeout, i.e.
virtual void LastAckTimeout(void)
Timeout at LAST_ACK, close the connection.
uint32_t Size(void) const
Get the actual buffer occupancy.
void SetWindowSize(uint16_t windowSize)
Definition: tcp-header.cc:80
Hold a floating point type.
Definition: double.h:41
virtual void DoForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by TcpSocketBase::ForwardUp().
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
indicates whether the socket has IP_TOS set.
Definition: socket.h:1142
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:53
Ptr< T > GetObject(void) const
Definition: object.h:361
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
EventId m_delAckEvent
Delayed ACK timeout event.
a unique identifier for an interface.
Definition: type-id.h:49
bool m_shutdownSend
Send no longer allowed.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:107
int SetupEndpoint6(void)
Configure the endpoint v6 to a local address.
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:295
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
bool SendPendingData(bool withAck=false)
Send as much pending data as possible according to the Tx window.
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMP packet to pass on to TCP.
TracedValue< uint32_t > m_rWnd
Flow control window at remote side.
static bool IsMatchingType(const Address &address)
void NotifyErrorClose(void)
Notify through the callback (if set) that the connection has been closed due to an error...
Definition: socket.cc:247
virtual void DoRetransmit(void)
Retransmit the oldest packet.
bool m_closeOnEmpty
Close socket upon tx buffer emptied.
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:112
virtual uint32_t GetDelAckMaxCount(void) const
Get the number of packet to fire an ACK before delay timeout.
virtual void SetConnTimeout(Time timeout)
Set the connection timeout.
EventId m_persistEvent
Persist event: Send 1 byte to probe for a non-zero Rx window.
void SetPeer(Ipv6Address addr, uint16_t port)
Set the peer informations (address and port).
int SetupEndpoint(void)
Configure the endpoint to a local address.
virtual Time GetConnTimeout(void) const
Get the connection timeout.
bool Finished(void)
Check if the buffer did receive all the data (and the connection is closed)
void Destroy6(void)
Kill this socket by zeroing its attributes (IPv6)
void SetHeadSequence(const SequenceNumber32 &seq)
Set the m_firstByteSeq to seq.
Time m_persistTimeout
Time between sending 1-byte probes.
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
virtual uint32_t GetRxAvailable(void) const
Return number of bytes which can be returned from one or multiple calls to Recv.
Ptr< Packet > CopyFromSequence(uint32_t numBytes, const SequenceNumber32 &seq)
Copy data of size numBytes into a packet, data from the range [seq, seq+numBytes) ...