branch merge

This commit is contained in:
Tom Henderson
2008-05-25 08:05:26 -07:00
21 changed files with 2553 additions and 30 deletions

View File

@@ -2,13 +2,21 @@ TEXI2HTML = texi2html
TEXI2PDF = texi2dvi --pdf
EPSTOPDF = epstopdf
TGIF = tgif
DIA = dia
CONVERT = convert
CSS = --css-include=tutorial.css
SPLIT = --split section
TGIF_SOURCES = helpers.obj
DIA_SOURCES = buffer.dia pp.dia dumbbell.dia star.dia
TGIF_SOURCES = packet.obj helpers.obj
DIA_EPS = ${DIA_SOURCES:.dia=.eps}
DIA_PNG = ${DIA_SOURCES:.dia=.png}
DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
TGIF_PNG = ${TGIF_SOURCES:.obj=.eps}
TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
all: images html split-html pdf
@@ -17,8 +25,11 @@ all: images html split-html pdf
# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
# display
images:
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
cd figures/; $(DIA) -t png $(DIA_SOURCES)
cd figures/; $(DIA) -t eps $(DIA_SOURCES)
cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
html: images
@@ -30,5 +41,9 @@ split-html: images
pdf: images
$(TEXI2PDF) tutorial.texi
clean:
figures-clean:
cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
clean: figures-clean
rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,8 +1,17 @@
Please write image files in a vector graphics format, when possible, and
generate the .png and .pdf versions on the fly (see ../Makefile).
Recommended tools are dia, tgif, and xfig. Store the .dia, .obj, or .fig
versions in mercurial, but not the .png or .pdfs.
Currently supported tools are dia and tgif. xfig could be added similarly
if someone wants to add it. The main requirement for adding another format
is that the tool to edit it is freely available and that a cron script can
autogenerate the pdf and png from the figure source.
Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs.
If the figure is not available in a vector graphics format, store both
a .png and a .pdf version in this directory.
If you add a source (.dia, .obj) file here, remember to add it to
the list of figure sources in the Makefile in the directory above
Note: tgif can convert from .obj to .pdf, but the pdf that results takes
up a whole page. Instead, we convert to an intermediate .eps step, and

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,227 @@
%TGIF 4.1.43-QPL
state(0,37,100.000,0,64,0,32,0,9,1,1,1,0,0,0,1,0,'Courier-Bold',1,103680,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
%
% @(#)$Header$
% %W%
%
unit("1 pixel/pixel").
color_info(11,65535,0,[
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
"red", 65535, 0, 0, 65535, 0, 0, 1,
"green", 0, 65535, 0, 0, 65535, 0, 1,
"blue", 0, 0, 65535, 0, 0, 65535, 1,
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
"black", 0, 0, 0, 0, 0, 0, 1,
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
]).
script_frac("0.6").
fg_bg_colors('black','white').
dont_reencode("FFDingbests:ZapfDingbats").
page(1,"",1,'').
box('black','',32,48,240,256,0,3,1,0,0,0,0,0,0,'3',0,[
]).
text('black',64,10,1,0,1,121,28,3,22,6,0,0,0,0,2,121,28,0,0,"",0,0,0,0,32,'',[
minilines(121,28,0,0,0,0,0,[
mini_line(121,22,6,0,0,0,[
str_block(0,121,22,6,0,0,0,0,0,[
str_seg('black','Times-Roman',0,138240,121,22,6,0,0,0,0,0,0,0,
"class Packet")])
])
])]).
text('black',416,100,1,0,1,116,28,15,22,6,0,0,0,0,2,116,28,0,0,"",0,0,0,0,122,'',[
minilines(116,28,0,0,0,0,0,[
mini_line(116,22,6,0,0,0,[
str_block(0,116,22,6,0,0,0,0,0,[
str_seg('black','Times-Roman',0,138240,116,22,6,0,0,0,0,0,0,0,
"class Buffer")])
])
])]).
text('black',48,178,4,0,1,83,69,32,14,4,0,0,0,0,2,83,69,0,0,"",0,0,0,0,192,'',[
minilines(83,69,0,0,0,0,0,[
mini_line(80,14,4,0,0,0,[
str_block(0,80,14,4,0,-1,0,0,0,[
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
"private data:")])
]),
mini_line(59,14,3,0,0,0,[
str_block(0,59,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,59,14,3,0,0,0,0,0,0,0,
"- unique id")])
]),
mini_line(83,14,3,0,0,0,[
str_block(0,83,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,83,14,3,0,0,0,0,0,0,0,
"- Buffer object")])
]),
mini_line(76,14,3,0,0,0,[
str_block(0,76,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,76,14,3,0,0,0,0,0,0,0,
"- Tags object")])
])
])]).
text('black',112,288,1,0,1,103,28,82,22,6,0,0,0,0,2,103,28,0,0,"",0,0,0,0,310,'',[
minilines(103,28,0,0,0,0,0,[
mini_line(103,22,6,0,0,0,[
str_block(0,103,22,6,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,138240,103,22,6,0,-1,0,0,0,0,0,
"class Tags")])
])
])]).
text('black',48,50,5,0,1,175,86,176,14,4,0,0,0,0,2,175,86,0,0,"",0,0,0,0,64,'',[
minilines(175,86,0,0,0,0,0,[
mini_line(105,14,4,0,0,0,[
str_block(0,105,14,4,0,-1,0,0,0,[
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
"public functions:")])
]),
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
"- constructors")])
]),
mini_line(175,14,3,0,0,0,[
str_block(0,175,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0,
"- add/remove/peek at Headers")])
]),
mini_line(155,14,3,0,0,0,[
str_block(0,155,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
"- add/remove/peek at Tags")])
]),
mini_line(88,14,3,0,0,0,[
str_block(0,88,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0,
"- fragmentation")])
])
])]).
box('black','',384,144,614,352,0,3,1,245,0,0,0,0,0,'3',0,[
]).
text('black',400,274,4,0,1,204,69,246,14,4,0,0,0,0,2,204,69,0,0,"",0,0,0,0,288,'',[
minilines(204,69,0,0,0,0,0,[
mini_line(80,14,4,0,0,0,[
str_block(0,80,14,4,0,-1,0,0,0,[
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
"private data:")])
]),
mini_line(193,14,3,0,0,0,[
str_block(0,193,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,193,14,3,0,0,0,0,0,0,0,
"- struct BufferData, a dynamically")])
]),
mini_line(160,14,3,0,0,0,[
str_block(0,160,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,160,14,3,0,0,0,0,0,0,0,
"varying byte buffer to which")])
]),
mini_line(204,14,3,0,0,0,[
str_block(0,204,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,204,14,3,0,0,0,0,0,0,0,
"data can be prepended or appended")])
])
])]).
text('black',400,146,5,0,1,188,86,247,14,4,0,0,0,0,2,188,86,0,0,"",0,0,0,0,160,'',[
minilines(188,86,0,0,0,0,0,[
mini_line(105,14,4,0,0,0,[
str_block(0,105,14,4,0,-1,0,0,0,[
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
"public functions:")])
]),
mini_line(172,14,3,0,0,0,[
str_block(0,172,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,172,14,3,0,0,0,0,0,0,0,
"- Iterators to move byte buffer")])
]),
mini_line(171,14,3,0,0,0,[
str_block(0,171,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,171,14,3,0,0,0,0,0,0,0,
"pointers forward or backward")])
]),
mini_line(188,14,3,0,0,0,[
str_block(0,188,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,188,14,3,0,0,0,0,0,0,0,
"- functions to read and write data")])
]),
mini_line(132,14,3,0,0,0,[
str_block(0,132,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,132,14,3,0,-1,0,0,0,0,0,
"of various sized chunks")])
])
])]).
box('black','',96,324,304,532,0,3,1,264,0,0,0,0,0,'3',0,[
]).
text('black',112,454,4,0,1,167,69,265,14,4,0,0,0,0,2,167,69,0,0,"",0,0,0,0,468,'',[
minilines(167,69,0,0,0,0,0,[
mini_line(80,14,4,0,0,0,[
str_block(0,80,14,4,0,-1,0,0,0,[
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
"private data:")])
]),
mini_line(167,14,3,0,0,0,[
str_block(0,167,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,167,14,3,0,0,0,0,0,0,0,
"- singly linked-list of TagData")])
]),
mini_line(158,14,3,0,0,0,[
str_block(0,158,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,158,14,3,0,0,0,0,0,0,0,
"structures, with a reference")])
]),
mini_line(32,14,3,0,0,0,[
str_block(0,32,14,3,0,0,0,0,0,[
str_seg('black','Times-Roman',0,80640,32,14,3,0,0,0,0,0,0,0,
"count")])
])
])]).
text('black',112,326,5,0,1,155,86,266,14,4,0,0,0,0,2,155,86,0,0,"",0,0,0,0,340,'',[
minilines(155,86,0,0,0,0,0,[
mini_line(105,14,4,0,0,0,[
str_block(0,105,14,4,0,-1,0,0,0,[
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
"public functions:")])
]),
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
"- constructors")])
]),
mini_line(155,14,3,0,0,0,[
str_block(0,155,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
"- templates to add, remove,")])
]),
mini_line(148,14,3,0,0,0,[
str_block(0,148,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0,
"or peek at Tags of various")])
]),
mini_line(31,14,3,0,0,0,[
str_block(0,31,14,3,0,-1,0,0,0,[
str_seg('black','Times-Roman',0,80640,31,14,3,0,-1,0,0,0,0,0,
"types")])
])
])]).
poly('black','',2,[
59,245,96,320],0,2,1,272,0,0,3,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',2,[
123,246,288,320],0,2,1,280,0,0,3,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',2,[
141,219,379,147],0,2,1,286,0,0,3,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',2,[
132,226,375,335],0,2,1,287,0,0,3,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).

BIN
doc/tutorial/figures/pp.dia Normal file

Binary file not shown.

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -34,7 +34,7 @@ see this point-to-point network, you can think of an RS-422 (or RS-232 for
you old-timers) cable. This topology is shown below.
@sp 1
@center @image{pp,,,,png}
@center @image{figures/pp,,,,png}
@cindex CreateObject
@cindex InternetNode
@@ -173,7 +173,7 @@ a file for you in the @code{tutorial} directory called @code{tutorial-star.cc}
that implements a simple star network as seen below.
@sp 1
@center @image{star,,,,png}
@center @image{figures/star,,,,png}
In order to create a star network, we need to be able to instantiate some
number (greater than one) of net devices on a node. In the name of simplicity
@@ -506,7 +506,7 @@ configured with a lower bandwidth than the bus elements to provide a
The following is a representation of the topology.
@sp 1
@center @image{dumbbell,,,,png}
@center @image{figures/dumbbell,,,,png}
We have provided a file that constructs this dumbbell network and creates
enough data flowing across the choke point that some packets will be dropped.

620
doc/tutorial/packets.texi Normal file
View File

@@ -0,0 +1,620 @@
@node ns-3 Packets
@chapter ns-3 Packets
The design of the Packet framework of @emph{ns} was heavily guided by a few
important use-cases:
@itemize @bullet
@item avoid changing the core of the simulator to introduce
new types of packet headers or trailers
@item maximize the ease of integration with real-world code
and systems
@item make it easy to support fragmentation, defragmentation,
and, concatenation which are important, especially in wireless systems.
@item make memory management of this object efficient
@item allow actual application data or dummy application bytes for
emulated applications
@end itemize
@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
trailers are serialized in this buffer of bytes using user-provided
serialization and deserialization routines. The content of this byte
buffer is expected to match bit-for-bit the content of a real packet on
a real network implementing the protocol of interest.
Fragmentation and defragmentation are quite natural to implement within
this context: since we have a buffer of real bytes, we can split it in
multiple fragments and re-assemble these fragments. We expect that this
choice will make it really easy to wrap our Packet data structure within
Linux-style skb or BSD-style mbuf to integrate real-world kernel code in
the simulator. We also expect that performing a real-time plug of the
simulator to a real-world network will be easy.
Because we understand that simulation developers often wish to store in
packet objects data which is not found in the real packets (such as
timestamps or any kind of similar in-band data), the @emph{ns} Packet class
can also store extra per-packet "Tags" which are 16 bytes blobs of data.
Any Packet can store any number of unique Tags, each of which is
uniquely identified by its C++ type. These tags make it easy to attach
per-model data to a packet without having to patch the main Packet
class or Packet facilities.
Memory management of Packet objects is entirely automatic and extremely
efficient: memory for the application-level payload can be modelized by
a virtual buffer of zero-filled bytes for which memory is never allocated
unless explicitely requested by the user or unless the packet is fragmented.
Furthermore, copying, adding, and, removing headers or trailers to a packet
has been optimized to be virtually free through a technique known as
Copy On Write.
Packets (messages) are fundamental objects in the simulator and
their design is important from a performance and resource management
perspective. There
are various ways to design the simulation packet, and tradeoffs
among the different approaches. In particular, there is a
tension between ease-of-use, performance, and safe interface
design.
There are a few requirements on this object design:
@itemize @bullet
@item Creation, management, and deletion of this object
should be as simple as possible, while avoiding the
chance for memory leaks and/or heap corruption;
@item Packets should support serialization and deserialization
so that network emulation is supported;
@item Packets should support fragmentation and concatenation
(multiple packets in a data link frame), especially for wireless
support;
@item It should be natural for packets to carry actual application
data, or if there is only an emulated application and there is
no need to carry dummy bytes, smaller packets could be used with
just the headers and a record of the payload size, but not actual
application bytes, conveyed in the simulated packet.
@item Packets should facilitate BSD-like operations on mbufs, for
support of ported operating system stacks.
@item Additional side-information should be supported, such as
a tag for cross-layer information.
@end itemize
@section Packet design overview
Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
structures corresponding to protocol headers, each network packet in
@emph{ns-3} contains a byte Buffer and a list of Tags:
@itemize @bullet
@item The byte buffer stores the serialized content of the chunks
added to a packet. The serialized representation of these chunks is
expected to match that of real network packets bit for bit
(although nothing forces you to do this) which means that the content
of a packet buffer is expected to be that of a real packet.
Packets can also be created with an arbitrary zero-filled payload
for which no real memory is allocated.
@item The list of tags stores an arbitrarily large set of arbitrary
user-provided data structures in the packet. Each Tag is uniquely
identified by its type; only one instance of each
type of data structure is allowed in a list of tags. These tags typically
contain per-packet cross-layer information or flow identifiers (i.e.,
things that you wouldn't find in the bits on the wire). Each tag
stored in the tag list can be at most 16 bytes.
Trying to attach bigger data structures will trigger
crashes at runtime. The 16 byte limit is a modifiable compilation
constant.
@end itemize
@float Figure,fig:packets
@caption{Implementation overview of Packet class.}
@image{figures/packet}
@end float
Figure @ref{fig:packets} is a high-level overview of the Packet
implementation; more detail on the byte Buffer implementation
is provided later in Figure @ref{fig:buffer}.
In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
or BSD mbuf; it is a serialized representation of the actual
data in the packet. The tag list is a container for extra
items useful for simulation convenience; if a Packet is converted
to an emulated packet and put over an actual network, the tags
are stripped off and the byte buffer is copied directly
into a real packet.
The Packet class has value semantics: it can be freely copied around,
allocated on the stack, and passed to functions as arguments. Whenever
an instance is copied, the full underlying data is not copied; it
has ``copy-on-write'' (COW) semantics. Packet instances can be passed
by value to function arguments without any performance hit.
The fundamental classes for adding to and removing from the byte
buffer are @code{class Header} and @code{class Trailer}.
Headers are more common but the below discussion also largely applies to
protocols using trailers. Every protocol header that needs to
be inserted and removed from a Packet instance should derive from
the abstract Header base class and implement the private pure
virtual methods listed below:
@itemize @bullet
@item @code{ns3::Header::SerializeTo()}
@item @code{ns3::Header::DeserializeFrom()}
@item @code{ns3::Header::GetSerializedSize()}
@item @code{ns3::Header::PrintTo()}
@end itemize
Basically, the first three functions are used to serialize and deserialize
protocol control information to/from a Buffer. For example,
one may define @code{class TCPHeader : public Header}. The
TCPHeader object will typically consist of some private data
(like a sequence number) and public interface access functions
(such as checking the bounds of an input). But the underlying
representation of the TCPHeader in a Packet Buffer is 20 serialized
bytes (plus TCP options). The TCPHeader::SerializeTo() function would
therefore be designed to write these 20 bytes properly into
the packet, in network byte order. The last function is used
to define how the Header object prints itself onto an output stream.
Similarly, user-defined Tags can be appended to the packet.
Unlike Headers, Tags are not serialized into a contiguous buffer
but are stored in an array. By default, Tags are limited to 16 bytes in
size. Tags can be flexibly defined to be any type, but there
can only be one instance of any particular object type in
the Tags buffer at any time. The implementation makes use
of templates to generate the proper set of Add(), Remove(),
and Peek() functions for each Tag type.
@section Packet interface
The public member functions of a Packet object are as follows:
@subsection Constructors
@verbatim
/**
* Create an empty packet with a new uid (as returned
* by getUid).
*/
Packet ();
/**
* Create a packet with a zero-filled payload.
* The memory necessary for the payload is not allocated:
* it will be allocated at any later point if you attempt
* to fragment this packet or to access the zero-filled
* bytes. The packet is allocated with a new uid (as
* returned by getUid).
*
* \param size the size of the zero-filled payload
*/
Packet (uint32_t size);
@end verbatim
@subsection Adding and removing Buffer data
The below code is reproduced for Header class only; similar functions
exist for Trailers.
@verbatim
/**
* Add header to this packet. This method invokes the
* ns3::Header::serializeTo method to request the header to serialize
* itself in the packet buffer.
*
* \param header a reference to the header to add to this packet.
*/
void Add (Header const &header);
/**
* Deserialize header from this packet. This method invokes the
* ns3::Header::deserializeFrom method to request the header to deserialize
* itself from the packet buffer. This method does not remove
* the data from the buffer. It merely reads it.
*
* \param header a reference to the header to deserialize from the buffer
*/
void Peek (Header &header);
/**
* Remove a deserialized header from the internal buffer.
* This method removes the bytes read by Packet::peek from
* the packet buffer.
*
* \param header a reference to the header to remove from the internal buffer.
*/
void Remove (Header const &header);
/**
* Add trailer to this packet. This method invokes the
* ns3::Trailer::serializeTo method to request the trailer to serialize
* itself in the packet buffer.
*
* \param trailer a reference to the trailer to add to this packet.
*/
@end verbatim
@subsection Adding and removing Tags
@verbatim
/**
* Attach a tag to this packet. The tag is fully copied
* in a packet-specific internal buffer. This operation
* is expected to be really fast.
*
* \param tag a pointer to the tag to attach to this packet.
*/
template <typename T>
void AddTag (T const &tag);
/**
* Remove a tag from this packet. The data stored internally
* for this tag is copied in the input tag if an instance
* of this tag type is present in the internal buffer. If this
* tag type is not present, the input tag is not modified.
*
* This operation can be potentially slow and might trigger
* unexpectedly large memory allocations. It is thus
* usually a better idea to create a copy of this packet,
* and invoke removeAllTags on the copy to remove all
* tags rather than remove the tags one by one from a packet.
*
* \param tag a pointer to the tag to remove from this packet
* \returns true if an instance of this tag type is stored
* in this packet, false otherwise.
*/
template <typename T>
bool RemoveTag (T &tag);
/**
* Copy a tag stored internally to the input tag. If no instance
* of this tag is present internally, the input tag is not modified.
*
* \param tag a pointer to the tag to read from this packet
* \returns true if an instance of this tag type is stored
* in this packet, false otherwise.
*/
template <typename T>
bool PeekTag (T &tag) const;
/**
* Remove all the tags stored in this packet. This operation is
* much much faster than invoking removeTag n times.
*/
void RemoveAllTags (void);
@end verbatim
@subsection Fragmentation
@verbatim
/**
* Create a new packet which contains a fragment of the original
* packet. The returned packet shares the same uid as this packet.
*
* \param start offset from start of packet to start of fragment to create
* \param length length of fragment to create
* \returns a fragment of the original packet
*/
Packet CreateFragment (uint32_t start, uint32_t length) const;
/**
* Concatenate the input packet at the end of the current
* packet. This does not alter the uid of either packet.
*
* \param packet packet to concatenate
*/
void addAtEnd (Packet packet);
/oncatenate the input packet at the end of the current
* packet. This does not alter the uid of either packet.
*
* \param packet packet to concatenate
*/
void AddAtEnd (Packet packet);
/**
* Concatenate the fragment of the input packet identified
* by the offset and size parameters at the end of the current
* packet. This does not alter the uid of either packet.
*
* \param packet to concatenate
* \param offset offset of fragment to copy from the start of the input packet
* \param size size of fragment of input packet to copy.
*/
void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
/**
* Remove size bytes from the end of the current packet
* It is safe to remove more bytes that what is present in
* the packet.
*
* \param size number of bytes from remove
*/
void RemoveAtEnd (uint32_t size);
/**
* Remove size bytes from the start of the current packet.
* It is safe to remove more bytes that what is present in
* the packet.
*
* \param size number of bytes from remove
*/
void RemoveAtStart (uint32_t size);
@end verbatim
@subsection Miscellaneous
@verbatim
/**
* \returns the size in bytes of the packet (including the zero-filled
* initial payload)
*/
uint32_t GetSize (void) const;
/**
* If you try to change the content of the buffer
* returned by this method, you will die.
*
* \returns a pointer to the internal buffer of the packet.
*/
uint8_t const *PeekData (void) const;
/**
* A packet is allocated a new uid when it is created
* empty or with zero-filled payload.
*
* \returns an integer identifier which uniquely
* identifies this packet.
*/
uint32_t GetUid (void) const;
@end verbatim
@section Using Headers
@emph{walk through an example of adding a UDP header}
@section Using Tags
@emph{walk through an example of adding a flow ID}
@section Using Fragmentation
@emph{walk through an example of link-layer fragmentation/reassembly}
@section Sample program
The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
some use of the Packet, Header, and Tag classes.
@verbatim
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
#include "ns3/packet.h"
#include "ns3/header.h"
#include <iostream>
using namespace ns3;
/* A sample Header implementation
*/
class MyHeader : public Header {
public:
MyHeader ();
virtual ~MyHeader ();
void SetData (uint16_t data);
uint16_t GetData (void) const;
private:
virtual void PrintTo (std::ostream &os) const;
virtual void SerializeTo (Buffer::Iterator start) const;
virtual void DeserializeFrom (Buffer::Iterator start);
virtual uint32_t GetSerializedSize (void) const;
uint16_t m_data;
};
MyHeader::MyHeader ()
{}
MyHeader::~MyHeader ()
{}
void
MyHeader::PrintTo (std::ostream &os) const
{
os << "MyHeader data=" << m_data << std::endl;
}
uint32_t
MyHeader::GetSerializedSize (void) const
{
return 2;
}
void
MyHeader::SerializeTo (Buffer::Iterator start) const
{
// serialize in head of buffer
start.WriteHtonU16 (m_data);
}
void
MyHeader::DeserializeFrom (Buffer::Iterator start)
{
// deserialize from head of buffer
m_data = start.ReadNtohU16 ();
}
void
MyHeader::SetData (uint16_t data)
{
m_data = data;
}
uint16_t
MyHeader::GetData (void) const
{
return m_data;
}
/* A sample Tag implementation
*/
struct MyTag {
uint16_t m_streamId;
};
static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
static void
Receive (Packet p)
{
MyHeader my;
p.Peek (my);
p.Remove (my);
std::cout << "received data=" << my.GetData () << std::endl;
struct MyTag myTag;
p.PeekTag (myTag);
}
int main (int argc, char *argv[])
{
Packet p;
MyHeader my;
my.SetData (2);
std::cout << "send data=2" << std::endl;
p.Add (my);
struct MyTag myTag;
myTag.m_streamId = 5;
p.AddTag (myTag);
Receive (p);
return 0;
}
@end verbatim
@section Implementation details
@subsection Private member variables
A Packet object's interface provides access to some private
data:
@verbatim
Buffer m_buffer;
Tags m_tags;
uint32_t m_uid;
static uint32_t m_global_uid;
@end verbatim
Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
A static member variable keeps track of the UIDs allocated. Note
that real network packets do not have a UID; the UID is therefore an
instance of data that normally would be stored as a Tag in the packet.
However, it was felt that a UID is a special case that is so often
used in simulations that it would be more convenient to store it
in a member variable.
@subsection Buffer implementation
Class Buffer represents a buffer of bytes. Its size is
automatically adjusted to hold any data prepended
or appended by the user. Its implementation is optimized
to ensure that the number of buffer resizes is minimized,
by creating new Buffers of the maximum size ever used.
The correct maximum size is learned at runtime during use by
recording the maximum size of each packet.
Authors of new Header or Trailer classes need to know the public
API of the Buffer class. (add summary here)
The byte buffer is implemented as follows:
@verbatim
struct BufferData {
uint32_t m_count;
uint32_t m_size;
uint32_t m_initialStart;
uint32_t m_dirtyStart;
uint32_t m_dirtySize;
uint8_t m_data[1];
};
struct BufferData *m_data;
uint32_t m_zeroAreaSize;
uint32_t m_start;
uint32_t m_size;
@end verbatim
@itemize @bullet
@item @code{BufferData::m_count}: reference count for BufferData structure
@item @code{BufferData::m_size}: size of data buffer stored in BufferData structure
@item @code{BufferData::m_initialStart}: offset from start of data buffer where data was first inserted
@item @code{BufferData::m_dirtyStart}: offset from start of buffer where every Buffer which holds a reference to this BufferData instance have written data so far
@item @code{BufferData::m_dirtySize}: size of area where data has been written so far
@item @code{BufferData::m_data}: pointer to data buffer
@item @code{Buffer::m_zeroAreaSize}: size of zero area which extends before @code{m_initialStart}
@item @code{Buffer::m_start}: offset from start of buffer to area used by this buffer
@item @code{Buffer::m_size}: size of area used by this Buffer in its BufferData structure
@end itemize
@float Figure,fig:buffer
@caption{Implementation overview of a packet's byte Buffer.}
@image{figures/buffer,15cm}
@end float
This data structure is summarized in Figure @ref{fig:buffer}.
Each Buffer holds a pointer to an instance of a BufferData. Most
Buffers should be able to share the same underlying BufferData and
thus simply increase the BufferData's reference count. If they have to
change the content of a BufferData inside the Dirty Area, and if the
reference count is not one, they first create a copy of the BufferData and
then complete their state-changing operation.
@subsection Tags implementation
Tags are implemented by a single pointer which points to the start of a
linked list ofTagData data structures. Each TagData structure points
to the next TagData in the list (its next pointer contains zero to
indicate the end of the linked list). Each TagData contains an integer
unique id which identifies the type of the tag stored in the TagData.
@verbatim
struct TagData {
struct TagData *m_next;
uint32_t m_id;
uint32_t m_count;
uint8_t m_data[Tags::SIZE];
};
class Tags {
struct TagData *m_next;
};
@end verbatim
Adding a tag is a matter of inserting a new TagData at the head of
the linked list. Looking at a tag requires you to find the relevant
TagData in the linked list and copy its data into the user data
structure. Removing a tag and updating the content of a tag
requires a deep copy of the linked list before performing this operation.
On the other hand, copying a Packet and its tags is a matter of
copying the TagData head pointer and incrementing its reference count.
Tags are found by the unique mapping betweent the Tag type and
its underlying id. This is why at most one instance of any Tag
can be stored in a packet. The mapping between Tag type and
underlying id is performed by a registration as follows:
@verbatim
/* A sample Tag implementation
*/
struct MyTag {
uint16_t m_streamId;
};
@end verbatim
@emph{add description of TagRegistration for printing}
@subsection Memory management
@emph{Describe free list.}
@emph{Describe dataless vs. data-full packets.}
@subsection Copy-on-write semantics
The current implementation of the byte buffers and tag list is based
on COW (Copy On Write). An introduction to COW can be found in Scott
Meyer's "More Effective C++", items 17 and 29). This design feature
and aspects of the public interface borrows from the packet design
of the Georgia Tech Network Simulator.
This implementation of COW uses a customized reference counting
smart pointer class.
What COW means is that
copying packets without modifying them is very cheap (in terms of CPU
and memory usage) and modifying them can be also very cheap. What is
key for proper COW implementations is being
able to detect when a given modification of the state of a packet triggers
a full copy of the data prior to the modification: COW systems need
to detect when an operation is ``dirty'' and must therefore invoke
a true copy.
Dirty operations:
@itemize @bullet
@item Packet::RemoveTag()
@item Packet::Add()
@item both versions of ns3::Packet::AddAtEnd()
@end itemize
Non-dirty operations:
@itemize @bullet
@item Packet::AddTag()
@item Packet::RemoveAllTags()
@item Packet::PeekTag()
@item Packet::Peek()
@item Packet::Remove()
@item Packet::CreateFragment()
@item Packet::RemoveAtStart()
@item Packet::RemoveAtEnd()
@end itemize
Dirty operations will always be slower than non-dirty operations,
sometimes by several orders of magnitude. However, even the
dirty operations have been optimized for common use-cases which
means that most of the time, these operations will not trigger
data copies and will thus be still very fast.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -93,7 +93,9 @@ Part 3: Reconfiguring Existing ns-3 Scripts
Part 4: Creating New or Revised Topologies
* Helper Functions::
* Other-network-topologies::
Part 5: Extending ns-3
Part 5: Key ns-3 objects and systems
* ns-3 Packets::
Part 6: Extending ns-3
* ns-3 Callbacks::
* ns-3 routing overview::
* Nonlinear-Thinking::
@@ -111,8 +113,9 @@ Part 5: Extending ns-3
@include attributes.texi
@include statistics.texi
@include helpers.texi
@include packets.texi
@include callbacks.texi
@include output.texi
@c @include output.texi
@include routing.texi
@c @include other.texi
@include troubleshoot.texi

View File

@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* Copyright (c) 2007, 2008 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,8 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washington.edu>
*/
#include "point-to-point-channel.h"

View File

@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005,2006 INRIA
* Copyright (c) 2007, 2008 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,9 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washington.edu>
* Revised: George Riley <riley@ece.gatech.edu>
*/
#include "ns3/log.h"
@@ -389,5 +386,4 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
m_rxCallback = cb;
}
} // namespace ns3

View File

@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 University of Washington
* Copyright (c) 2007, 2008 University of Washington
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,8 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Craig Dowell <craigdo@ee.washington.edu>
*/
#ifndef POINT_TO_POINT_NET_DEVICE_H

View File

@@ -1,11 +1,45 @@
/**
* \ingroup devices
* \defgroup PointToPoint Point-to-Point Models
* \defgroup PointToPoint Point-to-Point Model
*
* \section Point-to-Point Models
* \section Point-to-Point Model
*
* The set of Point-to-Point models provides an abstrated point-to-point link
* model, that simulates transmission delay (finite data rate) and
* propagation delay, and can also optionally include an error model
* (ns3::ErrorModel).
* The ns-3 point-to-point model is of a very simple point to point data link
* connecting exactly two ns3::PointToPointNetDevice devices over an
* ns3::PointToPointChannel. This can be viewed as equivalent to a full
* duplex RS-232 or RS-422 link with null modem and no handshaking.
*
* Data is encapsulated in the Point-to-Point Protocol (PPP -- RFC 1661),
* however the Link Control Protocol (LCP) and associated state machine is
* not implemented. The PPP link is assumed to be established and
* authenticated at all times.
*
* Data is not framed, therefore Address and Control fields will not be found.
* Since the data is not framed, there is no need to provide Flag Sequence and
* Control Escape octets, nor is a Frame Check Sequence appended. All that is
* required to implement non-framed PPP is to prepend the PPP protocol number
* for IP Version 4 which is the sixteen-bit number 0x21 (see
* http://www.iana.org/assignments/ppp-numbers).
*
* The ns3::PointToPointNetDevice provides following Attributes:
*
* - Address: The ns3::Mac48Address of the device (if desired);
* - DataRate: The data rate of the device;
* - TxQueue: The trasmit queue used by the device;
* - InterframeGap: The optional time to wait between "frames";
* - Rx: A trace source for received packets;
* - Drop: A trace source for dropped packets.
*
* The ns3::PointToPointNetDevice supports the assignment of a "receive error
* model." This is an ns3::ErrorModel object that is used to simulate data
* corruption on the link.
*
* The point to point net devices are connected via an
* ns3::PointToPointChannel. This channel models two wires transmitting bits
* at the data rate specified by the source net device. There is no overhead
* beyond the eight bits per byte of the packet sent. That is, we do not
* model Flag Sequences, Frame Check Sequences nor do we "escape" any data.
*
* The ns3::PointToPointChannel does model a speed-of-light delay which can
* be accessed via the attribute "Delay."
*/

View File

@@ -55,7 +55,7 @@ PppHeader::GetInstanceTypeId (void) const
void
PppHeader::Print (std::ostream &os) const
{
os << "Point-to-Point Protocol: IP (0x0021)" << std::endl;
os << "Point-to-Point Protocol: IP (0x0021)";
}
uint32_t

View File

@@ -1275,7 +1275,7 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
// the local side of the point-to-point links found on the node described by
// the vertex <v>.
//
for (uint32_t j = 0; j < nLinkRecords; j += 2)
for (uint32_t j = 0; j < nLinkRecords; ++j)
{
//
// We are only concerned about point-to-point links