mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-04 13:59:35 -05:00
tube work for mingw port.
git-svn-id: file:///svn/unbound/trunk@1159 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
ad041b9b8e
commit
e4ef5a6156
8 changed files with 280 additions and 56 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
121
util/tube.c
Normal 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
112
util/tube.h
Normal 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 */
|
||||
Loading…
Reference in a new issue