1/*
2 * util/tube.h - pipe service
3 *
4 * Copyright (c) 2008, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/**
37 * \file
38 *
39 * This file contains pipe service functions.
40 */
41
42#ifndef UTIL_TUBE_H
43#define UTIL_TUBE_H
44struct comm_reply;
45struct comm_point;
46struct comm_base;
47struct tube;
48struct tube_res_list;
49#ifdef USE_WINSOCK
50#include "util/locks.h"
51#endif
52
53/**
54 * Callback from pipe listen function
55 * void mycallback(tube, msg, len, error, user_argument);
56 * if error is true (NETEVENT_*), msg is probably NULL.
57 */
58typedef void tube_callback_type(struct tube*, uint8_t*, size_t, int, void*);
59
60/**
61 * A pipe
62 */
63struct tube {
64#ifndef USE_WINSOCK
65	/** pipe end to read from */
66	int sr;
67	/** pipe end to write on */
68	int sw;
69
70	/** listen commpoint */
71	struct comm_point* listen_com;
72	/** listen callback */
73	tube_callback_type* listen_cb;
74	/** listen callback user arg */
75	void* listen_arg;
76	/** are we currently reading a command, 0 if not, else bytecount */
77	size_t cmd_read;
78	/** size of current read command, may be partially read */
79	uint32_t cmd_len;
80	/** the current read command content, malloced, can be partially read*/
81	uint8_t* cmd_msg;
82
83	/** background write queue, commpoint to write results back */
84	struct comm_point* res_com;
85	/** are we currently writing a result, 0 if not, else bytecount into
86	 * the res_list first entry. */
87	size_t res_write;
88	/** list of outstanding results to be written back */
89	struct tube_res_list* res_list;
90	/** last in list */
91	struct tube_res_list* res_last;
92
93#else /* USE_WINSOCK */
94	/** listen callback */
95	tube_callback_type* listen_cb;
96	/** listen callback user arg */
97	void* listen_arg;
98	/** the windows sockets event (signaled if items in pipe) */
99	WSAEVENT event;
100	/** winsock event storage when registered with event base */
101	struct ub_event* ev_listen;
102
103	/** lock on the list of outstanding items */
104	lock_basic_type res_lock;
105	/** list of outstanding results on pipe */
106	struct tube_res_list* res_list;
107	/** last in list */
108	struct tube_res_list* res_last;
109#endif /* USE_WINSOCK */
110};
111
112/**
113 * List of results (arbitrary command serializations) to write back
114 */
115struct tube_res_list {
116	/** next in list */
117	struct tube_res_list* next;
118	/** serialized buffer to write */
119	uint8_t* buf;
120	/** length to write */
121	uint32_t len;
122};
123
124/**
125 * Create a pipe
126 * @return: new tube struct or NULL on error.
127 */
128struct tube* tube_create(void);
129
130/**
131 * Delete and destroy a pipe
132 * @param tube: to delete
133 */
134void tube_delete(struct tube* tube);
135
136/**
137 * Write length bytes followed by message.
138 * @param tube: the tube to write on.
139 *     If that tube is a pipe, its write fd is used as
140 *     the socket to write on. Is nonblocking.
141 *      Set to blocking by the function,
142 *      and back to non-blocking at exit of function.
143 * @param buf: the message.
144 * @param len: length of message.
145 * @param nonblock: if set to true, the first write is nonblocking.
146 *      If the first write fails the function returns -1.
147 *      If set false, the first write is blocking.
148 * @return: all remainder writes are nonblocking.
149 *      return 0 on error, in that case blocking/nonblocking of socket is
150 *              unknown.
151 *      return 1 if all OK.
152 */
153int tube_write_msg(struct tube* tube, uint8_t* buf, uint32_t len,
154	int nonblock);
155
156/**
157 * Read length bytes followed by message.
158 * @param tube: The tube to read on.
159 *     If that tube is a pipe, its read fd is used as
160 *     the socket to read on. Is nonblocking.
161 *      Set to blocking by the function,
162 *      and back to non-blocking at exit of function.
163 * @param buf: the message, malloced.
164 * @param len: length of message, returned.
165 * @param nonblock: if set to true, the first read is nonblocking.
166 *      If the first read fails the function returns -1.
167 *      If set false, the first read is blocking.
168 * @return: all remainder reads are nonblocking.
169 *      return 0 on error, in that case blocking/nonblocking of socket is
170 *              unknown. On EOF 0 is returned.
171 *      return 1 if all OK.
172 */
173int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len,
174	int nonblock);
175
176/**
177 * Close read part of the pipe.
178 * The tube can no longer be read from.
179 * @param tube: tube to operate on.
180 */
181void tube_close_read(struct tube* tube);
182
183/**
184 * Close write part of the pipe.
185 * The tube can no longer be written to.
186 * @param tube: tube to operate on.
187 */
188void tube_close_write(struct tube* tube);
189
190/**
191 * See if data is ready for reading on the tube without blocking.
192 * @param tube: tube to check for readable items
193 * @return true if readable items are present. False if not (or error).
194 *     true on pipe_closed.
195 */
196int tube_poll(struct tube* tube);
197
198/**
199 * Wait for data to be ready for reading on the tube. is blocking.
200 * No timeout.
201 * @param tube: the tube to wait on.
202 * @return: if there was something to read (false on error).
203 *     true on pipe_closed.
204 */
205int tube_wait(struct tube* tube);
206
207/**
208 * Wait for data to be ready with a timeout.
209 * @param tube: the tube to wait on.
210 * @param msec: timeout in milliseconds.
211 * @return 1 if there is something to read within timeout, readability.
212 * 	0 on a timeout. On failures -1, like errors. */
213int tube_wait_timeout(struct tube* tube, int msec);
214
215/**
216 * Get FD that is readable when new information arrives.
217 * @param tube
218 * @return file descriptor.
219 */
220int tube_read_fd(struct tube* tube);
221
222/**
223 * Start listening for information over the pipe.
224 * Background registration of a read listener, callback when read completed.
225 * Do not mix with tube_read_msg style direct reads from the pipe.
226 * @param tube: tube to listen on
227 * @param base: what base to register event callback.
228 * @param cb: callback routine.
229 * @param arg: user argument for callback routine.
230 * @return true if successful, false on error.
231 */
232int tube_setup_bg_listen(struct tube* tube, struct comm_base* base,
233	tube_callback_type* cb, void* arg);
234
235/**
236 * Remove bg listen setup from event base.
237 * @param tube: what tube to cleanup
238 */
239void tube_remove_bg_listen(struct tube* tube);
240
241/**
242 * Start background write handler for the pipe.
243 * Do not mix with tube_write_msg style direct writes to the pipe.
244 * @param tube: tube to write on
245 * @param base: what base to register event handler on.
246 * @return true if successful, false on error.
247 */
248int tube_setup_bg_write(struct tube* tube, struct comm_base* base);
249
250/**
251 * Remove bg write setup from event base.
252 * @param tube: what tube to cleanup
253 */
254void tube_remove_bg_write(struct tube* tube);
255
256
257/**
258 * Append data item to background list of writes.
259 * Mallocs a list entry behind the scenes.
260 * Not locked behind the scenes, call from one thread or lock on outside.
261 * @param tube: what tube to queue on.
262 * @param msg: memory message to send. Is free()d after use.
263 * 	Put at the end of the to-send queue.
264 * @param len: length of item.
265 * @return 0 on failure (msg freed).
266 */
267int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len);
268
269/** for fptr wlist, callback function */
270int tube_handle_listen(struct comm_point* c, void* arg, int error,
271	struct comm_reply* reply_info);
272
273/** for fptr wlist, callback function */
274int tube_handle_write(struct comm_point* c, void* arg, int error,
275	struct comm_reply* reply_info);
276
277/** for fptr wlist, winsock signal event callback function */
278void tube_handle_signal(int fd, short events, void* arg);
279
280#endif /* UTIL_TUBE_H */
281