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); } }
void t_rw (int j) { int r; char ch; static char *q = 0; char qtype[2], qclass[2]; struct tcpclient *x = NULL; x = t + j; if (x->state == -1) { r = write (x->tcp, x->buf + x->pos, x->len - x->pos); if (r <= 0) { t_close (j); return; } x->pos += r; if (x->pos == x->len) { t_free (j); x->state = 1; /* could drop connection immediately */ } return; } r = read (x->tcp, &ch, 1); if (r == 0) { errno = error_pipe; t_close (j); return; } if (r < 0) { t_close (j); return; } if (x->state == 1) { x->len = (unsigned char)ch; x->len <<= 8; x->state = 2; return; } if (x->state == 2) { x->len += (unsigned char)ch; if (!x->len) { errno = error_proto; t_close (j); return; } x->buf = alloc (x->len); if (!x->buf) { t_close(j); return; } x->pos = 0; x->state = 3; return; } if (x->state != 3) return; /* impossible */ x->buf[x->pos++] = ch; if (x->pos < x->len) return; if (!packetquery (x->buf, x->len, &q, qtype, qclass, x->id)) { t_close(j); return; } x->active = ++numqueries; 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: t_drop (j); return; case 1: t_respond (j); return; } t_free (j); x->state = 0; }