Annotation of 43BSDTahoe/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.
                      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.