72static const struct res_sym ns_sects[] = {
73 {
ns_s_qd,
"QUESTION",
"Question" },
74 {
ns_s_an,
"ANSWER",
"Answer" },
75 {
ns_s_ns,
"AUTHORITY",
"Authority" },
76 {
ns_s_ar,
"ADDITIONAL",
"Additional" },
79static const int num_ns_sect =
sizeof(ns_sects) /
sizeof(*ns_sects);
82#if HAVE_DECL_RES_NINIT
83# define SPF_h_errno res_state->res_h_errno
85# define SPF_h_errno h_errno
88#if HAVE_DECL_RES_NINIT
89static pthread_once_t res_state_control = PTHREAD_ONCE_INIT;
90static pthread_key_t res_state_key;
93SPF_dns_resolv_thread_term(
void *arg)
95#if HAVE_DECL_RES_NDESTROY
96 res_ndestroy( (
struct __res_state *)arg );
98 res_nclose( (
struct __res_state *)arg );
104SPF_dns_resolv_init_key(
void)
106 pthread_key_create(&res_state_key, SPF_dns_resolv_thread_term);
112SPF_dns_resolv_debug(SPF_dns_server_t *spf_dns_server,
ns_rr rr,
113 const u_char *responsebuf,
size_t responselen,
114 const u_char *rdata,
size_t rdlen)
116 char ip4_buf[ INET_ADDRSTRLEN ];
117 char ip6_buf[ INET6_ADDRSTRLEN ];
125 SPF_debugf(
"A: wrong rdlen %lu", (
unsigned long)rdlen);
128 inet_ntop(AF_INET, rdata,
129 ip4_buf,
sizeof(ip4_buf)));
134 SPF_debugf(
"AAAA: wrong rdlen %lu", (
unsigned long)rdlen);
137 inet_ntop(AF_INET6, rdata,
138 ip6_buf,
sizeof(ip6_buf)));
143 responsebuf + responselen,
145 name_buf,
sizeof(name_buf));
147 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
148 err, strerror(errno), errno);
155 responsebuf + responselen,
157 name_buf,
sizeof(name_buf));
159 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
160 err, strerror(errno), errno );
167 SPF_debugf(
"MX: rdlen too short: %lu", (
unsigned long)rdlen);
172 responsebuf + responselen,
174 name_buf,
sizeof(name_buf));
176 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
177 err, strerror(errno), errno);
191 (unsigned long)rdlen, (int)rdlen - 1, rdata + 1);
196 responsebuf + responselen,
198 name_buf,
sizeof(name_buf));
200 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
201 err, strerror(errno), errno);
219SPF_dns_resolv_lookup(SPF_dns_server_t *spf_dns_server,
220 const char *domain,
ns_type rr_type,
int should_cache)
243#if HAVE_DECL_RES_NINIT
245 struct __res_state *res_state;
250#if HAVE_DECL_RES_NINIT
252 res_spec = pthread_getspecific(res_state_key);
253 if (res_spec ==
NULL) {
254 res_state = (
struct __res_state *)
255 malloc(
sizeof(
struct __res_state));
259 SPF_errorf(
"Failed to allocate %lu bytes for res_state",
260 (
unsigned long)
sizeof(
struct __res_state));
261 memset(res_state, 0,
sizeof(
struct __res_state));
262 if (res_ninit(res_state) != 0)
264 pthread_setspecific(res_state_key, (
void *)res_state);
267 res_state = (
struct __res_state *)res_spec;
272 responsebuf = (u_char *)malloc(responselen);
275 memset(responsebuf, 0, responselen);
296#if HAVE_DECL_RES_NINIT
298 dns_len = res_nquery(res_state, domain,
ns_c_in, rr_type,
299 responsebuf, responselen);
301 dns_len = res_query(domain,
ns_c_in, rr_type,
302 responsebuf, responselen);
309 if (spf_dns_server->debug)
310 SPF_debugf(
"query failed: err = %d %s (%d): %s",
314 (spf_dns_server->layer_below !=
NULL)) {
316 domain, rr_type, should_cache);
321 else if (dns_len > responselen) {
327 responselen = dns_len;
344 err =
ns_initparse(responsebuf, responselen, &ns_handle);
347 if (spf_dns_server->debug)
348 SPF_debugf(
"ns_initparse failed: err = %d %s (%d)",
349 err, strerror(errno), errno);
358 if (spf_dns_server->debug > 1) {
377 if (ns_sects[
ns_sect].number !=
ns_s_an && spf_dns_server->debug <= 1)
382 if (spf_dns_server->debug > 1)
387 for (i = 0; i < nrec; i++) {
390 if (spf_dns_server->debug > 1)
391 SPF_debugf(
"ns_parserr failed: err = %d %s (%d)",
392 err, strerror(errno), errno);
401 if (spf_dns_server->debug > 1)
402 SPF_debugf(
"name: %s type: %d class: %d ttl: %d rdlen: %lu",
411 if (spf_dns_server->debug > 1)
412 SPF_dns_resolv_debug(spf_dns_server, rr,
413 responsebuf, responselen, rdata, rdlen);
421 SPF_debugf(
"unexpected rr type: %d expected: %d",
440 memcpy(&spfrr->
rr[cnt]->
a, rdata,
sizeof(spfrr->
rr[cnt]->
a));
457 memcpy(&spfrr->
rr[cnt]->
aaaa, rdata,
sizeof(spfrr->
rr[cnt]->
aaaa));
475 responsebuf + responselen,
477 name_buf,
sizeof(name_buf));
479 if (spf_dns_server->debug > 1)
480 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
481 err, strerror(errno), errno);
495 strcpy(spfrr->
rr[cnt]->
mx, name_buf);
514 dst = (u_char *)spfrr->
rr[cnt]->
txt;
515 src = (u_char *)rdata;
527 memcpy(dst, src, len);
543 spfrr->
rr[cnt]->
txt[0] =
'\0';
551 responsebuf + responselen,
553 name_buf,
sizeof(name_buf));
555 if (spf_dns_server->debug > 1)
556 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
557 err, strerror(errno), errno);
571 strcpy(spfrr->
rr[cnt]->
ptr, name_buf);
592SPF_dns_resolv_free(SPF_dns_server_t *spf_dns_server)
596#if ! HAVE_DECL_RES_NINIT
600 free(spf_dns_server);
605 const char *name,
int debug)
607 SPF_dns_server_t *spf_dns_server;
609#if HAVE_DECL_RES_NINIT
610 pthread_once(&res_state_control, SPF_dns_resolv_init_key);
612 if (res_init() != 0) {
618 spf_dns_server = malloc(
sizeof(SPF_dns_server_t));
619 if (spf_dns_server ==
NULL)
621 memset(spf_dns_server, 0,
sizeof(SPF_dns_server_t));
626 spf_dns_server->destroy = SPF_dns_resolv_free;
627 spf_dns_server->lookup = SPF_dns_resolv_lookup;
628 spf_dns_server->get_spf =
NULL;
629 spf_dns_server->get_exp =
NULL;
630 spf_dns_server->add_cache =
NULL;
631 spf_dns_server->layer_below = layer_below;
632 spf_dns_server->name = name;
633 spf_dns_server->debug =
debug;
635 return spf_dns_server;
#define ns_name_uncompress
#define ns_msg_id(handle)
#define ns_msg_count(handle, section)
SPF_dns_rr_t * SPF_dns_lookup(SPF_dns_server_t *spf_dns_server, const char *domain, ns_type rr_type, int should_cache)
SPF_dns_rr_t * SPF_dns_rr_new_init(SPF_dns_server_t *spf_dns_server, const char *domain, ns_type rr_type, int ttl, SPF_dns_stat_t herrno)
SPF_errcode_t SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len)
#define SPF_ASSERT_NOTNULL(x)
#define SPF_warning(errmsg)
#define SPF_error(errmsg)
SPF_dns_server_t * SPF_dns_resolv_new(SPF_dns_server_t *layer_below, const char *name, int debug)