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 ];
118 char name_buf[ NS_MAXDNAME ];
122 switch (ns_rr_type(rr)) {
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)));
142 err = ns_name_uncompress(responsebuf,
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);
154 err = ns_name_uncompress(responsebuf,
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 );
166 if (rdlen < NS_INT16SZ) {
167 SPF_debugf(
"MX: rdlen too short: %lu", (
unsigned long)rdlen);
170 prio = ns_get16(rdata);
171 err = ns_name_uncompress(responsebuf,
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);
184 SPF_debugf(
"TXT: rdlen too short: %lu", (
unsigned long)rdlen);
190 (
unsigned long)rdlen, (
int)rdlen - 1, rdata + 1);
194 err = ns_name_uncompress(responsebuf,
195 responsebuf + responselen,
197 name_buf,
sizeof(name_buf));
199 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
200 err, strerror(errno), errno);
206 SPF_debugf(
"not parsed: type: %d", ns_rr_type(rr));
218 SPF_dns_resolv_lookup(SPF_dns_server_t *spf_dns_server,
219 const char *domain,
ns_type rr_type,
int should_cache)
237 char name_buf[ NS_MAXDNAME ];
242 #if HAVE_DECL_RES_NINIT 244 struct __res_state *res_state;
249 #if HAVE_DECL_RES_NINIT 251 res_spec = pthread_getspecific(res_state_key);
252 if (res_spec ==
NULL) {
253 res_state = (
struct __res_state *)
254 malloc(
sizeof(
struct __res_state));
258 SPF_errorf(
"Failed to allocate %lu bytes for res_state",
259 (
unsigned long)
sizeof(
struct __res_state));
260 memset(res_state, 0,
sizeof(
struct __res_state));
261 if (res_ninit(res_state) != 0)
263 pthread_setspecific(res_state_key, (
void *)res_state);
266 res_state = (
struct __res_state *)res_spec;
271 responsebuf = (u_char *)malloc(responselen);
274 memset(responsebuf, 0, responselen);
295 #if HAVE_DECL_RES_NINIT 297 dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
298 responsebuf, responselen);
300 dns_len = res_query(domain, ns_c_in, rr_type,
301 responsebuf, responselen);
308 if (spf_dns_server->debug)
309 SPF_debugf(
"query failed: err = %d %s (%d): %s",
313 (spf_dns_server->layer_below !=
NULL)) {
315 domain, rr_type, should_cache);
320 else if (dns_len > responselen) {
323 responselen = dns_len + (dns_len >> 1);
326 if (responselen > 1048576) {
332 tmp = realloc(responsebuf, responselen);
341 responselen = dns_len;
358 err = ns_initparse(responsebuf, responselen, &ns_handle);
361 if (spf_dns_server->debug)
362 SPF_debugf(
"ns_initparse failed: err = %d %s (%d)",
363 err, strerror(errno), errno);
372 if (spf_dns_server->debug > 1) {
373 SPF_debugf(
"msg id: %d", ns_msg_id(ns_handle));
374 SPF_debugf(
"ns_f_qr quest/resp: %d", ns_msg_getflag(ns_handle, ns_f_qr));
375 SPF_debugf(
"ns_f_opcode: %d", ns_msg_getflag(ns_handle, ns_f_opcode));
376 SPF_debugf(
"ns_f_aa auth ans: %d", ns_msg_getflag(ns_handle, ns_f_aa));
377 SPF_debugf(
"ns_f_tc truncated: %d", ns_msg_getflag(ns_handle, ns_f_tc));
378 SPF_debugf(
"ns_f_rd rec desire: %d", ns_msg_getflag(ns_handle, ns_f_rd));
379 SPF_debugf(
"ns_f_ra rec avail: %d", ns_msg_getflag(ns_handle, ns_f_ra));
380 SPF_debugf(
"ns_f_rcode: %d", ns_msg_getflag(ns_handle, ns_f_rcode));
385 for (ns_sect = 0; ns_sect < num_ns_sect; ns_sect++) {
391 if (ns_sects[ns_sect].number != ns_s_an && spf_dns_server->debug <= 1)
394 nrec = ns_msg_count(ns_handle, ns_sects[ns_sect].number);
396 if (spf_dns_server->debug > 1)
397 SPF_debugf(
"%s: %d", ns_sects[ns_sect].name, nrec);
401 for (i = 0; i < nrec; i++) {
402 err = ns_parserr(&ns_handle, ns_sects[ns_sect].number, i, &rr);
404 if (spf_dns_server->debug > 1)
405 SPF_debugf(
"ns_parserr failed: err = %d %s (%d)",
406 err, strerror(errno), errno);
414 rdlen = ns_rr_rdlen(rr);
415 if (spf_dns_server->debug > 1)
416 SPF_debugf(
"name: %s type: %d class: %d ttl: %d rdlen: %lu",
417 ns_rr_name(rr), ns_rr_type(rr), ns_rr_class(rr),
418 ns_rr_ttl(rr), (
unsigned long)rdlen);
423 rdata = ns_rr_rdata(rr);
425 if (spf_dns_server->debug > 1)
426 SPF_dns_resolv_debug(spf_dns_server, rr,
427 responsebuf, responselen, rdata, rdlen);
430 if (ns_sects[ns_sect].number != ns_s_an)
435 SPF_debugf(
"unexpected rr type: %d expected: %d",
436 ns_rr_type(rr), rr_type);
440 switch (ns_rr_type(rr)) {
454 memcpy(&spfrr->
rr[cnt]->
a, rdata,
sizeof(spfrr->
rr[cnt]->
a));
471 memcpy(&spfrr->
rr[cnt]->
aaaa, rdata,
sizeof(spfrr->
rr[cnt]->
aaaa));
483 if (rdlen < NS_INT16SZ) {
488 err = ns_name_uncompress(responsebuf,
489 responsebuf + responselen,
491 name_buf,
sizeof(name_buf));
493 if (spf_dns_server->debug > 1)
494 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
495 err, strerror(errno), errno);
509 strcpy(spfrr->
rr[cnt]->
mx, name_buf);
527 dst = (u_char *)spfrr->
rr[cnt]->
txt;
528 src = (u_char *)rdata;
540 memcpy(dst, src, len);
556 spfrr->
rr[cnt]->
txt[0] =
'\0';
563 err = ns_name_uncompress(responsebuf,
564 responsebuf + responselen,
566 name_buf,
sizeof(name_buf));
568 if (spf_dns_server->debug > 1)
569 SPF_debugf(
"ns_name_uncompress failed: err = %d %s (%d)",
570 err, strerror(errno), errno);
584 strcpy(spfrr->
rr[cnt]->
ptr, name_buf);
605 SPF_dns_resolv_free(SPF_dns_server_t *spf_dns_server)
609 #if ! HAVE_DECL_RES_NINIT 613 free(spf_dns_server);
618 const char *name,
int debug)
620 SPF_dns_server_t *spf_dns_server;
622 #if HAVE_DECL_RES_NINIT 623 pthread_once(&res_state_control, SPF_dns_resolv_init_key);
625 if (res_init() != 0) {
631 spf_dns_server = malloc(
sizeof(SPF_dns_server_t));
632 if (spf_dns_server ==
NULL)
634 memset(spf_dns_server, 0,
sizeof(SPF_dns_server_t));
639 spf_dns_server->destroy = SPF_dns_resolv_free;
640 spf_dns_server->lookup = SPF_dns_resolv_lookup;
641 spf_dns_server->get_spf =
NULL;
642 spf_dns_server->get_exp =
NULL;
643 spf_dns_server->add_cache =
NULL;
644 spf_dns_server->layer_below = layer_below;
645 spf_dns_server->name = name;
646 spf_dns_server->debug =
debug;
648 return spf_dns_server;
SPF_dns_server_t * SPF_dns_resolv_new(SPF_dns_server_t *layer_below, const char *name, int debug)
#define SPF_ASSERT_NOTNULL(x)
SPF_errcode_t SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len)
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_warning(errmsg)
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_error(errmsg)