home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msr313src.zip / msntcp.c < prev    next >
C/C++ Source or Header  |  1993-07-12  |  51KB  |  1,898 lines

  1. /* File MSNTCP.C
  2.  * Main TCP protocol code
  3.  *
  4.  * Copyright (C) 1991, University of Waterloo.
  5.  * Copyright (C) 1985, 1993, Trustees of Columbia University in the 
  6.  * City of New York.  Permission is granted to any individual or institution
  7.  * to use this software as long as it is not sold for profit.  This copyright
  8.  * notice must be retained.  This software may not be included in commercial
  9.  * products without written permission of Columbia University.
  10.  *
  11.  * Original version created by Erick Engelke of the University of
  12.  *  Waterloo, Waterloo, Ontario, Canada.
  13.  * Adapted and modified for MS-DOS Kermit by Joe R. Doupnik, 
  14.  *  Utah State University, jrd@cc.usu.edu, jrd@usu.Bitnet.
  15.  *
  16.  * Last edit
  17.  * 18 Feb 1993 v3.13
  18.  *
  19.  *  PCTCP - the true worker of Waterloo TCP
  20.  *         - contains all opens, closes, major read/write routines and
  21.  *        basic IP handler for incomming packets
  22.  *      - NOTE: much of the TCP/UDP/IP layering is done at data structure
  23.  *        level, not in separate routines or tasks
  24.  *
  25.  */
  26.  
  27. #include "msntcp.h"
  28. #include "msnlib.h"
  29.  
  30. extern    int arp_handler(in_Header *);
  31. extern    int rarp_handler(void *);
  32. extern    int icmp_handler(void *);
  33. extern    void icmp_noport(void *);
  34. extern    void server_hello(tcp_Socket *s);
  35. extern    void eth_release(void);
  36. extern    void icmp_init(void);
  37. extern    int eth_init(void);
  38.  
  39. static    int tcp_handler(void *);
  40. static    int tcp_rst(in_Header *, tcp_Header *);
  41. static    int tcp_read(void *, byte FAR *, int);
  42. static    int tcp_write(void *, byte FAR *, int);
  43. static    int tcp_flush(void *);
  44. static    int tcp_close(void *);
  45. static    int tcp_processdata(void *, void *, int);
  46. static    int tcp_send(void *);
  47. static    int tcp_sendsoon(void *);
  48. static    int tcp_retransmitter(void);
  49. static    int tcp_unthread(void *);
  50. static    int udp_handler(void *);
  51. static    int udp_read(void *, byte FAR *, int);
  52. static    int udp_write(void *, byte FAR *, int);
  53. static    int udp_close(udp_Socket *);
  54.  
  55. extern word pktdevclass, MAC_len;   /* MAC address length, for ODI */
  56. longword ipbcast = 0xffffffffL;        /* default IP broadcast address */
  57.  
  58. static    initialized = 0;
  59. #define    DEF_WAITTIME 4        /* default time to hold pkt before sending,
  60.                    in PC Bios clock ticks (18.2/sec) */
  61. static word normal_waittime;    /* tcp_sendsoon, nominal waiting time */
  62. static word waittime;        /* tcp_sendsoon, Bios clocks ticks to wait */
  63.  
  64. #ifdef DEBUG
  65. void (*dbugxmit)() = NULL;
  66. void (*dbugrecv)() = NULL;
  67. #endif
  68. /*
  69.  * Local IP address
  70.  */
  71.  
  72. longword my_ip_addr = 0L;        /* for external references */
  73. longword sin_mask = 0xfffffe00L;
  74. longword sin_gate = 0L;
  75. byte    hostname[MAX_STRING+1];        /* our full name, from BootP */
  76. /*
  77.  * IP identification numbers
  78.  */
  79.  
  80. static int ip_id = 0;            /* packet number */
  81. static int next_tcp_port = 1024;    /* auto incremented */
  82. static int next_udp_port = 1024;
  83. static tcp_Socket *tcp_allsocs = NULL;    /* TCP socket linked list head */
  84. static udp_Socket *udp_allsocs = NULL;    /* UDP socket linked list head */
  85.  
  86. /* Timer definitions, in PC clock tics */
  87. #define RETRAN_STRAT_TIME  1     /* ticks, how often to check retransmitter*/
  88. #define tcp_LONGTIMEOUT 31       /* timeout, sec, for opens */
  89. #define tcp_TIMEOUT 13           /* timeout, sec, during a connection */
  90.  
  91. #define KARN_NEW 0        /* Karn count, new transmission */
  92. #define KARN_PENDING 1        /* Karn count, pending transmission */
  93. #define KARN_TIMEOUT 2        /* Karn count, transmission timed out */
  94.  
  95. word    debug_on = 0;
  96. word    mss = ETH_MSS;        /* Maximum Segment Size */
  97. word    sourcequench = 0;    /* non-zero if received ICMP Source Quench */
  98.  
  99. /*    TCP Header (and size in bits)
  100.     Source Port (16)
  101.     Destination Port (16)
  102.     Sequence Number (32)    First octet in this segment. If SYN then
  103.                 this is the initial seq num and first data
  104.                 octet is one larger.
  105.     Acknowledgment Number (32) Next octet expected to be received
  106.      Data Offset (4)        number of 32 bit words in this header so we
  107.                 know when options are present (and how large)
  108.      Reserved (6)
  109.      URG (1)            Urgent
  110.      ACK (1)            Acknowledgment
  111.      PSH (1)            Push function (expedite)
  112.      RST (1)            Reset the connection
  113.      SYN (1)            Synchronize sequence numbers
  114.      FIN (1)            Finish, no more data from sender
  115.      Window (16)        Octets willing to accept after Ack value
  116.      Checksum (16)        One's complement of header and Pseudo header
  117.      Urgent Pointer (16)    Points to octet following urgent data <sic>
  118.      Options & Padding (32)    Only Option is max segment size
  119.      Data (the rest)
  120. */
  121. /*
  122.  * tcp_init - Initialize the tcp implementation
  123.  *        - may be called more than once without hurting
  124.  */
  125. int
  126. tcp_init(void)
  127. {
  128.     extern int arp_last_gateway;
  129.     extern int last_nameserver;
  130.  
  131.     if (initialized != 0) return (1);    /* success, inited already */
  132.                 /* initialize ethernet interface */
  133.     icmp_init();            /* clear ICMP material */
  134.     arp_last_gateway = 0;        /* clear old gateway info */
  135.     last_nameserver = 0;        /* reset the nameserver table */
  136.     tcp_allsocs = NULL;        /* zero socket pointers */
  137.     udp_allsocs = NULL;
  138.     ip_id = 0;            /* packet number, convenient */
  139.     initialized = eth_init();    /* init the hardware, can fail */
  140.     if (my_ip_addr == 0L)         /* my_ap_addr is longword*/
  141.         bcopy(ð_addr[2], &my_ip_addr, 4); /* a pseudo long */
  142.                     /* next port numbers to choose */
  143.     next_udp_port = next_tcp_port = 1024 + (int)(realclock() & 0x1ff);
  144.     eth_free (NULL);        /* clear all pkt rcv bufs */
  145.     if ((pktdevclass == PD_SLIP) || 
  146.         (pktdevclass == PD_ETHER && MAC_len == 0))
  147.          normal_waittime = 4 * DEF_WAITTIME;    /* slow down */
  148.     else
  149.         normal_waittime = DEF_WAITTIME;
  150.     return (initialized);        /* success (1) or failure (0) */
  151. }
  152.  
  153. /*
  154.  * Shut down the card and all services
  155.  */
  156. void
  157. tcp_shutdown(void)
  158. {
  159.     while (tcp_allsocs != NULL)
  160.         tcp_abort(tcp_allsocs);
  161.     eth_release();
  162.     initialized = 0;
  163. }
  164.  
  165. int 
  166. udp_open(udp_Socket *s, word lport, longword ina, word port)
  167. {
  168.     if (s == NULL) return (0);
  169.  
  170.     if (s->rdata) free(s->rdata);    /* free any allocated buffer */
  171.     memset(s, 0, sizeof(udp_Socket));
  172.     s->rdata = malloc(UDP_BUFSIZE);
  173.     s->ip_type = UDP_PROTO;
  174.     if (lport == 0) lport = ++next_udp_port;  /* get a nonzero port val */
  175.     s->myport = lport;
  176.  
  177.     /* check for broadcast */
  178.     if (ina == 0xffffffffL || ina == 0L || ina == ipbcast)
  179.         memset(s->hisethaddr, 0xff, sizeof(eth_address));
  180.     else
  181.         if (arp_resolve(ina, &s->hisethaddr[0]) == 0)
  182.             return (0);
  183.     s->hisaddr = ina;
  184.     s->hisport = port;
  185.     s->next = udp_allsocs;
  186.     udp_allsocs = s;
  187.     s->sisopen = SOCKET_OPEN;
  188.     return (1);
  189. }
  190.  
  191. /*
  192.  * Actively open a TCP connection to a particular destination.
  193.  *    - 0 on error
  194.  */
  195. int 
  196. tcp_open(tcp_Socket *s, word lport, longword ina, word port) 
  197. {
  198.     if (s == NULL) return (0);
  199.  
  200.     if (s->rdata) free(s->rdata);        /* free preallocated buf */
  201.     if (s->sdata) free(s->sdata);        /* free preallocated buf */
  202.  
  203.     memset(s, 0, sizeof(tcp_Socket));    /* zero everything */
  204.     s->ip_type = TCP_PROTO;
  205.     if ((ina ^ my_ip_addr) & sin_mask)    /* if not on this network */
  206.         mss = (mss > 536)? 536: mss;    /* non-fragmentable max */
  207.     s->mss = mss;
  208.     s->state = tcp_StateSYNSENT;
  209.     s->timeout = set_timeout(tcp_LONGTIMEOUT);
  210.     s->rmaxdatalen = TCP_RBUFSIZE;
  211.     s->cwindow = 1;            /* slow start VJ algorithm */
  212.     s->vj_sa = 4;            /* about 250 ms (4/18.2 tics/sec) */
  213.     if (lport == 0)
  214.         lport = ++next_tcp_port;  /* get a nonzero port value */
  215.     s->myport = lport;
  216.     if (! arp_resolve(ina, &s->hisethaddr[0]))
  217.         return (0);        /* failed to get host Ethernet addr */
  218.     s->hisaddr = ina;
  219.     s->hisport = port;
  220.     s->seqnum = ntohl(set_timeout(0)) & 0xffff0000;
  221.     s->sdatalen = 0;
  222.     s->flags = tcp_FlagSYN;
  223.     s->rptxmit = TRUE;
  224.     s->next = tcp_allsocs;
  225.     s->rtt_delay = s->rtt_smooth = 18;    /* one second startup */
  226.     tcp_allsocs = s;
  227.     s->rdata = malloc(TCP_RBUFSIZE);    /* create data buffers */
  228.     s->sdata = malloc(TCP_SBUFSIZE);
  229.     s->sisopen = SOCKET_OPEN;
  230.     return (tcp_send(s));            /* fail if send fails */
  231. }
  232.  
  233. /*
  234.  * Passive open: listen for a connection on a particular port
  235.  */
  236. tcp_listen(tcp_Socket *s, word lport, longword ina, word port, word timeout)
  237. {
  238.     if (s == NULL) return (0);
  239.  
  240.     if (s->rdata) free(s->rdata);        /* free preallocated buf */
  241.     if (s->sdata) free(s->sdata);        /* free preallocated buf */
  242.     memset(s, 0, sizeof(tcp_Socket));
  243.     s->ip_type = TCP_PROTO;
  244.     s->mss = mss;
  245.     s->rmaxdatalen = TCP_RBUFSIZE;
  246.     s->cwindow = 1;            /* slow start VJ algorithm */
  247.     s->vj_sa = 4;            /* about 250 ms */
  248.     s->state = tcp_StateLISTEN;
  249.     if (timeout == 0)
  250.         s->timeout = 0;         /* no timeout */
  251.     else
  252.         s->timeout = set_timeout(timeout);
  253.     s->myport = lport;
  254.     s->hisport = port;
  255.     s->hisaddr = ina;
  256.     s->seqnum = ntohl(set_timeout(0)) & 0xffff0000;
  257.     s->sdatalen = 0;
  258.     s->flags = 0;
  259.     s->rptxmit = FALSE;
  260.     s->next = tcp_allsocs;
  261.     tcp_allsocs = s;
  262.     s->rdata = malloc(TCP_RBUFSIZE);    /* create data buffers */
  263.     s->sdata = malloc(TCP_SBUFSIZE);
  264.     s->sisopen = SOCKET_OPEN;
  265.     if ((pktdevclass == PD_SLIP) || 
  266.         (pktdevclass == PD_ETHER && MAC_len == 0))
  267.          normal_waittime = 4 * DEF_WAITTIME;    /* slow down */
  268.     else
  269.         normal_waittime = DEF_WAITTIME;
  270.     return (1);
  271. }
  272.  
  273.  
  274. static int
  275. udp_close(udp_Socket *ds)
  276. {
  277.     register udp_Socket *sp;
  278.  
  279.     sp = udp_allsocs;        /* ptr to first socket */
  280.     if (sp == NULL) return (0);    /* failure */
  281.  
  282.     ds->sisopen = SOCKET_CLOSED;    /* close before doing other work */
  283.         ds->rdatalen = 0;        /* flush pending reads */
  284.     if (sp == ds)
  285.         udp_allsocs = ds->next; /* if we are first, unlink */
  286.     while (sp != NULL)
  287.         {
  288.         if (sp->next == ds)    /* if current points to us */
  289.             {
  290.             sp->next = ds->next; /* point it to our successor */
  291.                break;
  292.             }
  293.         sp = sp->next;        /* look at next socket */
  294.         }
  295.     free(ds->rdata);        /* free data buffer */
  296.     ds->rdata = NULL;        /* invalidate data buffer address */
  297.     return (1);            /* success */
  298. }
  299.  
  300. /*
  301.  * Send a FIN on a particular port -- only works if it is open
  302.  * Must still allow receives
  303.  * Returns 0 for failure
  304.  */
  305. static int 
  306. tcp_close(tcp_Socket *s)
  307. {
  308.     if (s == NULL || s->ip_type != TCP_PROTO)
  309.         return (0);            /* failure */
  310.     if (s->state == tcp_StateESTAB || s->state == tcp_StateSYNREC)
  311.         {
  312.         if (s->err_msg == NULL)
  313.             s->err_msg = "TCP_Closed called";
  314.         s->flags = tcp_FlagACK | tcp_FlagFIN;
  315.         if (s->sdatalen)
  316.             s->flags |= tcp_FlagPUSH;
  317.         s->state = tcp_StateFINWT1;
  318.         s->timeout = set_timeout(4);
  319.                     /* should be a pretty lengthy time */
  320.         s->rptxmit = TRUE;
  321.         tcp_send(s);
  322.         return (1);            /* success */
  323.         }
  324.     return (0);
  325. }
  326.  
  327. /*
  328.  * Abort a tcp connection
  329.  * Returns 0 if failure
  330.  */
  331. int 
  332. tcp_abort(tcp_Socket *s)
  333. {
  334.     if (s == NULL) return (0);        /* failure */
  335.  
  336.     if (s->err_msg == NULL) s->err_msg = "TCP_ABORT";
  337.     if ((s->state != tcp_StateLISTEN) && (s->state != tcp_StateCLOSED))
  338.         {
  339.         s->flags = tcp_FlagRST | tcp_FlagACK;
  340.         tcp_send(s);
  341.         }
  342.     s->rptxmit = FALSE;
  343.     s->sdatalen = 0;
  344.     s->state = tcp_StateCLOSED;
  345.     tcp_unthread(s);
  346.     return (1);                /* success */
  347. }
  348.  
  349. /*
  350.  * tcp_sendsoon - schedule a transmission pretty soon
  351.  *        - this one has an imperfection at midnight, but it
  352.  *          is not significant to the connection performance
  353.  * Return 0 if failure.
  354.  */
  355. int
  356. tcp_sendsoon(tcp_Socket *s)
  357. {
  358.     register longword temp;
  359.  
  360.     if (s == NULL) return (0);
  361.  
  362.     if (s->ip_type != TCP_PROTO) return (0);
  363.  
  364.     s->karn_count = KARN_PENDING;
  365.     if (sourcequench != 0)            /* ICMP shutup message */
  366.         {
  367.         waittime += waittime;        /* double the timeout */
  368.         sourcequench = 0;        /* forget the reminder */
  369.         }
  370.  
  371.     temp = set_ttimeout(waittime);        /* Bios ticks into the future */
  372.     if ((s->rtt_time < temp))        /* if timeout is in future */
  373.         return (1);            /* then wait some more */
  374.     if (waittime > normal_waittime)        /* if backing off already */
  375.         waittime = (waittime * 15) / 16; /* recover slowly */
  376.     s->rtt_time = temp;            /* set timeout of this pkt */
  377.     return (1);
  378. }
  379.  
  380. /*
  381.  * Retransmitter - called periodically to perform tcp retransmissions
  382.  * Returns 0 if failure
  383.  */
  384. static int
  385. tcp_retransmitter(void)
  386. {
  387.     register tcp_Socket *s;
  388.     static longword retran_strat = 0L;    /* timeout retran strategy */
  389.  
  390.             /* do this only once per RETRAN_STRAT_TIME clock ticks */
  391.     if (!chk_timeout(retran_strat))
  392.         return (0L);
  393.     retran_strat = set_ttimeout(RETRAN_STRAT_TIME);
  394.  
  395.     for (s = tcp_allsocs; s != NULL; s = s->next)
  396.         {
  397.         if ((s->sdatalen > 0) || (s->rptxmit == TRUE) ||
  398.                 (s->karn_count == KARN_PENDING))
  399.                             /* retransmission strategy */
  400.                 if (chk_timeout(s->rtt_time)) /* if timeout */
  401.                 {
  402.                 if (s->karn_count == KARN_NEW)
  403.                             s->karn_count = KARN_TIMEOUT;
  404.                         /* if really did timeout */
  405.                         tcp_send(s);
  406.                     }
  407.  
  408.         if (s->timeout && chk_timeout(s->timeout))
  409.             {
  410.             if (s->state == tcp_StateTIMEWT)
  411.                 {
  412.                 s->flags = tcp_FlagACK;
  413.                 s->state = tcp_StateCLOSED;
  414.                 tcp_unthread(s);    /* purge it */
  415.                 }
  416.             else if (s->state != tcp_StateESTAB)
  417.                 {
  418.                 s->err_msg = "Timeout, aborting";
  419.                 tcp_abort(s);
  420.                 }
  421.             }
  422.         }
  423.     return (1);        /* success */
  424. }
  425.  
  426. /*
  427.  * Unthread a socket from the socket list, if it's there. Return 0 on failure
  428.  */
  429. static int
  430. tcp_unthread(tcp_Socket *ds)
  431. {
  432.     register tcp_Socket *sp;
  433.  
  434.     if (ds == NULL) return (0);        /* failure */
  435.  
  436.     if ((ds->rdatalen == 0) || (ds->state > tcp_StateESTAB))
  437.         ds->sisopen = SOCKET_CLOSED;    /* ok to close socket */
  438.     ds->state = tcp_StateCLOSED;
  439.  
  440.     if ((sp = tcp_allsocs) == NULL)        /* no socket in the queue */ 
  441.         return (0);
  442.  
  443.     if (sp == ds)
  444.         tcp_allsocs = ds->next; /* if we are first, unlink */
  445.     while (sp != NULL)
  446.         {
  447.         if (sp->next == ds)        /* if current points to us */
  448.             {
  449.             sp->next = ds->next; /* point it to our successor */
  450.                break;
  451.             }
  452.         sp = sp->next;            /* look at next socket */
  453.         }
  454.     return (1);                /* success */
  455. }
  456.  
  457. /*
  458.  * tcp_tick - called periodically by user application
  459.  *        - returns 0 when our socket closes
  460.  *        - called with socket parameter or NULL
  461.  */
  462. tcp_tick(sock_type *s)
  463. {
  464.     register in_Header *ip;
  465.     int packettype;
  466.                     /* read a packet */
  467.     while ((ip = (in_Header *)eth_arrived(&packettype)) != NULL)
  468.     {
  469.     switch (packettype)          /* network big endian form */
  470.     {
  471.     case TYPE_IP:                    /* do IP */
  472.         if ((ip->hdrlen_ver != 0x45) ||
  473.         (checksum(ip, in_GetHdrlenBytes(ip)) != 0xffff))
  474.             {
  475.             if (debug_on)
  476.                 outs("IP Received BAD Checksum \n\r");
  477.             break;
  478.             }
  479.         if ((my_ip_addr == 0L) || 
  480.             (htonl(ip->destination)    == my_ip_addr))
  481.             {
  482.             switch (ip->proto)
  483.                 {
  484.                 case TCP_PROTO:
  485.                     tcp_handler(ip);
  486.                     break;
  487.                 case UDP_PROTO:
  488.                     udp_handler(ip);
  489.                     break;
  490.                 case ICMP_PROTO:
  491.                     icmp_handler(ip);
  492.                     break;
  493.                 default:
  494.                     break;
  495.                 }    /* end of switch (ip->proto) */
  496.             }
  497.         break;
  498.  
  499.     case TYPE_ARP:                    /* do ARP */
  500.         arp_handler(ip);
  501.         break;
  502.     case TYPE_RARP:                    /* do RARP */
  503.         rarp_handler(ip);
  504.         break;
  505.     default:                /* unknown type */
  506.         break;
  507.     }                /* end of switch */
  508.     eth_free(ip);            /* free the processed packet */
  509.     }                    /* end of while */
  510.  
  511.     tcp_retransmitter();        /* check on pending sends */
  512.     return ((s != NULL)? s->tcp.sisopen: 0); /* 0 means closed socket */
  513. }
  514.  
  515. void
  516. tcp_set_debug_state(word x)
  517. {
  518.     debug_on = x;
  519. }
  520.  
  521. /* returns 1 if connection is established, else 0 */
  522. int 
  523. tcp_established(tcp_Socket *s)
  524. {
  525.     if (s == NULL) return (0);        /* failure */
  526.     return (s->state == tcp_StateESTAB);
  527. }
  528.  
  529.  
  530. static int
  531. udp_write(udp_Socket *s, byte FAR *datap, int len)
  532. {
  533.     tcp_PseudoHeader ph;
  534.     struct pkt
  535.         {
  536.         in_Header  in;
  537.         udp_Header udp;
  538.         int       data;
  539.         } register *pkt;
  540.  
  541.     if (s == NULL || datap == NULL)
  542.         return (0);            /* failure */
  543.  
  544.     pkt = (struct pkt *)eth_formatpacket(&s->hisethaddr[0], TYPE_IP);
  545.     pkt->in.length = htons(sizeof(in_Header) + UDP_LENGTH + len);
  546.                         /* UDP header */
  547.     pkt->udp.srcPort = htons(s->myport);
  548.     pkt->udp.dstPort = htons(s->hisport);
  549.     pkt->udp.length = htons(UDP_LENGTH + len);
  550.     bcopyff(datap, &pkt->data, len);
  551.                         /* Internet header */
  552.     pkt->in.hdrlen_ver = 0x45;        /* version 4, hdrlen 5 */
  553.     pkt->in.tos = 0;
  554.     pkt->in.identification = htons(++ip_id);    /* was post inc */
  555.     pkt->in.frag = 0;
  556. #ifdef KERMIT
  557.     pkt->in.ttl = 60;
  558. #else
  559.     pkt->in.ttl = 254;
  560. #endif
  561.     pkt->in.proto = UDP_PROTO;            /* UDP */
  562.     pkt->in.checksum = 0;
  563.     pkt->in.source = htonl(my_ip_addr);
  564.     pkt->in.destination = htonl(s->hisaddr);
  565.     pkt->in.checksum = ~checksum(&pkt->in, sizeof(in_Header));
  566.                     /* compute udp checksum if desired */
  567.     if (s->soc_mode & UDP_MODE_NOCHK)
  568.         pkt->udp.checksum = 0;
  569.     else
  570.         {
  571.         ph.src = pkt->in.source;        /* big endian now */
  572.         ph.dst = pkt->in.destination;
  573.         ph.mbz = 0;
  574.         ph.protocol = UDP_PROTO;        /* UDP */
  575.         ph.length = pkt->udp.length;        /* big endian now */
  576.         ph.checksum = checksum(&pkt->udp, htons(ph.length));
  577.         pkt->udp.checksum = ~checksum(&ph, sizeof(ph));
  578.         }
  579.  
  580. #ifdef DEBUG
  581.     if (dbugxmit) (*dbugxmit)(s,inp,udpp);
  582. #endif
  583.     if (eth_send(ntohs(pkt->in.length)) != 0)    /* send pkt */
  584.         return (len);
  585.     else    return (0);                /* failed */
  586. }
  587.  
  588. /*
  589.  * udp_read - read data from buffer, does large buffering.
  590.  * Return 0 on failure.
  591.  */
  592. static int 
  593. udp_read(udp_Socket *s, byte FAR * datap, int maxlen)
  594. {
  595.     register int x;
  596.  
  597.     if (s == NULL || datap == NULL || maxlen ==0) 
  598.                 return (0);    /* failure */
  599.     if ((x = s->rdatalen) > 0)
  600.         {
  601.         if (x > maxlen) x = maxlen;
  602.         bcopyff(s->rdata, datap, x);
  603.         if (s->rdatalen -= x)
  604.             bcopyff(&s->rdata[x], s->rdata, s->rdatalen);
  605.             }
  606.     return (x);
  607. }
  608.  
  609. udp_cancel(in_Header *ip)
  610. {
  611.     int len;
  612.     register udp_Header *up;
  613.     register udp_Socket *s;
  614.                         /* match to a udp socket */
  615.     len = in_GetHdrlenBytes(ip);
  616.     up = (udp_Header *)((byte *)ip + len);    /* udp frame pointer */
  617.                         /* demux to active sockets */
  618.     for (s = udp_allsocs; s != NULL; s = s->next)
  619.         {
  620.             if (s->hisport != 0 &&
  621.              ntohs(up->dstPort) == s->myport &&
  622.              ntohs(up->srcPort) == s->hisport &&
  623.              ntohl(ip->source) == s->hisaddr)
  624.                  break;
  625.             if (s->hisport != 0 &&        /* ICMP repeat of our pkt */
  626.              ntohs(up->dstPort) == s->hisport &&
  627.              ntohs(up->srcPort) == s->myport &&
  628.              ntohl(ip->source) == my_ip_addr)
  629.             break;        
  630.         }
  631.  
  632.     if (s == NULL)                /* demux to passive sockets */
  633.         for (s = udp_allsocs; s != NULL; s = s->next)
  634.                 if (s->hisport == 0 && 
  635.                 ntohs(up->dstPort) == s->myport)
  636.                     break;
  637.  
  638.     if (s != NULL)
  639.         udp_close(s);
  640.     return (1);                /* success */
  641. }
  642.  
  643. int
  644. tcp_cancel(in_Header *ip)
  645. {
  646.     int len;
  647.     register tcp_Socket *s;
  648.     register tcp_Header *tp;
  649.  
  650.     if (ip == NULL) return (0);        /* failure */
  651.     len = in_GetHdrlenBytes(ip);        /* check work */
  652.  
  653.     tp = (tcp_Header *)((byte *)ip + len);    /* TCP frame pointer */
  654.                         /* demux to active sockets */
  655.     for (s = tcp_allsocs; s != NULL; s = s->next)
  656.         {
  657.             if (s->hisport != 0 &&        /* them to us */
  658.              ntohs(tp->dstPort) == s->myport &&
  659.              ntohs(tp->srcPort) == s->hisport &&
  660.              ntohl(ip->source) == s->hisaddr)
  661.                  break;
  662.             if (s->hisport != 0 &&        /* ICMP repeat of our pkt */
  663.              ntohs(tp->dstPort) == s->hisport &&
  664.              ntohs(tp->srcPort) == s->myport &&
  665.              ntohl(ip->source) == my_ip_addr)
  666.             break;        
  667.         }
  668.  
  669.     if (s == NULL)            /* demux to passive sockets */
  670.         for (s = tcp_allsocs; s != NULL; s = s->next)
  671.                 if (s->hisport == 0 &&
  672.                 ntohs(tp->dstPort) == s->myport)
  673.                     break;
  674.  
  675.     if (s != NULL)
  676.         {
  677.         s->rdatalen = 0;
  678.         s->state = tcp_StateCLOSED;
  679.         tcp_unthread(s);
  680.         }
  681.     return (1);                /* success */
  682. }
  683.  
  684. static int 
  685. tcp_read(tcp_Socket *s, byte FAR *datap, int maxlen)
  686. {
  687.     register int x;
  688.  
  689.     if (s == NULL || datap == NULL || maxlen <= 0)
  690.             return (0);        /* failure or read nothing */
  691.     if ((x = s->rdatalen) > 0)
  692.         {
  693.         if (x > maxlen) x = maxlen;
  694.         bcopyff(s->rdata, datap, x);    /* copy out desired data */
  695.         s->rdatalen -= x;
  696.         bcopyff(&s->rdata[x], s->rdata, s->rdatalen);
  697.                     tcp_sendsoon(s);
  698.         if (x == maxlen && s->rdatalen <= maxlen)  /* last gulp */
  699.             tcp_sendsoon(s);    /* schedule window update */
  700.         else    /* for SLIP update when space for a new packet */
  701.         if (((pktdevclass == PD_SLIP) || (pktdevclass == PD_ETHER 
  702.         && MAC_len == 0)) && (TCP_RBUFSIZE - s->rdatalen > (int) mss)) 
  703.             tcp_sendsoon(s);    /* schedule window update */
  704.         }
  705.     return (x);                /* return bytes read */
  706. }
  707.  
  708. /*
  709.  * Write data to a connection.
  710.  * Returns number of bytes written, == 0 when connection is not in
  711.  * established state.
  712.  */
  713. static int
  714. tcp_write(tcp_Socket *s, byte FAR *dp, int len)
  715. {
  716.     register int x;
  717.  
  718.     if (s == NULL || dp == NULL) return (0);    /* failure */
  719.     if (s->state != tcp_StateESTAB) len = 0;
  720.     if (len > (x = TCP_SBUFSIZE - s->sdatalen)) len = x;
  721.     if (len > 0)
  722.         {
  723.         bcopyff(dp, &s->sdata[s->sdatalen], len); /* append to buf */
  724.         s->sdatalen += len;         /* implies sending a packet */
  725.  
  726.         if (s->soc_mode & TCP_MODE_NONAGLE)
  727.             tcp_send(s);
  728.         else    /* transmit if first data or reached MTU */
  729.                 /* not true MTU, but better than nothing */
  730.             /* Nagle's algorithm, RFC 896 */
  731.                 if ((s->sdatalen == len) || 
  732.                     (s->sdatalen >= (int)(s->mss)))
  733.                 tcp_send(s);
  734.         }
  735.     return (len);
  736. }
  737.  
  738. /*
  739.  * Send pending data
  740.  */
  741. static int
  742. tcp_flush(tcp_Socket *s)
  743. {
  744.     if (s == NULL) return (0);        /* failure */
  745.     if (s->sdatalen > 0)
  746.         {
  747.             s->flags |= tcp_FlagPUSH;
  748.         return (tcp_send(s));
  749.             }
  750.     return (1);                    /* success */
  751. }
  752.  
  753. /*
  754.  * Handler for incoming UDP packets. If no socket tell the host via ICMP.
  755.  */
  756. static int
  757. udp_handler(in_Header *ip)
  758. {
  759.     register udp_Header *up;
  760.     register udp_Socket *s;
  761.     tcp_PseudoHeader ph;
  762.     byte *dp;
  763.     word len;
  764.  
  765.     len = in_GetHdrlenBytes(ip);
  766.     up = (udp_Header *)((byte *)ip + len);    /* UDP segment pointer */
  767.     len = ntohs(up->length);
  768.                 /* demux to active sockets */
  769.     for (s = udp_allsocs; s != NULL; s = s->next)
  770.         if (s->sisopen == SOCKET_OPEN && s->hisport != 0 && 
  771.             ntohs(up->dstPort) == s->myport &&
  772.             ntohs(up->srcPort) == s->hisport &&
  773.             ntohl(ip->source) == s->hisaddr)
  774.                 break;
  775.  
  776. #ifdef DEBUG
  777.     if (dbugrecv) (*dbugrecv)(s,ip,up);
  778. #endif
  779.     if (s == NULL)            /* demux to passive sockets */
  780.         for (s = udp_allsocs; s != NULL; s = s->next)
  781.             if (s->sisopen == SOCKET_OPEN && s->hisaddr == 0 &&
  782.                 ntohs(up->dstPort) == s->myport)
  783.                 {
  784.                 if (arp_resolve(htonl(ip->source),
  785.                     &s->hisethaddr[0]))
  786.                     {
  787.                        s->hisaddr = ntohl(ip->source);
  788.                         s->hisport = ntohs(up->srcPort);
  789.                     }
  790.                 break;
  791.                     }
  792.  
  793.     if (s == NULL)        /* demux to broadcast sockets */
  794.         for (s = udp_allsocs; s != NULL; s = s->next)
  795.             if (s->sisopen == SOCKET_OPEN && 
  796.                 s->hisaddr == ipbcast &&
  797.                 ntohs(up->dstPort) == s->myport)
  798.                     break;
  799.  
  800.     if (s == NULL)
  801.         {
  802.         icmp_noport(ip);    /* tell host port is unreachable */
  803.         if (debug_on) outs(" discarding...");
  804.         return (0);            /* say no socket */
  805.         }
  806.  
  807.     if (up->checksum)
  808.         {
  809.         ph.src = ip->source;        /* already bigend'd */
  810.         ph.dst = ip->destination;
  811.         ph.mbz = 0;
  812.         ph.protocol = UDP_PROTO;
  813.         ph.length = up->length;
  814.         ph.checksum = checksum(up, len);
  815.         if (checksum(&ph, sizeof(tcp_PseudoHeader)) != 0xffff)
  816.             return (0);        /* failure */
  817.         }
  818.                         /* process user data */
  819.     if ((len -= UDP_LENGTH) > 0)
  820.         {
  821.         dp = (byte *)(up);
  822.         if (len > UDP_BUFSIZE) len = UDP_BUFSIZE;
  823.         bcopyff(&dp[UDP_LENGTH], s->rdata, len); /* write to buf */
  824.         s->rdatalen = len;
  825.         bcopyff(&ip->source, &s->hisaddr, 6); /* sender's IP */
  826.         }
  827.     return (1);                /* success */
  828. }
  829.  
  830. /* Handle TCP packets. If no socket send an RST pkt. */
  831.  
  832. static 
  833. tcp_handler(in_Header *ip)
  834. {
  835.     register tcp_Header *tp;
  836.     register tcp_Socket *s;
  837.     tcp_PseudoHeader ph;
  838.     int len, diff;                /* signed, please */
  839.     word flags;
  840.     long diffticks, ldiff;            /* must be signed */
  841.  
  842.     len = in_GetHdrlenBytes(ip);
  843.     tp = (tcp_Header *)((byte *)ip + len);    /* tcp frame pointer */
  844.     len = ntohs(ip->length) - len;        /* len of tcp data */
  845.     flags = ntohs(tp->flags);        /* flags from pkt */
  846.  
  847.                 /* demux to active sockets */
  848.     for (s = tcp_allsocs; s != NULL; s = s->next)
  849.         if (s->hisport != 0 &&
  850.             ntohs(tp->dstPort) == s->myport &&
  851.             ntohs(tp->srcPort) == s->hisport &&
  852.             ntohl(ip->source) == s->hisaddr)
  853.             break;
  854.  
  855.     if (s == NULL)    /* demux to passive sockets, must be a new session */
  856.         for (s = tcp_allsocs; s != NULL; s = s->next)
  857.             if ((s->hisport == 0) &&
  858.                 (ntohs(tp->dstPort) == s->myport))
  859.                 break;
  860.  
  861. #ifdef DEBUG
  862.     if (dbugrecv) (*dbugrecv)(s, ip, tp);
  863. #endif
  864.  
  865.     if (s == NULL)
  866.         {
  867.          /* no session seems to exist, nor is there desire to start 
  868.          one, so we must send a reset    */
  869.         tcp_rst(ip, tp);
  870.         return (0);        /* 0 to say socket is closed */
  871.         }
  872.  
  873.                 /* save remote Ethernet address to socket */
  874.     bcopy(&((((eth_Header *)ip) - 1)->source[0]), &s->hisethaddr[0],
  875.             sizeof(eth_address));
  876.  
  877.     ph.src = ip->source;            /* network order now */
  878.     ph.dst = ip->destination;
  879.     ph.mbz = 0;
  880.     ph.protocol = TCP_PROTO;
  881.     ph.length = htons(len);
  882.     ph.checksum =  checksum(tp, len);
  883.     if (checksum(&ph, sizeof(ph)) != 0xffff)
  884.         {
  885.          if (debug_on) outs("bad tcp checksum \n\r");
  886.          return (1);
  887.         }
  888.  
  889.                     /* reset code */
  890.     if (flags & tcp_FlagRST)
  891.         {
  892.         if (debug_on) outs("\7\7connection reset\n");
  893.         s->rdatalen = 0;
  894.         s->state = tcp_StateCLOSED;
  895.         tcp_unthread(s);
  896.         return (0);            /* say socket is closed */
  897.         }
  898.  
  899.                     /* update our retransmission stuff */
  900.     if (s->karn_count != KARN_TIMEOUT)
  901.         if ((diffticks = set_ttimeout(0) - s->vj_last) >= 0)
  902.         {                /* we ignore the overnight case */
  903.         diffticks -= (s->vj_sa >> 3);
  904.         s->vj_sa += (word)diffticks;
  905.         if (diffticks < 0)
  906.             diffticks = -diffticks;
  907.         diffticks -= (s->vj_sd >> 2);
  908.         s->vj_sd += (word)diffticks;
  909.         s->rto = ((s->vj_sa >> 2) + s->vj_sd) >> 1;
  910.         s->karn_count = KARN_NEW;
  911.         }    /* else (== KARN_TIMEOUT) use the backed off rto */
  912.  
  913.         s->rptxmit = FALSE;
  914.  
  915.     switch (s->state) {
  916.  
  917.     case tcp_StateLISTEN:            /* accepting SYNs */
  918.         if (flags & tcp_FlagSYN)
  919.         {
  920.         s->acknum = ntohl(tp->seqnum) + 1;
  921.         s->hisport = ntohs(tp->srcPort);
  922.         s->hisaddr = ntohl(ip->source);
  923.         s->flags = tcp_FlagSYN | tcp_FlagACK;
  924.         server_hello(s);    /* put greeting msg in socket */
  925.         tcp_send(s);        /* we must respond immediately */
  926.         s->state = tcp_StateSYNREC;
  927.         s->timeout = set_timeout(tcp_TIMEOUT);
  928.         }
  929.     else
  930.             tcp_rst(ip, tp);  /* send a reset */
  931.         break;
  932.  
  933.     case tcp_StateSYNSENT:        /* added ACK Section */
  934.     if (flags & tcp_FlagSYN)
  935.         {
  936.             s->flags = tcp_FlagACK;
  937.         s->timeout = set_timeout(tcp_TIMEOUT);
  938.  
  939.         /* FlagACK means connection established, else SYNREC */
  940.         if (flags & tcp_FlagACK)
  941.             {      /* but is it for the correct session? */
  942.             if (tp->acknum == htonl(s->seqnum + 1))
  943.                 {
  944.                 s->state = tcp_StateESTAB;
  945.                 s->seqnum++;        /* good increment */
  946.                 s->acknum = ntohl(tp->seqnum) + 1; /*32 bits*/
  947.                 tcp_processdata(s, tp, len);
  948.                 tcp_sendsoon(s);    /* reply */
  949.                 }
  950.             else
  951.                 { /* wrong ack, force a RST and resend SYN */
  952.                 s->flags = tcp_FlagRST;
  953.                 tcp_send(s);
  954.                 s->flags = tcp_FlagSYN;
  955.                 tcp_send(s);
  956.                 }
  957.             }
  958.         else
  959.             {
  960.             s->acknum++;
  961.             s->state = tcp_StateSYNREC;
  962.             /* maybe check sequence number stuff too */
  963.             }
  964.         }
  965.     break;
  966.  
  967.     case tcp_StateSYNREC:    /* recSYNSENT, sentACK, waiting EST */
  968.     if (flags & tcp_FlagSYN)
  969.         {
  970.         s->flags = tcp_FlagSYN | tcp_FlagACK;
  971.             tcp_send(s);
  972.         s->timeout = set_timeout(tcp_TIMEOUT);
  973.         }
  974.     if ((flags & tcp_FlagACK) && (ntohl(tp->acknum) == (s->seqnum + 1)))
  975.         {
  976.         s->flags = tcp_FlagACK;
  977.         tcp_send(s);
  978.         s->seqnum++;
  979.         s->state = tcp_StateESTAB;
  980.             s->timeout = 0;             /* never timeout */
  981.         tcp_processdata(s, tp, len);
  982.         }
  983.     break;
  984.  
  985.     case tcp_StateESTAB:
  986.     if ((flags & tcp_FlagACK) == 0) return (1); /* they must ack somthing*/
  987.  
  988.     s->timeout = 0L;    /* we do not timeout at this point */
  989.                 /* process their ack value in packet */
  990.     /* If their ack preceeds the window this is an old packet. */
  991.     /* If ack exceeds the window then they are lying, don't believe. */
  992.     /* However, in all cases grab any useful data for us. */        
  993.     ldiff = ntohl(tp->acknum) - s->seqnum; /* current - prev ack */
  994.     if (ldiff >= 0 && ldiff <= s->sdatalen)
  995.         {             /* their ack is in our window*/
  996.         s->seqnum += ldiff;    /* update ACK'd file pointer */
  997.         diff = (int)ldiff;    /* 16 bits, bigger than our window */
  998.         s->sdatalen -= diff;    /* deduct amount ACK'd */
  999.                     /* move down residual in send buf */
  1000.          bcopyff(&s->sdata[diff], s->sdata, s->sdatalen);
  1001.         }
  1002.     s->flags = tcp_FlagACK;        /* tell them thanks */
  1003.     tcp_processdata(s, tp, len);    /* process our data in the packet */
  1004.  
  1005.     if (ldiff != 0 || len != 0)
  1006.         tcp_sendsoon(s);    /* ACK to maybe our closed window */
  1007.     break;
  1008.  
  1009.     case tcp_StateFINWT1:
  1010.                     /* process ack value in packet */
  1011.     ldiff = ntohl(tp->acknum) - s->seqnum; /* current - prev ack */
  1012.     if (ldiff >= 0 && ldiff <= s->sdatalen) /* their ack is in our window*/
  1013.         {
  1014.         s->seqnum += ldiff;    /* update ACK'd file counter */
  1015.         diff = (int)ldiff;    /* 16 bits, more than our window */
  1016.         s->sdatalen -= diff;    /* deduct amount ACK'd */
  1017.         bcopyff(&s->sdata[diff], s->sdata, s->sdatalen);
  1018.                         /* move residual */
  1019.         }
  1020.     tcp_processdata(s, tp, len);    /* process our data in the packet */
  1021.     tcp_send(s);
  1022.  
  1023.     if (flags & tcp_FlagFIN)    /* trying to do simultaneous close */
  1024.         {
  1025.         if ((ntohl(tp->acknum) >= s->seqnum + 1) &&
  1026.             (ntohl(tp->seqnum) == s->acknum))
  1027.             {        /* other guy wishes to close too */
  1028.             s->seqnum++;
  1029.             s->acknum++;
  1030.             s->flags = tcp_FlagACK;
  1031.             s->rptxmit = TRUE;
  1032.             s->timeout = set_timeout(3);
  1033.             s->state = tcp_StateCLOSING;
  1034.             tcp_send(s);
  1035.             }
  1036.         }
  1037.     else if (flags & tcp_FlagACK)
  1038.                    /* other side is legitimately acking our fin */
  1039.         if ((ntohl(tp->acknum) == s->seqnum + 1) &&
  1040.             (ntohl(tp->seqnum) == s->acknum) &&
  1041.             (s->sdatalen == 0))
  1042.             {
  1043.             s->seqnum++;
  1044.             s->sdatalen = 0;
  1045.             s->state = tcp_StateFINWT2;
  1046.                 s->timeout = set_timeout(3);
  1047.             }
  1048.     break;
  1049.  
  1050.     case tcp_StateFINWT2:        /* we can timeout of this state */
  1051.     if ((flags & (tcp_FlagACK | tcp_FlagFIN)) ==
  1052.         (tcp_FlagACK | tcp_FlagFIN))
  1053.         if ((ntohl(tp->acknum) == s->seqnum) &&
  1054.             (ntohl(tp->seqnum) == s->acknum))
  1055.             {
  1056.             s->acknum++;
  1057.             s->flags = tcp_FlagACK;
  1058.             tcp_send(s);
  1059.             s->timeout = set_timeout(2); /* max seg life 2 sec */
  1060.             s->state = tcp_StateTIMEWT;
  1061.             }
  1062.     break;
  1063.  
  1064.     case tcp_StateCLOSING:
  1065.         if ((flags & (tcp_FlagACK | tcp_FlagFIN)) == tcp_FlagACK)
  1066.         if ((tp->acknum == htonl(s->seqnum)) &&
  1067.             (tp->seqnum == htonl(s->acknum))) /* all agree */
  1068.         {
  1069.         s->state = tcp_StateTIMEWT;
  1070.         s->timeout = set_timeout(tcp_TIMEOUT);
  1071.         }
  1072.     break;
  1073.  
  1074.     case tcp_StateLASTACK:
  1075.     if (flags & tcp_FlagFIN)    /* they lost our two packets, back up */
  1076.         {
  1077.         s->flags = tcp_FlagACK;
  1078.         tcp_send(s);
  1079.         s->flags = tcp_FlagACK | tcp_FlagFIN;
  1080.         tcp_send(s);
  1081.         }
  1082.     else
  1083.         {
  1084.         if ((ntohl(tp->acknum) == (s->seqnum + 1)) &&
  1085.             (ntohl(tp->seqnum) == s->acknum))
  1086.                 {
  1087.                 s->state = tcp_StateCLOSED;     /* no 2 msl */
  1088.                 tcp_unthread(s);
  1089.                 }
  1090.         return (1);
  1091.         }
  1092.     break;
  1093.  
  1094.     case tcp_StateTIMEWT:
  1095.     s->flags = tcp_FlagACK;
  1096.     s->acknum = ntohl(tp->seqnum) + 1;
  1097.     tcp_send(s);
  1098.     break;
  1099.     }                        /* end switch */
  1100.     return (1);                    /* success */
  1101. }
  1102.  
  1103. /*
  1104.  * Process the data in an incoming packet.
  1105.  * Called from all states where incoming data can be received: established,
  1106.  * fin-wait-1, fin-wait-2
  1107.  */
  1108. static int
  1109. tcp_processdata(tcp_Socket *s, tcp_Header *tp, int len)
  1110. {
  1111.     register int diff, x;
  1112.     long ldiff;                    /* signed */
  1113.     byte *dp;
  1114.     word flags, *options, numoptions, opt_temp;
  1115.  
  1116.     if (s == NULL || tp == NULL) return (0);    /* failure */
  1117.  
  1118.     s->window = ntohs(tp->window);
  1119.     if (s->window > 0x7fff)            /* SGI 64KB window nonsense?*/
  1120.         s->window = 0x7fff;        /* yes, cut window to 32KB */
  1121.     flags = ntohs(tp->flags);
  1122.     ldiff = s->acknum - ntohl(tp->seqnum);    /* signed long */
  1123.     if (flags & tcp_FlagSYN) ldiff--;    /* SYN counts as one unit */
  1124.     diff = (int)ldiff;            /* 16 bit version */
  1125.  
  1126.                         /* find the data portion */
  1127.     x = tcp_GetDataOffset(tp) << 2;        /* quadword to byte count */
  1128.     dp = (byte *)tp + x;            /* points to data */
  1129.  
  1130.                         /* process those options */
  1131.     if (numoptions = x - sizeof(tcp_Header))
  1132.         {
  1133.         options = (word *)(tp + sizeof(tcp_Header));
  1134.         while (numoptions-- > 0)
  1135.             switch (*options++)
  1136.                 {
  1137.                 case 0: numoptions = 0;    /* end of options */
  1138.                 case 1: break;        /* nop */
  1139.  
  1140.                   /* we are very liberal on MSS stuff */
  1141.                 case 2: if (*options == 2)
  1142.                         {
  1143.                 opt_temp = ntohs(* (word *)(&options[1]));
  1144.                         if (opt_temp < s->mss)
  1145.                             s->mss = opt_temp;
  1146.                         }
  1147.                     numoptions -= 2 + *options;
  1148.                     options += *options;
  1149.                       break;
  1150.                 }    /* end of switch and while */
  1151.         }            /* end of if */
  1152.                     /* done option processing */
  1153.  
  1154.     len -= x;            /* remove the header length */
  1155.     if (diff >= 0)            /* skip already received bytes */
  1156.         {
  1157.         dp += diff;        /* move to new data */
  1158.         len -= diff;        /* length of new data */
  1159.                     /* limit receive size to our window */
  1160.         if (s->rdatalen < 0)
  1161.             s->rdatalen = 0;    /* pointer sanity check */
  1162.         if (len > (x = TCP_RBUFSIZE - s->rdatalen))
  1163.                 len = x;    /* space available only */
  1164.  
  1165.         if (len > 0)
  1166.             {          /* new ack begins at end of data */
  1167.             s->acknum += len;
  1168.             bcopyff(dp, &s->rdata[s->rdatalen], len);
  1169.             s->rdatalen += len;
  1170.             }
  1171.         }                /* end of if (diff > 0) */
  1172.     s->rptxmit = FALSE;        /* don't send ACK response yet */
  1173.  
  1174.     if (flags & tcp_FlagFIN)
  1175.         {
  1176.         s->acknum++;
  1177.         switch (s->state)
  1178.             {
  1179.                 case tcp_StateESTAB:
  1180.                 s->err_msg = "Connection closed.";
  1181.                             /* tcp_StateCLOSWT ... here we go */
  1182.                 x = tcp_StateLASTACK;
  1183.                 s->flags |= tcp_FlagFIN;
  1184.                 s->rptxmit = TRUE;    /* to send packet */
  1185.                 break;
  1186.  
  1187.             case tcp_StateFINWT1:    /* on ack should go to finwt2 */
  1188.                 s->flags |= tcp_FlagFIN;
  1189.                     /* not certain of this addition */
  1190.                 x = tcp_StateCLOSING;
  1191.                 break;
  1192.  
  1193.                 case tcp_StateFINWT2:
  1194.                 x = tcp_StateTIMEWT;
  1195.                 break;
  1196.             }            /* end of switch (s->state) */
  1197.         s->state = x;
  1198.         }            /* end of if (flags & tcp_FlagFIN) */
  1199.     s->timeout = set_timeout(tcp_TIMEOUT);
  1200.     return (1);                /* success */
  1201. }
  1202.  
  1203. /*
  1204.  * Format and send an outgoing segment
  1205.  */
  1206. static int
  1207. tcp_send(tcp_Socket *s)
  1208. {
  1209.     tcp_PseudoHeader ph;
  1210.     struct pkt
  1211.         {
  1212.         in_Header in;
  1213.         tcp_Header tcp;
  1214.         word maxsegopt[2];
  1215.         } register *pkt;
  1216.     byte *dp;
  1217.     int senddatalen, sendtotlen, sendpktlen;
  1218.     register byte ippkt;                /* 1..s->cwindow */
  1219.  
  1220.     if (s == NULL) return (0);        /* failure */
  1221.  
  1222.     pkt = (struct pkt *)eth_formatpacket(&s->hisethaddr[0], TYPE_IP);
  1223.     dp = (byte *)pkt->maxsegopt;  /* dp constant for multi-packet sends */
  1224.  
  1225.                     /* this is our total possible send size */
  1226.     if (s->window > 0)
  1227.         senddatalen = (s->sdatalen >= (int)s->window)? 
  1228.             s->window - 1: s->sdatalen;
  1229.     else    senddatalen = 0;
  1230.  
  1231.     sendtotlen = 0;            /* running count of what we've sent */
  1232.  
  1233.                     /* step through our packets */
  1234.     for (ippkt = 1; ippkt <= s->cwindow; ippkt++)
  1235.         {            /* adjust size for each packet */
  1236.             if (senddatalen > (int)s->mss)
  1237.             senddatalen = (int)s->mss;
  1238.                     /* tcp header */
  1239.             pkt->tcp.srcPort = htons(s->myport);
  1240.             pkt->tcp.dstPort = htons(s->hisport);
  1241.             pkt->tcp.seqnum = htonl(s->seqnum + sendtotlen);
  1242.             pkt->tcp.acknum = htonl(s->acknum);
  1243.             pkt->tcp.window = htons(s->rmaxdatalen - s->rdatalen);
  1244.             pkt->tcp.flags = htons(s->flags | 0x5000);
  1245.             pkt->tcp.checksum = 0;
  1246.             pkt->tcp.urgentPointer = 0;
  1247.  
  1248.                 /* do options if this is our first packet */
  1249.             if ((s->flags & (tcp_FlagSYN | tcp_FlagACK)) == tcp_FlagSYN)
  1250.             {
  1251.             sendpktlen = sizeof(tcp_Header) + 
  1252.                     sizeof(in_Header) + 4;
  1253.             pkt->tcp.flags = htons(ntohs(pkt->tcp.flags) + 0x1000);
  1254.             pkt->maxsegopt[0] = 0x0402;
  1255.             pkt->maxsegopt[1] = htons(s->mss);
  1256.             dp += 4;
  1257.             }
  1258.         else
  1259.             {    
  1260.                 /* handle no-data, not-first-SYN packets */
  1261.                     sendpktlen = sizeof(tcp_Header) + sizeof(in_Header);
  1262.             if (senddatalen > 0)    /* handle packets with data */
  1263.                 {
  1264.                         sendpktlen += senddatalen;
  1265.                         bcopyff(&s->sdata[sendtotlen], dp, senddatalen);
  1266.                 }
  1267.                 }
  1268.  
  1269.                     /* Internet header */
  1270.         pkt->in.hdrlen_ver = 0x45;    /* version 4, hdrlen 5 */
  1271.             pkt->in.tos = 0;        /* crummy service is ok */
  1272.             pkt->in.identification = htons(++ip_id); /* pre-inc req'd */
  1273.             pkt->in.frag = 0;        /* we can't do fragments */
  1274. #ifdef KERMIT
  1275.             pkt->in.ttl = 60;        /* seconds */
  1276. #else
  1277.             pkt->in.ttl = 254;
  1278. #endif
  1279.         pkt->in.proto = TCP_PROTO;
  1280.             pkt->in.checksum = 0;
  1281.             pkt->in.source = htonl(my_ip_addr);
  1282.             pkt->in.destination = htonl(s->hisaddr);
  1283.             pkt->in.length = htons(sendpktlen);
  1284.  
  1285.             pkt->in.checksum = ~checksum(&pkt->in, sizeof(in_Header));
  1286.  
  1287.             /* compute tcp checksum */
  1288.             ph.src = pkt->in.source;   /* already in network order */
  1289.             ph.dst = pkt->in.destination;
  1290.             ph.mbz = 0;
  1291.             ph.protocol = TCP_PROTO;
  1292.             ph.length = htons(sendpktlen - sizeof(in_Header));
  1293.             ph.checksum = checksum(&pkt->tcp,
  1294.                 (sendpktlen - sizeof(in_Header) + 1) & 0xfffe);
  1295.             pkt->tcp.checksum = ~checksum(&ph, sizeof(ph));
  1296.  
  1297. #ifdef DEBUG
  1298.             if (dbugxmit) (*dbugxmit)(s, &pkt->in, &pkt->tcp);
  1299. #endif
  1300.             if (eth_send(htons(pkt->in.length)) == 0)
  1301.             return (0);            /* sending failed */
  1302.             sendtotlen += senddatalen;
  1303.     }                    /* do next ip pkt */
  1304.  
  1305.     if (s->karn_count == KARN_TIMEOUT)
  1306.         {
  1307.             if (s->rto) s->rto = (s->rto * 3) / 2;
  1308.         else s->rto = normal_waittime;
  1309.             }
  1310.     else
  1311.             {
  1312.         s->vj_last = set_ttimeout(0);
  1313.         s->karn_count = KARN_NEW;
  1314.         }
  1315.     s->rtt_time = set_ttimeout(s->rto);
  1316.     return (1);                    /* success */
  1317. }
  1318. /*
  1319.  * Format and send a reset tcp packet
  1320.  */
  1321. int
  1322. tcp_rst(in_Header *his_ip, tcp_Header *oldtcpp)
  1323. {
  1324.     tcp_PseudoHeader ph;
  1325.     struct pkt
  1326.         {
  1327.             in_Header in;
  1328.             tcp_Header tcp;
  1329.         word maxsegopt[2];
  1330.         } register *pkt;
  1331.  
  1332.     eth_Header *eth;
  1333.     register int sendtotlen;            /* length of packet */
  1334.  
  1335.     if (his_ip == NULL || oldtcpp == NULL) return (0);    /* failure */
  1336.  
  1337.                     /* see RFC 793 page 65 for details */
  1338.     oldtcpp->flags = ntohs(oldtcpp->flags);        /* net to local */
  1339.  
  1340.     if (oldtcpp->flags & tcp_FlagRST)
  1341.         return (0);  
  1342.     if ((oldtcpp->flags & tcp_FlagACK) == 0)
  1343.             oldtcpp->flags = tcp_FlagACK;
  1344.     else
  1345.             oldtcpp->flags = 0;
  1346.  
  1347.                 /* reads his Ethernet address or garbage */
  1348.     eth = eth_hardware((byte *)his_ip);
  1349.  
  1350.     pkt = (struct pkt *)eth_formatpacket(eth, TYPE_IP);
  1351.     sendtotlen = sizeof(tcp_Header) + sizeof(in_Header);
  1352.     pkt->in.length = htons(sendtotlen);
  1353.                     /* TCP header */
  1354.     pkt->tcp.srcPort = oldtcpp->dstPort;
  1355.     pkt->tcp.dstPort = oldtcpp->srcPort;
  1356.     pkt->tcp.seqnum = oldtcpp->acknum;
  1357.     pkt->tcp.acknum = htonl(ntohl(oldtcpp->seqnum) + 1);
  1358.     pkt->tcp.window = 0;
  1359.     pkt->tcp.flags = htons(tcp_FlagRST | oldtcpp->flags | 0x5000);
  1360.     pkt->tcp.checksum = 0;
  1361.     pkt->tcp.urgentPointer = 0;
  1362.                     /* Internet header */
  1363.     pkt->in.hdrlen_ver = 0x45;        /* version 4, hdrlen 5 */
  1364.     pkt->in.tos = 0;
  1365.     pkt->in.identification = htons(++ip_id); /* use pre-inc here */
  1366.     pkt->in.frag = 0;
  1367. #ifdef KERMIT
  1368.     pkt->in.ttl = 60;            /* time to live */
  1369. #else
  1370.     pkt->in.ttl = 254;
  1371. #endif
  1372.     pkt->in.proto = TCP_PROTO;
  1373.     pkt->in.checksum = 0;
  1374.     pkt->in.source = his_ip->destination;
  1375.     pkt->in.destination = his_ip->source;
  1376.     pkt->in.checksum = ~checksum(&pkt->in, sizeof(in_Header));
  1377.                         /* compute TCP checksum */
  1378.     ph.src = pkt->in.source;        /* already big endian */
  1379.     ph.dst = pkt->in.destination;
  1380.     ph.mbz = 0;
  1381.     ph.protocol = TCP_PROTO;
  1382.     ph.length = htons(sendtotlen - sizeof(in_Header));
  1383.     ph.checksum = checksum(&pkt->tcp, (sendtotlen - sizeof(in_Header) + 1)
  1384.                                 & 0xfffe);
  1385.     pkt->tcp.checksum = ~checksum(&ph, sizeof(ph));
  1386.  
  1387. #ifdef DEBUG
  1388.     if (dbugxmit) (*dbugxmit)(NULL, &pkt->in, &pkt->tcp);
  1389. #endif
  1390.     return (eth_send(htons(pkt->in.length)));
  1391. }
  1392.  
  1393. /* Handle ICMP Redirects. ICMP processor yields new gateway IP number
  1394.    in "gateway" and pointer to offending IP header which we have sent.
  1395.    Find socket with destination IP address matching the gateway
  1396.    sending us the Redirect message, replace the socket's destination
  1397.    Ethernet address with that of the new gateway (use arp_resolve).
  1398.    For TCP resend the packet, for UDP give up all hope.
  1399. */
  1400. void
  1401. do_redirect(longword gateway, in_Header *ip)
  1402. {
  1403.     register udp_Socket *s_udp;
  1404.     register tcp_Socket *s_tcp;
  1405.     tcp_Header *tp;
  1406.     int len;
  1407.     longword host;
  1408.  
  1409.     len = in_GetHdrlenBytes(ip);
  1410.     tp = (tcp_Header *)((byte *)ip + len);    /* tcp frame pointer */
  1411.     host = ntohl(ip->destination);        /* destination IP */
  1412.  
  1413.     switch(ip->proto)
  1414.         {
  1415.         case TCP_PROTO:        /* active TCP sockets */
  1416.         for (s_tcp = tcp_allsocs; s_tcp != NULL; s_tcp = s_tcp->next)
  1417.             if ((host == s_tcp->hisaddr) &&    /* if same dest IP */
  1418.                 (ntohs(tp->srcPort) == s_tcp->myport))
  1419.                                 /* & port */
  1420.                 {
  1421.                 arp_resolve(gateway, &s_tcp->hisethaddr[0]);
  1422.                 tcp_send(s_tcp);    /* resend the packet */
  1423.                 }
  1424.             break;
  1425.         case UDP_PROTO:            /* active UDP sockets */
  1426.         for (s_udp = udp_allsocs; s_udp != NULL; s_udp = s_udp->next)
  1427.             if ((host == s_udp->hisaddr) &&
  1428.                 (ntohs(tp->srcPort) == s_udp->myport))
  1429.                 arp_resolve(gateway, &s_udp->hisethaddr[0]);
  1430.             break;
  1431.         }
  1432. }
  1433.  
  1434. /**********************************************************************
  1435.  * socket functions
  1436.  **********************************************************************/
  1437.  
  1438. /* socket based procedures */
  1439.  
  1440. /*
  1441.  * sock_mode - set binary or ascii - affects sock_gets, sock_dataready
  1442.  *         - set udp checksums
  1443.  */
  1444. int
  1445. sock_mode(tcp_Socket *s, word mode)
  1446. {
  1447.     if (s != NULL)
  1448.         {
  1449.         s->soc_mode = (s->soc_mode & 0xfffc) | mode;
  1450.         return (1);        /* success */
  1451.         }
  1452.     else
  1453.         return (0);        /* failure */
  1454. }
  1455.  
  1456. /*
  1457.  * sock_read - read a socket with maximum n bytes
  1458.  *         - returns count also when connection gets closed
  1459.  */
  1460. int
  1461. sock_read(sock_type *s, byte FAR *dp, int len)
  1462. {
  1463.     register int templen, count;
  1464.     count = 0;
  1465.  
  1466.     if (s == NULL || dp == NULL) return (0);        /* failure */
  1467.     do        {
  1468.         switch (s->tcp.ip_type)
  1469.             {
  1470.             case UDP_PROTO:
  1471.                 templen = udp_read((udp_Socket *)s, dp, len);
  1472.                 break;
  1473.             case TCP_PROTO:
  1474.                 templen = tcp_read((tcp_Socket *)s, dp, len);
  1475.                 if (templen == 0 && 
  1476.                     s->tcp.sisopen == SOCKET_CLOSED)
  1477.                         return (count); /*quit early*/
  1478.                 break;
  1479.             default: return (0);
  1480.             }
  1481.         count += templen;
  1482.         len -= templen;
  1483.             }
  1484.     while (len > 0);
  1485.        return (count);
  1486. }
  1487.  
  1488. /*
  1489.  * sock_fastread - read a socket with maximum n bytes
  1490.  *         - does not busywait until buffer is full
  1491.  */
  1492. int
  1493. sock_fastread(sock_type *s, byte FAR *dp, int len)
  1494. {
  1495.     if (s == NULL)  return (0);        /* failure */
  1496.     switch(s->tcp.ip_type)
  1497.         {
  1498.         case UDP_PROTO:
  1499.             return (udp_read((udp_Socket *)s, dp, len));
  1500.         case TCP_PROTO:
  1501.             return (tcp_read((tcp_Socket *)s, dp, len));
  1502.         default: return (0);
  1503.         }
  1504. }
  1505.  
  1506.  
  1507. /*
  1508.  * sock_write - writes data and returns length written
  1509.  *          - does not perform flush
  1510.  */
  1511. int
  1512. sock_write(sock_type *s, byte FAR *dp, int len)
  1513. {
  1514.     register int offset, oldlen;
  1515.  
  1516.     oldlen = len;
  1517.     offset = 0;
  1518.     if (s == NULL || dp == NULL) return (0);    /* failure */
  1519.     while (len  > 0)
  1520.         {
  1521.         switch (s->tcp.ip_type)
  1522.             {
  1523.             case UDP_PROTO:
  1524.                 offset += 
  1525.                 udp_write((udp_Socket *)s, &dp[offset], len);
  1526.                 break;
  1527.             case TCP_PROTO:
  1528.                 offset += 
  1529.                 tcp_write((tcp_Socket *)s, &dp[offset], len);
  1530.                 break;
  1531.             default: return (0);
  1532.             }
  1533.         len = oldlen - offset;
  1534.         if (tcp_tick(s) == SOCKET_CLOSED)
  1535.             return (0);    /* no socket */
  1536.         }
  1537.     return (oldlen);
  1538. }
  1539.  
  1540. int
  1541. sock_fastwrite(sock_type *s, byte FAR *dp, int len)
  1542. {
  1543.     tcp_tick(NULL);                /* updates our output buffer*/
  1544.     if (s == NULL) return (0);        /* failure */
  1545.  
  1546.     switch (s->tcp.ip_type)
  1547.         {
  1548.         case UDP_PROTO: 
  1549.             return (udp_write((udp_Socket *)s, dp, len));
  1550.         case TCP_PROTO: 
  1551.             return (tcp_write((tcp_Socket *)s, dp, len));
  1552.         default: return (0);
  1553.         }
  1554. }
  1555.  
  1556. int
  1557. sock_flush(sock_type *s)
  1558. {
  1559.     if (s == NULL) return (0);            /* failure */
  1560.     if (s->tcp.ip_type == TCP_PROTO)
  1561.         return (tcp_flush((tcp_Socket *)s));
  1562.     return (1);
  1563. }
  1564. /*
  1565.  * sock_flushnext - cause next transmission to have a flush
  1566.  */
  1567. int
  1568. sock_flushnext(sock_type *s)
  1569. {
  1570.     if (s == NULL) return (0);            /* failure */
  1571.     if (s->tcp.ip_type == TCP_PROTO)
  1572.         s->tcp.flags |= tcp_FlagPUSH;
  1573.     return (1);                    /* success */
  1574. }
  1575.  
  1576. /*
  1577.  * sock_putc - put a character
  1578.  *         - no expansion but flushes on '\n'
  1579.  *         - returns character
  1580.  */
  1581. int
  1582. sock_putc(sock_type *s, byte c)
  1583. {
  1584.     byte ch;
  1585.  
  1586.     ch = c;
  1587.     if (s == NULL) return (-1);            /* failure */
  1588.     if ((ch == '\n') || (ch == '\r'))
  1589.         sock_flushnext(s);
  1590.     sock_write(s, &ch, 1);
  1591.     return (ch & 0xff);
  1592. }
  1593.  
  1594. int
  1595. sock_getc(sock_type *s)
  1596. {
  1597.     byte ch;
  1598.  
  1599.     if (s == NULL) return (-1);            /* failure */
  1600.     sock_read(s, &ch, 1);
  1601.     return (ch & 0xff);
  1602. }
  1603.  
  1604. #ifndef KERMIT
  1605. /*
  1606.  * sock_puts - does not append carriage return in binary mode
  1607.  *         - returns length
  1608.  */
  1609. int
  1610. sock_puts(sock_type *s, byte *dp)
  1611. {
  1612.     register int len;
  1613.  
  1614.     if (s == NULL || dp == NULL) return (0);    /* failure */
  1615.  
  1616.     len = strlen(dp);
  1617.     sock_flushnext(s);
  1618.     sock_write(s, dp, len);
  1619.     if (s->tcp.soc_mode & TCP_MODE_ASCII)
  1620.         sock_putc(s, '\n');
  1621.     return (len);
  1622. }
  1623. #endif    /* KERMIT */
  1624.  
  1625. /*
  1626.  * sock_update - update the socket window size to the other guy
  1627.  * Note: a better and safer criterion is s->rdatalen < mss
  1628.  *  which allows room for a full incoming segment without loss or overflow.
  1629.  */
  1630. static int
  1631. sock_update(tcp_Socket *s)
  1632. {
  1633.     if (s == NULL) return (0);            /* failure */
  1634.     if (s->ip_type == TCP_PROTO)
  1635.         {
  1636.         if (s->rdatalen <  s->rmaxdatalen >> 2)
  1637.             tcp_send(s);        /* update the window */
  1638.         else
  1639.             tcp_sendsoon(s);
  1640.         }
  1641.     return (1);                    /* success */
  1642. }
  1643.  
  1644. /*
  1645.  * sock_dataready - returns number of bytes waiting to be read
  1646.  *          - if in ASCII mode, return 0 until a line is present
  1647.  *            or the buffer is full
  1648.  */
  1649. word 
  1650. sock_dataready(sock_type *s)
  1651. {
  1652.     register int len;
  1653.     byte FAR *p;
  1654.  
  1655.     if (s == NULL) 
  1656.         return (0);
  1657.  
  1658.     if (s->tcp.soc_mode & TCP_MODE_ASCII)
  1659.         {
  1660.         if (len == TCP_RBUFSIZE)
  1661.             return (len);
  1662.                 /* check for terminating \n \r */
  1663.         p = s->tcp.rdata;
  1664.         if ((strchrf(p, '\n') == NULL) || (strchrf(p, '\r') == NULL))
  1665.             return (len);
  1666.         return (0);
  1667.         }
  1668.         return (s->tcp.rdatalen);
  1669. }
  1670.  
  1671. int
  1672. sock_established(sock_type *s)
  1673. {
  1674.     if (s == NULL) return (0);            /* failure */
  1675.     switch (s->tcp.ip_type)
  1676.         {
  1677.         case UDP_PROTO:
  1678.             return (1);
  1679.         case TCP_PROTO:
  1680.             return (s->tcp.state == tcp_StateESTAB);
  1681.         default:
  1682.             return (0);
  1683.         }
  1684. }
  1685.  
  1686. int
  1687. sock_close(sock_type *s)
  1688. {
  1689.     register int status;
  1690.  
  1691.     if (s == NULL) return (0);            /* failure */
  1692.     switch (s->tcp.ip_type)
  1693.         {
  1694.         case UDP_PROTO:
  1695.             status = udp_close((udp_Socket *)s);
  1696.             break;
  1697.         case TCP_PROTO:
  1698.             status = tcp_close((tcp_Socket *)s);
  1699.             tcp_tick(s);
  1700.             break;
  1701.         default:
  1702.             return (0);
  1703.         }
  1704.     return (status);                    /* success */
  1705. }
  1706.  
  1707. void 
  1708. sock_abort(sock_type *s)
  1709. {
  1710.     if (s == NULL) return;            /* do nothing */
  1711.     switch (s->tcp.ip_type)
  1712.         {
  1713.         case TCP_PROTO:
  1714.             tcp_abort((tcp_Socket *)s);
  1715.             break;
  1716.         case UDP_PROTO:
  1717.             udp_close((udp_Socket *)s);
  1718.             break;
  1719.         }
  1720. }
  1721.  
  1722. /*
  1723.  * ip user level timer stuff
  1724.  *   void ip_timer_init(void *s, int delayseconds)
  1725.  *   int  ip_timer_expired(void *s)
  1726.  *    - 0 if not expired
  1727.  */
  1728.  
  1729.  
  1730. void 
  1731. ip_timer_init(sock_type *s, int delayseconds)
  1732. {
  1733.     if (s == NULL)
  1734.         return;
  1735.     if (delayseconds != 0)
  1736.         s->udp.usertimer = set_timeout(delayseconds);
  1737.     else
  1738.         s->udp.usertimer = 0;
  1739. }
  1740.  
  1741. int 
  1742. ip_timer_expired(sock_type *s)
  1743. {
  1744.     if (s == NULL) return (1);            /* say time out */
  1745.     if (s->udp.usertimer == 0)            /* cannot expire */
  1746.         return (0);
  1747.  
  1748.     return (chk_timeout(s->udp.usertimer));
  1749. }
  1750.  
  1751. long 
  1752. make_timeout(word timeout)
  1753. {
  1754.     if (timeout) return (set_timeout(timeout));
  1755.     return (0);
  1756. }
  1757.  
  1758. /*
  1759.  * check_timeout - test agains timeout clock - account for overflow
  1760.  */
  1761. int 
  1762. check_timeout(unsigned long timeout)
  1763. {
  1764.     if (timeout) return (chk_timeout(timeout));
  1765.     return (0);
  1766. }
  1767.  
  1768. /*
  1769.  * ip_delay0 called by macro sock_wait_established()
  1770.  * ip_delay1 called by macro sock_wait_intput()
  1771.  * ip_delay2 called by macro sock_wait_closed();
  1772.  *
  1773.  */
  1774.  
  1775. ip_delay0(sock_type *s, int timeoutseconds, procref fn, int *statusptr)
  1776. {
  1777.     register int status;
  1778.  
  1779.     if (s == NULL)
  1780.         {
  1781.         status = -1;        /* failure */
  1782.             if (statusptr != NULL) *statusptr = status;
  1783.         return (status);
  1784.         }
  1785.     ip_timer_init(s, timeoutseconds);
  1786.  
  1787.     do
  1788.         {
  1789.         if (s->tcp.ip_type == TCP_PROTO)
  1790.             if (tcp_established((tcp_Socket *)s))
  1791.                 {
  1792.                 status = 0;
  1793.                 break;
  1794.                 }
  1795.         if (tcp_tick(s) == SOCKET_CLOSED)
  1796.             {
  1797.             s->tcp.err_msg = "Host refused connection";
  1798.             status = -1;    /* get an early reset */
  1799.             break;
  1800.             }
  1801.  
  1802.         if (ip_timer_expired(s))
  1803.             {
  1804.             sock_close(s);
  1805.             status = -1;
  1806.             break;
  1807.             }
  1808.         if (fn != NULL) 
  1809.             if (status = fn(s, NULL, 0)) break;
  1810.         if (s->tcp.ip_type == UDP_PROTO)
  1811.             {
  1812.             status = 0;
  1813.             break;
  1814.             }
  1815.         } while (1);
  1816.     if (statusptr != NULL) *statusptr = status;
  1817.     return (status);
  1818. }
  1819.  
  1820. int
  1821. ip_delay1(sock_type *s, int timeoutseconds, procref fn, int *statusptr)
  1822. {
  1823.     register int status;
  1824.  
  1825.     if (s == NULL)
  1826.         {
  1827.         status = -1;        /* failure */
  1828.             if (statusptr != NULL) *statusptr = status;
  1829.         return (status);
  1830.         }
  1831.  
  1832.     ip_timer_init(s, timeoutseconds);
  1833.     sock_flush(s);        /* new enhancement */
  1834.  
  1835.     do
  1836.         {
  1837.         if (sock_dataready(s))
  1838.             {
  1839.             status = 0;
  1840.             break;
  1841.             }
  1842.  
  1843.         if (tcp_tick(s) == SOCKET_CLOSED)
  1844.             {
  1845.             status = 1;
  1846.             break;
  1847.             }
  1848.         if (ip_timer_expired(s))
  1849.             {
  1850.             sock_close(s);
  1851.             status = -1;
  1852.             break;
  1853.             }
  1854.         if (fn != NULL)
  1855.             if (status = fn(s, NULL, 0)) break;
  1856.         } while (1 == 1);
  1857.  
  1858.     if (statusptr != NULL) *statusptr = status;
  1859.     return (status);
  1860. }
  1861.  
  1862. int
  1863. ip_delay2(sock_type *s, int timeoutseconds, procref fn, int *statusptr)
  1864. {
  1865.     register int status;
  1866.  
  1867.     if (s == NULL)
  1868.         {
  1869.         status = 0;        /* failure */
  1870.             if (statusptr != NULL) *statusptr = status;
  1871.         return (status);
  1872.         }
  1873.  
  1874.     ip_timer_init(s, timeoutseconds);
  1875.  
  1876.     if (s->tcp.ip_type != TCP_PROTO) return (1);
  1877.  
  1878.     do
  1879.         {
  1880.         if (tcp_tick(s) == SOCKET_CLOSED)     /*  no socket */
  1881.             {
  1882.             status = 1;
  1883.             break;
  1884.             }
  1885.         if (ip_timer_expired(s))
  1886.             {
  1887.             sock_abort(s);
  1888.             status = 0;
  1889.             break;
  1890.             }
  1891.         if (fn != NULL)
  1892.             if (status = fn(s, NULL, 0)) break;
  1893.         } while (1 == 1);
  1894.  
  1895.     if (statusptr != NULL) *statusptr = status;
  1896.     return (status);
  1897. }
  1898.