📄 dns_client_query.c
字号:
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 + -