1 1.1 christos /* 2 1.1 christos * util/tube.h - pipe service 3 1.1 christos * 4 1.1 christos * Copyright (c) 2008, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * This software is open source. 7 1.1 christos * 8 1.1 christos * Redistribution and use in source and binary forms, with or without 9 1.1 christos * modification, are permitted provided that the following conditions 10 1.1 christos * are met: 11 1.1 christos * 12 1.1 christos * Redistributions of source code must retain the above copyright notice, 13 1.1 christos * this list of conditions and the following disclaimer. 14 1.1 christos * 15 1.1 christos * Redistributions in binary form must reproduce the above copyright notice, 16 1.1 christos * this list of conditions and the following disclaimer in the documentation 17 1.1 christos * and/or other materials provided with the distribution. 18 1.1 christos * 19 1.1 christos * Neither the name of the NLNET LABS nor the names of its contributors may 20 1.1 christos * be used to endorse or promote products derived from this software without 21 1.1 christos * specific prior written permission. 22 1.1 christos * 23 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 1.1 christos * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 1.1 christos * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 1.1 christos * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 1.1 christos * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 1.1 christos * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 1.1 christos * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 1.1 christos */ 35 1.1 christos 36 1.1 christos /** 37 1.1 christos * \file 38 1.1 christos * 39 1.1 christos * This file contains pipe service functions. 40 1.1 christos */ 41 1.1 christos 42 1.1 christos #ifndef UTIL_TUBE_H 43 1.1 christos #define UTIL_TUBE_H 44 1.1 christos struct comm_reply; 45 1.1 christos struct comm_point; 46 1.1 christos struct comm_base; 47 1.1 christos struct tube; 48 1.1 christos struct tube_res_list; 49 1.1 christos #ifdef USE_WINSOCK 50 1.1 christos #include "util/locks.h" 51 1.1 christos #endif 52 1.1 christos 53 1.1 christos /** 54 1.1 christos * Callback from pipe listen function 55 1.1 christos * void mycallback(tube, msg, len, error, user_argument); 56 1.1 christos * if error is true (NETEVENT_*), msg is probably NULL. 57 1.1 christos */ 58 1.1.1.2 christos typedef void tube_callback_type(struct tube*, uint8_t*, size_t, int, void*); 59 1.1 christos 60 1.1 christos /** 61 1.1 christos * A pipe 62 1.1 christos */ 63 1.1 christos struct tube { 64 1.1 christos #ifndef USE_WINSOCK 65 1.1 christos /** pipe end to read from */ 66 1.1 christos int sr; 67 1.1 christos /** pipe end to write on */ 68 1.1 christos int sw; 69 1.1 christos 70 1.1 christos /** listen commpoint */ 71 1.1 christos struct comm_point* listen_com; 72 1.1 christos /** listen callback */ 73 1.1.1.2 christos tube_callback_type* listen_cb; 74 1.1 christos /** listen callback user arg */ 75 1.1 christos void* listen_arg; 76 1.1 christos /** are we currently reading a command, 0 if not, else bytecount */ 77 1.1 christos size_t cmd_read; 78 1.1 christos /** size of current read command, may be partially read */ 79 1.1 christos uint32_t cmd_len; 80 1.1 christos /** the current read command content, malloced, can be partially read*/ 81 1.1 christos uint8_t* cmd_msg; 82 1.1 christos 83 1.1 christos /** background write queue, commpoint to write results back */ 84 1.1 christos struct comm_point* res_com; 85 1.1 christos /** are we currently writing a result, 0 if not, else bytecount into 86 1.1 christos * the res_list first entry. */ 87 1.1 christos size_t res_write; 88 1.1 christos /** list of outstanding results to be written back */ 89 1.1 christos struct tube_res_list* res_list; 90 1.1 christos /** last in list */ 91 1.1 christos struct tube_res_list* res_last; 92 1.1 christos 93 1.1 christos #else /* USE_WINSOCK */ 94 1.1 christos /** listen callback */ 95 1.1.1.2 christos tube_callback_type* listen_cb; 96 1.1 christos /** listen callback user arg */ 97 1.1 christos void* listen_arg; 98 1.1 christos /** the windows sockets event (signaled if items in pipe) */ 99 1.1 christos WSAEVENT event; 100 1.1 christos /** winsock event storage when registered with event base */ 101 1.1 christos struct ub_event* ev_listen; 102 1.1 christos 103 1.1 christos /** lock on the list of outstanding items */ 104 1.1.1.2 christos lock_basic_type res_lock; 105 1.1 christos /** list of outstanding results on pipe */ 106 1.1 christos struct tube_res_list* res_list; 107 1.1 christos /** last in list */ 108 1.1 christos struct tube_res_list* res_last; 109 1.1 christos #endif /* USE_WINSOCK */ 110 1.1 christos }; 111 1.1 christos 112 1.1 christos /** 113 1.1 christos * List of results (arbitrary command serializations) to write back 114 1.1 christos */ 115 1.1 christos struct tube_res_list { 116 1.1 christos /** next in list */ 117 1.1 christos struct tube_res_list* next; 118 1.1 christos /** serialized buffer to write */ 119 1.1 christos uint8_t* buf; 120 1.1 christos /** length to write */ 121 1.1 christos uint32_t len; 122 1.1 christos }; 123 1.1 christos 124 1.1 christos /** 125 1.1 christos * Create a pipe 126 1.1 christos * @return: new tube struct or NULL on error. 127 1.1 christos */ 128 1.1 christos struct tube* tube_create(void); 129 1.1 christos 130 1.1 christos /** 131 1.1 christos * Delete and destroy a pipe 132 1.1 christos * @param tube: to delete 133 1.1 christos */ 134 1.1 christos void tube_delete(struct tube* tube); 135 1.1 christos 136 1.1 christos /** 137 1.1 christos * Write length bytes followed by message. 138 1.1 christos * @param tube: the tube to write on. 139 1.1 christos * If that tube is a pipe, its write fd is used as 140 1.1 christos * the socket to write on. Is nonblocking. 141 1.1 christos * Set to blocking by the function, 142 1.1 christos * and back to non-blocking at exit of function. 143 1.1 christos * @param buf: the message. 144 1.1 christos * @param len: length of message. 145 1.1 christos * @param nonblock: if set to true, the first write is nonblocking. 146 1.1 christos * If the first write fails the function returns -1. 147 1.1 christos * If set false, the first write is blocking. 148 1.1 christos * @return: all remainder writes are nonblocking. 149 1.1 christos * return 0 on error, in that case blocking/nonblocking of socket is 150 1.1 christos * unknown. 151 1.1 christos * return 1 if all OK. 152 1.1 christos */ 153 1.1 christos int tube_write_msg(struct tube* tube, uint8_t* buf, uint32_t len, 154 1.1 christos int nonblock); 155 1.1 christos 156 1.1 christos /** 157 1.1 christos * Read length bytes followed by message. 158 1.1 christos * @param tube: The tube to read on. 159 1.1 christos * If that tube is a pipe, its read fd is used as 160 1.1 christos * the socket to read on. Is nonblocking. 161 1.1 christos * Set to blocking by the function, 162 1.1 christos * and back to non-blocking at exit of function. 163 1.1 christos * @param buf: the message, malloced. 164 1.1 christos * @param len: length of message, returned. 165 1.1 christos * @param nonblock: if set to true, the first read is nonblocking. 166 1.1 christos * If the first read fails the function returns -1. 167 1.1 christos * If set false, the first read is blocking. 168 1.1 christos * @return: all remainder reads are nonblocking. 169 1.1 christos * return 0 on error, in that case blocking/nonblocking of socket is 170 1.1 christos * unknown. On EOF 0 is returned. 171 1.1 christos * return 1 if all OK. 172 1.1 christos */ 173 1.1 christos int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len, 174 1.1 christos int nonblock); 175 1.1 christos 176 1.1 christos /** 177 1.1 christos * Close read part of the pipe. 178 1.1 christos * The tube can no longer be read from. 179 1.1 christos * @param tube: tube to operate on. 180 1.1 christos */ 181 1.1 christos void tube_close_read(struct tube* tube); 182 1.1 christos 183 1.1 christos /** 184 1.1 christos * Close write part of the pipe. 185 1.1 christos * The tube can no longer be written to. 186 1.1 christos * @param tube: tube to operate on. 187 1.1 christos */ 188 1.1 christos void tube_close_write(struct tube* tube); 189 1.1 christos 190 1.1 christos /** 191 1.1 christos * See if data is ready for reading on the tube without blocking. 192 1.1 christos * @param tube: tube to check for readable items 193 1.1 christos * @return true if readable items are present. False if not (or error). 194 1.1 christos * true on pipe_closed. 195 1.1 christos */ 196 1.1 christos int tube_poll(struct tube* tube); 197 1.1 christos 198 1.1 christos /** 199 1.1 christos * Wait for data to be ready for reading on the tube. is blocking. 200 1.1 christos * No timeout. 201 1.1 christos * @param tube: the tube to wait on. 202 1.1 christos * @return: if there was something to read (false on error). 203 1.1 christos * true on pipe_closed. 204 1.1 christos */ 205 1.1 christos int tube_wait(struct tube* tube); 206 1.1 christos 207 1.1 christos /** 208 1.1.1.3 christos * Wait for data to be ready with a timeout. 209 1.1.1.3 christos * @param tube: the tube to wait on. 210 1.1.1.3 christos * @param msec: timeout in milliseconds. 211 1.1.1.3 christos * @return 1 if there is something to read within timeout, readability. 212 1.1.1.3 christos * 0 on a timeout. On failures -1, like errors. */ 213 1.1.1.3 christos int tube_wait_timeout(struct tube* tube, int msec); 214 1.1.1.3 christos 215 1.1.1.3 christos /** 216 1.1 christos * Get FD that is readable when new information arrives. 217 1.1 christos * @param tube 218 1.1 christos * @return file descriptor. 219 1.1 christos */ 220 1.1 christos int tube_read_fd(struct tube* tube); 221 1.1 christos 222 1.1 christos /** 223 1.1 christos * Start listening for information over the pipe. 224 1.1 christos * Background registration of a read listener, callback when read completed. 225 1.1 christos * Do not mix with tube_read_msg style direct reads from the pipe. 226 1.1 christos * @param tube: tube to listen on 227 1.1 christos * @param base: what base to register event callback. 228 1.1 christos * @param cb: callback routine. 229 1.1 christos * @param arg: user argument for callback routine. 230 1.1 christos * @return true if successful, false on error. 231 1.1 christos */ 232 1.1 christos int tube_setup_bg_listen(struct tube* tube, struct comm_base* base, 233 1.1.1.2 christos tube_callback_type* cb, void* arg); 234 1.1 christos 235 1.1 christos /** 236 1.1 christos * Remove bg listen setup from event base. 237 1.1 christos * @param tube: what tube to cleanup 238 1.1 christos */ 239 1.1 christos void tube_remove_bg_listen(struct tube* tube); 240 1.1 christos 241 1.1 christos /** 242 1.1 christos * Start background write handler for the pipe. 243 1.1 christos * Do not mix with tube_write_msg style direct writes to the pipe. 244 1.1 christos * @param tube: tube to write on 245 1.1 christos * @param base: what base to register event handler on. 246 1.1 christos * @return true if successful, false on error. 247 1.1 christos */ 248 1.1 christos int tube_setup_bg_write(struct tube* tube, struct comm_base* base); 249 1.1 christos 250 1.1 christos /** 251 1.1 christos * Remove bg write setup from event base. 252 1.1 christos * @param tube: what tube to cleanup 253 1.1 christos */ 254 1.1 christos void tube_remove_bg_write(struct tube* tube); 255 1.1 christos 256 1.1 christos 257 1.1 christos /** 258 1.1 christos * Append data item to background list of writes. 259 1.1 christos * Mallocs a list entry behind the scenes. 260 1.1 christos * Not locked behind the scenes, call from one thread or lock on outside. 261 1.1 christos * @param tube: what tube to queue on. 262 1.1 christos * @param msg: memory message to send. Is free()d after use. 263 1.1 christos * Put at the end of the to-send queue. 264 1.1 christos * @param len: length of item. 265 1.1 christos * @return 0 on failure (msg freed). 266 1.1 christos */ 267 1.1 christos int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len); 268 1.1 christos 269 1.1 christos /** for fptr wlist, callback function */ 270 1.1 christos int tube_handle_listen(struct comm_point* c, void* arg, int error, 271 1.1 christos struct comm_reply* reply_info); 272 1.1 christos 273 1.1 christos /** for fptr wlist, callback function */ 274 1.1 christos int tube_handle_write(struct comm_point* c, void* arg, int error, 275 1.1 christos struct comm_reply* reply_info); 276 1.1 christos 277 1.1 christos /** for fptr wlist, winsock signal event callback function */ 278 1.1 christos void tube_handle_signal(int fd, short events, void* arg); 279 1.1 christos 280 1.1 christos #endif /* UTIL_TUBE_H */ 281