#include <auth.h>
#include <fcall.h>
#include <bio.h>
-#include <ctype.h>
#include <ip.h>
-#include <pool.h>
#include "dns.h"
enum
int vers; /* incremented each clone/attach */
-static volatile int stop;
-
/* holds data to be returned via read of /net/dns, perhaps multiple reads */
struct Mfile
{
ulong now;
vlong nowns;
int sendnotifies;
-int testing;
char *trace;
int traceactivity;
char *zonerefreshprogram;
char *logfile = "dns"; /* or "dns.test" */
char *dbfile;
+char *dnsuser;
char mntpt[Maxpath];
int addforwtarg(char *);
void
usage(void)
{
- fprint(2, "usage: %s [-FnorRst] [-a maxage] [-f ndb-file] [-N target] "
+ fprint(2, "usage: %s [-FnorRs] [-a maxage] [-f ndb-file] [-N target] "
"[-T forwip] [-x netmtpt] [-z refreshprog]\n", argv0);
exits("usage");
}
void
main(int argc, char *argv[])
{
- int kid, pid;
char servefile[Maxpath], ext[Maxpath];
Dir *dir;
cfg.serve = 1; /* serve network */
cfg.cachedb = 1;
break;
- case 't':
- testing = 1;
- break;
case 'T':
addforwtarg(EARGF(usage()));
break;
if(argc != 0)
usage();
- if(testing)
- mainmem->flags |= POOL_NOREUSE | POOL_ANTAGONISM;
- mainmem->flags |= POOL_ANTAGONISM;
rfork(RFREND|RFNOTEG);
cfg.inside = (*mntpt == '\0' || strcmp(mntpt, "/net") == 0);
opendatabase();
now = time(nil); /* open time files before we fork */
nowns = nsec();
+ dnsuser = estrdup(getuser());
snprint(servefile, sizeof servefile, "#s/dns%s", ext);
dir = dirstat(servefile);
sysfatal("%s exists; another dns instance is running",
servefile);
free(dir);
-// unmount(servefile, mntpt);
-// remove(servefile);
-
mountinit(servefile, mntpt); /* forks, parent exits */
- srand(now*getpid());
+ srand(truerand());
db2cache(1);
if (cfg.straddle && !seerootns())
dnslog("straddle server misconfigured; can't see root name servers");
- /*
- * fork without sharing heap.
- * parent waits around for child to die, then forks & restarts.
- * child may spawn udp server, notify procs, etc.; when it gets too
- * big, it kills itself and any children.
- * /srv/dns and /net/dns remain open and valid.
- */
- for (;;) {
- kid = rfork(RFPROC|RFFDG|RFNOTEG);
- switch (kid) {
- case -1:
- sysfatal("fork failed: %r");
- case 0:
- if(cfg.serve)
- dnudpserver(mntpt);
- if(sendnotifies)
- notifyproc();
- io();
- _exits("restart");
- default:
- while ((pid = waitpid()) != kid && pid != -1)
- continue;
- break;
- }
- dnslog("dns restarting");
- }
+
+ if(cfg.serve)
+ dnudpserver(mntpt);
+ if(sendnotifies)
+ notifyproc();
+
+ io();
+ _exits(0);
}
/*
/* copy namespace to avoid a deadlock */
switch(rfork(RFFDG|RFPROC|RFNAMEG)){
- case 0: /* child: hang around and (re)start main proc */
+ case 0: /* child: start main proc */
close(p[1]);
- procsetname("%s restarter", mntpt);
+ procsetname("%s", mntpt);
break;
case -1:
sysfatal("fork failed: %r");
}
mf = emalloc(sizeof(*mf));
mf->fid = fid;
- mf->user = estrdup("dummy");
+ mf->qid.vers = vers;
+ mf->qid.type = QTDIR;
+ mf->qid.path = 0LL;
+ mf->user = estrdup("none");
mf->next = mfalloc.inuse;
mfalloc.inuse = mf;
unlock(&mfalloc);
if(nmf == nil)
return nil;
nmf->fid = fid;
- free(nmf->user); /* estrdup("dummy") */
+ free(nmf->user); /* estrdup("none") */
nmf->user = estrdup(mf->user);
nmf->qid.type = mf->qid.type;
nmf->qid.path = mf->qid.path;
if(setjmp(req.mret))
putactivity(0);
req.isslave = 0;
- stop = 0;
- while(!stop){
- procsetname("%d %s/dns Twrites of %d 9p rpcs read; %d alarms",
- stats.qrecvd9p, mntpt, stats.qrecvd9prpc, stats.alarms);
- n = read9pmsg(mfd[0], mdata, sizeof mdata);
- if(n<=0){
+ while((n = read9pmsg(mfd[0], mdata, sizeof mdata)) != 0){
+ if(n < 0){
dnslog("error reading 9P from %s: %r", mntpt);
- sleep(2000); /* don't thrash after read error */
- return;
+ break;
}
stats.qrecvd9prpc++;
job = newjob();
if(convM2S(mdata, n, &job->request) != n){
+ dnslog("format error %ux %ux %ux %ux %ux",
+ mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]);
freejob(job);
- continue;
+ break;
}
mf = newfid(job->request.fid, 0);
if(debug)
putactivity(0);
}
- /* kill any udp server, notifier, etc. processes */
- postnote(PNGROUP, getpid(), "die");
- sleep(1000);
}
void
if(cnt > 0 && job->request.data[cnt-1] == '\n')
job->request.data[cnt-1] = 0;
+ if(strcmp(mf->user, "none") == 0 || strcmp(mf->user, dnsuser) != 0)
+ goto query; /* skip special commands if not owner */
+
/*
* special commands
*/
-// dnslog("rwrite got: %s", job->request.data);
+ if(debug)
+ dnslog("rwrite got: %s", job->request.data);
send = 1;
if(strcmp(job->request.data, "debug")==0)
debug ^= 1;
- else if(strcmp(job->request.data, "testing")==0)
- testing ^= 1;
else if(strcmp(job->request.data, "dump")==0)
dndump("/lib/ndb/dnsdump");
- else if(strcmp(job->request.data, "poolcheck")==0)
- poolcheck(mainmem);
else if(strcmp(job->request.data, "refresh")==0)
needrefresh = 1;
- else if(strcmp(job->request.data, "restart")==0)
- stop = 1;
else if(strcmp(job->request.data, "stats")==0)
dnstats("/lib/ndb/dnsstats");
else if(strncmp(job->request.data, "target ", 7)==0){
if (send)
goto send;
+query:
/*
* kill previous reply
*/