PageRenderTime 44ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/internet/doc/internet-stack.rst

https://gitlab.com/msepahkar/location_in_wireless_ndn
ReStructuredText | 317 lines | 250 code | 67 blank | 0 comment | 0 complexity | 4a6935d0a7e46902c40f8a2a1696fc1a MD5 | raw file
  1. .. include:: replace.txt
  2. .. highlight:: cpp
  3. Internet Stack
  4. --------------
  5. Internet stack aggregation
  6. **************************
  7. A bare class :cpp:class:`Node` is not very useful as-is; other objects must be
  8. aggregated to it to provide useful node functionality.
  9. The |ns3| source code directory ``src/internet`` provides implementation
  10. of TCP/IPv4- and IPv6-related components. These include IPv4, ARP, UDP, TCP,
  11. IPv6, Neighbor Discovery, and other related protocols.
  12. Internet Nodes are not subclasses of class Node; they are simply Nodes that have
  13. had a bunch of IP-related objects aggregated to them. They can be put together
  14. by hand, or via a helper function :cpp:func:`InternetStackHelper::Install ()`
  15. which does the following to all nodes passed in as arguments::
  16. void
  17. InternetStackHelper::Install (Ptr<Node> node) const
  18. {
  19. if (m_ipv4Enabled)
  20. {
  21. /* IPv4 stack */
  22. if (node->GetObject<Ipv4> () != 0)
  23. {
  24. NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating "
  25. "an InternetStack to a node with an existing Ipv4 object");
  26. return;
  27. }
  28. CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
  29. CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol");
  30. CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
  31. // Set routing
  32. Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
  33. Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
  34. ipv4->SetRoutingProtocol (ipv4Routing);
  35. }
  36. if (m_ipv6Enabled)
  37. {
  38. /* IPv6 stack */
  39. if (node->GetObject<Ipv6> () != 0)
  40. {
  41. NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating "
  42. "an InternetStack to a node with an existing Ipv6 object");
  43. return;
  44. }
  45. CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv6L3Protocol");
  46. CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv6L4Protocol");
  47. // Set routing
  48. Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
  49. Ptr<Ipv6RoutingProtocol> ipv6Routing = m_routingv6->Create (node);
  50. ipv6->SetRoutingProtocol (ipv6Routing);
  51. /* register IPv6 extensions and options */
  52. ipv6->RegisterExtensions ();
  53. ipv6->RegisterOptions ();
  54. }
  55. if (m_ipv4Enabled || m_ipv6Enabled)
  56. {
  57. /* UDP and TCP stacks */
  58. CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
  59. node->AggregateObject (m_tcpFactory.Create<Object> ());
  60. Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
  61. node->AggregateObject (factory);
  62. }
  63. }
  64. Where multiple implementations exist in |ns3| (TCP, IP routing), these objects
  65. are added by a factory object (TCP) or by a routing helper (m_routing).
  66. Note that the routing protocol is configured and set outside this
  67. function. By default, the following protocols are added::
  68. void InternetStackHelper::Initialize ()
  69. {
  70. SetTcp ("ns3::TcpL4Protocol");
  71. Ipv4StaticRoutingHelper staticRouting;
  72. Ipv4GlobalRoutingHelper globalRouting;
  73. Ipv4ListRoutingHelper listRouting;
  74. Ipv6ListRoutingHelper listRoutingv6;
  75. Ipv6StaticRoutingHelper staticRoutingv6;
  76. listRouting.Add (staticRouting, 0);
  77. listRouting.Add (globalRouting, -10);
  78. listRoutingv6.Add (staticRoutingv6, 0);
  79. SetRoutingHelper (listRouting);
  80. SetRoutingHelper (listRoutingv6);
  81. }
  82. By default, IPv4 and IPv6 are enabled.
  83. Internet Node structure
  84. +++++++++++++++++++++++
  85. An IP-capable Node (an |ns3| Node augmented by aggregation to have one or more
  86. IP stacks) has the following internal structure.
  87. Layer-3 protocols
  88. ~~~~~~~~~~~~~~~~~
  89. At the lowest layer, sitting above the NetDevices, are the "layer 3" protocols,
  90. including IPv4, IPv6, ARP and so on. The class
  91. :cpp:class:`Ipv4L3Protocol` is an implementation class whose public interface is
  92. typically class :cpp:class:`Ipv4`, but the
  93. Ipv4L3Protocol public API is also used internally at present.
  94. In class Ipv4L3Protocol, one method described below is ``Receive ()``::
  95. /**
  96. * Lower layer calls this method after calling L3Demux::Lookup
  97. * The ARP subclass needs to know from which NetDevice this
  98. * packet is coming to:
  99. * - implement a per-NetDevice ARP cache
  100. * - send back arp replies on the right device
  101. */
  102. void Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol,
  103. const Address &from, const Address &to, NetDevice::PacketType packetType);
  104. First, note that the ``Receive ()`` function has a matching signature to the
  105. ReceiveCallback in the class :cpp:class:`Node`. This function pointer is
  106. inserted into the Node's protocol handler when ``AddInterface ()`` is called.
  107. The actual registration is done
  108. with a statement such as follows::
  109. RegisterProtocolHandler ( MakeCallback (&Ipv4Protocol::Receive, ipv4),
  110. Ipv4L3Protocol::PROT_NUMBER, 0);
  111. The Ipv4L3Protocol object is aggregated to the Node; there is only one such
  112. Ipv4L3Protocol object. Higher-layer protocols that have a packet to send down to
  113. the Ipv4L3Protocol object can call ``GetObject<Ipv4L3Protocol> ()`` to obtain a
  114. pointer, as follows::
  115. Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
  116. if (ipv4 != 0)
  117. {
  118. ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
  119. }
  120. This class nicely demonstrates two techniques we exploit in |ns3| to bind
  121. objects together: callbacks, and object aggregation.
  122. Once IPv4 routing has determined that a packet is for the local node, it
  123. forwards it up the stack. This is done with the following function::
  124. void
  125. Ipv4L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
  126. The first step is to find the right Ipv4L4Protocol object, based on IP protocol
  127. number. For instance, TCP is registered in the demux as protocol number 6.
  128. Finally, the ``Receive()`` function on the Ipv4L4Protocol (such as
  129. ``TcpL4Protocol::Receive`` is called.
  130. We have not yet introduced the class Ipv4Interface. Basically, each NetDevice is
  131. paired with an IPv4 representation of such device. In Linux, this class
  132. :cpp:class:`Ipv4Interface` roughly corresponds to the ``struct in_device``; the
  133. main purpose is to provide address-family specific information (addresses) about
  134. an interface.
  135. All the classes have appropriate traces in order to track sent, received and lost packets.
  136. The users is encouraged to use them so to find out if (and where) a packet is dropped. A
  137. common mistake is to forget the effects of local queues when sending packets, e.g., the ARP
  138. queue. This can be particularly puzzling when sending jumbo packets or packet bursts using UDP.
  139. The ARP cache pending queue is limited (3 datagrams) and IP packets might be fragmented, easily
  140. overfilling the ARP cache queue size. In those cases it is useful to increase the ARP cache
  141. pending size to a proper value, e.g.::
  142. Config::SetDefault ("ns3::ArpCache::PendingQueueSize", UintegerValue (MAX_BURST_SIZE/L2MTU*3));
  143. The IPv6 implementation follows a similar architecture. Dual-stacked nodes (one with
  144. support for both IPv4 and IPv6) will allow an IPv6 socket to receive IPv4 connections
  145. as a standard dual-stacked system does. A socket bound and listening to an IPv6 endpoint
  146. can receive an IPv4 connection and will return the remote address as an IPv4-mapped address.
  147. Support for the IPV6_V6ONLY socket option does not currently exist.
  148. Layer-4 protocols and sockets
  149. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  150. We next describe how the transport protocols, sockets, and applications tie
  151. together. In summary, each transport protocol implementation is a socket
  152. factory. An application that needs a new socket
  153. For instance, to create a UDP socket, an application would use a code snippet
  154. such as the following::
  155. Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
  156. Ptr<Socket> m_socket = socketFactory->CreateSocket ();
  157. m_socket->Bind (m_local_address);
  158. ...
  159. The above will query the node to get a pointer to its UDP socket factory, will
  160. create one such socket, and will use the socket with an API similar to the
  161. C-based sockets API, such as ``Connect ()`` and ``Send ()``. The address passed
  162. to the ``Bind ()``, ``Connect ()``, or ``Send ()`` functions may be a
  163. :cpp:class:`Ipv4Address`, :cpp:class:`Ipv6Address`, or :cpp:class:`Address`.
  164. If a :cpp:class:`Address` is passed in and contains anything other than
  165. a :cpp:class:`Ipv4Address` or :cpp:class:`Ipv6Address`, these functions will
  166. return an error. The ``Bind (void)`` and ``Bind6 (void)`` functions bind to
  167. "0.0.0.0" and "::" respectively.
  168. The socket can also be bound to a specific NetDevice though the
  169. ``BindToNetDevice (Ptr<NetDevice> netdevice)`` function.
  170. ``BindToNetDevice (Ptr<NetDevice> netdevice)`` will bind the socket
  171. to "0.0.0.0" and "::" (equivalent to calling ``Bind ()`` and ``Bind6 ()``,
  172. unless the socket has been already bound to a specific address.
  173. Summarizing, the correct sequence is::
  174. Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
  175. Ptr<Socket> m_socket = socketFactory->CreateSocket ();
  176. m_socket->BindToNetDevice (n_netDevice);
  177. ...
  178. or::
  179. Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
  180. Ptr<Socket> m_socket = socketFactory->CreateSocket ();
  181. m_socket->Bind (m_local_address);
  182. m_socket->BindToNetDevice (n_netDevice);
  183. ...
  184. The following raises an error::
  185. Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
  186. Ptr<Socket> m_socket = socketFactory->CreateSocket ();
  187. m_socket->BindToNetDevice (n_netDevice);
  188. m_socket->Bind (m_local_address);
  189. ...
  190. See the chapter on |ns3| sockets for more information.
  191. We have described so far a socket factory (e.g. ``class Udp``) and a socket,
  192. which may be specialized (e.g., class :cpp:class:`UdpSocket`). There are a few
  193. more key objects that relate to the specialized task of demultiplexing a packet
  194. to one or more receiving sockets. The key object in this task is class
  195. :cpp:class:`Ipv4EndPointDemux`. This demultiplexer stores objects of class
  196. :cpp:class:`Ipv4EndPoint`. This class holds the addressing/port tuple (local
  197. port, local address, destination port, destination address) associated with the
  198. socket, and a receive callback. This receive callback has a receive function
  199. registered by the socket. The ``Lookup ()`` function to Ipv4EndPointDemux
  200. returns a list of Ipv4EndPoint objects (there may be a list since more than one
  201. socket may match the packet). The layer-4 protocol copies the packet to each
  202. Ipv4EndPoint and calls its ``ForwardUp ()`` method, which then calls the
  203. ``Receive ()`` function registered by the socket.
  204. An issue that arises when working with the sockets API on real
  205. systems is the need to manage the reading from a socket, using
  206. some type of I/O (e.g., blocking, non-blocking, asynchronous, ...).
  207. |ns3| implements an asynchronous model for socket I/O; the application
  208. sets a callback to be notified of received data ready to be read, and the
  209. callback is invoked by the transport protocol when data is available.
  210. This callback is specified as follows::
  211. void Socket::SetRecvCallback (Callback<void, Ptr<Socket>,
  212. Ptr<Packet>,
  213. const Address&> receivedData);
  214. The data being received is conveyed in the Packet data buffer. An example
  215. usage is in class :cpp:class:`PacketSink`::
  216. m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this));
  217. To summarize, internally, the UDP implementation is organized as follows:
  218. * a ``UdpImpl`` class that implements the UDP socket factory functionality
  219. * a ``UdpL4Protocol`` class that implements the protocol logic that is
  220. socket-independent
  221. * a ``UdpSocketImpl`` class that implements socket-specific aspects of UDP
  222. * a class called ``Ipv4EndPoint`` that stores the addressing tuple (local port,
  223. local address, destination port, destination address) associated with the
  224. socket, and a receive callback for the socket.
  225. IP-capable node interfaces
  226. ++++++++++++++++++++++++++
  227. Many of the implementation details, or internal objects themselves, of
  228. IP-capable Node objects are not exposed at the simulator public API. This
  229. allows for different implementations; for instance, replacing the native |ns3|
  230. models with ported TCP/IP stack code.
  231. The C++ public APIs of all of these objects is found in the ``src/network``
  232. directory, including principally:
  233. * ``address.h``
  234. * ``socket.h``
  235. * ``node.h``
  236. * ``packet.h``
  237. These are typically base class objects that implement the default values used in
  238. the implementation, implement access methods to get/set state variables, host
  239. attributes, and implement publicly-available methods exposed to clients such as
  240. ``CreateSocket``.
  241. Example path of a packet
  242. ++++++++++++++++++++++++
  243. These two figures show an example stack trace of how packets flow through the
  244. Internet Node objects.
  245. .. _internet-node-send:
  246. .. figure:: figures/internet-node-send.*
  247. Send path of a packet.
  248. .. _internet-node-recv:
  249. .. figure:: figures/internet-node-recv.*
  250. Receive path of a packet.