Skip to contentSkip to conversation

Fix autotools check for res_init

PATCH In review Nicholas Hall 2 participants 8 messages Mar 6, 2015 – May 23, 2015

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix autotools check for res_init

Autotools configure check fails to detect res_init on recent glibc versions. It appears that resolv.h in recent glibc maps res_init to __res_init which autotools doesn't catch.

This is my first patch ever to anything autotools related. I used the check that the ntpd uses and tested on Debian 8 x64 (glibc 2.19) and LFS 7.4 (glibc 2.18) successfully.

This fixes bug #525
https://community.openvpn.net/openvpn/ticket/523

---
 configure.ac         | 14 ++++++++------
 src/openvpn/socket.c |  4 ++++
 2 files changed, 12 insertions(+), 6 deletions(-)
configure.ac +8 -6
index 9132468..c4db43a 100644
@@ -613,12 +613,14 @@ AC_SUBST([SOCKETS_LIBS])
 old_LIBS="${LIBS}"
 LIBS="${LIBS} ${SOCKETS_LIBS}"
 AC_CHECK_FUNCS([sendmsg recvmsg inet_ntop inet_pton])
-AC_CHECK_FUNCS(
-    [res_init],
-    ,
-    ,
-    [[#include <resolv.h>]]
-)
+AC_SEARCH_LIBS([res_init], [resolv], [], [], [-lsocket -lnsl])
+case "$host" in
+    *-*-darwin*)
+        AC_CHECK_LIB([resolv],[res_9_init])
+        ;;
+esac
+AC_HEADER_RESOLV
+AC_CHECK_FUNCS([res_init __res_init])
 # Windows use stdcall for winsock so we cannot auto detect these
 m4_define(
     [SOCKET_FUNCS],
src/openvpn/socket.c +4 -0
index f5c740d..5f98f01 100644
@@ -41,6 +41,10 @@
 #include "manage.h"
 #include "openvpn.h"
 
+#if !defined(HAVE_RES_INIT) && defined(HAVE___RES_INIT)
+# define HAVE_RES_INIT
+#endif
+
 #include "memdbg.h"
 
 const int proto_overhead[] = { /* indexed by PROTO_x */
Signature · 1 line
2.1.4
#1 lore raw

Hi,

Quoted 3 lines · Nicholas Hall

Autotools configure check fails to detect res_init on recent glibc versions. It appears that resolv.h in recent glibc maps res_init to __res_init which autotools doesn't catch.

Thanks for your patch.

Looking at it, I wonder why we're calling res_init() anyway. From a cursory reading of "man res_init" it seems to be a prerequisite to calling stuff like res_query(), res_search() or dn_comp() (etc) - but we actually call *none* of them, nor do we intend to...

We use getaddrinfo() and getnameinfo() extensively, which do not require res_init() to be called first...

So, instead of adding more convolutions to configure.ac, I propose to throw out res_init() and everything related to it :-) - much easier.

Arne, what do you think? You're the last one to have touched the code :-) (though you didn't introduce res_init(), that came into 2.1_rc8, back in the SVN days)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#2 lore raw

Hello!

Quoted 5 lines

We use getaddrinfo() and getnameinfo() extensively, which do not require res_init() to be called first...

So, instead of adding more convolutions to configure.ac, I propose to throw out res_init() and everything related to it :-) - much easier.

res_init seems to be necessary to pick up changes to /etc/resolv.conf mid-process (without some low-level caching like nscd). As of master right now, OpenVPN never recovers when it's started with bogus nameservers in /etc/resolv.conf.

The steps I describe in bug report #523 is still valid, even though my description of the implementation of openvpn_getaddrinfo() was wrong.

#3 lore raw

Hi,

Quoted 10 lines · Nicholas Hall
Quoted 5 lines

We use getaddrinfo() and getnameinfo() extensively, which do not require res_init() to be called first...

So, instead of adding more convolutions to configure.ac, I propose to throw out res_init() and everything related to it :-) - much easier.

res_init seems to be necessary to pick up changes to /etc/resolv.conf mid-process (without some low-level caching like nscd). As of master right now, OpenVPN never recovers when it's started with bogus nameservers in /etc/resolv.conf.

OK, i see. So getaddrinfo() is affected by calling res_init() repeatedly, even if it's not necessary for the initial call.

Quoted 2 lines

The steps I describe in bug report #523 is still valid, even though my description of the implementation of openvpn_getaddrinfo() was wrong.

I see that we need to fix finding res_init() then.

I'm not sure the patch is the right approach, though - it brings in system dependent stuff for MacOS to work around a Linux problem, which can't be right.

Turing around the question: is there any system out there that has tun/tap support but not res_init() (= do we need the HAVE_RES_INIT stuff anyway, as opposed to "just find the right library")? What about Windows?

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#4 lore raw

Re: [Openvpn-devel] [PATCH] Fix autotools check for res_init (#523)

In reply to Nicholas Hall

Hi,

Quoted 3 lines · Nicholas Hall

Autotools configure check fails to detect res_init on recent glibc versions. It appears that resolv.h in recent glibc maps res_init to __res_init which autotools doesn't catch.

Coming back to this. I agree this needs fixing (for 2.3.7 and 2.4), but I am not convinced the approach is the right one - it's too brittle, and I think we don't really need the #ifdef HAVE_RES_INIT at all.

Why? Because all (unixy) OSes that we support have res_init() - checked man pages for *BSD, MacOS X, Solaris, AIX and Linux. MS docs for Windows are unclear, but if it's not there, we can always #ifndef WIN32 it...

So I'd prefer a patch that would just find the necessary library to link (-lresolv, -lsocket, whatever) and otherwise assumes that res_init() is just there, no matter whether it's a macro or anything else.

Comments?

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#5 lore raw

PATCH 1/1 assume res_init() is always there.

In reply to Nicholas Hall

Previously, the code tried to find res_init(), and on some systems got it wrong in configure, silently not-using res_init(), leading to unexpected failures to re-init the resolver.

We know that all supported OSes (except Windows) have res_init(), so change the call to "#ifndef WIN32", and adjust configure.ac to just find the library to link (if any). With that, failures to find res_init() are no longer "hidden" but clearly visible at link time.

AC_SEARCH_LIBS() bits inspired by CUPS' cups_network.m4 (GPLv2)

Fix trac #523

---
 configure.ac         | 11 +++++------
 src/openvpn/socket.c |  2 +-
 2 files changed, 6 insertions(+), 7 deletions(-)
configure.ac +5 -6
index 9132468..a495c0d 100644
@@ -613,12 +613,6 @@ AC_SUBST([SOCKETS_LIBS])
 old_LIBS="${LIBS}"
 LIBS="${LIBS} ${SOCKETS_LIBS}"
 AC_CHECK_FUNCS([sendmsg recvmsg inet_ntop inet_pton])
-AC_CHECK_FUNCS(
-	[res_init],
-	,
-	,
-	[[#include <resolv.h>]]
-)
 # Windows use stdcall for winsock so we cannot auto detect these
 m4_define(
 	[SOCKET_FUNCS],
@@ -646,6 +640,11 @@ else
 fi
 LIBS="${old_LIBS}"
 
+# we assume res_init() always exist, but need to find out *where*...
+AC_SEARCH_LIBS(__res_init, resolv bind, ,
+    AC_SEARCH_LIBS(res_9_init, resolv bind, ,
+	AC_SEARCH_LIBS(res_init, resolv bind, , )))
+
 AC_ARG_VAR([TAP_CFLAGS], [C compiler flags for tap])
 old_CFLAGS="${CFLAGS}"
 CFLAGS="${CFLAGS} ${TAP_CFLAGS}"
src/openvpn/socket.c +1 -1
index afc1e60..13ed981 100644
@@ -314,7 +314,7 @@ openvpn_getaddrinfo (unsigned int flags,
 
   ASSERT(res);
 
-#if defined(HAVE_RES_INIT)
+#ifndef WIN32
   res_init ();
 #endif
 
Signature · 1 line
2.0.5
#6 lore raw

Re: [Openvpn-devel] [PATCH] assume res_init() is always there.

Hi,

Quoted 3 lines · Gert Doering

Previously, the code tried to find res_init(), and on some systems got it wrong in configure, silently not-using res_init(), leading to unexpected failures to re-init the resolver.

... for the record: tested on FreeBSD 9.1, Gentoo-something, AIX(!), OpenSolaris and MacOS X - and either it found and added the library fine, or discovered that it didn't need to do anything, but in any case, the resulting socket.o always referenced res_init() and linking worked.

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#7 lore raw

[Openvpn-devel] [PATCH applied] Re: assume res_init() is always there.

In reply to Gert Doering

Lazy-ACKed - tested on almost all supported OSes, no objections for nearly four weeks (and general support in the discussion beforehand).

Patch has been applied to the master and release/2.3 branches.

commit 403dc434d245e5df5ae262935aa2e7364547e260 (master) commit ae9aff25c5a74e770a29a3a675f5b8f8dd8c5bf8 (release/2.3)

Author: Gert Doering
Date:   Mon Apr 27 21:27:21 2015 +0200
     assume res_init() is always there.

     Signed-off-by: Gert Doering <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/9614

--
kind regards,

Gert Doering