tube work for mingw port.

git-svn-id: file:///svn/unbound/trunk@1159 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-07-18 15:06:59 +00:00
parent ad041b9b8e
commit e4ef5a6156
8 changed files with 280 additions and 56 deletions

View 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;
}
}

View 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);

View 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,

View 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.

View 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;
}

View 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 */
/**

121
util/tube.c Normal file
View file

@ -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;
}

112
util/tube.h Normal file
View file

@ -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 */