summaryrefslogtreecommitdiff
path: root/libc/inet/resolv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/inet/resolv.c')
-rw-r--r--libc/inet/resolv.c89
1 files changed, 40 insertions, 49 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index ca8f4c7ba..8c985ba33 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -166,7 +166,6 @@ 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);
@@ -561,45 +560,6 @@ 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__
@@ -620,7 +580,7 @@ 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;
+ int i, j, len, fd, pos, rc;
struct timeval tv;
fd_set fds;
struct resolv_header h;
@@ -629,6 +589,11 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,
unsigned char * packet = malloc(PACKETSZ);
char *dns, *lookup = malloc(MAXDNAME);
int variant = 0;
+ struct sockaddr_in sa;
+#ifdef __UCLIBC_HAS_IPV6__
+ int v6;
+ struct sockaddr_in6 sa6;
+#endif
fd = -1;
@@ -688,14 +653,39 @@ 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, dns);
- fd = __connect_dns(dns);
+#ifdef __UCLIBC_HAS_IPV6__
+ v6 = inet_pton(AF_INET6, dns, &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 < 0) {
- if (errno == ENETUNREACH) {
- /* routing error, presume not transient */
- goto tryall;
- } else
- /* retry */
- continue;
+ continue;
+ }
+
+ /* Connect to the UDP socket so that asyncronous errors are returned */
+#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(dns);
+ rc = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
+#ifdef __UCLIBC_HAS_IPV6__
+ }
+#endif
+ if (rc < 0) {
+ if (errno == ENETUNREACH) {
+ /* routing error, presume not transient */
+ goto tryall;
+ } else
+ /* retry */
+ continue;
}
DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n",
@@ -716,9 +706,10 @@ int __dns_lookup(const char *name, int type, int nscount, char **nsip,
}
i = recv(fd, packet, 512, 0);
- if (i < HFIXEDSZ)
+ if (i < HFIXEDSZ) {
/* too short ! */
goto again;
+ }
__decode_header(packet, &h);