# 2.11BSD#431 - /usr/src/usr.sbin/named/named/db_update.c

##### Functions

    addinv            X
    db_cmp            X
    db_update         X
    dhash             X
    fixttl            X
    rminv             X

##### Variables

    invtab            X
    max_cache_ttl     X
    min_cache_ttl     X

       1: /*
       2:  * Copyright (c) 1986 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  */
      12:
      13: #ifndef lint
      14: static char sccsid[] = "@(#)db_update.c	4.16 (Berkeley) 2/28/88";
      15: #endif /* not lint */
      16:
      17: #include <sys/types.h>
      18: #include <sys/socket.h>
      19: #include <sys/time.h>
      20: #include <netinet/in.h>
      21: #include <stdio.h>
      22: #include <syslog.h>
      23: #include <arpa/nameser.h>
      24: #include "ns.h"
      25: #include "db.h"
      26:
      27: extern struct timeval   tt;
      28: extern FILE *ddt;
      29: extern struct zoneinfo zones[];
      30: extern struct sockaddr_in from_addr;    /* Source addr of last packet */
      31: extern int needs_prime_cache;
      32:
      33: u_long  max_cache_ttl = (7*24*60*60);   /* ONE_WEEK maximum ttl */
      34: u_long  min_cache_ttl = (5*60);     /* 5 minute minimum ttl */
      35:
      36: /*
      37:  * Update data base. Flags control the action.
      38:  * Inverse query tables modified.
      39:  */
      40: db_update(name, odp, newdp, flags, htp)
      41:     char name[];
      42:     struct databuf *odp, *newdp;
      43:     int flags;
      44:     struct hashbuf *htp;
      45: {
      46:     register struct namebuf *np;
      47:     register struct databuf *dp, *pdp;
      48:     char *fname;
      49:         int foundRR = 0;
      50:
      51: #ifdef DEBUG
      52:     if (debug >= 3)
      53:         fprintf(ddt,"db_update(%s, 0x%x, 0x%x, 0%o, 0x%x)%s\n",
      54:             name, odp, newdp, flags, htp,
      55:             (odp && (odp->d_flags&DB_F_HINT)) ? " hint":"" );
      56: #endif
      57:     np = nlookup(name, &htp, &fname, newdp != NULL);
      58:     if (np == NULL || fname != name)
      59:         return (NONAME);
      60:
      61:         /* Reflect certain updates in hint cache also... */
      62:     /* Don't stick data we are authoritative for in hints. */
      63:         if (!(flags & DB_NOHINTS) && (odp != NULL) &&
      64:         (odp->d_zone <= 0) && !(odp->d_flags & DB_F_HINT) &&
      65:             ((name[0] == '\0' && odp->d_type == T_NS) ||
      66:          (odp->d_type == T_A)))
      67:         {
      68:         register struct databuf *dp;
      69: #ifdef DEBUG
      70:         if (debug >= 3)
      71:             fprintf(ddt,"db_update: hint '%s' %ld\n",
      72:                 name, odp->d_ttl);
      73: #endif
      74:         dp = savedata(odp->d_class, odp->d_type, odp->d_ttl,
      75:             odp->d_data, odp->d_size);
      76:         dp->d_zone = DB_Z_CACHE;
      77:         dp->d_flags = DB_F_HINT;
      78:         if (db_update(name, dp,dp, (flags|DB_NOHINTS), fcachetab) != OK) {
      79: #ifdef DEBUG
      80:             if (debug > 2)
      81:                 fprintf(ddt, "db_update: hint %x freed\n", dp);
      82: #endif
      83:             (void) free((char *)dp);
      84:         }
      85:         }
      86:
      87:     if (odp != NULL) {
      88:         pdp = NULL;
      89:         for (dp = np->n_data; dp != NULL; ) {
      90:             if (!match(dp, odp->d_class, odp->d_type)) {
      91:                 if ((dp->d_type == T_CNAME ||
      92:                     odp->d_type == T_CNAME) &&
      93:                     zones[odp->d_zone].z_type != Z_CACHE) {
      94:                     syslog(LOG_ERR,
      95:                 "%s has CNAME and other data (illegal)\n",
      96:                         name);
      97: #ifdef DEBUG
      98:                     if (debug)
      99:                         fprintf(ddt,
     100:                 "db_update: %s: CNAME and more (%d, %d)\n",
     101:                         name, odp->d_type, dp->d_type);
     102: #endif
     103:                 }
     104:                 goto skip;
     105:             }
     106: #ifdef DEBUG
     107:             if (debug >= 5)
     108:                 fprintf(ddt,"db_update: flags = %x, sizes = %d, %d (%d)\n",
     109:                     flags, odp->d_size, dp->d_size,
     110:                     db_cmp(dp, odp));
     111: #endif
     112:             if (flags & DB_NOTAUTH && dp->d_zone) {
     113: #ifdef DEBUG
     114:                 if (debug)
     115:                     fprintf(ddt,
     116:                     "%s attempted update to auth zone %d '%s'\n",
     117:                     inet_ntoa(from_addr.sin_addr),
     118:                     dp->d_zone, zones[dp->d_zone].z_origin);
     119: #endif
     120:                 return (AUTH);
     121:             }
     122:             if ((flags & DB_NODATA) && !db_cmp(dp, odp)) {
     123:                 /* refresh ttl if cache entry */
     124:                 if (dp->d_zone == 0) {
     125:                     fixttl(odp);
     126:                     if (odp->d_ttl > dp->d_ttl)
     127:                         dp->d_ttl = odp->d_ttl;
     128: #ifdef DEBUG
     129:                         if (debug >= 3)
     130:                         fprintf(ddt,"db_update: new ttl %ld, +%ld\n",
     131:                                 dp->d_ttl, dp->d_ttl - tt.tv_sec);
     132: #endif
     133:                 }
     134:                 return (DATAEXISTS);
     135:             }
     136:             /*
     137: 			 * If the old databuf has some data, check that the
     138: 			 * data matches that in the new databuf (so UPDATED
     139: 			 * will delete only the matching RR)
     140: 			 */
     141:             if (odp->d_size > 0) {
     142:                 if (db_cmp(dp, odp))
     143:                     goto skip;
     144:             }
     145:             foundRR = 1;
     146:             if (flags & DB_DELETE)
     147:                 dp = rm_datum(dp, np, pdp);
     148:             else {
     149: skip:               pdp = dp;
     150:                 dp = dp->d_next;
     151:             }
     152:         }
     153:                 if (!foundRR) {
     154:             if (flags & DB_DELETE)
     155:                 return(NODATA);
     156:             if (flags & DB_MEXIST)
     157:                 return(NODATA);
     158:         }
     159:     }
     160:     if (newdp == NULL)
     161:         return (OK);
     162:     fixttl(newdp);
     163: #ifdef DEBUG
     164:         if (debug >= 3)
     165:             fprintf(ddt,"db_update: adding%s %x\n",
     166:             (newdp->d_flags&DB_F_HINT) ? " hint":"", newdp);
     167: #endif
     168:     if (!(newdp->d_flags & DB_F_HINT))
     169:         addinv(np, newdp);  /* modify inverse query tables */
     170:
     171:     /* Add to end of list, generally preserving order */
     172:     newdp->d_next = NULL;
     173:     if ((dp = np->n_data) == NULL)  {
     174:         np->n_data = newdp;
     175:         return (OK);
     176:     }
     177:     /* XXX: need to check for duplicate WKS records and flag error */
     178:     while (dp->d_next != NULL) {
     179:         if ((flags & DB_NODATA) && !db_cmp(dp, newdp))
     180:             return (DATAEXISTS);
     181:         dp = dp->d_next;
     182:     }
     183:     if ((flags & DB_NODATA) && !db_cmp(dp, newdp))
     184:         return (DATAEXISTS);
     185:     dp->d_next = newdp;
     186:     return (OK);
     187: }
     188:
     189: fixttl(dp)
     190: register struct databuf *dp;
     191: {
     192:     if (dp->d_zone == 0 && !(dp->d_flags & DB_F_HINT)) {
     193:         if (dp->d_ttl <= tt.tv_sec)
     194:             return;
     195:         else if (dp->d_ttl < tt.tv_sec+min_cache_ttl)
     196:             dp->d_ttl = tt.tv_sec+min_cache_ttl;
     197:         else if (dp->d_ttl > tt.tv_sec+max_cache_ttl)
     198:             dp->d_ttl = tt.tv_sec+max_cache_ttl;
     199:     }
     200:     return;
     201: }
     202:
     203: struct invbuf *invtab[INVHASHSZ];   /* Inverse query hash table */
     204:
     205: /*
     206:  * Add data 'dp' to inverse query tables for name 'np'.
     207:  */
     208: addinv(np, dp)
     209:     struct namebuf *np;
     210:     struct databuf *dp;
     211: {
     212:     register struct invbuf *ip;
     213:     register int hval, i;
     214:
     215:     switch (dp->d_type) {
     216:     case T_A:
     217:     case T_UID:
     218:     case T_GID:
     219:         break;
     220:
     221:     default:
     222:         return;
     223:     }
     224:
     225:     hval = dhash(dp->d_data, dp->d_size);
     226:     for (ip = invtab[hval]; ip != NULL; ip = ip->i_next)
     227:         for (i = 0; i < INVBLKSZ; i++)
     228:             if (ip->i_dname[i] == NULL) {
     229:                 ip->i_dname[i] = np;
     230:                 return;
     231:             }
     232:     ip = saveinv();
     233:     ip->i_next = invtab[hval];
     234:     invtab[hval] = ip;
     235:     ip->i_dname[0] = np;
     236: }
     237:
     238: /*
     239:  * Remove data 'odp' from inverse query table.
     240:  */
     241: rminv(odp)
     242:     struct databuf *odp;
     243: {
     244:     register struct invbuf *ip;
     245:     register struct databuf *dp;
     246:     struct namebuf *np;
     247:     register int i;
     248:
     249:     for (ip = invtab[dhash(odp->d_data, odp->d_size)]; ip != NULL;
     250:         ip = ip->i_next) {
     251:         for (i = 0; i < INVBLKSZ; i++) {
     252:             if ((np = ip->i_dname[i]) == NULL)
     253:                 break;
     254:             for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
     255:                 if (!match(dp, odp->d_class, odp->d_type))
     256:                     continue;
     257:                 if (db_cmp(dp, odp))
     258:                     continue;
     259:                 while (i < INVBLKSZ-1) {
     260:                     ip->i_dname[i] = ip->i_dname[i+1];
     261:                     i++;
     262:                 }
     263:                 ip->i_dname[i] = NULL;
     264:                 return;
     265:             }
     266:         }
     267:     }
     268: }
     269:
     270: /*
     271:  * Compute hash value from data.
     272:  */
     273: dhash(dp, dlen)
     274:     char *dp;
     275:     int dlen;
     276: {
     277:     register char *cp;
     278:     register unsigned hval;
     279:     register int n;
     280:
     281:     n = dlen;
     282:     if (n > 8)
     283:         n = 8;
     284:     hval = 0;
     285:     for (cp = dp; --n >= 0; ) {
     286:         hval <<= 1;
     287:         hval += *cp++;
     288:     }
     289:     return (hval % INVHASHSZ);
     290: }
     291:
     292: /*
     293:  * Compare data sections from databufs for equivalence.  Must be case
     294:  * insensitive for some domain names.  We assume that they are the
     295:  * same type when they are passed.  Return 0 if equivalent, nonzero
     296:  * otherwise.
     297:  */
     298:
     299: db_cmp(dp1, dp2)
     300:     register struct databuf *dp1, *dp2;
     301:
     302: {
     303:     register char *cp1, *cp2;
     304:     int len;
     305:
     306:     if (dp1->d_size != dp2->d_size)
     307:         return(1);
     308:     if (dp1->d_mark != dp2->d_mark)
     309:         return(1);      /* old and new RR's are distinct */
     310:     switch (dp1->d_type) {
     311:
     312:     case T_A:
     313:     case T_UID:
     314:     case T_GID:
     315:     case T_WKS:
     316:     case T_NULL:
     317: #ifdef ALLOW_T_UNSPEC
     318:         case T_UNSPEC:
     319: #endif ALLOW_T_UNSPEC
     320:         return(bcmp(dp1->d_data, dp2->d_data, dp1->d_size));
     321:
     322:     case T_NS:
     323:     case T_CNAME:
     324:     case T_PTR:
     325:     case T_MB:
     326:     case T_MG:
     327:     case T_MR:
     328:     case T_UINFO:
     329:         return(strcasecmp(dp1->d_data, dp2->d_data));
     330:
     331:     case T_HINFO:
     332:         cp1 = dp1->d_data;
     333:         cp2 = dp2->d_data;
     334:         len = *cp1;
     335:         if (strncasecmp(++cp1, ++cp2, len))
     336:             return(1);
     337:         cp1 += len;
     338:         cp2 += len;
     339:         len = *cp1;
     340:         return(strncasecmp(++cp1, ++cp2, len));
     341:
     342:     case T_SOA:
     343:     case T_MINFO:
     344:         if (strcasecmp(dp1->d_data, dp2->d_data))
     345:             return(1);
     346:         cp1 = dp1->d_data + strlen(dp1->d_data) + 1;
     347:         cp2 = dp2->d_data + strlen(dp2->d_data) + 1;
     348:         if (dp1->d_type != T_SOA)
     349:             return(strcasecmp(cp1, cp2));
     350:         if (strcasecmp(cp1, cp2))
     351:             return(1);
     352:         cp1 += strlen(cp1) + 1;
     353:         cp2 += strlen(cp2) + 1;
     354:         return(bcmp(cp1, cp2, sizeof(u_long) * 5));
     355:
     356:     case T_MX:
     357:         cp1 = dp1->d_data;
     358:         cp2 = dp2->d_data;
     359:         if (*cp1++ != *cp2++ || *cp1++ != *cp2++)   /* cmp prio */
     360:             return(1);
     361:         return(strcasecmp(cp1, cp2));
     362:
     363:     default:
     364:         return (1);
     365:     }
     366: }

#### Defined functions

addinv defined in line 208; used 1 times

- in line 169

db_cmp defined in line 299; used 6 times

- in line 110, 122, 142, 179-183(2), 257

db_update defined in line 40; used 7 times

- in line 78
- in /usr/src/usr.sbin/named/named/db_load.c line 462
- in /usr/src/usr.sbin/named/named/ns_req.c line 1189
- in /usr/src/usr.sbin/named/named/ns_resp.c line 901, 918, 982, 1000

dhash defined in line 273; used 3 times

- in line 225, 249
- in /usr/src/usr.sbin/named/named/ns_req.c line 430

fixttl defined in line 189; used 2 times

- in line 125, 162

rminv defined in line 241; used 1 times

- in /usr/src/usr.sbin/named/named/ns_req.c line 1251

#### Defined variables

invtab defined in line 203; used 10 times

- in line 226, 233-234(2), 249
- in /usr/src/usr.sbin/named/named/db_reload.c line 89
- in /usr/src/usr.sbin/named/named/db_update.c line 226, 233-234(2), 249
- in /usr/src/usr.sbin/named/named/ns_req.c line 430

max_cache_ttl defined in line 33; used 4 times

- in line 197-198(2)
- in /usr/src/usr.sbin/named/named/db_load.c line 225-226(2)

min_cache_ttl defined in line 34; used 2 times

- in line 195-196(2)

sccsid defined in line 14; never used

Last modified: 1988-09-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1988 |