Annotation of 43BSD/etc/named/ns_maint.c, revision 1.1

1.1     ! root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.