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