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-route.h"
25 #include "ipv4-routing-protocol.h"
26 #include "ipv6-end-point-demux.h"
27 #include "ipv6-end-point.h"
28 #include "ipv6-l3-protocol.h"
29 #include "ipv6-route.h"
30 #include "ipv6-routing-protocol.h"
31 #include "rtt-estimator.h"
32 #include "tcp-congestion-ops.h"
33 #include "tcp-cubic.h"
34 #include "tcp-header.h"
35 #include "tcp-prr-recovery.h"
36 #include "tcp-recovery-ops.h"
37 #include "tcp-socket-base.h"
39 
40 #include "ns3/assert.h"
41 #include "ns3/boolean.h"
42 #include "ns3/log.h"
43 #include "ns3/node.h"
44 #include "ns3/nstime.h"
45 #include "ns3/object-map.h"
46 #include "ns3/packet.h"
47 #include "ns3/simulator.h"
48 
49 #include <iomanip>
50 #include <sstream>
51 #include <unordered_map>
52 #include <vector>
53 
54 namespace ns3
55 {
56 
57 NS_LOG_COMPONENT_DEFINE("TcpL4Protocol");
58 
59 NS_OBJECT_ENSURE_REGISTERED(TcpL4Protocol);
60 
61 // TcpL4Protocol stuff----------------------------------------------------------
62 
63 #undef NS_LOG_APPEND_CONTEXT
64 #define NS_LOG_APPEND_CONTEXT \
65  if (m_node) \
66  { \
67  std::clog << " [node " << m_node->GetId() << "] "; \
68  }
69 
70 /* see http://www.iana.org/assignments/protocol-numbers */
71 const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
72 
73 TypeId
75 {
76  static TypeId tid =
77  TypeId("ns3::TcpL4Protocol")
79  .SetGroupName("Internet")
80  .AddConstructor<TcpL4Protocol>()
81  .AddAttribute("RttEstimatorType",
82  "Type of RttEstimator objects.",
86  .AddAttribute("SocketType",
87  "Socket type of TCP objects.",
91  .AddAttribute("RecoveryType",
92  "Recovery type of TCP objects.",
96  .AddAttribute("SocketList",
97  "A container of sockets associated to this protocol. "
98  "The underlying type is an unordered map, the attribute name "
99  "is kept for backward compatibility.",
100  ObjectMapValue(),
102  MakeObjectMapChecker<TcpSocketBase>());
103  return tid;
104 }
105 
107  : m_endPoints(new Ipv4EndPointDemux()),
108  m_endPoints6(new Ipv6EndPointDemux())
109 {
110  NS_LOG_FUNCTION(this);
111 }
112 
114 {
115  NS_LOG_FUNCTION(this);
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION(this);
122  m_node = node;
123 }
124 
125 void
127 {
128  NS_LOG_FUNCTION(this);
129  Ptr<Node> node = this->GetObject<Node>();
130  Ptr<Ipv4> ipv4 = this->GetObject<Ipv4>();
131  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
132 
133  if (!m_node)
134  {
135  if (node && (ipv4 || ipv6))
136  {
137  this->SetNode(node);
138  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl>();
139  tcpFactory->SetTcp(this);
140  node->AggregateObject(tcpFactory);
141  }
142  }
143 
144  // We set at least one of our 2 down targets to the IPv4/IPv6 send
145  // functions. Since these functions have different prototypes, we
146  // need to keep track of whether we are connected to an IPv4 or
147  // IPv6 lower layer and call the appropriate one.
148 
149  if (ipv4 && m_downTarget.IsNull())
150  {
151  ipv4->Insert(this);
152  this->SetDownTarget(MakeCallback(&Ipv4::Send, ipv4));
153  }
154  if (ipv6 && m_downTarget6.IsNull())
155  {
156  ipv6->Insert(this);
157  this->SetDownTarget6(MakeCallback(&Ipv6::Send, ipv6));
158  }
160 }
161 
162 int
164 {
165  return PROT_NUMBER;
166 }
167 
168 void
170 {
171  NS_LOG_FUNCTION(this);
172  m_sockets.clear();
173 
174  if (m_endPoints != nullptr)
175  {
176  delete m_endPoints;
177  m_endPoints = nullptr;
178  }
179 
180  if (m_endPoints6 != nullptr)
181  {
182  delete m_endPoints6;
183  m_endPoints6 = nullptr;
184  }
185 
186  m_node = nullptr;
190 }
191 
194 {
195  return CreateSocket(congestionTypeId, m_recoveryTypeId);
196 }
197 
199 TcpL4Protocol::CreateSocket(TypeId congestionTypeId, TypeId recoveryTypeId)
200 {
201  NS_LOG_FUNCTION(this << congestionTypeId.GetName());
202  ObjectFactory rttFactory;
203  ObjectFactory congestionAlgorithmFactory;
204  ObjectFactory recoveryAlgorithmFactory;
205  rttFactory.SetTypeId(m_rttTypeId);
206  congestionAlgorithmFactory.SetTypeId(congestionTypeId);
207  recoveryAlgorithmFactory.SetTypeId(recoveryTypeId);
208 
209  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator>();
210  Ptr<TcpSocketBase> socket = CreateObject<TcpSocketBase>();
211  Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps>();
212  Ptr<TcpRecoveryOps> recovery = recoveryAlgorithmFactory.Create<TcpRecoveryOps>();
213 
214  socket->SetNode(m_node);
215  socket->SetTcp(this);
216  socket->SetRtt(rtt);
217  socket->SetCongestionControlAlgorithm(algo);
218  socket->SetRecoveryAlgorithm(recovery);
219 
220  m_sockets[m_socketIndex++] = socket;
221  return socket;
222 }
223 
226 {
228 }
229 
232 {
233  NS_LOG_FUNCTION(this);
234  return m_endPoints->Allocate();
235 }
236 
239 {
240  NS_LOG_FUNCTION(this << address);
241  return m_endPoints->Allocate(address);
242 }
243 
245 TcpL4Protocol::Allocate(Ptr<NetDevice> boundNetDevice, uint16_t port)
246 {
247  NS_LOG_FUNCTION(this << boundNetDevice << port);
248  return m_endPoints->Allocate(boundNetDevice, port);
249 }
250 
253 {
254  NS_LOG_FUNCTION(this << boundNetDevice << address << port);
255  return m_endPoints->Allocate(boundNetDevice, address, port);
256 }
257 
260  Ipv4Address localAddress,
261  uint16_t localPort,
262  Ipv4Address peerAddress,
263  uint16_t peerPort)
264 {
265  NS_LOG_FUNCTION(this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
266  return m_endPoints->Allocate(boundNetDevice, localAddress, localPort, peerAddress, peerPort);
267 }
268 
269 void
271 {
272  NS_LOG_FUNCTION(this << endPoint);
273  m_endPoints->DeAllocate(endPoint);
274 }
275 
278 {
279  NS_LOG_FUNCTION(this);
280  return m_endPoints6->Allocate();
281 }
282 
285 {
286  NS_LOG_FUNCTION(this << address);
287  return m_endPoints6->Allocate(address);
288 }
289 
292 {
293  NS_LOG_FUNCTION(this << boundNetDevice << port);
294  return m_endPoints6->Allocate(boundNetDevice, port);
295 }
296 
299 {
300  NS_LOG_FUNCTION(this << boundNetDevice << address << port);
301  return m_endPoints6->Allocate(boundNetDevice, address, port);
302 }
303 
306  Ipv6Address localAddress,
307  uint16_t localPort,
308  Ipv6Address peerAddress,
309  uint16_t peerPort)
310 {
311  NS_LOG_FUNCTION(this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
312  return m_endPoints6->Allocate(boundNetDevice, localAddress, localPort, peerAddress, peerPort);
313 }
314 
315 void
317 {
318  NS_LOG_FUNCTION(this << endPoint);
319  m_endPoints6->DeAllocate(endPoint);
320 }
321 
322 void
324  uint8_t icmpTtl,
325  uint8_t icmpType,
326  uint8_t icmpCode,
327  uint32_t icmpInfo,
328  Ipv4Address payloadSource,
329  Ipv4Address payloadDestination,
330  const uint8_t payload[8])
331 {
332  NS_LOG_FUNCTION(this << icmpSource << (uint16_t)icmpTtl << (uint16_t)icmpType
333  << (uint16_t)icmpCode << icmpInfo << payloadSource << payloadDestination);
334  uint16_t src;
335  uint16_t dst;
336  src = payload[0] << 8;
337  src |= payload[1];
338  dst = payload[2] << 8;
339  dst |= payload[3];
340 
341  Ipv4EndPoint* endPoint = m_endPoints->SimpleLookup(payloadSource, src, payloadDestination, dst);
342  if (endPoint != nullptr)
343  {
344  endPoint->ForwardIcmp(icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
345  }
346  else
347  {
348  NS_LOG_DEBUG("no endpoint found source=" << payloadSource
349  << ", destination=" << payloadDestination
350  << ", src=" << src << ", dst=" << dst);
351  }
352 }
353 
354 void
356  uint8_t icmpTtl,
357  uint8_t icmpType,
358  uint8_t icmpCode,
359  uint32_t icmpInfo,
360  Ipv6Address payloadSource,
361  Ipv6Address payloadDestination,
362  const uint8_t payload[8])
363 {
364  NS_LOG_FUNCTION(this << icmpSource << (uint16_t)icmpTtl << (uint16_t)icmpType
365  << (uint16_t)icmpCode << icmpInfo << payloadSource << payloadDestination);
366  uint16_t src;
367  uint16_t dst;
368  src = payload[0] << 8;
369  src |= payload[1];
370  dst = payload[2] << 8;
371  dst |= payload[3];
372 
373  Ipv6EndPoint* endPoint =
374  m_endPoints6->SimpleLookup(payloadSource, src, payloadDestination, dst);
375  if (endPoint != nullptr)
376  {
377  endPoint->ForwardIcmp(icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
378  }
379  else
380  {
381  NS_LOG_DEBUG("no endpoint found source=" << payloadSource
382  << ", destination=" << payloadDestination
383  << ", src=" << src << ", dst=" << dst);
384  }
385 }
386 
389  TcpHeader& incomingTcpHeader,
390  const Address& source,
391  const Address& destination)
392 {
393  NS_LOG_FUNCTION(this << packet << incomingTcpHeader << source << destination);
394 
395  if (Node::ChecksumEnabled())
396  {
397  incomingTcpHeader.EnableChecksums();
398  incomingTcpHeader.InitializeChecksum(source, destination, PROT_NUMBER);
399  }
400 
401  packet->PeekHeader(incomingTcpHeader);
402 
403  NS_LOG_LOGIC("TcpL4Protocol " << this << " receiving seq "
404  << incomingTcpHeader.GetSequenceNumber() << " ack "
405  << incomingTcpHeader.GetAckNumber() << " flags "
406  << TcpHeader::FlagsToString(incomingTcpHeader.GetFlags())
407  << " data size " << packet->GetSize());
408 
409  if (!incomingTcpHeader.IsChecksumOk())
410  {
411  NS_LOG_INFO("Bad checksum, dropping packet!");
413  }
414 
415  return IpL4Protocol::RX_OK;
416 }
417 
418 void
420  const Address& incomingSAddr,
421  const Address& incomingDAddr)
422 {
423  NS_LOG_FUNCTION(this << incomingHeader << incomingSAddr << incomingDAddr);
424 
425  if (!(incomingHeader.GetFlags() & TcpHeader::RST))
426  {
427  // build a RST packet and send
428  Ptr<Packet> rstPacket = Create<Packet>();
429  TcpHeader outgoingTcpHeader;
430 
431  if (incomingHeader.GetFlags() & TcpHeader::ACK)
432  {
433  // ACK bit was set
434  outgoingTcpHeader.SetFlags(TcpHeader::RST);
435  outgoingTcpHeader.SetSequenceNumber(incomingHeader.GetAckNumber());
436  }
437  else
438  {
439  outgoingTcpHeader.SetFlags(TcpHeader::RST | TcpHeader::ACK);
440  outgoingTcpHeader.SetSequenceNumber(SequenceNumber32(0));
441  outgoingTcpHeader.SetAckNumber(incomingHeader.GetSequenceNumber() +
442  SequenceNumber32(1));
443  }
444 
445  // Remember that parameters refer to the incoming packet; in reply,
446  // we need to swap src/dst
447 
448  outgoingTcpHeader.SetSourcePort(incomingHeader.GetDestinationPort());
449  outgoingTcpHeader.SetDestinationPort(incomingHeader.GetSourcePort());
450 
451  SendPacket(rstPacket, outgoingTcpHeader, incomingDAddr, incomingSAddr);
452  }
453 }
454 
457  const Ipv4Header& incomingIpHeader,
458  Ptr<Ipv4Interface> incomingInterface)
459 {
460  NS_LOG_FUNCTION(this << packet << incomingIpHeader << incomingInterface);
461 
462  TcpHeader incomingTcpHeader;
463  IpL4Protocol::RxStatus checksumControl;
464 
465  checksumControl = PacketReceived(packet,
466  incomingTcpHeader,
467  incomingIpHeader.GetSource(),
468  incomingIpHeader.GetDestination());
469 
470  if (checksumControl != IpL4Protocol::RX_OK)
471  {
472  return checksumControl;
473  }
474 
476  endPoints = m_endPoints->Lookup(incomingIpHeader.GetDestination(),
477  incomingTcpHeader.GetDestinationPort(),
478  incomingIpHeader.GetSource(),
479  incomingTcpHeader.GetSourcePort(),
480  incomingInterface);
481 
482  if (endPoints.empty())
483  {
484  if (this->GetObject<Ipv6L3Protocol>())
485  {
486  NS_LOG_LOGIC(" No Ipv4 endpoints matched on TcpL4Protocol, trying Ipv6 " << this);
487  Ptr<Ipv6Interface> fakeInterface;
488  Ipv6Header ipv6Header;
489  Ipv6Address src;
490  Ipv6Address dst;
491 
492  src = Ipv6Address::MakeIpv4MappedAddress(incomingIpHeader.GetSource());
493  dst = Ipv6Address::MakeIpv4MappedAddress(incomingIpHeader.GetDestination());
494  ipv6Header.SetSource(src);
495  ipv6Header.SetDestination(dst);
496  return (this->Receive(packet, ipv6Header, fakeInterface));
497  }
498 
499  NS_LOG_LOGIC("TcpL4Protocol "
500  << this
501  << " received a packet but"
502  " no endpoints matched."
503  << " destination IP: " << incomingIpHeader.GetDestination()
504  << " destination port: " << incomingTcpHeader.GetDestinationPort()
505  << " source IP: " << incomingIpHeader.GetSource()
506  << " source port: " << incomingTcpHeader.GetSourcePort());
507 
508  NoEndPointsFound(incomingTcpHeader,
509  incomingIpHeader.GetSource(),
510  incomingIpHeader.GetDestination());
511 
513  }
514 
515  NS_ASSERT_MSG(endPoints.size() == 1, "Demux returned more than one endpoint");
516  NS_LOG_LOGIC("TcpL4Protocol " << this
517  << " received a packet and"
518  " now forwarding it up to endpoint/socket");
519 
520  (*endPoints.begin())
521  ->ForwardUp(packet, incomingIpHeader, incomingTcpHeader.GetSourcePort(), incomingInterface);
522 
523  return IpL4Protocol::RX_OK;
524 }
525 
528  const Ipv6Header& incomingIpHeader,
529  Ptr<Ipv6Interface> interface)
530 {
531  NS_LOG_FUNCTION(this << packet << incomingIpHeader.GetSource()
532  << incomingIpHeader.GetDestination());
533 
534  TcpHeader incomingTcpHeader;
535  IpL4Protocol::RxStatus checksumControl;
536 
537  // If we are receiving a v4-mapped packet, we will re-calculate the TCP checksum
538  // Is it worth checking every received "v6" packet to see if it is v4-mapped in
539  // order to avoid re-calculating TCP checksums for v4-mapped packets?
540 
541  checksumControl = PacketReceived(packet,
542  incomingTcpHeader,
543  incomingIpHeader.GetSource(),
544  incomingIpHeader.GetDestination());
545 
546  if (checksumControl != IpL4Protocol::RX_OK)
547  {
548  return checksumControl;
549  }
550 
551  Ipv6EndPointDemux::EndPoints endPoints =
552  m_endPoints6->Lookup(incomingIpHeader.GetDestination(),
553  incomingTcpHeader.GetDestinationPort(),
554  incomingIpHeader.GetSource(),
555  incomingTcpHeader.GetSourcePort(),
556  interface);
557  if (endPoints.empty())
558  {
559  NS_LOG_LOGIC("TcpL4Protocol "
560  << this
561  << " received a packet but"
562  " no endpoints matched."
563  << " destination IP: " << incomingIpHeader.GetDestination()
564  << " destination port: " << incomingTcpHeader.GetDestinationPort()
565  << " source IP: " << incomingIpHeader.GetSource()
566  << " source port: " << incomingTcpHeader.GetSourcePort());
567 
568  NoEndPointsFound(incomingTcpHeader,
569  incomingIpHeader.GetSource(),
570  incomingIpHeader.GetDestination());
571 
573  }
574 
575  NS_ASSERT_MSG(endPoints.size() == 1, "Demux returned more than one endpoint");
576  NS_LOG_LOGIC("TcpL4Protocol " << this
577  << " received a packet and"
578  " now forwarding it up to endpoint/socket");
579 
580  (*endPoints.begin())
581  ->ForwardUp(packet, incomingIpHeader, incomingTcpHeader.GetSourcePort(), interface);
582 
583  return IpL4Protocol::RX_OK;
584 }
585 
586 void
588  const TcpHeader& outgoing,
589  const Ipv4Address& saddr,
590  const Ipv4Address& daddr,
591  Ptr<NetDevice> oif) const
592 {
593  NS_LOG_FUNCTION(this << packet << saddr << daddr << oif);
594  NS_LOG_LOGIC("TcpL4Protocol " << this << " sending seq " << outgoing.GetSequenceNumber()
595  << " ack " << outgoing.GetAckNumber() << " flags "
596  << TcpHeader::FlagsToString(outgoing.GetFlags()) << " data size "
597  << packet->GetSize());
598  // XXX outgoingHeader cannot be logged
599 
600  TcpHeader outgoingHeader = outgoing;
602  /* outgoingHeader.SetUrgentPointer (0); */
603  if (Node::ChecksumEnabled())
604  {
605  outgoingHeader.EnableChecksums();
606  }
607  outgoingHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
608 
609  packet->AddHeader(outgoingHeader);
610 
612  if (ipv4)
613  {
614  Ipv4Header header;
615  header.SetSource(saddr);
616  header.SetDestination(daddr);
617  header.SetProtocol(PROT_NUMBER);
618  Socket::SocketErrno errno_;
619  Ptr<Ipv4Route> route;
620  if (ipv4->GetRoutingProtocol())
621  {
622  route = ipv4->GetRoutingProtocol()->RouteOutput(packet, header, oif, errno_);
623  }
624  else
625  {
626  NS_LOG_ERROR("No IPV4 Routing Protocol");
627  route = nullptr;
628  }
629  m_downTarget(packet, saddr, daddr, PROT_NUMBER, route);
630  }
631  else
632  {
633  NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv4 interface");
634  }
635 }
636 
637 void
639  const TcpHeader& outgoing,
640  const Ipv6Address& saddr,
641  const Ipv6Address& daddr,
642  Ptr<NetDevice> oif) const
643 {
644  NS_LOG_FUNCTION(this << packet << saddr << daddr << oif);
645  NS_LOG_LOGIC("TcpL4Protocol " << this << " sending seq " << outgoing.GetSequenceNumber()
646  << " ack " << outgoing.GetAckNumber() << " flags "
647  << TcpHeader::FlagsToString(outgoing.GetFlags()) << " data size "
648  << packet->GetSize());
649  // XXX outgoingHeader cannot be logged
650 
651  if (daddr.IsIpv4MappedAddress())
652  {
653  return (SendPacket(packet,
654  outgoing,
655  saddr.GetIpv4MappedAddress(),
656  daddr.GetIpv4MappedAddress(),
657  oif));
658  }
659  TcpHeader outgoingHeader = outgoing;
661  /* outgoingHeader.SetUrgentPointer (0); */
662  if (Node::ChecksumEnabled())
663  {
664  outgoingHeader.EnableChecksums();
665  }
666  outgoingHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
667 
668  packet->AddHeader(outgoingHeader);
669 
671  if (ipv6)
672  {
673  Ipv6Header header;
674  header.SetSource(saddr);
675  header.SetDestination(daddr);
676  header.SetNextHeader(PROT_NUMBER);
677  Socket::SocketErrno errno_;
678  Ptr<Ipv6Route> route;
679  if (ipv6->GetRoutingProtocol())
680  {
681  route = ipv6->GetRoutingProtocol()->RouteOutput(packet, header, oif, errno_);
682  }
683  else
684  {
685  NS_LOG_ERROR("No IPV6 Routing Protocol");
686  route = nullptr;
687  }
688  m_downTarget6(packet, saddr, daddr, PROT_NUMBER, route);
689  }
690  else
691  {
692  NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv6 interface");
693  }
694 }
695 
696 void
698  const TcpHeader& outgoing,
699  const Address& saddr,
700  const Address& daddr,
701  Ptr<NetDevice> oif) const
702 {
703  NS_LOG_FUNCTION(this << pkt << outgoing << saddr << daddr << oif);
704  if (Ipv4Address::IsMatchingType(saddr))
705  {
707 
708  SendPacketV4(pkt,
709  outgoing,
712  oif);
713 
714  return;
715  }
716  else if (Ipv6Address::IsMatchingType(saddr))
717  {
719 
720  SendPacketV6(pkt,
721  outgoing,
724  oif);
725 
726  return;
727  }
728  else if (InetSocketAddress::IsMatchingType(saddr))
729  {
732 
733  SendPacketV4(pkt, outgoing, s.GetIpv4(), d.GetIpv4(), oif);
734 
735  return;
736  }
737  else if (Inet6SocketAddress::IsMatchingType(saddr))
738  {
741 
742  SendPacketV6(pkt, outgoing, s.GetIpv6(), d.GetIpv6(), oif);
743 
744  return;
745  }
746 
747  NS_FATAL_ERROR("Trying to send a packet without IP addresses");
748 }
749 
750 void
752 {
753  NS_LOG_FUNCTION(this << socket);
754 
755  for (auto& socketItem : m_sockets)
756  {
757  if (socketItem.second == socket)
758  {
759  return;
760  }
761  }
762  m_sockets[m_socketIndex++] = socket;
763 }
764 
765 bool
767 {
768  NS_LOG_FUNCTION(this << socket);
769 
770  for (auto& socketItem : m_sockets)
771  {
772  if (socketItem.second == socket)
773  {
774  socketItem.second = nullptr;
775  m_sockets.erase(socketItem.first);
776  return true;
777  }
778  }
779 
780  return false;
781 }
782 
783 void
785 {
786  m_downTarget = callback;
787 }
788 
791 {
792  return m_downTarget;
793 }
794 
795 void
797 {
798  m_downTarget6 = callback;
799 }
800 
803 {
804  return m_downTarget6;
805 }
806 
807 } // namespace ns3
a polymophic address class
Definition: address.h:101
void Nullify()
Discard the implementation, set it to null.
Definition: callback.h:575
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
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:42
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:80
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:49
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:35
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
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
Ipv6Address GetSource() const
Get the "Source address" field.
Definition: ipv6-header.cc:112
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:285
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:331
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:352
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:861
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:47
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:70
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:76
SequenceNumber32 GetSequenceNumber() const
Get the sequence number.
Definition: tcp-header.cc:118
uint16_t GetDestinationPort() const
Get the destination port.
Definition: tcp-header.cc:112
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:88
void InitializeChecksum(const Ipv4Address &source, const Ipv4Address &destination, uint8_t protocol)
Initialize the TCP checksum.
Definition: tcp-header.cc:166
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:39
uint16_t GetSourcePort() const
Get the source port.
Definition: tcp-header.cc:106
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:64
void EnableChecksums()
Enable checksum calculation for TCP.
Definition: tcp-header.cc:58
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:82
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:148
SequenceNumber32 GetAckNumber() const
Get the ACK number.
Definition: tcp-header.cc:124
bool IsChecksumOk() const
Is the TCP checksum correct ?
Definition: tcp-header.cc:237
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.
TypeId m_congestionTypeId
The socket TypeId.
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.
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)
std::unordered_map< uint64_t, Ptr< TcpSocketBase > > m_sockets
Unordered map of socket IDs and corresponding sockets.
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)
uint64_t m_socketIndex
index of the next socket to be created
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.
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.
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
std::string GetName() const
Get the name.
Definition: type-id.cc:991
uint16_t port
Definition: dsdv-manet.cc:44
#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
#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:47
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:704
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition: object-map.h:40
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition: type-id.cc:1250
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition: type-id.h:598
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:76