Permalink
Browse files

Added support for MX, and NS records

  • Loading branch information...
1 parent 09cbc3d commit a14c5bc14dee5e52eaa8336c6c330b965a87bd12 Jeroen Koekkoek committed Mar 30, 2012
Showing with 138 additions and 3 deletions.
  1. +95 −0 evdns.c
  2. +43 −3 include/event2/dns.h
View
95 evdns.c
@@ -144,12 +144,16 @@
/* that we bother recording */
#define MAX_V4_ADDRS 32
#define MAX_V6_ADDRS 32
+#define MAX_NS_RRS 32
+#define MAX_MX_RRS 32
#define TYPE_A EVDNS_TYPE_A
+#define TYPE_NS EVDNS_TYPE_NS
#define TYPE_CNAME 5
#define TYPE_PTR EVDNS_TYPE_PTR
#define TYPE_SOA EVDNS_TYPE_SOA
+#define TYPE_MX EVDNS_TYPE_MX
#define TYPE_AAAA EVDNS_TYPE_AAAA
#define CLASS_INET EVDNS_CLASS_INET
@@ -215,6 +219,14 @@ struct reply {
struct {
char name[HOST_NAME_MAX];
} ptr;
+ struct {
+ u32 count;
+ struct evdns_rr_ns records[MAX_NS_RRS];
+ } ns;
+ struct {
+ u32 count;
+ struct evdns_rr_mx records[MAX_MX_RRS];
+ } mx;
} data;
};
@@ -798,6 +810,22 @@ reply_run_callback(struct deferred_cb *d, void *user_pointer)
else
cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
break;
+ case TYPE_NS:
+ if (cb->have_reply)
+ cb->user_callback(DNS_ERR_NONE, DNS_NS,
+ cb->reply.data.ns.count, cb->ttl,
+ cb->reply.data.ns.records, user_pointer);
+ else
+ cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
+ break;
+ case TYPE_MX:
+ if (cb->have_reply)
+ cb->user_callback(DNS_ERR_NONE, DNS_MX,
+ cb->reply.data.mx.count, cb->ttl,
+ cb->reply.data.mx.records, user_pointer);
+ else
+ cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
+ break;
default:
EVUTIL_ASSERT(0);
}
@@ -1142,6 +1170,31 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) {
j += 16*addrtocopy;
reply.have_answer = 1;
if (reply.data.aaaa.addrcount == MAX_V6_ADDRS) break;
+ } else if (type == TYPE_NS) {
+ int cnt;
+ if (req->request_type != TYPE_NS) {
+ j += datalength; continue;
+ }
+ cnt = reply.data.ns.count;
+ ttl_r = MIN(ttl_r, ttl);
+ if (name_parse(packet, length, &j, reply.data.ns.records[cnt].name,
+ sizeof(reply.data.ns.records[cnt].name))<0)
+ goto err;
+ reply.have_answer = 1;
+ if (++reply.data.ns.count == MAX_NS_RRS) break;
+ } else if (type == TYPE_MX) {
+ int cnt;
+ if (req->request_type != TYPE_MX) {
+ j += datalength; continue;
+ }
+ cnt = reply.data.mx.count;
+ ttl_r = MIN(ttl_r, ttl);
+ GET16(reply.data.mx.records[cnt].pref);
+ if (name_parse(packet, length, &j, reply.data.mx.records[cnt].name,
+ sizeof(reply.data.mx.records[cnt].name))<0)
+ goto err;
+ reply.have_answer = 1;
+ if (++reply.data.mx.count == MAX_MX_RRS) break;
} else {
/* skip over any other type of resource */
j += datalength;
@@ -2938,6 +2991,48 @@ int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callb
? 0 : -1;
}
+struct evdns_request *
+evdns_base_resolve_ns(struct evdns_base *base, const char *name, int flags, evdns_callback_type callback, void *ptr)
+{
+ struct evdns_request *handle;
+ struct request *req;
+ log(EVDNS_LOG_DEBUG, "Resolve requested for %s (ns)", name);
+ handle = mm_calloc(1, sizeof (*handle));
+ if (handle == NULL)
+ return NULL;
+ EVDNS_LOCK(base);
+ req = request_new(base, handle, TYPE_NS, name, flags, callback, ptr);
+ if (req)
+ request_submit(req);
+ if (handle->current_req == NULL) {
+ mm_free(handle);
+ handle = NULL;
+ }
+ EVDNS_UNLOCK(base);
+ return (handle);
+}
+
+struct evdns_request *
+evdns_base_resolve_mx(struct evdns_base *base, const char *name, int flags, evdns_callback_type callback, void *ptr)
+{
+ struct evdns_request *handle;
+ struct request *req;
+ log(EVDNS_LOG_DEBUG, "Resolve requested for %s (mx)", name);
+ handle = mm_calloc(1, sizeof (*handle));
+ if (handle == NULL)
+ return NULL;
+ EVDNS_LOCK(base);
+ req = request_new(base, handle, TYPE_MX, name, flags, callback, ptr);
+ if (req)
+ request_submit(req);
+ if (handle->current_req == NULL) {
+ mm_free(handle);
+ handle = NULL;
+ }
+ EVDNS_UNLOCK(base);
+ return (handle);
+}
+
/* ================================================================= */
/* Search support */
/* */
View
@@ -174,6 +174,8 @@ extern "C" {
#define DNS_IPv4_A 1
#define DNS_PTR 2
#define DNS_IPv6_AAAA 3
+#define DNS_NS 4
+#define DNS_MX 5
#define DNS_QUERY_NO_SEARCH 1
@@ -189,18 +191,30 @@ extern "C" {
/**
* The callback that contains the results from a lookup.
* - result is one of the DNS_ERR_* values (DNS_ERR_NONE for success)
- * - type is either DNS_IPv4_A or DNS_PTR or DNS_IPv6_AAAA
+ * - type is either DNS_IPv4_A or DNS_PTR or DNS_IPv6_AAAA or DNS_MX or DNS_NS
* - count contains the number of addresses of form type
* - ttl is the number of seconds the resolution may be cached for.
* - addresses needs to be cast according to type. It will be an array of
- * 4-byte sequences for ipv4, or an array of 16-byte sequences for ipv6,
- * or a nul-terminated string for PTR.
+ * 4-byte sequences for ipv4, an array of 16-byte sequences for ipv6,
+ * a nul-terminated string for PTR, an array of evdns_rr_ns for NS, or
+ * an array of evdns_rr_mx for MX.
*/
typedef void (*evdns_callback_type) (int result, char type, int count, int ttl, void *addresses, void *arg);
struct evdns_base;
struct event_base;
+/* ???? HOST_NAME_MAX set to 64 in libevent 2.1.x-alpha? */
+struct evdns_rr_mx {
+ int pref;
+ char name[255];
+};
+
+/* evdns_rr_ns here for convenience */
+struct evdns_rr_ns {
+ char name[255];
+};
+
/**
Initialize the asynchronous DNS library.
@@ -377,6 +391,32 @@ struct evdns_request *evdns_base_resolve_reverse(struct evdns_base *base, const
struct evdns_request *evdns_base_resolve_reverse_ipv6(struct evdns_base *base, const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
/**
+ Lookup an NS records for a given name
+
+ @param base the evdns_base to which to apply this operation
+ @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 an evdns_request object if successful, or NULL if an error occurred.
+ @see evdns_cancel_request()
+ */
+struct evdns_request *evdns_base_resolve_ns(struct evdns_base *base, const char *name, int flags, evdns_callback_type callback, void *ptr);
+
+/**
+ Lookup an MX records for a given name
+
+ @param base the evdns_base to which to apply this operation
+ @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 an evdns_request object if successful, or NULL if an error occurred.
+ @see evdns_cancel_request()
+ */
+struct evdns_request *evdns_base_resolve_mx(struct evdns_base *base, const char *name, int flags, evdns_callback_type callback, void *ptr);
+
+/**
Cancels a pending DNS resolution request.
@param base the evdns_base that was used to make the request

0 comments on commit a14c5bc

Please sign in to comment.