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

📄 dns_client_query.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	        dprintf("NS_list[%d]: %s, address %s\n", j, ns[j].ns_name, ipstr);	    else	        dprintf("NS_list[%d] address: %s\n", j, ipstr);	}    }#endif    query->dns_construct = dns_ptr_query;    query->dns_response = dns_response_ptr_query;    query->dns_qreply = NULL;    query->ntrys = 0;    query->qtype = ptr_type;    query->qstate = wf_ptr;    query->next_srch = -1;          /* no need to worry about a search list here */#if defined (DNS_DEBUG) && defined (DNS_VERBOSE)    dprintf("starting query for %s\n", query->domain);#endif    if ( dns_query(query) < 0 ) {	dmsg->error = ETRYAGAIN;	free_querystate(query);	sendreply(msg);	return;    }}   /* end dns_gethostbyaddr() *//* * dns_query() * * this routine will construct the DNS message.  it sets up the message headers. * it then will send the UDP message and set initial timeout for this message. * * return:  number of bytes sent, or *          -1 to indicate an error. */intdns_query(QueryState *query){    int   num;      DNSC_DEBUG("entry\n");    /* construct the DNS query message */    if ( query->dns_construct(query) < 0 ) {        dprintf("%C error attempting to construct the DNS request message\n");        DNSC_DEBUG("exit - dns_construct failed\n");	return -1;    }    /*      * post_query() will open socket (if necessary), send the      * constructed DNS message and then DNS client starts      * listen to network since socket will be opened.     * It also increments our counters.     */    if ((num = post_query(query, 0)) < 0 ) {#ifdef DNS_DEBUG        char  strip[INET6_ADDRSTRLEN];	ip_string(&query->ns_addrs[0].ns_addr, strip, sizeof(strip));        dprintf("error sending DNS request to %s\n", strip);#endif        DNSC_DEBUG("exit - post_query failed\n");        return -1;    }  #if defined (DNS_DEBUG) && defined (DNS_VERBOSE)    else {        char  ip[INET6_ADDRSTRLEN];	ip_string(&query->ns_addrs[0].ns_addr, ip, sizeof(ip));	dprintf("server's IP address: %s\n", ip);	dprintf("bytes sent: %d\n", num);	dprintf("size of DNS message: %d\n\n", query->dq_size);    }#endif    DNSC_DEBUG("exit - %d\n", num);    return num;}   /* end dns_query() *//* * get_ns_list() * * this routine will use the host name to see if there are NS in the cache * that we should try, if so we add them to the list until we reach the max * amount to use.  if there is room left in the list we add some of the default  * servers to the list.  if no NS in the cache we just add the default servers  * to the list. * * return:  the number of NS added to the list. */intget_ns_list(const char *name, NS_t *list, DnsDomain *domain){    int  i, j, num;    DNSC_DEBUG("entry\n");    num = dns_create_ns_list(name, MAXNS, list);    for ( i = num, j = 0; j < domain->num_svr && i < MAXNS; i++, j++ ) {        memcpy(&list[i].ns_addr, &domain->nsaddr[j],                sizeof(struct sockaddr_storage));        list[i].ns_name[0] = '\0';	list[i].ns_recursion = 0;         /* assume no recursion */	list[i].ns_error = 0;	list[i].ns_try = 0;    }    DNSC_DEBUG("exit - %d\n", i);    return i;}   /* end get_ns_list() *//* * post_query() * * this routine will "post" the DNS query message to the name server indicated  * by index.  it increments the try count for the name server.  after posting  * the message it sets initial timeout for that message. * * return:  number of bytes sent, or *          -1 to indicate an error condition. */intpost_query(QueryState *qs, int index){    int nsent;    DNSC_DEBUG("entry\n");    /* Set the name server index in the query state structure. This will be used       to avoid any retries to this specific name server in case it returns a       "refuse" response */    qs->addr_index = index;    nsent = dns_client_udp_send(qs->dns_query, qs->dq_size,                                (struct sockaddr *)                                    &qs->ns_addrs[index].ns_addr,                                sizeof(qs->ns_addrs[index].ns_addr),                                MS2SEC(qs->dm.timeout));    if (nsent < 0)    {        /* Fatal error */        DNSC_TRACE("Error trying to send DNS request via UDP\n");        DNSC_DEBUG("exit - dns_client_udp_send failed\n");        return -1;    }    else     {        /* Get current timestamp */        if (gettimeofday(&qs->deadline, NULL) != 0)        {            DNSC_TRACE("gettimeofday() failed\n");            /* Fail here if it's debugged */            ASSERT(FALSE);            DNSC_DEBUG("exit - gettimeofday() error\n");            return -1;        }        if (nsent > 0)        {            /* Set up timeout value as in current domain */            qs->deadline.tv_sec += qs->dm.timeout;        }        else        {            /*             * Not fatal error but message wasn't sent and it's necessary             * time out request immediately             */        }    }#if defined (DNS_DEBUG) && defined (DNS_VERBOSE)    {        char  ipstr[INET6_ADDRSTRLEN];        ip_string(&qs->ns_addrs[index].ns_addr, ipstr, sizeof(ipstr));        dprintf("post_query: using server %s\n", ipstr);        display_dnsmsghdr(qs->dns_query);    }#endif    qs->ns_addrs[index].ns_try++;    qs->ntrys++;    DNSC_DEBUG("exit - %d bytes were sent\n", nsent);        return nsent;}   /* end post_query() *//* * copy_domain() * * this routine will copy one DnsDomain structure to another.  this is done * so that if a user changes the domain configuration it will not affect any * pending queries. */voidcopy_domain(DnsDomain *to, DnsDomain *from){    int  i;    DNSC_DEBUG("entry\n");    to->timeout = from->timeout;    to->retry = from->retry;    to->num_search = from->num_search;    for ( i = 0; i < to->num_search; i++ )        strcpy(to->search[i], from->search[i]);       to->num_svr = from->num_svr;    for ( i = 0; i < to->num_svr; i++ )        to->nsaddr[i] = from->nsaddr[i];    DNSC_DEBUG("exit\n");    }   /* end copy_domain() *//* * construct_std_dnsquery() * * this routine will construct a standard type query.  that is, a query * looking for an IP address for a hostname, A type, or one looking for the * host name associated with an IP address, PTR type. * * return: 0 for success, or *        -1 to indicate an error. */intconstruct_std_dnsquery(QueryState *query, U16 type){    DnsQuestion  question;   /* our query for the DNS */    DnsMsg       dnsmsg;     /* our representation of the DNS message */    DnsHdr       *header;    /* header to the DNS message */    U8           *data;      /* DNS packet */    DNSC_DEBUG("entry\n");    memset(&question, 0, sizeof(question));    strcpy(question.q_name, query->domain);    question.q_type = type;    question.q_class = QC_IN;    dnsmsg.m_questions = &question;    dnsmsg.m_answers = NULL;    dnsmsg.m_authoritys = NULL;    dnsmsg.m_additionals = NULL;    header = (DnsHdr *)&dnsmsg.m_dnshdr;    query->qid = header->id = msgid++;    if ( DNSIDMAX == msgid )        msgid = 1;    header->flags = RSV_STDQUERY;    header->nquest = 1;    header->nansrr = 0;    header->nauthrr = 0;    header->naddrr = 0;    data = query->dns_query + DNSOFFSET;    if ((query->dq_size = create_dns_message(data, &dnsmsg)) < 0) {	dprintf("%C: error creating DNS standard query\n");        DNSC_DEBUG("exit - create_dns_message failed\n");	return -1;    }    DNSC_DEBUG("exit - success\n");    return 0;}   /* end construct_std_dnsquery() *//* * dns_XX_query() * * this routine will construct and send a NAPTR or SRV query.  * * return: None */void dns_XX_query(ATMOS_MESSAGE *msg, DnsDomain *dm){    QueryState  *qs;    DnsRRec     *rr;    Qtype 	qtype;    MSG_D_DNS_GET_RR(dmsg, msg);       DNSC_DEBUG("entry\n");     if (dmsg->qtype == QT_NAPTR)	qtype = naptr_type;    else if (dmsg->qtype == QT_SRV)        qtype = srv_type;    else        return;    /* get a new query state */    if ((qs = dns_get_querystate()) == NULL) 	{        kprintf("%C no free query states available\n");        dmsg->error = ENOMEM;        sendreply(msg);        DNSC_DEBUG("exit - no free query states available\n");        return;    }    /* initialize the query state structure */    qs->use_cache = dmsg->use_cache;    qs->nquerys = 0;    qs->reply = msg;    qs->next_srch = -1;    copy_domain(&qs->dm, dm);    /*     * if the domain name ends with a dot, we assume the user wants us to try it     * as a complete domain name.  if not, then we first just add the dot to the     * name and try           */    strcpy(qs->domain, dmsg->dname);    if ( DOT != qs->domain[strlen(qs->domain)-1] ) 	{  		/* we've got a complete domain name */        strcat(qs->domain, SDOT);    /* add the '.' */      }	/* search the cache if required */    if ( qs->use_cache )     {        if ( dns_query_XX_cache(qs->domain, dmsg->qtype, &rr) == ESUCCESS )        {            fmt_XX_answer(qs, rr);            free_querystate(qs);            sendreply(msg);            DNSC_DEBUG("exit - reply from cache\n");            return;         }    }        /*      * first get a list of default name servers to try, then construct the DNS     * request message, send the message and start listen to network.     */    if ((qs->num_ns = get_ns_list(qs->domain, qs->ns_addrs, dm)) == 0) 	{        kprintf("%C No name servers to query\n");        dmsg->error = ENONSADDRESS;        free_querystate(qs);        sendreply(msg);        DNSC_DEBUG("exit - no name server to query\n");        return;    }    if (qtype == naptr_type)    {        qs->dns_construct = dns_NAPTR_query ;     }    else    {        qs->dns_construct = dns_SRV_query ;     }    qs->dns_response = dns_response_XX_query;    qs->dns_qreply = NULL;    qs->qtype = qtype;    qs->qstate = ((qtype == naptr_type) ? wf_naptr:wf_srv);    qs->ntrys = 0;        if ( dns_query(qs) < 0 ) {        dmsg->error = ETRYAGAIN;        free_querystate(qs);        sendreply(msg);        DNSC_DEBUG("exit - dns_query failed\n");        return;    }    DNSC_DEBUG("exit - SUCCESS\n");} /*End  dns_XX_query() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -