Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
senf
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
wiback
senf
Commits
0fd7c329
Commit
0fd7c329
authored
16 years ago
by
g0dil
Browse files
Options
Downloads
Patches
Plain Diff
Packets: More annotation documentation
parent
c97c06ad
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
Packets/Mainpage.dox
+71
-0
71 additions, 0 deletions
Packets/Mainpage.dox
Packets/Packet.hh
+10
-0
10 additions, 0 deletions
Packets/Packet.hh
senf.dict
+3
-0
3 additions, 0 deletions
senf.dict
with
84 additions
and
0 deletions
Packets/Mainpage.dox
+
71
−
0
View file @
0fd7c329
...
...
@@ -660,6 +660,77 @@
to define variants in a different way giving other names to the special members (\c has_\e
name or \c init_\e name etc.). This must be documented with the composite or protocol parser
which defines the variant.
\section packet_usage_annotation Annotations
Sometimes we need to store additional data with a packet. Data, which is not part of the packet
itself but gives us some information about the packet: A timestamp, the interface the packet was
received on or other processing related information.
This type of information can be stored using the annotation interface.
\code
struct Timestamp {
senf::ClockService::clock_t value;
};
senf::EthernetPacket packet (senf::EthernetPacket::create(senf::noinit));
sock.read(packet.data(), 0u);
packet.annotation<Timestamp>().value = senf::ClockService::now();
\endcode
In the same way, the annotation can be used later
\code
if (senf::ClockService::now() - packet.annotation<Timestamp>().value
> senf::ClockService::seconds(1)) {
// Ouch ... this packet is to old
// ...
}
\endcode
It is very important to define a specific structure (or class) type for each type of
annotation. \e Never directly store a fundamental type as an annotation: The name of the type is
used to look up the annotation, so you can store only one annotation for each built-in type. \c
typedef does not help since \c typedef does not introduce new type names, it only defines an
alias.
Of course, the annotation structure can be arbitrary. However, one very important caveat: If the
annotation is not a POD type, it needs to inherit from senf::ComplexAnnotation. A type is POD,
if it is really just a bunch of bytes: No (non-static) members, no constructor or destructor and
no base classes and all it's members must be POD too. So the following annotation is complex
since \c std::string is not POD
\code
struct ReadInfo : senf::ComplexAnnotation
{
std::string interface;
senf::ClockService::clock_t timestamp;
};
// ...
packet.annotation<ReadInfo>().interface = "eth0";
packet.annotation<ReadInfo>().timestamp = senf::ClockService::now();
// Or store a reference to the annotation for easier access
ReadInfo & info (packet.annotation<ReadInfo>());
if (info.interface == "eth0") {
// ...
}
\endcode
You should use annotations economically: Every annotation type used in your program will
allocate an annotation slot in \e all packet data structures. So don't use hundreds of different
annotation types if this is not really necessary: Reuse annotation types where possible or
aggregate data into larger annotation structures. The best solution is to use annotations only
for a small number of packet specific informations. If you really need to manage a train-load of
data together with the packet consider some other way (e.g. place the packet into another class
which holds that data).
\see senf::Packet::annotation()
*/
/** \page packet_new Defining new Packet types
...
...
This diff is collapsed.
Click to expand it.
Packets/Packet.hh
+
10
−
0
View file @
0fd7c329
...
...
@@ -358,6 +358,16 @@ namespace senf {
used). Additionally, non-complex small annotations
require no additional memory management (\c new /
\c delete).
\idea Pool the annotation vectors: In the destructor
swap the vector into a vector graveyard (swapping
two vectors is an O(1) no allocation operation). In
the constructor, if there is a vector in the
graveyard, swap it in from there. Of course, it
would be better to do away with the vector and just
allocate the space together with the packet but
that looks quite complicated to do ... especially
considering that the packetimpl itself uses a pool.
*/
///@}
...
...
This diff is collapsed.
Click to expand it.
senf.dict
+
3
−
0
View file @
0fd7c329
...
...
@@ -62,6 +62,7 @@ checksumPresent
CIDR
classsenf
ClientSocketHandle
ClockService
cloneable
CloneSource
cmd
...
...
@@ -72,6 +73,7 @@ CommandOverload
CommandParser
CommunicationPolicy
CommunicationPolicyBase
ComplexAnnotation
ConcretePacket
conf
config
...
...
@@ -435,6 +437,7 @@ ratestuffer
RawINetProtocol
RawV
rdynamic
ReadInfo
refcount
regex
registerEvent
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment