summaryrefslogtreecommitdiffstats
path: root/lib/libc/resolv/res_init.c
diff options
context:
space:
mode:
authorvangyzen <vangyzen@FreeBSD.org>2015-12-19 02:41:31 +0000
committervangyzen <vangyzen@FreeBSD.org>2015-12-19 02:41:31 +0000
commitb6f246520d532d80d0838a3b005db8ef8e9e9a47 (patch)
tree83f00a984fb131904f8621162a28cdfffaa7e50e /lib/libc/resolv/res_init.c
parentec40565958ba8acbc1f4b137261df32c9fc37568 (diff)
downloadFreeBSD-src-b6f246520d532d80d0838a3b005db8ef8e9e9a47.zip
FreeBSD-src-b6f246520d532d80d0838a3b005db8ef8e9e9a47.tar.gz
MFC r289315, r292216
resolver: automatically reload /etc/resolv.conf On each resolver query, use stat(2) to see if the modification time of /etc/resolv.conf has changed. If so, reload the file and reinitialize the resolver library. However, only call stat(2) if at least two seconds have passed since the last call to stat(2), since calling it on every query could kill performance. This new behavior is enabled by default. Add a "reload-period" option to disable it or change the period of the test. Document this behavior and option in resolv.conf(5). Polish the man page just enough to appease igor. Relnotes: yes Sponsored by: Dell Inc.
Diffstat (limited to 'lib/libc/resolv/res_init.c')
-rw-r--r--lib/libc/resolv/res_init.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c
index f636baa..41e9f5a 100644
--- a/lib/libc/resolv/res_init.c
+++ b/lib/libc/resolv/res_init.c
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/time.h>
#include <netinet/in.h>
@@ -238,6 +239,7 @@ __res_vinit(res_state statp, int preinit) {
statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
+ statp->_u._ext.ext->reload_period = 2;
} else {
/*
* Historically res_init() rarely, if at all, failed.
@@ -323,6 +325,18 @@ __res_vinit(res_state statp, int preinit) {
nserv = 0;
if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) {
+ struct stat sb;
+ struct timespec now;
+
+ if (statp->_u._ext.ext != NULL) {
+ if (_fstat(fileno(fp), &sb) == 0) {
+ statp->_u._ext.ext->conf_mtim = sb.st_mtim;
+ if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) == 0) {
+ statp->_u._ext.ext->conf_stat = now.tv_sec;
+ }
+ }
+ }
+
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
@@ -583,9 +597,7 @@ res_setoptions(res_state statp, const char *options, const char *source)
{
const char *cp = options;
int i;
-#ifndef _LIBC
struct __res_state_ext *ext = statp->_u._ext.ext;
-#endif
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -668,6 +680,12 @@ res_setoptions(res_state statp, const char *options, const char *source)
} else if (!strncmp(cp, "no-check-names",
sizeof("no-check-names") - 1)) {
statp->options |= RES_NOCHECKNAME;
+ } else if (!strncmp(cp, "reload-period:",
+ sizeof("reload-period:") - 1)) {
+ if (ext != NULL) {
+ ext->reload_period = (u_short)
+ atoi(cp + sizeof("reload-period:") - 1);
+ }
}
#ifdef RES_USE_EDNS0
else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
OpenPOWER on IntegriCloud