summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd/nsd-control.c
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2021-04-01 09:56:13 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2021-04-01 09:56:13 +0000
commit05ddf102e264b5237162df515ae685a140dfd340 (patch)
treee70b8569e0fbeefcca4c321c73dc1845fce69bdf /usr.sbin/nsd/nsd-control.c
parentaf8406fd802895a9cbb6c393e29475fc2627652b (diff)
merge NSD 4.3.6rc1
Diffstat (limited to 'usr.sbin/nsd/nsd-control.c')
-rw-r--r--usr.sbin/nsd/nsd-control.c81
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