Ports are shared and you can kill -HUP to do a reload (of config file).
git-svn-id: https://unbound.nlnetlabs.nl/svn/trunk@137 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
df0bfecb92
commit
3d6f070744
@ -83,14 +83,17 @@ daemon_fork(struct daemon* daemon)
|
||||
daemon->num = 1;
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
if(!(daemon->workers[0] = worker_init(daemon->cfg, BUFSZ)))
|
||||
if(!(daemon->workers[0] = worker_init(daemon->cfg, daemon->ports,
|
||||
BUFSZ)))
|
||||
fatal_exit("could not initialize thread # %d", 0);
|
||||
daemon->workers[0]->daemon = daemon;
|
||||
daemon->workers[0]->thread_num = 0;
|
||||
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
daemon->need_to_exit = 1;
|
||||
if(daemon->workers[0]->need_to_restart)
|
||||
daemon->need_to_exit = 0;
|
||||
else daemon->need_to_exit = 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -191,6 +191,7 @@ worker_sighandler(int sig, void* arg)
|
||||
switch(sig) {
|
||||
case SIGHUP:
|
||||
log_info("caught signal SIGHUP");
|
||||
worker->need_to_restart = 1;
|
||||
comm_base_exit(worker->base);
|
||||
break;
|
||||
case SIGINT:
|
||||
@ -208,12 +209,14 @@ worker_sighandler(int sig, void* arg)
|
||||
}
|
||||
|
||||
struct worker*
|
||||
worker_init(struct config_file *cfg, size_t buffer_size)
|
||||
worker_init(struct config_file *cfg, struct listen_port* ports,
|
||||
size_t buffer_size)
|
||||
{
|
||||
struct worker* worker = (struct worker*)calloc(1,
|
||||
sizeof(struct worker));
|
||||
if(!worker)
|
||||
return NULL;
|
||||
worker->need_to_restart = 0;
|
||||
worker->base = comm_base_create();
|
||||
if(!worker->base) {
|
||||
log_err("could not create event handling base");
|
||||
@ -229,8 +232,7 @@ worker_init(struct config_file *cfg, size_t buffer_size)
|
||||
worker_delete(worker);
|
||||
return NULL;
|
||||
}
|
||||
worker->front = listen_create(worker->base, 0, NULL, cfg->port,
|
||||
cfg->do_ip4, cfg->do_ip6, cfg->do_udp, cfg->do_tcp,
|
||||
worker->front = listen_create(worker->base, ports,
|
||||
buffer_size, worker_handle_request, worker);
|
||||
if(!worker->front) {
|
||||
log_err("could not create listening sockets");
|
||||
|
@ -50,6 +50,7 @@ struct listen_dnsport;
|
||||
struct outside_network;
|
||||
struct config_file;
|
||||
struct daemon;
|
||||
struct listen_port;
|
||||
|
||||
/** size of table used for random numbers. large to be more secure. */
|
||||
#define RND_STATE_SIZE 256
|
||||
@ -86,16 +87,20 @@ struct worker {
|
||||
|
||||
/** random() table for this worker. */
|
||||
char* rndstate;
|
||||
/** do we need to restart (instead of exit) ? */
|
||||
int need_to_restart;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize worker.
|
||||
* Allocates event base, listens to ports
|
||||
* @param cfg: configuration settings.
|
||||
* @param ports: list of shared query ports.
|
||||
* @param buffer_size: size of datagram buffer.
|
||||
* @return: The worker, or NULL on error.
|
||||
*/
|
||||
struct worker* worker_init(struct config_file *cfg, size_t buffer_size);
|
||||
struct worker* worker_init(struct config_file *cfg, struct listen_port* ports,
|
||||
size_t buffer_size);
|
||||
|
||||
/**
|
||||
* Make worker work.
|
||||
|
@ -1,3 +1,9 @@
|
||||
23 February 2007: Wouter
|
||||
- Can do reloads on sigHUP. Everything is stopped, and freed,
|
||||
except the listening ports. Then the config file is reread.
|
||||
And everything is started again (and listening ports if needed).
|
||||
- Ports for queries are shared.
|
||||
|
||||
22 February 2007: Wouter
|
||||
- Have a config file. Removed commandline options, moved to config.
|
||||
- tests use config file.
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "services/outside_network.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
@ -218,93 +219,90 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for listen_create. Creates one interface (or NULL for default).
|
||||
* Add port to open ports list.
|
||||
* @param list: list head. changed.
|
||||
* @param s: fd.
|
||||
* @param is_udp: if fd is UDP.
|
||||
* @return false on failure. list in unchanged then.
|
||||
*/
|
||||
static int
|
||||
port_insert(struct listen_port** list, int s, int is_udp)
|
||||
{
|
||||
struct listen_port* item = (struct listen_port*)malloc(
|
||||
sizeof(struct listen_port));
|
||||
if(!item)
|
||||
return 0;
|
||||
item->next = *list;
|
||||
item->fd = s;
|
||||
item->is_udp = is_udp;
|
||||
*list = item;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for ports_open. Creates one interface (or NULL for default).
|
||||
* @param ifname: The interface ip address.
|
||||
* @param front: The the listening info.
|
||||
* @param base: Event base.
|
||||
* @param port: Port number to use (as string).
|
||||
* @param do_udp: if udp should be used.
|
||||
* @param do_tcp: if udp should be used.
|
||||
* @param hints: for getaddrinfo. family and flags have to be set by caller.
|
||||
* @param bufsize: TCP buffer size.
|
||||
* @param cb: callback function
|
||||
* @param cb_arg: user parameter for callback function.
|
||||
* @param port: Port number to use (as string).
|
||||
* @param list: list of open ports, appended to, changed to point to list head.
|
||||
* @return: returns false on error.
|
||||
*/
|
||||
static int
|
||||
listen_create_if(const char* ifname, struct listen_dnsport* front,
|
||||
struct comm_base* base, const char* port, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, size_t bufsize, comm_point_callback_t* cb,
|
||||
void *cb_arg)
|
||||
ports_create_if(const char* ifname, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list)
|
||||
{
|
||||
struct comm_point *cp_udp = NULL, *cp_tcp = NULL;
|
||||
struct listen_list *el_udp, *el_tcp;
|
||||
int s;
|
||||
if(!do_udp && !do_tcp)
|
||||
return 0;
|
||||
if(do_udp) {
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints)) == -1)
|
||||
return 0;
|
||||
cp_udp = comm_point_create_udp(base, s, front->udp_buff,
|
||||
cb, cb_arg);
|
||||
if(!cp_udp) {
|
||||
log_err("can't create commpoint");
|
||||
if(!port_insert(list, s, 1)) {
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(do_tcp) {
|
||||
if((s = make_sock(SOCK_STREAM, ifname, port, hints)) == -1) {
|
||||
comm_point_delete(cp_udp);
|
||||
return 0;
|
||||
}
|
||||
cp_tcp = comm_point_create_tcp(base, s, TCP_COUNT, bufsize,
|
||||
cb, cb_arg);
|
||||
if(!cp_tcp) {
|
||||
log_err("can't create commpoint");
|
||||
comm_point_delete(cp_udp);
|
||||
if(!port_insert(list, s, 0)) {
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* add commpoints to the listen structure */
|
||||
el_udp = (struct listen_list*)malloc(sizeof(struct listen_list));
|
||||
if(!el_udp) {
|
||||
log_err("out of memory");
|
||||
comm_point_delete(cp_udp);
|
||||
comm_point_delete(cp_tcp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add items to commpoint list in front.
|
||||
* @param c: commpoint to add.
|
||||
* @param front: listen struct.
|
||||
* @return: false on failure.
|
||||
*/
|
||||
static int
|
||||
listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
|
||||
{
|
||||
struct listen_list* item = (struct listen_list*)malloc(
|
||||
sizeof(struct listen_list));
|
||||
if(!item)
|
||||
return 0;
|
||||
}
|
||||
el_tcp = (struct listen_list*)malloc(sizeof(struct listen_list));
|
||||
if(!el_tcp) {
|
||||
log_err("out of memory");
|
||||
free(el_udp);
|
||||
comm_point_delete(cp_udp);
|
||||
comm_point_delete(cp_tcp);
|
||||
return 0;
|
||||
}
|
||||
el_udp->com = cp_udp;
|
||||
el_udp->next = front->cps;
|
||||
front->cps = el_udp;
|
||||
el_tcp->com = cp_tcp;
|
||||
el_tcp->next = front->cps;
|
||||
front->cps = el_tcp;
|
||||
item->com = c;
|
||||
item->next = front->cps;
|
||||
front->cps = item;
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
|
||||
int port, int do_ip4, int do_ip6, int do_udp, int do_tcp,
|
||||
listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
size_t bufsize, comm_point_callback_t* cb, void *cb_arg)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
int i;
|
||||
char portbuf[10];
|
||||
struct listen_dnsport* front = (struct listen_dnsport*)
|
||||
malloc(sizeof(struct listen_dnsport));
|
||||
if(!front)
|
||||
return NULL;
|
||||
snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||
front->cps = NULL;
|
||||
front->udp_buff = ldns_buffer_new(bufsize);
|
||||
if(!front->udp_buff) {
|
||||
@ -312,59 +310,27 @@ listen_create(struct comm_base* base, int num_ifs, const char* ifs[],
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* getaddrinfo */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
/* no name lookups on our listening ports */
|
||||
if(num_ifs > 0)
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
#ifndef INET6
|
||||
do_ip6 = 0;
|
||||
#endif
|
||||
if(!do_ip4 && !do_ip6) {
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create ip4 and ip6 ports so that return addresses are nice. */
|
||||
if(num_ifs == 0) {
|
||||
if(do_ip6) {
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!listen_create_if(NULL, front, base, portbuf,
|
||||
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
/* create comm points as needed */
|
||||
while(ports) {
|
||||
struct comm_point* cp = NULL;
|
||||
if(ports->is_udp)
|
||||
cp = comm_point_create_udp(base, ports->fd,
|
||||
front->udp_buff, cb, cb_arg);
|
||||
else cp = comm_point_create_tcp(base, ports->fd,
|
||||
TCP_COUNT, bufsize, cb, cb_arg);
|
||||
if(!cp) {
|
||||
log_err("can't create commpoint");
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
if(do_ip4) {
|
||||
hints.ai_family = AF_INET;
|
||||
if(!listen_create_if(NULL, front, base, portbuf,
|
||||
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else for(i = 0; i<num_ifs; i++) {
|
||||
if(str_is_ip6(ifs[i])) {
|
||||
if(!do_ip6)
|
||||
continue;
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!listen_create_if(ifs[i], front, base, portbuf,
|
||||
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if(!do_ip4)
|
||||
continue;
|
||||
hints.ai_family = AF_INET;
|
||||
if(!listen_create_if(ifs[i], front, base, portbuf,
|
||||
do_udp, do_tcp, &hints, bufsize, cb, cb_arg)) {
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
cp->do_not_close = 1;
|
||||
if(!listen_cp_insert(cp, front)) {
|
||||
log_err("malloc failed");
|
||||
comm_point_delete(cp);
|
||||
listen_delete(front);
|
||||
return NULL;
|
||||
}
|
||||
ports = ports->next;
|
||||
}
|
||||
if(!front->cps) {
|
||||
log_err("Could not open sockets to accept queries.");
|
||||
@ -395,10 +361,77 @@ listen_delete(struct listen_dnsport* front)
|
||||
struct listen_port*
|
||||
listening_ports_open(struct config_file* cfg)
|
||||
{
|
||||
return calloc(1,1);
|
||||
struct listen_port* list = NULL;
|
||||
struct addrinfo hints;
|
||||
int i, do_ip4, do_ip6;
|
||||
char portbuf[32];
|
||||
snprintf(portbuf, sizeof(portbuf), "%d", cfg->port);
|
||||
do_ip4 = cfg->do_ip4;
|
||||
do_ip6 = cfg->do_ip6;
|
||||
|
||||
/* getaddrinfo */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
/* no name lookups on our listening ports */
|
||||
if(cfg->num_ifs > 0)
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
#ifndef INET6
|
||||
do_ip6 = 0;
|
||||
#endif
|
||||
if(!do_ip4 && !do_ip6) {
|
||||
return NULL;
|
||||
}
|
||||
/* create ip4 and ip6 ports so that return addresses are nice. */
|
||||
if(cfg->num_ifs == 0) {
|
||||
if(do_ip6) {
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!ports_create_if(NULL, cfg->do_udp, cfg->do_tcp,
|
||||
&hints, portbuf, &list)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(do_ip4) {
|
||||
hints.ai_family = AF_INET;
|
||||
if(!ports_create_if(NULL, cfg->do_udp, cfg->do_tcp,
|
||||
&hints, portbuf, &list)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else for(i = 0; i<cfg->num_ifs; i++) {
|
||||
if(str_is_ip6(cfg->ifs[i])) {
|
||||
if(!do_ip6)
|
||||
continue;
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!ports_create_if(cfg->ifs[i], cfg->do_udp,
|
||||
cfg->do_tcp, &hints, portbuf, &list)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if(!do_ip4)
|
||||
continue;
|
||||
hints.ai_family = AF_INET;
|
||||
if(!ports_create_if(cfg->ifs[i], cfg->do_udp,
|
||||
cfg->do_tcp, &hints, portbuf, &list)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void listening_ports_free(struct listen_port* list)
|
||||
{
|
||||
free(list);
|
||||
struct listen_port* nx;
|
||||
while(list) {
|
||||
nx = list->next;
|
||||
if(list->fd != -1)
|
||||
close(list->fd);
|
||||
free(list);
|
||||
list = nx;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,9 @@ struct listen_port {
|
||||
|
||||
/**
|
||||
* Create shared listening ports
|
||||
* Getaddrinfo, create socket, bind and listen to zero or more
|
||||
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
|
||||
* On the given port number. It creates the sockets.
|
||||
* @param cfg: settings on what ports to open.
|
||||
* @return: linked list of ports or NULL on error.
|
||||
*/
|
||||
@ -100,18 +103,10 @@ struct listen_port* listening_ports_open(struct config_file* cfg);
|
||||
void listening_ports_free(struct listen_port* list);
|
||||
|
||||
/**
|
||||
* Getaddrinfo, create socket, bind and listen to zero or more
|
||||
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
|
||||
* On the given port number. It creates the listening sockets.
|
||||
* Create commpoints with for this thread for the shared ports.
|
||||
* @param base: the comm_base that provides event functionality.
|
||||
* @param num_ifs: number of interfaces to listen on. Can be 0,
|
||||
* for default all ifs.
|
||||
* @param ifs: array of strings with interface specs, IP addresses.
|
||||
* @param port: the port number to bind to.
|
||||
* @param do_ip4: listen to ip4 queries.
|
||||
* @param do_ip6: listen to ip6 queries.
|
||||
* @param do_udp: listen to udp queries.
|
||||
* @param do_tcp: listen to tcp queries.
|
||||
* @param ports: the list of shared ports.
|
||||
* @param bufsize: size of datagram buffer.
|
||||
* @param cb: callback function when a request arrives. It is passed
|
||||
* the packet and user argument. Return true to send a reply.
|
||||
@ -119,9 +114,8 @@ void listening_ports_free(struct listen_port* list);
|
||||
* @return: the malloced listening structure, ready for use. NULL on error.
|
||||
*/
|
||||
struct listen_dnsport* listen_create(struct comm_base* base,
|
||||
int num_ifs, const char* ifs[], int port,
|
||||
int do_ip4, int do_ip6, int do_udp, int do_tcp,
|
||||
size_t bufsize, comm_point_callback_t* cb, void* cb_arg);
|
||||
struct listen_port* ports, size_t bufsize,
|
||||
comm_point_callback_t* cb, void* cb_arg);
|
||||
|
||||
/**
|
||||
* delete the listening structure
|
||||
|
@ -164,7 +164,7 @@ open_udp_port_range(const char* ifname, struct addrinfo* hints, int porthint)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s;
|
||||
char portstr[20];
|
||||
char portstr[32];
|
||||
if(porthint != -1)
|
||||
snprintf(portstr, sizeof(portstr), "%d", porthint);
|
||||
|
||||
|
@ -479,10 +479,7 @@ run_scenario(struct replay_runtime* runtime)
|
||||
/*********** Dummy routines ***********/
|
||||
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, int ATTR_UNUSED(num_ifs),
|
||||
const char* ATTR_UNUSED(ifs[]), int ATTR_UNUSED(port),
|
||||
int ATTR_UNUSED(do_ip4), int ATTR_UNUSED(do_ip6),
|
||||
int ATTR_UNUSED(do_udp), int ATTR_UNUSED(do_tcp),
|
||||
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
|
||||
size_t bufsize, comm_point_callback_t* cb, void* cb_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
|
@ -91,6 +91,8 @@ config_create()
|
||||
}
|
||||
cfg->fwd_port = UNBOUND_DNS_PORT;
|
||||
cfg->do_daemonize = 0;
|
||||
cfg->num_ifs = 0;
|
||||
cfg->ifs = NULL;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
@ -104,6 +106,7 @@ create_cfg_parser(struct config_file* cfg, char* filename)
|
||||
cfg_parser->line = 1;
|
||||
cfg_parser->errors = 0;
|
||||
cfg_parser->cfg = cfg;
|
||||
cfg_parser->server_settings_seen = 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -74,6 +74,11 @@ struct config_file {
|
||||
/** forwarder port */
|
||||
int fwd_port;
|
||||
|
||||
/** number of interfaces to open. If 0 default all interfaces. */
|
||||
int num_ifs;
|
||||
/** interface description strings (IP addresses) */
|
||||
char **ifs;
|
||||
|
||||
/** chrootdir, if not "" or chroot will be done */
|
||||
char* chrootdir;
|
||||
/** username to change to, if not "". */
|
||||
@ -115,6 +120,8 @@ struct config_parser_state {
|
||||
int errors;
|
||||
/** the result of parsing is stored here. */
|
||||
struct config_file* cfg;
|
||||
/** has server: already been seen. */
|
||||
int server_settings_seen;
|
||||
};
|
||||
|
||||
/** global config parser object used during config parsing */
|
||||
|
@ -52,7 +52,6 @@ void ub_c_error(const char *message);
|
||||
|
||||
/* these need to be global, otherwise they cannot be used inside yacc */
|
||||
extern struct config_parser_state* cfg_parser;
|
||||
static int server_settings_seen = 0;
|
||||
|
||||
#if 0
|
||||
#define OUTYY(s) printf s /* used ONLY when debugging */
|
||||
@ -80,10 +79,10 @@ toplevelvar: serverstart contents_server ;
|
||||
/* server: declaration */
|
||||
serverstart: VAR_SERVER
|
||||
{ OUTYY(("\nP(server:)\n"));
|
||||
if(server_settings_seen) {
|
||||
if(cfg_parser->server_settings_seen) {
|
||||
yyerror("duplicate server: element.");
|
||||
}
|
||||
server_settings_seen = 1;
|
||||
cfg_parser->server_settings_seen = 1;
|
||||
}
|
||||
;
|
||||
contents_server: contents_server content_server | ;
|
||||
|
@ -516,6 +516,7 @@ comm_point_create_udp(struct comm_base *base, int fd, ldns_buffer* buffer,
|
||||
c->tcp_free = NULL;
|
||||
c->type = comm_udp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
c->tcp_do_toggle_rw = 0;
|
||||
c->callback = callback;
|
||||
c->cb_arg = callback_arg;
|
||||
@ -569,6 +570,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
|
||||
c->tcp_free = NULL;
|
||||
c->type = comm_tcp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
c->tcp_do_toggle_rw = 0;
|
||||
c->callback = callback;
|
||||
c->cb_arg = callback_arg;
|
||||
@ -623,6 +625,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
|
||||
c->tcp_free = NULL;
|
||||
c->type = comm_tcp_accept;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
c->tcp_do_toggle_rw = 0;
|
||||
c->callback = NULL;
|
||||
c->cb_arg = NULL;
|
||||
@ -659,7 +662,7 @@ comm_point_close(struct comm_point* c)
|
||||
log_err("could not event_del on close");
|
||||
}
|
||||
/* close fd after removing from event lists, or epoll.. is messed up */
|
||||
if(c->fd != -1)
|
||||
if(c->fd != -1 && !c->do_not_close)
|
||||
close(c->fd);
|
||||
c->fd = -1;
|
||||
}
|
||||
|
@ -139,6 +139,9 @@ struct comm_point {
|
||||
} type;
|
||||
|
||||
/* ---------- Behaviour ----------- */
|
||||
/** if set the connection is NOT closed on delete. */
|
||||
int do_not_close;
|
||||
|
||||
/** if set, the connection is closed on error, on timeout,
|
||||
and after read/write completes. No callback is done. */
|
||||
int tcp_do_close;
|
||||
|
Loading…
Reference in New Issue
Block a user