some dns fixes
This commit is contained in:
@ -54,16 +54,21 @@ typedef union answer_u answer_t;
|
||||
|
||||
static int get_domain_name(answer_t *answer, int offset, char **name) {
|
||||
int start, len, i, offset2;
|
||||
char *name_buf, *name_buf2;
|
||||
char *name_buf, *name_buf2, *remember_name_buf;
|
||||
name_buf = NULL;
|
||||
|
||||
|
||||
|
||||
while (0 != (len = answer->buf[offset++])) {
|
||||
if (0xC0 == (len & 0xC0)) {
|
||||
if (NULL != name) { /* if we don't need the result, we don't need to recurse, since a ... */
|
||||
offset2 = ((len & ~0xC0) << 8) + answer->buf[offset++];
|
||||
get_domain_name(answer, offset2, &name_buf2);
|
||||
remember_name_buf = name_buf;
|
||||
name_buf = (char*) realloc(name_buf, ((NULL != name_buf) ? strlen(name_buf) : 0) + strlen(name_buf2) + 1);
|
||||
if (NULL == remember_name_buf) {
|
||||
name_buf[0] = '\0';
|
||||
}
|
||||
strcat(name_buf, name_buf2);
|
||||
free(name_buf2);
|
||||
*name = name_buf;
|
||||
@ -114,6 +119,20 @@ static int get_a_rdata(answer_t *answer, int offset, int len, a_rdata_t **resp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_cname_rdata(answer_t *answer, int offset, int len, cname_rdata_t **resp) {
|
||||
*resp = (cname_rdata_t*) malloc(sizeof(cname_rdata_t));
|
||||
get_domain_name(answer, offset, &(*resp)->cname);
|
||||
(*resp)->type = T_CNAME;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_cname_rdata(cname_rdata_t *resp) {
|
||||
free(resp->cname);
|
||||
free(resp);
|
||||
}
|
||||
|
||||
|
||||
static void free_a_rdata(a_rdata_t *resp) {
|
||||
free(resp);
|
||||
}
|
||||
@ -126,6 +145,9 @@ static int get_rdata(answer_t *answer, int type, int offset, int len, void **res
|
||||
case T_A:
|
||||
get_a_rdata(answer, offset, len, (a_rdata_t**)resp);
|
||||
break;
|
||||
case T_CNAME:
|
||||
get_cname_rdata(answer, offset, len, (cname_rdata_t**)resp);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "type %d unsupported\n", type);
|
||||
}
|
||||
@ -141,6 +163,9 @@ static void free_rdata(void *resp) {
|
||||
case T_A:
|
||||
free_a_rdata(resp);
|
||||
break;
|
||||
case T_CNAME:
|
||||
free_cname_rdata(resp);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "type %d unsupported\n", d->type);
|
||||
}
|
||||
@ -164,7 +189,7 @@ static void** get_rrs(char *domain, int qtype) {
|
||||
void **rdata, **rdata2;
|
||||
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "get_rrs: looking up domain %s, qtype %d", domain, qtype);
|
||||
res = res_search(domain, C_IN, qtype, (u_char*) &answer, sizeof(answer_t));
|
||||
if (-1 == res) {
|
||||
syslog(LOG_ERR, "get_rrs: error in res_search: h_errno=%d, errno=%d, (%s)",
|
||||
@ -189,7 +214,8 @@ static void** get_rrs(char *domain, int qtype) {
|
||||
for (y = 0; y < ntohs(answer.hdr.ancount); y++) {
|
||||
cnt = get_domain_name(&answer, cnt, NULL);
|
||||
type = get16(answer.buf, cnt);
|
||||
assert(type==qtype);
|
||||
syslog(LOG_DEBUG, "get_rrs: answer type %d", type);
|
||||
/* assert(type==qtype); */
|
||||
cnt += 2;
|
||||
class = get16(answer.buf, cnt);
|
||||
cnt += 2;
|
||||
@ -213,7 +239,18 @@ mx_rdata_t** get_mx_rrs(char *domain) {
|
||||
}
|
||||
|
||||
a_rdata_t** get_a_rrs(char *domain) {
|
||||
return (a_rdata_t**) get_rrs(domain, T_A);
|
||||
rdata_t **rdata, **rdata2;
|
||||
cname_rdata_t **cname_rdata;
|
||||
|
||||
rdata = (rdata_t**) get_rrs(domain, T_A);
|
||||
if ((*rdata)->type == T_CNAME) {
|
||||
cname_rdata = (cname_rdata_t**) rdata;
|
||||
rdata2 = (rdata_t**) get_a_rrs((*cname_rdata)->cname);
|
||||
free_rrs((void**)rdata);
|
||||
rdata = rdata2;
|
||||
}
|
||||
|
||||
return (a_rdata_t**) rdata;
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,13 @@ struct mx_rdata_s {
|
||||
|
||||
typedef struct mx_rdata_s mx_rdata_t;
|
||||
|
||||
struct cname_rdata_s {
|
||||
int type;
|
||||
char *cname;
|
||||
};
|
||||
|
||||
typedef struct cname_rdata_s cname_rdata_t;
|
||||
|
||||
struct a_rdata_s {
|
||||
int type;
|
||||
unsigned int address;
|
||||
@ -43,6 +50,7 @@ struct rdata_s {
|
||||
union {
|
||||
mx_rdata_t mx;
|
||||
a_rdata_t a;
|
||||
cname_rdata_t cname;
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -53,7 +61,7 @@ void free_rrs(void **resp);
|
||||
mx_rdata_t** get_mx_rrs(char *domain);
|
||||
mx_rdata_t** get_best_mx_rrs(char *domain);
|
||||
a_rdata_t** get_a_rrs(char *domain);
|
||||
|
||||
cname_rdata_t** get_cname_rrs(char *domain);
|
||||
|
||||
|
||||
|
||||
|
@ -347,7 +347,9 @@ int cache_lookup(verify_container_handle_t *vch, const char* address, int *resul
|
||||
*result = mydata->result;
|
||||
*output = (char*) malloc(sizeof(char) * (strlen(mydata->output) + 1));
|
||||
strcpy(*output, mydata->output);
|
||||
free(data.dptr);
|
||||
|
||||
/* Berkeley DB frees on its own! */
|
||||
/* free(data.dptr); */
|
||||
dbm_close(cache);
|
||||
res = 0;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user