The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/tcp_usrreq.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: tcp_usrreq.c,v 1.87.2.1 2004/05/28 07:23:55 tron Exp $ */
    2 
    3 /*
    4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the project nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*-
   33  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
   34  * All rights reserved.
   35  *
   36  * This code is derived from software contributed to The NetBSD Foundation
   37  * by Jason R. Thorpe and Kevin M. Lahey of the Numerical Aerospace Simulation
   38  * Facility, NASA Ames Research Center.
   39  *
   40  * Redistribution and use in source and binary forms, with or without
   41  * modification, are permitted provided that the following conditions
   42  * are met:
   43  * 1. Redistributions of source code must retain the above copyright
   44  *    notice, this list of conditions and the following disclaimer.
   45  * 2. Redistributions in binary form must reproduce the above copyright
   46  *    notice, this list of conditions and the following disclaimer in the
   47  *    documentation and/or other materials provided with the distribution.
   48  * 3. All advertising materials mentioning features or use of this software
   49  *    must display the following acknowledgement:
   50  *      This product includes software developed by the NetBSD
   51  *      Foundation, Inc. and its contributors.
   52  * 4. Neither the name of The NetBSD Foundation nor the names of its
   53  *    contributors may be used to endorse or promote products derived
   54  *    from this software without specific prior written permission.
   55  *
   56  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   57  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   58  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   59  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   60  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   61  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   62  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   63  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   64  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   65  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   66  * POSSIBILITY OF SUCH DAMAGE.
   67  */
   68 
   69 /*
   70  * Copyright (c) 1982, 1986, 1988, 1993, 1995
   71  *      The Regents of the University of California.  All rights reserved.
   72  *
   73  * Redistribution and use in source and binary forms, with or without
   74  * modification, are permitted provided that the following conditions
   75  * are met:
   76  * 1. Redistributions of source code must retain the above copyright
   77  *    notice, this list of conditions and the following disclaimer.
   78  * 2. Redistributions in binary form must reproduce the above copyright
   79  *    notice, this list of conditions and the following disclaimer in the
   80  *    documentation and/or other materials provided with the distribution.
   81  * 3. Neither the name of the University nor the names of its contributors
   82  *    may be used to endorse or promote products derived from this software
   83  *    without specific prior written permission.
   84  *
   85  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   86  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   88  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   89  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   90  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   91  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   92  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   93  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   94  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   95  * SUCH DAMAGE.
   96  *
   97  *      @(#)tcp_usrreq.c        8.5 (Berkeley) 6/21/95
   98  */
   99 
  100 #include <sys/cdefs.h>
  101 __KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.87.2.1 2004/05/28 07:23:55 tron Exp $");
  102 
  103 #include "opt_inet.h"
  104 #include "opt_ipsec.h"
  105 #include "opt_tcp_debug.h"
  106 #include "opt_mbuftrace.h"
  107 
  108 #include <sys/param.h>
  109 #include <sys/systm.h>
  110 #include <sys/kernel.h>
  111 #include <sys/malloc.h>
  112 #include <sys/mbuf.h>
  113 #include <sys/socket.h>
  114 #include <sys/socketvar.h>
  115 #include <sys/protosw.h>
  116 #include <sys/errno.h>
  117 #include <sys/stat.h>
  118 #include <sys/proc.h>
  119 #include <sys/domain.h>
  120 #include <sys/sysctl.h>
  121 
  122 #include <net/if.h>
  123 #include <net/route.h>
  124 
  125 #include <netinet/in.h>
  126 #include <netinet/in_systm.h>
  127 #include <netinet/in_var.h>
  128 #include <netinet/ip.h>
  129 #include <netinet/in_pcb.h>
  130 #include <netinet/ip_var.h>
  131 
  132 #ifdef INET6
  133 #ifndef INET
  134 #include <netinet/in.h>
  135 #endif
  136 #include <netinet/ip6.h>
  137 #include <netinet6/in6_pcb.h>
  138 #include <netinet6/ip6_var.h>
  139 #endif
  140 
  141 #include <netinet/tcp.h>
  142 #include <netinet/tcp_fsm.h>
  143 #include <netinet/tcp_seq.h>
  144 #include <netinet/tcp_timer.h>
  145 #include <netinet/tcp_var.h>
  146 #include <netinet/tcpip.h>
  147 #include <netinet/tcp_debug.h>
  148 
  149 #include "opt_tcp_space.h"
  150 
  151 #ifdef IPSEC
  152 #include <netinet6/ipsec.h>
  153 #endif /*IPSEC*/
  154 
  155 /*
  156  * TCP protocol interface to socket abstraction.
  157  */
  158 extern  char *tcpstates[];
  159 
  160 /*
  161  * Process a TCP user request for TCP tb.  If this is a send request
  162  * then m is the mbuf chain of send data.  If this is a timer expiration
  163  * (called from the software clock routine), then timertype tells which timer.
  164  */
  165 /*ARGSUSED*/
  166 int
  167 tcp_usrreq(so, req, m, nam, control, p)
  168         struct socket *so;
  169         int req;
  170         struct mbuf *m, *nam, *control;
  171         struct proc *p;
  172 {
  173         struct inpcb *inp;
  174 #ifdef INET6
  175         struct in6pcb *in6p;
  176 #endif
  177         struct tcpcb *tp = NULL;
  178         int s;
  179         int error = 0;
  180 #ifdef TCP_DEBUG
  181         int ostate = 0;
  182 #endif
  183         int family;     /* family of the socket */
  184 
  185         family = so->so_proto->pr_domain->dom_family;
  186 
  187         if (req == PRU_CONTROL) {
  188                 switch (family) {
  189 #ifdef INET
  190                 case PF_INET:
  191                         return (in_control(so, (long)m, (caddr_t)nam,
  192                             (struct ifnet *)control, p));
  193 #endif
  194 #ifdef INET6
  195                 case PF_INET6:
  196                         return (in6_control(so, (long)m, (caddr_t)nam,
  197                             (struct ifnet *)control, p));
  198 #endif
  199                 default:
  200                         return EAFNOSUPPORT;
  201                 }
  202         }
  203 
  204         if (req == PRU_PURGEIF) {
  205                 switch (family) {
  206 #ifdef INET
  207                 case PF_INET:
  208                         in_pcbpurgeif0(&tcbtable, (struct ifnet *)control);
  209                         in_purgeif((struct ifnet *)control);
  210                         in_pcbpurgeif(&tcbtable, (struct ifnet *)control);
  211                         break;
  212 #endif
  213 #ifdef INET6
  214                 case PF_INET6:
  215                         in6_pcbpurgeif0(&tcbtable, (struct ifnet *)control);
  216                         in6_purgeif((struct ifnet *)control);
  217                         in6_pcbpurgeif(&tcbtable, (struct ifnet *)control);
  218                         break;
  219 #endif
  220                 default:
  221                         return (EAFNOSUPPORT);
  222                 }
  223                 return (0);
  224         }
  225 
  226         s = splsoftnet();
  227         switch (family) {
  228 #ifdef INET
  229         case PF_INET:
  230                 inp = sotoinpcb(so);
  231 #ifdef INET6
  232                 in6p = NULL;
  233 #endif
  234                 break;
  235 #endif
  236 #ifdef INET6
  237         case PF_INET6:
  238                 inp = NULL;
  239                 in6p = sotoin6pcb(so);
  240                 break;
  241 #endif
  242         default:
  243                 splx(s);
  244                 return EAFNOSUPPORT;
  245         }
  246 
  247 #ifdef DIAGNOSTIC
  248 #ifdef INET6
  249         if (inp && in6p)
  250                 panic("tcp_usrreq: both inp and in6p set to non-NULL");
  251 #endif
  252         if (req != PRU_SEND && req != PRU_SENDOOB && control)
  253                 panic("tcp_usrreq: unexpected control mbuf");
  254 #endif
  255         /*
  256          * When a TCP is attached to a socket, then there will be
  257          * a (struct inpcb) pointed at by the socket, and this
  258          * structure will point at a subsidary (struct tcpcb).
  259          */
  260 #ifndef INET6
  261         if (inp == 0 && req != PRU_ATTACH)
  262 #else
  263         if ((inp == 0 && in6p == 0) && req != PRU_ATTACH)
  264 #endif
  265         {
  266                 error = EINVAL;
  267                 goto release;
  268         }
  269 #ifdef INET
  270         if (inp) {
  271                 tp = intotcpcb(inp);
  272                 /* WHAT IF TP IS 0? */
  273 #ifdef KPROF
  274                 tcp_acounts[tp->t_state][req]++;
  275 #endif
  276 #ifdef TCP_DEBUG
  277                 ostate = tp->t_state;
  278 #endif
  279         }
  280 #endif
  281 #ifdef INET6
  282         if (in6p) {
  283                 tp = in6totcpcb(in6p);
  284                 /* WHAT IF TP IS 0? */
  285 #ifdef KPROF
  286                 tcp_acounts[tp->t_state][req]++;
  287 #endif
  288 #ifdef TCP_DEBUG
  289                 ostate = tp->t_state;
  290 #endif
  291         }
  292 #endif
  293 
  294         switch (req) {
  295 
  296         /*
  297          * TCP attaches to socket via PRU_ATTACH, reserving space,
  298          * and an internet control block.
  299          */
  300         case PRU_ATTACH:
  301 #ifndef INET6
  302                 if (inp != 0)
  303 #else
  304                 if (inp != 0 || in6p != 0)
  305 #endif
  306                 {
  307                         error = EISCONN;
  308                         break;
  309                 }
  310                 error = tcp_attach(so);
  311                 if (error)
  312                         break;
  313                 if ((so->so_options & SO_LINGER) && so->so_linger == 0)
  314                         so->so_linger = TCP_LINGERTIME;
  315                 tp = sototcpcb(so);
  316                 break;
  317 
  318         /*
  319          * PRU_DETACH detaches the TCP protocol from the socket.
  320          */
  321         case PRU_DETACH:
  322                 tp = tcp_disconnect(tp);
  323                 break;
  324 
  325         /*
  326          * Give the socket an address.
  327          */
  328         case PRU_BIND:
  329                 switch (family) {
  330 #ifdef INET
  331                 case PF_INET:
  332                         error = in_pcbbind(inp, nam, p);
  333                         break;
  334 #endif
  335 #ifdef INET6
  336                 case PF_INET6:
  337                         error = in6_pcbbind(in6p, nam, p);
  338                         if (!error) {
  339                                 /* mapped addr case */
  340                                 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr))
  341                                         tp->t_family = AF_INET;
  342                                 else
  343                                         tp->t_family = AF_INET6;
  344                         }
  345                         break;
  346 #endif
  347                 }
  348                 break;
  349 
  350         /*
  351          * Prepare to accept connections.
  352          */
  353         case PRU_LISTEN:
  354 #ifdef INET
  355                 if (inp && inp->inp_lport == 0) {
  356                         error = in_pcbbind(inp, (struct mbuf *)0,
  357                             (struct proc *)0);
  358                         if (error)
  359                                 break;
  360                 }
  361 #endif
  362 #ifdef INET6
  363                 if (in6p && in6p->in6p_lport == 0) {
  364                         error = in6_pcbbind(in6p, (struct mbuf *)0,
  365                             (struct proc *)0);
  366                         if (error)
  367                                 break;
  368                 }
  369 #endif
  370                 tp->t_state = TCPS_LISTEN;
  371                 break;
  372 
  373         /*
  374          * Initiate connection to peer.
  375          * Create a template for use in transmissions on this connection.
  376          * Enter SYN_SENT state, and mark socket as connecting.
  377          * Start keep-alive timer, and seed output sequence space.
  378          * Send initial segment on connection.
  379          */
  380         case PRU_CONNECT:
  381 #ifdef INET
  382                 if (inp) {
  383                         if (inp->inp_lport == 0) {
  384                                 error = in_pcbbind(inp, (struct mbuf *)0,
  385                                     (struct proc *)0);
  386                                 if (error)
  387                                         break;
  388                         }
  389                         error = in_pcbconnect(inp, nam);
  390                 }
  391 #endif
  392 #ifdef INET6
  393                 if (in6p) {
  394                         if (in6p->in6p_lport == 0) {
  395                                 error = in6_pcbbind(in6p, (struct mbuf *)0,
  396                                     (struct proc *)0);
  397                                 if (error)
  398                                         break;
  399                         }
  400                         error = in6_pcbconnect(in6p, nam);
  401                         if (!error) {
  402                                 /* mapped addr case */
  403                                 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr))
  404                                         tp->t_family = AF_INET;
  405                                 else
  406                                         tp->t_family = AF_INET6;
  407                         }
  408                 }
  409 #endif
  410                 if (error)
  411                         break;
  412                 tp->t_template = tcp_template(tp);
  413                 if (tp->t_template == 0) {
  414 #ifdef INET
  415                         if (inp)
  416                                 in_pcbdisconnect(inp);
  417 #endif
  418 #ifdef INET6
  419                         if (in6p)
  420                                 in6_pcbdisconnect(in6p);
  421 #endif
  422                         error = ENOBUFS;
  423                         break;
  424                 }
  425                 /* Compute window scaling to request.  */
  426                 while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
  427                     (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
  428                         tp->request_r_scale++;
  429                 soisconnecting(so);
  430                 tcpstat.tcps_connattempt++;
  431                 tp->t_state = TCPS_SYN_SENT;
  432                 TCP_TIMER_ARM(tp, TCPT_KEEP, TCPTV_KEEP_INIT);
  433                 tp->iss = tcp_new_iss(tp, 0);
  434                 tcp_sendseqinit(tp);
  435                 error = tcp_output(tp);
  436                 break;
  437 
  438         /*
  439          * Create a TCP connection between two sockets.
  440          */
  441         case PRU_CONNECT2:
  442                 error = EOPNOTSUPP;
  443                 break;
  444 
  445         /*
  446          * Initiate disconnect from peer.
  447          * If connection never passed embryonic stage, just drop;
  448          * else if don't need to let data drain, then can just drop anyways,
  449          * else have to begin TCP shutdown process: mark socket disconnecting,
  450          * drain unread data, state switch to reflect user close, and
  451          * send segment (e.g. FIN) to peer.  Socket will be really disconnected
  452          * when peer sends FIN and acks ours.
  453          *
  454          * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
  455          */
  456         case PRU_DISCONNECT:
  457                 tp = tcp_disconnect(tp);
  458                 break;
  459 
  460         /*
  461          * Accept a connection.  Essentially all the work is
  462          * done at higher levels; just return the address
  463          * of the peer, storing through addr.
  464          */
  465         case PRU_ACCEPT:
  466 #ifdef INET
  467                 if (inp)
  468                         in_setpeeraddr(inp, nam);
  469 #endif
  470 #ifdef INET6
  471                 if (in6p)
  472                         in6_setpeeraddr(in6p, nam);
  473 #endif
  474                 break;
  475 
  476         /*
  477          * Mark the connection as being incapable of further output.
  478          */
  479         case PRU_SHUTDOWN:
  480                 socantsendmore(so);
  481                 tp = tcp_usrclosed(tp);
  482                 if (tp)
  483                         error = tcp_output(tp);
  484                 break;
  485 
  486         /*
  487          * After a receive, possibly send window update to peer.
  488          */
  489         case PRU_RCVD:
  490                 /*
  491                  * soreceive() calls this function when a user receives
  492                  * ancillary data on a listening socket. We don't call
  493                  * tcp_output in such a case, since there is no header
  494                  * template for a listening socket and hence the kernel
  495                  * will panic.
  496                  */
  497                 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) != 0)
  498                         (void) tcp_output(tp);
  499                 break;
  500 
  501         /*
  502          * Do a send by putting data in output queue and updating urgent
  503          * marker if URG set.  Possibly send more data.
  504          */
  505         case PRU_SEND:
  506                 if (control && control->m_len) {
  507                         m_freem(control);
  508                         m_freem(m);
  509                         error = EINVAL;
  510                         break;
  511                 }
  512                 sbappendstream(&so->so_snd, m);
  513                 error = tcp_output(tp);
  514                 break;
  515 
  516         /*
  517          * Abort the TCP.
  518          */
  519         case PRU_ABORT:
  520                 tp = tcp_drop(tp, ECONNABORTED);
  521                 break;
  522 
  523         case PRU_SENSE:
  524                 /*
  525                  * stat: don't bother with a blocksize.
  526                  */
  527                 splx(s);
  528                 return (0);
  529 
  530         case PRU_RCVOOB:
  531                 if (control && control->m_len) {
  532                         m_freem(control);
  533                         m_freem(m);
  534                         error = EINVAL;
  535                         break;
  536                 }
  537                 if ((so->so_oobmark == 0 &&
  538                     (so->so_state & SS_RCVATMARK) == 0) ||
  539                     so->so_options & SO_OOBINLINE ||
  540                     tp->t_oobflags & TCPOOB_HADDATA) {
  541                         error = EINVAL;
  542                         break;
  543                 }
  544                 if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
  545                         error = EWOULDBLOCK;
  546                         break;
  547                 }
  548                 m->m_len = 1;
  549                 *mtod(m, caddr_t) = tp->t_iobc;
  550                 if (((long)nam & MSG_PEEK) == 0)
  551                         tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
  552                 break;
  553 
  554         case PRU_SENDOOB:
  555                 if (sbspace(&so->so_snd) < -512) {
  556                         m_freem(m);
  557                         error = ENOBUFS;
  558                         break;
  559                 }
  560                 /*
  561                  * According to RFC961 (Assigned Protocols),
  562                  * the urgent pointer points to the last octet
  563                  * of urgent data.  We continue, however,
  564                  * to consider it to indicate the first octet
  565                  * of data past the urgent section.
  566                  * Otherwise, snd_up should be one lower.
  567                  */
  568                 sbappendstream(&so->so_snd, m);
  569                 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
  570                 tp->t_force = 1;
  571                 error = tcp_output(tp);
  572                 tp->t_force = 0;
  573                 break;
  574 
  575         case PRU_SOCKADDR:
  576 #ifdef INET
  577                 if (inp)
  578                         in_setsockaddr(inp, nam);
  579 #endif
  580 #ifdef INET6
  581                 if (in6p)
  582                         in6_setsockaddr(in6p, nam);
  583 #endif
  584                 break;
  585 
  586         case PRU_PEERADDR:
  587 #ifdef INET
  588                 if (inp)
  589                         in_setpeeraddr(inp, nam);
  590 #endif
  591 #ifdef INET6
  592                 if (in6p)
  593                         in6_setpeeraddr(in6p, nam);
  594 #endif
  595                 break;
  596 
  597         default:
  598                 panic("tcp_usrreq");
  599         }
  600 #ifdef TCP_DEBUG
  601         if (tp && (so->so_options & SO_DEBUG))
  602                 tcp_trace(TA_USER, ostate, tp, NULL, req);
  603 #endif
  604 
  605 release:
  606         splx(s);
  607         return (error);
  608 }
  609 
  610 int
  611 tcp_ctloutput(op, so, level, optname, mp)
  612         int op;
  613         struct socket *so;
  614         int level, optname;
  615         struct mbuf **mp;
  616 {
  617         int error = 0, s;
  618         struct inpcb *inp;
  619 #ifdef INET6
  620         struct in6pcb *in6p;
  621 #endif
  622         struct tcpcb *tp;
  623         struct mbuf *m;
  624         int i;
  625         int family;     /* family of the socket */
  626 
  627         family = so->so_proto->pr_domain->dom_family;
  628 
  629         s = splsoftnet();
  630         switch (family) {
  631 #ifdef INET
  632         case PF_INET:
  633                 inp = sotoinpcb(so);
  634 #ifdef INET6
  635                 in6p = NULL;
  636 #endif
  637                 break;
  638 #endif
  639 #ifdef INET6
  640         case PF_INET6:
  641                 inp = NULL;
  642                 in6p = sotoin6pcb(so);
  643                 break;
  644 #endif
  645         default:
  646                 splx(s);
  647                 return EAFNOSUPPORT;
  648         }
  649 #ifndef INET6
  650         if (inp == NULL)
  651 #else
  652         if (inp == NULL && in6p == NULL)
  653 #endif
  654         {
  655                 splx(s);
  656                 if (op == PRCO_SETOPT && *mp)
  657                         (void) m_free(*mp);
  658                 return (ECONNRESET);
  659         }
  660         if (level != IPPROTO_TCP) {
  661                 switch (family) {
  662 #ifdef INET
  663                 case PF_INET:
  664                         error = ip_ctloutput(op, so, level, optname, mp);
  665                         break;
  666 #endif
  667 #ifdef INET6
  668                 case PF_INET6:
  669                         error = ip6_ctloutput(op, so, level, optname, mp);
  670                         break;
  671 #endif
  672                 }
  673                 splx(s);
  674                 return (error);
  675         }
  676         if (inp)
  677                 tp = intotcpcb(inp);
  678 #ifdef INET6
  679         else if (in6p)
  680                 tp = in6totcpcb(in6p);
  681 #endif
  682         else
  683                 tp = NULL;
  684 
  685         switch (op) {
  686 
  687         case PRCO_SETOPT:
  688                 m = *mp;
  689                 switch (optname) {
  690 
  691                 case TCP_NODELAY:
  692                         if (m == NULL || m->m_len < sizeof (int))
  693                                 error = EINVAL;
  694                         else if (*mtod(m, int *))
  695                                 tp->t_flags |= TF_NODELAY;
  696                         else
  697                                 tp->t_flags &= ~TF_NODELAY;
  698                         break;
  699 
  700                 case TCP_MAXSEG:
  701                         if (m && (i = *mtod(m, int *)) > 0 &&
  702                             i <= tp->t_peermss)
  703                                 tp->t_peermss = i;  /* limit on send size */
  704                         else
  705                                 error = EINVAL;
  706                         break;
  707 
  708                 default:
  709                         error = ENOPROTOOPT;
  710                         break;
  711                 }
  712                 if (m)
  713                         (void) m_free(m);
  714                 break;
  715 
  716         case PRCO_GETOPT:
  717                 *mp = m = m_get(M_WAIT, MT_SOOPTS);
  718                 m->m_len = sizeof(int);
  719                 MCLAIM(m, so->so_mowner);
  720 
  721                 switch (optname) {
  722                 case TCP_NODELAY:
  723                         *mtod(m, int *) = tp->t_flags & TF_NODELAY;
  724                         break;
  725                 case TCP_MAXSEG:
  726                         *mtod(m, int *) = tp->t_peermss;
  727                         break;
  728                 default:
  729                         error = ENOPROTOOPT;
  730                         break;
  731                 }
  732                 break;
  733         }
  734         splx(s);
  735         return (error);
  736 }
  737 
  738 #ifndef TCP_SENDSPACE
  739 #define TCP_SENDSPACE   1024*32
  740 #endif
  741 int     tcp_sendspace = TCP_SENDSPACE;
  742 #ifndef TCP_RECVSPACE
  743 #define TCP_RECVSPACE   1024*32
  744 #endif
  745 int     tcp_recvspace = TCP_RECVSPACE;
  746 
  747 /*
  748  * Attach TCP protocol to socket, allocating
  749  * internet protocol control block, tcp control block,
  750  * bufer space, and entering LISTEN state if to accept connections.
  751  */
  752 int
  753 tcp_attach(so)
  754         struct socket *so;
  755 {
  756         struct tcpcb *tp;
  757         struct inpcb *inp;
  758 #ifdef INET6
  759         struct in6pcb *in6p;
  760 #endif
  761         int error;
  762         int family;     /* family of the socket */
  763 
  764         family = so->so_proto->pr_domain->dom_family;
  765 
  766 #ifdef MBUFTRACE
  767         so->so_mowner = &tcp_mowner;
  768         so->so_rcv.sb_mowner = &tcp_rx_mowner;
  769         so->so_snd.sb_mowner = &tcp_tx_mowner;
  770 #endif
  771         if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  772                 error = soreserve(so, tcp_sendspace, tcp_recvspace);
  773                 if (error)
  774                         return (error);
  775         }
  776         switch (family) {
  777 #ifdef INET
  778         case PF_INET:
  779                 error = in_pcballoc(so, &tcbtable);
  780                 if (error)
  781                         return (error);
  782                 inp = sotoinpcb(so);
  783 #ifdef INET6
  784                 in6p = NULL;
  785 #endif
  786                 break;
  787 #endif
  788 #ifdef INET6
  789         case PF_INET6:
  790                 error = in6_pcballoc(so, &tcbtable);
  791                 if (error)
  792                         return (error);
  793                 inp = NULL;
  794                 in6p = sotoin6pcb(so);
  795                 break;
  796 #endif
  797         default:
  798                 return EAFNOSUPPORT;
  799         }
  800         if (inp)
  801                 tp = tcp_newtcpcb(family, (void *)inp);
  802 #ifdef INET6
  803         else if (in6p)
  804                 tp = tcp_newtcpcb(family, (void *)in6p);
  805 #endif
  806         else
  807                 tp = NULL;
  808 
  809         if (tp == 0) {
  810                 int nofd = so->so_state & SS_NOFDREF;   /* XXX */
  811 
  812                 so->so_state &= ~SS_NOFDREF;    /* don't free the socket yet */
  813 #ifdef INET
  814                 if (inp)
  815                         in_pcbdetach(inp);
  816 #endif
  817 #ifdef INET6
  818                 if (in6p)
  819                         in6_pcbdetach(in6p);
  820 #endif
  821                 so->so_state |= nofd;
  822                 return (ENOBUFS);
  823         }
  824         tp->t_state = TCPS_CLOSED;
  825         return (0);
  826 }
  827 
  828 /*
  829  * Initiate (or continue) disconnect.
  830  * If embryonic state, just send reset (once).
  831  * If in ``let data drain'' option and linger null, just drop.
  832  * Otherwise (hard), mark socket disconnecting and drop
  833  * current input data; switch states based on user close, and
  834  * send segment to peer (with FIN).
  835  */
  836 struct tcpcb *
  837 tcp_disconnect(tp)
  838         struct tcpcb *tp;
  839 {
  840         struct socket *so;
  841 
  842         if (tp->t_inpcb)
  843                 so = tp->t_inpcb->inp_socket;
  844 #ifdef INET6
  845         else if (tp->t_in6pcb)
  846                 so = tp->t_in6pcb->in6p_socket;
  847 #endif
  848         else
  849                 so = NULL;
  850 
  851         if (TCPS_HAVEESTABLISHED(tp->t_state) == 0)
  852                 tp = tcp_close(tp);
  853         else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
  854                 tp = tcp_drop(tp, 0);
  855         else {
  856                 soisdisconnecting(so);
  857                 sbflush(&so->so_rcv);
  858                 tp = tcp_usrclosed(tp);
  859                 if (tp)
  860                         (void) tcp_output(tp);
  861         }
  862         return (tp);
  863 }
  864 
  865 /*
  866  * User issued close, and wish to trail through shutdown states:
  867  * if never received SYN, just forget it.  If got a SYN from peer,
  868  * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
  869  * If already got a FIN from peer, then almost done; go to LAST_ACK
  870  * state.  In all other cases, have already sent FIN to peer (e.g.
  871  * after PRU_SHUTDOWN), and just have to play tedious game waiting
  872  * for peer to send FIN or not respond to keep-alives, etc.
  873  * We can let the user exit from the close as soon as the FIN is acked.
  874  */
  875 struct tcpcb *
  876 tcp_usrclosed(tp)
  877         struct tcpcb *tp;
  878 {
  879 
  880         switch (tp->t_state) {
  881 
  882         case TCPS_CLOSED:
  883         case TCPS_LISTEN:
  884         case TCPS_SYN_SENT:
  885                 tp->t_state = TCPS_CLOSED;
  886                 tp = tcp_close(tp);
  887                 break;
  888 
  889         case TCPS_SYN_RECEIVED:
  890         case TCPS_ESTABLISHED:
  891                 tp->t_state = TCPS_FIN_WAIT_1;
  892                 break;
  893 
  894         case TCPS_CLOSE_WAIT:
  895                 tp->t_state = TCPS_LAST_ACK;
  896                 break;
  897         }
  898         if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
  899                 struct socket *so;
  900                 if (tp->t_inpcb)
  901                         so = tp->t_inpcb->inp_socket;
  902 #ifdef INET6
  903                 else if (tp->t_in6pcb)
  904                         so = tp->t_in6pcb->in6p_socket;
  905 #endif
  906                 else
  907                         so = NULL;
  908                 soisdisconnected(so);
  909                 /*
  910                  * If we are in FIN_WAIT_2, we arrived here because the
  911                  * application did a shutdown of the send side.  Like the
  912                  * case of a transition from FIN_WAIT_1 to FIN_WAIT_2 after
  913                  * a full close, we start a timer to make sure sockets are
  914                  * not left in FIN_WAIT_2 forever.
  915                  */
  916                 if ((tp->t_state == TCPS_FIN_WAIT_2) && (tcp_maxidle > 0))
  917                         TCP_TIMER_ARM(tp, TCPT_2MSL, tcp_maxidle);
  918         }
  919         return (tp);
  920 }
  921 
  922 /*
  923  * sysctl helper routine for net.inet.ip.mssdflt.  it can't be less
  924  * than 32.
  925  */
  926 static int
  927 sysctl_net_inet_tcp_mssdflt(SYSCTLFN_ARGS)
  928 {
  929         int error, mssdflt;
  930         struct sysctlnode node;
  931 
  932         mssdflt = tcp_mssdflt;
  933         node = *rnode;
  934         node.sysctl_data = &mssdflt;
  935         error = sysctl_lookup(SYSCTLFN_CALL(&node));
  936         if (error || newp == NULL)
  937                 return (error);
  938 
  939         if (mssdflt < 32)
  940                 return (EINVAL);
  941         tcp_mssdflt = mssdflt;
  942 
  943         return (0);
  944 }
  945 
  946 /*
  947  * sysctl helper routine for setting port related values under
  948  * net.inet.ip and net.inet6.ip6.  does basic range checking and does
  949  * additional checks for each type.  this code has placed in
  950  * tcp_input.c since INET and INET6 both use the same tcp code.
  951  *
  952  * this helper is not static so that both inet and inet6 can use it.
  953  */
  954 int
  955 sysctl_net_inet_ip_ports(SYSCTLFN_ARGS)
  956 {
  957         int error, tmp;
  958         int apmin, apmax;
  959 #ifndef IPNOPRIVPORTS
  960         int lpmin, lpmax;
  961 #endif /* IPNOPRIVPORTS */
  962         struct sysctlnode node;
  963 
  964         if (namelen != 0)
  965                 return (EINVAL);
  966 
  967         switch (name[-3]) {
  968 #ifdef INET
  969             case PF_INET:
  970                 apmin = anonportmin;
  971                 apmax = anonportmax;
  972 #ifndef IPNOPRIVPORTS
  973                 lpmin = lowportmin;
  974                 lpmax = lowportmax;
  975 #endif /* IPNOPRIVPORTS */
  976                 break;
  977 #endif /* INET */
  978 #ifdef INET6
  979             case PF_INET6:
  980                 apmin = ip6_anonportmin;
  981                 apmax = ip6_anonportmax;
  982 #ifndef IPNOPRIVPORTS
  983                 lpmin = ip6_lowportmin;
  984                 lpmax = ip6_lowportmax;
  985 #endif /* IPNOPRIVPORTS */
  986                 break;
  987 #endif /* INET6 */
  988             default:
  989                 return (EINVAL);
  990         }
  991 
  992         /*
  993          * insert temporary copy into node, perform lookup on
  994          * temporary, then restore pointer
  995          */
  996         node = *rnode;
  997         tmp = *(int*)rnode->sysctl_data;
  998         node.sysctl_data = &tmp;
  999         error = sysctl_lookup(SYSCTLFN_CALL(&node));
 1000         if (error || newp == NULL)
 1001                 return (error);
 1002 
 1003         /*
 1004          * simple port range check
 1005          */
 1006         if (tmp < 0 || tmp > 65535)
 1007                 return (EINVAL);
 1008 
 1009         /*
 1010          * per-node range checks
 1011          */
 1012         switch (rnode->sysctl_num) {
 1013         case IPCTL_ANONPORTMIN:
 1014                 if (tmp >= apmax)
 1015                         return (EINVAL);
 1016 #ifndef IPNOPRIVPORTS
 1017                 if (tmp < IPPORT_RESERVED)
 1018                         return (EINVAL);
 1019 #endif /* IPNOPRIVPORTS */
 1020                 break;
 1021 
 1022         case IPCTL_ANONPORTMAX:
 1023                 if (apmin >= tmp)
 1024                         return (EINVAL);
 1025 #ifndef IPNOPRIVPORTS
 1026                 if (tmp < IPPORT_RESERVED)
 1027                         return (EINVAL);
 1028 #endif /* IPNOPRIVPORTS */
 1029                 break;
 1030 
 1031 #ifndef IPNOPRIVPORTS
 1032         case IPCTL_LOWPORTMIN:
 1033                 if (tmp >= lpmax ||
 1034                     tmp > IPPORT_RESERVEDMAX ||
 1035                     tmp < IPPORT_RESERVEDMIN)
 1036                         return (EINVAL);
 1037                 break;
 1038 
 1039         case IPCTL_LOWPORTMAX:
 1040                 if (lpmin >= tmp ||
 1041                     tmp > IPPORT_RESERVEDMAX ||
 1042                     tmp < IPPORT_RESERVEDMIN)
 1043                         return (EINVAL);
 1044                 break;
 1045 #endif /* IPNOPRIVPORTS */
 1046 
 1047         default:
 1048                 return (EINVAL);
 1049         }
 1050 
 1051         *(int*)rnode->sysctl_data = tmp;
 1052 
 1053         return (0);
 1054 }
 1055 
 1056 /*
 1057  * sysctl helper routine for the net.inet.tcp.ident and
 1058  * net.inet6.tcp6.ident nodes.  contains backwards compat code for the
 1059  * old way of looking up the ident information for ipv4 which involves
 1060  * stuffing the port/addr pairs into the mib lookup.
 1061  */
 1062 static int
 1063 sysctl_net_inet_tcp_ident(SYSCTLFN_ARGS)
 1064 {
 1065 #ifdef INET
 1066         struct inpcb *inb;
 1067         struct sockaddr_in *si4[2];
 1068 #endif /* INET */
 1069 #ifdef INET6
 1070         struct in6pcb *in6b;
 1071         struct sockaddr_in6 *si6[2];
 1072 #endif /* INET6 */
 1073         struct in_addr laddr, raddr;
 1074         struct sockaddr_storage sa[2];
 1075         struct socket *sockp;
 1076         u_int lport, rport;
 1077         size_t sz;
 1078         uid_t uid;
 1079         int error, pf;
 1080 
 1081         if (namelen != 4 && namelen != 0)
 1082                 return (EINVAL);
 1083         if (name[-2] != IPPROTO_TCP)
 1084                 return (EINVAL);
 1085         pf = name[-3];
 1086 
 1087         /* old style lookup, ipv4 only */
 1088         if (namelen == 4) {
 1089 #ifdef INET
 1090                 if (pf != PF_INET)
 1091                         return (EPROTONOSUPPORT);
 1092                 raddr.s_addr = (uint32_t)name[0];
 1093                 rport = (u_int)name[1];
 1094                 laddr.s_addr = (uint32_t)name[2];
 1095                 lport = (u_int)name[3];
 1096                 inb = in_pcblookup_connect(&tcbtable, raddr, rport,
 1097                                            laddr, lport);
 1098                 if (inb == NULL || (sockp = inb->inp_socket) == NULL)
 1099                         return (ESRCH);
 1100                 uid = sockp->so_uid;
 1101                 if (oldp) {
 1102                         sz = MIN(sizeof(uid), *oldlenp);
 1103                         error = copyout(&uid, oldp, sz);
 1104                         if (error)
 1105                                 return (error);
 1106                 }
 1107                 *oldlenp = sizeof(uid);
 1108                 return (0);
 1109 #else /* INET */
 1110                 return (EINVAL);
 1111 #endif /* INET */
 1112         }
 1113 
 1114         if (newp == NULL || newlen != sizeof(sa))
 1115                 return (EINVAL);
 1116         error = copyin(newp, &sa, newlen);
 1117         if (error)
 1118                 return (error);
 1119 
 1120         /*
 1121          * requested families must match
 1122          */
 1123         if (pf != sa[0].ss_family || sa[0].ss_family != sa[1].ss_family)
 1124                 return (EINVAL);
 1125 
 1126         switch (pf) {
 1127 #ifdef INET
 1128             case PF_INET:
 1129                 si4[0] = (struct sockaddr_in*)&sa[0];
 1130                 si4[1] = (struct sockaddr_in*)&sa[1];
 1131                 if (si4[0]->sin_len != sizeof(*si4[0]) ||
 1132                     si4[0]->sin_len != si4[1]->sin_len)
 1133                         return (EINVAL);
 1134                 inb = in_pcblookup_connect(&tcbtable,
 1135                     si4[0]->sin_addr, si4[0]->sin_port,
 1136                     si4[1]->sin_addr, si4[1]->sin_port);
 1137                 if (inb == NULL || (sockp = inb->inp_socket) == NULL)
 1138                         return (ESRCH);
 1139                 break;
 1140 #endif /* INET */
 1141 #ifdef INET6
 1142             case PF_INET6:
 1143                 si6[0] = (struct sockaddr_in6*)&sa[0];
 1144                 si6[1] = (struct sockaddr_in6*)&sa[1];
 1145                 if (si6[0]->sin6_len != sizeof(*si6[0]) ||
 1146                     si6[0]->sin6_len != si6[1]->sin6_len)
 1147                         return (EINVAL);
 1148                 in6b = in6_pcblookup_connect(&tcbtable,
 1149                     &si6[0]->sin6_addr, si6[0]->sin6_port,
 1150                     &si6[1]->sin6_addr, si6[1]->sin6_port, 0);
 1151                 if (in6b == NULL || (sockp = in6b->in6p_socket) == NULL)
 1152                         return (ESRCH);
 1153                 break;
 1154 #endif /* INET6 */
 1155             default:
 1156                 return (EPROTONOSUPPORT);
 1157         }
 1158 
 1159         uid = sockp->so_uid;
 1160         if (oldp) {
 1161                 sz = MIN(sizeof(uid), *oldlenp);
 1162                 error = copyout(&uid, oldp, sz);
 1163                 if (error)
 1164                         return (error);
 1165         }
 1166         *oldlenp = sizeof(uid);
 1167 
 1168         return (0);
 1169 }
 1170 
 1171 /*
 1172  * this (second stage) setup routine is a replacement for tcp_sysctl()
 1173  * (which is currently used for ipv4 and ipv6)
 1174  */
 1175 static void
 1176 sysctl_net_inet_tcp_setup2(struct sysctllog **clog, int pf, const char *pfname,
 1177                            const char *tcpname)
 1178 {
 1179 
 1180         sysctl_createv(clog, 0, NULL, NULL,
 1181                        CTLFLAG_PERMANENT,
 1182                        CTLTYPE_NODE, "net", NULL,
 1183                        NULL, 0, NULL, 0,
 1184                        CTL_NET, CTL_EOL);
 1185         sysctl_createv(clog, 0, NULL, NULL,
 1186                        CTLFLAG_PERMANENT,
 1187                        CTLTYPE_NODE, pfname, NULL,
 1188                        NULL, 0, NULL, 0,
 1189                        CTL_NET, pf, CTL_EOL);
 1190         sysctl_createv(clog, 0, NULL, NULL,
 1191                        CTLFLAG_PERMANENT,
 1192                        CTLTYPE_NODE, tcpname,
 1193                        SYSCTL_DESCR("TCP related settings"),
 1194                        NULL, 0, NULL, 0,
 1195                        CTL_NET, pf, IPPROTO_TCP, CTL_EOL);
 1196 
 1197         sysctl_createv(clog, 0, NULL, NULL,
 1198                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1199                        CTLTYPE_INT, "rfc1323",
 1200                        SYSCTL_DESCR("Enable RFC1323 TCP extensions"),
 1201                        NULL, 0, &tcp_do_rfc1323, 0,
 1202                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RFC1323, CTL_EOL);
 1203         sysctl_createv(clog, 0, NULL, NULL,
 1204                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1205                        CTLTYPE_INT, "sendspace",
 1206                        SYSCTL_DESCR("Default TCP send buffer size"),
 1207                        NULL, 0, &tcp_sendspace, 0,
 1208                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SENDSPACE, CTL_EOL);
 1209         sysctl_createv(clog, 0, NULL, NULL,
 1210                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1211                        CTLTYPE_INT, "recvspace",
 1212                        SYSCTL_DESCR("Default TCP receive buffer size"),
 1213                        NULL, 0, &tcp_recvspace, 0,
 1214                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RECVSPACE, CTL_EOL);
 1215         sysctl_createv(clog, 0, NULL, NULL,
 1216                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1217                        CTLTYPE_INT, "mssdflt",
 1218                        SYSCTL_DESCR("Default maximum segment size"),
 1219                        sysctl_net_inet_tcp_mssdflt, 0, &tcp_mssdflt, 0,
 1220                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSSDFLT, CTL_EOL);
 1221         sysctl_createv(clog, 0, NULL, NULL,
 1222                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1223                        CTLTYPE_INT, "syn_cache_limit",
 1224                        SYSCTL_DESCR("Maximum number of entries in the TCP "
 1225                                     "compressed state engine"),
 1226                        NULL, 0, &tcp_syn_cache_limit, 0,
 1227                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_LIMIT,
 1228                        CTL_EOL);
 1229         sysctl_createv(clog, 0, NULL, NULL,
 1230                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1231                        CTLTYPE_INT, "syn_bucket_limit",
 1232                        SYSCTL_DESCR("Maximum number of entries per hash "
 1233                                     "bucket in the TCP compressed state "
 1234                                     "engine"),
 1235                        NULL, 0, &tcp_syn_bucket_limit, 0,
 1236                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_BUCKET_LIMIT,
 1237                        CTL_EOL);
 1238 #if 0 /* obsoleted */
 1239         sysctl_createv(clog, 0, NULL, NULL,
 1240                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1241                        CTLTYPE_INT, "syn_cache_interval",
 1242                        SYSCTL_DESCR("TCP compressed state engine's timer interval"),
 1243                        NULL, 0, &tcp_syn_cache_interval, 0,
 1244                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SYN_CACHE_INTER,
 1245                        CTL_EOL);
 1246 #endif
 1247         sysctl_createv(clog, 0, NULL, NULL,
 1248                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1249                        CTLTYPE_INT, "init_win",
 1250                        SYSCTL_DESCR("Initial TCP congestion window"),
 1251                        NULL, 0, &tcp_init_win, 0,
 1252                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN, CTL_EOL);
 1253         sysctl_createv(clog, 0, NULL, NULL,
 1254                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1255                        CTLTYPE_INT, "mss_ifmtu",
 1256                        SYSCTL_DESCR("Use interface MTU for calculating MSS"),
 1257                        NULL, 0, &tcp_mss_ifmtu, 0,
 1258                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_MSS_IFMTU, CTL_EOL);
 1259         sysctl_createv(clog, 0, NULL, NULL,
 1260                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1261                        CTLTYPE_INT, "sack",
 1262                        SYSCTL_DESCR("Enable RFC2018 Selection ACKnowledgement "
 1263                                     "(not implemented)"),
 1264                        NULL, 0, &tcp_do_sack, 0,
 1265                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SACK, CTL_EOL);
 1266         sysctl_createv(clog, 0, NULL, NULL,
 1267                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1268                        CTLTYPE_INT, "win_scale",
 1269                        SYSCTL_DESCR("Use RFC1323 window scale options"),
 1270                        NULL, 0, &tcp_do_win_scale, 0,
 1271                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_WSCALE, CTL_EOL);
 1272         sysctl_createv(clog, 0, NULL, NULL,
 1273                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1274                        CTLTYPE_INT, "timestamps",
 1275                        SYSCTL_DESCR("Use RFC1323 time stamp options"),
 1276                        NULL, 0, &tcp_do_timestamps, 0,
 1277                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_TSTAMP, CTL_EOL);
 1278         sysctl_createv(clog, 0, NULL, NULL,
 1279                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1280                        CTLTYPE_INT, "compat_42",
 1281                        SYSCTL_DESCR("Enable workarounds for 4.2BSD TCP bugs"),
 1282                        NULL, 0, &tcp_compat_42, 0,
 1283                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_COMPAT_42, CTL_EOL);
 1284         sysctl_createv(clog, 0, NULL, NULL,
 1285                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1286                        CTLTYPE_INT, "cwm",
 1287                        SYSCTL_DESCR("Hughes/Touch/Heidemann Congestion Window "
 1288                                     "Monitoring"),
 1289                        NULL, 0, &tcp_cwm, 0,
 1290                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM, CTL_EOL);
 1291         sysctl_createv(clog, 0, NULL, NULL,
 1292                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1293                        CTLTYPE_INT, "cwm_burstsize",
 1294                        SYSCTL_DESCR("Congestion Window Monitoring allowed "
 1295                                     "burst count in packets"),
 1296                        NULL, 0, &tcp_cwm_burstsize, 0,
 1297                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_CWM_BURSTSIZE,
 1298                        CTL_EOL);
 1299         sysctl_createv(clog, 0, NULL, NULL,
 1300                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1301                        CTLTYPE_INT, "ack_on_push",
 1302                        SYSCTL_DESCR("Immediately return ACK when PSH is "
 1303                                     "received"),
 1304                        NULL, 0, &tcp_ack_on_push, 0,
 1305                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_ACK_ON_PUSH, CTL_EOL);
 1306         sysctl_createv(clog, 0, NULL, NULL,
 1307                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1308                        CTLTYPE_INT, "keepidle",
 1309                        SYSCTL_DESCR("Allowed connection idle ticks before a "
 1310                                     "keepalive probe is sent"),
 1311                        NULL, 0, &tcp_keepidle, 0,
 1312                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPIDLE, CTL_EOL);
 1313         sysctl_createv(clog, 0, NULL, NULL,
 1314                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1315                        CTLTYPE_INT, "keepintvl",
 1316                        SYSCTL_DESCR("Ticks before next keepalive probe is sent"),
 1317                        NULL, 0, &tcp_keepintvl, 0,
 1318                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPINTVL, CTL_EOL);
 1319         sysctl_createv(clog, 0, NULL, NULL,
 1320                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1321                        CTLTYPE_INT, "keepcnt",
 1322                        SYSCTL_DESCR("Number of keepalive probes to send"),
 1323                        NULL, 0, &tcp_keepcnt, 0,
 1324                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_KEEPCNT, CTL_EOL);
 1325         sysctl_createv(clog, 0, NULL, NULL,
 1326                        CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
 1327                        CTLTYPE_INT, "slowhz",
 1328                        SYSCTL_DESCR("Keepalive ticks per second"),
 1329                        NULL, PR_SLOWHZ, NULL, 0,
 1330                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_SLOWHZ, CTL_EOL);
 1331         sysctl_createv(clog, 0, NULL, NULL,
 1332                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1333                        CTLTYPE_INT, "newreno",
 1334                        SYSCTL_DESCR("NewReno congestion control algorithm"),
 1335                        NULL, 0, &tcp_do_newreno, 0,
 1336                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_NEWRENO, CTL_EOL);
 1337         sysctl_createv(clog, 0, NULL, NULL,
 1338                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1339                        CTLTYPE_INT, "log_refused",
 1340                        SYSCTL_DESCR("Log refused TCP connections"),
 1341                        NULL, 0, &tcp_log_refused, 0,
 1342                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_LOG_REFUSED, CTL_EOL);
 1343 #if 0 /* obsoleted */
 1344         sysctl_createv(clog, 0, NULL, NULL,
 1345                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1346                        CTLTYPE_INT, "rstratelimit", NULL,
 1347                        NULL, 0, &tcp_rst_ratelim, 0,
 1348                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTRATELIMIT, CTL_EOL);
 1349 #endif
 1350         sysctl_createv(clog, 0, NULL, NULL,
 1351                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1352                        CTLTYPE_INT, "rstppslimit",
 1353                        SYSCTL_DESCR("Maximum number of RST packets to send "
 1354                                     "per second"),
 1355                        NULL, 0, &tcp_rst_ppslim, 0,
 1356                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_RSTPPSLIMIT, CTL_EOL);
 1357         sysctl_createv(clog, 0, NULL, NULL,
 1358                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1359                        CTLTYPE_INT, "delack_ticks",
 1360                        SYSCTL_DESCR("Number of ticks to delay sending an ACK"),
 1361                        NULL, 0, &tcp_delack_ticks, 0,
 1362                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_DELACK_TICKS, CTL_EOL);
 1363         sysctl_createv(clog, 0, NULL, NULL,
 1364                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1365                        CTLTYPE_INT, "init_win_local",
 1366                        SYSCTL_DESCR("Initial TCP window size (in segments)"),
 1367                        NULL, 0, &tcp_init_win_local, 0,
 1368                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_INIT_WIN_LOCAL,
 1369                        CTL_EOL);
 1370         sysctl_createv(clog, 0, NULL, NULL,
 1371                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1372                        CTLTYPE_STRUCT, "ident",
 1373                        SYSCTL_DESCR("RFC1413 Identification Protocol lookups"),
 1374                        sysctl_net_inet_tcp_ident, 0, NULL, sizeof(uid_t),
 1375                        CTL_NET, pf, IPPROTO_TCP, TCPCTL_IDENT, CTL_EOL);
 1376 }
 1377 
 1378 /*
 1379  * Sysctl for tcp variables.
 1380  */
 1381 #ifdef INET
 1382 SYSCTL_SETUP(sysctl_net_inet_tcp_setup, "sysctl net.inet.tcp subtree setup")
 1383 {
 1384 
 1385         sysctl_net_inet_tcp_setup2(clog, PF_INET, "inet", "tcp");
 1386 }
 1387 #endif /* INET */
 1388 
 1389 #ifdef INET6
 1390 SYSCTL_SETUP(sysctl_net_inet6_tcp6_setup, "sysctl net.inet6.tcp6 subtree setup")
 1391 {
 1392 
 1393         sysctl_net_inet_tcp_setup2(clog, PF_INET6, "inet6", "tcp6");
 1394 }
 1395 #endif /* INET6 */
 1396 

Cache object: f29db50ddcfd36ee9bf2a7857fb6d7c8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.