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