📄 dns_client_query6.c
字号:
/* * DNS Resolver * IPv6 Queries API * * Author: Pavel A. Bolokhov <Pavel.Bolokhov@oktet.ru> * * External API: * dns_getnodebyname() * dns_gethostbyaddr6() * dns_print_query() */#include <netdb.h>#include "errno.h"#include "messages.h"#include "dns_resolv.h"#include "dns_client_query.h"#include "dns_client_cache.h"#include "dns_client_resource.h"#include "dns_client_util6.h"#include "dns_client_statics.h"#ifdef DNS_DEBUGextern int dns_verbosity;#endif /* DNS_DEBUG *//* dns_getnodebyname() * This routine makes a query for IPv6 address. It is called upon * receival of DNS_GET_NODEBYNAME message. * * PARAMATERS * msg - message which triggered this routine * dm - DnsDomain structure with initial Resolver information * * RETURNS * N/A */voiddns_getnodebyname(IN ATMOS_MESSAGE *msg, IN DnsDomain *dm){ QueryState *qs; int cFlag = FALSE; MSG_D_DNS_GET_NODEBYNAME(dmsg, msg); DNSC_DEBUG("entry\n");#if defined(DEBUG) print_resource_pool();#endif /* * Verify that we were sent a valid host name. If not just return * an error without doing anything. */ if (dns_validate_hostname(dmsg->hostname) < 0) { DNSC_TRACE("bad host name\n"); dmsg->error = EHOSTNOTFOUND; sendreply(msg); DNSC_DEBUG("exit - dns_validate_hostname failed\n"); return; } /* Get a new query state */ if ((qs = dns_get_querystate()) == NULL) { DNSC_TRACE("no free query states available\n");#ifdef DNS_DEBUG print_resource_pool();#endif dmsg->error = ENOMEM; sendreply(msg); DNSC_DEBUG("exit - dns_get_querystate failed\n"); return; } /* Initialize the query state structure */ qs->use_cache = TRUE; qs->nquerys = dmsg->qcnt; qs->reply = msg; qs->qtype = aaaa_type; copy_domain(&qs->dm, dm); /* * If the host name ends with a dot, we assume the user wants us to try it * as a complete host name. If not, then we first just add the dot to the * name and try that then we'll add elements of the search list if that * fails. */ strcpy(qs->domain, dmsg->hostname); if (DOT == qs->domain[strlen(qs->domain) - 1]) { /* we've got a complete host name */ DNSC_TRACE("trying the null domain\n"); qs->next_srch = -1; } else { strcat(qs->domain, SDOT); /* add the '.' */ qs->next_srch = 0; /* set index of the first search list to try */ } /* * Now let us ask cache of all what interests us */ do { DnsQuestion question; /* cache requests are in the form of a DNS question */ DnsMsg dnsmsg; /* responses are returned in a DNS message */ int rc; memset(&question, 0, sizeof(question)); strcpy(question.q_name, qs->domain); question.q_type = QT_AAAA; question.q_class = QC_IN; memset(&dnsmsg, 0, sizeof(dnsmsg)); rc = dns_query_cache_byname6(&question, &dnsmsg); if (rc >= 0) { if (rc == DNS_NEGATIVE) { if (qs->next_srch > -1) { qs->next_srch++; DNSC_DEBUG("exit - call dns_start_next_search6\n"); return dns_start_next_search6(qs); } dmsg->error = EHOSTNOTFOUND; free_querystate(qs); sendreply(msg); DNSC_DEBUG("exit - negative reply from cache\n"); return; } if (rc == DNS_ANSWER || rc == DNS_CNAMEANSWER) { /* we got a direct answer */ dns_fmt_cache6_answer(qs, &dnsmsg); free_querystate(qs); dnsmsg_cleanup(&dnsmsg); sendreply(msg); DNSC_DEBUG("exit - positive reply from cache\n"); return; } /* * If the anwser RR is a CNAME and there are no additional records * then we have to construct the DNS query for the new name. Otherwise * format the answer and send it back. The cache places AAAA records * for a CNAME in the additional section. */ if (QT_CNAME == dnsmsg.m_answers->r_type && 0 == dnsmsg.m_dnshdr.naddrr) { strcpy(qs->cname, qs->domain); strcpy(qs->domain, dnsmsg.m_answers->r_data); dnsmsg_cleanup(&dnsmsg); cFlag = TRUE; } } /* if (rc > 0) */ /* * First get a list of default name servers to try, then construct the DNS * request message. Send the message and set timeout */ if ((qs->num_ns = get_ns_list(qs->domain, qs->ns_addrs, dm)) == 0) { dprintf("%C No name servers to query\n"); dmsg->error = ENONSADDRESS; free_querystate(qs); sendreply(msg); DNSC_DEBUG("exit - no name servers to query\n"); return; }#ifdef DNS_DEBUG if (dns_verbosity > 1) { int j; NS_t *ns; char ipStr[INET6_ADDRSTRLEN]; ns = qs->ns_addrs; for ( j = 0; j < qs->num_ns; j++ ) { ip_string(&ns[j].ns_addr, ipStr, sizeof(ipStr)); if ( ns[j].ns_name[0] != '\0' ) DNSC_TRACE("NS_list[%d]: %s, address %s\n", j, ns[j].ns_name, ipStr); else DNSC_TRACE("NS_list[%d] address: %s\n", j, ipStr); } }#endif qs->dns_construct = dns_std6_query; qs->dns_response = dns_response_std6_query; qs->dns_qreply = NULL; qs->ntrys = 0; if (FALSE == cFlag) { qs->qtype = aaaa_type; qs->qstate = wf_aaaa; } else { qs->qtype = ac_type; qs->qstate = wf_caddr; } #if defined (DNS_DEBUG) && defined (DNS_VERBOSE) DNSC_TRACE("starting query for %s\n", qs->domain);#endif if (dns_query(qs) < 0) { dmsg->error = ETRYAGAIN; free_querystate(qs); sendreply(msg); DNSC_DEBUG("exit - dns_query failed\n"); return; } } while (FALSE); DNSC_DEBUG("exit - success\n");} /* dns_getnodebyname *//* dns_gethostbyaddr6() * * This routine sets up a query state to handle a PTR request. * * PARAMETERS * msg - ATMOS message which triggered this routine * dm - initial Resolver information * * RETURNS * N/A */voiddns_gethostbyaddr6(IN ATMOS_MESSAGE *msg, IN DnsDomain *dm){ QueryState *query; struct sockaddr_storage addr; MSG_D_DNS_GET_HOSTBYADDR6(dmsg, msg); /* Get a new query state structure */ query = dns_get_querystate(); if (query == NULL) { DNSC_TRACE("no free query states available\n");#ifdef DNS_DEBUG print_resource_pool();#endif dmsg->error = ENOMEM; sendreply(msg); return; } /* Initialize the query state structure */ query->use_cache = TRUE; query->nquerys = dmsg->qcnt; query->reply = msg; copy_domain(&query->dm, dm); data2sock(&addr, dmsg->addr); reverse_sockaddr_int(&addr, query->domain); /* If alright by the user we first see if the info is in the cache */ /* pab note: it is always alright to lookup cache for IPv6 queries */ do { DnsQuestion question; /* the cache wants a DNS question */ DnsMsg dnsMsg; /* our representation of the DNS message */ /* Construct question, then try the cache */ strcpy(question.q_name, query->domain); question.q_type = QT_PTR; question.q_class = QC_IN; /* The cache either has a RR for this IP address or it doesn't */ memset(&dnsMsg, 0, sizeof(dnsMsg)); if (dns_query_cache_byaddr(question.q_name, &dnsMsg) == 0) { /* * See if the cache knows that this address doesn't exist. We * cache name error replies. No need to clean up the DnsMsg * if name error, only the flag is set. */ if ((dnsMsg.m_dnshdr.flags & DNS_RCODE) == DNS_NAMEERR) dmsg->error = EHOSTNOTFOUND; else { dns_fmt_ptr6_answer(query, &dnsMsg); dnsmsg_cleanup(&dnsMsg); } sendreply(msg); free_querystate(query); DNSC_DEBUG("exit - reply from cache\n"); return; } } while (FALSE); query->num_ns = get_ns_list(query->domain, query->ns_addrs, dm); if (query->num_ns == 0) { DNSC_MSG("No name servers to query\n"); dmsg->error = ENONSADDRESS; free_querystate(query); sendreply(msg); DNSC_DEBUG("exit - no name servers to query\n"); return; }#ifdef DNS_DEBUG if (dns_verbosity > 1) { int j; NS_t *ns; char ipStr[INET6_ADDRSTRLEN]; ns = query->ns_addrs; for (j = 0; j < query->num_ns; j++) { ip_string(&ns[j].ns_addr, ipStr, sizeof(ipStr)); if ( ns[j].ns_name[0] != '\0' ) DNSC_TRACE("NS_list[%d]: %s, address %s\n", j, ns[j].ns_name, ipStr); else DNSC_TRACE("NS_list[%d] address: %s\n", j, ipStr); } }#endif query->dns_construct = dns_ptr_query; query->dns_response = dns_response_ptr6_query; query->dns_qreply = NULL; query->ntrys = 0; query->qtype = ptr6_type; query->qstate = wf_ptr6; query->next_srch = -1; /* No need to worry about a search list here */#if defined (DNS_DEBUG) && defined (DNS_VERBOSE) DNSC_TRACE("starting query for %s\n", query->domain);#endif if (dns_query(query) < 0) { dmsg->error = ETRYAGAIN; free_querystate(query); sendreply(msg); DNSC_DEBUG("exit - dns_query failed\n"); return; } DNSC_DEBUG("exit - success\n"); } /* dns_gethostbyaddr6 */#ifdef DNS_DEBUG/* dns_print_query -- * Prints out query state structure * * PARAMETERS * qs - query state structure * * RETURNS * N/A */voiddns_print_query(IN QueryState *qs){ dprintf("------------------ Query Info ------------------\n"); if (!qs->used) { dprintf("<unused>\n"); } else { char buf[INET6_ADDRSTRLEN]; dprintf(" %-16s%s\n", "use cache", (qs->use_cache ? "yes" : "no")); ip_string(&qs->svripaddr, buf, sizeof(buf)); dprintf(" %-16s%s\n", "server", buf); dprintf(" %-16s%s\n", "domain", qs->domain); dprintf(" %-16s%d\n", "query id", qs->qid); dprintf(" %-16s%s\n", "query type", (qs->qtype == a_type ? "a" : (qs->qtype == a6_type ? "a6" : (qs->qtype == aaaa_type ? "aaaa" : (qs->qtype == ac_type ? "ac" : (qs->qtype == ptr_type ? "ptr" : (qs->qtype == ptr6_type ? "ptr6" : "<queer>"))))))); dprintf(" %-16swaiting for %s\n", "query state", (qs->qstate == wf_addr ? "IPv4 address" : (qs->qstate == wf_aaaa ? "IPv6 address" : (qs->qstate == wf_a6 ? "IPv6 address" : (qs->qstate == wf_nsaddr ? "nameserver IPv4 address" : (qs->qstate == wf_nsaddr6 ? "namserver IPv6 address" : (qs->qstate == wf_caddr ? "CNAME address" : (qs->qstate == wf_cqaddr ? "CNAME query" : (qs->qstate == wf_ptr ? "PTR for IPv4" : (qs->qstate == wf_ptr6 ? "PTR for IPv6" : "<weird>")))))))))); } dprintf("------------------------------------------------\n");}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -