6 static RR* doextquery(DNSmsg*, Request*, int);
7 static void hint(RR**, RR*);
10 int norecursion; /* don't allow recursive requests */
13 * answer a dns request
16 dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
27 recursionflag = norecursion? 0: Fcanrec;
28 memset(repp, 0, sizeof(*repp));
30 repp->flags = Fresp | recursionflag | Oquery;
32 /* move one question from reqp to repp */
40 if (rcode >= 0 && rcode < nrname)
41 errmsg = rname[rcode];
42 dnslog("server: response code 0%o (%s), req from %I",
43 rcode, errmsg, srcip);
44 /* provide feedback to clients who send us trash */
45 repp->flags = (rcode&Rmask) | Fresp | Fcanrec | Oquery;
48 if(!rrsupported(repp->qd->type)){
49 dnslog("server: unsupported request %s from %I",
50 rrname(repp->qd->type, tname, sizeof tname), srcip);
51 repp->flags = Runimplimented | Fresp | Fcanrec | Oquery;
55 if(repp->qd->owner->class != Cin){
56 dnslog("server: unsupported class %d from %I",
57 repp->qd->owner->class, srcip);
58 repp->flags = Runimplimented | Fresp | Fcanrec | Oquery;
62 myarea = inmyarea(repp->qd->owner->name);
64 if(repp->qd->type == Tixfr || repp->qd->type == Taxfr){
65 dnslog("server: unsupported xfr request %s for %s from %I",
66 rrname(repp->qd->type, tname, sizeof tname),
67 repp->qd->owner->name, srcip);
68 repp->flags = Runimplimented | Fresp | recursionflag |
74 /* we don't recurse and we're not authoritative */
75 repp->flags = Rok | Fresp | Oquery;
80 * get the answer if we can, in *repp
82 if(reqp->flags & Frecurse)
83 neg = doextquery(repp, req, Recurse);
85 neg = doextquery(repp, req, Dontrecurse);
87 /* authority is transitive */
88 if(myarea != nil || (repp->an && repp->an->auth))
91 /* pass on error codes */
93 dp = dnlookup(repp->qd->owner->name, repp->qd->owner->class, 0);
95 if(reqp->flags & Frecurse)
96 repp->flags |= dp->respcode | Fauth;
101 * add name server if we know
103 for(cp = repp->qd->owner->name; cp; cp = walkup(cp)){
104 nsdp = dnlookup(cp, repp->qd->owner->class, 0);
108 repp->ns = rrlookup(nsdp, Tns, OKneg);
110 /* don't pass on anything we know is wrong */
111 if(repp->ns->negative){
112 rrfreelist(repp->ns);
118 if (strncmp(nsdp->name, "local#", 6) == 0)
119 dnslog("returning %s as nameserver", nsdp->name);
120 repp->ns = dblookup(cp, repp->qd->owner->class, Tns, 0, 0);
126 * add ip addresses as hints
128 if(repp->qd->type != Taxfr && repp->qd->type != Tixfr){
129 for(tp = repp->ns; tp; tp = tp->next)
131 for(tp = repp->an; tp; tp = tp->next)
135 /* hint calls rrlookup which holds dnlock, so don't lock before this. */
138 * add an soa to the authority section to help client
139 * with negative caching
144 rrcopy(myarea->soarr, &tp);
145 rrcat(&repp->ns, tp);
147 } else if(neg != nil) {
148 if(neg->negsoaowner != nil) {
149 tp = rrlookup(neg->negsoaowner, Tsoa, NOneg);
151 rrcat(&repp->ns, tp);
154 repp->flags |= neg->negrcode;
158 * get rid of duplicates
172 * satisfy a recursive request. dnlookup will handle cnames.
175 doextquery(DNSmsg *mp, Request *req, int recurse)
181 name = mp->qd->owner->name;
183 rp = dnresolve(name, Cin, type, req, &mp->an, 0, recurse, 1, 0);
186 /* don't return soa hints as answers, it's wrong */
187 if(rp && rp->db && !rp->auth && rp->type == Tsoa) {
192 /* don't let negative cached entries escape */
200 hint(RR **last, RR *rp)
210 hp = rrlookup(rp->host, Ta, NOneg);
212 hp = dblookup(rp->host->name, Cin, Ta, 0, 0);
214 hp = rrlookup(rp->host, Taaaa, NOneg);
216 hp = dblookup(rp->host->name, Cin, Taaaa, 0, 0);
217 if (hp && strncmp(hp->owner->name, "local#", 6) == 0)
218 dnslog("returning %s as hint", hp->owner->name);