dirmngr: Use one context for all libdns queries.
authorWerner Koch <wk@gnupg.org>
Fri, 16 Dec 2016 20:00:14 +0000 (21:00 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 16 Dec 2016 20:00:14 +0000 (21:00 +0100)
* dirmngr/dns-stuff.c (libdns_reinit_pending): New var.
(enable_recursive_resolver): Set var.
(set_dns_nameserver): Ditto.
(libdns_init): Avoid double initialization.
(libdns_deinit): New.
(reload_dns_stuff): New.
(libdns_res_open): Act upon LIBDNS_REINIT_PENDING.
* dirmngr/t-dns-stuff.c (main): Call reload_dns_stuff to release
memory.
* dirmngr/dirmngr.c (cleanup): Ditto.
(dirmngr_sighup_action): Call reload_dns_stuff to set
LIBDNS_REINIT_PENDING.

Signed-off-by: Werner Koch <wk@gnupg.org>
dirmngr/dirmngr.c
dirmngr/dns-stuff.c
dirmngr/dns-stuff.h
dirmngr/t-dns-stuff.c

index a118327..ef30d2c 100644 (file)
@@ -1383,6 +1383,7 @@ cleanup (void)
 {
   crl_cache_deinit ();
   cert_cache_deinit (1);
+  reload_dns_stuff (1);
 
 #if USE_LDAP
   ldapserver_list_free (opt.ldapservers);
@@ -1689,6 +1690,7 @@ dirmngr_sighup_action (void)
   crl_cache_deinit ();
   cert_cache_init ();
   crl_cache_init ();
+  reload_dns_stuff (0);
 }
 
 
index 0f1f0ed..63951e5 100644 (file)
@@ -133,8 +133,13 @@ struct libdns_s
 
   struct sockaddr_storage socks_host;
 } libdns;
+
+/* If this flag is set, libdns shall be reinited for the next use.  */
+static int libdns_reinit_pending;
+
 #endif /*USE_LIBDNS*/
 
+
 /* Calling this function with YES set to True forces the use of the
  * standard resolver even if dirmngr has been built with support for
  * an alternative resolver.  */
@@ -159,6 +164,7 @@ void
 enable_recursive_resolver (int yes)
 {
   recursive_resolver = yes;
+  libdns_reinit_pending = 1;
 }
 
 
@@ -203,6 +209,7 @@ set_dns_nameserver (const char *ipaddr)
   strncpy (tor_nameserver, ipaddr? ipaddr : DEFAULT_NAMESERVER,
            sizeof tor_nameserver -1);
   tor_nameserver[sizeof tor_nameserver -1] = 0;
+  libdns_reinit_pending = 1;
 }
 
 
@@ -315,6 +322,9 @@ libdns_init (void)
   const char *fname;
   char *cfgstr = NULL;
 
+  if (libdns.resolv_conf)
+    return 0; /* Already initialized.  */
+
   memset (&ld, 0, sizeof ld);
 
   ld.resolv_conf = dns_resconf_open (&derr);
@@ -410,6 +420,41 @@ libdns_init (void)
 
 
 #ifdef USE_LIBDNS
+/* Deinitialize libdns.  */
+static void
+libdns_deinit (void)
+{
+  struct libdns_s ld;
+
+  if (!libdns.resolv_conf)
+    return; /* Not initialized.  */
+
+  ld = libdns;
+  memset (&libdns, 0, sizeof libdns);
+  dns_hints_close (ld.hints);
+  dns_hosts_close (ld.hosts);
+  dns_resconf_close (ld.resolv_conf);
+}
+#endif /*USE_LIBDNS*/
+
+/* SIGHUP action handler for this module.  With FORCE set objects are
+ * all immediately released. */
+void
+reload_dns_stuff (int force)
+{
+  if (force)
+    {
+#ifdef USE_LIBDNS
+      libdns_deinit ();
+#endif
+      libdns_reinit_pending = 0;
+    }
+  else
+    libdns_reinit_pending = 1;
+}
+
+
+#ifdef USE_LIBDNS
 /*
  * Initialize libdns if needed and open a dns_resolver context.
  * Returns 0 on success and stores the new context at R_RES.  On
@@ -424,6 +469,12 @@ libdns_res_open (struct dns_resolver **r_res)
 
   *r_res = NULL;
 
+  if (libdns_reinit_pending)
+    {
+      libdns_reinit_pending = 0;
+      libdns_deinit ();
+    }
+
   err = libdns_init ();
   if (err)
     return err;
index 20a4b41..2be972a 100644 (file)
@@ -116,6 +116,8 @@ gpg_error_t enable_dns_tormode (int new_circuit);
    next DNS query.  Note that this is only used in Tor mode.  */
 void set_dns_nameserver (const char *ipaddr);
 
+/* SIGHUP action handler for this module.  */
+void reload_dns_stuff (int force);
 
 void free_dns_addrinfo (dns_addrinfo_t ai);
 
index 224e948..5315138 100644 (file)
@@ -217,7 +217,6 @@ main (int argc, char **argv)
         {
           printf ("CNAME found: '%s'\n", cname);
         }
-
       xfree (cname);
     }
   else if (opt_srv)
@@ -291,6 +290,7 @@ main (int argc, char **argv)
       free_dns_addrinfo (aibuf);
     }
 
+  reload_dns_stuff (1); /* Release objects.  */
 
   return 0;
 }