Redefinition of _res in getrrsetbyname.c

Curt Sampson cjs at
Mon Mar 12 23:06:19 EST 2007

I've been trying to figure out why I can't seem to use SSHFP
fingerprints delivered via DNSSEC, which led me to try to figure out why
OpenSSH won't use DNSSEC on my NetBSD-4-branch platform.

It turns out that around line 70 in openbsd-compat/getrrsetbyname.c, we
have the following:

     /* to avoid conflicts where a platform already has _res */
     #ifdef _res
     # undef _res
     #define _res    _compat_res

     struct __res_state _res;

This defines a global, _compat_res, used only by OpenSSH (at least on
NetBSD), and makes _res be that instead of the "real" _res (however that
might be defined on various platforms).

_res is used only in the getrrsetbyname function, which never
initializes it in any way, but tries to act as if it's using the real
_res. So it calls init_res every time:

         if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {

and it never turns on DNSSEC, even when RES_USE_EDNS0 is set, since it's
checking for it in the wrong place:

         if (_resp->options & RES_USE_EDNS0)
 	    _resp->options |= RES_USE_DNSSEC;

So, what's the fix for this? The first thing that comes to my mind is
to rip out the redefinition; despite the comment in the changelog, any
platform for which just using _res directly for what getrrsetbyname is
doing doesn't work would appear to me to be rather broken.

Please ensure that responses are cc'd directly to me, since I'm not on
this list.

Curt Sampson            <cjs at>             +81 90 7737 2974
   The power of accurate observation is commonly called cynicism
   by those who have not got it.    --George Bernard Shaw

More information about the openssh-unix-dev mailing list