tube.h revision 292206
1184299Snwhitehorn/*
2184299Snwhitehorn * util/tube.h - pipe service
3184299Snwhitehorn *
4184299Snwhitehorn * Copyright (c) 2008, NLnet Labs. All rights reserved.
5184299Snwhitehorn *
6184299Snwhitehorn * This software is open source.
7184299Snwhitehorn *
8184299Snwhitehorn * Redistribution and use in source and binary forms, with or without
9184299Snwhitehorn * modification, are permitted provided that the following conditions
10184299Snwhitehorn * are met:
11184299Snwhitehorn *
12184299Snwhitehorn * Redistributions of source code must retain the above copyright notice,
13184299Snwhitehorn * this list of conditions and the following disclaimer.
14184299Snwhitehorn *
15184299Snwhitehorn * Redistributions in binary form must reproduce the above copyright notice,
16184299Snwhitehorn * this list of conditions and the following disclaimer in the documentation
17184299Snwhitehorn * and/or other materials provided with the distribution.
18184299Snwhitehorn *
19184299Snwhitehorn * Neither the name of the NLNET LABS nor the names of its contributors may
20184299Snwhitehorn * be used to endorse or promote products derived from this software without
21184299Snwhitehorn * specific prior written permission.
22184299Snwhitehorn *
23184299Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24184299Snwhitehorn * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25184299Snwhitehorn * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26184299Snwhitehorn * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27184299Snwhitehorn * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28184299Snwhitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29184299Snwhitehorn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30184299Snwhitehorn * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31184299Snwhitehorn * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32184299Snwhitehorn * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33184299Snwhitehorn * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34184299Snwhitehorn */
35184299Snwhitehorn
36184299Snwhitehorn/**
37184299Snwhitehorn * \file
38273009Sjhibbits *
39205506Snwhitehorn * This file contains pipe service functions.
40259284Sjhibbits */
41212054Snwhitehorn
42185727Snwhitehorn#ifndef UTIL_TUBE_H
43184299Snwhitehorn#define UTIL_TUBE_H
44184299Snwhitehornstruct comm_reply;
45184299Snwhitehornstruct comm_point;
46185782Snwhitehornstruct comm_base;
47184299Snwhitehornstruct tube;
48259284Sjhibbitsstruct tube_res_list;
49184299Snwhitehorn#ifdef USE_WINSOCK
50259284Sjhibbits#include "util/locks.h"
51259284Sjhibbits#include "util/winsock_event.h"
52184299Snwhitehorn#endif
53184299Snwhitehorn
54259284Sjhibbits/**
55184299Snwhitehorn * Callback from pipe listen function
56184299Snwhitehorn * void mycallback(tube, msg, len, error, user_argument);
57184299Snwhitehorn * if error is true (NETEVENT_*), msg is probably NULL.
58184299Snwhitehorn */
59184299Snwhitehorntypedef void tube_callback_t(struct tube*, uint8_t*, size_t, int, void*);
60184299Snwhitehorn
61184299Snwhitehorn/**
62184299Snwhitehorn * A pipe
63184299Snwhitehorn */
64184299Snwhitehornstruct tube {
65205506Snwhitehorn#ifndef USE_WINSOCK
66184299Snwhitehorn	/** pipe end to read from */
67184299Snwhitehorn	int sr;
68259284Sjhibbits	/** pipe end to write on */
69184299Snwhitehorn	int sw;
70259284Sjhibbits
71259284Sjhibbits	/** listen commpoint */
72259284Sjhibbits	struct comm_point* listen_com;
73259284Sjhibbits	/** listen callback */
74184299Snwhitehorn	tube_callback_t* listen_cb;
75205506Snwhitehorn	/** listen callback user arg */
76184299Snwhitehorn	void* listen_arg;
77184299Snwhitehorn	/** are we currently reading a command, 0 if not, else bytecount */
78184299Snwhitehorn	size_t cmd_read;
79184299Snwhitehorn	/** size of current read command, may be partially read */
80184299Snwhitehorn	uint32_t cmd_len;
81205506Snwhitehorn	/** the current read command content, malloced, can be partially read*/
82205506Snwhitehorn	uint8_t* cmd_msg;
83205506Snwhitehorn
84205506Snwhitehorn	/** background write queue, commpoint to write results back */
85205506Snwhitehorn	struct comm_point* res_com;
86205506Snwhitehorn	/** are we currently writing a result, 0 if not, else bytecount into
87205506Snwhitehorn	 * the res_list first entry. */
88205506Snwhitehorn	size_t res_write;
89205506Snwhitehorn	/** list of outstanding results to be written back */
90205506Snwhitehorn	struct tube_res_list* res_list;
91185727Snwhitehorn	/** last in list */
92185754Snwhitehorn	struct tube_res_list* res_last;
93185727Snwhitehorn
94194027Savg#else /* USE_WINSOCK */
95185754Snwhitehorn	/** listen callback */
96212054Snwhitehorn	tube_callback_t* listen_cb;
97212054Snwhitehorn	/** listen callback user arg */
98212054Snwhitehorn	void* listen_arg;
99212054Snwhitehorn	/** the windows sockets event (signaled if items in pipe) */
100212054Snwhitehorn	WSAEVENT event;
101185782Snwhitehorn	/** winsock event storage when registered with event base */
102185727Snwhitehorn	struct event ev_listen;
103193159Snwhitehorn
104185754Snwhitehorn	/** lock on the list of outstanding items */
105185754Snwhitehorn	lock_basic_t res_lock;
106185754Snwhitehorn	/** list of outstanding results on pipe */
107273113Sjhibbits	struct tube_res_list* res_list;
108273113Sjhibbits	/** last in list */
109273113Sjhibbits	struct tube_res_list* res_last;
110273113Sjhibbits#endif /* USE_WINSOCK */
111184299Snwhitehorn};
112185754Snwhitehorn
113185754Snwhitehorn/**
114185754Snwhitehorn * List of results (arbitrary command serializations) to write back
115185754Snwhitehorn */
116185754Snwhitehornstruct tube_res_list {
117185754Snwhitehorn	/** next in list */
118185754Snwhitehorn	struct tube_res_list* next;
119185754Snwhitehorn	/** serialized buffer to write */
120185754Snwhitehorn	uint8_t* buf;
121185754Snwhitehorn	/** length to write */
122185754Snwhitehorn	uint32_t len;
123185754Snwhitehorn};
124185754Snwhitehorn
125185754Snwhitehorn/**
126185754Snwhitehorn * Create a pipe
127184299Snwhitehorn * @return: new tube struct or NULL on error.
128184299Snwhitehorn */
129184299Snwhitehornstruct tube* tube_create(void);
130184299Snwhitehorn
131184299Snwhitehorn/**
132184299Snwhitehorn * Delete and destroy a pipe
133184299Snwhitehorn * @param tube: to delete
134184299Snwhitehorn */
135184299Snwhitehornvoid tube_delete(struct tube* tube);
136184299Snwhitehorn
137184299Snwhitehorn/**
138184299Snwhitehorn * Write length bytes followed by message.
139205506Snwhitehorn * @param tube: the tube to write on.
140205506Snwhitehorn *     If that tube is a pipe, its write fd is used as
141205506Snwhitehorn *     the socket to write on. Is nonblocking.
142205506Snwhitehorn *      Set to blocking by the function,
143227843Smarius *      and back to non-blocking at exit of function.
144184299Snwhitehorn * @param buf: the message.
145184299Snwhitehorn * @param len: length of message.
146184299Snwhitehorn * @param nonblock: if set to true, the first write is nonblocking.
147184299Snwhitehorn *      If the first write fails the function returns -1.
148184299Snwhitehorn *      If set false, the first write is blocking.
149184299Snwhitehorn * @return: all remainder writes are nonblocking.
150184299Snwhitehorn *      return 0 on error, in that case blocking/nonblocking of socket is
151184299Snwhitehorn *              unknown.
152184299Snwhitehorn *      return 1 if all OK.
153184299Snwhitehorn */
154184299Snwhitehornint tube_write_msg(struct tube* tube, uint8_t* buf, uint32_t len,
155184299Snwhitehorn	int nonblock);
156184299Snwhitehorn
157184299Snwhitehorn/**
158184299Snwhitehorn * Read length bytes followed by message.
159184299Snwhitehorn * @param tube: The tube to read on.
160184299Snwhitehorn *     If that tube is a pipe, its read fd is used as
161184299Snwhitehorn *     the socket to read on. Is nonblocking.
162184299Snwhitehorn *      Set to blocking by the function,
163184299Snwhitehorn *      and back to non-blocking at exit of function.
164184299Snwhitehorn * @param buf: the message, malloced.
165184299Snwhitehorn * @param len: length of message, returned.
166184299Snwhitehorn * @param nonblock: if set to true, the first read is nonblocking.
167184299Snwhitehorn *      If the first read fails the function returns -1.
168184299Snwhitehorn *      If set false, the first read is blocking.
169184299Snwhitehorn * @return: all remainder reads are nonblocking.
170184299Snwhitehorn *      return 0 on error, in that case blocking/nonblocking of socket is
171184299Snwhitehorn *              unknown. On EOF 0 is returned.
172184299Snwhitehorn *      return 1 if all OK.
173184299Snwhitehorn */
174184299Snwhitehornint tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len,
175184299Snwhitehorn	int nonblock);
176184299Snwhitehorn
177184299Snwhitehorn/**
178184299Snwhitehorn * Close read part of the pipe.
179184299Snwhitehorn * The tube can no longer be read from.
180184299Snwhitehorn * @param tube: tube to operate on.
181184299Snwhitehorn */
182184299Snwhitehornvoid tube_close_read(struct tube* tube);
183184299Snwhitehorn
184184299Snwhitehorn/**
185184299Snwhitehorn * Close write part of the pipe.
186184299Snwhitehorn * The tube can no longer be written to.
187184299Snwhitehorn * @param tube: tube to operate on.
188184299Snwhitehorn */
189184299Snwhitehornvoid tube_close_write(struct tube* tube);
190184299Snwhitehorn
191184299Snwhitehorn/**
192184299Snwhitehorn * See if data is ready for reading on the tube without blocking.
193184299Snwhitehorn * @param tube: tube to check for readable items
194184299Snwhitehorn * @return true if readable items are present. False if not (or error).
195184299Snwhitehorn *     true on pipe_closed.
196184299Snwhitehorn */
197184299Snwhitehornint tube_poll(struct tube* tube);
198184299Snwhitehorn
199184299Snwhitehorn/**
200184299Snwhitehorn * Wait for data to be ready for reading on the tube. is blocking.
201184299Snwhitehorn * No timeout.
202184299Snwhitehorn * @param tube: the tube to wait on.
203184299Snwhitehorn * @return: if there was something to read (false on error).
204184299Snwhitehorn *     true on pipe_closed.
205184299Snwhitehorn */
206184299Snwhitehornint tube_wait(struct tube* tube);
207184299Snwhitehorn
208184299Snwhitehorn/**
209259284Sjhibbits * Get FD that is readable when new information arrives.
210184299Snwhitehorn * @param tube
211184299Snwhitehorn * @return file descriptor.
212184299Snwhitehorn */
213184299Snwhitehornint tube_read_fd(struct tube* tube);
214184299Snwhitehorn
215184299Snwhitehorn/**
216184299Snwhitehorn * Start listening for information over the pipe.
217184299Snwhitehorn * Background registration of a read listener, callback when read completed.
218184299Snwhitehorn * Do not mix with tube_read_msg style direct reads from the pipe.
219184299Snwhitehorn * @param tube: tube to listen on
220184299Snwhitehorn * @param base: what base to register event callback.
221184299Snwhitehorn * @param cb: callback routine.
222184299Snwhitehorn * @param arg: user argument for callback routine.
223184299Snwhitehorn * @return true if successful, false on error.
224184299Snwhitehorn */
225184299Snwhitehornint tube_setup_bg_listen(struct tube* tube, struct comm_base* base,
226184299Snwhitehorn	tube_callback_t* cb, void* arg);
227184299Snwhitehorn
228184299Snwhitehorn/**
229184299Snwhitehorn * Remove bg listen setup from event base.
230184299Snwhitehorn * @param tube: what tube to cleanup
231184299Snwhitehorn */
232184299Snwhitehornvoid tube_remove_bg_listen(struct tube* tube);
233184299Snwhitehorn
234184299Snwhitehorn/**
235184299Snwhitehorn * Start background write handler for the pipe.
236184299Snwhitehorn * Do not mix with tube_write_msg style direct writes to the pipe.
237184299Snwhitehorn * @param tube: tube to write on
238184299Snwhitehorn * @param base: what base to register event handler on.
239184299Snwhitehorn * @return true if successful, false on error.
240184299Snwhitehorn */
241184299Snwhitehornint tube_setup_bg_write(struct tube* tube, struct comm_base* base);
242184299Snwhitehorn
243184299Snwhitehorn/**
244184299Snwhitehorn * Remove bg write setup from event base.
245259284Sjhibbits * @param tube: what tube to cleanup
246184299Snwhitehorn */
247184299Snwhitehornvoid tube_remove_bg_write(struct tube* tube);
248184299Snwhitehorn
249184299Snwhitehorn
250184299Snwhitehorn/**
251184299Snwhitehorn * Append data item to background list of writes.
252184299Snwhitehorn * Mallocs a list entry behind the scenes.
253184299Snwhitehorn * Not locked behind the scenes, call from one thread or lock on outside.
254184299Snwhitehorn * @param tube: what tube to queue on.
255184299Snwhitehorn * @param msg: memory message to send. Is free()d after use.
256184299Snwhitehorn * 	Put at the end of the to-send queue.
257184299Snwhitehorn * @param len: length of item.
258184299Snwhitehorn * @return 0 on failure (msg freed).
259184299Snwhitehorn */
260184299Snwhitehornint tube_queue_item(struct tube* tube, uint8_t* msg, size_t len);
261184299Snwhitehorn
262184299Snwhitehorn/** for fptr wlist, callback function */
263184299Snwhitehornint tube_handle_listen(struct comm_point* c, void* arg, int error,
264273113Sjhibbits	struct comm_reply* reply_info);
265273009Sjhibbits
266273009Sjhibbits/** for fptr wlist, callback function */
267273009Sjhibbitsint tube_handle_write(struct comm_point* c, void* arg, int error,
268273009Sjhibbits	struct comm_reply* reply_info);
269273009Sjhibbits
270273009Sjhibbits/** for fptr wlist, winsock signal event callback function */
271273009Sjhibbitsvoid tube_handle_signal(int fd, short events, void* arg);
272184299Snwhitehorn
273184299Snwhitehorn#endif /* UTIL_TUBE_H */
274184299Snwhitehorn