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) {
324 responselen = dns_len + (dns_len >> 1);
327 if (responselen > 1048576) {
333 tmp = realloc(responsebuf, responselen);
342 responselen = dns_len;
359 err =
ns_initparse(responsebuf, responselen, &ns_handle);
362 if (spf_dns_server->debug)
363 SPF_debugf(
"ns_initparse failed: err = %d %s (%d)",
364 err, strerror(errno), errno);
373 if (spf_dns_server->debug > 1) {
392 if (ns_sects[
ns_sect].number !=
ns_s_an && spf_dns_server->debug <= 1)
397 if (spf_dns_server->debug > 1)
402 for (i = 0; i < nrec; i++) {
405 if (spf_dns_server->debug > 1)
406 SPF_debugf(
"ns_parserr failed: err = %d %s (%d)",
407 err, strerror(errno), errno);
416 if (spf_dns_server->debug > 1)
417 SPF_debugf(
"name: %s type: %d class: %d ttl: %d rdlen: %lu",
426 if (spf_dns_server->debug > 1)
427 SPF_dns_resolv_debug(spf_dns_server, rr,
428 responsebuf, responselen, rdata, rdlen);
436 SPF_debugf(
"unexpected rr type: %d expected: %d",
455 memcpy(&spfrr->
rr[cnt]->
a, rdata,
sizeof(spfrr->
rr[cnt]->
a));
472 memcpy(&spfrr->
rr[cnt]->
aaaa, rdata,
sizeof(spfrr->
rr[cnt]->
aaaa));
490 responsebuf + responselen,
492 name_buf,
sizeof(name_buf));
494 if (spf_dns_server->debug > 1)
495 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
496 err, strerror(errno), errno);
510 strcpy(spfrr->
rr[cnt]->
mx, name_buf);
529 dst = (u_char *)spfrr->
rr[cnt]->
txt;
530 src = (u_char *)rdata;
542 memcpy(dst, src, len);
558 spfrr->
rr[cnt]->
txt[0] =
'\0';
566 responsebuf + responselen,
568 name_buf,
sizeof(name_buf));
570 if (spf_dns_server->debug > 1)
571 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
572 err, strerror(errno), errno);
586 strcpy(spfrr->
rr[cnt]->
ptr, name_buf);
607SPF_dns_resolv_free(SPF_dns_server_t *spf_dns_server)
611#if ! HAVE_DECL_RES_NINIT
615 free(spf_dns_server);
620 const char *name,
int debug)
622 SPF_dns_server_t *spf_dns_server;
624#if HAVE_DECL_RES_NINIT
625 pthread_once(&res_state_control, SPF_dns_resolv_init_key);
627 if (res_init() != 0) {
633 spf_dns_server = malloc(
sizeof(SPF_dns_server_t));
634 if (spf_dns_server ==
NULL)
636 memset(spf_dns_server, 0,
sizeof(SPF_dns_server_t));
641 spf_dns_server->destroy = SPF_dns_resolv_free;
642 spf_dns_server->lookup = SPF_dns_resolv_lookup;
643 spf_dns_server->get_spf =
NULL;
644 spf_dns_server->get_exp =
NULL;
645 spf_dns_server->add_cache =
NULL;
646 spf_dns_server->layer_below = layer_below;
647 spf_dns_server->name = name;
648 spf_dns_server->debug =
debug;
650 return spf_dns_server;
#define ns_msg_id(handle)
#define ns_msg_count(handle, section)
int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
int ns_initparse(const u_char *msg, int msglen, ns_msg *handle)
int ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src, char *dst, size_t dstsiz)
SPF_dns_server_t * SPF_dns_resolv_new(SPF_dns_server_t *layer_below, const char *name, int debug)
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_rr_t * SPF_dns_lookup(SPF_dns_server_t *spf_dns_server, const char *domain, ns_type rr_type, int should_cache)