Changeset View
Changeset View
Standalone View
Standalone View
contrib/ldns/resolver.c
Show First 20 Lines • Show All 758 Lines • ▼ Show 20 Lines | |||||
ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp) | ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp) | ||||
{ | { | ||||
return ldns_resolver_new_frm_fp_l(res, fp, NULL); | return ldns_resolver_new_frm_fp_l(res, fp, NULL); | ||||
} | } | ||||
ldns_status | ldns_status | ||||
ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) | ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) | ||||
{ | { | ||||
ldns_resolver *r; | ldns_resolver *r = NULL; | ||||
const char *keyword[LDNS_RESOLV_KEYWORDS]; | const char *keyword[LDNS_RESOLV_KEYWORDS]; | ||||
char word[LDNS_MAX_LINELEN + 1]; | char word[LDNS_MAX_LINELEN + 1]; | ||||
int8_t expect; | int8_t expect; | ||||
uint8_t i; | uint8_t i; | ||||
ldns_rdf *tmp; | ldns_rdf *tmp; | ||||
#ifdef HAVE_SSL | #ifdef HAVE_SSL | ||||
ldns_rr *tmp_rr; | ldns_rr *tmp_rr; | ||||
#endif | #endif | ||||
ssize_t gtr, bgtr; | ssize_t gtr, bgtr; | ||||
ldns_buffer *b; | ldns_buffer *b; | ||||
int lnr = 0, oldline; | int lnr = 0, oldline; | ||||
FILE* myfp = fp; | FILE* myfp = fp; | ||||
if(!line_nr) line_nr = &lnr; | if(!line_nr) line_nr = &lnr; | ||||
if(!fp) { | if(!fp) { | ||||
myfp = fopen("/etc/resolv.conf", "r"); | myfp = fopen(LDNS_RESOLV_CONF, "r"); | ||||
if(!myfp) | if(!myfp) | ||||
return LDNS_STATUS_FILE_ERR; | return LDNS_STATUS_FILE_ERR; | ||||
} | } | ||||
/* do this better | /* do this better | ||||
* expect = | * expect = | ||||
* 0: keyword | * 0: keyword | ||||
* 1: default domain dname | * 1: default domain dname | ||||
* 2: NS aaaa or a record | * 2: NS aaaa or a record | ||||
*/ | */ | ||||
/* recognized keywords */ | /* recognized keywords */ | ||||
keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; | keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; | ||||
keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; | keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; | ||||
keyword[LDNS_RESOLV_SEARCH] = "search"; | keyword[LDNS_RESOLV_SEARCH] = "search"; | ||||
/* these two are read but not used atm TODO */ | /* these two are read but not used atm TODO */ | ||||
keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; | keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; | ||||
keyword[LDNS_RESOLV_OPTIONS] = "options"; | keyword[LDNS_RESOLV_OPTIONS] = "options"; | ||||
keyword[LDNS_RESOLV_ANCHOR] = "anchor"; | keyword[LDNS_RESOLV_ANCHOR] = "anchor"; | ||||
expect = LDNS_RESOLV_KEYWORD; | |||||
r = ldns_resolver_new(); | r = ldns_resolver_new(); | ||||
if (!r) { | if (!r) { | ||||
if(!fp) fclose(myfp); | if(!fp) fclose(myfp); | ||||
return LDNS_STATUS_MEM_ERR; | return LDNS_STATUS_MEM_ERR; | ||||
} | } | ||||
gtr = 1; | gtr = 1; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | switch(expect) { | ||||
} | } | ||||
} | } | ||||
break; | break; | ||||
case LDNS_RESOLV_DEFDOMAIN: | case LDNS_RESOLV_DEFDOMAIN: | ||||
/* default domain dname */ | /* default domain dname */ | ||||
gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); | gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); | ||||
if (gtr == 0) { | if (gtr == 0) { | ||||
if(!fp) fclose(myfp); | if(!fp) fclose(myfp); | ||||
ldns_resolver_deep_free(r); | |||||
return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; | return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; | ||||
} | } | ||||
if(word[0] == '#') { | if(word[0] == '#') { | ||||
expect = LDNS_RESOLV_KEYWORD; | expect = LDNS_RESOLV_KEYWORD; | ||||
continue; | continue; | ||||
} | } | ||||
tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); | tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); | ||||
if (!tmp) { | if (!tmp) { | ||||
ldns_resolver_deep_free(r); | |||||
if(!fp) fclose(myfp); | if(!fp) fclose(myfp); | ||||
ldns_resolver_deep_free(r); | |||||
return LDNS_STATUS_SYNTAX_DNAME_ERR; | return LDNS_STATUS_SYNTAX_DNAME_ERR; | ||||
} | } | ||||
/* DOn't free, because we copy the pointer */ | /* DOn't free, because we copy the pointer */ | ||||
ldns_resolver_set_domain(r, tmp); | ldns_resolver_set_domain(r, tmp); | ||||
expect = LDNS_RESOLV_KEYWORD; | expect = LDNS_RESOLV_KEYWORD; | ||||
break; | break; | ||||
case LDNS_RESOLV_NAMESERVER: | case LDNS_RESOLV_NAMESERVER: | ||||
/* NS aaaa or a record */ | /* NS aaaa or a record */ | ||||
gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); | gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); | ||||
if (gtr == 0) { | if (gtr == 0) { | ||||
if(!fp) fclose(myfp); | if(!fp) fclose(myfp); | ||||
ldns_resolver_deep_free(r); | |||||
return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; | return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; | ||||
} | } | ||||
if(word[0] == '#') { | if(word[0] == '#') { | ||||
expect = LDNS_RESOLV_KEYWORD; | expect = LDNS_RESOLV_KEYWORD; | ||||
continue; | continue; | ||||
} | } | ||||
if(strchr(word, '%')) { | if(strchr(word, '%')) { | ||||
/* snip off interface labels, | /* snip off interface labels, | ||||
▲ Show 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) { | ||||
&root_dname); | &root_dname); | ||||
} else { | } else { | ||||
new_name = ldns_dname_cat_clone(name, | new_name = ldns_dname_cat_clone(name, | ||||
search_list[i]); | search_list[i]); | ||||
} | } | ||||
s = ldns_resolver_query_status(pkt, r, | s = ldns_resolver_query_status(pkt, r, | ||||
new_name, t, c, flags); | new_name, t, c, flags); | ||||
ldns_rdf_free(new_name); | ldns_rdf_deep_free(new_name); | ||||
if (pkt && *pkt) { | if (pkt && *pkt) { | ||||
if (s == LDNS_STATUS_OK && | if (s == LDNS_STATUS_OK && | ||||
ldns_pkt_get_rcode(*pkt) == | ldns_pkt_get_rcode(*pkt) == | ||||
LDNS_RCODE_NOERROR) { | LDNS_RCODE_NOERROR) { | ||||
return LDNS_STATUS_OK; | return LDNS_STATUS_OK; | ||||
} | } | ||||
ldns_pkt_free(*pkt); | ldns_pkt_free(*pkt); | ||||
*pkt = NULL; | *pkt = NULL; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return s; | return s; | ||||
} | } | ||||
ldns_pkt * | ldns_pkt * | ||||
ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name, | ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name, | ||||
ldns_rr_type t, ldns_rr_class c, uint16_t flags) | ldns_rr_type t, ldns_rr_class c, uint16_t flags) | ||||
{ | { | ||||
ldns_pkt* pkt = NULL; | ldns_pkt* pkt = NULL; | ||||
if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r, | if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r, | ||||
name, t, c, flags) != LDNS_STATUS_OK) { | name, t, c, flags) != LDNS_STATUS_OK) { | ||||
ldns_pkt_free(pkt); | ldns_pkt_free(pkt); | ||||
return NULL; | |||||
} | } | ||||
return pkt; | return pkt; | ||||
} | } | ||||
ldns_status | ldns_status | ||||
ldns_resolver_query_status(ldns_pkt** pkt, | ldns_resolver_query_status(ldns_pkt** pkt, | ||||
ldns_resolver *r, const ldns_rdf *name, | ldns_resolver *r, const ldns_rdf *name, | ||||
ldns_rr_type t, ldns_rr_class c, uint16_t flags) | ldns_rr_type t, ldns_rr_class c, uint16_t flags) | ||||
Show All 17 Lines | |||||
ldns_pkt * | ldns_pkt * | ||||
ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, | ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, | ||||
ldns_rr_type t, ldns_rr_class c, uint16_t flags) | ldns_rr_type t, ldns_rr_class c, uint16_t flags) | ||||
{ | { | ||||
ldns_pkt* pkt = NULL; | ldns_pkt* pkt = NULL; | ||||
if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r, | if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r, | ||||
name, t, c, flags) != LDNS_STATUS_OK) { | name, t, c, flags) != LDNS_STATUS_OK) { | ||||
ldns_pkt_free(pkt); | ldns_pkt_free(pkt); | ||||
return NULL; | |||||
} | } | ||||
return pkt; | return pkt; | ||||
} | } | ||||
static size_t * | static size_t * | ||||
ldns_resolver_backup_rtt(ldns_resolver *r) | ldns_resolver_backup_rtt(ldns_resolver *r) | ||||
{ | { | ||||
size_t *new_rtt; | size_t *new_rtt; | ||||
size_t *old_rtt = ldns_resolver_rtt(r); | size_t *old_rtt = ldns_resolver_rtt(r); | ||||
if (old_rtt && ldns_resolver_nameserver_count(r)) { | if (old_rtt && ldns_resolver_nameserver_count(r)) { | ||||
new_rtt = LDNS_XMALLOC(size_t | new_rtt = LDNS_XMALLOC(size_t | ||||
, ldns_resolver_nameserver_count(r)); | , ldns_resolver_nameserver_count(r)); | ||||
if (!new_rtt) return NULL; | |||||
memcpy(new_rtt, old_rtt, sizeof(size_t) | memcpy(new_rtt, old_rtt, sizeof(size_t) | ||||
* ldns_resolver_nameserver_count(r)); | * ldns_resolver_nameserver_count(r)); | ||||
ldns_resolver_set_rtt(r, new_rtt); | ldns_resolver_set_rtt(r, new_rtt); | ||||
return old_rtt; | return old_rtt; | ||||
} | } | ||||
return NULL; | return NULL; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) { | ||||
, query_pkt); | , query_pkt); | ||||
ldns_resolver_restore_rtt(r, rtt); | ldns_resolver_restore_rtt(r, rtt); | ||||
} | } | ||||
/* either way, if it is still truncated, use TCP */ | /* either way, if it is still truncated, use TCP */ | ||||
if (stat != LDNS_STATUS_OK || | if (stat != LDNS_STATUS_OK || | ||||
ldns_pkt_tc(answer_pkt)) { | ldns_pkt_tc(answer_pkt)) { | ||||
ldns_resolver_set_usevc(r, true); | ldns_resolver_set_usevc(r, true); | ||||
ldns_pkt_free(answer_pkt); | ldns_pkt_free(answer_pkt); | ||||
answer_pkt = NULL; | |||||
stat = ldns_send(&answer_pkt, r, query_pkt); | stat = ldns_send(&answer_pkt, r, query_pkt); | ||||
ldns_resolver_set_usevc(r, false); | ldns_resolver_set_usevc(r, false); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (answer) { | if (answer && answer_pkt) { | ||||
*answer = answer_pkt; | *answer = answer_pkt; | ||||
} | } | ||||
return stat; | return stat; | ||||
} | } | ||||
ldns_status | ldns_status | ||||
ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, | ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, | ||||
▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | |||||
* without it an aborted transfer will lead to the AXFR code in the | * without it an aborted transfer will lead to the AXFR code in the | ||||
* library staying in an indetermined state because the socket for the | * library staying in an indetermined state because the socket for the | ||||
* AXFR is never closed | * AXFR is never closed | ||||
*/ | */ | ||||
void | void | ||||
ldns_axfr_abort(ldns_resolver *resolver) | ldns_axfr_abort(ldns_resolver *resolver) | ||||
{ | { | ||||
/* Only abort if an actual AXFR is in progress */ | /* Only abort if an actual AXFR is in progress */ | ||||
if (resolver->_socket != 0) | if (resolver->_socket != -1) | ||||
{ | { | ||||
#ifndef USE_WINSOCK | #ifndef USE_WINSOCK | ||||
close(resolver->_socket); | close(resolver->_socket); | ||||
#else | #else | ||||
closesocket(resolver->_socket); | closesocket(resolver->_socket); | ||||
#endif | #endif | ||||
resolver->_socket = 0; | resolver->_socket = -1; | ||||
} | } | ||||
} | } | ||||
bool | bool | ||||
ldns_axfr_complete(const ldns_resolver *res) | ldns_axfr_complete(const ldns_resolver *res) | ||||
{ | { | ||||
/* complete when soa count is 2? */ | /* complete when soa count is 2? */ | ||||
return res->_axfr_soa_count == 2; | return res->_axfr_soa_count == 2; | ||||
▲ Show 20 Lines • Show All 46 Lines • Show Last 20 Lines |