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