78ed81a3 |
1 | /* protg.c |
2 | The 'g' protocol. |
3 | |
4 | Copyright (C) 1991, 1992 Ian Lance Taylor |
5 | |
6 | This file is part of the Taylor UUCP package. |
7 | |
8 | This program is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU General Public License as |
10 | published by the Free Software Foundation; either version 2 of the |
11 | License, or (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, but |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21 | |
22 | The author of the program may be contacted at ian@airs.com or |
23 | c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. |
24 | */ |
25 | |
26 | #include "uucp.h" |
27 | |
28 | #if USE_RCS_ID |
29 | const char protg_rcsid[] = "$Id: protg.c,v 1.1 1993/08/04 19:36:20 jtc Exp $"; |
30 | #endif |
31 | |
32 | #include <ctype.h> |
33 | #include <errno.h> |
34 | |
35 | #include "uudefs.h" |
36 | #include "uuconf.h" |
37 | #include "conn.h" |
38 | #include "trans.h" |
39 | #include "system.h" |
40 | #include "prot.h" |
41 | \f |
42 | /* Each 'g' protocol packet begins with six bytes. They are: |
43 | |
44 | <DLE><k><c0><c1><C><x> |
45 | |
46 | <DLE> is the ASCII DLE character (^P or '\020'). |
47 | if 1 <= <k> <= 8, the packet is followed by 2 ** (k + 4) bytes of data; |
48 | if <k> == 9, these six bytes are a complete control packet; |
49 | other value of <k> are illegal. |
50 | <c0> is the low byte of a checksum. |
51 | <c1> is the high byte of a checksum. |
52 | <C> is a control byte (see below). |
53 | <x> is <k> ^ <c0> ^ <c1> ^ <C>. |
54 | |
55 | The control byte <C> is divided into three bitfields: |
56 | |
57 | t t x x x y y y |
58 | |
59 | The two bit field tt is the packet type. |
60 | The three bit field xxx is the control type for a control packet, or |
61 | the sequence number for a data packet. |
62 | The three bit field yyy is a value for a control packet, or the |
63 | sequence number of the last packet received for a data packet. |
64 | |
65 | For all successfully recieved packets, the control byte is stored |
66 | into iGpacket_control. */ |
67 | |
68 | /* Names for the bytes in the frame header. */ |
69 | #define IFRAME_DLE (0) |
70 | #define IFRAME_K (1) |
71 | #define IFRAME_CHECKLOW (2) |
72 | #define IFRAME_CHECKHIGH (3) |
73 | #define IFRAME_CONTROL (4) |
74 | #define IFRAME_XOR (5) |
75 | |
76 | /* Length of the frame header. */ |
77 | #define CFRAMELEN (6) |
78 | |
79 | /* Macros to break apart the control bytes. */ |
80 | #define CONTROL_TT(b) ((int)(((b) >> 6) & 03)) |
81 | #define CONTROL_XXX(b) ((int)(((b) >> 3) & 07)) |
82 | #define CONTROL_YYY(b) ((int)((b) & 07)) |
83 | |
84 | /* DLE value. */ |
85 | #define DLE ('\020') |
86 | |
87 | /* Get the length of a packet given a pointer to the header. */ |
88 | #define CPACKLEN(z) ((size_t) (1 << ((z)[IFRAME_K] + 4))) |
89 | |
90 | /* <k> field value for a control message. */ |
91 | #define KCONTROL (9) |
92 | |
93 | /* Get the next sequence number given a sequence number. */ |
94 | #define INEXTSEQ(i) ((i + 1) & 07) |
95 | |
96 | /* Compute i1 - i2 modulo 8. */ |
97 | #define CSEQDIFF(i1, i2) (((i1) + 8 - (i2)) & 07) |
98 | |
99 | /* Packet types. These are from the tt field. |
100 | CONTROL -- control packet |
101 | ALTCHAN -- alternate channel; not used by UUCP |
102 | DATA -- full data segment |
103 | SHORTDATA -- less than full data segment (all the bytes specified by |
104 | the packet length <k> are always transferred). Let <u> be the number |
105 | of bytes in the data segment not to be used. If <u> <= 0x7f, the first |
106 | byte of the data segment is <u> and the data follows. If <u> > 0x7f, |
107 | the first byte of the data segment is 0x80 | (<u> & 0x7f), the second |
108 | byte of the data segment is <u> >> 7, and the data follows. The |
109 | maximum possible data segment size is 2**12, so this handles all |
110 | possible cases. */ |
111 | #define CONTROL (0) |
112 | #define ALTCHAN (1) |
113 | #define DATA (2) |
114 | #define SHORTDATA (3) |
115 | |
116 | /* Control types. These are from the xxx field if the type (tt field) |
117 | is CONTROL. |
118 | |
119 | CLOSE -- close the connection |
120 | RJ -- reject; packet yyy last to be received correctly |
121 | SRJ -- selective reject; reject only packet yyy (not used by UUCP) |
122 | RR -- receiver ready; packet yyy received correctly |
123 | INITC -- third step of initialization; yyy holds window size |
124 | INITB -- second step of initialization; yyy holds maximum <k> value - 1 |
125 | INITA -- first step of initialization; yyy holds window size. |
126 | |
127 | The yyy value for RR is the same as the yyy value for an ordinary |
128 | data packet. */ |
129 | #define CLOSE (1) |
130 | #define RJ (2) |
131 | #define SRJ (3) |
132 | #define RR (4) |
133 | #define INITC (5) |
134 | #define INITB (6) |
135 | #define INITA (7) |
136 | |
137 | /* Maximum amount of data in a single packet. This is set by the <k> |
138 | field in the header; the amount of data in a packet is |
139 | 2 ** (<k> + 4). <k> ranges from 1 to 8. */ |
140 | |
141 | #define CMAXDATAINDEX (8) |
142 | |
143 | #define CMAXDATA (1 << (CMAXDATAINDEX + 4)) |
144 | |
145 | /* Maximum window size. */ |
146 | #define CMAXWINDOW (7) |
147 | \f |
148 | /* Defaults for the protocol parameters. These may all be changed by |
149 | using the ``protocol-parameter g'' command, so there is no |
150 | particular reason to change the values given here. */ |
151 | |
152 | /* The desired window size. This is what we tell the other system to |
153 | use. It must be between 1 and 7, and there's no reason to use less |
154 | than 7. Protocol parameter ``window''. */ |
155 | #define IWINDOW (7) |
156 | |
157 | /* The desired packet size. Many implementations only support 64 byte |
158 | packets. Protocol parameter ``packet-size''. */ |
159 | #define IPACKSIZE (64) |
160 | |
161 | /* The number of times to retry the exchange of INIT packets when |
162 | starting the protocol. Protocol parameter ``startup-retries''. */ |
163 | #define CSTARTUP_RETRIES (8) |
164 | |
165 | /* The timeout to use when waiting for an INIT packet when starting up |
166 | the protocol. Protocol parameter ``init-timeout''. */ |
167 | #define CEXCHANGE_INIT_TIMEOUT (10) |
168 | |
169 | /* The number of times to retry sending and waiting for a single INIT |
170 | packet when starting the protocol. This controls a single INIT |
171 | packet, while CSTARTUP_RETRIES controls how many times to try the |
172 | entire INIT sequence. Protocol parameter ``init-retries''. */ |
173 | #define CEXCHANGE_INIT_RETRIES (4) |
174 | |
175 | /* The timeout to use when waiting for a packet. Protocol parameter |
176 | ``timeout''. */ |
177 | #define CTIMEOUT (10) |
178 | |
179 | /* The number of times to retry waiting for a packet. Each time the |
180 | timeout fails we send a copy of our last data packet or a reject |
181 | message for the packet we expect from the other side, depending on |
182 | whether we are waiting for an acknowledgement or a data packet. |
183 | This is the number of times we try doing that and then waiting |
184 | again. Protocol parameter ``retries''. */ |
185 | #define CRETRIES (6) |
186 | |
187 | /* If we see more than this much unrecognized data, we drop the |
188 | connection. This must be larger than a single packet size, which |
189 | means it must be larger than 4096 (the largest possible packet |
190 | size). Protocol parameter ``garbage''. */ |
191 | #define CGARBAGE (10000) |
192 | |
193 | /* If we see more than this many protocol errors, we drop the |
194 | connection. Protocol parameter ``errors''. */ |
195 | #define CERRORS (100) |
196 | |
197 | /* Default decay rate. Each time we send or receive this many packets |
198 | succesfully, we decrement the error level by one (protocol |
199 | parameter ``error-decay''). */ |
200 | #define CERROR_DECAY (10) |
201 | |
202 | /* If this value is non-zero, it will be used as the remote window |
203 | size regardless of what the other side requested. This can be |
204 | useful for dealing with some particularly flawed packages. This |
205 | default value should always be 0, and protocol parameter |
206 | ``remote-window'' should be used for the affected systems. */ |
207 | #define IREMOTE_WINDOW (0) |
208 | |
209 | /* If this value is non-zero, it will be used as the packet size to |
210 | send to the remote system regardless of what it requested. It's |
211 | difficult to imagine any circumstances where you would want to set |
212 | this. Protocol parameter ``remote-packet-size''. */ |
213 | #define IREMOTE_PACKSIZE (0) |
214 | \f |
215 | /* Local variables. */ |
216 | |
217 | /* Next sequence number to send. */ |
218 | static int iGsendseq; |
219 | |
220 | /* Last sequence number that has been acked. */ |
221 | static int iGremote_ack; |
222 | |
223 | /* Last sequence number to be retransmitted. */ |
224 | static int iGretransmit_seq; |
225 | |
226 | /* Last sequence number we have received. */ |
227 | static int iGrecseq; |
228 | |
229 | /* Last sequence number we have acked. */ |
230 | static int iGlocal_ack; |
231 | |
232 | /* Window size to request (protocol parameter ``window''). */ |
233 | static int iGrequest_winsize = IWINDOW; |
234 | |
235 | /* Packet size to request (protocol parameter ``packet-size''). */ |
236 | static int iGrequest_packsize = IPACKSIZE; |
237 | |
238 | /* Remote window size (set during handshake). */ |
239 | static int iGremote_winsize; |
240 | |
241 | /* Forced remote window size (protocol parameter ``remote-window''). */ |
242 | static int iGforced_remote_winsize = IREMOTE_WINDOW; |
243 | |
244 | /* Remote segment size (set during handshake). This is one less than |
245 | the value in a packet header. */ |
246 | static int iGremote_segsize; |
247 | |
248 | /* Remote packet size (set based on iGremote_segsize). */ |
249 | static size_t iGremote_packsize; |
250 | |
251 | /* Forced remote packet size (protocol parameter |
252 | ``remote-packet-size''). */ |
253 | static int iGforced_remote_packsize = IREMOTE_PACKSIZE; |
254 | |
255 | /* Recieved control byte. */ |
256 | static int iGpacket_control; |
257 | |
258 | /* Number of times to retry the initial handshake. Protocol parameter |
259 | ``startup-retries''. */ |
260 | static int cGstartup_retries = CSTARTUP_RETRIES; |
261 | |
262 | /* Number of times to retry sending an initial control packet. |
263 | Protocol parameter ``init-retries''. */ |
264 | static int cGexchange_init_retries = CEXCHANGE_INIT_RETRIES; |
265 | |
266 | /* Timeout (seconds) for receiving an initial control packet. |
267 | Protocol parameter ``init-timeout''. */ |
268 | static int cGexchange_init_timeout = CEXCHANGE_INIT_TIMEOUT; |
269 | |
270 | /* Timeout (seconds) for receiving a data packet. Protocol parameter |
271 | ``timeout''. */ |
272 | static int cGtimeout = CTIMEOUT; |
273 | |
274 | /* Maximum number of timeouts when receiving a data packet or |
275 | acknowledgement. Protocol parameter ``retries''. */ |
276 | static int cGretries = CRETRIES; |
277 | |
278 | /* Amount of garbage data we are prepared to see before giving up. |
279 | Protocol parameter ``garbage''. */ |
280 | static int cGgarbage_data = CGARBAGE; |
281 | |
282 | /* Maximum number of errors we are prepared to see before giving up. |
283 | Protocol parameter ``errors''. */ |
284 | static int cGmax_errors = CERRORS; |
285 | |
286 | /* Each time we receive this many packets succesfully, we decrement |
287 | the error level by one (protocol parameter ``error-decay''). */ |
288 | static int cGerror_decay = CERROR_DECAY; |
289 | |
290 | /* Whether to use shorter packets when possible. Protocol parameter |
291 | ``short-packets''. */ |
292 | static boolean fGshort_packets = TRUE; |
293 | |
294 | /* Protocol parameter commands. */ |
295 | struct uuconf_cmdtab asGproto_params[] = |
296 | { |
297 | { "window", UUCONF_CMDTABTYPE_INT, (pointer) &iGrequest_winsize, NULL }, |
298 | { "packet-size", UUCONF_CMDTABTYPE_INT, (pointer) &iGrequest_packsize, |
299 | NULL }, |
300 | { "startup-retries", UUCONF_CMDTABTYPE_INT, (pointer) &cGstartup_retries, |
301 | NULL }, |
302 | { "init-timeout", UUCONF_CMDTABTYPE_INT, (pointer) &cGexchange_init_timeout, |
303 | NULL }, |
304 | { "init-retries", UUCONF_CMDTABTYPE_INT, (pointer) &cGexchange_init_retries, |
305 | NULL }, |
306 | { "timeout", UUCONF_CMDTABTYPE_INT, (pointer) &cGtimeout, NULL }, |
307 | { "retries", UUCONF_CMDTABTYPE_INT, (pointer) &cGretries, NULL }, |
308 | { "garbage", UUCONF_CMDTABTYPE_INT, (pointer) &cGgarbage_data, NULL }, |
309 | { "errors", UUCONF_CMDTABTYPE_INT, (pointer) &cGmax_errors, NULL }, |
310 | { "error-decay", UUCONF_CMDTABTYPE_INT, (pointer) &cGerror_decay, NULL }, |
311 | { "remote-window", UUCONF_CMDTABTYPE_INT, |
312 | (pointer) &iGforced_remote_winsize, NULL }, |
313 | { "remote-packet-size", UUCONF_CMDTABTYPE_INT, |
314 | (pointer) &iGforced_remote_packsize, NULL }, |
315 | { "short-packets", UUCONF_CMDTABTYPE_BOOLEAN, (pointer) &fGshort_packets, |
316 | NULL }, |
317 | { NULL, 0, NULL, NULL } |
318 | }; |
319 | |
320 | /* Statistics. */ |
321 | |
322 | /* Number of packets we have sent. */ |
323 | static long cGsent_packets; |
324 | |
325 | /* Number of packets we have resent (these are not included in |
326 | cGsent_packets). */ |
327 | static long cGresent_packets; |
328 | |
329 | /* Number of packets we have delayed sending (these should not be |
330 | counted in cGresent_packets). */ |
331 | static long cGdelayed_packets; |
332 | |
333 | /* Number of packets we have received. */ |
334 | static long cGrec_packets; |
335 | |
336 | /* Number of packets rejected because the header was bad. */ |
337 | static long cGbad_hdr; |
338 | |
339 | /* Number of packets rejected because the checksum was bad. */ |
340 | static long cGbad_checksum; |
341 | |
342 | /* Number of packets received out of order. */ |
343 | static long cGbad_order; |
344 | |
345 | /* Number of packets rejected by receiver (number of RJ packets |
346 | received). */ |
347 | static long cGremote_rejects; |
348 | |
349 | /* The error level. This is the total number of errors as adjusted by |
350 | cGerror_decay. */ |
351 | static long cGerror_level; |
352 | |
353 | /* Each time we send an RJ, we can expect several out of order of |
354 | packets, because the other side will probably have sent a full |
355 | window by the time it sees the RJ. This variable keeps track of |
356 | the number of out of order packets we expect to see. We don't |
357 | count expected out of order packets against the error level. This |
358 | is reset to 0 when an in order packet is received. */ |
359 | static int cGexpect_bad_order; |
360 | |
361 | #if DEBUG > 1 |
362 | /* Control packet names used for debugging. */ |
363 | static const char * const azGcontrol[] = |
364 | {"?0?", "CLOSE", "RJ", "SRJ", "RR", "INITC", "INITB", "INITA"}; |
365 | #endif |
366 | \f |
367 | /* Local functions. */ |
368 | static boolean fgexchange_init P((struct sdaemon *qdaemon, int ictl, |
369 | int ival, int *piset)); |
370 | static boolean fgsend_control P((struct sdaemon *qdaemon, int ictl, |
371 | int ival)); |
372 | static char *zgadjust_ack P((int iseq)); |
373 | static boolean fgwait_for_packet P((struct sdaemon *qdaemon, |
374 | boolean freturncontrol, int ctimeout, |
375 | int cretries)); |
376 | static boolean fgsend_acks P((struct sdaemon *qdaemon)); |
377 | static boolean fggot_ack P((struct sdaemon *qdaemon, int iack)); |
378 | static boolean fgprocess_data P((struct sdaemon *qdaemon, boolean fdoacks, |
379 | boolean freturncontrol, |
380 | boolean *pfexit, size_t *pcneed, |
381 | boolean *pffound)); |
382 | static boolean fginit_sendbuffers P((boolean fallocate)); |
383 | static boolean fgcheck_errors P((struct sdaemon *qdaemon)); |
384 | static int igchecksum P((const char *zdata, size_t clen)); |
385 | static int igchecksum2 P((const char *zfirst, size_t cfirst, |
386 | const char *zsecond, size_t csecond)); |
387 | \f |
388 | /* Start the protocol. This requires a three way handshake. Both sides |
389 | must send and receive an INITA packet, an INITB packet, and an INITC |
390 | packet. The INITA and INITC packets contain the window size, and the |
391 | INITB packet contains the packet size. */ |
392 | |
393 | boolean |
394 | fgstart (qdaemon, pzlog) |
395 | struct sdaemon *qdaemon; |
396 | char **pzlog; |
397 | { |
398 | int iseg; |
399 | int i; |
400 | boolean fgota, fgotb; |
401 | |
402 | *pzlog = NULL; |
403 | |
404 | /* The 'g' protocol requires a full eight bit interface. */ |
405 | if (! fconn_set (qdaemon->qconn, PARITYSETTING_NONE, |
406 | STRIPSETTING_EIGHTBITS, XONXOFF_OFF)) |
407 | return FALSE; |
408 | |
409 | iGsendseq = 1; |
410 | iGremote_ack = 0; |
411 | iGretransmit_seq = -1; |
412 | iGrecseq = 0; |
413 | iGlocal_ack = 0; |
414 | cGsent_packets = 0; |
415 | cGresent_packets = 0; |
416 | cGdelayed_packets = 0; |
417 | cGrec_packets = 0; |
418 | cGbad_hdr = 0; |
419 | cGbad_checksum = 0; |
420 | cGbad_order = 0; |
421 | cGremote_rejects = 0; |
422 | cGerror_level = 0; |
423 | cGexpect_bad_order = 0; |
424 | |
425 | /* We must determine the segment size based on the packet size |
426 | which may have been modified by a protocol parameter command. |
427 | A segment size of 2^n is passed as n - 5. */ |
428 | i = iGrequest_packsize; |
429 | iseg = -1; |
430 | while (i > 0) |
431 | { |
432 | ++iseg; |
433 | i >>= 1; |
434 | } |
435 | iseg -= 5; |
436 | if (iseg < 0 || iseg > 7) |
437 | { |
438 | ulog (LOG_ERROR, "Illegal packet size %d for '%c' protocol", |
439 | iGrequest_packsize, qdaemon->qproto->bname); |
440 | iseg = 1; |
441 | } |
442 | |
443 | fgota = FALSE; |
444 | fgotb = FALSE; |
445 | for (i = 0; i < cGstartup_retries; i++) |
446 | { |
447 | if (fgota) |
448 | { |
449 | if (! fgsend_control (qdaemon, INITA, iGrequest_winsize)) |
450 | return FALSE; |
451 | } |
452 | else |
453 | { |
454 | if (! fgexchange_init (qdaemon, INITA, iGrequest_winsize, |
455 | &iGremote_winsize)) |
456 | continue; |
457 | } |
458 | fgota = TRUE; |
459 | |
460 | if (fgotb) |
461 | { |
462 | if (! fgsend_control (qdaemon, INITB, iseg)) |
463 | return FALSE; |
464 | } |
465 | else |
466 | { |
467 | if (! fgexchange_init (qdaemon, INITB, iseg, &iGremote_segsize)) |
468 | continue; |
469 | } |
470 | fgotb = TRUE; |
471 | |
472 | if (! fgexchange_init (qdaemon, INITC, iGrequest_winsize, |
473 | &iGremote_winsize)) |
474 | continue; |
475 | |
476 | /* We have succesfully connected. Determine the remote packet |
477 | size. */ |
478 | iGremote_packsize = 1 << (iGremote_segsize + 5); |
479 | |
480 | /* If the user requested us to force specific remote window and |
481 | packet sizes, do so now. */ |
482 | if (iGforced_remote_winsize > 0 |
483 | && iGforced_remote_winsize <= CMAXWINDOW) |
484 | iGremote_winsize = iGforced_remote_winsize; |
485 | |
486 | if (iGforced_remote_packsize >= 32 |
487 | && iGforced_remote_packsize <= 4096) |
488 | { |
489 | /* Force the value to a power of two. */ |
490 | i = iGforced_remote_packsize; |
491 | iseg = -1; |
492 | while (i > 0) |
493 | { |
494 | ++iseg; |
495 | i >>= 1; |
496 | } |
497 | iGremote_packsize = 1 << iseg; |
498 | iGremote_segsize = iseg - 5; |
499 | } |
500 | |
501 | /* Set up packet buffers to use. We don't do this until we know |
502 | the maximum packet size we are going to send. */ |
503 | if (! fginit_sendbuffers (TRUE)) |
504 | return FALSE; |
505 | |
506 | *pzlog = zbufalc (sizeof "protocol '' packet size window " + 50); |
507 | sprintf (*pzlog, "protocol '%c' packet size %d window %d", |
508 | qdaemon->qproto->bname, (int) iGremote_packsize, |
509 | (int) iGremote_winsize); |
510 | |
511 | return TRUE; |
512 | } |
513 | |
514 | DEBUG_MESSAGE0 (DEBUG_PROTO | DEBUG_ABNORMAL, |
515 | "fgstart: Protocol startup failed"); |
516 | |
517 | return FALSE; |
518 | } |
519 | \f |
520 | /* The 'G' protocol is identical to the 'g' protocol, except that |
521 | short packets are never supported. */ |
522 | |
523 | boolean |
524 | fbiggstart (qdaemon, pzlog) |
525 | struct sdaemon *qdaemon; |
526 | char **pzlog; |
527 | { |
528 | fGshort_packets = FALSE; |
529 | return fgstart (qdaemon, pzlog); |
530 | } |
531 | \f |
532 | /* Exchange initialization messages with the other system. |
533 | |
534 | A problem: |
535 | |
536 | We send INITA; it gets received |
537 | We receive INITA |
538 | We send INITB; it gets garbled |
539 | We receive INITB |
540 | |
541 | We have seen and sent INITB, so we start to send INITC. The other |
542 | side as sent INITB but not seen it, so it times out and resends |
543 | INITB. We will continue sending INITC and the other side will |
544 | continue sending INITB until both sides give up and start again |
545 | with INITA. |
546 | |
547 | It might seem as though if we are sending INITC and receive INITB, |
548 | we should resend our INITB, but this could cause infinite echoing |
549 | of INITB on a long-latency line. Rather than risk that, I have |
550 | implemented a fast drop-back procedure. If we are sending INITB and |
551 | receive INITC, the other side has gotten ahead of us. We immediately |
552 | fail and begin again with INITA. For the other side, if we are |
553 | sending INITC and see INITA, we also immediately fail back to INITA. |
554 | |
555 | Unfortunately, this doesn't work for the other case, in which we |
556 | are sending INITB but the other side has not yet seen INITA. As |
557 | far as I can see, if this happens we just have to wait until we |
558 | time out and resend INITA. */ |
559 | |
560 | static boolean |
561 | fgexchange_init (qdaemon, ictl, ival, piset) |
562 | struct sdaemon *qdaemon; |
563 | int ictl; |
564 | int ival; |
565 | int *piset; |
566 | { |
567 | int i; |
568 | |
569 | /* The three-way handshake should be independent of who initializes |
570 | it, but it seems that some versions of uucico assume that the |
571 | caller sends first and the callee responds. This only matters if |
572 | we are the callee and the first packet is garbled. If we send a |
573 | packet, the other side will assume that we must have seen the |
574 | packet they sent and will never time out and send it again. |
575 | Therefore, if we are the callee we don't send a packet the first |
576 | time through the loop. This can still fail, but should usually |
577 | work, and, after all, if the initialization packets are received |
578 | correctly there will be no problem no matter what we do. */ |
579 | for (i = 0; i < cGexchange_init_retries; i++) |
580 | { |
581 | long itime; |
582 | int ctimeout; |
583 | |
584 | if (qdaemon->fcaller || i > 0) |
585 | { |
586 | if (! fgsend_control (qdaemon, ictl, ival)) |
587 | return FALSE; |
588 | } |
589 | |
590 | itime = ixsysdep_time ((long *) NULL); |
591 | ctimeout = cGexchange_init_timeout; |
592 | |
593 | do |
594 | { |
595 | long inewtime; |
596 | |
597 | /* We pass 0 as the retry count to fgwait_for_packet because |
598 | we want to handle retries here and because if it retried |
599 | it would send a packet, which would be bad. */ |
600 | if (! fgwait_for_packet (qdaemon, TRUE, ctimeout, 0)) |
601 | break; |
602 | |
603 | if (CONTROL_TT (iGpacket_control) == CONTROL) |
604 | { |
605 | if (CONTROL_XXX (iGpacket_control) == ictl) |
606 | { |
607 | *piset = CONTROL_YYY (iGpacket_control); |
608 | |
609 | /* If we didn't already send our initialization |
610 | packet, send it now. */ |
611 | if (! qdaemon->fcaller && i == 0) |
612 | { |
613 | if (! fgsend_control (qdaemon, ictl, ival)) |
614 | return FALSE; |
615 | } |
616 | |
617 | return TRUE; |
618 | } |
619 | |
620 | /* If the other side is farther along than we are, |
621 | we have lost a packet. Fail immediately back to |
622 | INITA (but don't fail if we are already doing INITA, |
623 | since that would count against cStart_retries more |
624 | than it should). */ |
625 | if (CONTROL_XXX (iGpacket_control) < ictl && ictl != INITA) |
626 | return FALSE; |
627 | |
628 | /* If we are sending INITC and we receive an INITA, the other |
629 | side has failed back (we know this because we have |
630 | seen an INITB from them). Fail back ourselves to |
631 | start the whole handshake over again. */ |
632 | if (CONTROL_XXX (iGpacket_control) == INITA && ictl == INITC) |
633 | return FALSE; |
634 | |
635 | /* As a special hack, if we are sending INITC and we |
636 | receive INITB, we update the segment size from the |
637 | packet. This permits a second INITB to override the |
638 | first one. It would be nice to do this in a cleaner |
639 | way. */ |
640 | if (CONTROL_XXX (iGpacket_control) == INITB && ictl == INITC) |
641 | iGremote_segsize = CONTROL_YYY (iGpacket_control); |
642 | } |
643 | |
644 | inewtime = ixsysdep_time ((long *) NULL); |
645 | ctimeout -= inewtime - itime; |
646 | } |
647 | while (ctimeout > 0); |
648 | } |
649 | |
650 | return FALSE; |
651 | } |
652 | \f |
653 | /* Shut down the protocol. */ |
654 | |
655 | boolean |
656 | fgshutdown (qdaemon) |
657 | struct sdaemon *qdaemon; |
658 | { |
659 | (void) fgsend_control (qdaemon, CLOSE, 0); |
660 | (void) fgsend_control (qdaemon, CLOSE, 0); |
661 | (void) fginit_sendbuffers (FALSE); |
662 | |
663 | /* The count of sent packets may not be accurate, because some of |
664 | them may have not been sent yet if the connection failed in the |
665 | middle (the ones that counted for cGdelayed_packets). I don't |
666 | think it's worth being precise. */ |
667 | ulog (LOG_NORMAL, |
668 | "Protocol '%c' packets: sent %ld, resent %ld, received %ld", |
669 | qdaemon->qproto->bname, cGsent_packets, |
670 | cGresent_packets - cGdelayed_packets, cGrec_packets); |
671 | if (cGbad_hdr != 0 |
672 | || cGbad_checksum != 0 |
673 | || cGbad_order != 0 |
674 | || cGremote_rejects != 0) |
675 | ulog (LOG_NORMAL, |
676 | "Errors: header %ld, checksum %ld, order %ld, remote rejects %ld", |
677 | cGbad_hdr, cGbad_checksum, cGbad_order, cGremote_rejects); |
678 | |
679 | /* Reset all the parameters to their default values, so that the |
680 | protocol parameters used for this connection do not affect the |
681 | next one. */ |
682 | iGrequest_winsize = IWINDOW; |
683 | iGrequest_packsize = IPACKSIZE; |
684 | cGstartup_retries = CSTARTUP_RETRIES; |
685 | cGexchange_init_timeout = CEXCHANGE_INIT_TIMEOUT; |
686 | cGexchange_init_retries = CEXCHANGE_INIT_RETRIES; |
687 | cGtimeout = CTIMEOUT; |
688 | cGretries = CRETRIES; |
689 | cGgarbage_data = CGARBAGE; |
690 | cGmax_errors = CERRORS; |
691 | cGerror_decay = CERROR_DECAY; |
692 | iGforced_remote_winsize = IREMOTE_WINDOW; |
693 | iGforced_remote_packsize = IREMOTE_PACKSIZE; |
694 | fGshort_packets = TRUE; |
695 | |
696 | return TRUE; |
697 | } |
698 | \f |
699 | /* Send a command string. We send packets containing the string until |
700 | the entire string has been sent. Each packet is full. */ |
701 | |
702 | /*ARGSUSED*/ |
703 | boolean |
704 | fgsendcmd (qdaemon, z, ilocal, iremote) |
705 | struct sdaemon *qdaemon; |
706 | const char *z; |
707 | int ilocal; |
708 | int iremote; |
709 | { |
710 | size_t clen; |
711 | boolean fagain; |
712 | |
713 | DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "fgsendcmd: Sending command \"%s\"", z); |
714 | |
715 | clen = strlen (z); |
716 | |
717 | do |
718 | { |
719 | char *zpacket; |
720 | size_t cdummy; |
721 | |
722 | zpacket = zggetspace (qdaemon, &cdummy); |
723 | |
724 | if (clen < iGremote_packsize) |
725 | { |
726 | size_t csize; |
727 | |
728 | /* If the remote packet size is larger than 64 (the default, |
729 | which may indicate an older UUCP package), try to fit |
730 | this command into a smaller packet. We still always send |
731 | a complete packet, though. */ |
732 | if (iGremote_packsize <= 64 || ! fGshort_packets) |
733 | csize = iGremote_packsize; |
734 | else |
735 | { |
736 | csize = 32; |
737 | while (csize <= clen) |
738 | csize <<= 1; |
739 | } |
740 | |
741 | memcpy (zpacket, z, clen); |
742 | bzero (zpacket + clen, csize - clen); |
743 | fagain = FALSE; |
744 | |
745 | if (! fgsenddata (qdaemon, zpacket, csize, 0, 0, (long) 0)) |
746 | return FALSE; |
747 | } |
748 | else |
749 | { |
750 | memcpy (zpacket, z, iGremote_packsize); |
751 | z += iGremote_packsize; |
752 | clen -= iGremote_packsize; |
753 | fagain = TRUE; |
754 | |
755 | if (! fgsenddata (qdaemon, zpacket, iGremote_packsize, |
756 | 0, 0, (long) 0)) |
757 | return FALSE; |
758 | } |
759 | } |
760 | while (fagain); |
761 | |
762 | return TRUE; |
763 | } |
764 | \f |
765 | /* We keep an array of buffers to retransmit as necessary. Rather |
766 | than waste static space on large buffer sizes, we allocate the |
767 | buffers once we know how large the other system expects them to be. |
768 | The sequence numbers used in the 'g' protocol are only three bits |
769 | long, so we allocate eight buffers and maintain a correspondence |
770 | between buffer index and sequence number. This always wastes some |
771 | buffer space, but it's easy to implement. |
772 | |
773 | We leave room at the front of the buffer for the frame header and |
774 | two additional bytes. The two extra bytes are used for short |
775 | packets, which essentially use a longer header and shorter data. |
776 | We do this to avoid moving the data. We zero out any unused bytes |
777 | before the frame, so we can locate the real header given a buffer |
778 | by finding the first non-zero byte (which will be one of the first |
779 | three bytes in the buffer). */ |
780 | |
781 | #define CSENDBUFFERS (CMAXWINDOW + 1) |
782 | |
783 | static char *azGsendbuffers[CSENDBUFFERS]; |
784 | |
785 | static boolean |
786 | fginit_sendbuffers (fallocate) |
787 | boolean fallocate; |
788 | { |
789 | int i; |
790 | |
791 | /* Free up any remaining old buffers. */ |
792 | for (i = 0; i < CSENDBUFFERS; i++) |
793 | { |
794 | xfree ((pointer) azGsendbuffers[i]); |
795 | if (fallocate) |
796 | { |
797 | azGsendbuffers[i] = (char *) malloc (CFRAMELEN + 2 |
798 | + iGremote_packsize); |
799 | if (azGsendbuffers[i] == NULL) |
800 | return FALSE; |
801 | |
802 | /* This bzero might not seem necessary, since before we send |
803 | out each packet we zero out any non-data bytes. However, |
804 | if we receive an SRJ at the start of the conversation, we |
805 | will send out the packet before it has been set to |
806 | anything, thus sending the contents of our heap. We |
807 | avoid this by using bzero. */ |
808 | bzero (azGsendbuffers[i], CFRAMELEN + 2 + iGremote_packsize); |
809 | } |
810 | else |
811 | azGsendbuffers[i] = NULL; |
812 | } |
813 | return TRUE; |
814 | } |
815 | |
816 | /* Allocate a packet to send out. The return value of this function |
817 | must be filled in and passed to fgsenddata, or discarded. This |
818 | will ensure that the buffers and iGsendseq stay in synch. Set |
819 | *pclen to the amount of data to place in the buffer. */ |
820 | |
821 | /*ARGSUSED*/ |
822 | char * |
823 | zggetspace (qdaemon, pclen) |
824 | struct sdaemon *qdaemon; |
825 | size_t *pclen; |
826 | { |
827 | *pclen = iGremote_packsize; |
828 | return azGsendbuffers[iGsendseq] + CFRAMELEN + 2; |
829 | } |
830 | |
831 | /* Send out a data packet. This computes the checksum, sets up the |
832 | header, and sends the packet out. The argument zdata should point |
833 | to the return value of zggetspace. */ |
834 | |
835 | /*ARGSIGNORED*/ |
836 | boolean |
837 | fgsenddata (qdaemon, zdata, cdata, ilocal, iremote, ipos) |
838 | struct sdaemon *qdaemon; |
839 | char *zdata; |
840 | size_t cdata; |
841 | int ilocal; |
842 | int iremote; |
843 | long ipos; |
844 | { |
845 | char *z; |
846 | int itt, iseg; |
847 | size_t csize; |
848 | int iclr1, iclr2; |
849 | unsigned short icheck; |
850 | |
851 | /* Set the initial length bytes. See the description at the definition |
852 | of SHORTDATA, above. */ |
853 | itt = DATA; |
854 | csize = iGremote_packsize; |
855 | iseg = iGremote_segsize + 1; |
856 | |
857 | #if DEBUG > 0 |
858 | if (cdata > csize) |
859 | ulog (LOG_FATAL, "fgsend_packet: Packet size too large"); |
860 | #endif |
861 | |
862 | iclr1 = -1; |
863 | iclr2 = -2; |
864 | if (cdata < csize) |
865 | { |
866 | /* If the remote packet size is larger than 64, the default, we |
867 | can assume they can handle a smaller packet as well, which |
868 | will be more efficient to send. */ |
869 | if (iGremote_packsize > 64 && fGshort_packets) |
870 | { |
871 | /* The packet size is 1 << (iseg + 4). */ |
872 | iseg = 1; |
873 | csize = 32; |
874 | while (csize < cdata) |
875 | { |
876 | csize <<= 1; |
877 | ++iseg; |
878 | } |
879 | } |
880 | |
881 | if (csize != cdata) |
882 | { |
883 | size_t cshort; |
884 | |
885 | /* We have to add bytes which indicate how short the packet |
886 | is. We do this by pushing the header backward, which we |
887 | can do because we allocated two extra bytes for this |
888 | purpose. */ |
889 | iclr2 = 0; |
890 | itt = SHORTDATA; |
891 | cshort = csize - cdata; |
892 | if (cshort <= 127) |
893 | { |
894 | --zdata; |
895 | zdata[0] = (char) cshort; |
896 | zdata[-1] = '\0'; |
897 | bzero (zdata + cdata + 1, cshort - 1); |
898 | } |
899 | else |
900 | { |
901 | zdata -= 2; |
902 | zdata[0] = (char) (0x80 | (cshort & 0x7f)); |
903 | zdata[1] = (char) (cshort >> 7); |
904 | bzero (zdata + cdata + 2, cshort - 2); |
905 | iclr1 = 0; |
906 | } |
907 | } |
908 | } |
909 | |
910 | z = zdata - CFRAMELEN; |
911 | |
912 | /* Zero out the preceding bytes, in case the last time this buffer |
913 | was used those bytes were used. We need to zero out the initial |
914 | bytes so that we can find the true start of the packet in |
915 | zgadjust_ack. */ |
916 | z[iclr1] = '\0'; |
917 | z[iclr2] = '\0'; |
918 | |
919 | z[IFRAME_DLE] = DLE; |
920 | z[IFRAME_K] = (char) iseg; |
921 | |
922 | icheck = (unsigned short) igchecksum (zdata, csize); |
923 | |
924 | /* We're just about ready to go. Wait until there is room in the |
925 | receiver's window for us to send the packet. We do this now so |
926 | that we send the correct value for the last packet received. |
927 | Note that if iGsendseq == iGremote_ack, this means that the |
928 | sequence numbers are actually 8 apart, since the packet could not |
929 | have been acknowledged before it was sent; this can happen when |
930 | the window size is 7. */ |
931 | while (iGsendseq == iGremote_ack |
932 | || CSEQDIFF (iGsendseq, iGremote_ack) > iGremote_winsize) |
933 | { |
934 | if (! fgwait_for_packet (qdaemon, TRUE, cGtimeout, cGretries)) |
935 | return FALSE; |
936 | } |
937 | |
938 | /* Ack all packets up to the next one, since the UUCP protocol |
939 | requires that all packets be acked in order. */ |
940 | while (CSEQDIFF (iGrecseq, iGlocal_ack) > 1) |
941 | { |
942 | iGlocal_ack = INEXTSEQ (iGlocal_ack); |
943 | if (! fgsend_control (qdaemon, RR, iGlocal_ack)) |
944 | return FALSE; |
945 | } |
946 | iGlocal_ack = iGrecseq; |
947 | |
948 | z[IFRAME_CONTROL] = (char) ((itt << 6) | (iGsendseq << 3) | iGrecseq); |
949 | |
950 | iGsendseq = INEXTSEQ (iGsendseq); |
951 | |
952 | icheck = ((unsigned short) |
953 | ((0xaaaa - (icheck ^ (z[IFRAME_CONTROL] & 0xff))) & 0xffff)); |
954 | z[IFRAME_CHECKLOW] = (char) (icheck & 0xff); |
955 | z[IFRAME_CHECKHIGH] = (char) (icheck >> 8); |
956 | |
957 | z[IFRAME_XOR] = (char) (z[IFRAME_K] ^ z[IFRAME_CHECKLOW] |
958 | ^ z[IFRAME_CHECKHIGH] ^ z[IFRAME_CONTROL]); |
959 | |
960 | /* If we're waiting for acks of retransmitted packets, then don't |
961 | send this packet yet. The other side may not be ready for it |
962 | yet. Instead, code in fggot_ack will send the outstanding |
963 | packets when an ack is received. */ |
964 | ++cGsent_packets; |
965 | |
966 | if (iGretransmit_seq != -1) |
967 | { |
968 | ++cGdelayed_packets; |
969 | return TRUE; |
970 | } |
971 | |
972 | DEBUG_MESSAGE2 (DEBUG_PROTO, |
973 | "fgsenddata: Sending packet %d (%d bytes)", |
974 | CONTROL_XXX (z[IFRAME_CONTROL]), cdata); |
975 | |
976 | return fsend_data (qdaemon->qconn, z, CFRAMELEN + csize, TRUE); |
977 | } |
978 | |
979 | /* Recompute the control byte and checksum of a packet so that it |
980 | includes the correct packet acknowledgement. This is called when a |
981 | packet is retransmitted to make sure the retransmission does not |
982 | confuse the other side. It returns a pointer to the start of the |
983 | packet, skipping the bytes that may be unused at the start of |
984 | azGsendbuffers[iseq]. */ |
985 | |
986 | static char * |
987 | zgadjust_ack (iseq) |
988 | int iseq; |
989 | { |
990 | register char *z; |
991 | unsigned short icheck; |
992 | |
993 | z = azGsendbuffers[iseq]; |
994 | if (*z == '\0') |
995 | ++z; |
996 | if (*z == '\0') |
997 | ++z; |
998 | |
999 | /* If the received packet number is the same, there is nothing |
1000 | to do. */ |
1001 | if (CONTROL_YYY (z[IFRAME_CONTROL]) == iGrecseq) |
1002 | return z; |
1003 | |
1004 | /* Get the old checksum. */ |
1005 | icheck = (unsigned short) (((z[IFRAME_CHECKHIGH] & 0xff) << 8) |
1006 | | (z[IFRAME_CHECKLOW] & 0xff)); |
1007 | icheck = ((unsigned short) |
1008 | (((0xaaaa - icheck) ^ (z[IFRAME_CONTROL] & 0xff)) & 0xffff)); |
1009 | |
1010 | /* Update the control byte. */ |
1011 | z[IFRAME_CONTROL] = (char) ((z[IFRAME_CONTROL] &~ 07) | iGrecseq); |
1012 | |
1013 | /* Create the new checksum. */ |
1014 | icheck = ((unsigned short) |
1015 | ((0xaaaa - (icheck ^ (z[IFRAME_CONTROL] & 0xff))) & 0xffff)); |
1016 | z[IFRAME_CHECKLOW] = (char) (icheck & 0xff); |
1017 | z[IFRAME_CHECKHIGH] = (char) (icheck >> 8); |
1018 | |
1019 | /* Update the XOR byte. */ |
1020 | z[IFRAME_XOR] = (char) (z[IFRAME_K] ^ z[IFRAME_CHECKLOW] |
1021 | ^ z[IFRAME_CHECKHIGH] ^ z[IFRAME_CONTROL]); |
1022 | |
1023 | return z; |
1024 | } |
1025 | |
1026 | /* Send a control packet. These are fairly simple to construct. It |
1027 | seems reasonable to me that we should be able to send a control |
1028 | packet at any time, even if the receive window is closed. In |
1029 | particular, we don't want to delay when sending a CLOSE control |
1030 | message. If I'm wrong, it can be changed easily enough. */ |
1031 | |
1032 | static boolean |
1033 | fgsend_control (qdaemon, ixxx, iyyy) |
1034 | struct sdaemon *qdaemon; |
1035 | int ixxx; |
1036 | int iyyy; |
1037 | { |
1038 | char ab[CFRAMELEN]; |
1039 | int ictl; |
1040 | unsigned short icheck; |
1041 | |
1042 | #if DEBUG > 1 |
1043 | if (FDEBUGGING (DEBUG_PROTO) || |
1044 | (FDEBUGGING (DEBUG_ABNORMAL) && ixxx != RR)) |
1045 | ulog (LOG_DEBUG, "fgsend_control: Sending control %s %d", |
1046 | azGcontrol[ixxx], iyyy); |
1047 | #endif |
1048 | |
1049 | ab[IFRAME_DLE] = DLE; |
1050 | ab[IFRAME_K] = KCONTROL; |
1051 | |
1052 | ictl = (CONTROL << 6) | (ixxx << 3) | iyyy; |
1053 | icheck = (unsigned short) (0xaaaa - ictl); |
1054 | ab[IFRAME_CHECKLOW] = (char) (icheck & 0xff); |
1055 | ab[IFRAME_CHECKHIGH] = (char) (icheck >> 8); |
1056 | |
1057 | ab[IFRAME_CONTROL] = (char) ictl; |
1058 | |
1059 | ab[IFRAME_XOR] = (char) (ab[IFRAME_K] ^ ab[IFRAME_CHECKLOW] |
1060 | ^ ab[IFRAME_CHECKHIGH] ^ ab[IFRAME_CONTROL]); |
1061 | |
1062 | return fsend_data (qdaemon->qconn, ab, (size_t) CFRAMELEN, TRUE); |
1063 | } |
1064 | \f |
1065 | /* Wait for data to come in. This continues processing until a |
1066 | complete file or command has been received. */ |
1067 | |
1068 | boolean |
1069 | fgwait (qdaemon) |
1070 | struct sdaemon *qdaemon; |
1071 | { |
1072 | return fgwait_for_packet (qdaemon, FALSE, cGtimeout, cGretries); |
1073 | } |
1074 | \f |
1075 | /* Get a packet. This is called when we have nothing to send, but |
1076 | want to wait for a packet to come in. If freturncontrol is TRUE, |
1077 | this will return after getting any control packet. Otherwise, it |
1078 | will continue to receive packets until a complete file or a |
1079 | complete command has been received. The timeout and the number of |
1080 | retries are specified as arguments. The function returns FALSE if |
1081 | an error occurs or if cretries timeouts of ctimeout seconds were |
1082 | exceeded. */ |
1083 | |
1084 | static boolean |
1085 | fgwait_for_packet (qdaemon, freturncontrol, ctimeout, cretries) |
1086 | struct sdaemon *qdaemon; |
1087 | boolean freturncontrol; |
1088 | int ctimeout; |
1089 | int cretries; |
1090 | { |
1091 | int ctimeouts; |
1092 | int cgarbage; |
1093 | int cshort; |
1094 | |
1095 | ctimeouts = 0; |
1096 | cgarbage = 0; |
1097 | cshort = 0; |
1098 | |
1099 | while (TRUE) |
1100 | { |
1101 | boolean fexit; |
1102 | size_t cneed; |
1103 | boolean ffound; |
1104 | size_t crec; |
1105 | |
1106 | if (! fgprocess_data (qdaemon, TRUE, freturncontrol, &fexit, |
1107 | &cneed, &ffound)) |
1108 | return FALSE; |
1109 | |
1110 | if (fexit) |
1111 | return TRUE; |
1112 | |
1113 | DEBUG_MESSAGE1 (DEBUG_PROTO, |
1114 | "fgwait_for_packet: Need %lu bytes", |
1115 | (unsigned long) cneed); |
1116 | |
1117 | if (ffound) |
1118 | { |
1119 | ctimeouts = 0; |
1120 | cgarbage = 0; |
1121 | } |
1122 | else |
1123 | { |
1124 | if (cgarbage > cGgarbage_data) |
1125 | { |
1126 | ulog (LOG_ERROR, "Too much unrecognized data"); |
1127 | return FALSE; |
1128 | } |
1129 | } |
1130 | |
1131 | if (! freceive_data (qdaemon->qconn, cneed, &crec, ctimeout, TRUE)) |
1132 | return FALSE; |
1133 | |
1134 | cgarbage += crec; |
1135 | |
1136 | if (crec != 0) |
1137 | { |
1138 | /* If we don't get enough data twice in a row, we may have |
1139 | dropped some data and still be looking for the end of a |
1140 | large packet. Incrementing iPrecstart will force |
1141 | fgprocess_data to skip that packet and look through the |
1142 | rest of the data. In some situations, this will be a |
1143 | mistake. */ |
1144 | if (crec >= cneed) |
1145 | cshort = 0; |
1146 | else |
1147 | { |
1148 | ++cshort; |
1149 | if (cshort > 1) |
1150 | { |
1151 | iPrecstart = (iPrecstart + 1) % CRECBUFLEN; |
1152 | cshort = 0; |
1153 | } |
1154 | } |
1155 | } |
1156 | else |
1157 | { |
1158 | /* The read timed out. If we have an unacknowledged packet, |
1159 | send it again. Otherwise, send an RJ with the last |
1160 | packet we received correctly. */ |
1161 | ++ctimeouts; |
1162 | if (ctimeouts > cretries) |
1163 | { |
1164 | if (cretries > 0) |
1165 | ulog (LOG_ERROR, "Timed out waiting for packet"); |
1166 | return FALSE; |
1167 | } |
1168 | |
1169 | if (INEXTSEQ (iGremote_ack) != iGsendseq) |
1170 | { |
1171 | int inext; |
1172 | char *zsend; |
1173 | |
1174 | inext = INEXTSEQ (iGremote_ack); |
1175 | |
1176 | DEBUG_MESSAGE1 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1177 | "fgwait_for_packet: Resending packet %d", |
1178 | inext); |
1179 | |
1180 | ++cGresent_packets; |
1181 | zsend = zgadjust_ack (inext); |
1182 | if (! fsend_data (qdaemon->qconn, zsend, |
1183 | CFRAMELEN + CPACKLEN (zsend), TRUE)) |
1184 | return FALSE; |
1185 | iGretransmit_seq = inext; |
1186 | } |
1187 | else |
1188 | { |
1189 | /* Send all pending acks first, to avoid confusing |
1190 | the other side. */ |
1191 | if (iGlocal_ack != iGrecseq) |
1192 | { |
1193 | if (! fgsend_acks (qdaemon)) |
1194 | return FALSE; |
1195 | } |
1196 | if (! fgsend_control (qdaemon, RJ, iGrecseq)) |
1197 | return FALSE; |
1198 | } |
1199 | } |
1200 | } |
1201 | } |
1202 | \f |
1203 | /* Send acks for all packets we haven't acked yet. */ |
1204 | |
1205 | static boolean |
1206 | fgsend_acks (qdaemon) |
1207 | struct sdaemon *qdaemon; |
1208 | { |
1209 | while (iGlocal_ack != iGrecseq) |
1210 | { |
1211 | iGlocal_ack = INEXTSEQ (iGlocal_ack); |
1212 | if (! fgsend_control (qdaemon, RR, iGlocal_ack)) |
1213 | return FALSE; |
1214 | } |
1215 | return TRUE; |
1216 | } |
1217 | |
1218 | /* Handle an ack of a packet. According to Hanrahan's paper, this |
1219 | acknowledges all previous packets. If this is an ack for a |
1220 | retransmitted packet, continue by resending up to two more packets |
1221 | following the retransmitted one. This should recover quickly from |
1222 | a line glitch, while avoiding the problem of continual |
1223 | retransmission. */ |
1224 | |
1225 | static boolean |
1226 | fggot_ack (qdaemon, iack) |
1227 | struct sdaemon *qdaemon; |
1228 | int iack; |
1229 | { |
1230 | int inext; |
1231 | char *zsend; |
1232 | |
1233 | /* We only decrement the error level if we are not retransmitting |
1234 | packets. We want to catch a sudden downgrade in line quality as |
1235 | fast as possible. */ |
1236 | if (cGerror_level > 0 |
1237 | && iGretransmit_seq == -1 |
1238 | && cGsent_packets % cGerror_decay == 0) |
1239 | --cGerror_level; |
1240 | cGexpect_bad_order = 0; |
1241 | |
1242 | /* Each time packet 0 is acknowledged, we call uwindow_acked since a |
1243 | new window has been acked. */ |
1244 | if (iack < iGremote_ack) |
1245 | uwindow_acked (qdaemon, FALSE); |
1246 | |
1247 | iGremote_ack = iack; |
1248 | |
1249 | if (iGretransmit_seq == -1) |
1250 | return TRUE; |
1251 | |
1252 | inext = INEXTSEQ (iGretransmit_seq); |
1253 | if (inext == iGsendseq) |
1254 | iGretransmit_seq = -1; |
1255 | else |
1256 | { |
1257 | DEBUG_MESSAGE1 (DEBUG_PROTO, |
1258 | "fggot_ack: Sending packet %d", inext); |
1259 | |
1260 | ++cGresent_packets; |
1261 | zsend = zgadjust_ack (inext); |
1262 | if (! fsend_data (qdaemon->qconn, zsend, CFRAMELEN + CPACKLEN (zsend), |
1263 | TRUE)) |
1264 | return FALSE; |
1265 | inext = INEXTSEQ (inext); |
1266 | if (inext == iGsendseq) |
1267 | iGretransmit_seq = -1; |
1268 | else |
1269 | { |
1270 | DEBUG_MESSAGE1 (DEBUG_PROTO, |
1271 | "fggot_ack: Sending packet %d", inext); |
1272 | |
1273 | ++cGresent_packets; |
1274 | zsend = zgadjust_ack (inext); |
1275 | if (! fsend_data (qdaemon->qconn, zsend, |
1276 | CFRAMELEN + CPACKLEN (zsend), TRUE)) |
1277 | return FALSE; |
1278 | iGretransmit_seq = inext; |
1279 | } |
1280 | } |
1281 | |
1282 | return TRUE; |
1283 | } |
1284 | \f |
1285 | /* See if we've received more than the permitted number of errors. If |
1286 | we receive a bad packet, we can expect a window full (less one) of |
1287 | out of order packets to follow, so we discount cGbad_order |
1288 | accordingly. */ |
1289 | |
1290 | static boolean |
1291 | fgcheck_errors (qdaemon) |
1292 | struct sdaemon *qdaemon; |
1293 | { |
1294 | if (cGerror_level > cGmax_errors && cGmax_errors >= 0) |
1295 | { |
1296 | ulog (LOG_ERROR, "Too many '%c' protocol errors", |
1297 | qdaemon->qproto->bname); |
1298 | return FALSE; |
1299 | } |
1300 | |
1301 | return TRUE; |
1302 | } |
1303 | |
1304 | /* Process the receive buffer into a data packet, if possible. All |
1305 | control packets are handled here. When a data packet is received, |
1306 | fgprocess_data calls fgot_data with the data; if that sets its |
1307 | pfexit argument to TRUE fgprocess_data will set *pfexit to TRUE and |
1308 | return TRUE. Also, if the freturncontrol argument is TRUE |
1309 | fgprocess_data will set *pfexit to TRUE and return TRUE. Otherwise |
1310 | fgprocess_data will continue trying to process data. If some error |
1311 | occurs, fgprocess_data will return FALSE. If there is not enough |
1312 | data to form a complete packet, then *pfexit will be set to FALSE, |
1313 | *pcneed will be set to the number of bytes needed to form a |
1314 | complete packet (unless pcneed is NULL) and fgprocess_data will |
1315 | return TRUE. If this function found a data packet, and pffound is |
1316 | not NULL, it will set *pffound to TRUE; this can be used to tell |
1317 | valid data from an endless stream of garbage and control packets. |
1318 | If fdoacks is TRUE, received packets will be acknowledged; |
1319 | otherwise they must be acknowledged later. */ |
1320 | |
1321 | static boolean |
1322 | fgprocess_data (qdaemon, fdoacks, freturncontrol, pfexit, pcneed, pffound) |
1323 | struct sdaemon *qdaemon; |
1324 | boolean fdoacks; |
1325 | boolean freturncontrol; |
1326 | boolean *pfexit; |
1327 | size_t *pcneed; |
1328 | boolean *pffound; |
1329 | { |
1330 | *pfexit = FALSE; |
1331 | if (pffound != NULL) |
1332 | *pffound = FALSE; |
1333 | |
1334 | while (iPrecstart != iPrecend) |
1335 | { |
1336 | char ab[CFRAMELEN]; |
1337 | int i, iget, cwant; |
1338 | unsigned short ihdrcheck, idatcheck; |
1339 | const char *zfirst, *zsecond; |
1340 | int cfirst, csecond; |
1341 | boolean fduprr; |
1342 | |
1343 | /* Look for the DLE which must start a packet. */ |
1344 | if (abPrecbuf[iPrecstart] != DLE) |
1345 | { |
1346 | char *zdle; |
1347 | |
1348 | cfirst = iPrecend - iPrecstart; |
1349 | if (cfirst < 0) |
1350 | cfirst = CRECBUFLEN - iPrecstart; |
1351 | |
1352 | zdle = memchr (abPrecbuf + iPrecstart, DLE, (size_t) cfirst); |
1353 | |
1354 | if (zdle == NULL) |
1355 | { |
1356 | iPrecstart = (iPrecstart + cfirst) % CRECBUFLEN; |
1357 | continue; |
1358 | } |
1359 | |
1360 | /* We don't need % CRECBUFLEN here because zdle - (abPrecbuf |
1361 | + iPrecstart) < cfirst <= CRECBUFLEN - iPrecstart. */ |
1362 | iPrecstart += zdle - (abPrecbuf + iPrecstart); |
1363 | } |
1364 | |
1365 | /* Get the first six bytes into ab. */ |
1366 | for (i = 0, iget = iPrecstart; |
1367 | i < CFRAMELEN && iget != iPrecend; |
1368 | i++, iget = (iget + 1) % CRECBUFLEN) |
1369 | ab[i] = abPrecbuf[iget]; |
1370 | |
1371 | /* If there aren't six bytes, there is no packet. */ |
1372 | if (i < CFRAMELEN) |
1373 | { |
1374 | if (pcneed != NULL) |
1375 | *pcneed = CFRAMELEN - i; |
1376 | return TRUE; |
1377 | } |
1378 | |
1379 | /* Make sure these six bytes start a packet. The check on |
1380 | IFRAME_DLE is basically a debugging check, since the above |
1381 | code should have ensured that it will never fail. If this is |
1382 | not the start of a packet, bump iPrecstart and loop around to |
1383 | look for another DLE. */ |
1384 | if (ab[IFRAME_DLE] != DLE |
1385 | || ab[IFRAME_K] < 1 |
1386 | || ab[IFRAME_K] > 9 |
1387 | || ab[IFRAME_XOR] != (ab[IFRAME_K] ^ ab[IFRAME_CHECKLOW] |
1388 | ^ ab[IFRAME_CHECKHIGH] ^ ab[IFRAME_CONTROL]) |
1389 | || CONTROL_TT (ab[IFRAME_CONTROL]) == ALTCHAN) |
1390 | { |
1391 | ++cGbad_hdr; |
1392 | ++cGerror_level; |
1393 | |
1394 | DEBUG_MESSAGE4 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1395 | "fgprocess_data: Bad header: K %d TT %d XOR byte %d calc %d", |
1396 | ab[IFRAME_K] & 0xff, |
1397 | CONTROL_TT (ab[IFRAME_CONTROL]), |
1398 | ab[IFRAME_XOR] & 0xff, |
1399 | (ab[IFRAME_K] |
1400 | ^ ab[IFRAME_CHECKLOW] |
1401 | ^ ab[IFRAME_CHECKHIGH] |
1402 | ^ ab[IFRAME_CONTROL]) & 0xff); |
1403 | |
1404 | if (! fgcheck_errors (qdaemon)) |
1405 | return FALSE; |
1406 | |
1407 | iPrecstart = (iPrecstart + 1) % CRECBUFLEN; |
1408 | continue; |
1409 | } |
1410 | |
1411 | /* The zfirst and cfirst pair point to the first set of data for |
1412 | this packet; the zsecond and csecond point to the second set, |
1413 | in case the packet wraps around the end of the buffer. */ |
1414 | zfirst = abPrecbuf + iPrecstart + CFRAMELEN; |
1415 | cfirst = 0; |
1416 | zsecond = NULL; |
1417 | csecond = 0; |
1418 | |
1419 | if (ab[IFRAME_K] == KCONTROL) |
1420 | { |
1421 | /* This is a control packet. It should not have any data. */ |
1422 | if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL) |
1423 | { |
1424 | ++cGbad_hdr; |
1425 | ++cGerror_level; |
1426 | |
1427 | DEBUG_MESSAGE0 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1428 | "fgprocess_data: Bad header: control packet with data"); |
1429 | |
1430 | if (! fgcheck_errors (qdaemon)) |
1431 | return FALSE; |
1432 | |
1433 | iPrecstart = (iPrecstart + 1) % CRECBUFLEN; |
1434 | continue; |
1435 | } |
1436 | |
1437 | idatcheck = (unsigned short) (0xaaaa - ab[IFRAME_CONTROL]); |
1438 | cwant = 0; |
1439 | } |
1440 | else |
1441 | { |
1442 | int cinbuf; |
1443 | unsigned short icheck; |
1444 | |
1445 | /* This is a data packet. It should not be type CONTROL. */ |
1446 | if (CONTROL_TT (ab[IFRAME_CONTROL]) == CONTROL) |
1447 | { |
1448 | ++cGbad_hdr; |
1449 | ++cGerror_level; |
1450 | |
1451 | DEBUG_MESSAGE0 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1452 | "fgprocess_data: Bad header: data packet is type CONTROL"); |
1453 | |
1454 | if (! fgcheck_errors (qdaemon)) |
1455 | return FALSE; |
1456 | |
1457 | iPrecstart = (iPrecstart + 1) % CRECBUFLEN; |
1458 | continue; |
1459 | } |
1460 | |
1461 | cinbuf = iPrecend - iPrecstart; |
1462 | if (cinbuf < 0) |
1463 | cinbuf += CRECBUFLEN; |
1464 | cinbuf -= CFRAMELEN; |
1465 | |
1466 | /* Make sure we have enough data. If we don't, wait for |
1467 | more. */ |
1468 | |
1469 | cwant = (int) CPACKLEN (ab); |
1470 | if (cinbuf < cwant) |
1471 | { |
1472 | if (pcneed != NULL) |
1473 | *pcneed = cwant - cinbuf; |
1474 | return TRUE; |
1475 | } |
1476 | |
1477 | /* Set up the data pointers and compute the checksum. */ |
1478 | if (iPrecend >= iPrecstart) |
1479 | cfirst = cwant; |
1480 | else |
1481 | { |
1482 | cfirst = CRECBUFLEN - (iPrecstart + CFRAMELEN); |
1483 | if (cfirst >= cwant) |
1484 | cfirst = cwant; |
1485 | else if (cfirst > 0) |
1486 | { |
1487 | zsecond = abPrecbuf; |
1488 | csecond = cwant - cfirst; |
1489 | } |
1490 | else |
1491 | { |
1492 | /* Here cfirst is non-positive, so subtracting from |
1493 | abPrecbuf will actually skip the appropriate number |
1494 | of bytes at the start of abPrecbuf. */ |
1495 | zfirst = abPrecbuf - cfirst; |
1496 | cfirst = cwant; |
1497 | } |
1498 | } |
1499 | |
1500 | if (csecond == 0) |
1501 | icheck = (unsigned short) igchecksum (zfirst, (size_t) cfirst); |
1502 | else |
1503 | icheck = (unsigned short) igchecksum2 (zfirst, (size_t) cfirst, |
1504 | zsecond, |
1505 | (size_t) csecond); |
1506 | |
1507 | idatcheck = ((unsigned short) |
1508 | (((0xaaaa - (icheck ^ (ab[IFRAME_CONTROL] & 0xff))) |
1509 | & 0xffff))); |
1510 | } |
1511 | |
1512 | ihdrcheck = (unsigned short) (((ab[IFRAME_CHECKHIGH] & 0xff) << 8) |
1513 | | (ab[IFRAME_CHECKLOW] & 0xff)); |
1514 | |
1515 | if (ihdrcheck != idatcheck) |
1516 | { |
1517 | DEBUG_MESSAGE2 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1518 | "fgprocess_data: Bad checksum: header 0x%x, data 0x%x", |
1519 | ihdrcheck, idatcheck); |
1520 | |
1521 | ++cGbad_checksum; |
1522 | ++cGerror_level; |
1523 | |
1524 | if (! fgcheck_errors (qdaemon)) |
1525 | return FALSE; |
1526 | |
1527 | /* If the checksum failed for a data packet, then if it was |
1528 | the one we were expecting send an RJ, otherwise ignore |
1529 | it. Previously if this code got the wrong packet number |
1530 | it would send an RR, but that may confuse some Telebit |
1531 | modems and it doesn't help in any case since the receiver |
1532 | will probably just ignore the RR as a duplicate (that's |
1533 | basically what this code does). If we totally missed the |
1534 | packet we will time out and send an RJ in the function |
1535 | fgwait_for_packet above. */ |
1536 | if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL) |
1537 | { |
1538 | /* Make sure we've acked everything up to this point. */ |
1539 | if (iGrecseq != iGlocal_ack) |
1540 | { |
1541 | if (! fgsend_acks (qdaemon)) |
1542 | return FALSE; |
1543 | } |
1544 | |
1545 | /* If this is the packet we wanted, tell the sender that |
1546 | it failed. */ |
1547 | if (CONTROL_XXX (ab[IFRAME_CONTROL]) == INEXTSEQ (iGrecseq)) |
1548 | { |
1549 | if (! fgsend_control (qdaemon, RJ, iGrecseq)) |
1550 | return FALSE; |
1551 | cGexpect_bad_order += iGrequest_winsize - 1; |
1552 | } |
1553 | } |
1554 | |
1555 | /* We can't skip the packet data after this, because if we |
1556 | have lost incoming bytes the next DLE will be somewhere |
1557 | in what we thought was the packet data. */ |
1558 | iPrecstart = (iPrecstart + 1) % CRECBUFLEN; |
1559 | continue; |
1560 | } |
1561 | |
1562 | /* We have a packet; remove the processed bytes from the receive |
1563 | buffer. */ |
1564 | iPrecstart = (iPrecstart + cwant + CFRAMELEN) % CRECBUFLEN; |
1565 | |
1566 | /* Store the control byte for the handshake routines. */ |
1567 | iGpacket_control = ab[IFRAME_CONTROL] & 0xff; |
1568 | |
1569 | /* Annoyingly, some UUCP packages appear to send an RR packet |
1570 | rather than an RJ packet when they want a packet to be |
1571 | resent. If we get a duplicate RR, we treat it as an RJ. */ |
1572 | fduprr = FALSE; |
1573 | if (CONTROL_TT (ab[IFRAME_CONTROL]) == CONTROL |
1574 | && CONTROL_XXX (ab[IFRAME_CONTROL]) == RR |
1575 | && iGremote_ack == CONTROL_YYY (ab[IFRAME_CONTROL]) |
1576 | && INEXTSEQ (iGremote_ack) != iGsendseq) |
1577 | { |
1578 | DEBUG_MESSAGE0 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1579 | "fgprocess_data: Treating duplicate RR as RJ"); |
1580 | fduprr = TRUE; |
1581 | } |
1582 | |
1583 | /* Update the received sequence number from the yyy field of a |
1584 | data packet or an RR control packet. If we've been delaying |
1585 | sending packets until we received an ack, this may send out |
1586 | some packets. */ |
1587 | if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL |
1588 | || CONTROL_XXX (ab[IFRAME_CONTROL]) == RR) |
1589 | { |
1590 | if (! fggot_ack (qdaemon, CONTROL_YYY (ab[IFRAME_CONTROL]))) |
1591 | return FALSE; |
1592 | } |
1593 | |
1594 | /* If this isn't a control message, make sure we have received |
1595 | the expected packet sequence number, acknowledge the packet |
1596 | if it's the right one, and process the data. */ |
1597 | if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL) |
1598 | { |
1599 | if (CONTROL_XXX (ab[IFRAME_CONTROL]) != INEXTSEQ (iGrecseq)) |
1600 | { |
1601 | /* We got the wrong packet number. */ |
1602 | DEBUG_MESSAGE2 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1603 | "fgprocess_data: Got packet %d; expected %d", |
1604 | CONTROL_XXX (ab[IFRAME_CONTROL]), |
1605 | INEXTSEQ (iGrecseq)); |
1606 | |
1607 | if (cGexpect_bad_order > 0) |
1608 | --cGexpect_bad_order; |
1609 | else |
1610 | { |
1611 | ++cGbad_order; |
1612 | ++cGerror_level; |
1613 | if (! fgcheck_errors (qdaemon)) |
1614 | return FALSE; |
1615 | } |
1616 | |
1617 | /* This code used to send an RR to encourage the other |
1618 | side to get back in synch, but that may confuse some |
1619 | Telebit modems and does little good in any case, |
1620 | since the other side will probably just ignore it |
1621 | anyhow (that's what this code does). */ |
1622 | continue; |
1623 | } |
1624 | |
1625 | /* We got the packet we expected. */ |
1626 | ++cGrec_packets; |
1627 | if (cGerror_level > 0 |
1628 | && cGrec_packets % cGerror_decay == 0) |
1629 | --cGerror_level; |
1630 | cGexpect_bad_order = 0; |
1631 | |
1632 | iGrecseq = INEXTSEQ (iGrecseq); |
1633 | |
1634 | DEBUG_MESSAGE1 (DEBUG_PROTO, |
1635 | "fgprocess_data: Got packet %d", iGrecseq); |
1636 | |
1637 | /* Tell the caller that we found something. */ |
1638 | if (pffound != NULL) |
1639 | *pffound = TRUE; |
1640 | |
1641 | /* If we are supposed to do acknowledgements here, send back |
1642 | an RR packet. */ |
1643 | if (fdoacks) |
1644 | { |
1645 | if (! fgsend_acks (qdaemon)) |
1646 | return FALSE; |
1647 | } |
1648 | |
1649 | /* If this is a short data packet, adjust the data pointers |
1650 | and lengths. */ |
1651 | if (CONTROL_TT (ab[IFRAME_CONTROL]) == SHORTDATA) |
1652 | { |
1653 | int cshort, cmove; |
1654 | |
1655 | if ((zfirst[0] & 0x80) == 0) |
1656 | { |
1657 | cshort = zfirst[0] & 0xff; |
1658 | cmove = 1; |
1659 | } |
1660 | else |
1661 | { |
1662 | int cbyte2; |
1663 | |
1664 | if (cfirst > 1) |
1665 | cbyte2 = zfirst[1] & 0xff; |
1666 | else |
1667 | cbyte2 = zsecond[0] & 0xff; |
1668 | cshort = (zfirst[0] & 0x7f) + (cbyte2 << 7); |
1669 | cmove = 2; |
1670 | } |
1671 | |
1672 | DEBUG_MESSAGE1 (DEBUG_PROTO, |
1673 | "fgprocess_data: Packet short by %d", |
1674 | cshort); |
1675 | |
1676 | /* Adjust the start of the buffer for the bytes used |
1677 | by the count. */ |
1678 | if (cfirst > cmove) |
1679 | { |
1680 | zfirst += cmove; |
1681 | cfirst -= cmove; |
1682 | } |
1683 | else |
1684 | { |
1685 | zfirst = zsecond + (cmove - cfirst); |
1686 | cfirst = csecond - (cmove - cfirst); |
1687 | csecond = 0; |
1688 | } |
1689 | |
1690 | /* Adjust the length of the buffer for the bytes we are |
1691 | not supposed to consider. */ |
1692 | cshort -= cmove; |
1693 | if (csecond >= cshort) |
1694 | csecond -= cshort; |
1695 | else |
1696 | { |
1697 | cfirst -= cshort - csecond; |
1698 | csecond = 0; |
1699 | } |
1700 | |
1701 | #if DEBUG > 0 |
1702 | /* This should not happen, but just in case. */ |
1703 | if (cfirst < 0) |
1704 | cfirst = 0; |
1705 | #endif |
1706 | } |
1707 | |
1708 | if (! fgot_data (qdaemon, zfirst, (size_t) cfirst, |
1709 | zsecond, (size_t) csecond, |
1710 | -1, -1, (long) -1, |
1711 | INEXTSEQ (iGremote_ack) == iGsendseq, |
1712 | pfexit)) |
1713 | return FALSE; |
1714 | |
1715 | /* If fgot_data told us that we were finished, get out. */ |
1716 | if (*pfexit) |
1717 | return TRUE; |
1718 | |
1719 | /* If we've been asked to return control packets, get out |
1720 | now. */ |
1721 | if (freturncontrol) |
1722 | { |
1723 | *pfexit = TRUE; |
1724 | return TRUE; |
1725 | } |
1726 | |
1727 | continue; |
1728 | } |
1729 | |
1730 | /* Handle control messages here. */ |
1731 | #if DEBUG > 1 |
1732 | if (FDEBUGGING (DEBUG_PROTO) |
1733 | || (FDEBUGGING (DEBUG_ABNORMAL) |
1734 | && CONTROL_XXX (ab[IFRAME_CONTROL]) != RR)) |
1735 | ulog (LOG_DEBUG, "fgprocess_data: Got control %s %d", |
1736 | azGcontrol[CONTROL_XXX (ab[IFRAME_CONTROL])], |
1737 | CONTROL_YYY (ab[IFRAME_CONTROL])); |
1738 | #endif |
1739 | |
1740 | switch (CONTROL_XXX (ab[IFRAME_CONTROL])) |
1741 | { |
1742 | case CLOSE: |
1743 | /* The other side has closed the connection. */ |
1744 | if (fLog_sighup) |
1745 | { |
1746 | ulog (LOG_ERROR, "Received unexpected CLOSE packet"); |
1747 | (void) fgsend_control (qdaemon, CLOSE, 0); |
1748 | } |
1749 | return FALSE; |
1750 | case RR: |
1751 | /* Acknowledge receipt of a packet. This was already handled |
1752 | above, unless we are treating it as RJ. */ |
1753 | if (! fduprr) |
1754 | break; |
1755 | /* Fall through. */ |
1756 | case RJ: |
1757 | /* The other side dropped a packet. Begin retransmission with |
1758 | the packet following the one acknowledged. We don't |
1759 | retransmit the packets immediately, but instead wait |
1760 | for the first one to be acked. This prevents us from |
1761 | sending an entire window several times if we get several |
1762 | RJ packets. */ |
1763 | iGremote_ack = CONTROL_YYY (ab[IFRAME_CONTROL]); |
1764 | iGretransmit_seq = INEXTSEQ (iGremote_ack); |
1765 | if (iGretransmit_seq == iGsendseq) |
1766 | iGretransmit_seq = -1; |
1767 | else |
1768 | { |
1769 | char *zpack; |
1770 | |
1771 | DEBUG_MESSAGE2 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1772 | "fgprocess_data: Remote reject: next %d resending %d", |
1773 | iGsendseq, iGretransmit_seq); |
1774 | |
1775 | ++cGresent_packets; |
1776 | ++cGremote_rejects; |
1777 | ++cGerror_level; |
1778 | if (! fgcheck_errors (qdaemon)) |
1779 | return FALSE; |
1780 | zpack = zgadjust_ack (iGretransmit_seq); |
1781 | if (! fsend_data (qdaemon->qconn, zpack, |
1782 | CFRAMELEN + CPACKLEN (zpack), |
1783 | TRUE)) |
1784 | return FALSE; |
1785 | } |
1786 | break; |
1787 | case SRJ: |
1788 | /* Selectively reject a particular packet. This is not used |
1789 | by UUCP, but it's easy to support. */ |
1790 | DEBUG_MESSAGE1 (DEBUG_PROTO | DEBUG_ABNORMAL, |
1791 | "fgprocess_data: Selective reject of %d", |
1792 | CONTROL_YYY (ab[IFRAME_CONTROL])); |
1793 | { |
1794 | char *zpack; |
1795 | |
1796 | ++cGresent_packets; |
1797 | ++cGremote_rejects; |
1798 | ++cGerror_level; |
1799 | zpack = zgadjust_ack (CONTROL_YYY (ab[IFRAME_CONTROL])); |
1800 | if (! fsend_data (qdaemon->qconn, zpack, |
1801 | CFRAMELEN + CPACKLEN (zpack), |
1802 | TRUE)) |
1803 | return FALSE; |
1804 | } |
1805 | break; |
1806 | case INITC: |
1807 | case INITB: |
1808 | case INITA: |
1809 | /* Ignore attempts to reinitialize. */ |
1810 | break; |
1811 | } |
1812 | |
1813 | /* If we've been asked to return control packets, get out. */ |
1814 | if (freturncontrol) |
1815 | { |
1816 | *pfexit = TRUE; |
1817 | return TRUE; |
1818 | } |
1819 | |
1820 | /* Loop around to look for the next packet, if any. */ |
1821 | } |
1822 | |
1823 | /* There is no data left in the receive buffer. */ |
1824 | if (pcneed != NULL) |
1825 | *pcneed = CFRAMELEN; |
1826 | return TRUE; |
1827 | } |
1828 | \f |
1829 | /* Compute the 'g' protocol checksum. This is unfortunately rather |
1830 | awkward. This is the most time consuming code in the entire |
1831 | program. It's also not a great checksum, since it can be fooled |
1832 | by some single bit errors. */ |
1833 | |
1834 | /* Sorry about this knavery, but it speeds up the VAX code |
1835 | significantly. It would be better to rewrite the whole routine in |
1836 | assembler. */ |
1837 | #ifdef __GNUC__ |
1838 | #ifdef __vax__ |
1839 | #define VAX_ASM 1 |
1840 | #endif |
1841 | #endif |
1842 | |
1843 | #if VAX_ASM |
1844 | #define ROTATE(i) \ |
1845 | asm ("cvtwl %1,%0\n\trotl $1,%0,%0" : "=g" (i) : "g" (i)) |
1846 | #else |
1847 | #define ROTATE(i) i += i + ((i & 0x8000) >> 15) |
1848 | #endif |
1849 | |
1850 | #define ITERATION \ |
1851 | /* Rotate ichk1 left. */ \ |
1852 | ROTATE (ichk1); \ |
1853 | \ |
1854 | /* The guts of the checksum. */ \ |
1855 | b = BUCHAR (*z++); \ |
1856 | if (b != 0) \ |
1857 | { \ |
1858 | ichk1 &= 0xffff; \ |
1859 | ichk1 += b; \ |
1860 | ichk2 += ichk1 ^ c; \ |
1861 | if ((ichk1 >> 16) != 0) \ |
1862 | ichk1 ^= ichk2; \ |
1863 | } \ |
1864 | else \ |
1865 | { \ |
1866 | ichk2 += ichk1 ^ c; \ |
1867 | ichk1 ^= ichk2; \ |
1868 | } \ |
1869 | \ |
1870 | --c |
1871 | |
1872 | static int |
1873 | igchecksum (z, c) |
1874 | register const char *z; |
1875 | register size_t c; |
1876 | { |
1877 | register unsigned long ichk1, ichk2; |
1878 | |
1879 | ichk1 = 0xffff; |
1880 | ichk2 = 0; |
1881 | |
1882 | do |
1883 | { |
1884 | register unsigned int b; |
1885 | |
1886 | ITERATION; |
1887 | ITERATION; |
1888 | ITERATION; |
1889 | ITERATION; |
1890 | } |
1891 | while (c > 0); |
1892 | |
1893 | return ichk1 & 0xffff; |
1894 | } |
1895 | |
1896 | /* We use a separate function compute the checksum if the block is |
1897 | split around the end of the receive buffer since it occurs much |
1898 | less frequently and the checksum is already high up in the |
1899 | profiles. These functions are almost identical, and this one |
1900 | actually only has a few more instructions in the inner loop. */ |
1901 | |
1902 | static int |
1903 | igchecksum2 (zfirst, cfirst, zsecond, csecond) |
1904 | const char *zfirst; |
1905 | size_t cfirst; |
1906 | const char *zsecond; |
1907 | size_t csecond; |
1908 | { |
1909 | register unsigned long ichk1, ichk2; |
1910 | register const char *z; |
1911 | register size_t c; |
1912 | |
1913 | z = zfirst; |
1914 | c = cfirst + csecond; |
1915 | |
1916 | ichk1 = 0xffff; |
1917 | ichk2 = 0; |
1918 | |
1919 | do |
1920 | { |
1921 | register unsigned int b; |
1922 | |
1923 | ITERATION; |
1924 | |
1925 | /* If the first buffer has been finished, switch to the second. */ |
1926 | --cfirst; |
1927 | if (cfirst == 0) |
1928 | z = zsecond; |
1929 | } |
1930 | while (c > 0); |
1931 | |
1932 | return ichk1 & 0xffff; |
1933 | } |