dn.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ip.h>
  4. #include <pool.h>
  5. #include <ctype.h>
  6. #include "dns.h"
  7. /*
  8. * Hash table for domain names. The hash is based only on the
  9. * first element of the domain name.
  10. */
  11. DN *ht[HTLEN];
  12. static struct
  13. {
  14. Lock;
  15. ulong names; /* names allocated */
  16. ulong oldest; /* longest we'll leave a name around */
  17. int active;
  18. int mutex;
  19. int id;
  20. } dnvars;
  21. /* names of RR types */
  22. char *rrtname[] =
  23. {
  24. [Ta] "ip",
  25. [Tns] "ns",
  26. [Tmd] "md",
  27. [Tmf] "mf",
  28. [Tcname] "cname",
  29. [Tsoa] "soa",
  30. [Tmb] "mb",
  31. [Tmg] "mg",
  32. [Tmr] "mr",
  33. [Tnull] "null",
  34. [Twks] "wks",
  35. [Tptr] "ptr",
  36. [Thinfo] "hinfo",
  37. [Tminfo] "minfo",
  38. [Tmx] "mx",
  39. [Ttxt] "txt",
  40. [Trp] "rp",
  41. [Tkey] "key",
  42. [Tcert] "cert",
  43. [Tsig] "sig",
  44. [Taaaa] "ipv6",
  45. [Tixfr] "ixfr",
  46. [Taxfr] "axfr",
  47. [Tall] "all",
  48. 0,
  49. };
  50. /* names of response codes */
  51. char *rname[] =
  52. {
  53. [Rok] "ok",
  54. [Rformat] "format error",
  55. [Rserver] "server failure",
  56. [Rname] "bad name",
  57. [Runimplimented] "unimplemented",
  58. [Rrefused] "we don't like you",
  59. };
  60. /* names of op codes */
  61. char *opname[] =
  62. {
  63. [Oquery] "query",
  64. [Oinverse] "inverse",
  65. [Ostatus] "status",
  66. };
  67. Lock dnlock;
  68. static int sencodefmt(Fmt*);
  69. /*
  70. * set up a pipe to use as a lock
  71. */
  72. void
  73. dninit(void)
  74. {
  75. fmtinstall('E', eipfmt);
  76. fmtinstall('I', eipfmt);
  77. fmtinstall('V', eipfmt);
  78. fmtinstall('R', rrfmt);
  79. fmtinstall('Q', rravfmt);
  80. fmtinstall('H', sencodefmt);
  81. dnvars.oldest = maxage;
  82. dnvars.names = 0;
  83. }
  84. /*
  85. * hash for a domain name
  86. */
  87. static ulong
  88. dnhash(char *name)
  89. {
  90. ulong hash;
  91. uchar *val = (uchar*)name;
  92. for(hash = 0; *val; val++)
  93. hash = (hash*13) + tolower(*val)-'a';
  94. return hash % HTLEN;
  95. }
  96. /*
  97. * lookup a symbol. if enter is not zero and the name is
  98. * not found, create it.
  99. */
  100. DN*
  101. dnlookup(char *name, int class, int enter)
  102. {
  103. DN **l;
  104. DN *dp;
  105. l = &ht[dnhash(name)];
  106. lock(&dnlock);
  107. for(dp = *l; dp; dp = dp->next) {
  108. assert(dp->magic == DNmagic);
  109. if(dp->class == class && cistrcmp(dp->name, name) == 0){
  110. dp->referenced = now;
  111. unlock(&dnlock);
  112. return dp;
  113. }
  114. l = &dp->next;
  115. }
  116. if(enter == 0){
  117. unlock(&dnlock);
  118. return 0;
  119. }
  120. dnvars.names++;
  121. dp = emalloc(sizeof(*dp));
  122. dp->magic = DNmagic;
  123. dp->name = estrdup(name);
  124. assert(dp->name != 0);
  125. dp->class = class;
  126. dp->rr = 0;
  127. dp->next = 0;
  128. dp->referenced = now;
  129. *l = dp;
  130. unlock(&dnlock);
  131. return dp;
  132. }
  133. /*
  134. * dump the cache
  135. */
  136. void
  137. dndump(char *file)
  138. {
  139. DN *dp;
  140. int i, fd;
  141. RR *rp;
  142. fd = open(file, OWRITE|OTRUNC);
  143. if(fd < 0)
  144. return;
  145. lock(&dnlock);
  146. for(i = 0; i < HTLEN; i++){
  147. for(dp = ht[i]; dp; dp = dp->next){
  148. fprint(fd, "%s\n", dp->name);
  149. for(rp = dp->rr; rp; rp = rp->next)
  150. fprint(fd, " %R %c%c %lud/%lud\n", rp, rp->auth?'A':'U',
  151. rp->db?'D':'N', rp->expire, rp->ttl);
  152. }
  153. }
  154. unlock(&dnlock);
  155. close(fd);
  156. }
  157. /*
  158. * purge all records
  159. */
  160. void
  161. dnpurge(void)
  162. {
  163. DN *dp;
  164. RR *rp;
  165. int i;
  166. lock(&dnlock);
  167. for(i = 0; i < HTLEN; i++)
  168. for(dp = ht[i]; dp; dp = dp->next){
  169. rp = dp->rr;
  170. dp->rr = nil;
  171. for(; rp != nil; rp = rp->next)
  172. rp->cached = 0;
  173. rrfreelist(dp->rr);
  174. }
  175. unlock(&dnlock);
  176. }
  177. /*
  178. * check the age of resource records, free any that have timed out
  179. */
  180. void
  181. dnage(DN *dp)
  182. {
  183. RR **l;
  184. RR *rp, *next;
  185. ulong diff;
  186. diff = now - dp->referenced;
  187. if(diff < Reserved)
  188. return;
  189. l = &dp->rr;
  190. for(rp = dp->rr; rp; rp = next){
  191. assert(rp->magic == RRmagic && rp->cached);
  192. next = rp->next;
  193. if(!rp->db)
  194. if(rp->expire < now || diff > dnvars.oldest){
  195. *l = next;
  196. rp->cached = 0;
  197. rrfree(rp);
  198. continue;
  199. }
  200. l = &rp->next;
  201. }
  202. }
  203. #define REF(x) if(x) x->refs++
  204. /*
  205. * our target is 4000 names cached, this should be larger on large servers
  206. */
  207. #define TARGET 4000
  208. /*
  209. * periodicly sweep for old records and remove unreferenced domain names
  210. *
  211. * only called when all other threads are locked out
  212. */
  213. void
  214. dnageall(int doit)
  215. {
  216. DN *dp, **l;
  217. int i;
  218. RR *rp;
  219. static ulong nextage;
  220. if(dnvars.names < TARGET && now < nextage && !doit){
  221. dnvars.oldest = maxage;
  222. return;
  223. }
  224. if(dnvars.names > TARGET)
  225. dnvars.oldest /= 2;
  226. nextage = now + maxage;
  227. lock(&dnlock);
  228. /* time out all old entries (and set refs to 0) */
  229. for(i = 0; i < HTLEN; i++)
  230. for(dp = ht[i]; dp; dp = dp->next){
  231. dp->refs = 0;
  232. dnage(dp);
  233. }
  234. /* mark all referenced domain names */
  235. for(i = 0; i < HTLEN; i++)
  236. for(dp = ht[i]; dp; dp = dp->next)
  237. for(rp = dp->rr; rp; rp = rp->next){
  238. REF(rp->owner);
  239. if(rp->negative){
  240. REF(rp->negsoaowner);
  241. continue;
  242. }
  243. switch(rp->type){
  244. case Thinfo:
  245. REF(rp->cpu);
  246. REF(rp->os);
  247. break;
  248. case Ttxt:
  249. REF(rp->txt);
  250. break;
  251. case Tcname:
  252. case Tmb:
  253. case Tmd:
  254. case Tmf:
  255. case Tns:
  256. REF(rp->host);
  257. break;
  258. case Tmg:
  259. case Tmr:
  260. REF(rp->mb);
  261. break;
  262. case Tminfo:
  263. REF(rp->rmb);
  264. REF(rp->mb);
  265. break;
  266. case Trp:
  267. REF(rp->rmb);
  268. REF(rp->txt);
  269. break;
  270. case Tmx:
  271. REF(rp->host);
  272. break;
  273. case Ta:
  274. case Taaaa:
  275. REF(rp->ip);
  276. break;
  277. case Tptr:
  278. REF(rp->ptr);
  279. break;
  280. case Tsoa:
  281. REF(rp->host);
  282. REF(rp->rmb);
  283. break;
  284. }
  285. }
  286. /* sweep and remove unreferenced domain names */
  287. for(i = 0; i < HTLEN; i++){
  288. l = &ht[i];
  289. for(dp = *l; dp; dp = *l){
  290. if(dp->rr == 0 && dp->refs == 0){
  291. *l = dp->next;
  292. if(dp->name)
  293. free(dp->name);
  294. dnvars.names--;
  295. free(dp);
  296. continue;
  297. }
  298. l = &dp->next;
  299. }
  300. }
  301. unlock(&dnlock);
  302. }
  303. /*
  304. * timeout all database records (used when rereading db)
  305. */
  306. void
  307. dnagedb(void)
  308. {
  309. DN *dp;
  310. int i;
  311. RR *rp;
  312. static ulong nextage;
  313. lock(&dnlock);
  314. /* time out all database entries */
  315. for(i = 0; i < HTLEN; i++)
  316. for(dp = ht[i]; dp; dp = dp->next)
  317. for(rp = dp->rr; rp; rp = rp->next)
  318. if(rp->db)
  319. rp->expire = 0;
  320. unlock(&dnlock);
  321. }
  322. /*
  323. * mark all local db records about my area as authoritative, time out any others
  324. */
  325. void
  326. dnauthdb(void)
  327. {
  328. DN *dp;
  329. int i;
  330. Area *area;
  331. RR *rp;
  332. static ulong nextage;
  333. lock(&dnlock);
  334. /* time out all database entries */
  335. for(i = 0; i < HTLEN; i++)
  336. for(dp = ht[i]; dp; dp = dp->next){
  337. area = inmyarea(dp->name);
  338. for(rp = dp->rr; rp; rp = rp->next)
  339. if(rp->db){
  340. if(area){
  341. if(rp->ttl < area->soarr->soa->minttl)
  342. rp->ttl = area->soarr->soa->minttl;
  343. rp->auth = 1;
  344. }
  345. if(rp->expire == 0){
  346. rp->db = 0;
  347. dp->referenced = now - Reserved - 1;
  348. }
  349. }
  350. }
  351. unlock(&dnlock);
  352. }
  353. /*
  354. * keep track of other processes to know if we can
  355. * garbage collect. block while garbage collecting.
  356. */
  357. int
  358. getactivity(Request *req)
  359. {
  360. int rv;
  361. lock(&dnvars);
  362. while(dnvars.mutex){
  363. unlock(&dnvars);
  364. sleep(200);
  365. lock(&dnvars);
  366. }
  367. rv = ++dnvars.active;
  368. now = time(0);
  369. req->id = ++dnvars.id;
  370. unlock(&dnvars);
  371. return rv;
  372. }
  373. void
  374. putactivity(void)
  375. {
  376. static ulong lastclean;
  377. lock(&dnvars);
  378. dnvars.active--;
  379. assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */;
  380. /*
  381. * clean out old entries and check for new db periodicly
  382. */
  383. if(dnvars.mutex || (needrefresh == 0 && dnvars.active > 0)){
  384. unlock(&dnvars);
  385. return;
  386. }
  387. /* wait till we're alone */
  388. dnvars.mutex = 1;
  389. while(dnvars.active > 0){
  390. unlock(&dnvars);
  391. sleep(100);
  392. lock(&dnvars);
  393. }
  394. unlock(&dnvars);
  395. db2cache(needrefresh);
  396. dnageall(0);
  397. /* let others back in */
  398. lastclean = now;
  399. needrefresh = 0;
  400. dnvars.mutex = 0;
  401. }
  402. /*
  403. * Attach a single resource record to a domain name.
  404. * - Avoid duplicates with already present RR's
  405. * - Chain all RR's of the same type adjacent to one another
  406. * - chain authoritative RR's ahead of non-authoritative ones
  407. */
  408. static void
  409. rrattach1(RR *new, int auth)
  410. {
  411. RR **l;
  412. RR *rp;
  413. DN *dp;
  414. assert(new->magic == RRmagic && !new->cached);
  415. if(!new->db)
  416. new->expire = new->ttl;
  417. else
  418. new->expire = now + Year;
  419. dp = new->owner;
  420. assert(dp->magic == DNmagic);
  421. new->auth |= auth;
  422. new->next = 0;
  423. /*
  424. * find first rr of the right type
  425. */
  426. l = &dp->rr;
  427. for(rp = *l; rp; rp = *l){
  428. assert(rp->magic == RRmagic && rp->cached);
  429. if(rp->type == new->type)
  430. break;
  431. l = &rp->next;
  432. }
  433. /*
  434. * negative entries replace positive entries
  435. * positive entries replace negative entries
  436. * newer entries replace older entries with the same fields
  437. */
  438. for(rp = *l; rp; rp = *l){
  439. assert(rp->magic == RRmagic && rp->cached);
  440. if(rp->type != new->type)
  441. break;
  442. if(rp->db == new->db && rp->auth == new->auth){
  443. /* negative drives out positive and vice versa */
  444. if(rp->negative != new->negative){
  445. *l = rp->next;
  446. rp->cached = 0;
  447. rrfree(rp);
  448. continue;
  449. }
  450. /* all things equal, pick the newer one */
  451. if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){
  452. /* new drives out old */
  453. if(new->ttl > rp->ttl || new->expire > rp->expire){
  454. *l = rp->next;
  455. rp->cached = 0;
  456. rrfree(rp);
  457. continue;
  458. } else {
  459. rrfree(new);
  460. return;
  461. }
  462. }
  463. /* Hack for pointer records. This makes sure
  464. * the ordering in the list reflects the ordering
  465. * received or read from the database
  466. */
  467. if(rp->type == Tptr){
  468. if(!rp->negative && !new->negative
  469. && rp->ptr->ordinal > new->ptr->ordinal)
  470. break;
  471. }
  472. }
  473. l = &rp->next;
  474. }
  475. /*
  476. * add to chain
  477. */
  478. new->cached = 1;
  479. new->next = *l;
  480. *l = new;
  481. }
  482. /*
  483. * Attach a list of resource records to a domain name.
  484. * - Avoid duplicates with already present RR's
  485. * - Chain all RR's of the same type adjacent to one another
  486. * - chain authoritative RR's ahead of non-authoritative ones
  487. * - remove any expired RR's
  488. */
  489. void
  490. rrattach(RR *rp, int auth)
  491. {
  492. RR *next;
  493. lock(&dnlock);
  494. for(; rp; rp = next){
  495. next = rp->next;
  496. rp->next = 0;
  497. /* avoid any outside spoofing */
  498. if(cachedb && !rp->db && inmyarea(rp->owner->name))
  499. rrfree(rp);
  500. else
  501. rrattach1(rp, auth);
  502. }
  503. unlock(&dnlock);
  504. }
  505. /*
  506. * allocate a resource record of a given type
  507. */
  508. RR*
  509. rralloc(int type)
  510. {
  511. RR *rp;
  512. rp = emalloc(sizeof(*rp));
  513. rp->magic = RRmagic;
  514. rp->pc = getcallerpc(&type);
  515. rp->type = type;
  516. switch(type){
  517. case Tsoa:
  518. rp->soa = emalloc(sizeof(*rp->soa));
  519. break;
  520. case Tkey:
  521. rp->key = emalloc(sizeof(*rp->key));
  522. break;
  523. case Tcert:
  524. rp->cert = emalloc(sizeof(*rp->cert));
  525. break;
  526. case Tsig:
  527. rp->sig = emalloc(sizeof(*rp->sig));
  528. break;
  529. case Tnull:
  530. rp->null = emalloc(sizeof(*rp->null));
  531. break;
  532. }
  533. rp->ttl = 0;
  534. rp->expire = 0;
  535. rp->next = 0;
  536. return rp;
  537. }
  538. /*
  539. * free a resource record and any related structs
  540. */
  541. void
  542. rrfree(RR *rp)
  543. {
  544. DN *dp;
  545. RR *nrp;
  546. assert(!rp->cached);
  547. dp = rp->owner;
  548. if(dp){
  549. assert(dp->magic == DNmagic);
  550. for(nrp = dp->rr; nrp; nrp = nrp->next)
  551. assert(nrp != rp); /* "rrfree of live rr" */;
  552. }
  553. switch(rp->type){
  554. case Tsoa:
  555. free(rp->soa);
  556. break;
  557. case Tkey:
  558. free(rp->key->data);
  559. free(rp->key);
  560. break;
  561. case Tcert:
  562. free(rp->cert->data);
  563. free(rp->cert);
  564. break;
  565. case Tsig:
  566. free(rp->sig->data);
  567. free(rp->sig);
  568. break;
  569. case Tnull:
  570. free(rp->null->data);
  571. free(rp->null);
  572. break;
  573. }
  574. free(rp);
  575. }
  576. /*
  577. * free a list of resource records and any related structs
  578. */
  579. void
  580. rrfreelist(RR *rp)
  581. {
  582. RR *next;
  583. for(; rp; rp = next){
  584. next = rp->next;
  585. rrfree(rp);
  586. }
  587. }
  588. extern RR**
  589. rrcopy(RR *rp, RR **last)
  590. {
  591. RR *nrp;
  592. SOA *soa;
  593. Key *key;
  594. Cert *cert;
  595. Sig *sig;
  596. Null *null;
  597. nrp = rralloc(rp->type);
  598. switch(rp->type){
  599. case Tsoa:
  600. soa = nrp->soa;
  601. *nrp = *rp;
  602. nrp->soa = soa;
  603. *nrp->soa = *rp->soa;
  604. break;
  605. case Tkey:
  606. key = nrp->key;
  607. *nrp = *rp;
  608. nrp->key = key;
  609. *key = *rp->key;
  610. key->data = emalloc(key->dlen);
  611. memmove(key->data, rp->key->data, rp->key->dlen);
  612. break;
  613. case Tsig:
  614. sig = nrp->sig;
  615. *nrp = *rp;
  616. nrp->sig = sig;
  617. *sig = *rp->sig;
  618. sig->data = emalloc(sig->dlen);
  619. memmove(sig->data, rp->sig->data, rp->sig->dlen);
  620. break;
  621. case Tcert:
  622. cert = nrp->cert;
  623. *nrp = *rp;
  624. nrp->cert = cert;
  625. *cert = *rp->cert;
  626. cert->data = emalloc(cert->dlen);
  627. memmove(cert->data, rp->cert->data, rp->cert->dlen);
  628. break;
  629. case Tnull:
  630. null = nrp->null;
  631. *nrp = *rp;
  632. nrp->null = null;
  633. *null = *rp->null;
  634. null->data = emalloc(null->dlen);
  635. memmove(null->data, rp->null->data, rp->null->dlen);
  636. break;
  637. default:
  638. *nrp = *rp;
  639. break;
  640. }
  641. nrp->cached = 0;
  642. nrp->next = 0;
  643. *last = nrp;
  644. return &nrp->next;
  645. }
  646. /*
  647. * lookup a resource record of a particular type and
  648. * class attached to a domain name. Return copies.
  649. *
  650. * Priority ordering is:
  651. * db authoritative
  652. * not timed out network authoritative
  653. * not timed out network unauthoritative
  654. * unauthoritative db
  655. *
  656. * if flag NOneg is set, don't return negative cached entries.
  657. * return nothing instead.
  658. */
  659. RR*
  660. rrlookup(DN *dp, int type, int flag)
  661. {
  662. RR *rp, *first, **last;
  663. assert(dp->magic == DNmagic);
  664. first = 0;
  665. last = &first;
  666. lock(&dnlock);
  667. /* try for an authoritative db entry */
  668. for(rp = dp->rr; rp; rp = rp->next){
  669. assert(rp->magic == RRmagic && rp->cached);
  670. if(rp->db)
  671. if(rp->auth)
  672. if(tsame(type, rp->type))
  673. last = rrcopy(rp, last);
  674. }
  675. if(first)
  676. goto out;
  677. /* try for an living authoritative network entry */
  678. for(rp = dp->rr; rp; rp = rp->next){
  679. if(!rp->db)
  680. if(rp->auth)
  681. if(rp->ttl + 60 > now)
  682. if(tsame(type, rp->type)){
  683. if(flag == NOneg && rp->negative)
  684. goto out;
  685. last = rrcopy(rp, last);
  686. }
  687. }
  688. if(first)
  689. goto out;
  690. /* try for an living unauthoritative network entry */
  691. for(rp = dp->rr; rp; rp = rp->next){
  692. if(!rp->db)
  693. if(rp->ttl + 60 > now)
  694. if(tsame(type, rp->type)){
  695. if(flag == NOneg && rp->negative)
  696. goto out;
  697. last = rrcopy(rp, last);
  698. }
  699. }
  700. if(first)
  701. goto out;
  702. /* try for an unauthoritative db entry */
  703. for(rp = dp->rr; rp; rp = rp->next){
  704. if(rp->db)
  705. if(tsame(type, rp->type))
  706. last = rrcopy(rp, last);
  707. }
  708. if(first)
  709. goto out;
  710. /* otherwise, settle for anything we got (except for negative caches) */
  711. for(rp = dp->rr; rp; rp = rp->next){
  712. if(tsame(type, rp->type)){
  713. if(rp->negative)
  714. goto out;
  715. last = rrcopy(rp, last);
  716. }
  717. }
  718. out:
  719. unlock(&dnlock);
  720. unique(first);
  721. return first;
  722. }
  723. /*
  724. * convert an ascii RR type name to its integer representation
  725. */
  726. int
  727. rrtype(char *atype)
  728. {
  729. int i;
  730. for(i = 0; i <= Tall; i++)
  731. if(rrtname[i] && strcmp(rrtname[i], atype) == 0)
  732. return i;
  733. // make any a synonym for all
  734. if(strcmp(atype, "any") == 0)
  735. return Tall;
  736. return atoi(atype);
  737. }
  738. /*
  739. * convert an integer RR type to it's ascii name
  740. */
  741. char*
  742. rrname(int type, char *buf, int len)
  743. {
  744. char *t;
  745. t = 0;
  746. if(type <= Tall)
  747. t = rrtname[type];
  748. if(t==0){
  749. snprint(buf, len, "%d", type);
  750. t = buf;
  751. }
  752. return t;
  753. }
  754. /*
  755. * return 0 if not a supported rr type
  756. */
  757. int
  758. rrsupported(int type)
  759. {
  760. if(type < 0 || type >Tall)
  761. return 0;
  762. return rrtname[type] != 0;
  763. }
  764. /*
  765. * compare 2 types
  766. */
  767. int
  768. tsame(int t1, int t2)
  769. {
  770. return t1 == t2 || t1 == Tall;
  771. }
  772. /*
  773. * Add resource records to a list, duplicate them if they are cached
  774. * RR's since these are shared.
  775. */
  776. RR*
  777. rrcat(RR **start, RR *rp)
  778. {
  779. RR **last;
  780. last = start;
  781. while(*last != 0)
  782. last = &(*last)->next;
  783. *last = rp;
  784. return *start;
  785. }
  786. /*
  787. * remove negative cache rr's from an rr list
  788. */
  789. RR*
  790. rrremneg(RR **l)
  791. {
  792. RR **nl, *rp;
  793. RR *first;
  794. first = nil;
  795. nl = &first;
  796. while(*l != nil){
  797. rp = *l;
  798. if(rp->negative){
  799. *l = rp->next;
  800. *nl = rp;
  801. nl = &rp->next;
  802. *nl = nil;
  803. } else
  804. l = &rp->next;
  805. }
  806. return first;
  807. }
  808. /*
  809. * remove rr's of a particular type from an rr list
  810. */
  811. RR*
  812. rrremtype(RR **l, int type)
  813. {
  814. RR **nl, *rp;
  815. RR *first;
  816. first = nil;
  817. nl = &first;
  818. while(*l != nil){
  819. rp = *l;
  820. if(rp->type == type){
  821. *l = rp->next;
  822. *nl = rp;
  823. nl = &rp->next;
  824. *nl = nil;
  825. } else
  826. l = &(*l)->next;
  827. }
  828. return first;
  829. }
  830. /*
  831. * print conversion for rr records
  832. */
  833. int
  834. rrfmt(Fmt *f)
  835. {
  836. RR *rp;
  837. char *strp;
  838. Fmt fstr;
  839. int rv;
  840. char buf[Domlen];
  841. fmtstrinit(&fstr);
  842. rp = va_arg(f->args, RR*);
  843. if(rp == 0){
  844. fmtprint(&fstr, "<null>");
  845. goto out;
  846. }
  847. fmtprint(&fstr, "%s %s", rp->owner->name,
  848. rrname(rp->type, buf, sizeof buf));
  849. if(rp->negative){
  850. fmtprint(&fstr, "\tnegative - rcode %d", rp->negrcode);
  851. goto out;
  852. }
  853. switch(rp->type){
  854. case Thinfo:
  855. fmtprint(&fstr, "\t%s %s", rp->cpu->name, rp->os->name);
  856. break;
  857. case Tcname:
  858. case Tmb:
  859. case Tmd:
  860. case Tmf:
  861. case Tns:
  862. fmtprint(&fstr, "\t%s", rp->host->name);
  863. break;
  864. case Tmg:
  865. case Tmr:
  866. fmtprint(&fstr, "\t%s", rp->mb->name);
  867. break;
  868. case Tminfo:
  869. fmtprint(&fstr, "\t%s %s", rp->mb->name, rp->rmb->name);
  870. break;
  871. case Tmx:
  872. fmtprint(&fstr, "\t%lud %s", rp->pref, rp->host->name);
  873. break;
  874. case Ta:
  875. case Taaaa:
  876. fmtprint(&fstr, "\t%s", rp->ip->name);
  877. break;
  878. case Tptr:
  879. fmtprint(&fstr, "\t%s(%lud)", rp->ptr->name, rp->ptr->ordinal);
  880. break;
  881. case Tsoa:
  882. fmtprint(&fstr, "\t%s %s %lud %lud %lud %lud %lud", rp->host->name,
  883. rp->rmb->name, rp->soa->serial, rp->soa->refresh, rp->soa->retry,
  884. rp->soa->expire, rp->soa->minttl);
  885. break;
  886. case Tnull:
  887. fmtprint(&fstr, "\t%.*H", rp->null->dlen, rp->null->data);
  888. break;
  889. case Ttxt:
  890. fmtprint(&fstr, "\t%s", rp->txt->name);
  891. break;
  892. case Trp:
  893. fmtprint(&fstr, "\t%s %s", rp->rmb->name, rp->txt->name);
  894. break;
  895. case Tkey:
  896. fmtprint(&fstr, "\t%d %d %d", rp->key->flags, rp->key->proto,
  897. rp->key->alg);
  898. break;
  899. case Tsig:
  900. fmtprint(&fstr, "\t%d %d %d %lud %lud %lud %d %s",
  901. rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl,
  902. rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name);
  903. break;
  904. case Tcert:
  905. fmtprint(&fstr, "\t%d %d %d",
  906. rp->sig->type, rp->sig->tag, rp->sig->alg);
  907. break;
  908. default:
  909. break;
  910. }
  911. out:
  912. strp = fmtstrflush(&fstr);
  913. rv = fmtstrcpy(f, strp);
  914. free(strp);
  915. return rv;
  916. }
  917. /*
  918. * print conversion for rr records in attribute value form
  919. */
  920. int
  921. rravfmt(Fmt *f)
  922. {
  923. RR *rp;
  924. char *strp;
  925. Fmt fstr;
  926. int rv;
  927. fmtstrinit(&fstr);
  928. rp = va_arg(f->args, RR*);
  929. if(rp == 0){
  930. fmtprint(&fstr, "<null>");
  931. goto out;
  932. }
  933. if(rp->type == Tptr)
  934. fmtprint(&fstr, "ptr=%s", rp->owner->name);
  935. else
  936. fmtprint(&fstr, "dom=%s", rp->owner->name);
  937. switch(rp->type){
  938. case Thinfo:
  939. fmtprint(&fstr, " cpu=%s os=%s", rp->cpu->name, rp->os->name);
  940. break;
  941. case Tcname:
  942. fmtprint(&fstr, " cname=%s", rp->host->name);
  943. break;
  944. case Tmb:
  945. case Tmd:
  946. case Tmf:
  947. fmtprint(&fstr, " mbox=%s", rp->host->name);
  948. break;
  949. case Tns:
  950. fmtprint(&fstr, " ns=%s", rp->host->name);
  951. break;
  952. case Tmg:
  953. case Tmr:
  954. fmtprint(&fstr, " mbox=%s", rp->mb->name);
  955. break;
  956. case Tminfo:
  957. fmtprint(&fstr, " mbox=%s mbox=%s", rp->mb->name, rp->rmb->name);
  958. break;
  959. case Tmx:
  960. fmtprint(&fstr, " pref=%lud mx=%s", rp->pref, rp->host->name);
  961. break;
  962. case Ta:
  963. case Taaaa:
  964. fmtprint(&fstr, " ip=%s", rp->ip->name);
  965. break;
  966. case Tptr:
  967. fmtprint(&fstr, " dom=%s", rp->ptr->name);
  968. break;
  969. case Tsoa:
  970. fmtprint(&fstr, " ns=%s mbox=%s serial=%lud refresh=%lud retry=%lud expire=%lud ttl=%lud",
  971. rp->host->name, rp->rmb->name, rp->soa->serial,
  972. rp->soa->refresh, rp->soa->retry,
  973. rp->soa->expire, rp->soa->minttl);
  974. break;
  975. case Tnull:
  976. fmtprint(&fstr, " null=%.*H", rp->null->dlen, rp->null->data);
  977. break;
  978. case Ttxt:
  979. fmtprint(&fstr, " txt=%s", rp->txt->name);
  980. break;
  981. case Trp:
  982. fmtprint(&fstr, " rp=%s txt=%s", rp->rmb->name, rp->txt->name);
  983. break;
  984. case Tkey:
  985. fmtprint(&fstr, " flags=%d proto=%d alg=%d",
  986. rp->key->flags, rp->key->proto, rp->key->alg);
  987. break;
  988. case Tsig:
  989. fmtprint(&fstr, " type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s",
  990. rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl,
  991. rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name);
  992. break;
  993. case Tcert:
  994. fmtprint(&fstr, " type=%d tag=%d alg=%d",
  995. rp->sig->type, rp->sig->tag, rp->sig->alg);
  996. break;
  997. default:
  998. break;
  999. }
  1000. out:
  1001. strp = fmtstrflush(&fstr);
  1002. rv = fmtstrcpy(f, strp);
  1003. free(strp);
  1004. return rv;
  1005. }
  1006. void
  1007. warning(char *fmt, ...)
  1008. {
  1009. char dnserr[128];
  1010. va_list arg;
  1011. va_start(arg, fmt);
  1012. vseprint(dnserr, dnserr+sizeof(dnserr), fmt, arg);
  1013. va_end(arg);
  1014. syslog(1, "dns", dnserr);
  1015. }
  1016. /*
  1017. * create a slave process to handle a request to avoid one request blocking
  1018. * another
  1019. */
  1020. void
  1021. slave(Request *req)
  1022. {
  1023. static int slaveid;
  1024. if(req->isslave)
  1025. return; /* we're already a slave process */
  1026. /* limit parallelism */
  1027. if(getactivity(req) > Maxactive){
  1028. putactivity();
  1029. return;
  1030. }
  1031. switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
  1032. case -1:
  1033. putactivity();
  1034. break;
  1035. case 0:
  1036. req->isslave = 1;
  1037. break;
  1038. default:
  1039. longjmp(req->mret, 1);
  1040. }
  1041. }
  1042. /*
  1043. * chasing down double free's
  1044. */
  1045. void
  1046. dncheck(void *p, int dolock)
  1047. {
  1048. int i;
  1049. DN *dp;
  1050. RR *rp;
  1051. extern Pool *mainmem;
  1052. if(p != nil){
  1053. dp = p;
  1054. assert(dp->magic == DNmagic);
  1055. }
  1056. if(!testing)
  1057. return;
  1058. if(dolock)
  1059. lock(&dnlock);
  1060. poolcheck(mainmem);
  1061. for(i = 0; i < HTLEN; i++)
  1062. for(dp = ht[i]; dp; dp = dp->next){
  1063. assert(dp != p);
  1064. assert(dp->magic == DNmagic);
  1065. for(rp = dp->rr; rp; rp = rp->next){
  1066. assert(rp->magic == RRmagic);
  1067. assert(rp->cached);
  1068. assert(rp->owner == dp);
  1069. }
  1070. }
  1071. if(dolock)
  1072. unlock(&dnlock);
  1073. }
  1074. static int
  1075. rrequiv(RR *r1, RR *r2)
  1076. {
  1077. return r1->owner == r2->owner
  1078. && r1->type == r2->type
  1079. && r1->arg0 == r2->arg0
  1080. && r1->arg1 == r2->arg1;
  1081. }
  1082. void
  1083. unique(RR *rp)
  1084. {
  1085. RR **l, *nrp;
  1086. for(; rp; rp = rp->next){
  1087. l = &rp->next;
  1088. for(nrp = *l; nrp; nrp = *l){
  1089. if(rrequiv(rp, nrp)){
  1090. *l = nrp->next;
  1091. rrfree(nrp);
  1092. } else
  1093. l = &nrp->next;
  1094. }
  1095. }
  1096. }
  1097. /*
  1098. * true if second domain is subsumed by the first
  1099. */
  1100. int
  1101. subsume(char *higher, char *lower)
  1102. {
  1103. int hn, ln;
  1104. ln = strlen(lower);
  1105. hn = strlen(higher);
  1106. if(ln < hn)
  1107. return 0;
  1108. if(cistrcmp(lower + ln - hn, higher) != 0)
  1109. return 0;
  1110. if(ln > hn && hn != 0 && lower[ln - hn - 1] != '.')
  1111. return 0;
  1112. return 1;
  1113. }
  1114. /*
  1115. * randomize the order we return items to provide some
  1116. * load balancing for servers.
  1117. *
  1118. * only randomize the first class of entries
  1119. */
  1120. RR*
  1121. randomize(RR *rp)
  1122. {
  1123. RR *first, *last, *x, *base;
  1124. ulong n;
  1125. if(rp == nil || rp->next == nil)
  1126. return rp;
  1127. /* just randomize addresses and mx's */
  1128. for(x = rp; x; x = x->next)
  1129. if(x->type != Ta && x->type != Tmx && x->type != Tns)
  1130. return rp;
  1131. base = rp;
  1132. n = rand();
  1133. last = first = nil;
  1134. while(rp != nil){
  1135. /* stop randomizing if we've moved past our class */
  1136. if(base->auth != rp->auth || base->db != rp->db){
  1137. last->next = rp;
  1138. break;
  1139. }
  1140. /* unchain */
  1141. x = rp;
  1142. rp = x->next;
  1143. x->next = nil;
  1144. if(n&1){
  1145. /* add to tail */
  1146. if(last == nil)
  1147. first = x;
  1148. else
  1149. last->next = x;
  1150. last = x;
  1151. } else {
  1152. /* add to head */
  1153. if(last == nil)
  1154. last = x;
  1155. x->next = first;
  1156. first = x;
  1157. }
  1158. /* reroll the dice */
  1159. n >>= 1;
  1160. }
  1161. return first;
  1162. }
  1163. static int
  1164. sencodefmt(Fmt *f)
  1165. {
  1166. char *out;
  1167. char *buf;
  1168. int i, len;
  1169. int ilen;
  1170. int rv;
  1171. uchar *b;
  1172. char obuf[64]; // rsc optimization
  1173. if(!(f->flags&FmtPrec) || f->prec < 1)
  1174. goto error;
  1175. b = va_arg(f->args, uchar*);
  1176. if(b == nil)
  1177. goto error;
  1178. /* if it's a printable, go for it */
  1179. len = f->prec;
  1180. for(i = 0; i < len; i++)
  1181. if(!isprint(b[i]))
  1182. break;
  1183. if(i == len){
  1184. if(len >= sizeof obuf)
  1185. len = sizeof(obuf)-1;
  1186. memmove(obuf, b, len);
  1187. obuf[len] = 0;
  1188. fmtstrcpy(f, obuf);
  1189. return 0;
  1190. }
  1191. ilen = f->prec;
  1192. f->prec = 0;
  1193. f->flags &= ~FmtPrec;
  1194. switch(f->r){
  1195. case '<':
  1196. len = (8*ilen+4)/5 + 3;
  1197. break;
  1198. case '[':
  1199. len = (8*ilen+5)/6 + 4;
  1200. break;
  1201. case 'H':
  1202. len = 2*ilen + 1;
  1203. break;
  1204. default:
  1205. goto error;
  1206. }
  1207. if(len > sizeof(obuf)){
  1208. buf = malloc(len);
  1209. if(buf == nil)
  1210. goto error;
  1211. } else
  1212. buf = obuf;
  1213. // convert
  1214. out = buf;
  1215. switch(f->r){
  1216. case '<':
  1217. rv = enc32(out, len, b, ilen);
  1218. break;
  1219. case '[':
  1220. rv = enc64(out, len, b, ilen);
  1221. break;
  1222. case 'H':
  1223. rv = enc16(out, len, b, ilen);
  1224. break;
  1225. default:
  1226. rv = -1;
  1227. break;
  1228. }
  1229. if(rv < 0)
  1230. goto error;
  1231. fmtstrcpy(f, buf);
  1232. if(buf != obuf)
  1233. free(buf);
  1234. return 0;
  1235. error:
  1236. return fmtstrcpy(f, "<encodefmt>");
  1237. }
  1238. void*
  1239. emalloc(int size)
  1240. {
  1241. char *x;
  1242. x = mallocz(size, 1);
  1243. if(x == nil)
  1244. abort();
  1245. return x;
  1246. }
  1247. char*
  1248. estrdup(char *s)
  1249. {
  1250. int size;
  1251. char *p;
  1252. size = strlen(s)+1;
  1253. p = mallocz(size, 0);
  1254. if(p == nil)
  1255. abort();
  1256. memmove(p, s, size);
  1257. return p;
  1258. }
  1259. /*
  1260. * create a pointer record
  1261. */
  1262. static RR*
  1263. mkptr(DN *dp, char *ptr, ulong ttl)
  1264. {
  1265. DN *ipdp;
  1266. RR *rp;
  1267. ipdp = dnlookup(ptr, Cin, 1);
  1268. rp = rralloc(Tptr);
  1269. rp->ptr = dp;
  1270. rp->owner = ipdp;
  1271. rp->db = 1;
  1272. if(ttl)
  1273. rp->ttl = ttl;
  1274. return rp;
  1275. }
  1276. /*
  1277. * look for all ip addresses in this network and make
  1278. * pointer records for them.
  1279. */
  1280. void
  1281. dnptr(uchar *net, uchar *mask, char *dom, int bytes, int ttl)
  1282. {
  1283. int i, j;
  1284. DN *dp;
  1285. RR *rp, *nrp, *first, **l;
  1286. uchar ip[IPaddrlen];
  1287. uchar nnet[IPaddrlen];
  1288. char ptr[Domlen];
  1289. char *p, *e;
  1290. syslog(0, logfile, "looking for things in %s %I %I", dom, net, mask);
  1291. l = &first;
  1292. first = nil;
  1293. for(i = 0; i < HTLEN; i++){
  1294. for(dp = ht[i]; dp; dp = dp->next){
  1295. for(rp = dp->rr; rp; rp = rp->next){
  1296. if(rp->type != Ta)
  1297. continue;
  1298. parseip(ip, rp->ip->name);
  1299. maskip(ip, mask, nnet);
  1300. if(ipcmp(net, nnet) != 0)
  1301. continue;
  1302. p = ptr;
  1303. e = ptr+sizeof(ptr);
  1304. for(j = IPaddrlen-1; j >= IPaddrlen-bytes; j--)
  1305. p = seprint(p, e, "%d.", ip[j]);
  1306. seprint(p, e, "%s", dom);
  1307. nrp = mkptr(dp, ptr, ttl);
  1308. *l = nrp;
  1309. l = &nrp->next;
  1310. }
  1311. }
  1312. }
  1313. for(rp = first; rp != nil; rp = nrp){
  1314. nrp = rp->next;
  1315. rp->next = nil;
  1316. rrattach(rp, 1);
  1317. }
  1318. }