|
|
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.