From: Wouter Wijngaards Date: Fri, 18 Jul 2008 15:06:59 +0000 (+0000) Subject: tube work for mingw port. X-Git-Tag: release-1.1.0~187 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4ef5a6156fc7c6dedc4d166f78c68bda3bfe83b;p=thirdparty%2Funbound.git tube work for mingw port. git-svn-id: file:///svn/unbound/trunk@1159 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/daemon.c b/daemon/daemon.c index dda9c4e36..f34a1c0d7 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -54,6 +54,7 @@ #include "services/modstack.h" #include "util/module.h" #include "util/random.h" +#include "util/tube.h" #include /** How many quit requests happened. */ @@ -292,14 +293,8 @@ void close_other_pipes(struct daemon* daemon, int thr) int i; for(i=0; inum; i++) if(i!=thr) { - if(daemon->workers[i]->cmd_send_fd != -1) { - close(daemon->workers[i]->cmd_send_fd); - daemon->workers[i]->cmd_send_fd = -1; - } - if(daemon->workers[i]->cmd_recv_fd != -1) { - close(daemon->workers[i]->cmd_recv_fd); - daemon->workers[i]->cmd_recv_fd = -1; - } + tube_delete(daemon->workers[i]->cmd); + daemon->workers[i]->cmd = NULL; } } diff --git a/daemon/worker.c b/daemon/worker.c index c39375f4c..9512f447c 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -63,6 +63,7 @@ #include "util/data/msgencode.h" #include "util/data/dname.h" #include "util/fptr_wlist.h" +#include "util/tube.h" #ifdef HAVE_SYS_TYPES_H # include @@ -198,9 +199,9 @@ worker_send_cmd(struct worker* worker, ldns_buffer* buffer, ldns_buffer_write_u16(buffer, sizeof(uint32_t)); ldns_buffer_write_u32(buffer, (uint32_t)cmd); ldns_buffer_flip(buffer); - if(!write_socket(worker->cmd_send_fd, ldns_buffer_begin(buffer), - ldns_buffer_limit(buffer))) - log_err("write socket: %s", strerror(errno)); + if(!tube_send_cmd(worker->cmd, buffer)) { + log_err("worker send cmd %d failed", (int)cmd); + } } int @@ -318,9 +319,9 @@ worker_check_request(ldns_buffer* pkt, struct worker* worker) return 0; } -int -worker_handle_control_cmd(struct comm_point* c, void* arg, int error, - struct comm_reply* ATTR_UNUSED(reply_info)) +void +worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), ldns_buffer* buffer, + int error, void* arg) { struct worker* worker = (struct worker*)arg; enum worker_commands cmd; @@ -328,13 +329,13 @@ worker_handle_control_cmd(struct comm_point* c, void* arg, int error, if(error == NETEVENT_CLOSED) comm_base_exit(worker->base); else log_info("control event: %d", error); - return 0; + return; } - if(ldns_buffer_limit(c->buffer) != sizeof(uint32_t)) { + if(ldns_buffer_limit(buffer) != sizeof(uint32_t)) { fatal_exit("bad control msg length %d", - (int)ldns_buffer_limit(c->buffer)); + (int)ldns_buffer_limit(buffer)); } - cmd = ldns_buffer_read_u32(c->buffer); + cmd = ldns_buffer_read_u32(buffer); switch(cmd) { case worker_cmd_quit: verbose(VERB_ALGO, "got control cmd quit"); @@ -344,7 +345,6 @@ worker_handle_control_cmd(struct comm_point* c, void* arg, int error, log_err("bad command %d", (int)cmd); break; } - return 0; } /** check if a delegation is secure */ @@ -916,24 +916,12 @@ worker_create(struct daemon* daemon, int id, int* ports, int n) } worker->daemon = daemon; worker->thread_num = id; - worker->cmd_send_fd = -1; - worker->cmd_recv_fd = -1; if(id != 0) { - int sv[2]; - /* create socketpair to communicate with worker */ - if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) { - free(worker); - log_err("socketpair: %s", strerror(errno)); - return NULL; - } - if(!fd_set_nonblock(sv[0]) || !fd_set_nonblock(sv[1])) { - close(sv[0]); - close(sv[1]); + if(!(worker->cmd = tube_create())) { + free(worker->ports); free(worker); return NULL; } - worker->cmd_send_fd = sv[0]; - worker->cmd_recv_fd = sv[1]; } return worker; } @@ -1010,9 +998,9 @@ worker_init(struct worker* worker, struct config_file *cfg, } if(worker->thread_num != 0) { /* start listening to commands */ - if(!(worker->cmd_com=comm_point_create_local(worker->base, - worker->cmd_recv_fd, cfg->msg_buffer_size, - worker_handle_control_cmd, worker))) { + if(!tube_listen_cmd(worker->cmd, worker->base, + cfg->msg_buffer_size, worker_handle_control_cmd, + worker)) { log_err("could not create control compt."); worker_delete(worker); return 0; @@ -1089,21 +1077,13 @@ worker_delete(struct worker* worker) listen_delete(worker->front); outside_network_delete(worker->back); comm_signal_delete(worker->comsig); - comm_point_delete(worker->cmd_com); + tube_delete(worker->cmd); comm_timer_delete(worker->stat_timer); free(worker->ports); if(worker->thread_num == 0) log_set_time(NULL); comm_base_delete(worker->base); ub_randfree(worker->rndstate); - /* close fds after deleting commpoints, to be sure. - Also epoll does not like closing fd before event_del */ - if(worker->cmd_send_fd != -1) - close(worker->cmd_send_fd); - worker->cmd_send_fd = -1; - if(worker->cmd_recv_fd != -1) - close(worker->cmd_recv_fd); - worker->cmd_recv_fd = -1; alloc_clear(&worker->alloc); regional_destroy(worker->scratchpad); free(worker); diff --git a/daemon/worker.h b/daemon/worker.h index 64eaa73c1..55def23af 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -58,6 +58,7 @@ struct daemon; struct listen_port; struct ub_randstate; struct regional; +struct tube; /** worker commands */ enum worker_commands { @@ -76,10 +77,8 @@ struct worker { struct daemon* daemon; /** thread id */ ub_thread_t thr_id; - /** fd 0 of socketpair, write commands for worker to this one */ - int cmd_send_fd; - /** fd 1 of socketpair, worker listens on this one */ - int cmd_recv_fd; + /** pipe, for commands for this worker */ + struct tube* cmd; /** the event base this worker works with */ struct comm_base* base; /** the frontside listening interface where request events come in */ @@ -199,13 +198,13 @@ struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen, /** * process control messages from the main thread. - * @param c: comm point to read from. - * @param arg: worker. - * @param error: error status of comm point. - * @param reply_info: not used. + * @param tube: tube control message came on. + * @param buf: buffer with message in it. + * @param error: if error (NETEVENT_*) happened. + * @param arg: user argument */ -int worker_handle_control_cmd(struct comm_point* c, void* arg, int error, - struct comm_reply* reply_info); +void worker_handle_control_cmd(struct tube* tube, ldns_buffer* buffer, + int error, void* arg); /** handles callbacks from listening event interface */ int worker_handle_request(struct comm_point* c, void* arg, int error, diff --git a/doc/Changelog b/doc/Changelog index 537fcb5e9..c9adbbea5 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,5 +1,6 @@ 18 July 2008: Wouter - branch for 1.0 support. + - trunk work on tube.c. 17 July 2008: Wouter - fix bug #196, compile outside source tree. diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index 0ae2e532b..98caef554 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -68,6 +68,7 @@ #include "daemon/acl_list.h" #include "libunbound/libworker.h" #include "libunbound/context.h" +#include "util/tube.h" int fptr_whitelist_comm_point(comm_point_callback_t *fptr) @@ -75,7 +76,7 @@ fptr_whitelist_comm_point(comm_point_callback_t *fptr) if(fptr == &worker_handle_request) return 1; else if(fptr == &outnet_udp_cb) return 1; else if(fptr == &outnet_tcp_cb) return 1; - else if(fptr == &worker_handle_control_cmd) return 1; + else if(fptr == &tube_handle_listen) return 1; return 0; } @@ -325,3 +326,9 @@ fptr_whitelist_alloc_cleanup(void (*fptr)(void*)) if(fptr == &worker_alloc_cleanup) return 1; return 0; } + +int fptr_whitelist_tube_listen(tube_callback_t* fptr) +{ + if(fptr == &worker_handle_control_cmd) return 1; + return 0; +} diff --git a/util/fptr_wlist.h b/util/fptr_wlist.h index a986de3bd..b8451260e 100644 --- a/util/fptr_wlist.h +++ b/util/fptr_wlist.h @@ -57,6 +57,7 @@ #include "util/netevent.h" #include "util/storage/lruhash.h" #include "util/module.h" +#include "util/tube.h" /** * Macro to perform an assertion check for fptr wlist checks. @@ -290,6 +291,14 @@ int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id)); */ int fptr_whitelist_alloc_cleanup(void (*fptr)(void*)); +/** + * Check function pointer whitelist for tube listen handler values. + * + * @param fptr: function pointer to check. + * @return false if not in whitelist. + */ +int fptr_whitelist_tube_listen(tube_callback_t* fptr); + /** Due to module breakage by fptr wlist, these test app declarations * are presented here */ /** diff --git a/util/tube.c b/util/tube.c new file mode 100644 index 000000000..4f58054f5 --- /dev/null +++ b/util/tube.c @@ -0,0 +1,121 @@ +/* + * util/tube.c - pipe service + * + * Copyright (c) 2008, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains pipe service functions. + */ +#include "config.h" +#include "util/tube.h" +#include "util/log.h" +#include "util/net_help.h" +#include "util/netevent.h" +#include "util/fptr_wlist.h" + +struct tube* tube_create(void) +{ + struct tube* tube = (struct tube*)calloc(1, sizeof(*tube)); + int sv[2]; + if(!tube) return 0; + tube->sr = -1; + tube->sw = -1; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) { + log_err("socketpair: %s", strerror(errno)); + free(tube); + return NULL; + } + tube->sr = sv[0]; + tube->sw = sv[1]; + if(!fd_set_nonblock(tube->sr) || !fd_set_nonblock(tube->sw)) { + log_err("tube: cannot set nonblocking"); + tube_delete(tube); + return NULL; + } + return tube; +} + +void tube_delete(struct tube* tube) +{ + if(!tube) return; + if(tube->listen_com) { + comm_point_delete(tube->listen_com); + } + /* close fds after deleting commpoints, to be sure. + * Also epoll does not like closing fd before event_del */ + if(tube->sr != -1) close(tube->sr); + if(tube->sw != -1) close(tube->sw); + tube->sr = -1; + tube->sw = -1; + free(tube); +} + +int +tube_handle_listen(struct comm_point* c, void* arg, int error, + struct comm_reply* ATTR_UNUSED(reply_info)) +{ + struct tube* tube = (struct tube*)arg; + if(error != NETEVENT_NOERROR) { + fptr_ok(fptr_whitelist_tube_listen(tube->listen_cb)); + (*tube->listen_cb)(tube, NULL, error, tube->listen_arg); + return 0; + } + fptr_ok(fptr_whitelist_tube_listen(tube->listen_cb)); + (*tube->listen_cb)(tube, c->buffer, error, tube->listen_arg); + return 0; +} + +int tube_listen_cmd(struct tube* tube, struct comm_base* base, + size_t msg_buffer_sz, tube_callback_t* cb, void* arg) +{ + tube->listen_cb = cb; + tube->listen_arg = arg; + if(!(tube->listen_com = comm_point_create_local(base, tube->sr, + msg_buffer_sz, tube_handle_listen, tube))) { + log_err("tube_listen_cmd: commpoint creation failed"); + return 0; + } + return 1; +} + +int tube_send_cmd(struct tube* tube, ldns_buffer* buffer) +{ + if(!write_socket(tube->sw, ldns_buffer_begin(buffer), + ldns_buffer_limit(buffer))) { + log_err("write socket: %s", strerror(errno)); + return 0; + } + return 1; +} diff --git a/util/tube.h b/util/tube.h new file mode 100644 index 000000000..00092ec91 --- /dev/null +++ b/util/tube.h @@ -0,0 +1,112 @@ +/* + * util/tube.h - pipe service + * + * Copyright (c) 2008, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains pipe service functions. + */ + +#ifndef UTIL_TUBE_H +#define UTIL_TUBE_H +struct comm_reply; +struct comm_base; +struct tube; + +/** + * Callback from pipe listen function + * void mycallback(tube, buffer, error, argument); + * if error is true (NETEVENT_*), buffer is probably NULL. + */ +typedef void (tube_callback_t)(struct tube* tube, ldns_buffer* buffer, + int error, void* arg); + +/** + * A pipe + */ +struct tube { + /** pipe end to read from */ + int sr; + /** pipe end to write on */ + int sw; + + /** listen commpoint */ + struct comm_point* listen_com; + /** listen callback */ + tube_callback_t* listen_cb; + /** listen callback user arg */ + void* listen_arg; +}; + +/** + * Create a pipe + * @return: new tube struct or NULL on error. + */ +struct tube* tube_create(void); + +/** + * Delete and destroy a pipe + * @param tube: to delete + */ +void tube_delete(struct tube* tube); + +/** + * Start listening for information over the pipe + * @param tube: tube to listen on + * @param base: what base to register event callback. + * @param msg_buffer_sz: what message buffer size to use. + * @param cb: callback routine. + * @param arg: user argument for callback routine. + * @return true if successful, false on error. + */ +int tube_listen_cmd(struct tube* tube, struct comm_base* base, + size_t msg_buffer_sz, tube_callback_t* cb, void* arg); + +/** + * Send a command over a pipe, blocking operation. + * @param tube: tube to send the info on. + * @param buffer: buffer to send. starts with network order uint16 with + * length of remainder of buffer. + * The receiver does not receive the length uint16 in the buffer + * (the buffer is sized appropriately). + * @return 0 on error, true on success. + */ +int tube_send_cmd(struct tube* tube, ldns_buffer* buffer); + +/** decl for fptr_wlist of tube pipe listen handler */ +int tube_handle_listen(struct comm_point* c, void* arg, int error, + struct comm_reply* reply_info); + +#endif /* UTIL_TUBE_H */