[Bug 5954] res_nclose never returns

bugzilla at busybox.net bugzilla at busybox.net
Wed Feb 20 14:46:45 UTC 2013


https://bugs.busybox.net/show_bug.cgi?id=5954

--- Comment #5 from Greg Beresford <greg.beresford at zbdsolutions.com> 2013-02-20 14:47:07 UTC ---
Yes - it looks like res_nclose should close the res_state that is passed, and
not the global one.

Connman only uses the res_ninit/res_nclose with a user res_state so that it can
read the nameservers out to add to its own internal list. So connman won't care
what really happens in res_nclose, but I imagine other applications might get
an unpleasant surprise if res_nclose closes the global state, not the
user-supplied one.

On closer inspection, connman expects different behaviour in the population of
res_state than what uClibc provides. It expects res.nscount and res.nsaddr_list
to contain both v4 and v6 nameservers, and only gets the ipv6 address from
res._u._ext.nsaddrs[i]->sin6_addr if res.nsaddr_list[i].sin_family == AF_INET6. 

Example largely created from code taken from connman:

/etc/resolv.conf:
nameserver 127.0.0.1
nameserver ::1
nameserver ::2

restest2.c:
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netdb.h>

int main(int argc, char **argv)
{
    int r, i;
    struct __res_state state;

    r = res_ninit(&state);
    if (r < 0)
        herror("init");
    printf("Initialised: %d nameservers, %d ext nameservers\n", state.nscount,
state._u._ext.nscount);


    for (i = 0; i < state.nscount; i++) {
        char buf[100];
        int family = state.nsaddr_list[i].sin_family;
        void *sa_addr = &state.nsaddr_list[i].sin_addr;

        if (family != AF_INET && state._u._ext.nsaddrs[i]) {
            family = AF_INET6;
            sa_addr = &state._u._ext.nsaddrs[i]->sin6_addr;
        }

        if (family != AF_INET && family != AF_INET6)
            continue;

        if (inet_ntop(family, sa_addr, buf, sizeof(buf)))
            printf("Read nameserver: %s\n", buf);
    }

    res_nclose(&state);

    printf("Closed: %d nameservers, %d ext nameservers\n", state.nscount,
state._u._ext.nscount);

    return 0;
}

glibc output:
Initialised: 3 nameservers, 0 ext nameservers
Read nameserver: 127.0.0.1
Read nameserver: ::1
Read nameserver: ::2
Closed: 3 nameservers, 0 ext nameservers

uClibc output:
Initialised: 1 nameservers, 3 ext nameservers
Read nameserver: 127.0.0.1
Closed: 1 nameservers, 3 ext nameservers

I haven't got time to try to put together a patch now, but I can when I return
from holiday in 2 weeks.

-- 
Configure bugmail: https://bugs.busybox.net/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


More information about the uClibc-cvs mailing list