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

unix.superglobalmegacorp.com

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