adns.c 20 KB

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