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). */ |
126 |
|
request->sentat = CurrentTime; |
127 |
|
request->retries = 2; |
128 |
|
request->timeout = 4; /* Start at 4 and exponential inc. */ |
139 |
– |
request->state = REQ_IDLE; |
129 |
|
request->callback = callback; |
130 |
|
request->callback_ctx = ctx; |
131 |
|
|
405 |
|
} |
406 |
|
|
407 |
|
/* |
419 |
– |
* gethost_byname - wrapper for _type - send T_AAAA first if IPV6 supported |
420 |
– |
*/ |
421 |
– |
void |
422 |
– |
gethost_byname(dns_callback_fnc callback, void *ctx, const char *name) |
423 |
– |
{ |
424 |
– |
gethost_byname_type(callback, ctx, name, T_AAAA); |
425 |
– |
} |
426 |
– |
|
427 |
– |
/* |
408 |
|
* gethost_byaddr - get host name from address |
409 |
|
*/ |
410 |
|
void |
434 |
|
* proc_answer - process name server reply |
435 |
|
*/ |
436 |
|
static int |
437 |
< |
proc_answer(struct reslist *request, HEADER *header, char *buf, char *eob) |
437 |
> |
proc_answer(struct reslist *request, HEADER *header, unsigned char *buf, unsigned char *eob) |
438 |
|
{ |
439 |
|
char hostbuf[RFC1035_MAX_DOMAIN_LENGTH + 100]; /* working buffer */ |
440 |
< |
unsigned char *current; /* current position in buf */ |
441 |
< |
int type; /* answer type */ |
440 |
> |
unsigned char *current = buf + sizeof(HEADER); /* current position in buf */ |
441 |
> |
unsigned int type = 0; /* answer type */ |
442 |
> |
unsigned int rd_length = 0; |
443 |
|
int n; /* temp count */ |
463 |
– |
int rd_length; |
444 |
|
struct sockaddr_in *v4; /* conversion */ |
445 |
|
struct sockaddr_in6 *v6; |
446 |
|
|
467 |
– |
current = (unsigned char *)buf + sizeof(HEADER); |
468 |
– |
|
447 |
|
for (; header->qdcount > 0; --header->qdcount) |
448 |
|
{ |
449 |
< |
if ((n = irc_dn_skipname(current, (unsigned char *)eob)) < 0) |
449 |
> |
if ((n = irc_dn_skipname(current, eob)) < 0) |
450 |
|
break; |
451 |
|
|
452 |
|
current += (size_t)n + QFIXEDSZ; |
455 |
|
/* |
456 |
|
* Process each answer sent to us blech. |
457 |
|
*/ |
458 |
< |
while (header->ancount > 0 && (char *)current < eob) |
458 |
> |
while (header->ancount > 0 && current < eob) |
459 |
|
{ |
460 |
|
header->ancount--; |
461 |
|
|
462 |
< |
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, |
485 |
< |
hostbuf, sizeof(hostbuf)); |
462 |
> |
n = irc_dn_expand(buf, eob, current, hostbuf, sizeof(hostbuf)); |
463 |
|
|
464 |
|
if (n < 0 /* Broken message */ || n == 0 /* No more answers left */) |
465 |
|
return 0; |
473 |
|
*/ |
474 |
|
current += (size_t)n; |
475 |
|
|
476 |
< |
if (!(((char *)current + ANSWER_FIXED_SIZE) < eob)) |
476 |
> |
if (!((current + ANSWER_FIXED_SIZE) < eob)) |
477 |
|
break; |
478 |
|
|
479 |
|
type = irc_ns_get16(current); |
521 |
|
if (request->type != T_PTR) |
522 |
|
return 0; |
523 |
|
|
524 |
< |
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, |
548 |
< |
current, hostbuf, sizeof(hostbuf)); |
524 |
> |
n = irc_dn_expand(buf, eob, current, hostbuf, sizeof(hostbuf)); |
525 |
|
if (n < 0 /* Broken message */ || n == 0 /* No more answers left */) |
526 |
|
return 0; |
527 |
|
|
528 |
|
request->namelength = strlcpy(request->name, hostbuf, sizeof(request->name)); |
529 |
|
return 1; |
530 |
|
break; |
531 |
< |
case T_CNAME: /* First check we already haven't started looking into a cname */ |
556 |
< |
if (request->type != T_PTR) |
557 |
< |
return 0; |
558 |
< |
|
559 |
< |
if (request->state == REQ_CNAME) |
560 |
< |
{ |
561 |
< |
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, |
562 |
< |
current, hostbuf, sizeof(hostbuf)); |
563 |
< |
|
564 |
< |
if (n < 0) |
565 |
< |
return 0; |
566 |
< |
return 1; |
567 |
< |
} |
568 |
< |
|
569 |
< |
request->state = REQ_CNAME; |
531 |
> |
case T_CNAME: |
532 |
|
current += rd_length; |
533 |
|
break; |
534 |
|
|
551 |
|
static void |
552 |
|
res_readreply(fde_t *fd, void *data) |
553 |
|
{ |
554 |
< |
char buf[sizeof(HEADER) + MAXPACKET]; |
554 |
> |
unsigned char buf[sizeof(HEADER) + MAXPACKET]; |
555 |
|
HEADER *header; |
556 |
|
struct reslist *request = NULL; |
557 |
|
ssize_t rc = 0; |