xref: /freebsd/contrib/unbound/util/tube.h (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
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
44 struct comm_reply;
45 struct comm_point;
46 struct comm_base;
47 struct tube;
48 struct 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  */
58 typedef void tube_callback_type(struct tube*, uint8_t*, size_t, int, void*);
59 
60 /**
61  * A pipe
62  */
63 struct 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  */
115 struct 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  */
128 struct tube* tube_create(void);
129 
130 /**
131  * Delete and destroy a pipe
132  * @param tube: to delete
133  */
134 void 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  */
153 int 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  */
173 int 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  */
181 void 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  */
188 void 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  */
196 int 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  */
205 int 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. */
213 int 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  */
220 int 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  */
232 int 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  */
239 void 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  */
248 int 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  */
254 void 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  */
267 int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len);
268 
269 /** for fptr wlist, callback function */
270 int tube_handle_listen(struct comm_point* c, void* arg, int error,
271 	struct comm_reply* reply_info);
272 
273 /** for fptr wlist, callback function */
274 int 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 */
278 void tube_handle_signal(int fd, short events, void* arg);
279 
280 #endif /* UTIL_TUBE_H */
281