dnresolve.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  1. /*
  2. * domain name resolvers, see rfcs 1035 and 1123
  3. */
  4. #include <u.h>
  5. #include <libc.h>
  6. #include <ip.h>
  7. #include <bio.h>
  8. #include <ndb.h>
  9. #include "dns.h"
  10. #define NS2MS(ns) ((ns) / 1000000L)
  11. #define S2MS(s) ((s) * 1000)
  12. #define MS2S(ms) ((ms) / 1000)
  13. typedef struct Dest Dest;
  14. typedef struct Ipaddr Ipaddr;
  15. typedef struct Query Query;
  16. enum
  17. {
  18. Udp, Tcp,
  19. Maxdest= 24, /* maximum destinations for a request message */
  20. Maxtrans= 3, /* maximum transmissions to a server */
  21. Destmagic= 0xcafebabe,
  22. Querymagic= 0xdeadbeef,
  23. };
  24. enum { Hurry, Patient, };
  25. enum { Outns, Inns, };
  26. enum { Remntretry = 15, }; /* min. sec.s between remount attempts */
  27. struct Ipaddr {
  28. Ipaddr *next;
  29. uchar ip[IPaddrlen];
  30. };
  31. struct Dest
  32. {
  33. uchar a[IPaddrlen]; /* ip address */
  34. DN *s; /* name server */
  35. int nx; /* number of transmissions */
  36. int code; /* response code; used to clear dp->respcode */
  37. ulong magic;
  38. };
  39. struct Query {
  40. DN *dp; /* domain */
  41. int type; /* and type to look up */
  42. Request *req;
  43. RR *nsrp; /* name servers to consult */
  44. /* dest must not be on the stack due to forking in slave() */
  45. Dest *dest; /* array of destinations */
  46. Dest *curdest; /* pointer to one of them */
  47. int ndest;
  48. int udpfd;
  49. QLock tcplock; /* only one tcp call at a time per query */
  50. int tcpset;
  51. int tcpfd; /* if Tcp, read replies from here */
  52. int tcpctlfd;
  53. uchar tcpip[IPaddrlen];
  54. ulong magic;
  55. };
  56. /* estimated % probability of such a record existing at all */
  57. int likely[] = {
  58. [Ta] 95,
  59. [Taaaa] 10,
  60. [Tcname] 15,
  61. [Tmx] 60,
  62. [Tns] 90,
  63. [Tnull] 5,
  64. [Tptr] 35,
  65. [Tsoa] 90,
  66. [Tsrv] 60,
  67. [Ttxt] 15,
  68. [Tall] 95,
  69. };
  70. static RR* dnresolve1(char*, int, int, Request*, int, int);
  71. static int netquery(Query *, int);
  72. /*
  73. * reading /proc/pid/args yields either "name" or "name [display args]",
  74. * so return only display args, if any.
  75. */
  76. static char *
  77. procgetname(void)
  78. {
  79. int fd, n;
  80. char *lp, *rp;
  81. char buf[256];
  82. snprint(buf, sizeof buf, "#p/%d/args", getpid());
  83. if((fd = open(buf, OREAD)) < 0)
  84. return strdup("");
  85. *buf = '\0';
  86. n = read(fd, buf, sizeof buf-1);
  87. close(fd);
  88. if (n >= 0)
  89. buf[n] = '\0';
  90. if ((lp = strchr(buf, '[')) == nil ||
  91. (rp = strrchr(buf, ']')) == nil)
  92. return strdup("");
  93. *rp = '\0';
  94. return strdup(lp+1);
  95. }
  96. /*
  97. * lookup 'type' info for domain name 'name'. If it doesn't exist, try
  98. * looking it up as a canonical name.
  99. */
  100. RR*
  101. dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
  102. int recurse, int rooted, int *status)
  103. {
  104. RR *rp, *nrp, *drp;
  105. DN *dp;
  106. int loops;
  107. char *procname;
  108. char nname[Domlen];
  109. if(status)
  110. *status = 0;
  111. if(depth > 12) /* in a recursive loop? */
  112. return nil;
  113. procname = procgetname();
  114. /*
  115. * hack for systems that don't have resolve search
  116. * lists. Just look up the simple name in the database.
  117. */
  118. if(!rooted && strchr(name, '.') == 0){
  119. rp = nil;
  120. drp = domainlist(class);
  121. for(nrp = drp; rp == nil && nrp != nil; nrp = nrp->next){
  122. snprint(nname, sizeof nname, "%s.%s", name,
  123. nrp->ptr->name);
  124. rp = dnresolve(nname, class, type, req, cn, depth+1,
  125. recurse, rooted, status);
  126. rrfreelist(rrremneg(&rp));
  127. }
  128. if(drp != nil)
  129. rrfreelist(drp); /* was rrfree */
  130. procsetname(procname);
  131. free(procname);
  132. return rp;
  133. }
  134. /*
  135. * try the name directly
  136. */
  137. rp = dnresolve1(name, class, type, req, depth, recurse);
  138. if(rp) {
  139. procsetname(procname);
  140. free(procname);
  141. return randomize(rp);
  142. }
  143. /* try it as a canonical name if we weren't told the name didn't exist */
  144. dp = dnlookup(name, class, 0);
  145. if(type != Tptr && dp->respcode != Rname)
  146. for(loops = 0; rp == nil && loops < 32; loops++){
  147. rp = dnresolve1(name, class, Tcname, req, depth, recurse);
  148. if(rp == nil)
  149. break;
  150. if(rp->negative){
  151. rrfreelist(rp);
  152. rp = nil;
  153. break;
  154. }
  155. name = rp->host->name;
  156. if(cn)
  157. rrcat(cn, rp);
  158. else
  159. rrfreelist(rp);
  160. rp = dnresolve1(name, class, type, req, depth, recurse);
  161. }
  162. /* distinction between not found and not good */
  163. if(rp == nil && status != nil && dp->respcode != 0)
  164. *status = dp->respcode;
  165. procsetname(procname);
  166. free(procname);
  167. return randomize(rp);
  168. }
  169. static void
  170. queryinit(Query *qp, DN *dp, int type, Request *req)
  171. {
  172. memset(qp, 0, sizeof *qp);
  173. qp->udpfd = qp->tcpfd = qp->tcpctlfd = -1;
  174. qp->dp = dp;
  175. qp->type = type;
  176. qp->req = req;
  177. qp->nsrp = nil;
  178. qp->dest = qp->curdest = nil;
  179. qp->magic = Querymagic;
  180. }
  181. static void
  182. queryck(Query *qp)
  183. {
  184. assert(qp);
  185. assert(qp->magic == Querymagic);
  186. }
  187. static void
  188. querydestroy(Query *qp)
  189. {
  190. queryck(qp);
  191. /* leave udpfd alone */
  192. if (qp->tcpfd > 0)
  193. close(qp->tcpfd);
  194. if (qp->tcpctlfd > 0) {
  195. hangup(qp->tcpctlfd);
  196. close(qp->tcpctlfd);
  197. }
  198. free(qp->dest);
  199. memset(qp, 0, sizeof *qp); /* prevent accidents */
  200. qp->udpfd = qp->tcpfd = qp->tcpctlfd = -1;
  201. }
  202. static void
  203. destinit(Dest *p)
  204. {
  205. memset(p, 0, sizeof *p);
  206. p->magic = Destmagic;
  207. }
  208. static void
  209. destck(Dest *p)
  210. {
  211. assert(p);
  212. assert(p->magic == Destmagic);
  213. }
  214. static void
  215. destdestroy(Dest *p)
  216. {
  217. USED(p);
  218. }
  219. /*
  220. * if the response to a query hasn't arrived within 100 ms.,
  221. * it's unlikely to arrive at all. after 1 s., it's really unlikely.
  222. * queries for missing RRs are likely to produce time-outs rather than
  223. * negative responses, so cname and aaaa queries are likely to time out,
  224. * thus we don't wait very long for them.
  225. */
  226. static void
  227. notestats(vlong start, int tmout, int type)
  228. {
  229. qlock(&stats);
  230. if (tmout) {
  231. stats.tmout++;
  232. if (type == Taaaa)
  233. stats.tmoutv6++;
  234. else if (type == Tcname)
  235. stats.tmoutcname++;
  236. } else {
  237. long wait10ths = NS2MS(nsec() - start) / 100;
  238. if (wait10ths <= 0)
  239. stats.under10ths[0]++;
  240. else if (wait10ths >= nelem(stats.under10ths))
  241. stats.under10ths[nelem(stats.under10ths) - 1]++;
  242. else
  243. stats.under10ths[wait10ths]++;
  244. }
  245. qunlock(&stats);
  246. }
  247. static void
  248. noteinmem(void)
  249. {
  250. qlock(&stats);
  251. stats.answinmem++;
  252. qunlock(&stats);
  253. }
  254. static RR*
  255. dnresolve1(char *name, int class, int type, Request *req, int depth,
  256. int recurse)
  257. {
  258. char *cp;
  259. Area *area;
  260. DN *dp, *nsdp;
  261. RR *rp, *nsrp, *dbnsrp;
  262. Query query;
  263. if(debug)
  264. dnslog("[%d] dnresolve1 %s %d %d", getpid(), name, type, class);
  265. /* only class Cin implemented so far */
  266. if(class != Cin)
  267. return nil;
  268. dp = dnlookup(name, class, 1);
  269. /*
  270. * Try the cache first
  271. */
  272. rp = rrlookup(dp, type, OKneg);
  273. if(rp)
  274. if(rp->db){
  275. /* unauthoritative db entries are hints */
  276. if(rp->auth) {
  277. noteinmem();
  278. return rp;
  279. }
  280. } else
  281. /* cached entry must still be valid */
  282. if(rp->ttl > now)
  283. /* but Tall entries are special */
  284. if(type != Tall || rp->query == Tall) {
  285. noteinmem();
  286. return rp;
  287. }
  288. rrfreelist(rp);
  289. /*
  290. * try the cache for a canonical name. if found punt
  291. * since we'll find it during the canonical name search
  292. * in dnresolve().
  293. */
  294. if(type != Tcname){
  295. rp = rrlookup(dp, Tcname, NOneg);
  296. rrfreelist(rp);
  297. if(rp)
  298. return nil;
  299. }
  300. /*
  301. * if the domain name is within an area of ours,
  302. * we should have found its data in memory by now.
  303. */
  304. area = inmyarea(dp->name);
  305. if (area || strncmp(dp->name, "local#", 6) == 0) {
  306. // char buf[32];
  307. // dnslog("%s %s: no data in area %s", dp->name,
  308. // rrname(type, buf, sizeof buf), area->soarr->owner->name);
  309. return nil;
  310. }
  311. queryinit(&query, dp, type, req);
  312. /*
  313. * if we're running as just a resolver, query our
  314. * designated name servers
  315. */
  316. if(cfg.resolver){
  317. nsrp = randomize(getdnsservers(class));
  318. if(nsrp != nil) {
  319. query.nsrp = nsrp;
  320. if(netquery(&query, depth+1)){
  321. rrfreelist(nsrp);
  322. querydestroy(&query);
  323. return rrlookup(dp, type, OKneg);
  324. }
  325. rrfreelist(nsrp);
  326. }
  327. }
  328. /*
  329. * walk up the domain name looking for
  330. * a name server for the domain.
  331. */
  332. for(cp = name; cp; cp = walkup(cp)){
  333. /*
  334. * if this is a local (served by us) domain,
  335. * return answer
  336. */
  337. dbnsrp = randomize(dblookup(cp, class, Tns, 0, 0));
  338. if(dbnsrp && dbnsrp->local){
  339. rp = dblookup(name, class, type, 1, dbnsrp->ttl);
  340. rrfreelist(dbnsrp);
  341. querydestroy(&query);
  342. return rp;
  343. }
  344. /*
  345. * if recursion isn't set, just accept local
  346. * entries
  347. */
  348. if(recurse == Dontrecurse){
  349. if(dbnsrp)
  350. rrfreelist(dbnsrp);
  351. continue;
  352. }
  353. /* look for ns in cache */
  354. nsdp = dnlookup(cp, class, 0);
  355. nsrp = nil;
  356. if(nsdp)
  357. nsrp = randomize(rrlookup(nsdp, Tns, NOneg));
  358. /* if the entry timed out, ignore it */
  359. if(nsrp && nsrp->ttl < now){
  360. rrfreelist(nsrp);
  361. nsrp = nil;
  362. }
  363. if(nsrp){
  364. rrfreelist(dbnsrp);
  365. /* query the name servers found in cache */
  366. query.nsrp = nsrp;
  367. if(netquery(&query, depth+1)){
  368. rrfreelist(nsrp);
  369. querydestroy(&query);
  370. return rrlookup(dp, type, OKneg);
  371. }
  372. rrfreelist(nsrp);
  373. continue;
  374. }
  375. /* use ns from db */
  376. if(dbnsrp){
  377. /* try the name servers found in db */
  378. query.nsrp = dbnsrp;
  379. if(netquery(&query, depth+1)){
  380. /* we got an answer */
  381. rrfreelist(dbnsrp);
  382. querydestroy(&query);
  383. return rrlookup(dp, type, NOneg);
  384. }
  385. rrfreelist(dbnsrp);
  386. }
  387. }
  388. querydestroy(&query);
  389. /* settle for a non-authoritative answer */
  390. rp = rrlookup(dp, type, OKneg);
  391. if(rp)
  392. return rp;
  393. /* noone answered. try the database, we might have a chance. */
  394. return dblookup(name, class, type, 0, 0);
  395. }
  396. /*
  397. * walk a domain name one element to the right.
  398. * return a pointer to that element.
  399. * in other words, return a pointer to the parent domain name.
  400. */
  401. char*
  402. walkup(char *name)
  403. {
  404. char *cp;
  405. cp = strchr(name, '.');
  406. if(cp)
  407. return cp+1;
  408. else if(*name)
  409. return "";
  410. else
  411. return 0;
  412. }
  413. /*
  414. * Get a udp port for sending requests and reading replies. Put the port
  415. * into "headers" mode.
  416. */
  417. static char *hmsg = "headers";
  418. int
  419. udpport(char *mtpt)
  420. {
  421. int fd, ctl;
  422. char ds[64], adir[64];
  423. /* get a udp port */
  424. snprint(ds, sizeof ds, "%s/udp!*!0", (mtpt? mtpt: "/net"));
  425. ctl = announce(ds, adir);
  426. if(ctl < 0){
  427. /* warning("can't get udp port"); */
  428. return -1;
  429. }
  430. /* turn on header style interface */
  431. if(write(ctl, hmsg, strlen(hmsg)) , 0){
  432. close(ctl);
  433. warning(hmsg);
  434. return -1;
  435. }
  436. /* grab the data file */
  437. snprint(ds, sizeof ds, "%s/data", adir);
  438. fd = open(ds, ORDWR);
  439. close(ctl);
  440. if(fd < 0)
  441. warning("can't open udp port %s: %r", ds);
  442. return fd;
  443. }
  444. /* generate a DNS UDP query packet */
  445. int
  446. mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
  447. {
  448. DNSmsg m;
  449. int len;
  450. Udphdr *uh = (Udphdr*)buf;
  451. /* stuff port number into output buffer */
  452. memset(uh, 0, sizeof *uh);
  453. hnputs(uh->rport, 53);
  454. /* make request and convert it to output format */
  455. memset(&m, 0, sizeof m);
  456. m.flags = flags;
  457. m.id = reqno;
  458. m.qd = rralloc(type);
  459. m.qd->owner = dp;
  460. m.qd->type = type;
  461. len = convDNS2M(&m, &buf[Udphdrsize], Maxudp);
  462. rrfree(m.qd);
  463. return len;
  464. }
  465. /* for alarms in readreply */
  466. static void
  467. ding(void *x, char *msg)
  468. {
  469. USED(x);
  470. if(strcmp(msg, "alarm") == 0)
  471. noted(NCONT);
  472. else
  473. noted(NDFLT);
  474. }
  475. void
  476. freeanswers(DNSmsg *mp)
  477. {
  478. rrfreelist(mp->qd);
  479. rrfreelist(mp->an);
  480. rrfreelist(mp->ns);
  481. rrfreelist(mp->ar);
  482. mp->qd = mp->an = mp->ns = mp->ar = nil;
  483. }
  484. /* sets srcip */
  485. static int
  486. readnet(Query *qp, int medium, uchar *ibuf, ulong endtime, uchar **replyp,
  487. uchar *srcip)
  488. {
  489. int len, fd;
  490. long ms;
  491. vlong startns = nsec();
  492. uchar *reply;
  493. uchar lenbuf[2];
  494. /* timed read of reply */
  495. ms = S2MS(endtime) - NS2MS(startns);
  496. if (ms < 2000)
  497. ms = 2000; /* give the remote ns a fighting chance */
  498. reply = ibuf;
  499. len = -1; /* pessimism */
  500. memset(srcip, 0, IPaddrlen);
  501. if (medium == Udp)
  502. if (qp->udpfd <= 0)
  503. dnslog("readnet: qp->udpfd closed");
  504. else {
  505. alarm(ms);
  506. len = read(qp->udpfd, ibuf, Udphdrsize+Maxudpin);
  507. alarm(0);
  508. notestats(startns, len < 0, qp->type);
  509. if (len >= IPaddrlen)
  510. memmove(srcip, ibuf, IPaddrlen);
  511. if (len >= Udphdrsize) {
  512. len -= Udphdrsize;
  513. reply += Udphdrsize;
  514. }
  515. }
  516. else {
  517. if (!qp->tcpset)
  518. dnslog("readnet: tcp params not set");
  519. alarm(ms);
  520. fd = qp->tcpfd;
  521. if (fd <= 0)
  522. dnslog("readnet: %s: tcp fd unset for dest %I",
  523. qp->dp->name, qp->tcpip);
  524. else if (readn(fd, lenbuf, 2) != 2) {
  525. dnslog("readnet: short read of tcp size from %I",
  526. qp->tcpip);
  527. /* probably a time-out */
  528. notestats(startns, 1, qp->type);
  529. } else {
  530. len = lenbuf[0]<<8 | lenbuf[1];
  531. if (readn(fd, ibuf, len) != len) {
  532. dnslog("readnet: short read of tcp data from %I",
  533. qp->tcpip);
  534. /* probably a time-out */
  535. notestats(startns, 1, qp->type);
  536. len = -1;
  537. }
  538. }
  539. alarm(0);
  540. memmove(srcip, qp->tcpip, IPaddrlen);
  541. }
  542. *replyp = reply;
  543. return len;
  544. }
  545. /*
  546. * read replies to a request and remember the rrs in the answer(s).
  547. * ignore any of the wrong type.
  548. * wait at most until endtime.
  549. */
  550. static int
  551. readreply(Query *qp, int medium, ushort req, uchar *ibuf, DNSmsg *mp,
  552. ulong endtime)
  553. {
  554. int len, rv;
  555. char *err;
  556. char tbuf[32];
  557. uchar *reply;
  558. uchar srcip[IPaddrlen];
  559. RR *rp;
  560. notify(ding);
  561. queryck(qp);
  562. rv = 0;
  563. memset(mp, 0, sizeof *mp);
  564. if (time(nil) >= endtime)
  565. return -1; /* timed out before we started */
  566. memset(srcip, 0, sizeof srcip);
  567. if (0)
  568. len = -1;
  569. for (; time(nil) < endtime &&
  570. (len = readnet(qp, medium, ibuf, endtime, &reply, srcip)) >= 0;
  571. freeanswers(mp)){
  572. /* convert into internal format */
  573. memset(mp, 0, sizeof *mp);
  574. err = convM2DNS(reply, len, mp, nil);
  575. if (mp->flags & Ftrunc) {
  576. free(err);
  577. freeanswers(mp);
  578. /* notify our caller to retry the query via tcp. */
  579. return -1;
  580. } else if(err){
  581. dnslog("readreply: %s: input err, len %d: %s: %I",
  582. qp->dp->name, len, err, srcip);
  583. free(err);
  584. continue;
  585. }
  586. if(debug)
  587. logreply(qp->req->id, srcip, mp);
  588. /* answering the right question? */
  589. if(mp->id != req)
  590. dnslog("%d: id %d instead of %d: %I", qp->req->id,
  591. mp->id, req, srcip);
  592. else if(mp->qd == 0)
  593. dnslog("%d: no question RR: %I", qp->req->id, srcip);
  594. else if(mp->qd->owner != qp->dp)
  595. dnslog("%d: owner %s instead of %s: %I", qp->req->id,
  596. mp->qd->owner->name, qp->dp->name, srcip);
  597. else if(mp->qd->type != qp->type)
  598. dnslog("%d: qp->type %d instead of %d: %I",
  599. qp->req->id, mp->qd->type, qp->type, srcip);
  600. else {
  601. /* remember what request this is in answer to */
  602. for(rp = mp->an; rp; rp = rp->next)
  603. rp->query = qp->type;
  604. return rv;
  605. }
  606. }
  607. if (time(nil) >= endtime) {
  608. ; /* query expired */
  609. } else if (0) {
  610. /* this happens routinely when a read times out */
  611. dnslog("readreply: %s type %s: ns %I read error or eof "
  612. "(returned %d): %r", qp->dp->name, rrname(qp->type,
  613. tbuf, sizeof tbuf), srcip, len);
  614. if (medium == Udp)
  615. for (rp = qp->nsrp; rp != nil; rp = rp->next)
  616. if (rp->type == Tns)
  617. dnslog("readreply: %s: query sent to "
  618. "ns %s", qp->dp->name,
  619. rp->host->name);
  620. }
  621. return -1;
  622. }
  623. /*
  624. * return non-0 if first list includes second list
  625. */
  626. int
  627. contains(RR *rp1, RR *rp2)
  628. {
  629. RR *trp1, *trp2;
  630. for(trp2 = rp2; trp2; trp2 = trp2->next){
  631. for(trp1 = rp1; trp1; trp1 = trp1->next)
  632. if(trp1->type == trp2->type)
  633. if(trp1->host == trp2->host)
  634. if(trp1->owner == trp2->owner)
  635. break;
  636. if(trp1 == nil)
  637. return 0;
  638. }
  639. return 1;
  640. }
  641. /*
  642. * return multicast version if any
  643. */
  644. int
  645. ipisbm(uchar *ip)
  646. {
  647. if(isv4(ip)){
  648. if (ip[IPv4off] >= 0xe0 && ip[IPv4off] < 0xf0 ||
  649. ipcmp(ip, IPv4bcast) == 0)
  650. return 4;
  651. } else
  652. if(ip[0] == 0xff)
  653. return 6;
  654. return 0;
  655. }
  656. /*
  657. * Get next server address
  658. */
  659. static int
  660. serveraddrs(Query *qp, int nd, int depth)
  661. {
  662. RR *rp, *arp, *trp;
  663. Dest *cur;
  664. if(nd >= Maxdest)
  665. return 0;
  666. /*
  667. * look for a server whose address we already know.
  668. * if we find one, mark it so we ignore this on
  669. * subsequent passes.
  670. */
  671. arp = 0;
  672. for(rp = qp->nsrp; rp; rp = rp->next){
  673. assert(rp->magic == RRmagic);
  674. if(rp->marker)
  675. continue;
  676. arp = rrlookup(rp->host, Ta, NOneg);
  677. if(arp){
  678. rp->marker = 1;
  679. break;
  680. }
  681. arp = dblookup(rp->host->name, Cin, Ta, 0, 0);
  682. if(arp){
  683. rp->marker = 1;
  684. break;
  685. }
  686. }
  687. /*
  688. * if the cache and database lookup didn't find any new
  689. * server addresses, try resolving one via the network.
  690. * Mark any we try to resolve so we don't try a second time.
  691. */
  692. if(arp == 0)
  693. for(rp = qp->nsrp; rp; rp = rp->next){
  694. if(rp->marker)
  695. continue;
  696. rp->marker = 1;
  697. /*
  698. * avoid loops looking up a server under itself
  699. */
  700. if(subsume(rp->owner->name, rp->host->name))
  701. continue;
  702. arp = dnresolve(rp->host->name, Cin, Ta, qp->req, 0,
  703. depth+1, Recurse, 1, 0);
  704. rrfreelist(rrremneg(&arp));
  705. if(arp)
  706. break;
  707. }
  708. /* use any addresses that we found */
  709. for(trp = arp; trp && nd < Maxdest; trp = trp->next){
  710. cur = &qp->dest[nd];
  711. parseip(cur->a, trp->ip->name);
  712. /*
  713. * straddling servers can reject all nameservers if they are all
  714. * inside, so be sure to list at least one outside ns at
  715. * the end of the ns list in /lib/ndb for `dom='.
  716. */
  717. if (ipisbm(cur->a) ||
  718. cfg.straddle && !insideaddr(qp->dp->name) && insidens(cur->a))
  719. continue;
  720. cur->nx = 0;
  721. cur->s = trp->owner;
  722. cur->code = Rtimeout;
  723. nd++;
  724. }
  725. rrfreelist(arp);
  726. return nd;
  727. }
  728. /*
  729. * cache negative responses
  730. */
  731. static void
  732. cacheneg(DN *dp, int type, int rcode, RR *soarr)
  733. {
  734. RR *rp;
  735. DN *soaowner;
  736. ulong ttl;
  737. stats.negcached++;
  738. /* no cache time specified, don't make anything up */
  739. if(soarr != nil){
  740. if(soarr->next != nil){
  741. rrfreelist(soarr->next);
  742. soarr->next = nil;
  743. }
  744. soaowner = soarr->owner;
  745. } else
  746. soaowner = nil;
  747. /* the attach can cause soarr to be freed so mine it now */
  748. if(soarr != nil && soarr->soa != nil)
  749. ttl = soarr->soa->minttl+now;
  750. else
  751. ttl = 5*Min;
  752. /* add soa and negative RR to the database */
  753. rrattach(soarr, 1);
  754. rp = rralloc(type);
  755. rp->owner = dp;
  756. rp->negative = 1;
  757. rp->negsoaowner = soaowner;
  758. rp->negrcode = rcode;
  759. rp->ttl = ttl;
  760. rrattach(rp, 1);
  761. }
  762. static int
  763. setdestoutns(Dest *p, int n)
  764. {
  765. uchar *outns = outsidens(n);
  766. destck(p);
  767. destinit(p);
  768. if (outns == nil) {
  769. if (n == 0)
  770. dnslog("[%d] no outside-ns in ndb", getpid());
  771. return -1;
  772. }
  773. memmove(p->a, outns, sizeof p->a);
  774. p->s = dnlookup("outside-ns-ips", Cin, 1);
  775. return 0;
  776. }
  777. /*
  778. * issue query via UDP or TCP as appropriate.
  779. * for TCP, returns with qp->tcpip set from udppkt header.
  780. */
  781. static int
  782. mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
  783. {
  784. int rv = -1, nfd;
  785. char *domain;
  786. char conndir[40];
  787. uchar belen[2];
  788. NetConnInfo *nci;
  789. queryck(qp);
  790. switch (medium) {
  791. case Udp:
  792. nfd = dup(qp->udpfd, -1);
  793. if (nfd < 0) {
  794. warning("mydnsquery: qp->udpfd %d: %r", qp->udpfd);
  795. close(qp->udpfd); /* ensure it's closed */
  796. qp->udpfd = -1; /* poison it */
  797. return rv;
  798. }
  799. close(nfd);
  800. if (qp->udpfd <= 0)
  801. dnslog("mydnsquery: qp->udpfd %d closed", qp->udpfd);
  802. else {
  803. if (write(qp->udpfd, udppkt, len+Udphdrsize) !=
  804. len+Udphdrsize)
  805. warning("sending udp msg: %r");
  806. else {
  807. stats.qsent++;
  808. rv = 0;
  809. }
  810. }
  811. break;
  812. case Tcp:
  813. /* send via TCP & keep fd around for reply */
  814. domain = smprint("%I", udppkt);
  815. alarm(10*1000);
  816. qp->tcpfd = rv = dial(netmkaddr(domain, "tcp", "dns"), nil,
  817. conndir, &qp->tcpctlfd);
  818. alarm(0);
  819. if (qp->tcpfd < 0) {
  820. dnslog("can't dial tcp!%s!dns: %r", domain);
  821. free(domain);
  822. break;
  823. }
  824. free(domain);
  825. nci = getnetconninfo(conndir, qp->tcpfd);
  826. if (nci) {
  827. parseip(qp->tcpip, nci->rsys);
  828. freenetconninfo(nci);
  829. } else
  830. dnslog("mydnsquery: getnetconninfo failed");
  831. qp->tcpset = 1;
  832. belen[0] = len >> 8;
  833. belen[1] = len;
  834. if (write(qp->tcpfd, belen, 2) != 2 ||
  835. write(qp->tcpfd, udppkt + Udphdrsize, len) != len)
  836. warning("sending tcp msg: %r");
  837. break;
  838. default:
  839. sysfatal("mydnsquery: bad medium");
  840. }
  841. return rv;
  842. }
  843. /*
  844. * send query to all UDP destinations or one TCP destination,
  845. * taken from obuf (udp packet) header
  846. */
  847. static int
  848. xmitquery(Query *qp, int medium, int depth, uchar *obuf, int inns, int len)
  849. {
  850. int j, n;
  851. char buf[32];
  852. Dest *p;
  853. queryck(qp);
  854. if(time(nil) >= qp->req->aborttime)
  855. return -1;
  856. /*
  857. * get a nameserver address if we need one.
  858. * serveraddrs populates qp->dest.
  859. */
  860. p = qp->dest;
  861. destck(p);
  862. if (qp->ndest < 0 || qp->ndest > Maxdest)
  863. dnslog("qp->ndest %d out of range", qp->ndest);
  864. if (qp->ndest > qp->curdest - p)
  865. qp->curdest = &qp->dest[serveraddrs(qp, qp->curdest - p, depth)];
  866. destck(qp->curdest);
  867. /* no servers, punt */
  868. if (qp->curdest == qp->dest)
  869. if (cfg.straddle && cfg.inside) {
  870. /* get ips of "outside-ns-ips" */
  871. p = qp->curdest = qp->dest;
  872. for(n = 0; n < Maxdest; n++, qp->curdest++)
  873. if (setdestoutns(qp->curdest, n) < 0)
  874. break;
  875. } else {
  876. /* it's probably just a bogus domain, don't log it */
  877. // dnslog("xmitquery: %s: no nameservers", qp->dp->name);
  878. return -1;
  879. }
  880. /* send to first 'qp->ndest' destinations */
  881. j = 0;
  882. if (medium == Tcp) {
  883. j++;
  884. queryck(qp);
  885. assert(qp->dp);
  886. procsetname("tcp %sside query for %s %s", (inns? "in": "out"),
  887. qp->dp->name, rrname(qp->type, buf, sizeof buf));
  888. mydnsquery(qp, medium, obuf, len); /* sets qp->tcpip from obuf */
  889. if(debug)
  890. logsend(qp->req->id, depth, qp->tcpip, "", qp->dp->name,
  891. qp->type);
  892. } else
  893. for(; p < &qp->dest[qp->ndest] && p < qp->curdest; p++){
  894. /* skip destinations we've finished with */
  895. if(p->nx >= Maxtrans)
  896. continue;
  897. j++;
  898. /* exponential backoff of requests */
  899. if((1<<p->nx) > qp->ndest)
  900. continue;
  901. procsetname("udp %sside query to %I/%s %s %s",
  902. (inns? "in": "out"), p->a, p->s->name,
  903. qp->dp->name, rrname(qp->type, buf, sizeof buf));
  904. if(debug)
  905. logsend(qp->req->id, depth, p->a, p->s->name,
  906. qp->dp->name, qp->type);
  907. /* fill in UDP destination addr & send it */
  908. memmove(obuf, p->a, sizeof p->a);
  909. mydnsquery(qp, medium, obuf, len);
  910. p->nx++;
  911. }
  912. if(j == 0) {
  913. // dnslog("xmitquery: %s: no destinations left", qp->dp->name);
  914. return -1;
  915. }
  916. return 0;
  917. }
  918. static int lckindex[Maxlcks] = {
  919. 0, /* all others map here */
  920. Ta,
  921. Tns,
  922. Tcname,
  923. Tsoa,
  924. Tptr,
  925. Tmx,
  926. Ttxt,
  927. Taaaa,
  928. };
  929. static int
  930. qtype2lck(int qtype) /* map query type to querylck index */
  931. {
  932. int i;
  933. for (i = 1; i < nelem(lckindex); i++)
  934. if (lckindex[i] == qtype)
  935. return i;
  936. return 0;
  937. }
  938. /* is mp a cachable negative response (with Rname set)? */
  939. static int
  940. isnegrname(DNSmsg *mp)
  941. {
  942. /* TODO: could add || cfg.justforw to RHS of && */
  943. return mp->an == nil && (mp->flags & Rmask) == Rname;
  944. }
  945. static int
  946. procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
  947. {
  948. int rv;
  949. // int lcktype;
  950. char buf[32];
  951. DN *ndp;
  952. Query nquery;
  953. RR *tp, *soarr;
  954. if (mp->an == nil)
  955. stats.negans++;
  956. /* ignore any error replies */
  957. if((mp->flags & Rmask) == Rserver){
  958. stats.negserver++;
  959. freeanswers(mp);
  960. if(p != qp->curdest)
  961. p->code = Rserver;
  962. return -1;
  963. }
  964. /* ignore any bad delegations */
  965. if(mp->ns && baddelegation(mp->ns, qp->nsrp, srcip)){
  966. stats.negbaddeleg++;
  967. if(mp->an == nil){
  968. stats.negbdnoans++;
  969. freeanswers(mp);
  970. if(p != qp->curdest)
  971. p->code = Rserver;
  972. return -1;
  973. }
  974. rrfreelist(mp->ns);
  975. mp->ns = nil;
  976. }
  977. /* remove any soa's from the authority section */
  978. soarr = rrremtype(&mp->ns, Tsoa);
  979. /* incorporate answers */
  980. if(mp->an)
  981. rrattach(mp->an, (mp->flags & Fauth) != 0);
  982. if(mp->ar)
  983. rrattach(mp->ar, 0);
  984. if(mp->ns && !cfg.justforw){
  985. ndp = mp->ns->owner;
  986. rrattach(mp->ns, 0);
  987. } else {
  988. ndp = nil;
  989. rrfreelist(mp->ns);
  990. mp->ns = nil;
  991. }
  992. /* free the question */
  993. if(mp->qd) {
  994. rrfreelist(mp->qd);
  995. mp->qd = nil;
  996. }
  997. /*
  998. * Any reply from an authoritative server,
  999. * or a positive reply terminates the search.
  1000. * A negative response now also terminates the search.
  1001. */
  1002. if(mp->an != nil || (mp->flags & Fauth)){
  1003. if(isnegrname(mp))
  1004. qp->dp->respcode = Rname;
  1005. else
  1006. qp->dp->respcode = 0;
  1007. /*
  1008. * cache any negative responses, free soarr.
  1009. * negative responses need not be authoritative:
  1010. * they can legitimately come from a cache.
  1011. */
  1012. if( /* (mp->flags & Fauth) && */ mp->an == nil)
  1013. cacheneg(qp->dp, qp->type, (mp->flags & Rmask), soarr);
  1014. else
  1015. rrfreelist(soarr);
  1016. return 1;
  1017. } else if (isnegrname(mp)) {
  1018. qp->dp->respcode = Rname;
  1019. /*
  1020. * cache negative response.
  1021. * negative responses need not be authoritative:
  1022. * they can legitimately come from a cache.
  1023. */
  1024. cacheneg(qp->dp, qp->type, (mp->flags & Rmask), soarr);
  1025. return 1;
  1026. }
  1027. stats.negnorname++;
  1028. rrfreelist(soarr);
  1029. /*
  1030. * if we've been given better name servers, recurse.
  1031. * if we're a pure resolver, don't recurse, we have
  1032. * to forward to a fixed set of named servers.
  1033. */
  1034. if(!mp->ns || cfg.resolver && cfg.justforw)
  1035. return 0;
  1036. tp = rrlookup(ndp, Tns, NOneg);
  1037. if(contains(qp->nsrp, tp)){
  1038. rrfreelist(tp);
  1039. return 0;
  1040. }
  1041. procsetname("recursive query for %s %s", qp->dp->name,
  1042. rrname(qp->type, buf, sizeof buf));
  1043. /*
  1044. * we're called from udpquery, called from
  1045. * netquery, which current holds qp->dp->querylck,
  1046. * so release it now and acquire it upon return.
  1047. */
  1048. // lcktype = qtype2lck(qp->type);
  1049. // qunlock(&qp->dp->querylck[lcktype]);
  1050. queryinit(&nquery, qp->dp, qp->type, qp->req);
  1051. nquery.nsrp = tp;
  1052. rv = netquery(&nquery, depth+1);
  1053. // qlock(&qp->dp->querylck[lcktype]);
  1054. rrfreelist(tp);
  1055. querydestroy(&nquery);
  1056. return rv;
  1057. }
  1058. /*
  1059. * send a query via tcp to a single address (from ibuf's udp header)
  1060. * and read the answer(s) into mp->an.
  1061. */
  1062. static int
  1063. tcpquery(Query *qp, DNSmsg *mp, int depth, uchar *ibuf, uchar *obuf, int len,
  1064. int waitsecs, int inns, ushort req)
  1065. {
  1066. int rv = 0;
  1067. ulong endtime;
  1068. endtime = time(nil) + waitsecs;
  1069. if(endtime > qp->req->aborttime)
  1070. endtime = qp->req->aborttime;
  1071. if (0)
  1072. dnslog("%s: udp reply truncated; retrying query via tcp to %I",
  1073. qp->dp->name, qp->tcpip);
  1074. qlock(&qp->tcplock);
  1075. memmove(obuf, ibuf, IPaddrlen); /* send back to respondent */
  1076. /* sets qp->tcpip from obuf's udp header */
  1077. if (xmitquery(qp, Tcp, depth, obuf, inns, len) < 0 ||
  1078. readreply(qp, Tcp, req, ibuf, mp, endtime) < 0)
  1079. rv = -1;
  1080. if (qp->tcpfd > 0) {
  1081. hangup(qp->tcpctlfd);
  1082. close(qp->tcpctlfd);
  1083. close(qp->tcpfd);
  1084. }
  1085. qp->tcpfd = qp->tcpctlfd = -1;
  1086. qunlock(&qp->tcplock);
  1087. return rv;
  1088. }
  1089. /*
  1090. * query name servers. If the name server returns a pointer to another
  1091. * name server, recurse.
  1092. */
  1093. static int
  1094. queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, int waitsecs, int inns)
  1095. {
  1096. int ndest, len, replywaits, rv;
  1097. ushort req;
  1098. ulong endtime;
  1099. char buf[12];
  1100. uchar srcip[IPaddrlen];
  1101. Dest *p, *np, *dest;
  1102. // Dest dest[Maxdest];
  1103. /* pack request into a udp message */
  1104. req = rand();
  1105. len = mkreq(qp->dp, qp->type, obuf, Frecurse|Oquery, req);
  1106. /* no server addresses yet */
  1107. queryck(qp);
  1108. dest = emalloc(Maxdest * sizeof *dest); /* dest can't be on stack */
  1109. for (p = dest; p < dest + Maxdest; p++)
  1110. destinit(p);
  1111. qp->curdest = qp->dest = dest;
  1112. /*
  1113. * transmit udp requests and wait for answers.
  1114. * at most Maxtrans attempts to each address.
  1115. * each cycle send one more message than the previous.
  1116. * retry a query via tcp if its response is truncated.
  1117. */
  1118. for(ndest = 1; ndest < Maxdest; ndest++){
  1119. qp->ndest = ndest;
  1120. qp->tcpset = 0;
  1121. if (xmitquery(qp, Udp, depth, obuf, inns, len) < 0)
  1122. break;
  1123. endtime = time(nil) + waitsecs;
  1124. if(endtime > qp->req->aborttime)
  1125. endtime = qp->req->aborttime;
  1126. for(replywaits = 0; replywaits < ndest; replywaits++){
  1127. DNSmsg m;
  1128. procsetname("reading %sside reply from %I: %s %s from %s",
  1129. (inns? "in": "out"), obuf, qp->dp->name,
  1130. rrname(qp->type, buf, sizeof buf), qp->req->from);
  1131. /* read udp answer into m */
  1132. if (readreply(qp, Udp, req, ibuf, &m, endtime) >= 0)
  1133. memmove(srcip, ibuf, IPaddrlen);
  1134. else if (!(m.flags & Ftrunc)) {
  1135. freeanswers(&m);
  1136. break; /* timed out on this dest */
  1137. } else {
  1138. /* whoops, it was truncated! ask again via tcp */
  1139. rv = tcpquery(qp, &m, depth, ibuf, obuf, len,
  1140. waitsecs, inns, req); /* answer in m */
  1141. if (rv < 0) {
  1142. freeanswers(&m);
  1143. break; /* failed via tcp too */
  1144. }
  1145. memmove(srcip, qp->tcpip, IPaddrlen);
  1146. }
  1147. /* find responder */
  1148. // dnslog("queryns got reply from %I", srcip);
  1149. for(p = qp->dest; p < qp->curdest; p++)
  1150. if(memcmp(p->a, srcip, sizeof p->a) == 0)
  1151. break;
  1152. /* remove all addrs of responding server from list */
  1153. for(np = qp->dest; np < qp->curdest; np++)
  1154. if(np->s == p->s)
  1155. p->nx = Maxtrans;
  1156. /* free or incorporate RRs in m */
  1157. rv = procansw(qp, &m, srcip, depth, p);
  1158. if (rv > 0)
  1159. return rv;
  1160. }
  1161. }
  1162. /* if all servers returned failure, propagate it */
  1163. qp->dp->respcode = Rserver;
  1164. for(p = dest; p < qp->curdest; p++) {
  1165. destck(p);
  1166. if(p->code != Rserver)
  1167. qp->dp->respcode = 0;
  1168. p->magic = 0; /* prevent accidents */
  1169. }
  1170. // if (qp->dp->respcode)
  1171. // dnslog("queryns setting Rserver for %s", qp->dp->name);
  1172. free(qp->dest);
  1173. qp->dest = qp->curdest = nil; /* prevent accidents */
  1174. return 0;
  1175. }
  1176. /*
  1177. * run a command with a supplied fd as standard input
  1178. */
  1179. char *
  1180. system(int fd, char *cmd)
  1181. {
  1182. int pid, p, i;
  1183. static Waitmsg msg;
  1184. if((pid = fork()) == -1)
  1185. sysfatal("fork failed: %r");
  1186. else if(pid == 0){
  1187. dup(fd, 0);
  1188. close(fd);
  1189. for (i = 3; i < 200; i++)
  1190. close(i); /* don't leak fds */
  1191. execl("/bin/rc", "rc", "-c", cmd, nil);
  1192. sysfatal("exec rc: %r");
  1193. }
  1194. for(p = waitpid(); p >= 0; p = waitpid())
  1195. if(p == pid)
  1196. return msg.msg;
  1197. return "lost child";
  1198. }
  1199. /* compute wait, weighted by probability of success, with minimum */
  1200. static ulong
  1201. weight(ulong ms, unsigned pcntprob)
  1202. {
  1203. ulong wait;
  1204. wait = (ms * pcntprob) / 100;
  1205. if (wait < 1500)
  1206. wait = 1500;
  1207. return wait;
  1208. }
  1209. /*
  1210. * in principle we could use a single descriptor for a udp port
  1211. * to send all queries and receive all the answers to them,
  1212. * but we'd have to sort out the answers by dns-query id.
  1213. */
  1214. static int
  1215. udpquery(Query *qp, char *mntpt, int depth, int patient, int inns)
  1216. {
  1217. int fd, rv;
  1218. long now;
  1219. ulong pcntprob, wait, reqtm;
  1220. char *msg;
  1221. uchar *obuf, *ibuf;
  1222. static QLock mntlck;
  1223. static ulong lastmount;
  1224. /* use alloced buffers rather than ones from the stack */
  1225. // ibuf = emalloc(Maxudpin+Udphdrsize);
  1226. ibuf = emalloc(64*1024); /* max. tcp reply size */
  1227. obuf = emalloc(Maxudp+Udphdrsize);
  1228. fd = udpport(mntpt);
  1229. while (fd < 0 && cfg.straddle && strcmp(mntpt, "/net.alt") == 0) {
  1230. /* HACK: remount /net.alt */
  1231. now = time(nil);
  1232. if (now < lastmount + Remntretry)
  1233. sleep((lastmount + Remntretry - now)*1000);
  1234. qlock(&mntlck);
  1235. fd = udpport(mntpt); /* try again under lock */
  1236. if (fd < 0) {
  1237. dnslog("[%d] remounting /net.alt", getpid());
  1238. unmount(nil, "/net.alt");
  1239. msg = system(open("/dev/null", ORDWR), "outside");
  1240. lastmount = time(nil);
  1241. if (msg && *msg) {
  1242. dnslog("[%d] can't remount /net.alt: %s",
  1243. getpid(), msg);
  1244. sleep(10*1000); /* don't spin wildly */
  1245. } else
  1246. fd = udpport(mntpt);
  1247. }
  1248. qunlock(&mntlck);
  1249. }
  1250. if (fd < 0) {
  1251. dnslog("can't get udpport for %s query of name %s: %r",
  1252. mntpt, qp->dp->name);
  1253. sysfatal("out of udp conversations"); /* we're buggered */
  1254. }
  1255. /*
  1256. * Our QIP servers are busted, don't answer AAAA and
  1257. * take forever to answer CNAME if there isn't one.
  1258. * They rarely set Rname.
  1259. * make time-to-wait proportional to estimated probability of an
  1260. * RR of that type existing.
  1261. */
  1262. if (qp->type < 0 || qp->type >= nelem(likely))
  1263. pcntprob = 35; /* unpopular query type */
  1264. else
  1265. pcntprob = likely[qp->type];
  1266. reqtm = (patient? 2*Maxreqtm: Maxreqtm);
  1267. /* time for a single outgoing udp query */
  1268. wait = weight(S2MS(reqtm)/3, pcntprob);
  1269. qp->req->aborttime = time(nil) + MS2S(3*wait); /* for all udp queries */
  1270. qp->udpfd = fd;
  1271. rv = queryns(qp, depth, ibuf, obuf, MS2S(wait), inns);
  1272. close(fd);
  1273. qp->udpfd = -1;
  1274. free(obuf);
  1275. free(ibuf);
  1276. return rv;
  1277. }
  1278. /* look up (qp->dp->name,qp->type) rr in dns, via *nsrp with results in *reqp */
  1279. static int
  1280. netquery(Query *qp, int depth)
  1281. {
  1282. int lock, rv, triedin, inname, lcktype;
  1283. char buf[32];
  1284. RR *rp;
  1285. if(depth > 12) /* in a recursive loop? */
  1286. return 0;
  1287. slave(qp->req);
  1288. /*
  1289. * slave might have forked. if so, the parent process longjmped to
  1290. * req->mret; we're usually the child slave, but if there are too
  1291. * many children already, we're still the same process.
  1292. */
  1293. /*
  1294. * don't lock before call to slave so only children can block.
  1295. * just lock at top-level invocation.
  1296. */
  1297. lock = depth <= 1 && qp->req->isslave != 0;
  1298. if(lock) {
  1299. procsetname("query lock wait: %s %s from %s", qp->dp->name,
  1300. rrname(qp->type, buf, sizeof buf), qp->req->from);
  1301. /*
  1302. * don't make concurrent queries for this name.
  1303. * dozens of processes blocking here probably indicates
  1304. * an error in our dns data that causes us to not
  1305. * recognise a zone (area) as one of our own, thus
  1306. * causing us to query other nameservers.
  1307. */
  1308. lcktype = qtype2lck(qp->type);
  1309. qlock(&qp->dp->querylck[lcktype]);
  1310. } else
  1311. lcktype = 0;
  1312. procsetname("netquery: %s", qp->dp->name);
  1313. /* prepare server RR's for incremental lookup */
  1314. for(rp = qp->nsrp; rp; rp = rp->next)
  1315. rp->marker = 0;
  1316. rv = 0; /* pessimism */
  1317. triedin = 0;
  1318. /*
  1319. * normal resolvers and servers will just use mntpt for all addresses,
  1320. * even on the outside. straddling servers will use mntpt (/net)
  1321. * for inside addresses and /net.alt for outside addresses,
  1322. * thus bypassing other inside nameservers.
  1323. */
  1324. inname = insideaddr(qp->dp->name);
  1325. if (!cfg.straddle || inname) {
  1326. rv = udpquery(qp, mntpt, depth, Hurry, (cfg.inside? Inns: Outns));
  1327. triedin = 1;
  1328. }
  1329. /*
  1330. * if we're still looking, are inside, and have an outside domain,
  1331. * try it on our outside interface, if any.
  1332. */
  1333. if (rv == 0 && cfg.inside && !inname) {
  1334. if (triedin)
  1335. dnslog(
  1336. "[%d] netquery: internal nameservers failed for %s; trying external",
  1337. getpid(), qp->dp->name);
  1338. /* prepare server RR's for incremental lookup */
  1339. for(rp = qp->nsrp; rp; rp = rp->next)
  1340. rp->marker = 0;
  1341. rv = udpquery(qp, "/net.alt", depth, Patient, Outns);
  1342. }
  1343. // if (rv == 0) /* could ask /net.alt/dns directly */
  1344. // askoutdns(qp->dp, qp->type);
  1345. if(lock)
  1346. qunlock(&qp->dp->querylck[lcktype]);
  1347. return rv;
  1348. }
  1349. int
  1350. seerootns(void)
  1351. {
  1352. int rv;
  1353. char root[] = "";
  1354. Request req;
  1355. Query query;
  1356. memset(&req, 0, sizeof req);
  1357. req.isslave = 1;
  1358. req.aborttime = now + Maxreqtm;
  1359. req.from = "internal";
  1360. queryinit(&query, dnlookup(root, Cin, 1), Tns, &req);
  1361. query.nsrp = dblookup(root, Cin, Tns, 0, 0);
  1362. rv = netquery(&query, 0);
  1363. rrfreelist(query.nsrp);
  1364. querydestroy(&query);
  1365. return rv;
  1366. }