ns_resp.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,318 行 · 第 1/4 页
C
2,318 行
} while (--c > 0); tp = cp; }#endif AUTHEN#ifdef AUTHEN if (authen_count) { if(ans_authentype == qp->q_authentype_out && ans_authentype == AUTH_KRB && ans_authenver == qp->q_authenver_out && ans_authenver == ONE) { krbnameptr = res_dotname_head(Q_NEXTNAME(qp, qp->q_curaddr)); dnameptr = dname_authenrr; if(type_authenrr != T_SOA && type_authenrr != T_AXFR) res_dotname_rmhead(&dnameptr); if(res_rds_krbcred(ONE, "named", krbnameptr, Q_NEXTCRED(qp, qp->q_curaddr), msg, authen_rr, authen_rrlen, dnameptr, type_authenrr, class_authenrr) < RET_OK) authen = 0; else { read_cred = 1; authen = 1; } free(krbnameptr); } }#endif AUTHEN /* * Add the info received in the response to the Data Base */ c = ancount + aucount + arcount;#ifdef notdef /* * If the request was for a CNAME that doesn't exist, * but the name is valid, fetch any other data for the name. * DON'T do this now, as it will requery if data are already * in the cache (maybe later with negative caching). */#ifdef AUTHEN if (hp->qdcount && type == T_CNAME && ((c == 1 && authen_count) !! (c == 0 && !authen_count)) && && hp->rcode == NOERROR && !qp->q_system && authen) {#else AUTHEN if (hp->qdcount && type == T_CNAME && c == 0 && hp->rcode == NOERROR && !qp->q_system) {#endif AUTHEN#ifdef DEBUG if (debug >= 3) fprintf(ddt,"resp: leaving, no CNAME\n");#endif /* Cause us to put it in the cache later */ prime(class, T_ANY, qp); /* Nothing to store, just give user the answer */ goto return_msg; }#endif /* notdef */ nspp = nsp; if (qp->q_system) dbflags = DB_NOTAUTH | DB_NODATA; else dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS; for (i = 0;#ifdef AUTHEN i < c && authen; i++) {#else AUTHEN i < c; i++) {#endif AUTHEN struct databuf *ns3;#ifdef AUTHEN if(arcount && authen_count && c == i+1) break;#endif AUTHEN if (cp >= msg + msglen) goto formerr; ns3 = 0;#ifdef AUTHEN if ((n = doupdate(msg, msglen, cp, 0, &ns3, ans_authentype, ans_authenver, dbflags)) < 0) {#else AUTHEN if ((n = doupdate(msg, msglen, cp, 0, &ns3, dbflags)) < 0) {#endif AUTHEN#ifdef DEBUG if (debug) fprintf(ddt,"resp: leaving, doupdate failed\n");#endif /* return code filled in by doupdate */ goto return_msg; } /* * Remember nameservers from the authority section * for referrals. * (This is usually overwritten by findns below(?). XXX */ if (ns3 && i >= ancount && i < ancount + aucount && nspp < &nsp[NSMAX-1]) *nspp++ = ns3; cp += n; }#ifdef AUTHEN if (qp->q_system && ancount) {#else AUTHEN if (qp->q_system) {#endif AUTHEN if (qp->q_system == PRIMING_CACHE) check_root();#ifdef DEBUG if (debug > 2) fprintf(ddt,"resp: leaving, SYSQUERY ancount %d\n", ancount);#endif qremove(qp); return; } if (cp > msg + msglen) goto formerr; /* * If there are addresses and this is a local query, * sort them appropriately for the local context. */ if (ancount > 1 && (lp = local(&qp->q_from)) != NULL#ifdef AUTHEN && authen) {#else AUTHEN )#endif AUTHEN sort_response(tp, ancount, lp, msg + msglen);#ifdef AUTHEN dname_authenrr = ans_name; n = dn_expand(msg, msg + msglen, tp, dname_authenrr, MAXDNAME); if (n < 0) goto servfail; }#endif AUTHEN /* * An answer to a C_ANY query or a successful answer to a * regular query with no indirection, then just return answer. */#ifdef AUTHEN if (authen && ((type == C_ANY && ancount) || (!cname && !qp->q_cmsglen && ancount))) {#else AUTHEN if((type == C_ANY && ancount) || (!cname && !qp->q_cmsglen && ancount)) {#endif AUTHEN#ifdef DEBUG if (debug >= 3) fprintf(ddt,"resp: got as much answer as there is\n");#endif goto return_msg; } /* * Eventually we will want to cache this negative answer. */#ifdef AUTHEN if (authen && ancount == 0 && (hp->aa || qp->q_fwd) && nscount == 0) {#else AUTHEN if (ancount == 0 && (hp->aa || qp->q_fwd) && nscount == 0) {#endif AUTHEN /* We have an authoritative NO */#ifdef DEBUG if (debug >= 3) fprintf(ddt,"resp: leaving auth NO\n");#endif if (qp->q_cmsglen) { msg = (u_char *)qp->q_cmsg; msglen = qp->q_cmsglen; hp = (HEADER *)msg; } goto return_msg; } /* * All messages in here need further processing. i.e. they * are either CNAMEs or we got referred again. */ count = 0; founddata = 0; foundname = 0; dname = name; if (!cname && qp->q_cmsglen && ancount) {#ifdef DEBUG if (debug) fprintf(ddt,"Cname second pass\n");#endif newmsglen = qp->q_cmsglen; bcopy(qp->q_cmsg, newmsg, newmsglen);#ifdef AUTHEN type_authenrr = qp->q_type; class_authenrr = qp->q_class; dname_authenrr = qp->q_dname;#endif AUTHEN } else { newmsglen = msglen; bcopy(msg, newmsg, newmsglen);#ifdef AUTHEN type_authenrr = type; class_authenrr = class; dname_authenrr= resp_name;#endif AUTHEN } hp = (HEADER *) newmsg; hp->ancount = 0; hp->nscount = 0; hp->arcount = 0; dnptrs[0] = newmsg; dnptrs[1] = NULL; cp = newmsg + sizeof(HEADER); if (cname)#ifdef AUTHEN cp += dn_skipname(cp, newmsg + newmsglen) + (hp->opcode == AQUERY ? AQFIXEDSZ : QFIXEDSZ);#else AUTHEN cp += dn_skipname(cp, newmsg + newmsglen) + QFIXEDSZ;#endif AUTHEN if ((n = dn_expand(newmsg, newmsg + newmsglen, cp, dname, sizeof(name))) < 0) {#ifdef DEBUG if (debug) fprintf(ddt,"dn_expand failed\n" );#endif goto servfail; }#ifdef AUTHEN cp = newmsg + sizeof(HEADER) + (cname ? dn_skipname(cp, newmsg + newmsglen) : n) + (hp->opcode == AQUERY ? AQFIXEDSZ : QFIXEDSZ);#else AUTHEN cp = newmsg + sizeof(HEADER) + (cname ? dn_skipname(cp, newmsg + newmsglen) : n) + QFIXEDSZ;#endif AUTHEN buflen = sizeof(newmsg) - (cp - newmsg);try_again:#ifdef DEBUG if (debug) fprintf(ddt,"resp: nlookup(%s) type=%d\n",dname, type);#endif fname = ""; htp = hashtab; /* lookup relative to root */ np = nlookup(dname, &htp, &fname, 0);#ifdef DEBUG if (debug) fprintf(ddt,"resp: %s '%s' as '%s' (cname=%d)\n", np == NULL ? "missed" : "found", dname, fname, cname);#endif if (np == NULL || fname != dname) goto fetch_ns; foundname++; count = cp - newmsg;#ifdef AUTHEN if (cname) { n = finddata(np, class, type, hp, &dname, &buflen, &count, qp->q_authentype_out, qp->q_authenver_out, &junk, &junk); }else { dname_authenrr = ans_name; strcpy(dname_authenrr, dname); n = finddata(np, class, type, hp, &dname_authenrr, &buflen, &count, qp->q_authentype_out, qp->q_authenver_out, &type_authenrr, &class_authenrr); dname = dname_authenrr; }#else AUTHEN n = finddata(np, class, type, hp, &dname, &buflen, &count);#endif AUTHEN if (n == 0) goto fetch_ns; /* NO data available */ cp += n; buflen -= n; hp->ancount += count; if (strcmp(fname, dname) && type != T_CNAME && type != T_ANY) { cname++; goto try_again; } founddata = 1;#ifdef DEBUG if (debug >= 3) { fprintf(ddt,"resp: foundname = %d count = %d ", foundname, count); fprintf(ddt,"founddata = %d cname = %d\n", founddata, cname); }#endiffetch_ns: hp->ancount = htons(hp->ancount); /* * Look for name servers to refer to and fill in the authority * section or record the address for forwarding the query * (recursion desired). */ switch (findns(&np, class, nsp, &count)) { case NXDOMAIN: /* shouldn't happen */#ifdef DEBUG if (debug >= 3) fprintf(ddt,"req: leaving (%s, rcode %d)\n", dname, hp->rcode);#endif if (!foundname) hp->rcode = NXDOMAIN; if (class != C_ANY) { hp->aa = 1; /* * should return SOA if founddata == 0, * but old named's are confused by an SOA * in the auth. section if there's no error. */ if (foundname == 0 && np) { n = doaddauth(hp, cp, buflen, np, nsp[0]); cp += n; buflen -= n; } } goto return_newmsg; case SERVFAIL: goto servfail; } if (founddata) { hp = (HEADER *)newmsg; n = add_data(np, nsp, cp, buflen); if (n < 0) { hp->tc = 1; n = (-n); } cp += n; buflen -= n; hp->nscount = htons((u_short)count); goto return_newmsg; } /* * If we get here, we don't have the answer yet and are about * to iterate to try and get it. First, infinite loop avoidance. */ if (qp->q_nqueries++ > MAXQUERIES) {#ifdef DEBUG if (debug) fprintf(ddt,"resp: MAXQUERIES exceeded (%s, class %d, type %d)\n", dname, class, type);#endif syslog(LOG_NOTICE, "MAXQUERIES exceeded, possible data loop in resolving (%s)", dname); goto servfail; } /* Reset the query control structure */ qp->q_naddr = 0; qp->q_curaddr = 0;#ifdef ULTRIXFUNC qp->q_fwd = qp->q_fwdorig;#else ULTRIXFUNC qp->q_fwd = fwdtab;#endif ULTRIXFUNC qp->q_addr[0].stime = tt; if (nslookup(nsp, qp) == 0) {#ifdef DEBUG if (debug >= 3) fprintf(ddt,"resp: no addrs found for NS's\n");#endif goto servfail; } if (cname) { if (qp->q_cname++ == MAXCNAMES) {#ifdef DEBUG if (debug >= 3) fprintf(ddt,"resp: leaving, MAXCNAMES exceeded\n");#endif goto servfail; }#ifdef DEBUG if (debug) fprintf(ddt,"q_cname = %d\n",qp->q_cname); if (debug >= 3) fprintf(ddt,"resp: building recursive query; nslookup\n");#endif if (qp->q_msg) (void) free(qp->q_msg); if ((qp->q_msg = malloc(BUFSIZ)) == NULL) {#ifdef DEBUG if (debug) fprintf(ddt,"resp: malloc error\n");#endif goto servfail; }#ifdef AUTHEN qp->q_msglen = res_mkquery(qp->q_type_out, dname, class, type, (char *)NULL, 0, NULL, qp->q_msg, BUFSIZ); dname_authenrr = dname; type_authenrr = type; class_authenrr = class; strcpy(qp->q_dname_curr, dname); qp->q_type_curr = type; qp->q_class_curr = class;#else AUTHEN qp->q_msglen = res_mkquery(QUERY, dname, class, type, (char *)NULL, 0, NULL, qp->q_msg, BUFSIZ);#endif AUTHEN#ifndef AUTHEN hp = (HEADER *) qp->q_msg;#endif AUTHEN hp->rd = 0; }#ifndef AUTHEN else hp = (HEADER *) qp->q_msg;#endif AUTHEN#ifdef AUTHEN hp = (HEADER *) msgbuf; bcopy(qp->q_msg, msgbuf, qp->q_msglen); msgbuflen = qp->q_msglen; hp->id = qp->q_nsid = htons((u_short)++nsid); if(qp->q_type_out == AQUERY && qp->q_authentype_out == AUTH_KRB && qp->q_authenver_out == ONE) { krbnameptr = res_dotname_head(Q_NEXTNAME(qp,0)); dnameptr = dname_authenrr; if(type_authenrr != T_SOA && type_authenrr != T_AXFR) res_dotname_rmhead(&dnameptr); if(res_mkl_krbcred(ONE, "named", dnameptr, Q_NEXTCRED(qp, 0), msgbuf, msgbuf + msgbuflen, sizeof(msgbuf) - msgbuflen, dnameptr, type_authenrr, class_authenrr) < RET_OK) goto servfail; hp->arcount = 1; } else if( qp->q_type_in == AQUERY) goto servfail;#else AUTHEN hp->id = qp->q_nsid = htons((u_short)++nsid);#endif AUTHEN unsched(qp);#ifdef ULTRIXFUNC schedretry(qp, qp->q_fwd ? (2*RETRYBASE): retrytime(qp) );#else ULTRIXFUNC schedretry(qp, retrytime(qp));#endif ULTRIXFUNC#ifdef DEBUG if (debug) fprintf(ddt,"resp: forw -> %s %d (%d) nsid=%d id=%d %dms\n", inet_ntoa(Q_NEXTADDR(qp,0)->sin_addr), ds, ntohs(Q_NEXTADDR(qp,0)->sin_port), ntohs(qp->q_nsid), ntohs(qp->q_id), qp->q_addr[0].nsdata->d_nstime); if ( debug >= 10) fp_query(msg, ddt);#endif#ifdef AUTHEN if (sendto(ds, msgbuf, msgbuflen, 0, (struct sockaddr *)Q_NEXTADDR(qp,0), sizeof(struct sockaddr_in)) < 0)#else AUTHEN if (sendto(ds, qp->q_msg, qp->q_msglen, 0, (struct sockaddr *)Q_NEXTADDR(qp,0), sizeof(struct sockaddr_in)) < 0)#endif AUTHEN {#ifdef DEBUG if (debug >= 5) fprintf(ddt, "sendto error = %d\n", errno);#endif }#ifdef STATS stats[S_OUTPKTS].cnt++;#endif#ifdef DEBUG if (debug >= 3) fprintf(ddt,"resp: Query sent.\n");#endif return;formerr:#ifdef DEBUG if (debug) fprintf(ddt,"FORMERR resp() from %s size err %d, msglen %d\n", inet_ntoa(from_addr.sin_addr), cp-msg, msglen);#endif syslog(LOG_INFO, "Malformed response from %s\n", inet_ntoa(from_addr.sin_addr));#ifdef STATS stats[S_RESPFORMERR].cnt++;#endif return;#ifdef AUTHENservfail:#ifdef STATS stats[S_RESPFAIL].cnt++;#endif hp = (HEADER *)(cname ? qp->q_cmsg : qp->q_msg); hp->rcode = SERVFAIL; hp->id = qp->q_id; tmplen = (cname ? qp->q_cmsglen : qp->q_msglen); tmpmsg = (u_char *)(cname ? qp->q_cmsg : qp->q_msg); dname_authenrr = qp->q_dname; type_authenrr = qp->q_type; class_authenrr = qp->q_class; new = 1; goto return_msg;return_newmsg: if (addcount) { n = doaddinfo(hp, cp, buflen); cp += n; buflen -= n; } tmplen = cp - newmsg; tmpmsg = newmsg;#ifdef STATS stats[S_RESPOK].cnt++;#endif new = 1;return_msg: if (!new) { tmpmsg = msg; tmplen = msglen;#ifdef STATS stats[S_RESPOK].cnt++;#endif } hp->id = qp->q_id; hp->rd = 1; hp->ra = 1; hp->qr = 1; if(qp->q_type_in == QUERY && qp->q_type_out == AQUERY) { cp = tmpmsg; cp += sizeof(HEADER); n = dn_skipname(cp, tmpmsg + tmplen); cp += n + 4 * sizeof(u_short); if (fixup_rrs(cp, tmplen - (cp - tmpmsg), cp - (u_char *)hp, -(2 * sizeof(u_short))) < 0) return(-1); bcopy(cp, cp - (2 * sizeof(u_short)), tmplen - (cp - tmpmsg)); tmplen -= authen_rrlen + (2 * sizeof(u_short)); hp->arcount = 0; hp->opcode = QUERY; } if(qp->q_type_in == AQUERY && qp->q_authentype_in == AUTH_KRB && qp->q_authenver_in == ONE && read_cred) { dnameptr = dname_authenrr; if (type_authenrr != T_SOA && type_authenrr != T_AXFR) res_dotname_rmhead(&dnameptr);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?