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