45 # ifdef HAVE_STRINGS_H 72 static 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" },
79 static 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 89 static pthread_once_t res_state_control = PTHREAD_ONCE_INIT;
90 static pthread_key_t res_state_key;
93 SPF_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 );
104 SPF_dns_resolv_init_key(
void)
106 pthread_key_create(&res_state_key, SPF_dns_resolv_thread_term);
112 SPF_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);
219 SPF_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);
371 if (spf_dns_server->debug > 1) {
394 if (spf_dns_server->debug > 1)
398 for (i = 0; i < nrec; i++) {
401 if (spf_dns_server->debug > 1)
402 SPF_debugf(
"ns_parserr failed: err = %d %s (%d)",
403 err, strerror(errno), errno);
410 if (spf_dns_server->debug > 1)
411 SPF_debugf(
"name: %s type: %d class: %d ttl: %d rdlen: %lu",
420 if (spf_dns_server->debug > 1)
421 SPF_dns_resolv_debug(spf_dns_server, rr,
422 responsebuf, responselen, rdata, rdlen);
430 SPF_debugf(
"unexpected rr type: %d expected: %d",
448 memcpy(&spfrr->
rr[cnt]->
a, rdata,
sizeof(spfrr->
rr[cnt]->
a));
464 memcpy(&spfrr->
rr[cnt]->
aaaa, rdata,
sizeof(spfrr->
rr[cnt]->
aaaa));
482 responsebuf + responselen,
484 name_buf,
sizeof(name_buf));
486 if (spf_dns_server->debug > 1)
487 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
488 err, strerror(errno), errno);
500 strcpy(spfrr->
rr[cnt]->
mx, name_buf);
518 dst = (u_char *)spfrr->
rr[cnt]->
txt;
519 src = (u_char *)rdata;
531 memcpy(dst, src, len);
546 spfrr->
rr[cnt]->
txt[0] =
'\0';
554 responsebuf + responselen,
556 name_buf,
sizeof(name_buf));
558 if (spf_dns_server->debug > 1)
559 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
560 err, strerror(errno), errno);
572 strcpy(spfrr->
rr[cnt]->
ptr, name_buf);
593 SPF_dns_resolv_free(SPF_dns_server_t *spf_dns_server)
597 #if ! HAVE_DECL_RES_NINIT 601 free(spf_dns_server);
606 const char *name,
int debug)
608 SPF_dns_server_t *spf_dns_server;
610 #if HAVE_DECL_RES_NINIT 611 pthread_once(&res_state_control, SPF_dns_resolv_init_key);
613 if (res_init() != 0) {
619 spf_dns_server = malloc(
sizeof(SPF_dns_server_t));
620 if (spf_dns_server ==
NULL)
622 memset(spf_dns_server, 0,
sizeof(SPF_dns_server_t));
627 spf_dns_server->destroy = SPF_dns_resolv_free;
628 spf_dns_server->lookup = SPF_dns_resolv_lookup;
629 spf_dns_server->get_spf =
NULL;
630 spf_dns_server->get_exp =
NULL;
631 spf_dns_server->add_cache =
NULL;
632 spf_dns_server->layer_below = layer_below;
633 spf_dns_server->name = name;
634 spf_dns_server->debug =
debug;
636 return spf_dns_server;
#define ns_msg_count(handle, section)
#define SPF_ASSERT_NOTNULL(x)
#define ns_msg_id(handle)
SPF_dns_server_t * SPF_dns_resolv_new(SPF_dns_server_t *layer_below, const char *name, int debug)
SPF_errcode_t SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len)
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)
#define SPF_warning(errmsg)
int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
SPF_dns_rr_t * SPF_dns_lookup(SPF_dns_server_t *spf_dns_server, const char *domain, ns_type rr_type, int should_cache)
#define SPF_error(errmsg)
int ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src, char *dst, size_t dstsiz)
int ns_initparse(const u_char *msg, int msglen, ns_msg *handle)