diff options
-rw-r--r-- | libc/inet/resolv.c | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 66bc8df69..2033036f7 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -55,6 +55,7 @@ #include <errno.h> #include <sys/socket.h> #include <sys/types.h> +#include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> @@ -140,6 +141,7 @@ extern int read_etc_hosts_r(FILE *fp, const char * name, int type, char * buf, size_t buflen, struct hostent ** result, int * h_errnop); +extern int connect_dns(char *dns); extern int dns_lookup(const char * name, int type, int nscount, char ** nsip, unsigned char ** outpacket, struct resolv_answer * a); @@ -529,6 +531,45 @@ int form_query(int id, const char *name, int type, unsigned char *packet, } #endif +#ifdef L_connect_dns +int connect_dns(char *nsip) +{ + int fd, rc; + struct sockaddr_in sa; +#ifdef __UCLIBC_HAS_IPV6__ + int v6; + struct sockaddr_in6 sa6; + v6 = inet_pton(AF_INET6, nsip, &sa6.sin6_addr) > 0; + fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP); +#else + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif + if (fd == -1) return -1; + +#ifdef __UCLIBC_HAS_IPV6__ + if (v6) { + sa6.sin6_family = AF_INET6; + sa6.sin6_port = htons(NAMESERVER_PORT); + /* sa6.sin6_addr is already here */ + rc = connect(fd, (struct sockaddr *) &sa6, sizeof(sa6)); + } else { +#endif + sa.sin_family = AF_INET; + sa.sin_port = htons(NAMESERVER_PORT); + sa.sin_addr.s_addr = inet_addr(nsip); + rc = connect(fd, (struct sockaddr *) &sa, sizeof(sa)); +#ifdef __UCLIBC_HAS_IPV6__ + } +#endif + if (rc != 0) { + close(fd); + return -1; + } + return fd; +} +#endif + + #ifdef L_dnslookup #ifdef __UCLIBC_HAS_THREADS__ @@ -542,18 +583,15 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; #endif /* Just for the record, having to lock dns_lookup() just for these two globals - * is pretty lame. Sometime I should work on making the locking a bit more - * careful to avoid needless blocking... */ + * is pretty lame. I think these two variables can probably be de-global-ized, + * which should eliminate the need for doing locking here... Needs a closer + * look anyways. */ static int ns=0, id=1; int dns_lookup(const char *name, int type, int nscount, char **nsip, unsigned char **outpacket, struct resolv_answer *a) { int i, j, len, fd, pos; - struct sockaddr_in sa; -#ifdef __UCLIBC_HAS_IPV6__ - struct sockaddr_in6 sa6; -#endif /* __UCLIBC_HAS_IPV6__ */ struct timeval tv; fd_set fds; struct resolv_header h; @@ -562,9 +600,6 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip, unsigned char * packet = malloc(PACKETSZ); char * lookup = malloc(MAXDNAME); int variant = 0; -#ifdef __UCLIBC_HAS_IPV6__ - int v6; -#endif /* __UCLIBC_HAS_IPV6__ */ fd = -1; @@ -577,22 +612,9 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip, ns %= nscount; while (retries++ < MAX_RETRIES) { -#ifdef __UCLIBC_HAS_IPV6__ - v6 = (inet_pton(AF_INET6, nsip[ns], &sa6.sin6_addr) > 0); -#endif /* __UCLIBC_HAS_IPV6__ */ - if (fd != -1) close(fd); -#ifndef __UCLIBC_HAS_IPV6__ - fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); -#else /* __UCLIBC_HAS_IPV6__ */ - fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP); -#endif /* __UCLIBC_HAS_IPV6__ */ - - if (fd == -1) - goto fail; - memset(packet, 0, PACKETSZ); memset(&h, 0, sizeof(h)); @@ -626,28 +648,8 @@ int dns_lookup(const char *name, int type, int nscount, char **nsip, DPRINTF("On try %d, sending query to port %d of machine %s\n", retries, NAMESERVER_PORT, nsip[ns]); -#ifndef __UCLIBC_HAS_IPV6__ - sa.sin_family = AF_INET; - sa.sin_port = htons(NAMESERVER_PORT); - sa.sin_addr.s_addr = inet_addr(nsip[ns]); -#else /* __UCLIBC_HAS_IPV6__ */ - if (v6) { - sa6.sin6_family = AF_INET6; - sa6.sin6_port = htons(NAMESERVER_PORT); - /* sa6.sin6_addr is already here */ - } else { - sa.sin_family = AF_INET; - sa.sin_port = htons(NAMESERVER_PORT); - sa.sin_addr.s_addr = inet_addr(nsip[ns]); - } -#endif /* __UCLIBC_HAS_IPV6__ */ - -#ifndef __UCLIBC_HAS_IPV6__ - if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { -#else /* __UCLIBC_HAS_IPV6__ */ - if (connect(fd, (struct sockaddr *) (v6 ? &sa6 : &sa), - v6 ? sizeof(sa6) : sizeof(sa)) == -1) { -#endif /* __UCLIBC_HAS_IPV6__ */ + fd = connect_dns(nsip[ns]); + if (fd < 0) { if (errno == ENETUNREACH) { /* routing error, presume not transient */ goto tryall; |