adns.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. #include "common.h"
  2. #include "adns.h"
  3. #include "egg_timer.h"
  4. #include "main.h"
  5. #include "net.h"
  6. #include "socket.h"
  7. #include <netinet/in.h>
  8. #include <sys/socket.h>
  9. #include <arpa/inet.h>
  10. typedef struct {
  11. char **list;
  12. int len;
  13. } dns_answer_t;
  14. typedef struct dns_query {
  15. struct dns_query *next;
  16. dns_answer_t answer;
  17. dns_callback_t callback;
  18. time_t time;
  19. int id;
  20. int timer_id;
  21. int remaining;
  22. char *query;
  23. void *client_data;
  24. } dns_query_t;
  25. typedef struct {
  26. unsigned short id;
  27. unsigned short flags;
  28. unsigned short question_count;
  29. unsigned short answer_count;
  30. unsigned short ns_count;
  31. unsigned short ar_count;
  32. } dns_header_t;
  33. typedef struct {
  34. /* char name[]; */
  35. unsigned short type;
  36. unsigned short dclass;
  37. int ttl;
  38. unsigned short rdlength;
  39. /* char rdata[]; */
  40. } dns_rr_t;
  41. /* Entries from resolv.conf */
  42. typedef struct dns_server {
  43. char *ip;
  44. int idx;
  45. } dns_server_t;
  46. /* Entries from hosts */
  47. typedef struct {
  48. char *host;
  49. char *ip;
  50. } dns_host_t;
  51. typedef struct {
  52. dns_answer_t answer;
  53. char *query;
  54. time_t expiretime;
  55. } dns_cache_t;
  56. static int query_id = 1;
  57. static dns_header_t _dns_header = {0, 0, 0, 0, 0, 0};
  58. static dns_query_t *query_head = NULL;
  59. static dns_host_t *hosts = NULL;
  60. static int nhosts = 0;
  61. static dns_cache_t *cache = NULL;
  62. static int ncache = 0;
  63. static dns_server_t *servers = NULL;
  64. static int nservers = 0;
  65. static int cur_server = -1;
  66. static char separators[] = " ,\t\r\n";
  67. int dns_idx = -1;
  68. int dns_sock = -1;
  69. const char *dns_ip = NULL;
  70. static int make_header(char *buf, int id);
  71. static int cut_host(const char *host, char *query);
  72. static int reverse_ip(const char *host, char *reverse);
  73. static void read_resolv(char *fname);
  74. static void read_hosts(char *fname);
  75. static int get_dns_idx();
  76. static int cache_find(const char *);
  77. //static int dns_on_read(void *client_data, int idx, char *buf, int len);
  78. //static int dns_on_eof(void *client_data, int idx, int err, const char *errmsg);
  79. static void dns_on_read(int idx, char *buf, int atr);
  80. static void dns_on_eof(int idx);
  81. static const char *dns_next_server();
  82. static void parse_reply(char *response, int nbytes);
  83. time_t async_resolve_timeout = 30;
  84. static void
  85. dns_display(int idx, char *buf)
  86. {
  87. sprintf(buf, "adns waited %lis", now - dcc[idx].timeval);
  88. }
  89. static void
  90. dns_reinit(int idx)
  91. {
  92. sdprintf("Re-opening dns socket...");
  93. killsock(dcc[idx].sock);
  94. lostdcc(idx);
  95. dns_idx = -1;
  96. dns_sock = -1;
  97. dns_ip = NULL;
  98. if (!get_dns_idx())
  99. sdprintf("Successfully reopened dns socket");
  100. else
  101. sdprintf("Failed to reopen dns socket");
  102. }
  103. static void
  104. dns_timeout(int idx)
  105. {
  106. sdprintf("DNS socket timed out");
  107. /*egg_dns_cancel(dcc[idx].u.dns_id, 1);*/
  108. dns_reinit(idx);
  109. }
  110. static struct dcc_table dns_handler = {
  111. "adns",
  112. DCT_VALIDIDX,
  113. dns_on_eof,
  114. dns_on_read,
  115. &async_resolve_timeout,
  116. dns_timeout,
  117. dns_display,
  118. NULL,
  119. NULL,
  120. NULL,
  121. };
  122. static void async_timeout(void *client_data)
  123. {
  124. int id = (int) client_data;
  125. dns_query_t *q = NULL;
  126. for (q = query_head; q; q = q->next)
  127. if (q->id == id) break;
  128. if (!q) return;
  129. sdprintf("%s failed!", q->query);
  130. }
  131. static void answer_init(dns_answer_t *answer)
  132. {
  133. memset(answer, 0, sizeof(*answer));
  134. }
  135. static void answer_add(dns_answer_t *answer, const char *what)
  136. {
  137. answer->list = (char **) realloc(answer->list, sizeof(*answer->list) * (answer->len+2));
  138. answer->list[answer->len] = strdup(what);
  139. answer->len++;
  140. answer->list[answer->len] = NULL;
  141. }
  142. static void answer_free(dns_answer_t *answer)
  143. {
  144. int i;
  145. for (i = 0; i < answer->len; i++) free(answer->list[i]);
  146. if (answer->list) free(answer->list);
  147. }
  148. static dns_query_t *alloc_query(void *client_data, dns_callback_t callback, const char *query)
  149. {
  150. dns_query_t *q = (dns_query_t *) calloc(1, sizeof(*q));
  151. q->id = query_id;
  152. query_id++;
  153. q->query = strdup(query);
  154. q->callback = callback;
  155. q->client_data = client_data;
  156. q->time = now;
  157. q->next = query_head;
  158. query_head = q;
  159. return q;
  160. }
  161. static int get_dns_idx()
  162. {
  163. int i, sock;
  164. sock = -1;
  165. for (i = 0; i < nservers; i++) {
  166. if (!dns_ip) dns_ip = dns_next_server();
  167. sock = socket_create(dns_ip, DNS_PORT, NULL, 0, SOCKET_CLIENT | SOCKET_NONBLOCK | SOCKET_UDP);
  168. if (sock < 0) {
  169. /* Try the next server. */
  170. dns_ip = NULL;
  171. }
  172. else break;
  173. }
  174. if (i == nservers) return 1;
  175. // dns_idx = sockbuf_new();
  176. // sockbuf_set_handler(dns_idx, &dns_handler, NULL);
  177. // sockbuf_set_sock(dns_idx, sock, 0);
  178. // allocsock(sock, SOCK_CONNECT);
  179. dns_idx = new_dcc(&dns_handler, 0);
  180. sdprintf("dns_idx: %d", dns_idx);
  181. dcc[dns_idx].sock = sock;
  182. dns_sock = sock;
  183. sdprintf("dns_sock: %d", dcc[dns_idx].sock);
  184. strcpy(dcc[dns_idx].nick, "(new_dns)");
  185. sdprintf("dns_ip: %s", dns_ip);
  186. dcc[dns_idx].timeval = now;
  187. dns_handler.timeout_val = 0;
  188. return 0;
  189. }
  190. void egg_dns_send(char *query, int len)
  191. {
  192. if (dns_idx < 0) {
  193. if (get_dns_idx()) {
  194. sdprintf("get_dns_idx() failed in egg_dns_send");
  195. return;
  196. }
  197. }
  198. dns_handler.timeout_val = &async_resolve_timeout;
  199. dcc[dns_idx].timeval = now;
  200. write(dcc[dns_idx].sock, query, len);
  201. // sockbuf_write(dns_idx, query, len);
  202. }
  203. /* Perform an async dns lookup. This is host -> ip. For ip -> host, use
  204. * egg_dns_reverse(). We return a dns id that you can use to cancel the
  205. * lookup. */
  206. int egg_dns_lookup(const char *host, int timeout, dns_callback_t callback, void *client_data)
  207. {
  208. char buf[512] = "";
  209. dns_query_t *q = NULL;
  210. int i, len, cache_id;
  211. if (is_dotted_ip(host)) {
  212. /* If it's already an ip, we're done. */
  213. dns_answer_t answer;
  214. answer_init(&answer);
  215. answer_add(&answer, host);
  216. callback(client_data, host, answer.list);
  217. answer_free(&answer);
  218. return(-1);
  219. }
  220. /* Ok, now see if it's in our host cache. */
  221. for (i = 0; i < nhosts; i++) {
  222. if (!strcasecmp(host, hosts[i].host)) {
  223. dns_answer_t answer;
  224. answer_init(&answer);
  225. answer_add(&answer, hosts[i].ip);
  226. callback(client_data, host, answer.list);
  227. answer_free(&answer);
  228. return(-1);
  229. }
  230. }
  231. cache_id = cache_find(host);
  232. if (cache_id >= 0) {
  233. callback(client_data, host, cache[cache_id].answer.list);
  234. return(-1);
  235. }
  236. /* Allocate our query struct. */
  237. q = alloc_query(client_data, callback, host);
  238. /* setup a timer to detect dead ns */
  239. // egg_timeval_t howlong;
  240. // howlong.sec = async_resolve_timeout;
  241. // howlong.usec = 0;
  242. // q->timer_id = timer_create_complex(&howlong, host, (Function) async_timeout, (void *) q->id, 0);
  243. /* Send the ipv4 query. */
  244. q->remaining = 1;
  245. len = make_header(buf, q->id);
  246. len += cut_host(host, buf + len);
  247. buf[len] = 0; len++; buf[len] = 1; len++;
  248. buf[len] = 0; len++; buf[len] = 1; len++;
  249. egg_dns_send(buf, len);
  250. #ifdef USE_IPV6
  251. /* Now send the ipv6 query. */
  252. q->remaining++;
  253. len = make_header(buf, q->id);
  254. len += cut_host(host, buf + len);
  255. buf[len] = 0; len++; buf[len] = 28; len++;
  256. buf[len] = 0; len++; buf[len] = 1; len++;
  257. egg_dns_send(buf, len);
  258. #endif
  259. return(q->id);
  260. }
  261. /* Perform an async dns reverse lookup. This does ip -> host. For host -> ip
  262. * use egg_dns_lookup(). We return a dns id that you can use to cancel the
  263. * lookup. */
  264. int egg_dns_reverse(const char *ip, int timeout, dns_callback_t callback, void *client_data)
  265. {
  266. dns_query_t *q;
  267. char buf[512], *reversed_ip;
  268. int i, len, cache_id;
  269. if (!is_dotted_ip(ip)) {
  270. /* If it's not a valid ip, don't even make the request. */
  271. callback(client_data, ip, NULL);
  272. return(-1);
  273. }
  274. /* Ok, see if we have it in our host cache. */
  275. for (i = 0; i < nhosts; i++) {
  276. if (!strcasecmp(hosts[i].ip, ip)) {
  277. dns_answer_t answer;
  278. answer_init(&answer);
  279. answer_add(&answer, hosts[i].host);
  280. callback(client_data, ip, answer.list);
  281. answer_free(&answer);
  282. return(-1);
  283. }
  284. }
  285. cache_id = cache_find(ip);
  286. if (cache_id >= 0) {
  287. callback(client_data, ip, cache[cache_id].answer.list);
  288. return(-1);
  289. }
  290. /* We need to transform the ip address into the proper form
  291. * for reverse lookup. */
  292. if (strchr(ip, ':')) {
  293. char temp[65];
  294. socket_ipv6_to_dots(ip, temp);
  295. reversed_ip = (char *) malloc(strlen(temp) + 10);
  296. reverse_ip(temp, reversed_ip);
  297. strcat(reversed_ip, ".in6.arpa");
  298. }
  299. else {
  300. reversed_ip = (char *) malloc(strlen(ip) + 14);
  301. reverse_ip(ip, reversed_ip);
  302. strcat(reversed_ip, ".in-addr.arpa");
  303. }
  304. len = make_header(buf, query_id);
  305. len += cut_host(reversed_ip, buf + len);
  306. buf[len] = 0; len++; buf[len] = 12; len++;
  307. buf[len] = 0; len++; buf[len] = 1; len++;
  308. free(reversed_ip);
  309. q = alloc_query(client_data, callback, ip);
  310. egg_dns_send(buf, len);
  311. return(q->id);
  312. }
  313. //static int dns_on_read(void *client_data, int idx, char *buf, int len)
  314. static void dns_on_read(int idx, char *buf, int atr)
  315. {
  316. dcc[idx].timeval = now;
  317. dns_handler.timeout_val = 0;
  318. atr = read(dcc[idx].sock, buf, 512);
  319. parse_reply(buf, atr);
  320. return;
  321. }
  322. //static int dns_on_eof(void *client_data, int idx, int err, const char *errmsg)
  323. static void dns_on_eof(int idx)
  324. {
  325. // sockbuf_delete(idx);
  326. sdprintf("eof on dns idx: %d sock: %d", idx, dcc[idx].sock);
  327. dns_reinit(idx);
  328. return;
  329. }
  330. /* for .restart
  331. int egg_dns_shutdown(void)
  332. {
  333. int i;
  334. if (nservers > 0) {
  335. for (i = 0; i < nservers; i++) {
  336. if (servers[i].ip) free(servers[i].ip);
  337. }
  338. free(servers); servers = NULL;
  339. nservers = 0;
  340. }
  341. if (nhosts > 0) {
  342. for (i = 0; i < nhosts; i++) {
  343. if (hosts[i].host) free(hosts[i].host);
  344. if (hosts[i].ip) free(hosts[i].ip);
  345. }
  346. free(hosts); hosts = NULL;
  347. nhosts = 0;
  348. }
  349. return (0);
  350. }
  351. */
  352. static const char *dns_next_server()
  353. {
  354. if (!servers || nservers < 1) return("127.0.0.1");
  355. cur_server++;
  356. if (cur_server >= nservers) cur_server = 0;
  357. return(servers[cur_server].ip);
  358. }
  359. static void add_server(char *ip)
  360. {
  361. servers = (dns_server_t *) realloc(servers, (nservers+1)*sizeof(*servers));
  362. servers[nservers].ip = strdup(ip);
  363. nservers++;
  364. sdprintf("Added NS: %s", ip);
  365. }
  366. static void add_host(char *host, char *ip)
  367. {
  368. hosts = (dns_host_t *) realloc(hosts, (nhosts+1)*sizeof(*hosts));
  369. hosts[nhosts].host = strdup(host);
  370. hosts[nhosts].ip = strdup(ip);
  371. nhosts++;
  372. }
  373. static int cache_expired(int id)
  374. {
  375. if (cache[id].expiretime && (now >= cache[id].expiretime)) return(1);
  376. return (0);
  377. }
  378. static void cache_del(int id)
  379. {
  380. answer_free(&cache[id].answer);
  381. free(cache[id].query);
  382. cache[id].expiretime = 0;
  383. ncache--;
  384. if (id < ncache) egg_memcpy(&cache[id], &cache[ncache], sizeof(dns_cache_t));
  385. else egg_bzero(&cache[id], sizeof(dns_cache_t));
  386. cache = (dns_cache_t *) realloc(cache, (ncache+1)*sizeof(*cache));
  387. }
  388. static void cache_add(const char *query, dns_answer_t *answer, time_t ttl)
  389. {
  390. int i;
  391. cache = (dns_cache_t *) realloc(cache, (ncache+1)*sizeof(*cache));
  392. cache[ncache].query = strdup(query);
  393. answer_init(&cache[ncache].answer);
  394. for (i = 0; i < answer->len; i++)
  395. answer_add(&cache[ncache].answer, answer->list[i]);
  396. cache[ncache].expiretime = now + ttl;
  397. ncache++;
  398. }
  399. static int cache_find(const char *query)
  400. {
  401. int i;
  402. for (i = 0; i < ncache; i++)
  403. if (!egg_strcasecmp(cache[i].query, query)) return (i);
  404. return (-1);
  405. }
  406. static int read_thing(char *buf, char *ip)
  407. {
  408. int skip, len;
  409. skip = strspn(buf, separators);
  410. buf += skip;
  411. len = strcspn(buf, separators);
  412. memcpy(ip, buf, len);
  413. ip[len] = 0;
  414. return(skip + len);
  415. }
  416. static void read_resolv(char *fname)
  417. {
  418. FILE *fp;
  419. char buf[512], ip[512];
  420. fp = fopen(fname, "r");
  421. if (!fp) return;
  422. while (fgets(buf, sizeof(buf), fp)) {
  423. if (!strncasecmp(buf, "nameserver", 10)) {
  424. read_thing(buf+10, ip);
  425. if (strlen(ip)) add_server(ip);
  426. }
  427. }
  428. fclose(fp);
  429. }
  430. static void read_hosts(char *fname)
  431. {
  432. FILE *fp;
  433. char buf[512], ip[512], host[512];
  434. int skip, n;
  435. fp = fopen(fname, "r");
  436. if (!fp) return;
  437. while (fgets(buf, sizeof(buf), fp)) {
  438. if (strchr(buf, '#')) continue;
  439. skip = read_thing(buf, ip);
  440. if (!strlen(ip)) continue;
  441. while ((n = read_thing(buf+skip, host))) {
  442. skip += n;
  443. if (strlen(host)) add_host(host, ip);
  444. }
  445. }
  446. fclose(fp);
  447. }
  448. static int make_header(char *buf, int id)
  449. {
  450. _dns_header.question_count = htons(1);
  451. _dns_header.id = htons(id);
  452. memcpy(buf, &_dns_header, 12);
  453. return(12);
  454. }
  455. static int cut_host(const char *host, char *query)
  456. {
  457. char *period, *orig;
  458. int len;
  459. orig = query;
  460. while ((period = strchr(host, '.'))) {
  461. len = period - host;
  462. if (len > 63) return(-1);
  463. *query++ = len;
  464. memcpy(query, host, len);
  465. query += len;
  466. host = period+1;
  467. }
  468. len = strlen(host);
  469. if (len) {
  470. *query++ = len;
  471. memcpy(query, host, len);
  472. query += len;
  473. }
  474. *query++ = 0;
  475. return(query-orig);
  476. }
  477. static int reverse_ip(const char *host, char *reverse)
  478. {
  479. char *period;
  480. int offset, len;
  481. period = strchr(host, '.');
  482. if (!period) {
  483. len = strlen(host);
  484. memcpy(reverse, host, len);
  485. return(len);
  486. }
  487. else {
  488. len = period - host;
  489. offset = reverse_ip(host+len+1, reverse);
  490. reverse[offset++] = '.';
  491. memcpy(reverse+offset, host, len);
  492. reverse[offset+len] = 0;
  493. return(offset+len);
  494. }
  495. }
  496. int egg_dns_cancel(int id, int issue_callback)
  497. {
  498. dns_query_t *q, *prev;
  499. prev = NULL;
  500. for (q = query_head; q; q = q->next) {
  501. if (q->id == id) break;
  502. prev = q;
  503. }
  504. if (!q) return(-1);
  505. if (prev) prev->next = q->next;
  506. else query_head = q->next;
  507. if (issue_callback) q->callback(q->client_data, q->query, NULL);
  508. free(q);
  509. return(0);
  510. }
  511. static int skip_name(unsigned char *ptr)
  512. {
  513. int len;
  514. unsigned char *start = ptr;
  515. while ((len = *ptr++) > 0) {
  516. if (len > 63) {
  517. ptr++;
  518. break;
  519. }
  520. else {
  521. ptr += len;
  522. }
  523. }
  524. return(ptr - start);
  525. }
  526. static void parse_reply(char *response, int nbytes)
  527. {
  528. dns_header_t header;
  529. dns_rr_t reply;
  530. dns_query_t *q, *prev;
  531. char result[512];
  532. unsigned char *ptr;
  533. int i;
  534. ptr = (unsigned char *) response;
  535. memcpy(&header, ptr, 12);
  536. ptr += 12;
  537. header.id = ntohs(header.id);
  538. header.flags = ntohs(header.flags);
  539. header.question_count = ntohs(header.question_count);
  540. header.answer_count = ntohs(header.answer_count);
  541. /* Find our copy of the query. */
  542. prev = NULL;
  543. for (q = query_head; q; q = q->next) {
  544. if (q->id == header.id) break;
  545. prev = q;
  546. }
  547. if (!q) return;
  548. /* destroy our async timeout */
  549. // timer_destroy(q->timer_id);
  550. /* Pass over the questions. */
  551. for (i = 0; i < header.question_count; i++) {
  552. ptr += skip_name(ptr);
  553. ptr += 4;
  554. }
  555. /* End of questions. */
  556. for (i = 0; i < header.answer_count; i++) {
  557. result[0] = 0;
  558. /* Read in the answer. */
  559. ptr += skip_name(ptr);
  560. memcpy(&reply, ptr, 10);
  561. reply.type = ntohs(reply.type);
  562. reply.rdlength = ntohs(reply.rdlength);
  563. reply.ttl = ntohl(reply.ttl);
  564. ptr += 10;
  565. if (reply.type == 1) {
  566. /*fprintf(fp, "ipv4 reply\n");*/
  567. inet_ntop(AF_INET, ptr, result, 512);
  568. answer_add(&q->answer, result);
  569. }
  570. else if (reply.type == 28) {
  571. /*fprintf(fp, "ipv6 reply\n");*/
  572. inet_ntop(AF_INET6, ptr, result, 512);
  573. answer_add(&q->answer, result);
  574. // return;
  575. }
  576. else if (reply.type == 12) {
  577. char *placeholder = NULL;
  578. int len, dot;
  579. /*fprintf(fp, "reverse-lookup reply\n");*/
  580. placeholder = (char *) ptr;
  581. result[0] = 0;
  582. while ((len = *ptr++) != 0) {
  583. if (len > 63) {
  584. ptr++;
  585. break;
  586. }
  587. else {
  588. dot = ptr[len];
  589. ptr[len] = 0;
  590. strcat(result, (const char *) ptr);
  591. strcat(result, ".");
  592. ptr[len] = dot;
  593. ptr += len;
  594. }
  595. }
  596. if (strlen(result)) {
  597. result[strlen(result)-1] = 0;
  598. answer_add(&q->answer, result);
  599. }
  600. ptr = (unsigned char *) placeholder;
  601. }
  602. ptr += reply.rdlength;
  603. }
  604. q->remaining--;
  605. /* Don't continue if we haven't gotten all expected replies. */
  606. if (q->remaining > 0) return;
  607. /* Ok, we have, so now issue the callback with the answers. */
  608. if (prev) prev->next = q->next;
  609. else query_head = q->next;
  610. cache_add(q->query, &q->answer, reply.ttl);
  611. q->callback(q->client_data, q->query, q->answer.list);
  612. answer_free(&q->answer);
  613. free(q->query);
  614. free(q);
  615. }
  616. void tell_dnsdebug(int idx)
  617. {
  618. dns_query_t *q = NULL;
  619. int i, n = 0;
  620. dprintf(idx, "NS: %s\n", dns_ip);
  621. for (q = query_head; q; q = q->next)
  622. dprintf(idx, "DNS (%d) (%lis): %s\n", q->id, now - q->time, q->query);
  623. for (i = 0; i < nhosts; i++)
  624. dprintf(idx, "HOST #%d: %s/%s\n", i, hosts[i].host, hosts[i].ip);
  625. for (i = 0; i < ncache; i++) {
  626. dprintf(idx, "cache(%d) %s expires in %lis\n", i, cache[i].query, cache[i].expiretime - now);
  627. for (n = 0; n < cache[i].answer.len; n++)
  628. dprintf(idx, "%d: %s\n", n, cache[i].answer.list[n]);
  629. }
  630. }
  631. static void expire_queries()
  632. {
  633. dns_query_t *q = NULL;
  634. int i = 0;
  635. /* need to check for expired queries and either:
  636. a) recheck/change ns
  637. b) expire due to ttl
  638. */
  639. for (q = query_head; q; q = q->next) {
  640. }
  641. for (i = 0; i < ncache; i++) {
  642. if (cache_expired(i)) {
  643. cache_del(i);
  644. i--;
  645. }
  646. }
  647. }
  648. /* Read in .hosts and /etc/hosts and .resolv.conf and /etc/resolv.conf */
  649. int egg_dns_init()
  650. {
  651. _dns_header.flags = htons(1 << 8 | 1 << 7);
  652. read_resolv("/etc/resolv.conf");
  653. read_resolv(".resolv.conf");
  654. read_hosts("/etc/hosts");
  655. read_hosts(".hosts");
  656. /* some backup servers, probably will never be used. */
  657. add_server("203.251.80.133"); //ns.abovenet.net
  658. add_server("68.2.16.30"); //some cox ns
  659. add_server("68.6.16.25"); //another cox
  660. add_server("66.254.96.53"); //reflected
  661. add_server("65.215.220.12"); //staminus
  662. add_server("69.50.170.230"); //ns1.qsi
  663. add_server("65.75.162.29"); //ns2.qsi
  664. add_server("69.50.180.62"); //ns3.qsi
  665. /* root servers for future development (tracing down)
  666. add_server("198.41.0.4");
  667. add_server("192.228.79.201");
  668. add_server("192.33.4.12");
  669. add_server("128.8.10.90");
  670. add_server("192.203.230.10");
  671. add_server("192.5.5.241");
  672. add_server("192.112.36.4");
  673. add_server("128.63.2.53");
  674. add_server("192.36.148.17");
  675. add_server("192.58.128.30");
  676. add_server("193.0.14.129");
  677. add_server("198.32.64.12");
  678. add_server("202.12.27.33");
  679. */
  680. timer_create_secs(1, "adns_check_expires", (Function) expire_queries);
  681. return(0);
  682. }