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