|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.