diff options
author | Sergey Matveychuk <sem33@yandex-team.ru> | 2021-04-07 20:39:18 +0300 |
---|---|---|
committer | Azat Khuzhin <azat@libevent.org> | 2021-05-24 21:03:45 +0300 |
commit | 19b3fd0bf03c94e694ac25ad95fe43ac10df73b5 (patch) | |
tree | 1efe5d81b55a16c67d93e161a8638680393ead90 /evdns.c | |
parent | 087bbc572c48d9304d8b6b911e6b0cf966ba3c28 (diff) | |
download | libevent-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.c | 31 |
1 files changed, 23 insertions, 8 deletions
@@ -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); |