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