Annotation of coherent/g/usr/lib/uucp/tay104/protg.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.