mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Match the query in DNS replies to the query in the request; from Vsevolod Stakhov
svn:r930
This commit is contained in:
parent
c968eb3e01
commit
a710d817ad
@ -122,6 +122,7 @@ Changes in current version:
|
|||||||
o Fix off-by-one errors in devpoll; from Ian Bell
|
o Fix off-by-one errors in devpoll; from Ian Bell
|
||||||
o Make event_add not change any state if it fails; reported by Ian Bell.
|
o Make event_add not change any state if it fails; reported by Ian Bell.
|
||||||
o Fix a bug where headers arriving in multiple packets were not parsed; fix from Jiang Hong; test by me.
|
o Fix a bug where headers arriving in multiple packets were not parsed; fix from Jiang Hong; test by me.
|
||||||
|
o Match the query in DNS replies to the query in the request; from Vsevolod Stakhov.
|
||||||
|
|
||||||
Changes in 1.4.0:
|
Changes in 1.4.0:
|
||||||
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
||||||
|
46
evdns.c
46
evdns.c
@ -711,7 +711,10 @@ reply_callback(struct evdns_request *const req, u32 ttl, u32 err, struct reply *
|
|||||||
static void
|
static void
|
||||||
reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply *reply) {
|
reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply *reply) {
|
||||||
int error;
|
int error;
|
||||||
static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
|
static const int error_codes[] = {
|
||||||
|
DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST,
|
||||||
|
DNS_ERR_NOTIMPL, DNS_ERR_REFUSED
|
||||||
|
};
|
||||||
|
|
||||||
if (flags & 0x020f || !reply || !reply->have_answer) {
|
if (flags & 0x020f || !reply || !reply->have_answer) {
|
||||||
/* there was an error */
|
/* there was an error */
|
||||||
@ -739,9 +742,10 @@ reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply *
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DNS_ERR_SERVERFAILED:
|
case DNS_ERR_SERVERFAILED:
|
||||||
/* rcode 2 (servfailed) sometimes means "we are broken" and
|
/* rcode 2 (servfailed) sometimes means "we
|
||||||
* sometimes (with some binds) means "that request was very
|
* are broken" and sometimes (with some binds)
|
||||||
* confusing." Treat this as a timeout, not a failure.
|
* means "that request was very confusing."
|
||||||
|
* Treat this as a timeout, not a failure.
|
||||||
*/
|
*/
|
||||||
log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
|
log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
|
||||||
"will allow the request to time out.",
|
"will allow the request to time out.",
|
||||||
@ -753,10 +757,13 @@ reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (req->search_state && req->request_type != TYPE_PTR) {
|
if (req->search_state && req->request_type != TYPE_PTR) {
|
||||||
/* if we have a list of domains to search in, try the next one */
|
/* if we have a list of domains to search in,
|
||||||
|
* try the next one */
|
||||||
if (!search_try_next(req)) {
|
if (!search_try_next(req)) {
|
||||||
/* a new request was issued so this request is finished and */
|
/* a new request was issued so this
|
||||||
/* the user callback will be made when that request (or a */
|
* request is finished and */
|
||||||
|
/* the user callback will be made when
|
||||||
|
* that request (or a */
|
||||||
/* child of it) finishes. */
|
/* child of it) finishes. */
|
||||||
request_finished(req, &REQ_HEAD(req->base, req->trans_id));
|
request_finished(req, &REQ_HEAD(req->base, req->trans_id));
|
||||||
return;
|
return;
|
||||||
@ -833,10 +840,10 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
|
|||||||
/* parses a raw request from a nameserver */
|
/* parses a raw request from a nameserver */
|
||||||
static int
|
static int
|
||||||
reply_parse(struct evdns_base *base, u8 *packet, int length) {
|
reply_parse(struct evdns_base *base, u8 *packet, int length) {
|
||||||
int j = 0; /* index into packet */
|
int j = 0, k = 0; /* index into packet */
|
||||||
u16 _t; /* used by the macros */
|
u16 _t; /* used by the macros */
|
||||||
u32 _t32; /* used by the macros */
|
u32 _t32; /* used by the macros */
|
||||||
char tmp_name[256]; /* used by the macros */
|
char tmp_name[256], cmp_name[256]; /* used by the macros */
|
||||||
|
|
||||||
u16 trans_id, questions, answers, authority, additional, datalength;
|
u16 trans_id, questions, answers, authority, additional, datalength;
|
||||||
u16 flags = 0;
|
u16 flags = 0;
|
||||||
@ -870,10 +877,21 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) {
|
|||||||
|
|
||||||
/* This macro skips a name in the DNS reply. */
|
/* This macro skips a name in the DNS reply. */
|
||||||
#define SKIP_NAME \
|
#define SKIP_NAME \
|
||||||
do { tmp_name[0] = '\0'; \
|
do { tmp_name[0] = '\0'; \
|
||||||
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
|
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\
|
||||||
goto err; \
|
goto err; \
|
||||||
} while(0);
|
} while(0)
|
||||||
|
#define TEST_NAME \
|
||||||
|
do { tmp_name[0] = '\0'; \
|
||||||
|
cmp_name[0] = '\0'; \
|
||||||
|
k = j; \
|
||||||
|
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\
|
||||||
|
goto err; \
|
||||||
|
if (name_parse(req->request, req->request_len, &k, cmp_name, sizeof(cmp_name))<0) \
|
||||||
|
goto err; \
|
||||||
|
if (memcmp(tmp_name, cmp_name, strlen (tmp_name)) != 0) \
|
||||||
|
return (-1); /* we ignore mismatching names */ \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
reply.type = req->request_type;
|
reply.type = req->request_type;
|
||||||
|
|
||||||
@ -882,7 +900,7 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) {
|
|||||||
/* the question looks like
|
/* the question looks like
|
||||||
* <label:name><u16:type><u16:class>
|
* <label:name><u16:type><u16:class>
|
||||||
*/
|
*/
|
||||||
SKIP_NAME;
|
TEST_NAME;
|
||||||
j += 4;
|
j += 4;
|
||||||
if (j > length) goto err;
|
if (j > length) goto err;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user