[exim-cvs] DNS resolver init changes for NetBSD compatibilit…

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] DNS resolver init changes for NetBSD compatibility.
Gitweb: http://git.exim.org/exim.git/commitdiff/5bfb4cdf352ad40304c6bbf0d826569dea761699
Commit:     5bfb4cdf352ad40304c6bbf0d826569dea761699
Parent:     c4d9f824f7dc63f898f0261d18ea09dc48b48ca8
Author:     Phil Pennock <pdp@???>
AuthorDate: Sat May 5 21:38:18 2012 -0700
Committer:  Phil Pennock <pdp@???>
CommitDate: Sat May 5 21:38:18 2012 -0700


    DNS resolver init changes for NetBSD compatibility.
---
 doc/doc-txt/ChangeLog |    5 +++++
 src/OS/os.h-NetBSD    |    4 ++++
 src/src/dns.c         |   30 +++++++++++++++++++-----------
 src/src/exim.h        |   11 +++++++++++
 src/src/exim_lock.c   |    4 ++++
 src/src/os.c          |   44 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 87 insertions(+), 11 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 80e8edf..ed226b7 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -81,6 +81,11 @@ PP/17 OpenSSL: new expansion var $tls_sni, which if used in tls_certificate
 PP/18 Bugzilla 1122 - check localhost_number expansion for failure, avoid
       NULL dereference.  Report and patch from Alun Jones.


+PP/19 DNS resolver init changes for NetBSD compatibility.  (Risk of breakage
+      on less well tested platforms).  Obviates NetBSD pkgsrc patch-ac.
+      Not seeing resolver debug output on NetBSD, but suspect this is a
+      resolver implementation change.
+


Exim version 4.77
-----------------
diff --git a/src/OS/os.h-NetBSD b/src/OS/os.h-NetBSD
index 0f3a3d8..19a8ac0 100644
--- a/src/OS/os.h-NetBSD
+++ b/src/OS/os.h-NetBSD
@@ -12,6 +12,10 @@ typedef struct flock flock_t;
#define os_strsignal strsignal
#define OS_STRSIGNAL

+#define os_get_dns_resolver_res __res_get_state
+#define os_put_dns_resolver_res(RP) __res_put_state(RP)
+#define OS_GET_DNS_RESOLVER_RES
+
#include <sys/param.h>

 #if __NetBSD_Version__ >= 299000900
diff --git a/src/src/dns.c b/src/src/dns.c
index f5e8ab7..c903d0b 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -166,26 +166,30 @@ Returns:            nothing
 void
 dns_init(BOOL qualify_single, BOOL search_parents)
 {
-if ((_res.options & RES_INIT) == 0)
+res_state resp = os_get_dns_resolver_res();
+
+if ((resp->options & RES_INIT) == 0)
   {
-  DEBUG(D_resolver) _res.options |= RES_DEBUG;     /* For Cygwin */
+  DEBUG(D_resolver) resp->options |= RES_DEBUG;     /* For Cygwin */
+  os_put_dns_resolver_res(resp);
   res_init();
-  DEBUG(D_resolver) _res.options |= RES_DEBUG;
+  DEBUG(D_resolver) resp->options |= RES_DEBUG;
+  os_put_dns_resolver_res(resp);
   }


-_res.options &= ~(RES_DNSRCH | RES_DEFNAMES);
-_res.options |= (qualify_single? RES_DEFNAMES : 0) |
+resp->options &= ~(RES_DNSRCH | RES_DEFNAMES);
+resp->options |= (qualify_single? RES_DEFNAMES : 0) |
                 (search_parents? RES_DNSRCH : 0);
-if (dns_retrans > 0) _res.retrans = dns_retrans;
-if (dns_retry > 0) _res.retry = dns_retry;
+if (dns_retrans > 0) resp->retrans = dns_retrans;
+if (dns_retry > 0) resp->retry = dns_retry;


 #ifdef RES_USE_EDNS0
 if (dns_use_edns0 >= 0)
   {
   if (dns_use_edns0)
-    _res.options |= RES_USE_EDNS0;
+    resp->options |= RES_USE_EDNS0;
   else
-    _res.options &= ~RES_USE_EDNS0;
+    resp->options &= ~RES_USE_EDNS0;
   DEBUG(D_resolver)
     debug_printf("Coerced resolver EDNS0 support %s.\n",
         dns_use_edns0 ? "on" : "off");
@@ -196,6 +200,8 @@ if (dns_use_edns0 >= 0)
     debug_printf("Unable to %sset EDNS0 without resolver support.\n",
         dns_use_edns0 ? "" : "un");
 #endif
+
+os_put_dns_resolver_res(resp);
 }



@@ -440,9 +446,10 @@ Returns:     the return code
 static int
 dns_return(uschar *name, int type, int rc)
 {
+res_state resp = os_get_dns_resolver_res();
 tree_node *node = store_get_perm(sizeof(tree_node) + 290);
 sprintf(CS node->name, "%.255s-%s-%lx", name, dns_text_type(type),
-  _res.options);
+  resp->options);
 node->data.val = rc;
 (void)tree_insertnode(&tree_dns_fails, node);
 return rc;
@@ -482,6 +489,7 @@ dns_basic_lookup(dns_answer *dnsa, uschar *name, int type)
 int rc = -1;
 uschar *save;
 #endif
+res_state resp = os_get_dns_resolver_res();


tree_node *previous;
uschar node_name[290];
@@ -492,7 +500,7 @@ have many addresses in the same domain. We rely on the resolver and name server
caching for successful lookups. */

sprintf(CS node_name, "%.255s-%s-%lx", name, dns_text_type(type),
- _res.options);
+ resp->options);
previous = tree_search(tree_dns_fails, node_name);
if (previous != NULL)
{
diff --git a/src/src/exim.h b/src/src/exim.h
index 626d33d..e6e72fa 100644
--- a/src/src/exim.h
+++ b/src/src/exim.h
@@ -353,6 +353,17 @@ to undefine it if resolv.h defines it. */
#undef __P
#endif

+/* If not defined by os.h, we do nothing special to push DNS resolver state
+back to be available by the classic resolver routines. Also, provide
+prototype for our get routine, unless defined away. */
+
+#ifndef os_put_dns_resolver_res
+# define os_put_dns_resolver_res(R) do {/**/} while(0)
+#endif
+#ifndef os_get_dns_resolver_res
+res_state os_get_dns_resolver_res(void);
+#endif
+
/* These three are to support the IP option logging code. Linux is
different to everyone else and there are also other systems which don't
have netinet/ip_var.h, so there's a general macro to control its inclusion. */
diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c
index 027a558..0a9dfde 100644
--- a/src/src/exim_lock.c
+++ b/src/src/exim_lock.c
@@ -70,6 +70,10 @@ the other stuff in os.c, so force the other macros to omit it. */
#define FIND_RUNNING_INTERFACES
#endif

+#ifndef OS_GET_DNS_RESOLVER_RES
+ #define OS_GET_DNS_RESOLVER_RES
+#endif
+
#include "../src/os.c"


diff --git a/src/src/os.c b/src/src/os.c
index 07514b5..a70bc61 100644
--- a/src/src/os.c
+++ b/src/src/os.c
@@ -795,6 +795,50 @@ return yield;



+/* ----------------------------------------------------------------------- */
+
+/***********************************************************
+*                 DNS Resolver Base Finder                 *
+***********************************************************/
+
+/* We need to be able to set options for the system resolver(5), historically
+made available as _res.  At least one OS (NetBSD) now no longer provides this
+directly, instead making you call a function per thread to get a handle.
+Other OSs handle thread-safe resolver differently, in ways which fail if the
+programmer creates their own structs. */
+
+#ifndef OS_GET_DNS_RESOLVER_RES
+
+#include <resolv.h>
+
+/* confirmed that res_state is typedef'd as a struct* on BSD and Linux, will
+find out how unportable it is on other OSes, but most resolver implementations
+should be descended from ISC's bind.
+
+Linux and BSD do:
+  define _res (*__res_state())
+identically.  We just can't rely on __foo functions.  It's surprising that use
+of _res has been as portable as it has, for so long.
+
+So, since _res works everywhere, and everything can decode the struct, I'm
+going to gamble that res_state is a typedef everywhere and use that as the
+return type.
+*/
+
+res_state
+os_get_dns_resolver_res(void)
+{
+  return &_res;
+}
+
+#endif /* OS_GET_DNS_RESOLVER_RES */
+
+
+/* ----------------------------------------------------------------------- */
+
+
+
+


/*************************************************
**************************************************