Annotation of researchv10no/ipc/mgrs/nonetmgr/main.c, revision 1.1

1.1     ! root        1: #include <sys/param.h>
        !             2: #include <sys/enio.h>
        !             3: #include <sys/filio.h>
        !             4: #include <errno.h>
        !             5: #include <ipc.h>
        !             6: #include <signal.h>
        !             7: 
        !             8: typedef unsigned char uchar;
        !             9: 
        !            10: /*
        !            11:  *  one structure per fd to decide what to do with
        !            12:  *  input on the fd.
        !            13:  */
        !            14: typedef struct {
        !            15:        void (*func)();         /* function to call */
        !            16:        void *ptr;
        !            17: } Fdesc;
        !            18: Fdesc f[NOFILE];
        !            19: 
        !            20: /*
        !            21:  *  bit mask of fds to listen on
        !            22:  */
        !            23: fd_set master;
        !            24: int etherfd;
        !            25: 
        !            26: /*
        !            27:  *  name to address translation
        !            28:  */
        !            29: typedef struct Address {
        !            30:        char *name;
        !            31:        uchar addr[6];
        !            32:        int ack;
        !            33: } Address;
        !            34: Address addr[] = {
        !            35:        { "ross",       0x02, 0x07, 0x01, 0x00, 0x5e, 0xff,     0 },
        !            36:        { "research",   0x02, 0x07, 0x01, 0x00, 0x62, 0x8a,     1 },
        !            37:        { "ara",        0x08, 0x00, 0x47, 0x00, 0x09, 0xfa,     1 },
        !            38:        { "shamash",    0x08, 0x00, 0x20, 0x01, 0x37, 0x78,     1 },
        !            39:        { "ra",         0x08, 0x00, 0x20, 0x01, 0x34, 0x13,     1 },
        !            40:        { "aten",       0x08, 0x00, 0x20, 0x01, 0x3b, 0x74,     1 },
        !            41:        { "pipe",       0x08, 0x00, 0x2b, 0x09, 0x57, 0x94,     1 },
        !            42:        { "sol",        0x08, 0x00, 0x20, 0x01, 0x64, 0xab,     1 },
        !            43:        { "bowell",     0x08, 0x00, 0x2b, 0x0b, 0xce, 0xda,     1 },
        !            44:        { "pyxis",      0x08, 0x00, 0x69, 0x02, 0x01, 0x4e,     1 },
        !            45:        { "r70",        0x08, 0x00, 0x2b, 0x04, 0x26, 0x5d,     1 },
        !            46:        { "nun",        0x08, 0x00, 0x20, 0x00, 0x24, 0xc4,     1 },
        !            47:        { "wild",       0x02, 0x07, 0x01, 0x00, 0x4e, 0x05,     1 },
        !            48:        { "coma",       0x08, 0x00, 0x2b, 0x0b, 0x1d, 0x9b,     1 },
        !            49:        { "tempel",     0x02, 0xcf, 0x1f, 0x11, 0x73, 0x13,     1 },
        !            50:        { "bootes",     0x08, 0x00, 0x69, 0x02, 0x02, 0x05,     0 },
        !            51:        { "helix",      0x08, 0x00, 0x69, 0x02, 0x04, 0x27,     1 },
        !            52:        { "spindle",    0x08, 0x00, 0x69, 0x02, 0x01, 0x9e,     1 },
        !            53:        { "hr4784",     0x00, 0x00, 0xa7, 0x00, 0x08, 0x28,     1 },
        !            54:        { 0 }
        !            55: };
        !            56: 
        !            57: /*
        !            58:  *  ethernet header
        !            59:  */
        !            60: typedef struct Etherhdr {
        !            61:        uchar   d[6];
        !            62:        uchar   s[6];
        !            63:        uchar   type[2];
        !            64:        uchar   circuit[3];     /* circuit number */
        !            65:        uchar   flag;
        !            66:        uchar   mid;            /* message id */
        !            67:        uchar   ack;            /* piggy back ack */
        !            68:        uchar   remain[2];      /* count of remaing bytes of data */
        !            69:        uchar   sum[2];         /* checksum (0 means none) */
        !            70: } Etherhdr;
        !            71: 
        !            72: /*
        !            73:  *  ethernet packet
        !            74:  */
        !            75: typedef struct Ethermsg {
        !            76:        uchar   d[6];
        !            77:        uchar   s[6];
        !            78:        uchar   type[2];
        !            79:        uchar   circuit[3];     /* circuit number */
        !            80:        uchar   flag;
        !            81:        uchar   mid;            /* message id */
        !            82:        uchar   ack;            /* piggy back ack */
        !            83:        uchar   remain[2];      /* count of remaing bytes of data */
        !            84:        uchar   sum[2];         /* checksum (0 means none) */
        !            85:        uchar   data[1500 - 10];
        !            86: } Ethermsg;
        !            87: #define HDRSIZE 24
        !            88: #define NEWCALL        0x1             /* flag bit marking a new circuit */
        !            89: #define HANGUP 0x2             /* flag bit requesting hangup */
        !            90: #define ACKME 0x4              /* acknowledge this message */
        !            91: #define ETHER_TYPE 0x9         /* most significant byte last */
        !            92: 
        !            93: char *dev[] = {
        !            94:        "/dev/qe02",
        !            95:        "/dev/il02",
        !            96:        "/dev/bna02",
        !            97:        0,
        !            98: };
        !            99: 
        !           100: /*
        !           101:  *  nonet conversations
        !           102:  */
        !           103: #define NCIRC (NOFILE/2)
        !           104: #define MAXMSG (8*1024+100)
        !           105: typedef struct Circuit {
        !           106:        Fdesc   *f;
        !           107:        int     hangingup;
        !           108:        int     hungup;
        !           109:        int     version;
        !           110: 
        !           111:        uchar   rcved;          /* last msg rcved */
        !           112:        int     mid;            /* id of current input message */
        !           113:        int     rem;            /* remaining bytes for input current message */
        !           114:        int     rcvcircuit;     /* circuit number of incoming packets */
        !           115:        uchar   ibuf[MAXMSG];
        !           116:        int     ibi;
        !           117:        int     eofs;
        !           118: 
        !           119:        uchar   sent;           /* last msg sent */
        !           120:        uchar   ackrcved;       /* last ack received */
        !           121:        int     resent;         /* number of times a message is transmitted */
        !           122:        Etherhdr eh;            /* prototype ethernet header */
        !           123:        uchar   obuf[MAXMSG];
        !           124:        int     obi;
        !           125: } Circuit;
        !           126: Circuit circ[NCIRC];
        !           127: 
        !           128: void announce();
        !           129: void openether();
        !           130: void newcall();
        !           131: void fromclient();
        !           132: void fromether();
        !           133: void timeout();
        !           134: void fillhdr();
        !           135: void send();
        !           136: void hangup();
        !           137: void ack();
        !           138: void resend();
        !           139: void ackdead();
        !           140: 
        !           141: int debug;
        !           142: 
        !           143: main(ac, av)
        !           144:        int ac;
        !           145:        char *av[];
        !           146: {
        !           147:        fd_set set;
        !           148:        int fds;
        !           149:        int i;
        !           150: 
        !           151:        debug = 0;
        !           152:        if(ac > 1 && strcmp(av[1], "-d")==0)
        !           153:                debug = 1;
        !           154:        chdir("/cs");
        !           155:        FD_ZERO(master);
        !           156:        if(!debug)
        !           157:                detach("nonet");
        !           158:        announce();
        !           159:        openether();
        !           160:        signal(SIGPIPE, SIG_IGN);
        !           161:        for(;;){
        !           162:                /*
        !           163:                 *  keep polling the fds for input.  call an
        !           164:                 *  fd's input routine whenever it has any input.
        !           165:                 */
        !           166:                set = master;
        !           167:                switch(fds = select(NOFILE, &set, 0, 1000)){
        !           168:                case -1:
        !           169:                        logevent("switch returned -1");
        !           170:                        exit(1);
        !           171:                case 0:
        !           172:                        timeout();
        !           173:                        continue;
        !           174:                }
        !           175:                for(i = 0; fds && i < NOFILE; i++){
        !           176:                        if(FD_ISSET(i, set)) {
        !           177:                                fds--;
        !           178:                                if(f[i].func != 0)
        !           179:                                        (*f[i].func)(i);
        !           180:                                else {
        !           181:                                        logevent("io on bad fd %d\n", i);
        !           182:                                        FD_CLR(i, master);
        !           183:                                        close(i);
        !           184:                                }
        !           185:                        }
        !           186:                }
        !           187:        }
        !           188: }
        !           189: 
        !           190: /*
        !           191:  *  set up a connected pair of fd's to listen on.
        !           192:  *  if fd2 < 0, then there is only 1 fd.
        !           193:  */
        !           194: newf(fd, func)
        !           195:        int fd;
        !           196:        void (*func)();
        !           197: {
        !           198:        f[fd].func = func;
        !           199:        FD_SET(fd, master);
        !           200: }
        !           201: 
        !           202: /*
        !           203:  *  close an fd, stop listening to it, and close off it's related fd.
        !           204:  */
        !           205: delf(fd)
        !           206:        int fd;
        !           207: {
        !           208:        if(fd < 0)
        !           209:                return;
        !           210:        if(f[fd].func == 0)
        !           211:                return;
        !           212:        f[fd].func = 0;
        !           213:        close(fd);
        !           214:        FD_CLR(fd, master);
        !           215: }
        !           216: 
        !           217: /*
        !           218:  *  plug into the name space
        !           219:  */
        !           220: void
        !           221: announce()
        !           222: {
        !           223:        int fd;
        !           224: 
        !           225:        fd = ipccreat("/cs/nonet", "");
        !           226:        if(fd<0){
        !           227:                logconsole("error announcing /cs/nonet\n");
        !           228:                exit(1);
        !           229:        }
        !           230:        newf(fd, newcall);
        !           231:        logconsole("/cs/nonet announced\n");
        !           232: }
        !           233: 
        !           234: /*
        !           235:  *  listen to the nonet ether type
        !           236:  */
        !           237: void
        !           238: openether()
        !           239: {
        !           240:        int fd;
        !           241:        int i;
        !           242:        extern int buf_ld;
        !           243: 
        !           244:        for(i = 0; dev[i]; i++){
        !           245:                fd = open(dev[i], 2);
        !           246:                if(fd >= 0)
        !           247:                        break;
        !           248:        }
        !           249:        if(fd < 0){
        !           250:                logevent("opening ethernet device\n");
        !           251:                exit(1);
        !           252:        }
        !           253:        i = ETHER_TYPE;
        !           254:        if(ioctl(fd, ENIOTYPE, &i) < 0){
        !           255:                perror("ENIOTYPE");
        !           256:                exit(1);
        !           257:        }
        !           258:        newf(fd, fromether);
        !           259:        etherfd = fd;
        !           260:        if(ioctl(etherfd, FIOPUSHLD, &buf_ld)<0){
        !           261:                perror("pushing buf_ld");
        !           262:        }
        !           263:        if(ioctl(etherfd, FIOPUSHLD, &buf_ld)<0){
        !           264:                perror("pushing buf_ld");
        !           265:        }
        !           266: }
        !           267: 
        !           268: /*
        !           269:  *  there is input on the announcement channel.  see if a
        !           270:  *  new call has come in.
        !           271:  */
        !           272: void
        !           273: newcall(fd)
        !           274:        int fd;
        !           275: {
        !           276:        ipcinfo *ipc;
        !           277:        Circuit *cp;
        !           278:        Address *a;
        !           279:        int circuit;
        !           280:        int nfd;
        !           281:        char *service;
        !           282:        char *strchr();
        !           283: 
        !           284:        logevent("newcall\n");
        !           285:        ipc = ipclisten(fd);
        !           286:        if(ipc == 0){
        !           287:                logevent("listening %s\n", errstr);
        !           288:                return;
        !           289:        }
        !           290: 
        !           291:        /*
        !           292:         *  Find a new circuit for the call.
        !           293:         */
        !           294:        for(cp = circ; cp < &circ[NCIRC]; cp++){
        !           295:                if(cp->f == 0)
        !           296:                        break;
        !           297:        }
        !           298:        if(cp == &circ[NCIRC]){
        !           299:                logevent("call from %s!%s busy\n", ipc->machine, ipc->user);
        !           300:                ipcreject(ipc, EBUSY, "out of output channels");
        !           301:                return;
        !           302:        }
        !           303:        logevent("call from %s!%s on %d\n", ipc->machine, ipc->user, cp - circ);
        !           304: 
        !           305:        /*
        !           306:         * separate name and service
        !           307:         */
        !           308:        service = strchr(ipc->name, '.');
        !           309:        if(service)
        !           310:                *service++ = 0;
        !           311:        else{
        !           312:                service = strchr(ipc->name, '!');
        !           313:                if(service)
        !           314:                        *service++ = 0;
        !           315:        }
        !           316:        if(service==0)
        !           317:                service = "";
        !           318: 
        !           319:        /*
        !           320:         *  see if we know the destination
        !           321:         */
        !           322:        for(a = addr; a->name; a++){
        !           323:                if(strcmp(a->name, ipc->name) == 0)
        !           324:                        break;
        !           325:        }
        !           326:        if(a->name == 0){
        !           327:                logevent("call from %s!%s, %s!%s unknown dest\n", ipc->machine, ipc->user,
        !           328:                        ipc->name, service);
        !           329:                ipcreject(ipc, EEXIST, "unknown destination");
        !           330:                return;
        !           331:        }
        !           332:        nfd = ipcaccept(ipc);
        !           333:        if(nfd < 0){
        !           334:                logevent("call from %s!%s error accepting\n", ipc->machine, ipc->user);
        !           335:                return;
        !           336:        }
        !           337:        logevent("call from %s!%s to %s!%s accepted\n", ipc->machine, ipc->user, ipc->name,
        !           338:                service);
        !           339: 
        !           340:        /*
        !           341:         *  init the circuit
        !           342:         */
        !           343:        f[nfd].ptr = (void *)cp;
        !           344:        cp->f = &f[nfd];
        !           345:        cp->hangingup = 0;
        !           346:        cp->hungup = 0;
        !           347:        cp->eofs = 0;
        !           348:        cp->ackrcved = 0;
        !           349:        cp->sent = 0;
        !           350:        cp->ibi = 0;
        !           351:        cp->obi = 0;
        !           352:        cp->rcved = 0;
        !           353:        cp->mid = 0;
        !           354:        circuit = 2*((cp - circ)+cp->version*NCIRC);
        !           355:        cp->rcvcircuit = circuit+1;
        !           356:        cp->version++;
        !           357:        if(a->ack)
        !           358:                cp->eh.flag = NEWCALL|ACKME;
        !           359:        else
        !           360:                cp->eh.flag = NEWCALL;
        !           361:        cp->eh.circuit[2] = circuit>>16;
        !           362:        cp->eh.circuit[1] = circuit>>8;
        !           363:        cp->eh.circuit[0] = circuit;
        !           364:        memcpy(cp->eh.d, a->addr, sizeof(a->addr));
        !           365:        cp->eh.type[1] = ETHER_TYPE>>8;
        !           366:        cp->eh.type[0] = ETHER_TYPE;
        !           367:        newf(nfd, fromclient);
        !           368: 
        !           369:        if(strcmp(service, "bootfs") == 0){
        !           370:                /*
        !           371:                 *  send ok to the caller
        !           372:                 */
        !           373:                write(nfd, "OK", 2);
        !           374:        } else  if(strcmp(service, "fs") != 0){
        !           375:                /*
        !           376:                 *  send user id
        !           377:                 */
        !           378:                sprint(cp->obuf, "%s %s", ipc->user, service);
        !           379:                cp->obi += strlen(cp->obuf);
        !           380:                send(cp);
        !           381:        }
        !           382: }
        !           383: 
        !           384: /*
        !           385:  *  input from the ethernet
        !           386:  */
        !           387: void
        !           388: fromether(fd)
        !           389:        int fd;
        !           390: {
        !           391:        int len;
        !           392:        short r;
        !           393:        int c;
        !           394:        Circuit *cp;
        !           395:        Ethermsg em;
        !           396:        int hungup;
        !           397: 
        !           398:        /*
        !           399:         *  read/parse an ethernet message
        !           400:         */
        !           401:        len = read(fd, &em, sizeof(Ethermsg));
        !           402:        if(len <= 0){
        !           403:                logevent("error reading from ether\n");
        !           404:                return;
        !           405:        }
        !           406:        if(debug)
        !           407:                printpacket("in", &em);
        !           408:        r = (em.remain[1]<<8) | em.remain[0];
        !           409:        c = (em.circuit[2]<<16) | (em.circuit[1]<<8) | em.circuit[0];
        !           410:        hungup = em.flag & HANGUP;
        !           411:        
        !           412:        /*
        !           413:         *  look for an existing client
        !           414:         */
        !           415:        for(cp = circ; cp < &circ[NCIRC]; cp++){
        !           416:                if(cp->f && c == cp->rcvcircuit
        !           417:                && memcmp(cp->eh.d, em.s, sizeof(em.s)) == 0)
        !           418:                        break;
        !           419:        }
        !           420:        if(cp == &circ[NCIRC]) {
        !           421:                logevent("no client found\n");
        !           422:                ackdead(&em);
        !           423:                return;
        !           424:        }
        !           425: 
        !           426:        len -= HDRSIZE;
        !           427:        if(r>=0){
        !           428:                /*
        !           429:                 *  a new message, forget any old messages
        !           430:                 */
        !           431:                cp->ibi = 0;
        !           432:                cp->mid = em.mid;
        !           433:                cp->rem = r;
        !           434:        } else {
        !           435:                /*
        !           436:                 *  a continuation
        !           437:                 */
        !           438:                if(cp->mid != em.mid || -r != cp->rem) {
        !           439:                        /* bad fragment -- drop anything ibuffered */
        !           440:                        logevent("cp->mid %d em.mid %d r %d cp->rem %d\n", cp->mid, em.mid,
        !           441:                                r, cp->rem);
        !           442:                        cp->ibi = 0;
        !           443:                        return;
        !           444:                }
        !           445:        }
        !           446:        cp->rem -= len;
        !           447: 
        !           448:        /*
        !           449:         *  last packet may be ``padded out''.  adjust size if it is.
        !           450:         */
        !           451:        if(cp->rem < 0){
        !           452:                if(-cp->rem <= len){
        !           453:                        len += cp->rem;
        !           454:                        cp->rem = 0;
        !           455:                } else {
        !           456:                        logevent("short packet\n");
        !           457:                        return;
        !           458:                }
        !           459:        }
        !           460: 
        !           461:        /*
        !           462:         *  copy the packet into the buffer
        !           463:         */
        !           464:        memcpy(&(cp->ibuf[cp->ibi]), em.data, len);
        !           465:        cp->ibi += len;
        !           466: 
        !           467:        /*
        !           468:         *  if last packet of a message...
        !           469:         */
        !           470:        if(cp->rem == 0){
        !           471:                /*
        !           472:                 * ... is it what we expected?
        !           473:                 */
        !           474:                if(((cp->rcved+1)&0xff) != cp->mid){
        !           475:                        if(cp->rcved == cp->mid){
        !           476:                                cp->ackrcved = em.ack;
        !           477:                                if(cp->ibi)
        !           478:                                        ack(cp);                /* retransmission */
        !           479:                                fd = cp->f - f;
        !           480:                                if(cp->ackrcved == cp->sent && f[fd].func)
        !           481:                                        FD_SET(fd, master);
        !           482:                                return;
        !           483:                        }
        !           484:                        logevent("expected %d got %d\n", (cp->rcved+1)&0xff,  cp->mid);
        !           485:                        cp->ibi = 0;
        !           486:                        return;
        !           487:                }
        !           488:                /*
        !           489:                 *  ... update state and send packet to client
        !           490:                 */
        !           491:                cp->eh.flag &= ~NEWCALL;
        !           492:                cp->rcved = cp->mid;
        !           493:                cp->ackrcved = em.ack;
        !           494:                fd = cp->f - f;
        !           495:                if(cp->ackrcved == cp->sent && f[fd].func)
        !           496:                        FD_SET(fd, master);
        !           497:                if(cp->ibi && write(fd, cp->ibuf, cp->ibi) != cp->ibi){
        !           498:                        logevent("error writing to client %d %d\n", fd, cp->ibi);
        !           499:                        hangup(cp);
        !           500:                }
        !           501:                if(hungup){
        !           502:                        cp->hungup = 1;
        !           503:                        hangup(cp);
        !           504:                }
        !           505:                if(cp->eh.flag & ACKME)
        !           506:                        ack(cp);
        !           507:        }
        !           508: }
        !           509: 
        !           510: /*
        !           511:  *  collect a message from a client.  4 eofs in a row mean the connection
        !           512:  *  is closed.
        !           513:  */
        !           514: void
        !           515: fromclient(fd)
        !           516:        int fd;
        !           517: {
        !           518:        int len;
        !           519:        Circuit *cp;
        !           520: 
        !           521:        cp = (Circuit *)(f[fd].ptr);
        !           522: 
        !           523:        /*
        !           524:         *  read in the message
        !           525:         */
        !           526:        len = read(fd, cp->obuf, sizeof(cp->obuf));
        !           527:        if(len < 0){
        !           528:                hangup(cp);
        !           529:                return;
        !           530:        }
        !           531:        if(len == 0){
        !           532:                if(++(cp->eofs) == 4){
        !           533:                        hangup(cp);
        !           534:                        return;
        !           535:                }
        !           536:        } else
        !           537:                cp->eofs = 0;
        !           538:        cp->obi = len;
        !           539: 
        !           540:        /*
        !           541:         *  send message
        !           542:         */
        !           543:        send(cp);
        !           544: }
        !           545: 
        !           546: /*
        !           547:  *  send a message on a circuit
        !           548:  */
        !           549: void
        !           550: send(cp)
        !           551:        Circuit *cp;
        !           552: {
        !           553:        cp->sent++;
        !           554:        cp->resent = 0;
        !           555:        FD_CLR(cp->f - f, master);
        !           556:        resend(cp);
        !           557: }
        !           558: 
        !           559: /*
        !           560:  *  resend a message on a circuit
        !           561:  */
        !           562: void
        !           563: resend(cp)
        !           564:        Circuit *cp;
        !           565: {
        !           566:        Ethermsg em;
        !           567:        int rem, len, first;
        !           568: 
        !           569:        /*
        !           570:         *  break up the message into some number of
        !           571:         *  ethernet packets and send them.
        !           572:         */
        !           573:        first = 1;
        !           574:        for (rem = cp->obi; first || rem > 0; rem -= len){
        !           575:                first = 0;
        !           576:                fillhdr(cp, &em, rem == cp->obi ? rem : -rem);
        !           577:                len = rem > sizeof(em.data) ? sizeof(em.data) : rem;
        !           578:                memcpy(em.data, &(cp->obuf[cp->obi - rem]), len);
        !           579:                if(len < 128-HDRSIZE)
        !           580:                        len = 128-HDRSIZE;
        !           581:                if(debug)
        !           582:                        printpacket("out", &em);
        !           583:                if(write(etherfd, &em, len + HDRSIZE) != len + HDRSIZE){
        !           584:                        logevent("error writing to ether\n");
        !           585:                        return;
        !           586:                }
        !           587:        }
        !           588: }
        !           589: 
        !           590: /*
        !           591:  *  ack a dead client
        !           592:  */
        !           593: void
        !           594: ackdead(e)
        !           595:        Ethermsg *e;
        !           596: {
        !           597:        Ethermsg em;
        !           598: 
        !           599:        memcpy(em.d, e->s, sizeof(em.d));
        !           600:        memcpy(em.s, e->d, sizeof(em.s));
        !           601:        em.mid = e->ack;
        !           602:        em.ack = e->mid;
        !           603:        em.flag = HANGUP;
        !           604:        e->remain[1] = 0;
        !           605:        e->remain[0] = 0;
        !           606:        e->sum[0] = e->sum[1] = 0;
        !           607: 
        !           608:        if(write(etherfd, &em, HDRSIZE) != HDRSIZE){
        !           609:                logevent("error writing to ether\n");
        !           610:                return;
        !           611:        }
        !           612: }
        !           613: 
        !           614: /*
        !           615:  *  fill in an ethernet/nonet header
        !           616:  */
        !           617: void
        !           618: fillhdr(cp, e, rem)
        !           619:        Circuit *cp;
        !           620:        Ethermsg *e;
        !           621:        int rem;
        !           622: {
        !           623:        memcpy(e, &cp->eh, HDRSIZE);
        !           624:        e->mid = cp->sent;
        !           625:        e->ack = cp->rcved;
        !           626:        e->remain[1] = rem>>8;
        !           627:        e->remain[0] = rem;
        !           628:        e->sum[0] = e->sum[1] = 0;
        !           629: }
        !           630: 
        !           631: /*
        !           632:  *  retransmit any unacknowledged messages
        !           633:  */
        !           634: void
        !           635: timeout(sig)
        !           636:        int sig;
        !           637: {
        !           638:        Circuit *cp;
        !           639: 
        !           640:        for(cp = circ; cp < &circ[NCIRC]; cp++){
        !           641:                if(cp->f && cp->sent != cp->ackrcved){
        !           642:                        if(++(cp->resent) > 15) {
        !           643:                                logevent("too many rexmits, giving up %d\n", cp - circ);
        !           644:                                delf(cp->f - f);
        !           645:                                cp->f = 0;
        !           646:                        } else
        !           647:                                resend(cp);
        !           648:                }
        !           649:                if(cp->f && cp->hungup && cp->hangingup && cp->sent == cp->ackrcved)
        !           650:                        cp->f = 0;
        !           651:        }
        !           652: }
        !           653: 
        !           654: /*
        !           655:  *  hangup a connection
        !           656:  */
        !           657: void
        !           658: hangup(cp)
        !           659:        Circuit *cp;
        !           660: {
        !           661:        Ethermsg em;
        !           662: 
        !           663:        logevent("hanging up %d\n", cp - circ);
        !           664:        if(cp->hangingup)
        !           665:                return;
        !           666:        cp->hangingup = 1;
        !           667:        cp->eh.flag |= HANGUP;
        !           668:        cp->obi = 0;
        !           669:        delf(cp->f - f);
        !           670:        send(cp);
        !           671:        cp->f = 0;
        !           672: }
        !           673: 
        !           674: /*
        !           675:  *  ack a message
        !           676:  */
        !           677: void
        !           678: ack(cp)
        !           679:        Circuit *cp;
        !           680: {
        !           681:        Ethermsg em;
        !           682: 
        !           683:        fillhdr(cp, &em, 0);
        !           684:        if(write(etherfd, &em, HDRSIZE) != HDRSIZE){
        !           685:                logevent("error writing to ether\n");
        !           686:                return;
        !           687:        }
        !           688: }
        !           689: 
        !           690: printpacket(tag, p)
        !           691:        char *tag;
        !           692:        Ethermsg *p;
        !           693: {
        !           694:        uchar *cp;
        !           695:        cp = p->circuit;
        !           696:   fprint(2, "%s: d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%ux %ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n",
        !           697:        tag,
        !           698:        p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5],
        !           699:        p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1],
        !           700:        cp[0], cp[1], cp[2], cp[3], cp[4], cp[5],
        !           701:        cp[6], cp[7], cp[8], cp[9], cp[10], cp[11]);
        !           702: }
        !           703: 

unix.superglobalmegacorp.com

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