1: #ifndef lint
   2: static char sccsid[] = "@(#)ns_init.c	4.3 (Berkeley) 6/4/86";
   3: #endif
   4: 
   5: /*
   6:  * Copyright (c) 1986 Regents of the University of California
   7:  *	All Rights Reserved
   8:  */
   9: 
  10: #include <sys/types.h>
  11: #include <sys/socket.h>
  12: #include <sys/time.h>
  13: #include <netinet/in.h>
  14: #include <stdio.h>
  15: #include <errno.h>
  16: #include <signal.h>
  17: #include <syslog.h>
  18: #include <ctype.h>
  19: #include <arpa/nameser.h>
  20: #include "ns.h"
  21: #include "db.h"
  22: 
  23: struct  zoneinfo zones[MAXZONES];   /* zone information */
  24: int nzones;             /* number of zones in use */
  25: 
  26: /*
  27:  * Read boot file for configuration info.
  28:  */
  29: ns_init(bootfile)
  30:     char *bootfile;
  31: {
  32:     register struct zoneinfo *zp;
  33:     char buf[BUFSIZ];
  34:     char *tm;
  35:     FILE *fp;
  36:     int type, first = 1;
  37:     time_t next_refresh;
  38:     struct itimerval ival;
  39: 
  40: #ifdef DEBUG
  41:     if (debug >= 3)
  42:         fprintf(ddt,"ns_init(%s)\n", bootfile);
  43: #endif
  44: 
  45:     if ((fp = fopen(bootfile, "r")) == NULL) {
  46:         syslog(LOG_ERR, "%s: %m", bootfile);
  47:         exit(1);
  48:     }
  49: 
  50:     /* allocate root hash table */
  51:     hashtab = savehash((struct hashbuf *)NULL);
  52: 
  53:     /* init zone data */
  54:     nzones = 1;     /* zone zero is cache data */
  55:     while (getword(buf, sizeof(buf), fp)) {
  56:         /* read 'primary', 'secondary', 'cache' or 'domain' */
  57:     top:
  58:         if (cistrcmp(buf, "cache") == 0) {
  59:             type = Z_CACHE;
  60:             zp = zones;
  61:         } else {
  62:             if (cistrcmp(buf, "primary") == 0)
  63:                 type = Z_PRIMARY;
  64:             else if (cistrcmp(buf, "secondary") == 0)
  65:                 type = Z_SECONDARY;
  66:             else if (cistrcmp(buf, "domain") == 0)
  67:                 type = Z_DOMAIN;
  68:             else {
  69:                 syslog(LOG_ERR, "%s: unknown type", buf);
  70:                 exit(1);
  71:             }
  72:             if (nzones >= MAXZONES) {
  73:                 syslog(LOG_ERR, "too many zones");
  74:                 exit(1);
  75:             }
  76:             zp = &zones[nzones++];
  77:         }
  78:         zp->z_type = type;
  79:         zp->z_addrcnt = 0;
  80:         /*
  81: 		 * read zone origin
  82: 		 */
  83:         (void) getword(buf, sizeof(buf), fp);
  84:         if (buf[0] == '.')
  85:             buf[0] = '\0';
  86:         zp->z_origin = savestr(buf);
  87:         /*
  88: 		 * read source file or host address
  89: 		 */
  90:         if (type != Z_DOMAIN) {
  91:             (void) getword(buf, sizeof(buf), fp);
  92:             zp->z_source = savestr(buf);
  93: #ifdef DEBUG
  94:             if (debug) {
  95:                 fprintf(ddt,"zone found (%d): ", zp->z_type);
  96:                 if (zp->z_origin[0] == '\0')
  97:                     fprintf(ddt,"'.'");
  98:                 else
  99:                     fprintf(ddt,"'%s'", zp->z_origin);
 100:                 fprintf(ddt,", source = %s", zp->z_source);
 101:             }
 102: #endif
 103:         }
 104: #ifdef DEBUG
 105:         else if (debug)
 106:             fprintf(ddt,"zone found (%d): domain name = '%s'",
 107:                 zp->z_type, zp->z_origin);
 108: #endif
 109:         switch (zp->z_type) {
 110:         case Z_PRIMARY:
 111:         case Z_CACHE:
 112: #ifdef DEBUG
 113:             if (debug)
 114:                 fprintf(ddt,"\n");
 115: #endif
 116:             (void) db_load(zp->z_source, zp->z_origin, zp - zones);
 117:             break;
 118: 
 119:         case Z_SECONDARY:
 120:             zp->z_addr[zp->z_addrcnt].s_addr =
 121:                 inet_addr(zp->z_source);
 122:             if (zp->z_addr[zp->z_addrcnt].s_addr != (unsigned)-1)
 123:                     zp->z_addrcnt++;
 124:             while (getword(buf, sizeof(buf), fp)) {
 125:                 tm = savestr(buf);
 126:                 zp->z_addr[zp->z_addrcnt].s_addr =
 127:                     inet_addr(tm);
 128:                 if (zp->z_addr[zp->z_addrcnt].s_addr ==
 129:                         (unsigned)-1) {
 130: #ifdef DEBUG
 131:                     if (debug)
 132:                         fprintf(ddt," (addrcnt) = %d\n",
 133:                             zp->z_addrcnt);
 134: #endif
 135:                     zoneinit(zp);
 136:                     if (first) {
 137:                         next_refresh = zp->z_time;
 138:                         first = 0;
 139:                     } else
 140:                         if (next_refresh > zp->z_time)
 141:                         next_refresh = zp->z_time;
 142:                     goto top;
 143:                 }
 144: #ifdef DEBUG
 145:                 if (debug)
 146:                     fprintf(ddt,", %s",buf);
 147: #endif
 148:                 if (++zp->z_addrcnt >= MAXNS) {
 149:                     zp->z_addrcnt = MAXNS;
 150: #ifdef DEBUG
 151:                     if (debug)
 152:                         fprintf(ddt,
 153:                         "\nns.h MAXNS reached\n");
 154: #endif
 155:                     break;
 156:                 }
 157:             }
 158: #ifdef DEBUG
 159:             if (debug)
 160:                 fprintf(ddt," addrcnt = %d\n", zp->z_addrcnt);
 161: #endif
 162:             zoneinit(zp);
 163:             if (first) {
 164:                 next_refresh = zp->z_time;
 165:                 first = 0;
 166:             } else
 167:                 if (next_refresh > zp->z_time)
 168:                     next_refresh = zp->z_time;
 169:             break;
 170: 
 171:         case Z_DOMAIN:
 172:             while (getword(buf, sizeof(buf), fp)) {
 173:                 tm = savestr(buf);
 174:                 zp->z_addr[zp->z_addrcnt].s_addr =
 175:                     inet_addr(tm);
 176:                 if (zp->z_addr[zp->z_addrcnt].s_addr ==
 177:                         (unsigned)-1) {
 178: #ifdef DEBUG
 179:                     if (debug)
 180:                         fprintf(ddt," addrcnt = %d\n",
 181:                             zp->z_addrcnt);
 182: #endif
 183:                     goto top;
 184:                 }
 185: #ifdef DEBUG
 186:                 if (debug)
 187:                     fprintf(ddt,", %s",buf);
 188: #endif
 189:                 if (++zp->z_addrcnt >= MAXNS) {
 190:                     zp->z_addrcnt = MAXNS;
 191: #ifdef DEBUG
 192:                     if (debug)
 193:                        fprintf(ddt,"\nns.h MAXNS reached\n");
 194: #endif
 195:                     break;
 196:                 }
 197:             }
 198: #ifdef DEBUG
 199:             if (debug)
 200:                 fprintf(ddt," addrcnt = %d\n",
 201:                     zp->z_addrcnt);
 202: #endif
 203:             break;
 204: 
 205:         }
 206:     }
 207:     (void) fclose(fp);
 208:     if (!first) {
 209:         if (gettimeofday(&tt, (struct timezone *)0) < 0) {
 210:             syslog(LOG_ERR, "gettimeofday failed: %m");
 211:             ival.it_value.tv_sec = 5 * 60;
 212:         } else {
 213:             bzero((char *)&ival, sizeof(ival));
 214:             ival.it_value.tv_sec = next_refresh - tt.tv_sec;
 215:             if (ival.it_value.tv_sec < 0)
 216:                 ival.it_value.tv_sec = 60;
 217:         }
 218:     } else
 219:         ival.it_value.tv_sec = 0;
 220:     (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
 221: #if DEBUG
 222:     if (debug)
 223:         fprintf(ddt,"exit ns_init() Next interupt in %d sec\n",
 224:             ival.it_value.tv_sec);
 225: #endif
 226: }
 227: 
 228: zoneinit(zp)
 229:     struct zoneinfo *zp;
 230: {
 231:     struct sockaddr_in sin;
 232:     HEADER *hp;
 233:     char buf[PACKETSZ];
 234:     u_short len;
 235:     char *cp;
 236:     char *tmp;
 237:     int s, n, l;
 238:     int cnt, soacnt, error = 0;
 239:     int zone = zp - zones;
 240:     u_long serial;
 241:     struct itimerval ival;
 242:     struct itimerval zeroival;
 243:     extern struct sockaddr_in nsaddr;
 244:     extern int errno;
 245:     extern int read_alarm();
 246:     struct sigvec sv, osv;
 247:     extern int read_interrupted;
 248: 
 249: #ifdef DEBUG
 250:     if (debug)
 251:         fprintf(ddt,"zoneinit()\n");
 252: #endif
 253: 
 254:     bzero((char *)&zeroival, sizeof(zeroival));
 255:     ival = zeroival;
 256:     ival.it_value.tv_sec = 2 * 60;
 257:     sv.sv_handler = read_alarm;
 258:     sv.sv_onstack = 0;
 259:     sv.sv_mask = ~0;
 260:     (void) sigvec(SIGALRM, &sv, &osv);
 261: 
 262:     for( cnt = 0; cnt < zp->z_addrcnt; cnt++) {
 263:         error = 0;
 264:         bzero((char *)&sin, sizeof(sin));
 265:         sin.sin_family = AF_INET;
 266:         sin.sin_port = nsaddr.sin_port;
 267:         sin.sin_addr = zp->z_addr[cnt];
 268:         if ((n = res_mkquery(QUERY, zp->z_origin, C_IN, T_AXFR,
 269:             (char *)NULL, 0, NULL, buf, sizeof(buf))) < 0) {
 270:             syslog(LOG_ERR, "zoneinit: res_mkquery failed");
 271:             (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 272:             return;
 273:         }
 274:         if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 275:             syslog(LOG_ERR, "zoneref: socket: %m");
 276:             exit(1);
 277:         }
 278: #ifdef DEBUG
 279:         if (debug >= 2) {
 280:             fprintf(ddt,"connecting to server #%d %s, %d (%d)\n",
 281:                 cnt+1, inet_ntoa(sin.sin_addr),
 282:                 ntohs(sin.sin_port), n);
 283:         }
 284: #endif
 285:         if (connect(s, &sin, sizeof(sin)) < 0) {
 286:             (void) close(s);
 287:             error++;
 288: #ifdef DEBUG
 289:             if (debug >= 2)
 290:                 fprintf(ddt,"connect failed\n");
 291: #endif
 292:             continue;
 293:         }
 294:         /*
 295: 	 	 * Send length & message for zone transfer
 296: 	 	 */
 297:         if (writemsg(s, buf, n) < 0) {
 298:             (void) close(s);
 299:             error++;
 300: #ifdef DEBUG
 301:             if (debug >= 2)
 302:                 fprintf(ddt,"writemsg failed\n");
 303: #endif
 304:             continue;
 305:         }
 306: 
 307:         hp = (HEADER *) buf;
 308:         soacnt = 0;
 309: 
 310:         for (;;) {
 311:             /*
 312: 			 * Receive length & response
 313: 			 */
 314:             cp = buf;
 315:             l = sizeof(u_short);
 316:             read_interrupted = 0;
 317:             while (l > 0) {
 318:                 (void) setitimer(ITIMER_REAL, &ival,
 319:                     (struct itimerval *)NULL);
 320:                 if ((n = recv(s, cp, l, 0)) > 0) {
 321:                     cp += n;
 322:                     l -= n;
 323:                 } else {
 324:                     if (errno == EINTR && !read_interrupted)
 325:                         continue;
 326:                     error++;
 327:                     break;
 328:                 }
 329:             }
 330:             (void) setitimer(ITIMER_REAL, &zeroival,
 331:                 (struct itimerval *)NULL);
 332:             if (error)
 333:                 break;
 334:             if ((len = htons(*(u_short *)buf)) == 0)
 335:                 break;
 336:             l = len;
 337:             cp = buf;
 338:             while (l > 0) {
 339:                 (void) setitimer(ITIMER_REAL, &ival,
 340:                     (struct itimerval *)NULL);
 341:                 if ((n = recv(s, cp, l, 0)) > 0) {
 342:                     cp += n;
 343:                     l -= n;
 344:                 } else {
 345:                     if (errno == EINTR && !read_interrupted)
 346:                         continue;
 347:                     error++;
 348:                     break;
 349:                 }
 350:             }
 351:             (void) setitimer(ITIMER_REAL, &zeroival,
 352:                 (struct itimerval *)NULL);
 353:             if (error)
 354:                 break;
 355: #ifdef DEBUG
 356:             if (debug >= 3) {
 357:                 fprintf(ddt,"len = %d\n", len);
 358:                 fp_query(buf, ddt);
 359:             }
 360: #endif
 361:             cp = buf + sizeof(HEADER);
 362:             if (hp->qdcount)
 363:                 cp += dn_skip(cp) + QFIXEDSZ;
 364:             tmp = cp + dn_skip(cp);
 365:             n = doupdate(buf, sizeof(buf), cp, zone, 0);
 366:             if ((cp - buf) + n != len) {
 367: #ifdef DEBUG
 368:                if (debug)
 369:                          fprintf(ddt,"zoneinit: doupdate failed (%d, %d)\n",
 370:                     cp - buf, n);
 371: #endif
 372:                 error++;
 373:                 break;
 374:             }
 375:             if ((getshort(tmp)) == T_SOA) {
 376:                 if (soacnt == 0) {
 377:                     soacnt++;
 378:                     tmp += 3 * sizeof(u_short)
 379:                         + sizeof(u_long);
 380:                     tmp += dn_skip(tmp);
 381:                     tmp += dn_skip(tmp);
 382:                     serial = getlong(tmp);
 383:                     continue;
 384:                 }
 385:                 soa_zinfo(zp, tmp);
 386:                 if (serial != zp->z_serial)
 387:                      soacnt = 0;
 388:                 else {
 389:                     break;
 390:                 }
 391:             }
 392:         }
 393:         (void) close(s);
 394:         if ( error == 0) {
 395:             (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 396:             return;
 397:         }
 398: #ifdef DEBUG
 399:         if (debug >= 2)
 400:             fprintf(ddt,"error reciving zone transfer\n");
 401: #endif
 402:     }
 403:     /*
 404: 	 *     Freedom at last!!
 405: 	 *
 406: 	 *  The land where all repressed slaves dream of.
 407: 	 *
 408: 	 *  Can't find a master to talk to.
 409: 	 *  syslog it and hope we can find a master during maintenance
 410: 	 */
 411:     if (error)
 412:         syslog(LOG_ERR, "zoneinit: Can't find Master for secondary zone %s",
 413:         zp->z_origin);
 414:     /*
 415: 	 * Set zone to be refreshed in 5 min.
 416: 	 *	maybe by then we can refresh it.
 417: 	 */
 418:     zp->z_refresh = 300; /* 300 seconds = 5 Min. */
 419:     zp->z_retry = 300;
 420:     if (gettimeofday(&tt, (struct timezone *)0) < 0)
 421:         syslog(LOG_ERR, "gettimeofday failed: %m");
 422:     zp->z_time = tt.tv_sec + 300;
 423:     (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 424:     return;
 425: }
 426: #ifdef notdef
 427: /*
 428:  * Look for an authoritative zone that matches the RHS of dname
 429:  * and return is zone # or zero if not found.
 430:  */
 431: findzone(dname, class)
 432:     char *dname;
 433:     int class;
 434: {
 435:     register struct zoneinfo *zp;
 436:     register char *d1, *d2;
 437:     register int c;
 438:     char *end;
 439: 
 440:     end = dname + strlen(dname);
 441:     for (zp = &zones[1]; zp < &zones[nzones]; zp++) {
 442:         d1 = end;
 443:         d2 = zp->z_origin + strlen(zp->z_origin);
 444:         while (d2 > zp->z_origin) {
 445:             if ((c*--
 446:         }
 447:         return (zp - zones);
 448:     }
 449:     return (0);
 450: }
 451: #endif
 452: 
 453: soa_zinfo(zp, cp)
 454:     struct zoneinfo *zp;
 455:     char *cp;
 456: {
 457:     cp += 3 * sizeof(u_short);
 458:     cp += sizeof(u_long);
 459:     cp += dn_skip(cp);
 460:     cp += dn_skip(cp);
 461:     zp->z_serial = getlong(cp);
 462:     cp += sizeof(u_long);
 463:     zp->z_refresh = getlong(cp);
 464:     if (gettimeofday(&tt, (struct timezone *)0) < 0)
 465:         syslog(LOG_ERR, "gettimeofday failed: %m");
 466:     zp->z_time = tt.tv_sec + zp->z_refresh;
 467:     cp += sizeof(u_long);
 468:     zp->z_retry = getlong(cp);
 469:     cp += sizeof(u_long);
 470:     zp->z_expire = getlong(cp);
 471:     cp += sizeof(u_long);
 472:     zp->z_minimum = getlong(cp);
 473:     cp += sizeof(u_long);
 474: }

Defined functions

findzone defined in line 431; used 2 times
ns_init defined in line 29; used 2 times
soa_zinfo defined in line 453; used 3 times
zoneinit defined in line 228; used 2 times

Defined variables

nzones defined in line 24; used 10 times
sccsid defined in line 2; never used
zones defined in line 23; used 20 times
Last modified: 1986-06-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1867
Valid CSS Valid XHTML 1.0 Strict