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