938a4e7d37833ca76c7aef1b9c37b839f01bfaff
[oonf.git] / include / oonf / subsystems / oonf_stream_socket.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #ifndef OONF_STREAM_SOCKET_H_
47 #define OONF_STREAM_SOCKET_H_
48
49 #include <oonf/libcommon/autobuf.h>
50 #include <oonf/oonf.h>
51 #include <oonf/libcommon/list.h>
52 #include <oonf/libcommon/netaddr.h>
53 #include <oonf/libcommon/netaddr_acl.h>
54
55 #include <oonf/subsystems/oonf_class.h>
56 #include <oonf/subsystems/oonf_socket.h>
57 #include <oonf/subsystems/oonf_timer.h>
58 #include <oonf/subsystems/os_interface.h>
59
60 /*! subsystem identifier */
61 #define OONF_STREAM_SUBSYSTEM "stream_socket"
62
63 /**
64  * TCP session states
65  */
66 enum oonf_stream_session_state
67 {
68   /*! tcp session has not been initialized */
69   STREAM_SESSION_INACTIVE,
70
71   /*! tcp session is active */
72   STREAM_SESSION_ACTIVE,
73
74   /*! tcp session will send its current buffer content and terminate */
75   STREAM_SESSION_SEND_AND_QUIT,
76
77   /*! tcp session will terminate */
78   STREAM_SESSION_CLEANUP,
79 };
80
81 /**
82  * generic stream errors useful for HTTP and telnet
83  */
84 enum oonf_stream_errors
85 {
86   /*! remote endpoint is not permitted to use service */
87   STREAM_REQUEST_FORBIDDEN = 403,
88
89   /*! input buffer overflow */
90   STREAM_REQUEST_TOO_LARGE = 413,
91
92   /*! too many incoming sessions */
93   STREAM_SERVICE_UNAVAILABLE = 503,
94 };
95
96 /**
97  * TCP stream socket
98  */
99 struct oonf_stream_session {
100   /*! ip addr of peer */
101   struct netaddr remote_address;
102
103   /*! full socket (ip, port, maybe interface) of peer */
104   union netaddr_socket remote_socket;
105
106   /**
107    * output buffer, anything inside will be written to the peer as
108    * soon as possible
109    */
110   struct autobuf out;
111
112   /**
113    * file input descriptor for file upload
114    *
115    * will only be used in SEND_AND_QUIT state if out buffer is empty
116    */
117   struct os_fd copy_fd;
118
119   /*! name of socket */
120   char socket_name[sizeof(struct netaddr_str) * 2 + 10];
121
122   /*! number of bytes already copied in file upload */
123   size_t copy_bytes_sent;
124
125   /*! total number of bytes to copy for file upload */
126   size_t copy_total_size;
127
128   /*! hook into list of tcp sessions of TCP socket */
129   struct list_entity node;
130
131   /*! backpointer to the stream socket */
132   struct oonf_stream_socket *stream_socket;
133
134   /*! scheduler handler for the session */
135   struct oonf_socket_entry scheduler_entry;
136
137   /*! timer for handling session timeout */
138   struct oonf_timer_instance timeout;
139
140   /*! input buffer for session */
141   struct autobuf in;
142
143   /**
144    * true if session user want to send before receiving anything. Will trigger
145    * an empty read even as soon as session is connected
146    */
147   bool send_first;
148
149   /*! true if session is still waiting for initial handshake to finish */
150   bool wait_for_connect;
151
152   /*! session event is just busy in scheduler */
153   bool busy;
154
155   /*! session has been remove while being busy */
156   bool removed;
157
158   /*! state of the session */
159   enum oonf_stream_session_state state;
160 };
161
162 /**
163  * Configuration of a stream socket
164  */
165 struct oonf_stream_config {
166   /**
167    * memory cookie to allocate struct for tcp session
168    * the first part of this memory will be a tcp_steam_session!
169    */
170   struct oonf_class *memcookie;
171
172   /*! number of simultaneous sessions (default 10) */
173   int allowed_sessions;
174
175   /**
176    * Timeout of the socket. A session will be closed if it does not
177    * send or receive data for timeout milliseconds.
178    */
179   uint64_t session_timeout;
180
181   /*! maximum allowed size of input buffer (default 65536) */
182   size_t maximum_input_buffer;
183
184   /**
185    * true if the socket wants to send data before it receives anything.
186    * This will trigger an size 0 read event as soon as the socket is connected
187    */
188   bool send_first;
189
190   /*! only clients that match the acl (if set) can connect */
191   struct netaddr_acl *acl;
192
193   /**
194    * Callback to notify that a new session has been created
195    * @param session stream session
196    * @return -1 if an error happened, 0 otherwise
197    */
198   int (*init_session)(struct oonf_stream_session *session);
199
200   /**
201    * Callback to notify that a stream session will be terminated
202    * @param session stream session
203    */
204   void (*cleanup_session)(struct oonf_stream_session *session);
205
206   /**
207    * Callback to notify that the socket has been terminated
208    * @param socket terminated stream socket
209    */
210   void (*cleanup_socket)(struct oonf_stream_socket *stream_socket);
211
212   /**
213    * Callback to notify that an error happened and the user might
214    * want to put an error message in the output buffer.
215    * @param session stream session
216    * @param error tcp stream error code
217    */
218   void (*create_error)(struct oonf_stream_session *session, enum oonf_stream_errors error);
219
220   /**
221    * Callback that is called every times no data has been written
222    * into the input buffer
223    * @param stream stream session
224    * @return stream session status code
225    */
226   enum oonf_stream_session_state (*receive_data)(struct oonf_stream_session *stream);
227
228   /*
229    * Called when we could write to the buffer but it is empty
230    */
231   /**
232    * Callback to notify that the user asked scheduler to write
233    * data, but outgoing buffer is empty
234    * @param session stream session
235    * @return stream session status code
236    */
237   enum oonf_stream_session_state (*buffer_underrun)(struct oonf_stream_session *session);
238 };
239
240 /**
241  * Represents a TCP server socket or a configuration for a set of outgoing
242  * TCP streams.
243  */
244 struct oonf_stream_socket {
245   /*! hook into global list of TCP sockets */
246   struct list_entity _node;
247
248   /*! local address/port of socket */
249   union netaddr_socket local_socket;
250
251   /*! list of open sessions of this socket */
252   struct list_entity session;
253
254   /*! scheduler for handling server socket */
255   struct oonf_socket_entry scheduler_entry;
256
257   /*! configuration of server socket */
258   struct oonf_stream_config config;
259
260   /*! optional back pointer for managed tcp sockets */
261   struct oonf_stream_managed *managed;
262
263   /*! name of socket */
264   char socket_name[sizeof(struct netaddr_str) + 14];
265
266   /*! number of currently active sessions */
267   int32_t session_counter;
268
269   /*! true if socket is currently busy in scheduler */
270   bool busy;
271
272   /*! true if socket should be removed */
273   bool remove;
274
275   /*! true if socket should be removed when output buffer is empty */
276   bool remove_when_finished;
277 };
278
279 /**
280  * configuration of a managed dualstack TCP server socket
281  */
282 struct oonf_stream_managed_config {
283   /*! access control for IP addresses allowed to access the socket */
284   struct netaddr_acl acl;
285
286   /*! interface to bind to socket to, empty string for "all interfaces" */
287   char interface[IF_NAMESIZE];
288
289   /*! ACL for selecting the address to bind the socket to */
290   struct netaddr_acl bindto;
291
292   /*! port number for TCP server socket, 0 for random port */
293   int32_t port;
294 };
295
296 /**
297  * managed dualstack TCP server socket
298  */
299 struct oonf_stream_managed {
300   /*! stream socket for IPv4 */
301   struct oonf_stream_socket socket_v4;
302
303   /*! stream socket for IPv6 */
304   struct oonf_stream_socket socket_v6;
305
306   /*! configuration for both stream sockets */
307   struct oonf_stream_config config;
308
309   /*! configuration of managed socket */
310   struct oonf_stream_managed_config _managed_config;
311
312   /*! listener to interface the socket is bound to */
313   struct os_interface_listener _if_listener;
314 };
315
316 EXPORT int oonf_stream_add(struct oonf_stream_socket *, const union netaddr_socket *local);
317 EXPORT void oonf_stream_remove(struct oonf_stream_socket *, bool force);
318 EXPORT void oonf_stream_close_all_sessions(struct oonf_stream_socket *stream_socket);
319 EXPORT struct oonf_stream_session *oonf_stream_connect_to(
320   struct oonf_stream_socket *, const union netaddr_socket *remote);
321 EXPORT void oonf_stream_flush(struct oonf_stream_session *con);
322
323 EXPORT void oonf_stream_set_timeout(struct oonf_stream_session *con, uint64_t timeout);
324 EXPORT void oonf_stream_close(struct oonf_stream_session *con);
325
326 EXPORT void oonf_stream_add_managed(struct oonf_stream_managed *);
327 EXPORT int oonf_stream_apply_managed(struct oonf_stream_managed *, struct oonf_stream_managed_config *);
328 EXPORT void oonf_stream_remove_managed(struct oonf_stream_managed *, bool force);
329 EXPORT void oonf_stream_close_all_managed_sessions(struct oonf_stream_managed *managed);
330 EXPORT void oonf_stream_copy_managed_config(
331   struct oonf_stream_managed_config *dst, struct oonf_stream_managed_config *src);
332 EXPORT void oonf_stream_free_managed_config(struct oonf_stream_managed_config *config);
333
334 #endif /* OONF_STREAM_SOCKET_H_ */