djbdnscurve6  38
djbdnscurve6
dnscache.c
Go to the documentation of this file.
1 #include <unistd.h>
2 #include "case.h"
3 #include "env.h"
4 #include "exit.h"
5 #include "scan.h"
6 #include "logmsg.h"
7 #include "str.h"
8 #include "ip.h"
9 #include "uint_t.h"
10 #include "socket_if.h"
11 #include "dns.h"
12 #include "taia.h"
13 #include "byte.h"
14 #include "roots.h"
15 #include "fmt.h"
16 #include "iopause.h"
17 #include "query.h"
18 #include "alloc.h"
19 #include "response.h"
20 #include "cache.h"
21 #include "ndelay.h"
22 #include "log.h"
23 #include "clientok.h"
24 #include "droproot.h"
25 #include "readclose.h"
26 #include "edns0.h"
27 #include "curvedns.h"
28 
29 uint16 dnsport = 53;
30 stralloc ifname = {0};
31 uint32 ifidx = 0; /* aka scope_id */
32 
33 #define WHO "dnscache"
34 
36 int flagdualstack = 0;
38 char *p = "u";
39 //unsigned long fallback;
40 
41 
42 static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2])
43 {
44  unsigned int pos;
45  unsigned int ad = 0;
46  char header[12];
47 
48  errno = EPROTO;
49  pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return 0;
50  if (header[2] & 128) return 0; /* must not respond to responses */
51  if (!(header[2] & 1)) return 0; /* do not respond to non-recursive queries */
52  if (header[2] & 120) return 0; /* standard query only */
53  if (header[2] & 2) return 0; /* Truncation not allowed */
54  if (header[3] & 32) ad = 1; /* Authenticated data */
55  if (byte_diff(header + 4,2,"\0\1")) return 0;
56 
57  pos = dns_packet_getname(buf,len,pos,q); if (!pos) return 0;
58  pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) return 0;
59  pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) return 0;
60  if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) return 0;
61  if (!dns_packet_edns0(header,buf,len,pos)) return 0;
62 
63  byte_copy(id,2,header);
64  return 1;
65 }
66 
67 static char ipsending[16];
68 static char iplistening[16];
69 static char buf[2 * MSGSIZE + 2];
70 uint64 numqueries = 0;
71 
72 static int udp53;
73 
74 static struct udpclient {
75  struct query q;
76  struct taia start;
77  uint64 active; /* query number, if active; otherwise 0 */
78  iopause_fd *io;
79  char ip[16];
80  uint16 port;
81  char id[2];
82  uint32 scope_id;
83 } u[QUERY_MAXUDP];
84 int uactive = 0;
85 int eactive = 0;
86 
87 void u_drop(int j)
88 {
89  if (!u[j].active) return;
90  p = "u";
91  log_querydrop(&u[j].active,p);
92  u[j].active = 0; --uactive;
93 }
94 
95 void u_respond(int j)
96 {
97  if (!u[j].active) return;
98  response_id(u[j].id);
100  if (flagdualstack) // dualstack implies IPv6
101  socket_send6(udp53,response,response_len,u[j].ip,u[j].port,u[j].scope_id);
102  else
103  socket_send(udp53,response,response_len,u[j].ip,u[j].port,u[j].scope_id);
104  p = "u";
105  log_querydone(&u[j].active,response_len,p);
106  u[j].active = 0; --uactive;
107 }
108 
109 void u_new(void)
110 {
111  int j;
112  int i;
113  struct udpclient *x;
114  int len;
115  static char *q = 0;
116  char qtype[2];
117  char qclass[2];
118 
119  for (j = 0; j < QUERY_MAXUDP; ++j)
120  if (!u[j].active)
121  break;
122 
123  if (j >= QUERY_MAXUDP) {
124  j = 0;
125  for (i = 1; i < QUERY_MAXUDP; ++i)
126  if (taia_less(&u[i].start,&u[j].start))
127  j = i;
128  errno = ETIMEDOUT;
129  u_drop(j);
130  }
131 
132  x = u + j;
133  taia_now(&x->start);
134 
135  len = socket_recv(udp53,buf,sizeof(buf),x->ip,&x->port,&x->scope_id);
136  if (len == -1) return;
137  if (len >= sizeof(buf)) return;
138  if (x->port < 1024) if (x->port != 53) return;
139  if (!clientok(x->ip)) {
140  char ipstr[IP6_FMT];
141  if (ip6_isv4mapped(x->ip)) len = ip4_fmt(ipstr,x->ip + 12);
142  else len = ip6_fmt(ipstr,x->ip);
143  ipstr[len] = '\0';
144  logmsg(WHO,-99,WARN,B("client blocked: ",ipstr));
145  return;
146  }
147 
148  if (!packetquery(buf,len,&q,qtype,qclass,x->id)) return;
149 
150  x->active = ++numqueries; ++uactive;
151  p = "u";
152  if (max_response_len > MSGSIZE) { ++eactive; p = "e"; }
153  log_query(&x->active,x->ip,x->port,x->id,q,qtype,p);
154 
155  switch (query_start(&x->q,q,qtype,qclass,ipsending,ifidx)) {
156  case -1: case -2: case -3: u_drop(j); return;
157  case 1: u_respond(j);
158  }
159 }
160 
161 static int tcp53;
162 
163 struct tcpclient {
164  struct query q;
165  struct taia start;
166  struct taia timeout;
167  uint64 active; /* query number or 1, if active; otherwise 0 */
168  iopause_fd *io;
169  char ip[16]; /* send response to this address */
170  uint16 port; /* send response to this port */
171  char id[2];
172  int tcp; /* open TCP socket, if active */
173  int state;
174  char *buf; /* 0, or dynamically allocated of length len */
175  unsigned int len;
176  unsigned int pos;
177  uint32 scope_id;
179 int tactive = 0;
180 
181 /*
182 state 1: buf 0; normal state at beginning of TCP connection
183 state 2: buf 0; have read 1 byte of query packet length into len
184 state 3: buf allocated; have read pos bytes of buf
185 state 0: buf 0; handling query in q
186 state -1: buf allocated; have written pos bytes
187 */
188 
189 void t_free(int j)
190 {
191  if (!t[j].buf) return;
192  alloc_free(t[j].buf);
193  t[j].buf = 0;
194 }
195 
196 void t_timeout(int j)
197 {
198  struct taia now;
199  if (!t[j].active) return;
200  taia_now(&now);
201  taia_uint(&t[j].timeout,10);
202  taia_add(&t[j].timeout,&t[j].timeout,&now);
203 }
204 
205 void t_close(int j)
206 {
207  if (!t[j].active) return;
208  t_free(j);
209  log_tcpclose(t[j].ip,t[j].port);
210  close(t[j].tcp);
211  t[j].active = 0; --tactive;
212 }
213 
214 void t_drop(int j)
215 {
216  p = "t";
217  log_querydrop(&t[j].active,p);
218  errno = EPIPE;
219  t_close(j);
220 }
221 
222 void t_respond(int j)
223 {
224  if (!t[j].active) return;
225  p = "t";
226  log_querydone(&t[j].active,response_len,p);
227  response_id(t[j].id);
228  t[j].len = response_len + 2;
229  t_free(j);
230  t[j].buf = alloc(response_len + 2);
231  if (!t[j].buf) { t_close(j); return; }
232  uint16_pack_big(t[j].buf,response_len);
233  byte_copy(t[j].buf + 2,response_len,response);
234  t[j].pos = 0;
235  t[j].state = -1;
236 }
237 
238 void t_rw(int j)
239 {
240  struct tcpclient *x;
241  char *ch;
242  static char *q = 0;
243  unsigned int readsize;
244  char qtype[2];
245  char qclass[2];
246  int r;
247 
248  x = t + j;
249  if (x->state == -1) {
250  r = write(x->tcp,x->buf + x->pos,x->len - x->pos);
251  if (r <= 0) { t_close(j); return; }
252  x->pos += r;
253  if (x->pos == x->len) {
254  t_free(j);
255  x->state = 1; /* could drop connection immediately */
256  }
257  return;
258  }
259 
260  r = read(x->tcp,&ch,1);
261  switch (x->state) {
262  case 1: readsize = 2U; break;
263  case 2: readsize = 1U; break;
264  case 3: readsize = x->len - x->pos; break;
265  default: return; /* impossible */
266  }
267  r = read(x->tcp,buf,readsize);
268 
269  if (r == 0) { errno = EPIPE; t_close(j); return; }
270  if (r < 0) { t_close(j); return; }
271 
272  ch = buf;
273  if (x->state == 1) {
274  x->len = (unsigned char) *ch++;
275  x->len <<= 8;
276  x->state = 2;
277  if (--r <= 0) return;
278  }
279  if (x->state == 2) {
280  x->len += (unsigned char) *ch;
281  if (x->len < 12) { errno = EPROTO; t_close(j); return; }
282  x->buf = alloc(x->len);
283  if (!x->buf) { t_close(j); return; }
284  x->pos = 0;
285  x->state = 3;
286  return;
287  }
288 
289  if (x->state != 3) return; /* impossible */
290 
291  x->buf[x->pos++] = *ch;
292  byte_copy(&x->buf[x->pos],r,ch);
293  x->pos += r;
294  if (x->pos < x->len) return;
295 
296  if (!packetquery(x->buf,x->len,&q,qtype,qclass,x->id)) { t_close(j); return; }
297 
298  x->active = ++numqueries;
299  p = "t";
300  log_query(&x->active,x->ip,x->port,x->id,q,qtype,p);
301  switch (query_start(&x->q,q,qtype,qclass,ipsending,ifidx)) {
302  case -1: case -2: case -3: t_drop(j); return;
303  case 1: t_respond(j); return;
304  }
305  t_free(j);
306  x->state = 0;
307 }
308 
309 void t_new(void)
310 {
311  int i;
312  int j;
313  int len;
314  struct tcpclient *x;
315 
316  for (j = 0; j < QUERY_MAXTCP; ++j)
317  if (!t[j].active)
318  break;
319 
320  if (j >= QUERY_MAXTCP) {
321  j = 0;
322  for (i = 1; i < QUERY_MAXTCP; ++i)
323  if (taia_less(&t[i].start,&t[j].start))
324  j = i;
325  errno = ETIMEDOUT;
326  if (t[j].state == 0)
327  t_drop(j);
328  else
329  t_close(j);
330  }
331 
332  x = t + j;
333  taia_now(&x->start);
334 
335  x->tcp = socket_accept(tcp53,x->ip,&x->port,&x->scope_id);
336  if (x->tcp == -1) return;
337  if (x->port < 1024) if (x->port != 53) { close(x->tcp); return; }
338  if (!clientok(x->ip)) {
339  char ipstr[IP6_FMT];
340  if (ip6_isv4mapped(x->ip)) len = ip4_fmt(ipstr,x->ip + 12);
341  else len = ip6_fmt(ipstr,x->ip);
342  ipstr[len+1] = '\0';
343  logmsg(WHO,-99,WARN,B("client blocked: ",ipstr));
344  close(x->tcp);
345  return;
346  }
347  if (ndelay_on(x->tcp) == -1) { close(x->tcp); return; } /* Linux bug */
348 
349  x->active = 1; ++tactive;
350  x->state = 1;
351  t_timeout(j);
352 
353  log_tcpopen(x->ip,x->port);
354 }
355 
356 
357 iopause_fd io[3 + QUERY_MAXUDP + QUERY_MAXTCP];
358 iopause_fd *udp53io;
359 iopause_fd *tcp53io;
360 
361 static void doit(void)
362 {
363  int j;
364  struct taia deadline;
365  struct taia stamp;
366  int iolen;
367  int r;
368 
369  for (;;) {
370  taia_now(&stamp);
371  taia_uint(&deadline,120);
372  taia_add(&deadline,&deadline,&stamp);
373 
374  iolen = 0;
375 
376  udp53io = io + iolen++;
377  udp53io->fd = udp53;
378  udp53io->events = IOPAUSE_READ;
379 
380  tcp53io = io + iolen++;
381  tcp53io->fd = tcp53;
382  tcp53io->events = IOPAUSE_READ;
383 
384  for (j = 0; j < QUERY_MAXUDP; ++j)
385  if (u[j].active) {
386  u[j].io = io + iolen++;
387  query_io(&u[j].q,u[j].io,&deadline);
388  }
389 
390  for (j = 0; j < QUERY_MAXTCP; ++j)
391  if (t[j].active) {
392  t[j].io = io + iolen++;
393  if (t[j].state == 0)
394  query_io(&t[j].q,t[j].io,&deadline);
395  else {
396  if (taia_less(&t[j].timeout,&deadline)) deadline = t[j].timeout;
397  t[j].io->fd = t[j].tcp;
398  t[j].io->events = (t[j].state > 0) ? IOPAUSE_READ : IOPAUSE_WRITE;
399  }
400  }
401 
402  if (iopause(io,iolen,&deadline,&stamp) < 0) {
403  errno = ECONNRESET;
404  logmsg(WHO,errno,FATAL,"IO resources not available");
405  }
406 
407  for (j = 0; j < QUERY_MAXUDP; ++j)
408  if (u[j].active) {
409  r = query_get(&u[j].q,u[j].io,&stamp);
410  if (r == -1 || r == -2 || r == -3) { errno = ECONNRESET; u_drop(j); }
411  if (r == 1) u_respond(j);
412  }
413 
414  for (j = 0; j < QUERY_MAXTCP; ++j)
415  if (t[j].active) {
416  if (t[j].io->revents) t_timeout(j);
417  if (t[j].state == 0) {
418  r = query_get(&t[j].q,t[j].io,&stamp);
419  if (r == -1 || r == -2 || r == -3) { errno = ECONNRESET; t_drop(j); }
420  if (r == 1) t_respond(j);
421  }
422  else if (t[j].io->revents || taia_less(&t[j].timeout,&stamp))
423  t_rw(j);
424  }
425 
426  if (udp53io)
427  if (udp53io->revents)
428  u_new();
429 
430  if (tcp53io)
431  if (tcp53io->revents)
432  t_new();
433  }
434 }
435 
436 char seed[128];
437 
438 int main()
439 {
440  char *x;
441  unsigned long cachesize;
442 
443  x = env_get("IP");
444  if (!x)
445  logmsg(WHO,111,ERROR,"$IP not set");
446  if (case_equals(x,"::")) {
447  flagipv6anycast = 1;
448  } else if (case_equals(x,":0")) {
449  flagdualstack = 1;
450  byte_copy(x,2,"::");
451  }
452  if (!ip6_ifscan(x,iplistening,&ifname))
453  logmsg(WHO,101,SYNTAX,B("unable to parse IP address: ",x));
454 
455  if (ifname.len > 1) ifidx = socket_getifidx(ifname.s);
456  if (ip6_isv4mapped(iplistening))
457  udp53 = socket_udp4();
458  else
459  udp53 = socket_udp();
460  if (udp53 == -1)
461  logmsg(WHO,111,FATAL,"unable to create UDP socket");
462 
463  if (flagdualstack) socket_dualstack(udp53);
464  if (flagipv6anycast) socket_ip6anycast(udp53);
465  if (socket_bind_reuse(udp53,iplistening,dnsport,ifidx) == -1)
466  logmsg(WHO,111,FATAL,"unable to bind to UDP socket");
467 
468  if (ip6_isv4mapped(iplistening))
469  tcp53 = socket_tcp4();
470  else
471  tcp53 = socket_tcp();
472  if (tcp53 == -1)
473  logmsg(WHO,111,FATAL,"unable to create TCP socket");
474 
475  if (flagdualstack) socket_dualstack(tcp53);
476  if (flagipv6anycast) socket_ip6anycast(tcp53);
477  if (socket_bind_reuse(tcp53,iplistening,dnsport,ifidx) == -1)
478  logmsg(WHO,111,FATAL,"unable to bind to TCP socket");
479 
480  droproot(WHO);
481 
482  socket_tryreservein(udp53,131072);
483 
484  byte_zero(seed,sizeof(seed));
485  read(0,seed,sizeof(seed));
487  close(0);
488  query_init();
489 
490  x = env_get("IPSEND");
491  if (!x)
492  logmsg(WHO,111,ERROR,"$IPSEND not set");
493  if (!ip6_ifscan(x,ipsending,&ifname))
494  logmsg(WHO,100,SYNTAX,B("unable to parse IP address: ",x));
495 
496  x = env_get("CACHESIZE");
497  if (!x)
498  logmsg(WHO,111,ERROR,"$CACHESIZE not set");
499  scan_ulong(x,&cachesize);
500  if (!cache_init(cachesize))
501  logmsg(WHO,111,FATAL,B("not enough memory for cache of size: ",x));
502 
503  if (env_get("HIDETTL"))
505  if (env_get("FORWARDONLY"))
507  if (env_get("USETEXTFORMAT"))
508  flagusetxtformat = 1;
509  x = env_get("UZ5FALLBACK");
510  fallback = 0;
511  if (x) scan_ulong(x,&fallback);
512  flagedserver = 0;
513  if (env_get("FLAGEDSERVER"))
514  flagedserver = 1;
515 
516 
517  if (!roots_init())
518  logmsg(WHO,111,ERROR,"unable to read servers");
519 
520  if (socket_listen(tcp53,20) == -1)
521  logmsg(WHO,111,FATAL,"unable to listen on TCP socket");
522 
523  log_startup(iplistening,ifidx,ipsending,MSGSIZE);
524  doit();
525 }
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
Definition: axfr-get.c:131
unsigned long port
Definition: axfrdns.c:127
struct tai now
Definition: axfrdns.c:130
char ip[16]
Definition: axfrdns.c:126
uint16 len
Definition: axfrdns.c:302
char buf[MSGSIZE]
Definition: axfrdns.c:301
int cache_init(unsigned int cachesize)
Definition: cache.c:184
int clientok(char ip[16])
Definition: clientok.c:11
int flagedserver
Definition: curvedns.c:16
unsigned long fallback
Definition: dns_transmit.c:17
unsigned int dns_packet_copy(const char *, unsigned int, unsigned int, char *, unsigned int)
Definition: dns_packet.c:8
#define DNS_C_IN
Definition: dns.h:34
#define MSGSIZE
Definition: dns.h:26
#define DNS_C_ANY
Definition: dns.h:35
unsigned int dns_packet_getname(const char *, unsigned int, unsigned int, char **)
Definition: dns_packet.c:35
void dns_random_init(const char *)
uint64 numqueries
Definition: dnscache.c:70
int flagipv6anycast
Definition: dnscache.c:37
void t_close(int j)
Definition: dnscache.c:205
void u_new(void)
Definition: dnscache.c:109
uint32 ifidx
Definition: dnscache.c:31
void t_respond(int j)
Definition: dnscache.c:222
void u_respond(int j)
Definition: dnscache.c:95
iopause_fd * udp53io
Definition: dnscache.c:358
void t_new(void)
Definition: dnscache.c:309
void u_drop(int j)
Definition: dnscache.c:87
char * p
Definition: dnscache.c:38
int flagusetxtformat
Definition: dnscache.c:35
iopause_fd * tcp53io
Definition: dnscache.c:359
void t_timeout(int j)
Definition: dnscache.c:196
int uactive
Definition: dnscache.c:84
void t_free(int j)
Definition: dnscache.c:189
stralloc ifname
Definition: dnscache.c:30
uint16 dnsport
Definition: dnscache.c:29
int eactive
Definition: dnscache.c:85
void t_drop(int j)
Definition: dnscache.c:214
#define WHO
Definition: dnscache.c:33
char seed[128]
Definition: dnscache.c:436
int main()
Definition: dnscache.c:438
int flagdualstack
Definition: dnscache.c:36
struct tcpclient t[QUERY_MAXTCP]
iopause_fd io[3+QUERY_MAXUDP+QUERY_MAXTCP]
Definition: dnscache.c:357
void t_rw(int j)
Definition: dnscache.c:238
int tactive
Definition: dnscache.c:179
int iolen
Definition: dnsfilter.c:46
struct line * x
char ipstr[IP6_FMT]
Definition: dnstrace.c:31
void droproot(const char *fatal)
Definition: droproot.c:8
unsigned int dns_packet_edns0(const char header[12], const char *buf, const int len, unsigned int pos)
Definition: edns0.c:22
void start(const char *s)
Definition: generic-conf.c:41
void log_tcpclose(const char client[16], unsigned int port)
Definition: log.c:149
void log_tcpopen(const char client[16], unsigned int port)
Definition: log.c:142
void log_querydone(uint64 *qnum, unsigned int len, const char *p)
Definition: log.c:119
void log_startup(const char listip[16], uint32 scope, const char sendip[16], int size)
Definition: log.c:94
void log_query(uint64 *qnum, const char client[16], unsigned int port, const char id[2], const char *q, const char qtype[2], const char *p)
Definition: log.c:110
void log_querydrop(uint64 *qnum, const char *p)
Definition: log.c:126
void query_init(void)
Definition: query.c:21
void query_io(struct query *z, iopause_fd *x, struct taia *deadline)
Definition: query.c:1226
int query_get(struct query *z, iopause_fd *x, struct taia *stamp)
Definition: query.c:1215
void query_forwardonly(void)
Definition: query.c:34
int query_start(struct query *z, char *dn, char type[2], char class[2], char localip[16], uint32 scope_id)
Definition: query.c:1197
#define QUERY_MAXTCP
Definition: query.h:14
#define QUERY_MAXUDP
Definition: query.h:13
void response_hidettl(void)
Definition: response.c:70
void response_id(const char id[2])
Definition: response.c:114
char response[65535]
Definition: response.c:6
void response_tc(void)
Definition: response.c:119
unsigned int max_response_len
Definition: response.c:8
unsigned int response_len
Definition: response.c:7
int roots_init(void)
Definition: roots.c:123
unsigned long u
Definition: utime.c:10
struct query q
Definition: dnscache.c:164
uint32 scope_id
Definition: dnscache.c:177
struct taia timeout
Definition: dnscache.c:166
char * buf
Definition: dnscache.c:174
uint16 port
Definition: dnscache.c:170
unsigned int len
Definition: dnscache.c:175
iopause_fd * io
Definition: dnscache.c:168
int state
Definition: dnscache.c:173
char ip[16]
Definition: dnscache.c:169
uint64 active
Definition: dnscache.c:167
unsigned int pos
Definition: dnscache.c:176
struct taia start
Definition: dnscache.c:165
int tcp
Definition: dnscache.c:172
Definition: query.h:56