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 /*-
    2  * Copyright (c) 1982, 1986, 1988, 1993
    3  *      The Regents of the University of California.
    4  * Copyright (c) 2006-2007 Robert N. M. Watson
    5  * Copyright (c) 2010-2011 Juniper Networks, Inc.
    6  * All rights reserved.
    7  *
    8  * Portions of this software were developed by Robert N. M. Watson under
    9  * contract to Juniper Networks, Inc.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 4. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  *      From: @(#)tcp_usrreq.c  8.2 (Berkeley) 1/3/94
   36  */
   37 
   38 #include <sys/cdefs.h>
   39 __FBSDID("$FreeBSD: releng/9.0/sys/netinet/tcp_usrreq.c 222602 2011-06-02 10:21:05Z rwatson $");
   40 
   41 #include "opt_ddb.h"
   42 #include "opt_inet.h"
   43 #include "opt_inet6.h"
   44 #include "opt_tcpdebug.h"
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/malloc.h>
   49 #include <sys/kernel.h>
   50 #include <sys/sysctl.h>
   51 #include <sys/mbuf.h>
   52 #ifdef INET6
   53 #include <sys/domain.h>
   54 #endif /* INET6 */
   55 #include <sys/socket.h>
   56 #include <sys/socketvar.h>
   57 #include <sys/protosw.h>
   58 #include <sys/proc.h>
   59 #include <sys/jail.h>
   60 
   61 #ifdef DDB
   62 #include <ddb/ddb.h>
   63 #endif
   64 
   65 #include <net/if.h>
   66 #include <net/route.h>
   67 #include <net/vnet.h>
   68 
   69 #include <netinet/cc.h>
   70 #include <netinet/in.h>
   71 #include <netinet/in_pcb.h>
   72 #include <netinet/in_systm.h>
   73 #include <netinet/in_var.h>
   74 #include <netinet/ip_var.h>
   75 #ifdef INET6
   76 #include <netinet/ip6.h>
   77 #include <netinet6/in6_pcb.h>
   78 #include <netinet6/ip6_var.h>
   79 #include <netinet6/scope6_var.h>
   80 #endif
   81 #include <netinet/tcp_fsm.h>
   82 #include <netinet/tcp_seq.h>
   83 #include <netinet/tcp_timer.h>
   84 #include <netinet/tcp_var.h>
   85 #include <netinet/tcpip.h>
   86 #ifdef TCPDEBUG
   87 #include <netinet/tcp_debug.h>
   88 #endif
   89 #include <netinet/tcp_offload.h>
   90 
   91 /*
   92  * TCP protocol interface to socket abstraction.
   93  */
   94 static int      tcp_attach(struct socket *);
   95 #ifdef INET
   96 static int      tcp_connect(struct tcpcb *, struct sockaddr *,
   97                     struct thread *td);
   98 #endif /* INET */
   99 #ifdef INET6
  100 static int      tcp6_connect(struct tcpcb *, struct sockaddr *,
  101                     struct thread *td);
  102 #endif /* INET6 */
  103 static void     tcp_disconnect(struct tcpcb *);
  104 static void     tcp_usrclosed(struct tcpcb *);
  105 static void     tcp_fill_info(struct tcpcb *, struct tcp_info *);
  106 
  107 #ifdef TCPDEBUG
  108 #define TCPDEBUG0       int ostate = 0
  109 #define TCPDEBUG1()     ostate = tp ? tp->t_state : 0
  110 #define TCPDEBUG2(req)  if (tp && (so->so_options & SO_DEBUG)) \
  111                                 tcp_trace(TA_USER, ostate, tp, 0, 0, req)
  112 #else
  113 #define TCPDEBUG0
  114 #define TCPDEBUG1()
  115 #define TCPDEBUG2(req)
  116 #endif
  117 
  118 /*
  119  * TCP attaches to socket via pru_attach(), reserving space,
  120  * and an internet control block.
  121  */
  122 static int
  123 tcp_usr_attach(struct socket *so, int proto, struct thread *td)
  124 {
  125         struct inpcb *inp;
  126         struct tcpcb *tp = NULL;
  127         int error;
  128         TCPDEBUG0;
  129 
  130         inp = sotoinpcb(so);
  131         KASSERT(inp == NULL, ("tcp_usr_attach: inp != NULL"));
  132         TCPDEBUG1();
  133 
  134         error = tcp_attach(so);
  135         if (error)
  136                 goto out;
  137 
  138         if ((so->so_options & SO_LINGER) && so->so_linger == 0)
  139                 so->so_linger = TCP_LINGERTIME;
  140 
  141         inp = sotoinpcb(so);
  142         tp = intotcpcb(inp);
  143 out:
  144         TCPDEBUG2(PRU_ATTACH);
  145         return error;
  146 }
  147 
  148 /*
  149  * tcp_detach is called when the socket layer loses its final reference
  150  * to the socket, be it a file descriptor reference, a reference from TCP,
  151  * etc.  At this point, there is only one case in which we will keep around
  152  * inpcb state: time wait.
  153  *
  154  * This function can probably be re-absorbed back into tcp_usr_detach() now
  155  * that there is a single detach path.
  156  */
  157 static void
  158 tcp_detach(struct socket *so, struct inpcb *inp)
  159 {
  160         struct tcpcb *tp;
  161 
  162         INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
  163         INP_WLOCK_ASSERT(inp);
  164 
  165         KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp"));
  166         KASSERT(inp->inp_socket == so, ("tcp_detach: inp_socket != so"));
  167 
  168         tp = intotcpcb(inp);
  169 
  170         if (inp->inp_flags & INP_TIMEWAIT) {
  171                 /*
  172                  * There are two cases to handle: one in which the time wait
  173                  * state is being discarded (INP_DROPPED), and one in which
  174                  * this connection will remain in timewait.  In the former,
  175                  * it is time to discard all state (except tcptw, which has
  176                  * already been discarded by the timewait close code, which
  177                  * should be further up the call stack somewhere).  In the
  178                  * latter case, we detach from the socket, but leave the pcb
  179                  * present until timewait ends.
  180                  *
  181                  * XXXRW: Would it be cleaner to free the tcptw here?
  182                  */
  183                 if (inp->inp_flags & INP_DROPPED) {
  184                         KASSERT(tp == NULL, ("tcp_detach: INP_TIMEWAIT && "
  185                             "INP_DROPPED && tp != NULL"));
  186                         in_pcbdetach(inp);
  187                         in_pcbfree(inp);
  188                 } else {
  189                         in_pcbdetach(inp);
  190                         INP_WUNLOCK(inp);
  191                 }
  192         } else {
  193                 /*
  194                  * If the connection is not in timewait, we consider two
  195                  * two conditions: one in which no further processing is
  196                  * necessary (dropped || embryonic), and one in which TCP is
  197                  * not yet done, but no longer requires the socket, so the
  198                  * pcb will persist for the time being.
  199                  *
  200                  * XXXRW: Does the second case still occur?
  201                  */
  202                 if (inp->inp_flags & INP_DROPPED ||
  203                     tp->t_state < TCPS_SYN_SENT) {
  204                         tcp_discardcb(tp);
  205                         in_pcbdetach(inp);
  206                         in_pcbfree(inp);
  207                 } else
  208                         in_pcbdetach(inp);
  209         }
  210 }
  211 
  212 /*
  213  * pru_detach() detaches the TCP protocol from the socket.
  214  * If the protocol state is non-embryonic, then can't
  215  * do this directly: have to initiate a pru_disconnect(),
  216  * which may finish later; embryonic TCB's can just
  217  * be discarded here.
  218  */
  219 static void
  220 tcp_usr_detach(struct socket *so)
  221 {
  222         struct inpcb *inp;
  223 
  224         inp = sotoinpcb(so);
  225         KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL"));
  226         INP_INFO_WLOCK(&V_tcbinfo);
  227         INP_WLOCK(inp);
  228         KASSERT(inp->inp_socket != NULL,
  229             ("tcp_usr_detach: inp_socket == NULL"));
  230         tcp_detach(so, inp);
  231         INP_INFO_WUNLOCK(&V_tcbinfo);
  232 }
  233 
  234 #ifdef INET
  235 /*
  236  * Give the socket an address.
  237  */
  238 static int
  239 tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
  240 {
  241         int error = 0;
  242         struct inpcb *inp;
  243         struct tcpcb *tp = NULL;
  244         struct sockaddr_in *sinp;
  245 
  246         sinp = (struct sockaddr_in *)nam;
  247         if (nam->sa_len != sizeof (*sinp))
  248                 return (EINVAL);
  249         /*
  250          * Must check for multicast addresses and disallow binding
  251          * to them.
  252          */
  253         if (sinp->sin_family == AF_INET &&
  254             IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
  255                 return (EAFNOSUPPORT);
  256 
  257         TCPDEBUG0;
  258         inp = sotoinpcb(so);
  259         KASSERT(inp != NULL, ("tcp_usr_bind: inp == NULL"));
  260         INP_WLOCK(inp);
  261         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  262                 error = EINVAL;
  263                 goto out;
  264         }
  265         tp = intotcpcb(inp);
  266         TCPDEBUG1();
  267         INP_HASH_WLOCK(&V_tcbinfo);
  268         error = in_pcbbind(inp, nam, td->td_ucred);
  269         INP_HASH_WUNLOCK(&V_tcbinfo);
  270 out:
  271         TCPDEBUG2(PRU_BIND);
  272         INP_WUNLOCK(inp);
  273 
  274         return (error);
  275 }
  276 #endif /* INET */
  277 
  278 #ifdef INET6
  279 static int
  280 tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
  281 {
  282         int error = 0;
  283         struct inpcb *inp;
  284         struct tcpcb *tp = NULL;
  285         struct sockaddr_in6 *sin6p;
  286 
  287         sin6p = (struct sockaddr_in6 *)nam;
  288         if (nam->sa_len != sizeof (*sin6p))
  289                 return (EINVAL);
  290         /*
  291          * Must check for multicast addresses and disallow binding
  292          * to them.
  293          */
  294         if (sin6p->sin6_family == AF_INET6 &&
  295             IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
  296                 return (EAFNOSUPPORT);
  297 
  298         TCPDEBUG0;
  299         inp = sotoinpcb(so);
  300         KASSERT(inp != NULL, ("tcp6_usr_bind: inp == NULL"));
  301         INP_WLOCK(inp);
  302         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  303                 error = EINVAL;
  304                 goto out;
  305         }
  306         tp = intotcpcb(inp);
  307         TCPDEBUG1();
  308         INP_HASH_WLOCK(&V_tcbinfo);
  309         inp->inp_vflag &= ~INP_IPV4;
  310         inp->inp_vflag |= INP_IPV6;
  311 #ifdef INET
  312         if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
  313                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr))
  314                         inp->inp_vflag |= INP_IPV4;
  315                 else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
  316                         struct sockaddr_in sin;
  317 
  318                         in6_sin6_2_sin(&sin, sin6p);
  319                         inp->inp_vflag |= INP_IPV4;
  320                         inp->inp_vflag &= ~INP_IPV6;
  321                         error = in_pcbbind(inp, (struct sockaddr *)&sin,
  322                             td->td_ucred);
  323                         INP_HASH_WUNLOCK(&V_tcbinfo);
  324                         goto out;
  325                 }
  326         }
  327 #endif
  328         error = in6_pcbbind(inp, nam, td->td_ucred);
  329         INP_HASH_WUNLOCK(&V_tcbinfo);
  330 out:
  331         TCPDEBUG2(PRU_BIND);
  332         INP_WUNLOCK(inp);
  333         return (error);
  334 }
  335 #endif /* INET6 */
  336 
  337 #ifdef INET
  338 /*
  339  * Prepare to accept connections.
  340  */
  341 static int
  342 tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
  343 {
  344         int error = 0;
  345         struct inpcb *inp;
  346         struct tcpcb *tp = NULL;
  347 
  348         TCPDEBUG0;
  349         inp = sotoinpcb(so);
  350         KASSERT(inp != NULL, ("tcp_usr_listen: inp == NULL"));
  351         INP_WLOCK(inp);
  352         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  353                 error = EINVAL;
  354                 goto out;
  355         }
  356         tp = intotcpcb(inp);
  357         TCPDEBUG1();
  358         SOCK_LOCK(so);
  359         error = solisten_proto_check(so);
  360         INP_HASH_WLOCK(&V_tcbinfo);
  361         if (error == 0 && inp->inp_lport == 0)
  362                 error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
  363         INP_HASH_WUNLOCK(&V_tcbinfo);
  364         if (error == 0) {
  365                 tp->t_state = TCPS_LISTEN;
  366                 solisten_proto(so, backlog);
  367                 tcp_offload_listen_open(tp);
  368         }
  369         SOCK_UNLOCK(so);
  370 
  371 out:
  372         TCPDEBUG2(PRU_LISTEN);
  373         INP_WUNLOCK(inp);
  374         return (error);
  375 }
  376 #endif /* INET */
  377 
  378 #ifdef INET6
  379 static int
  380 tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
  381 {
  382         int error = 0;
  383         struct inpcb *inp;
  384         struct tcpcb *tp = NULL;
  385 
  386         TCPDEBUG0;
  387         inp = sotoinpcb(so);
  388         KASSERT(inp != NULL, ("tcp6_usr_listen: inp == NULL"));
  389         INP_WLOCK(inp);
  390         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  391                 error = EINVAL;
  392                 goto out;
  393         }
  394         tp = intotcpcb(inp);
  395         TCPDEBUG1();
  396         SOCK_LOCK(so);
  397         error = solisten_proto_check(so);
  398         INP_HASH_WLOCK(&V_tcbinfo);
  399         if (error == 0 && inp->inp_lport == 0) {
  400                 inp->inp_vflag &= ~INP_IPV4;
  401                 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
  402                         inp->inp_vflag |= INP_IPV4;
  403                 error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
  404         }
  405         INP_HASH_WUNLOCK(&V_tcbinfo);
  406         if (error == 0) {
  407                 tp->t_state = TCPS_LISTEN;
  408                 solisten_proto(so, backlog);
  409         }
  410         SOCK_UNLOCK(so);
  411 
  412 out:
  413         TCPDEBUG2(PRU_LISTEN);
  414         INP_WUNLOCK(inp);
  415         return (error);
  416 }
  417 #endif /* INET6 */
  418 
  419 #ifdef INET
  420 /*
  421  * Initiate connection to peer.
  422  * Create a template for use in transmissions on this connection.
  423  * Enter SYN_SENT state, and mark socket as connecting.
  424  * Start keep-alive timer, and seed output sequence space.
  425  * Send initial segment on connection.
  426  */
  427 static int
  428 tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
  429 {
  430         int error = 0;
  431         struct inpcb *inp;
  432         struct tcpcb *tp = NULL;
  433         struct sockaddr_in *sinp;
  434 
  435         sinp = (struct sockaddr_in *)nam;
  436         if (nam->sa_len != sizeof (*sinp))
  437                 return (EINVAL);
  438         /*
  439          * Must disallow TCP ``connections'' to multicast addresses.
  440          */
  441         if (sinp->sin_family == AF_INET
  442             && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
  443                 return (EAFNOSUPPORT);
  444         if ((error = prison_remote_ip4(td->td_ucred, &sinp->sin_addr)) != 0)
  445                 return (error);
  446 
  447         TCPDEBUG0;
  448         inp = sotoinpcb(so);
  449         KASSERT(inp != NULL, ("tcp_usr_connect: inp == NULL"));
  450         INP_WLOCK(inp);
  451         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  452                 error = EINVAL;
  453                 goto out;
  454         }
  455         tp = intotcpcb(inp);
  456         TCPDEBUG1();
  457         if ((error = tcp_connect(tp, nam, td)) != 0)
  458                 goto out;
  459         error = tcp_output_connect(so, nam);
  460 out:
  461         TCPDEBUG2(PRU_CONNECT);
  462         INP_WUNLOCK(inp);
  463         return (error);
  464 }
  465 #endif /* INET */
  466 
  467 #ifdef INET6
  468 static int
  469 tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
  470 {
  471         int error = 0;
  472         struct inpcb *inp;
  473         struct tcpcb *tp = NULL;
  474         struct sockaddr_in6 *sin6p;
  475 
  476         TCPDEBUG0;
  477 
  478         sin6p = (struct sockaddr_in6 *)nam;
  479         if (nam->sa_len != sizeof (*sin6p))
  480                 return (EINVAL);
  481         /*
  482          * Must disallow TCP ``connections'' to multicast addresses.
  483          */
  484         if (sin6p->sin6_family == AF_INET6
  485             && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
  486                 return (EAFNOSUPPORT);
  487 
  488         inp = sotoinpcb(so);
  489         KASSERT(inp != NULL, ("tcp6_usr_connect: inp == NULL"));
  490         INP_WLOCK(inp);
  491         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  492                 error = EINVAL;
  493                 goto out;
  494         }
  495         tp = intotcpcb(inp);
  496         TCPDEBUG1();
  497 #ifdef INET
  498         /*
  499          * XXXRW: Some confusion: V4/V6 flags relate to binding, and
  500          * therefore probably require the hash lock, which isn't held here.
  501          * Is this a significant problem?
  502          */
  503         if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
  504                 struct sockaddr_in sin;
  505 
  506                 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
  507                         error = EINVAL;
  508                         goto out;
  509                 }
  510 
  511                 in6_sin6_2_sin(&sin, sin6p);
  512                 inp->inp_vflag |= INP_IPV4;
  513                 inp->inp_vflag &= ~INP_IPV6;
  514                 if ((error = prison_remote_ip4(td->td_ucred,
  515                     &sin.sin_addr)) != 0)
  516                         goto out;
  517                 if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
  518                         goto out;
  519                 error = tcp_output_connect(so, nam);
  520                 goto out;
  521         }
  522 #endif
  523         inp->inp_vflag &= ~INP_IPV4;
  524         inp->inp_vflag |= INP_IPV6;
  525         inp->inp_inc.inc_flags |= INC_ISIPV6;
  526         if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0)
  527                 goto out;
  528         if ((error = tcp6_connect(tp, nam, td)) != 0)
  529                 goto out;
  530         error = tcp_output_connect(so, nam);
  531 
  532 out:
  533         TCPDEBUG2(PRU_CONNECT);
  534         INP_WUNLOCK(inp);
  535         return (error);
  536 }
  537 #endif /* INET6 */
  538 
  539 /*
  540  * Initiate disconnect from peer.
  541  * If connection never passed embryonic stage, just drop;
  542  * else if don't need to let data drain, then can just drop anyways,
  543  * else have to begin TCP shutdown process: mark socket disconnecting,
  544  * drain unread data, state switch to reflect user close, and
  545  * send segment (e.g. FIN) to peer.  Socket will be really disconnected
  546  * when peer sends FIN and acks ours.
  547  *
  548  * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
  549  */
  550 static int
  551 tcp_usr_disconnect(struct socket *so)
  552 {
  553         struct inpcb *inp;
  554         struct tcpcb *tp = NULL;
  555         int error = 0;
  556 
  557         TCPDEBUG0;
  558         INP_INFO_WLOCK(&V_tcbinfo);
  559         inp = sotoinpcb(so);
  560         KASSERT(inp != NULL, ("tcp_usr_disconnect: inp == NULL"));
  561         INP_WLOCK(inp);
  562         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  563                 error = ECONNRESET;
  564                 goto out;
  565         }
  566         tp = intotcpcb(inp);
  567         TCPDEBUG1();
  568         tcp_disconnect(tp);
  569 out:
  570         TCPDEBUG2(PRU_DISCONNECT);
  571         INP_WUNLOCK(inp);
  572         INP_INFO_WUNLOCK(&V_tcbinfo);
  573         return (error);
  574 }
  575 
  576 #ifdef INET
  577 /*
  578  * Accept a connection.  Essentially all the work is done at higher levels;
  579  * just return the address of the peer, storing through addr.
  580  *
  581  * The rationale for acquiring the tcbinfo lock here is somewhat complicated,
  582  * and is described in detail in the commit log entry for r175612.  Acquiring
  583  * it delays an accept(2) racing with sonewconn(), which inserts the socket
  584  * before the inpcb address/port fields are initialized.  A better fix would
  585  * prevent the socket from being placed in the listen queue until all fields
  586  * are fully initialized.
  587  */
  588 static int
  589 tcp_usr_accept(struct socket *so, struct sockaddr **nam)
  590 {
  591         int error = 0;
  592         struct inpcb *inp = NULL;
  593         struct tcpcb *tp = NULL;
  594         struct in_addr addr;
  595         in_port_t port = 0;
  596         TCPDEBUG0;
  597 
  598         if (so->so_state & SS_ISDISCONNECTED)
  599                 return (ECONNABORTED);
  600 
  601         inp = sotoinpcb(so);
  602         KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL"));
  603         INP_INFO_RLOCK(&V_tcbinfo);
  604         INP_WLOCK(inp);
  605         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  606                 error = ECONNABORTED;
  607                 goto out;
  608         }
  609         tp = intotcpcb(inp);
  610         TCPDEBUG1();
  611 
  612         /*
  613          * We inline in_getpeeraddr and COMMON_END here, so that we can
  614          * copy the data of interest and defer the malloc until after we
  615          * release the lock.
  616          */
  617         port = inp->inp_fport;
  618         addr = inp->inp_faddr;
  619 
  620 out:
  621         TCPDEBUG2(PRU_ACCEPT);
  622         INP_WUNLOCK(inp);
  623         INP_INFO_RUNLOCK(&V_tcbinfo);
  624         if (error == 0)
  625                 *nam = in_sockaddr(port, &addr);
  626         return error;
  627 }
  628 #endif /* INET */
  629 
  630 #ifdef INET6
  631 static int
  632 tcp6_usr_accept(struct socket *so, struct sockaddr **nam)
  633 {
  634         struct inpcb *inp = NULL;
  635         int error = 0;
  636         struct tcpcb *tp = NULL;
  637         struct in_addr addr;
  638         struct in6_addr addr6;
  639         in_port_t port = 0;
  640         int v4 = 0;
  641         TCPDEBUG0;
  642 
  643         if (so->so_state & SS_ISDISCONNECTED)
  644                 return (ECONNABORTED);
  645 
  646         inp = sotoinpcb(so);
  647         KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL"));
  648         INP_INFO_RLOCK(&V_tcbinfo);
  649         INP_WLOCK(inp);
  650         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  651                 error = ECONNABORTED;
  652                 goto out;
  653         }
  654         tp = intotcpcb(inp);
  655         TCPDEBUG1();
  656 
  657         /*
  658          * We inline in6_mapped_peeraddr and COMMON_END here, so that we can
  659          * copy the data of interest and defer the malloc until after we
  660          * release the lock.
  661          */
  662         if (inp->inp_vflag & INP_IPV4) {
  663                 v4 = 1;
  664                 port = inp->inp_fport;
  665                 addr = inp->inp_faddr;
  666         } else {
  667                 port = inp->inp_fport;
  668                 addr6 = inp->in6p_faddr;
  669         }
  670 
  671 out:
  672         TCPDEBUG2(PRU_ACCEPT);
  673         INP_WUNLOCK(inp);
  674         INP_INFO_RUNLOCK(&V_tcbinfo);
  675         if (error == 0) {
  676                 if (v4)
  677                         *nam = in6_v4mapsin6_sockaddr(port, &addr);
  678                 else
  679                         *nam = in6_sockaddr(port, &addr6);
  680         }
  681         return error;
  682 }
  683 #endif /* INET6 */
  684 
  685 /*
  686  * Mark the connection as being incapable of further output.
  687  */
  688 static int
  689 tcp_usr_shutdown(struct socket *so)
  690 {
  691         int error = 0;
  692         struct inpcb *inp;
  693         struct tcpcb *tp = NULL;
  694 
  695         TCPDEBUG0;
  696         INP_INFO_WLOCK(&V_tcbinfo);
  697         inp = sotoinpcb(so);
  698         KASSERT(inp != NULL, ("inp == NULL"));
  699         INP_WLOCK(inp);
  700         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  701                 error = ECONNRESET;
  702                 goto out;
  703         }
  704         tp = intotcpcb(inp);
  705         TCPDEBUG1();
  706         socantsendmore(so);
  707         tcp_usrclosed(tp);
  708         if (!(inp->inp_flags & INP_DROPPED))
  709                 error = tcp_output_disconnect(tp);
  710 
  711 out:
  712         TCPDEBUG2(PRU_SHUTDOWN);
  713         INP_WUNLOCK(inp);
  714         INP_INFO_WUNLOCK(&V_tcbinfo);
  715 
  716         return (error);
  717 }
  718 
  719 /*
  720  * After a receive, possibly send window update to peer.
  721  */
  722 static int
  723 tcp_usr_rcvd(struct socket *so, int flags)
  724 {
  725         struct inpcb *inp;
  726         struct tcpcb *tp = NULL;
  727         int error = 0;
  728 
  729         TCPDEBUG0;
  730         inp = sotoinpcb(so);
  731         KASSERT(inp != NULL, ("tcp_usr_rcvd: inp == NULL"));
  732         INP_WLOCK(inp);
  733         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  734                 error = ECONNRESET;
  735                 goto out;
  736         }
  737         tp = intotcpcb(inp);
  738         TCPDEBUG1();
  739         tcp_output_rcvd(tp);
  740 
  741 out:
  742         TCPDEBUG2(PRU_RCVD);
  743         INP_WUNLOCK(inp);
  744         return (error);
  745 }
  746 
  747 /*
  748  * Do a send by putting data in output queue and updating urgent
  749  * marker if URG set.  Possibly send more data.  Unlike the other
  750  * pru_*() routines, the mbuf chains are our responsibility.  We
  751  * must either enqueue them or free them.  The other pru_* routines
  752  * generally are caller-frees.
  753  */
  754 static int
  755 tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
  756     struct sockaddr *nam, struct mbuf *control, struct thread *td)
  757 {
  758         int error = 0;
  759         struct inpcb *inp;
  760         struct tcpcb *tp = NULL;
  761 #ifdef INET6
  762         int isipv6;
  763 #endif
  764         TCPDEBUG0;
  765 
  766         /*
  767          * We require the pcbinfo lock if we will close the socket as part of
  768          * this call.
  769          */
  770         if (flags & PRUS_EOF)
  771                 INP_INFO_WLOCK(&V_tcbinfo);
  772         inp = sotoinpcb(so);
  773         KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
  774         INP_WLOCK(inp);
  775         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  776                 if (control)
  777                         m_freem(control);
  778                 if (m)
  779                         m_freem(m);
  780                 error = ECONNRESET;
  781                 goto out;
  782         }
  783 #ifdef INET6
  784         isipv6 = nam && nam->sa_family == AF_INET6;
  785 #endif /* INET6 */
  786         tp = intotcpcb(inp);
  787         TCPDEBUG1();
  788         if (control) {
  789                 /* TCP doesn't do control messages (rights, creds, etc) */
  790                 if (control->m_len) {
  791                         m_freem(control);
  792                         if (m)
  793                                 m_freem(m);
  794                         error = EINVAL;
  795                         goto out;
  796                 }
  797                 m_freem(control);       /* empty control, just free it */
  798         }
  799         if (!(flags & PRUS_OOB)) {
  800                 sbappendstream(&so->so_snd, m);
  801                 if (nam && tp->t_state < TCPS_SYN_SENT) {
  802                         /*
  803                          * Do implied connect if not yet connected,
  804                          * initialize window to default value, and
  805                          * initialize maxseg/maxopd using peer's cached
  806                          * MSS.
  807                          */
  808 #ifdef INET6
  809                         if (isipv6)
  810                                 error = tcp6_connect(tp, nam, td);
  811 #endif /* INET6 */
  812 #if defined(INET6) && defined(INET)
  813                         else
  814 #endif
  815 #ifdef INET
  816                                 error = tcp_connect(tp, nam, td);
  817 #endif
  818                         if (error)
  819                                 goto out;
  820                         tp->snd_wnd = TTCP_CLIENT_SND_WND;
  821                         tcp_mss(tp, -1);
  822                 }
  823                 if (flags & PRUS_EOF) {
  824                         /*
  825                          * Close the send side of the connection after
  826                          * the data is sent.
  827                          */
  828                         INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
  829                         socantsendmore(so);
  830                         tcp_usrclosed(tp);
  831                 }
  832                 if (!(inp->inp_flags & INP_DROPPED)) {
  833                         if (flags & PRUS_MORETOCOME)
  834                                 tp->t_flags |= TF_MORETOCOME;
  835                         error = tcp_output_send(tp);
  836                         if (flags & PRUS_MORETOCOME)
  837                                 tp->t_flags &= ~TF_MORETOCOME;
  838                 }
  839         } else {
  840                 /*
  841                  * XXXRW: PRUS_EOF not implemented with PRUS_OOB?
  842                  */
  843                 SOCKBUF_LOCK(&so->so_snd);
  844                 if (sbspace(&so->so_snd) < -512) {
  845                         SOCKBUF_UNLOCK(&so->so_snd);
  846                         m_freem(m);
  847                         error = ENOBUFS;
  848                         goto out;
  849                 }
  850                 /*
  851                  * According to RFC961 (Assigned Protocols),
  852                  * the urgent pointer points to the last octet
  853                  * of urgent data.  We continue, however,
  854                  * to consider it to indicate the first octet
  855                  * of data past the urgent section.
  856                  * Otherwise, snd_up should be one lower.
  857                  */
  858                 sbappendstream_locked(&so->so_snd, m);
  859                 SOCKBUF_UNLOCK(&so->so_snd);
  860                 if (nam && tp->t_state < TCPS_SYN_SENT) {
  861                         /*
  862                          * Do implied connect if not yet connected,
  863                          * initialize window to default value, and
  864                          * initialize maxseg/maxopd using peer's cached
  865                          * MSS.
  866                          */
  867 #ifdef INET6
  868                         if (isipv6)
  869                                 error = tcp6_connect(tp, nam, td);
  870 #endif /* INET6 */
  871 #if defined(INET6) && defined(INET)
  872                         else
  873 #endif
  874 #ifdef INET
  875                                 error = tcp_connect(tp, nam, td);
  876 #endif
  877                         if (error)
  878                                 goto out;
  879                         tp->snd_wnd = TTCP_CLIENT_SND_WND;
  880                         tcp_mss(tp, -1);
  881                 }
  882                 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
  883                 tp->t_flags |= TF_FORCEDATA;
  884                 error = tcp_output_send(tp);
  885                 tp->t_flags &= ~TF_FORCEDATA;
  886         }
  887 out:
  888         TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB :
  889                   ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
  890         INP_WUNLOCK(inp);
  891         if (flags & PRUS_EOF)
  892                 INP_INFO_WUNLOCK(&V_tcbinfo);
  893         return (error);
  894 }
  895 
  896 /*
  897  * Abort the TCP.  Drop the connection abruptly.
  898  */
  899 static void
  900 tcp_usr_abort(struct socket *so)
  901 {
  902         struct inpcb *inp;
  903         struct tcpcb *tp = NULL;
  904         TCPDEBUG0;
  905 
  906         inp = sotoinpcb(so);
  907         KASSERT(inp != NULL, ("tcp_usr_abort: inp == NULL"));
  908 
  909         INP_INFO_WLOCK(&V_tcbinfo);
  910         INP_WLOCK(inp);
  911         KASSERT(inp->inp_socket != NULL,
  912             ("tcp_usr_abort: inp_socket == NULL"));
  913 
  914         /*
  915          * If we still have full TCP state, and we're not dropped, drop.
  916          */
  917         if (!(inp->inp_flags & INP_TIMEWAIT) &&
  918             !(inp->inp_flags & INP_DROPPED)) {
  919                 tp = intotcpcb(inp);
  920                 TCPDEBUG1();
  921                 tcp_drop(tp, ECONNABORTED);
  922                 TCPDEBUG2(PRU_ABORT);
  923         }
  924         if (!(inp->inp_flags & INP_DROPPED)) {
  925                 SOCK_LOCK(so);
  926                 so->so_state |= SS_PROTOREF;
  927                 SOCK_UNLOCK(so);
  928                 inp->inp_flags |= INP_SOCKREF;
  929         }
  930         INP_WUNLOCK(inp);
  931         INP_INFO_WUNLOCK(&V_tcbinfo);
  932 }
  933 
  934 /*
  935  * TCP socket is closed.  Start friendly disconnect.
  936  */
  937 static void
  938 tcp_usr_close(struct socket *so)
  939 {
  940         struct inpcb *inp;
  941         struct tcpcb *tp = NULL;
  942         TCPDEBUG0;
  943 
  944         inp = sotoinpcb(so);
  945         KASSERT(inp != NULL, ("tcp_usr_close: inp == NULL"));
  946 
  947         INP_INFO_WLOCK(&V_tcbinfo);
  948         INP_WLOCK(inp);
  949         KASSERT(inp->inp_socket != NULL,
  950             ("tcp_usr_close: inp_socket == NULL"));
  951 
  952         /*
  953          * If we still have full TCP state, and we're not dropped, initiate
  954          * a disconnect.
  955          */
  956         if (!(inp->inp_flags & INP_TIMEWAIT) &&
  957             !(inp->inp_flags & INP_DROPPED)) {
  958                 tp = intotcpcb(inp);
  959                 TCPDEBUG1();
  960                 tcp_disconnect(tp);
  961                 TCPDEBUG2(PRU_CLOSE);
  962         }
  963         if (!(inp->inp_flags & INP_DROPPED)) {
  964                 SOCK_LOCK(so);
  965                 so->so_state |= SS_PROTOREF;
  966                 SOCK_UNLOCK(so);
  967                 inp->inp_flags |= INP_SOCKREF;
  968         }
  969         INP_WUNLOCK(inp);
  970         INP_INFO_WUNLOCK(&V_tcbinfo);
  971 }
  972 
  973 /*
  974  * Receive out-of-band data.
  975  */
  976 static int
  977 tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
  978 {
  979         int error = 0;
  980         struct inpcb *inp;
  981         struct tcpcb *tp = NULL;
  982 
  983         TCPDEBUG0;
  984         inp = sotoinpcb(so);
  985         KASSERT(inp != NULL, ("tcp_usr_rcvoob: inp == NULL"));
  986         INP_WLOCK(inp);
  987         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
  988                 error = ECONNRESET;
  989                 goto out;
  990         }
  991         tp = intotcpcb(inp);
  992         TCPDEBUG1();
  993         if ((so->so_oobmark == 0 &&
  994              (so->so_rcv.sb_state & SBS_RCVATMARK) == 0) ||
  995             so->so_options & SO_OOBINLINE ||
  996             tp->t_oobflags & TCPOOB_HADDATA) {
  997                 error = EINVAL;
  998                 goto out;
  999         }
 1000         if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
 1001                 error = EWOULDBLOCK;
 1002                 goto out;
 1003         }
 1004         m->m_len = 1;
 1005         *mtod(m, caddr_t) = tp->t_iobc;
 1006         if ((flags & MSG_PEEK) == 0)
 1007                 tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
 1008 
 1009 out:
 1010         TCPDEBUG2(PRU_RCVOOB);
 1011         INP_WUNLOCK(inp);
 1012         return (error);
 1013 }
 1014 
 1015 #ifdef INET
 1016 struct pr_usrreqs tcp_usrreqs = {
 1017         .pru_abort =            tcp_usr_abort,
 1018         .pru_accept =           tcp_usr_accept,
 1019         .pru_attach =           tcp_usr_attach,
 1020         .pru_bind =             tcp_usr_bind,
 1021         .pru_connect =          tcp_usr_connect,
 1022         .pru_control =          in_control,
 1023         .pru_detach =           tcp_usr_detach,
 1024         .pru_disconnect =       tcp_usr_disconnect,
 1025         .pru_listen =           tcp_usr_listen,
 1026         .pru_peeraddr =         in_getpeeraddr,
 1027         .pru_rcvd =             tcp_usr_rcvd,
 1028         .pru_rcvoob =           tcp_usr_rcvoob,
 1029         .pru_send =             tcp_usr_send,
 1030         .pru_shutdown =         tcp_usr_shutdown,
 1031         .pru_sockaddr =         in_getsockaddr,
 1032         .pru_sosetlabel =       in_pcbsosetlabel,
 1033         .pru_close =            tcp_usr_close,
 1034 };
 1035 #endif /* INET */
 1036 
 1037 #ifdef INET6
 1038 struct pr_usrreqs tcp6_usrreqs = {
 1039         .pru_abort =            tcp_usr_abort,
 1040         .pru_accept =           tcp6_usr_accept,
 1041         .pru_attach =           tcp_usr_attach,
 1042         .pru_bind =             tcp6_usr_bind,
 1043         .pru_connect =          tcp6_usr_connect,
 1044         .pru_control =          in6_control,
 1045         .pru_detach =           tcp_usr_detach,
 1046         .pru_disconnect =       tcp_usr_disconnect,
 1047         .pru_listen =           tcp6_usr_listen,
 1048         .pru_peeraddr =         in6_mapped_peeraddr,
 1049         .pru_rcvd =             tcp_usr_rcvd,
 1050         .pru_rcvoob =           tcp_usr_rcvoob,
 1051         .pru_send =             tcp_usr_send,
 1052         .pru_shutdown =         tcp_usr_shutdown,
 1053         .pru_sockaddr =         in6_mapped_sockaddr,
 1054         .pru_sosetlabel =       in_pcbsosetlabel,
 1055         .pru_close =            tcp_usr_close,
 1056 };
 1057 #endif /* INET6 */
 1058 
 1059 #ifdef INET
 1060 /*
 1061  * Common subroutine to open a TCP connection to remote host specified
 1062  * by struct sockaddr_in in mbuf *nam.  Call in_pcbbind to assign a local
 1063  * port number if needed.  Call in_pcbconnect_setup to do the routing and
 1064  * to choose a local host address (interface).  If there is an existing
 1065  * incarnation of the same connection in TIME-WAIT state and if the remote
 1066  * host was sending CC options and if the connection duration was < MSL, then
 1067  * truncate the previous TIME-WAIT state and proceed.
 1068  * Initialize connection parameters and enter SYN-SENT state.
 1069  */
 1070 static int
 1071 tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 1072 {
 1073         struct inpcb *inp = tp->t_inpcb, *oinp;
 1074         struct socket *so = inp->inp_socket;
 1075         struct in_addr laddr;
 1076         u_short lport;
 1077         int error;
 1078 
 1079         INP_WLOCK_ASSERT(inp);
 1080         INP_HASH_WLOCK(&V_tcbinfo);
 1081 
 1082         if (inp->inp_lport == 0) {
 1083                 error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
 1084                 if (error)
 1085                         goto out;
 1086         }
 1087 
 1088         /*
 1089          * Cannot simply call in_pcbconnect, because there might be an
 1090          * earlier incarnation of this same connection still in
 1091          * TIME_WAIT state, creating an ADDRINUSE error.
 1092          */
 1093         laddr = inp->inp_laddr;
 1094         lport = inp->inp_lport;
 1095         error = in_pcbconnect_setup(inp, nam, &laddr.s_addr, &lport,
 1096             &inp->inp_faddr.s_addr, &inp->inp_fport, &oinp, td->td_ucred);
 1097         if (error && oinp == NULL)
 1098                 goto out;
 1099         if (oinp) {
 1100                 error = EADDRINUSE;
 1101                 goto out;
 1102         }
 1103         inp->inp_laddr = laddr;
 1104         in_pcbrehash(inp);
 1105         INP_HASH_WUNLOCK(&V_tcbinfo);
 1106 
 1107         /*
 1108          * Compute window scaling to request:
 1109          * Scale to fit into sweet spot.  See tcp_syncache.c.
 1110          * XXX: This should move to tcp_output().
 1111          */
 1112         while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
 1113             (TCP_MAXWIN << tp->request_r_scale) < sb_max)
 1114                 tp->request_r_scale++;
 1115 
 1116         soisconnecting(so);
 1117         TCPSTAT_INC(tcps_connattempt);
 1118         tp->t_state = TCPS_SYN_SENT;
 1119         tcp_timer_activate(tp, TT_KEEP, tcp_keepinit);
 1120         tp->iss = tcp_new_isn(tp);
 1121         tcp_sendseqinit(tp);
 1122 
 1123         return 0;
 1124 
 1125 out:
 1126         INP_HASH_WUNLOCK(&V_tcbinfo);
 1127         return (error);
 1128 }
 1129 #endif /* INET */
 1130 
 1131 #ifdef INET6
 1132 static int
 1133 tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
 1134 {
 1135         struct inpcb *inp = tp->t_inpcb, *oinp;
 1136         struct socket *so = inp->inp_socket;
 1137         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
 1138         struct in6_addr addr6;
 1139         int error;
 1140 
 1141         INP_WLOCK_ASSERT(inp);
 1142         INP_HASH_WLOCK(&V_tcbinfo);
 1143 
 1144         if (inp->inp_lport == 0) {
 1145                 error = in6_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
 1146                 if (error)
 1147                         goto out;
 1148         }
 1149 
 1150         /*
 1151          * Cannot simply call in_pcbconnect, because there might be an
 1152          * earlier incarnation of this same connection still in
 1153          * TIME_WAIT state, creating an ADDRINUSE error.
 1154          * in6_pcbladdr() also handles scope zone IDs.
 1155          *
 1156          * XXXRW: We wouldn't need to expose in6_pcblookup_hash_locked()
 1157          * outside of in6_pcb.c if there were an in6_pcbconnect_setup().
 1158          */
 1159         error = in6_pcbladdr(inp, nam, &addr6);
 1160         if (error)
 1161                 goto out;
 1162         oinp = in6_pcblookup_hash_locked(inp->inp_pcbinfo,
 1163                                   &sin6->sin6_addr, sin6->sin6_port,
 1164                                   IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)
 1165                                   ? &addr6
 1166                                   : &inp->in6p_laddr,
 1167                                   inp->inp_lport,  0, NULL);
 1168         if (oinp) {
 1169                 error = EADDRINUSE;
 1170                 goto out;
 1171         }
 1172         if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
 1173                 inp->in6p_laddr = addr6;
 1174         inp->in6p_faddr = sin6->sin6_addr;
 1175         inp->inp_fport = sin6->sin6_port;
 1176         /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
 1177         inp->inp_flow &= ~IPV6_FLOWLABEL_MASK;
 1178         if (inp->inp_flags & IN6P_AUTOFLOWLABEL)
 1179                 inp->inp_flow |=
 1180                     (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
 1181         in_pcbrehash(inp);
 1182         INP_HASH_WUNLOCK(&V_tcbinfo);
 1183 
 1184         /* Compute window scaling to request.  */
 1185         while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
 1186             (TCP_MAXWIN << tp->request_r_scale) < sb_max)
 1187                 tp->request_r_scale++;
 1188 
 1189         soisconnecting(so);
 1190         TCPSTAT_INC(tcps_connattempt);
 1191         tp->t_state = TCPS_SYN_SENT;
 1192         tcp_timer_activate(tp, TT_KEEP, tcp_keepinit);
 1193         tp->iss = tcp_new_isn(tp);
 1194         tcp_sendseqinit(tp);
 1195 
 1196         return 0;
 1197 
 1198 out:
 1199         INP_HASH_WUNLOCK(&V_tcbinfo);
 1200         return error;
 1201 }
 1202 #endif /* INET6 */
 1203 
 1204 /*
 1205  * Export TCP internal state information via a struct tcp_info, based on the
 1206  * Linux 2.6 API.  Not ABI compatible as our constants are mapped differently
 1207  * (TCP state machine, etc).  We export all information using FreeBSD-native
 1208  * constants -- for example, the numeric values for tcpi_state will differ
 1209  * from Linux.
 1210  */
 1211 static void
 1212 tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
 1213 {
 1214 
 1215         INP_WLOCK_ASSERT(tp->t_inpcb);
 1216         bzero(ti, sizeof(*ti));
 1217 
 1218         ti->tcpi_state = tp->t_state;
 1219         if ((tp->t_flags & TF_REQ_TSTMP) && (tp->t_flags & TF_RCVD_TSTMP))
 1220                 ti->tcpi_options |= TCPI_OPT_TIMESTAMPS;
 1221         if (tp->t_flags & TF_SACK_PERMIT)
 1222                 ti->tcpi_options |= TCPI_OPT_SACK;
 1223         if ((tp->t_flags & TF_REQ_SCALE) && (tp->t_flags & TF_RCVD_SCALE)) {
 1224                 ti->tcpi_options |= TCPI_OPT_WSCALE;
 1225                 ti->tcpi_snd_wscale = tp->snd_scale;
 1226                 ti->tcpi_rcv_wscale = tp->rcv_scale;
 1227         }
 1228 
 1229         ti->tcpi_rto = tp->t_rxtcur * tick;
 1230         ti->tcpi_last_data_recv = (long)(ticks - (int)tp->t_rcvtime) * tick;
 1231         ti->tcpi_rtt = ((u_int64_t)tp->t_srtt * tick) >> TCP_RTT_SHIFT;
 1232         ti->tcpi_rttvar = ((u_int64_t)tp->t_rttvar * tick) >> TCP_RTTVAR_SHIFT;
 1233 
 1234         ti->tcpi_snd_ssthresh = tp->snd_ssthresh;
 1235         ti->tcpi_snd_cwnd = tp->snd_cwnd;
 1236 
 1237         /*
 1238          * FreeBSD-specific extension fields for tcp_info.
 1239          */
 1240         ti->tcpi_rcv_space = tp->rcv_wnd;
 1241         ti->tcpi_rcv_nxt = tp->rcv_nxt;
 1242         ti->tcpi_snd_wnd = tp->snd_wnd;
 1243         ti->tcpi_snd_bwnd = 0;          /* Unused, kept for compat. */
 1244         ti->tcpi_snd_nxt = tp->snd_nxt;
 1245         ti->tcpi_snd_mss = tp->t_maxseg;
 1246         ti->tcpi_rcv_mss = tp->t_maxseg;
 1247         if (tp->t_flags & TF_TOE)
 1248                 ti->tcpi_options |= TCPI_OPT_TOE;
 1249         ti->tcpi_snd_rexmitpack = tp->t_sndrexmitpack;
 1250         ti->tcpi_rcv_ooopack = tp->t_rcvoopack;
 1251         ti->tcpi_snd_zerowin = tp->t_sndzerowin;
 1252 }
 1253 
 1254 /*
 1255  * tcp_ctloutput() must drop the inpcb lock before performing copyin on
 1256  * socket option arguments.  When it re-acquires the lock after the copy, it
 1257  * has to revalidate that the connection is still valid for the socket
 1258  * option.
 1259  */
 1260 #define INP_WLOCK_RECHECK(inp) do {                                     \
 1261         INP_WLOCK(inp);                                                 \
 1262         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {            \
 1263                 INP_WUNLOCK(inp);                                       \
 1264                 return (ECONNRESET);                                    \
 1265         }                                                               \
 1266         tp = intotcpcb(inp);                                            \
 1267 } while(0)
 1268 
 1269 int
 1270 tcp_ctloutput(struct socket *so, struct sockopt *sopt)
 1271 {
 1272         int     error, opt, optval;
 1273         struct  inpcb *inp;
 1274         struct  tcpcb *tp;
 1275         struct  tcp_info ti;
 1276         char buf[TCP_CA_NAME_MAX];
 1277         struct cc_algo *algo;
 1278 
 1279         error = 0;
 1280         inp = sotoinpcb(so);
 1281         KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL"));
 1282         INP_WLOCK(inp);
 1283         if (sopt->sopt_level != IPPROTO_TCP) {
 1284 #ifdef INET6
 1285                 if (inp->inp_vflag & INP_IPV6PROTO) {
 1286                         INP_WUNLOCK(inp);
 1287                         error = ip6_ctloutput(so, sopt);
 1288                 }
 1289 #endif /* INET6 */
 1290 #if defined(INET6) && defined(INET)
 1291                 else
 1292 #endif
 1293 #ifdef INET
 1294                 {
 1295                         INP_WUNLOCK(inp);
 1296                         error = ip_ctloutput(so, sopt);
 1297                 }
 1298 #endif
 1299                 return (error);
 1300         }
 1301         if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
 1302                 INP_WUNLOCK(inp);
 1303                 return (ECONNRESET);
 1304         }
 1305 
 1306         switch (sopt->sopt_dir) {
 1307         case SOPT_SET:
 1308                 switch (sopt->sopt_name) {
 1309 #ifdef TCP_SIGNATURE
 1310                 case TCP_MD5SIG:
 1311                         INP_WUNLOCK(inp);
 1312                         error = sooptcopyin(sopt, &optval, sizeof optval,
 1313                             sizeof optval);
 1314                         if (error)
 1315                                 return (error);
 1316 
 1317                         INP_WLOCK_RECHECK(inp);
 1318                         if (optval > 0)
 1319                                 tp->t_flags |= TF_SIGNATURE;
 1320                         else
 1321                                 tp->t_flags &= ~TF_SIGNATURE;
 1322                         INP_WUNLOCK(inp);
 1323                         break;
 1324 #endif /* TCP_SIGNATURE */
 1325                 case TCP_NODELAY:
 1326                 case TCP_NOOPT:
 1327                         INP_WUNLOCK(inp);
 1328                         error = sooptcopyin(sopt, &optval, sizeof optval,
 1329                             sizeof optval);
 1330                         if (error)
 1331                                 return (error);
 1332 
 1333                         INP_WLOCK_RECHECK(inp);
 1334                         switch (sopt->sopt_name) {
 1335                         case TCP_NODELAY:
 1336                                 opt = TF_NODELAY;
 1337                                 break;
 1338                         case TCP_NOOPT:
 1339                                 opt = TF_NOOPT;
 1340                                 break;
 1341                         default:
 1342                                 opt = 0; /* dead code to fool gcc */
 1343                                 break;
 1344                         }
 1345 
 1346                         if (optval)
 1347                                 tp->t_flags |= opt;
 1348                         else
 1349                                 tp->t_flags &= ~opt;
 1350                         INP_WUNLOCK(inp);
 1351                         break;
 1352 
 1353                 case TCP_NOPUSH:
 1354                         INP_WUNLOCK(inp);
 1355                         error = sooptcopyin(sopt, &optval, sizeof optval,
 1356                             sizeof optval);
 1357                         if (error)
 1358                                 return (error);
 1359 
 1360                         INP_WLOCK_RECHECK(inp);
 1361                         if (optval)
 1362                                 tp->t_flags |= TF_NOPUSH;
 1363                         else if (tp->t_flags & TF_NOPUSH) {
 1364                                 tp->t_flags &= ~TF_NOPUSH;
 1365                                 if (TCPS_HAVEESTABLISHED(tp->t_state))
 1366                                         error = tcp_output(tp);
 1367                         }
 1368                         INP_WUNLOCK(inp);
 1369                         break;
 1370 
 1371                 case TCP_MAXSEG:
 1372                         INP_WUNLOCK(inp);
 1373                         error = sooptcopyin(sopt, &optval, sizeof optval,
 1374                             sizeof optval);
 1375                         if (error)
 1376                                 return (error);
 1377 
 1378                         INP_WLOCK_RECHECK(inp);
 1379                         if (optval > 0 && optval <= tp->t_maxseg &&
 1380                             optval + 40 >= V_tcp_minmss)
 1381                                 tp->t_maxseg = optval;
 1382                         else
 1383                                 error = EINVAL;
 1384                         INP_WUNLOCK(inp);
 1385                         break;
 1386 
 1387                 case TCP_INFO:
 1388                         INP_WUNLOCK(inp);
 1389                         error = EINVAL;
 1390                         break;
 1391 
 1392                 case TCP_CONGESTION:
 1393                         INP_WUNLOCK(inp);
 1394                         bzero(buf, sizeof(buf));
 1395                         error = sooptcopyin(sopt, &buf, sizeof(buf), 1);
 1396                         if (error)
 1397                                 break;
 1398                         INP_WLOCK_RECHECK(inp);
 1399                         /*
 1400                          * Return EINVAL if we can't find the requested cc algo.
 1401                          */
 1402                         error = EINVAL;
 1403                         CC_LIST_RLOCK();
 1404                         STAILQ_FOREACH(algo, &cc_list, entries) {
 1405                                 if (strncmp(buf, algo->name, TCP_CA_NAME_MAX)
 1406                                     == 0) {
 1407                                         /* We've found the requested algo. */
 1408                                         error = 0;
 1409                                         /*
 1410                                          * We hold a write lock over the tcb
 1411                                          * so it's safe to do these things
 1412                                          * without ordering concerns.
 1413                                          */
 1414                                         if (CC_ALGO(tp)->cb_destroy != NULL)
 1415                                                 CC_ALGO(tp)->cb_destroy(tp->ccv);
 1416                                         CC_ALGO(tp) = algo;
 1417                                         /*
 1418                                          * If something goes pear shaped
 1419                                          * initialising the new algo,
 1420                                          * fall back to newreno (which
 1421                                          * does not require initialisation).
 1422                                          */
 1423                                         if (algo->cb_init != NULL)
 1424                                                 if (algo->cb_init(tp->ccv) > 0) {
 1425                                                         CC_ALGO(tp) = &newreno_cc_algo;
 1426                                                         /*
 1427                                                          * The only reason init
 1428                                                          * should fail is
 1429                                                          * because of malloc.
 1430                                                          */
 1431                                                         error = ENOMEM;
 1432                                                 }
 1433                                         break; /* Break the STAILQ_FOREACH. */
 1434                                 }
 1435                         }
 1436                         CC_LIST_RUNLOCK();
 1437                         INP_WUNLOCK(inp);
 1438                         break;
 1439 
 1440                 default:
 1441                         INP_WUNLOCK(inp);
 1442                         error = ENOPROTOOPT;
 1443                         break;
 1444                 }
 1445                 break;
 1446 
 1447         case SOPT_GET:
 1448                 tp = intotcpcb(inp);
 1449                 switch (sopt->sopt_name) {
 1450 #ifdef TCP_SIGNATURE
 1451                 case TCP_MD5SIG:
 1452                         optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
 1453                         INP_WUNLOCK(inp);
 1454                         error = sooptcopyout(sopt, &optval, sizeof optval);
 1455                         break;
 1456 #endif
 1457 
 1458                 case TCP_NODELAY:
 1459                         optval = tp->t_flags & TF_NODELAY;
 1460                         INP_WUNLOCK(inp);
 1461                         error = sooptcopyout(sopt, &optval, sizeof optval);
 1462                         break;
 1463                 case TCP_MAXSEG:
 1464                         optval = tp->t_maxseg;
 1465                         INP_WUNLOCK(inp);
 1466                         error = sooptcopyout(sopt, &optval, sizeof optval);
 1467                         break;
 1468                 case TCP_NOOPT:
 1469                         optval = tp->t_flags & TF_NOOPT;
 1470                         INP_WUNLOCK(inp);
 1471                         error = sooptcopyout(sopt, &optval, sizeof optval);
 1472                         break;
 1473                 case TCP_NOPUSH:
 1474                         optval = tp->t_flags & TF_NOPUSH;
 1475                         INP_WUNLOCK(inp);
 1476                         error = sooptcopyout(sopt, &optval, sizeof optval);
 1477                         break;
 1478                 case TCP_INFO:
 1479                         tcp_fill_info(tp, &ti);
 1480                         INP_WUNLOCK(inp);
 1481                         error = sooptcopyout(sopt, &ti, sizeof ti);
 1482                         break;
 1483                 case TCP_CONGESTION:
 1484                         bzero(buf, sizeof(buf));
 1485                         strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX);
 1486                         INP_WUNLOCK(inp);
 1487                         error = sooptcopyout(sopt, buf, TCP_CA_NAME_MAX);
 1488                         break;
 1489                 default:
 1490                         INP_WUNLOCK(inp);
 1491                         error = ENOPROTOOPT;
 1492                         break;
 1493                 }
 1494                 break;
 1495         }
 1496         return (error);
 1497 }
 1498 #undef INP_WLOCK_RECHECK
 1499 
 1500 /*
 1501  * tcp_sendspace and tcp_recvspace are the default send and receive window
 1502  * sizes, respectively.  These are obsolescent (this information should
 1503  * be set by the route).
 1504  */
 1505 u_long  tcp_sendspace = 1024*32;
 1506 SYSCTL_ULONG(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLFLAG_RW,
 1507     &tcp_sendspace , 0, "Maximum outgoing TCP datagram size");
 1508 u_long  tcp_recvspace = 1024*64;
 1509 SYSCTL_ULONG(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
 1510     &tcp_recvspace , 0, "Maximum incoming TCP datagram size");
 1511 
 1512 /*
 1513  * Attach TCP protocol to socket, allocating
 1514  * internet protocol control block, tcp control block,
 1515  * bufer space, and entering LISTEN state if to accept connections.
 1516  */
 1517 static int
 1518 tcp_attach(struct socket *so)
 1519 {
 1520         struct tcpcb *tp;
 1521         struct inpcb *inp;
 1522         int error;
 1523 
 1524         if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
 1525                 error = soreserve(so, tcp_sendspace, tcp_recvspace);
 1526                 if (error)
 1527                         return (error);
 1528         }
 1529         so->so_rcv.sb_flags |= SB_AUTOSIZE;
 1530         so->so_snd.sb_flags |= SB_AUTOSIZE;
 1531         INP_INFO_WLOCK(&V_tcbinfo);
 1532         error = in_pcballoc(so, &V_tcbinfo);
 1533         if (error) {
 1534                 INP_INFO_WUNLOCK(&V_tcbinfo);
 1535                 return (error);
 1536         }
 1537         inp = sotoinpcb(so);
 1538 #ifdef INET6
 1539         if (inp->inp_vflag & INP_IPV6PROTO) {
 1540                 inp->inp_vflag |= INP_IPV6;
 1541                 inp->in6p_hops = -1;    /* use kernel default */
 1542         }
 1543         else
 1544 #endif
 1545         inp->inp_vflag |= INP_IPV4;
 1546         tp = tcp_newtcpcb(inp);
 1547         if (tp == NULL) {
 1548                 in_pcbdetach(inp);
 1549                 in_pcbfree(inp);
 1550                 INP_INFO_WUNLOCK(&V_tcbinfo);
 1551                 return (ENOBUFS);
 1552         }
 1553         tp->t_state = TCPS_CLOSED;
 1554         INP_WUNLOCK(inp);
 1555         INP_INFO_WUNLOCK(&V_tcbinfo);
 1556         return (0);
 1557 }
 1558 
 1559 /*
 1560  * Initiate (or continue) disconnect.
 1561  * If embryonic state, just send reset (once).
 1562  * If in ``let data drain'' option and linger null, just drop.
 1563  * Otherwise (hard), mark socket disconnecting and drop
 1564  * current input data; switch states based on user close, and
 1565  * send segment to peer (with FIN).
 1566  */
 1567 static void
 1568 tcp_disconnect(struct tcpcb *tp)
 1569 {
 1570         struct inpcb *inp = tp->t_inpcb;
 1571         struct socket *so = inp->inp_socket;
 1572 
 1573         INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
 1574         INP_WLOCK_ASSERT(inp);
 1575 
 1576         /*
 1577          * Neither tcp_close() nor tcp_drop() should return NULL, as the
 1578          * socket is still open.
 1579          */
 1580         if (tp->t_state < TCPS_ESTABLISHED) {
 1581                 tp = tcp_close(tp);
 1582                 KASSERT(tp != NULL,
 1583                     ("tcp_disconnect: tcp_close() returned NULL"));
 1584         } else if ((so->so_options & SO_LINGER) && so->so_linger == 0) {
 1585                 tp = tcp_drop(tp, 0);
 1586                 KASSERT(tp != NULL,
 1587                     ("tcp_disconnect: tcp_drop() returned NULL"));
 1588         } else {
 1589                 soisdisconnecting(so);
 1590                 sbflush(&so->so_rcv);
 1591                 tcp_usrclosed(tp);
 1592                 if (!(inp->inp_flags & INP_DROPPED))
 1593                         tcp_output_disconnect(tp);
 1594         }
 1595 }
 1596 
 1597 /*
 1598  * User issued close, and wish to trail through shutdown states:
 1599  * if never received SYN, just forget it.  If got a SYN from peer,
 1600  * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
 1601  * If already got a FIN from peer, then almost done; go to LAST_ACK
 1602  * state.  In all other cases, have already sent FIN to peer (e.g.
 1603  * after PRU_SHUTDOWN), and just have to play tedious game waiting
 1604  * for peer to send FIN or not respond to keep-alives, etc.
 1605  * We can let the user exit from the close as soon as the FIN is acked.
 1606  */
 1607 static void
 1608 tcp_usrclosed(struct tcpcb *tp)
 1609 {
 1610 
 1611         INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
 1612         INP_WLOCK_ASSERT(tp->t_inpcb);
 1613 
 1614         switch (tp->t_state) {
 1615         case TCPS_LISTEN:
 1616                 tcp_offload_listen_close(tp);
 1617                 /* FALLTHROUGH */
 1618         case TCPS_CLOSED:
 1619                 tp->t_state = TCPS_CLOSED;
 1620                 tp = tcp_close(tp);
 1621                 /*
 1622                  * tcp_close() should never return NULL here as the socket is
 1623                  * still open.
 1624                  */
 1625                 KASSERT(tp != NULL,
 1626                     ("tcp_usrclosed: tcp_close() returned NULL"));
 1627                 break;
 1628 
 1629         case TCPS_SYN_SENT:
 1630         case TCPS_SYN_RECEIVED:
 1631                 tp->t_flags |= TF_NEEDFIN;
 1632                 break;
 1633 
 1634         case TCPS_ESTABLISHED:
 1635                 tp->t_state = TCPS_FIN_WAIT_1;
 1636                 break;
 1637 
 1638         case TCPS_CLOSE_WAIT:
 1639                 tp->t_state = TCPS_LAST_ACK;
 1640                 break;
 1641         }
 1642         if (tp->t_state >= TCPS_FIN_WAIT_2) {
 1643                 soisdisconnected(tp->t_inpcb->inp_socket);
 1644                 /* Prevent the connection hanging in FIN_WAIT_2 forever. */
 1645                 if (tp->t_state == TCPS_FIN_WAIT_2) {
 1646                         int timeout;
 1647 
 1648                         timeout = (tcp_fast_finwait2_recycle) ? 
 1649                             tcp_finwait2_timeout : tcp_maxidle;
 1650                         tcp_timer_activate(tp, TT_2MSL, timeout);
 1651                 }
 1652         }
 1653 }
 1654 
 1655 #ifdef DDB
 1656 static void
 1657 db_print_indent(int indent)
 1658 {
 1659         int i;
 1660 
 1661         for (i = 0; i < indent; i++)
 1662                 db_printf(" ");
 1663 }
 1664 
 1665 static void
 1666 db_print_tstate(int t_state)
 1667 {
 1668 
 1669         switch (t_state) {
 1670         case TCPS_CLOSED:
 1671                 db_printf("TCPS_CLOSED");
 1672                 return;
 1673 
 1674         case TCPS_LISTEN:
 1675                 db_printf("TCPS_LISTEN");
 1676                 return;
 1677 
 1678         case TCPS_SYN_SENT:
 1679                 db_printf("TCPS_SYN_SENT");
 1680                 return;
 1681 
 1682         case TCPS_SYN_RECEIVED:
 1683                 db_printf("TCPS_SYN_RECEIVED");
 1684                 return;
 1685 
 1686         case TCPS_ESTABLISHED:
 1687                 db_printf("TCPS_ESTABLISHED");
 1688                 return;
 1689 
 1690         case TCPS_CLOSE_WAIT:
 1691                 db_printf("TCPS_CLOSE_WAIT");
 1692                 return;
 1693 
 1694         case TCPS_FIN_WAIT_1:
 1695                 db_printf("TCPS_FIN_WAIT_1");
 1696                 return;
 1697 
 1698         case TCPS_CLOSING:
 1699                 db_printf("TCPS_CLOSING");
 1700                 return;
 1701 
 1702         case TCPS_LAST_ACK:
 1703                 db_printf("TCPS_LAST_ACK");
 1704                 return;
 1705 
 1706         case TCPS_FIN_WAIT_2:
 1707                 db_printf("TCPS_FIN_WAIT_2");
 1708                 return;
 1709 
 1710         case TCPS_TIME_WAIT:
 1711                 db_printf("TCPS_TIME_WAIT");
 1712                 return;
 1713 
 1714         default:
 1715                 db_printf("unknown");
 1716                 return;
 1717         }
 1718 }
 1719 
 1720 static void
 1721 db_print_tflags(u_int t_flags)
 1722 {
 1723         int comma;
 1724 
 1725         comma = 0;
 1726         if (t_flags & TF_ACKNOW) {
 1727                 db_printf("%sTF_ACKNOW", comma ? ", " : "");
 1728                 comma = 1;
 1729         }
 1730         if (t_flags & TF_DELACK) {
 1731                 db_printf("%sTF_DELACK", comma ? ", " : "");
 1732                 comma = 1;
 1733         }
 1734         if (t_flags & TF_NODELAY) {
 1735                 db_printf("%sTF_NODELAY", comma ? ", " : "");
 1736                 comma = 1;
 1737         }
 1738         if (t_flags & TF_NOOPT) {
 1739                 db_printf("%sTF_NOOPT", comma ? ", " : "");
 1740                 comma = 1;
 1741         }
 1742         if (t_flags & TF_SENTFIN) {
 1743                 db_printf("%sTF_SENTFIN", comma ? ", " : "");
 1744                 comma = 1;
 1745         }
 1746         if (t_flags & TF_REQ_SCALE) {
 1747                 db_printf("%sTF_REQ_SCALE", comma ? ", " : "");
 1748                 comma = 1;
 1749         }
 1750         if (t_flags & TF_RCVD_SCALE) {
 1751                 db_printf("%sTF_RECVD_SCALE", comma ? ", " : "");
 1752                 comma = 1;
 1753         }
 1754         if (t_flags & TF_REQ_TSTMP) {
 1755                 db_printf("%sTF_REQ_TSTMP", comma ? ", " : "");
 1756                 comma = 1;
 1757         }
 1758         if (t_flags & TF_RCVD_TSTMP) {
 1759                 db_printf("%sTF_RCVD_TSTMP", comma ? ", " : "");
 1760                 comma = 1;
 1761         }
 1762         if (t_flags & TF_SACK_PERMIT) {
 1763                 db_printf("%sTF_SACK_PERMIT", comma ? ", " : "");
 1764                 comma = 1;
 1765         }
 1766         if (t_flags & TF_NEEDSYN) {
 1767                 db_printf("%sTF_NEEDSYN", comma ? ", " : "");
 1768                 comma = 1;
 1769         }
 1770         if (t_flags & TF_NEEDFIN) {
 1771                 db_printf("%sTF_NEEDFIN", comma ? ", " : "");
 1772                 comma = 1;
 1773         }
 1774         if (t_flags & TF_NOPUSH) {
 1775                 db_printf("%sTF_NOPUSH", comma ? ", " : "");
 1776                 comma = 1;
 1777         }
 1778         if (t_flags & TF_MORETOCOME) {
 1779                 db_printf("%sTF_MORETOCOME", comma ? ", " : "");
 1780                 comma = 1;
 1781         }
 1782         if (t_flags & TF_LQ_OVERFLOW) {
 1783                 db_printf("%sTF_LQ_OVERFLOW", comma ? ", " : "");
 1784                 comma = 1;
 1785         }
 1786         if (t_flags & TF_LASTIDLE) {
 1787                 db_printf("%sTF_LASTIDLE", comma ? ", " : "");
 1788                 comma = 1;
 1789         }
 1790         if (t_flags & TF_RXWIN0SENT) {
 1791                 db_printf("%sTF_RXWIN0SENT", comma ? ", " : "");
 1792                 comma = 1;
 1793         }
 1794         if (t_flags & TF_FASTRECOVERY) {
 1795                 db_printf("%sTF_FASTRECOVERY", comma ? ", " : "");
 1796                 comma = 1;
 1797         }
 1798         if (t_flags & TF_CONGRECOVERY) {
 1799                 db_printf("%sTF_CONGRECOVERY", comma ? ", " : "");
 1800                 comma = 1;
 1801         }
 1802         if (t_flags & TF_WASFRECOVERY) {
 1803                 db_printf("%sTF_WASFRECOVERY", comma ? ", " : "");
 1804                 comma = 1;
 1805         }
 1806         if (t_flags & TF_SIGNATURE) {
 1807                 db_printf("%sTF_SIGNATURE", comma ? ", " : "");
 1808                 comma = 1;
 1809         }
 1810         if (t_flags & TF_FORCEDATA) {
 1811                 db_printf("%sTF_FORCEDATA", comma ? ", " : "");
 1812                 comma = 1;
 1813         }
 1814         if (t_flags & TF_TSO) {
 1815                 db_printf("%sTF_TSO", comma ? ", " : "");
 1816                 comma = 1;
 1817         }
 1818         if (t_flags & TF_ECN_PERMIT) {
 1819                 db_printf("%sTF_ECN_PERMIT", comma ? ", " : "");
 1820                 comma = 1;
 1821         }
 1822 }
 1823 
 1824 static void
 1825 db_print_toobflags(char t_oobflags)
 1826 {
 1827         int comma;
 1828 
 1829         comma = 0;
 1830         if (t_oobflags & TCPOOB_HAVEDATA) {
 1831                 db_printf("%sTCPOOB_HAVEDATA", comma ? ", " : "");
 1832                 comma = 1;
 1833         }
 1834         if (t_oobflags & TCPOOB_HADDATA) {
 1835                 db_printf("%sTCPOOB_HADDATA", comma ? ", " : "");
 1836                 comma = 1;
 1837         }
 1838 }
 1839 
 1840 static void
 1841 db_print_tcpcb(struct tcpcb *tp, const char *name, int indent)
 1842 {
 1843 
 1844         db_print_indent(indent);
 1845         db_printf("%s at %p\n", name, tp);
 1846 
 1847         indent += 2;
 1848 
 1849         db_print_indent(indent);
 1850         db_printf("t_segq first: %p   t_segqlen: %d   t_dupacks: %d\n",
 1851            LIST_FIRST(&tp->t_segq), tp->t_segqlen, tp->t_dupacks);
 1852 
 1853         db_print_indent(indent);
 1854         db_printf("tt_rexmt: %p   tt_persist: %p   tt_keep: %p\n",
 1855             &tp->t_timers->tt_rexmt, &tp->t_timers->tt_persist, &tp->t_timers->tt_keep);
 1856 
 1857         db_print_indent(indent);
 1858         db_printf("tt_2msl: %p   tt_delack: %p   t_inpcb: %p\n", &tp->t_timers->tt_2msl,
 1859             &tp->t_timers->tt_delack, tp->t_inpcb);
 1860 
 1861         db_print_indent(indent);
 1862         db_printf("t_state: %d (", tp->t_state);
 1863         db_print_tstate(tp->t_state);
 1864         db_printf(")\n");
 1865 
 1866         db_print_indent(indent);
 1867         db_printf("t_flags: 0x%x (", tp->t_flags);
 1868         db_print_tflags(tp->t_flags);
 1869         db_printf(")\n");
 1870 
 1871         db_print_indent(indent);
 1872         db_printf("snd_una: 0x%08x   snd_max: 0x%08x   snd_nxt: x0%08x\n",
 1873             tp->snd_una, tp->snd_max, tp->snd_nxt);
 1874 
 1875         db_print_indent(indent);
 1876         db_printf("snd_up: 0x%08x   snd_wl1: 0x%08x   snd_wl2: 0x%08x\n",
 1877            tp->snd_up, tp->snd_wl1, tp->snd_wl2);
 1878 
 1879         db_print_indent(indent);
 1880         db_printf("iss: 0x%08x   irs: 0x%08x   rcv_nxt: 0x%08x\n",
 1881             tp->iss, tp->irs, tp->rcv_nxt);
 1882 
 1883         db_print_indent(indent);
 1884         db_printf("rcv_adv: 0x%08x   rcv_wnd: %lu   rcv_up: 0x%08x\n",
 1885             tp->rcv_adv, tp->rcv_wnd, tp->rcv_up);
 1886 
 1887         db_print_indent(indent);
 1888         db_printf("snd_wnd: %lu   snd_cwnd: %lu\n",
 1889            tp->snd_wnd, tp->snd_cwnd);
 1890 
 1891         db_print_indent(indent);
 1892         db_printf("snd_ssthresh: %lu   snd_recover: "
 1893             "0x%08x\n", tp->snd_ssthresh, tp->snd_recover);
 1894 
 1895         db_print_indent(indent);
 1896         db_printf("t_maxopd: %u   t_rcvtime: %u   t_startime: %u\n",
 1897             tp->t_maxopd, tp->t_rcvtime, tp->t_starttime);
 1898 
 1899         db_print_indent(indent);
 1900         db_printf("t_rttime: %u   t_rtsq: 0x%08x\n",
 1901             tp->t_rtttime, tp->t_rtseq);
 1902 
 1903         db_print_indent(indent);
 1904         db_printf("t_rxtcur: %d   t_maxseg: %u   t_srtt: %d\n",
 1905             tp->t_rxtcur, tp->t_maxseg, tp->t_srtt);
 1906 
 1907         db_print_indent(indent);
 1908         db_printf("t_rttvar: %d   t_rxtshift: %d   t_rttmin: %u   "
 1909             "t_rttbest: %u\n", tp->t_rttvar, tp->t_rxtshift, tp->t_rttmin,
 1910             tp->t_rttbest);
 1911 
 1912         db_print_indent(indent);
 1913         db_printf("t_rttupdated: %lu   max_sndwnd: %lu   t_softerror: %d\n",
 1914             tp->t_rttupdated, tp->max_sndwnd, tp->t_softerror);
 1915 
 1916         db_print_indent(indent);
 1917         db_printf("t_oobflags: 0x%x (", tp->t_oobflags);
 1918         db_print_toobflags(tp->t_oobflags);
 1919         db_printf(")   t_iobc: 0x%02x\n", tp->t_iobc);
 1920 
 1921         db_print_indent(indent);
 1922         db_printf("snd_scale: %u   rcv_scale: %u   request_r_scale: %u\n",
 1923             tp->snd_scale, tp->rcv_scale, tp->request_r_scale);
 1924 
 1925         db_print_indent(indent);
 1926         db_printf("ts_recent: %u   ts_recent_age: %u\n",
 1927             tp->ts_recent, tp->ts_recent_age);
 1928 
 1929         db_print_indent(indent);
 1930         db_printf("ts_offset: %u   last_ack_sent: 0x%08x   snd_cwnd_prev: "
 1931             "%lu\n", tp->ts_offset, tp->last_ack_sent, tp->snd_cwnd_prev);
 1932 
 1933         db_print_indent(indent);
 1934         db_printf("snd_ssthresh_prev: %lu   snd_recover_prev: 0x%08x   "
 1935             "t_badrxtwin: %u\n", tp->snd_ssthresh_prev,
 1936             tp->snd_recover_prev, tp->t_badrxtwin);
 1937 
 1938         db_print_indent(indent);
 1939         db_printf("snd_numholes: %d  snd_holes first: %p\n",
 1940             tp->snd_numholes, TAILQ_FIRST(&tp->snd_holes));
 1941 
 1942         db_print_indent(indent);
 1943         db_printf("snd_fack: 0x%08x   rcv_numsacks: %d   sack_newdata: "
 1944             "0x%08x\n", tp->snd_fack, tp->rcv_numsacks, tp->sack_newdata);
 1945 
 1946         /* Skip sackblks, sackhint. */
 1947 
 1948         db_print_indent(indent);
 1949         db_printf("t_rttlow: %d   rfbuf_ts: %u   rfbuf_cnt: %d\n",
 1950             tp->t_rttlow, tp->rfbuf_ts, tp->rfbuf_cnt);
 1951 }
 1952 
 1953 DB_SHOW_COMMAND(tcpcb, db_show_tcpcb)
 1954 {
 1955         struct tcpcb *tp;
 1956 
 1957         if (!have_addr) {
 1958                 db_printf("usage: show tcpcb <addr>\n");
 1959                 return;
 1960         }
 1961         tp = (struct tcpcb *)addr;
 1962 
 1963         db_print_tcpcb(tp, "tcpcb", 0);
 1964 }
 1965 #endif

Cache object: d61780939184bfd5c22865f6825b1412


[ 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.