blob: 5d7b8ac0986a10c6d9894ae903e47f561cb1671f [file] [log] [blame]
Spyridon Mastorakis95be5092015-08-26 15:07:37 -07001Simulating real NDN applications
2================================
Alexander Afanasyev5dee3612015-08-25 16:09:04 -07003
Spyridon Mastorakis95be5092015-08-26 15:07:37 -07004The version of `ndn-cxx library <http://named-data.net/doc/ndn-cxx/>`__ bundled with ndnSIM includes
5a modified version of :ndnsim:`ndn::Face` to directly send and receive Interest and Data packets to
6and from the simulated instances of NFD. With this modification, ndnSIM enables support to simulate
7real NDN applications written against the ndn-cxx, if they satisfy requirements listed in this guide
8or can be modified to satisfy these requirements.
9
10
11Requirements
12++++++++++++
13
14#. **Source code of the application must be available**
15
16 The application (parts of the application) needs to be compiled against the ndnSIM version of
17 ndn-cxx library.
18
19#. **Source code should separate** ``main`` **function from the functional components of the
20 application that will be simulated**
21
22 The entry point to the application (its functional component) will be NS-3 application class,
23 which should be able to create and destroy an instance of the simulated component when scheduled
24 by the scenario.
25
26#. **The application should not use global variables, if they define a state for the application
27 instance**
28
29 ndnSIM should be able to create multiple different instances of the application, e.g., for each
30 simulated node.
31
32 Exception to this requirement is :ndnsim:`ndn::Scheduler <ndn::util::scheduler::Scheduler>`: its
33 implementation has been rewired to use NS-3's scheduling routines.
34
35#. **The application MUST NOT contain any GUI or command-line terminal interactions**
36
37#. **The application SHOULD NOT use disk operations, unless application instances access unique
38 parts of the file system**
39
40 In the simulated environment, all application instances will be accessing the same local file
41 system, which can result in undefined behavior if not properly handled.
42
43#. **The application MUST use a subset of** :ndnsim:`ndn::Face` **API:**
44
45 - If the application create :ndnsim:`ndn::Face`, it MUST BE created either with a default
46 constructor or constructor that accepts a single ``boost::asio::io_service`` parameter.
47
48 .. code-block:: c++
49
50 // Supported
51 ndn::Face face1();
52 ndn::Face face2(ioService);
53
54 // Not supported in ndnSIM
55 ndn::Face face4(host_name, port_number)
56 ndn::Face face3(transport);
57 // and others
58
59 - :ndnsim:`ndn::Face::getIoService()` should be used only to obtain a reference to
60 ``boost::asio::io_service``. **Application MUST NOT use any methods of**
61 ``boost::asio::io_service``, **otherwise the simulation will crash.**
62
63 .. code-block:: c++
64
65 ndn::Face face;
66 ...
67 // Supported (the rewired Scheduler implementation does not access io_service methods)
68 Scheduler scheduler(face.getIoService());
69
70 // Not supported in ndnSIM and will result in crash
71 face.getIoService().stop();
72
73
74 - Application should avoid use of :ndnsim:`Face::processEvents` or use it with caution
75
76 In real applications, processEvents blocks until some data is received or the timeout callback
77 is called. In this case, any variables created before calling this method will still exist
78 after the method returns. However, in ndnSIM, such an assumption cannot be made, since the
79 scope of a variable is local.
80
81 .. code-block:: c++
82
83 void
84 foo
85 {
86 ndn::Face face;
87 face.expressInterest(...);
88 face.setInterestFilter(...);
89
90 // ndnSIM version of processEvents will not block!
91 face.processEvents();
92 }
93 // after existing foo scope, face variable is deallocated and all scheduled operations
94 // will be canceled
95
96#. **Application (simulated component) MUST NOT create instances of** ``boost::asio::io_service``
97 **and use their methods**
98
99 ``boost::asio::io_service`` is inherently incompatible with NS-3, as both are providing mechanisms
100 for asynchronous event processing.
101
102#. We also recommend that functional part of the application accepts reference to the
103 :ndnsim:`KeyChain` instance, instead of creating instance itself.
104
105 When simulating non-security aspects of the application, in simulation scenario it will be
106 possible to use a dummy implementation of the :ndnsim:`KeyChain` that does not perform crypto
107 operations, but signs Data and Interests with fake signatures.
108
109 For example, this can be achieved by enabling the constructor of the real application to accept a reference
110 to the :ndnsim:`KeyChain`:
111
112 .. code-block:: c++
113
114 // Real applications should accept a reference to the KeyChain instance
115 RealApp::RealApp(KeyChain& keyChain)
116 : m_keyChain(keyChain)
117 {
118 }
119
120
121How to simulate real applications using ndnSIM
122++++++++++++++++++++++++++++++++++++++++++++++
123
124To simulate a real application, the simulation scenario should contain a class derived from
125``ns3::Application``. This class needs to create an instance of the :ndnsim:`ndn::Face` and/or real
126application in the overloaded ``StartApplication`` method. This class also need to ensure that the
127created instance is not deallocated until ``StopApplication`` method is called.
128
129For example, if the functional class of the real application looks like:
130
131.. literalinclude:: ../../examples/ndn-cxx-simple/real-app.hpp
132 :language: c++
133 :linenos:
134 :lines: 23-75
135
136
137The corresponding NS-3 "entry point" application class can be like this:
138
139.. literalinclude:: ../../examples/ndn-cxx-simple/real-app-starter.hpp
140 :language: c++
141 :linenos:
142 :lines: 25-65
143
144.. note::
145 There is a requirement that :ndnsim:`ndn::Face` MUST BE created within the context of a specific
146 ``ns3::Node``. In simple words this means that :ndnsim:`ndn::Face` constructor must be called
147 somewhere within the overloaded ``StartApplication`` method.
148
149 Attempt to create a :ndnsim:`ndn::Face` outside ``ns3::Node`` (e.g., if the example included
150 member variable ``Face m_face`` in ``RealAppStarter`` class) will result in simulation crash.
151
152The final step is to actually write a simulation scenario that defines network topology, routing
153information between nodes, on which nodes the application should be installed and when it should be
154started and stopped.
155
156For the trivial example, let us assume that we have only one simulation node and we want to start
157the application at time moment 6.5 seconds. This scenario can look like:
158
159.. literalinclude:: ../../examples/ndn-cxx-simple.cpp
160 :language: c++
161 :linenos:
162 :lines: 20-
163
164
165Example of a real application simulation
166++++++++++++++++++++++++++++++++++++++++
167
168To demonstrate functionality of ndnSIM in a more complex and realistic case, we will use the NDN
169ping application included as part of `NDN Essential Tools`_.
170
171For this example, we used a `scenario template repository`_ as a base to write simulation-specific
172extensions and define scenarios, and the `final version of the scenario is available in GitHub
173<https://github.com/named-data-ndnSIM/scenario-ndn-ping>`__.
174
175The following lists steps we did to simulate `ndnping` and `ndnpingserver` apps on a simple
176three-node topology:
177
178- forked `scenario template repository`_
179
180- imported the latest version of `NDN Essential Tools`_ source code as a git submodule
181
182- updated the build script (``wscript``) to compile the source code of ``ndnping`` and
183 ``ndnpingserver`` (with the exception of compilation units that contain ``main`` function) against
184 ndnSIM
185
186 `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/74269dc4de6afe2b6e13a0bcc8c0faac350d8fa3>`__
187
188- defined ``PingClient`` and ``PingServer`` classes to hold state of application instances
189
190 `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/4f087a16e3171af38c05b53c6cfd9e752e7cda72>`__
191
192- defined ``PingClientApp`` and ``PingServerApp`` NS-3 applications, that create and destroy
193 instances of ``PingClient`` and ``PingServer`` per NS-3 logic.
194
195 `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/2b317860f55b71b34ffdccac31444246d9b804fe>`__
196
197- defined a simple scenario that creates a three node topology, installs NDN stacks, and installs
198 ``PingClientApp`` and ``PingServerApp`` applications on different simulation nodes.
199
200 `View changes <https://github.com/named-data-ndnSIM/scenario-ndn-ping/commit/2b317860f55b71b34ffdccac31444246d9b804fe>`__
201
202After all these steps, the repository is ready to run the simulation (see `README.md
203<https://github.com/named-data-ndnSIM/scenario-ndn-ping/blob/master/README.md>`__ for more details).
204
205
206.. note::
207 The listed steps did not include any modification of `NDN Essential Tools`_ source code.
208 However, this was not the case when we initially attempted to run the simulation, as the source
209 code was violating a few requirements of this guide. `The changes that we made
210 <https://github.com/named-data/ndn-tools/commit/1e7a7b20c93014e86639e3d07f357c95b48b34ac>`__ are
211 an example of how to adapt the source code to be compatible with ndnSIM simulations.
212
213
214.. _NDN Essential Tools: http://github.com/named-data/ndn-tools
215
216.. _scenario template repository: https://github.com/named-data-ndnSIM/scenario-template