From b5f356e9fba2d99909f8f54d7b7e6836bed87b68 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 May 2017 11:33:07 +0200 Subject: [PATCH] dirmngr: Re-init libdns resolver on towel change of resolv.conf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * dirmngr/dns-stuff.c: Include sys/stat.h. (RESOLV_CONF_NAME): New macro to replace a string. (resolv_conf_changed_p): New. (libdns_init): Call new function (libdns_res_open): Ditto. -- Don't panic. This is a simple change Suggested-by: Stefan Bühler to avoid complicated if-up.d hooks to reload resolv.conf. Signed-off-by: Werner Koch --- dirmngr/dns-stuff.c | 47 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index a6c14cdcd..a8ddbc64e 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -45,6 +45,9 @@ # endif # include #endif +#ifdef HAVE_STAT +# include +#endif #include #include @@ -111,6 +114,8 @@ #define DEFAULT_TIMEOUT 30 +#define RESOLV_CONF_NAME "/etc/resolv.conf" + /* Two flags to enable verbose and debug mode. */ static int opt_verbose; static int opt_debug; @@ -391,6 +396,37 @@ libdns_error_to_gpg_error (int serr) #endif /*USE_LIBDNS*/ +/* Return true if resolve.conf changed since it was last loaded. */ +#ifdef USE_LIBDNS +static int +resolv_conf_changed_p (void) +{ +#if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT) + return 0; +#else + static time_t last_mtime; + const char *fname = RESOLV_CONF_NAME; + struct stat statbuf; + int changed; + + if (stat (fname, &statbuf)) + { + log_error ("stat'ing '%s' failed: %s\n", + fname, gpg_strerror (gpg_error_from_syserror ())); + changed = 0; + last_mtime = 1; /* Force a "changed" result the next time stat + * works. */ + } + else + { + changed = last_mtime && (last_mtime != statbuf.st_mtime); + last_mtime = statbuf.st_mtime; + } + return changed; +#endif +} +#endif /*USE_LIBDNS*/ + #ifdef USE_LIBDNS /* Initialize libdns. Returns 0 on success; prints a diagnostic and * returns an error code on failure. */ @@ -496,7 +532,8 @@ libdns_init (void) #else /* Unix */ const char *fname; - fname = "/etc/resolv.conf"; + fname = RESOLV_CONF_NAME; + resolv_conf_changed_p (); /* Reset timestamp. */ err = libdns_error_to_gpg_error (dns_resconf_loadpath (ld.resolv_conf, fname)); if (err) @@ -653,6 +690,14 @@ libdns_res_open (struct dns_resolver **r_res) *r_res = NULL; + /* Force a reload if resolv.conf has changed. */ + if (resolv_conf_changed_p ()) + { + if (opt_debug) + log_debug ("dns: resolv.conf changed - forcing reload\n"); + libdns_reinit_pending = 1; + } + if (libdns_reinit_pending) { libdns_reinit_pending = 0;