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