3 /** \mainpage The SENF Socket Library
5 The Socket library provides a high level and object oriented abstraction of the BSD socket
6 API. The abstraction is based on several concepts:
8 \li The basic visible interface is a \link handle_group handle object \endlink
9 \li The socket interface relies on a \link policy_group policy framework \endlink to configure
11 \li The rest of the socket API is accessible using a classic inheritance hierarchy of \link
12 protocol_group protocol classes \endlink
14 The handle/body architecture provides automatic reference counted management of socket
15 instances, the policy framework provides highly efficient access to the most important socket
16 functions (like reading and writing) and the inheritance hierarchy provides convenient access to
17 the multitude of special and protocol dependent options.
24 \ref protocol_group \n
30 /** \page structure Overview of the Socket Library Structure
32 \image html Handle.png
34 This diagram tries to give a structural overview of the Socket Library, it does \e not directly
35 show, how the library is implemented. This will be explained later.
37 The outside interface to the library is a Handle object. This is the only object, the library
38 user directly interacts with. Every handle references some socket. This is like the ordinary
39 POSIX API: the file descriptor (also called file handle, an integer number) references a socket
40 structure which lives in kernel space. In this library, the Handle object (which is not a simple
41 integer any more but an object) references the Socket (which is part of the
42 implementation). Several handles may reference the same Socket. In contrast to the kernel API,
43 the library employs reference counting to release a socket when the last Handle to it goes out
46 The behavior of a Socket is defined by it's Protocol. It is divided into two parts: the
47 <em>policy interface</em> and the <em>protocol interface</em>. Together they provide the
48 complete API for a specific type of Socket as defined by the Protocol. The <em>policy
49 interface</em> provides highly efficient access to the most frequently used operations whereas
50 the <em>protocol interface</em> completes the interface by providing a complete set of all
51 protocol specific operations not found in the policy interface. This structure allows us to
52 combine the benefits of two design methodologies: The policy interface utilizes a policy based
53 design technique and is highly efficient albeit more complex to implement, whereas the protocol
54 interface is based on a more common inheritance architecture which is not as optimized for
55 performance but much simpler to implement. We reduce the complexity of the implementation by
56 reducing the policy interface to a minimal sensible subset of the complete API.
58 \section over_policy The Policy Interface
60 The policy of a Socket consists of several parts, called <em>policy axis</em>. Each axis
61 corresponds to one specific interface aspect of the Socket. The exact meaning of the policy axis
62 are defined elsewhere (see \ref policy_group). The Protocol will always provide a complete set
63 of <em>policy classes</em>, one for each axis.
65 This <em>complete socket policy</em> defines the policy interface of the protocol. This
66 interface is carried over into the Handle. The socket policy as defined in the Handle however
67 may be <em>incomplete</em>. This mans, that the \e accessible interface of the Socket depends on
68 the type of Handle used. The inherent interface does not change but the view of this interface
69 does if the Handle does not provide the \e complete policy interface. This feature is very
70 important. It allows to define generic Handle types. A generic Handle with an incompletely
71 defined policy can point to an arbitrary Socket as long as all those policy axis which \e are
72 defined match those defined in that Socket's protocol. Using such a generic handle decouples the
73 implementation parts using this handle from the other socket aspects (e.g. you may define a
74 generic socket handle for TCP based communication leaving the addressingPolicy undefined which
75 makes your code independent of the type of addressing, IPv4 or IPv6).
77 This can be described as generalized compile-time polymorphism: A base class reference to some
78 derived class will only give access to a reduced interface (the base class interface) of a
79 class. The class still is of it's derived type (and inherently has the complete interface) but
80 only part of it is accessible via the base class reference. Likewise a generic handle (aka base
81 class reference) will only provide a reduced interface (aka base class interface) to the derived
82 class instance (aka socket).
84 \section over_protocol The Protocol Interface
86 The protocol interface is provided by a set of <em>protocol facets</em>. Each facet provides a
87 part of the interface. Whereas the policy interface is strictly defined (the number and type of
88 policy axis is fixed and also the possible members provided by the policy interface are fixed),
89 the protocol interface is much more flexible. Any member needed to provide a complete API for
90 the specific protocol may be defined, the number and type of facets combined to provide the
91 complete interface is up to the Protocol implementor. This flexibility is necessary to provide a
92 complete API for every possible protocol.
94 However this flexibility comes at a cost: To access the protocol interface the user must know
95 the exact protocol of the socket. With other words, the protocol is only accessible if the
96 handle you use is a <em>protocol specific</em> handle. A protocol specific Handle differs from a
97 generic Handle in two ways: It always has a complete policy and it knows the exact protocol type
98 of the socket (which generic handles don't). This allows to access to the complete protocol
101 \section over_impl Implementation of the Socket Libarary Structure
103 In the Implementation, the socket policy is identified by an instance of the senf::SocketPolicy
104 template. The Socket representation is internally represented in a senf::SocketBody which is not
105 outside visible. The Handle is provided by a hierarchy of handle templates. Each Handle template
106 uses template arguments for the policy and/or protocol as needed (see \ref handle_group).
108 The Handle hierarchy divides the interface into two separate strains: the client interface
109 (senf::ClientSocketHandle and senf::ProtocolClientSocketHandle) provides the interface of a
110 client socket whereas the server interface (senf::ServerSocketHandle and
111 senf::ProtocolServerSocketHandle) provides the interface as used by server sockets.
113 The protocol interface is implemented using inheritance: The Protocol class inherits from each
114 protocol facet using multiple (virtual public) inheritance. The Protocol class therefore
115 provides the complete protocol API in a unified (see \ref protocol_group).
118 /** \page usage Using the Socket Library
120 Whenever you use the socket library, what you will be dealing with are FileHandle derived
121 instances. The socket library relies on reference counting to automatically manage the
122 underlying socket representation. This frees you of having to manage the socket lifetime
125 \section usage_create Creating a Socket Handle
127 To create a new socket handle (opening a socket), you will need to use
128 ProtocolClientSocketHandle or ProtocolServerSocketHandle. You will probably not use these
129 templates as is but use proper typedefs (for example TCPv4ClientSocketHandle or
130 PacketSocketHandle). The documentation for these socket handles are found in the protocol class
131 (for example TCPv4SocketProtocol or PacketProtocol).
133 \section usage_reusable Writing Reusable Components
135 To make your code more flexible, you should not pass around your socket in this form. Most of
136 your code will be using only a small subset of the ProtocolClientSocketHandle or
137 ProtocolServerSocketHandle API.
139 If instead of using the fully specified handle type you use a more incomplete type, you allow
140 your code to be used with all sockets which fulfill the minimal requirements of your code. These
141 types are based on the ClientSocketHandle and ServerSocketHandle templates which implement the
142 policy interface without providing the concrete protocol interface. To use those templates you
143 may define a special reduced policy or handle for your code. By giving only an incomplete policy
144 you thereby reduce the interface to that required by your module:
147 typedef ClientSocketHandle<
151 ConnectedCommunicationPolicy > > MyReadableHandle;
155 This defines \c MyReadableHandle as a ClientSocketHandle which will have only read
156 functionality. Your code expects a stream interface (in contrast to a packet or datagram based
157 interface). You will not have \c write or \c readfrom members. \c write will be disabled since
158 the WritePolicy is unknown, \c readfrom will be disabled since a socket with the
159 ConnectedCommunicationPolicy does not have a \c readfrom member.
167 /** \page extend Extending the Library
169 There are two layers, on which the socket library can be extended: On the protocol layer and on
170 the policy layer. Extending the protocol layer is quite simple and works as long as the desired
171 protocol does use the same BSD API used by the standard internet protocols as implemented in the
172 standard policies (i.e. it uses ordinary read() and write() or rcvfrom() or sendto() calls and
175 If however the implementation of a policy feature needs to be changed, a new policy class has to
176 be written. This also is not very complicated however the integration is more complex.
178 \section extend_protocol Writing a new protocol class
180 Most protocols can be implemented by just implementing a new protocol class. The protocol class
181 must be derived from ConcreteSocketProtocol and takes the socket policy (as created by
182 MakeSocketPolicy) as a template argument. See the documentation of this class for the interface.
184 \attention You may want to use multiple inheritance as it is used in the implementation of the
185 standard protocols (See \ref protocol_group). You must however be extra careful to ensure, that
186 every class ultimately has SocketPolicy as a public \e virtual base.
188 After the protocol class has been defined, you will probably want to provide typedefs for the
189 new protocol sockets. If the new protocol is connection oriented, this will be like
191 typedef ProtocolClientSocketHandle<MyProtocolClass> MyProtocolClientSocketHandle;
192 typedef ProtocolServerSocketHandle<MyProtocolClass> MyProtocolServerSocketHandle;
195 \section extend_policy Extending the policy framework
197 If you have to extend the policy framework, you will need to be aware of some important
198 limitations of the socket library:
200 \li When you define a new policy for some axis, this new policy <em>must not</em> be derived
201 from one of the existing concrete policy classes (except of course the respective policy
202 axis base class). This is important since the policy type is \e not polymorphic. The policy
203 to be used is selected by the compiler using the \e static type, which is exactly what is
204 desired, since this allows calls to be efficiently inlined.
206 \li Therefore, extending the policy framework will make the new socket probably \e incompatible
207 with generic code which relies on the policy axis which is extended. Example: If you write a
208 new write policy because your protocol does not use ordinary write() system calls but some
209 protocol specific API, Then any generic function relying on WritablePolicy will \e not work
210 with the new socket, since the socket does \e not have this policy, it has some other kind
213 Therefore you need to be careful of what you are doing. The first step is to find out, which
214 policy you will have to implement. For this, find the ClientSocketHandle and/or
215 ServerSocketHandle members you want to change (see \ref ClientSocketHandle and \ref
216 ServerSocketHandle). Not all policy axis directly contribute to the SocketHandle
217 interface. However, some policy members additionally depend on other policy axis (example:
218 AddressingPolicy::connect is only defined if the communication policy is
219 ConnectedCommunication).
224 /** \page glossary Glossary
226 <table class="glossary">
228 <tr><td>policy</td> <td>collection of policy classes, one for each policy axis, instantiation of
229 the SocketPolicy template</td></tr>
231 <tr><td>policy axis</td> <td>one aspect defined in the socket policy, typedef and member of the
232 SocketPolicy template</td></tr>
234 <tr><td>policy class</td> <td>implementation of a single policy axis, class derived from the
235 axis base class</td></tr>
237 <tr><td>complete policy</td> <td>socket policy where each axis is specified completely</td></tr>
239 <tr><td>incomplete policy</td> <td>socket policy, where at least one axis is not fully
242 <tr><td>protocol class</td> <td>definition of a protocol as a class, class inheriting from
243 ConcreteSocketProtocol.</td></tr>
245 <tr><td>protocol facet</td> <td>a class providing some subset of the protocol interface, class
246 derived from SocketProtocol but not from ConcreteSocketProtocol</td></tr>
248 <tr><td>policy interface</td> <td>interface directly provided by
249 ClientSocketHandle/ServerSocketHandle and defined through the policy</td>
251 <tr><td>protocol interface</td> <td>interface provided by the protocol class and accessible via
252 the ProtocolClientSocketHandle::protocol()/ProtocolServerSocketHandle::protocol()
258 /** \page implementation Implementation notes
260 \section class_diagram Class Diagram
262 \image html SocketLibrary-classes.png
264 \section impl_notes Arbitrary Implementation Notes
266 \li The implementation tries to isolate the library user as much as possible from the system
267 header files since those headers define a lot of define symbols and introduce a host of
268 symbols into the global namespace. This is, why some classes define their own \c enum types
269 to replace system defined define constants. This also precludes inlining some functionality.
271 \li To reduce overhead, template functions/members which are more than one-liners are often
272 implemented in terms of a non-template function/member. This is also used to further the
273 isolation from system headers as defined above (template code must always be included into
274 every compilation unit together with all headers need for the implementation).
283 // c-file-style: "senf"
284 // indent-tabs-mode: nil
285 // ispell-local-dictionary: "american"