81 |
|
#define RDLENGTH_SIZE (size_t)2 |
82 |
|
#define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE) |
83 |
|
|
84 |
– |
typedef enum |
85 |
– |
{ |
86 |
– |
REQ_IDLE, /**< We're doing not much at all */ |
87 |
– |
REQ_PTR, /**< Looking up a PTR */ |
88 |
– |
REQ_A, /**< Looking up an A, possibly because AAAA failed */ |
89 |
– |
REQ_AAAA, /**< Looking up an AAAA */ |
90 |
– |
REQ_CNAME /**< We got a CNAME in response, we better get a real answer next */ |
91 |
– |
} request_state; |
92 |
– |
|
84 |
|
struct reslist |
85 |
|
{ |
86 |
|
dlink_node node; /**< Doubly linked list node. */ |
87 |
|
int id; /**< Request ID (from request header). */ |
88 |
|
int sent; /**< Number of requests sent */ |
98 |
– |
request_state state; /**< State the resolver machine is in */ |
89 |
|
char type; /**< Current request type. */ |
90 |
|
char retries; /**< Retry counter */ |
91 |
|
unsigned int sends; /**< Number of sends (>1 means resent). */ |
102 |
– |
char resend; /**< Send flag; 0 == don't resend. */ |
92 |
|
time_t sentat; /**< Timestamp we last sent this request. */ |
93 |
|
time_t timeout; /**< When this request times out. */ |
94 |
|
struct irc_ssaddr addr; /**< Address for this request. */ |
125 |
|
|
126 |
|
request->sentat = CurrentTime; |
127 |
|
request->retries = 2; |
139 |
– |
request->resend = 1; |
128 |
|
request->timeout = 4; /* Start at 4 and exponential inc. */ |
141 |
– |
request->state = REQ_IDLE; |
129 |
|
request->callback = callback; |
130 |
|
request->callback_ctx = ctx; |
131 |
|
|
332 |
|
request = make_request(callback, ctx); |
333 |
|
request->type = type; |
334 |
|
request->namelength = strlcpy(request->name, host_name, sizeof(request->name)); |
348 |
– |
|
349 |
– |
if (type != T_A) |
350 |
– |
request->state = REQ_AAAA; |
351 |
– |
else |
352 |
– |
request->state = REQ_A; |
335 |
|
} |
336 |
|
|
337 |
|
request->type = type; |
425 |
|
static void |
426 |
|
resend_query(struct reslist *request) |
427 |
|
{ |
446 |
– |
if (request->resend == 0) |
447 |
– |
return; |
448 |
– |
|
428 |
|
switch (request->type) |
429 |
|
{ |
430 |
|
case T_PTR: |
431 |
|
do_query_number(NULL, NULL, &request->addr, request); |
432 |
|
break; |
433 |
|
case T_A: |
434 |
+ |
case T_AAAA: |
435 |
|
do_query_name(NULL, NULL, request->name, request, request->type); |
436 |
|
break; |
457 |
– |
case T_AAAA: /* Didn't work, try A */ |
458 |
– |
if (request->state == REQ_AAAA) |
459 |
– |
do_query_name(NULL, NULL, request->name, request, T_A); |
437 |
|
default: |
438 |
|
break; |
439 |
|
} |
447 |
|
{ |
448 |
|
char hostbuf[RFC1035_MAX_DOMAIN_LENGTH + 100]; /* working buffer */ |
449 |
|
unsigned char *current; /* current position in buf */ |
450 |
< |
int type; /* answer type */ |
450 |
> |
unsigned int type = 0; /* answer type */ |
451 |
> |
unsigned int rd_length = 0; |
452 |
|
int n; /* temp count */ |
475 |
– |
int rd_length; |
453 |
|
struct sockaddr_in *v4; /* conversion */ |
454 |
|
struct sockaddr_in6 *v6; |
455 |
|
|
541 |
|
request->namelength = strlcpy(request->name, hostbuf, sizeof(request->name)); |
542 |
|
return 1; |
543 |
|
break; |
544 |
< |
case T_CNAME: /* First check we already haven't started looking into a cname */ |
568 |
< |
if (request->type != T_PTR) |
569 |
< |
return 0; |
570 |
< |
|
571 |
< |
if (request->state == REQ_CNAME) |
572 |
< |
{ |
573 |
< |
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, |
574 |
< |
current, hostbuf, sizeof(hostbuf)); |
575 |
< |
|
576 |
< |
if (n < 0) |
577 |
< |
return 0; |
578 |
< |
return 1; |
579 |
< |
} |
580 |
< |
|
581 |
< |
request->state = REQ_CNAME; |
544 |
> |
case T_CNAME: |
545 |
|
current += rd_length; |
546 |
|
break; |
547 |
|
|
598 |
|
if ((request = find_id(header->id)) == NULL) |
599 |
|
continue; |
600 |
|
|
601 |
< |
if ((header->rcode != NO_ERRORS) || (header->ancount == 0)) |
601 |
> |
if (header->rcode != NO_ERRORS || header->ancount == 0) |
602 |
|
{ |
603 |
< |
if (header->rcode == SERVFAIL || header->rcode == NXDOMAIN) |
604 |
< |
{ |
605 |
< |
/* |
606 |
< |
* If a bad error was returned, stop here and don't |
607 |
< |
* send any more (no retries granted). |
608 |
< |
*/ |
646 |
< |
(*request->callback)(request->callback_ctx, NULL, NULL, 0); |
647 |
< |
rem_request(request); |
648 |
< |
} |
649 |
< |
else |
650 |
< |
{ |
651 |
< |
/* |
652 |
< |
* If we havent already tried this, and we're looking up AAAA, try A now. |
653 |
< |
*/ |
654 |
< |
if (request->state == REQ_AAAA && request->type == T_AAAA) |
655 |
< |
{ |
656 |
< |
request->timeout += 4; |
657 |
< |
resend_query(request); |
658 |
< |
} |
659 |
< |
} |
660 |
< |
|
603 |
> |
/* |
604 |
> |
* If a bad error was returned, stop here and don't |
605 |
> |
* send any more (no retries granted). |
606 |
> |
*/ |
607 |
> |
(*request->callback)(request->callback_ctx, NULL, NULL, 0); |
608 |
> |
rem_request(request); |
609 |
|
continue; |
610 |
|
} |
611 |
|
|