void u_new (void) { int i = 0, j = 0, len = 0; struct udpclient *x = NULL; static char *q = 0; char qtype[2], qclass[2]; for (j = 0; j < MAXUDP; j++) if (!u[j].active) break; if (j >= MAXUDP) { j = 0; for (i = 1; i < MAXUDP; i++) if (taia_less (&u[i].start, &u[j].start)) j = i; errno = error_timeout; u_drop (j); } x = u + j; taia_now (&x->start); len = socket_recv4 (udp53, buf, sizeof (buf), x->ip, &x->port, &odst); if (len == -1) return; if ((unsigned)len >= sizeof buf) return; if (x->port < 1024 && x->port != 53) return; if (!okclient (x->ip)) return; if (!packetquery (buf, len, &q, qtype, qclass, x->id)) return; x->active = ++numqueries; ++uactive; if (debug_level) log_query (x->active, x->ip, x->port, x->id, q, qtype); switch (query_start (&x->q, q, qtype, qclass, myipoutgoing)) { case -1: u_drop (j); return; case 1: u_respond (j); } }
void u_new(void) { int j; int i; struct udpclient *x; int len; static char *q = 0; char qtype[2]; char qclass[2]; for (j = 0;j < MAXUDP;++j) if (!u[j].active) break; if (j >= MAXUDP) { j = 0; for (i = 1;i < MAXUDP;++i) if (taia_less(&u[i].start,&u[j].start)) j = i; errno = error_timeout; u_drop(j); } x = u + j; taia_now(&x->start); len = socket_recv6(udp53,buf,sizeof buf,x->ip,&x->port,&x->scope_id); if (len == -1) return; if (len >= sizeof buf) return; if (x->port < 1024) if (x->port != 53) return; if (!okclient(x->ip)) return; if (!packetquery(buf,len,&q,qtype,qclass,x->id)) return; x->active = ++numqueries; ++uactive; log_query(&x->active,x->ip,x->port,x->id,q,qtype); switch(query_start(&x->q,q,qtype,qclass,myipoutgoing,interface)) { case -1: u_drop(j); return; case 1: u_respond(j); } }
static void doit (void) { struct taia stamp; struct taia deadline; int j = 0, r = 0, iolen = 0; for (;;) { taia_now (&stamp); taia_uint (&deadline, 120); taia_add (&deadline, &deadline, &stamp); iolen = 0; udp53io = io + iolen++; udp53io->fd = udp53; udp53io->events = IOPAUSE_READ; tcp53io = io + iolen++; tcp53io->fd = tcp53; tcp53io->events = IOPAUSE_READ; for (j = 0; j < MAXUDP; ++j) { if (u[j].active) { u[j].io = io + iolen++; query_io (&u[j].q, u[j].io, &deadline); } } for (j = 0; j < MAXTCP; ++j) { if (t[j].active) { t[j].io = io + iolen++; if (t[j].state == 0) query_io (&t[j].q, t[j].io, &deadline); else { if (taia_less (&t[j].timeout, &deadline)) deadline = t[j].timeout; t[j].io->fd = t[j].tcp; t[j].io->events = (t[j].state > 0) ? IOPAUSE_READ : IOPAUSE_WRITE; } } } iopause (io, iolen, &deadline, &stamp); for (j = 0; j < MAXUDP; ++j) { if (u[j].active) { r = query_get (&u[j].q, u[j].io, &stamp); if (r == -1) u_drop (j); if (r == 1) u_respond (j); } } for (j = 0; j < MAXTCP; ++j) { if (t[j].active) { if (t[j].io->revents) t_timeout (j); if (t[j].state == 0) { r = query_get (&t[j].q, t[j].io, &stamp); if (r == -1) t_drop (j); if (r == 1) t_respond (j); } else if (t[j].io->revents || taia_less (&t[j].timeout, &stamp)) t_rw (j); } } if (udp53io && udp53io->revents) u_new(); if (tcp53io && tcp53io->revents) t_new(); } }