*/
#include <u.h>
#include <libc.h>
+#include <bio.h>
+#include <ndb.h>
#include <ip.h>
#include "dns.h"
char *caller = "";
char *dbfile;
+int anyone;
int debug;
-uchar ipaddr[IPaddrlen]; /* my ip address */
char *logfile = "dns";
int maxage = 60*60;
char mntpt[Maxpath];
int needrefresh;
ulong now;
vlong nowns;
-int testing;
int traceactivity;
char *zonerefreshprogram;
static int readmsg(int, uchar*, int);
static void reply(int, DNSmsg*, Request*);
-static void dnzone(DNSmsg*, DNSmsg*, Request*);
+static void dnzone(DNSmsg*, DNSmsg*, Request*, uchar*);
static void getcaller(char*);
static void refreshmain(char*);
void
usage(void)
{
- fprint(2, "usage: %s [-rR] [-f ndb-file] [-x netmtpt] [conndir]\n", argv0);
+ fprint(2, "usage: %s [-adrR] [-f ndbfile] [-x netmtpt] [conndir]\n", argv0);
exits("usage");
}
volatile DNSmsg reqmsg, repmsg;
volatile Request req;
- alarm(2*60*1000);
cfg.cachedb = 1;
ARGBEGIN{
+ case 'a':
+ anyone++;
+ break;
case 'd':
debug++;
break;
break;
}ARGEND
- if(debug < 2)
- debug = 0;
-
if(argc > 0)
getcaller(argv[0]);
cfg.inside = 1;
dninit();
- snprint(mntpt, sizeof mntpt, "/net%s", ext);
- if(myipaddr(ipaddr, mntpt) < 0)
- sysfatal("can't read my ip address");
- dnslog("dnstcp call from %s to %I", caller, ipaddr);
+ if(*ext == '/')
+ snprint(mntpt, sizeof mntpt, "%s", ext);
+ else
+ snprint(mntpt, sizeof mntpt, "/net%s", ext);
+
+ dnslog("dnstcp call from %s", caller);
memset(callip, 0, sizeof callip);
parseip(callip, caller);
+ srand(truerand());
db2cache(1);
memset(&req, 0, sizeof req);
req.isslave = 0;
procsetname("main loop");
+ alarm(10*1000);
+
/* loop on requests */
for(;; putactivity(0)){
now = time(nil);
reqmsg.flags & Omask, caller);
break;
}
+
+ if(reqmsg.qd == nil){
+ dnslog("server: no question RR from %s", caller);
+ break;
+ }
+
if(debug)
dnslog("[%d] %d: serve (%s) %d %s %s",
getpid(), req.id, caller,
/* loop through each question */
while(reqmsg.qd)
if(reqmsg.qd->type == Taxfr)
- dnzone(&reqmsg, &repmsg, &req);
+ dnzone(&reqmsg, &repmsg, &req, callip);
else {
dnserver(&reqmsg, &repmsg, &req, callip, rcode);
reply(1, &repmsg, &req);
n = strlen(dp->name);
if(n < namelen)
return 0;
- if(strcmp(name, dp->name + n - namelen) != 0)
+ if(cistrcmp(name, dp->name + n - namelen) != 0)
return 0;
if(n > namelen && dp->name[n - namelen - 1] != '.')
return 0;
return 1;
}
+static Server*
+findserver(uchar *srcip, Server *servers, Request *req)
+{
+ uchar ip[IPaddrlen];
+ RR *list, *rp;
+ int tmp;
+
+ for(; servers != nil; servers = servers->next){
+ if(strcmp(ipattr(servers->name), "ip") == 0){
+ if(parseip(ip, servers->name) == -1)
+ continue;
+ if(ipcmp(srcip, ip) == 0)
+ return servers;
+ continue;
+ }
+
+ tmp = cfg.resolver;
+ cfg.resolver = 1;
+ list = dnresolve(servers->name, Cin, isv4(srcip)? Ta: Taaaa,
+ req, nil, 0, Recurse, 0, nil);
+ cfg.resolver = tmp;
+
+ for(rp = list; rp != nil; rp = rp->next){
+ if(parseip(ip, rp->ip->name) == -1)
+ continue;
+ if(ipcmp(srcip, ip) == 0)
+ break;
+ }
+ rrfreelist(list);
+ if(rp != nil)
+ return servers;
+ }
+ return nil;
+}
+
static void
-dnzone(DNSmsg *reqp, DNSmsg *repp, Request *req)
+dnzone(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip)
{
DN *dp, *ndp;
RR r, *rp;
/* send the soa */
repp->an = rrlookup(dp, Tsoa, NOneg);
+ if(repp->an != nil && !anyone && !myip(srcip)
+ && findserver(srcip, repp->an->soa->slaves, req) == nil){
+ dnslog("dnstcp: %I axfr %s - not a dnsslave", srcip, dp->name);
+ rrfreelist(repp->an);
+ repp->an = nil;
+ }
reply(1, repp, req);
- if(repp->an == 0)
+ if(repp->an == nil)
goto out;
rrfreelist(repp->an);
repp->an = nil;