+// $Id$
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// 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.
+
+namespace senf {
+
/** \mainpage The SENF Socket Library
- The Socket library provides a high level and object oriented
- abstraction of the BSD socket API. The abstraction is based on
- several concepts:
-
- \li The basic visible interface is a \link handle_group handle
- object \endlink
- \li The socket interface relies on a \link policy_group policy
- framework \endlink to configure it's functionality
- \li The rest of the socket API is accessible using a classic
- inheritance hierarchy of \link protocol_group protocol classes
- \endlink
-
- The handle/body architecture provides automatic reference counted
- management of socket instances, the policy framework provides
- highly efficient access to the most important socket functions
- (like reading and writing) and the inheritance hierarchy provides
- convenient access to the multitude of special and protocol
- dependent options.
-
- \see \ref usage \n
- \ref handle_group \n
- \ref policy_group \n
- \ref protocol_group \n
- \ref extend \n
- \ref implementation
+ The Socket library provides a high level and object oriented abstraction based on the BSD socket
+ API (but not limited to it).
+
+ \autotoc
+
+ \section socket_intro Introduction
+ \seechapter \ref structure \n
+ \seechapter \ref usage
+
+ The socket library abstraction is based on several concepts:
+
+ \li The basic visible interface is a \link handle_group handle object\endlink
+ \li The socket interface relies on a \link policy_group policy framework \endlink to configure
+ it's functionality
+ \li The rest of the socket API is accessible using a classic inheritance hierarchy of \link
+ protocol_group protocol classes \endlink
+ \li There is a family of auxilliary \ref addr_group to supplement the socket library
+
+
+ \section socket_handle Socket Handles
+ \seechapter \ref handle_group \n
+ \seechapter \ref concrete_protocol_group
+
+ The handle/body architecture provides automatic reference counted management of socket
+ instances. This is the visible interface to the socket library.
+
+ Each specific protocol is used primarily via a protocol specific handle (a typedef
+ symbol). However, more generic kinds of handles can be defined for more generic functionality.
+
+
+
+ \section socket_policy The Policy interface
+ \seechapter \ref policy_group
+
+ The policy framework configures the exact features, a specific type of socket handle
+ provides. This offers highly efficient access to the most important socket functions (like
+ reading and writing). The policy interface however is a \e static, non-polymorphic interface.
+
+
+ \section socket_protocol The Protocol interface
+ \seechapter \ref protocol_group
+
+
+ The protocol interface provides further protocol dependent and (possibly) polymorphic access to
+ further socket funcitonality. On the other hand, this type of interface is not as flexible,
+ generic and fast as the policy interface.
+
+ \section socket_addr Auxilliary Addressing classes
+ \seechapter \ref addr_group
+
+ To supplement the socket library, there are a multitude of addressing classes. These come in two
+ basic groups:
+ \li Protocol specific addresses (e.g. INet4Address, MACAddress)
+ \li Socket addresses (\c sockaddr) (e.g. INet4SocketAddress, LLSocketAddress)
+
+ Whereas the protocol specific addresses are custom value types which represent their
+ corresponding low-level address, the socket addresses are based on the corresponding \c sockaddr
+ structures.
+
+ \section socket_further Going further
+ \seechapter \ref extend \n
+ \seechapter \ref implementation
+
+ The socket library is highly flexible and extensible. The implementation is not restricted to
+ plain BSD sockets: Any type of read/write communication can be wrapped into the socket library
+ (one Example is the TapSocketHandle which provides access to a Linux \c tap device).
+
+ */
+
+/** \page structure Overview of the Socket Library Structure
+
+ \image html Handle.png
+
+ This diagram tries to give a structural overview of the Socket Library, it does \e not directly
+ show, how the library is implemented. This will be explained later.
+
+ The outside interface to the library is a Handle object. This is the only object, the library
+ user directly interacts with. Every handle references some socket. This is like the ordinary
+ POSIX API: the file descriptor (also called file handle, an integer number) references a socket
+ structure which lives in kernel space. In this library, the Handle object (which is not a simple
+ integer any more but an object) references the Socket (which is part of the
+ implementation). Several handles may reference the same Socket. In contrast to the kernel API,
+ the library employs reference counting to release a socket when the last Handle to it goes out
+ of scope.
+
+ The behavior of a Socket is defined by it's Protocol. It is divided into two parts: the
+ <em>policy interface</em> and the <em>protocol interface</em>. Together they provide the
+ complete API for a specific type of Socket as defined by the Protocol. The <em>policy
+ interface</em> provides highly efficient access to the most frequently used operations whereas
+ the <em>protocol interface</em> completes the interface by providing a complete set of all
+ protocol specific operations not found in the policy interface. This structure allows us to
+ combine the benefits of two design methodologies: The policy interface utilizes a policy based
+ design technique and is highly efficient albeit more complex to implement, whereas the protocol
+ interface is based on a more common inheritance architecture which is not as optimized for
+ performance but much simpler to implement. We reduce the complexity of the implementation by
+ reducing the policy interface to a minimal sensible subset of the complete API.
+
+ \section over_policy The Policy Interface
+
+ The policy of a Socket consists of several parts, called <em>policy axis</em>. Each axis
+ corresponds to one specific interface aspect of the Socket. The exact meaning of the policy axis
+ are defined elsewhere (see \ref policy_group). The Protocol will always provide a complete set
+ of <em>policy classes</em>, one for each axis.
+
+ This <em>complete socket policy</em> defines the policy interface of the protocol. This
+ interface is carried over into the Handle. The socket policy as defined in the Handle however
+ may be <em>incomplete</em>. This mans, that the \e accessible interface of the Socket depends on
+ the type of Handle used. The inherent interface does not change but the view of this interface
+ does if the Handle does not provide the \e complete policy interface. This feature is very
+ important. It allows to define generic Handle types. A generic Handle with an incompletely
+ defined policy can point to an arbitrary Socket as long as all those policy axis which \e are
+ defined match those defined in that Socket's protocol. Using such a generic handle decouples the
+ implementation parts using this handle from the other socket aspects (e.g. you may define a
+ generic socket handle for TCP based communication leaving the addressingPolicy undefined which
+ makes your code independent of the type of addressing, IPv4 or IPv6).
+
+ This can be described as generalized compile-time polymorphism: A base class reference to some
+ derived class will only give access to a reduced interface (the base class interface) of a
+ class. The class still is of it's derived type (and inherently has the complete interface) but
+ only part of it is accessible via the base class reference. Likewise a generic handle (aka base
+ class reference) will only provide a reduced interface (aka base class interface) to the derived
+ class instance (aka socket).
+
+ \section over_protocol The Protocol Interface
+
+ The protocol interface is provided by a set of <em>protocol facets</em>. Each facet provides a
+ part of the interface. Whereas the policy interface is strictly defined (the number and type of
+ policy axis is fixed and also the possible members provided by the policy interface are fixed),
+ the protocol interface is much more flexible. Any member needed to provide a complete API for
+ the specific protocol may be defined, the number and type of facets combined to provide the
+ complete interface is up to the Protocol implementor. This flexibility is necessary to provide a
+ complete API for every possible protocol.
+
+ However this flexibility comes at a cost: To access the protocol interface the user must know
+ the exact protocol of the socket. With other words, the protocol is only accessible if the
+ handle you use is a <em>protocol specific</em> handle. A protocol specific Handle differs from a
+ generic Handle in two ways: It always has a complete policy and it knows the exact protocol type
+ of the socket (which generic handles don't). This allows to access to the complete protocol
+ interface.
+
+ \section over_impl Implementation of the Socket Libarary Structure
+
+ In the Implementation, the socket policy is identified by an instance of the senf::SocketPolicy
+ template. The Socket representation is internally represented in a senf::SocketBody which is not
+ outside visible. The Handle is provided by a hierarchy of handle templates. Each Handle template
+ uses template arguments for the policy and/or protocol as needed (see \ref handle_group).
+
+ The Handle hierarchy divides the interface into two separate strains: the client interface
+ (senf::ClientSocketHandle and senf::ProtocolClientSocketHandle) provides the interface of a
+ client socket whereas the server interface (senf::ServerSocketHandle and
+ senf::ProtocolServerSocketHandle) provides the interface as used by server sockets.
+
+ The protocol interface is implemented using inheritance: The Protocol class inherits from each
+ protocol facet using multiple (virtual public) inheritance. The Protocol class therefore
+ provides the complete protocol API in a unified (see \ref protocol_group).
*/
/** \page usage Using the Socket Library
- Whenever you use the socket library, what you will be dealing with
- are senf::FileHandle derived instances. The socket library relies
- on reference counting to automatically manage the underlying
- socket representation. This frees you of having to manage the
- socket lifetime explicitly.
+ Whenever you use the socket library, what you will be dealing with are FileHandle derived
+ instances. The socket library relies on reference counting to automatically manage the
+ underlying socket representation. This frees you of having to manage the socket lifetime
+ explicitly.
\section usage_create Creating a Socket Handle
- To create a new socket handle (opening a socket), you will need to
- use senf::ProtocolClientSocketHandle or
- senf::ProtocolServerSocketHandle. You will probably not use these
- templates as is but use proper typedefs (for example
- senf::TCPv4ClientSocketHandle or senf::PacketSocketHandle). The
- documentation for these socket handles are found in the protocol
- class (for example senf::TCPv4SocketProtocol or
- senf::PacketProtocol).
+ To create a new socket handle (opening a socket), you will need to use
+ ProtocolClientSocketHandle or ProtocolServerSocketHandle. You will probably not use these
+ templates as is but use proper typedefs (for example TCPv4ClientSocketHandle or
+ PacketSocketHandle). The documentation for these socket handles are found in the protocol class
+ (for example TCPv4SocketProtocol or PacketSocketProtocol).
\section usage_reusable Writing Reusable Components
- To make your code more flexible, you should not pass around your
- socket in this form. Most of your code will be using only a small
- subset of the senf::ProtocolClientSocketHandle or
- senf::ProtocolServerSocketHandle API. If instead of using the
- fully specified handle type you use a more incomplete type, you
- allow your code to be used with all socket which fulfill the
- minimal requirements of your code.
-
- This works, by defining a special reduced policy or handle for
- your code:
+ To make your code more flexible, you should not pass around your socket in this form. Most of
+ your code will be using only a small subset of the ProtocolClientSocketHandle or
+ ProtocolServerSocketHandle API.
+
+ If instead of using the fully specified handle type you use a more incomplete type, you allow
+ your code to be used with all sockets which fulfill the minimal requirements of your code. These
+ types are based on the ClientSocketHandle and ServerSocketHandle templates which implement the
+ policy interface without providing the concrete protocol interface. To use those templates you
+ may define a special reduced policy or handle for your code. By giving only an incomplete policy
+ you thereby reduce the interface to that required by your module:
\code
- typedef senf::ClientSocketHandle<
- senf::MakeSocketPolicy<
- senf::ReadablePolicy,
- senf::StreamFramingPolicy,
- senf::ConnectedCommunicationPolicy > > MyReadableHandle;
-
+ typedef ClientSocketHandle<
+ MakeSocketPolicy<
+ ReadablePolicy,
+ StreamFramingPolicy,
+ ConnectedCommunicationPolicy > > MyReadableHandle;
+
\endcode
- This defines \c MyReadableHandle as a senf::ClientSocketHandle
- which will have only read functionality. Your code expects a
- stream interface (in contrast to a packet or datagram based
- interface). You will not have \c write or \c readfrom members. \c
- write will be disabled since the WritePolicy is unknown, \c
- readfrom will be disabled since a socket with the
- senf::ConnectedCommunicationPolicy does not have a \c readfrom
- member.
- */
-
+ This defines \c MyReadableHandle as a ClientSocketHandle which will have only read
+ functionality. Your code expects a stream interface (in contrast to a packet or datagram based
+ interface). You will not have \c write or \c readfrom members. \c write will be disabled since
+ the WritePolicy is unknown, \c readfrom will be disabled since a socket with the
+ ConnectedCommunicationPolicy does not have a \c readfrom member.
+ \see
+ \ref policy_group \n
+ \ref handle_group \n
+ \ref protocol_group
+ */
/** \page extend Extending the Library
-
- There are two layers, on which the socket library can be
- extended: On the protocol layer and on the policy layer. Extending
- the protocol layer is quite simple and works as long as the
- desired protocol does use the same BSD API used by the standard
- internet protocols as implemented in the standard policies
- (i.e. it uses ordinary read() and write() or rcvfrom() or sendto()
- calls and so on).
-
- If however the implementation of a policy feature needs to be
- changed, a new policy class has to be written. This also is not
- very complicated however the integration is more complex.
+
+ There are two layers, on which the socket library can be extended: On the protocol layer and on
+ the policy layer. Extending the protocol layer is quite simple and works as long as the desired
+ protocol does use the same BSD API used by the standard internet protocols as implemented in the
+ standard policies (i.e. it uses ordinary read() and write() or rcvfrom() or sendto() calls and
+ so on).
+
+ If however the implementation of a policy feature needs to be changed, a new policy class has to
+ be written. This also is not very complicated however the integration is more complex.
\section extend_protocol Writing a new protocol class
-
- Most protocols can be implemented by just implementing a new
- protocol class. The protocol class must be derived from
- senf::ConcreteSocketProtocol and takes the socket policy (as
- created by senf::MakeSocketPolicy) as a template argument. See the
- documentation of this class for the interface.
-
- \attention
- You may want to use multiple inheritance as it is used in the
- implementation of the standard protocols (See \ref
- protocol_interface). You must however be extra careful to ensure,
- that every class ultimately has senf::SocketPolicy as a public
- \e virtual base.
-
- After the protocol class has been defined, you will probably want to
- provide typedefs for the new protocol sockets. If the new protocol
- is connection oriented, this will be like
- <code>
- typedef senf::ProtocolClientSocketHandle<MyProtocolClass> MyProtocolClientSocketHandle;
- typedef senf::ProtocolServerSocketHandle<MyProtocolClass> MyProtocolServerSocketHandle;
- </code>
+
+ Most protocols can be implemented by just implementing a new protocol class. The protocol class
+ must be derived from ConcreteSocketProtocol and takes the socket policy (as created by
+ MakeSocketPolicy) as a template argument. See the documentation of this class for the interface.
+
+ \attention You may want to use multiple inheritance as it is used in the implementation of the
+ standard protocols (See \ref protocol_group). You must however be extra careful to ensure, that
+ every class ultimately has SocketPolicy as a public \e virtual base.
+
+ After the protocol class has been defined, you will probably want to provide typedefs for the
+ new protocol sockets. If the new protocol is connection oriented, this will be like
+ \code
+ typedef ProtocolClientSocketHandle<MySocketProtocolClass> MySocketProtocolClientSocketHandle;
+ typedef ProtocolServerSocketHandle<MySocketProtocolClass> MySocketProtocolServerSocketHandle;
+ \endcode
\section extend_policy Extending the policy framework
- If you have to extend the policy framework, you will need to be
- aware of some important limitations of the socket library:
-
- \li When you define a new policy for some axis, this new policy
- <em>must not</em> be derived from one of the existing concrete
- policy classes (except of course the respective policy axis
- base class). This is important since the policy type is \e not
- polymorphic. The policy to be used is selected by the compiler
- using the \e static type, which is exactly what is desired,
- since this allows calls to be efficiently inlined.
-
- \li Therefore, extending the policy framework will make the new
- socket probably \e incompatible with generic code which relies
- on the policy axis which is extended. Example: If you write a
- new write policy because your protocol does not use ordinary
- write() system calls but some protocol specific API, Then any
- generic function relying on senf::WritablePolicy will \e not
- work with the new socket, since the socket does \e not have
- this policy, it has some other kind of write policy.
-
- Therefore you need to be careful of what you are doing. The first
- step is to find out, which policy you will have to implement. For
- this, find the senf::ClientSocketHandle and/or
- senf::ServerSocketHandle members you want to change (see \ref
- senf::ClientSocketHandle and \ref senf::ServerSocketHandle). Not
- all policy axis directly contribute to the SocketHandle
- interface. However, some policy members additionally depend on
- other policy axis (example: AddressingPolicy::connect is only
- defined if the communication policy is
+ If you have to extend the policy framework, you will need to be aware of some important
+ limitations of the socket library:
+
+ \li When you define a new policy for some axis, this new policy <em>must not</em> be derived
+ from one of the existing concrete policy classes (except of course the respective policy
+ axis base class). This is important since the policy type is \e not polymorphic. The policy
+ to be used is selected by the compiler using the \e static type, which is exactly what is
+ desired, since this allows calls to be efficiently inlined.
+
+ \li Therefore, extending the policy framework will make the new socket probably \e incompatible
+ with generic code which relies on the policy axis which is extended. Example: If you write a
+ new write policy because your protocol does not use ordinary write() system calls but some
+ protocol specific API, Then any generic function relying on WritablePolicy will \e not work
+ with the new socket, since the socket does \e not have this policy, it has some other kind
+ of write policy.
+
+ Therefore you need to be careful of what you are doing. The first step is to find out, which
+ policy you will have to implement. For this, find the ClientSocketHandle and/or
+ ServerSocketHandle members you want to change (see \ref ClientSocketHandle and \ref
+ ServerSocketHandle). Not all policy axis directly contribute to the SocketHandle
+ interface. However, some policy members additionally depend on other policy axis (example:
+ AddressingPolicy::connect is only defined if the communication policy is
ConnectedCommunication).
\see policy_group
/** \page implementation Implementation notes
- \image html SocketLibrary-classes.png
+ \section class_diagram Class Diagram
+
+ <div class="diamap" name="SocketLibrary-classes">
+ <span coords="472,667,559,689">\ref IPv4Protocol</span>
+ <span coords="29,773,139,794">\ref WritePolicyBase</span>
+ <span coords="97,939,238,960">\ref SocketBufferingPolicy</span>
+ <span coords="97,390,223,411">\ref NoAddressingPolicy</span>
+ <span coords="97,736,217,758">\ref NotReadablePolicy</span>
+ <span coords="418,609,613,631">\ref AdressableBSDSocketProtocol</span>
+ <span coords="18,895,153,917">\ref BufferingPolicyBase</span>
+ <span coords="22,426,148,447">\ref FramingPolicyBase</span>
+ <span coords="409,0,495,36">\ref FileBody</span>
+ <span coords="97,469,249,491">\ref DatagramFramingPolicy</span>
+ <span coords="97,317,240,339">\ref INet6AddressingPolicy</span>
+ <span coords="453,544,578,566">\ref BSDSocketProtocol</span>
+ <span coords="97,281,240,303">\ref INet4AddressingPolicy</span>
+ <span coords="452,177,706,209">\ref ProtocolServerSocketHandle</span>
+ <span coords="412,259,486,281">\ref PolicyBase</span>
+ <span coords="474,768,557,790">\ref TCPProtocol</span>
+ <span coords="97,700,197,722">\ref ReadablePolicy</span>
+ <span coords="342,249,654,411">\ref SocketPolicy</span>
+ <span coords="0,541,173,563">\ref CommunicationPolicyBase</span>
+ <span coords="640,859,736,881">\ref TCPv6Protocol</span>
+ <span coords="353,428,453,465">\ref SocketProtocol</span>
+ <span coords="97,585,297,606">\ref ConnectedCommunicationPolicy</span>
+ <span coords="172,177,420,209">\ref ProtocolClientSocketHandle</span>
+ <span coords="472,718,559,739">\ref IPv6Protocol</span>
+ <span coords="97,816,192,838">\ref WritablePolicy</span>
+ <span coords="383,62,520,98">\ref SocketBody</span>
+ <span coords="698,888,798,910">\ref PacketProtocol</span>
+ <span coords="97,852,213,874">\ref NotWritablePolicy</span>
+ <span coords="31,657,138,679">\ref ReadPolicyBase</span>
+ <span coords="213,60,369,91">\ref SocketHandle</span>
+ <span coords="197,126,385,158">\ref ClientSocketHandle</span>
+ <span coords="97,621,311,642">\ref UnconnectedCommunicationPolicy</span>
+ <span coords="567,480,786,526">\ref ConcreteSocketProtocol</span>
+ <span coords="582,830,678,852">\ref TCPv4Protocol</span>
+ <span coords="97,505,234,527">\ref StreamFramingPolicy</span>
+ <span coords="13,238,161,259">\ref AddressingPolicyBase</span>
+ <span coords="224,0,294,36">\ref FileHandle</span>
+ <span coords="97,353,222,375">\ref LLAddressingPolicy</span>
+ <span coords="476,126,671,158">\ref ServerSocketHandle</span>
+ </div>
+ \htmlonly <img src="SocketLibrary-classes.png" border="0" alt="SocketLibrary-classes" usemap="#SocketLibrary-classes"> \endhtmlonly
+
+ \section impl_notes Arbitrary Implementation Notes
+
+ \li The implementation tries to isolate the library user as much as possible from the system
+ header files since those headers define a lot of define symbols and introduce a host of
+ symbols into the global namespace. This is, why some classes define their own \c enum types
+ to replace system defined define constants. This also precludes inlining some functionality.
+
+ \li To reduce overhead, template functions/members which are more than one-liners are often
+ implemented in terms of a non-template function/member. This is also used to further the
+ isolation from system headers as defined above (template code must always be included into
+ every compilation unit together with all headers need for the implementation).
*/
+}
+
\f
// Local Variables:
// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// mode: flyspell
// mode: auto-fill
-// ispell-local-dictionary: "american"
+// compile-command: "scons -u doc"
// End: