1 #include "taia.h"
2 #include "openreadclose.h"
3 #include "byte.h"
4 #include "ip4.h"
5 #include "ip6.h"
6 #include "env.h"
7 #include "dns.h"
8 
9 static stralloc data = {0};
10 
init(char ip[256])11 static int init(char ip[256])
12 {
13   int i;
14   int j;
15   int iplen = 0;
16   char *x;
17 
18   x = env_get("DNSCACHEIP");
19   if (x)
20     while (iplen <= 60) {
21       if (*x == '.')
22 	++x;
23       else {
24         i = ip6_scan(x,ip + iplen);
25 	if (!i) break;
26 	x += i;
27 	iplen += 16;
28       }
29     }
30 
31   if (!iplen) {
32     i = openreadclose("/etc/resolv.conf",&data,64);
33     if (i == -1) return -1;
34     if (i) {
35       if (!stralloc_append(&data,"\n")) return -1;
36       i = 0;
37       for (j = 0;j < data.len;++j)
38         if (data.s[j] == '\n') {
39           if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) {
40             i += 10;
41             while ((data.s[i] == ' ') || (data.s[i] == '\t'))
42               ++i;
43             if (iplen <= 60)
44               if (ip6_scan(data.s + i,ip + iplen)) {
45                 iplen += 16;
46 	      }
47           }
48           i = j + 1;
49         }
50     }
51   }
52 
53   if (!iplen) {
54     byte_copy(ip,16,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
55     iplen = 16;
56   }
57   byte_zero(ip + iplen,256 - iplen);
58   return 0;
59 }
60 
61 static int ok = 0;
62 static unsigned int uses;
63 static struct taia deadline;
64 static char ip[256]; /* defined if ok */
65 
dns_resolvconfip(char s[256])66 int dns_resolvconfip(char s[256])
67 {
68   struct taia now;
69 
70   taia_now(&now);
71   if (taia_less(&deadline,&now)) ok = 0;
72   if (!uses) ok = 0;
73 
74   if (!ok) {
75     if (init(ip) == -1) return -1;
76     taia_uint(&deadline,600);
77     taia_add(&deadline,&now,&deadline);
78     uses = 10000;
79     ok = 1;
80   }
81 
82   --uses;
83   byte_copy(s,256,ip);
84   return 0;
85 }
86