Socket: Move protocol into the socket body (as private base class) and allow non...
[senf.git] / Socket / SocketProtocol.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS) 
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY 
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief SocketProtocol and ConcreteSocketProtocol public header
25
26     \idea We should optimize the protocol handling. Allocating a protocol instance for every socket
27         body seems quite wasteful. We could derive SocketPolicy from SocketBody (probably privately,
28         since private inheritance models more of 'has a' than 'is a'). This would allow to reduce
29         the number of heap-allocations per socket to one which is good.
30  */
31
32 // The private inheritance idea should indeed work very well: We just need to change the
33 // implementations of body() and protocol() and that of the ProtocolClient/ServerSocketHandle
34 // constructors and the SocketBody constructor. The body and the protocol would still be visible
35 // like several instances because of the private inheritance but we would save the backwards
36 // pointer.
37
38 /** \defgroup protocol_group The Protocol Classes
39
40     \htmlonly
41     <map name="protocols">
42     <area shape="rect" alt="SocketPolicy" href="structsenf_1_1SocketPolicy.html" title="SocketPolicy" coords="416,50,536,68" />
43     <area shape="rect" alt="ConcreteSocketProtocol" href="classsenf_1_1ConcreteSocketProtocol.html" title="ConcreteSocketProtocol" coords="268,65,456,88" />
44     <area shape="rect" alt="SocketProtocol" href="classsenf_1_1SocketProtocol.html" title="SocketProtocol" coords="1,2,120,26" />
45     <area shape="rect" alt="BSDSocketProtocol" href="classsenf_1_1BSDSocketProtocol.html" title="BSDSocketProtocol" coords="124,118,276,143" />
46     <area shape="rect" alt="AddressableBSDSocketProtocol" href="classsenf_1_1AddressableBSDSocketProtocol.html" title="AddressableBSDSocketProtocol" coords="82,200,314,224" />
47     <area shape="rect" alt="IPv4Protocol" href="classsenf_1_1IPv4Protocol.html" title="IPv4Protocol" coords="149,272,252,296" />
48     <area shape="rect" alt="IPv6Protocol" href="classsenf_1_1IPv6Protocol.html" title="IPv6Protocol" coords="149,335,251,359" />
49     <area shape="rect" alt="TCPProtocol" href="classsenf_1_1TCPProtocol.html" title="TCPProtocol" coords="151,398,248,420" />
50     <area shape="rect" alt="TCPv4SocketProtocol" href="classsenf_1_1TCPv4SocketProtocol.html" title="TCPv4SocketProtocol" coords="288,471,405,494" />
51     <area shape="rect" alt="TCPv6SocketProtocol" href="classsenf_1_1TCPv6SocketProtocol.html" title="TCPv6SocketProtocol" coords="424,470,540,494" />
52     <area shape="rect" alt="PacketProtocol" href="classsenf_1_1PacketProtocol.html" title="PacketProtocol" coords="560,469,680,495" />
53     </map>
54     <img src="Protocols.png" border="0" alt="Protocols" usemap="#protocols">
55     \endhtmlonly
56
57     The socket handle classes and templates only implement the most important socket API methods
58     using the policy framework. To access the complete API, the protocol interface is
59     provided. Access to the protocol interface is only possible via senf::ProtocolClientSocketHandle
60     and senf::ProtocolServerSocketHandle which have the necessary \c protocol() member. This member
61     returns a reference to the protocol class instance which contains members covering all the API
62     functions (mostly setsockopt/getsockopt related calls but there may be more, this is completely
63     up to the implementor of the protocol class) not found in the SocketHandle interface. The
64     protocol interface is specific to the protocol. It's implementation is quite free. The standard
65     protocols are implemented using a simple multiple-inheritance hierarchy as shown above.
66
67     Since the protocol class is protocol specific (how intelligent ...), the protocol class also
68     defines the \e complete socket policy to be used with it's protocol. Complete meaning, that
69     every policy axis must be assigned it's the most specific (that is derived) policy class to be
70     used with the protocol and that no policy axis is allowed to be left unspecified.
71
72     \see
73         \ref handle_group \n
74         \ref policy_group
75
76     \todo Complete the protocol interface implementations. Better distribution of members to
77         protocol facets and more precise distribution of functionality among the facets.
78  */
79
80 /** \defgroup concrete_protocol_group Protocol Implementations (Concrete Protocol Classes)
81     \ingroup protocol_group
82
83     Theese protocol classes define concrete and complete protocol implementations. They inherit from
84     ConcreteSocketProtocol and are used with the ProtocolClientSocketHandle and
85     ProtocolServerSocketHandle templates to instantiate socket handles. Appropriate typedefs are
86     always provided.
87
88     Every protocol defines both the protocol and the policy interface provided by that protocol. See
89     the documentation of the protocol classes listed below for more information on the supported
90     protocols. Every protocol class documents it's policy interface. Use the 'list all members' link
91     of the protocol class to find the complete policy interface.
92  */
93
94 /** \defgroup protocol_facets_group Protocol Facets
95     \ingroup protocol_group
96
97     The protocol facets are classes used as building blocks to build concrete protocol classes. Each
98     protocol facet will implement some functional part of the protocol interface. The protocol
99     facets all inherit from SocketProtocol by public \e virtual inheritance. This ensures the
100     accessibility of the socket body from all facets.
101  */
102
103 #ifndef HH_SocketProtocol_
104 #define HH_SocketProtocol_ 1
105
106 // Custom includes
107 #include <boost/utility.hpp>
108 // Hrmpf ... I have tried very hard, but I just can't find a nice, generic way to clean
109 // up this include
110 #include "SocketHandle.ih"
111
112 //#include "SocketProtocol.mpp"
113 ///////////////////////////////hh.p////////////////////////////////////////
114
115 namespace senf {
116
117     /// \addtogroup protocol_group
118     /// @{
119
120     class SocketPolicyBase;
121
122     /** \brief Socket Protocol base class
123
124         This is the base class of all socket protocol classes. Every protocol class must directly or
125         indirectly inherit from SocketProtocol
126
127         \attention SocketProtocol must \e always be inherited using public \e virtual inheritance.
128      */
129     class SocketProtocol 
130         : boost::noncopyable
131     {
132     public:
133         ///////////////////////////////////////////////////////////////////////////
134         // Types
135
136         ///////////////////////////////////////////////////////////////////////////
137         ///\name Structors and default members
138         ///@{
139
140         SocketProtocol();
141         virtual ~SocketProtocol() = 0;
142
143         // default default constructor
144         // no copy
145         // no conversion constructors
146
147         ///@}
148         ///////////////////////////////////////////////////////////////////////////
149
150         virtual SocketPolicyBase const & policy() const = 0;
151         ///< Access the policy instance
152
153         ///////////////////////////////////////////////////////////////////////////
154         // Virtual interface
155
156         virtual unsigned available() const = 0;
157                                         ///< Return (maximum) number of bytes available for reading
158                                         ///< without < blocking
159                                         /**< This member will check in a (very, sigh) protocol
160                                              dependent way, how many bytes may be read from a socket
161                                              in a single (non-blocking) read operation. If the
162                                              socket does not support reading (viz. NotReadablePolicy
163                                              is set), this member should always return \c 0.
164                                              
165                                              Depending on the protocol, it may not be possible to
166                                              return a good value. In this case, an upper bound may
167                                              be returned (e.g.: When reading from a socket which
168                                              returns ethernet frames, returning 1500 from
169                                              available() is ok). However, this should only be done
170                                              as a last resort. Also beware, that this number should
171                                              not be too large since the socket layer will always
172                                              need to allocate that number of bytes for the data to
173                                              be read. */
174
175         virtual bool eof() const = 0;   ///< Check for end-of-file condition
176                                         /**< This is another check which (like available()) is
177                                              extremely protocol dependent. This member will return
178                                              \c true only, if at end-of-file. If the protocol does
179                                              not support the notion of EOF, this member should
180                                              always return \c false. */
181
182         virtual void close() const;     ///< Close socket
183                                         /**< This override will automatically \c shutdown() the
184                                              socket whenever it is closed.
185                                              \throws senf::SystemException */
186         
187         virtual void terminate() const; ///< Forcibly close socket
188                                         /**< This override will automatically \c shutdown() the
189                                              socket whenever it is called. Additionally it will
190                                              disable SO_LINGER to ensure, that v_terminate will not
191                                              block. Like the overriden method, this member will ignore
192                                              failures and will never throw. It is therefore safe to be
193                                              called from a destructor. */
194
195         virtual void state(SocketStateMap & map, unsigned lod) const;
196                                         ///< Return socket state information
197                                         /**< This member is called to add state information to the
198                                              status \a map. The protocol map should provide as
199                                              detailed information as possible. The amount of
200                                              information to be added to the map is selected by the
201                                              \a lod value with a default value of 0. The
202                                              interpretation of the \a lod value is completely
203                                              implementation defined.
204                                              
205                                              Every class derived from SocketProtocol should
206                                              reimplement state(). The reimplemented method should
207                                              call (all) baseclass-implementations of this
208                                              member.
209
210                                              The \a map Argument is a map which associates
211                                              std:string keys with std:string-like values. The map
212                                              keys are interpreted as hierarchical strings with '.'
213                                              as a separator (like hostnames or struct or class
214                                              members). They are automatically sorted correctly.
215                                              
216                                              The values are std:string with one additional feature:
217                                              they allow assignment or conversion from *any* type as
218                                              long as that type is streamable. This simplifies
219                                              assigning non-string values to the map:
220                                              
221                                              \code
222                                                  map["socket.protocol.ip.address"] << peer();
223                                                  map["socket.protocol.tcp.backlog"] << backlog();
224                                              \endcode
225                                              
226                                              This will work even if peer() returns an ip-address
227                                              object or backlog() returns an integer. The values are
228                                              automatically converted to their string representation.
229                                              
230                                              Additionally, if the slot the date is written to is not
231                                              empty, the <tt>\<\<</tt> operator will add add a comma
232                                              as separator. */
233
234     protected:
235         FileHandle fh() const;          ///< Get a FileHandle for this instance
236                                         /**< This member will re turn a FileHandle instance for this
237                                              protocol instance. You may cast this FileHandle
238                                              instance to a ClientSocketHandle / ServerSocketHandle
239                                              as long as you know some of the socket policy using
240                                              static_socket_cast or dynamic_socket_cast */
241
242         int fd() const;                 ///< Get file descriptor
243                                         /**< Returns the file descriptor this protocol instance
244                                              references. This is the same as <tt>fh().fd()</tt> but
245                                              is implemented here since it is needed so often. */
246
247         void fd(int) const;             ///< Initialize file descriptor
248                                         /**< Assigns the file descriptor to the file handle, this
249                                              protocol instance references. Only valid, if the file
250                                              handle has not yet been assigned any descriptor (To
251                                              change the file descriptor association later, use \c
252                                              ::dup2()). */
253
254     private:
255         virtual std::auto_ptr<SocketBody> clone(bool isServer) const = 0;
256         virtual std::auto_ptr<SocketBody> clone(int fd, bool isServer) const = 0;
257         virtual SocketBody & body() const = 0;
258
259         friend class SocketBody;
260     };
261     
262     template <class Policy> class ClientSocketHandle;
263     template <class Policy> class ServerSocketHandle;
264
265     /** \brief Concrete Socket Protocol implementation base class
266
267         ConcreteSocketProtocol is the base class of a concrete socket protocol implementation. The
268         final protocol class must inherit from ConcreteSocketProtocol. The template argument \a
269         SocketPolicy must be set to the complete socket policy of the protocol.
270
271         A protocol implementation may define the protocol interface directly. It can also
272         (additionally) make use of multiple inheritance to combine a set of protocol facets into a
273         specific protocol implementation (i.e. TCPv4SocketProtocol inherits from
274         ConcreteSocketProtocol and from the protocol facets IPv4Protocol, TCPProtocol,
275         BSDSocketProtocol and AddressableBSDSocketProtocol). The protocol facets are not concrete
276         protocols themselves, they are combined to build concrete protocols. This structure will
277         remove a lot of code duplication. It is important to ensure, that the protocol facets do not
278         overlap, since otherwise there will be problems resolving overlapping members.
279         
280         \doc init_client init_server
281      */
282     template <class SocketPolicy, class Self>
283     class ConcreteSocketProtocol
284         : public virtual SocketProtocol
285     {
286     public:
287         ///////////////////////////////////////////////////////////////////////////
288         // Types
289
290         typedef SocketPolicy Policy;    ///< The protocols policy
291
292         ///////////////////////////////////////////////////////////////////////////
293         ///\name Structors and default members
294         ///@{
295
296         ~ConcreteSocketProtocol() = 0;
297
298         // no default constructor
299         // no copy
300         // no conversion constructors
301
302         ///@}
303         ///////////////////////////////////////////////////////////////////////////
304
305         Policy const & policy() const;
306         
307     protected:
308         ClientSocketHandle<Policy> clientHandle() const; 
309                                         ///< Get client handle for associated socket
310                                         /**< Returns a client handle for the socket associated with
311                                              this protocol instance */
312         ServerSocketHandle<Policy> serverHandle() const;
313                                         ///< Get server handle for associated socket
314                                         /**< Returns a server handle for the socket associated with
315                                              this protocol instance */
316
317     private:
318         virtual std::auto_ptr<SocketBody> clone(bool isServer) const;
319         virtual std::auto_ptr<SocketBody> clone(int fd, bool isServer) const;
320         virtual SocketBody & body() const;
321
322         Policy policy_;
323     };
324
325     /// @}
326 }
327
328 ///////////////////////////////hh.e////////////////////////////////////////
329 #include "SocketProtocol.cci"
330 //#include "SocketProtocol.ct"
331 #include "SocketProtocol.cti"
332 #endif
333
334 \f
335 // Local Variables:
336 // mode: c++
337 // fill-column: 100
338 // c-file-style: "senf"
339 // indent-tabs-mode: nil
340 // ispell-local-dictionary: "american"
341 // compile-command: "scons -u test"
342 // comment-column: 40
343 // End: