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) {
|
static int get_domain_name(answer_t *answer, int offset, char **name) {
|
||||||
int start, len, i, offset2;
|
int start, len, i, offset2;
|
||||||
char *name_buf, *name_buf2;
|
char *name_buf, *name_buf2, *remember_name_buf;
|
||||||
name_buf = NULL;
|
name_buf = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (0 != (len = answer->buf[offset++])) {
|
while (0 != (len = answer->buf[offset++])) {
|
||||||
if (0xC0 == (len & 0xC0)) {
|
if (0xC0 == (len & 0xC0)) {
|
||||||
if (NULL != name) { /* if we don't need the result, we don't need to recurse, since a ... */
|
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++];
|
offset2 = ((len & ~0xC0) << 8) + answer->buf[offset++];
|
||||||
get_domain_name(answer, offset2, &name_buf2);
|
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);
|
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);
|
strcat(name_buf, name_buf2);
|
||||||
free(name_buf2);
|
free(name_buf2);
|
||||||
*name = name_buf;
|
*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;
|
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) {
|
static void free_a_rdata(a_rdata_t *resp) {
|
||||||
free(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:
|
case T_A:
|
||||||
get_a_rdata(answer, offset, len, (a_rdata_t**)resp);
|
get_a_rdata(answer, offset, len, (a_rdata_t**)resp);
|
||||||
break;
|
break;
|
||||||
|
case T_CNAME:
|
||||||
|
get_cname_rdata(answer, offset, len, (cname_rdata_t**)resp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
syslog(LOG_ERR, "type %d unsupported\n", type);
|
syslog(LOG_ERR, "type %d unsupported\n", type);
|
||||||
}
|
}
|
||||||
@ -141,6 +163,9 @@ static void free_rdata(void *resp) {
|
|||||||
case T_A:
|
case T_A:
|
||||||
free_a_rdata(resp);
|
free_a_rdata(resp);
|
||||||
break;
|
break;
|
||||||
|
case T_CNAME:
|
||||||
|
free_cname_rdata(resp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
syslog(LOG_ERR, "type %d unsupported\n", d->type);
|
syslog(LOG_ERR, "type %d unsupported\n", d->type);
|
||||||
}
|
}
|
||||||
@ -164,7 +189,7 @@ static void** get_rrs(char *domain, int qtype) {
|
|||||||
void **rdata, **rdata2;
|
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));
|
res = res_search(domain, C_IN, qtype, (u_char*) &answer, sizeof(answer_t));
|
||||||
if (-1 == res) {
|
if (-1 == res) {
|
||||||
syslog(LOG_ERR, "get_rrs: error in res_search: h_errno=%d, errno=%d, (%s)",
|
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++) {
|
for (y = 0; y < ntohs(answer.hdr.ancount); y++) {
|
||||||
cnt = get_domain_name(&answer, cnt, NULL);
|
cnt = get_domain_name(&answer, cnt, NULL);
|
||||||
type = get16(answer.buf, cnt);
|
type = get16(answer.buf, cnt);
|
||||||
assert(type==qtype);
|
syslog(LOG_DEBUG, "get_rrs: answer type %d", type);
|
||||||
|
/* assert(type==qtype); */
|
||||||
cnt += 2;
|
cnt += 2;
|
||||||
class = get16(answer.buf, cnt);
|
class = get16(answer.buf, cnt);
|
||||||
cnt += 2;
|
cnt += 2;
|
||||||
@ -213,7 +239,18 @@ mx_rdata_t** get_mx_rrs(char *domain) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a_rdata_t** get_a_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;
|
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 {
|
struct a_rdata_s {
|
||||||
int type;
|
int type;
|
||||||
unsigned int address;
|
unsigned int address;
|
||||||
@ -43,6 +50,7 @@ struct rdata_s {
|
|||||||
union {
|
union {
|
||||||
mx_rdata_t mx;
|
mx_rdata_t mx;
|
||||||
a_rdata_t a;
|
a_rdata_t a;
|
||||||
|
cname_rdata_t cname;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +61,7 @@ void free_rrs(void **resp);
|
|||||||
mx_rdata_t** get_mx_rrs(char *domain);
|
mx_rdata_t** get_mx_rrs(char *domain);
|
||||||
mx_rdata_t** get_best_mx_rrs(char *domain);
|
mx_rdata_t** get_best_mx_rrs(char *domain);
|
||||||
a_rdata_t** get_a_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;
|
*result = mydata->result;
|
||||||
*output = (char*) malloc(sizeof(char) * (strlen(mydata->output) + 1));
|
*output = (char*) malloc(sizeof(char) * (strlen(mydata->output) + 1));
|
||||||
strcpy(*output, mydata->output);
|
strcpy(*output, mydata->output);
|
||||||
free(data.dptr);
|
|
||||||
|
/* Berkeley DB frees on its own! */
|
||||||
|
/* free(data.dptr); */
|
||||||
dbm_close(cache);
|
dbm_close(cache);
|
||||||
res = 0;
|
res = 0;
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user