PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/ndjbdns-1.05.4/query.c

#
C | 1271 lines | 1096 code | 151 blank | 24 comment | 332 complexity | 7bfb291080c7ec2a194203e37cce29fd MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * query.c: This file is part of the `djbdns' project, originally written
  3. * by Dr. D J Bernstein and later released under public-domain since late
  4. * December 2007 (http://cr.yp.to/distributors.html).
  5. *
  6. * Copyright (C) 2009 - 2012 Prasad J Pandit
  7. *
  8. * This program is a free software; you can redistribute it and/or modify
  9. * it under the terms of GNU General Public License as published by Free
  10. * Software Foundation; either version 2 of the license or (at your option)
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15. * of FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  16. * more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to Free Software Foundation, Inc., 51
  20. * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include "error.h"
  23. #include "roots.h"
  24. #include "log.h"
  25. #include "case.h"
  26. #include "cache.h"
  27. #include "byte.h"
  28. #include "dns.h"
  29. #include "uint64.h"
  30. #include "uint32.h"
  31. #include "uint16.h"
  32. #include "dd.h"
  33. #include "alloc.h"
  34. #include "response.h"
  35. #include "query.h"
  36. extern short debug_level;
  37. static int flagforwardonly = 0;
  38. void
  39. query_forwardonly (void)
  40. {
  41. flagforwardonly = 1;
  42. }
  43. static void
  44. cachegeneric (const char type[2], const char *d,
  45. const char *data, unsigned int datalen, uint32 ttl)
  46. {
  47. char key[257];
  48. unsigned int len = 0;
  49. len = dns_domain_length (d);
  50. if (len > 255)
  51. return;
  52. byte_copy (key, 2, type);
  53. byte_copy (key + 2, len, d);
  54. case_lowerb (key + 2, len);
  55. cache_set (key, len + 2, data, datalen, ttl);
  56. }
  57. static char save_buf[8192];
  58. static unsigned int save_ok;
  59. static unsigned int save_len;
  60. static void
  61. save_start (void)
  62. {
  63. save_ok = 1;
  64. save_len = 0;
  65. }
  66. static void
  67. save_data (const char *buf, unsigned int len)
  68. {
  69. if (!save_ok)
  70. return;
  71. if (len > (sizeof save_buf) - save_len)
  72. {
  73. save_ok = 0;
  74. return;
  75. }
  76. byte_copy (save_buf + save_len, len, buf);
  77. save_len += len;
  78. }
  79. static void
  80. save_finish (const char type[2], const char *d, uint32 ttl)
  81. {
  82. if (!save_ok)
  83. return;
  84. cachegeneric (type, d, save_buf, save_len, ttl);
  85. }
  86. static int
  87. typematch (const char rtype[2], const char qtype[2])
  88. {
  89. return byte_equal (qtype, 2, rtype) || byte_equal (qtype, 2, DNS_T_ANY);
  90. }
  91. static uint32
  92. ttlget (char buf[4])
  93. {
  94. uint32 ttl = 0;
  95. uint32_unpack_big (buf, &ttl);
  96. if (ttl > 1000000000)
  97. return 0;
  98. if (ttl > 604800)
  99. return 604800;
  100. return ttl;
  101. }
  102. static void
  103. cleanup (struct query *z)
  104. {
  105. int j = 0, k = 0;
  106. dns_transmit_free (&z->dt);
  107. for (j = 0; j < QUERY_MAXALIAS; ++j)
  108. dns_domain_free (&z->alias[j]);
  109. for (j = 0; j < QUERY_MAXLEVEL; ++j)
  110. {
  111. dns_domain_free (&z->name[j]);
  112. for (k = 0; k < QUERY_MAXNS; ++k)
  113. dns_domain_free (&z->ns[j][k]);
  114. }
  115. }
  116. static int
  117. rqa (struct query *z)
  118. {
  119. int i = 0;
  120. for (i = QUERY_MAXALIAS - 1; i >= 0; --i)
  121. {
  122. if (z->alias[i])
  123. {
  124. if (!response_query (z->alias[i], z->type, z->class))
  125. return 0;
  126. while (i > 0)
  127. {
  128. if (!response_cname (z->alias[i],
  129. z->alias[i - 1], z->aliasttl[i]))
  130. return 0;
  131. --i;
  132. }
  133. if (!response_cname (z->alias[0], z->name[0], z->aliasttl[0]))
  134. return 0;
  135. return 1;
  136. }
  137. }
  138. if (!response_query (z->name[0], z->type, z->class))
  139. return 0;
  140. return 1;
  141. }
  142. static int
  143. globalip (char *d, char ip[4])
  144. {
  145. if (dns_domain_equal (d, "\011localhost\0"))
  146. {
  147. byte_copy (ip, 4, "\177\0\0\1");
  148. return 1;
  149. }
  150. if (dd (d, "", ip) == 4)
  151. return 1;
  152. return 0;
  153. }
  154. static char *t1 = 0;
  155. static char *t2 = 0;
  156. static char *t3 = 0;
  157. static char *cname = 0;
  158. static char *referral = 0;
  159. static unsigned int *records = 0;
  160. static int
  161. smaller (char *buf, unsigned int len, unsigned int pos1, unsigned int pos2)
  162. {
  163. int r = 0;
  164. char header1[12], header2[12];
  165. unsigned int len1 = 0, len2 = 0;
  166. pos1 = dns_packet_getname (buf, len, pos1, &t1);
  167. dns_packet_copy (buf, len, pos1, header1, 10);
  168. pos2 = dns_packet_getname (buf, len, pos2, &t2);
  169. dns_packet_copy (buf, len, pos2, header2, 10);
  170. r = byte_diff (header1, 4, header2);
  171. if (r < 0)
  172. return 1;
  173. if (r > 0)
  174. return 0;
  175. len1 = dns_domain_length (t1);
  176. len2 = dns_domain_length (t2);
  177. if (len1 < len2)
  178. return 1;
  179. if (len1 > len2)
  180. return 0;
  181. r = case_diffb (t1, len1, t2);
  182. if (r < 0)
  183. return 1;
  184. if (r > 0)
  185. return 0;
  186. if (pos1 < pos2)
  187. return 1;
  188. return 0;
  189. }
  190. static int
  191. doit (struct query *z, int state)
  192. {
  193. char key[257];
  194. char misc[20], header[12];
  195. char *buf = 0, *cached = 0;
  196. const char *whichserver = 0;
  197. unsigned int rcode = 0;
  198. unsigned int posanswers = 0;
  199. unsigned int len = 0, cachedlen = 0;
  200. uint16 numanswers = 0;
  201. uint16 numauthority = 0;
  202. unsigned int posauthority = 0;
  203. uint16 numglue = 0;
  204. unsigned int posglue = 0;
  205. unsigned int pos = 0, pos2 = 0;
  206. uint16 datalen = 0;
  207. char *control = 0, *d = 0;
  208. const char *dtype = 0;
  209. unsigned int dlen = 0;
  210. int flagout = 0, flagcname = 0;
  211. int flagreferral = 0, flagsoa = 0;
  212. int i = 0, j = 0, k = 0, p = 0, q = 0;
  213. uint32 ttl = 0, soattl = 0, cnamettl = 0;
  214. errno = error_io;
  215. if (state == 1)
  216. goto HAVEPACKET;
  217. if (state == -1)
  218. {
  219. if (debug_level > 1)
  220. log_servfail (z->name[z->level]);
  221. goto SERVFAIL;
  222. }
  223. NEWNAME:
  224. if (++z->loop == 100)
  225. goto DIE;
  226. d = z->name[z->level];
  227. dtype = z->level ? DNS_T_A : z->type;
  228. dlen = dns_domain_length (d);
  229. if (globalip (d, misc))
  230. {
  231. if (z->level)
  232. {
  233. for (k = 0; k < 64; k += 4)
  234. {
  235. if (byte_equal (z->servers[z->level - 1] + k, 4, "\0\0\0\0"))
  236. {
  237. byte_copy (z->servers[z->level - 1] + k, 4, misc);
  238. break;
  239. }
  240. }
  241. goto LOWERLEVEL;
  242. }
  243. if (!rqa (z))
  244. goto DIE;
  245. if (typematch (DNS_T_A, dtype))
  246. {
  247. if (!response_rstart (d, DNS_T_A, 655360))
  248. goto DIE;
  249. if (!response_addbytes (misc, 4))
  250. goto DIE;
  251. response_rfinish (RESPONSE_ANSWER);
  252. }
  253. cleanup (z);
  254. return 1;
  255. }
  256. if (dns_domain_equal (d, "\0011\0010\0010\003127\7in-addr\4arpa\0"))
  257. {
  258. if (z->level)
  259. goto LOWERLEVEL;
  260. if (!rqa (z))
  261. goto DIE;
  262. if (typematch (DNS_T_PTR, dtype))
  263. {
  264. if (!response_rstart (d, DNS_T_PTR, 655360))
  265. goto DIE;
  266. if (!response_addname ("\011localhost\0"))
  267. goto DIE;
  268. response_rfinish (RESPONSE_ANSWER);
  269. }
  270. cleanup (z);
  271. if (debug_level > 2)
  272. log_stats ();
  273. return 1;
  274. }
  275. if (dlen <= 255)
  276. {
  277. byte_copy (key, 2, DNS_T_ANY);
  278. byte_copy (key + 2, dlen, d);
  279. case_lowerb (key + 2, dlen);
  280. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  281. if (cached)
  282. {
  283. if (debug_level > 2)
  284. log_cachednxdomain (d);
  285. goto NXDOMAIN;
  286. }
  287. byte_copy (key, 2, DNS_T_CNAME);
  288. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  289. if (cached)
  290. {
  291. if (typematch (DNS_T_CNAME, dtype))
  292. {
  293. if (debug_level > 2)
  294. log_cachedanswer (d, DNS_T_CNAME);
  295. if (!rqa (z))
  296. goto DIE;
  297. if (!response_cname (z->name[0], cached, ttl))
  298. goto DIE;
  299. cleanup (z);
  300. return 1;
  301. }
  302. if (debug_level > 2)
  303. log_cachedcname (d, cached);
  304. if (!dns_domain_copy (&cname, cached))
  305. goto DIE;
  306. goto CNAME;
  307. }
  308. if (typematch (DNS_T_NS, dtype))
  309. {
  310. byte_copy (key, 2, DNS_T_NS);
  311. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  312. if (cached && (cachedlen || byte_diff (dtype, 2, DNS_T_ANY)))
  313. {
  314. if (debug_level > 2)
  315. log_cachedanswer (d, DNS_T_NS);
  316. if (!rqa (z))
  317. goto DIE;
  318. pos = 0;
  319. while ((pos=dns_packet_getname (cached, cachedlen, pos, &t2)))
  320. {
  321. if (!response_rstart (d, DNS_T_NS, ttl))
  322. goto DIE;
  323. if (!response_addname (t2))
  324. goto DIE;
  325. response_rfinish (RESPONSE_ANSWER);
  326. }
  327. cleanup (z);
  328. return 1;
  329. }
  330. }
  331. if (typematch (DNS_T_PTR, dtype))
  332. {
  333. byte_copy (key, 2, DNS_T_PTR);
  334. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  335. if (cached && (cachedlen || byte_diff(dtype, 2, DNS_T_ANY)))
  336. {
  337. if (debug_level > 2)
  338. log_cachedanswer (d, DNS_T_PTR);
  339. if (!rqa (z))
  340. goto DIE;
  341. pos = 0;
  342. while ((pos=dns_packet_getname (cached, cachedlen, pos, &t2)))
  343. {
  344. if (!response_rstart (d, DNS_T_PTR, ttl))
  345. goto DIE;
  346. if (!response_addname (t2))
  347. goto DIE;
  348. response_rfinish (RESPONSE_ANSWER);
  349. }
  350. cleanup(z);
  351. return 1;
  352. }
  353. }
  354. if (typematch (DNS_T_MX, dtype))
  355. {
  356. byte_copy (key, 2, DNS_T_MX);
  357. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  358. if (cached && (cachedlen || byte_diff (dtype, 2, DNS_T_ANY)))
  359. {
  360. if (debug_level > 2)
  361. log_cachedanswer (d, DNS_T_MX);
  362. if (!rqa (z))
  363. goto DIE;
  364. pos = 0;
  365. while ((pos=dns_packet_copy (cached, cachedlen, pos, misc, 2)))
  366. {
  367. pos = dns_packet_getname (cached, cachedlen, pos, &t2);
  368. if (!pos)
  369. break;
  370. if (!response_rstart (d, DNS_T_MX, ttl))
  371. goto DIE;
  372. if (!response_addbytes (misc, 2))
  373. goto DIE;
  374. if (!response_addname (t2))
  375. goto DIE;
  376. response_rfinish (RESPONSE_ANSWER);
  377. }
  378. cleanup (z);
  379. return 1;
  380. }
  381. }
  382. if (typematch (DNS_T_A, dtype))
  383. {
  384. byte_copy (key,2,DNS_T_A);
  385. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  386. if (cached && (cachedlen || byte_diff (dtype, 2, DNS_T_ANY)))
  387. {
  388. if (z->level)
  389. {
  390. if (debug_level > 2)
  391. log_cachedanswer (d, DNS_T_A);
  392. while (cachedlen >= 4)
  393. {
  394. for (k = 0; k < 64; k += 4)
  395. {
  396. if (byte_equal (z->servers[z->level - 1] + k,
  397. 4, "\0\0\0\0"))
  398. {
  399. byte_copy (z->servers[z->level - 1] + k,
  400. 4, cached);
  401. break;
  402. }
  403. }
  404. cached += 4;
  405. cachedlen -= 4;
  406. }
  407. goto LOWERLEVEL;
  408. }
  409. if (debug_level > 2)
  410. log_cachedanswer (d, DNS_T_A);
  411. if (!rqa (z))
  412. goto DIE;
  413. while (cachedlen >= 4)
  414. {
  415. if (!response_rstart (d, DNS_T_A, ttl))
  416. goto DIE;
  417. if (!response_addbytes (cached, 4))
  418. goto DIE;
  419. response_rfinish (RESPONSE_ANSWER);
  420. cached += 4;
  421. cachedlen -= 4;
  422. }
  423. cleanup (z);
  424. return 1;
  425. }
  426. }
  427. if (!typematch (DNS_T_ANY, dtype)
  428. && !typematch (DNS_T_AXFR, dtype)
  429. && !typematch (DNS_T_CNAME, dtype)
  430. && !typematch (DNS_T_NS, dtype)
  431. && !typematch (DNS_T_PTR, dtype)
  432. && !typematch (DNS_T_A, dtype)
  433. && !typematch (DNS_T_MX, dtype))
  434. {
  435. byte_copy (key, 2, dtype);
  436. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  437. if (cached && (cachedlen || byte_diff (dtype, 2, DNS_T_ANY)))
  438. {
  439. if (debug_level > 2)
  440. log_cachedanswer (d, dtype);
  441. if (!rqa (z))
  442. goto DIE;
  443. while (cachedlen >= 2)
  444. {
  445. uint16_unpack_big (cached, &datalen);
  446. cached += 2;
  447. cachedlen -= 2;
  448. if (datalen > cachedlen)
  449. goto DIE;
  450. if (!response_rstart (d, dtype, ttl))
  451. goto DIE;
  452. if (!response_addbytes (cached, datalen))
  453. goto DIE;
  454. response_rfinish (RESPONSE_ANSWER);
  455. cached += datalen;
  456. cachedlen -= datalen;
  457. }
  458. cleanup (z);
  459. return 1;
  460. }
  461. }
  462. }
  463. for (;;)
  464. {
  465. if (roots (z->servers[z->level], d))
  466. {
  467. for (j = 0; j < QUERY_MAXNS; ++j)
  468. dns_domain_free (&z->ns[z->level][j]);
  469. z->control[z->level] = d;
  470. break;
  471. }
  472. if (!flagforwardonly && (z->level < 2))
  473. {
  474. if (dlen < 255)
  475. {
  476. byte_copy (key,2,DNS_T_NS);
  477. byte_copy (key + 2,dlen,d);
  478. case_lowerb (key + 2,dlen);
  479. cached = cache_get (key, dlen + 2, &cachedlen, &ttl);
  480. if (cached && cachedlen)
  481. {
  482. z->control[z->level] = d;
  483. byte_zero (z->servers[z->level],64);
  484. for (j = 0; j < QUERY_MAXNS; ++j)
  485. dns_domain_free (&z->ns[z->level][j]);
  486. j = pos = 0;
  487. pos = dns_packet_getname (cached, cachedlen, pos, &t1);
  488. while (pos)
  489. {
  490. if (debug_level > 2)
  491. log_cachedns (d, t1);
  492. if (j < QUERY_MAXNS)
  493. if (!dns_domain_copy (&z->ns[z->level][j++], t1))
  494. goto DIE;
  495. pos = dns_packet_getname (cached, cachedlen, pos, &t1);
  496. }
  497. break;
  498. }
  499. }
  500. }
  501. if (!*d)
  502. goto DIE;
  503. j = 1 + (unsigned int) (unsigned char) *d;
  504. dlen -= j;
  505. d += j;
  506. }
  507. HAVENS:
  508. for (j = 0; j < QUERY_MAXNS; ++j)
  509. {
  510. if (z->ns[z->level][j])
  511. {
  512. if (z->level + 1 < QUERY_MAXLEVEL)
  513. {
  514. int dc = dns_domain_copy (&z->name[z->level + 1],
  515. z->ns[z->level][j]);
  516. if (!dc)
  517. goto DIE;
  518. dns_domain_free (&z->ns[z->level][j]);
  519. ++z->level;
  520. goto NEWNAME;
  521. }
  522. dns_domain_free (&z->ns[z->level][j]);
  523. }
  524. }
  525. for (j = 0; j < 64; j += 4)
  526. if (byte_diff (z->servers[z->level] + j, 4, "\0\0\0\0"))
  527. break;
  528. if (j == 64)
  529. goto SERVFAIL;
  530. dns_sortip (z->servers[z->level], 64);
  531. if (z->level)
  532. {
  533. if (debug_level > 2)
  534. log_tx (z->name[z->level], DNS_T_A,
  535. z->control[z->level], z->servers[z->level],z->level);
  536. if (dns_transmit_start (&z->dt, z->servers[z->level], flagforwardonly,
  537. z->name[z->level], DNS_T_A,z->localip) == -1)
  538. goto DIE;
  539. }
  540. else
  541. {
  542. if (debug_level > 2)
  543. log_tx (z->name[0], z->type, z->control[0], z->servers[0], 0);
  544. if (dns_transmit_start (&z->dt, z->servers[0], flagforwardonly,
  545. z->name[0], z->type, z->localip) == -1)
  546. goto DIE;
  547. }
  548. return 0;
  549. LOWERLEVEL:
  550. dns_domain_free (&z->name[z->level]);
  551. for (j = 0; j < QUERY_MAXNS; ++j)
  552. dns_domain_free (&z->ns[z->level][j]);
  553. --z->level;
  554. goto HAVENS;
  555. HAVEPACKET:
  556. if (++z->loop == 100)
  557. goto DIE;
  558. buf = z->dt.packet;
  559. len = z->dt.packetlen;
  560. whichserver = z->dt.servers + 4 * z->dt.curserver;
  561. control = z->control[z->level];
  562. d = z->name[z->level];
  563. dtype = z->level ? DNS_T_A : z->type;
  564. if (!(pos = dns_packet_copy (buf, len, 0, header, 12)))
  565. goto DIE;
  566. if (!(pos = dns_packet_skipname (buf, len, pos)))
  567. goto DIE;
  568. pos += 4;
  569. posanswers = pos;
  570. uint16_unpack_big (header + 6, &numanswers);
  571. uint16_unpack_big (header + 8, &numauthority);
  572. uint16_unpack_big (header + 10, &numglue);
  573. rcode = header[3] & 15;
  574. if (rcode && (rcode != 3))
  575. goto DIE; /* impossible; see irrelevant() */
  576. flagsoa = soattl = cnamettl = 0;
  577. flagout = flagcname = flagreferral = 0;
  578. for (j = 0; j < numanswers; ++j)
  579. {
  580. pos = dns_packet_getname (buf, len, pos, &t1);
  581. if (!pos)
  582. goto DIE;
  583. pos = dns_packet_copy (buf, len, pos, header, 10);
  584. if (!pos)
  585. goto DIE;
  586. if (dns_domain_equal (t1, d))
  587. {
  588. if (byte_equal (header + 2, 2, DNS_C_IN))
  589. {
  590. /* should always be true */
  591. if (typematch (header, dtype))
  592. flagout = 1;
  593. else if (typematch (header, DNS_T_CNAME))
  594. {
  595. if (!dns_packet_getname (buf, len, pos, &cname))
  596. goto DIE;
  597. flagcname = 1;
  598. cnamettl = ttlget (header + 4);
  599. }
  600. }
  601. }
  602. uint16_unpack_big (header + 8, &datalen);
  603. pos += datalen;
  604. }
  605. posauthority = pos;
  606. for (j = 0; j < numauthority; ++j)
  607. {
  608. pos = dns_packet_getname (buf, len, pos, &t1);
  609. if (!pos)
  610. goto DIE;
  611. pos = dns_packet_copy (buf, len, pos, header, 10);
  612. if (!pos)
  613. goto DIE;
  614. if (typematch (header, DNS_T_SOA))
  615. {
  616. flagsoa = 1;
  617. soattl = ttlget (header + 4);
  618. if (soattl > 3600)
  619. soattl = 3600;
  620. }
  621. else if (typematch (header, DNS_T_NS))
  622. {
  623. flagreferral = 1;
  624. if (!dns_domain_copy (&referral, t1))
  625. goto DIE;
  626. }
  627. uint16_unpack_big (header + 8, &datalen);
  628. pos += datalen;
  629. }
  630. posglue = pos;
  631. if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
  632. {
  633. if (dns_domain_equal (referral, control)
  634. || !dns_domain_suffix (referral, control))
  635. {
  636. if (debug_level > 2)
  637. log_lame (whichserver, control, referral);
  638. byte_zero (whichserver, 4);
  639. goto HAVENS;
  640. }
  641. }
  642. if (records)
  643. {
  644. alloc_free (records);
  645. records = 0;
  646. }
  647. k = numanswers + numauthority + numglue;
  648. records = (unsigned int *) alloc (k * sizeof (unsigned int));
  649. if (!records)
  650. goto DIE;
  651. pos = posanswers;
  652. for (j = 0; j < k; ++j)
  653. {
  654. records[j] = pos;
  655. pos = dns_packet_getname (buf, len, pos, &t1);
  656. if (!pos)
  657. goto DIE;
  658. pos = dns_packet_copy (buf, len, pos, header, 10);
  659. if (!pos)
  660. goto DIE;
  661. uint16_unpack_big (header + 8, &datalen);
  662. pos += datalen;
  663. }
  664. i = j = k;
  665. while (j > 1)
  666. {
  667. if (i > 1)
  668. {
  669. --i;
  670. pos = records[i - 1];
  671. }
  672. else
  673. {
  674. pos = records[j - 1];
  675. records[j - 1] = records[i - 1];
  676. --j;
  677. }
  678. q = i;
  679. while ((p = q * 2) < j)
  680. {
  681. if (!smaller (buf, len, records[p], records[p - 1]))
  682. ++p;
  683. records[q - 1] = records[p - 1];
  684. q = p;
  685. }
  686. if (p == j)
  687. {
  688. records[q - 1] = records[p - 1];
  689. q = p;
  690. }
  691. while ((q > i) && smaller (buf, len, records[(p = q/2) - 1], pos))
  692. {
  693. records[q - 1] = records[p - 1];
  694. q = p;
  695. }
  696. records[q - 1] = pos;
  697. }
  698. i = 0;
  699. while (i < k)
  700. {
  701. char type[2];
  702. if (!(pos = dns_packet_getname (buf, len, records[i], &t1)))
  703. goto DIE;
  704. if (!(pos = dns_packet_copy (buf, len, pos, header, 10)))
  705. goto DIE;
  706. ttl = ttlget (header + 4);
  707. byte_copy (type, 2, header);
  708. if (byte_diff (header + 2, 2, DNS_C_IN))
  709. {
  710. ++i;
  711. continue;
  712. }
  713. for (j = i + 1; j < k; ++j)
  714. {
  715. pos = dns_packet_getname (buf, len, records[j], &t2);
  716. if (!pos)
  717. goto DIE;
  718. pos = dns_packet_copy (buf, len, pos, header, 10);
  719. if (!pos)
  720. goto DIE;
  721. if (!dns_domain_equal (t1, t2))
  722. break;
  723. if (byte_diff (header, 2, type))
  724. break;
  725. if (byte_diff (header + 2, 2, DNS_C_IN))
  726. break;
  727. }
  728. if (!dns_domain_suffix (t1, control))
  729. {
  730. i = j;
  731. continue;
  732. }
  733. if (!roots_same (t1, control))
  734. {
  735. i = j;
  736. continue;
  737. }
  738. if (byte_equal (type, 2, DNS_T_ANY))
  739. ;
  740. else if (byte_equal(type, 2, DNS_T_AXFR))
  741. ;
  742. else if (byte_equal (type, 2, DNS_T_SOA))
  743. {
  744. while (i < j)
  745. {
  746. pos = dns_packet_skipname (buf, len, records[i]);
  747. if (!pos)
  748. goto DIE;
  749. pos = dns_packet_getname (buf, len, pos + 10, &t2);
  750. if (!pos)
  751. goto DIE;
  752. pos = dns_packet_getname (buf, len, pos, &t3);
  753. if (!pos)
  754. goto DIE;
  755. pos = dns_packet_copy (buf, len, pos, misc, 20);
  756. if (!pos)
  757. goto DIE;
  758. if (records[i] < posauthority && debug_level > 2)
  759. log_rrsoa (whichserver, t1, t2, t3, misc, ttl);
  760. ++i;
  761. }
  762. }
  763. else if (byte_equal (type, 2, DNS_T_CNAME))
  764. {
  765. pos = dns_packet_skipname (buf, len, records[j - 1]);
  766. if (!pos)
  767. goto DIE;
  768. pos = dns_packet_getname (buf, len, pos + 10, &t2);
  769. if (!pos)
  770. goto DIE;
  771. if (debug_level > 2)
  772. log_rrcname (whichserver, t1, t2, ttl);
  773. cachegeneric (DNS_T_CNAME, t1, t2, dns_domain_length (t2), ttl);
  774. }
  775. else if (byte_equal (type, 2, DNS_T_PTR))
  776. {
  777. save_start ();
  778. while (i < j)
  779. {
  780. pos = dns_packet_skipname (buf, len, records[i]);
  781. if (!pos)
  782. goto DIE;
  783. pos = dns_packet_getname (buf, len, pos + 10, &t2);
  784. if (!pos)
  785. goto DIE;
  786. if (debug_level > 2)
  787. log_rrptr (whichserver, t1, t2, ttl);
  788. save_data (t2, dns_domain_length (t2));
  789. ++i;
  790. }
  791. save_finish (DNS_T_PTR, t1, ttl);
  792. }
  793. else if (byte_equal (type, 2, DNS_T_NS))
  794. {
  795. save_start ();
  796. while (i < j)
  797. {
  798. pos = dns_packet_skipname (buf, len, records[i]);
  799. if (!pos)
  800. goto DIE;
  801. pos = dns_packet_getname (buf, len, pos + 10, &t2);
  802. if (!pos)
  803. goto DIE;
  804. if (debug_level > 2)
  805. log_rrns (whichserver, t1, t2, ttl);
  806. save_data (t2, dns_domain_length (t2));
  807. ++i;
  808. }
  809. save_finish (DNS_T_NS, t1, ttl);
  810. }
  811. else if (byte_equal (type, 2, DNS_T_MX))
  812. {
  813. save_start ();
  814. while (i < j)
  815. {
  816. pos = dns_packet_skipname (buf, len, records[i]);
  817. if (!pos)
  818. goto DIE;
  819. pos = dns_packet_copy (buf, len, pos + 10, misc, 2);
  820. if (!pos)
  821. goto DIE;
  822. pos = dns_packet_getname (buf, len, pos, &t2);
  823. if (!pos)
  824. goto DIE;
  825. if (debug_level > 2)
  826. log_rrmx (whichserver, t1, t2, misc, ttl);
  827. save_data (misc, 2);
  828. save_data (t2, dns_domain_length (t2));
  829. ++i;
  830. }
  831. save_finish (DNS_T_MX, t1, ttl);
  832. }
  833. else if (byte_equal (type, 2, DNS_T_A))
  834. {
  835. save_start ();
  836. while (i < j)
  837. {
  838. pos = dns_packet_skipname (buf, len, records[i]);
  839. if (!pos)
  840. goto DIE;
  841. pos = dns_packet_copy (buf, len, pos, header, 10);
  842. if (!pos)
  843. goto DIE;
  844. if (byte_equal (header + 8, 2, "\0\4"))
  845. {
  846. pos = dns_packet_copy (buf, len, pos, header, 4);
  847. if (!pos)
  848. goto DIE;
  849. save_data (header, 4);
  850. if (debug_level > 2)
  851. log_rr (whichserver, t1, DNS_T_A, header, 4, ttl);
  852. }
  853. ++i;
  854. }
  855. save_finish (DNS_T_A, t1, ttl);
  856. }
  857. else
  858. {
  859. save_start ();
  860. while (i < j)
  861. {
  862. pos = dns_packet_skipname (buf, len, records[i]);
  863. if (!pos)
  864. goto DIE;
  865. pos = dns_packet_copy (buf, len, pos, header, 10);
  866. if (!pos)
  867. goto DIE;
  868. uint16_unpack_big (header + 8, &datalen);
  869. if (datalen > len - pos)
  870. goto DIE;
  871. save_data (header + 8, 2);
  872. save_data (buf + pos, datalen);
  873. if (debug_level > 2)
  874. log_rr (whichserver, t1, type, buf + pos, datalen, ttl);
  875. ++i;
  876. }
  877. save_finish (type, t1, ttl);
  878. }
  879. i = j;
  880. }
  881. alloc_free (records);
  882. records = 0;
  883. if (flagcname)
  884. {
  885. ttl = cnamettl;
  886. CNAME:
  887. if (!z->level)
  888. {
  889. if (z->alias[QUERY_MAXALIAS - 1])
  890. goto DIE;
  891. for (j = QUERY_MAXALIAS - 1; j > 0; --j)
  892. z->alias[j] = z->alias[j - 1];
  893. for (j = QUERY_MAXALIAS - 1; j > 0; --j)
  894. z->aliasttl[j] = z->aliasttl[j - 1];
  895. z->alias[0] = z->name[0];
  896. z->aliasttl[0] = ttl;
  897. z->name[0] = 0;
  898. }
  899. if (!dns_domain_copy (&z->name[z->level], cname))
  900. goto DIE;
  901. goto NEWNAME;
  902. }
  903. if (rcode == 3)
  904. {
  905. if (debug_level > 2)
  906. log_nxdomain (whichserver, d, soattl);
  907. cachegeneric (DNS_T_ANY, d, "", 0, soattl);
  908. NXDOMAIN:
  909. if (z->level)
  910. goto LOWERLEVEL;
  911. if (!rqa (z))
  912. goto DIE;
  913. response_nxdomain ();
  914. cleanup (z);
  915. return 1;
  916. }
  917. if (!flagout && flagsoa)
  918. if (byte_diff (DNS_T_ANY, 2, dtype))
  919. if (byte_diff (DNS_T_AXFR, 2, dtype))
  920. if (byte_diff (DNS_T_CNAME, 2, dtype))
  921. {
  922. save_start ();
  923. save_finish (dtype, d, soattl);
  924. if (debug_level > 2)
  925. log_nodata (whichserver, d, dtype, soattl);
  926. }
  927. if (debug_level > 2)
  928. log_stats ();
  929. if (flagout || flagsoa || !flagreferral)
  930. {
  931. if (z->level)
  932. {
  933. pos = posanswers;
  934. for (j = 0; j < numanswers; ++j)
  935. {
  936. pos = dns_packet_getname (buf, len, pos, &t1);
  937. if (!pos)
  938. goto DIE;
  939. pos = dns_packet_copy (buf, len, pos, header, 10);
  940. if (!pos)
  941. goto DIE;
  942. uint16_unpack_big (header + 8, &datalen);
  943. if (dns_domain_equal (t1, d))
  944. if (typematch (header, DNS_T_A))
  945. if (byte_equal (header + 2, 2, DNS_C_IN))
  946. /* should always be true */
  947. if (datalen == 4)
  948. for (k = 0; k < 64; k += 4)
  949. {
  950. if (byte_equal (z->servers[z->level - 1]
  951. + k, 4, "\0\0\0\0"))
  952. {
  953. if (!dns_packet_copy (buf, len, pos,
  954. z->servers[z->level - 1] + k, 4))
  955. goto DIE;
  956. break;
  957. }
  958. }
  959. pos += datalen;
  960. }
  961. goto LOWERLEVEL;
  962. }
  963. if (!rqa (z))
  964. goto DIE;
  965. pos = posanswers;
  966. for (j = 0; j < numanswers; ++j)
  967. {
  968. pos = dns_packet_getname (buf, len, pos, &t1);
  969. if (!pos)
  970. goto DIE;
  971. pos = dns_packet_copy (buf, len, pos, header, 10);
  972. if (!pos)
  973. goto DIE;
  974. ttl = ttlget (header + 4);
  975. uint16_unpack_big (header + 8, &datalen);
  976. if (dns_domain_equal (t1, d))
  977. {
  978. if (byte_equal (header + 2, 2, DNS_C_IN))
  979. { /* should always be true */
  980. if (typematch (header, dtype))
  981. {
  982. if (!response_rstart (t1, header, ttl))
  983. goto DIE;
  984. if (typematch (header, DNS_T_NS)
  985. || typematch (header, DNS_T_CNAME)
  986. || typematch (header, DNS_T_PTR))
  987. {
  988. if (!dns_packet_getname (buf, len, pos, &t2))
  989. goto DIE;
  990. if (!response_addname (t2))
  991. goto DIE;
  992. }
  993. else if (typematch (header, DNS_T_MX))
  994. {
  995. pos2 = dns_packet_copy (buf, len, pos, misc, 2);
  996. if (!pos2)
  997. goto DIE;
  998. if (!response_addbytes (misc, 2))
  999. goto DIE;
  1000. if (!dns_packet_getname (buf, len, pos2, &t2))
  1001. goto DIE;
  1002. if (!response_addname (t2))
  1003. goto DIE;
  1004. }
  1005. else if (typematch (header, DNS_T_SOA))
  1006. {
  1007. pos2 = dns_packet_getname (buf, len, pos, &t2);
  1008. if (!pos2)
  1009. goto DIE;
  1010. if (!response_addname (t2))
  1011. goto DIE;
  1012. pos2 = dns_packet_getname (buf, len, pos2, &t3);
  1013. if (!pos2)
  1014. goto DIE;
  1015. if (!response_addname (t3))
  1016. goto DIE;
  1017. pos2 = dns_packet_copy (buf, len, pos2, misc, 20);
  1018. if (!pos2)
  1019. goto DIE;
  1020. if (!response_addbytes (misc, 20))
  1021. goto DIE;
  1022. }
  1023. else
  1024. {
  1025. if (pos + datalen > len)
  1026. goto DIE;
  1027. if (!response_addbytes (buf + pos, datalen))
  1028. goto DIE;
  1029. }
  1030. response_rfinish(RESPONSE_ANSWER);
  1031. }
  1032. }
  1033. }
  1034. pos += datalen;
  1035. }
  1036. cleanup (z);
  1037. return 1;
  1038. }
  1039. if (!dns_domain_suffix (d, referral))
  1040. goto DIE;
  1041. control = d + dns_domain_suffixpos (d, referral);
  1042. z->control[z->level] = control;
  1043. byte_zero (z->servers[z->level], 64);
  1044. for (j = 0; j < QUERY_MAXNS; ++j)
  1045. dns_domain_free (&z->ns[z->level][j]);
  1046. k = 0;
  1047. pos = posauthority;
  1048. for (j = 0; j < numauthority; ++j)
  1049. {
  1050. pos = dns_packet_getname (buf, len, pos, &t1);
  1051. if (!pos)
  1052. goto DIE;
  1053. pos = dns_packet_copy (buf, len, pos, header, 10);
  1054. if (!pos)
  1055. goto DIE;
  1056. uint16_unpack_big (header + 8, &datalen);
  1057. if (dns_domain_equal (referral, t1)) /* should always be true */
  1058. if (typematch (header, DNS_T_NS)) /* should always be true */
  1059. /* should always be true */
  1060. if (byte_equal (header + 2, 2, DNS_C_IN))
  1061. if (k < QUERY_MAXNS)
  1062. if (!dns_packet_getname (buf, len, pos,
  1063. &z->ns[z->level][k++]))
  1064. goto DIE;
  1065. pos += datalen;
  1066. }
  1067. goto HAVENS;
  1068. SERVFAIL:
  1069. if (z->level)
  1070. goto LOWERLEVEL;
  1071. if (!rqa (z))
  1072. goto DIE;
  1073. response_servfail ();
  1074. cleanup (z);
  1075. return 1;
  1076. DIE:
  1077. cleanup (z);
  1078. if (records)
  1079. {
  1080. alloc_free (records);
  1081. records = 0;
  1082. }
  1083. return -1;
  1084. }
  1085. int
  1086. query_start (struct query *z, char *dn, char type[2],
  1087. char class[2], char localip[4])
  1088. {
  1089. if (byte_equal (type, 2, DNS_T_AXFR))
  1090. {
  1091. errno = error_perm;
  1092. return -1;
  1093. }
  1094. cleanup (z);
  1095. z->level = 0;
  1096. z->loop = 0;
  1097. if (!dns_domain_copy (&z->name[0], dn))
  1098. return -1;
  1099. byte_copy (z->type, 2, type);
  1100. byte_copy (z->class, 2, class);
  1101. byte_copy (z->localip, 4, localip);
  1102. return doit (z, 0);
  1103. }
  1104. int
  1105. query_get (struct query *z, iopause_fd *x, struct taia *stamp)
  1106. {
  1107. switch (dns_transmit_get (&z->dt, x, stamp))
  1108. {
  1109. case 1:
  1110. return doit (z, 1);
  1111. case -1:
  1112. return doit (z, -1);
  1113. }
  1114. return 0;
  1115. }
  1116. void
  1117. query_io (struct query *z, iopause_fd *x, struct taia *deadline)
  1118. {
  1119. dns_transmit_io (&z->dt, x, deadline);
  1120. }