switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / PPI / SocketSink.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief SocketSink public header */
30
31 #ifndef HH_SENF_PPI_SocketSink_
32 #define HH_SENF_PPI_SocketSink_ 1
33
34 // Custom includes
35 #include <senf/Packets/Packets.hh>
36 #include <senf/Socket/ClientSocketHandle.hh>
37 #include <senf/Socket/SocketPolicy.hh>
38 #include <senf/Socket/ReadWritePolicy.hh>
39 #include <senf/Socket/FramingPolicy.hh>
40 #include <senf/Socket/CommunicationPolicy.hh>
41 #include "Module.hh"
42 #include "Connectors.hh"
43 #include <senf/Socket/Protocols/INet/INetAddressing.hh>
44 #include "IOEvent.hh"
45
46 //#include "SocketSink.mpp"
47 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48
49 namespace senf {
50 namespace ppi {
51
52     /** \brief Writer for module::ActiveSocketSink / module::PassiveSocketSink
53
54         This writer will write the packets completely as datagrams to the given socket which must be connected.
55      */
56     class ConnectedDgramWriter
57     {
58     public:
59         typedef senf::ClientSocketHandle<
60             senf::MakeSocketPolicy< senf::WriteablePolicy,
61                                     senf::DatagramFramingPolicy,
62                                     senf::ConnectedCommunicationPolicy>::policy > Handle;
63                                         ///< Handle type supported by this writer
64         typedef Packet PacketType;
65
66         bool operator()(Handle & handle, Packet const & packet);
67                                         ///< Write \a packet to \a handle
68                                         /**< Write the complete \a packet as a datagram to \a
69                                              handle.
70                                              \param[in] handle Handle to write data to
71                                              \param[in] packet Packet to write */
72     };
73
74     /** \brief Writer sending data with ClientSocketHandle::writeto()
75
76         This writer will send out data using ClientSocketHandle::writeto(). The target address can
77         be specified in the writer constructor and can be adjusted at any time.
78
79         If no target address is set, incoming data will be <em>silently dropped</em>.
80      */
81     template <class HandleType>
82     class TargetDgramWriter
83     {
84     public:
85         typedef HandleType Handle;
86         typedef Packet PacketType;
87
88         TargetDgramWriter();            ///< Create TargetDgramWriter with unset target address
89         TargetDgramWriter(typename Handle::Address const & target);
90                                         ///< Create TargetDgramWriter sending to \a target
91
92         typename Handle::Address target() const; ///< Get current target address
93         void target(typename Handle::Address const & target); ///< Set target address
94
95         bool operator()(Handle & handle, Packet const & packet); ///< Write \a packet to \a handle
96                                         /**< Write the complete \a packet as a datagram to \a
97                                              handle.
98                                              \param[in] handle Handle to write data to
99                                              \param[in] packet Packet to write */
100
101     private:
102         typename Handle::Address target_;
103     };
104
105     class IPv4SourceForcingDgramWriter : ConnectedDgramWriter
106     {
107     public:
108         IPv4SourceForcingDgramWriter();
109         IPv4SourceForcingDgramWriter(senf::INet4Address sourceAddr, senf::INet4SocketAddress destAddr);
110         typedef senf::ClientSocketHandle<
111             senf::MakeSocketPolicy< senf::WriteablePolicy,
112                                     senf::DatagramFramingPolicy>::policy > Handle;
113                                         ///< Handle type supported by this writer
114         typedef Packet PacketType;
115
116         void source(senf::INet4Address & source);
117         senf::INet4Address source();
118         void destination(senf::INet4SocketAddress & dest);
119         senf::INet4SocketAddress destination();
120
121         bool operator()(Handle & handle, Packet const & packet);
122                                         ///< Write \a packet to \a handle
123                                         /**< Write the complete \a packet as a datagram to \a
124                                              handle.
125                                              \param[in] handle Handle to write data to
126                                              \param[in] packet Packet to write */
127     private:
128         int sendtoandfrom(int sock, const void *data, size_t dataLen, const in_addr *dst, int port, const in_addr *src);
129         senf::INet4Address source_;
130         senf::INet4Address destination_;
131         unsigned int protocolId_;
132     };
133
134     class IPv6SourceForcingDgramWriter : ConnectedDgramWriter
135     {
136     public:
137         IPv6SourceForcingDgramWriter();
138         IPv6SourceForcingDgramWriter(senf::INet6Address sourceAddr, senf::INet6SocketAddress destAddr);
139         typedef senf::ClientSocketHandle<
140             senf::MakeSocketPolicy< senf::WriteablePolicy,
141                                     senf::DatagramFramingPolicy>::policy > Handle;
142                                         ///< Handle type supported by this writer
143         typedef Packet PacketType;
144
145         void source(senf::INet6Address & source);
146         senf::INet6Address source();
147         void destination(senf::INet6SocketAddress & dest);
148         senf::INet6SocketAddress destination();
149
150         bool operator()(Handle & handle, Packet const & packet);
151                                         ///< Write \a packet to \a handle
152                                         /**< Write the complete \a packet as a datagram to \a
153                                              handle.
154                                              \param[in] handle Handle to write data to
155                                              \param[in] packet Packet to write */
156     private:
157         int sendtoandfrom(int sock, const void *data, size_t dataLen, const in6_addr *dst, int port, const in6_addr *src);
158         senf::INet6Address source_;
159         senf::INet6Address destination_;
160         unsigned int protocolId_;
161 };
162
163
164 }}
165
166 namespace senf {
167 namespace ppi {
168 namespace module {
169
170     /** \brief Output %module writing data to a FileHandle using the provided Writer.
171         If using the default ConnectedDgramWriter the filehandle must be writable, connected and
172         able to handle complete datagrams.
173
174         This output %module will write data to a FileHandle object using a given \a Writer. This
175         output %module is active. This requires the file handle to be able to signal its readiness to
176         accept more data via the Scheduler.
177
178         The default \a Writer is senf::ppi::ConnectedDgramWriter which will write out the complete packet to
179         the file handle.
180
181         A \a Writer must fulfill the following interface:
182         \code
183           class SomeWriter
184           {
185           public:
186               typedef unspecified Handle;                          // type of handle requested
187               typedef unspecified_type PacketType                  // type of packet read
188
189               SomeWriter();                                        // EITHER default constructible OR
190               SomeWriter(SomeWriter const & other);                // copy constructible
191
192               bool operator()(Handle handle, Packet packet);       // insertion function
193           };
194         \endcode
195         Whenever a packet is received for sending, the \a Writer's \c operator() is called.
196
197         \ingroup io_modules
198      */
199     template <class Writer=ConnectedDgramWriter>
200     class ActiveSocketSink : public Module
201     {
202         SENF_PPI_MODULE(ActiveSocketSink);
203
204     public:
205         typedef typename Writer::Handle Handle; ///< Handle type requested by writer
206
207         connector::ActiveInput<typename Writer::PacketType> input; ///< Input connector from which data is received
208
209         ActiveSocketSink();             ///< Create non-connected writer
210                                         /**< The writer will be disabled until a socket is set
211                                              \pre Requires \a Writer to be default constructible */
212         explicit ActiveSocketSink(Writer const & writer);
213                                         ///< Create non-connected writer
214                                         /**< The writer will be disabled until a socket is set
215                                              \pre Requires \a Writer to be copy constructible
216                                              \param[in] writer Writer helper writing packet date to
217                                                  the socket */
218         explicit ActiveSocketSink(Handle const & handle);
219                                         ///< Create new writer for the given handle
220                                         /**< Data will be written to \a handle using \a Writer.
221                                              \pre Requires \a Writer to be default constructible
222                                              \param[in] handle Handle to write data to */
223         ActiveSocketSink(Handle const & handle, Writer const & writer);
224                                         ///< Create new writer for the given handle
225                                         /**< Data will be written to \a handle using \a Writer.
226                                              \pre Requires \a Writer to be copy constructible
227                                              \param[in] handle Handle to write data to
228                                              \param[in] writer Writer helper writing packet date to
229                                                  the socket */
230
231         Writer & writer();              ///< Access the Writer
232         Handle handle();                ///< Access handle
233         void handle(Handle const & handle);
234                                         ///< Set handle
235                                         /**< Assigning an empty or in-valid() handle will disable
236                                              the module until a new. valid handle is assigned. */
237
238     private:
239         void write();
240
241         Handle handle_;
242         IOEvent event_;
243         Writer writer_;
244     };
245
246     /** \brief Output module writing data to a FileHandle using the provided \a Writer.
247         If using the default ConnectedDgramWriter the filehandle must be writable, connected and
248         able to handle complete datagrams.
249
250         This output module will write data to a FileHandle object using a given \a Writer. This
251         output module is passive. This implies, that <em>the output handle may not block</em>. This
252         also implies, that data will probably get lost if written to fast for the underlying
253         transport mechanism. Either this is desired (like for a UDP socket) or some additional
254         bandwidth shaping needs to be used.
255
256         The default \a Writer is senf::ppi::ConnectedDgramWriter which will write out the complete packet to
257         the file handle.
258
259         The \a Writer must fulfill the following interface:
260         \code
261           class SomeWriter
262           {
263           public:
264               typedef unspecified Handle;                          // type of handle requested
265               typedef unspecified_type PacketType                  // type of packet read
266
267               SomeWriter();                                          // EITHER default constructible
268               SomeWriter(SomeWriter const & other);                    // OR copy constructible
269
270               bool operator()(Handle handle, Packet packet);       // insertion function
271           };
272         \endcode
273         Whenever a packet is received for sending, the \a Writer's \c operator() is called.
274
275         \ingroup io_modules
276      */
277     template <class Writer=ConnectedDgramWriter>
278     class PassiveSocketSink : public Module
279     {
280         SENF_PPI_MODULE(PassiveSocketSink);
281
282     public:
283         typedef typename Writer::Handle Handle; ///< Handle type requested by writer
284
285         connector::PassiveInput<typename Writer::PacketType> input; ///< Input connector from which data is received
286
287         PassiveSocketSink();            ///< Create non-connected writer
288                                         /**< The writer will be disabled until a socket is set
289                                              \pre Requires \a Writer to be default constructible */
290         explicit PassiveSocketSink(Writer const & writer);
291                                         ///< Create non-connected writer
292                                         /**< The writer will be disabled until a socket is set
293                                              \pre Requires \a Writer to be copy constructible
294                                              \param[in] writer Writer helper writing packet date to
295                                                  the socket */
296         explicit PassiveSocketSink(Handle const & handle);
297                                         ///< Create new writer for the given handle
298                                         /**< Data will be written to \a handle using \a Writer.
299                                              \pre Requires \a Writer to be default constructible
300                                              \param[in] handle Handle to write data to */
301         PassiveSocketSink(Handle const & handle, Writer const & writer);
302                                         ///< Create new writer for the given handle
303                                         /**< Data will be written to \a handle using \a Writer.
304                                              \pre Requires \a Writer to be copy constructible
305                                              \param[in] handle Handle to write data to
306                                              \param[in] writer Writer helper writing packet date to
307                                                  the socket */
308
309         Writer & writer();              ///< Access the Writer
310         Handle & handle();              ///< Access handle
311         void handle(Handle const & handle);
312                                         ///< Set handle
313                                         /**< Assigning an empty or in-valid() handle will disable
314                                              the module until a new valid handle is assigned. */
315
316 #ifndef DOXYGEN
317         void replaceHandle(Handle newHandle);
318 #endif
319
320     private:
321         void write();
322         void checkThrottle();
323
324         Handle handle_;
325         Writer writer_;
326     };
327
328 }}}
329
330
331 //-/////////////////////////////////////////////////////////////////////////////////////////////////
332 #include "SocketSink.cci"
333 #include "SocketSink.ct"
334 #include "SocketSink.cti"
335 #endif
336
337 \f
338 // Local Variables:
339 // mode: c++
340 // fill-column: 100
341 // c-file-style: "senf"
342 // indent-tabs-mode: nil
343 // ispell-local-dictionary: "american"
344 // compile-command: "scons -u test"
345 // comment-column: 40
346 // End: