1: #ifndef lint
   2: static char sccsid[] = "@(#)ns_maint.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 <syslog.h>
  16: #include <signal.h>
  17: #include <errno.h>
  18: #include <arpa/nameser.h>
  19: #include "ns.h"
  20: #include "db.h"
  21: 
  22: /*
  23:  * Invoked at regular intervals by signal interrupt; refresh all secondary
  24:  * zones from primary name server and remove old cache entries.
  25:  */
  26: ns_maint()
  27: {
  28:     register struct zoneinfo *zp;
  29:     struct itimerval ival;
  30:     time_t now, next_refresh;
  31:     int first;
  32:     extern errno;
  33: #ifdef DEBUG
  34:     if (debug)
  35:         fprintf(ddt,"ns_maint()\n");
  36: #endif
  37: 
  38: 
  39:     first = 1;
  40:     for (zp = zones; zp < &zones[nzones]; zp++) {
  41:         if (zp->z_type != Z_SECONDARY)
  42:             continue;
  43:         if (gettimeofday(&tt, (struct timezone *)0) < 0)
  44:             syslog(LOG_ERR, "gettimeofday failed: %m");
  45:         now = tt.tv_sec;
  46: #ifdef DEBUG
  47:         if (debug >=2) {
  48:             if (zp->z_origin[0] == '\0')
  49:                 fprintf(ddt,"origin ='.'");
  50:             else
  51:                 fprintf(ddt,"origin ='%s'", zp->z_origin);
  52:             fprintf(ddt,", source = %s\n", zp->z_source);
  53:             fprintf(ddt,"z_refresh = %ld", zp->z_refresh);
  54:             fprintf(ddt,", retry = %ld", zp->z_retry);
  55:             fprintf(ddt,", expire = %ld", zp->z_expire);
  56:             fprintf(ddt,", minimum = %ld", zp->z_minimum);
  57:             fprintf(ddt,", serial = %ld\n", zp->z_serial);
  58:             fprintf(ddt,"z_time = %d", zp->z_time);
  59:             fprintf(ddt,", now time : %d sec", now);
  60:             fprintf(ddt,", time left: %d sec\n", zp->z_time - now);
  61:         }
  62: #endif
  63:         if (now >= zp->z_time) {
  64:             zoneref(zp);
  65:             zp->z_time = tt.tv_sec + zp->z_refresh;
  66:         }
  67:         /*
  68: 		 * Find when the next refresh needs to be and set
  69: 		 * interupt time accordingly.
  70: 		 * Why have needless intruptions.
  71: 		 * 	I just hate it when the cleaning crew come early.
  72: 		 */
  73:         if (first) {
  74:             next_refresh = zp->z_time;
  75:             first = 0;
  76:         }
  77:         else if (next_refresh > zp->z_time)
  78:             next_refresh = zp->z_time;
  79:     }
  80:     /*
  81: 	 * If first is still true, no secondary zones were found
  82: 	 *   therefore refreshes aren't needed and interupts are turned off
  83: 	 * This needs to be changed when we have refreshes for co-masters
  84: 	 */
  85:     if (!first) {
  86:         bzero((char *)&ival, sizeof (ival));
  87:         ival.it_value.tv_sec = next_refresh - now;
  88:         if (ival.it_value.tv_sec < 0)
  89:             ival.it_value.tv_sec = 60;
  90:         (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
  91: #ifdef DEBUG
  92:         if (debug)
  93:             fprintf(ddt,"exit ns_maint() Next interupt in %d sec\n",
  94:                 ival.it_value.tv_sec);
  95: #endif
  96:     }
  97: }
  98: 
  99: zoneref(zp)
 100:     struct zoneinfo *zp;
 101: {
 102:     register struct databuf *dp;
 103:     HEADER *hp;
 104:     u_short len;
 105:     u_long serial;
 106:     int s, n, l;
 107:     int cnt, soacnt, error = 0;
 108:     int zone = zp - zones;
 109:     char *cp;
 110:     char *tmp;
 111:     char *fname;
 112:     char buf[PACKETSZ];
 113:     struct sockaddr_in sin;
 114:     struct zoneinfo zp_start, zp_finish;
 115:     struct databuf *pdp, *tdp;
 116:     struct namebuf *np;
 117:     struct hashbuf *htp;
 118:     struct itimerval ival;
 119:     struct itimerval zeroival;
 120:     extern struct sockaddr_in nsaddr;
 121:     extern int errno;
 122:     extern int read_interrupted;
 123:     extern int read_alarm();
 124:     struct sigvec sv, osv;
 125: 
 126: #ifdef DEBUG
 127:     if (debug)
 128:         fprintf(ddt,"zoneref()\n");
 129: #endif
 130:     bzero((char *)&zeroival, sizeof(zeroival));
 131:     ival = zeroival;
 132:     ival.it_value.tv_sec = 30;
 133:     sv.sv_handler = read_alarm;
 134:     sv.sv_onstack = 0;
 135:     sv.sv_mask = ~0;
 136:     (void) sigvec(SIGALRM, &sv, &osv);
 137: 
 138:     for( cnt = 0; cnt < zp->z_addrcnt; cnt++) {
 139:         error = 0;
 140:         bzero((char *)&sin, sizeof(sin));
 141:         sin.sin_family = AF_INET;
 142:         sin.sin_port = nsaddr.sin_port;
 143:         sin.sin_addr = zp->z_addr[cnt];
 144:         if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 145:             syslog(LOG_ERR, "zoneref: socket: %m");
 146:             exit(1);
 147:         }
 148: #ifdef DEBUG
 149:         if (debug >= 2) {
 150:             fprintf(ddt,"connecting to server #%d %s, %d\n",
 151:                cnt+1, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
 152:         }
 153: #endif
 154:         if (connect(s, &sin, sizeof(sin)) < 0) {
 155:             (void) close(s);
 156:             error++;
 157: #ifdef DEBUG
 158:             if (debug >= 2)
 159:                 fprintf(ddt,"connect failed\n");
 160: #endif
 161:             continue;
 162:         }
 163:         if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,
 164:             T_SOA, (char *)NULL, 0, NULL, buf, sizeof(buf))) < 0) {
 165:                 syslog(LOG_ERR, "zoneref: res_mkquery failed");
 166:             (void) close(s);
 167:             (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 168:                 return;
 169:         }
 170:         /*
 171: 	 	 * Send length & message for zone transfer
 172: 	 	 */
 173:         if (writemsg(s, buf, n) < 0) {
 174:             (void) close(s);
 175:             error++;
 176: #ifdef DEBUG
 177:             if (debug >= 2)
 178:                 fprintf(ddt,"writemsg failed\n");
 179: #endif
 180:             continue;
 181:         }
 182:         /*
 183: 		 * Get out your butterfly net and catch the SOA
 184: 		 */
 185:         cp = buf;
 186:         l = sizeof(u_short);
 187:         read_interrupted = 0;
 188:         while (l > 0) {
 189:             (void) setitimer(ITIMER_REAL, &ival,
 190:                 (struct itimerval *)NULL);
 191:             if ((n = recv(s, cp, l, 0)) > 0) {
 192:                 cp += n;
 193:                 l -= n;
 194:             } else {
 195:                 if (errno == EINTR && !read_interrupted)
 196:                     continue;
 197:                 error++;
 198:                 break;
 199:             }
 200:         }
 201:         (void) setitimer(ITIMER_REAL, &zeroival,
 202:             (struct itimerval *)NULL);
 203:         if (error) {
 204:             (void) close(s);
 205:             continue;
 206:         }
 207:         if ((len = htons(*(u_short *)buf)) == 0) {
 208:             (void) close(s);
 209:             continue;
 210:         }
 211:         l = len;
 212:         cp = buf;
 213:         while (l > 0) {
 214:             (void) setitimer(ITIMER_REAL, &ival,
 215:                 (struct itimerval *)NULL);
 216:             if ((n = recv(s, cp, l, 0)) > 0) {
 217:                 cp += n;
 218:                 l -= n;
 219:             } else {
 220:                 if (errno == EINTR && !read_interrupted)
 221:                     continue;
 222:                 error++;
 223:                 break;
 224:             }
 225:         }
 226:         (void) setitimer(ITIMER_REAL, &zeroival,
 227:             (struct itimerval *)NULL);
 228:         if (error) {
 229:             (void) close(s);
 230:             continue;
 231:         }
 232: #ifdef DEBUG
 233:         if (debug >= 3) {
 234:             fprintf(ddt,"len = %d\n", len);
 235:             fp_query(buf, ddt);
 236:         }
 237: #endif DEBUG
 238:         zp_start = *zp;
 239:         tmp = buf + sizeof(HEADER);
 240:         tmp += dn_skip(tmp) + QFIXEDSZ;
 241:         tmp += dn_skip(tmp);
 242:         soa_zinfo(&zp_start, tmp);
 243:         if (zp->z_serial >= zp_start.z_serial)  {
 244:             (void) close(s);
 245:             (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 246:             return;
 247:         }
 248:         zp_finish = *zp;
 249:         hp = (HEADER *) buf;
 250:         soacnt = 0;
 251:         for(;;) {
 252:             if (soacnt == 0) {
 253:                 if ((n = res_mkquery(QUERY, zp->z_origin, C_IN,
 254:                   T_AXFR, (char *)NULL, 0, NULL,
 255:                   buf, sizeof(buf))) < 0) {
 256:                 syslog(LOG_ERR, "zoneref: res_mkquery failed");
 257:                 (void) close(s);
 258:                 (void) sigvec(SIGALRM, &osv,
 259:                     (struct sigvec *)0);
 260:                 return;
 261:                 }
 262:                 /*
 263: 	 	 	    * Send length & message for zone transfer
 264: 	 	 	    */
 265:                 if (writemsg(s, buf, n) < 0) {
 266:                     (void) close(s);
 267:                     error++;
 268: #ifdef DEBUG
 269:                     if (debug >= 2)
 270:                         fprintf(ddt,"writemsg failed\n");
 271: #endif
 272:                     break;
 273:                 }
 274:             }
 275:             /*
 276: 			 * Receive length & response
 277: 			 */
 278:             cp = buf;
 279:             l = sizeof(u_short);
 280:             while (l > 0) {
 281:                 (void) setitimer(ITIMER_REAL, &ival,
 282:                     (struct itimerval *)NULL);
 283:                 if ((n = recv(s, cp, l, 0)) > 0) {
 284:                     cp += n;
 285:                     l -= n;
 286:                 } else {
 287:                     if (errno == EINTR && !read_interrupted)
 288:                         continue;
 289:                     error++;
 290:                     break;
 291:                 }
 292:             }
 293:             (void) setitimer(ITIMER_REAL, &zeroival,
 294:                 (struct itimerval *)NULL);
 295:             if (error)
 296:                 break;
 297:             if ((len = htons(*(u_short *)buf)) == 0)
 298:                 break;
 299:             l = len;
 300:             cp = buf;
 301:             while (l > 0) {
 302:                 (void) setitimer(ITIMER_REAL, &ival,
 303:                     (struct itimerval *)NULL);
 304:                 if ((n = recv(s, cp, l, 0)) > 0) {
 305:                     cp += n;
 306:                     l -= n;
 307:                 } else {
 308:                     if (errno == EINTR && !read_interrupted)
 309:                         continue;
 310:                     error++;
 311:                     break;
 312:                 }
 313:             }
 314:             (void) setitimer(ITIMER_REAL, &zeroival,
 315:                 (struct itimerval *)NULL);
 316:             if (error)
 317:                 break;
 318: #ifdef DEBUG
 319:             if (debug >= 3) {
 320:                 fprintf(ddt,"len = %d\n", len);
 321:                 fp_query(buf, ddt);
 322:             }
 323: #endif
 324:             cp = buf + sizeof(HEADER);
 325:             if (hp->qdcount)
 326:                 cp += dn_skip(cp) + QFIXEDSZ;
 327:             tmp = cp + dn_skip(cp);
 328:             n = doupdate(buf, sizeof(buf), cp, zone, 0);
 329:             if ((cp - buf) + n != len) {
 330: #ifdef DEBUG
 331:                if (debug)
 332:                          fprintf(ddt,"zoneref: doupdate failed (%d, %d)\n",
 333:                     cp - buf, n);
 334: #endif
 335:                 error++;
 336:                 break;
 337:             }
 338:             if ((getshort(tmp)) == T_SOA) {
 339:                 if (soacnt == 0) {
 340:                     soacnt++;
 341:                     tmp += 3 * sizeof(u_short)
 342:                         + sizeof(u_long);
 343:                     tmp += dn_skip(tmp);
 344:                     tmp += dn_skip(tmp);
 345:                     serial = getlong(tmp);
 346:                     continue;
 347:                 }
 348:                 soa_zinfo(zp, tmp);
 349:                 if (serial != zp->z_serial)
 350:                      soacnt = 0;
 351:                 else {
 352:                     break;
 353:                 }
 354:             }
 355:         }
 356:         (void) close(s);
 357:         if ( error == 0) {
 358:             htp = hashtab;
 359:             np = nlookup(zp->z_origin, &htp, &fname, 0);
 360:             if (np == NULL || fname != zp->z_origin) {
 361:                 (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 362:                 return;
 363:             }
 364:             pdp = NULL;
 365:             dp = np->n_data;
 366:             while (dp != NULL) {
 367:                 if (!match(dp, C_ANY, T_SOA)) {
 368:                     pdp = dp;
 369:                     dp = dp->d_next;
 370:                     continue;
 371:                 }
 372:             /* find serial number */
 373:             cp = dp->d_data;
 374:             cp += strlen(cp) + 1; /* origin */
 375:             cp += strlen(cp) + 1; /* address */
 376:             serial = getlong(cp);
 377: #ifdef DEBUG
 378:             if (debug >= 2)
 379:                 fprintf(ddt,"Found serial = %d\n",serial);
 380: #endif
 381: 
 382:             /* remove data if not = current serial number */
 383:                 if (serial != zp->z_serial) {
 384: #ifdef DEBUG
 385:                     if (debug >= 2)
 386:                     fprintf(ddt,"deleting SOA serial #%d\n",
 387:                         serial);
 388: #endif
 389:                     tdp = dp->d_next;
 390:                     free((char *)dp);
 391:                     dp = tdp;
 392:                     if (pdp == NULL)
 393:                         np->n_data = dp;
 394:                     else
 395:                         pdp->d_next = dp;
 396:                     continue;
 397:                 }
 398:                 pdp = dp;
 399:                 dp = dp->d_next;
 400:             }
 401:             (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 402:             return;
 403:         }
 404: #ifdef DEBUG
 405:         if (debug >= 2)
 406:             fprintf(ddt,"error reciving zone transfer\n");
 407: #endif
 408:     }
 409:     (void) sigvec(SIGALRM, &osv, (struct sigvec *)0);
 410:     /*
 411: 	 *     Freedom at last!!
 412: 	 *
 413: 	 *  The land where all repressed slaves dream of.
 414: 	 *
 415: 	 *  Can't find a master to talk to.
 416: 	 *  syslog it and hope we can find a master during maintenance
 417: 	 */
 418:     if (error)
 419:         syslog(LOG_ERR, "zoneref: Can't find Master for secondary zone %s",
 420:         zp->z_origin);
 421:     zp->z_refresh = zp->z_retry;
 422:     if (gettimeofday(&tt, (struct timezone *)0) < 0)
 423:             syslog(LOG_ERR, "gettimeofday failed: %m");
 424:     zp->z_time = tt.tv_sec + zp->z_retry;
 425:     return;
 426: }

Defined functions

ns_maint defined in line 26; used 1 times
zoneref defined in line 99; used 1 times
  • in line 64

Defined variables

sccsid defined in line 2; never used
Last modified: 1986-06-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1621
Valid CSS Valid XHTML 1.0 Strict