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