⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns_client_query6.c

📁 DNS 的实现代码
💻 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 + -