]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
tube work for mingw port.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 18 Jul 2008 15:06:59 +0000 (15:06 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 18 Jul 2008 15:06:59 +0000 (15:06 +0000)
git-svn-id: file:///svn/unbound/trunk@1159 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/daemon.c
daemon/worker.c
daemon/worker.h
doc/Changelog
util/fptr_wlist.c
util/fptr_wlist.h
util/tube.c [new file with mode: 0644]
util/tube.h [new file with mode: 0644]

index dda9c4e36d2b98001d8509285a5c2c119f748b9e..f34a1c0d7b51985371344b53223a45b393e5a8bb 100644 (file)
@@ -54,6 +54,7 @@
 #include "services/modstack.h"
 #include "util/module.h"
 #include "util/random.h"
+#include "util/tube.h"
 #include <signal.h>
 
 /** How many quit requests happened. */
@@ -292,14 +293,8 @@ void close_other_pipes(struct daemon* daemon, int thr)
        int i;
        for(i=0; i<daemon->num; 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;
                }
 }
 
index c39375f4ce55afeab95f6e695a24fcbabd5db408..9512f447c2775fcbb174e25da649b22354a82d6d 100644 (file)
@@ -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 <sys/types.h>
@@ -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);
index 64eaa73c130fcd7c7e0725fddbe535a507951ade..55def23afcd4808e1abcd922881c030d100613fd 100644 (file)
@@ -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,
index 537fcb5e9f4c2a6d01b2b4230b99d35b99a3e6f1..c9adbbea5c6a7c75bca849368209d5e8d97305e7 100644 (file)
@@ -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.
index 0ae2e532bddf2ab89bb8a96fbce9d774d3bcdb1d..98caef554229f67b26ea9f3b478167f4852e83ba 100644 (file)
@@ -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;
+}
index a986de3bdf5df68e38d9dc10ab972ef2aaee1eb6..b8451260ee300cfe128bb2133e766d69aea58eac 100644 (file)
@@ -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 (file)
index 0000000..4f58054
--- /dev/null
@@ -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 (file)
index 0000000..00092ec
--- /dev/null
@@ -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 */