svn commit: trunk/uClibc/libc/inet

vda at uclibc.org vda at uclibc.org
Sat Nov 1 23:33:16 UTC 2008


Author: vda
Date: 2008-11-01 16:33:16 -0700 (Sat, 01 Nov 2008)
New Revision: 23896

Log:
__dns_lookup: document and optimize a bit

    text           data     bss     dec     hex filename
-   1545              2       4    1551     60f libc/inet/dnslookup.o
+   1528              2       4    1534     5fe libc/inet/dnslookup.o



Modified:
   trunk/uClibc/libc/inet/resolv.c


Changeset:
Modified: trunk/uClibc/libc/inet/resolv.c
===================================================================
--- trunk/uClibc/libc/inet/resolv.c	2008-11-01 23:25:50 UTC (rev 23895)
+++ trunk/uClibc/libc/inet/resolv.c	2008-11-01 23:33:16 UTC (rev 23896)
@@ -742,8 +742,25 @@
  * rw data costs more. */
 static uint16_t static_id = 1;
 
-int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char **nsip,
-			   unsigned char **outpacket, struct resolv_answer *a)
+/* On entry:
+ *  a.buf(len) = auxiliary buffer for IP addresses after first one
+ *  a.add_count = how many additional addresses are there already
+ *  outpacket = where to save ptr to raw packet? can be NULL
+ * On exit:
+ *  ret < 0: error, all other data is not valid
+ *  a.add_count & a.buf: updated
+ *  a.rdlength: length of addresses (4 bytes for IPv4)
+ *  *outpacket: updated (packet is malloced, you need to free it)
+ *  a.rdata: points into *outpacket to 1st IP addr
+ *      NB: don't pass outpacket == NULL if you need to use a.rdata!
+ *  a.atype: type of query?
+ *  a.dotted: numeric IP as a string (malloced, may be NULL if strdup failed)
+ *      (which one of potentially many??)
+ */
+int attribute_hidden __dns_lookup(const char *name, int type,
+			int nscount, char **nsip,
+			unsigned char **outpacket,
+			struct resolv_answer *a)
 {
 	int i, j, len, fd, pos, rc;
 #ifdef USE_SELECT
@@ -762,13 +779,15 @@
 	int variant = -1;  /* search domain to append, -1 - none */
 	int local_ns = -1, local_id = -1;
 	bool ends_with_dot;
+	union {
+		struct sockaddr sa;
+#ifdef __UCLIBC_HAS_IPV4__
+		struct sockaddr_in sa4;
+#endif
 #ifdef __UCLIBC_HAS_IPV6__
-	bool v6;
-	struct sockaddr_in6 sa6;
+		struct sockaddr_in6 sa6;
 #endif
-#ifdef __UCLIBC_HAS_IPV4__
-	struct sockaddr_in sa;
-#endif
+	} sa;
 
 	fd = -1;
 
@@ -841,43 +860,38 @@
 		DPRINTF("On try %d, sending query to port %d of machine %s\n",
 				retries+1, NAMESERVER_PORT, dns);
 
+		sa.sa.sa_family = AF_INET;
 #ifdef __UCLIBC_HAS_IPV6__
 		//__UCLIBC_MUTEX_LOCK(__resolv_lock);
 		///* 'dns' is really __nameserver[] which is a global that
 		//   needs to hold __resolv_lock before access!! */
-		v6 = inet_pton(AF_INET6, dns, &sa6.sin6_addr) > 0;
+		if (inet_pton(AF_INET6, dns, &sa.sa6.sin6_addr) > 0)
+			sa.sa.sa_family = AF_INET6;
 		//__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-		fd = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-#else
-		fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 #endif
-		if (fd < 0) {
-			retries++;
-			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);
+		if (sa.sa.sa_family == AF_INET6) {
+			sa.sa6.sin6_port = htons(NAMESERVER_PORT);
 			/* sa6.sin6_addr is already here */
-			rc = connect(fd, (struct sockaddr *) &sa6, sizeof(sa6));
-		} else {
+		} else
 #endif
 #ifdef __UCLIBC_HAS_IPV4__
-			sa.sin_family = AF_INET;
-			sa.sin_port = htons(NAMESERVER_PORT);
+		{
+			sa.sa4.sin_port = htons(NAMESERVER_PORT);
 			//__UCLIBC_MUTEX_LOCK(__resolv_lock);
 			///* 'dns' is really __nameserver[] which is a global that
 			//   needs to hold __resolv_lock before access!! */
-			sa.sin_addr.s_addr = inet_addr(dns);
+			sa.sa4.sin_addr.s_addr = inet_addr(dns);
 			//__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
-			rc = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
+		}
 #endif
-#ifdef __UCLIBC_HAS_IPV6__
+		fd = socket(sa.sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
+		if (fd < 0) {
+			retries++;
+			continue;
 		}
-#endif
+		rc = connect(fd, &sa.sa, sizeof(sa));
 		if (rc < 0) {
 			if (errno == ENETUNREACH) {
 				/* routing error, presume not transient */
@@ -900,7 +914,6 @@
 		tv.tv_usec = 0;
 		if (select(fd + 1, &fds, NULL, NULL, &tv) <= 0) {
 			DPRINTF("Timeout\n");
-
 			/* timed out, so retry send and receive,
 			 * to next nameserver on queue */
 			goto tryall;
@@ -910,7 +923,6 @@
 		fds.events = POLLIN;
 		if (poll(&fds, 1, REPLY_TIMEOUT * 1000) <= 0) {
 			DPRINTF("Timeout\n");
-
 			/* timed out, so retry send and receive,
 			 * to next nameserver on queue */
 			goto tryall;
@@ -967,9 +979,8 @@
 		DPRINTF("Decoding answer at pos %d\n", pos);
 
 		first_answer = 1;
-		for (j = 0; j < h.ancount && pos < len; j++, pos += i) {
+		for (j = 0; j < h.ancount && pos < len; j++) {
 			i = __decode_answer(packet, pos, len, &ma);
-
 			if (i < 0) {
 				DPRINTF("failed decode %d\n", i);
 				/* if the message was truncated and we have
@@ -978,13 +989,14 @@
 					break;
 				goto again;
 			}
+			pos += i;
 
 			if (first_answer) {
 				ma.buf = a->buf;
 				ma.buflen = a->buflen;
 				ma.add_count = a->add_count;
 				memcpy(a, &ma, sizeof(ma));
-				if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
+				if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA)))
 					break;
 				if (a->atype != type) {
 					free(a->dotted);
@@ -1288,7 +1300,7 @@
               unsigned char *answer, int anslen)
 {
 	int i;
-	unsigned char * packet = 0;
+	unsigned char * packet = NULL;
 	struct resolv_answer a;
 	int __nameserversXX;
 	char ** __nameserverXX;




More information about the uClibc-cvs mailing list