author | Tom Henderson <tomh@tomh.org> |
Mon, 19 Oct 2009 07:54:31 -0700 | |
changeset 5434 | 81a3858041a8 |
parent 4755 | 04a9a7e9a624 |
child 6611 | 693b34a6e655 |
permissions | -rw-r--r-- |
3707 | 1 |
@node TCP |
2 |
@chapter TCP models in ns-3 |
|
3 |
@anchor{chap:TCP} |
|
4 |
||
5 |
This chapter describes the TCP models available in ns-3. |
|
6 |
||
7 |
@section Generic support for TCP |
|
8 |
||
9 |
ns-3 was written to support multiple TCP implementations. The |
|
10 |
implementations inherit from a few common header classes in the |
|
11 |
@code{src/node} directory, so that user code can swap out implementations |
|
12 |
with minimal changes to the scripts. |
|
13 |
||
14 |
There are two important abstract base classes: |
|
15 |
@itemize @bullet |
|
4411 | 16 |
@item @code{class TcpSocket}: This is defined in @code{src/node/tcp-socket.@{cc,h@}}. This class exists for hosting TcpSocket attributes that can be |
3707 | 17 |
reused across different implementations. For instance, |
18 |
@code{TcpSocket::SetInitialCwnd()} can be used for any of the implementations |
|
19 |
that derive from @code{class TcpSocket}. |
|
20 |
@item @code{class TcpSocketFactory}: This is used by applications to |
|
21 |
create TCP sockets. A typical usage can be seen in this snippet: |
|
22 |
@verbatim |
|
23 |
// Create the socket if not already created |
|
24 |
if (!m_socket) |
|
25 |
{ |
|
26 |
m_socket = Socket::CreateSocket (GetNode(), m_tid); |
|
27 |
m_socket->Bind (m_local); |
|
28 |
... |
|
29 |
} |
|
30 |
@end verbatim |
|
4755
04a9a7e9a624
Manual spelling fixes from Johannes Buchner
Tom Henderson <tomh@tomh.org>
parents:
4411
diff
changeset
|
31 |
The parameter @code{m_tid} controls the TypeId of the actual TCP Socket |
3707 | 32 |
implementation that is instantiated. This way, the application can be |
33 |
written generically and different socket implementations can be swapped out |
|
34 |
by specifying the TypeId. |
|
35 |
@end itemize |
|
36 |
||
37 |
@section ns-3 TCP |
|
38 |
||
39 |
ns-3 contains a port of the TCP model from |
|
40 |
@uref{http://www.ece.gatech.edu/research/labs/MANIACS/GTNetS/index.html,,GTNetS}. This model is a full TCP, in that it is |
|
41 |
bidirectional and attempts to model the connection setup and |
|
42 |
close logic. In fact, it is a more complete implementation of the TCP |
|
43 |
state machine than ns-2's "FullTcp" model. This TCP model was originally |
|
44 |
written by George Riley |
|
45 |
as part of GTNetS and ported to ns-3 by Raj Bhattacharjea. |
|
46 |
||
47 |
The implementation of TCP is contained in the following files: |
|
48 |
@verbatim |
|
49 |
src/internet-stack/tcp-header.{cc,h} |
|
50 |
src/internet-stack/tcp-l4-protocol.{cc,h} |
|
51 |
src/internet-stack/tcp-socket-factory-impl.{cc,h} |
|
52 |
src/internet-stack/tcp-socket-impl.{cc,h} |
|
53 |
src/internet-stack/tcp-typedefs.h |
|
54 |
src/internet-stack/rtt-estimator.{cc,h} |
|
55 |
src/internet-stack/sequence-number.{cc,h} |
|
56 |
@end verbatim |
|
57 |
||
58 |
@subsection Usage |
|
59 |
||
60 |
The file @code{examples/tcp-star-server.cc} contains an example that |
|
61 |
makes use of @code{ns3::OnOffApplication} and @code{ns3::PacketSink} |
|
62 |
applications. |
|
63 |
||
64 |
Using the helper functions defined in @code{src/helper}, here is how |
|
65 |
one would create a TCP receiver: |
|
66 |
@verbatim |
|
67 |
// Create a packet sink on the star "hub" to receive these packets |
|
68 |
uint16_t port = 50000; |
|
69 |
Address sinkLocalAddress(InetSocketAddress (Ipv4Address::GetAny (), port)); |
|
70 |
PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress); |
|
71 |
ApplicationContainer sinkApp = sinkHelper.Install (serverNode); |
|
72 |
sinkApp.Start (Seconds (1.0)); |
|
73 |
sinkApp.Stop (Seconds (10.0)); |
|
74 |
@end verbatim |
|
75 |
||
76 |
Similarly, the below snippet configures OnOffApplication traffic |
|
77 |
source to use |
|
78 |
TCP: |
|
79 |
@verbatim |
|
80 |
// Create the OnOff applications to send TCP to the server |
|
81 |
OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ()); |
|
82 |
@end verbatim |
|
83 |
||
84 |
The careful reader will note above that we have specified the TypeId |
|
85 |
of an abstract base class @code{TcpSocketFactory}. How does the |
|
86 |
script tell ns-3 that it wants the native ns-3 TCP vs. some other one? |
|
87 |
Well, when internet stacks are added to the node, the default |
|
88 |
TCP implementation that is aggregated to the node is the ns-3 TCP. |
|
89 |
This can be overridden as we show below when using Network |
|
90 |
Simulation Cradle. So, by default, when using the ns-3 helper API, |
|
91 |
the TCP that is aggregated to nodes with an Internet stack is the |
|
92 |
native ns-3 TCP. |
|
93 |
||
94 |
Once a TCP socket is created, you will want to follow conventional |
|
95 |
socket logic and either connect() and send() (for a TCP client) |
|
96 |
or bind(), listen(), and accept() (for a TCP server). |
|
97 |
@xref{Sockets APIs,,Sockets API} for a review of how sockets are used |
|
98 |
in ns-3. |
|
99 |
||
100 |
To configure behavior of TCP, a number of parameters are exported through |
|
101 |
the @ref{Attributes,,ns-3 attribute system}. These are documented in the |
|
102 |
@uref{http://www.nsnam.org/doxygen/classns3_1_1_tcp_socket.html,,Doxygen} |
|
103 |
for @code{class TcpSocket}. |
|
104 |
||
105 |
@subsection Current limitations |
|
106 |
@itemize @bullet |
|
107 |
@item Only Tahoe congestion control is presently supported. |
|
5434 | 108 |
@item Only IPv4 is supported (IPv6 support will start to be added after ns-3.6). |
3707 | 109 |
@end itemize |
110 |
||
111 |
@section Network Simulation Cradle |
|
112 |
||
113 |
The @uref{http://www.wand.net.nz/~stj2/nsc/,,Network Simulation Cradle (NSC)} |
|
114 |
is a framework for wrapping real-world network |
|
115 |
code into simulators, allowing simulation of real-world behavior at little |
|
116 |
extra cost. This work has been validated by comparing situations using |
|
117 |
a test network with the same situations in the simulator. To date, it has |
|
118 |
been shown that the NSC is able to produce extremely accurate results. |
|
119 |
NSC supports four real world stacks: FreeBSD, OpenBSD, lwIP and Linux. |
|
120 |
Emphasis has been placed on not changing any of the network stacks by hand. |
|
121 |
Not a single line of code has been changed in the network protocol |
|
122 |
implementations of any of the above four stacks. However, a custom C |
|
123 |
parser was built to programmatically change source code. |
|
124 |
||
125 |
NSC has previously been ported to ns-2 and OMNeT++, and recently |
|
126 |
was added to ns-3. This section describes the ns-3 port of NSC and |
|
127 |
how to use it. |
|
128 |
||
129 |
@subsection Prerequisites |
|
130 |
||
131 |
Presently, NSC has been tested and shown to work on these platforms: |
|
5434 | 132 |
Linux i386 and Linux x86-64. NSC does not support powerpc. |
3707 | 133 |
|
5434 | 134 |
Building NSC requires the packages flex and bison. |
3707 | 135 |
|
136 |
@subsection Configuring and Downloading |
|
137 |
||
5434 | 138 |
Using the @code{build.py} script in ns-3-allinone directory, NSC will be |
139 |
enabled by default unless the platform does not support it. To disable |
|
140 |
it when building ns-3, type: |
|
3707 | 141 |
@verbatim |
5434 | 142 |
./waf configure --disable-nsc |
3707 | 143 |
@end verbatim |
144 |
||
145 |
@subsection Building and validating |
|
146 |
||
147 |
Building ns-3 with nsc support is the same as building it without; no |
|
148 |
additional arguments are needed for waf. Building nsc may take some time |
|
149 |
compared to ns-3; it is interleaved in the ns-3 building process. |
|
150 |
||
151 |
Try running the regression tests: @code{./waf --regression}. If NSC has |
|
152 |
been successfully built, the following test should show up in the results: |
|
153 |
@verbatim |
|
154 |
PASS test-tcp-nsc-lfn |
|
155 |
@end verbatim |
|
156 |
||
157 |
This confirms that NSC is ready to use. |
|
158 |
||
159 |
@subsection Usage |
|
160 |
There are a few example files. Try |
|
161 |
@verbatim |
|
162 |
./waf --run tcp-nsc-zoo |
|
163 |
./waf --run tcp-nsc-lfn |
|
164 |
@end verbatim |
|
165 |
These examples will deposit some @code{.pcap} files in your directory, |
|
166 |
which can be examined by tcpdump or wireshark. |
|
167 |
||
168 |
Let's look at the @code{examples/tcp-nsc-zoo.cc} file for some typical |
|
169 |
usage. How does it differ from using native ns-3 TCP? There is one |
|
170 |
main configuration line, when using NSC and the ns-3 helper API, that needs |
|
171 |
to be set: |
|
172 |
@verbatim |
|
173 |
InternetStackHelper internetStack; |
|
174 |
||
175 |
internetStack.SetNscStack ("liblinux2.6.26.so"); |
|
176 |
// this switches nodes 0 and 1 to NSCs Linux 2.6.26 stack. |
|
177 |
internetStack.Install (n.Get(0)); |
|
178 |
internetStack.Install (n.Get(1)); |
|
179 |
@end verbatim |
|
180 |
||
181 |
The key line is the @code{SetNscStack}. This tells the InternetStack |
|
182 |
helper to aggregate instances of NSC TCP instead of native ns-3 TCP |
|
183 |
to the remaining nodes. It is important that this function be called |
|
4755
04a9a7e9a624
Manual spelling fixes from Johannes Buchner
Tom Henderson <tomh@tomh.org>
parents:
4411
diff
changeset
|
184 |
@strong{before} calling the @code{Install()} function, as shown above. |
3707 | 185 |
|
186 |
Which stacks are available to use? Presently, the focus has been on |
|
187 |
Linux 2.6.18 and Linux 2.6.26 stacks for ns-3. To see which stacks |
|
188 |
were built, one can execute the following find command at the ns-3 top level |
|
189 |
directory: |
|
190 |
@verbatim |
|
191 |
~/ns-3.2> find nsc -name "*.so" -type f |
|
192 |
nsc/linux-2.6.18/liblinux2.6.18.so |
|
193 |
nsc/linux-2.6.26/liblinux2.6.26.so |
|
194 |
@end verbatim |
|
195 |
This tells us that we may either pass the library name liblinux2.6.18.so or |
|
196 |
liblinux2.6.26.so to the above configuration step. |
|
197 |
||
198 |
@subsection Stack configuration |
|
199 |
NSC TCP shares the same configuration attributes that are common |
|
200 |
across TCP sockets, as described above and documented in |
|
201 |
@uref{http://www.nsnam.org/doxygen/classns3_1_1_tcp_socket.html,,Doxygen} |
|
202 |
||
203 |
Additionally, NSC TCP exports a lot of configuration variables into the |
|
204 |
ns-3 @ref{Attributes} system, via a @uref{http://en.wikipedia.org/wiki/Sysctl,, |
|
205 |
sysctl}-like interface. In the @code{examples/tcp-nsc-zoo} example, you |
|
206 |
can see the following configuration: |
|
5434 | 207 |
@smallformat |
208 |
@example |
|
209 |
// this disables TCP SACK, wscale and timestamps on node 1 (the attributes |
|
210 |
represent sysctl-values). |
|
211 |
Config::Set ("/NodeList/1/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_sack", |
|
212 |
StringValue ("0")); |
|
213 |
Config::Set ("/NodeList/1/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_timestamps", |
|
214 |
StringValue ("0")); |
|
215 |
Config::Set ("/NodeList/1/$ns3::Ns3NscStack<linux2.6.26>/net.ipv4.tcp_window_scaling", |
|
216 |
StringValue ("0")); |
|
217 |
@end example |
|
218 |
@end smallformat |
|
3707 | 219 |
These additional configuration variables are not available to native ns-3 |
220 |
TCP. |
|
221 |
||
222 |
@subsection NSC API |
|
223 |
||
224 |
This subsection describes the API that NSC presents to ns-3 or any other |
|
225 |
simulator. NSC provides its API in the form of a number of classes that |
|
226 |
are defined in @code{sim/sim_interface.h} in the nsc directory. |
|
227 |
||
228 |
@itemize @bullet |
|
229 |
@item @strong{INetStack} |
|
230 |
INetStack contains the 'low level' operations for the operating system |
|
231 |
network stack, e.g. in and output functions from and to the network stack |
|
232 |
(think of this as the 'network driver interface'. There are also functions |
|
233 |
to create new TCP or UDP sockets. |
|
234 |
@item @strong{ISendCallback} |
|
235 |
This is called by NSC when a packet should be sent out to the network. |
|
236 |
This simulator should use this callback to re-inject the packet into the |
|
237 |
simulator so the actual data can be delivered/routed to its destination, |
|
238 |
where it will eventually be handed into Receive() (and eventually back to the |
|
239 |
receivers NSC instance via INetStack->if_receive() ). |
|
240 |
@item @strong{INetStreamSocket} |
|
241 |
This is the structure defining a particular connection endpoint (file |
|
242 |
descriptor). It contains methods to operate on this endpoint, e.g. connect, |
|
243 |
disconnect, accept, listen, send_data/read_data, ... |
|
244 |
@item @strong{IInterruptCallback} |
|
245 |
This contains the wakeup callback, which is called by NSC whenever |
|
246 |
something of interest happens. Think of wakeup() as a replacement of the |
|
247 |
operating systems wakeup function: Whenever the operating system would |
|
248 |
wake up a process that has been waiting for an operation to complete (for |
|
249 |
example the TCP handshake during connect()), NSC invokes the wakeup() callback |
|
250 |
to allow the simulator to check for state changes in its connection endpoints. |
|
251 |
@end itemize |
|
252 |
||
253 |
@subsection ns-3 implementation |
|
254 |
||
255 |
The ns-3 implementation makes use of the above NSC API, and is implemented |
|
256 |
as follows. |
|
257 |
||
258 |
The three main parts are: |
|
259 |
@itemize @bullet |
|
260 |
@item @code{ns3::NscTcpL4Protocol}: a subclass of Ipv4L4Protocol (and two nsc classes: ISendCallback and IInterruptCallback) |
|
261 |
@item @code{ns3::NscTcpSocketImpl}: a subclass of TcpSocket |
|
262 |
@item @code{ns3::NscTcpSocketFactoryImpl}: a factory to create new NSC |
|
263 |
sockets |
|
264 |
@end itemize |
|
265 |
||
266 |
@code{src/internet-stack/nsc-tcp-l4-protocol} is the main class. Upon |
|
267 |
Initialization, it loads an nsc network stack to use (via dlopen()). Each |
|
268 |
instance of this class may use a different stack. The stack |
|
269 |
(=shared library) to use is set using the SetNscLibrary() method (at |
|
270 |
this time its called indirectly via the internet stack helper). The nsc |
|
271 |
stack is then set up accordingly (timers etc). The |
|
272 |
NscTcpL4Protocol::Receive() function hands the packet it receives (must be |
|
273 |
a complete tcp/ip packet) to the nsc stack for further processing. |
|
274 |
To be able to send packets, this class implements the nsc send_callback |
|
275 |
method. This method is called by nsc whenever the nsc stack wishes to |
|
276 |
send a packet out to the network. Its arguments are a raw buffer, |
|
277 |
containing a complete TCP/IP packet, and a length value. This method |
|
278 |
therefore has to convert the raw data to a Ptr<Packet> usable by ns-3. |
|
279 |
In order to avoid various ipv4 header issues, the nsc ip header is not |
|
280 |
included. Instead, the tcp header and the actual payload are put into the |
|
281 |
Ptr<Packet>, after this the Packet is passed down to layer 3 for sending |
|
282 |
the packet out (no further special treatment is needed in the send code |
|
283 |
path). |
|
284 |
||
285 |
This class calls @code{ns3::NscTcpSocketImpl} both from the nsc wakeup() |
|
286 |
callback and from the Receive path (to ensure that possibly queued data |
|
287 |
is scheduled for sending). |
|
288 |
||
289 |
||
290 |
@code{src/internet-stack/nsc-tcp-socket-impl} implements the nsc socket |
|
291 |
interface. Each instance has its own nscTcpSocket. Data that is Send() |
|
292 |
will be handed to the nsc stack via m_nscTcpSocket->send_data(). (and not |
|
293 |
to nsc-tcp-l4, this is the major difference compared to ns-3 TCP). The |
|
294 |
class also queues up data that is Send() before the underlying |
|
295 |
descriptor has entered an ESTABLISHED state. This class is called from |
|
296 |
the nsc-tcp-l4 class, when the nsc-tcp-l4 wakeup() callback is invoked by |
|
297 |
nsc. nsc-tcp-socket-impl then checks the current connection state |
|
298 |
(SYN_SENT, ESTABLISHED, LISTEN...) and schedules appropriate callbacks as |
|
299 |
needed, e.g. a LISTEN socket will schedule Accept to see if a new |
|
300 |
connection must be accepted, an ESTABLISHED socket schedules any pending |
|
301 |
data for writing, schedule a read callback, etc. |
|
302 |
||
303 |
Note that @code{ns3::NscTcpSocketImpl} does not interact with nsc-tcp |
|
304 |
directly: instead, data is redirected to nsc. nsc-tcp calls the |
|
305 |
nsc-tcp-sockets of a node when its wakeup callback is invoked by nsc. |
|
306 |
||
307 |
@subsection Limitations |
|
308 |
@itemize @bullet |
|
309 |
@item NSC only works on single-interface nodes; attempting to run it on |
|
310 |
a multi-interface node will cause a program error. This limitation should |
|
5434 | 311 |
be fixed by ns-3.7. |
312 |
@item Cygwin and OS X PPC are not supported |
|
313 |
@item The non-Linux stacks of NSC are not supported in ns-3 |
|
314 |
@item Not all socket API callbacks are supported |
|
3707 | 315 |
@end itemize |
316 |
||
317 |
For more information, see |
|
318 |
@uref{http://www.nsnam.org/wiki/index.php/Network_Simulation_Cradle_Integration,, this wiki page}. |