]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/ndb/dnstcp.c
ip/ipconfig, ndb/dns, libndb: handle parseipmask() errors
[plan9front.git] / sys / src / cmd / ndb / dnstcp.c
index 72c188df95b6e0a643c7e7bc4da3fb859b950e86..a5049eb77f4d1eaae7d77b11d9f018bea7cb84c5 100644 (file)
@@ -3,6 +3,8 @@
  */
 #include <u.h>
 #include <libc.h>
+#include <bio.h>
+#include <ndb.h>
 #include <ip.h>
 #include "dns.h"
 
@@ -10,28 +12,27 @@ Cfg cfg;
 
 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");
 }
 
@@ -45,9 +46,11 @@ main(int argc, char *argv[])
        volatile DNSmsg reqmsg, repmsg;
        volatile Request req;
 
-       alarm(2*60*1000);
        cfg.cachedb = 1;
        ARGBEGIN{
+       case 'a':
+               anyone++;
+               break;
        case 'd':
                debug++;
                break;
@@ -68,22 +71,22 @@ main(int argc, char *argv[])
                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);
@@ -91,6 +94,8 @@ main(int argc, char *argv[])
        req.isslave = 0;
        procsetname("main loop");
 
+       alarm(10*1000);
+
        /* loop on requests */
        for(;; putactivity(0)){
                now = time(nil);
@@ -122,6 +127,12 @@ main(int argc, char *argv[])
                                        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,
@@ -131,7 +142,7 @@ main(int argc, char *argv[])
                /* 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);
@@ -240,8 +251,43 @@ inzone(DN *dp, char *name, int namelen, int depth)
        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;
@@ -259,8 +305,14 @@ dnzone(DNSmsg *reqp, DNSmsg *repp, Request *req)
 
        /* 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;