Annotation of 43BSD/etc/timed/readmsg.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)readmsg.c  2.9 (Berkeley) 6/5/86";
        !             9: #endif not lint
        !            10: 
        !            11: #include "globals.h"
        !            12: #include <protocols/timed.h>
        !            13: 
        !            14: extern char *tsptype[];
        !            15: 
        !            16: /*
        !            17:  * LOOKAT checks if the message is of the requested type and comes from
        !            18:  * the right machine, returning 1 in case of affirmative answer 
        !            19:  */
        !            20: 
        !            21: #define LOOKAT(msg, mtype, mfrom, netp, froms) \
        !            22:        (((((mtype) == TSP_ANY) || ((mtype) == (msg).tsp_type)) && \
        !            23:        (((mfrom) == NULL) || (strcmp((mfrom), (msg).tsp_name) == 0)) && \
        !            24:        (((netp) == NULL) || \
        !            25:        (((netp)->mask & (froms).sin_addr.s_addr) == (netp)->net))) \
        !            26:        ? 1 : 0)
        !            27: 
        !            28: #define MORETIME(rtime, rtout) \
        !            29:        (((rtime).tv_sec > (rtout).tv_sec || \
        !            30:            ((rtime).tv_sec == (rtout).tv_sec && \
        !            31:                (rtime).tv_usec >= (rtout).tv_usec)) \
        !            32:        ? 0 : 1)
        !            33: 
        !            34: struct timeval rtime, rwait, rtout;
        !            35: struct tsp msgin;
        !            36: static struct tsplist {
        !            37:        struct tsp info;
        !            38:        struct sockaddr_in addr;
        !            39:        struct tsplist *p;
        !            40: } msgslist;
        !            41: struct sockaddr_in from;
        !            42: struct netinfo *fromnet;
        !            43: 
        !            44: /*
        !            45:  * `readmsg' returns message `type' sent by `machfrom' if it finds it 
        !            46:  * either in the receive queue, or in a linked list of previously received 
        !            47:  * messages that it maintains.
        !            48:  * Otherwise it waits to see if the appropriate message arrives within
        !            49:  * `intvl' seconds. If not, it returns NULL.
        !            50:  */
        !            51: 
        !            52: struct tsp *
        !            53: readmsg(type, machfrom, intvl, netfrom)
        !            54: 
        !            55: int type;
        !            56: char *machfrom;
        !            57: struct timeval *intvl;
        !            58: struct netinfo *netfrom;
        !            59: {
        !            60:        int length;
        !            61:        fd_set ready;
        !            62:        static struct tsplist *head = &msgslist;
        !            63:        static struct tsplist *tail = &msgslist;
        !            64:        struct tsplist *prev;
        !            65:        register struct netinfo *ntp;
        !            66:        register struct tsplist *ptr;
        !            67: 
        !            68:        if (trace) {
        !            69:                fprintf(fd, "looking for %s from %s\n",
        !            70:                        tsptype[type], machfrom == NULL ? "ANY" : machfrom);
        !            71:                ptr = head->p;
        !            72:                fprintf(fd, "msgqueue:\n");
        !            73:                while (ptr != NULL) {
        !            74:                        fprintf(fd, "\t");
        !            75:                        print(&ptr->info, &ptr->addr);
        !            76:                        ptr = ptr->p;
        !            77:                }
        !            78:        }
        !            79: 
        !            80:        ptr = head->p;
        !            81:        prev = head;
        !            82: 
        !            83:        /*
        !            84:         * Look for the requested message scanning through the 
        !            85:         * linked list. If found, return it and free the space 
        !            86:         */
        !            87: 
        !            88:        while (ptr != NULL) {
        !            89:                if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) {
        !            90:                        msgin = ptr->info;
        !            91:                        from = ptr->addr;
        !            92:                        prev->p = ptr->p;
        !            93:                        if (ptr == tail) 
        !            94:                                tail = prev;
        !            95:                        free((char *)ptr);
        !            96:                        fromnet = NULL;
        !            97:                        if (netfrom == NULL)
        !            98:                            for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
        !            99:                                    if ((ntp->mask & from.sin_addr.s_addr) ==
        !           100:                                        ntp->net) {
        !           101:                                            fromnet = ntp;
        !           102:                                            break;
        !           103:                                    }
        !           104:                            }
        !           105:                        else
        !           106:                            fromnet = netfrom;
        !           107:                        if (trace) {
        !           108:                                fprintf(fd, "readmsg: ");
        !           109:                                print(&msgin, &from);
        !           110:                        }
        !           111:                        return(&msgin);
        !           112:                } else {
        !           113:                        prev = ptr;
        !           114:                        ptr = ptr->p;
        !           115:                }
        !           116:        }
        !           117: 
        !           118:        /*
        !           119:         * If the message was not in the linked list, it may still be
        !           120:         * coming from the network. Set the timer and wait 
        !           121:         * on a select to read the next incoming message: if it is the
        !           122:         * right one, return it, otherwise insert it in the linked list.
        !           123:         */
        !           124: 
        !           125:        (void)gettimeofday(&rtime, (struct timezone *)0);
        !           126:        rtout.tv_sec = rtime.tv_sec + intvl->tv_sec;
        !           127:        rtout.tv_usec = rtime.tv_usec + intvl->tv_usec;
        !           128:        if (rtout.tv_usec > 1000000) {
        !           129:                rtout.tv_usec -= 1000000;
        !           130:                rtout.tv_sec++;
        !           131:        }
        !           132: 
        !           133:        FD_ZERO(&ready);
        !           134:        for (; MORETIME(rtime, rtout);
        !           135:            (void)gettimeofday(&rtime, (struct timezone *)0)) {
        !           136:                rwait.tv_sec = rtout.tv_sec - rtime.tv_sec;
        !           137:                rwait.tv_usec = rtout.tv_usec - rtime.tv_usec;
        !           138:                if (rwait.tv_usec < 0) {
        !           139:                        rwait.tv_usec += 1000000;
        !           140:                        rwait.tv_sec--;
        !           141:                }
        !           142:                if (rwait.tv_sec < 0) 
        !           143:                        rwait.tv_sec = rwait.tv_usec = 0;
        !           144: 
        !           145:                if (trace) {
        !           146:                        fprintf(fd, "readmsg: wait: (%d %d)\n", 
        !           147:                                                rwait.tv_sec, rwait.tv_usec);
        !           148:                }
        !           149:                FD_SET(sock, &ready);
        !           150:                if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0,
        !           151:                    &rwait)) {
        !           152:                        length = sizeof(struct sockaddr_in);
        !           153:                        if (recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 
        !           154:                                                0, &from, &length) < 0) {
        !           155:                                syslog(LOG_ERR, "receiving datagram packet: %m");
        !           156:                                exit(1);
        !           157:                        }
        !           158: 
        !           159:                        bytehostorder(&msgin);
        !           160: 
        !           161:                        if (msgin.tsp_vers > TSPVERSION) {
        !           162:                                if (trace) {
        !           163:                                    fprintf(fd, "readmsg: version mismatch\n");
        !           164:                                    /* should do a dump of the packet, but... */
        !           165:                                }
        !           166:                                continue;
        !           167:                        }
        !           168: 
        !           169:                        fromnet = NULL;
        !           170:                        for (ntp = nettab; ntp != NULL; ntp = ntp->next)
        !           171:                                if ((ntp->mask & from.sin_addr.s_addr) ==
        !           172:                                    ntp->net) {
        !           173:                                        fromnet = ntp;
        !           174:                                        break;
        !           175:                                }
        !           176: 
        !           177:                        /*
        !           178:                         * drop packets from nets we are ignoring permanently
        !           179:                         */
        !           180:                        if (fromnet == NULL) {
        !           181:                                /* 
        !           182:                                 * The following messages may originate on
        !           183:                                 * this host with an ignored network address
        !           184:                                 */
        !           185:                                if (msgin.tsp_type != TSP_TRACEON &&
        !           186:                                    msgin.tsp_type != TSP_SETDATE &&
        !           187:                                    msgin.tsp_type != TSP_MSITE &&
        !           188: #ifdef TESTING
        !           189:                                    msgin.tsp_type != TSP_TEST &&
        !           190: #endif
        !           191:                                    msgin.tsp_type != TSP_TRACEOFF) {
        !           192:                                        if (trace) {
        !           193:                                            fprintf(fd, "readmsg: discarded: ");
        !           194:                                            print(&msgin, &from);
        !           195:                                        }
        !           196:                                        continue;
        !           197:                                }
        !           198:                        }
        !           199: 
        !           200:                        /*
        !           201:                         * Throw away messages coming from this machine, unless
        !           202:                         * they are of some particular type.
        !           203:                         * This gets rid of broadcast messages and reduces
        !           204:                         * master processing time.
        !           205:                         */
        !           206:                        if ( !(strcmp(msgin.tsp_name, hostname) != 0 ||
        !           207:                                        msgin.tsp_type == TSP_SETDATE ||
        !           208: #ifdef TESTING
        !           209:                                        msgin.tsp_type == TSP_TEST ||
        !           210: #endif
        !           211:                                        msgin.tsp_type == TSP_MSITE ||
        !           212:                                        (msgin.tsp_type == TSP_LOOP &&
        !           213:                                        msgin.tsp_hopcnt != 10) ||
        !           214:                                        msgin.tsp_type == TSP_TRACEON ||
        !           215:                                        msgin.tsp_type == TSP_TRACEOFF)) {
        !           216:                                if (trace) {
        !           217:                                        fprintf(fd, "readmsg: discarded: ");
        !           218:                                        print(&msgin, &from);
        !           219:                                }
        !           220:                                continue;
        !           221:                        }
        !           222: 
        !           223:                        /*
        !           224:                         * Send acknowledgements here; this is faster and avoids
        !           225:                         * deadlocks that would occur if acks were sent from a 
        !           226:                         * higher level routine.  Different acknowledgements are
        !           227:                         * necessary, depending on status.
        !           228:                         */
        !           229:                        if (fromnet->status == MASTER)
        !           230:                                masterack();
        !           231:                        else if (fromnet->status == SLAVE)
        !           232:                                slaveack();
        !           233:                        else
        !           234:                                ignoreack();
        !           235:                                
        !           236:                        if (LOOKAT(msgin, type, machfrom, netfrom, from)) {
        !           237:                                if (trace) {
        !           238:                                        fprintf(fd, "readmsg: ");
        !           239:                                        print(&msgin, &from);
        !           240:                                }
        !           241:                                return(&msgin);
        !           242:                        } else {
        !           243:                                tail->p = (struct tsplist *)
        !           244:                                                malloc(sizeof(struct tsplist)); 
        !           245:                                tail = tail->p;
        !           246:                                tail->p = NULL;
        !           247:                                tail->info = msgin;
        !           248:                                tail->addr = from;
        !           249:                        }
        !           250:                } else {
        !           251:                        break;
        !           252:                }
        !           253:        }
        !           254:        return((struct tsp *)NULL);
        !           255: }
        !           256: 
        !           257: /*
        !           258:  * `slaveack' sends the necessary acknowledgements: 
        !           259:  * only the type ACK is to be sent by a slave 
        !           260:  */
        !           261: 
        !           262: slaveack()
        !           263: {
        !           264:        int length;
        !           265:        struct tsp resp;
        !           266: 
        !           267:        length = sizeof(struct sockaddr_in);
        !           268:        switch(msgin.tsp_type) {
        !           269: 
        !           270:        case TSP_ADJTIME:
        !           271:        case TSP_SETTIME:
        !           272:        case TSP_ACCEPT:
        !           273:        case TSP_REFUSE:
        !           274:        case TSP_TRACEON:
        !           275:        case TSP_TRACEOFF:
        !           276:        case TSP_QUIT:
        !           277:                resp = msgin;
        !           278:                resp.tsp_type = TSP_ACK;
        !           279:                resp.tsp_vers = TSPVERSION;
        !           280:                (void)strcpy(resp.tsp_name, hostname);
        !           281:                if (trace) {
        !           282:                        fprintf(fd, "Slaveack: ");
        !           283:                        print(&resp, &from);
        !           284:                }
        !           285:                bytenetorder(&resp);     /* this is not really necessary here */
        !           286:                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
        !           287:                                                &from, length) < 0) {
        !           288:                        syslog(LOG_ERR, "sendto: %m");
        !           289:                        exit(1);
        !           290:                }
        !           291:                break;
        !           292:        default:
        !           293:                break;
        !           294:        }
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * Certain packets may arrive from this machine on ignored networks.
        !           299:  * These packets should be acknowledged.
        !           300:  */
        !           301: 
        !           302: ignoreack()
        !           303: {
        !           304:        int length;
        !           305:        struct tsp resp;
        !           306: 
        !           307:        length = sizeof(struct sockaddr_in);
        !           308:        switch(msgin.tsp_type) {
        !           309: 
        !           310:        case TSP_TRACEON:
        !           311:        case TSP_TRACEOFF:
        !           312:                resp = msgin;
        !           313:                resp.tsp_type = TSP_ACK;
        !           314:                resp.tsp_vers = TSPVERSION;
        !           315:                (void)strcpy(resp.tsp_name, hostname);
        !           316:                if (trace) {
        !           317:                        fprintf(fd, "Ignoreack: ");
        !           318:                        print(&resp, &from);
        !           319:                }
        !           320:                bytenetorder(&resp);     /* this is not really necessary here */
        !           321:                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
        !           322:                                                &from, length) < 0) {
        !           323:                        syslog(LOG_ERR, "sendto: %m");
        !           324:                        exit(1);
        !           325:                }
        !           326:                break;
        !           327:        default:
        !           328:                break;
        !           329:        }
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * `masterack' sends the necessary acknowledgments 
        !           334:  * to the messages received by a master 
        !           335:  */
        !           336: 
        !           337: masterack()
        !           338: {
        !           339:        int length;
        !           340:        struct tsp resp;
        !           341: 
        !           342:        length = sizeof(struct sockaddr_in);
        !           343: 
        !           344:        resp = msgin;
        !           345:        resp.tsp_vers = TSPVERSION;
        !           346:        (void)strcpy(resp.tsp_name, hostname);
        !           347: 
        !           348:        switch(msgin.tsp_type) {
        !           349: 
        !           350:        case TSP_QUIT:
        !           351:        case TSP_TRACEON:
        !           352:        case TSP_TRACEOFF:
        !           353:        case TSP_MSITE:
        !           354:        case TSP_MSITEREQ:
        !           355:                resp.tsp_type = TSP_ACK;
        !           356:                bytenetorder(&resp);
        !           357:                if (trace) {
        !           358:                        fprintf(fd, "Masterack: ");
        !           359:                        print(&resp, &from);
        !           360:                }
        !           361:                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
        !           362:                                                &from, length) < 0) {
        !           363:                        syslog(LOG_ERR, "sendto: %m");
        !           364:                        exit(1);
        !           365:                }
        !           366:                break;
        !           367:        case TSP_RESOLVE:
        !           368:        case TSP_MASTERREQ:
        !           369:                resp.tsp_type = TSP_MASTERACK;
        !           370:                bytenetorder(&resp);
        !           371:                if (trace) {
        !           372:                        fprintf(fd, "Masterack: ");
        !           373:                        print(&resp, &from);
        !           374:                }
        !           375:                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
        !           376:                                                &from, length) < 0) {
        !           377:                        syslog(LOG_ERR, "sendto: %m");
        !           378:                        exit(1);
        !           379:                }
        !           380:                break;
        !           381:        case TSP_SETDATEREQ:
        !           382:                resp.tsp_type = TSP_DATEACK;
        !           383:                bytenetorder(&resp);
        !           384:                if (trace) {
        !           385:                        fprintf(fd, "Masterack: ");
        !           386:                        print(&resp, &from);
        !           387:                }
        !           388:                if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0, 
        !           389:                                                &from, length) < 0) {
        !           390:                        syslog(LOG_ERR, "sendto: %m");
        !           391:                        exit(1);
        !           392:                }
        !           393:                break;
        !           394:        default:
        !           395:                break;
        !           396:        }
        !           397: }
        !           398: 
        !           399: /*
        !           400:  * Print a TSP message 
        !           401:  */
        !           402: print(msg, addr)
        !           403: struct tsp *msg;
        !           404: struct sockaddr_in *addr;
        !           405: {
        !           406:        switch (msg->tsp_type) {
        !           407: 
        !           408:        case TSP_LOOP:
        !           409:                fprintf(fd, "%s %d %d (#%d) %s %s\n",
        !           410:                        tsptype[msg->tsp_type],
        !           411:                        msg->tsp_vers,
        !           412:                        msg->tsp_seq,
        !           413:                        msg->tsp_hopcnt,
        !           414:                        msg->tsp_name,
        !           415:                        inet_ntoa(addr->sin_addr));
        !           416:                break;
        !           417: 
        !           418:        case TSP_SETTIME:
        !           419:        case TSP_ADJTIME:
        !           420:        case TSP_SETDATE:
        !           421:        case TSP_SETDATEREQ:
        !           422:                fprintf(fd, "%s %d %d (%d, %d) %s %s\n",
        !           423:                        tsptype[msg->tsp_type],
        !           424:                        msg->tsp_vers,
        !           425:                        msg->tsp_seq,
        !           426:                        msg->tsp_time.tv_sec, 
        !           427:                        msg->tsp_time.tv_usec, 
        !           428:                        msg->tsp_name,
        !           429:                        inet_ntoa(addr->sin_addr));
        !           430:                break;
        !           431: 
        !           432:        default:
        !           433:                fprintf(fd, "%s %d %d %s %s\n",
        !           434:                        tsptype[msg->tsp_type],
        !           435:                        msg->tsp_vers,
        !           436:                        msg->tsp_seq,
        !           437:                        msg->tsp_name,
        !           438:                        inet_ntoa(addr->sin_addr));
        !           439:                break;
        !           440:        }
        !           441: }

unix.superglobalmegacorp.com

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