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_usrreq.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  15KB  |  569 lines

  1. RCS_ID_C="$Id: tcp_usrreq.c,v 1.10 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_usrreq.c,v $
  9.  * Revision 1.10  1993/06/04  11:16:15  jraja
  10.  * Fixes for first public release.
  11.  *
  12.  * Revision 1.9  1993/05/17  00:16:44  ppessi
  13.  * Changed RCS version. Added rcsid.
  14.  *
  15.  * Revision 1.8  1993/04/24  17:48:13  jraja
  16.  * Removed MCLBYTES, set default buffer size to 8 kilobytes.
  17.  *
  18.  * Revision 1.7  93/04/19  02:39:50  02:39:50  ppessi (Pekka Pessi)
  19.  * Default socket buffer space made bigger
  20.  * 
  21.  * Revision 1.6  93/04/05  19:06:44  19:06:44  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.5  93/03/16  08:28:51  08:28:51  jraja (Jarno Tapio Rajahalme)
  26.  * Made PRU_SENSE (stat) unsupported on AmiTCP
  27.  * 
  28.  * Revision 1.4  93/03/05  21:09:45  21:09:45  jraja (Jarno Tapio Rajahalme)
  29.  * Fixed includes (again).
  30.  * 
  31.  * Revision 1.3  93/03/03  21:28:27  21:28:27  jraja (Jarno Tapio Rajahalme)
  32.  * Moved various data definitions from header files to here.
  33.  * 
  34.  * Revision 1.2  93/02/26  09:59:47  09:59:47  jraja (Jarno Tapio Rajahalme)
  35.  * Made this compile with ANSI C (added prototypes).
  36.  * Changed so_linger to so_linger.tv_sec, since so_linger changed from short
  37.  * 
  38.  * Revision 1.1  92/11/17  16:31:09  16:31:09  jraja (Jarno Tapio Rajahalme)
  39.  * Initial revision
  40.  *
  41.  */
  42.  
  43. /*
  44.  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
  45.  * All rights reserved.
  46.  *
  47.  * Redistribution and use in source and binary forms, with or without
  48.  * modification, are permitted provided that the following conditions
  49.  * are met:
  50.  * 1. Redistributions of source code must retain the above copyright
  51.  *    notice, this list of conditions and the following disclaimer.
  52.  * 2. Redistributions in binary form must reproduce the above copyright
  53.  *    notice, this list of conditions and the following disclaimer in the
  54.  *    documentation and/or other materials provided with the distribution.
  55.  * 3. All advertising materials mentioning features or use of this software
  56.  *    must display the following acknowledgement:
  57.  *    This product includes software developed by the University of
  58.  *    California, Berkeley and its contributors.
  59.  * 4. Neither the name of the University nor the names of its contributors
  60.  *    may be used to endorse or promote products derived from this software
  61.  *    without specific prior written permission.
  62.  *
  63.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  64.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  65.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  66.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  67.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  68.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  69.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  70.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  71.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  72.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  73.  * SUCH DAMAGE.
  74.  *
  75.  *    @(#)tcp_usrreq.c    7.15 (Berkeley) 6/28/90
  76.  */
  77.  
  78. #include <conf.h>
  79.  
  80. #include <sys/param.h>
  81. #include <sys/systm.h>
  82. #include <sys/malloc.h>
  83. #include <sys/mbuf.h>
  84. #include <sys/socket.h>
  85. #include <sys/socketvar.h>
  86. #include <sys/protosw.h>
  87. #include <sys/errno.h>
  88. #include <sys/synch.h>
  89.  
  90. #include <net/if.h>
  91. #include <net/route.h>
  92.  
  93. #include <netinet/in.h>
  94. #include <netinet/in_systm.h>
  95. #include <netinet/ip.h>
  96. #include <netinet/in_pcb.h>
  97. #include <netinet/ip_var.h>
  98. #include <netinet/tcp.h>
  99. #include <netinet/tcp_fsm.h>
  100. #include <netinet/tcp_seq.h>
  101. #include <netinet/tcp_timer.h>
  102. #include <netinet/tcp_var.h>
  103. #include <netinet/tcpip.h>
  104. #include <netinet/tcp_debug.h>
  105.  
  106. #include <netinet/tcp_usrreq_protos.h>
  107. #include <netinet/tcp_output_protos.h>
  108. #include <netinet/tcp_subr_protos.h>
  109. #include <netinet/tcp_timer_protos.h>
  110. #include <netinet/in_protos.h>
  111. #include <netinet/in_pcb_protos.h>
  112. #include <kern/uipc_socket2_protos.h>
  113. #include <netinet/tcp_debug_protos.h>
  114. #include <netinet/ip_output_protos.h>
  115.  
  116. struct    inpcb tcb = { 0 };        /* head of queue of active tcpcb's */
  117. struct    tcpstat tcpstat = { 0 };    /* tcp statistics */
  118. tcp_seq    tcp_iss = { 0 };        /* tcp initial send seq # */
  119. #ifdef KPROF
  120. int    tcp_acounts[TCP_NSTATES][PRU_NREQ] = { 0 };
  121. #endif
  122. /* 
  123.  * Configurable variables
  124.  */
  125. u_long    tcp_sendspace = 8 * 1024;
  126. u_long    tcp_recvspace = 8 * 1024;
  127.  
  128. /*
  129.  * TCP protocol interface to socket abstraction.
  130.  */
  131. extern    char *tcpstates[];
  132. struct    tcpcb *tcp_newtcpcb();
  133.  
  134. /*
  135.  * Process a TCP user request for TCP tb.  If this is a send request
  136.  * then m is the mbuf chain of send data.  If this is a timer expiration
  137.  * (called from the software clock routine), then timertype tells which timer.
  138.  */
  139. int
  140. tcp_usrreq(so, req, m, nam, control)
  141.     struct socket *so;
  142.     int req;
  143.     struct mbuf *m, *nam, *control;
  144. {
  145.     register struct inpcb *inp;
  146.     register struct tcpcb *tp;
  147.     spl_t s;
  148.     int error = 0;
  149.     int ostate;
  150.  
  151.     if (req == PRU_CONTROL)
  152.         return (in_control(so, (int)m, (caddr_t)nam,
  153.             (struct ifnet *)control));
  154.     if (control && control->m_len) {
  155.         m_freem(control);
  156.         if (m)
  157.             m_freem(m);
  158.         return (EINVAL);
  159.     }
  160.  
  161.     s = splnet();
  162.     inp = sotoinpcb(so);
  163.     /*
  164.      * When a TCP is attached to a socket, then there will be
  165.      * a (struct inpcb) pointed at by the socket, and this
  166.      * structure will point at a subsidary (struct tcpcb).
  167.      */
  168.     if (inp == 0 && req != PRU_ATTACH) {
  169.         splx(s);
  170.         return (EINVAL);        /* XXX */
  171.     }
  172.     if (inp) {
  173.         tp = intotcpcb(inp);
  174.         /* WHAT IF TP IS 0? */
  175. #ifdef KPROF
  176.         tcp_acounts[tp->t_state][req]++;
  177. #endif
  178.         ostate = tp->t_state;
  179.     } else
  180.         ostate = 0;
  181.     switch (req) {
  182.  
  183.     /*
  184.      * TCP attaches to socket via PRU_ATTACH, reserving space,
  185.      * and an internet control block.
  186.      */
  187.     case PRU_ATTACH:
  188.         if (inp) {
  189.             error = EISCONN;
  190.             break;
  191.         }
  192.         error = tcp_attach(so);
  193.         if (error)
  194.             break;
  195.         if ((so->so_options & SO_LINGER) && so->so_linger.tv_sec == 0)
  196.             so->so_linger.tv_sec = TCP_LINGERTIME;
  197.         tp = sototcpcb(so);
  198.         break;
  199.  
  200.     /*
  201.      * PRU_DETACH detaches the TCP protocol from the socket.
  202.      * If the protocol state is non-embryonic, then can't
  203.      * do this directly: have to initiate a PRU_DISCONNECT,
  204.      * which may finish later; embryonic TCB's can just
  205.      * be discarded here.
  206.      */
  207.     case PRU_DETACH:
  208.         if (tp->t_state > TCPS_LISTEN)
  209.             tp = tcp_disconnect(tp);
  210.         else
  211.             tp = tcp_close(tp);
  212.         break;
  213.  
  214.     /*
  215.      * Give the socket an address.
  216.      */
  217.     case PRU_BIND:
  218.         error = in_pcbbind(inp, nam);
  219.         if (error)
  220.             break;
  221.         break;
  222.  
  223.     /*
  224.      * Prepare to accept connections.
  225.      */
  226.     case PRU_LISTEN:
  227.         if (inp->inp_lport == 0)
  228.             error = in_pcbbind(inp, (struct mbuf *)0);
  229.         if (error == 0)
  230.             tp->t_state = TCPS_LISTEN;
  231.         break;
  232.  
  233.     /*
  234.      * Initiate connection to peer.
  235.      * Create a template for use in transmissions on this connection.
  236.      * Enter SYN_SENT state, and mark socket as connecting.
  237.      * Start keep-alive timer, and seed output sequence space.
  238.      * Send initial segment on connection.
  239.      */
  240.     case PRU_CONNECT:
  241.         if (inp->inp_lport == 0) {
  242.             error = in_pcbbind(inp, (struct mbuf *)0);
  243.             if (error)
  244.                 break;
  245.         }
  246.         error = in_pcbconnect(inp, nam);
  247.         if (error)
  248.             break;
  249.         tp->t_template = tcp_template(tp);
  250.         if (tp->t_template == 0) {
  251.             in_pcbdisconnect(inp);
  252.             error = ENOBUFS;
  253.             break;
  254.         }
  255.         soisconnecting(so);
  256.         tcpstat.tcps_connattempt++;
  257.         tp->t_state = TCPS_SYN_SENT;
  258.         tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
  259.         tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
  260.         tcp_sendseqinit(tp);
  261.         error = tcp_output(tp);
  262.         break;
  263.  
  264.     /*
  265.      * Create a TCP connection between two sockets.
  266.      */
  267.     case PRU_CONNECT2:
  268.         error = EOPNOTSUPP;
  269.         break;
  270.  
  271.     /*
  272.      * Initiate disconnect from peer.
  273.      * If connection never passed embryonic stage, just drop;
  274.      * else if don't need to let data drain, then can just drop anyways,
  275.      * else have to begin TCP shutdown process: mark socket disconnecting,
  276.      * drain unread data, state