]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/ndb/dblookup.c
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / ndb / dblookup.c
index 9ff423d2c530388deca4487992dbcc26baa8c013..50d9e367d61619ff31b3642542dd7efd0c93766d 100644 (file)
@@ -3,6 +3,7 @@
 #include <bio.h>
 #include <ndb.h>
 #include <ip.h>
+#include <ctype.h>
 #include "dns.h"
 
 enum {
@@ -16,7 +17,7 @@ enum {
         * confused by a zero ttl, and instead of using the data and then
         * discarding the RR, they conclude that they don't have valid data.
         */
-       Ptrttl = 120,
+       Ptrttl = 2*Min,
 };
 
 static Ndb *db;
@@ -102,8 +103,7 @@ RR*
 dblookup(char *name, int class, int type, int auth, int ttl)
 {
        int err;
-       char *wild, *cp;
-       char buf[256];
+       char buf[Domlen], *wild;
        RR *rp, *tp;
        DN *dp, *ndp;
 
@@ -116,17 +116,14 @@ dblookup(char *name, int class, int type, int auth, int ttl)
 
        if(type == Tall){
                for (type = Ta; type < Tall; type++)
-                       if(implemented[type]) {
-                               tp = dblookup(name, class, type, auth, ttl);
-                               lock(&dnlock);
-                               rrcat(&rp, tp);
-                               unlock(&dnlock);
-                       }
+                       if(implemented[type])
+                               rrcat(&rp, dblookup(name, class, type, auth, ttl));
+
                return rp;
        }
 
        lock(&dblock);
-       dp = dnlookup(name, class, 1);
+       dp = idnlookup(name, class, 1);
 
        if(opendatabase() < 0)
                goto out;
@@ -141,20 +138,10 @@ dblookup(char *name, int class, int type, int auth, int ttl)
        if(rp)
                goto out;
 
-       /* try lower case version */
-       for(cp = name; *cp; cp++)
-               *cp = tolower(*cp);
-       if(cfg.cachedb)
-               rp = rrlookup(dp, type, NOneg);
-       else
-               rp = dblookup1(name, type, auth, ttl);
-       if(rp)
-               goto out;
-
        /* walk the domain name trying the wildcard '*' at each position */
        for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
                snprint(buf, sizeof buf, "*%s", wild);
-               ndp = dnlookup(buf, class, 1);
+               ndp = idnlookup(buf, class, 1);
                if(ndp->rr)
                        err = 0;
                if(cfg.cachedb)
@@ -174,7 +161,7 @@ out:
                 * don't call it non-existent if it's not ours
                 * (unless we're a resolver).
                 */
-               if(err == Rname && (!inmyarea(name) || cfg.resolver))
+               if(err == Rname && (!inmyarea(dp->name) || cfg.resolver))
                        err = Rserver;
                dp->respcode = err;
        }
@@ -191,6 +178,18 @@ intval(Ndbtuple *entry, Ndbtuple *pair, char *attr, ulong def)
        return (t? strtoul(t->val, 0, 10): def);
 }
 
+static void
+mklowcase(char *cp)
+{
+       Rune r;
+
+       while(*cp != 0){
+               chartorune(&r, cp);
+               r = tolowerrune(r);
+               cp += runetochar(cp, &r);
+       }
+}
+
 /*
  *  lookup an RR in the network database
  */
@@ -248,28 +247,47 @@ dblookup1(char *name, int type, int auth, int ttl)
        case Tixfr:
                return doaxfr(db, name);
        default:
-//             dnslog("dnlookup1(%s) bad type", name);
+//             dnslog("dblookup1(%s) bad type", name);
                return nil;
        }
 
        /*
         *  find a matching entry in the database
         */
-       t = nil;
-       free(ndbgetvalue(db, &s, "dom", name, attr, &t));
+       nstrcpy(dname, name, sizeof dname);
+       for(x=0; x<4; x++){
+               switch(x){
+               case 1: /* try unicode */
+                       if(idn2utf(name, dname, sizeof dname) == nil){
+                               nstrcpy(dname, name, sizeof dname);
+                               continue;
+                       }
+                       if(strcmp(name, dname) == 0)
+                               continue;
+                       break;
+               case 3: /* try ascii (lower case) */
+                       if(utf2idn(name, dname, sizeof dname) == nil)
+                               continue;
+               case 2:
+                       mklowcase(dname);
+                       if(strcmp(name, dname) == 0)
+                               continue;
+                       break;
+               }
+               t = nil;
+               free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
+               if(t == nil && strchr(dname, '.') == nil)
+                       free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
+               if(t != nil)
+                       break;
+       }
 
-       /*
-        *  hack for local names
-        */
-       if(t == nil && strchr(name, '.') == nil)
-               free(ndbgetvalue(db, &s, "sys", name, attr, &t));
        if(t == nil) {
-//             dnslog("dnlookup1(%s) name not found", name);
+//             dnslog("dblookup1(%s) name not found", name);
                return nil;
        }
 
        /* search whole entry for default domain name */
-       strncpy(dname, name, sizeof dname);
        for(nt = t; nt; nt = nt->entry)
                if(strcmp(nt->attr, "dom") == 0){
                        nstrcpy(dname, nt->val, sizeof dname);
@@ -298,14 +316,14 @@ dblookup1(char *name, int type, int auth, int ttl)
                        nstrcpy(dname, nt->val, sizeof dname);
                        found = 1;
                }
-               if(cistrcmp(attr, nt->attr) == 0){
+               if(strcmp(attr, nt->attr) == 0){
                        rp = (*f)(t, nt);
                        rp->auth = auth;
                        rp->db = 1;
                        if(ttl)
                                rp->ttl = ttl;
                        if(dp == nil)
-                               dp = dnlookup(dname, Cin, 1);
+                               dp = idnlookup(dname, Cin, 1);
                        rp->owner = dp;
                        *l = rp;
                        l = &rp->next;
@@ -318,21 +336,21 @@ dblookup1(char *name, int type, int auth, int ttl)
 
        /* search whole entry */
        for(nt = t; nt; nt = nt->entry)
-               if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){
+               if(nt->ptr == 0 && strcmp(attr, nt->attr) == 0){
                        rp = (*f)(t, nt);
                        rp->db = 1;
                        if(ttl)
                                rp->ttl = ttl;
                        rp->auth = auth;
                        if(dp == nil)
-                               dp = dnlookup(dname, Cin, 1);
+                               dp = idnlookup(dname, Cin, 1);
                        rp->owner = dp;
                        *l = rp;
                        l = &rp->next;
                }
        ndbfree(t);
 
-//     dnslog("dnlookup1(%s) -> %#p", name, list);
+//     dnslog("dblookup1(%s) -> %#p", name, list);
        return list;
 }
 
@@ -408,7 +426,7 @@ cnamerr(Ndbtuple *entry, Ndbtuple *pair)
 
        USED(entry);
        rp = rralloc(Tcname);
-       rp->host = dnlookup(pair->val, Cin, 1);
+       rp->host = idnlookup(pair->val, Cin, 1);
        return rp;
 }
 static RR*
@@ -417,7 +435,7 @@ mxrr(Ndbtuple *entry, Ndbtuple *pair)
        RR *rp;
 
        rp = rralloc(Tmx);
-       rp->host = dnlookup(pair->val, Cin, 1);
+       rp->host = idnlookup(pair->val, Cin, 1);
        rp->pref = intval(entry, pair, "pref", 1);
        return rp;
 }
@@ -428,7 +446,7 @@ nsrr(Ndbtuple *entry, Ndbtuple *pair)
        Ndbtuple *t;
 
        rp = rralloc(Tns);
-       rp->host = dnlookup(pair->val, Cin, 1);
+       rp->host = idnlookup(pair->val, Cin, 1);
        t = look(entry, pair, "soa");
        if(t && t->val[0] == 0)
                rp->local = 1;
@@ -468,7 +486,7 @@ soarr(Ndbtuple *entry, Ndbtuple *pair)
        ns = look(entry, pair, "ns");
        if(ns == nil)
                ns = look(entry, pair, "dom");
-       rp->host = dnlookup(ns->val, Cin, 1);
+       rp->host = idnlookup(ns->val, Cin, 1);
 
        /* accept all of:
         *  mbox=person
@@ -483,15 +501,15 @@ soarr(Ndbtuple *entry, Ndbtuple *pair)
                        p = strchr(mb->val, '@');
                        if(p != nil)
                                *p = '.';
-                       rp->rmb = dnlookup(mb->val, Cin, 1);
+                       rp->rmb = idnlookup(mb->val, Cin, 1);
                } else {
                        snprint(mailbox, sizeof mailbox, "%s.%s",
                                mb->val, ns->val);
-                       rp->rmb = dnlookup(mailbox, Cin, 1);
+                       rp->rmb = idnlookup(mailbox, Cin, 1);
                }
        else {
                snprint(mailbox, sizeof mailbox, "postmaster.%s", ns->val);
-               rp->rmb = dnlookup(mailbox, Cin, 1);
+               rp->rmb = idnlookup(mailbox, Cin, 1);
        }
 
        /*
@@ -511,7 +529,7 @@ srvrr(Ndbtuple *entry, Ndbtuple *pair)
        RR *rp;
 
        rp = rralloc(Tsrv);
-       rp->host = dnlookup(pair->val, Cin, 1);
+       rp->host = idnlookup(pair->val, Cin, 1);
        rp->srv->pri = intval(entry, pair, "pri", 0);
        rp->srv->weight = intval(entry, pair, "weight", 0);
        /* TODO: translate service name to port # */
@@ -530,7 +548,7 @@ look(Ndbtuple *entry, Ndbtuple *line, char *attr)
 
        /* first look on same line (closer binding) */
        for(nt = line;;){
-               if(cistrcmp(attr, nt->attr) == 0)
+               if(strcmp(attr, nt->attr) == 0)
                        return nt;
                nt = nt->line;
                if(nt == line)
@@ -538,7 +556,7 @@ look(Ndbtuple *entry, Ndbtuple *line, char *attr)
        }
        /* search whole tuple */
        for(nt = entry; nt; nt = nt->entry)
-               if(cistrcmp(attr, nt->attr) == 0)
+               if(strcmp(attr, nt->attr) == 0)
                        return nt;
        return 0;
 }
@@ -588,33 +606,35 @@ dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair)
        static ulong ord;
 
        rp = 0;
-       if(cistrcmp(pair->attr, "ip") == 0 ||
-          cistrcmp(pair->attr, "ipv6") == 0){
+       if(strcmp(pair->attr, "ip") == 0 ||
+          strcmp(pair->attr, "ipv6") == 0) {
                dp->ordinal = ord++;
                rp = addrrr(entry, pair);
-       } else  if(cistrcmp(pair->attr, "ns") == 0)
+       }
+       else if(strcmp(pair->attr, "ns") == 0)
                rp = nsrr(entry, pair);
-       else if(cistrcmp(pair->attr, "soa") == 0) {
+       else if(strcmp(pair->attr, "soa") == 0) {
                rp = soarr(entry, pair);
                addarea(dp, rp, pair);
-       } else if(cistrcmp(pair->attr, "mx") == 0)
+       }
+       else if(strcmp(pair->attr, "mx") == 0)
                rp = mxrr(entry, pair);
-       else if(cistrcmp(pair->attr, "srv") == 0)
+       else if(strcmp(pair->attr, "srv") == 0)
                rp = srvrr(entry, pair);
-       else if(cistrcmp(pair->attr, "cname") == 0)
+       else if(strcmp(pair->attr, "cname") == 0)
                rp = cnamerr(entry, pair);
-       else if(cistrcmp(pair->attr, "nullrr") == 0)
+       else if(strcmp(pair->attr, "nullrr") == 0)
                rp = nullrr(entry, pair);
-       else if(cistrcmp(pair->attr, "txtrr") == 0)
+       else if(strcmp(pair->attr, "txtrr") == 0)
                rp = txtrr(entry, pair);
        if(rp == nil)
                return;
 
        rp->owner = dp;
-       dnagenever(dp, 1);
        rp->db = 1;
        rp->ttl = intval(entry, pair, "ttl", rp->ttl);
        rrattach(rp, Notauthoritative);
+       dnagenever(dp);
 }
 static void
 dbtuple2cache(Ndbtuple *t)
@@ -624,7 +644,7 @@ dbtuple2cache(Ndbtuple *t)
 
        for(et = t; et; et = et->entry)
                if(strcmp(et->attr, "dom") == 0){
-                       dp = dnlookup(et->val, Cin, 1);
+                       dp = idnlookup(et->val, Cin, 1);
 
                        /* first same line */
                        for(nt = et->line; nt != et; nt = nt->line){
@@ -756,14 +776,6 @@ db2cache(int doit)
        unlock(&dblock);
 }
 
-void
-dnforceage(void)
-{
-       lock(&dblock);
-       dnageall(1);
-       unlock(&dblock);
-}
-
 extern char    mntpt[Maxpath];         /* net mountpoint */
 static uchar   ipaddr[IPaddrlen];      /* my ip address */
 
@@ -795,64 +807,50 @@ lookupinfo(char *attr)
        return t;
 }
 
-char *localservers =     "local#dns#servers";
-char *localserverprefix = "local#dns#server";
-
 /*
  *  return non-zero if this is a bad delegation
  */
 int
 baddelegation(RR *rp, RR *nsrp, uchar *addr)
 {
-       Ndbtuple *nt;
        static int whined;
        static Ndbtuple *t;
+       Ndbtuple *nt;
 
-       if(t == nil)
-               t = lookupinfo("dom");
-       if(t == nil)
+       if(rp->type != Tns)
                return 0;
 
-       for(; rp; rp = rp->next){
-               if(rp->type != Tns)
-                       continue;
-
-               /* see if delegation is looping */
-               if(nsrp)
-               if(rp->owner != nsrp->owner)
-               if(subsume(rp->owner->name, nsrp->owner->name) &&
-                  strcmp(nsrp->owner->name, localservers) != 0){
-                       dnslog("delegation loop %R -> %R from %I",
-                               nsrp, rp, addr);
-                       return 1;
-               }
-
+       if(t == nil)
+               t = lookupinfo("dom");
+       if(t != nil){
                /* see if delegating to us what we don't own */
                for(nt = t; nt != nil; nt = nt->entry)
                        if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
                                break;
+
                if(nt != nil && !inmyarea(rp->owner->name)){
                        if (!whined) {
                                whined = 1;
-                               dnslog("bad delegation %R from %I; "
-                                       "no further logging of them", rp, addr);
+                               dnslog("bad delegation %R from %I/%s; "
+                                       "no further logging of them",
+                                       rp, addr, nsrp->host->name);
                        }
                        return 1;
                }
        }
-
        return 0;
 }
 
 int
 myaddr(char *addr)
 {
-       char *name, *line, *sp;
+       char *line, *sp;
        char buf[64];
        Biobuf *bp;
 
        if(ipcmp(ipaddr, IPnoaddr) == 0)
-               return -1;
+               if(myipaddr(ipaddr, mntpt) < 0)
+                       return -1;
 
        snprint(buf, sizeof buf, "%I", ipaddr);
        if (strcmp(addr, buf) == 0) {
@@ -860,9 +858,8 @@ myaddr(char *addr)
                return 1;
        }
 
-       name = smprint("%s/ipselftab", mntpt);
-       bp = Bopen(name, OREAD);
-       free(name);
+       snprint(buf, sizeof buf, "%s/ipselftab", mntpt);
+       bp = Bopen(buf, OREAD);
        if (bp != nil) {
                while ((line = Brdline(bp, '\n')) != nil) {
                        line[Blinelen(bp) - 1] = '\0';
@@ -912,15 +909,15 @@ addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
 
        /* ns record for name server, make up an impossible name */
        rp = rralloc(Tns);
-       snprint(buf, sizeof buf, "%s%d", localserverprefix, i);
+       snprint(buf, sizeof buf, "local#dns#server%d", i);
        nsdp = dnlookup(buf, class, 1);
        rp->host = nsdp;
        rp->owner = dp;                 /* e.g., local#dns#servers */
        rp->local = 1;
        rp->db = 1;
-//     rp->ttl = 10*Min;               /* seems too short */
-       rp->ttl = (1UL<<31)-1;
+       rp->ttl = 10*Min;
        rrattach(rp, Authoritative);    /* will not attach rrs in my area */
+       dnagenever(dp);
 
        /* A or AAAA record */
        if (parseip(ip, ipaddr) >= 0 && isv4(ip))
@@ -931,9 +928,9 @@ addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
        rp->owner = nsdp;
        rp->local = 1;
        rp->db = 1;
-//     rp->ttl = 10*Min;               /* seems too short */
-       rp->ttl = (1UL<<31)-1;
+       rp->ttl = 10*Min;
        rrattach(rp, Authoritative);    /* will not attach rrs in my area */
+       dnagenever(nsdp);
 
        dnslog("added local dns server %s at %s", buf, ipaddr);
 }
@@ -952,7 +949,7 @@ dnsservers(int class)
        RR *nsrp;
        DN *dp;
 
-       dp = dnlookup(localservers, class, 1);
+       dp = dnlookup("local#dns#servers", class, 1);
        nsrp = rrlookup(dp, Tns, NOneg);
        if(nsrp != nil)
                return nsrp;
@@ -990,6 +987,7 @@ addlocaldnsdomain(DN *dp, int class, char *domain)
        rp->db = 1;
        rp->ttl = 10*Min;
        rrattach(rp, Authoritative);
+       dnagenever(dp);
 }
 
 /*
@@ -1033,7 +1031,7 @@ createv4ptrs(void)
 {
        int len, dlen, n;
        char *dom;
-       char buf[Domlen+1], ipa[48];
+       char buf[Domlen], ipa[48];
        char *f[40];
        uchar net[IPaddrlen], mask[IPaddrlen];
        Area *s;
@@ -1048,8 +1046,7 @@ createv4ptrs(void)
                        continue;
 
                /* get mask and net value */
-               strncpy(buf, dom, sizeof buf);
-               buf[sizeof buf-1] = 0;
+               nstrcpy(buf, dom, sizeof buf);
                /* buf contains something like 178.204.in-addr.arpa (n==4) */
                n = getfields(buf, f, nelem(f), 0, ".");
                memset(mask, 0xff, IPaddrlen);
@@ -1133,7 +1130,7 @@ createv6ptrs(void)
 {
        int len, dlen, i, n, pfxnibs;
        char *dom;
-       char buf[Domlen+1];
+       char buf[Domlen];
        char *f[40];
        uchar net[IPaddrlen], mask[IPaddrlen];
        uchar nibnet[IPaddrlen*2], nibmask[IPaddrlen*2];
@@ -1148,8 +1145,7 @@ createv6ptrs(void)
                        continue;
 
                /* get mask and net value */
-               strncpy(buf, dom, sizeof buf);
-               buf[sizeof buf-1] = 0;
+               nstrcpy(buf, dom, sizeof buf);
                /* buf contains something like 2.0.0.2.ip6.arpa (n==6) */
                n = getfields(buf, f, nelem(f), 0, ".");
                pfxnibs = n - 2;                /* 2 for .ip6.arpa */
@@ -1246,18 +1242,17 @@ insidens(uchar *ip)
        return 0;
 }
 
-uchar *
-outsidens(int n)
+int
+outsidensip(int n, uchar *ip)
 {
        int i;
        Ndbtuple *t;
-       static uchar ipa[IPaddrlen];
 
        i = 0;
        for (t = outnmsrvs; t != nil; t = t->entry)
                if (strcmp(t->attr, "ip") == 0 && i++ == n) {
-                       parseip(ipa, t->val);
-                       return ipa;
+                       parseip(ip, t->val);
+                       return 0;
                }
-       return nil;
+       return -1;
 }