A Discrete-Event Network Simulator
API
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/pointer.h"
43 #include "ns3/trace-source-accessor.h"
44 #include "tcp-socket-base.h"
45 #include "tcp-l4-protocol.h"
46 #include "ipv4-end-point.h"
47 #include "ipv6-end-point.h"
48 #include "ipv6-l3-protocol.h"
49 #include "tcp-header.h"
50 #include "tcp-option-winscale.h"
51 #include "tcp-option-ts.h"
52 #include "rtt-estimator.h"
53 
54 #include <math.h>
55 #include <algorithm>
56 
57 namespace ns3 {
58 
59 NS_LOG_COMPONENT_DEFINE ("TcpSocketBase");
60 
61 NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase);
62 
63 TypeId
65 {
66  static TypeId tid = TypeId ("ns3::TcpSocketBase")
67  .SetParent<TcpSocket> ()
68 // .AddAttribute ("TcpState", "State in TCP state machine",
69 // TypeId::ATTR_GET,
70 // EnumValue (CLOSED),
71 // MakeEnumAccessor (&TcpSocketBase::m_state),
72 // MakeEnumChecker (CLOSED, "Closed"))
73  .AddAttribute ("MaxSegLifetime",
74  "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
75  DoubleValue (120), /* RFC793 says MSL=2 minutes*/
77  MakeDoubleChecker<double> (0))
78  .AddAttribute ("MaxWindowSize", "Max size of advertised window",
79  UintegerValue (65535),
81  MakeUintegerChecker<uint16_t> ())
82  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
83  CallbackValue (),
86  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
87  CallbackValue (),
90  .AddAttribute ("WindowScaling", "Enable or disable Window Scaling option",
91  BooleanValue (true),
94  .AddAttribute ("Timestamp", "Enable or disable Timestamp option",
95  BooleanValue (true),
98  .AddAttribute ("MinRto",
99  "Minimum retransmit timeout value",
100  TimeValue (Seconds (0.2)), // RFC2988 says min RTO=1 sec, but Linux uses 200ms. See http://www.postel.org/pipermail/end2end-interest/2004-November/004402.html
103  MakeTimeChecker ())
104  .AddAttribute ("ClockGranularity",
105  "Clock Granularity used in RTO calculations",
106  TimeValue (MilliSeconds (1)), // RFC6298 suggest to use fine clock granularity
109  MakeTimeChecker ())
110  .AddAttribute ("TxBuffer",
111  "TCP Tx buffer",
112  PointerValue (),
114  MakePointerChecker<TcpTxBuffer> ())
115  .AddAttribute ("RxBuffer",
116  "TCP Rx buffer",
117  PointerValue (),
119  MakePointerChecker<TcpRxBuffer> ())
120  .AddTraceSource ("RTO",
121  "Retransmission timeout",
123  "ns3::Time::TracedValueCallback")
124  .AddTraceSource ("RTT",
125  "Last RTT sample",
127  "ns3::Time::TracedValueCallback")
128  .AddTraceSource ("NextTxSequence",
129  "Next sequence number to send (SND.NXT)",
131  "ns3::SequenceNumber32TracedValueCallback")
132  .AddTraceSource ("HighestSequence",
133  "Highest sequence number ever sent in socket's life time",
135  "ns3::SequenceNumber32TracedValueCallback")
136  .AddTraceSource ("State",
137  "TCP state",
139  "ns3::TcpStatesTracedValueCallback")
140  .AddTraceSource ("RWND",
141  "Remote side's flow control window",
143  "ns3::TracedValue::Uint32Callback")
144  ;
145  return tid;
146 }
147 
149  : m_dupAckCount (0),
150  m_delAckCount (0),
151  m_endPoint (0),
152  m_endPoint6 (0),
153  m_node (0),
154  m_tcp (0),
155  m_rtt (0),
156  m_nextTxSequence (0),
157  // Change this for non-zero initial sequence number
158  m_highTxMark (0),
159  m_rxBuffer (0),
160  m_txBuffer (0),
161  m_state (CLOSED),
162  m_errno (ERROR_NOTERROR),
163  m_closeNotified (false),
164  m_closeOnEmpty (false),
165  m_shutdownSend (false),
166  m_shutdownRecv (false),
167  m_connected (false),
168  m_segmentSize (0),
169  // For attribute initialization consistency (quiet valgrind)
170  m_rWnd (0),
171  m_sndScaleFactor (0),
172  m_rcvScaleFactor (0),
173  m_timestampEnabled (true),
174  m_timestampToEcho (0)
175 
176 {
177  NS_LOG_FUNCTION (this);
178  m_rxBuffer = CreateObject<TcpRxBuffer> ();
179  m_txBuffer = CreateObject<TcpTxBuffer> ();
180 }
181 
183  : TcpSocket (sock),
184  //copy object::m_tid and socket::callbacks
185  m_dupAckCount (sock.m_dupAckCount),
186  m_delAckCount (0),
187  m_delAckMaxCount (sock.m_delAckMaxCount),
188  m_noDelay (sock.m_noDelay),
189  m_cnRetries (sock.m_cnRetries),
190  m_delAckTimeout (sock.m_delAckTimeout),
191  m_persistTimeout (sock.m_persistTimeout),
192  m_cnTimeout (sock.m_cnTimeout),
193  m_endPoint (0),
194  m_endPoint6 (0),
195  m_node (sock.m_node),
196  m_tcp (sock.m_tcp),
197  m_rtt (0),
198  m_nextTxSequence (sock.m_nextTxSequence),
199  m_highTxMark (sock.m_highTxMark),
200  m_state (sock.m_state),
201  m_errno (sock.m_errno),
202  m_closeNotified (sock.m_closeNotified),
203  m_closeOnEmpty (sock.m_closeOnEmpty),
204  m_shutdownSend (sock.m_shutdownSend),
205  m_shutdownRecv (sock.m_shutdownRecv),
206  m_connected (sock.m_connected),
207  m_msl (sock.m_msl),
208  m_segmentSize (sock.m_segmentSize),
209  m_maxWinSize (sock.m_maxWinSize),
210  m_rWnd (sock.m_rWnd),
211  m_winScalingEnabled (sock.m_winScalingEnabled),
212  m_sndScaleFactor (sock.m_sndScaleFactor),
213  m_rcvScaleFactor (sock.m_rcvScaleFactor),
214  m_timestampEnabled (sock.m_timestampEnabled),
215  m_timestampToEcho (sock.m_timestampToEcho)
216 
217 {
218  NS_LOG_FUNCTION (this);
219  NS_LOG_LOGIC ("Invoked the copy constructor");
220  // Copy the rtt estimator if it is set
221  if (sock.m_rtt)
222  {
223  m_rtt = sock.m_rtt->Copy ();
224  }
225  // Reset all callbacks to null
226  Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
227  Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
228  Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
229  SetConnectCallback (vPS, vPS);
230  SetDataSentCallback (vPSUI);
231  SetSendCallback (vPSUI);
232  SetRecvCallback (vPS);
235 }
236 
238 {
239  NS_LOG_FUNCTION (this);
240  m_node = 0;
241  if (m_endPoint != 0)
242  {
243  NS_ASSERT (m_tcp != 0);
244  /*
245  * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
246  * DestroyCallback is set to TcpSocketBase::Destroy. If we called
247  * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
248  * which in turn destroys my m_endPoint, and in turn invokes
249  * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
250  */
251  NS_ASSERT (m_endPoint != 0);
252  m_tcp->DeAllocate (m_endPoint);
253  NS_ASSERT (m_endPoint == 0);
254  }
255  if (m_endPoint6 != 0)
256  {
257  NS_ASSERT (m_tcp != 0);
258  NS_ASSERT (m_endPoint6 != 0);
259  m_tcp->DeAllocate (m_endPoint6);
260  NS_ASSERT (m_endPoint6 == 0);
261  }
262  m_tcp = 0;
263  CancelAllTimers ();
264 }
265 
266 /* Associate a node with this TCP socket */
267 void
269 {
270  m_node = node;
271 }
272 
273 /* Associate the L4 protocol (e.g. mux/demux) with this socket */
274 void
276 {
277  m_tcp = tcp;
278 }
279 
280 /* Set an RTT estimator with this socket */
281 void
283 {
284  m_rtt = rtt;
285 }
286 
287 /* Inherit from Socket class: Returns error code */
290 {
291  return m_errno;
292 }
293 
294 /* Inherit from Socket class: Returns socket type, NS3_SOCK_STREAM */
297 {
298  return NS3_SOCK_STREAM;
299 }
300 
301 /* Inherit from Socket class: Returns associated node */
302 Ptr<Node>
304 {
306  return m_node;
307 }
308 
309 /* Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */
310 int
312 {
313  NS_LOG_FUNCTION (this);
314  m_endPoint = m_tcp->Allocate ();
315  if (0 == m_endPoint)
316  {
318  return -1;
319  }
320 
321  if (std::find(m_tcp->m_sockets.begin(), m_tcp->m_sockets.end(), this) == m_tcp->m_sockets.end())
322  {
323  m_tcp->m_sockets.push_back (this);
324  }
325  return SetupCallback ();
326 }
327 
328 int
330 {
331  NS_LOG_FUNCTION (this);
332  m_endPoint6 = m_tcp->Allocate6 ();
333  if (0 == m_endPoint6)
334  {
336  return -1;
337  }
338 
339  if (std::find(m_tcp->m_sockets.begin(), m_tcp->m_sockets.end(), this) == m_tcp->m_sockets.end())
340  {
341  m_tcp->m_sockets.push_back (this);
342  }
343  return SetupCallback ();
344 }
345 
346 /* Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
347 int
349 {
350  NS_LOG_FUNCTION (this << address);
351  if (InetSocketAddress::IsMatchingType (address))
352  {
354  Ipv4Address ipv4 = transport.GetIpv4 ();
355  uint16_t port = transport.GetPort ();
356  if (ipv4 == Ipv4Address::GetAny () && port == 0)
357  {
358  m_endPoint = m_tcp->Allocate ();
359  }
360  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
361  {
362  m_endPoint = m_tcp->Allocate (port);
363  }
364  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
365  {
366  m_endPoint = m_tcp->Allocate (ipv4);
367  }
368  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
369  {
370  m_endPoint = m_tcp->Allocate (ipv4, port);
371  }
372  if (0 == m_endPoint)
373  {
375  return -1;
376  }
377  }
378  else if (Inet6SocketAddress::IsMatchingType (address))
379  {
381  Ipv6Address ipv6 = transport.GetIpv6 ();
382  uint16_t port = transport.GetPort ();
383  if (ipv6 == Ipv6Address::GetAny () && port == 0)
384  {
385  m_endPoint6 = m_tcp->Allocate6 ();
386  }
387  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
388  {
389  m_endPoint6 = m_tcp->Allocate6 (port);
390  }
391  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
392  {
393  m_endPoint6 = m_tcp->Allocate6 (ipv6);
394  }
395  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
396  {
397  m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
398  }
399  if (0 == m_endPoint6)
400  {
402  return -1;
403  }
404  }
405  else
406  {
408  return -1;
409  }
410 
411  if (std::find(m_tcp->m_sockets.begin(), m_tcp->m_sockets.end(), this) == m_tcp->m_sockets.end())
412  {
413  m_tcp->m_sockets.push_back (this);
414  }
415  NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
416 
417  return SetupCallback ();
418 }
419 
420 /* Inherit from Socket class: Initiate connection to a remote address:port */
421 int
423 {
424  NS_LOG_FUNCTION (this << address);
425 
426  // If haven't do so, Bind() this socket first
427  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
428  {
429  if (m_endPoint == 0)
430  {
431  if (Bind () == -1)
432  {
433  NS_ASSERT (m_endPoint == 0);
434  return -1; // Bind() failed
435  }
436  NS_ASSERT (m_endPoint != 0);
437  }
439  m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
440  m_endPoint6 = 0;
441 
442  // Get the appropriate local address and port number from the routing protocol and set up endpoint
443  if (SetupEndpoint () != 0)
444  { // Route to destination does not exist
445  return -1;
446  }
447  }
448  else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
449  {
450  // If we are operating on a v4-mapped address, translate the address to
451  // a v4 address and re-call this function
453  Ipv6Address v6Addr = transport.GetIpv6 ();
454  if (v6Addr.IsIpv4MappedAddress () == true)
455  {
456  Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
457  return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
458  }
459 
460  if (m_endPoint6 == 0)
461  {
462  if (Bind6 () == -1)
463  {
464  NS_ASSERT (m_endPoint6 == 0);
465  return -1; // Bind() failed
466  }
467  NS_ASSERT (m_endPoint6 != 0);
468  }
469  m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
470  m_endPoint = 0;
471 
472  // Get the appropriate local address and port number from the routing protocol and set up endpoint
473  if (SetupEndpoint6 () != 0)
474  { // Route to destination does not exist
475  return -1;
476  }
477  }
478  else
479  {
481  return -1;
482  }
483 
484  // Re-initialize parameters in case this socket is being reused after CLOSE
485  m_rtt->Reset ();
487 
488  // DoConnect() will do state-checking and send a SYN packet
489  return DoConnect ();
490 }
491 
492 /* Inherit from Socket class: Listen on the endpoint for an incoming connection */
493 int
495 {
496  NS_LOG_FUNCTION (this);
497  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
498  if (m_state != CLOSED)
499  {
501  return -1;
502  }
503  // In other cases, set the state to LISTEN and done
504  NS_LOG_INFO ("CLOSED -> LISTEN");
505  m_state = LISTEN;
506  return 0;
507 }
508 
509 /* Inherit from Socket class: Kill this socket and signal the peer (if any) */
510 int
512 {
513  NS_LOG_FUNCTION (this);
517  if (m_rxBuffer->Size () != 0)
518  {
519  NS_LOG_INFO ("Socket " << this << " << unread rx data during close. Sending reset");
520  SendRST ();
521  return 0;
522  }
523 
524  if (m_txBuffer->SizeFromSequence (m_nextTxSequence) > 0)
525  { // App close with pending data must wait until all data transmitted
526  if (m_closeOnEmpty == false)
527  {
528  m_closeOnEmpty = true;
529  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
530  }
531  return 0;
532  }
533  return DoClose ();
534 }
535 
536 /* Inherit from Socket class: Signal a termination of send */
537 int
539 {
540  NS_LOG_FUNCTION (this);
541 
542  //this prevents data from being added to the buffer
543  m_shutdownSend = true;
544  m_closeOnEmpty = true;
545  //if buffer is already empty, send a fin now
546  //otherwise fin will go when buffer empties.
547  if (m_txBuffer->Size () == 0)
548  {
549  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
550  {
551  NS_LOG_INFO("Emtpy tx buffer, send fin");
553 
554  if (m_state == ESTABLISHED)
555  { // On active close: I am the first one to send FIN
556  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
558  }
559  else
560  { // On passive close: Peer sent me FIN already
561  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
562  m_state = LAST_ACK;
563  }
564  }
565  }
566 
567  return 0;
568 }
569 
570 /* Inherit from Socket class: Signal a termination of receive */
571 int
573 {
574  NS_LOG_FUNCTION (this);
575  m_shutdownRecv = true;
576  return 0;
577 }
578 
579 /* Inherit from Socket class: Send a packet. Parameter flags is not used.
580  Packet has no TCP header. Invoked by upper-layer application */
581 int
582 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
583 {
584  NS_LOG_FUNCTION (this << p);
585  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
587  {
588  // Store the packet into Tx buffer
589  if (!m_txBuffer->Add (p))
590  { // TxBuffer overflow, send failed
592  return -1;
593  }
594  if (m_shutdownSend)
595  {
597  return -1;
598  }
599  // Submit the data to lower layers
600  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer->Size () << " state " << TcpStateName[m_state]);
601  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
602  { // Try to send the data out
604  }
605  return p->GetSize ();
606  }
607  else
608  { // Connection not established yet
610  return -1; // Send failure
611  }
612 }
613 
614 /* Inherit from Socket class: In TcpSocketBase, it is same as Send() call */
615 int
617 {
618  return Send (p, flags); // SendTo() and Send() are the same
619 }
620 
621 /* Inherit from Socket class: Return data to upper-layer application. Parameter flags
622  is not used. Data is returned as a packet of size no larger than maxSize */
624 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
625 {
626  NS_LOG_FUNCTION (this);
627  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
628  if (m_rxBuffer->Size () == 0 && m_state == CLOSE_WAIT)
629  {
630  return Create<Packet> (); // Send EOF on connection close
631  }
632  Ptr<Packet> outPacket = m_rxBuffer->Extract (maxSize);
633  if (outPacket != 0 && outPacket->GetSize () != 0)
634  {
635  SocketAddressTag tag;
636  if (m_endPoint != 0)
637  {
639  }
640  else if (m_endPoint6 != 0)
641  {
643  }
644  outPacket->AddPacketTag (tag);
645  }
646  return outPacket;
647 }
648 
649 /* Inherit from Socket class: Recv and return the remote's address */
651 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
652 {
653  NS_LOG_FUNCTION (this << maxSize << flags);
654  Ptr<Packet> packet = Recv (maxSize, flags);
655  // Null packet means no data to read, and an empty packet indicates EOF
656  if (packet != 0 && packet->GetSize () != 0)
657  {
658  if (m_endPoint != 0)
659  {
661  }
662  else if (m_endPoint6 != 0)
663  {
665  }
666  else
667  {
668  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
669  }
670  }
671  return packet;
672 }
673 
674 /* Inherit from Socket class: Get the max number of bytes an app can send */
675 uint32_t
677 {
678  NS_LOG_FUNCTION (this);
679  return m_txBuffer->Available ();
680 }
681 
682 /* Inherit from Socket class: Get the max number of bytes an app can read */
683 uint32_t
685 {
686  NS_LOG_FUNCTION (this);
687  return m_rxBuffer->Available ();
688 }
689 
690 /* Inherit from Socket class: Return local address:port */
691 int
693 {
694  NS_LOG_FUNCTION (this);
695  if (m_endPoint != 0)
696  {
698  }
699  else if (m_endPoint6 != 0)
700  {
702  }
703  else
704  { // It is possible to call this method on a socket without a name
705  // in which case, behavior is unspecified
706  // Should this return an InetSocketAddress or an Inet6SocketAddress?
707  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
708  }
709  return 0;
710 }
711 
712 /* Inherit from Socket class: Bind this socket to the specified NetDevice */
713 void
715 {
716  NS_LOG_FUNCTION (netdevice);
717  Socket::BindToNetDevice (netdevice); // Includes sanity check
718  if (m_endPoint == 0)
719  {
720  if (Bind () == -1)
721  {
722  NS_ASSERT (m_endPoint == 0);
723  return;
724  }
725  NS_ASSERT (m_endPoint != 0);
726  }
727  m_endPoint->BindToNetDevice (netdevice);
728 
729  if (m_endPoint6 == 0)
730  {
731  if (Bind6 () == -1)
732  {
733  NS_ASSERT (m_endPoint6 == 0);
734  return;
735  }
736  NS_ASSERT (m_endPoint6 != 0);
737  }
738  m_endPoint6->BindToNetDevice (netdevice);
739 
740  return;
741 }
742 
743 /* Clean up after Bind. Set up callback functions in the end-point. */
744 int
746 {
747  NS_LOG_FUNCTION (this);
748 
749  if (m_endPoint == 0 && m_endPoint6 == 0)
750  {
751  return -1;
752  }
753  if (m_endPoint != 0)
754  {
758  }
759  if (m_endPoint6 != 0)
760  {
764  }
765 
766  return 0;
767 }
768 
769 /* Perform the real connection tasks: Send SYN if allowed, RST if invalid */
770 int
772 {
773  NS_LOG_FUNCTION (this);
774 
775  // A new connection is allowed only if this socket does not have a connection
777  { // send a SYN packet and change state into SYN_SENT
779  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
780  m_state = SYN_SENT;
781  }
782  else if (m_state != TIME_WAIT)
783  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
784  // exists. We send RST, tear down everything, and close this socket.
785  SendRST ();
786  CloseAndNotify ();
787  }
788  return 0;
789 }
790 
791 /* Do the action to close the socket. Usually send a packet with appropriate
792  flags depended on the current m_state. */
793 int
795 {
796  NS_LOG_FUNCTION (this);
797  switch (m_state)
798  {
799  case SYN_RCVD:
800  case ESTABLISHED:
801  // send FIN to close the peer
803  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
805  break;
806  case CLOSE_WAIT:
807  // send FIN+ACK to close the peer
809  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
810  m_state = LAST_ACK;
811  break;
812  case SYN_SENT:
813  case CLOSING:
814  // Send RST if application closes in SYN_SENT and CLOSING
815  SendRST ();
816  CloseAndNotify ();
817  break;
818  case LISTEN:
819  case LAST_ACK:
820  // In these three states, move to CLOSED and tear down the end point
821  CloseAndNotify ();
822  break;
823  case CLOSED:
824  case FIN_WAIT_1:
825  case FIN_WAIT_2:
826  case TIME_WAIT:
827  default: /* mute compiler */
828  // Do nothing in these four states
829  break;
830  }
831  return 0;
832 }
833 
834 /* Peacefully close the socket by notifying the upper layer and deallocate end point */
835 void
837 {
838  NS_LOG_FUNCTION (this);
839 
840  if (!m_closeNotified)
841  {
843  m_closeNotified = true;
844  }
845 
846  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
847  m_state = CLOSED;
848  DeallocateEndPoint ();
849 }
850 
851 
852 /* Tell if a sequence number range is out side the range that my rx buffer can
853  accpet */
854 bool
856 {
857  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
858  { // Rx buffer in these states are not initialized.
859  return false;
860  }
861  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
862  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
863  // sequence number must equals to m_rxBuffer->NextRxSequence ()
864  return (m_rxBuffer->NextRxSequence () != head);
865  }
866 
867  // In all other cases, check if the sequence number is in range
868  return (tail < m_rxBuffer->NextRxSequence () || m_rxBuffer->MaxRxSequence () <= head);
869 }
870 
871 /* Function called by the L3 protocol when it received a packet to pass on to
872  the TCP. This function is registered as the "RxCallback" function in
873  SetupCallback(), which invoked by Bind(), and CompleteFork() */
874 void
876  Ptr<Ipv4Interface> incomingInterface)
877 {
878  DoForwardUp (packet, header, port, incomingInterface);
879 }
880 
881 void
882 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, Ptr<Ipv6Interface> incomingInterface)
883 {
884  DoForwardUp (packet, header, port);
885 }
886 
887 void
888 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
889  uint8_t icmpType, uint8_t icmpCode,
890  uint32_t icmpInfo)
891 {
892  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
893  (uint32_t)icmpCode << icmpInfo);
894  if (!m_icmpCallback.IsNull ())
895  {
896  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
897  }
898 }
899 
900 void
901 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
902  uint8_t icmpType, uint8_t icmpCode,
903  uint32_t icmpInfo)
904 {
905  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
906  (uint32_t)icmpCode << icmpInfo);
907  if (!m_icmpCallback6.IsNull ())
908  {
909  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
910  }
911 }
912 
913 /* The real function to handle the incoming packet from lower layers. This is
914  wrapped by ForwardUp() so that this function can be overloaded by daughter
915  classes. */
916 void
918  Ptr<Ipv4Interface> incomingInterface)
919 {
920  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
922  ":" << m_endPoint->GetPeerPort () <<
923  " to " << m_endPoint->GetLocalAddress () <<
924  ":" << m_endPoint->GetLocalPort ());
925  Address fromAddress = InetSocketAddress (header.GetSource (), port);
926  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
927 
928  // Peel off TCP header and do validity checking
929  TcpHeader tcpHeader;
930  uint32_t bytesRemoved = packet->RemoveHeader (tcpHeader);
931  if (bytesRemoved == 0 || bytesRemoved > 60)
932  {
933  NS_LOG_ERROR ("Bytes removed: " << bytesRemoved << " invalid");
934  return; // Discard invalid packet
935  }
936 
937  ReadOptions (tcpHeader);
938 
939  if (tcpHeader.GetFlags () & TcpHeader::ACK)
940  {
941  EstimateRtt (tcpHeader);
942  }
943 
944  // Update Rx window size, i.e. the flow control window
945  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
946  { // persist probes end
947  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
949  }
950  m_rWnd = tcpHeader.GetWindowSize ();
952 
953  // Discard fully out of range data packets
954  if (packet->GetSize ()
955  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
956  {
957  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
958  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
959  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
960  ") out of range [" << m_rxBuffer->NextRxSequence () << ":" <<
961  m_rxBuffer->MaxRxSequence () << ")");
962  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
963  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
964  {
966  }
967  return;
968  }
969 
970  // TCP state machine code in different process functions
971  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
972  switch (m_state)
973  {
974  case ESTABLISHED:
975  ProcessEstablished (packet, tcpHeader);
976  break;
977  case LISTEN:
978  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
979  break;
980  case TIME_WAIT:
981  // Do nothing
982  break;
983  case CLOSED:
984  // Send RST if the incoming packet is not a RST
985  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
986  { // Since m_endPoint is not configured yet, we cannot use SendRST here
987  TcpHeader h;
990  h.SetAckNumber (m_rxBuffer->NextRxSequence ());
991  h.SetSourcePort (tcpHeader.GetDestinationPort ());
992  h.SetDestinationPort (tcpHeader.GetSourcePort ());
994  AddOptions (h);
995  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
996  }
997  break;
998  case SYN_SENT:
999  ProcessSynSent (packet, tcpHeader);
1000  break;
1001  case SYN_RCVD:
1002  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
1003  break;
1004  case FIN_WAIT_1:
1005  case FIN_WAIT_2:
1006  case CLOSE_WAIT:
1007  ProcessWait (packet, tcpHeader);
1008  break;
1009  case CLOSING:
1010  ProcessClosing (packet, tcpHeader);
1011  break;
1012  case LAST_ACK:
1013  ProcessLastAck (packet, tcpHeader);
1014  break;
1015  default: // mute compiler
1016  break;
1017  }
1018 }
1019 
1020 // XXX this is duplicate code with the other DoForwardUp()
1021 void
1023 {
1024  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
1026  ":" << m_endPoint6->GetPeerPort () <<
1027  " to " << m_endPoint6->GetLocalAddress () <<
1028  ":" << m_endPoint6->GetLocalPort ());
1029  Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port);
1031 
1032  // Peel off TCP header and do validity checking
1033  TcpHeader tcpHeader;
1034  uint32_t bytesRemoved = packet->RemoveHeader (tcpHeader);
1035  if (bytesRemoved == 0 || bytesRemoved > 60)
1036  {
1037  NS_LOG_ERROR ("Bytes removed: " << bytesRemoved << " invalid");
1038  return; // Discard invalid packet
1039  }
1040 
1041  ReadOptions (tcpHeader);
1042 
1043  if (tcpHeader.GetFlags () & TcpHeader::ACK)
1044  {
1045  EstimateRtt (tcpHeader);
1046  }
1047 
1048  // Update Rx window size, i.e. the flow control window
1049  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
1050  { // persist probes end
1051  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
1053  }
1054  m_rWnd = tcpHeader.GetWindowSize ();
1056 
1057  // Discard fully out of range packets
1058  if (packet->GetSize ()
1059  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
1060  {
1061  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
1062  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
1063  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
1064  ") out of range [" << m_rxBuffer->NextRxSequence () << ":" <<
1065  m_rxBuffer->MaxRxSequence () << ")");
1066  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
1067  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
1068  {
1070  }
1071  return;
1072  }
1073 
1074  // TCP state machine code in different process functions
1075  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
1076  switch (m_state)
1077  {
1078  case ESTABLISHED:
1079  ProcessEstablished (packet, tcpHeader);
1080  break;
1081  case LISTEN:
1082  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
1083  break;
1084  case TIME_WAIT:
1085  // Do nothing
1086  break;
1087  case CLOSED:
1088  // Send RST if the incoming packet is not a RST
1089  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
1090  { // Since m_endPoint is not configured yet, we cannot use SendRST here
1091  TcpHeader h;
1094  h.SetAckNumber (m_rxBuffer->NextRxSequence ());
1095  h.SetSourcePort (tcpHeader.GetDestinationPort ());
1096  h.SetDestinationPort (tcpHeader.GetSourcePort ());
1098  AddOptions (h);
1099  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestinationAddress (), header.GetSourceAddress (), m_boundnetdevice);
1100  }
1101  break;
1102  case SYN_SENT:
1103  ProcessSynSent (packet, tcpHeader);
1104  break;
1105  case SYN_RCVD:
1106  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
1107  break;
1108  case FIN_WAIT_1:
1109  case FIN_WAIT_2:
1110  case CLOSE_WAIT:
1111  ProcessWait (packet, tcpHeader);
1112  break;
1113  case CLOSING:
1114  ProcessClosing (packet, tcpHeader);
1115  break;
1116  case LAST_ACK:
1117  ProcessLastAck (packet, tcpHeader);
1118  break;
1119  default: // mute compiler
1120  break;
1121  }
1122 }
1123 
1124 /* Received a packet upon ESTABLISHED state. This function is mimicking the
1125  role of tcp_rcv_established() in tcp_input.c in Linux kernel. */
1126 void
1128 {
1129  NS_LOG_FUNCTION (this << tcpHeader);
1130 
1131  // Extract the flags. PSH and URG are not honoured.
1132  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1133 
1134  // Different flags are different events
1135  if (tcpflags == TcpHeader::ACK)
1136  {
1137  ReceivedAck (packet, tcpHeader);
1138  }
1139  else if (tcpflags == TcpHeader::SYN)
1140  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
1141  // respond with a SYN+ACK. But it is not a legal state transition as of
1142  // RFC793. Thus this is ignored.
1143  }
1144  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1145  { // No action for received SYN+ACK, it is probably a duplicated packet
1146  }
1147  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1148  { // Received FIN or FIN+ACK, bring down this socket nicely
1149  PeerClose (packet, tcpHeader);
1150  }
1151  else if (tcpflags == 0)
1152  { // No flags means there is only data
1153  ReceivedData (packet, tcpHeader);
1154  if (m_rxBuffer->Finished ())
1155  {
1156  PeerClose (packet, tcpHeader);
1157  }
1158  }
1159  else
1160  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1161  if (tcpflags != TcpHeader::RST)
1162  { // this must be an invalid flag, send reset
1163  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1164  SendRST ();
1165  }
1166  CloseAndNotify ();
1167  }
1168 }
1169 
1170 /* Process the newly received ACK */
1171 void
1173 {
1174  NS_LOG_FUNCTION (this << tcpHeader);
1175 
1176  // Received ACK. Compare the ACK number against highest unacked seqno
1177  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1178  { // Ignore if no ACK flag
1179  }
1180  else if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ())
1181  { // Case 1: Old ACK, ignored.
1182  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1183  }
1184  else if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence ())
1185  { // Case 2: Potentially a duplicated ACK
1186  if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0)
1187  {
1188  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1189  DupAck (tcpHeader, ++m_dupAckCount);
1190  }
1191  // otherwise, the ACK is precisely equal to the nextTxSequence
1192  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1193  }
1194  else if (tcpHeader.GetAckNumber () > m_txBuffer->HeadSequence ())
1195  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1196  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1197  NewAck (tcpHeader.GetAckNumber ());
1198  m_dupAckCount = 0;
1199  }
1200  // If there is any data piggybacked, store it into m_rxBuffer
1201  if (packet->GetSize () > 0)
1202  {
1203  ReceivedData (packet, tcpHeader);
1204  }
1205 }
1206 
1207 /* Received a packet upon LISTEN state. */
1208 void
1210  const Address& fromAddress, const Address& toAddress)
1211 {
1212  NS_LOG_FUNCTION (this << tcpHeader);
1213 
1214  // Extract the flags. PSH and URG are not honoured.
1215  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1216 
1217  // Fork a socket if received a SYN. Do nothing otherwise.
1218  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1219  if (tcpflags != TcpHeader::SYN)
1220  {
1221  return;
1222  }
1223 
1224  // Call socket's notify function to let the server app know we got a SYN
1225  // If the server app refuses the connection, do nothing
1226  if (!NotifyConnectionRequest (fromAddress))
1227  {
1228  return;
1229  }
1230  // Clone the socket, simulate fork
1231  Ptr<TcpSocketBase> newSock = Fork ();
1232  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1234  packet, tcpHeader, fromAddress, toAddress);
1235 }
1236 
1237 /* Received a packet upon SYN_SENT */
1238 void
1240 {
1241  NS_LOG_FUNCTION (this << tcpHeader);
1242 
1243  // Extract the flags. PSH and URG are not honoured.
1244  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1245 
1246  if (tcpflags == 0)
1247  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1248  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1249  m_state = ESTABLISHED;
1250  m_connected = true;
1251  m_retxEvent.Cancel ();
1253  ReceivedData (packet, tcpHeader);
1255  }
1256  else if (tcpflags == TcpHeader::ACK)
1257  { // Ignore ACK in SYN_SENT
1258  }
1259  else if (tcpflags == TcpHeader::SYN)
1260  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1261  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1262  m_state = SYN_RCVD;
1264  m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
1266  }
1267  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1268  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1269  { // Handshake completed
1270  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1271  m_state = ESTABLISHED;
1272  m_connected = true;
1273  m_retxEvent.Cancel ();
1274  m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
1276  m_txBuffer->SetHeadSequence (m_nextTxSequence);
1280  // Always respond to first data packet to speed up the connection.
1281  // Remove to get the behaviour of old NS-3 code.
1283  }
1284  else
1285  { // Other in-sequence input
1286  if (tcpflags != TcpHeader::RST)
1287  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1288  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1289  SendRST ();
1290  }
1291  CloseAndNotify ();
1292  }
1293 }
1294 
1295 /* Received a packet upon SYN_RCVD */
1296 void
1298  const Address& fromAddress, const Address& toAddress)
1299 {
1300  NS_LOG_FUNCTION (this << tcpHeader);
1301 
1302  // Extract the flags. PSH and URG are not honoured.
1303  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1304 
1305  if (tcpflags == 0
1306  || (tcpflags == TcpHeader::ACK
1307  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1308  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1309  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1310  // handshake is completed nicely.
1311  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1312  m_state = ESTABLISHED;
1313  m_connected = true;
1314  m_retxEvent.Cancel ();
1316  m_txBuffer->SetHeadSequence (m_nextTxSequence);
1317  if (m_endPoint)
1318  {
1319  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1320  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1321  }
1322  else if (m_endPoint6)
1323  {
1324  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1325  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1326  }
1327  // Always respond to first data packet to speed up the connection.
1328  // Remove to get the behaviour of old NS-3 code.
1330  ReceivedAck (packet, tcpHeader);
1331  NotifyNewConnectionCreated (this, fromAddress);
1332  // As this connection is established, the socket is available to send data now
1333  if (GetTxAvailable () > 0)
1334  {
1336  }
1337  }
1338  else if (tcpflags == TcpHeader::SYN)
1339  { // Probably the peer lost my SYN+ACK
1340  m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
1342  }
1343  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1344  {
1345  if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ())
1346  { // In-sequence FIN before connection complete. Set up connection and close.
1347  m_connected = true;
1348  m_retxEvent.Cancel ();
1350  m_txBuffer->SetHeadSequence (m_nextTxSequence);
1351  if (m_endPoint)
1352  {
1353  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1354  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1355  }
1356  else if (m_endPoint6)
1357  {
1358  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1359  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1360  }
1361  PeerClose (packet, tcpHeader);
1362  }
1363  }
1364  else
1365  { // Other in-sequence input
1366  if (tcpflags != TcpHeader::RST)
1367  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1368  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1369  if (m_endPoint)
1370  {
1371  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1372  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1373  }
1374  else if (m_endPoint6)
1375  {
1376  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1377  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1378  }
1379  SendRST ();
1380  }
1381  CloseAndNotify ();
1382  }
1383 }
1384 
1385 /* Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */
1386 void
1388 {
1389  NS_LOG_FUNCTION (this << tcpHeader);
1390 
1391  // Extract the flags. PSH and URG are not honoured.
1392  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1393 
1394  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1395  { // Bare data, accept it
1396  ReceivedData (packet, tcpHeader);
1397  }
1398  else if (tcpflags == TcpHeader::ACK)
1399  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1400  ReceivedAck (packet, tcpHeader);
1401  if (m_state == FIN_WAIT_1 && m_txBuffer->Size () == 0
1402  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1403  { // This ACK corresponds to the FIN sent
1404  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1405  m_state = FIN_WAIT_2;
1406  }
1407  }
1408  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1409  { // Got FIN, respond with ACK and move to next state
1410  if (tcpflags & TcpHeader::ACK)
1411  { // Process the ACK first
1412  ReceivedAck (packet, tcpHeader);
1413  }
1414  m_rxBuffer->SetFinSequence (tcpHeader.GetSequenceNumber ());
1415  }
1416  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1417  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1418  return;
1419  }
1420  else
1421  { // This is a RST or bad flags
1422  if (tcpflags != TcpHeader::RST)
1423  {
1424  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1425  SendRST ();
1426  }
1427  CloseAndNotify ();
1428  return;
1429  }
1430 
1431  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1432  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer->Finished ())
1433  {
1434  if (m_state == FIN_WAIT_1)
1435  {
1436  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1437  m_state = CLOSING;
1438  if (m_txBuffer->Size () == 0
1439  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1440  { // This ACK corresponds to the FIN sent
1441  TimeWait ();
1442  }
1443  }
1444  else if (m_state == FIN_WAIT_2)
1445  {
1446  TimeWait ();
1447  }
1449  if (!m_shutdownRecv)
1450  {
1451  NotifyDataRecv ();
1452  }
1453  }
1454 }
1455 
1456 /* Received a packet upon CLOSING */
1457 void
1459 {
1460  NS_LOG_FUNCTION (this << tcpHeader);
1461 
1462  // Extract the flags. PSH and URG are not honoured.
1463  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1464 
1465  if (tcpflags == TcpHeader::ACK)
1466  {
1467  if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ())
1468  { // This ACK corresponds to the FIN sent
1469  TimeWait ();
1470  }
1471  }
1472  else
1473  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1474  // anyone. If anything other than ACK is received, respond with a reset.
1475  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1476  { // FIN from the peer as well. We can close immediately.
1478  }
1479  else if (tcpflags != TcpHeader::RST)
1480  { // Receive of SYN or SYN+ACK or bad flags or pure data
1481  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1482  SendRST ();
1483  }
1484  CloseAndNotify ();
1485  }
1486 }
1487 
1488 /* Received a packet upon LAST_ACK */
1489 void
1491 {
1492  NS_LOG_FUNCTION (this << tcpHeader);
1493 
1494  // Extract the flags. PSH and URG are not honoured.
1495  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1496 
1497  if (tcpflags == 0)
1498  {
1499  ReceivedData (packet, tcpHeader);
1500  }
1501  else if (tcpflags == TcpHeader::ACK)
1502  {
1503  if (tcpHeader.GetSequenceNumber () == m_rxBuffer->NextRxSequence ())
1504  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1505  CloseAndNotify ();
1506  }
1507  }
1508  else if (tcpflags == TcpHeader::FIN)
1509  { // Received FIN again, the peer probably lost the FIN+ACK
1511  }
1512  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1513  {
1514  CloseAndNotify ();
1515  }
1516  else
1517  { // Received a SYN or SYN+ACK or bad flags
1518  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1519  SendRST ();
1520  CloseAndNotify ();
1521  }
1522 }
1523 
1524 /* Peer sent me a FIN. Remember its sequence in rx buffer. */
1525 void
1527 {
1528  NS_LOG_FUNCTION (this << tcpHeader);
1529 
1530  // Ignore all out of range packets
1531  if (tcpHeader.GetSequenceNumber () < m_rxBuffer->NextRxSequence ()
1532  || tcpHeader.GetSequenceNumber () > m_rxBuffer->MaxRxSequence ())
1533  {
1534  return;
1535  }
1536  // For any case, remember the FIN position in rx buffer first
1537  m_rxBuffer->SetFinSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1538  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1539  // If there is any piggybacked data, process it
1540  if (p->GetSize ())
1541  {
1542  ReceivedData (p, tcpHeader);
1543  }
1544  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1545  if (!m_rxBuffer->Finished ())
1546  {
1547  return;
1548  }
1549 
1550  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1551  if (m_state == FIN_WAIT_1)
1552  {
1553  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1554  m_state = CLOSING;
1555  return;
1556  }
1557 
1558  DoPeerClose (); // Change state, respond with ACK
1559 }
1560 
1561 /* Received a in-sequence FIN. Close down this socket. */
1562 void
1564 {
1566 
1567  // Move the state to CLOSE_WAIT
1568  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1569  m_state = CLOSE_WAIT;
1570 
1571  if (!m_closeNotified)
1572  {
1573  // The normal behaviour for an application is that, when the peer sent a in-sequence
1574  // FIN, the app should prepare to close. The app has two choices at this point: either
1575  // respond with ShutdownSend() call to declare that it has nothing more to send and
1576  // the socket can be closed immediately; or remember the peer's close request, wait
1577  // until all its existing data are pushed into the TCP socket, then call Close()
1578  // explicitly.
1579  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1580  NotifyNormalClose ();
1581  m_closeNotified = true;
1582  }
1583  if (m_shutdownSend)
1584  { // The application declares that it would not sent any more, close this socket
1585  Close ();
1586  }
1587  else
1588  { // Need to ack, the application will close later
1590  }
1591  if (m_state == LAST_ACK)
1592  {
1593  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1594  Time lastRto = m_rtt->GetEstimate () + Max (m_clockGranularity, m_rtt->GetVariation ()*4);
1596  }
1597 }
1598 
1599 /* Kill this socket. This is a callback function configured to m_endpoint in
1600  SetupCallback(), invoked when the endpoint is destroyed. */
1601 void
1603 {
1604  NS_LOG_FUNCTION (this);
1605  m_endPoint = 0;
1606  if (m_tcp != 0)
1607  {
1608  std::vector<Ptr<TcpSocketBase> >::iterator it
1609  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1610  if (it != m_tcp->m_sockets.end ())
1611  {
1612  m_tcp->m_sockets.erase (it);
1613  }
1614  }
1615  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1616  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1617  CancelAllTimers ();
1618 }
1619 
1620 /* Kill this socket. This is a callback function configured to m_endpoint in
1621  SetupCallback(), invoked when the endpoint is destroyed. */
1622 void
1624 {
1625  NS_LOG_FUNCTION (this);
1626  m_endPoint6 = 0;
1627  if (m_tcp != 0)
1628  {
1629  std::vector<Ptr<TcpSocketBase> >::iterator it
1630  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1631  if (it != m_tcp->m_sockets.end ())
1632  {
1633  m_tcp->m_sockets.erase (it);
1634  }
1635  }
1636  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1637  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1638  CancelAllTimers ();
1639 }
1640 
1641 /* Send an empty packet with specified TCP flags */
1642 void
1644 {
1645  NS_LOG_FUNCTION (this << (uint32_t)flags);
1646  Ptr<Packet> p = Create<Packet> ();
1647  TcpHeader header;
1649 
1650  /*
1651  * Add tags for each socket option.
1652  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1653  * if both options are set. Once the packet got to layer three, only
1654  * the corresponding tags will be read.
1655  */
1656  if (IsManualIpTos ())
1657  {
1658  SocketIpTosTag ipTosTag;
1659  ipTosTag.SetTos (GetIpTos ());
1660  p->AddPacketTag (ipTosTag);
1661  }
1662 
1663  if (IsManualIpv6Tclass ())
1664  {
1665  SocketIpv6TclassTag ipTclassTag;
1666  ipTclassTag.SetTclass (GetIpv6Tclass ());
1667  p->AddPacketTag (ipTclassTag);
1668  }
1669 
1670  if (IsManualIpTtl ())
1671  {
1672  SocketIpTtlTag ipTtlTag;
1673  ipTtlTag.SetTtl (GetIpTtl ());
1674  p->AddPacketTag (ipTtlTag);
1675  }
1676 
1677  if (IsManualIpv6HopLimit ())
1678  {
1679  SocketIpv6HopLimitTag ipHopLimitTag;
1680  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1681  p->AddPacketTag (ipHopLimitTag);
1682  }
1683 
1684  if (m_endPoint == 0 && m_endPoint6 == 0)
1685  {
1686  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1687  return;
1688  }
1689  if (flags & TcpHeader::FIN)
1690  {
1691  flags |= TcpHeader::ACK;
1692  }
1693  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1694  {
1695  ++s;
1696  }
1697 
1698  header.SetFlags (flags);
1699  header.SetSequenceNumber (s);
1700  header.SetAckNumber (m_rxBuffer->NextRxSequence ());
1701  if (m_endPoint != 0)
1702  {
1703  header.SetSourcePort (m_endPoint->GetLocalPort ());
1704  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1705  }
1706  else
1707  {
1708  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1709  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1710  }
1711  AddOptions (header);
1712  header.SetWindowSize (AdvertisedWindowSize ());
1713 
1714  // RFC 6298, clause 2.4
1715  m_rto = Max (m_rtt->GetEstimate () + Max (m_clockGranularity, m_rtt->GetVariation ()*4), Time::FromDouble (1, Time::S));
1716 
1717  bool hasSyn = flags & TcpHeader::SYN;
1718  bool hasFin = flags & TcpHeader::FIN;
1719  bool isAck = flags == TcpHeader::ACK;
1720  if (hasSyn)
1721  {
1722  if (m_cnCount == 0)
1723  { // No more connection retries, give up
1724  NS_LOG_LOGIC ("Connection failed.");
1725  m_rtt->Reset (); //According to recommendation -> RFC 6298
1726  CloseAndNotify ();
1727  return;
1728  }
1729  else
1730  { // Exponential backoff of connection time out
1731  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1732  m_rto = m_cnTimeout * backoffCount;
1733  m_cnCount--;
1734  }
1735  }
1736  if (m_endPoint != 0)
1737  {
1738  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1740  }
1741  else
1742  {
1743  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1745  }
1746  if (flags & TcpHeader::ACK)
1747  { // If sending an ACK, cancel the delay ACK as well
1748  m_delAckEvent.Cancel ();
1749  m_delAckCount = 0;
1750  }
1751  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1752  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1753  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1754  << Simulator::Now ().GetSeconds () << " to expire at time "
1755  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1757  }
1758 }
1759 
1760 /* This function closes the endpoint completely. Called upon RST_TX action. */
1761 void
1763 {
1764  NS_LOG_FUNCTION (this);
1766  NotifyErrorClose ();
1767  DeallocateEndPoint ();
1768 }
1769 
1770 /* Deallocate the end point and cancel all the timers */
1771 void
1773 {
1774  if (m_endPoint != 0)
1775  {
1776  CancelAllTimers ();
1777  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1778  m_tcp->DeAllocate (m_endPoint);
1779  m_endPoint = 0;
1780  std::vector<Ptr<TcpSocketBase> >::iterator it
1781  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1782  if (it != m_tcp->m_sockets.end ())
1783  {
1784  m_tcp->m_sockets.erase (it);
1785  }
1786  }
1787  else if (m_endPoint6 != 0)
1788  {
1789  CancelAllTimers ();
1790  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1791  m_tcp->DeAllocate (m_endPoint6);
1792  m_endPoint6 = 0;
1793  std::vector<Ptr<TcpSocketBase> >::iterator it
1794  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1795  if (it != m_tcp->m_sockets.end ())
1796  {
1797  m_tcp->m_sockets.erase (it);
1798  }
1799  }
1800 }
1801 
1802 /* Configure the endpoint to a local address. Called by Connect() if Bind() didn't specify one. */
1803 int
1805 {
1806  NS_LOG_FUNCTION (this);
1807  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1808  NS_ASSERT (ipv4 != 0);
1809  if (ipv4->GetRoutingProtocol () == 0)
1810  {
1811  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1812  }
1813  // Create a dummy packet, then ask the routing function for the best output
1814  // interface's address
1815  Ipv4Header header;
1817  Socket::SocketErrno errno_;
1818  Ptr<Ipv4Route> route;
1820  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1821  if (route == 0)
1822  {
1823  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1824  NS_LOG_ERROR (errno_);
1825  m_errno = errno_;
1826  return -1;
1827  }
1828  NS_LOG_LOGIC ("Route exists");
1829  m_endPoint->SetLocalAddress (route->GetSource ());
1830  return 0;
1831 }
1832 
1833 int
1835 {
1836  NS_LOG_FUNCTION (this);
1838  NS_ASSERT (ipv6 != 0);
1839  if (ipv6->GetRoutingProtocol () == 0)
1840  {
1841  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1842  }
1843  // Create a dummy packet, then ask the routing function for the best output
1844  // interface's address
1845  Ipv6Header header;
1847  Socket::SocketErrno errno_;
1848  Ptr<Ipv6Route> route;
1850  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1851  if (route == 0)
1852  {
1853  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1854  NS_LOG_ERROR (errno_);
1855  m_errno = errno_;
1856  return -1;
1857  }
1858  NS_LOG_LOGIC ("Route exists");
1859  m_endPoint6->SetLocalAddress (route->GetSource ());
1860  return 0;
1861 }
1862 
1863 /* This function is called only if a SYN received in LISTEN state. After
1864  TcpSocketBase cloned, allocate a new end point to handle the incoming
1865  connection and send a SYN+ACK to complete the handshake. */
1866 void
1868  const Address& fromAddress, const Address& toAddress)
1869 {
1870  // Get port and address from peer (connecting host)
1871  if (InetSocketAddress::IsMatchingType (toAddress))
1872  {
1873  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1874  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1875  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1876  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1877  m_endPoint6 = 0;
1878  }
1879  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1880  {
1881  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1882  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1883  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1884  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1885  m_endPoint = 0;
1886  }
1887  m_tcp->m_sockets.push_back (this);
1888 
1889  // Change the cloned socket from LISTEN state to SYN_RCVD
1890  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1891  m_state = SYN_RCVD;
1893  SetupCallback ();
1894  // Set the sequence number and send SYN+ACK
1895  m_rxBuffer->SetNextRxSequence (h.GetSequenceNumber () + SequenceNumber32 (1));
1896 
1898 }
1899 
1900 void
1902 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1903  // be called as a scheduled event
1905  // The if-block below was moved from ProcessSynSent() to here because we need
1906  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1907  // reflect the behaviour in the real world.
1908  if (GetTxAvailable () > 0)
1909  {
1911  }
1912 }
1913 
1914 /* Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
1915  TCP header, and send to TcpL4Protocol */
1916 uint32_t
1917 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1918 {
1919  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1920 
1921  bool isRetransmission = false;
1922  if ( seq == m_txBuffer->HeadSequence () )
1923  {
1924  isRetransmission = true;
1925  }
1926 
1927  Ptr<Packet> p = m_txBuffer->CopyFromSequence (maxSize, seq);
1928  uint32_t sz = p->GetSize (); // Size of packet
1929  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1930  uint32_t remainingData = m_txBuffer->SizeFromSequence (seq + SequenceNumber32 (sz));
1931 
1932  if (withAck)
1933  {
1934  m_delAckEvent.Cancel ();
1935  m_delAckCount = 0;
1936  }
1937 
1938  /*
1939  * Add tags for each socket option.
1940  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1941  * if both options are set. Once the packet got to layer three, only
1942  * the corresponding tags will be read.
1943  */
1944  if (IsManualIpTos ())
1945  {
1946  SocketIpTosTag ipTosTag;
1947  ipTosTag.SetTos (GetIpTos ());
1948  p->AddPacketTag (ipTosTag);
1949  }
1950 
1951  if (IsManualIpv6Tclass ())
1952  {
1953  SocketIpv6TclassTag ipTclassTag;
1954  ipTclassTag.SetTclass (GetIpv6Tclass ());
1955  p->AddPacketTag (ipTclassTag);
1956  }
1957 
1958  if (IsManualIpTtl ())
1959  {
1960  SocketIpTtlTag ipTtlTag;
1961  ipTtlTag.SetTtl (GetIpTtl ());
1962  p->AddPacketTag (ipTtlTag);
1963  }
1964 
1965  if (IsManualIpv6HopLimit ())
1966  {
1967  SocketIpv6HopLimitTag ipHopLimitTag;
1968  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1969  p->AddPacketTag (ipHopLimitTag);
1970  }
1971 
1972  if (m_closeOnEmpty && (remainingData == 0))
1973  {
1974  flags |= TcpHeader::FIN;
1975  if (m_state == ESTABLISHED)
1976  { // On active close: I am the first one to send FIN
1977  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1978  m_state = FIN_WAIT_1;
1979  }
1980  else if (m_state == CLOSE_WAIT)
1981  { // On passive close: Peer sent me FIN already
1982  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1983  m_state = LAST_ACK;
1984  }
1985  }
1986  TcpHeader header;
1987  header.SetFlags (flags);
1988  header.SetSequenceNumber (seq);
1989  header.SetAckNumber (m_rxBuffer->NextRxSequence ());
1990  if (m_endPoint)
1991  {
1992  header.SetSourcePort (m_endPoint->GetLocalPort ());
1994  }
1995  else
1996  {
1997  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1999  }
2000  header.SetWindowSize (AdvertisedWindowSize ());
2001  AddOptions (header);
2002 
2003  if (m_retxEvent.IsExpired () )
2004  {
2005  // RFC 6298, clause 2.5
2006  Time doubledRto = m_rto + m_rto;
2007  m_rto = Min (doubledRto, Time::FromDouble (60, Time::S));
2008 
2009  // Schedules retransmit
2010 
2011  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
2012  Simulator::Now ().GetSeconds () << " to expire at time " <<
2013  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
2015  }
2016  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
2017  if (m_endPoint)
2018  {
2019  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
2021  }
2022  else
2023  {
2024  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
2026  }
2027 
2028  // update the history of sequence numbers used to calculate the RTT
2029  if (isRetransmission == false)
2030  { // This is the next expected one, just log at end
2031  m_history.push_back (RttHistory (seq, sz, Simulator::Now () ));
2032  }
2033  else
2034  { // This is a retransmit, find in list and mark as re-tx
2035  for (RttHistory_t::iterator i = m_history.begin (); i != m_history.end (); ++i)
2036  {
2037  if ((seq >= i->seq) && (seq < (i->seq + SequenceNumber32 (i->count))))
2038  { // Found it
2039  i->retx = true;
2040  i->count = ((seq + SequenceNumber32 (sz)) - i->seq); // And update count in hist
2041  break;
2042  }
2043  }
2044  }
2045 
2046  // Notify the application of the data being sent unless this is a retransmit
2047  if (seq == m_highTxMark)
2048  {
2050  }
2051  // Update highTxMark
2052  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
2053  return sz;
2054 }
2055 
2056 /* Send as much pending data as possible according to the Tx window. Note that
2057  * this function did not implement the PSH flag
2058  */
2059 bool
2061 {
2062  NS_LOG_FUNCTION (this << withAck);
2063  if (m_txBuffer->Size () == 0)
2064  {
2065  return false; // Nothing to send
2066 
2067  }
2068  if (m_endPoint == 0 && m_endPoint6 == 0)
2069  {
2070  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
2071  return false; // Is this the right way to handle this condition?
2072  }
2073  uint32_t nPacketsSent = 0;
2074  while (m_txBuffer->SizeFromSequence (m_nextTxSequence))
2075  {
2076  uint32_t w = AvailableWindow (); // Get available window size
2077  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
2078  " w " << w <<
2079  " rxwin " << m_rWnd <<
2080  " segsize " << m_segmentSize <<
2081  " nextTxSeq " << m_nextTxSequence <<
2082  " highestRxAck " << m_txBuffer->HeadSequence () <<
2083  " pd->Size " << m_txBuffer->Size () <<
2084  " pd->SFS " << m_txBuffer->SizeFromSequence (m_nextTxSequence));
2085  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
2086  if (w < m_segmentSize && m_txBuffer->SizeFromSequence (m_nextTxSequence) > w)
2087  {
2088  break; // No more
2089  }
2090  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
2091  // in the buffer and the amount of data to send is less than one segment
2092  if (!m_noDelay && UnAckDataCount () > 0
2093  && m_txBuffer->SizeFromSequence (m_nextTxSequence) < m_segmentSize)
2094  {
2095  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
2096  break;
2097  }
2098  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
2099  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
2100  nPacketsSent++; // Count sent this loop
2101  m_nextTxSequence += sz; // Advance next tx sequence
2102  }
2103  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
2104  return (nPacketsSent > 0);
2105 }
2106 
2107 uint32_t
2109 {
2110  NS_LOG_FUNCTION (this);
2111  return m_nextTxSequence.Get () - m_txBuffer->HeadSequence ();
2112 }
2113 
2114 uint32_t
2116 {
2117  NS_LOG_FUNCTION (this);
2118  return m_highTxMark.Get () - m_txBuffer->HeadSequence ();
2119 }
2120 
2121 uint32_t
2123 {
2124  NS_LOG_FUNCTION (this);
2125  return m_rWnd;
2126 }
2127 
2128 uint32_t
2130 {
2132  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
2133  uint32_t win = Window (); // Number of bytes allowed to be outstanding
2134  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
2135  return (win < unack) ? 0 : (win - unack);
2136 }
2137 
2138 uint16_t
2140 {
2141  uint32_t w = m_rxBuffer->MaxBufferSize () - m_rxBuffer->Size ();
2142 
2143  w >>= m_sndScaleFactor;
2144 
2145  if (w > m_maxWinSize)
2146  {
2147  NS_LOG_WARN ("There is a loss in the adv win size, wrt buffer size");
2148  w = m_maxWinSize;
2149  }
2150 
2151  return (uint16_t) w;
2152 }
2153 
2154 // Receipt of new packet, put into Rx buffer
2155 void
2157 {
2158  NS_LOG_FUNCTION (this << tcpHeader);
2159  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
2160  " ack " << tcpHeader.GetAckNumber () <<
2161  " pkt size " << p->GetSize () );
2162 
2163  // Put into Rx buffer
2164  SequenceNumber32 expectedSeq = m_rxBuffer->NextRxSequence ();
2165  if (!m_rxBuffer->Add (p, tcpHeader))
2166  { // Insert failed: No data or RX buffer full
2168  return;
2169  }
2170  // Now send a new ACK packet acknowledging all received and delivered data
2171  if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequence () > expectedSeq + p->GetSize ())
2172  { // A gap exists in the buffer, or we filled a gap: Always ACK
2174  }
2175  else
2176  { // In-sequence packet: ACK if delayed ack count allows
2178  {
2179  m_delAckEvent.Cancel ();
2180  m_delAckCount = 0;
2182  }
2183  else if (m_delAckEvent.IsExpired ())
2184  {
2187  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
2188  }
2189  }
2190  // Notify app to receive if necessary
2191  if (expectedSeq < m_rxBuffer->NextRxSequence ())
2192  { // NextRxSeq advanced, we have something to send to the app
2193  if (!m_shutdownRecv)
2194  {
2195  NotifyDataRecv ();
2196  }
2197  // Handle exceptions
2198  if (m_closeNotified)
2199  {
2200  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
2201  }
2202  // If we received FIN before and now completed all "holes" in rx buffer,
2203  // invoke peer close procedure
2204  if (m_rxBuffer->Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2205  {
2206  DoPeerClose ();
2207  }
2208  }
2209 }
2210 
2218 void
2220 {
2221  SequenceNumber32 ackSeq = tcpHeader.GetAckNumber();
2222  Time m = Time (0.0);
2223 
2224  // An ack has been received, calculate rtt and log this measurement
2225  // Note we use a linear search (O(n)) for this since for the common
2226  // case the ack'ed packet will be at the head of the list
2227  if (!m_history.empty ())
2228  {
2229  RttHistory& h = m_history.front ();
2230  if (!h.retx && ackSeq >= (h.seq + SequenceNumber32 (h.count)))
2231  { // Ok to use this sample
2232  if (m_timestampEnabled && tcpHeader.HasOption (TcpOption::TS))
2233  {
2234  Ptr<TcpOptionTS> ts;
2235  ts = DynamicCast<TcpOptionTS> (tcpHeader.GetOption (TcpOption::TS));
2236  m = TcpOptionTS::ElapsedTimeFromTsValue (ts->GetEcho ());
2237  }
2238  else
2239  {
2240  m = Simulator::Now () - h.time; // Elapsed time
2241  }
2242  }
2243  }
2244 
2245  // Now delete all ack history with seq <= ack
2246  while(!m_history.empty ())
2247  {
2248  RttHistory& h = m_history.front ();
2249  if ((h.seq + SequenceNumber32 (h.count)) > ackSeq) break; // Done removing
2250  m_history.pop_front (); // Remove
2251  }
2252 
2253  if (!m.IsZero ())
2254  {
2255  m_rtt->Measurement (m); // Log the measurement
2256  // RFC 6298, clause 2.4
2257  m_rto = Max (m_rtt->GetEstimate () + Max (m_clockGranularity, m_rtt->GetVariation ()*4), Time::FromDouble (1, Time::S));
2258  m_lastRtt = m_rtt->GetEstimate ();
2259  NS_LOG_FUNCTION(this << m_lastRtt);
2260  }
2261 }
2262 
2263 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
2264 // when the three-way handshake completed. This cancels retransmission timer
2265 // and advances Tx window
2266 void
2268 {
2269  NS_LOG_FUNCTION (this << ack);
2270 
2271  if (m_state != SYN_RCVD)
2272  { // Set RTO unless the ACK is received in SYN_RCVD state
2273  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2274  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2275  m_retxEvent.Cancel ();
2276  // On receiving a "New" ack we restart retransmission timer .. RFC 6298
2277  // RFC 6298, clause 2.4
2278  m_rto = Max (m_rtt->GetEstimate () + Max (m_clockGranularity, m_rtt->GetVariation ()*4), Time::FromDouble (1, Time::S));
2279 
2280  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
2281  Simulator::Now ().GetSeconds () << " to expire at time " <<
2282  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2284  }
2285  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
2286  { // Zero window: Enter persist state to send 1 byte to probe
2287  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
2288  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
2289  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2290  m_retxEvent.Cancel ();
2291  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
2292  Simulator::Now ().GetSeconds () << " to expire at time " <<
2293  (Simulator::Now () + m_persistTimeout).GetSeconds ());
2296  }
2297  // Note the highest ACK and tell app to send more
2298  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2299  " numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed
2300  m_txBuffer->DiscardUpTo (ack);
2301  if (GetTxAvailable () > 0)
2302  {
2304  }
2305  if (ack > m_nextTxSequence)
2306  {
2307  m_nextTxSequence = ack; // If advanced
2308  }
2309  if (m_txBuffer->Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2310  { // No retransmit timer if no data to retransmit
2311  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2312  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2313  m_retxEvent.Cancel ();
2314  }
2315  // Try to send more data
2317 }
2318 
2319 // Retransmit timeout
2320 void
2322 {
2323  NS_LOG_FUNCTION (this);
2324  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2325  // If erroneous timeout in closed/timed-wait state, just return
2326  if (m_state == CLOSED || m_state == TIME_WAIT)
2327  {
2328  return;
2329  }
2330  // If all data are received (non-closing socket and nothing to send), just return
2331  if (m_state <= ESTABLISHED && m_txBuffer->HeadSequence () >= m_highTxMark)
2332  {
2333  return;
2334  }
2335 
2336  Retransmit ();
2337 }
2338 
2339 void
2341 {
2342  m_delAckCount = 0;
2344 }
2345 
2346 void
2348 {
2349  NS_LOG_FUNCTION (this);
2350 
2352  if (m_state == LAST_ACK)
2353  {
2354  CloseAndNotify ();
2355  }
2356  if (!m_closeNotified)
2357  {
2358  m_closeNotified = true;
2359  }
2360 }
2361 
2362 // Send 1-byte data to probe for the window size at the receiver when
2363 // the local knowledge tells that the receiver has zero window size
2364 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2365 void
2367 {
2368  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2369  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2370  Ptr<Packet> p = m_txBuffer->CopyFromSequence (1, m_nextTxSequence);
2371  TcpHeader tcpHeader;
2372  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2373  tcpHeader.SetAckNumber (m_rxBuffer->NextRxSequence ());
2374  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2375  if (m_endPoint != 0)
2376  {
2377  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2378  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2379  }
2380  else
2381  {
2382  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2383  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2384  }
2385  AddOptions (tcpHeader);
2386 
2387  if (m_endPoint != 0)
2388  {
2389  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2391  }
2392  else
2393  {
2394  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2396  }
2397  NS_LOG_LOGIC ("Schedule persist timeout at time "
2398  << Simulator::Now ().GetSeconds () << " to expire at time "
2399  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2401 }
2402 
2403 void
2405 {
2406  m_nextTxSequence = m_txBuffer->HeadSequence (); // Start from highest Ack
2407  m_dupAckCount = 0;
2408  DoRetransmit (); // Retransmit the packet
2409 }
2410 
2411 void
2413 {
2414  NS_LOG_FUNCTION (this);
2415  // Retransmit SYN packet
2416  if (m_state == SYN_SENT)
2417  {
2418  if (m_cnCount > 0)
2419  {
2421  }
2422  else
2423  {
2425  }
2426  return;
2427  }
2428  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2429  if (m_txBuffer->Size () == 0)
2430  {
2431  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2432  { // Must have lost FIN, re-send
2434  }
2435  return;
2436  }
2437  // Retransmit a data packet: Call SendDataPacket
2438  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer->HeadSequence ());
2439  uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_segmentSize, true);
2440  // In case of RTO, advance m_nextTxSequence
2441  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz);
2442 
2443 }
2444 
2445 void
2447 {
2448  m_retxEvent.Cancel ();
2450  m_delAckEvent.Cancel ();
2453 }
2454 
2455 /* Move TCP to Time_Wait state and schedule a transition to Closed state */
2456 void
2458 {
2459  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2460  m_state = TIME_WAIT;
2461  CancelAllTimers ();
2462  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2463  // according to RFC793, p.28
2466 }
2467 
2468 /* Below are the attribute get/set functions */
2469 
2470 void
2472 {
2473  m_txBuffer->SetMaxBufferSize (size);
2474 }
2475 
2476 uint32_t
2478 {
2479  return m_txBuffer->MaxBufferSize ();
2480 }
2481 
2482 void
2484 {
2485  m_rxBuffer->SetMaxBufferSize (size);
2486 }
2487 
2488 uint32_t
2490 {
2491  return m_rxBuffer->MaxBufferSize ();
2492 }
2493 
2494 void
2496 {
2497  m_segmentSize = size;
2498  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2499 }
2500 
2501 uint32_t
2503 {
2504  return m_segmentSize;
2505 }
2506 
2507 void
2509 {
2510  m_cnTimeout = timeout;
2511 }
2512 
2513 Time
2515 {
2516  return m_cnTimeout;
2517 }
2518 
2519 void
2521 {
2522  m_cnRetries = count;
2523 }
2524 
2525 uint32_t
2527 {
2528  return m_cnRetries;
2529 }
2530 
2531 void
2533 {
2535 }
2536 
2537 Time
2539 {
2540  return m_delAckTimeout;
2541 }
2542 
2543 void
2545 {
2546  m_delAckMaxCount = count;
2547 }
2548 
2549 uint32_t
2551 {
2552  return m_delAckMaxCount;
2553 }
2554 
2555 void
2557 {
2558  m_noDelay = noDelay;
2559 }
2560 
2561 bool
2563 {
2564  return m_noDelay;
2565 }
2566 
2567 void
2569 {
2571 }
2572 
2573 Time
2575 {
2576  return m_persistTimeout;
2577 }
2578 
2579 bool
2581 {
2582  // Broadcast is not implemented. Return true only if allowBroadcast==false
2583  return (!allowBroadcast);
2584 }
2585 
2586 bool
2588 {
2589  return false;
2590 }
2591 
2592 void
2594 {
2595  NS_LOG_FUNCTION (this << header);
2596 
2597  if ((header.GetFlags () & TcpHeader::SYN))
2598  {
2599  if (m_winScalingEnabled)
2600  {
2601  m_winScalingEnabled = false;
2602 
2603  if (header.HasOption (TcpOption::WINSCALE))
2604  {
2605  m_winScalingEnabled = true;
2607  }
2608  }
2609  }
2610 
2611  m_timestampEnabled = false;
2612 
2613  if (header.HasOption (TcpOption::TS))
2614  {
2615  m_timestampEnabled = true;
2617  }
2618 }
2619 
2620 void
2622 {
2623  NS_LOG_FUNCTION (this << header);
2624 
2625  // The window scaling option is set only on SYN packets
2626  if (m_winScalingEnabled && (header.GetFlags () & TcpHeader::SYN))
2627  {
2628  AddOptionWScale (header);
2629  }
2630 
2631  if (m_timestampEnabled)
2632  {
2633  AddOptionTimestamp (header);
2634  }
2635 }
2636 
2637 void
2639 {
2640  NS_LOG_FUNCTION (this << option);
2641 
2642  Ptr<const TcpOptionWinScale> ws = DynamicCast<const TcpOptionWinScale> (option);
2643 
2644  // In naming, we do the contrary of RFC 1323. The received scaling factor
2645  // is Rcv.Wind.Scale (and not Snd.Wind.Scale)
2646  m_rcvScaleFactor = ws->GetScale ();
2647 
2648  if (m_rcvScaleFactor > 14)
2649  {
2650  NS_LOG_WARN ("Possible error; m_rcvScaleFactor exceeds 14: " << m_rcvScaleFactor);
2651  m_rcvScaleFactor = 14;
2652  }
2653 
2654  NS_LOG_INFO (m_node->GetId () << " Received a scale factor of " <<
2655  static_cast<int> (m_rcvScaleFactor));
2656 }
2657 
2658 uint8_t
2660 {
2661  NS_LOG_FUNCTION (this);
2662  uint32_t maxSpace = m_rxBuffer->MaxBufferSize ();
2663  uint8_t scale = 0;
2664 
2665  while (maxSpace > m_maxWinSize)
2666  {
2667  maxSpace = maxSpace >> 1;
2668  ++scale;
2669  }
2670 
2671  if (scale > 14)
2672  {
2673  NS_LOG_WARN ("Possible error; scale exceeds 14: " << scale);
2674  scale = 14;
2675  }
2676 
2677  NS_LOG_INFO ("Node " << m_node->GetId () << " calculated wscale factor of " <<
2678  static_cast<int> (scale) << " for buffer size " << m_rxBuffer->MaxBufferSize ());
2679  return scale;
2680 }
2681 
2682 void
2684 {
2685  NS_LOG_FUNCTION (this << header);
2686  NS_ASSERT(header.GetFlags () & TcpHeader::SYN);
2687 
2688  Ptr<TcpOptionWinScale> option = CreateObject<TcpOptionWinScale> ();
2689 
2690  // In naming, we do the contrary of RFC 1323. The sended scaling factor
2691  // is Snd.Wind.Scale (and not Rcv.Wind.Scale)
2692 
2694  option->SetScale (m_sndScaleFactor);
2695 
2696  header.AppendOption (option);
2697 
2698  NS_LOG_INFO (m_node->GetId () << " Send a scaling factor of " <<
2699  static_cast<int> (m_sndScaleFactor));
2700 }
2701 
2702 void
2704 {
2705  NS_LOG_FUNCTION (this << option);
2706 
2707  Ptr<const TcpOptionTS> ts = DynamicCast<const TcpOptionTS> (option);
2708  m_timestampToEcho = ts->GetTimestamp ();
2709 
2710  NS_LOG_INFO (m_node->GetId () << " Got timestamp=" <<
2711  m_timestampToEcho << " and Echo=" << ts->GetEcho ());
2712 }
2713 
2714 void
2716 {
2717  NS_LOG_FUNCTION (this << header);
2718 
2719  Ptr<TcpOptionTS> option = CreateObject<TcpOptionTS> ();
2720 
2721  option->SetTimestamp (TcpOptionTS::NowToTsValue ());
2722  option->SetEcho (m_timestampToEcho);
2723 
2724  header.AppendOption (option);
2725  NS_LOG_INFO (m_node->GetId () << " Add option TS, ts=" <<
2726  option->GetTimestamp () << " echo=" << m_timestampToEcho);
2727 }
2728 
2729 void
2731 {
2732  NS_LOG_FUNCTION (this << minRto);
2733  m_minRto = minRto;
2734 }
2735 
2736 Time
2738 {
2739  return m_minRto;
2740 }
2741 
2742 void
2744 {
2745  NS_LOG_FUNCTION (this << clockGranularity);
2746  m_clockGranularity = clockGranularity;
2747 }
2748 
2749 Time
2751 {
2752  return m_clockGranularity;
2753 }
2754 
2757 {
2758  return m_txBuffer;
2759 }
2760 
2763 {
2764  return m_rxBuffer;
2765 }
2766 
2767 
2768 //RttHistory methods
2770  : seq (s), count (c), time (t), retx (false)
2771 {
2772 }
2773 
2775  : seq (h.seq), count (h.count), time (h.time), retx (h.retx)
2776 {
2777 }
2778 
2779 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:232
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:816
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.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
bool IsManualIpTtl(void) const
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:382
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)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void ProcessWait(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon CLOSE_WAIT, FIN_WAIT_1, FIN_WAIT_2.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:115
AttributeValue implementation for Boolean.
Definition: boolean.h:34
virtual uint8_t GetIpTtl(void) const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:470
virtual uint16_t AdvertisedWindowSize(void)
The amount of Rx window announced to the peer.
Callback template class.
Definition: callback.h:978
bool m_noDelay
Set to true to disable Nagle's algorithm.
virtual uint32_t GetSegSize(void) const
Get the segment size.
Time GetClockGranularity(void) const
Get the Clock Granularity (used in RTO calcs).
uint8_t GetIpTos(void) const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:403
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:1047
(abstract) base class of all TcpSockets
Definition: tcp-socket.h:77
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
static Time ElapsedTimeFromTsValue(uint32_t echoTime)
Estimate the Time elapsed from a TS echo value.
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:133
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:304
virtual int ShutdownRecv(void)
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Set the reception callback.
TcpSocketBase(void)
Create an unbound TCP socket.
void SetClockGranularity(Time clockGranularity)
Sets the Clock Granularity (used in RTO calcs).
EventId m_retxEvent
Retransmission event.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
IPv6 layer implementation.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:121
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.
bool IsZero(void) const
Definition: nstime.h:269
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:836
void SetAddress(Address addr)
Set the tag's address.
Definition: socket.cc:522
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:226
static TypeId GetTypeId(void)
Get the type ID.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
void SendRST(void)
Send reset and tear down this socket.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:867
bool m_winScalingEnabled
Window Scale option enabled.
bool m_timestampEnabled
Timestamp option enabled.
uint16_t m_maxWinSize
Maximum window size to advertise.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
second
Definition: nstime.h:107
bool retx
True if this has been retransmitted.
bool IsManualIpTos(void) const
Checks if the socket has a specific IPv4 ToS set.
Definition: socket.cc:370
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.
uint32_t count
Number of bytes sent.
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
virtual uint8_t GetIpv6HopLimit(void) const
Query the value of IP Hop Limit field of this socket.
Definition: socket.cc:495
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.
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
EventId m_lastAckEvent
Last ACK timeout event.
void ConnectionSucceeded(void)
Schedule-friendly wrapper for Socket::NotifyConnectionSucceeded()
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:760
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:819
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
Get the underlying value.
Definition: traced-value.h:186
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:999
virtual Time GetPersistTimeout(void) const
Get the timout for persistent connection.
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:256
virtual void PersistTimeout(void)
Send 1 byte probe to get an updated window size.
Ptr< TcpTxBuffer > GetTxBuffer(void) const
Get a pointer to the Tx buffer.
TracedValue< TcpStates_t > m_state
TCP state.
uint32_t m_delAckMaxCount
Number of packet to fire an ACK before delay timeout.
uint8_t CalculateWScale() const
Calculate window scale value based on receive buffer space.
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:90
void SetMinRto(Time minRto)
Sets the Minimum RTO.
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
uint16_t GetPeerPort()
Get the peer port.
AttributeValue implementation for Callback.
Definition: callback.h:1681
uint32_t m_cnRetries
Number of connection retries before giving up.
virtual uint32_t GetRcvBufSize(void) const
Get the receive buffer size.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
uint32_t m_delAckCount
Delayed ACK counter.
virtual bool GetTcpNoDelay(void) const
Check if Nagle's algorithm is enabled or not.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
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.
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.
bool AppendOption(Ptr< TcpOption > option)
Append an option to the TCP header.
Definition: tcp-header.cc:453
virtual void ReadOptions(const TcpHeader &tcpHeader)
Read TCP options from incoming packets.
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:191
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
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.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:210
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:73
Time time
Time this one was sent.
virtual uint32_t UnAckDataCount(void)
Return count of number of unacked bytes.
Ptr< TcpTxBuffer > m_txBuffer
Tx buffer.
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:93
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:582
AttributeValue implementation for Time.
Definition: nstime.h:921
virtual uint32_t GetSndBufSize(void) const
Get the send buffer size.
virtual enum SocketType GetSocketType(void) const
uint16_t GetLocalPort()
Get the local port.
void AddOptionTimestamp(TcpHeader &header)
Add the timestamp option to the header.
Hold an unsigned integer type.
Definition: uinteger.h:44
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.
Ptr< const AttributeAccessor > MakeCallbackAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: callback.h:1723
Ipv4Address GetLocalAddress(void)
Get the local address.
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:203
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:951
RttHistory(SequenceNumber32 s, uint32_t c, Time t)
Constructor - builds an RttHistory with the given parameters.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
bool IsManualIpv6Tclass(void) const
Checks if the socket has a specific IPv6 Tclass set.
Definition: socket.cc:376
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:284
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:127
enum SocketErrno m_errno
Socket error code.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition: object.h:490
A base class for implementation of a stream socket using TCP.
uint8_t m_sndScaleFactor
Sent Window Scale (i.e., the one of the node)
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.
Ptr< TcpRxBuffer > m_rxBuffer
Rx buffer (reordering buffer)
int SetupCallback(void)
Common part of the two Bind(), i.e.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
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:642
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)
Set the destination port.
Definition: tcp-header.cc:67
void NotifyConnectionSucceeded(void)
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:216
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:85
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
bool IsManualIpv6HopLimit(void) const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition: socket.cc:388
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:236
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 options to TcpHeader.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t m_dupAckCount
Dupack counter.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ptr< Node > m_node
the associated node
Hold objects of type Ptr.
Definition: pointer.h:36
void NotifyNewConnectionCreated(Ptr< Socket > socket, const Address &from)
Notify through the callback (if set) that a new connection has been created.
Definition: socket.cc:274
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
void TimeWait(void)
Move from CLOSING or FIN_WAIT_2 to TIME_WAIT state.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
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)
Set the source port.
Definition: tcp-header.cc:61
virtual uint32_t BytesInFlight(void)
Return total bytes in flight.
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1192
uint8_t GetIpv6Tclass(void) const
Query the value of IPv6 Traffic Class field of this socket.
Definition: socket.cc:445
void Destroy(void)
Kill this socket by zeroing its attributes (IPv4)
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:980
virtual int Close(void)
Close a socket.
static Ipv4Address GetZero(void)
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:922
void SetPeer(Ipv4Address address, uint16_t port)
Set the peer informations (address and port).
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
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:120
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.
Ptr< const AttributeChecker > MakeCallbackChecker(void)
Definition: callback.cc:75
TracedValue< SequenceNumber32 > m_highTxMark
Highest seqno ever sent, regardless of ReTx.
Time m_minRto
minimum value of the Retransmit timeout
static uint32_t NowToTsValue()
Return an uint32_t value which represent "now".
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
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:113
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: double.h:42
void SetLocalAddress(Ipv4Address address)
Set the local address.
virtual void SetSndBufSize(uint32_t size)
Set the send buffer size.
Ptr< TcpOption > GetOption(uint8_t kind) const
Get the option specified.
Definition: tcp-header.cc:479
static Time FromDouble(double value, enum Unit unit)
Create a Time equal to value in unit unit.
Definition: nstime.h:417
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 and m_endPoint6.
Ptr< TcpRxBuffer > GetRxBuffer(void) const
Get a pointer to the Rx buffer.
Describes an IPv6 address.
Definition: ipv6-address.h:47
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
Time GetMinRto(void) const
Get the Minimum RTO.
void ProcessEstablished(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon ESTABLISHED state.
void ProcessOptionWScale(const Ptr< const TcpOption > option)
Read and parse the Window scale option.
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:914
bool m_connected
Connection established.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
uint32_t GetId(void) const
Definition: node.cc:106
TracedValue< Time > m_rto
Retransmit timeout.
Helper class to store RTT measurements.
uint16_t GetLocalPort(void)
Get the local port.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:79
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.
SequenceNumber32 seq
First sequence number in packet sent.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
RttHistory_t m_history
List of sent packet.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Ipv4Address GetPeerAddress(void)
Get the peer address.
uint32_t m_timestampToEcho
Timestamp to echo.
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:53
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)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
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:83
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.
uint8_t m_rcvScaleFactor
Received Window Scale (i.e., the one of the peer)
bool m_shutdownRecv
Receive no longer allowed.
virtual Time GetDelAckTimeout(void) const
Get the time to delay an ACK.
virtual void DelAckTimeout(void)
Action upon delay ACK timeout, i.e.
bool HasOption(uint8_t kind) const
Check if the header has the option specified.
Definition: tcp-header.cc:495
virtual void LastAckTimeout(void)
Timeout at LAST_ACK, close the connection.
void SetWindowSize(uint16_t windowSize)
Set the window size.
Definition: tcp-header.cc:91
This class can be used to hold variables of floating point type such as 'double' or 'float'...
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:1145
void ProcessOptionTimestamp(const Ptr< const TcpOption > option)
Process the timestamp option from other side.
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
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:51
bool m_shutdownSend
Send no longer allowed.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
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:294
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
Time m_clockGranularity
Clock Granularity used in RTO calcs.
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:246
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
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:111
void AddOptionWScale(TcpHeader &header)
Add the window scale option to the header.
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.
void Destroy6(void)
Kill this socket by zeroing its attributes (IPv6)
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.