dnresolve.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  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, '.') == nil){
  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, Authoritative);
  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, Authoritative);
  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. domain = smprint("%I", udppkt);
  791. if (myaddr(domain)) {
  792. dnslog("mydnsquery: trying to send to myself (%s); bzzzt",
  793. domain);
  794. free(domain);
  795. return rv;
  796. }
  797. switch (medium) {
  798. case Udp:
  799. free(domain);
  800. nfd = dup(qp->udpfd, -1);
  801. if (nfd < 0) {
  802. warning("mydnsquery: qp->udpfd %d: %r", qp->udpfd);
  803. close(qp->udpfd); /* ensure it's closed */
  804. qp->udpfd = -1; /* poison it */
  805. return rv;
  806. }
  807. close(nfd);
  808. if (qp->udpfd <= 0)
  809. dnslog("mydnsquery: qp->udpfd %d closed", qp->udpfd);
  810. else {
  811. if (write(qp->udpfd, udppkt, len+Udphdrsize) !=
  812. len+Udphdrsize)
  813. warning("sending udp msg: %r");
  814. else {
  815. stats.qsent++;
  816. rv = 0;
  817. }
  818. }
  819. break;
  820. case Tcp:
  821. /* send via TCP & keep fd around for reply */
  822. alarm(10*1000);
  823. qp->tcpfd = rv = dial(netmkaddr(domain, "tcp", "dns"), nil,
  824. conndir, &qp->tcpctlfd);
  825. alarm(0);
  826. if (qp->tcpfd < 0) {
  827. dnslog("can't dial tcp!%s!dns: %r", domain);
  828. free(domain);
  829. break;
  830. }
  831. free(domain);
  832. nci = getnetconninfo(conndir, qp->tcpfd);
  833. if (nci) {
  834. parseip(qp->tcpip, nci->rsys);
  835. freenetconninfo(nci);
  836. } else
  837. dnslog("mydnsquery: getnetconninfo failed");
  838. qp->tcpset = 1;
  839. belen[0] = len >> 8;
  840. belen[1] = len;
  841. if (write(qp->tcpfd, belen, 2) != 2 ||
  842. write(qp->tcpfd, udppkt + Udphdrsize, len) != len)
  843. warning("sending tcp msg: %r");
  844. break;
  845. default:
  846. sysfatal("mydnsquery: bad medium");
  847. }
  848. return rv;
  849. }
  850. /*
  851. * send query to all UDP destinations or one TCP destination,
  852. * taken from obuf (udp packet) header
  853. */
  854. static int
  855. xmitquery(Query *qp, int medium, int depth, uchar *obuf, int inns, int len)
  856. {
  857. int j, n;
  858. char buf[32];
  859. Dest *p;
  860. queryck(qp);
  861. if(time(nil) >= qp->req->aborttime)
  862. return -1;
  863. /*
  864. * get a nameserver address if we need one.
  865. * serveraddrs populates qp->dest.
  866. */
  867. p = qp->dest;
  868. destck(p);
  869. if (qp->ndest < 0 || qp->ndest > Maxdest)
  870. dnslog("qp->ndest %d out of range", qp->ndest);
  871. if (qp->ndest > qp->curdest - p)
  872. qp->curdest = &qp->dest[serveraddrs(qp, qp->curdest - p, depth)];
  873. destck(qp->curdest);
  874. /* no servers, punt */
  875. if (qp->curdest == qp->dest)
  876. if (cfg.straddle && cfg.inside) {
  877. /* get ips of "outside-ns-ips" */
  878. p = qp->curdest = qp->dest;
  879. for(n = 0; n < Maxdest; n++, qp->curdest++)
  880. if (setdestoutns(qp->curdest, n) < 0)
  881. break;
  882. } else {
  883. /* it's probably just a bogus domain, don't log it */
  884. // dnslog("xmitquery: %s: no nameservers", qp->dp->name);
  885. return -1;
  886. }
  887. /* send to first 'qp->ndest' destinations */
  888. j = 0;
  889. if (medium == Tcp) {
  890. j++;
  891. queryck(qp);
  892. assert(qp->dp);
  893. procsetname("tcp %sside query for %s %s", (inns? "in": "out"),
  894. qp->dp->name, rrname(qp->type, buf, sizeof buf));
  895. mydnsquery(qp, medium, obuf, len); /* sets qp->tcpip from obuf */
  896. if(debug)
  897. logsend(qp->req->id, depth, qp->tcpip, "", qp->dp->name,
  898. qp->type);
  899. } else
  900. for(; p < &qp->dest[qp->ndest] && p < qp->curdest; p++){
  901. /* skip destinations we've finished with */
  902. if(p->nx >= Maxtrans)
  903. continue;
  904. j++;
  905. /* exponential backoff of requests */
  906. if((1<<p->nx) > qp->ndest)
  907. continue;
  908. procsetname("udp %sside query to %I/%s %s %s",
  909. (inns? "in": "out"), p->a, p->s->name,
  910. qp->dp->name, rrname(qp->type, buf, sizeof buf));
  911. if(debug)
  912. logsend(qp->req->id, depth, p->a, p->s->name,
  913. qp->dp->name, qp->type);
  914. /* fill in UDP destination addr & send it */
  915. memmove(obuf, p->a, sizeof p->a);
  916. mydnsquery(qp, medium, obuf, len);
  917. p->nx++;
  918. }
  919. if(j == 0) {
  920. // dnslog("xmitquery: %s: no destinations left", qp->dp->name);
  921. return -1;
  922. }
  923. return 0;
  924. }
  925. static int lckindex[Maxlcks] = {
  926. 0, /* all others map here */
  927. Ta,
  928. Tns,
  929. Tcname,
  930. Tsoa,
  931. Tptr,
  932. Tmx,
  933. Ttxt,
  934. Taaaa,
  935. };
  936. static int
  937. qtype2lck(int qtype) /* map query type to querylck index */
  938. {
  939. int i;
  940. for (i = 1; i < nelem(lckindex); i++)
  941. if (lckindex[i] == qtype)
  942. return i;
  943. return 0;
  944. }
  945. /* is mp a cachable negative response (with Rname set)? */
  946. static int
  947. isnegrname(DNSmsg *mp)
  948. {
  949. /* TODO: could add || cfg.justforw to RHS of && */
  950. return mp->an == nil && (mp->flags & Rmask) == Rname;
  951. }
  952. static int
  953. procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
  954. {
  955. int rv;
  956. // int lcktype;
  957. char buf[32];
  958. DN *ndp;
  959. Query nquery;
  960. RR *tp, *soarr;
  961. if (mp->an == nil)
  962. stats.negans++;
  963. /* ignore any error replies */
  964. if((mp->flags & Rmask) == Rserver){
  965. stats.negserver++;
  966. freeanswers(mp);
  967. if(p != qp->curdest)
  968. p->code = Rserver;
  969. return -1;
  970. }
  971. /* ignore any bad delegations */
  972. if(mp->ns && baddelegation(mp->ns, qp->nsrp, srcip)){
  973. stats.negbaddeleg++;
  974. if(mp->an == nil){
  975. stats.negbdnoans++;
  976. freeanswers(mp);
  977. if(p != qp->curdest)
  978. p->code = Rserver;
  979. return -1;
  980. }
  981. rrfreelist(mp->ns);
  982. mp->ns = nil;
  983. }
  984. /* remove any soa's from the authority section */
  985. soarr = rrremtype(&mp->ns, Tsoa);
  986. /* incorporate answers */
  987. unique(mp->an);
  988. unique(mp->ns);
  989. unique(mp->ar);
  990. if(mp->an)
  991. rrattach(mp->an, (mp->flags & Fauth) != 0);
  992. if(mp->ar)
  993. rrattach(mp->ar, Notauthoritative);
  994. if(mp->ns && !cfg.justforw){
  995. ndp = mp->ns->owner;
  996. rrattach(mp->ns, Notauthoritative);
  997. } else {
  998. ndp = nil;
  999. rrfreelist(mp->ns);
  1000. mp->ns = nil;
  1001. }
  1002. /* free the question */
  1003. if(mp->qd) {
  1004. rrfreelist(mp->qd);
  1005. mp->qd = nil;
  1006. }
  1007. /*
  1008. * Any reply from an authoritative server,
  1009. * or a positive reply terminates the search.
  1010. * A negative response now also terminates the search.
  1011. */
  1012. if(mp->an != nil || (mp->flags & Fauth)){
  1013. if(isnegrname(mp))
  1014. qp->dp->respcode = Rname;
  1015. else
  1016. qp->dp->respcode = 0;
  1017. /*
  1018. * cache any negative responses, free soarr.
  1019. * negative responses need not be authoritative:
  1020. * they can legitimately come from a cache.
  1021. */
  1022. if( /* (mp->flags & Fauth) && */ mp->an == nil)
  1023. cacheneg(qp->dp, qp->type, (mp->flags & Rmask), soarr);
  1024. else
  1025. rrfreelist(soarr);
  1026. return 1;
  1027. } else if (isnegrname(mp)) {
  1028. qp->dp->respcode = Rname;
  1029. /*
  1030. * cache negative response.
  1031. * negative responses need not be authoritative:
  1032. * they can legitimately come from a cache.
  1033. */
  1034. cacheneg(qp->dp, qp->type, (mp->flags & Rmask), soarr);
  1035. return 1;
  1036. }
  1037. stats.negnorname++;
  1038. rrfreelist(soarr);
  1039. /*
  1040. * if we've been given better name servers, recurse.
  1041. * if we're a pure resolver, don't recurse, we have
  1042. * to forward to a fixed set of named servers.
  1043. */
  1044. if(!mp->ns || cfg.resolver && cfg.justforw)
  1045. return 0;
  1046. tp = rrlookup(ndp, Tns, NOneg);
  1047. if(contains(qp->nsrp, tp)){
  1048. rrfreelist(tp);
  1049. return 0;
  1050. }
  1051. procsetname("recursive query for %s %s", qp->dp->name,
  1052. rrname(qp->type, buf, sizeof buf));
  1053. /*
  1054. * we're called from udpquery, called from
  1055. * netquery, which current holds qp->dp->querylck,
  1056. * so release it now and acquire it upon return.
  1057. */
  1058. // lcktype = qtype2lck(qp->type);
  1059. // qunlock(&qp->dp->querylck[lcktype]);
  1060. queryinit(&nquery, qp->dp, qp->type, qp->req);
  1061. nquery.nsrp = tp;
  1062. rv = netquery(&nquery, depth+1);
  1063. // qlock(&qp->dp->querylck[lcktype]);
  1064. rrfreelist(tp);
  1065. querydestroy(&nquery);
  1066. return rv;
  1067. }
  1068. /*
  1069. * send a query via tcp to a single address (from ibuf's udp header)
  1070. * and read the answer(s) into mp->an.
  1071. */
  1072. static int
  1073. tcpquery(Query *qp, DNSmsg *mp, int depth, uchar *ibuf, uchar *obuf, int len,
  1074. int waitsecs, int inns, ushort req)
  1075. {
  1076. int rv = 0;
  1077. ulong endtime;
  1078. endtime = time(nil) + waitsecs;
  1079. if(endtime > qp->req->aborttime)
  1080. endtime = qp->req->aborttime;
  1081. if (0)
  1082. dnslog("%s: udp reply truncated; retrying query via tcp to %I",
  1083. qp->dp->name, qp->tcpip);
  1084. qlock(&qp->tcplock);
  1085. memmove(obuf, ibuf, IPaddrlen); /* send back to respondent */
  1086. /* sets qp->tcpip from obuf's udp header */
  1087. if (xmitquery(qp, Tcp, depth, obuf, inns, len) < 0 ||
  1088. readreply(qp, Tcp, req, ibuf, mp, endtime) < 0)
  1089. rv = -1;
  1090. if (qp->tcpfd > 0) {
  1091. hangup(qp->tcpctlfd);
  1092. close(qp->tcpctlfd);
  1093. close(qp->tcpfd);
  1094. }
  1095. qp->tcpfd = qp->tcpctlfd = -1;
  1096. qunlock(&qp->tcplock);
  1097. return rv;
  1098. }
  1099. /*
  1100. * query name servers. If the name server returns a pointer to another
  1101. * name server, recurse.
  1102. */
  1103. static int
  1104. queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, int waitsecs, int inns)
  1105. {
  1106. int ndest, len, replywaits, rv;
  1107. ushort req;
  1108. ulong endtime;
  1109. char buf[12];
  1110. uchar srcip[IPaddrlen];
  1111. Dest *p, *np, *dest;
  1112. // Dest dest[Maxdest];
  1113. /* pack request into a udp message */
  1114. req = rand();
  1115. len = mkreq(qp->dp, qp->type, obuf, Frecurse|Oquery, req);
  1116. /* no server addresses yet */
  1117. queryck(qp);
  1118. dest = emalloc(Maxdest * sizeof *dest); /* dest can't be on stack */
  1119. for (p = dest; p < dest + Maxdest; p++)
  1120. destinit(p);
  1121. qp->curdest = qp->dest = dest;
  1122. /*
  1123. * transmit udp requests and wait for answers.
  1124. * at most Maxtrans attempts to each address.
  1125. * each cycle send one more message than the previous.
  1126. * retry a query via tcp if its response is truncated.
  1127. */
  1128. for(ndest = 1; ndest < Maxdest; ndest++){
  1129. qp->ndest = ndest;
  1130. qp->tcpset = 0;
  1131. if (xmitquery(qp, Udp, depth, obuf, inns, len) < 0)
  1132. break;
  1133. endtime = time(nil) + waitsecs;
  1134. if(endtime > qp->req->aborttime)
  1135. endtime = qp->req->aborttime;
  1136. for(replywaits = 0; replywaits < ndest; replywaits++){
  1137. DNSmsg m;
  1138. procsetname("reading %sside reply from %I: %s %s from %s",
  1139. (inns? "in": "out"), obuf, qp->dp->name,
  1140. rrname(qp->type, buf, sizeof buf), qp->req->from);
  1141. /* read udp answer into m */
  1142. if (readreply(qp, Udp, req, ibuf, &m, endtime) >= 0)
  1143. memmove(srcip, ibuf, IPaddrlen);
  1144. else if (!(m.flags & Ftrunc)) {
  1145. freeanswers(&m);
  1146. break; /* timed out on this dest */
  1147. } else {
  1148. /* whoops, it was truncated! ask again via tcp */
  1149. rv = tcpquery(qp, &m, depth, ibuf, obuf, len,
  1150. waitsecs, inns, req); /* answer in m */
  1151. if (rv < 0) {
  1152. freeanswers(&m);
  1153. break; /* failed via tcp too */
  1154. }
  1155. memmove(srcip, qp->tcpip, IPaddrlen);
  1156. }
  1157. /* find responder */
  1158. // dnslog("queryns got reply from %I", srcip);
  1159. for(p = qp->dest; p < qp->curdest; p++)
  1160. if(memcmp(p->a, srcip, sizeof p->a) == 0)
  1161. break;
  1162. /* remove all addrs of responding server from list */
  1163. for(np = qp->dest; np < qp->curdest; np++)
  1164. if(np->s == p->s)
  1165. p->nx = Maxtrans;
  1166. /* free or incorporate RRs in m */
  1167. rv = procansw(qp, &m, srcip, depth, p);
  1168. if (rv > 0)
  1169. return rv;
  1170. }
  1171. }
  1172. /* if all servers returned failure, propagate it */
  1173. qp->dp->respcode = Rserver;
  1174. for(p = dest; p < qp->curdest; p++) {
  1175. destck(p);
  1176. if(p->code != Rserver)
  1177. qp->dp->respcode = 0;
  1178. p->magic = 0; /* prevent accidents */
  1179. }
  1180. // if (qp->dp->respcode)
  1181. // dnslog("queryns setting Rserver for %s", qp->dp->name);
  1182. free(qp->dest);
  1183. qp->dest = qp->curdest = nil; /* prevent accidents */
  1184. return 0;
  1185. }
  1186. /*
  1187. * run a command with a supplied fd as standard input
  1188. */
  1189. char *
  1190. system(int fd, char *cmd)
  1191. {
  1192. int pid, p, i;
  1193. static Waitmsg msg;
  1194. if((pid = fork()) == -1)
  1195. sysfatal("fork failed: %r");
  1196. else if(pid == 0){
  1197. dup(fd, 0);
  1198. close(fd);
  1199. for (i = 3; i < 200; i++)
  1200. close(i); /* don't leak fds */
  1201. execl("/bin/rc", "rc", "-c", cmd, nil);
  1202. sysfatal("exec rc: %r");
  1203. }
  1204. for(p = waitpid(); p >= 0; p = waitpid())
  1205. if(p == pid)
  1206. return msg.msg;
  1207. return "lost child";
  1208. }
  1209. /* compute wait, weighted by probability of success, with minimum */
  1210. static ulong
  1211. weight(ulong ms, unsigned pcntprob)
  1212. {
  1213. ulong wait;
  1214. wait = (ms * pcntprob) / 100;
  1215. if (wait < 1500)
  1216. wait = 1500;
  1217. return wait;
  1218. }
  1219. /*
  1220. * in principle we could use a single descriptor for a udp port
  1221. * to send all queries and receive all the answers to them,
  1222. * but we'd have to sort out the answers by dns-query id.
  1223. */
  1224. static int
  1225. udpquery(Query *qp, char *mntpt, int depth, int patient, int inns)
  1226. {
  1227. int fd, rv;
  1228. long now;
  1229. ulong pcntprob, wait, reqtm;
  1230. char *msg;
  1231. uchar *obuf, *ibuf;
  1232. static QLock mntlck;
  1233. static ulong lastmount;
  1234. /* use alloced buffers rather than ones from the stack */
  1235. // ibuf = emalloc(Maxudpin+Udphdrsize);
  1236. ibuf = emalloc(64*1024); /* max. tcp reply size */
  1237. obuf = emalloc(Maxudp+Udphdrsize);
  1238. fd = udpport(mntpt);
  1239. while (fd < 0 && cfg.straddle && strcmp(mntpt, "/net.alt") == 0) {
  1240. /* HACK: remount /net.alt */
  1241. now = time(nil);
  1242. if (now < lastmount + Remntretry)
  1243. sleep((lastmount + Remntretry - now)*1000);
  1244. qlock(&mntlck);
  1245. fd = udpport(mntpt); /* try again under lock */
  1246. if (fd < 0) {
  1247. dnslog("[%d] remounting /net.alt", getpid());
  1248. unmount(nil, "/net.alt");
  1249. msg = system(open("/dev/null", ORDWR), "outside");
  1250. lastmount = time(nil);
  1251. if (msg && *msg) {
  1252. dnslog("[%d] can't remount /net.alt: %s",
  1253. getpid(), msg);
  1254. sleep(10*1000); /* don't spin wildly */
  1255. } else
  1256. fd = udpport(mntpt);
  1257. }
  1258. qunlock(&mntlck);
  1259. }
  1260. if (fd < 0) {
  1261. dnslog("can't get udpport for %s query of name %s: %r",
  1262. mntpt, qp->dp->name);
  1263. sysfatal("out of udp conversations"); /* we're buggered */
  1264. }
  1265. /*
  1266. * Our QIP servers are busted, don't answer AAAA and
  1267. * take forever to answer CNAME if there isn't one.
  1268. * They rarely set Rname.
  1269. * make time-to-wait proportional to estimated probability of an
  1270. * RR of that type existing.
  1271. */
  1272. if (qp->type < 0 || qp->type >= nelem(likely))
  1273. pcntprob = 35; /* unpopular query type */
  1274. else
  1275. pcntprob = likely[qp->type];
  1276. reqtm = (patient? 2*Maxreqtm: Maxreqtm);
  1277. /* time for a single outgoing udp query */
  1278. wait = weight(S2MS(reqtm)/3, pcntprob);
  1279. qp->req->aborttime = time(nil) + MS2S(3*wait); /* for all udp queries */
  1280. qp->udpfd = fd;
  1281. rv = queryns(qp, depth, ibuf, obuf, MS2S(wait), inns);
  1282. close(fd);
  1283. qp->udpfd = -1;
  1284. free(obuf);
  1285. free(ibuf);
  1286. return rv;
  1287. }
  1288. /* look up (qp->dp->name,qp->type) rr in dns, via *nsrp with results in *reqp */
  1289. static int
  1290. netquery(Query *qp, int depth)
  1291. {
  1292. int lock, rv, triedin, inname, lcktype;
  1293. char buf[32];
  1294. RR *rp;
  1295. DN *dp;
  1296. if(depth > 12) /* in a recursive loop? */
  1297. return 0;
  1298. slave(qp->req);
  1299. /*
  1300. * slave might have forked. if so, the parent process longjmped to
  1301. * req->mret; we're usually the child slave, but if there are too
  1302. * many children already, we're still the same process.
  1303. */
  1304. /*
  1305. * don't lock before call to slave so only children can block.
  1306. * just lock at top-level invocation.
  1307. */
  1308. lock = depth <= 1 && qp->req->isslave != 0;
  1309. dp = qp->dp; /* ensure that it doesn't change underfoot */
  1310. if(lock) {
  1311. procsetname("query lock wait: %s %s from %s", dp->name,
  1312. rrname(qp->type, buf, sizeof buf), qp->req->from);
  1313. /*
  1314. * don't make concurrent queries for this name.
  1315. * dozens of processes blocking here probably indicates
  1316. * an error in our dns data that causes us to not
  1317. * recognise a zone (area) as one of our own, thus
  1318. * causing us to query other nameservers.
  1319. */
  1320. lcktype = qtype2lck(qp->type);
  1321. qlock(&dp->querylck[lcktype]);
  1322. } else
  1323. lcktype = 0;
  1324. procsetname("netquery: %s", dp->name);
  1325. /* prepare server RR's for incremental lookup */
  1326. for(rp = qp->nsrp; rp; rp = rp->next)
  1327. rp->marker = 0;
  1328. rv = 0; /* pessimism */
  1329. triedin = 0;
  1330. /*
  1331. * normal resolvers and servers will just use mntpt for all addresses,
  1332. * even on the outside. straddling servers will use mntpt (/net)
  1333. * for inside addresses and /net.alt for outside addresses,
  1334. * thus bypassing other inside nameservers.
  1335. */
  1336. inname = insideaddr(dp->name);
  1337. if (!cfg.straddle || inname) {
  1338. rv = udpquery(qp, mntpt, depth, Hurry, (cfg.inside? Inns: Outns));
  1339. triedin = 1;
  1340. }
  1341. /*
  1342. * if we're still looking, are inside, and have an outside domain,
  1343. * try it on our outside interface, if any.
  1344. */
  1345. if (rv == 0 && cfg.inside && !inname) {
  1346. if (triedin)
  1347. dnslog(
  1348. "[%d] netquery: internal nameservers failed for %s; trying external",
  1349. getpid(), dp->name);
  1350. /* prepare server RR's for incremental lookup */
  1351. for(rp = qp->nsrp; rp; rp = rp->next)
  1352. rp->marker = 0;
  1353. rv = udpquery(qp, "/net.alt", depth, Patient, Outns);
  1354. }
  1355. // if (rv == 0) /* could ask /net.alt/dns directly */
  1356. // askoutdns(dp, qp->type);
  1357. if(lock)
  1358. qunlock(&dp->querylck[lcktype]);
  1359. return rv;
  1360. }
  1361. int
  1362. seerootns(void)
  1363. {
  1364. int rv;
  1365. char root[] = "";
  1366. Request req;
  1367. Query query;
  1368. memset(&req, 0, sizeof req);
  1369. req.isslave = 1;
  1370. req.aborttime = now + Maxreqtm;
  1371. req.from = "internal";
  1372. queryinit(&query, dnlookup(root, Cin, 1), Tns, &req);
  1373. query.nsrp = dblookup(root, Cin, Tns, 0, 0);
  1374. rv = netquery(&query, 0);
  1375. rrfreelist(query.nsrp);
  1376. querydestroy(&query);
  1377. return rv;
  1378. }