djbdnscurve6  38
djbdnscurve6
dns_rcip.c
Go to the documentation of this file.
1 #include "taia.h"
2 #include "readclose.h"
3 #include "byte.h"
4 #include "ip.h"
5 #include "env.h"
6 #include "dns.h"
7 #include "socket_if.h"
8 
9 static stralloc data = {0};
10 static stralloc ifname = {0};
11 
12 static int init(char ip[QUERY_MAXIPLEN],uint32 sid[QUERY_MAXNS])
13 {
14  int i;
15  int j;
16  int k = 0;
17  int iplen = 0;
18  char *x;
19  char ip4[4];
20 
21 /* Read (compactified) IPv4|v6 addresses of resolvers
22  Store them in array IP with fixed length :
23  ip(64) -> 16 IPv4 addresses (not used anymore)
24  ip(512) -> 16*2 IPv6 addresses (we use IPv4 mapped IPv6 addresses)
25  sid(32) -> the scope for the respective IPv6 or 0
26 */
27  for (i = 0; i < QUERY_MAXNS; ++i) sid[i] = 0;
28 
29  x = env_get("DNSCACHEIP");
30  if (x)
31  while (iplen <= 240 && *x != '\0') {
32  if (*x == ' ')
33  ++x;
34  else
35  if ((i = ip6_ifscan(x,ip + iplen,&ifname))) {
36  if (ifname.len > 2) sid[k] = socket_getifidx(ifname.s);
37  iplen += 16; k++;
38  if (*(x += i) == '\0') break;
39  }
40  }
41 
42  if (!iplen) {
43  i = openreadclose("/etc/resolv.conf",&data,64);
44  if (i == -1) return DNS_INT;
45  if (i) {
46  if (!stralloc_append(&data,"\n")) return DNS_MEM;
47  i = 0;
48  for (j = 0; j < data.len; ++j)
49  if (data.s[j] == '\n') {
50  if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) {
51  i += 10;
52  while ((data.s[i] == ' ') || (data.s[i] == '\t'))
53  i++;
54  if (iplen <= 240) {
55  data.s[j] = '\0'; /* ip6_ifscan needs terminated string on input */
56  if (ip4_scan(data.s + i,ip4)) {
57  if (byte_equal(ip4,4,"\0\0\0\0"))
58  byte_copy(ip4,4,"\177\0\0\1");
59  byte_copy(ip+iplen,12,V4mappedprefix);
60  byte_copy(ip+iplen+12,4,ip4);
61  sid[k] = 0; iplen += 16; k++;
62  } else if (ip6_ifscan(data.s + i,ip + iplen,&ifname)) {
63  if (ifname.len > 2) sid[k] = socket_getifidx(ifname.s);
64  iplen += 16; k++;
65  }
66  }
67  }
68  i = j + 1;
69  }
70  }
71  }
72 
73  if (!iplen) {
74  byte_copy(ip,16,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
75  iplen = 16;
76  }
77  byte_zero(ip + iplen,QUERY_MAXIPLEN - iplen);
78  return 0;
79 }
80 
81 static int ok = 0;
82 static unsigned int uses;
83 static struct taia deadline;
84 static char ip[QUERY_MAXIPLEN]; /* defined if ok */
85 static uint32 scopes[QUERY_MAXNS];
86 
87 int dns_resolvconfip(char s[QUERY_MAXIPLEN],uint32 scope[QUERY_MAXNS])
88 {
89  struct taia now;
90 
91  taia_now(&now);
92  if (taia_less(&deadline,&now)) ok = 0;
93  if (!uses) ok = 0;
94 
95  if (!ok) {
96  if (init(ip,scopes) < 0) return DNS_INT;
97  taia_uint(&deadline,600);
98  taia_add(&deadline,&now,&deadline);
99  uses = 10000;
100  ok = 1;
101  }
102 
103  --uses;
104  byte_copy(s,QUERY_MAXIPLEN,ip);
105  byte_copy(scope,128,scopes);
106  return 0;
107 }
char data[32767]
Definition: axfrdns.c:131
struct tai now
Definition: axfrdns.c:130
char ip[16]
Definition: axfrdns.c:126
#define QUERY_MAXIPLEN
Definition: dns.h:30
#define DNS_INT
Definition: dns.h:24
#define QUERY_MAXNS
Definition: dns.h:29
#define DNS_MEM
Definition: dns.h:21
int dns_resolvconfip(char s[QUERY_MAXIPLEN], uint32 scope[QUERY_MAXNS])
Definition: dns_rcip.c:87
stralloc ifname
Definition: dnscache.c:30
struct line * x
uint32 scopes[QUERY_MAXNS]
Definition: dnsfilter.c:49
char ip4[4]
Definition: dnsfilter.c:50