home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / comm / amitcp-3.0ß2.lha / AmiTCP / src / amitcp / netinet / tcp_output.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  17KB  |  578 lines

  1. RCS_ID_C="$Id: tcp_output.c,v 1.9 1993/06/04 11:16:15 jraja Exp $";
  2. /*
  3.  * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>,
  4.  *                    Helsinki University of Technology, Finland.
  5.  *                    All rights reserved.
  6.  *
  7.  * HISTORY
  8.  * $Log: tcp_output.c,v $
  9.  * Revision 1.9  1993/06/04  11:16:15  jraja
  10.  * Fixes for first public release.
  11.  *
  12.  * Revision 1.8  1993/05/17  00:16:44  ppessi
  13.  * Changed RCS version. Added rcsid.
  14.  *
  15.  * Revision 1.7  1993/04/24  23:22:13  jraja
  16.  * Removed #ifdef NOALIGN, now using straight structure copies.
  17.  *
  18.  * Revision 1.6  93/04/13  22:16:32  22:16:32  jraja (Jarno Tapio Rajahalme)
  19.  * Added ALIGNED to the tcp_initopt (which was odd aligned).
  20.  * 
  21.  * Revision 1.5  93/04/05  19:06:32  19:06:32  jraja (Jarno Tapio Rajahalme)
  22.  * Changed storage of the spl functions  return values to type spl_t.
  23.  * Added include for conf.h to every .c file.
  24.  * 
  25.  * Revision 1.4  93/03/22  16:59:39  16:59:39  jraja (Jarno Tapio Rajahalme)
  26.  * Changed bcopy()s and bzero()s with word aligned pointers to
  27.  * aligned_b(copy|zero) ar aligned_b(copy|zero)_const. The latter is for calls
  28.  * in which the size is constant.
  29.  * These can be disabled by defining NOALIGN.
  30.  *  Converted bcopys doing structure copies (on aligned pointers) to structure
  31.  * assignments, since at least SASC produces better code with assignment.
  32.  * 
  33.  * Revision 1.3  93/03/03  21:29:37  21:29:37  jraja (Jarno Tapio Rajahalme)
  34.  * Moved various data definitions from header files to here.
  35.  * 
  36.  * Revision 1.2  93/02/26  09:49:02  09:49:02  jraja (Jarno Tapio Rajahalme)
  37.  * Made this compile with ANSI C (added prototypes).
  38.  * Added one (phony) argument to tcp_quench() call, since it now takes two
  39.  * arguments, but does not use the second.
  40.  * 
  41.  * Revision 1.1  92/11/17  16:30:39  16:30:39  jraja (Jarno Tapio Rajahalme)
  42.  * Initial revision
  43.  *
  44.  */
  45.  
  46. /*
  47.  * Copyright (c) 1982, 1986, 1988, 1990 Regents of the University of California.
  48.  * All rights reserved.
  49.  *
  50.  * Redistribution and use in source and binary forms, with or without
  51.  * modification, are permitted provided that the following conditions
  52.  * are met:
  53.  * 1. Redistributions of source code must retain the above copyright
  54.  *    notice, this list of conditions and the following disclaimer.
  55.  * 2. Redistributions in binary form must reproduce the above copyright
  56.  *    notice, this list of conditions and the following disclaimer in the
  57.  *    documentation and/or other materials provided with the distribution.
  58.  * 3. All advertising materials mentioning features or use of this software
  59.  *    must display the following acknowledgement:
  60.  *    This product includes software developed by the University of
  61.  *    California, Berkeley and its contributors.
  62.  * 4. Neither the name of the University nor the names of its contributors
  63.  *    may be used to endorse or promote products derived from this software
  64.  *    without specific prior written permission.
  65.  *
  66.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  67.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  68.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  69.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  70.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  71.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  72.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  73.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  74.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  75.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  76.  * SUCH DAMAGE.
  77.  *
  78.  *    @(#)tcp_output.c    7.22 (Berkeley) 8/31/90
  79.  */
  80.  
  81. #include <conf.h>
  82.  
  83. #include <sys/param.h>
  84. #include <sys/systm.h>
  85. #include <sys/malloc.h>
  86. #include <sys/mbuf.h>
  87. #include <sys/protosw.h>
  88. #include <sys/socket.h>
  89. #include <sys/socketvar.h>
  90. #include <sys/errno.h>
  91. #include <sys/synch.h>
  92.  
  93. #include <net/route.h>
  94.  
  95. #include <netinet/in.h>
  96. #include <netinet/in_systm.h>
  97. #include <netinet/ip.h>
  98. #include <netinet/in_pcb.h>
  99. #include <netinet/ip_var.h>
  100. #include <netinet/tcp.h>
  101. #define    TCPOUTFLAGS
  102. #include <netinet/tcp_fsm.h>
  103. #include <netinet/tcp_seq.h>
  104. #include <netinet/tcp_timer.h>
  105. #include <netinet/tcp_var.h>
  106. #include <netinet/tcpip.h>
  107. #include <netinet/tcp_debug.h>
  108.  
  109. #include <netinet/tcp_output_protos.h>
  110. #include <netinet/tcp_input_protos.h>
  111. #include <netinet/tcp_debug_protos.h>
  112. #include <netinet/tcp_subr_protos.h>
  113. #include <netinet/ip_output_protos.h>
  114. #include <netinet/in_cksum_protos.h>
  115.  
  116. #ifdef notyet
  117. extern struct mbuf *m_copypack();
  118. #endif
  119.  
  120. /* --- start moved from tcp_fsm.h --- */
  121. #ifdef    TCPOUTFLAGS
  122. /*
  123.  * Flags used when sending segments in tcp_output.
  124.  * Basic flags (TH_RST,TH_ACK,TH_SYN,TH_FIN) are totally
  125.  * determined by state, with the proviso that TH_FIN is sent only
  126.  * if all data queued for output is included in the segment.
  127.  */
  128. u_char    tcp_outflags[TCP_NSTATES] = {
  129.     TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
  130.     TH_ACK, TH_ACK,
  131.     TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
  132. };
  133. #endif
  134. /* --- end moved from tcp_fsm.h --- */
  135.  
  136. /*
  137.  * Initial options.
  138.  */
  139. ALIGNED u_char    tcp_initopt[4] = { TCPOPT_MAXSEG, 4, 0x0, 0x0, };
  140.  
  141. /*
  142.  * Tcp output routine: figure out what should be sent and send it.
  143.  */
  144. int
  145. tcp_output(tp)
  146.     register struct tcpcb *tp;
  147. {
  148.     register struct socket *so = tp->t_inpcb->inp_socket;
  149.     register long len, win;
  150.     int off, flags, error;
  151.     register struct mbuf *m;
  152.     register struct tcpiphdr *ti;
  153.     u_char *opt;
  154.     unsigned optlen, hdrlen;
  155.     int idle, sendalot;
  156.  
  157.     /*
  158.      * Determine length of data that should be transmitted,
  159.      * and flags that will be used.
  160.      * If there is some data or critical controls (SYN, RST)
  161.      * to send, then transmit; otherwise, investigate further.
  162.      */
  163.     idle = (tp->snd_max == tp->snd_una);
  164.     if (idle && tp->t_idle >= tp->t_rxtcur)
  165.         /*
  166.          * We have been idle for "a while" and no acks are
  167.          * expected to clock out any data we send --
  168.          * slow start to get ack "clock" running again.
  169.          */
  170.         tp->snd_cwnd = tp->t_maxseg;
  171. again:
  172.     sendalot = 0;
  173.     off = tp->snd_nxt - tp->snd_una;
  174.     win = min(tp->snd_wnd, tp->snd_cwnd);
  175.  
  176.     /*
  177.      * If in persist timeout with window of 0, send 1 byte.
  178.      * Otherwise, if window is small but nonzero
  179.      * and timer expired, we will send what we can
  180.      * and go to transmit state.
  181.      */
  182.     if (tp->t_force) {
  183.         if (win == 0)
  184.             win = 1;
  185.         else {
  186.             tp->t_timer[TCPT_PERSIST] = 0;
  187.             tp->t_rxtshift = 0;
  188.         }
  189.     }
  190.  
  191.     flags = tcp_outflags[tp->t_state];
  192.     len = min(so->so_snd.sb_cc, win) - off;
  193.  
  194.     if (len < 0) {
  195.         /*
  196.          * If FIN has been sent but not acked,
  197.          * but we haven't been called to retransmit,
  198.          * len will be -1.  Otherwise, window shrank
  199.          * after we sent into it.  If window shrank to 0,
  200.          * cancel pending retransmit and pull snd_nxt
  201.          * back to (closed) window.  We will enter persist
  202.          * state below.  If the window didn't close completely,
  203.          * just wait for an ACK.
  204.          */
  205.         len = 0;
  206.         if (win == 0) {
  207.             tp->t_timer[TCPT_REXMT] = 0;
  208.             tp->snd_nxt = tp->snd_una;
  209.         }
  210.     }
  211.     if (len > tp->t_maxseg) {
  212.         len = tp->t_maxseg;
  213.         sendalot = 1;
  214.     }
  215.     if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
  216.         flags &= ~TH_FIN;
  217.  
  218.     win = sbspace(&so->so_rcv);
  219.  
  220.     /*
  221.      * Sender silly window avoidance.  If connection is idle
  222.      * and can send all data, a maximum segment,
  223.      * at least a maximum default-size segment do it,
  224.      * or are forced, do it; otherwise don't bother.
  225.      * If peer's buffer is tiny, then send
  226.      * when window is at least half open.
  227.      * If retransmitting (possibly after persist timer forced us
  228.      * to send into a small window), then must resend.
  229.      */
  230.     if (len) {
  231.         if (len == tp->t_maxseg)
  232.             goto send;
  233.         if ((idle || tp->t_flags & TF_NODELAY) &&
  234.             len + off >= so->so_snd.sb_cc)
  235.             goto send;
  236.         if (tp->t_force)
  237.             goto send;
  238.         if (len >= tp->max_sndwnd / 2)
  239.             goto send;
  240.         if (SEQ_LT(tp->snd_nxt, tp->snd_max))
  241.             goto send;
  242.     }
  243.  
  244.     /*
  245.      * Compare available window to amount of window
  246.      * known to peer (as advertised window less
  247.      * next expected input).  If the difference is at least two
  248.      * max size segments, or at least 50% of the maximum possible
  249.      * window, then want t