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