|
|
1.1 root 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 [email protected] 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 93/07/30 07:53:21 bin Exp Locker: bin $";
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.