diff --git a/smmapdfw/libsmmapdfw/dns.c b/smmapdfw/libsmmapdfw/dns.c index 10c8ba0..ac9639c 100644 --- a/smmapdfw/libsmmapdfw/dns.c +++ b/smmapdfw/libsmmapdfw/dns.c @@ -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; } diff --git a/smmapdfw/libsmmapdfw/dns.h b/smmapdfw/libsmmapdfw/dns.h index e5d63cf..09a9198 100644 --- a/smmapdfw/libsmmapdfw/dns.h +++ b/smmapdfw/libsmmapdfw/dns.h @@ -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); diff --git a/smmapdfw/verify_worker/verify_worker.c b/smmapdfw/verify_worker/verify_worker.c index 7cda153..585b9d4 100644 --- a/smmapdfw/verify_worker/verify_worker.c +++ b/smmapdfw/verify_worker/verify_worker.c @@ -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 {