[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r9089: Add ipv6 functionality to evdns. (in tor/trunk: . doc src/or)



Author: nickm
Date: 2006-12-11 22:48:46 -0500 (Mon, 11 Dec 2006)
New Revision: 9089

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/configure.in
   tor/trunk/doc/TODO
   tor/trunk/src/or/eventdns.c
   tor/trunk/src/or/eventdns.h
Log:
 r11536@Kushana:  nickm | 2006-12-11 22:48:21 -0500
 Add ipv6 functionality to evdns.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r11536] on c95137ef-5f19-0410-b913-86e773d04f59

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2006-12-12 02:57:42 UTC (rev 9088)
+++ tor/trunk/ChangeLog	2006-12-12 03:48:46 UTC (rev 9089)
@@ -6,7 +6,8 @@
     - Try to batch changes to the state so that we do as few disk writes
       as possible while still storing important things in a timely
       fashion.
-    - Ongoing work on eventdns infrastructure
+    - Ongoing work on eventdns infrastructure: add dns server and ipv6
+      support.
 
   o Major bugfixes:
     - Fix a longstanding bug in eventdns that prevented the count of

Modified: tor/trunk/configure.in
===================================================================
--- tor/trunk/configure.in	2006-12-12 02:57:42 UTC (rev 9088)
+++ tor/trunk/configure.in	2006-12-12 03:48:46 UTC (rev 9089)
@@ -554,6 +554,10 @@
 
 AC_CHECK_TYPES([uint, u_char])
 
+AC_CHECK_TYPES([struct in6_addr, struct sockaddr_storage], , ,
+[#include <netinet/in.h>
+#include <sys/socket.h>])
+
 if test -z "$CROSS_COMPILE"; then
 AC_CACHE_CHECK([whether time_t is signed], tor_cv_time_t_signed, [
 AC_TRY_RUN([

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2006-12-12 02:57:42 UTC (rev 9088)
+++ tor/trunk/doc/TODO	2006-12-12 03:48:46 UTC (rev 9089)
@@ -92,7 +92,7 @@
     . Asynchronous DNS
       o Document and rename SearchDomains, ResolvConf options
       D Make API closer to getaddrinfo()
-      - Teach evdns about ipv6.
+      o Teach evdns about ipv6.
       - Make evdns use windows strerror equivalents.
       - Teach evdns to be able to listen for requests to be processed.
         o Design interface.

Modified: tor/trunk/src/or/eventdns.c
===================================================================
--- tor/trunk/src/or/eventdns.c	2006-12-12 02:57:42 UTC (rev 9088)
+++ tor/trunk/src/or/eventdns.c	2006-12-12 03:48:46 UTC (rev 9089)
@@ -349,6 +349,12 @@
 	char transmit_me;  // needs to be transmitted
 };
 
+#ifndef HAVE_STRUCT_IN6_ADDR
+struct in6_addr {
+    u8 s6_addr[16];
+};
+#endif
+
 struct reply {
 	unsigned int type;
 	unsigned int have_answer;
@@ -358,6 +364,10 @@
 			u32 addresses[MAX_ADDRS];
 		} a;
 		struct {
+			u32 addrcount;
+			struct in6_addr addresses[MAX_ADDRS];
+		} aaaa;
+		struct {
 			char name[HOST_NAME_MAX];
 		} ptr;
 	} data;
@@ -811,7 +821,7 @@
 		if (reply)
 			req->user_callback(DNS_ERR_NONE, DNS_IPv4_A,
 							   reply->data.a.addrcount, ttl,
-						 reply->data.a.addresses,
+							   reply->data.a.addresses,
 							   req->user_pointer);
 		else
 			req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
@@ -826,6 +836,14 @@
 							   req->user_pointer);
 		}
 		return;
+	case TYPE_AAAA:
+		if (reply)
+			req->user_callback(DNS_ERR_NONE, DNS_IPv4_AAAA,
+							   reply->data.aaaa.addrcount, ttl,
+							   reply->data.aaaa.addresses,
+							   req->user_pointer);
+		else
+			req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
 	}
 	assert(0);
 }
@@ -1015,11 +1033,11 @@
 
 		if (type == TYPE_A && class == CLASS_INET) {
 			int addrcount, addrtocopy;
-			if (req->request_type != TYPE_A) {
+			if (req->request_type != type) {
 				j += datalength; continue;
 			}
-			// XXXX do something sane with malformed A answers.
-			addrcount = datalength >> 2;  // each IP address is 4 bytes
+			// XXXX do something sane with malformed answers.
+			addrcount = datalength >> 2;  // each address is 4 bytes long
 			addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
 			ttl_r = MIN(ttl_r, ttl);
 
@@ -1027,8 +1045,8 @@
 			if (j + 4*addrtocopy > length) return -1;
 			memcpy(&reply.data.a.addresses[reply.data.a.addrcount],
 				   packet + j, 4*addrtocopy);
+			reply.data.a.addrcount += addrtocopy;
 			j += 4*addrtocopy;
-			reply.data.a.addrcount += addrtocopy;
 			reply.have_answer = 1;
 			if (reply.data.a.addrcount == MAX_ADDRS) break;
 		} else if (type == TYPE_PTR && class == CLASS_INET) {
@@ -1040,12 +1058,24 @@
 				return -1;
 			reply.have_answer = 1;
 			break;
-		} else if (type == TYPE_AAAA && class == CLASS_INET) {
-			if (req->request_type != TYPE_AAAA) {
+        } else if (type == TYPE_AAAA && class == CLASS_INET) {
+			int addrcount, addrtocopy;
+			if (req->request_type != type) {
 				j += datalength; continue;
 			}
-			// XXXX Implement me. -NM
-			j += datalength;
+			// XXXX do something sane with malformed answers.
+			addrcount = datalength >> 4;  // each address is 16 bytes long
+			addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
+			ttl_r = MIN(ttl_r, ttl);
+
+			// we only bother with the first four addresses.
+			if (j + 16*addrtocopy > length) return -1;
+			memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount],
+				   packet + j, 16*addrtocopy);
+			reply.data.aaaa.addrcount += addrtocopy;
+			j += 16*addrtocopy;
+			reply.have_answer = 1;
+			if (reply.data.a.addrcount == MAX_ADDRS) break;
 		} else {
 			// skip over any other type of resource
 			j += datalength;
@@ -2309,6 +2339,22 @@
 	}
 }
 
+// exported function
+int evdns_resolve_ipv6(const char *name, int flags,
+                       evdns_callback_type callback, void *ptr) {
+	log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
+	if (flags & DNS_QUERY_NO_SEARCH) {
+		struct request *const req =
+            request_new(TYPE_AAAA, name, flags, callback, ptr);
+		if (req == NULL)
+            return 1;
+		request_submit(req);
+		return 0;
+	} else {
+		return search_request_new(TYPE_AAAA, name, flags, callback, ptr);
+	}
+}
+
 int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
 	char buf[32];
 	struct request *req;
@@ -2327,6 +2373,30 @@
 	return 0;
 }
 
+int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
+	char buf[64];
+    char *cp;
+	struct request *req;
+    int i;
+	assert(in);
+
+    cp = buf;
+    for (i=0; i < 16; ++i) {
+        u8 byte = in->s6_addr[i];
+        *cp++ = "0123456789abcdef"[byte >> 4];
+        *cp++ = '.';
+		*cp++ = "0123456789abcdef"[byte & 0x0f];
+        *cp++ = '.';
+    }
+    assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf));
+    strcpy(cp, ".ip6.arpa");
+	log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
+	req = request_new(TYPE_PTR, buf, flags, callback, ptr);
+	if (!req) return 1;
+	request_submit(req);
+	return 0;
+}
+
 /////////////////////////////////////////////////////////////////////
 // Search support
 //

Modified: tor/trunk/src/or/eventdns.h
===================================================================
--- tor/trunk/src/or/eventdns.h	2006-12-12 02:57:42 UTC (rev 9088)
+++ tor/trunk/src/or/eventdns.h	2006-12-12 03:48:46 UTC (rev 9089)
@@ -41,6 +41,7 @@
 
 #define DNS_IPv4_A 1
 #define DNS_PTR 2
+#define DNS_IPv4_AAAA 3
 
 #define DNS_QUERY_NO_SEARCH 1
 
@@ -60,8 +61,11 @@
 int evdns_resume(void);
 int evdns_nameserver_ip_add(const char *ip_as_string);
 int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr);
+int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr);
 struct in_addr;
+struct in6_addr;
 int evdns_resolve_reverse(struct in_addr *addr, int flags, evdns_callback_type callback, void *ptr);
+int evdns_resolve_reverse_ipv6(struct in6_addr *addr, int flags, evdns_callback_type callback, void *ptr);
 int evdns_resolv_conf_parse(int flags, const char *);
 #ifdef MS_WINDOWS
 int evdns_config_windows_nameservers(void);