diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2021-04-01 09:56:13 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2021-04-01 09:56:13 +0000 |
commit | 05ddf102e264b5237162df515ae685a140dfd340 (patch) | |
tree | e70b8569e0fbeefcca4c321c73dc1845fce69bdf /usr.sbin/nsd/nsd-control.c | |
parent | af8406fd802895a9cbb6c393e29475fc2627652b (diff) |
merge NSD 4.3.6rc1
Diffstat (limited to 'usr.sbin/nsd/nsd-control.c')
-rw-r--r-- | usr.sbin/nsd/nsd-control.c | 81 |
1 files changed, 68 insertions, 13 deletions
diff --git a/usr.sbin/nsd/nsd-control.c b/usr.sbin/nsd/nsd-control.c index 1216e248ae9..3d77790446f 100644 --- a/usr.sbin/nsd/nsd-control.c +++ b/usr.sbin/nsd/nsd-control.c @@ -59,6 +59,10 @@ #ifdef HAVE_SYS_UN_H #include <sys/un.h> #endif +#include <fcntl.h> +#ifndef AF_LOCAL +#define AF_LOCAL AF_UNIX +#endif #include "util.h" #include "tsig.h" #include "options.h" @@ -67,6 +71,9 @@ static void usage(void) ATTR_NORETURN; static void ssl_err(const char* s) ATTR_NORETURN; static void ssl_path_err(const char* s, const char *path) ATTR_NORETURN; +/** timeout to wait for connection over stream, in msec */ +#define NSD_CONTROL_CONNECT_TIMEOUT 5000 + /** Give nsd-control usage, and exit (1). */ static void usage() @@ -185,6 +192,21 @@ setup_ctx(struct nsd_options* cfg) return ctx; } +/** check connect error */ +static void +checkconnecterr(int err, const char* svr, int port, int statuscmd) +{ + if(!port) fprintf(stderr, "error: connect (%s): %s\n", svr, + strerror(err)); + else fprintf(stderr, "error: connect (%s@%d): %s\n", svr, port, + strerror(err)); + if(err == ECONNREFUSED && statuscmd) { + printf("nsd is stopped\n"); + exit(3); + } + exit(1); +} + /** contact the server with TCP connect */ static int contact_server(const char* svr, struct nsd_options* cfg, int statuscmd) @@ -270,17 +292,53 @@ contact_server(const char* svr, struct nsd_options* cfg, int statuscmd) fprintf(stderr, "socket: %s\n", strerror(errno)); exit(1); } + if(fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { + fprintf(stderr, "error: set nonblocking: fcntl: %s", + strerror(errno)); + } if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) { - int err = errno; - if(!port) fprintf(stderr, "error: connect (%s): %s\n", svr, - strerror(err)); - else fprintf(stderr, "error: connect (%s@%d): %s\n", svr, port, - strerror(err)); - if(err == ECONNREFUSED && statuscmd) { - printf("nsd is stopped\n"); - exit(3); + if(errno != EINPROGRESS) { + checkconnecterr(errno, svr, port, statuscmd); } - exit(1); + } + while(1) { + fd_set rset, wset, eset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fd, &rset); + FD_ZERO(&wset); + FD_SET(fd, &wset); + FD_ZERO(&eset); + FD_SET(fd, &eset); + tv.tv_sec = NSD_CONTROL_CONNECT_TIMEOUT/1000; + tv.tv_usec= (NSD_CONTROL_CONNECT_TIMEOUT%1000)*1000; + if(select(fd+1, &rset, &wset, &eset, &tv) == -1) { + fprintf(stderr, "select: %s\n", strerror(errno)); + exit(1); + } + if(!FD_ISSET(fd, &rset) && !FD_ISSET(fd, &wset) && + !FD_ISSET(fd, &eset)) { + fprintf(stderr, "timeout: could not connect to server\n"); + exit(1); + } else { + /* check nonblocking connect error */ + int error = 0; + socklen_t len = (socklen_t)sizeof(error); + if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error, + &len) < 0) { + error = errno; /* on solaris errno is error */ + } + if(error != 0) { + if(error == EINPROGRESS || error == EWOULDBLOCK) + continue; /* try again later */ + checkconnecterr(error, svr, port, statuscmd); + } + } + break; + } + if(fcntl(fd, F_SETFL, 0) == -1) { + fprintf(stderr, "error: set blocking: fcntl: %s", + strerror(errno)); } return fd; } @@ -437,6 +495,7 @@ go(const char* cfgfile, char* svr, int argc, char* argv[]) } if(!opt->control_enable) fprintf(stderr, "warning: control-enable is 'no' in the config file.\n"); + resolve_interface_names(opt); ctx = setup_ctx(opt); /* contact server */ @@ -464,10 +523,6 @@ int main(int argc, char* argv[]) int c; const char* cfgfile = CONFIGFILE; char* svr = NULL; -#ifdef USE_WINSOCK - int r; - WSADATA wsa_data; -#endif log_init("nsd-control"); #ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS |