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