26 static int packetquery(char *buf
,unsigned int len
,char **q
,char qtype
[2],char qclass
[2],char id
[2])
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;
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;
44 byte_copy(id
,2,header
);
49 static char myipoutgoing
[4];
50 static char myipincoming
[4];
51 static char buf
[1024];
52 uint64 numqueries
= 0;
58 static struct udpclient
{
61 uint64 active
; /* query number, if active; otherwise 0 */
71 if (!u
[j
].active
) return;
72 log_querydrop(&u
[j
].active
);
73 u
[j
].active
= 0; --uactive
;
78 if (!u
[j
].active
) return;
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
;
96 for (j
= 0;j
< MAXUDP
;++j
)
102 for (i
= 1;i
< MAXUDP
;++i
)
103 if (taia_less(&u
[i
].start
,&u
[j
].start
))
105 errno
= error_timeout
;
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;
118 if (!packetquery(buf
,len
,&q
,qtype
,qclass
,x
->id
)) return;
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
)) {
139 uint64 active
; /* query number or 1, if active; otherwise 0 */
141 char ip
[4]; /* send response to this address */
142 uint16 port
; /* send response to this port */
144 int tcp
; /* open TCP socket, if active */
146 char *buf
; /* 0, or dynamically allocated of length len */
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
162 if (!t
[j
].buf
) return;
163 alloc_free(t
[j
].buf
);
167 void t_timeout(int j
)
170 if (!t
[j
].active
) return;
172 taia_uint(&t
[j
].timeout
,10);
173 taia_add(&t
[j
].timeout
,&t
[j
].timeout
,&now
);
178 if (!t
[j
].active
) return;
180 log_tcpclose(t
[j
].ip
,t
[j
].port
);
182 t
[j
].active
= 0; --tactive
;
187 log_querydrop(&t
[j
].active
);
192 void t_respond(int j
)
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;
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
);
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; }
221 if (x
->pos
== x
->len
) {
223 x
->state
= 1; /* could drop connection immediately */
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; }
233 x
->len
= (unsigned char) ch
;
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; }
248 if (x
->state
!= 3) return; /* impossible */
250 x
->buf
[x
->pos
++] = ch
;
251 if (x
->pos
< x
->len
) return;
253 if (!packetquery(x
->buf
,x
->len
,&q
,qtype
,qclass
,x
->id
)) { t_close(j
); return; }
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
)) {
275 for (j
= 0;j
< MAXTCP
;++j
)
281 for (i
= 1;i
< MAXTCP
;++i
)
282 if (taia_less(&t
[i
].start
,&t
[j
].start
))
284 errno
= error_timeout
;
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 */
300 x
->active
= 1; ++tactive
;
304 log_tcpopen(x
->ip
,x
->port
);
308 iopause_fd io
[3 + MAXUDP
+ MAXTCP
];
312 static void doit(void)
315 struct taia deadline
;
322 taia_uint(&deadline
,120);
323 taia_add(&deadline
,&deadline
,&stamp
);
327 udp53io
= io
+ iolen
++;
329 udp53io
->events
= IOPAUSE_READ
;
331 tcp53io
= io
+ iolen
++;
333 tcp53io
->events
= IOPAUSE_READ
;
335 for (j
= 0;j
< MAXUDP
;++j
)
337 u
[j
].io
= io
+ iolen
++;
338 query_io(&u
[j
].q
,u
[j
].io
,&deadline
);
340 for (j
= 0;j
< MAXTCP
;++j
)
342 t
[j
].io
= io
+ iolen
++;
344 query_io(&t
[j
].q
,t
[j
].io
,&deadline
);
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
;
352 iopause(io
,iolen
,&deadline
,&stamp
);
354 for (j
= 0;j
< MAXUDP
;++j
)
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
);
361 for (j
= 0;j
< MAXTCP
;++j
)
363 if (t
[j
].io
->revents
)
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
);
371 if (t
[j
].io
->revents
|| taia_less(&t
[j
].timeout
,&stamp
))
376 if (udp53io
->revents
)
380 if (tcp53io
->revents
)
385 #define FATAL "dnscache: fatal: "
392 unsigned long cachesize
;
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
);
400 udp53
= socket_udp();
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: ");
406 tcp53
= socket_tcp();
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: ");
414 socket_tryreservein(udp53
,131072);
416 byte_zero(seed
,sizeof seed
);
417 read(0,seed
,sizeof seed
);
418 dns_random_init(seed
);
421 x
= env_get("IPSEND");
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
);
427 x
= env_get("CACHESIZE");
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
);
434 if (env_get("HIDETTL"))
436 if (env_get("FORWARDONLY"))
440 strerr_die2sys(111,FATAL
,"unable to read servers: ");
442 if (socket_listen(tcp53
,20) == -1)
443 strerr_die2sys(111,FATAL
,"unable to listen on TCP socket: ");