i noticed the list *after* sending the patch on a private email addy, apologize 
to the owner.

diffed against 1.4.1-beta, regress tests included 

-- 
adrian ilarion ciobanu (cia)
http://pub.mud.ro/~cia/
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.7 (FreeBSD)

mQGiBEeDA88RBADj6/6ogFf7XLKuoFUZf8RkzSk+DUoZ4q1/hheyEiqIss0ixuWz
RphMxo5iUL32sUMB+apjLhZQN0xaSnoxFyEOzRGKNv+VooSiLx89YpXRCJrBTjXT
56tFw0uIFm2bi4W+tl/UcK7E2lAC+pIhfm0Y0kTKeA7a69wwcPDwBi57NwCg9yYO
zW4e/QHvan6HA+mOZOu73NsEAOOV9PW5k1rKswwQhYdzGFNn4ESe3BqV2MF1UFTc
IJlPWQk0BLDv4U9shVIfbKMt7yPriFIThHx7kQrG+p8/S5W/hE9pgf9hV+uYImrv
TMR04Jk0nh8atWAyrEN2TAdKRf8BUY+PQ3QcXyCrkHKOxamx86FoMKAPIbjAZOO/
puu3A/9qJ+HrUgcqr5z2ySZ6oJ1J/j8jlNevGuqG80aFyhUFQq35mjfuE4r16EoV
AWTV7ykuRQ5bsuuFMs2q8C//Q8axBYAlShL7vdj8Up3GYh5k/5V8jyoWr3TbaV3u
pI+08BeqkZGgROsWElNlzs5DQ5mTnv1fRlgpyUX/GtibCYZX67QjYWRyaWFuIGls
YXJpb24gY2lvYmFudSA8Y2lhQG11ZC5ybz6IYAQTEQIAIAUCR4MDzwIbAwYLCQgH
AwIEFQIIAwQWAgMBAh4BAheAAAoJEKJkaij4DxHn8z0AoLbr1chzsY81Ok8JRGrs
R3GI/4dAAKCjduS70wfDpfxCU1RN59W3oOr/j9HRA9EBARAAAQEAAAAAAAAAAAAA
AAD/2P/gABBKRklGAAEBAQBIAEgAAP/hABZFeGlmAABNTQAqAAAACAAAAAAAAP/+
AB1hZHJpYW4uaWxhcmlvbkBjaW9iYW51Lm5hbWX/2wBDAAEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCABGADIDASIAAhEBAxEB/8QAHQAA
AgIDAQEBAAAAAAAAAAAAAAgHCQUGCgQCA//EAC4QAAIDAAEDBAIBAwQDAQAAAAID
AQQFBgcREgAIEyEUFSMiMVEJMkFxFiRCof/EABsBAAICAwEAAAAAAAAAAAAAAAcI
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
=5rWz
-----END PGP PUBLIC KEY BLOCK-----
diff -Nru libevent-1.4.1-beta/evdns.c libevent-1.4.1-beta-dnsmx/evdns.c
--- libevent-1.4.1-beta/evdns.c	2007-12-22 05:03:54.000000000 +0200
+++ libevent-1.4.1-beta-dnsmx/evdns.c	2008-01-17 09:22:44.000000000 +0200
@@ -49,6 +49,7 @@
 
 /* #define NDEBUG */
 
+
 #ifndef DNS_USE_CPU_CLOCK_FOR_ID
 #ifndef DNS_USE_GETTIMEOFDAY_FOR_ID
 #ifndef DNS_USE_OPENSSL_FOR_ID
@@ -162,7 +163,7 @@
 #define TYPE_CNAME     5
 #define TYPE_PTR       EVDNS_TYPE_PTR
 #define TYPE_AAAA      EVDNS_TYPE_AAAA
-
+#define TYPE_MX				 EVDNS_TYPE_MX
 #define CLASS_INET     EVDNS_CLASS_INET
 
 struct request {
@@ -196,7 +197,12 @@
 	u8 s6_addr[16];
 };
 #endif
-
+/*
+struct mx_rr {
+	u16 pri;
+	char host[HOST_NAME_MAX];
+};
+*/
 struct reply {
 	unsigned int type;
 	unsigned int have_answer;
@@ -212,6 +218,10 @@
 		struct {
 			char name[HOST_NAME_MAX];
 		} ptr;
+		struct {
+			u32 mxcount;
+			struct mx_rr mxnames[MAX_ADDRS];
+		} mx;
 	} data;
 };
 
@@ -668,6 +678,16 @@
 		else
 			req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
 		return;
+	case TYPE_MX:
+		if (reply) {
+			req->user_callback(DNS_ERR_NONE, DNS_MX,
+								reply->data.mx.mxcount, ttl,
+								reply->data.mx.mxnames,
+								req->user_pointer);
+		} else {
+			req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
+		}
+		return;
 	case TYPE_PTR:
 		if (reply) {
 			char *name = reply->data.ptr.name;
@@ -751,7 +771,6 @@
 		reply_callback(req, 0, error, NULL);
 		request_finished(req, &req_head);
 	} else {
-		/* all ok, tell the user */
 		reply_callback(req, ttl, 0, reply);
 		nameserver_up(req->ns);
 		request_finished(req, &req_head);
@@ -873,7 +892,6 @@
 	/* now we have the answer section which looks like
 	 * <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
 	 */
-
 	for (i = 0; i < answers; ++i) {
 		u16 type, class;
 
@@ -902,6 +920,24 @@
 			reply.data.a.addrcount += addrtocopy;
 			reply.have_answer = 1;
 			if (reply.data.a.addrcount == MAX_ADDRS) break;
+		} else if (type == TYPE_MX && class == CLASS_INET) {
+			if (req->request_type != TYPE_MX) {
+				printf("warning: type mx but we have request_type=%d\n", req->request_type);
+				j += datalength; continue;
+			}
+			ttl_r = MIN(ttl_r,ttl);
+			GET16(reply.data.mx.mxnames[reply.data.mx.mxcount].pri);
+			if (name_parse(packet, length, &j, reply.data.mx.mxnames[reply.data.mx.mxcount].host,
+				sizeof(reply.data.mx.mxnames[reply.data.mx.mxcount].host))<0) {
+				fprintf(stdout, "name_parse() error!\n");
+				goto err;
+			}
+			reply.data.mx.mxcount +=1;
+			reply.have_answer = 1;
+			if (reply.data.mx.mxcount == MAX_ADDRS) {
+				printf("reached MAX_ADDRS , skipping the next answers\n");
+				break;
+			}
 		} else if (type == TYPE_PTR && class == CLASS_INET) {
 			if (req->request_type != TYPE_PTR) {
 				j += datalength; continue;
@@ -936,7 +972,6 @@
 			j += datalength;
 		}
 	}
-
 	reply_handle(req, flags, ttl_r, &reply);
 	return 0;
  err:
@@ -1554,7 +1589,14 @@
 		  req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
 		  ttl, n*4, 0, addrs);
 }
-
+/* exported function */
+int
+evdns_server_request_add_mx_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
+{
+	return evdns_server_request_add_reply(
+		req, EVDNS_ANSWER_SECTION,name,TYPE_MX, CLASS_INET,
+			ttl,n,0,addrs); 
+}
 /* exported function */
 int
 evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
@@ -2286,6 +2328,22 @@
 	}
 }
 
+/* exported function */
+int evdns_resolve_mx(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_MX, name, flags, callback, ptr);
+		if (req == NULL)
+			return (1);
+		request_submit(req);
+		return (0);
+	} else {
+		return (search_request_new(TYPE_MX,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;
@@ -2485,7 +2543,7 @@
 
 static int
 search_request_new(int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg) {
-	assert(type == TYPE_A || type == TYPE_AAAA);
+	assert(type == TYPE_A || type == TYPE_AAAA || type == TYPE_MX);
 	if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
 	     global_search_state &&
 		 global_search_state->num_domains) {
diff -Nru libevent-1.4.1-beta/evdns.h libevent-1.4.1-beta-dnsmx/evdns.h
--- libevent-1.4.1-beta/evdns.h	2007-11-12 04:37:32.000000000 +0200
+++ libevent-1.4.1-beta-dnsmx/evdns.h	2008-01-17 09:19:17.000000000 +0200
@@ -193,7 +193,7 @@
 #define DNS_IPv4_A 1
 #define DNS_PTR 2
 #define DNS_IPv6_AAAA 3
-
+#define DNS_MX 4
 #define DNS_QUERY_NO_SEARCH 1
 
 #define DNS_OPTION_SEARCH 1
@@ -201,6 +201,16 @@
 #define DNS_OPTION_MISC 4
 #define DNS_OPTIONS_ALL 7
 
+/*
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif
+*/
+struct mx_rr {
+	uint16_t pri;
+	char host[255];
+};
+
 /**
  * The callback that contains the results from a lookup.
  * - type is either DNS_IPv4_A or DNS_PTR or DNS_IPv6_AAAA
@@ -320,6 +330,17 @@
  */
 int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr);
 
+/**
+  Lookup an MX record for a given name.
+
+  @param name a DNS hostname
+  @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
+  @see evdns_resolve_ipv6(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6()
+ */
+int evdns_resolve_mx(const char *name, int flags, evdns_callback_type callback, void *ptr);
 
 /**
   Lookup an AAAA record for a given name.
@@ -512,6 +533,7 @@
 
 int evdns_server_request_add_reply(struct evdns_server_request *req, int section, const char *name, int type, int dns_class, int ttl, int datalen, int is_name, const char *data);
 int evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl);
+int evdns_server_request_add_mx_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl);
 int evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl);
 int evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl);
 int evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl);
diff -Nru libevent-1.4.1-beta/test/regress_dns.c libevent-1.4.1-beta-dnsmx/test/regress_dns.c
--- libevent-1.4.1-beta/test/regress_dns.c	2007-12-18 19:18:40.000000000 +0200
+++ libevent-1.4.1-beta-dnsmx/test/regress_dns.c	2008-01-17 09:46:41.000000000 +0200
@@ -73,7 +73,6 @@
     void *addresses, void *arg)
 {
 	dns_ok = dns_err = 0;
-
 	if (result == DNS_ERR_TIMEOUT) {
 		fprintf(stdout, "[Timed out] ");
 		dns_err = result;
@@ -116,6 +115,14 @@
 			fprintf(stderr, "%s ", inet_ntoa(in_addrs[i]));
 		break;
 	}
+	case DNS_MX: {
+		struct mx_rr *mxinf = addresses;
+		if (ttl < 0 || count < 1 )
+			goto out;
+		fprintf(stderr, "test_domain=%s,rr_count=%d, first rr: pri=%d,mxhost=%s ",
+			(char *)arg,count,mxinf[0].pri,mxinf[0].host);
+		break;
+	}
 	case DNS_PTR:
 		/* may get at most one PTR */
 		if (count != 1)
@@ -148,7 +155,21 @@
 		exit(1);
 	}
 }
-
+static void
+dns_gethostmx(void)
+{
+	fprintf(stdout,"MX DNS resolve: ");
+	evdns_resolve_mx("aol.com",0,dns_gethostbyname_cb,"aol.com");
+	event_dispatch();
+	if (dns_ok == DNS_MX) {
+		fprintf(stdout,"OK\n");
+	} else if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) {
+		fprintf(stdout, "SKIPPED\n");
+	} else {
+		fprintf(stdout, "FAILED (%d)\n", dns_ok);
+		exit(1);
+	}
+}
 static void
 dns_gethostbyname6(void)
 {
@@ -217,6 +238,22 @@
 					   "ZZ.EXAMPLE.COM", 54321);
 			if (r<0)
 				dns_ok = 0;
+		} else if (req->questions[i]->type == EVDNS_TYPE_MX &&
+						req->questions[i]->dns_question_class == EVDNS_CLASS_INET &&
+						!strcmp(req->questions[i]->name,"example.com")) {
+			uint32_t datalen = 9;
+			uint8_t len = 2;
+			char *addrs = (char *)malloc(/*mxpri*/ 2 + /*length of 2 labels */ 2 + /*c1.xx*/ 4);
+			bzero(addrs, 9);
+			/*let pri 0 */
+			/*len(c1)*/
+			memcpy(addrs+2,&len,1);
+			memcpy(addrs+3,"c1",2);
+			memcpy(addrs+5,&len,1);
+			memcpy(addrs+6,"xx",2);
+			r = evdns_server_request_add_mx_reply(req,"example.com",datalen,addrs,300);
+			if (r<0)
+				dns_ok = 0;
 		} else {
 			fprintf(stdout, "Unexpected question %d %d \"%s\" ",
 					req->questions[i]->type,
@@ -281,11 +318,21 @@
 		}
 		break;
 	}
+	case DNS_MX: {
+		struct mx_rr *mxinf = (struct mx_rr *)addresses;
+		if (mxinf[0].pri != 0 || strcmp(mxinf[0].host,"c1.xx") != 0) {
+			fprintf(stdout, "Unexpected MX reply pri=%d,mxhost=%s!\n",mxinf[0].pri,mxinf[0].host);
+			dns_ok = 0;
+			goto out;
+		} /*else {
+			fprintf(stderr, "MX_REPLY: %d %s [OK]\n", mxinf[0].pri,mxinf[0].host);
+		} */
+		break;
+	}
 	default:
 		fprintf(stdout, "Bad response type %d. ", type);
 		dns_ok = 0;
 	}
-
  out:
 	if (++n_server_responses == 3) {
 		event_loopexit(NULL);
@@ -343,7 +390,8 @@
 	resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
 	evdns_resolve_reverse(&resolve_addr, 0,
 						  dns_server_gethostbyname_cb, NULL);
-
+	evdns_resolve_mx("example.com",DNS_QUERY_NO_SEARCH,
+							dns_server_gethostbyname_cb,NULL);
 	event_dispatch();
 
 	if (dns_ok) {
@@ -371,6 +419,7 @@
 	dns_gethostbyname();
 	dns_gethostbyname6();
 	dns_gethostbyaddr();
+	dns_gethostmx();
 
 	evdns_shutdown(0);
 }

Attachment: pgpeLvHUolX4I.pgp
Description: PGP signature

_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users

Reply via email to