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_subr.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  13KB  |  469 lines

  1. RCS_ID_C="$Id: tcp_subr.c,v 1.7 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_subr.c,v $
  9.  * Revision 1.7  1993/06/04  11:16:15  jraja
  10.  * Fixes for first public release.
  11.  *
  12.  * Revision 1.6  1993/05/17  00:16:44  ppessi
  13.  * Changed RCS version. Added rcsid.
  14.  *
  15.  * Revision 1.5  1993/04/05  19:06:36  jraja
  16.  * Changed storage of the spl functions  return values to type spl_t.
  17.  * Added include for conf.h to every .c file.
  18.  *
  19.  * Revision 1.4  93/03/05  21:09:42  21:09:42  jraja (Jarno Tapio Rajahalme)
  20.  * Fixed includes (again).
  21.  * 
  22.  * Revision 1.3  93/03/05  03:20:20  03:20:20  ppessi (Pekka Pessi)
  23.  * Compiles with SASC. Initial test version.
  24.  * 
  25.  * Revision 1.2  93/02/26  09:53:23  09:53:23  jraja (Jarno Tapio Rajahalme)
  26.  * Made this compile with ANSI C (added prototypes).
  27.  * Added second argument to tcp_quench to be able to use it as notify function
  28.  * with in_pcbnotify().
  29.  * 
  30.  * Revision 1.1  92/11/17  16:30:49  16:30:49  jraja (Jarno Tapio Rajahalme)
  31.  * Initial revision
  32.  *
  33.  */
  34.  
  35. /*
  36.  * Copyright (c) 1982, 1986, 1988, 1990 Regents of the University of California.
  37.  * All rights reserved.
  38.  *
  39.  * Redistribution and use in source and binary forms, with or without
  40.  * modification, are permitted provided that the following conditions
  41.  * are met:
  42.  * 1. Redistributions of source code must retain the above copyright
  43.  *    notice, this list of conditions and the following disclaimer.
  44.  * 2. Redistributions in binary form must reproduce the above copyright
  45.  *    notice, this list of conditions and the following disclaimer in the
  46.  *    documentation and/or other materials provided with the distribution.
  47.  * 3. All advertising materials mentioning features or use of this software
  48.  *    must display the following acknowledgement:
  49.  *    This product includes software developed by the University of
  50.  *    California, Berkeley and its contributors.
  51.  * 4. Neither the name of the University nor the names of its contributors
  52.  *    may be used to endorse or promote products derived from this software
  53.  *    without specific prior written permission.
  54.  *
  55.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  56.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  57.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  58.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  59.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  60.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  61.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  62.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  63.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  64.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  65.  * SUCH DAMAGE.
  66.  *
  67.  *    @(#)tcp_subr.c    7.20 (Berkeley) 12/1/90
  68.  */
  69.  
  70. #include <conf.h>
  71.  
  72. #include <sys/param.h>
  73. #include <sys/systm.h>
  74. #include <sys/malloc.h>
  75. #include <sys/mbuf.h>
  76. #include <sys/socket.h>
  77. #include <sys/socketvar.h>
  78. #include <sys/protosw.h>
  79. #include <sys/errno.h>
  80.  
  81. #include <net/route.h>
  82. #include <net/if.h>
  83.  
  84. #include <netinet/in.h>
  85. #include <netinet/in_systm.h>
  86. #include <netinet/ip.h>
  87. #include <netinet/in_pcb.h>
  88. #include <netinet/ip_var.h>
  89. #include <netinet/ip_icmp.h>
  90. #include <netinet/tcp.h>
  91. #include <netinet/tcp_fsm.h>
  92. #include <netinet/tcp_seq.h>
  93. #include <netinet/tcp_timer.h>
  94. #include <netinet/tcp_var.h>
  95. #include <netinet/tcpip.h>
  96.  
  97. #include <netinet/tcp_subr_protos.h>
  98. #include <netinet/tcp_output_protos.h>
  99. #include <netinet/ip_output_protos.h>
  100. #include <netinet/in_cksum_protos.h>
  101. #include <netinet/in_pcb_protos.h>
  102. #include <kern/uipc_socket2_protos.h>
  103. #include <kern/kern_synch_protos.h>
  104.  
  105. /* patchable/settable parameters for tcp */
  106. int    tcp_ttl = TCP_TTL;
  107. int     tcp_mssdflt = TCP_MSS;
  108. int     tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
  109.  
  110. extern    struct inpcb *tcp_last_inpcb;
  111.  
  112. /*
  113.  * Tcp initialization
  114.  */
  115. void
  116. tcp_init()
  117. {
  118.  
  119.     tcp_iss = 1;        /* wrong */
  120.     tcb.inp_next = tcb.inp_prev = &tcb;
  121.     if (max_protohdr < sizeof(struct tcpiphdr))
  122.         max_protohdr = sizeof(struct tcpiphdr);
  123.     if (max_linkhdr + sizeof(struct tcpiphdr) > MHLEN)
  124.         panic("tcp_init");
  125. }
  126.  
  127. /*
  128.  * Create template to be used to send tcp packets on a connection.
  129.  * Call after host entry created, allocates an mbuf and fills
  130.  * in a skeletal tcp/ip header, minimizing the amount of work
  131.  * necessary when the connection is used.
  132.  */
  133. struct tcpiphdr *
  134. tcp_template(tp)
  135.     struct tcpcb *tp;
  136. {
  137.     register struct inpcb *inp = tp->t_inpcb;
  138.     register struct mbuf *m;
  139.     register struct tcpiphdr *n;
  140.  
  141.     if ((n = tp->t_template) == 0) {
  142.         m = m_get(M_DONTWAIT, MT_HEADER);
  143.         if (m == NULL)
  144.             return (0);
  145.         m->m_len = sizeof (struct tcpiphdr);
  146.         n = mtod(m, struct tcpiphdr *);
  147.     }
  148.     n->ti_next = n->ti_prev = 0;
  149.     n->ti_x1 = 0;
  150.     n->ti_pr = IPPROTO_TCP;
  151.     n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
  152.     n->ti_src = inp->inp_laddr;
  153.     n->ti_dst = inp->inp_faddr;
  154.     n->ti_sport = inp->inp_lport;
  155.     n->ti_dport = inp->inp_fport;
  156.     n->ti_seq = 0;
  157.     n->ti_ack = 0;
  158.     n->ti_x2 = 0;
  159.     n->ti_off = 5;
  160.     n->ti_flags = 0;
  161.     n->ti_win = 0;
  162.     n->ti_sum = 0;
  163.     n->ti_urp = 0;
  164.     return (n);
  165. }
  166.  
  167. /*
  168.  * Send a single message to the TCP at address specified by
  169.  * the given TCP/IP header.  If m == 0, then we make a copy
  170.  * of the tcpiphdr at ti and send directly to the addressed host.
  171.  * This is used to force keep alive messages out using the TCP
  172.  * template for a connection tp->t_template.  If flags are given
  173.  * then we send a message back to the TCP which originated the
  174.  * segment ti, and discard the mbuf containing it and any other
  175.  * attached mbufs.
  176.  *
  177.  * In any case the ack and sequence number of the transmitted
  178.  * segment are as specified by the parameters.
  179.  */
  180. void
  181. tcp_respond(tp, ti, m, ack, seq, flags)
  182.     struct tcpcb *tp;
  183.     register struct tcpiphdr *ti;
  184.     register struct mbuf *m;
  185.     tcp_seq ack, seq;
  186.     int flags;
  187. {
  188.     register int tlen;
  189.     int win = 0;
  190.     struct route *ro = 0;
  191.  
  192.     if (tp) {
  193.         win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);
  194.         ro = &tp->t_inpcb->inp_route;
  195.     }
  196.     if (m == 0) {
  197.         m = m_gethdr(M_DONTWAIT, MT_HEADER);
  198.         if (m == NULL)
  199.             return;
  200. #if TCP_COMPAT_42
  201.         tlen = 1;
  202. #else
  203.         tlen = 0;
  204. #endif
  205.         m->m_data += max_linkhdr;
  206.         *mtod(m, struct tcpiphdr *) = *ti;
  207.         ti = mtod(m, struct tcpiphdr *);
  208.         flags = TH_ACK;
  209.     } else {
  210.         m_freem(m->m_next);
  211.         m->m_next = 0;
  212.         m->m_data = (caddr_t)ti;
  213.         m->m_len = sizeof (struct tcpiphdr);
  214.         tlen = 0;
  215. #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
  216.         xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_long);
  217.         xchg(ti->ti_dport, ti->ti_sport, u_short);
  218. #undef xchg
  219.     }
  220.     ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
  221.     tlen += sizeof (struct tcpiphdr);
  222.     m->m_len = tlen;
  223.     m->m_pkthdr.len = tlen;
  224.     m->m_pkthdr.rcvif = (struct ifnet *) 0;
  225.     ti->ti_next = ti->ti_prev = 0;
  226.     ti->ti_x1 = 0;
  227.     ti->ti_seq = htonl(seq);
  228.     ti->ti_ack = htonl(ack);
  229.     ti->ti_x2 = 0;
  230.     ti->ti_off = sizeof (struct tcphdr) >> 2;
  231.     ti->ti_flags = flags;
  232.     ti->ti_win = htons((u_short)win);
  233.     ti->ti_urp = 0;
  234.     ti->ti_sum = in_cksum(m, tlen);
  235.     ((struct ip *)ti)->ip_len = tlen;
  236.     ((struct ip *)ti)->ip_ttl = tcp_ttl;
  237.     (void) ip_output(m, (struct mbuf *)0, ro, 0);
  238. }
  239.  
  240. /*
  241.  * Create a new TCP control block, making an
  242.  * empty reassembly queue and hooking it to the argument
  243.  * protocol control block.
  244.  */
  245. struct tcpcb *
  246. tcp_newtcpcb(inp)
  247.     struct inpcb *inp;
  248. {
  249.     struct mbuf *m = m_getclr(M_DONTWAIT, MT_PCB);
  250.     register struct tcpcb *tp;
  251.  
  252.     if (m == NULL)
  253.         return ((struct tcpcb *)0);
  254.     tp = mtod(m, struct tcpcb *);
  255.     tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp;
  256.     tp->t_maxseg = tcp_mssdflt;
  257.  
  258.     tp->t_flags = 0;        /* sends options! */
  259.     tp->t_inpcb = inp;
  260.     /*
  261.      * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
  262.      * rtt estimate.  Set rttvar so that srtt + 2 * rttvar gives
  263.      * reasonable initial retransmit time.
  264.      */
  265.     tp->t_srtt = TCPTV_SRTTBASE;
  266.     tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
  267.     tp->t_rttmin = TCPTV_MIN;
  268.     TCPT_RANGESET(tp->t_rxtcur, 
  269.         ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTT