remove unused

This commit is contained in:
rsc 2006-02-14 19:43:19 +00:00
parent 54357361fb
commit 5c9f76b5e5
13 changed files with 193 additions and 557 deletions

View file

@ -408,7 +408,6 @@ static RR*
rrloop(Scan *sp, int count, int quest) rrloop(Scan *sp, int count, int quest)
{ {
int i; int i;
static char errbuf[64];
RR *first, *rp, **l; RR *first, *rp, **l;
if(sp->err) if(sp->err)

View file

@ -78,9 +78,6 @@ dblookup(char *name, int class, int type, int auth, int ttl)
char *wild, *cp; char *wild, *cp;
DN *dp, *ndp; DN *dp, *ndp;
int err; int err;
static int parallel;
static int parfd[2];
static char token[1];
/* so far only internet lookups are implemented */ /* so far only internet lookups are implemented */
if(class != Cin) if(class != Cin)
@ -490,16 +487,6 @@ look(Ndbtuple *entry, Ndbtuple *line, char *attr)
return 0; return 0;
} }
static RR**
linkrr(RR *rp, DN *dp, RR **l)
{
rp->owner = dp;
rp->auth = 1;
rp->db = 1;
*l = rp;
return &rp->next;
}
/* these are answered specially by the tcp version */ /* these are answered specially by the tcp version */
static RR* static RR*
doaxfr(Ndb *db, char *name) doaxfr(Ndb *db, char *name)

View file

@ -4,6 +4,7 @@
#include <ctype.h> #include <ctype.h>
#include <bio.h> #include <bio.h>
#include <ndb.h> #include <ndb.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
/* /*
@ -346,7 +347,6 @@ dnagedb(void)
DN *dp; DN *dp;
int i; int i;
RR *rp; RR *rp;
static ulong nextage;
lock(&dnlock); lock(&dnlock);
@ -370,7 +370,6 @@ dnauthdb(void)
int i; int i;
Area *area; Area *area;
RR *rp; RR *rp;
static ulong nextage;
lock(&dnlock); lock(&dnlock);
@ -404,7 +403,7 @@ getactivity(Request *req)
{ {
int rv; int rv;
if(traceactivity) syslog(0, "dns", "get %d by %d", dnvars.active, getpid()); if(traceactivity) syslog(0, "dns", "get %d by %d.%d", dnvars.active, getpid(), threadid());
lock(&dnvars.lk); lock(&dnvars.lk);
while(dnvars.mutex){ while(dnvars.mutex){
unlock(&dnvars.lk); unlock(&dnvars.lk);
@ -423,7 +422,7 @@ putactivity(void)
{ {
static ulong lastclean; static ulong lastclean;
if(traceactivity) syslog(0, "dns", "put %d by %d", dnvars.active, getpid()); if(traceactivity) syslog(0, "dns", "put %d by %d.%d", dnvars.active, getpid(), threadid());
lock(&dnvars.lk); lock(&dnvars.lk);
dnvars.active--; dnvars.active--;
assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */; assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */;
@ -1178,36 +1177,6 @@ warning(char *fmt, ...)
syslog(1, "dns", dnserr); syslog(1, "dns", dnserr);
} }
/*
* create a slave process to handle a request to avoid one request blocking
* another
*/
void
slave(Request *req)
{
static int slaveid;
if(req->isslave)
return; /* we're already a slave process */
/* limit parallelism */
if(getactivity(req) > Maxactive){
putactivity();
return;
}
switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
case -1:
putactivity();
break;
case 0:
req->isslave = 1;
break;
default:
longjmp(req->mret, 1);
}
}
/* /*
* chasing down double free's * chasing down double free's
*/ */

View file

@ -3,6 +3,7 @@
#include <bio.h> #include <bio.h>
#include <ndb.h> #include <ndb.h>
#include <ip.h> #include <ip.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
Area *owned; Area *owned;
@ -90,6 +91,7 @@ freearea(Area **l)
* this entails running a command 'zonerefreshprogram'. This could * this entails running a command 'zonerefreshprogram'. This could
* copy over databases from elsewhere or just do a zone transfer. * copy over databases from elsewhere or just do a zone transfer.
*/ */
/* XXX WRONG - can't use fork and exec */
void void
refresh_areas(Area *s) refresh_areas(Area *s)
{ {
@ -110,7 +112,7 @@ refresh_areas(Area *s)
break; break;
case 0: case 0:
execl(zonerefreshprogram, "zonerefresh", s->soarr->owner->name, 0); execl(zonerefreshprogram, "zonerefresh", s->soarr->owner->name, 0);
exits(0); threadexitsall(0);
break; break;
default: default:
for(;;){ for(;;){

View file

@ -46,6 +46,10 @@ syslog(0, logfile, "serial old %lud new %lud", a->soarr->soa->serial, repp->qd->
a->needrefresh = 1; a->needrefresh = 1;
} }
/*
* this isn't going to work as a thread!
*/
static void static void
ding(void *u, char *msg) ding(void *u, char *msg)
{ {
@ -62,10 +66,10 @@ static void
send_notify(char *slave, RR *soa, Request *req) send_notify(char *slave, RR *soa, Request *req)
{ {
int i, len, n, reqno, status, fd; int i, len, n, reqno, status, fd;
uchar obuf[Maxudp+OUdphdrsize]; uchar obuf[Maxudp+Udphdrsize];
uchar ibuf[Maxudp+OUdphdrsize]; uchar ibuf[Maxudp+Udphdrsize];
RR *rp; RR *rp;
OUdphdr *up = (OUdphdr*)obuf; Udphdr *up = (Udphdr*)obuf;
char *err; char *err;
DNSmsg repmsg; DNSmsg repmsg;
@ -93,14 +97,14 @@ send_notify(char *slave, RR *soa, Request *req)
/* send 3 times or until we get anything back */ /* send 3 times or until we get anything back */
for(i = 0; i < 3; i++){ for(i = 0; i < 3; i++){
syslog(0, logfile, "sending %d byte notify to %s/%I.%d about %s", n, slave, up->raddr, nhgets(up->rport), soa->owner->name); syslog(0, logfile, "sending %d byte notify to %s/%I.%d about %s", n, slave, up->raddr, nhgets(up->rport), soa->owner->name);
if(udpwrite(fd, (OUdphdr*)obuf, obuf+OUdphdrsize, n) != n) if(udpwrite(fd, (Udphdr*)obuf, obuf+Udphdrsize, n) != n)
break; break;
alarm(2*1000); alarm(2*1000);
len = udpread(fd, (Udphdr*)ibuf, ibuf+OUdphdrsize, Maxudp); len = udpread(fd, (Udphdr*)ibuf, ibuf+Udphdrsize, Maxudp);
alarm(0); alarm(0);
if(len <= OUdphdrsize) if(len <= Udphdrsize)
continue; continue;
err = convM2DNS(&ibuf[OUdphdrsize], len, &repmsg); err = convM2DNS(&ibuf[Udphdrsize], len, &repmsg);
if(err != nil) if(err != nil)
continue; continue;
if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify) if(repmsg.id == reqno && (repmsg.flags & Omask) == Onotify)
@ -132,24 +136,11 @@ notify_areas(Area *a, Request *req)
* (also reads in new databases) * (also reads in new databases)
*/ */
void void
notifyproc(void) notifyproc(void *v)
{ {
Request req; Request req;
static int already;
if(already) USED(v);
return;
switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
case -1:
return;
case 0:
break;
default:
return;
}
req.isslave = 1; /* son't fork off subprocesses */
for(;;){ for(;;){
getactivity(&req); getactivity(&req);

View file

@ -258,7 +258,7 @@ mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
{ {
DNSmsg m; DNSmsg m;
int len; int len;
OUdphdr *uh = (OUdphdr*)buf; Udphdr *uh = (Udphdr*)buf;
/* stuff port number into output buffer */ /* stuff port number into output buffer */
memset(uh, 0, sizeof(*uh)); memset(uh, 0, sizeof(*uh));
@ -271,7 +271,7 @@ mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
m.qd = rralloc(type); m.qd = rralloc(type);
m.qd->owner = dp; m.qd->owner = dp;
m.qd->type = type; m.qd->type = type;
len = convDNS2M(&m, &buf[OUdphdrsize], Maxudp); len = convDNS2M(&m, &buf[Udphdrsize], Maxudp);
if(len < 0) if(len < 0)
abort(); /* "can't convert" */; abort(); /* "can't convert" */;
rrfree(m.qd); rrfree(m.qd);
@ -319,14 +319,14 @@ readreply(int fd, DN *dp, int type, ushort req,
/* timed read */ /* timed read */
alarm((endtime - now) * 1000); alarm((endtime - now) * 1000);
len = udpread(fd, (OUdphdr*)ibuf, ibuf+OUdphdrsize, Maxudpin); len = udpread(fd, (Udphdr*)ibuf, ibuf+Udphdrsize, Maxudpin);
alarm(0); alarm(0);
if(len < 0) if(len < 0)
return -1; /* timed out */ return -1; /* timed out */
/* convert into internal format */ /* convert into internal format */
memset(mp, 0, sizeof(*mp)); memset(mp, 0, sizeof(*mp));
err = convM2DNS(&ibuf[OUdphdrsize], len, mp); err = convM2DNS(&ibuf[Udphdrsize], len, mp);
if(err){ if(err){
syslog(0, LOG, "input err %s: %I", err, ibuf); syslog(0, LOG, "input err %s: %I", err, ibuf);
continue; continue;
@ -544,6 +544,7 @@ netquery1(int fd, DN *dp, int type, RR *nsrp, Request *reqp, int depth, uchar *i
Dest dest[Maxdest]; Dest dest[Maxdest];
DNSmsg m; DNSmsg m;
ulong endtime; ulong endtime;
Udphdr *uh;
/* pack request into a message */ /* pack request into a message */
req = rand(); req = rand();
@ -591,10 +592,9 @@ netquery1(int fd, DN *dp, int type, RR *nsrp, Request *reqp, int depth, uchar *i
if(debug) if(debug)
logsend(reqp->id, depth, obuf, p->s->name, logsend(reqp->id, depth, obuf, p->s->name,
dp->name, type); dp->name, type);
{Udphdr *uh = (Udphdr*)obuf; uh = (Udphdr*)obuf;
print("send %I %I %d %d\n", uh->raddr, uh->laddr, nhgets(uh->rport), nhgets(uh->lport)); fprint(2, "send %I %I %d %d\n", uh->raddr, uh->laddr, nhgets(uh->rport), nhgets(uh->lport));
} if(udpwrite(fd, uh, obuf+Udphdrsize, len) < 0)
if(udpwrite(fd, (OUdphdr*)obuf, obuf+OUdphdrsize, len) < 0)
warning("sending udp msg %r"); warning("sending udp msg %r");
p->nx++; p->nx++;
} }
@ -732,10 +732,8 @@ netquery(DN *dp, int type, RR *nsrp, Request *reqp, int depth)
return 0; return 0;
/* use alloced buffers rather than ones from the stack */ /* use alloced buffers rather than ones from the stack */
ibuf = emalloc(Maxudpin+OUdphdrsize); ibuf = emalloc(Maxudpin+Udphdrsize);
obuf = emalloc(Maxudp+OUdphdrsize); obuf = emalloc(Maxudp+Udphdrsize);
slave(reqp);
/* prepare server RR's for incremental lookup */ /* prepare server RR's for incremental lookup */
for(rp = nsrp; rp; rp = rp->next) for(rp = nsrp; rp; rp = rp->next)

View file

@ -6,6 +6,7 @@
#include <ctype.h> #include <ctype.h>
#include <ip.h> #include <ip.h>
#include <ndb.h> #include <ndb.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
enum enum
@ -89,13 +90,14 @@ void rremove(Job*, Mfile*);
void rstat(Job*, Mfile*); void rstat(Job*, Mfile*);
void rwstat(Job*, Mfile*); void rwstat(Job*, Mfile*);
void sendmsg(Job*, char*); void sendmsg(Job*, char*);
void mountinit(char*, char*); void mountinit(char*);
void io(void); void io(void);
int fillreply(Mfile*, int); int fillreply(Mfile*, int);
Job* newjob(void); Job* newjob(void);
void freejob(Job*); void freejob(Job*);
void setext(char*, int, char*); void setext(char*, int, char*);
char *portname = "domain";
char *logfile = "dns"; char *logfile = "dns";
char *dbfile; char *dbfile;
char mntpt[Maxpath]; char mntpt[Maxpath];
@ -104,61 +106,52 @@ char *LOG;
void void
usage(void) usage(void)
{ {
fprint(2, "usage: %s [-rs] [-f ndb-file] [-x netmtpt]\n", argv0); fprint(2, "usage: %s [-dnrstT] [-a maxage] [-f ndb-file] [-p port] [-x service] [-z zoneprog]\n", argv0);
exits("usage"); threadexitsall("usage");
} }
void void
main(int argc, char *argv[]) threadmain(int argc, char *argv[])
{ {
int serve; int serveudp, servetcp;
char servefile[Maxpath]; char *service;
char ext[Maxpath];
char *p;
serve = 0; serveudp = 0;
// setnetmtpt(mntpt, sizeof(mntpt), nil); servetcp = 0;
ext[0] = 0; service = "dns";
ARGBEGIN{ ARGBEGIN{
case 'd': case 'd':
debug = 1; debug = 1;
traceactivity = 1; traceactivity = 1;
break; break;
case 'f': case 'f':
p = ARGF(); dbfile = EARGF(usage());
if(p == nil)
usage();
dbfile = p;
break; break;
case 'i': case 'x':
haveip = 1; service = EARGF(usage());
parseip(ipaddr, EARGF(usage()));
break; break;
// case 'x':
// p = ARGF();
// if(p == nil)
// usage();
// setnetmtpt(mntpt, sizeof(mntpt), p);
// setext(ext, sizeof(ext), mntpt);
// break;
case 'r': case 'r':
resolver = 1; resolver = 1;
break; break;
case 's': case 's':
serve = 1; /* serve network */ serveudp = 1; /* serve network */
cachedb = 1;
break;
case 'T':
servetcp = 1;
cachedb = 1; cachedb = 1;
break; break;
case 'a': case 'a':
p = ARGF(); maxage = atoi(EARGF(usage()));
if(p == nil)
usage();
maxage = atoi(p);
break; break;
case 't': case 't':
testing = 1; testing = 1;
break; break;
case 'z': case 'z':
zonerefreshprogram = ARGF(); zonerefreshprogram = EARGF(usage());
break;
case 'p':
portname = EARGF(usage());
break; break;
case 'n': case 'n':
sendnotifies = 1; sendnotifies = 1;
@ -167,9 +160,7 @@ main(int argc, char *argv[])
USED(argc); USED(argc);
USED(argv); USED(argv);
//if(testing) mainmem->flags |= POOL_NOREUSE; rfork(RFNOTEG);
#define RFREND 0
rfork(RFREND|RFNOTEG);
/* start syslog before we fork */ /* start syslog before we fork */
fmtinstall('F', fcallfmt); fmtinstall('F', fcallfmt);
@ -181,25 +172,20 @@ main(int argc, char *argv[])
opendatabase(); opendatabase();
/* mountinit(service);
snprint(servefile, sizeof(servefile), "#s/dns%s", ext);
unmount(servefile, mntpt);
remove(servefile);
*/
mountinit(servefile, mntpt);
now = time(0); now = time(0);
srand(now*getpid()); srand(now*getpid());
db2cache(1); db2cache(1);
// if(serve) if(serveudp)
// proccreate(dnudpserver, mntpt, STACK); proccreate(dnudpserver, nil, STACK);
if(servetcp)
proccreate(dntcpserver, nil, STACK);
if(sendnotifies) if(sendnotifies)
notifyproc(); proccreate(notifyproc, nil, STACK);
io(); io();
syslog(0, logfile, "io returned, exiting");
exits(0);
} }
int int
@ -231,25 +217,15 @@ setext(char *ext, int n, char *p)
} }
void void
mountinit(char *service, char *mntpt) mountinit(char *service)
{ {
int p[2]; int p[2];
if(pipe(p) < 0) if(pipe(p) < 0)
abort(); /* "pipe failed" */; abort(); /* "pipe failed" */;
switch(rfork(RFFDG|RFPROC|RFNAMEG)){ if(post9pservice(p[1], service) < 0)
case 0:
close(p[1]);
break;
case -1:
abort(); /* "fork failed\n" */;
default:
close(p[0]);
if(post9pservice(p[1], "dns") < 0)
fprint(2, "post9pservice dns: %r\n"); fprint(2, "post9pservice dns: %r\n");
_exits(0); close(p[1]);
}
mfd[0] = mfd[1] = p[0]; mfd[0] = mfd[1] = p[0];
} }
@ -286,7 +262,6 @@ freefid(Mfile *mf)
{ {
Mfile **l; Mfile **l;
fprint(2, "freefid %d\n", mf->fid);
lock(&mfalloc.lk); lock(&mfalloc.lk);
for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){ for(l = &mfalloc.inuse; *l != nil; l = &(*l)->next){
if(*l == mf){ if(*l == mf){
@ -363,7 +338,7 @@ flushjob(int tag)
} }
void void
io(void) ioproc0(void *v)
{ {
long n; long n;
Mfile *mf; Mfile *mf;
@ -371,19 +346,13 @@ io(void)
Request req; Request req;
Job *job; Job *job;
/* USED(v);
* a slave process is sometimes forked to wait for replies from other
* servers. The master process returns immediately via a longjmp
* through 'mret'.
*/
if(setjmp(req.mret))
putactivity();
req.isslave = 0;
for(;;){ for(;;){
n = read9pmsg(mfd[0], mdata, sizeof mdata); n = read9pmsg(mfd[0], mdata, sizeof mdata);
if(n<=0){ if(n<=0){
syslog(0, logfile, "error reading mntpt: %r"); syslog(0, logfile, "error reading mntpt: %r");
exits(0); break;
} }
job = newjob(); job = newjob();
if(convM2S(mdata, n, &job->request) != n){ if(convM2S(mdata, n, &job->request) != n){
@ -464,19 +433,19 @@ io(void)
} }
skip: skip:
freejob(job); freejob(job);
/*
* slave processes die after replying
*/
if(req.isslave){
putactivity();
_exits(0);
}
putactivity(); putactivity();
} }
} }
void
io(void)
{
int i;
for(i=0; i<Maxactive; i++)
proccreate(ioproc0, 0, STACK);
}
void void
rversion(Job *job) rversion(Job *job)
{ {
@ -667,6 +636,7 @@ rwrite(Job *job, Mfile *mf, Request *req)
char *err, *p, *atype; char *err, *p, *atype;
RR *rp, *tp, *neg; RR *rp, *tp, *neg;
int wantsav; int wantsav;
static char *dumpfile;
err = 0; err = 0;
cnt = job->request.count; cnt = job->request.count;
@ -685,18 +655,21 @@ rwrite(Job *job, Mfile *mf, Request *req)
/* /*
* special commands * special commands
*/ */
if(strncmp(job->request.data, "debug", 5)==0 && job->request.data[5] == 0){ p = job->request.data;
if(strcmp(p, "debug")==0){
debug ^= 1; debug ^= 1;
goto send; goto send;
} else if(strncmp(job->request.data, "dump", 4)==0 && job->request.data[4] == 0){ } else if(strcmp(p, "dump")==0){
dndump("/lib/ndb/dnsdump"); if(dumpfile == nil)
dumpfile = unsharp("#9/ndb/dnsdump");
dndump(dumpfile);
goto send; goto send;
} else if(strncmp(job->request.data, "refresh", 7)==0 && job->request.data[7] == 0){ } else if(strncmp(p, "dump ", 5) == 0){
dndump(p+5);
goto send;
} else if(strcmp(p, "refresh")==0){
needrefresh = 1; needrefresh = 1;
goto send; goto send;
// } else if(strncmp(job->request.data, "poolcheck", 9)==0 && job->request.data[9] == 0){
// poolcheck(mainmem);
// goto send;
} }
/* /*

View file

@ -1,6 +1,3 @@
#define OUdphdrsize Udphdrsize
#define OUdphdr Udphdr
enum enum
{ {
/* RR types */ /* RR types */
@ -114,9 +111,7 @@ typedef struct Txt Txt;
*/ */
struct Request struct Request
{ {
int isslave; /* pid of slave */
ulong aborttime; /* time at which we give up */ ulong aborttime; /* time at which we give up */
jmp_buf mret; /* where master jumps to after starting a slave */
int id; int id;
}; };
@ -291,6 +286,11 @@ enum
OKneg, OKneg,
}; };
enum
{
STACK = 32*1024
};
/* dn.c */ /* dn.c */
extern char *rrtname[]; extern char *rrtname[];
extern char *rname[]; extern char *rname[];
@ -326,7 +326,6 @@ extern int getactivity(Request*);
extern void putactivity(void); extern void putactivity(void);
extern void abort(); /* char*, ... */; extern void abort(); /* char*, ... */;
extern void warning(char*, ...); extern void warning(char*, ...);
extern void slave(Request*);
extern void dncheck(void*, int); extern void dncheck(void*, int);
extern void unique(RR*); extern void unique(RR*);
extern int subsume(char*, char*); extern int subsume(char*, char*);
@ -364,11 +363,13 @@ extern int mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno);
/* dnserver.c */ /* dnserver.c */
extern void dnserver(DNSmsg*, DNSmsg*, Request*); extern void dnserver(DNSmsg*, DNSmsg*, Request*);
extern void dntcpserver(char*); extern void dnudpserver(void*);
extern void dntcpserver(void*);
extern void tcpproc(void*);
/* dnnotify.c */ /* dnnotify.c */
extern void dnnotify(DNSmsg*, DNSmsg*, Request*); extern void dnnotify(DNSmsg*, DNSmsg*, Request*);
extern void notifyproc(void); extern void notifyproc(void*);
/* convDNS2M.c */ /* convDNS2M.c */
extern int convDNS2M(DNSmsg*, uchar*, int); extern int convDNS2M(DNSmsg*, uchar*, int);
@ -397,6 +398,8 @@ extern ulong now; /* time base */
extern Area *owned; extern Area *owned;
extern Area *delegated; extern Area *delegated;
extern char *portname;
#pragma varargck type "R" RR* #pragma varargck type "R" RR*
#pragma varargck type "Q" RR* #pragma varargck type "Q" RR*

View file

@ -4,6 +4,7 @@
#include <ctype.h> #include <ctype.h>
#include <ip.h> #include <ip.h>
#include <ndb.h> #include <ndb.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
enum enum
@ -16,7 +17,6 @@ enum
}; };
static char *servername; static char *servername;
static RR *serverrr;
static RR *serveraddrs; static RR *serveraddrs;
int debug; int debug;
@ -42,7 +42,14 @@ void doquery(char*, char*);
void docmd(int, char**); void docmd(int, char**);
void void
main(int argc, char *argv[]) usage(void)
{
fprint(2, "usage: dnsdebug -rxf [-p port] [query ...]\n");
threadexitsall("usage");
}
void
threadmain(int argc, char *argv[])
{ {
int n; int n;
Biobuf in; Biobuf in;
@ -52,6 +59,9 @@ main(int argc, char *argv[])
strcpy(mntpt, "/net"); strcpy(mntpt, "/net");
ARGBEGIN{ ARGBEGIN{
case 'p': /* XXX */
portname = EARGF(usage());
break;
case 'r': case 'r':
resolver = 1; resolver = 1;
break; break;
@ -60,8 +70,10 @@ main(int argc, char *argv[])
strcpy(mntpt, "/net.alt"); strcpy(mntpt, "/net.alt");
break; break;
case 'f': case 'f':
dbfile = ARGF(); dbfile = EARGF(usage());
break; break;
default:
usage();
}ARGEND }ARGEND
now = time(0); now = time(0);
@ -78,7 +90,7 @@ main(int argc, char *argv[])
if(argc > 0){ if(argc > 0){
docmd(argc, argv); docmd(argc, argv);
exits(0); threadexitsall(0);
} }
Binit(&in, 0, OREAD); Binit(&in, 0, OREAD);
@ -94,7 +106,7 @@ main(int argc, char *argv[])
docmd(n, f); docmd(n, f);
} }
exits(0); threadexitsall(0);
} }
static char* static char*

View file

@ -2,58 +2,43 @@
#include <libc.h> #include <libc.h>
#include <bio.h> #include <bio.h>
#include <ndb.h> #include <ndb.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
#include "ip.h" #include "ip.h"
void
usage(void)
{
fprint(2, "usage: dnsquery [-x dns]\n");
threadexitsall("usage");
}
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int fd, n, len, domount; char *dns;
CFid *fd;
int n, len;
Biobuf in; Biobuf in;
char line[1024], *lp, *p, *np, *mtpt, *srv, *dns; char line[1024], *lp, *p, *np, *mtpt, *srv, *dns;
char buf[1024]; char buf[1024];
dns = "/net/dns"; dns = "dns";
mtpt = "/net";
srv = "/srv/dns";
domount = 1;
ARGBEGIN{ ARGBEGIN{
case 'x': case 'x':
dns = "/net.alt/dns"; dns = EARGF(usage());
mtpt = "/net.alt";
srv = "/srv/dns_net.alt";
break; break;
default: default:
fprint(2, "usage: %s -x [dns-mount-point]\n", argv0); usage();
exits("usage");
}ARGEND; }ARGEND;
if(argc == 1){ if(argc)
domount = 0; usage();
mtpt = argv[0];
} fd = nsopen(dns, nil, "dns", ORDWR);
if(fd == nil)
sysfatal("open %s!dns: %r", dns);
fd = open(dns, ORDWR);
if(fd < 0){
if(domount == 0){
fprint(2, "can't open %s: %r\n", mtpt);
exits(0);
}
fd = open(srv, ORDWR);
if(fd < 0){
print("can't open %s: %r\n", srv);
exits(0);
}
if(mount(fd, -1, mtpt, MBEFORE, "") < 0){
print("can't mount(%s, %s): %r\n", srv, mtpt);
exits(0);
}
fd = open(mtpt, ORDWR);
if(fd < 0){
print("can't open %s: %r\n", mtpt);
exits(0);
}
}
Binit(&in, 0, OREAD); Binit(&in, 0, OREAD);
for(print("> "); lp = Brdline(&in, '\n'); print("> ")){ for(print("> "); lp = Brdline(&in, '\n'); print("> ")){
n = Blinelen(&in)-1; n = Blinelen(&in)-1;
@ -98,16 +83,16 @@ main(int argc, char *argv[])
n = strlen(line); n = strlen(line);
} }
seek(fd, 0, 0); fsseek(fd, 0, 0);
if(write(fd, line, n) < 0) { if(fswrite(fd, line, n) < 0) {
print("!%r\n"); print("!%r\n");
continue; continue;
} }
seek(fd, 0, 0); fsseek(fd, 0, 0);
while((n = read(fd, buf, sizeof(buf))) > 0){ while((n = fsread(fd, buf, sizeof(buf))) > 0){
buf[n] = 0; buf[n] = 0;
print("%s\n", buf); print("%s\n", buf);
} }
} }
exits(0); threadexitsall(0);
} }

View file

@ -1,6 +1,9 @@
#include <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include <ip.h> #include <ip.h>
#include <bio.h>
#include <ndb.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
enum enum
@ -17,308 +20,39 @@ int traceactivity;
int needrefresh; int needrefresh;
int resolver; int resolver;
char mntpt[Maxpath]; char mntpt[Maxpath];
char *caller = "";
ulong now; ulong now;
int maxage; int maxage;
uchar ipaddr[IPaddrlen]; /* my ip address */ uchar ipaddr[IPaddrlen]; /* my ip address */
char *LOG; char *LOG;
char *zonerefreshprogram; char *zonerefreshprogram;
char *portname = "domain";
static int readmsg(int, uchar*, int);
static void reply(int, DNSmsg*, Request*);
static void dnzone(DNSmsg*, DNSmsg*, Request*);
static void getcaller(char*);
static void refreshmain(char*);
void void
main(int argc, char *argv[]) threadmain(int argc, char *argv[])
{ {
int len;
Request req;
DNSmsg reqmsg, repmsg;
uchar buf[512];
char tname[32];
char *err;
char *ext = ""; char *ext = "";
ARGBEGIN{ ARGBEGIN{
default:
usage();
case 'd': case 'd':
debug++; debug++;
break; break;
case 'f': case 'f':
dbfile = ARGF(); dbfile = EARGF(usage());
break; break;
case 'r': case 'r':
resolver = 1; resolver = 1;
break; break;
case 'x':
ext = ARGF();
break;
}ARGEND }ARGEND
if(debug < 2) if(debug < 2)
debug = 0; debug = 0;
if(argc > 0)
getcaller(argv[0]);
dninit(); dninit();
snprint(mntpt, sizeof(mntpt), "/net%s", ext);
if(myipaddr(ipaddr, mntpt) < 0)
sysfatal("can't read my ip address");
syslog(0, logfile, "dnstcp call from %s to %I", caller, ipaddr);
db2cache(1); db2cache(1);
tcpproc(0);
setjmp(req.mret);
req.isslave = 0;
/* loop on requests */
for(;; putactivity()){
now = time(0);
memset(&repmsg, 0, sizeof(repmsg));
alarm(10*60*1000);
len = readmsg(0, buf, sizeof(buf));
alarm(0);
if(len <= 0)
break;
getactivity(&req);
req.aborttime = now + 15*Min;
err = convM2DNS(buf, len, &reqmsg);
if(err){
syslog(0, logfile, "server: input error: %s from %I", err, buf);
break;
}
if(reqmsg.qdcount < 1){
syslog(0, logfile, "server: no questions from %I", buf);
break;
}
if(reqmsg.flags & Fresp){
syslog(0, logfile, "server: reply not request from %I", buf);
break;
}
if((reqmsg.flags & Omask) != Oquery){
syslog(0, logfile, "server: op %d from %I", reqmsg.flags & Omask, buf);
break;
}
if(debug)
syslog(0, logfile, "%d: serve (%s) %d %s %s",
req.id, caller,
reqmsg.id,
reqmsg.qd->owner->name,
rrname(reqmsg.qd->type, tname, sizeof tname));
/* loop through each question */
while(reqmsg.qd){
if(reqmsg.qd->type == Taxfr){
dnzone(&reqmsg, &repmsg, &req);
} else {
dnserver(&reqmsg, &repmsg, &req);
reply(1, &repmsg, &req);
rrfreelist(repmsg.qd);
rrfreelist(repmsg.an);
rrfreelist(repmsg.ns);
rrfreelist(repmsg.ar);
}
}
rrfreelist(reqmsg.qd);
rrfreelist(reqmsg.an);
rrfreelist(reqmsg.ns);
rrfreelist(reqmsg.ar);
if(req.isslave){
putactivity();
_exits(0);
}
}
refreshmain(mntpt);
}
static int
readmsg(int fd, uchar *buf, int max)
{
int n;
uchar x[2];
if(readn(fd, x, 2) != 2)
return -1;
n = (x[0]<<8) | x[1];
if(n > max)
return -1;
if(readn(fd, buf, n) != n)
return -1;
return n;
}
static void
reply(int fd, DNSmsg *rep, Request *req)
{
int len, rv;
char tname[32];
uchar buf[4096];
RR *rp;
if(debug){
syslog(0, logfile, "%d: reply (%s) %s %s %ux",
req->id, caller,
rep->qd->owner->name,
rrname(rep->qd->type, tname, sizeof tname),
rep->flags);
for(rp = rep->an; rp; rp = rp->next)
syslog(0, logfile, "an %R", rp);
for(rp = rep->ns; rp; rp = rp->next)
syslog(0, logfile, "ns %R", rp);
for(rp = rep->ar; rp; rp = rp->next)
syslog(0, logfile, "ar %R", rp);
}
len = convDNS2M(rep, buf+2, sizeof(buf) - 2);
if(len <= 0)
abort(); /* "dnserver: converting reply" */;
buf[0] = len>>8;
buf[1] = len;
rv = write(fd, buf, len+2);
if(rv != len+2){
syslog(0, logfile, "sending reply: %d instead of %d", rv, len+2);
exits(0);
}
}
/*
* Hash table for domain names. The hash is based only on the
* first element of the domain name.
*/
extern DN *ht[HTLEN];
static int
numelem(char *name)
{
int i;
i = 1;
for(; *name; name++)
if(*name == '.')
i++;
return i;
}
int
inzone(DN *dp, char *name, int namelen, int depth)
{
int n;
if(dp->name == 0)
return 0;
if(numelem(dp->name) != depth)
return 0;
n = strlen(dp->name);
if(n < namelen)
return 0;
if(strcmp(name, dp->name + n - namelen) != 0)
return 0;
if(n > namelen && dp->name[n - namelen - 1] != '.')
return 0;
return 1;
}
static void
dnzone(DNSmsg *reqp, DNSmsg *repp, Request *req)
{
DN *dp, *ndp;
RR r, *rp;
int h, depth, found, nlen;
memset(repp, 0, sizeof(*repp));
repp->id = reqp->id;
repp->flags = Fauth | Fresp | Fcanrec | Oquery;
repp->qd = reqp->qd;
reqp->qd = reqp->qd->next;
repp->qd->next = 0;
dp = repp->qd->owner;
/* send the soa */
repp->an = rrlookup(dp, Tsoa, NOneg);
reply(1, repp, req);
if(repp->an == 0)
goto out;
rrfreelist(repp->an);
nlen = strlen(dp->name);
/* construct a breadth first search of the name space (hard with a hash) */
repp->an = &r;
for(depth = numelem(dp->name); ; depth++){
found = 0;
for(h = 0; h < HTLEN; h++)
for(ndp = ht[h]; ndp; ndp = ndp->next)
if(inzone(ndp, dp->name, nlen, depth)){
for(rp = ndp->rr; rp; rp = rp->next){
/* there shouldn't be negatives, but just in case */
if(rp->negative)
continue;
/* don't send an soa's, ns's are enough */
if(rp->type == Tsoa)
continue;
r = *rp;
r.next = 0;
reply(1, repp, req);
}
found = 1;
}
if(!found)
break;
}
/* resend the soa */
repp->an = rrlookup(dp, Tsoa, NOneg);
reply(1, repp, req);
rrfreelist(repp->an);
out:
rrfree(repp->qd);
}
static void
getcaller(char *dir)
{
int fd, n;
static char remote[128];
snprint(remote, sizeof(remote), "%s/remote", dir);
fd = open(remote, OREAD);
if(fd < 0)
return;
n = read(fd, remote, sizeof(remote)-1);
close(fd);
if(n <= 0)
return;
if(remote[n-1] == '\n')
n--;
remote[n] = 0;
caller = remote;
}
static void
refreshmain(char *net)
{
int fd;
char file[128];
snprint(file, sizeof(file), "%s/dns", net);
if(debug)
syslog(0, logfile, "refreshing %s", file);
fd = open(file, ORDWR);
if(fd < 0){
syslog(0, logfile, "can't refresh %s", file);
return;
}
fprint(fd, "refresh");
close(fd);
} }
/* /*

View file

@ -3,6 +3,7 @@
#include <ip.h> #include <ip.h>
#include <bio.h> #include <bio.h>
#include <ndb.h> #include <ndb.h>
#include <thread.h>
#include "dns.h" #include "dns.h"
static int udpannounce(char*); static int udpannounce(char*);
@ -10,21 +11,11 @@ static void reply(int, uchar*, DNSmsg*, Request*);
extern char *logfile; extern char *logfile;
static void
ding(void *x, char *msg)
{
USED(x);
if(strcmp(msg, "alarm") == 0)
noted(NCONT);
else
noted(NDFLT);
}
typedef struct Inprogress Inprogress; typedef struct Inprogress Inprogress;
struct Inprogress struct Inprogress
{ {
int inuse; int inuse;
OUdphdr uh; Udphdr uh;
DN *owner; DN *owner;
int type; int type;
int id; int id;
@ -33,15 +24,15 @@ Inprogress inprog[Maxactive+2];
/* /*
* record client id and ignore retransmissions. * record client id and ignore retransmissions.
* we're still single thread at this point. * we're still single thread at this point. BUG
*/ */
static Inprogress* static Inprogress*
clientrxmit(DNSmsg *req, uchar *buf) clientrxmit(DNSmsg *req, uchar *buf)
{ {
Inprogress *p, *empty; Inprogress *p, *empty;
OUdphdr *uh; Udphdr *uh;
uh = (OUdphdr *)buf; uh = (Udphdr *)buf;
empty = 0; empty = 0;
for(p = inprog; p < &inprog[Maxactive]; p++){ for(p = inprog; p < &inprog[Maxactive]; p++){
if(p->inuse == 0){ if(p->inuse == 0){
@ -52,7 +43,7 @@ clientrxmit(DNSmsg *req, uchar *buf)
if(req->id == p->id) if(req->id == p->id)
if(req->qd->owner == p->owner) if(req->qd->owner == p->owner)
if(req->qd->type == p->type) if(req->qd->type == p->type)
if(memcmp(uh, &p->uh, OUdphdrsize) == 0) if(memcmp(uh, &p->uh, Udphdrsize) == 0)
return 0; return 0;
} }
if(empty == 0) if(empty == 0)
@ -61,7 +52,7 @@ clientrxmit(DNSmsg *req, uchar *buf)
empty->id = req->id; empty->id = req->id;
empty->owner = req->qd->owner; empty->owner = req->qd->owner;
empty->type = req->qd->type; empty->type = req->qd->type;
memmove(&empty->uh, uh, OUdphdrsize); memmove(&empty->uh, uh, Udphdrsize);
empty->inuse = 1; empty->inuse = 1;
return empty; return empty;
} }
@ -69,52 +60,33 @@ clientrxmit(DNSmsg *req, uchar *buf)
/* /*
* a process to act as a dns server for outside reqeusts * a process to act as a dns server for outside reqeusts
*/ */
void static void
dnudpserver(char *mntpt) udpproc(void *v)
{ {
int fd, len, op; int fd, len, op;
Request req; Request req;
DNSmsg reqmsg, repmsg; DNSmsg reqmsg, repmsg;
uchar buf[OUdphdrsize + Maxudp + 1024]; uchar buf[Udphdrsize + Maxudp + 1024];
char *err; char *err;
Inprogress *p; Inprogress *p;
char tname[32]; char tname[32];
OUdphdr *uh; Udphdr *uh;
/* fork sharing text, data, and bss with parent */ fd = (int)v;
switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){
case -1:
break;
case 0:
break;
default:
return;
}
fd = -1;
notify(ding);
restart:
if(fd >= 0)
close(fd);
while((fd = udpannounce(mntpt)) < 0)
sleep(5000);
if(setjmp(req.mret))
putactivity();
req.isslave = 0;
/* loop on requests */ /* loop on requests */
for(;; putactivity()){ for(;; putactivity()){
memset(&repmsg, 0, sizeof(repmsg)); memset(&repmsg, 0, sizeof(repmsg));
memset(&reqmsg, 0, sizeof(reqmsg)); memset(&reqmsg, 0, sizeof(reqmsg));
alarm(60*1000); alarm(60*1000);
len = udpread(fd, (OUdphdr*)buf, buf+OUdphdrsize, sizeof(buf)-OUdphdrsize); len = udpread(fd, (Udphdr*)buf, buf+Udphdrsize, sizeof(buf)-Udphdrsize);
alarm(0); alarm(0);
if(len <= 0) if(len <= 0)
goto restart; continue;
uh = (OUdphdr*)buf; uh = (Udphdr*)buf;
getactivity(&req); getactivity(&req);
req.aborttime = now + 30; /* don't spend more than 30 seconds */ req.aborttime = now + 30; /* don't spend more than 30 seconds */
err = convM2DNS(&buf[OUdphdrsize], len, &reqmsg); err = convM2DNS(&buf[Udphdrsize], len, &reqmsg);
if(err){ if(err){
syslog(0, logfile, "server: input error: %s from %I", err, buf); syslog(0, logfile, "server: input error: %s from %I", err, buf);
continue; continue;
@ -173,12 +145,6 @@ freereq:
rrfreelist(reqmsg.an); rrfreelist(reqmsg.an);
rrfreelist(reqmsg.ns); rrfreelist(reqmsg.ns);
rrfreelist(reqmsg.ar); rrfreelist(reqmsg.ar);
if(req.isslave){
putactivity();
_exits(0);
}
} }
} }
@ -193,7 +159,8 @@ udpannounce(char *mntpt)
USED(mntpt); USED(mntpt);
if((fd=announce("udp!*!nameserver", buf)) < 0) snprint(buf, sizeof buf, "udp!*!%s", portname);
if((fd=announce(buf, buf)) < 0)
warning("can't announce on dns udp port"); warning("can't announce on dns udp port");
return fd; return fd;
} }
@ -211,7 +178,7 @@ reply(int fd, uchar *buf, DNSmsg *rep, Request *reqp)
rep->id, rep->qd->owner->name, rep->id, rep->qd->owner->name,
rrname(rep->qd->type, tname, sizeof tname), rep->an, rep->ns, rep->ar); rrname(rep->qd->type, tname, sizeof tname), rep->an, rep->ns, rep->ar);
len = convDNS2M(rep, &buf[OUdphdrsize], Maxudp); len = convDNS2M(rep, &buf[Udphdrsize], Maxudp);
if(len <= 0){ if(len <= 0){
syslog(0, logfile, "error converting reply: %s %d", rep->qd->owner->name, syslog(0, logfile, "error converting reply: %s %d", rep->qd->owner->name,
rep->qd->type); rep->qd->type);
@ -223,6 +190,18 @@ reply(int fd, uchar *buf, DNSmsg *rep, Request *reqp)
syslog(0, logfile, "ar %R", rp); syslog(0, logfile, "ar %R", rp);
return; return;
} }
if(udpwrite(fd, (OUdphdr*)buf, buf+OUdphdrsize, len) != len) if(udpwrite(fd, (Udphdr*)buf, buf+Udphdrsize, len) != len)
syslog(0, logfile, "error sending reply: %r"); syslog(0, logfile, "error sending reply: %r");
} }
void
dnudpserver(void *v)
{
int i, fd;
while((fd = udpannounce(v)) < 0)
sleep(5*1000);
for(i=0; i<Maxactive; i++)
proccreate(udpproc, (void*)fd, STACK);
}

View file

@ -1,7 +1,10 @@
<$PLAN9/src/mkhdr <$PLAN9/src/mkhdr
TARG=\ TARG=\
# dns\ dns\
dnsquery\
dnsdebug\
dnstcp\
ndbmkdb\ ndbmkdb\
ndbquery\ ndbquery\
ndbmkhash\ ndbmkhash\
@ -20,6 +23,7 @@ DNSOFILES=\
dn.$O\ dn.$O\
dnresolve.$O\ dnresolve.$O\
dnserver.$O\ dnserver.$O\
dntcpserver.$O\
$DNSOFILES dns.$O dnstcp.$O dnsdebug.$O: dns.h $DNSOFILES dns.$O dnstcp.$O dnsdebug.$O: dns.h