Annotation of 43BSD/etc/named/ns_maint.c, revision 1.1.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.