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