+ case rcode_refused:
+ adns__warn(ads,serv,qu,"server refused our query");
+ adns__query_fail(qu,adns_s_rcoderefused);
+ return;
+ default:
+ adns__warn(ads,serv,qu,"server gave unknown response code %d",rcode);
+ adns__query_fail(qu,adns_s_rcodeunknown);
+ return;
+ }
+
+ /* Now, take a look at the answer section, and see if it is complete.
+ * If it has any CNAMEs we stuff them in the answer.
+ */
+ wantedrrs= 0;
+ cbyte= anstart;
+ for (rri= 0; rri<ancount; rri++) {
+ rrstart= cbyte;
+ st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
+ &rrtype,&rrclass,&rdlength,&rdstart,
+ &ownermatched);
+ if (st) { adns__query_fail(qu,st); return; }
+ if (rrtype == -1) goto x_truncated;
+
+ if (rrclass != DNS_CLASS_IN) {
+ adns__diag(ads,serv,qu,"ignoring answer RR with wrong class %d (expected IN=%d)",
+ rrclass,DNS_CLASS_IN);
+ continue;
+ }
+ if (!ownermatched) {
+ if (ads->iflags & adns_if_debug) {
+ adns__debug(ads,serv,qu,"ignoring RR with an unexpected owner %s",
+ adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rrstart));
+ }
+ continue;
+ }
+ if (rrtype == adns_r_cname && /* fixme - implement adns_qf_nocname */
+ (qu->typei->type & adns__rrt_typemask) != adns_r_cname) {
+ if (qu->flags & adns_qf_cname_forbid) {
+ adns__query_fail(qu,adns_s_prohibitedcname);
+ return;
+ } else if (!qu->cname_dgram) { /* Ignore second and subsequent CNAMEs */
+ qu->cname_begin= rdstart;
+ qu->cname_dglen= dglen;
+ st= adns__parse_domain(ads,serv,qu, &qu->vb,
+ qu->flags & adns_qf_quoteok_cname ? pdf_quoteok : 0,
+ dgram,dglen, &rdstart,rdstart+rdlength);
+ if (!qu->vb.used) goto x_truncated;
+ if (st) { adns__query_fail(qu,st); return; }
+ l= strlen(qu->vb.buf)+1;
+ qu->answer->cname= adns__alloc_interim(qu,l);
+ if (!qu->answer->cname) { adns__query_fail(qu,adns_s_nomemory); return; }
+
+ qu->cname_dgram= adns__alloc_mine(qu,dglen);
+ memcpy(qu->cname_dgram,dgram,dglen);
+
+ memcpy(qu->answer->cname,qu->vb.buf,l);
+ cname_here= 1;
+ /* If we find the answer section truncated after this point we restart
+ * the query at the CNAME; if beforehand then we obviously have to use
+ * TCP. If there is no truncation we can use the whole answer if
+ * it contains the relevant info.
+ */
+ } else {
+ adns__debug(ads,serv,qu,"ignoring duplicate CNAME (%s, as well as %s)",
+ adns__diag_domain(ads,serv,qu, &qu->vb, dgram,dglen,rdstart),
+ qu->answer->cname);
+ }
+ } else if (rrtype == (qu->typei->type & adns__rrt_typemask)) {
+ wantedrrs++;
+ } else {
+ adns__debug(ads,serv,qu,"ignoring answer RR with irrelevant type %d",rrtype);
+ }