static int udpannounce(char*);
static void reply(int, uchar*, DNSmsg*, Request*);
typedef struct Inprogress Inprogress;
struct Inprogress
{
int inuse;
Udphdr uh;
DN *owner;
ushort type;
int id;
};
Inprogress inprog[Maxactive+2];
typedef struct Forwtarg Forwtarg;
struct Forwtarg {
char *host;
uchar addr[IPaddrlen];
int fd;
ulong lastdial;
};
Forwtarg forwtarg[10];
int forwtcount;
static char *hmsg = "headers";
/*
* record client id and ignore retransmissions.
* we're still single thread at this point.
*/
static Inprogress*
clientrxmit(DNSmsg *req, uchar *buf)
{
Inprogress *p, *empty;
Udphdr *uh;
/*
* fast forwarding of incoming queries to other dns servers.
* intended primarily for debugging.
*/
static void
redistrib(uchar *buf, int len)
{
uchar save[Udphdrsize];
Forwtarg *tp;
Udphdr *uh;
memmove(save, buf, Udphdrsize);
uh = (Udphdr *)buf;
for (tp = forwtarg; tp < forwtarg + forwtcount; tp++)
if (tp->fd >= 0) {
memmove(uh->raddr, tp->addr, sizeof tp->addr);
hnputs(uh->rport, 53); /* dns port */
if (write(tp->fd, buf, len) != len) {
close(tp->fd);
tp->fd = -1;
}
} else if (tp->host && time(nil) - tp->lastdial > 60) {
tp->lastdial = time(nil);
tp->fd = udpport(mntpt);
}
memmove(buf, save, Udphdrsize);
}
/*
* a process to act as a dns server for outside reqeusts
*/
void
dnudpserver(char *mntpt)
{
volatile int fd, len, op, rcode;
char *volatile err;
volatile char tname[32];
volatile uchar buf[Udphdrsize + Maxudp + 1024];
volatile DNSmsg reqmsg, repmsg;
Inprogress *volatile p;
volatile Request req;
Udphdr *volatile uh;
/*
* fork sharing text, data, and bss with parent.
* stay in the same note group.
*/
switch(rfork(RFPROC|RFMEM|RFNOWAIT)){
case -1:
break;
case 0:
break;
default:
return;
}
/*
* announce on well-known dns udp port and set message style interface
*/
static int
udpannounce(char *mntpt)
{
int data, ctl;
char dir[64], datafile[64+6];
static int whined;
/* get a udp port */
sprint(datafile, "%s/udp!*!dns", mntpt);
ctl = announce(datafile, dir);
if(ctl < 0){
if(!whined++)
warning("can't announce on %s", datafile);
return -1;
}