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