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