A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
tcp-socket-base.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 Georgia Tech Research Corporation
4  * Copyright (c) 2010 Adrian Sai-wah Tam
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
20  */
21 
22 #define NS_LOG_APPEND_CONTEXT \
23  if (m_node) { std::clog << Simulator::Now ().GetSeconds () << " [node " << m_node->GetId () << "] "; }
24 
25 #include "ns3/abort.h"
26 #include "ns3/node.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/inet6-socket-address.h"
29 #include "ns3/log.h"
30 #include "ns3/ipv4.h"
31 #include "ns3/ipv6.h"
32 #include "ns3/ipv4-interface-address.h"
33 #include "ns3/ipv4-route.h"
34 #include "ns3/ipv6-route.h"
35 #include "ns3/ipv4-routing-protocol.h"
36 #include "ns3/ipv6-routing-protocol.h"
37 #include "ns3/simulation-singleton.h"
38 #include "ns3/simulator.h"
39 #include "ns3/packet.h"
40 #include "ns3/uinteger.h"
41 #include "ns3/double.h"
42 #include "ns3/trace-source-accessor.h"
43 #include "tcp-socket-base.h"
44 #include "tcp-l4-protocol.h"
45 #include "ipv4-end-point.h"
46 #include "ipv6-end-point.h"
47 #include "ipv6-l3-protocol.h"
48 #include "tcp-header.h"
49 #include "tcp-option-winscale.h"
50 #include "tcp-option-ts.h"
51 #include "rtt-estimator.h"
52 
53 #include <math.h>
54 #include <algorithm>
55 
56 NS_LOG_COMPONENT_DEFINE ("TcpSocketBase");
57 
58 namespace ns3 {
59 
60 NS_OBJECT_ENSURE_REGISTERED (TcpSocketBase);
61 
62 TypeId
64 {
65  static TypeId tid = TypeId ("ns3::TcpSocketBase")
66  .SetParent<TcpSocket> ()
67 // .AddAttribute ("TcpState", "State in TCP state machine",
68 // TypeId::ATTR_GET,
69 // EnumValue (CLOSED),
70 // MakeEnumAccessor (&TcpSocketBase::m_state),
71 // MakeEnumChecker (CLOSED, "Closed"))
72  .AddAttribute ("MaxSegLifetime",
73  "Maximum segment lifetime in seconds, use for TIME_WAIT state transition to CLOSED state",
74  DoubleValue (120), /* RFC793 says MSL=2 minutes*/
75  MakeDoubleAccessor (&TcpSocketBase::m_msl),
76  MakeDoubleChecker<double> (0))
77  .AddAttribute ("MaxWindowSize", "Max size of advertised window",
78  UintegerValue (65535),
79  MakeUintegerAccessor (&TcpSocketBase::m_maxWinSize),
80  MakeUintegerChecker<uint16_t> ())
81  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
82  CallbackValue (),
83  MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback),
84  MakeCallbackChecker ())
85  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
86  CallbackValue (),
87  MakeCallbackAccessor (&TcpSocketBase::m_icmpCallback6),
88  MakeCallbackChecker ())
89  .AddAttribute ("WindowScaling", "Enable or disable Window Scaling option",
90  BooleanValue (true),
91  MakeBooleanAccessor (&TcpSocketBase::m_winScalingEnabled),
92  MakeBooleanChecker ())
93  .AddAttribute ("Timestamp", "Enable or disable Timestamp option",
94  BooleanValue (true),
95  MakeBooleanAccessor (&TcpSocketBase::m_timestampEnabled),
96  MakeBooleanChecker ())
97  .AddTraceSource ("RTO",
98  "Retransmission timeout",
100  .AddTraceSource ("RTT",
101  "Last RTT sample",
103  .AddTraceSource ("NextTxSequence",
104  "Next sequence number to send (SND.NXT)",
106  .AddTraceSource ("HighestSequence",
107  "Highest sequence number ever sent in socket's life time",
109  .AddTraceSource ("State",
110  "TCP state",
112  .AddTraceSource ("RWND",
113  "Remote side's flow control window",
115  ;
116  return tid;
117 }
118 
120  : m_dupAckCount (0),
121  m_delAckCount (0),
122  m_endPoint (0),
123  m_endPoint6 (0),
124  m_node (0),
125  m_tcp (0),
126  m_rtt (0),
127  m_nextTxSequence (0),
128  // Change this for non-zero initial sequence number
129  m_highTxMark (0),
130  m_rxBuffer (0),
131  m_txBuffer (0),
132  m_state (CLOSED),
133  m_errno (ERROR_NOTERROR),
134  m_closeNotified (false),
135  m_closeOnEmpty (false),
136  m_shutdownSend (false),
137  m_shutdownRecv (false),
138  m_connected (false),
139  m_segmentSize (0),
140  // For attribute initialization consistency (quiet valgrind)
141  m_rWnd (0),
142  m_sndScaleFactor (0),
143  m_rcvScaleFactor (0),
144  m_timestampEnabled (true),
145  m_timestampToEcho (0),
146  m_lastEchoedTime (0)
147 
148 {
149  NS_LOG_FUNCTION (this);
150 }
151 
153  : TcpSocket (sock),
154  //copy object::m_tid and socket::callbacks
155  m_dupAckCount (sock.m_dupAckCount),
156  m_delAckCount (0),
157  m_delAckMaxCount (sock.m_delAckMaxCount),
158  m_noDelay (sock.m_noDelay),
159  m_cnRetries (sock.m_cnRetries),
160  m_delAckTimeout (sock.m_delAckTimeout),
161  m_persistTimeout (sock.m_persistTimeout),
162  m_cnTimeout (sock.m_cnTimeout),
163  m_endPoint (0),
164  m_endPoint6 (0),
165  m_node (sock.m_node),
166  m_tcp (sock.m_tcp),
167  m_rtt (0),
168  m_nextTxSequence (sock.m_nextTxSequence),
169  m_highTxMark (sock.m_highTxMark),
170  m_rxBuffer (sock.m_rxBuffer),
171  m_txBuffer (sock.m_txBuffer),
172  m_state (sock.m_state),
173  m_errno (sock.m_errno),
174  m_closeNotified (sock.m_closeNotified),
175  m_closeOnEmpty (sock.m_closeOnEmpty),
176  m_shutdownSend (sock.m_shutdownSend),
177  m_shutdownRecv (sock.m_shutdownRecv),
178  m_connected (sock.m_connected),
179  m_msl (sock.m_msl),
180  m_segmentSize (sock.m_segmentSize),
181  m_maxWinSize (sock.m_maxWinSize),
182  m_rWnd (sock.m_rWnd),
183  m_winScalingEnabled (sock.m_winScalingEnabled),
184  m_sndScaleFactor (sock.m_sndScaleFactor),
185  m_rcvScaleFactor (sock.m_rcvScaleFactor),
186  m_timestampEnabled (sock.m_timestampEnabled),
187  m_timestampToEcho (sock.m_timestampToEcho),
188  m_lastEchoedTime (sock.m_lastEchoedTime)
189 
190 {
191  NS_LOG_FUNCTION (this);
192  NS_LOG_LOGIC ("Invoked the copy constructor");
193  // Copy the rtt estimator if it is set
194  if (sock.m_rtt)
195  {
196  m_rtt = sock.m_rtt->Copy ();
197  }
198  // Reset all callbacks to null
199  Callback<void, Ptr< Socket > > vPS = MakeNullCallback<void, Ptr<Socket> > ();
200  Callback<void, Ptr<Socket>, const Address &> vPSA = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
201  Callback<void, Ptr<Socket>, uint32_t> vPSUI = MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
202  SetConnectCallback (vPS, vPS);
203  SetDataSentCallback (vPSUI);
204  SetSendCallback (vPSUI);
205  SetRecvCallback (vPS);
206 }
207 
209 {
210  NS_LOG_FUNCTION (this);
211  m_node = 0;
212  if (m_endPoint != 0)
213  {
214  NS_ASSERT (m_tcp != 0);
215  /*
216  * Upon Bind, an Ipv4Endpoint is allocated and set to m_endPoint, and
217  * DestroyCallback is set to TcpSocketBase::Destroy. If we called
218  * m_tcp->DeAllocate, it wil destroy its Ipv4EndpointDemux::DeAllocate,
219  * which in turn destroys my m_endPoint, and in turn invokes
220  * TcpSocketBase::Destroy to nullify m_node, m_endPoint, and m_tcp.
221  */
222  NS_ASSERT (m_endPoint != 0);
223  m_tcp->DeAllocate (m_endPoint);
224  NS_ASSERT (m_endPoint == 0);
225  }
226  if (m_endPoint6 != 0)
227  {
228  NS_ASSERT (m_tcp != 0);
229  NS_ASSERT (m_endPoint6 != 0);
230  m_tcp->DeAllocate (m_endPoint6);
231  NS_ASSERT (m_endPoint6 == 0);
232  }
233  m_tcp = 0;
234  CancelAllTimers ();
235 }
236 
237 /* Associate a node with this TCP socket */
238 void
240 {
241  m_node = node;
242 }
243 
244 /* Associate the L4 protocol (e.g. mux/demux) with this socket */
245 void
247 {
248  m_tcp = tcp;
249 }
250 
251 /* Set an RTT estimator with this socket */
252 void
254 {
255  m_rtt = rtt;
256 }
257 
258 /* Inherit from Socket class: Returns error code */
261 {
262  return m_errno;
263 }
264 
265 /* Inherit from Socket class: Returns socket type, NS3_SOCK_STREAM */
268 {
269  return NS3_SOCK_STREAM;
270 }
271 
272 /* Inherit from Socket class: Returns associated node */
273 Ptr<Node>
275 {
277  return m_node;
278 }
279 
280 /* Inherit from Socket class: Bind socket to an end-point in TcpL4Protocol */
281 int
283 {
284  NS_LOG_FUNCTION (this);
285  m_endPoint = m_tcp->Allocate ();
286  if (0 == m_endPoint)
287  {
289  return -1;
290  }
291 
292  if (std::find(m_tcp->m_sockets.begin(), m_tcp->m_sockets.end(), this) == m_tcp->m_sockets.end())
293  {
294  m_tcp->m_sockets.push_back (this);
295  }
296  return SetupCallback ();
297 }
298 
299 int
301 {
302  NS_LOG_FUNCTION (this);
303  m_endPoint6 = m_tcp->Allocate6 ();
304  if (0 == m_endPoint6)
305  {
307  return -1;
308  }
309 
310  if (std::find(m_tcp->m_sockets.begin(), m_tcp->m_sockets.end(), this) == m_tcp->m_sockets.end())
311  {
312  m_tcp->m_sockets.push_back (this);
313  }
314  return SetupCallback ();
315 }
316 
317 /* Inherit from Socket class: Bind socket (with specific address) to an end-point in TcpL4Protocol */
318 int
320 {
321  NS_LOG_FUNCTION (this << address);
322  if (InetSocketAddress::IsMatchingType (address))
323  {
325  Ipv4Address ipv4 = transport.GetIpv4 ();
326  uint16_t port = transport.GetPort ();
327  if (ipv4 == Ipv4Address::GetAny () && port == 0)
328  {
329  m_endPoint = m_tcp->Allocate ();
330  }
331  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
332  {
333  m_endPoint = m_tcp->Allocate (port);
334  }
335  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
336  {
337  m_endPoint = m_tcp->Allocate (ipv4);
338  }
339  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
340  {
341  m_endPoint = m_tcp->Allocate (ipv4, port);
342  }
343  if (0 == m_endPoint)
344  {
346  return -1;
347  }
348  }
349  else if (Inet6SocketAddress::IsMatchingType (address))
350  {
352  Ipv6Address ipv6 = transport.GetIpv6 ();
353  uint16_t port = transport.GetPort ();
354  if (ipv6 == Ipv6Address::GetAny () && port == 0)
355  {
356  m_endPoint6 = m_tcp->Allocate6 ();
357  }
358  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
359  {
360  m_endPoint6 = m_tcp->Allocate6 (port);
361  }
362  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
363  {
364  m_endPoint6 = m_tcp->Allocate6 (ipv6);
365  }
366  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
367  {
368  m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
369  }
370  if (0 == m_endPoint6)
371  {
373  return -1;
374  }
375  }
376  else
377  {
379  return -1;
380  }
381 
382  if (std::find(m_tcp->m_sockets.begin(), m_tcp->m_sockets.end(), this) == m_tcp->m_sockets.end())
383  {
384  m_tcp->m_sockets.push_back (this);
385  }
386  NS_LOG_LOGIC ("TcpSocketBase " << this << " got an endpoint: " << m_endPoint);
387 
388  return SetupCallback ();
389 }
390 
391 /* Inherit from Socket class: Initiate connection to a remote address:port */
392 int
394 {
395  NS_LOG_FUNCTION (this << address);
396 
397  // If haven't do so, Bind() this socket first
398  if (InetSocketAddress::IsMatchingType (address) && m_endPoint6 == 0)
399  {
400  if (m_endPoint == 0)
401  {
402  if (Bind () == -1)
403  {
404  NS_ASSERT (m_endPoint == 0);
405  return -1; // Bind() failed
406  }
407  NS_ASSERT (m_endPoint != 0);
408  }
410  m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ());
411  m_endPoint6 = 0;
412 
413  // Get the appropriate local address and port number from the routing protocol and set up endpoint
414  if (SetupEndpoint () != 0)
415  { // Route to destination does not exist
416  return -1;
417  }
418  }
419  else if (Inet6SocketAddress::IsMatchingType (address) && m_endPoint == 0)
420  {
421  // If we are operating on a v4-mapped address, translate the address to
422  // a v4 address and re-call this function
424  Ipv6Address v6Addr = transport.GetIpv6 ();
425  if (v6Addr.IsIpv4MappedAddress () == true)
426  {
427  Ipv4Address v4Addr = v6Addr.GetIpv4MappedAddress ();
428  return Connect (InetSocketAddress (v4Addr, transport.GetPort ()));
429  }
430 
431  if (m_endPoint6 == 0)
432  {
433  if (Bind6 () == -1)
434  {
435  NS_ASSERT (m_endPoint6 == 0);
436  return -1; // Bind() failed
437  }
438  NS_ASSERT (m_endPoint6 != 0);
439  }
440  m_endPoint6->SetPeer (v6Addr, transport.GetPort ());
441  m_endPoint = 0;
442 
443  // Get the appropriate local address and port number from the routing protocol and set up endpoint
444  if (SetupEndpoint6 () != 0)
445  { // Route to destination does not exist
446  return -1;
447  }
448  }
449  else
450  {
452  return -1;
453  }
454 
455  // Re-initialize parameters in case this socket is being reused after CLOSE
456  m_rtt->Reset ();
458 
459  // DoConnect() will do state-checking and send a SYN packet
460  return DoConnect ();
461 }
462 
463 /* Inherit from Socket class: Listen on the endpoint for an incoming connection */
464 int
466 {
467  NS_LOG_FUNCTION (this);
468  // Linux quits EINVAL if we're not in CLOSED state, so match what they do
469  if (m_state != CLOSED)
470  {
472  return -1;
473  }
474  // In other cases, set the state to LISTEN and done
475  NS_LOG_INFO ("CLOSED -> LISTEN");
476  m_state = LISTEN;
477  return 0;
478 }
479 
480 /* Inherit from Socket class: Kill this socket and signal the peer (if any) */
481 int
483 {
484  NS_LOG_FUNCTION (this);
488  if (m_rxBuffer.Size () != 0)
489  {
490  NS_LOG_INFO ("Socket " << this << " << unread rx data during close. Sending reset");
491  SendRST ();
492  return 0;
493  }
494 
496  { // App close with pending data must wait until all data transmitted
497  if (m_closeOnEmpty == false)
498  {
499  m_closeOnEmpty = true;
500  NS_LOG_INFO ("Socket " << this << " deferring close, state " << TcpStateName[m_state]);
501  }
502  return 0;
503  }
504  return DoClose ();
505 }
506 
507 /* Inherit from Socket class: Signal a termination of send */
508 int
510 {
511  NS_LOG_FUNCTION (this);
512 
513  //this prevents data from being added to the buffer
514  m_shutdownSend = true;
515  m_closeOnEmpty = true;
516  //if buffer is already empty, send a fin now
517  //otherwise fin will go when buffer empties.
518  if (m_txBuffer.Size () == 0)
519  {
520  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
521  {
522  NS_LOG_INFO("Emtpy tx buffer, send fin");
524 
525  if (m_state == ESTABLISHED)
526  { // On active close: I am the first one to send FIN
527  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
529  }
530  else
531  { // On passive close: Peer sent me FIN already
532  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
533  m_state = LAST_ACK;
534  }
535  }
536  }
537 
538  return 0;
539 }
540 
541 /* Inherit from Socket class: Signal a termination of receive */
542 int
544 {
545  NS_LOG_FUNCTION (this);
546  m_shutdownRecv = true;
547  return 0;
548 }
549 
550 /* Inherit from Socket class: Send a packet. Parameter flags is not used.
551  Packet has no TCP header. Invoked by upper-layer application */
552 int
553 TcpSocketBase::Send (Ptr<Packet> p, uint32_t flags)
554 {
555  NS_LOG_FUNCTION (this << p);
556  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Send()");
558  {
559  // Store the packet into Tx buffer
560  if (!m_txBuffer.Add (p))
561  { // TxBuffer overflow, send failed
563  return -1;
564  }
565  if (m_shutdownSend)
566  {
568  return -1;
569  }
570  // Submit the data to lower layers
571  NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
572  if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
573  { // Try to send the data out
575  }
576  return p->GetSize ();
577  }
578  else
579  { // Connection not established yet
581  return -1; // Send failure
582  }
583 }
584 
585 /* Inherit from Socket class: In TcpSocketBase, it is same as Send() call */
586 int
588 {
589  return Send (p, flags); // SendTo() and Send() are the same
590 }
591 
592 /* Inherit from Socket class: Return data to upper-layer application. Parameter flags
593  is not used. Data is returned as a packet of size no larger than maxSize */
595 TcpSocketBase::Recv (uint32_t maxSize, uint32_t flags)
596 {
597  NS_LOG_FUNCTION (this);
598  NS_ABORT_MSG_IF (flags, "use of flags is not supported in TcpSocketBase::Recv()");
599  if (m_rxBuffer.Size () == 0 && m_state == CLOSE_WAIT)
600  {
601  return Create<Packet> (); // Send EOF on connection close
602  }
603  Ptr<Packet> outPacket = m_rxBuffer.Extract (maxSize);
604  if (outPacket != 0 && outPacket->GetSize () != 0)
605  {
606  SocketAddressTag tag;
607  if (m_endPoint != 0)
608  {
610  }
611  else if (m_endPoint6 != 0)
612  {
614  }
615  outPacket->AddPacketTag (tag);
616  }
617  return outPacket;
618 }
619 
620 /* Inherit from Socket class: Recv and return the remote's address */
622 TcpSocketBase::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
623 {
624  NS_LOG_FUNCTION (this << maxSize << flags);
625  Ptr<Packet> packet = Recv (maxSize, flags);
626  // Null packet means no data to read, and an empty packet indicates EOF
627  if (packet != 0 && packet->GetSize () != 0)
628  {
629  if (m_endPoint != 0)
630  {
632  }
633  else if (m_endPoint6 != 0)
634  {
636  }
637  else
638  {
639  fromAddress = InetSocketAddress (Ipv4Address::GetZero (), 0);
640  }
641  }
642  return packet;
643 }
644 
645 /* Inherit from Socket class: Get the max number of bytes an app can send */
646 uint32_t
648 {
649  NS_LOG_FUNCTION (this);
650  return m_txBuffer.Available ();
651 }
652 
653 /* Inherit from Socket class: Get the max number of bytes an app can read */
654 uint32_t
656 {
657  NS_LOG_FUNCTION (this);
658  return m_rxBuffer.Available ();
659 }
660 
661 /* Inherit from Socket class: Return local address:port */
662 int
664 {
665  NS_LOG_FUNCTION (this);
666  if (m_endPoint != 0)
667  {
669  }
670  else if (m_endPoint6 != 0)
671  {
673  }
674  else
675  { // It is possible to call this method on a socket without a name
676  // in which case, behavior is unspecified
677  // Should this return an InetSocketAddress or an Inet6SocketAddress?
678  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
679  }
680  return 0;
681 }
682 
683 /* Inherit from Socket class: Bind this socket to the specified NetDevice */
684 void
686 {
687  NS_LOG_FUNCTION (netdevice);
688  Socket::BindToNetDevice (netdevice); // Includes sanity check
689  if (m_endPoint == 0)
690  {
691  if (Bind () == -1)
692  {
693  NS_ASSERT (m_endPoint == 0);
694  return;
695  }
696  NS_ASSERT (m_endPoint != 0);
697  }
698  m_endPoint->BindToNetDevice (netdevice);
699 
700  if (m_endPoint6 == 0)
701  {
702  if (Bind6 () == -1)
703  {
704  NS_ASSERT (m_endPoint6 == 0);
705  return;
706  }
707  NS_ASSERT (m_endPoint6 != 0);
708  }
709  m_endPoint6->BindToNetDevice (netdevice);
710 
711  return;
712 }
713 
714 /* Clean up after Bind. Set up callback functions in the end-point. */
715 int
717 {
718  NS_LOG_FUNCTION (this);
719 
720  if (m_endPoint == 0 && m_endPoint6 == 0)
721  {
722  return -1;
723  }
724  if (m_endPoint != 0)
725  {
729  }
730  if (m_endPoint6 != 0)
731  {
735  }
736 
737  return 0;
738 }
739 
740 /* Perform the real connection tasks: Send SYN if allowed, RST if invalid */
741 int
743 {
744  NS_LOG_FUNCTION (this);
745 
746  // A new connection is allowed only if this socket does not have a connection
748  { // send a SYN packet and change state into SYN_SENT
750  NS_LOG_INFO (TcpStateName[m_state] << " -> SYN_SENT");
751  m_state = SYN_SENT;
752  }
753  else if (m_state != TIME_WAIT)
754  { // In states SYN_RCVD, ESTABLISHED, FIN_WAIT_1, FIN_WAIT_2, and CLOSING, an connection
755  // exists. We send RST, tear down everything, and close this socket.
756  SendRST ();
757  CloseAndNotify ();
758  }
759  return 0;
760 }
761 
762 /* Do the action to close the socket. Usually send a packet with appropriate
763  flags depended on the current m_state. */
764 int
766 {
767  NS_LOG_FUNCTION (this);
768  switch (m_state)
769  {
770  case SYN_RCVD:
771  case ESTABLISHED:
772  // send FIN to close the peer
774  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
776  break;
777  case CLOSE_WAIT:
778  // send FIN+ACK to close the peer
780  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
781  m_state = LAST_ACK;
782  break;
783  case SYN_SENT:
784  case CLOSING:
785  // Send RST if application closes in SYN_SENT and CLOSING
786  SendRST ();
787  CloseAndNotify ();
788  break;
789  case LISTEN:
790  case LAST_ACK:
791  // In these three states, move to CLOSED and tear down the end point
792  CloseAndNotify ();
793  break;
794  case CLOSED:
795  case FIN_WAIT_1:
796  case FIN_WAIT_2:
797  case TIME_WAIT:
798  default: /* mute compiler */
799  // Do nothing in these four states
800  break;
801  }
802  return 0;
803 }
804 
805 /* Peacefully close the socket by notifying the upper layer and deallocate end point */
806 void
808 {
809  NS_LOG_FUNCTION (this);
810 
811  if (!m_closeNotified)
812  {
814  }
815 
816  if (m_state != TIME_WAIT)
817  {
819  }
820 
821  m_closeNotified = true;
822  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSED");
823  CancelAllTimers ();
824  m_state = CLOSED;
825 }
826 
827 
828 /* Tell if a sequence number range is out side the range that my rx buffer can
829  accpet */
830 bool
832 {
833  if (m_state == LISTEN || m_state == SYN_SENT || m_state == SYN_RCVD)
834  { // Rx buffer in these states are not initialized.
835  return false;
836  }
837  if (m_state == LAST_ACK || m_state == CLOSING || m_state == CLOSE_WAIT)
838  { // In LAST_ACK and CLOSING states, it only wait for an ACK and the
839  // sequence number must equals to m_rxBuffer.NextRxSequence ()
840  return (m_rxBuffer.NextRxSequence () != head);
841  }
842 
843  // In all other cases, check if the sequence number is in range
844  return (tail < m_rxBuffer.NextRxSequence () || m_rxBuffer.MaxRxSequence () <= head);
845 }
846 
847 /* Function called by the L3 protocol when it received a packet to pass on to
848  the TCP. This function is registered as the "RxCallback" function in
849  SetupCallback(), which invoked by Bind(), and CompleteFork() */
850 void
852  Ptr<Ipv4Interface> incomingInterface)
853 {
854  DoForwardUp (packet, header, port, incomingInterface);
855 }
856 
857 void
858 TcpSocketBase::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, Ptr<Ipv6Interface> incomingInterface)
859 {
860  DoForwardUp (packet, header, port);
861 }
862 
863 void
864 TcpSocketBase::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
865  uint8_t icmpType, uint8_t icmpCode,
866  uint32_t icmpInfo)
867 {
868  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
869  (uint32_t)icmpCode << icmpInfo);
870  if (!m_icmpCallback.IsNull ())
871  {
872  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
873  }
874 }
875 
876 void
877 TcpSocketBase::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
878  uint8_t icmpType, uint8_t icmpCode,
879  uint32_t icmpInfo)
880 {
881  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
882  (uint32_t)icmpCode << icmpInfo);
883  if (!m_icmpCallback6.IsNull ())
884  {
885  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
886  }
887 }
888 
889 /* The real function to handle the incoming packet from lower layers. This is
890  wrapped by ForwardUp() so that this function can be overloaded by daughter
891  classes. */
892 void
894  Ptr<Ipv4Interface> incomingInterface)
895 {
896  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
898  ":" << m_endPoint->GetPeerPort () <<
899  " to " << m_endPoint->GetLocalAddress () <<
900  ":" << m_endPoint->GetLocalPort ());
901  Address fromAddress = InetSocketAddress (header.GetSource (), port);
902  Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort ());
903 
904  // Peel off TCP header and do validity checking
905  TcpHeader tcpHeader;
906  uint32_t bytesRemoved = packet->RemoveHeader (tcpHeader);
907  if (bytesRemoved == 0 || bytesRemoved > 60)
908  {
909  NS_LOG_ERROR ("Bytes removed: " << bytesRemoved << " invalid");
910  return; // Discard invalid packet
911  }
912 
913  ReadOptions (tcpHeader);
914 
915  if (tcpHeader.GetFlags () & TcpHeader::ACK)
916  {
917  EstimateRtt (tcpHeader);
918  }
919 
920  // Update Rx window size, i.e. the flow control window
921  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
922  { // persist probes end
923  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
925  }
926  m_rWnd = tcpHeader.GetWindowSize ();
928 
929  // Discard fully out of range data packets
930  if (packet->GetSize ()
931  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
932  {
933  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
934  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
935  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
936  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
937  m_rxBuffer.MaxRxSequence () << ")");
938  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
939  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
940  {
942  }
943  return;
944  }
945 
946  // TCP state machine code in different process functions
947  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
948  switch (m_state)
949  {
950  case ESTABLISHED:
951  ProcessEstablished (packet, tcpHeader);
952  break;
953  case LISTEN:
954  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
955  break;
956  case TIME_WAIT:
957  // Do nothing
958  break;
959  case CLOSED:
960  // Send RST if the incoming packet is not a RST
961  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
962  { // Since m_endPoint is not configured yet, we cannot use SendRST here
963  TcpHeader h;
967  h.SetSourcePort (tcpHeader.GetDestinationPort ());
968  h.SetDestinationPort (tcpHeader.GetSourcePort ());
970  AddOptions (h);
971  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestination (), header.GetSource (), m_boundnetdevice);
972  }
973  break;
974  case SYN_SENT:
975  ProcessSynSent (packet, tcpHeader);
976  break;
977  case SYN_RCVD:
978  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
979  break;
980  case FIN_WAIT_1:
981  case FIN_WAIT_2:
982  case CLOSE_WAIT:
983  ProcessWait (packet, tcpHeader);
984  break;
985  case CLOSING:
986  ProcessClosing (packet, tcpHeader);
987  break;
988  case LAST_ACK:
989  ProcessLastAck (packet, tcpHeader);
990  break;
991  default: // mute compiler
992  break;
993  }
994 }
995 
996 // XXX this is duplicate code with the other DoForwardUp()
997 void
999 {
1000  NS_LOG_LOGIC ("Socket " << this << " forward up " <<
1002  ":" << m_endPoint6->GetPeerPort () <<
1003  " to " << m_endPoint6->GetLocalAddress () <<
1004  ":" << m_endPoint6->GetLocalPort ());
1005  Address fromAddress = Inet6SocketAddress (header.GetSourceAddress (), port);
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  // Update Rx window size, i.e. the flow control window
1025  if (m_rWnd.Get () == 0 && tcpHeader.GetWindowSize () != 0)
1026  { // persist probes end
1027  NS_LOG_LOGIC (this << " Leaving zerowindow persist state");
1029  }
1030  m_rWnd = tcpHeader.GetWindowSize ();
1032 
1033  // Discard fully out of range packets
1034  if (packet->GetSize ()
1035  && OutOfRange (tcpHeader.GetSequenceNumber (), tcpHeader.GetSequenceNumber () + packet->GetSize ()))
1036  {
1037  NS_LOG_LOGIC ("At state " << TcpStateName[m_state] <<
1038  " received packet of seq [" << tcpHeader.GetSequenceNumber () <<
1039  ":" << tcpHeader.GetSequenceNumber () + packet->GetSize () <<
1040  ") out of range [" << m_rxBuffer.NextRxSequence () << ":" <<
1041  m_rxBuffer.MaxRxSequence () << ")");
1042  // Acknowledgement should be sent for all unacceptable packets (RFC793, p.69)
1043  if (m_state == ESTABLISHED && !(tcpHeader.GetFlags () & TcpHeader::RST))
1044  {
1046  }
1047  return;
1048  }
1049 
1050  // TCP state machine code in different process functions
1051  // C.f.: tcp_rcv_state_process() in tcp_input.c in Linux kernel
1052  switch (m_state)
1053  {
1054  case ESTABLISHED:
1055  ProcessEstablished (packet, tcpHeader);
1056  break;
1057  case LISTEN:
1058  ProcessListen (packet, tcpHeader, fromAddress, toAddress);
1059  break;
1060  case TIME_WAIT:
1061  // Do nothing
1062  break;
1063  case CLOSED:
1064  // Send RST if the incoming packet is not a RST
1065  if ((tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG)) != TcpHeader::RST)
1066  { // Since m_endPoint is not configured yet, we cannot use SendRST here
1067  TcpHeader h;
1071  h.SetSourcePort (tcpHeader.GetDestinationPort ());
1072  h.SetDestinationPort (tcpHeader.GetSourcePort ());
1074  AddOptions (h);
1075  m_tcp->SendPacket (Create<Packet> (), h, header.GetDestinationAddress (), header.GetSourceAddress (), m_boundnetdevice);
1076  }
1077  break;
1078  case SYN_SENT:
1079  ProcessSynSent (packet, tcpHeader);
1080  break;
1081  case SYN_RCVD:
1082  ProcessSynRcvd (packet, tcpHeader, fromAddress, toAddress);
1083  break;
1084  case FIN_WAIT_1:
1085  case FIN_WAIT_2:
1086  case CLOSE_WAIT:
1087  ProcessWait (packet, tcpHeader);
1088  break;
1089  case CLOSING:
1090  ProcessClosing (packet, tcpHeader);
1091  break;
1092  case LAST_ACK:
1093  ProcessLastAck (packet, tcpHeader);
1094  break;
1095  default: // mute compiler
1096  break;
1097  }
1098 }
1099 
1100 /* Received a packet upon ESTABLISHED state. This function is mimicking the
1101  role of tcp_rcv_established() in tcp_input.c in Linux kernel. */
1102 void
1104 {
1105  NS_LOG_FUNCTION (this << tcpHeader);
1106 
1107  // Extract the flags. PSH and URG are not honoured.
1108  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1109 
1110  // Different flags are different events
1111  if (tcpflags == TcpHeader::ACK)
1112  {
1113  ReceivedAck (packet, tcpHeader);
1114  }
1115  else if (tcpflags == TcpHeader::SYN)
1116  { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and
1117  // respond with a SYN+ACK. But it is not a legal state transition as of
1118  // RFC793. Thus this is ignored.
1119  }
1120  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1121  { // No action for received SYN+ACK, it is probably a duplicated packet
1122  }
1123  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1124  { // Received FIN or FIN+ACK, bring down this socket nicely
1125  PeerClose (packet, tcpHeader);
1126  }
1127  else if (tcpflags == 0)
1128  { // No flags means there is only data
1129  ReceivedData (packet, tcpHeader);
1130  if (m_rxBuffer.Finished ())
1131  {
1132  PeerClose (packet, tcpHeader);
1133  }
1134  }
1135  else
1136  { // Received RST or the TCP flags is invalid, in either case, terminate this socket
1137  if (tcpflags != TcpHeader::RST)
1138  { // this must be an invalid flag, send reset
1139  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1140  SendRST ();
1141  }
1142  CloseAndNotify ();
1143  }
1144 }
1145 
1146 /* Process the newly received ACK */
1147 void
1149 {
1150  NS_LOG_FUNCTION (this << tcpHeader);
1151 
1152  // Received ACK. Compare the ACK number against highest unacked seqno
1153  if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
1154  { // Ignore if no ACK flag
1155  }
1156  else if (tcpHeader.GetAckNumber () < m_txBuffer.HeadSequence ())
1157  { // Case 1: Old ACK, ignored.
1158  NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ());
1159  }
1160  else if (tcpHeader.GetAckNumber () == m_txBuffer.HeadSequence ())
1161  { // Case 2: Potentially a duplicated ACK
1162  if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0)
1163  {
1164  NS_LOG_LOGIC ("Dupack of " << tcpHeader.GetAckNumber ());
1165  DupAck (tcpHeader, ++m_dupAckCount);
1166  }
1167  // otherwise, the ACK is precisely equal to the nextTxSequence
1168  NS_ASSERT (tcpHeader.GetAckNumber () <= m_nextTxSequence);
1169  }
1170  else if (tcpHeader.GetAckNumber () > m_txBuffer.HeadSequence ())
1171  { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
1172  NS_LOG_LOGIC ("New ack of " << tcpHeader.GetAckNumber ());
1173  NewAck (tcpHeader.GetAckNumber ());
1174  m_dupAckCount = 0;
1175  }
1176  // If there is any data piggybacked, store it into m_rxBuffer
1177  if (packet->GetSize () > 0)
1178  {
1179  ReceivedData (packet, tcpHeader);
1180  }
1181 }
1182 
1183 /* Received a packet upon LISTEN state. */
1184 void
1186  const Address& fromAddress, const Address& toAddress)
1187 {
1188  NS_LOG_FUNCTION (this << tcpHeader);
1189 
1190  // Extract the flags. PSH and URG are not honoured.
1191  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1192 
1193  // Fork a socket if received a SYN. Do nothing otherwise.
1194  // C.f.: the LISTEN part in tcp_v4_do_rcv() in tcp_ipv4.c in Linux kernel
1195  if (tcpflags != TcpHeader::SYN)
1196  {
1197  return;
1198  }
1199 
1200  // Call socket's notify function to let the server app know we got a SYN
1201  // If the server app refuses the connection, do nothing
1202  if (!NotifyConnectionRequest (fromAddress))
1203  {
1204  return;
1205  }
1206  // Clone the socket, simulate fork
1207  Ptr<TcpSocketBase> newSock = Fork ();
1208  NS_LOG_LOGIC ("Cloned a TcpSocketBase " << newSock);
1210  packet, tcpHeader, fromAddress, toAddress);
1211 }
1212 
1213 /* Received a packet upon SYN_SENT */
1214 void
1216 {
1217  NS_LOG_FUNCTION (this << tcpHeader);
1218 
1219  // Extract the flags. PSH and URG are not honoured.
1220  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1221 
1222  if (tcpflags == 0)
1223  { // Bare data, accept it and move to ESTABLISHED state. This is not a normal behaviour. Remove this?
1224  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1225  m_state = ESTABLISHED;
1226  m_connected = true;
1227  m_retxEvent.Cancel ();
1229  ReceivedData (packet, tcpHeader);
1231  }
1232  else if (tcpflags == TcpHeader::ACK)
1233  { // Ignore ACK in SYN_SENT
1234  }
1235  else if (tcpflags == TcpHeader::SYN)
1236  { // Received SYN, move to SYN_RCVD state and respond with SYN+ACK
1237  NS_LOG_INFO ("SYN_SENT -> SYN_RCVD");
1238  m_state = SYN_RCVD;
1242  }
1243  else if (tcpflags == (TcpHeader::SYN | TcpHeader::ACK)
1244  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
1245  { // Handshake completed
1246  NS_LOG_INFO ("SYN_SENT -> ESTABLISHED");
1247  m_state = ESTABLISHED;
1248  m_connected = true;
1249  m_retxEvent.Cancel ();
1256  // Always respond to first data packet to speed up the connection.
1257  // Remove to get the behaviour of old NS-3 code.
1259  }
1260  else
1261  { // Other in-sequence input
1262  if (tcpflags != TcpHeader::RST)
1263  { // When (1) rx of FIN+ACK; (2) rx of FIN; (3) rx of bad flags
1264  NS_LOG_LOGIC ("Illegal flag " << std::hex << static_cast<uint32_t> (tcpflags) << std::dec << " received. Reset packet is sent.");
1265  SendRST ();
1266  }
1267  CloseAndNotify ();
1268  }
1269 }
1270 
1271 /* Received a packet upon SYN_RCVD */
1272 void
1274  const Address& fromAddress, const Address& toAddress)
1275 {
1276  NS_LOG_FUNCTION (this << tcpHeader);
1277 
1278  // Extract the flags. PSH and URG are not honoured.
1279  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1280 
1281  if (tcpflags == 0
1282  || (tcpflags == TcpHeader::ACK
1283  && m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ()))
1284  { // If it is bare data, accept it and move to ESTABLISHED state. This is
1285  // possibly due to ACK lost in 3WHS. If in-sequence ACK is received, the
1286  // handshake is completed nicely.
1287  NS_LOG_INFO ("SYN_RCVD -> ESTABLISHED");
1288  m_state = ESTABLISHED;
1289  m_connected = true;
1290  m_retxEvent.Cancel ();
1293  if (m_endPoint)
1294  {
1295  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1296  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1297  }
1298  else if (m_endPoint6)
1299  {
1300  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1301  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1302  }
1303  // Always respond to first data packet to speed up the connection.
1304  // Remove to get the behaviour of old NS-3 code.
1306  ReceivedAck (packet, tcpHeader);
1307  NotifyNewConnectionCreated (this, fromAddress);
1308  // As this connection is established, the socket is available to send data now
1309  if (GetTxAvailable () > 0)
1310  {
1312  }
1313  }
1314  else if (tcpflags == TcpHeader::SYN)
1315  { // Probably the peer lost my SYN+ACK
1318  }
1319  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1320  {
1321  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1322  { // In-sequence FIN before connection complete. Set up connection and close.
1323  m_connected = true;
1324  m_retxEvent.Cancel ();
1327  if (m_endPoint)
1328  {
1329  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1330  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1331  }
1332  else if (m_endPoint6)
1333  {
1334  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1335  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1336  }
1337  PeerClose (packet, tcpHeader);
1338  }
1339  }
1340  else
1341  { // Other in-sequence input
1342  if (tcpflags != TcpHeader::RST)
1343  { // When (1) rx of SYN+ACK; (2) rx of FIN; (3) rx of bad flags
1344  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1345  if (m_endPoint)
1346  {
1347  m_endPoint->SetPeer (InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1348  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1349  }
1350  else if (m_endPoint6)
1351  {
1352  m_endPoint6->SetPeer (Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1353  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1354  }
1355  SendRST ();
1356  }
1357  CloseAndNotify ();
1358  }
1359 }
1360 
1361 /* Received a packet upon CLOSE_WAIT, FIN_WAIT_1, or FIN_WAIT_2 states */
1362 void
1364 {
1365  NS_LOG_FUNCTION (this << tcpHeader);
1366 
1367  // Extract the flags. PSH and URG are not honoured.
1368  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1369 
1370  if (packet->GetSize () > 0 && tcpflags != TcpHeader::ACK)
1371  { // Bare data, accept it
1372  ReceivedData (packet, tcpHeader);
1373  }
1374  else if (tcpflags == TcpHeader::ACK)
1375  { // Process the ACK, and if in FIN_WAIT_1, conditionally move to FIN_WAIT_2
1376  ReceivedAck (packet, tcpHeader);
1377  if (m_state == FIN_WAIT_1 && m_txBuffer.Size () == 0
1378  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1379  { // This ACK corresponds to the FIN sent
1380  NS_LOG_INFO ("FIN_WAIT_1 -> FIN_WAIT_2");
1381  m_state = FIN_WAIT_2;
1382  }
1383  }
1384  else if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1385  { // Got FIN, respond with ACK and move to next state
1386  if (tcpflags & TcpHeader::ACK)
1387  { // Process the ACK first
1388  ReceivedAck (packet, tcpHeader);
1389  }
1391  }
1392  else if (tcpflags == TcpHeader::SYN || tcpflags == (TcpHeader::SYN | TcpHeader::ACK))
1393  { // Duplicated SYN or SYN+ACK, possibly due to spurious retransmission
1394  return;
1395  }
1396  else
1397  { // This is a RST or bad flags
1398  if (tcpflags != TcpHeader::RST)
1399  {
1400  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1401  SendRST ();
1402  }
1403  CloseAndNotify ();
1404  return;
1405  }
1406 
1407  // Check if the close responder sent an in-sequence FIN, if so, respond ACK
1408  if ((m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2) && m_rxBuffer.Finished ())
1409  {
1410  if (m_state == FIN_WAIT_1)
1411  {
1412  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1413  m_state = CLOSING;
1414  if (m_txBuffer.Size () == 0
1415  && tcpHeader.GetAckNumber () == m_highTxMark + SequenceNumber32 (1))
1416  { // This ACK corresponds to the FIN sent
1417  TimeWait ();
1418  }
1419  }
1420  else if (m_state == FIN_WAIT_2)
1421  {
1422  TimeWait ();
1423  }
1425  if (!m_shutdownRecv)
1426  {
1427  NotifyDataRecv ();
1428  }
1429  }
1430 }
1431 
1432 /* Received a packet upon CLOSING */
1433 void
1435 {
1436  NS_LOG_FUNCTION (this << tcpHeader);
1437 
1438  // Extract the flags. PSH and URG are not honoured.
1439  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1440 
1441  if (tcpflags == TcpHeader::ACK)
1442  {
1443  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1444  { // This ACK corresponds to the FIN sent
1445  TimeWait ();
1446  }
1447  }
1448  else
1449  { // CLOSING state means simultaneous close, i.e. no one is sending data to
1450  // anyone. If anything other than ACK is received, respond with a reset.
1451  if (tcpflags == TcpHeader::FIN || tcpflags == (TcpHeader::FIN | TcpHeader::ACK))
1452  { // FIN from the peer as well. We can close immediately.
1454  }
1455  else if (tcpflags != TcpHeader::RST)
1456  { // Receive of SYN or SYN+ACK or bad flags or pure data
1457  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1458  SendRST ();
1459  }
1460  CloseAndNotify ();
1461  }
1462 }
1463 
1464 /* Received a packet upon LAST_ACK */
1465 void
1467 {
1468  NS_LOG_FUNCTION (this << tcpHeader);
1469 
1470  // Extract the flags. PSH and URG are not honoured.
1471  uint8_t tcpflags = tcpHeader.GetFlags () & ~(TcpHeader::PSH | TcpHeader::URG);
1472 
1473  if (tcpflags == 0)
1474  {
1475  ReceivedData (packet, tcpHeader);
1476  }
1477  else if (tcpflags == TcpHeader::ACK)
1478  {
1479  if (tcpHeader.GetSequenceNumber () == m_rxBuffer.NextRxSequence ())
1480  { // This ACK corresponds to the FIN sent. This socket closed peacefully.
1481  CloseAndNotify ();
1482  }
1483  }
1484  else if (tcpflags == TcpHeader::FIN)
1485  { // Received FIN again, the peer probably lost the FIN+ACK
1487  }
1488  else if (tcpflags == (TcpHeader::FIN | TcpHeader::ACK) || tcpflags == TcpHeader::RST)
1489  {
1490  CloseAndNotify ();
1491  }
1492  else
1493  { // Received a SYN or SYN+ACK or bad flags
1494  NS_LOG_LOGIC ("Illegal flag " << tcpflags << " received. Reset packet is sent.");
1495  SendRST ();
1496  CloseAndNotify ();
1497  }
1498 }
1499 
1500 /* Peer sent me a FIN. Remember its sequence in rx buffer. */
1501 void
1503 {
1504  NS_LOG_FUNCTION (this << tcpHeader);
1505 
1506  // Ignore all out of range packets
1507  if (tcpHeader.GetSequenceNumber () < m_rxBuffer.NextRxSequence ()
1508  || tcpHeader.GetSequenceNumber () > m_rxBuffer.MaxRxSequence ())
1509  {
1510  return;
1511  }
1512  // For any case, remember the FIN position in rx buffer first
1514  NS_LOG_LOGIC ("Accepted FIN at seq " << tcpHeader.GetSequenceNumber () + SequenceNumber32 (p->GetSize ()));
1515  // If there is any piggybacked data, process it
1516  if (p->GetSize ())
1517  {
1518  ReceivedData (p, tcpHeader);
1519  }
1520  // Return if FIN is out of sequence, otherwise move to CLOSE_WAIT state by DoPeerClose
1521  if (!m_rxBuffer.Finished ())
1522  {
1523  return;
1524  }
1525 
1526  // Simultaneous close: Application invoked Close() when we are processing this FIN packet
1527  if (m_state == FIN_WAIT_1)
1528  {
1529  NS_LOG_INFO ("FIN_WAIT_1 -> CLOSING");
1530  m_state = CLOSING;
1531  return;
1532  }
1533 
1534  DoPeerClose (); // Change state, respond with ACK
1535 }
1536 
1537 /* Received a in-sequence FIN. Close down this socket. */
1538 void
1540 {
1542 
1543  // Move the state to CLOSE_WAIT
1544  NS_LOG_INFO (TcpStateName[m_state] << " -> CLOSE_WAIT");
1545  m_state = CLOSE_WAIT;
1546 
1547  if (!m_closeNotified)
1548  {
1549  // The normal behaviour for an application is that, when the peer sent a in-sequence
1550  // FIN, the app should prepare to close. The app has two choices at this point: either
1551  // respond with ShutdownSend() call to declare that it has nothing more to send and
1552  // the socket can be closed immediately; or remember the peer's close request, wait
1553  // until all its existing data are pushed into the TCP socket, then call Close()
1554  // explicitly.
1555  NS_LOG_LOGIC ("TCP " << this << " calling NotifyNormalClose");
1556  NotifyNormalClose ();
1557  m_closeNotified = true;
1558  }
1559  if (m_shutdownSend)
1560  { // The application declares that it would not sent any more, close this socket
1561  Close ();
1562  }
1563  else
1564  { // Need to ack, the application will close later
1566  }
1567  if (m_state == LAST_ACK)
1568  {
1569  NS_LOG_LOGIC ("TcpSocketBase " << this << " scheduling LATO1");
1570  m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
1572  }
1573 }
1574 
1575 /* Kill this socket. This is a callback function configured to m_endpoint in
1576  SetupCallback(), invoked when the endpoint is destroyed. */
1577 void
1579 {
1580  NS_LOG_FUNCTION (this);
1581  m_endPoint = 0;
1582  if (m_tcp != 0)
1583  {
1584  std::vector<Ptr<TcpSocketBase> >::iterator it
1585  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1586  if (it != m_tcp->m_sockets.end ())
1587  {
1588  m_tcp->m_sockets.erase (it);
1589  }
1590  }
1591  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1592  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1593  CancelAllTimers ();
1594 }
1595 
1596 /* Kill this socket. This is a callback function configured to m_endpoint in
1597  SetupCallback(), invoked when the endpoint is destroyed. */
1598 void
1600 {
1601  NS_LOG_FUNCTION (this);
1602  m_endPoint6 = 0;
1603  if (m_tcp != 0)
1604  {
1605  std::vector<Ptr<TcpSocketBase> >::iterator it
1606  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1607  if (it != m_tcp->m_sockets.end ())
1608  {
1609  m_tcp->m_sockets.erase (it);
1610  }
1611  }
1612  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
1613  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
1614  CancelAllTimers ();
1615 }
1616 
1617 /* Send an empty packet with specified TCP flags */
1618 void
1620 {
1621  NS_LOG_FUNCTION (this << (uint32_t)flags);
1622  Ptr<Packet> p = Create<Packet> ();
1623  TcpHeader header;
1625 
1626  /*
1627  * Add tags for each socket option.
1628  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1629  * if both options are set. Once the packet got to layer three, only
1630  * the corresponding tags will be read.
1631  */
1632  if (IsManualIpTos ())
1633  {
1634  SocketIpTosTag ipTosTag;
1635  ipTosTag.SetTos (GetIpTos ());
1636  p->AddPacketTag (ipTosTag);
1637  }
1638 
1639  if (IsManualIpv6Tclass ())
1640  {
1641  SocketIpv6TclassTag ipTclassTag;
1642  ipTclassTag.SetTclass (GetIpv6Tclass ());
1643  p->AddPacketTag (ipTclassTag);
1644  }
1645 
1646  if (IsManualIpTtl ())
1647  {
1648  SocketIpTtlTag ipTtlTag;
1649  ipTtlTag.SetTtl (GetIpTtl ());
1650  p->AddPacketTag (ipTtlTag);
1651  }
1652 
1653  if (IsManualIpv6HopLimit ())
1654  {
1655  SocketIpv6HopLimitTag ipHopLimitTag;
1656  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1657  p->AddPacketTag (ipHopLimitTag);
1658  }
1659 
1660  if (m_endPoint == 0 && m_endPoint6 == 0)
1661  {
1662  NS_LOG_WARN ("Failed to send empty packet due to null endpoint");
1663  return;
1664  }
1665  if (flags & TcpHeader::FIN)
1666  {
1667  flags |= TcpHeader::ACK;
1668  }
1669  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1670  {
1671  ++s;
1672  }
1673 
1674  header.SetFlags (flags);
1675  header.SetSequenceNumber (s);
1676  header.SetAckNumber (m_rxBuffer.NextRxSequence ());
1677  if (m_endPoint != 0)
1678  {
1679  header.SetSourcePort (m_endPoint->GetLocalPort ());
1680  header.SetDestinationPort (m_endPoint->GetPeerPort ());
1681  }
1682  else
1683  {
1684  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1685  header.SetDestinationPort (m_endPoint6->GetPeerPort ());
1686  }
1687  AddOptions (header);
1688  header.SetWindowSize (AdvertisedWindowSize ());
1689  m_rto = m_rtt->RetransmitTimeout ();
1690  bool hasSyn = flags & TcpHeader::SYN;
1691  bool hasFin = flags & TcpHeader::FIN;
1692  bool isAck = flags == TcpHeader::ACK;
1693  if (hasSyn)
1694  {
1695  if (m_cnCount == 0)
1696  { // No more connection retries, give up
1697  NS_LOG_LOGIC ("Connection failed.");
1698  CloseAndNotify ();
1699  return;
1700  }
1701  else
1702  { // Exponential backoff of connection time out
1703  int backoffCount = 0x1 << (m_cnRetries - m_cnCount);
1704  m_rto = m_cnTimeout * backoffCount;
1705  m_cnCount--;
1706  }
1707  }
1708  if (m_endPoint != 0)
1709  {
1710  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1712  }
1713  else
1714  {
1715  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1717  }
1718  if (flags & TcpHeader::ACK)
1719  { // If sending an ACK, cancel the delay ACK as well
1720  m_delAckEvent.Cancel ();
1721  m_delAckCount = 0;
1722  }
1723  if (m_retxEvent.IsExpired () && (hasSyn || hasFin) && !isAck )
1724  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1725  NS_LOG_LOGIC ("Schedule retransmission timeout at time "
1726  << Simulator::Now ().GetSeconds () << " to expire at time "
1727  << (Simulator::Now () + m_rto.Get ()).GetSeconds ());
1729  }
1730 }
1731 
1732 /* This function closes the endpoint completely. Called upon RST_TX action. */
1733 void
1735 {
1736  NS_LOG_FUNCTION (this);
1738  NotifyErrorClose ();
1739  DeallocateEndPoint ();
1740 }
1741 
1742 /* Deallocate the end point and cancel all the timers */
1743 void
1745 {
1746  if (m_endPoint != 0)
1747  {
1748  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
1749  m_tcp->DeAllocate (m_endPoint);
1750  m_endPoint = 0;
1751  std::vector<Ptr<TcpSocketBase> >::iterator it
1752  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1753  if (it != m_tcp->m_sockets.end ())
1754  {
1755  m_tcp->m_sockets.erase (it);
1756  }
1757  CancelAllTimers ();
1758  }
1759  if (m_endPoint6 != 0)
1760  {
1761  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
1762  m_tcp->DeAllocate (m_endPoint6);
1763  m_endPoint6 = 0;
1764  std::vector<Ptr<TcpSocketBase> >::iterator it
1765  = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
1766  if (it != m_tcp->m_sockets.end ())
1767  {
1768  m_tcp->m_sockets.erase (it);
1769  }
1770  CancelAllTimers ();
1771  }
1772 }
1773 
1774 /* Configure the endpoint to a local address. Called by Connect() if Bind() didn't specify one. */
1775 int
1777 {
1778  NS_LOG_FUNCTION (this);
1779  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
1780  NS_ASSERT (ipv4 != 0);
1781  if (ipv4->GetRoutingProtocol () == 0)
1782  {
1783  NS_FATAL_ERROR ("No Ipv4RoutingProtocol in the node");
1784  }
1785  // Create a dummy packet, then ask the routing function for the best output
1786  // interface's address
1787  Ipv4Header header;
1789  Socket::SocketErrno errno_;
1790  Ptr<Ipv4Route> route;
1792  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1793  if (route == 0)
1794  {
1795  NS_LOG_LOGIC ("Route to " << m_endPoint->GetPeerAddress () << " does not exist");
1796  NS_LOG_ERROR (errno_);
1797  m_errno = errno_;
1798  return -1;
1799  }
1800  NS_LOG_LOGIC ("Route exists");
1801  m_endPoint->SetLocalAddress (route->GetSource ());
1802  return 0;
1803 }
1804 
1805 int
1807 {
1808  NS_LOG_FUNCTION (this);
1810  NS_ASSERT (ipv6 != 0);
1811  if (ipv6->GetRoutingProtocol () == 0)
1812  {
1813  NS_FATAL_ERROR ("No Ipv6RoutingProtocol in the node");
1814  }
1815  // Create a dummy packet, then ask the routing function for the best output
1816  // interface's address
1817  Ipv6Header header;
1819  Socket::SocketErrno errno_;
1820  Ptr<Ipv6Route> route;
1822  route = ipv6->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), header, oif, errno_);
1823  if (route == 0)
1824  {
1825  NS_LOG_LOGIC ("Route to " << m_endPoint6->GetPeerAddress () << " does not exist");
1826  NS_LOG_ERROR (errno_);
1827  m_errno = errno_;
1828  return -1;
1829  }
1830  NS_LOG_LOGIC ("Route exists");
1831  m_endPoint6->SetLocalAddress (route->GetSource ());
1832  return 0;
1833 }
1834 
1835 /* This function is called only if a SYN received in LISTEN state. After
1836  TcpSocketBase cloned, allocate a new end point to handle the incoming
1837  connection and send a SYN+ACK to complete the handshake. */
1838 void
1840  const Address& fromAddress, const Address& toAddress)
1841 {
1842  // Get port and address from peer (connecting host)
1843  if (InetSocketAddress::IsMatchingType (toAddress))
1844  {
1845  m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
1846  InetSocketAddress::ConvertFrom (toAddress).GetPort (),
1847  InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
1848  InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
1849  m_endPoint6 = 0;
1850  }
1851  else if (Inet6SocketAddress::IsMatchingType (toAddress))
1852  {
1853  m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
1854  Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
1855  Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
1856  Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
1857  m_endPoint = 0;
1858  }
1859  m_tcp->m_sockets.push_back (this);
1860 
1861  // Change the cloned socket from LISTEN state to SYN_RCVD
1862  NS_LOG_INFO ("LISTEN -> SYN_RCVD");
1863  m_state = SYN_RCVD;
1865  SetupCallback ();
1866  // Set the sequence number and send SYN+ACK
1868 
1870 }
1871 
1872 void
1874 { // Wrapper to protected function NotifyConnectionSucceeded() so that it can
1875  // be called as a scheduled event
1877  // The if-block below was moved from ProcessSynSent() to here because we need
1878  // to invoke the NotifySend() only after NotifyConnectionSucceeded() to
1879  // reflect the behaviour in the real world.
1880  if (GetTxAvailable () > 0)
1881  {
1883  }
1884 }
1885 
1886 /* Extract at most maxSize bytes from the TxBuffer at sequence seq, add the
1887  TCP header, and send to TcpL4Protocol */
1888 uint32_t
1889 TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool withAck)
1890 {
1891  NS_LOG_FUNCTION (this << seq << maxSize << withAck);
1892 
1893  Ptr<Packet> p = m_txBuffer.CopyFromSequence (maxSize, seq);
1894  uint32_t sz = p->GetSize (); // Size of packet
1895  uint8_t flags = withAck ? TcpHeader::ACK : 0;
1896  uint32_t remainingData = m_txBuffer.SizeFromSequence (seq + SequenceNumber32 (sz));
1897 
1898  /*
1899  * Add tags for each socket option.
1900  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1901  * if both options are set. Once the packet got to layer three, only
1902  * the corresponding tags will be read.
1903  */
1904  if (IsManualIpTos ())
1905  {
1906  SocketIpTosTag ipTosTag;
1907  ipTosTag.SetTos (GetIpTos ());
1908  p->AddPacketTag (ipTosTag);
1909  }
1910 
1911  if (IsManualIpv6Tclass ())
1912  {
1913  SocketIpv6TclassTag ipTclassTag;
1914  ipTclassTag.SetTclass (GetIpv6Tclass ());
1915  p->AddPacketTag (ipTclassTag);
1916  }
1917 
1918  if (IsManualIpTtl ())
1919  {
1920  SocketIpTtlTag ipTtlTag;
1921  ipTtlTag.SetTtl (GetIpTtl ());
1922  p->AddPacketTag (ipTtlTag);
1923  }
1924 
1925  if (IsManualIpv6HopLimit ())
1926  {
1927  SocketIpv6HopLimitTag ipHopLimitTag;
1928  ipHopLimitTag.SetHopLimit (GetIpv6HopLimit ());
1929  p->AddPacketTag (ipHopLimitTag);
1930  }
1931 
1932  if (m_closeOnEmpty && (remainingData == 0))
1933  {
1934  flags |= TcpHeader::FIN;
1935  if (m_state == ESTABLISHED)
1936  { // On active close: I am the first one to send FIN
1937  NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
1938  m_state = FIN_WAIT_1;
1939  }
1940  else if (m_state == CLOSE_WAIT)
1941  { // On passive close: Peer sent me FIN already
1942  NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
1943  m_state = LAST_ACK;
1944  }
1945  }
1946  TcpHeader header;
1947  header.SetFlags (flags);
1948  header.SetSequenceNumber (seq);
1950  if (m_endPoint)
1951  {
1952  header.SetSourcePort (m_endPoint->GetLocalPort ());
1954  }
1955  else
1956  {
1957  header.SetSourcePort (m_endPoint6->GetLocalPort ());
1959  }
1960  header.SetWindowSize (AdvertisedWindowSize ());
1961  AddOptions (header);
1962  if (m_retxEvent.IsExpired () )
1963  { // Schedule retransmit
1964  m_rto = m_rtt->RetransmitTimeout ();
1965  NS_LOG_LOGIC (this << " SendDataPacket Schedule ReTxTimeout at time " <<
1966  Simulator::Now ().GetSeconds () << " to expire at time " <<
1967  (Simulator::Now () + m_rto.Get ()).GetSeconds () );
1969  }
1970  NS_LOG_LOGIC ("Send packet via TcpL4Protocol with flags 0x" << std::hex << static_cast<uint32_t> (flags) << std::dec);
1971  if (m_endPoint)
1972  {
1973  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (),
1975  }
1976  else
1977  {
1978  m_tcp->SendPacket (p, header, m_endPoint6->GetLocalAddress (),
1980  }
1981  m_rtt->SentSeq (seq, sz); // notify the RTT
1982  // Notify the application of the data being sent unless this is a retransmit
1983  if (seq == m_nextTxSequence)
1984  {
1986  }
1987  // Update highTxMark
1988  m_highTxMark = std::max (seq + sz, m_highTxMark.Get ());
1989  return sz;
1990 }
1991 
1992 /* Send as much pending data as possible according to the Tx window. Note that
1993  * this function did not implement the PSH flag
1994  */
1995 bool
1997 {
1998  NS_LOG_FUNCTION (this << withAck);
1999  if (m_txBuffer.Size () == 0)
2000  {
2001  return false; // Nothing to send
2002 
2003  }
2004  if (m_endPoint == 0 && m_endPoint6 == 0)
2005  {
2006  NS_LOG_INFO ("TcpSocketBase::SendPendingData: No endpoint; m_shutdownSend=" << m_shutdownSend);
2007  return false; // Is this the right way to handle this condition?
2008  }
2009  uint32_t nPacketsSent = 0;
2011  {
2012  uint32_t w = AvailableWindow (); // Get available window size
2013  NS_LOG_LOGIC ("TcpSocketBase " << this << " SendPendingData" <<
2014  " w " << w <<
2015  " rxwin " << m_rWnd <<
2016  " segsize " << m_segmentSize <<
2017  " nextTxSeq " << m_nextTxSequence <<
2018  " highestRxAck " << m_txBuffer.HeadSequence () <<
2019  " pd->Size " << m_txBuffer.Size () <<
2020  " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
2021  // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
2023  {
2024  break; // No more
2025  }
2026  // Nagle's algorithm (RFC896): Hold off sending if there is unacked data
2027  // in the buffer and the amount of data to send is less than one segment
2028  if (!m_noDelay && UnAckDataCount () > 0
2030  {
2031  NS_LOG_LOGIC ("Invoking Nagle's algorithm. Wait to send.");
2032  break;
2033  }
2034  uint32_t s = std::min (w, m_segmentSize); // Send no more than window
2035  uint32_t sz = SendDataPacket (m_nextTxSequence, s, withAck);
2036  nPacketsSent++; // Count sent this loop
2037  m_nextTxSequence += sz; // Advance next tx sequence
2038  }
2039  NS_LOG_LOGIC ("SendPendingData sent " << nPacketsSent << " packets");
2040  return (nPacketsSent > 0);
2041 }
2042 
2043 uint32_t
2045 {
2046  NS_LOG_FUNCTION (this);
2048 }
2049 
2050 uint32_t
2052 {
2053  NS_LOG_FUNCTION (this);
2054  return m_highTxMark.Get () - m_txBuffer.HeadSequence ();
2055 }
2056 
2057 uint32_t
2059 {
2060  NS_LOG_FUNCTION (this);
2061  return m_rWnd;
2062 }
2063 
2064 uint32_t
2066 {
2068  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
2069  uint32_t win = Window (); // Number of bytes allowed to be outstanding
2070  NS_LOG_LOGIC ("UnAckCount=" << unack << ", Win=" << win);
2071  return (win < unack) ? 0 : (win - unack);
2072 }
2073 
2074 uint16_t
2076 {
2077  uint32_t w = m_rxBuffer.MaxBufferSize () - m_rxBuffer.Size ();
2078 
2079  w >>= m_sndScaleFactor;
2080 
2081  if (w > m_maxWinSize)
2082  {
2083  NS_LOG_WARN ("There is a loss in the adv win size, wrt buffer size");
2084  w = m_maxWinSize;
2085  }
2086 
2087  return (uint16_t) w;
2088 }
2089 
2090 // Receipt of new packet, put into Rx buffer
2091 void
2093 {
2094  NS_LOG_FUNCTION (this << tcpHeader);
2095  NS_LOG_LOGIC ("seq " << tcpHeader.GetSequenceNumber () <<
2096  " ack " << tcpHeader.GetAckNumber () <<
2097  " pkt size " << p->GetSize () );
2098 
2099  // Put into Rx buffer
2100  SequenceNumber32 expectedSeq = m_rxBuffer.NextRxSequence ();
2101  if (!m_rxBuffer.Add (p, tcpHeader))
2102  { // Insert failed: No data or RX buffer full
2104  return;
2105  }
2106  // Now send a new ACK packet acknowledging all received and delivered data
2107  if (m_rxBuffer.Size () > m_rxBuffer.Available () || m_rxBuffer.NextRxSequence () > expectedSeq + p->GetSize ())
2108  { // A gap exists in the buffer, or we filled a gap: Always ACK
2110  }
2111  else
2112  { // In-sequence packet: ACK if delayed ack count allows
2114  {
2115  m_delAckEvent.Cancel ();
2116  m_delAckCount = 0;
2118  }
2119  else if (m_delAckEvent.IsExpired ())
2120  {
2123  NS_LOG_LOGIC (this << " scheduled delayed ACK at " << (Simulator::Now () + Simulator::GetDelayLeft (m_delAckEvent)).GetSeconds ());
2124  }
2125  }
2126  // Notify app to receive if necessary
2127  if (expectedSeq < m_rxBuffer.NextRxSequence ())
2128  { // NextRxSeq advanced, we have something to send to the app
2129  if (!m_shutdownRecv)
2130  {
2131  NotifyDataRecv ();
2132  }
2133  // Handle exceptions
2134  if (m_closeNotified)
2135  {
2136  NS_LOG_WARN ("Why TCP " << this << " got data after close notification?");
2137  }
2138  // If we received FIN before and now completed all "holes" in rx buffer,
2139  // invoke peer close procedure
2140  if (m_rxBuffer.Finished () && (tcpHeader.GetFlags () & TcpHeader::FIN) == 0)
2141  {
2142  DoPeerClose ();
2143  }
2144  }
2145 }
2146 
2154 void
2156 {
2157  Time nextRtt;
2158 
2159  if (m_timestampEnabled)
2160  {
2162  }
2163  else
2164  {
2165  // Use m_rtt for the estimation. Note, RTT of duplicated acknowledgement
2166  // (which should be ignored) is handled by m_rtt.
2167  nextRtt = m_rtt->EstimateRttFromSeq (tcpHeader.GetAckNumber () );
2168  }
2169 
2170  //nextRtt will be zero for dup acks. Don't want to update lastRtt in that case
2171  //but still needed to do list clearing that is done in EstimateRttFromSeq.
2172  if(nextRtt != Time (0))
2173  {
2174  m_lastRtt = nextRtt;
2175  NS_LOG_FUNCTION(this << m_lastRtt);
2176  }
2177 
2178 }
2179 
2180 // Called by the ReceivedAck() when new ACK received and by ProcessSynRcvd()
2181 // when the three-way handshake completed. This cancels retransmission timer
2182 // and advances Tx window
2183 void
2185 {
2186  NS_LOG_FUNCTION (this << ack);
2187 
2188  if (m_state != SYN_RCVD)
2189  { // Set RTO unless the ACK is received in SYN_RCVD state
2190  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2191  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2192  m_retxEvent.Cancel ();
2193  // On recieving a "New" ack we restart retransmission timer .. RFC 2988
2194  m_rto = m_rtt->RetransmitTimeout ();
2195  NS_LOG_LOGIC (this << " Schedule ReTxTimeout at time " <<
2196  Simulator::Now ().GetSeconds () << " to expire at time " <<
2197  (Simulator::Now () + m_rto.Get ()).GetSeconds ());
2199  }
2200  if (m_rWnd.Get () == 0 && m_persistEvent.IsExpired ())
2201  { // Zero window: Enter persist state to send 1 byte to probe
2202  NS_LOG_LOGIC (this << "Enter zerowindow persist state");
2203  NS_LOG_LOGIC (this << "Cancelled ReTxTimeout event which was set to expire at " <<
2204  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2205  m_retxEvent.Cancel ();
2206  NS_LOG_LOGIC ("Schedule persist timeout at time " <<
2207  Simulator::Now ().GetSeconds () << " to expire at time " <<
2208  (Simulator::Now () + m_persistTimeout).GetSeconds ());
2211  }
2212  // Note the highest ACK and tell app to send more
2213  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
2214  " numberAck " << (ack - m_txBuffer.HeadSequence ())); // Number bytes ack'ed
2215  m_txBuffer.DiscardUpTo (ack);
2216  if (GetTxAvailable () > 0)
2217  {
2219  }
2220  if (ack > m_nextTxSequence)
2221  {
2222  m_nextTxSequence = ack; // If advanced
2223  }
2224  if (m_txBuffer.Size () == 0 && m_state != FIN_WAIT_1 && m_state != CLOSING)
2225  { // No retransmit timer if no data to retransmit
2226  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
2227  (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
2228  m_retxEvent.Cancel ();
2229  }
2230  // Try to send more data
2232 }
2233 
2234 // Retransmit timeout
2235 void
2237 {
2238  NS_LOG_FUNCTION (this);
2239  NS_LOG_LOGIC (this << " ReTxTimeout Expired at time " << Simulator::Now ().GetSeconds ());
2240  // If erroneous timeout in closed/timed-wait state, just return
2241  if (m_state == CLOSED || m_state == TIME_WAIT)
2242  {
2243  return;
2244  }
2245  // If all data are received (non-closing socket and nothing to send), just return
2247  {
2248  return;
2249  }
2250 
2251  Retransmit ();
2252 }
2253 
2254 void
2256 {
2257  m_delAckCount = 0;
2259 }
2260 
2261 void
2263 {
2264  NS_LOG_FUNCTION (this);
2265 
2267  if (m_state == LAST_ACK)
2268  {
2269  CloseAndNotify ();
2270  }
2271  if (!m_closeNotified)
2272  {
2273  m_closeNotified = true;
2274  }
2275 }
2276 
2277 // Send 1-byte data to probe for the window size at the receiver when
2278 // the local knowledge tells that the receiver has zero window size
2279 // C.f.: RFC793 p.42, RFC1112 sec.4.2.2.17
2280 void
2282 {
2283  NS_LOG_LOGIC ("PersistTimeout expired at " << Simulator::Now ().GetSeconds ());
2284  m_persistTimeout = std::min (Seconds (60), Time (2 * m_persistTimeout)); // max persist timeout = 60s
2286  TcpHeader tcpHeader;
2287  tcpHeader.SetSequenceNumber (m_nextTxSequence);
2288  tcpHeader.SetAckNumber (m_rxBuffer.NextRxSequence ());
2289  tcpHeader.SetWindowSize (AdvertisedWindowSize ());
2290  if (m_endPoint != 0)
2291  {
2292  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort ());
2293  tcpHeader.SetDestinationPort (m_endPoint->GetPeerPort ());
2294  }
2295  else
2296  {
2297  tcpHeader.SetSourcePort (m_endPoint6->GetLocalPort ());
2298  tcpHeader.SetDestinationPort (m_endPoint6->GetPeerPort ());
2299  }
2300  AddOptions (tcpHeader);
2301 
2302  if (m_endPoint != 0)
2303  {
2304  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
2306  }
2307  else
2308  {
2309  m_tcp->SendPacket (p, tcpHeader, m_endPoint6->GetLocalAddress (),
2311  }
2312  NS_LOG_LOGIC ("Schedule persist timeout at time "
2313  << Simulator::Now ().GetSeconds () << " to expire at time "
2314  << (Simulator::Now () + m_persistTimeout).GetSeconds ());
2316 }
2317 
2318 void
2320 {
2321  m_nextTxSequence = m_txBuffer.HeadSequence (); // Start from highest Ack
2322  m_rtt->IncreaseMultiplier (); // Double the timeout value for next retx timer
2323  m_dupAckCount = 0;
2324  DoRetransmit (); // Retransmit the packet
2325 }
2326 
2327 void
2329 {
2330  NS_LOG_FUNCTION (this);
2331  // Retransmit SYN packet
2332  if (m_state == SYN_SENT)
2333  {
2334  if (m_cnCount > 0)
2335  {
2337  }
2338  else
2339  {
2341  }
2342  return;
2343  }
2344  // Retransmit non-data packet: Only if in FIN_WAIT_1 or CLOSING state
2345  if (m_txBuffer.Size () == 0)
2346  {
2347  if (m_state == FIN_WAIT_1 || m_state == CLOSING)
2348  { // Must have lost FIN, re-send
2350  }
2351  return;
2352  }
2353  // Retransmit a data packet: Call SendDataPacket
2354  NS_LOG_LOGIC ("TcpSocketBase " << this << " retxing seq " << m_txBuffer.HeadSequence ());
2355  uint32_t sz = SendDataPacket (m_txBuffer.HeadSequence (), m_segmentSize, true);
2356  // In case of RTO, advance m_nextTxSequence
2357  m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer.HeadSequence () + sz);
2358 
2359 }
2360 
2361 void
2363 {
2364  m_retxEvent.Cancel ();
2366  m_delAckEvent.Cancel ();
2369 }
2370 
2371 /* Move TCP to Time_Wait state and schedule a transition to Closed state */
2372 void
2374 {
2375  NS_LOG_INFO (TcpStateName[m_state] << " -> TIME_WAIT");
2376  m_state = TIME_WAIT;
2377  CancelAllTimers ();
2378  // Move from TIME_WAIT to CLOSED after 2*MSL. Max segment lifetime is 2 min
2379  // according to RFC793, p.28
2382 }
2383 
2384 /* Below are the attribute get/set functions */
2385 
2386 void
2388 {
2390 }
2391 
2392 uint32_t
2394 {
2395  return m_txBuffer.MaxBufferSize ();
2396 }
2397 
2398 void
2400 {
2402 }
2403 
2404 uint32_t
2406 {
2407  return m_rxBuffer.MaxBufferSize ();
2408 }
2409 
2410 void
2412 {
2413  m_segmentSize = size;
2414  NS_ABORT_MSG_UNLESS (m_state == CLOSED, "Cannot change segment size dynamically.");
2415 }
2416 
2417 uint32_t
2419 {
2420  return m_segmentSize;
2421 }
2422 
2423 void
2425 {
2426  m_cnTimeout = timeout;
2427 }
2428 
2429 Time
2431 {
2432  return m_cnTimeout;
2433 }
2434 
2435 void
2437 {
2438  m_cnRetries = count;
2439 }
2440 
2441 uint32_t
2443 {
2444  return m_cnRetries;
2445 }
2446 
2447 void
2449 {
2451 }
2452 
2453 Time
2455 {
2456  return m_delAckTimeout;
2457 }
2458 
2459 void
2461 {
2462  m_delAckMaxCount = count;
2463 }
2464 
2465 uint32_t
2467 {
2468  return m_delAckMaxCount;
2469 }
2470 
2471 void
2473 {
2474  m_noDelay = noDelay;
2475 }
2476 
2477 bool
2479 {
2480  return m_noDelay;
2481 }
2482 
2483 void
2485 {
2487 }
2488 
2489 Time
2491 {
2492  return m_persistTimeout;
2493 }
2494 
2495 bool
2497 {
2498  // Broadcast is not implemented. Return true only if allowBroadcast==false
2499  return (!allowBroadcast);
2500 }
2501 
2502 bool
2504 {
2505  return false;
2506 }
2507 
2508 void
2510 {
2511  NS_LOG_FUNCTION (this << header);
2512 
2513  if ((header.GetFlags () & TcpHeader::SYN))
2514  {
2515  if (m_winScalingEnabled)
2516  {
2517  m_winScalingEnabled = false;
2518 
2519  if (header.HasOption (TcpOption::WINSCALE))
2520  {
2521  m_winScalingEnabled = true;
2523  }
2524  }
2525  }
2526 
2527  m_timestampEnabled = false;
2528  if (header.HasOption (TcpOption::TS))
2529  {
2530  m_timestampEnabled = true;
2532  }
2533 }
2534 
2535 void
2537 {
2538  NS_LOG_FUNCTION (this << header);
2539 
2540  // The window scaling option is set only on SYN packets
2541  if (m_winScalingEnabled && (header.GetFlags () & TcpHeader::SYN))
2542  {
2543  AddOptionWScale (header);
2544  }
2545 
2546  if (m_timestampEnabled)
2547  {
2548  AddOptionTimestamp (header);
2549  }
2550 }
2551 
2552 void
2554 {
2555  NS_LOG_FUNCTION (this << option);
2556 
2557  Ptr<const TcpOptionWinScale> ws = DynamicCast<const TcpOptionWinScale> (option);
2558 
2559  // In naming, we do the contrary of RFC 1323. The received scaling factor
2560  // is Rcv.Wind.Scale (and not Snd.Wind.Scale)
2561  m_rcvScaleFactor = ws->GetScale ();
2562 
2563  if (m_rcvScaleFactor > 14)
2564  {
2565  NS_LOG_WARN ("Possible error; m_rcvScaleFactor exceeds 14: " << m_rcvScaleFactor);
2566  m_rcvScaleFactor = 14;
2567  }
2568 
2569  NS_LOG_INFO (m_node->GetId () << " Received a scale factor of " <<
2570  static_cast<int> (m_rcvScaleFactor));
2571 }
2572 
2573 uint8_t
2575 {
2576  NS_LOG_FUNCTION (this);
2577  uint32_t maxSpace = m_rxBuffer.MaxBufferSize ();
2578  uint8_t scale = 0;
2579 
2580  while (maxSpace > m_maxWinSize)
2581  {
2582  maxSpace = maxSpace >> 1;
2583  ++scale;
2584  }
2585 
2586  if (scale > 14)
2587  {
2588  NS_LOG_WARN ("Possible error; scale exceeds 14: " << scale);
2589  scale = 14;
2590  }
2591 
2592  NS_LOG_INFO ("Node " << m_node->GetId () << " calculated wscale factor of " <<
2593  static_cast<int> (scale) << " for buffer size " << m_rxBuffer.MaxBufferSize ());
2594  return scale;
2595 }
2596 
2597 void
2599 {
2600  NS_LOG_FUNCTION (this << header);
2601  NS_ASSERT(header.GetFlags () & TcpHeader::SYN);
2602 
2603  Ptr<TcpOptionWinScale> option = CreateObject<TcpOptionWinScale> ();
2604 
2605  // In naming, we do the contrary of RFC 1323. The sended scaling factor
2606  // is Snd.Wind.Scale (and not Rcv.Wind.Scale)
2607 
2609  option->SetScale (m_sndScaleFactor);
2610 
2611  header.AppendOption (option);
2612 
2613  NS_LOG_INFO (m_node->GetId () << " Send a scaling factor of " <<
2614  static_cast<int> (m_sndScaleFactor));
2615 }
2616 
2617 void
2619 {
2620  NS_LOG_FUNCTION (this << option);
2621 
2622  Ptr<const TcpOptionTS> ts = DynamicCast<const TcpOptionTS> (option);
2623  m_timestampToEcho = ts->GetTimestamp ();
2624  m_lastEchoedTime = ts->GetEcho ();
2625 
2626  NS_LOG_INFO (m_node->GetId () << " Got timestamp=" <<
2627  m_timestampToEcho << " and Echo=" << m_lastEchoedTime);
2628 }
2629 
2630 void
2632 {
2633  NS_LOG_FUNCTION (this << header);
2634 
2635  Ptr<TcpOptionTS> option = CreateObject<TcpOptionTS> ();
2636 
2637  option->SetTimestamp (TcpOptionTS::NowToTsValue ());
2638  option->SetEcho (m_timestampToEcho);
2639 
2640  header.AppendOption (option);
2641  NS_LOG_INFO (m_node->GetId () << " Add option TS, ts=" <<
2642  option->GetTimestamp () << " echo=" << m_timestampToEcho);
2643 }
2644 
2645 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Definition: simulator.cc:189
Ipv6Address GetLocalAddress()
Get the local address.
void PeerClose(Ptr< Packet > p, const TcpHeader &tcpHeader)
Received a FIN from peer, notify rx buffer.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition: socket.cc:816
void ProcessListen(Ptr< Packet > packet, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Received a packet upon LISTEN state.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
virtual int Listen(void)
Listen for incoming connections.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
bool IsManualIpTtl(void) const
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:382
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
an Inet address class
virtual int GetSockName(Address &address) const
Get socket address.
Ipv4Address GetIpv4(void) const
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
static Ipv4Address GetAny(void)
uint32_t Size(void) const
Returns total number of bytes in this Tx buffer.
#define NS_LOG_FUNCTION(parameters)
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.
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:115
Hold a bool native type.
Definition: boolean.h:38
virtual uint8_t GetIpTtl(void) const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:470
virtual uint16_t AdvertisedWindowSize(void)
The amount of Rx window announced to the peer.
Callback template class.
Definition: callback.h:972
bool Add(Ptr< Packet > p, TcpHeader const &tcph)
Insert a packet into the buffer and update the availBytes counter to reflect the number of bytes read...
bool m_noDelay
Set to true to disable Nagle's algorithm.
virtual uint32_t GetSegSize(void) const
Get the segment size.
uint8_t GetIpTos(void) const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:403
uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck)
Extract at most maxSize bytes from the TxBuffer at sequence seq, add the TCP header, and send to TcpL4Protocol.
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:1047
void DiscardUpTo(const SequenceNumber32 &seq)
Discard data up to but not including this sequence number.
(abstract) base class of all TcpSockets
Definition: tcp-socket.h:64
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
static Time ElapsedTimeFromTsValue(uint32_t echoTime)
Estimate the Time elapsed from a TS echo value.
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:133
virtual ~TcpSocketBase(void)
TracedValue< Time > m_lastRtt
Last RTT sample collected.
void NotifyDataRecv(void)
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:304
virtual int ShutdownRecv(void)
uint32_t SizeFromSequence(const SequenceNumber32 &seq) const
Returns the number of bytes from the buffer in the range [seq, tailSequence)
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Set the reception callback.
TcpSocketBase(void)
Create an unbound TCP socket.
EventId m_retxEvent
Retransmission event.
SequenceNumber32 HeadSequence(void) const
Returns the first byte's sequence number.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
IPv6 layer implementation.
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:121
void ForwardUp6(Ptr< Packet > packet, Ipv6Header header, uint16_t port, Ptr< Ipv6Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
void SetAddress(Address addr)
Set the tag's address.
Definition: socket.cc:522
virtual void SetPersistTimeout(Time timeout)
Set the timout for persistent connection.
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
virtual bool GetAllowBroadcast(void) const
Query whether broadcast datagram transmissions are allowed.
EventId m_timewaitEvent
TIME_WAIT expiration event: Move this socket to CLOSED state.
void NotifyConnectionFailed(void)
Notify through the callback (if set) that the connection has not been established due to an error...
Definition: socket.cc:226
static TypeId GetTypeId(void)
Get the type ID.
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
uint32_t Available() const
Get the actual number of bytes available to be read.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
void SendRST(void)
Send reset and tear down this socket.
uint32_t MaxBufferSize(void) const
Returns the Tx window size.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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:744
bool IsManualIpTos(void) const
Checks if the socket has a specific IPv4 ToS set.
Definition: socket.cc:370
Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback
ICMP callback.
void CancelAllTimers(void)
Cancel all timer when endpoint is deleted.
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
virtual uint8_t GetIpv6HopLimit(void) const
Query the value of IP Hop Limit field of this socket.
Definition: socket.cc:495
Time m_cnTimeout
Timeout for connection retry.
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
uint32_t m_segmentSize
Segment size.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
EventId m_lastAckEvent
Last ACK timeout event.
void ConnectionSucceeded(void)
Schedule-friendly wrapper for Socket::NotifyConnectionSucceeded()
void SetFinSequence(const SequenceNumber32 &s)
Set the FIN Sequence number (i.e., the one closing the connection)
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:760
TracedValue< SequenceNumber32 > m_nextTxSequence
Next seqnum to be sent (SND.NXT), ReTx pushes it back.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
virtual void ReceivedAck(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received an ACK packet.
ns3::Time timeout
uint32_t m_cnCount
Count of remaining connection retries.
T Get(void) const
Definition: traced-value.h:99
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.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
void DoPeerClose(void)
FIN is in sequence, notify app and respond with a FIN.
bool NotifyConnectionRequest(const Address &from)
Notify through the callback (if set) that an incoming connection is being requested by a remote host...
Definition: socket.cc:256
SequenceNumber32 NextRxSequence(void) const
Get Next Rx Sequence number.
virtual void PersistTimeout(void)
Send 1 byte probe to get an updated window size.
TracedValue< TcpStates_t > m_state
TCP state.
uint32_t m_delAckMaxCount
Number of packet to fire an ACK before delay timeout.
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:86
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
uint16_t GetPeerPort()
Get the peer port.
AttributeValue form of a Callback.
Definition: callback.h:1678
uint32_t m_cnRetries
Number of connection retries before giving up.
virtual uint32_t GetRcvBufSize(void) const
Get the receive buffer size.
uint32_t m_delAckCount
Delayed ACK counter.
virtual bool GetTcpNoDelay(void) const
Check if Nagle's algorithm is enabled or not.
void ForwardIcmp6(Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMPv6 packet to pass on to TCP.
virtual int Bind(void)
Allocate a local IPv4 endpoint for this socket.
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number
SequenceNumber32 MaxRxSequence(void) const
Get the lowest sequence number that this TcpRxBuffer cannot accept.
TcpTxBuffer m_txBuffer
Tx buffer.
virtual void Retransmit(void)
Halving cwnd and call DoRetransmit()
Packet header for IPv4.
Definition: ipv4-header.h:31
void SetLocalAddress(Ipv6Address addr)
Set the local address.
bool AppendOption(Ptr< TcpOption > option)
Append an option to the TCP header.
Definition: tcp-header.cc:453
virtual void ReadOptions(const TcpHeader &tcpHeader)
Read TCP options from incoming packets.
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.
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:73
virtual uint32_t UnAckDataCount(void)
Return count of number of unacked bytes.
void ForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
static const char *const TcpStateName[LAST_STATE]
Literal names of TCP states for use in log messages.
Definition: tcp-socket.h:80
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:582
virtual uint32_t GetSndBufSize(void) const
Get the send buffer size.
virtual enum SocketType GetSocketType(void) const
uint16_t GetLocalPort()
Get the local port.
void AddOptionTimestamp(TcpHeader &header)
Add the timestamp option to the header.
Hold an unsigned integer type.
Definition: uinteger.h:46
Ipv6EndPoint * m_endPoint6
the IPv6 endpoint
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Ptr< SampleEmitter > s
bool OutOfRange(SequenceNumber32 head, SequenceNumber32 tail) const
Check if a sequence number range is within the rx window.
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
Ipv4Address GetLocalAddress(void)
Get the local address.
An Inet6 address class.
virtual void SetTcpNoDelay(bool noDelay)
Enable/Disable Nagle's algorithm.
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:951
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1283
bool IsManualIpv6Tclass(void) const
Checks if the socket has a specific IPv6 Tclass set.
Definition: socket.cc:376
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:284
virtual uint32_t GetConnCount(void) const
Get the number of connection retries before giving up.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
enum SocketErrno m_errno
Socket error code.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
void SetNextRxSequence(const SequenceNumber32 &s)
Set the Next Sequence number.
A base class for implementation of a stream socket using TCP.
Ptr< RttEstimator > m_rtt
Round trip time estimator.
bool m_closeNotified
Told app to close socket.
void ProcessSynSent(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon SYN_SENT.
int SetupCallback(void)
Common part of the two Bind(), i.e.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
virtual void SetTcp(Ptr< TcpL4Protocol > tcp)
Set the associated TCP L4 protocol.
Ptr< TcpL4Protocol > m_tcp
the associated TCP L4 protocol
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition: socket.cc:642
void SetMaxBufferSize(uint32_t n)
Set the Tx window size.
void ProcessSynRcvd(Ptr< Packet > packet, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Received a packet upon SYN_RCVD.
virtual int ShutdownSend(void)
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:67
void NotifyConnectionSucceeded(void)
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:216
uint32_t Available(void) const
Returns the available capacity in this Tx window.
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:85
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
void SetMaxBufferSize(uint32_t s)
Set the Maximum buffer size.
bool IsManualIpv6HopLimit(void) const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition: socket.cc:388
virtual void SetDelAckMaxCount(uint32_t count)
Set the number of packet to fire an ACK before delay timeout.
void NotifyNormalClose(void)
Notify through the callback (if set) that the connection has been closed.
Definition: socket.cc:236
int DoConnect(void)
Perform the real connection tasks: Send SYN if allowed, RST if invalid.
void CompleteFork(Ptr< Packet > p, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Complete a connection by forking the socket.
virtual void AddOptions(TcpHeader &tcpHeader)
Add options to TcpHeader.
Ptr< Packet > Extract(uint32_t maxSize)
Extract data from the head of the buffer as indicated by nextRxSeq.
uint32_t m_dupAckCount
Dupack counter.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ptr< Node > m_node
the associated node
void NotifyNewConnectionCreated(Ptr< Socket > socket, const Address &from)
Notify through the callback (if set) that a new connection has been created.
Definition: socket.cc:274
void TimeWait(void)
Move from CLOSING or FIN_WAIT_2 to TIME_WAIT state.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
virtual void SetNode(Ptr< Node > node)
Set the associated node.
void SetIcmpCallback(Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:61
virtual uint32_t BytesInFlight(void)
Return total bytes in flight.
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1192
uint8_t GetIpv6Tclass(void) const
Query the value of IPv6 Traffic Class field of this socket.
Definition: socket.cc:445
void Destroy(void)
Kill this socket by zeroing its attributes (IPv4)
bool Add(Ptr< Packet > p)
Append a data packet to the end of the buffer.
virtual int Connect(const Address &address)
Initiate a connection to a remote host.
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:986
virtual int Close(void)
Close a socket.
static Ipv4Address GetZero(void)
void SetPeer(Ipv4Address address, uint16_t port)
Set the peer informations (address and port).
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
virtual uint32_t AvailableWindow(void)
Return unfilled portion of window.
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
Definition: socket.cc:120
virtual Ptr< TcpSocketBase > Fork(void)=0
Call CopyObject<> to clone me.
virtual void DupAck(const TcpHeader &tcpHeader, uint32_t count)=0
Received dupack (duplicate ACK)
virtual void SetRtt(Ptr< RttEstimator > rtt)
Set the associated RTT estimator.
double m_msl
Max segment lifetime.
virtual void ReTxTimeout(void)
Call Retransmit() upon RTO event.
TracedValue< SequenceNumber32 > m_highTxMark
Highest seqno ever sent, regardless of ReTx.
static uint32_t NowToTsValue()
Return an uint32_t value which represent "now".
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
void SendEmptyPacket(uint8_t flags)
Send a empty packet that carries a flag, e.g.
Time m_delAckTimeout
Time to delay an ACK.
void SetDataSentCallback(Callback< void, Ptr< Socket >, uint32_t > dataSent)
Notify application when a packet has been sent from transport protocol (non-standard socket call) ...
Definition: socket.cc:113
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
void SetLocalAddress(Ipv4Address address)
Set the local address.
virtual void SetSndBufSize(uint32_t size)
Set the send buffer size.
Ptr< TcpOption > GetOption(uint8_t kind) const
Get the option specified.
Definition: tcp-header.cc:479
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.
TcpRxBuffer m_rxBuffer
Rx buffer (reordering buffer)
Describes an IPv6 address.
Definition: ipv6-address.h:46
uint32_t MaxBufferSize(void) const
Get the Maximum buffer size.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
void ProcessEstablished(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon ESTABLISHED state.
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 cond is false.
Definition: abort.h:136
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:101
uint32_t GetId(void) const
Definition: node.cc:106
TracedValue< Time > m_rto
Retransmit timeout.
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:203
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:79
Ipv6Address GetPeerAddress()
Get the peer address.
int DoClose(void)
Close a socket by sending RST, FIN, or FIN+ACK, depend on the current state.
virtual void SetConnCount(uint32_t count)
Set the number of connection retries before giving up.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:845
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
Ipv4Address GetPeerAddress(void)
Get the peer address.
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t, Ptr< Ipv6Interface > > callback)
Set the reception callback.
static bool IsMatchingType(const Address &addr)
If the address match.
uint16_t GetPeerPort(void)
Get the peer port.
uint16_t GetPort(void) const
Get the port.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
virtual uint32_t Window(void)
Return the max possible number of unacked bytes.
virtual enum SocketErrno GetErrno(void) const
Get last error number.
void ProcessLastAck(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon LAST_ACK.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
virtual void SetSegSize(uint32_t size)
Set the segment size.
void ProcessClosing(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received a packet upon CLOSING.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
uint16_t GetPort(void) const
virtual void ReceivedData(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Recv of a data, put into buffer, call L7 to get it if necessary.
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:83
void CloseAndNotify(void)
Peacefully close the socket by notifying the upper layer and deallocate end point.
Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback6
ICMPv6 callback.
tuple address
Definition: first.py:37
virtual Ptr< Node > GetNode(void) const
Return the node this socket is associated with.
virtual void SetRcvBufSize(uint32_t size)
Set the receive buffer size.
bool m_shutdownRecv
Receive no longer allowed.
virtual Time GetDelAckTimeout(void) const
Get the time to delay an ACK.
virtual void DelAckTimeout(void)
Action upon delay ACK timeout, i.e.
bool HasOption(uint8_t kind) const
Check if the header has the option specified.
Definition: tcp-header.cc:495
virtual void LastAckTimeout(void)
Timeout at LAST_ACK, close the connection.
uint32_t Size(void) const
Get the actual buffer occupancy.
void SetWindowSize(uint16_t windowSize)
Set the window size.
Definition: tcp-header.cc:91
Hold a floating point type.
Definition: double.h:41
virtual void DoForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by TcpSocketBase::ForwardUp().
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
indicates whether the socket has IP_TOS set.
Definition: socket.h: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:53
Ptr< T > GetObject(void) const
Definition: object.h:362
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
EventId m_delAckEvent
Delayed ACK timeout event.
a unique identifier for an interface.
Definition: type-id.h:49
bool m_shutdownSend
Send no longer allowed.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
int SetupEndpoint6(void)
Configure the endpoint v6 to a local address.
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:294
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
bool SendPendingData(bool withAck=false)
Send as much pending data as possible according to the Tx window.
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMP packet to pass on to TCP.
TracedValue< uint32_t > m_rWnd
Flow control window at remote side.
static bool IsMatchingType(const Address &address)
void NotifyErrorClose(void)
Notify through the callback (if set) that the connection has been closed due to an error...
Definition: socket.cc:246
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.
bool Finished(void)
Check if the buffer did receive all the data (and the connection is closed)
void Destroy6(void)
Kill this socket by zeroing its attributes (IPv6)
void SetHeadSequence(const SequenceNumber32 &seq)
Set the m_firstByteSeq to seq.
Time m_persistTimeout
Time between sending 1-byte probes.
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
virtual uint32_t GetRxAvailable(void) const
Return number of bytes which can be returned from one or multiple calls to Recv.
Ptr< Packet > CopyFromSequence(uint32_t numBytes, const SequenceNumber32 &seq)
Copy data of size numBytes into a packet, data from the range [seq, seq+numBytes) ...