1 #include <unistd.h>
2 #include "env.h"
3 #include "exit.h"
4 #include "scan.h"
5 #include "strerr.h"
6 #include "error.h"
7 #include "ip4.h"
8 #include "uint16.h"
9 #include "uint64.h"
10 #include "socket.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 "okclient.h"
24 #include "droproot.h"
25 
packetquery(char * buf,unsigned int len,char ** q,char qtype[2],char qclass[2],char id[2])26 static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2])
27 {
28   unsigned int pos;
29   char header[12];
30 
31   errno = error_proto;
32   pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return 0;
33   if (header[2] & 128) return 0; /* must not respond to responses */
34   if (!(header[2] & 1)) return 0; /* do not respond to non-recursive queries */
35   if (header[2] & 120) return 0;
36   if (header[2] & 2) return 0;
37   if (byte_diff(header + 4,2,"\0\1")) return 0;
38 
39   pos = dns_packet_getname(buf,len,pos,q); if (!pos) return 0;
40   pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) return 0;
41   pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) return 0;
42   if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) return 0;
43 
44   byte_copy(id,2,header);
45   return 1;
46 }
47 
48 
49 static char myipoutgoing[4];
50 static char myipincoming[4];
51 static char buf[1024];
52 uint64 numqueries = 0;
53 
54 
55 static int udp53;
56 
57 #define MAXUDP 200
58 static struct udpclient {
59   struct query q;
60   struct taia start;
61   uint64 active; /* query number, if active; otherwise 0 */
62   iopause_fd *io;
63   char ip[4];
64   uint16 port;
65   char id[2];
66 } u[MAXUDP];
67 int uactive = 0;
68 
u_drop(int j)69 void u_drop(int j)
70 {
71   if (!u[j].active) return;
72   log_querydrop(&u[j].active);
73   u[j].active = 0; --uactive;
74 }
75 
u_respond(int j)76 void u_respond(int j)
77 {
78   if (!u[j].active) return;
79   response_id(u[j].id);
80   if (response_len > 512) response_tc();
81   socket_send4(udp53,response,response_len,u[j].ip,u[j].port);
82   log_querydone(&u[j].active,response_len);
83   u[j].active = 0; --uactive;
84 }
85 
u_new(void)86 void u_new(void)
87 {
88   int j;
89   int i;
90   struct udpclient *x;
91   int len;
92   static char *q = 0;
93   char qtype[2];
94   char qclass[2];
95 
96   for (j = 0;j < MAXUDP;++j)
97     if (!u[j].active)
98       break;
99 
100   if (j >= MAXUDP) {
101     j = 0;
102     for (i = 1;i < MAXUDP;++i)
103       if (taia_less(&u[i].start,&u[j].start))
104 	j = i;
105     errno = error_timeout;
106     u_drop(j);
107   }
108 
109   x = u + j;
110   taia_now(&x->start);
111 
112   len = socket_recv4(udp53,buf,sizeof buf,x->ip,&x->port);
113   if (len == -1) return;
114   if (len >= sizeof buf) return;
115   if (x->port < 1024) if (x->port != 53) return;
116   if (!okclient(x->ip)) return;
117 
118   if (!packetquery(buf,len,&q,qtype,qclass,x->id)) return;
119 
120   x->active = ++numqueries; ++uactive;
121   log_query(&x->active,x->ip,x->port,x->id,q,qtype);
122   switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) {
123     case -1:
124       u_drop(j);
125       return;
126     case 1:
127       u_respond(j);
128   }
129 }
130 
131 
132 static int tcp53;
133 
134 #define MAXTCP 20
135 struct tcpclient {
136   struct query q;
137   struct taia start;
138   struct taia timeout;
139   uint64 active; /* query number or 1, if active; otherwise 0 */
140   iopause_fd *io;
141   char ip[4]; /* send response to this address */
142   uint16 port; /* send response to this port */
143   char id[2];
144   int tcp; /* open TCP socket, if active */
145   int state;
146   char *buf; /* 0, or dynamically allocated of length len */
147   unsigned int len;
148   unsigned int pos;
149 } t[MAXTCP];
150 int tactive = 0;
151 
152 /*
153 state 1: buf 0; normal state at beginning of TCP connection
154 state 2: buf 0; have read 1 byte of query packet length into len
155 state 3: buf allocated; have read pos bytes of buf
156 state 0: buf 0; handling query in q
157 state -1: buf allocated; have written pos bytes
158 */
159 
t_free(int j)160 void t_free(int j)
161 {
162   if (!t[j].buf) return;
163   alloc_free(t[j].buf);
164   t[j].buf = 0;
165 }
166 
t_timeout(int j)167 void t_timeout(int j)
168 {
169   struct taia now;
170   if (!t[j].active) return;
171   taia_now(&now);
172   taia_uint(&t[j].timeout,10);
173   taia_add(&t[j].timeout,&t[j].timeout,&now);
174 }
175 
t_close(int j)176 void t_close(int j)
177 {
178   if (!t[j].active) return;
179   t_free(j);
180   log_tcpclose(t[j].ip,t[j].port);
181   close(t[j].tcp);
182   t[j].active = 0; --tactive;
183 }
184 
t_drop(int j)185 void t_drop(int j)
186 {
187   log_querydrop(&t[j].active);
188   errno = error_pipe;
189   t_close(j);
190 }
191 
t_respond(int j)192 void t_respond(int j)
193 {
194   if (!t[j].active) return;
195   log_querydone(&t[j].active,response_len);
196   response_id(t[j].id);
197   t[j].len = response_len + 2;
198   t_free(j);
199   t[j].buf = alloc(response_len + 2);
200   if (!t[j].buf) { t_close(j); return; }
201   uint16_pack_big(t[j].buf,response_len);
202   byte_copy(t[j].buf + 2,response_len,response);
203   t[j].pos = 0;
204   t[j].state = -1;
205 }
206 
t_rw(int j)207 void t_rw(int j)
208 {
209   struct tcpclient *x;
210   char ch;
211   static char *q = 0;
212   char qtype[2];
213   char qclass[2];
214   int r;
215 
216   x = t + j;
217   if (x->state == -1) {
218     r = write(x->tcp,x->buf + x->pos,x->len - x->pos);
219     if (r <= 0) { t_close(j); return; }
220     x->pos += r;
221     if (x->pos == x->len) {
222       t_free(j);
223       x->state = 1; /* could drop connection immediately */
224     }
225     return;
226   }
227 
228   r = read(x->tcp,&ch,1);
229   if (r == 0) { errno = error_pipe; t_close(j); return; }
230   if (r < 0) { t_close(j); return; }
231 
232   if (x->state == 1) {
233     x->len = (unsigned char) ch;
234     x->len <<= 8;
235     x->state = 2;
236     return;
237   }
238   if (x->state == 2) {
239     x->len += (unsigned char) ch;
240     if (!x->len) { errno = error_proto; t_close(j); return; }
241     x->buf = alloc(x->len);
242     if (!x->buf) { t_close(j); return; }
243     x->pos = 0;
244     x->state = 3;
245     return;
246   }
247 
248   if (x->state != 3) return; /* impossible */
249 
250   x->buf[x->pos++] = ch;
251   if (x->pos < x->len) return;
252 
253   if (!packetquery(x->buf,x->len,&q,qtype,qclass,x->id)) { t_close(j); return; }
254 
255   x->active = ++numqueries;
256   log_query(&x->active,x->ip,x->port,x->id,q,qtype);
257   switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) {
258     case -1:
259       t_drop(j);
260       return;
261     case 1:
262       t_respond(j);
263       return;
264   }
265   t_free(j);
266   x->state = 0;
267 }
268 
t_new(void)269 void t_new(void)
270 {
271   int i;
272   int j;
273   struct tcpclient *x;
274 
275   for (j = 0;j < MAXTCP;++j)
276     if (!t[j].active)
277       break;
278 
279   if (j >= MAXTCP) {
280     j = 0;
281     for (i = 1;i < MAXTCP;++i)
282       if (taia_less(&t[i].start,&t[j].start))
283 	j = i;
284     errno = error_timeout;
285     if (t[j].state == 0)
286       t_drop(j);
287     else
288       t_close(j);
289   }
290 
291   x = t + j;
292   taia_now(&x->start);
293 
294   x->tcp = socket_accept4(tcp53,x->ip,&x->port);
295   if (x->tcp == -1) return;
296   if (x->port < 1024) if (x->port != 53) { close(x->tcp); return; }
297   if (!okclient(x->ip)) { close(x->tcp); return; }
298   if (ndelay_on(x->tcp) == -1) { close(x->tcp); return; } /* Linux bug */
299 
300   x->active = 1; ++tactive;
301   x->state = 1;
302   t_timeout(j);
303 
304   log_tcpopen(x->ip,x->port);
305 }
306 
307 
308 iopause_fd io[3 + MAXUDP + MAXTCP];
309 iopause_fd *udp53io;
310 iopause_fd *tcp53io;
311 
doit(void)312 static void doit(void)
313 {
314   int j;
315   struct taia deadline;
316   struct taia stamp;
317   int iolen;
318   int r;
319 
320   for (;;) {
321     taia_now(&stamp);
322     taia_uint(&deadline,120);
323     taia_add(&deadline,&deadline,&stamp);
324 
325     iolen = 0;
326 
327     udp53io = io + iolen++;
328     udp53io->fd = udp53;
329     udp53io->events = IOPAUSE_READ;
330 
331     tcp53io = io + iolen++;
332     tcp53io->fd = tcp53;
333     tcp53io->events = IOPAUSE_READ;
334 
335     for (j = 0;j < MAXUDP;++j)
336       if (u[j].active) {
337 	u[j].io = io + iolen++;
338 	query_io(&u[j].q,u[j].io,&deadline);
339       }
340     for (j = 0;j < MAXTCP;++j)
341       if (t[j].active) {
342 	t[j].io = io + iolen++;
343 	if (t[j].state == 0)
344 	  query_io(&t[j].q,t[j].io,&deadline);
345 	else {
346 	  if (taia_less(&t[j].timeout,&deadline)) deadline = t[j].timeout;
347 	  t[j].io->fd = t[j].tcp;
348 	  t[j].io->events = (t[j].state > 0) ? IOPAUSE_READ : IOPAUSE_WRITE;
349 	}
350       }
351 
352     iopause(io,iolen,&deadline,&stamp);
353 
354     for (j = 0;j < MAXUDP;++j)
355       if (u[j].active) {
356 	r = query_get(&u[j].q,u[j].io,&stamp);
357 	if (r == -1) u_drop(j);
358 	if (r == 1) u_respond(j);
359       }
360 
361     for (j = 0;j < MAXTCP;++j)
362       if (t[j].active) {
363 	if (t[j].io->revents)
364 	  t_timeout(j);
365 	if (t[j].state == 0) {
366 	  r = query_get(&t[j].q,t[j].io,&stamp);
367 	  if (r == -1) t_drop(j);
368 	  if (r == 1) t_respond(j);
369 	}
370 	else
371 	  if (t[j].io->revents || taia_less(&t[j].timeout,&stamp))
372 	    t_rw(j);
373       }
374 
375     if (udp53io)
376       if (udp53io->revents)
377 	u_new();
378 
379     if (tcp53io)
380       if (tcp53io->revents)
381 	t_new();
382   }
383 }
384 
385 #define FATAL "dnscache: fatal: "
386 
387 char seed[128];
388 
main()389 int main()
390 {
391   char *x;
392   unsigned long cachesize;
393 
394   x = env_get("IP");
395   if (!x)
396     strerr_die2x(111,FATAL,"$IP not set");
397   if (!ip4_scan(x,myipincoming))
398     strerr_die3x(111,FATAL,"unable to parse IP address ",x);
399 
400   udp53 = socket_udp();
401   if (udp53 == -1)
402     strerr_die2sys(111,FATAL,"unable to create UDP socket: ");
403   if (socket_bind4_reuse(udp53,myipincoming,53) == -1)
404     strerr_die2sys(111,FATAL,"unable to bind UDP socket: ");
405 
406   tcp53 = socket_tcp();
407   if (tcp53 == -1)
408     strerr_die2sys(111,FATAL,"unable to create TCP socket: ");
409   if (socket_bind4_reuse(tcp53,myipincoming,53) == -1)
410     strerr_die2sys(111,FATAL,"unable to bind TCP socket: ");
411 
412   droproot(FATAL);
413 
414   socket_tryreservein(udp53,131072);
415 
416   byte_zero(seed,sizeof seed);
417   read(0,seed,sizeof seed);
418   dns_random_init(seed);
419   close(0);
420 
421   x = env_get("IPSEND");
422   if (!x)
423     strerr_die2x(111,FATAL,"$IPSEND not set");
424   if (!ip4_scan(x,myipoutgoing))
425     strerr_die3x(111,FATAL,"unable to parse IP address ",x);
426 
427   x = env_get("CACHESIZE");
428   if (!x)
429     strerr_die2x(111,FATAL,"$CACHESIZE not set");
430   scan_ulong(x,&cachesize);
431   if (!cache_init(cachesize))
432     strerr_die3x(111,FATAL,"not enough memory for cache of size ",x);
433 
434   if (env_get("HIDETTL"))
435     response_hidettl();
436   if (env_get("FORWARDONLY"))
437     query_forwardonly();
438 
439   if (!roots_init())
440     strerr_die2sys(111,FATAL,"unable to read servers: ");
441 
442   if (socket_listen(tcp53,20) == -1)
443     strerr_die2sys(111,FATAL,"unable to listen on TCP socket: ");
444 
445   log_startup();
446   doit();
447 }
448