|
|
1.1 ! root 1: /* ! 2: * Packet protocol processor ! 3: */ ! 4: ! 5: #include "../h/param.h" ! 6: #include "../h/stream.h" ! 7: #include "../h/conf.h" ! 8: #include "../h/ioctl.h" ! 9: #include "../h/ttyld.h" ! 10: #include "pk.h" ! 11: ! 12: struct pack { ! 13: u_char istate; ! 14: u_char ostate; ! 15: u_char xlogseg; /* code for xmit segment size */ ! 16: u_char S; /* current output seqno */ ! 17: u_char SN; /* next output seqno */ ! 18: u_char XW; /* size of output window */ ! 19: u_char R; /* current input seqno */ ! 20: u_char timer; ! 21: short xsegment; /* output segment size */ ! 22: short iwant; /* # chars needed before i q enable */ ! 23: struct block *xpacks[8]; /* waiting output blocks */ ! 24: struct { ! 25: u_char k; /* packet size */ ! 26: u_char c0; /* low checksum byte */ ! 27: u_char c1; /* high checksum byte */ ! 28: u_char C; /* control byte */ ! 29: u_char x; /* header check */ ! 30: } hdr; /* copy of header of received segment */ ! 31: struct queue *rdq; /* associated read queue */ ! 32: }; ! 33: ! 34: #define PK_TYPE 0xC0 ! 35: #define PKCNTL 0x00 ! 36: #define PKDATA 0x80 ! 37: #define PKSDATA 0xC0 ! 38: ! 39: #define PK_CLOSE 010 ! 40: #define PK_RJ 020 ! 41: #define PK_RR 040 ! 42: #define PK_INITC 050 ! 43: #define PK_INITB 060 ! 44: #define PK_INITA 070 ! 45: ! 46: #define CHECK 0125252 ! 47: ! 48: #define WDATA 01 ! 49: #define PKDELIM 02 ! 50: #define PKREJ 04 ! 51: ! 52: #define SYN 020 /* sic */ ! 53: ! 54: #define SINITA 1 ! 55: #define SINITB 2 ! 56: #define SINITC 3 ! 57: #define OPEN 4 ! 58: #define LCLOSE 5 ! 59: #define RCLOSE 6 ! 60: ! 61: #define PKPRI 28 ! 62: #define DKDATA 0400 ! 63: ! 64: #define RWINSIZE 3 ! 65: #define RSEGSIZE 1 /* 64 bytes */ ! 66: ! 67: #define PKTIME 5 ! 68: ! 69: struct pack packs[NPK]; ! 70: short pksizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 }; ! 71: u_short pkc_sum; ! 72: u_short pkc_x; ! 73: int pkc_size; ! 74: ! 75: int pkiput(), pkisrv(), pkoput(), pkosrv(), pkopen(), pkclose(); ! 76: static struct qinit pkrinit = { pkiput, pkisrv, pkopen, pkclose, 512, 64 }; ! 77: static struct qinit pkwinit = { pkoput, pkosrv, pkopen, pkclose, 128, 65 }; ! 78: struct streamtab pkinfo = { &pkrinit, &pkwinit }; ! 79: ! 80: pkopen(q) ! 81: register struct queue *q; ! 82: { ! 83: register struct pack *pkp; ! 84: register s; ! 85: static timer = 0; ! 86: int pktimer(); ! 87: ! 88: if (q->ptr) { ! 89: pkp = (struct pack *)q->ptr; ! 90: if (pkp->ostate != OPEN) ! 91: return(0); /* don't reopen half-open chans */ ! 92: return(1); ! 93: } else { ! 94: for (pkp = packs; pkp->ostate!=0; pkp++) ! 95: if (pkp >= &packs[NPK]) ! 96: return(0); ! 97: pkp->rdq = q; ! 98: q->ptr = (caddr_t)pkp; ! 99: WR(q)->ptr = (caddr_t)pkp; ! 100: pkp->S = 1; ! 101: pkp->SN = 1; ! 102: pkp->R = 0; ! 103: putctl(q->next, M_FLUSH); ! 104: pkp->ostate = SINITA; ! 105: pkp->istate = 0; ! 106: pkp->timer = 2; ! 107: pkscntl(pkp, PK_INITA+RWINSIZE); ! 108: } ! 109: if (timer == 0) { ! 110: timer = 1; ! 111: timeout(pktimer, (caddr_t)NULL, 60); ! 112: } ! 113: s = spl5(); ! 114: while (pkp->ostate != OPEN) { ! 115: switch (tsleep((caddr_t)pkp, PKPRI, 15)) { ! 116: case TS_OK: ! 117: continue; ! 118: case TS_SIG: ! 119: case TS_TIME: ! 120: pkp->ostate = 0; ! 121: splx(s); ! 122: return(0); ! 123: } ! 124: } ! 125: q->flag |= QDELIM; ! 126: splx(s); ! 127: return(1); ! 128: } ! 129: ! 130: /* ! 131: * Shut it down. ! 132: * The problem is to dispose of unacked stuff in the window. ! 133: * -- no real solution; the receiver might hang on for hours. ! 134: * Give it 15 seconds. ! 135: */ ! 136: pkclose(q) ! 137: register struct queue *q; ! 138: { ! 139: register struct pack *pkp; ! 140: register s = spl5(); ! 141: register i; ! 142: ! 143: pkp = (struct pack *)q->ptr; ! 144: pkp->ostate = LCLOSE; ! 145: flushq(q, 1); ! 146: for (i=0; pkp->S < pkp->SN && i<15; i++) ! 147: tsleep((caddr_t)pkp, PKPRI, 1); ! 148: splx(s); ! 149: flushq(WR(q), 1); ! 150: pkrack(pkp, pkp->SN-1, 0); ! 151: pkscntl(pkp, PK_CLOSE); ! 152: pkp->ostate = 0; ! 153: } ! 154: ! 155: ! 156: /* ! 157: * Process a bunch of input ! 158: */ ! 159: pkisrv(q) ! 160: register struct queue *q; ! 161: { ! 162: register struct pack *pkp = (struct pack *)q->ptr; ! 163: register struct block *bp; ! 164: register segsize, msgsize; ! 165: int R, OK; ! 166: u_char c; ! 167: ! 168: more: ! 169: while ((pkp->istate & WDATA) == 0) { ! 170: if (pkwant(pkp, 6)==0) ! 171: return; ! 172: pkgetb(q, &c, 1); ! 173: if (c != SYN) ! 174: continue; ! 175: pkgetb(q, (u_char *)&pkp->hdr, 5); ! 176: if (pkp->hdr.x != (pkp->hdr.k ^ pkp->hdr.c0 ^ ! 177: pkp->hdr.c1 ^ pkp->hdr.C)) { /* bad header? */ ! 178: continue; ! 179: } ! 180: switch (pkp->hdr.C & PK_TYPE) { ! 181: case PKCNTL: ! 182: pkp->istate &= ~PKREJ; ! 183: pkcntl(pkp); ! 184: continue; ! 185: ! 186: case PKDATA: ! 187: case PKSDATA: ! 188: if (pkp->ostate==SINITC) { ! 189: pkp->ostate = OPEN; ! 190: wakeup((caddr_t)pkp); ! 191: } ! 192: if (pkp->S != pkp->SN) /* if need an ack */ ! 193: pkrack(pkp, pkp->hdr.C&07, 0); ! 194: if (pkp->hdr.k<1 || pkp->hdr.k>8) { ! 195: continue; ! 196: } ! 197: pkp->istate |= WDATA; ! 198: break; ! 199: ! 200: default: ! 201: continue; ! 202: } ! 203: break; ! 204: } ! 205: if (q->next->flag&QFULL) ! 206: return; ! 207: msgsize = segsize = pksizes[pkp->hdr.k]; ! 208: if (pkwant(pkp, segsize) == 0) ! 209: return; ! 210: /* ! 211: * Now have a segment's worth of data; if in window, compute checksum ! 212: * and accept if all is OK ! 213: */ ! 214: R = (pkp->hdr.C>>3) & 07; ! 215: if (R <= pkp->R) ! 216: R += 8; ! 217: /* compute checksum */ ! 218: OK = 0; ! 219: pkc_sum = -1; ! 220: pkc_x = 0; ! 221: pkc_size = segsize; ! 222: for (bp = q->first; segsize>0; bp = bp->next) { ! 223: register sz = bp->wptr - bp->rptr; ! 224: pkcksum(bp->rptr, sz); ! 225: segsize -= sz; ! 226: } ! 227: segsize = msgsize; ! 228: pkc_sum ^= pkp->hdr.C; ! 229: pkc_sum += (pkp->hdr.c1<<8) + pkp->hdr.c0; ! 230: if (pkc_sum != CHECK || R != pkp->R+1) { /* Bad? */ ! 231: if (R < pkp->R+RWINSIZE) { ! 232: flushq(q, 0); ! 233: if ((pkp->istate & PKREJ) == 0) ! 234: pkscntl(pkp, PK_RJ+pkp->R); ! 235: pkp->istate &= ~WDATA; ! 236: pkp->istate |= PKREJ; ! 237: goto more; ! 238: } ! 239: msgsize = -1; /* duplicate; just ignore */ ! 240: } else { /* It's good */ ! 241: pkp->R = (pkp->R+1)&07; ! 242: OK = 1; ! 243: if ((pkp->hdr.C&PK_TYPE) == PKSDATA) { ! 244: pkgetb(q, &c, 1); ! 245: msgsize -= c & 0x7F; ! 246: segsize -= 1; ! 247: if (c&0x80) { ! 248: pkgetb(q, &c, 1); ! 249: msgsize -= c << 7; ! 250: segsize -= 1; ! 251: } ! 252: } ! 253: } ! 254: pkp->istate &= ~PKREJ; ! 255: pkscntl(pkp, PK_RR+pkp->R); ! 256: while (segsize > 0) { ! 257: register i; ! 258: bp = getq(q); ! 259: i = bp->wptr - bp->rptr; ! 260: if (i <= msgsize) { ! 261: (*q->next->qinfo->putp)(q->next, bp); ! 262: msgsize -= i; ! 263: segsize -= i; ! 264: continue; ! 265: } ! 266: if (msgsize>0) { ! 267: register struct block *bp1 = allocb(msgsize); ! 268: if (bp1) { ! 269: bcopy(bp->rptr, bp1->wptr, msgsize); ! 270: bp->rptr += msgsize; ! 271: bp1->wptr += msgsize; ! 272: (*q->next->qinfo->putp)(q->next, bp1); ! 273: segsize -= msgsize; ! 274: msgsize = 0; ! 275: putbq(q, bp); ! 276: continue; ! 277: } else ! 278: panic("pk alloc\n"); ! 279: } ! 280: if (i <= segsize) { ! 281: freeb(bp); ! 282: segsize -= i; ! 283: continue; ! 284: } ! 285: bp->rptr += segsize; ! 286: putbq(q, bp); ! 287: break; ! 288: } ! 289: if (OK) ! 290: putctl(q->next, M_DELIM); ! 291: pkp->istate &= ~WDATA; ! 292: goto more; ! 293: } ! 294: ! 295: /* ! 296: * Packet arrives. ! 297: */ ! 298: pkiput(q, bp) ! 299: struct queue *q; ! 300: register struct block *bp; ! 301: { ! 302: register struct pack *pkp; ! 303: register c; ! 304: ! 305: if ((pkp = (struct pack *)q->ptr)==NULL || pkp->ostate==LCLOSE) { ! 306: freeb(bp); ! 307: return; ! 308: } ! 309: switch (bp->type) { ! 310: ! 311: case M_DATA: ! 312: if (q->flag&QFULL) { ! 313: freeb(bp); ! 314: return; ! 315: } ! 316: if ((pkp->iwant -= bp->wptr - bp->rptr) <= 0) { ! 317: pkp->iwant = 0; ! 318: qenable(q); ! 319: } ! 320: putq(q, bp); ! 321: return; ! 322: ! 323: case M_HANGUP: ! 324: pkp->ostate = RCLOSE; ! 325: flushq(WR(q), 0); ! 326: pkrack(pkp, pkp->SN-1, 0); ! 327: qenable(q); ! 328: freeb(bp); ! 329: return; ! 330: ! 331: case M_IOCACK: ! 332: case M_IOCNAK: ! 333: (*q->next->qinfo->putp)(q->next, bp); ! 334: return; ! 335: ! 336: default: ! 337: freeb(bp); ! 338: return; ! 339: } ! 340: } ! 341: ! 342: /* ! 343: * --- Output processor ! 344: */ ! 345: ! 346: /* ! 347: * accept data from writer ! 348: * -- handle all non-data messages ! 349: */ ! 350: pkoput(q, bp) ! 351: register struct queue *q; ! 352: register struct block *bp; ! 353: { ! 354: register struct pack *pkp = (struct pack *)q->ptr; ! 355: register union stmsg *sp; ! 356: ! 357: if (pkp->ostate == RCLOSE) { ! 358: freeb(bp); ! 359: return; ! 360: } ! 361: switch (bp->type) { ! 362: ! 363: case M_DELIM: ! 364: if (pkp->istate & PKDELIM) ! 365: goto isdata; ! 366: pkp->istate |= PKDELIM; ! 367: /* flow through */ ! 368: case M_FLUSH: ! 369: freeb(bp); ! 370: return; ! 371: ! 372: case M_IOCTL: ! 373: sp = (union stmsg *)bp->rptr; ! 374: switch (sp->ioc0.com) { ! 375: ! 376: case TIOCGETP: ! 377: sp->ioc1.sb.sg_erase = 0; ! 378: sp->ioc1.sb.sg_kill = 0; ! 379: sp->ioc1.sb.sg_flags = RAW; ! 380: bp->wptr = bp->rptr+sizeof(struct ioc1); ! 381: bp->type = M_IOCACK; ! 382: qreply(q, bp); ! 383: break; ! 384: ! 385: default: ! 386: (*q->next->qinfo->putp)(q->next, bp); ! 387: break; ! 388: } ! 389: return; ! 390: ! 391: default: ! 392: freeb(bp); ! 393: return; ! 394: ! 395: case M_DATA: ! 396: pkp->istate &= ~PKDELIM; ! 397: isdata: ! 398: putq(q, bp); ! 399: if (pkp->SN < pkp->S + pkp->XW) ! 400: qenable(q); ! 401: return; ! 402: } ! 403: } ! 404: ! 405: /* ! 406: * PK out server: ! 407: * if space in window, process queue ! 408: * take care of splitting packets bigger than segment size ! 409: * if timer has expired, retransmit ! 410: */ ! 411: pkosrv(q) ! 412: register struct queue *q; ! 413: { ! 414: register struct pack *pkp = (struct pack *)q->ptr; ! 415: register struct block *bp, *xbp; ! 416: ! 417: if (pkp->timer==0 && pkp->S != pkp->SN) ! 418: pkxmit(q, pkp->xpacks[pkp->S], pkp->S); ! 419: while (pkp->SN < pkp->S + pkp->XW) { ! 420: if ((bp = getq(q)) == NULL) ! 421: break; ! 422: if (bp->wptr-bp->rptr > pkp->xsegment) { ! 423: if ((xbp = allocb(pkp->xsegment)) == NULL) { ! 424: putbq(q, bp); ! 425: return; ! 426: } ! 427: bcopy(bp->rptr, xbp->wptr, pkp->xsegment); ! 428: bp->rptr += pkp->xsegment; ! 429: xbp->wptr += pkp->xsegment; ! 430: putbq(q, bp); ! 431: bp = xbp; ! 432: } ! 433: bp->type = M_DATA; /* M_DELIM -> 0-length write */ ! 434: pkp->xpacks[pkp->SN & 07] = bp; ! 435: pkxmit(q, bp, pkp->SN); ! 436: pkp->SN++; ! 437: } ! 438: } ! 439: ! 440: /* ! 441: * Send out a packet, with header. ! 442: * -- only a "pointer" to the data is sent; the original ! 443: * is kept. ! 444: */ ! 445: pkxmit(q, bp, pkno) ! 446: struct queue *q; ! 447: register struct block *bp; ! 448: unsigned pkno; ! 449: { ! 450: register struct block *hbp; ! 451: register size; ! 452: register seg; ! 453: register struct pack *pkp = (struct pack *)q->ptr; ! 454: register struct block *sbp = NULL; ! 455: register sizeadjust = 0; ! 456: static u_char zero[64]; ! 457: ! 458: if (bp == (struct block *)NULL) { ! 459: printf("0 bp in pkxmit\n"); ! 460: return; ! 461: } ! 462: pkp->timer = PKTIME; ! 463: if ((hbp = allocb(8)) == NULL) ! 464: return; /* hope timeouts will recover */ ! 465: pkno &= 07; ! 466: size = bp->wptr - bp->rptr; ! 467: /* compute header */ ! 468: hbp->wptr += 6; /* header size */ ! 469: hbp->rptr[0] = SYN; ! 470: hbp->rptr[1] = pkp->xlogseg; ! 471: seg = pkp->xsegment; ! 472: pkc_sum = -1; ! 473: pkc_x = 0; ! 474: pkc_size = seg; ! 475: if (size < seg) { ! 476: hbp->rptr[4] = PKSDATA | (pkno << 3) | pkp->R; ! 477: if ((sbp = allocb(2)) == NULL) { ! 478: freeb(hbp); ! 479: return; ! 480: } ! 481: /* hack in the size bytes */ ! 482: if ((seg - size) <= 127) { ! 483: *sbp->wptr++ = seg - size; ! 484: sizeadjust = 1; ! 485: } else { ! 486: *sbp->wptr++ = 0x80 + ((seg - size) & 0x7F); ! 487: *sbp->wptr++ = (seg - size) >> 7; ! 488: sizeadjust = 2; ! 489: } ! 490: pkcksum(sbp->rptr, sizeadjust); ! 491: pkcksum(bp->rptr, size); ! 492: seg -= size; ! 493: while (seg>0) { ! 494: pkcksum(zero, 64); ! 495: seg -= 64; ! 496: } ! 497: } else { ! 498: if (size > seg) { ! 499: printf("pk size botch\n"); ! 500: return; ! 501: } ! 502: hbp->rptr[4] = PKDATA | (pkno<<3) | pkp->R; ! 503: pkcksum(bp->rptr, size); ! 504: } ! 505: pkc_sum = CHECK - (pkc_sum ^ hbp->rptr[4]); ! 506: hbp->rptr[2] = pkc_sum; ! 507: hbp->rptr[3] = pkc_sum>>8; ! 508: hbp->rptr[5] = hbp->rptr[1]^hbp->rptr[2]^hbp->rptr[3]^hbp->rptr[4]; ! 509: /* send header */ ! 510: (*q->next->qinfo->putp)(q->next, hbp); ! 511: /* send size */ ! 512: if (sbp) ! 513: (*q->next->qinfo->putp)(q->next, sbp); ! 514: /* send data ptr */ ! 515: if (hbp = allocb(0)) { /* if fail, pray for timeout */ ! 516: hbp->rptr = bp->rptr; /* copy ptrs */ ! 517: hbp->wptr = bp->wptr; ! 518: (*q->next->qinfo->putp)(q->next, hbp); /* send data */ ! 519: } ! 520: /* send padding */ ! 521: seg = pkp->xsegment - sizeadjust; ! 522: while (size < seg) { ! 523: register deficit = seg - size; ! 524: if (deficit > 64) ! 525: deficit = 64; ! 526: if (hbp = allocb(deficit)) { ! 527: hbp->rptr = zero; ! 528: hbp->wptr = zero + deficit; ! 529: (*q->next->qinfo->putp)(q->next, hbp); ! 530: } ! 531: size += deficit; ! 532: } ! 533: } ! 534: ! 535: /* ! 536: * Receive an ack for a transmitted packet. ! 537: * Advance the window. Retransmit stacked up stuff if required. ! 538: */ ! 539: pkrack(pkp, packno, rxmit) ! 540: register unsigned packno; ! 541: register struct pack *pkp; ! 542: { ! 543: register struct block **bpp; ! 544: register s = spl5(); ! 545: ! 546: packno &= 07; ! 547: if (packno < pkp->S) ! 548: packno += 8; ! 549: pkp->timer = PKTIME; ! 550: if (packno < pkp->SN) ! 551: while (pkp->S <= packno) { ! 552: bpp = &pkp->xpacks[pkp->S & 07]; ! 553: if (*bpp) { ! 554: freeb(*bpp); ! 555: *bpp = NULL; ! 556: } ! 557: pkp->S++; ! 558: } ! 559: if (WR(pkp->rdq)->count) ! 560: qenable(WR(pkp->rdq)); ! 561: if (rxmit) { ! 562: for (packno = pkp->S; packno < pkp->SN; packno++) ! 563: pkxmit(WR(pkp->rdq), pkp->xpacks[packno&07], packno); ! 564: } ! 565: if (pkp->S >= 8) { ! 566: pkp->S -= 8; ! 567: pkp->SN -= 8; ! 568: } ! 569: splx(s); ! 570: } ! 571: ! 572: /* ! 573: * If n bytes are available, return 1, else 0. ! 574: */ ! 575: pkwant(pkp, n) ! 576: register n; ! 577: register struct pack *pkp; ! 578: { ! 579: register int navail = 0; ! 580: register struct block *bp; ! 581: int s = spl5(); ! 582: ! 583: for (bp = pkp->rdq->first; bp; bp = bp->next) { ! 584: navail += bp->wptr - bp->rptr; ! 585: if (navail >= n) { ! 586: splx(s); ! 587: return(1); ! 588: } ! 589: } ! 590: if (pkp->ostate==RCLOSE) ! 591: putctl(pkp->rdq->next, M_HANGUP); ! 592: pkp->iwant = n - navail; ! 593: splx(s); ! 594: return(0); ! 595: } ! 596: ! 597: /* ! 598: * Copy n bytes from the front of the queue. ! 599: */ ! 600: pkgetb(q, cp, n) ! 601: register struct queue *q; ! 602: register u_char *cp; ! 603: register n; ! 604: { ! 605: register struct block *bp; ! 606: ! 607: while (n) { ! 608: if ((bp = q->first) == NULL) { ! 609: printf("pkgetb fail\n"); ! 610: return; ! 611: } ! 612: if (bp->rptr >= bp->wptr) { ! 613: freeb(getq(q)); ! 614: continue; ! 615: } ! 616: *cp++ = *bp->rptr++; ! 617: --n; ! 618: } ! 619: if (bp->rptr >= bp->wptr) ! 620: freeb(getq(q)); ! 621: } ! 622: ! 623: /* ! 624: * The very strange checksum ! 625: */ ! 626: pkcksum(cp, nbytes) ! 627: register u_char *cp; ! 628: register nbytes; ! 629: { ! 630: register sum, t, x; ! 631: ! 632: if (nbytes > pkc_size) ! 633: nbytes = pkc_size; ! 634: sum = pkc_sum; ! 635: x = pkc_x; ! 636: while (--nbytes >= 0) { ! 637: sum <<= 1; ! 638: if (sum & 0x10000) ! 639: sum++; ! 640: t = sum & 0xFFFF; ! 641: sum += *cp++; ! 642: sum &= 0xFFFF; ! 643: x += sum ^ pkc_size; ! 644: pkc_size--; ! 645: if (sum <= t) ! 646: sum ^= x; ! 647: } ! 648: pkc_x = x; ! 649: pkc_sum = sum; ! 650: } ! 651: ! 652: /* ! 653: * Send a control packet ! 654: */ ! 655: pkscntl(pkp, cmd) ! 656: struct pack *pkp; ! 657: { ! 658: register struct block *bp; ! 659: register u_char *cp; ! 660: register struct queue *q; ! 661: ! 662: if ((bp = allocb(6)) == NULL) ! 663: return; /* what else to do? */ ! 664: bp->wptr += 6; ! 665: cp = bp->rptr; ! 666: *cp++ = SYN; ! 667: *cp++ = 9; /* ctl pack marker */ ! 668: *cp++ = cmd; ! 669: *cp++ = 0; ! 670: *cp++ = cmd; ! 671: *cp++ = 9; /* xor of hdr[1..4] */ ! 672: q = WR(pkp->rdq); ! 673: (*q->next->qinfo->putp)(q->next, bp); ! 674: } ! 675: ! 676: /* ! 677: * Receive a control packet ! 678: */ ! 679: pkcntl(pkp) ! 680: register struct pack *pkp; ! 681: { ! 682: register val; ! 683: register reject = 0; ! 684: ! 685: if (pkp->hdr.k != 9) { ! 686: return; ! 687: } ! 688: val = pkp->hdr.C & 07; ! 689: switch (pkp->hdr.C & 0370) { ! 690: ! 691: case PK_INITA: ! 692: pkp->timer = 2; ! 693: pkp->XW = val; ! 694: if (pkp->ostate==SINITA || pkp->ostate==SINITB) { ! 695: pkscntl(pkp, PK_INITA+RWINSIZE); ! 696: pkscntl(pkp, PK_INITB+RSEGSIZE); ! 697: pkp->ostate = SINITB; ! 698: return; ! 699: } ! 700: return; ! 701: ! 702: case PK_INITB: ! 703: pkp->timer = 2; ! 704: pkp->xsegment = pksizes[val+1]; ! 705: pkp->xlogseg = val + 1; ! 706: if (pkp->ostate==SINITB) { ! 707: pkp->ostate = SINITC; ! 708: pkscntl(pkp, PK_INITB+RSEGSIZE); ! 709: pkscntl(pkp, PK_INITC+RWINSIZE); ! 710: return; ! 711: } ! 712: return; ! 713: ! 714: case PK_INITC: ! 715: if (pkp->ostate>=SINITB) { ! 716: if (pkp->ostate==SINITB) ! 717: pkscntl(pkp, PK_INITC+RWINSIZE); ! 718: pkp->ostate = OPEN; ! 719: wakeup((caddr_t)pkp); ! 720: return; ! 721: } ! 722: return; ! 723: ! 724: case PK_RJ: ! 725: reject = 1; ! 726: case PK_RR: ! 727: pkrack(pkp, val, reject); ! 728: return; ! 729: ! 730: case PK_CLOSE: ! 731: pkp->ostate = RCLOSE; ! 732: flushq(WR(pkp->rdq), 0); ! 733: pkrack(pkp, pkp->SN-1, 0); ! 734: qenable(pkp->rdq); ! 735: return; ! 736: ! 737: default: ! 738: return; ! 739: } ! 740: } ! 741: ! 742: pktimer() ! 743: { ! 744: register struct pack *pkp; ! 745: ! 746: for (pkp = packs; pkp < &packs[NPK]; pkp++) { ! 747: if (pkp->timer) { ! 748: pkp->timer--; ! 749: continue; ! 750: } ! 751: switch (pkp->ostate) { ! 752: ! 753: case 0: ! 754: continue; ! 755: ! 756: case OPEN: ! 757: case LCLOSE: ! 758: qenable(WR(pkp->rdq)); ! 759: continue; ! 760: ! 761: case SINITA: ! 762: pkscntl(pkp, PK_INITA+RWINSIZE); ! 763: pkp->timer = 2; ! 764: continue; ! 765: ! 766: case SINITB: ! 767: pkscntl(pkp, PK_INITA+RWINSIZE); ! 768: pkscntl(pkp, PK_INITB+RSEGSIZE); ! 769: pkp->timer = 2; ! 770: continue; ! 771: } ! 772: } ! 773: timeout(pktimer, (caddr_t)NULL, 60); ! 774: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.