A Discrete-Event Network Simulator
API
tcp-l4-protocol.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  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Raj Bhattacharjea <raj.b@gatech.edu>
19  */
20 
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/nstime.h"
24 #include "ns3/boolean.h"
25 #include "ns3/object-vector.h"
26 
27 #include "ns3/packet.h"
28 #include "ns3/node.h"
29 #include "ns3/simulator.h"
30 #include "ns3/ipv4-route.h"
31 #include "ns3/ipv6-route.h"
32 
33 #include "tcp-l4-protocol.h"
34 #include "tcp-header.h"
35 #include "ipv4-end-point-demux.h"
36 #include "ipv6-end-point-demux.h"
37 #include "ipv4-end-point.h"
38 #include "ipv6-end-point.h"
39 #include "ipv4-l3-protocol.h"
40 #include "ipv6-l3-protocol.h"
41 #include "ipv6-routing-protocol.h"
43 #include "tcp-socket-base.h"
44 #include "tcp-congestion-ops.h"
45 #include "tcp-cubic.h"
46 #include "tcp-recovery-ops.h"
47 #include "tcp-prr-recovery.h"
48 #include "rtt-estimator.h"
49 
50 #include <vector>
51 #include <sstream>
52 #include <iomanip>
53 
54 namespace ns3 {
55 
56 NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
57 
58 NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol);
59 
60 //TcpL4Protocol stuff----------------------------------------------------------
61 
62 #undef NS_LOG_APPEND_CONTEXT
63 #define NS_LOG_APPEND_CONTEXT \
64  if (m_node) { std::clog << " [node " << m_node->GetId () << "] "; }
65 
66 /* see http://www.iana.org/assignments/protocol-numbers */
67 const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
68 
69 TypeId
71 {
72  static TypeId tid = TypeId ("ns3::TcpL4Protocol")
74  .SetGroupName ("Internet")
75  .AddConstructor<TcpL4Protocol> ()
76  .AddAttribute ("RttEstimatorType",
77  "Type of RttEstimator objects.",
81  .AddAttribute ("SocketType",
82  "Socket type of TCP objects.",
86  .AddAttribute ("RecoveryType",
87  "Recovery type of TCP objects.",
91  .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
94  MakeObjectVectorChecker<TcpSocketBase> ())
95  ;
96  return tid;
97 }
98 
100  : m_endPoints (new Ipv4EndPointDemux ()), m_endPoints6 (new Ipv6EndPointDemux ())
101 {
102  NS_LOG_FUNCTION (this);
103 }
104 
106 {
107  NS_LOG_FUNCTION (this);
108 }
109 
110 void
112 {
113  NS_LOG_FUNCTION (this);
114  m_node = node;
115 }
116 
117 void
119 {
120  NS_LOG_FUNCTION (this);
121  Ptr<Node> node = this->GetObject<Node> ();
122  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
123  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
124 
125  if (m_node == 0)
126  {
127  if ((node != 0) && (ipv4 != 0 || ipv6 != 0))
128  {
129  this->SetNode (node);
130  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
131  tcpFactory->SetTcp (this);
132  node->AggregateObject (tcpFactory);
133  }
134  }
135 
136  // We set at least one of our 2 down targets to the IPv4/IPv6 send
137  // functions. Since these functions have different prototypes, we
138  // need to keep track of whether we are connected to an IPv4 or
139  // IPv6 lower layer and call the appropriate one.
140 
141  if (ipv4 != 0 && m_downTarget.IsNull ())
142  {
143  ipv4->Insert (this);
144  this->SetDownTarget (MakeCallback (&Ipv4::Send, ipv4));
145  }
146  if (ipv6 != 0 && m_downTarget6.IsNull ())
147  {
148  ipv6->Insert (this);
149  this->SetDownTarget6 (MakeCallback (&Ipv6::Send, ipv6));
150  }
152 }
153 
154 int
156 {
157  return PROT_NUMBER;
158 }
159 
160 void
162 {
163  NS_LOG_FUNCTION (this);
164  m_sockets.clear ();
165 
166  if (m_endPoints != 0)
167  {
168  delete m_endPoints;
169  m_endPoints = 0;
170  }
171 
172  if (m_endPoints6 != 0)
173  {
174  delete m_endPoints6;
175  m_endPoints6 = 0;
176  }
177 
178  m_node = 0;
182 }
183 
186 {
187  return CreateSocket (congestionTypeId, m_recoveryTypeId);
188 }
189 
191 TcpL4Protocol::CreateSocket (TypeId congestionTypeId, TypeId recoveryTypeId)
192 {
193  NS_LOG_FUNCTION (this << congestionTypeId.GetName ());
194  ObjectFactory rttFactory;
195  ObjectFactory congestionAlgorithmFactory;
196  ObjectFactory recoveryAlgorithmFactory;
197  rttFactory.SetTypeId (m_rttTypeId);
198  congestionAlgorithmFactory.SetTypeId (congestionTypeId);
199  recoveryAlgorithmFactory.SetTypeId (recoveryTypeId);
200 
201  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator> ();
202  Ptr<TcpSocketBase> socket = CreateObject<TcpSocketBase> ();
203  Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps> ();
204  Ptr<TcpRecoveryOps> recovery = recoveryAlgorithmFactory.Create<TcpRecoveryOps> ();
205 
206  socket->SetNode (m_node);
207  socket->SetTcp (this);
208  socket->SetRtt (rtt);
209  socket->SetCongestionControlAlgorithm (algo);
210  socket->SetRecoveryAlgorithm (recovery);
211 
212  m_sockets.push_back (socket);
213  return socket;
214 }
215 
218 {
220 }
221 
222 Ipv4EndPoint *
224 {
225  NS_LOG_FUNCTION (this);
226  return m_endPoints->Allocate ();
227 }
228 
229 Ipv4EndPoint *
231 {
232  NS_LOG_FUNCTION (this << address);
233  return m_endPoints->Allocate (address);
234 }
235 
236 Ipv4EndPoint *
237 TcpL4Protocol::Allocate (Ptr<NetDevice> boundNetDevice, uint16_t port)
238 {
239  NS_LOG_FUNCTION (this << boundNetDevice << port);
240  return m_endPoints->Allocate (boundNetDevice, port);
241 }
242 
243 Ipv4EndPoint *
245 {
246  NS_LOG_FUNCTION (this << boundNetDevice << address << port);
247  return m_endPoints->Allocate (boundNetDevice, address, port);
248 }
249 
250 Ipv4EndPoint *
252  Ipv4Address localAddress, uint16_t localPort,
253  Ipv4Address peerAddress, uint16_t peerPort)
254 {
255  NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
256  return m_endPoints->Allocate (boundNetDevice,
257  localAddress, localPort,
258  peerAddress, peerPort);
259 }
260 
261 void
263 {
264  NS_LOG_FUNCTION (this << endPoint);
265  m_endPoints->DeAllocate (endPoint);
266 }
267 
268 Ipv6EndPoint *
270 {
271  NS_LOG_FUNCTION (this);
272  return m_endPoints6->Allocate ();
273 }
274 
275 Ipv6EndPoint *
277 {
278  NS_LOG_FUNCTION (this << address);
279  return m_endPoints6->Allocate (address);
280 }
281 
282 Ipv6EndPoint *
283 TcpL4Protocol::Allocate6 (Ptr<NetDevice> boundNetDevice, uint16_t port)
284 {
285  NS_LOG_FUNCTION (this << boundNetDevice << port);
286  return m_endPoints6->Allocate (boundNetDevice, port);
287 }
288 
289 Ipv6EndPoint *
291 {
292  NS_LOG_FUNCTION (this << boundNetDevice << address << port);
293  return m_endPoints6->Allocate (boundNetDevice, address, port);
294 }
295 
296 Ipv6EndPoint *
298  Ipv6Address localAddress, uint16_t localPort,
299  Ipv6Address peerAddress, uint16_t peerPort)
300 {
301  NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
302  return m_endPoints6->Allocate (boundNetDevice,
303  localAddress, localPort,
304  peerAddress, peerPort);
305 }
306 
307 void
309 {
310  NS_LOG_FUNCTION (this << endPoint);
311  m_endPoints6->DeAllocate (endPoint);
312 }
313 
314 void
315 TcpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
316  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
317  Ipv4Address payloadSource,Ipv4Address payloadDestination,
318  const uint8_t payload[8])
319 {
320  NS_LOG_FUNCTION (this << icmpSource << (uint16_t) icmpTtl << (uint16_t) icmpType << (uint16_t) icmpCode << icmpInfo
321  << payloadSource << payloadDestination);
322  uint16_t src, dst;
323  src = payload[0] << 8;
324  src |= payload[1];
325  dst = payload[2] << 8;
326  dst |= payload[3];
327 
328  Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
329  if (endPoint != 0)
330  {
331  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
332  }
333  else
334  {
335  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
336  ", destination=" << payloadDestination <<
337  ", src=" << src << ", dst=" << dst);
338  }
339 }
340 
341 void
342 TcpL4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
343  uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
344  Ipv6Address payloadSource,Ipv6Address payloadDestination,
345  const uint8_t payload[8])
346 {
347  NS_LOG_FUNCTION (this << icmpSource << (uint16_t) icmpTtl << (uint16_t) icmpType << (uint16_t) icmpCode << icmpInfo
348  << payloadSource << payloadDestination);
349  uint16_t src, dst;
350  src = payload[0] << 8;
351  src |= payload[1];
352  dst = payload[2] << 8;
353  dst |= payload[3];
354 
355  Ipv6EndPoint *endPoint = m_endPoints6->SimpleLookup (payloadSource, src, payloadDestination, dst);
356  if (endPoint != 0)
357  {
358  endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
359  }
360  else
361  {
362  NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
363  ", destination=" << payloadDestination <<
364  ", src=" << src << ", dst=" << dst);
365  }
366 }
367 
369 TcpL4Protocol::PacketReceived (Ptr<Packet> packet, TcpHeader &incomingTcpHeader,
370  const Address &source, const Address &destination)
371 {
372  NS_LOG_FUNCTION (this << packet << incomingTcpHeader << source << destination);
373 
374  if (Node::ChecksumEnabled ())
375  {
376  incomingTcpHeader.EnableChecksums ();
377  incomingTcpHeader.InitializeChecksum (source, destination, PROT_NUMBER);
378  }
379 
380  packet->PeekHeader (incomingTcpHeader);
381 
382  NS_LOG_LOGIC ("TcpL4Protocol " << this
383  << " receiving seq " << incomingTcpHeader.GetSequenceNumber ()
384  << " ack " << incomingTcpHeader.GetAckNumber ()
385  << " flags "<< TcpHeader::FlagsToString (incomingTcpHeader.GetFlags ())
386  << " data size " << packet->GetSize ());
387 
388  if (!incomingTcpHeader.IsChecksumOk ())
389  {
390  NS_LOG_INFO ("Bad checksum, dropping packet!");
392  }
393 
394  return IpL4Protocol::RX_OK;
395 }
396 
397 void
399  const Address &incomingSAddr,
400  const Address &incomingDAddr)
401 {
402  NS_LOG_FUNCTION (this << incomingHeader << incomingSAddr << incomingDAddr);
403 
404  if (!(incomingHeader.GetFlags () & TcpHeader::RST))
405  {
406  // build a RST packet and send
407  Ptr<Packet> rstPacket = Create<Packet> ();
408  TcpHeader outgoingTcpHeader;
409 
410  if (incomingHeader.GetFlags () & TcpHeader::ACK)
411  {
412  // ACK bit was set
413  outgoingTcpHeader.SetFlags (TcpHeader::RST);
414  outgoingTcpHeader.SetSequenceNumber (incomingHeader.GetAckNumber ());
415  }
416  else
417  {
418  outgoingTcpHeader.SetFlags (TcpHeader::RST | TcpHeader::ACK);
419  outgoingTcpHeader.SetSequenceNumber (SequenceNumber32 (0));
420  outgoingTcpHeader.SetAckNumber (incomingHeader.GetSequenceNumber () +
421  SequenceNumber32 (1));
422  }
423 
424  // Remember that parameters refer to the incoming packet; in reply,
425  // we need to swap src/dst
426 
427  outgoingTcpHeader.SetSourcePort (incomingHeader.GetDestinationPort ());
428  outgoingTcpHeader.SetDestinationPort (incomingHeader.GetSourcePort ());
429 
430  SendPacket (rstPacket, outgoingTcpHeader, incomingDAddr, incomingSAddr);
431  }
432 }
433 
436  Ipv4Header const &incomingIpHeader,
437  Ptr<Ipv4Interface> incomingInterface)
438 {
439  NS_LOG_FUNCTION (this << packet << incomingIpHeader << incomingInterface);
440 
441  TcpHeader incomingTcpHeader;
442  IpL4Protocol::RxStatus checksumControl;
443 
444  checksumControl = PacketReceived (packet, incomingTcpHeader,
445  incomingIpHeader.GetSource (),
446  incomingIpHeader.GetDestination ());
447 
448  if (checksumControl != IpL4Protocol::RX_OK)
449  {
450  return checksumControl;
451  }
452 
454  endPoints = m_endPoints->Lookup (incomingIpHeader.GetDestination (),
455  incomingTcpHeader.GetDestinationPort (),
456  incomingIpHeader.GetSource (),
457  incomingTcpHeader.GetSourcePort (),
458  incomingInterface);
459 
460  if (endPoints.empty ())
461  {
462  if (this->GetObject<Ipv6L3Protocol> () != 0)
463  {
464  NS_LOG_LOGIC (" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 " << this);
465  Ptr<Ipv6Interface> fakeInterface;
466  Ipv6Header ipv6Header;
467  Ipv6Address src, dst;
468 
469  src = Ipv6Address::MakeIpv4MappedAddress (incomingIpHeader.GetSource ());
470  dst = Ipv6Address::MakeIpv4MappedAddress (incomingIpHeader.GetDestination ());
471  ipv6Header.SetSource (src);
472  ipv6Header.SetDestination (dst);
473  return (this->Receive (packet, ipv6Header, fakeInterface));
474  }
475 
476  NS_LOG_LOGIC ("TcpL4Protocol " << this << " received a packet but"
477  " no endpoints matched." <<
478  " destination IP: " << incomingIpHeader.GetDestination () <<
479  " destination port: "<< incomingTcpHeader.GetDestinationPort () <<
480  " source IP: " << incomingIpHeader.GetSource () <<
481  " source port: "<< incomingTcpHeader.GetSourcePort ());
482 
483  NoEndPointsFound (incomingTcpHeader, incomingIpHeader.GetSource (),
484  incomingIpHeader.GetDestination ());
485 
487 
488  }
489 
490  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
491  NS_LOG_LOGIC ("TcpL4Protocol " << this << " received a packet and"
492  " now forwarding it up to endpoint/socket");
493 
494  (*endPoints.begin ())->ForwardUp (packet, incomingIpHeader,
495  incomingTcpHeader.GetSourcePort (),
496  incomingInterface);
497 
498  return IpL4Protocol::RX_OK;
499 }
500 
502 TcpL4Protocol::Receive (Ptr<Packet> packet,
503  Ipv6Header const &incomingIpHeader,
504  Ptr<Ipv6Interface> interface)
505 {
506  NS_LOG_FUNCTION (this << packet << incomingIpHeader.GetSource () <<
507  incomingIpHeader.GetDestination ());
508 
509  TcpHeader incomingTcpHeader;
510  IpL4Protocol::RxStatus checksumControl;
511 
512  // If we are receiving a v4-mapped packet, we will re-calculate the TCP checksum
513  // Is it worth checking every received "v6" packet to see if it is v4-mapped in
514  // order to avoid re-calculating TCP checksums for v4-mapped packets?
515 
516  checksumControl = PacketReceived (packet, incomingTcpHeader,
517  incomingIpHeader.GetSource (),
518  incomingIpHeader.GetDestination ());
519 
520  if (checksumControl != IpL4Protocol::RX_OK)
521  {
522  return checksumControl;
523  }
524 
525  Ipv6EndPointDemux::EndPoints endPoints =
526  m_endPoints6->Lookup (incomingIpHeader.GetDestination (),
527  incomingTcpHeader.GetDestinationPort (),
528  incomingIpHeader.GetSource (),
529  incomingTcpHeader.GetSourcePort (), interface);
530  if (endPoints.empty ())
531  {
532  NS_LOG_LOGIC ("TcpL4Protocol " << this << " received a packet but"
533  " no endpoints matched." <<
534  " destination IP: " << incomingIpHeader.GetDestination () <<
535  " destination port: "<< incomingTcpHeader.GetDestinationPort () <<
536  " source IP: " << incomingIpHeader.GetSource () <<
537  " source port: "<< incomingTcpHeader.GetSourcePort ());
538 
539  NoEndPointsFound (incomingTcpHeader, incomingIpHeader.GetSource (),
540  incomingIpHeader.GetDestination ());
541 
543  }
544 
545  NS_ASSERT_MSG (endPoints.size () == 1, "Demux returned more than one endpoint");
546  NS_LOG_LOGIC ("TcpL4Protocol " << this << " received a packet and"
547  " now forwarding it up to endpoint/socket");
548 
549  (*endPoints.begin ())->ForwardUp (packet, incomingIpHeader,
550  incomingTcpHeader.GetSourcePort (), interface);
551 
552  return IpL4Protocol::RX_OK;
553 }
554 
555 void
557  const Ipv4Address &saddr, const Ipv4Address &daddr,
558  Ptr<NetDevice> oif) const
559 {
560  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
561  NS_LOG_LOGIC ("TcpL4Protocol " << this
562  << " sending seq " << outgoing.GetSequenceNumber ()
563  << " ack " << outgoing.GetAckNumber ()
564  << " flags " << TcpHeader::FlagsToString (outgoing.GetFlags ())
565  << " data size " << packet->GetSize ());
566  // XXX outgoingHeader cannot be logged
567 
568  TcpHeader outgoingHeader = outgoing;
570  /* outgoingHeader.SetUrgentPointer (0); */
571  if (Node::ChecksumEnabled ())
572  {
573  outgoingHeader.EnableChecksums ();
574  }
575  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
576 
577  packet->AddHeader (outgoingHeader);
578 
579  Ptr<Ipv4> ipv4 =
580  m_node->GetObject<Ipv4> ();
581  if (ipv4 != 0)
582  {
583  Ipv4Header header;
584  header.SetSource (saddr);
585  header.SetDestination (daddr);
586  header.SetProtocol (PROT_NUMBER);
587  Socket::SocketErrno errno_;
588  Ptr<Ipv4Route> route;
589  if (ipv4->GetRoutingProtocol () != 0)
590  {
591  route = ipv4->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
592  }
593  else
594  {
595  NS_LOG_ERROR ("No IPV4 Routing Protocol");
596  route = 0;
597  }
598  m_downTarget (packet, saddr, daddr, PROT_NUMBER, route);
599  }
600  else
601  {
602  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv4 interface");
603  }
604 }
605 
606 void
608  const Ipv6Address &saddr, const Ipv6Address &daddr,
609  Ptr<NetDevice> oif) const
610 {
611  NS_LOG_FUNCTION (this << packet << saddr << daddr << oif);
612  NS_LOG_LOGIC ("TcpL4Protocol " << this
613  << " sending seq " << outgoing.GetSequenceNumber ()
614  << " ack " << outgoing.GetAckNumber ()
615  << " flags " << TcpHeader::FlagsToString (outgoing.GetFlags ())
616  << " data size " << packet->GetSize ());
617  // XXX outgoingHeader cannot be logged
618 
619  if (daddr.IsIpv4MappedAddress ())
620  {
621  return (SendPacket (packet, outgoing, saddr.GetIpv4MappedAddress (), daddr.GetIpv4MappedAddress (), oif));
622  }
623  TcpHeader outgoingHeader = outgoing;
625  /* outgoingHeader.SetUrgentPointer (0); */
626  if (Node::ChecksumEnabled ())
627  {
628  outgoingHeader.EnableChecksums ();
629  }
630  outgoingHeader.InitializeChecksum (saddr, daddr, PROT_NUMBER);
631 
632  packet->AddHeader (outgoingHeader);
633 
635  if (ipv6 != 0)
636  {
637  Ipv6Header header;
638  header.SetSource (saddr);
639  header.SetDestination (daddr);
640  header.SetNextHeader (PROT_NUMBER);
641  Socket::SocketErrno errno_;
642  Ptr<Ipv6Route> route;
643  if (ipv6->GetRoutingProtocol () != 0)
644  {
645  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, errno_);
646  }
647  else
648  {
649  NS_LOG_ERROR ("No IPV6 Routing Protocol");
650  route = 0;
651  }
652  m_downTarget6 (packet, saddr, daddr, PROT_NUMBER, route);
653  }
654  else
655  {
656  NS_FATAL_ERROR ("Trying to use Tcp on a node without an Ipv6 interface");
657  }
658 }
659 
660 void
662  const Address &saddr, const Address &daddr,
663  Ptr<NetDevice> oif) const
664 {
665  NS_LOG_FUNCTION (this << pkt << outgoing << saddr << daddr << oif);
666  if (Ipv4Address::IsMatchingType (saddr))
667  {
669 
670  SendPacketV4 (pkt, outgoing, Ipv4Address::ConvertFrom (saddr),
671  Ipv4Address::ConvertFrom (daddr), oif);
672 
673  return;
674  }
675  else if (Ipv6Address::IsMatchingType (saddr))
676  {
678 
679  SendPacketV6 (pkt, outgoing, Ipv6Address::ConvertFrom (saddr),
680  Ipv6Address::ConvertFrom (daddr), oif);
681 
682  return;
683  }
684  else if (InetSocketAddress::IsMatchingType (saddr))
685  {
688 
689  SendPacketV4 (pkt, outgoing, s.GetIpv4 (), d.GetIpv4 (), oif);
690 
691  return;
692  }
693  else if (Inet6SocketAddress::IsMatchingType (saddr))
694  {
697 
698  SendPacketV6 (pkt, outgoing, s.GetIpv6 (), d.GetIpv6 (), oif);
699 
700  return;
701  }
702 
703  NS_FATAL_ERROR ("Trying to send a packet without IP addresses");
704 }
705 
706 void
708 {
709  NS_LOG_FUNCTION (this << socket);
710  std::vector<Ptr<TcpSocketBase> >::iterator it = m_sockets.begin ();
711 
712  while (it != m_sockets.end ())
713  {
714  if (*it == socket)
715  {
716  return;
717  }
718 
719  ++it;
720  }
721 
722  m_sockets.push_back (socket);
723 }
724 
725 bool
727 {
728  NS_LOG_FUNCTION (this << socket);
729  std::vector<Ptr<TcpSocketBase> >::iterator it = m_sockets.begin ();
730 
731  while (it != m_sockets.end ())
732  {
733  if (*it == socket)
734  {
735  m_sockets.erase (it);
736  return true;
737  }
738 
739  ++it;
740  }
741 
742  return false;
743 }
744 
745 void
747 {
748  m_downTarget = callback;
749 }
750 
753 {
754  return m_downTarget;
755 }
756 
757 void
759 {
760  m_downTarget6 = callback;
761 }
762 
765 {
766  return m_downTarget6;
767 }
768 
769 } // namespace ns3
770 
a polymophic address class
Definition: address.h:91
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
void Nullify(void)
Discard the implementation, set it to null.
Definition: callback.h:1391
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
an Inet address class
Ipv4Address GetIpv4(void) const
static bool IsMatchingType(const Address &address)
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
L4 Protocol abstract base class.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Ipv4Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
Demultiplexes packets to various transport layer endpoints.
std::list< Ipv4EndPoint * > EndPoints
Container of the IPv4 endpoints.
Ipv4EndPoint * SimpleLookup(Ipv4Address daddr, uint16_t dport, Ipv4Address saddr, uint16_t sport)
simple lookup for a match with all the parameters.
Ipv4EndPoint * Allocate(void)
Allocate a Ipv4EndPoint.
EndPoints Lookup(Ipv4Address daddr, uint16_t dport, Ipv4Address saddr, uint16_t sport, Ptr< Ipv4Interface > incomingInterface)
lookup for a match with all the parameters.
void DeAllocate(Ipv4EndPoint *endPoint)
Remove a end point.
A representation of an internet endpoint/connection.
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Forward the ICMP packet to the upper level.
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Demultiplexer for end points.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
std::list< Ipv6EndPoint * > EndPoints
Container of the IPv6 endpoints.
Ipv6EndPoint * Allocate(void)
Allocate a Ipv6EndPoint.
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
A representation of an IPv6 endpoint/connection.
void ForwardIcmp(Ipv6Address src, uint8_t ttl, uint8_t type, uint8_t code, uint32_t info)
Forward the ICMP packet to the upper level.
Packet header for IPv6.
Definition: ipv6-header.h:36
void SetDestination(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:115
void SetSource(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:95
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:75
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:82
virtual void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)=0
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
IPv6 layer implementation.
static bool ChecksumEnabled(void)
Definition: node.cc:278
Instantiate subclasses of ns3::Object.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
Container for a set of ns3::Object pointers.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Base class for all RTT Estimators.
Definition: rtt-estimator.h:43
static TypeId GetTypeId(void)
Get the type ID.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
Congestion control abstract class.
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-cubic.cc:33
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:95
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:101
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:143
uint16_t GetDestinationPort() const
Get the destination port.
Definition: tcp-header.cc:137
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:113
void InitializeChecksum(const Ipv4Address &source, const Ipv4Address &destination, uint8_t protocol)
Initialize the TCP checksum.
Definition: tcp-header.cc:191
static std::string FlagsToString(uint8_t flags, const std::string &delimiter="|")
Converts an integer into a human readable list of Tcp flags.
Definition: tcp-header.cc:55
bool IsChecksumOk(void) const
Is the TCP checksum correct ?
Definition: tcp-header.cc:264
uint16_t GetSourcePort() const
Get the source port.
Definition: tcp-header.cc:131
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:89
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:107
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:173
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:149
void EnableChecksums(void)
Enable checksum calculation for TCP.
Definition: tcp-header.cc:83
TCP socket creation and multiplexing/demultiplexing.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
void NoEndPointsFound(const TcpHeader &incomingHeader, const Address &incomingSAddr, const Address &incomingDAddr)
Check if RST packet should be sent, and in case, send it.
bool RemoveSocket(Ptr< TcpSocketBase > socket)
Remove a socket from the internal list.
TypeId m_congestionTypeId
The socket TypeId.
virtual int GetProtocolNumber(void) const
Returns the protocol number of this protocol.
enum IpL4Protocol::RxStatus PacketReceived(Ptr< Packet > packet, TcpHeader &incomingTcpHeader, const Address &source, const Address &destination)
Get the tcp header of the incoming packet and checks its checksum if needed.
void SendPacketV6(Ptr< Packet > pkt, const TcpHeader &outgoing, const Ipv6Address &saddr, const Ipv6Address &daddr, Ptr< NetDevice > oif=0) const
Send a packet via TCP (IPv6)
TypeId m_recoveryTypeId
The recovery TypeId.
IpL4Protocol::DownTargetCallback m_downTarget
Callback to send packets over IPv4.
virtual enum IpL4Protocol::RxStatus Receive(Ptr< Packet > p, Ipv4Header const &incomingIpHeader, Ptr< Ipv4Interface > incomingInterface)
Called from lower-level layers to send the packet up in the stack.
Ipv4EndPointDemux * m_endPoints
A list of IPv4 end points.
std::vector< Ptr< TcpSocketBase > > m_sockets
list of sockets
virtual IpL4Protocol::DownTargetCallback GetDownTarget(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
Ipv6EndPointDemux * m_endPoints6
A list of IPv6 end points.
Ptr< Socket > CreateSocket(void)
Create a TCP socket using the TypeId set by SocketType attribute.
Ptr< Node > m_node
the node this stack is associated with
virtual void DoDispose(void)
Destructor implementation.
Ipv4EndPoint * Allocate(void)
Allocate an IPv4 Endpoint.
virtual void SetDownTarget(IpL4Protocol::DownTargetCallback cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
virtual void ReceiveIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, Ipv4Address payloadSource, Ipv4Address payloadDestination, const uint8_t payload[8])
Called from lower-level layers to send the ICMP packet up in the stack.
void DeAllocate(Ipv4EndPoint *endPoint)
Remove an IPv4 Endpoint.
void SendPacketV4(Ptr< Packet > pkt, const TcpHeader &outgoing, const Ipv4Address &saddr, const Ipv4Address &daddr, Ptr< NetDevice > oif=0) const
Send a packet via TCP (IPv4)
static const uint8_t PROT_NUMBER
protocol number (0x6)
virtual IpL4Protocol::DownTargetCallback6 GetDownTarget6(void) const
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
void SendPacket(Ptr< Packet > pkt, const TcpHeader &outgoing, const Address &saddr, const Address &daddr, Ptr< NetDevice > oif=0) const
Send a packet via TCP (IP-agnostic)
virtual void NotifyNewAggregate()
Setup socket factory and callbacks when aggregated to a node.
static TypeId GetTypeId(void)
Get the type ID.
Ipv6EndPoint * Allocate6(void)
Allocate an IPv6 Endpoint.
void AddSocket(Ptr< TcpSocketBase > socket)
Make a socket fully operational.
virtual void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb)
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
IpL4Protocol::DownTargetCallback6 m_downTarget6
Callback to send packets over IPv6.
TypeId m_rttTypeId
The RTT Estimator TypeId.
static TypeId GetTypeId(void)
Get the type ID.
recovery abstract class
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
std::string GetName(void) const
Get the name.
Definition: type-id.cc:976
AttributeValue implementation for TypeId.
Definition: type-id.h:595
uint16_t port
Definition: dsdv-manet.cc:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:81
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: type-id.h:595
Ptr< const AttributeChecker > MakeTypeIdChecker(void)
Definition: type-id.cc:1226
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648