summaryrefslogtreecommitdiff
path: root/evdns.c
diff options
context:
space:
mode:
authorSergey Matveychuk <sem33@yandex-team.ru>2021-04-07 20:39:18 +0300
committerAzat Khuzhin <azat@libevent.org>2021-05-24 21:03:45 +0300
commit19b3fd0bf03c94e694ac25ad95fe43ac10df73b5 (patch)
tree1efe5d81b55a16c67d93e161a8638680393ead90 /evdns.c
parent087bbc572c48d9304d8b6b911e6b0cf966ba3c28 (diff)
downloadlibevent-19b3fd0bf03c94e694ac25ad95fe43ac10df73b5.tar.gz
evdns: add ability to get CNAME
Add new flag (DNS_CNAME_CALLBACK) for evdns_base_resolve_ipv4()/evdns_base_resolve_ipv6(). If set, you will get one more callback with type == DNS_CNAME and CNAME in addrs argument.
Diffstat (limited to 'evdns.c')
-rw-r--r--evdns.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/evdns.c b/evdns.c
index 52077064..0f1c3595 100644
--- a/evdns.c
+++ b/evdns.c
@@ -209,6 +209,7 @@ struct request {
u16 trans_id; /* the transaction id */
unsigned request_appended :1; /* true if the request pointer is data which follows this struct */
unsigned transmit_me :1; /* needs to be transmitted */
+ unsigned need_cname :1; /* make a separate callback for CNAME */
/* XXXX This is a horrible hack. */
char **put_cname_in_ptr; /* store the cname here if we get one. */
@@ -228,6 +229,7 @@ struct reply {
char *ptr_name;
void *raw;
} data;
+ char *cname;
};
enum tcp_state {
@@ -986,12 +988,15 @@ reply_run_callback(struct event_callback *d, void *user_pointer)
switch (cb->request_type) {
case TYPE_A:
- if (cb->have_reply)
+ if (cb->have_reply) {
cb->user_callback(DNS_ERR_NONE, DNS_IPv4_A,
cb->reply.rr_count, cb->ttl,
cb->reply.data.a,
user_pointer);
- else
+ if (cb->reply.cname)
+ cb->user_callback(DNS_ERR_NONE, DNS_CNAME, 1,
+ cb->ttl, cb->reply.cname, user_pointer);
+ } else
cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
break;
case TYPE_PTR:
@@ -1004,12 +1009,15 @@ reply_run_callback(struct event_callback *d, void *user_pointer)
}
break;
case TYPE_AAAA:
- if (cb->have_reply)
+ if (cb->have_reply) {
cb->user_callback(DNS_ERR_NONE, DNS_IPv6_AAAA,
cb->reply.rr_count, cb->ttl,
cb->reply.data.aaaa,
user_pointer);
- else
+ if (cb->reply.cname)
+ cb->user_callback(DNS_ERR_NONE, DNS_CNAME, 1,
+ cb->ttl, cb->reply.cname, user_pointer);
+ } else
cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
break;
default:
@@ -1024,6 +1032,10 @@ reply_run_callback(struct event_callback *d, void *user_pointer)
mm_free(cb->reply.data.raw);
}
+ if (cb->reply.cname) {
+ mm_free(cb->reply.cname);
+ }
+
mm_free(cb);
}
@@ -1383,13 +1395,13 @@ reply_parse(struct evdns_base *base, u8 *packet, int length)
break;
} else if (type == TYPE_CNAME) {
char cname[HOST_NAME_MAX];
- if (!req->put_cname_in_ptr || *req->put_cname_in_ptr) {
- j += datalength; continue;
- }
if (name_parse(packet, length, &j, cname,
sizeof(cname))<0)
goto err;
- *req->put_cname_in_ptr = mm_strdup(cname);
+ if (req->need_cname)
+ reply.cname = mm_strdup(cname);
+ if (req->put_cname_in_ptr && !*req->put_cname_in_ptr)
+ *req->put_cname_in_ptr = mm_strdup(cname);
} else if (type == TYPE_AAAA && class == CLASS_INET) {
int addrcount;
if (req->request_type != TYPE_AAAA) {
@@ -3555,6 +3567,9 @@ request_new(struct evdns_base *base, struct evdns_request *handle, int type,
handle->base = base;
}
+ if (flags & DNS_CNAME_CALLBACK)
+ req->need_cname = 1;
+
return req;
err1:
mm_free(req);