Hi,

We are using evdns for RBL requests and I think it may be useful to have support of TXT records in evdns. I've made a patch to current trunk. Regression test for TXT records asks a record from google.com (just for testing), this can be a point to change.
--- evdns.c.orig	2008-09-10 19:40:25.344885214 +0400
+++ evdns.c	2008-09-10 20:01:01.516463201 +0400
@@ -155,6 +155,7 @@
 #define TYPE_CNAME     5
 #define TYPE_PTR       EVDNS_TYPE_PTR
 #define TYPE_AAAA      EVDNS_TYPE_AAAA
+#define TYPE_TXT       EVDNS_TYPE_TXT
 
 #define CLASS_INET     EVDNS_CLASS_INET
 
@@ -207,6 +208,10 @@
 		struct {
 			char name[HOST_NAME_MAX];
 		} ptr;
+		/* TXT field may be longer than 508 bytes, but UDP packets are limited to 512 octets */
+		struct {
+			char data[508];
+		} txt; 
 	} data;
 };
 
@@ -687,6 +692,16 @@
 		else
 			req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
                 return;
+	case TYPE_TXT:
+		if (reply) {
+			char *data = reply->data.txt.data;
+			req->user_callback(DNS_ERR_NONE, DNS_TXT, 1, ttl,
+								&data, req->user_pointer);
+		}
+		else {
+			req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
+		}
+		return; 
 	}
 	assert(0);
 }
@@ -950,6 +965,16 @@
 			j += 16*addrtocopy;
 			reply.have_answer = 1;
 			if (reply.data.aaaa.addrcount == MAX_ADDRS) break;
+		} else if (type == TYPE_TXT) {
+			if (req->request_type != TYPE_TXT) {
+				j += datalength;
+				continue;
+			}
+			memcpy(&reply.data.txt.data, packet + j + 1, MIN(sizeof(reply.data.txt.data), datalength - 1));
+			j += datalength;
+			ttl_r = MIN(ttl_r, ttl);
+			reply.have_answer = 1;
+			break;
 		} else {
 			/* skip over any other type of resource */
 			j += datalength;
@@ -2437,6 +2462,23 @@
 		? 0 : -1;
 }
 
+struct evdns_request *
+evdns_base_resolve_txt(struct evdns_base *base, const char *in, int flags, evdns_callback_type callback, void *ptr) {
+	struct evdns_request *req;
+	assert(in);
+	log(EVDNS_LOG_DEBUG, "Resolve requested for %s (txt)", in);
+	req = request_new(base, TYPE_TXT, in, flags, callback, ptr);
+	if (!req) return NULL;
+	request_submit(req);
+	return req;
+}
+
+int
+evdns_resolve_txt(const char *in, int flags, evdns_callback_type callback, void *ptr)  {
+	return evdns_base_resolve_txt(current_base, in, flags, callback, ptr)
+		? 0 : -1;
+}
+
 /*/////////////////////////////////////////////////////////////////// */
 /* Search support */
 /* */
--- evdns.h.orig	2008-09-10 19:50:32.380908466 +0400
+++ evdns.h	2008-09-10 19:52:58.009929005 +0400
@@ -193,6 +193,7 @@
 #define DNS_IPv4_A 1
 #define DNS_PTR 2
 #define DNS_IPv6_AAAA 3
+#define DNS_TXT 4
 
 #define DNS_QUERY_NO_SEARCH 1
 
@@ -376,6 +377,16 @@
 int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
 struct evdns_request *evdns_base_resolve_reverse_ipv6(struct evdns_base *base, struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
 
+/**
+  Lookup a TXT entry for a specified DNS name.
+  @param name a DNS name
+  @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query.
+  @param callback a callback function to invoke when the request is completed
+  @param ptr an argument to pass to the callback function
+  @return 0 if successful, or -1 if an error occurred
+*/
+int evdns_resolve_txt(const char *in, int flags, evdns_callback_type callback, void *ptr);
+struct evdns_request* evdns_base_resolve_txt(struct evdns_base *base, const char *in, int flags, evdns_callback_type callback, void *ptr);
 
 /**
   Set the value of a configuration option.
--- test/regress_dns.c.orig	2008-09-10 19:53:19.632882605 +0400
+++ test/regress_dns.c	2008-09-10 19:57:35.593441882 +0400
@@ -118,6 +118,7 @@
 		break;
 	}
 	case DNS_PTR:
+	case DNS_TXT:
 		/* may get at most one PTR */
 		if (count != 1)
 			goto out;
@@ -186,6 +187,22 @@
 	}
 }
 
+static void
+dns_gettxtrec(void)
+{
+	fprintf(stdout, "Simple TXT DNS lookup: ");
+	dns_ok = 0;
+	evdns_resolve_txt("google.com", 0, dns_gethostbyname_cb, NULL);
+	event_dispatch();
+
+	if (dns_ok == DNS_TXT) {
+		fprintf(stdout, "OK\n");
+	} else {
+		fprintf(stdout, "FAILED\n");
+		exit(1);
+	}
+}
+
 static int n_server_responses = 0;
 
 static void
@@ -282,6 +299,10 @@
 		}
 		break;
 	}
+	case DNS_TXT: {
+		fprintf (stdout, "Got TXT record for google.com: %s\n", *(char **)addresses);
+		break;
+	}
 	default:
 		fprintf(stdout, "Bad response type %d. ", type);
 		dns_ok = 0;
@@ -372,6 +393,7 @@
 	dns_gethostbyname();
 	dns_gethostbyname6();
 	dns_gethostbyaddr();
+	dns_gettxtrec();
 
 	evdns_shutdown(0);
 }
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users

Reply via email to