|
|
1.1 ! root 1: /* ! 2: ** Process receiver buffers ! 3: */ ! 4: ! 5: #include "pconfig.h" ! 6: #include "proto.h" ! 7: #include "packets.h" ! 8: #include "pstats.h" ! 9: ! 10: ! 11: /* extern int crc(); */ ! 12: void Reply(), Control(); ! 13: int Retry(); ! 14: ! 15: struct Pktstate precvpkt; ! 16: /* static */ Pkt_p Pkp; ! 17: /* static */ char * pbufp; ! 18: /* static */ char * Sbufp; ! 19: /* static */ short dcount; ! 20: /* static */ short Scount; ! 21: ! 22: #define Pkt precvpkt.pkt ! 23: #define State precvpkt.state ! 24: #define Timo precvpkt.timo ! 25: #define Header Pkt.header ! 26: #define Dsize Pkt.dsize ! 27: #define Data Pkp->data ! 28: ! 29: #define Ptyp (Pkt.header & P_PTYPE) ! 30: #define Cntl (Pkt.header & P_CNTL) ! 31: #define Channel P_channel(Pkt.header) ! 32: #define Seq P_seq(Pkt.header) ! 33: #define Nextseq pconvs[Channel].rseq ! 34: ! 35: ! 36: ! 37: void ! 38: #ifndef Blit ! 39: precv(bufp, count) ! 40: register char * bufp; ! 41: register int count; ! 42: { ! 43: int haveheader = 0; ! 44: ! 45: while ( count-- ) ! 46: #else Blit ! 47: precv(c) ! 48: char c; ! 49: #endif Blit ! 50: { ! 51: switch ( State ) ! 52: { ! 53: case PR_NULL: ! 54: # ifndef Blit ! 55: Pkp = (Pkt_p)bufp; ! 56: haveheader++; ! 57: Header = *bufp++; ! 58: # else Blit ! 59: Header = c; ! 60: # endif Blit ! 61: if ( !Ptyp ) ! 62: { ! 63: PSTATS(PS_BADHDR); ! 64: ptracepkt(Pkp, pstats[PS_BADHDR].descp); ! 65: break; ! 66: } ! 67: Timo = Prtimeout; ! 68: if ( !Ptflag ) ! 69: { ! 70: Ptflag++; ! 71: # ifndef Blit ! 72: (void)alarm(Pscanrate); ! 73: # endif ! 74: } ! 75: State = PR_SIZE; ! 76: # ifndef Blit ! 77: continue; ! 78: # else ! 79: return; ! 80: # endif ! 81: ! 82: case PR_SIZE: ! 83: # ifndef Blit ! 84: Dsize = *bufp++; ! 85: # else ! 86: Dsize = c; ! 87: # endif ! 88: Scount = Dsize; ! 89: if ( Scount > MAXPKTDSIZE ) ! 90: { ! 91: PSTATS(PS_BADSIZE); ! 92: ptracepkt((haveheader?Pkp:&Pkt), pstats[PS_BADSIZE].descp); ! 93: break; ! 94: } ! 95: dcount = Scount + EDSIZE; ! 96: # ifndef Blit ! 97: if ( dcount <= count && haveheader ) ! 98: { ! 99: /* Don't move data */ ! 100: Sbufp = bufp; ! 101: bufp += dcount; ! 102: count -= dcount; ! 103: goto check; ! 104: } ! 105: # endif ! 106: Pkp = &Pkt; ! 107: Sbufp = (char *)Data; ! 108: pbufp = Sbufp; ! 109: State = PR_DATA; ! 110: # ifndef Blit ! 111: continue; ! 112: # else ! 113: return; ! 114: # endif ! 115: ! 116: case PR_DATA: ! 117: # ifndef Blit ! 118: *pbufp++ = *bufp++; ! 119: # else ! 120: *pbufp++ = c; ! 121: # endif ! 122: if ( --dcount > 0 ) ! 123: # ifndef Blit ! 124: continue; ! 125: # else ! 126: return; ! 127: # endif ! 128: ! 129: check: ! 130: /** Now at CRC **/ ! 131: ! 132: plogpkt(Pkp, PLOGIN); ! 133: ! 134: if ( crc((uchar *)Pkp, (int)(Scount+2)) ) /* if bit fields were independent */ ! 135: { ! 136: PSTATS(PS_BADCRC); ! 137: ptracepkt(Pkp, pstats[PS_BADCRC].descp); ! 138: } ! 139: else ! 140: { ! 141: if ( Cntl ) ! 142: Control(); ! 143: else ! 144: { ! 145: Pcdata = (uchar)0; ! 146: if ( Seq == Nextseq ) ! 147: { ! 148: if ( (*Prfuncp)(Channel, Sbufp, Scount) ) ! 149: { ! 150: PSTATS(PS_BUSY); ! 151: /* Better to let this timeout, ! 152: ** as a following sequence will ! 153: ** generate a second retransmission ! 154: */ ! 155: Reply(NAK); ! 156: } ! 157: else ! 158: { ! 159: Nextseq = (Nextseq+1) & (SEQMOD-1); /* NB rseq is a byte, not a bit field, for efficiency */ ! 160: PSTATS(PS_RPKTS); ! 161: # ifdef PSTATISTICS ! 162: pstats[PS_RBYTES].count += Scount; ! 163: # endif ! 164: pconvs[Channel].cdata[Seq] = Pcdata; ! 165: Reply(ACK); ! 166: } ! 167: } ! 168: else ! 169: if ( Retry() ) ! 170: { ! 171: PSTATS(PS_RDUP); ! 172: Reply(ACK); ! 173: } ! 174: else ! 175: { ! 176: PSTATS(PS_OUTSEQ); ! 177: Reply(NAK); ! 178: pdumphist(pstats[PS_OUTSEQ].descp); ! 179: } ! 180: } ! 181: } ! 182: } ! 183: ! 184: Timo = 0; ! 185: State = PR_NULL; ! 186: #ifndef Blit ! 187: } ! 188: #endif ! 189: } ! 190: ! 191: ! 192: ! 193: /* ! 194: ** Deal with control packet ! 195: */ ! 196: ! 197: void ! 198: Control() ! 199: { ! 200: register Pch_p pcp = &pconvs[Channel]; ! 201: register Pks_p psp = pcp->nextpkt; ! 202: register Pbyte *lastseqp = &pseqtable[Seq+SEQMOD]; ! 203: register Pbyte *seqp = lastseqp - (NPCBUFS-1); ! 204: register int hit = 0; ! 205: # ifdef Blit ! 206: register int x = spl1(); ! 207: # endif ! 208: ! 209: if ( Scount == 0 ) ! 210: goto ack; ! 211: ! 212: switch ( Data[0] ) ! 213: { ! 214: case ACK: ! 215: /** This and all lesser sequenced packets ok **/ ! 216: ack: ! 217: do ! 218: { ! 219: if ( *seqp == P_seq(psp->pkt.header) ) ! 220: { ! 221: if ( psp->state != PX_WAIT ) ! 222: { ! 223: # if PDEBUG == 1 || PSTATISTICS == 1 ! 224: if ( psp->state != PX_OK ) ! 225: { ! 226: PSTATS(PS_BADXST); ! 227: pdumphist(pstats[PS_BADXST].descp); ! 228: } ! 229: # endif ! 230: } ! 231: else ! 232: { ! 233: psp->state = PX_OK; ! 234: psp->timo = 0; ! 235: hit++; ! 236: } ! 237: if ( ++psp >= &pcp->pkts[NPCBUFS] ) ! 238: psp = pcp->pkts; ! 239: } ! 240: } while ! 241: ( ++seqp <= lastseqp ); ! 242: if ( hit ) ! 243: { ! 244: pcp->nextpkt = psp; ! 245: pcp->freepkts += hit; ! 246: # ifdef PSTATISTICS ! 247: pstats[PS_XPKTS].count += hit; ! 248: if ( hit > 1 ) ! 249: PSTATS(PS_LOSTACK); ! 250: # endif ! 251: break; ! 252: } ! 253: # if PDEBUG == 1 || PSTATISTICS == 1 ! 254: PSTATS(PS_BADACK); ! 255: pdumphist(pstats[PS_BADACK].descp); ! 256: # endif ! 257: # ifdef Blit ! 258: splx(x); ! 259: # endif ! 260: return; ! 261: ! 262: case NAK: ! 263: /** Retransmit this and all lesser sequenced packets **/ ! 264: ! 265: do ! 266: { ! 267: if ( *seqp == P_seq(psp->pkt.header) ) ! 268: { ! 269: if ( psp->state != PX_WAIT ) ! 270: { ! 271: # if PSTATISTICS == 1 || PDEBUG == 1 ! 272: if ( psp->state != PX_OK ) ! 273: { ! 274: PSTATS(PS_BADXST); ! 275: pdumphist(pstats[PS_BADXST].descp); ! 276: } ! 277: # endif ! 278: } ! 279: else ! 280: { ! 281: psp->timo = Pxtimeout; ! 282: (void)Pxfunc(&psp->pkt, psp->size); ! 283: PSTATS(PS_NAKPKT); ! 284: hit++; ! 285: plogpkt(&psp->pkt, PLOGOUT); ! 286: } ! 287: if ( ++psp >= &pcp->pkts[NPCBUFS] ) ! 288: psp = pcp->pkts; ! 289: } ! 290: } while ! 291: ( ++seqp <= lastseqp ); ! 292: if ( !hit ) ! 293: { ! 294: PSTATS(PS_BADNAK); ! 295: pdumphist(pstats[PS_BADNAK].descp); ! 296: # ifdef Blit ! 297: splx(x); ! 298: # endif ! 299: return; ! 300: } ! 301: break; ! 302: ! 303: case PCDATA: ! 304: break; ! 305: ! 306: default: ! 307: PSTATS(PS_BADCNTL); ! 308: ptracepkt(Pkp, pstats[PS_BADCNTL].descp); ! 309: # ifdef Blit ! 310: splx(x); ! 311: # endif ! 312: return; ! 313: } ! 314: # ifdef Blit ! 315: splx(x); ! 316: # endif ! 317: ! 318: if ( --Scount > 0 ) ! 319: { ! 320: (*Prcfuncp)(Channel, Sbufp+1, Scount); ! 321: # ifdef PSTATISTICS ! 322: pstats[PS_RCBYTES].count += Scount; ! 323: # endif ! 324: } ! 325: } ! 326: ! 327: ! 328: ! 329: /* ! 330: ** Reply to good packet ! 331: */ ! 332: ! 333: void ! 334: Reply(ctl) ! 335: Pbyte ctl; ! 336: { ! 337: register int count; ! 338: ! 339: Pkt.header |= P_CNTL; ! 340: if ( Pcdata ) ! 341: { ! 342: PSTATS(PS_XCBYTES); ! 343: count = 2; ! 344: Pkt.data[1] = Pcdata; ! 345: Pkt.data[0] = ctl; ! 346: } ! 347: else ! 348: if ( ctl != ACK ) ! 349: { ! 350: count = 1; ! 351: Pkt.data[0] = ctl; ! 352: } ! 353: else ! 354: count = 0; ! 355: Dsize = count; ! 356: count += 2; /* if bit fields were independent */ ! 357: ! 358: (void)crc((Pbyte *)&Pkt, count); ! 359: count += EDSIZE; ! 360: ! 361: (void)Pxfunc(&Pkt, count); ! 362: plogpkt(&Pkt, PLOGOUT); ! 363: } ! 364: ! 365: ! 366: ! 367: /* ! 368: ** Non trivial sequence number validation: ! 369: ** is this a valid retransmission? ! 370: */ ! 371: ! 372: int ! 373: Retry() ! 374: { ! 375: register Pbyte *lastseqp = &pseqtable[Nextseq+SEQMOD-1]; ! 376: register Pbyte *seqp = lastseqp - (NPCBUFS-1); ! 377: ! 378: do ! 379: if ( *seqp == Seq ) ! 380: { ! 381: Pcdata = pconvs[Channel].cdata[Seq]; ! 382: return 1; ! 383: } ! 384: while ! 385: ( ++seqp <= lastseqp ); ! 386: ! 387: return 0; ! 388: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.