2  * Copyright (c) 2000-2016 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1982, 1986, 1988, 1993 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  35  * 1. Redistributions of source code must retain the above copyright 
  36  *    notice, this list of conditions and the following disclaimer. 
  37  * 2. Redistributions in binary form must reproduce the above copyright 
  38  *    notice, this list of conditions and the following disclaimer in the 
  39  *    documentation and/or other materials provided with the distribution. 
  40  * 3. All advertising materials mentioning features or use of this software 
  41  *    must display the following acknowledgement: 
  42  *      This product includes software developed by the University of 
  43  *      California, Berkeley and its contributors. 
  44  * 4. Neither the name of the University nor the names of its contributors 
  45  *    may be used to endorse or promote products derived from this software 
  46  *    without specific prior written permission. 
  48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  60  *      From: @(#)tcp_usrreq.c  8.2 (Berkeley) 1/3/94 
  61  * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.51.2.9 2001/08/22 00:59:12 silby Exp $ 
  65 #include <sys/param.h> 
  66 #include <sys/systm.h> 
  67 #include <sys/kernel.h> 
  68 #include <sys/sysctl.h> 
  71 #include <sys/domain.h> 
  74 #include <sys/socket.h> 
  75 #include <sys/socketvar.h> 
  76 #include <sys/protosw.h> 
  77 #include <sys/syslog.h> 
  80 #include <net/route.h> 
  81 #include <net/ntstat.h> 
  82 #include <net/content_filter.h> 
  84 #include <netinet/in.h> 
  85 #include <netinet/in_systm.h> 
  87 #include <netinet/ip6.h> 
  89 #include <netinet/in_pcb.h> 
  91 #include <netinet6/in6_pcb.h> 
  93 #include <netinet/in_var.h> 
  94 #include <netinet/ip_var.h> 
  96 #include <netinet6/ip6_var.h> 
  98 #include <netinet/tcp.h> 
  99 #include <netinet/tcp_fsm.h> 
 100 #include <netinet/tcp_seq.h> 
 101 #include <netinet/tcp_timer.h> 
 102 #include <netinet/tcp_var.h> 
 103 #include <netinet/tcpip.h> 
 104 #include <mach/sdt.h> 
 106 #include <netinet/tcp_debug.h> 
 109 #include <netinet/mptcp_var.h> 
 113 #include <netinet6/ipsec.h> 
 117 #include <netinet/flow_divert.h> 
 118 #endif /* FLOW_DIVERT */ 
 120 void    tcp_fill_info(struct tcpcb 
*, struct tcp_info 
*); 
 121 errno_t 
tcp_fill_info_for_info_tuple(struct info_tuple 
*, struct tcp_info 
*); 
 123 int tcp_sysctl_info(struct sysctl_oid 
*, void *, int , struct sysctl_req 
*); 
 124 static void tcp_connection_fill_info(struct tcpcb 
*tp
, 
 125     struct tcp_connection_info 
*tci
); 
 128  * TCP protocol interface to socket abstraction. 
 130 extern  char *tcpstates
[];      /* XXX ??? */ 
 132 static int      tcp_attach(struct socket 
*, struct proc 
*); 
 133 static int      tcp_connect(struct tcpcb 
*, struct sockaddr 
*, struct proc 
*); 
 135 static int      tcp6_connect(struct tcpcb 
*, struct sockaddr 
*, struct proc 
*); 
 136 static int      tcp6_usr_connect(struct socket 
*, struct sockaddr 
*, 
 139 static struct tcpcb 
*tcp_disconnect(struct tcpcb 
*); 
 140 static struct tcpcb 
*tcp_usrclosed(struct tcpcb 
*); 
 141 extern void tcp_sbrcv_trim(struct tcpcb 
*tp
, struct sockbuf 
*sb
); 
 144 #define TCPDEBUG0       int ostate = 0 
 145 #define TCPDEBUG1()     ostate = tp ? tp->t_state : 0 
 146 #define TCPDEBUG2(req)  if (tp && (so->so_options & SO_DEBUG)) \ 
 147                                 tcp_trace(TA_USER, ostate, tp, 0, 0, req) 
 151 #define TCPDEBUG2(req) 
 154 SYSCTL_PROC(_net_inet_tcp
, OID_AUTO
, info
, 
 155     CTLFLAG_RW 
| CTLFLAG_LOCKED 
| CTLFLAG_ANYBODY 
| CTLFLAG_KERN
, 
 156     0 , 0, tcp_sysctl_info
, "S", "TCP info per tuple"); 
 159  * TCP attaches to socket via pru_attach(), reserving space, 
 160  * and an internet control block. 
 166  *      tcp_attach:???                  [IPSEC specific] 
 169 tcp_usr_attach(struct socket 
*so
, __unused 
int proto
, struct proc 
*p
) 
 172         struct inpcb 
*inp 
= sotoinpcb(so
); 
 173         struct tcpcb 
*tp 
= 0; 
 182         error 
= tcp_attach(so
, p
); 
 186         if ((so
->so_options 
& SO_LINGER
) && so
->so_linger 
== 0) 
 187                 so
->so_linger 
= TCP_LINGERTIME 
* hz
; 
 190         TCPDEBUG2(PRU_ATTACH
); 
 195  * pru_detach() detaches the TCP protocol from the socket. 
 196  * If the protocol state is non-embryonic, then can't 
 197  * do this directly: have to initiate a pru_disconnect(), 
 198  * which may finish later; embryonic TCB's can just 
 202 tcp_usr_detach(struct socket 
*so
) 
 205         struct inpcb 
*inp 
= sotoinpcb(so
); 
 209         if (inp 
== 0 || (inp
->inp_state 
== INPCB_STATE_DEAD
)) { 
 210                 return EINVAL
;  /* XXX */ 
 212         lck_mtx_assert(&((struct inpcb 
*)so
->so_pcb
)->inpcb_mtx
, LCK_MTX_ASSERT_OWNED
); 
 214         /* In case we got disconnected from the peer */ 
 219         calculate_tcp_clock(); 
 221         tp 
= tcp_disconnect(tp
); 
 223         TCPDEBUG2(PRU_DETACH
); 
 228 #define COMMON_START()  TCPDEBUG0;                                      \ 
 230         if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD)          \ 
 232         if (necp_socket_should_use_flow_divert(inp))                    \ 
 233                 return (EPROTOTYPE);                                    \ 
 234         tp = intotcpcb(inp);                                            \ 
 236         calculate_tcp_clock();                                          \ 
 239 #define COMMON_START()  TCPDEBUG0;                                      \ 
 241         if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD)          \ 
 243         tp = intotcpcb(inp);                                            \ 
 245         calculate_tcp_clock();                                          \ 
 249 #define COMMON_END(req) out: TCPDEBUG2(req); return error; goto out 
 253  * Give the socket an address. 
 256  *              EINVAL                  Invalid argument [COMMON_START] 
 257  *              EAFNOSUPPORT            Address family not supported 
 258  *      in_pcbbind:EADDRNOTAVAIL        Address not available. 
 259  *      in_pcbbind:EINVAL               Invalid argument 
 260  *      in_pcbbind:EAFNOSUPPORT         Address family not supported [notdef] 
 261  *      in_pcbbind:EACCES               Permission denied 
 262  *      in_pcbbind:EADDRINUSE           Address in use 
 263  *      in_pcbbind:EAGAIN               Resource unavailable, try again 
 264  *      in_pcbbind:EPERM                Operation not permitted 
 267 tcp_usr_bind(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 270         struct inpcb 
*inp 
= sotoinpcb(so
); 
 272         struct sockaddr_in 
*sinp
; 
 276         if (nam
->sa_family 
!= 0 && nam
->sa_family 
!= AF_INET
) { 
 277                 error 
= EAFNOSUPPORT
; 
 282          * Must check for multicast addresses and disallow binding 
 285         sinp 
= (struct sockaddr_in 
*)(void *)nam
; 
 286         if (sinp
->sin_family 
== AF_INET 
&& 
 287             IN_MULTICAST(ntohl(sinp
->sin_addr
.s_addr
))) { 
 288                 error 
= EAFNOSUPPORT
; 
 291         error 
= in_pcbbind(inp
, nam
, p
); 
 294         COMMON_END(PRU_BIND
); 
 300 tcp6_usr_bind(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 303         struct inpcb 
*inp 
= sotoinpcb(so
); 
 305         struct sockaddr_in6 
*sin6p
; 
 309         if (nam
->sa_family 
!= 0 && nam
->sa_family 
!= AF_INET6
) { 
 310                 error 
= EAFNOSUPPORT
; 
 315          * Must check for multicast addresses and disallow binding 
 318         sin6p 
= (struct sockaddr_in6 
*)(void *)nam
; 
 319         if (sin6p
->sin6_family 
== AF_INET6 
&& 
 320             IN6_IS_ADDR_MULTICAST(&sin6p
->sin6_addr
)) { 
 321                 error 
= EAFNOSUPPORT
; 
 324         inp
->inp_vflag 
&= ~INP_IPV4
; 
 325         inp
->inp_vflag 
|= INP_IPV6
; 
 326         if ((inp
->inp_flags 
& IN6P_IPV6_V6ONLY
) == 0) { 
 327                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6p
->sin6_addr
)) 
 328                         inp
->inp_vflag 
|= INP_IPV4
; 
 329                 else if (IN6_IS_ADDR_V4MAPPED(&sin6p
->sin6_addr
)) { 
 330                         struct sockaddr_in sin
; 
 332                         in6_sin6_2_sin(&sin
, sin6p
); 
 333                         inp
->inp_vflag 
|= INP_IPV4
; 
 334                         inp
->inp_vflag 
&= ~INP_IPV6
; 
 335                         error 
= in_pcbbind(inp
, (struct sockaddr 
*)&sin
, p
); 
 339         error 
= in6_pcbbind(inp
, nam
, p
); 
 342         COMMON_END(PRU_BIND
); 
 347  * Prepare to accept connections. 
 350  *              EINVAL [COMMON_START] 
 351  *      in_pcbbind:EADDRNOTAVAIL        Address not available. 
 352  *      in_pcbbind:EINVAL               Invalid argument 
 353  *      in_pcbbind:EAFNOSUPPORT         Address family not supported [notdef] 
 354  *      in_pcbbind:EACCES               Permission denied 
 355  *      in_pcbbind:EADDRINUSE           Address in use 
 356  *      in_pcbbind:EAGAIN               Resource unavailable, try again 
 357  *      in_pcbbind:EPERM                Operation not permitted 
 360 tcp_usr_listen(struct socket 
*so
, struct proc 
*p
) 
 363         struct inpcb 
*inp 
= sotoinpcb(so
); 
 367         if (inp
->inp_lport 
== 0) 
 368                 error 
= in_pcbbind(inp
, NULL
, p
); 
 370                 tp
->t_state 
= TCPS_LISTEN
; 
 371         COMMON_END(PRU_LISTEN
); 
 376 tcp6_usr_listen(struct socket 
*so
, struct proc 
*p
) 
 379         struct inpcb 
*inp 
= sotoinpcb(so
); 
 383         if (inp
->inp_lport 
== 0) { 
 384                 inp
->inp_vflag 
&= ~INP_IPV4
; 
 385                 if ((inp
->inp_flags 
& IN6P_IPV6_V6ONLY
) == 0) 
 386                         inp
->inp_vflag 
|= INP_IPV4
; 
 387                 error 
= in6_pcbbind(inp
, NULL
, p
); 
 390                 tp
->t_state 
= TCPS_LISTEN
; 
 391         COMMON_END(PRU_LISTEN
); 
 396 tcp_connect_complete(struct socket 
*so
) 
 398         struct tcpcb 
*tp 
= sototcpcb(so
); 
 401         /* TFO delays the tcp_output until later, when the app calls write() */ 
 402         if (so
->so_flags1 
& SOF1_PRECONNECT_DATA
) { 
 403                 if (!necp_socket_is_allowed_to_send_recv(sotoinpcb(so
), NULL
, NULL
)) 
 404                         return (EHOSTUNREACH
); 
 406                 /* Initialize enough state so that we can actually send data */ 
 407                 tcp_mss(tp
, -1, IFSCOPE_NONE
); 
 408                 tp
->snd_wnd 
= tp
->t_maxseg
; 
 410                 error 
= tcp_output(tp
); 
 417  * Initiate connection to peer. 
 418  * Create a template for use in transmissions on this connection. 
 419  * Enter SYN_SENT state, and mark socket as connecting. 
 420  * Start keep-alive timer, and seed output sequence space. 
 421  * Send initial segment on connection. 
 424 tcp_usr_connect(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 427         struct inpcb 
*inp 
= sotoinpcb(so
); 
 429         struct sockaddr_in 
*sinp
; 
 434         } else if (inp
->inp_state 
== INPCB_STATE_DEAD
) { 
 436                         error 
= so
->so_error
; 
 444         else if (necp_socket_should_use_flow_divert(inp
)) { 
 445                 uint32_t fd_ctl_unit 
= necp_socket_get_flow_divert_control_unit(inp
); 
 446                 if (fd_ctl_unit 
> 0) { 
 447                         error 
= flow_divert_pcb_init(so
, fd_ctl_unit
); 
 449                                 error 
= flow_divert_connect_out(so
, nam
, p
); 
 457 #endif /* FLOW_DIVERT */ 
 459         error 
= cfil_sock_attach(so
); 
 462 #endif /* CONTENT_FILTER */ 
 467         calculate_tcp_clock(); 
 469         if (nam
->sa_family 
!= 0 && nam
->sa_family 
!= AF_INET
) { 
 470                 error 
= EAFNOSUPPORT
; 
 474          * Must disallow TCP ``connections'' to multicast addresses. 
 476         sinp 
= (struct sockaddr_in 
*)(void *)nam
; 
 477         if (sinp
->sin_family 
== AF_INET
 
 478             && IN_MULTICAST(ntohl(sinp
->sin_addr
.s_addr
))) { 
 479                 error 
= EAFNOSUPPORT
; 
 483         if ((error 
= tcp_connect(tp
, nam
, p
)) != 0) 
 486         error 
= tcp_connect_complete(so
); 
 488         COMMON_END(PRU_CONNECT
); 
 492 tcp_usr_connectx_common(struct socket 
*so
, int af
, 
 493     struct sockaddr_list 
**src_sl
, struct sockaddr_list 
**dst_sl
, 
 494     struct proc 
*p
, uint32_t ifscope
, sae_associd_t aid
, sae_connid_t 
*pcid
, 
 495     uint32_t flags
, void *arg
, uint32_t arglen
, struct uio 
*auio
, 
 496     user_ssize_t 
*bytes_written
) 
 500 #pragma unused(flags, arg, arglen) 
 502         struct sockaddr_entry 
*src_se 
= NULL
, *dst_se 
= NULL
; 
 503         struct inpcb 
*inp 
= sotoinpcb(so
); 
 505         user_ssize_t datalen 
= 0; 
 510         VERIFY(dst_sl 
!= NULL
); 
 512         /* select source (if specified) and destination addresses */ 
 513         error 
= in_selectaddrs(af
, src_sl
, &src_se
, dst_sl
, &dst_se
); 
 517         VERIFY(*dst_sl 
!= NULL 
&& dst_se 
!= NULL
); 
 518         VERIFY(src_se 
== NULL 
|| *src_sl 
!= NULL
); 
 519         VERIFY(dst_se
->se_addr
->sa_family 
== af
); 
 520         VERIFY(src_se 
== NULL 
|| src_se
->se_addr
->sa_family 
== af
); 
 523         inp_update_necp_policy(inp
, src_se 
? src_se
->se_addr 
: NULL
, dst_se 
? dst_se
->se_addr 
: NULL
, ifscope
); 
 526         if ((so
->so_flags1 
& SOF1_DATA_IDEMPOTENT
) && 
 527             (tcp_fastopen 
& TCP_FASTOPEN_CLIENT
)) 
 528                 sototcpcb(so
)->t_flagsext 
|= TF_FASTOPEN
; 
 531          * We get here for 2 cases: 
 533          *   a. From MPTCP, to connect a subflow.  There is no need to 
 534          *      bind the socket to the source address and/or interface, 
 535          *      since everything has been taken care of by MPTCP.  We 
 536          *      simply check whether or not this is for the initial 
 537          *      MPTCP connection attempt, or to join an existing one. 
 539          *   b. From the socket layer, to connect a TCP.  Perform the 
 540          *      bind to source address and/or interface as necessary. 
 543         if (flags 
& CONNREQF_MPTCP
) { 
 544                 struct mptsub_connreq 
*mpcr 
= arg
; 
 546                 /* Check to make sure this came down from MPTCP */ 
 547                 if (arg 
== NULL 
|| arglen 
!= sizeof (*mpcr
)) 
 550                 switch (mpcr
->mpcr_type
) { 
 551                 case MPTSUB_CONNREQ_MP_ENABLE
: 
 553                 case MPTSUB_CONNREQ_MP_ADD
: 
 561                 /* bind socket to the specified interface, if requested */ 
 562                 if (ifscope 
!= IFSCOPE_NONE 
&& 
 563                     (error 
= inp_bindif(inp
, ifscope
, NULL
)) != 0) 
 566                 /* if source address and/or port is specified, bind to it */ 
 567                 if (src_se 
!= NULL
) { 
 568                         struct sockaddr 
*sa 
= src_se
->se_addr
; 
 569                         error 
= sobindlock(so
, sa
, 0);  /* already locked */ 
 577                 error 
= tcp_usr_connect(so
, dst_se
->se_addr
, p
); 
 581                 error 
= tcp6_usr_connect(so
, dst_se
->se_addr
, p
); 
 592         /* if there is data, copy it */ 
 594                 socket_unlock(so
, 0); 
 596                 VERIFY(bytes_written 
!= NULL
); 
 598                 datalen 
= uio_resid(auio
); 
 599                 error 
= so
->so_proto
->pr_usrreqs
->pru_sosend(so
, NULL
, 
 600                     (uio_t
)auio
, NULL
, NULL
, 0); 
 603                 if (error 
== 0 || error 
== EWOULDBLOCK
) 
 604                         *bytes_written 
= datalen 
- uio_resid(auio
); 
 607                  * sosend returns EWOULDBLOCK if it's a non-blocking 
 608                  * socket or a timeout occured (this allows to return 
 609                  * the amount of queued data through sendit()). 
 611                  * However, connectx() returns EINPROGRESS in case of a 
 612                  * blocking socket. So we change the return value here. 
 614                 if (error 
== EWOULDBLOCK
) 
 618         if (error 
== 0 && pcid 
!= NULL
) 
 619                 *pcid 
= 1; /* there is only one connection in regular TCP */ 
 625 tcp_usr_connectx(struct socket 
*so
, struct sockaddr_list 
**src_sl
, 
 626     struct sockaddr_list 
**dst_sl
, struct proc 
*p
, uint32_t ifscope
, 
 627     sae_associd_t aid
, sae_connid_t 
*pcid
, uint32_t flags
, void *arg
, 
 628     uint32_t arglen
, struct uio 
*uio
, user_ssize_t 
*bytes_written
) 
 630         return (tcp_usr_connectx_common(so
, AF_INET
, src_sl
, dst_sl
, 
 631             p
, ifscope
, aid
, pcid
, flags
, arg
, arglen
, uio
, 
 637 tcp6_usr_connect(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 640         struct inpcb 
*inp 
= sotoinpcb(so
); 
 642         struct sockaddr_in6 
*sin6p
; 
 647         } else if (inp
->inp_state 
== INPCB_STATE_DEAD
) { 
 649                         error 
= so
->so_error
; 
 657         else if (necp_socket_should_use_flow_divert(inp
)) { 
 658                 uint32_t fd_ctl_unit 
= necp_socket_get_flow_divert_control_unit(inp
); 
 659                 if (fd_ctl_unit 
> 0) { 
 660                         error 
= flow_divert_pcb_init(so
, fd_ctl_unit
); 
 662                                 error 
= flow_divert_connect_out(so
, nam
, p
); 
 670 #endif /* FLOW_DIVERT */ 
 672         error 
= cfil_sock_attach(so
); 
 675 #endif /* CONTENT_FILTER */ 
 681         calculate_tcp_clock(); 
 683         if (nam
->sa_family 
!= 0 && nam
->sa_family 
!= AF_INET6
) { 
 684                 error 
= EAFNOSUPPORT
; 
 689          * Must disallow TCP ``connections'' to multicast addresses. 
 691         sin6p 
= (struct sockaddr_in6 
*)(void *)nam
; 
 692         if (sin6p
->sin6_family 
== AF_INET6
 
 693             && IN6_IS_ADDR_MULTICAST(&sin6p
->sin6_addr
)) { 
 694                 error 
= EAFNOSUPPORT
; 
 698         if (IN6_IS_ADDR_V4MAPPED(&sin6p
->sin6_addr
)) { 
 699                 struct sockaddr_in sin
; 
 701                 if ((inp
->inp_flags 
& IN6P_IPV6_V6ONLY
) != 0) 
 704                 in6_sin6_2_sin(&sin
, sin6p
); 
 705                 inp
->inp_vflag 
|= INP_IPV4
; 
 706                 inp
->inp_vflag 
&= ~INP_IPV6
; 
 707                 if ((error 
= tcp_connect(tp
, (struct sockaddr 
*)&sin
, p
)) != 0) 
 710                 error 
= tcp_connect_complete(so
); 
 713         inp
->inp_vflag 
&= ~INP_IPV4
; 
 714         inp
->inp_vflag 
|= INP_IPV6
; 
 715         if ((error 
= tcp6_connect(tp
, nam
, p
)) != 0) 
 718         error 
= tcp_connect_complete(so
); 
 719         COMMON_END(PRU_CONNECT
); 
 723 tcp6_usr_connectx(struct socket 
*so
, struct sockaddr_list 
**src_sl
, 
 724     struct sockaddr_list 
**dst_sl
, struct proc 
*p
, uint32_t ifscope
, 
 725     sae_associd_t aid
, sae_connid_t 
*pcid
, uint32_t flags
, void *arg
, 
 726     uint32_t arglen
, struct uio 
*uio
, user_ssize_t 
*bytes_written
) 
 728         return (tcp_usr_connectx_common(so
, AF_INET6
, src_sl
, dst_sl
, 
 729             p
, ifscope
, aid
, pcid
, flags
, arg
, arglen
, uio
, 
 735  * Initiate disconnect from peer. 
 736  * If connection never passed embryonic stage, just drop; 
 737  * else if don't need to let data drain, then can just drop anyways, 
 738  * else have to begin TCP shutdown process: mark socket disconnecting, 
 739  * drain unread data, state switch to reflect user close, and 
 740  * send segment (e.g. FIN) to peer.  Socket will be really disconnected 
 741  * when peer sends FIN and acks ours. 
 743  * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB. 
 746 tcp_usr_disconnect(struct socket 
*so
) 
 749         struct inpcb 
*inp 
= sotoinpcb(so
); 
 752         lck_mtx_assert(&((struct inpcb 
*)so
->so_pcb
)->inpcb_mtx
, 
 753             LCK_MTX_ASSERT_OWNED
); 
 755         /* In case we got disconnected from the peer */ 
 758         tp 
= tcp_disconnect(tp
); 
 759         COMMON_END(PRU_DISCONNECT
); 
 763  * User-protocol pru_disconnectx callback. 
 766 tcp_usr_disconnectx(struct socket 
*so
, sae_associd_t aid
, sae_connid_t cid
) 
 769         if (aid 
!= SAE_ASSOCID_ANY 
&& aid 
!= SAE_ASSOCID_ALL
) 
 772         return (tcp_usr_disconnect(so
)); 
 776  * Accept a connection.  Essentially all the work is 
 777  * done at higher levels; just return the address 
 778  * of the peer, storing through addr. 
 781 tcp_usr_accept(struct socket 
*so
, struct sockaddr 
**nam
) 
 784         struct inpcb 
*inp 
= sotoinpcb(so
); 
 785         struct tcpcb 
*tp 
= NULL
; 
 788         in_getpeeraddr(so
, nam
); 
 790         if (so
->so_state 
& SS_ISDISCONNECTED
) { 
 791                 error 
= ECONNABORTED
; 
 794         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
 797         else if (necp_socket_should_use_flow_divert(inp
)) 
 800         error 
= cfil_sock_attach(so
); 
 803 #endif /* CONTENT_FILTER */ 
 809         calculate_tcp_clock(); 
 811         COMMON_END(PRU_ACCEPT
); 
 816 tcp6_usr_accept(struct socket 
*so
, struct sockaddr 
**nam
) 
 819         struct inpcb 
*inp 
= sotoinpcb(so
); 
 820         struct tcpcb 
*tp 
= NULL
; 
 823         if (so
->so_state 
& SS_ISDISCONNECTED
) { 
 824                 error 
= ECONNABORTED
; 
 827         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
 830         else if (necp_socket_should_use_flow_divert(inp
)) 
 833         error 
= cfil_sock_attach(so
); 
 836 #endif /* CONTENT_FILTER */ 
 842         calculate_tcp_clock(); 
 844         in6_mapped_peeraddr(so
, nam
); 
 845         COMMON_END(PRU_ACCEPT
); 
 850  * Mark the connection as being incapable of further output. 
 853  *              EINVAL [COMMON_START] 
 854  *      tcp_output:EADDRNOTAVAIL 
 856  *      tcp_output:EMSGSIZE 
 857  *      tcp_output:EHOSTUNREACH 
 858  *      tcp_output:ENETUNREACH 
 859  *      tcp_output:ENETDOWN 
 862  *      tcp_output:EMSGSIZE 
 864  *      tcp_output:???                  [ignorable: mostly IPSEC/firewall/DLIL] 
 867 tcp_usr_shutdown(struct socket 
*so
) 
 870         struct inpcb 
*inp 
= sotoinpcb(so
); 
 874         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
 880          * In case we got disconnected from the peer, or if this is 
 881          * a socket that is to be flow-diverted (but not yet). 
 888                 || (necp_socket_should_use_flow_divert(inp
)) 
 896         calculate_tcp_clock(); 
 898         tp 
= tcp_usrclosed(tp
); 
 900         /* A reset has been sent but socket exists, do not send FIN */ 
 901         if ((so
->so_flags 
& SOF_MP_SUBFLOW
) && 
 902             (tp
) && (tp
->t_mpflags 
& TMPF_RESET
)) { 
 907         /* Don't send a FIN yet */ 
 908         if (tp 
&& !(so
->so_state 
& SS_ISDISCONNECTED
) && 
 909                 cfil_sock_data_pending(&so
->so_snd
)) 
 911 #endif /* CONTENT_FILTER */ 
 913                 error 
= tcp_output(tp
); 
 914         COMMON_END(PRU_SHUTDOWN
); 
 918  * After a receive, possibly send window update to peer. 
 921 tcp_usr_rcvd(struct socket 
*so
, __unused 
int flags
) 
 924         struct inpcb 
*inp 
= sotoinpcb(so
); 
 928         /* In case we got disconnected from the peer */ 
 931         tcp_sbrcv_trim(tp
, &so
->so_rcv
); 
 934          * This tcp_output is solely there to trigger window-updates. 
 935          * However, we really do not want these window-updates while we 
 936          * are still in SYN_SENT or SYN_RECEIVED. 
 938         if (TCPS_HAVEESTABLISHED(tp
->t_state
)) 
 942         cfil_sock_buf_update(&so
->so_rcv
); 
 943 #endif /* CONTENT_FILTER */ 
 945         COMMON_END(PRU_RCVD
); 
 949  * Do a send by putting data in output queue and updating urgent 
 950  * marker if URG set.  Possibly send more data.  Unlike the other 
 951  * pru_*() routines, the mbuf chains are our responsibility.  We 
 952  * must either enqueue them or free them.  The other pru_* routines 
 953  * generally are caller-frees. 
 959  *      tcp_connect:EADDRINUSE          Address in use 
 960  *      tcp_connect:EADDRNOTAVAIL       Address not available. 
 961  *      tcp_connect:EINVAL              Invalid argument 
 962  *      tcp_connect:EAFNOSUPPORT        Address family not supported [notdef] 
 963  *      tcp_connect:EACCES              Permission denied 
 964  *      tcp_connect:EAGAIN              Resource unavailable, try again 
 965  *      tcp_connect:EPERM               Operation not permitted 
 966  *      tcp_output:EADDRNOTAVAIL 
 968  *      tcp_output:EMSGSIZE 
 969  *      tcp_output:EHOSTUNREACH 
 970  *      tcp_output:ENETUNREACH 
 971  *      tcp_output:ENETDOWN 
 974  *      tcp_output:EMSGSIZE 
 976  *      tcp_output:???                  [ignorable: mostly IPSEC/firewall/DLIL] 
 977  *      tcp6_connect:???                [IPV6 only] 
 980 tcp_usr_send(struct socket 
*so
, int flags
, struct mbuf 
*m
, 
 981      struct sockaddr 
*nam
, struct mbuf 
*control
, struct proc 
*p
) 
 984         struct inpcb 
*inp 
= sotoinpcb(so
); 
 986         uint32_t msgpri 
= MSG_PRI_DEFAULT
; 
 992         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
 
 994                 || (necp_socket_should_use_flow_divert(inp
)) 
 998                  * OOPS! we lost a race, the TCP session got reset after 
 999                  * we checked SS_CANTSENDMORE, eg: while doing uiomove or a 
1000                  * network interrupt in the non-splnet() section of sosend(). 
1004                 if (control 
!= NULL
) { 
1010                         error 
= ECONNRESET
;     /* XXX EPIPE? */ 
1018         isipv6 
= nam 
&& nam
->sa_family 
== AF_INET6
; 
1020         tp 
= intotcpcb(inp
); 
1023         calculate_tcp_clock(); 
1025         if (control 
!= NULL
) { 
1026                 if (so
->so_flags 
& SOF_ENABLE_MSGS
) { 
1027                         /* Get the msg priority from control mbufs */ 
1028                         error 
= tcp_get_msg_priority(control
, &msgpri
); 
1039                 } else if (control
->m_len
) { 
1041                          * if not unordered, TCP should not have  
1054         if (so
->so_flags 
& SOF_ENABLE_MSGS
) { 
1055                 VERIFY(m
->m_flags 
& M_PKTHDR
); 
1056                 m
->m_pkthdr
.msg_pri 
= msgpri
; 
1059         /* MPTCP sublow socket buffers must not be compressed */ 
1060         VERIFY(!(so
->so_flags 
& SOF_MP_SUBFLOW
) || 
1061             (so
->so_snd
.sb_flags 
& SB_NOCOMPRESS
)); 
1063         if(!(flags 
& PRUS_OOB
) || (so
->so_flags1 
& SOF1_PRECONNECT_DATA
)) { 
1064                 /* Call msg send if message delivery is enabled */ 
1065                 if (so
->so_flags 
& SOF_ENABLE_MSGS
) 
1066                         sbappendmsg_snd(&so
->so_snd
, m
); 
1068                         sbappendstream(&so
->so_snd
, m
); 
1070                 if (nam 
&& tp
->t_state 
< TCPS_SYN_SENT
) { 
1073                          * Do implied connect if not yet connected, 
1074                          * initialize window to default value, and 
1075                          * initialize maxseg/maxopd using peer's cached 
1080                                 error 
= tcp6_connect(tp
, nam
, p
); 
1083                                 error 
= tcp_connect(tp
, nam
, p
); 
1086                         tp
->snd_wnd 
= TTCP_CLIENT_SND_WND
; 
1087                         tcp_mss(tp
, -1, IFSCOPE_NONE
); 
1090                 if (flags 
& PRUS_EOF
) { 
1092                          * Close the send side of the connection after 
1096                         tp 
= tcp_usrclosed(tp
); 
1099                         if (flags 
& PRUS_MORETOCOME
) 
1100                                 tp
->t_flags 
|= TF_MORETOCOME
; 
1101                         error 
= tcp_output(tp
); 
1102                         if (flags 
& PRUS_MORETOCOME
) 
1103                                 tp
->t_flags 
&= ~TF_MORETOCOME
; 
1106                 if (sbspace(&so
->so_snd
) == 0) {  
1107                         /* if no space is left in sockbuf,  
1108                          * do not try to squeeze in OOB traffic */ 
1114                  * According to RFC961 (Assigned Protocols), 
1115                  * the urgent pointer points to the last octet 
1116                  * of urgent data.  We continue, however, 
1117                  * to consider it to indicate the first octet 
1118                  * of data past the urgent section. 
1119                  * Otherwise, snd_up should be one lower. 
1121                 sbappendstream(&so
->so_snd
, m
); 
1122                 if (nam 
&& tp
->t_state 
< TCPS_SYN_SENT
) { 
1124                          * Do implied connect if not yet connected, 
1125                          * initialize window to default value, and 
1126                          * initialize maxseg/maxopd using peer's cached 
1131                                 error 
= tcp6_connect(tp
, nam
, p
); 
1134                         error 
= tcp_connect(tp
, nam
, p
); 
1137                         tp
->snd_wnd 
= TTCP_CLIENT_SND_WND
; 
1138                         tcp_mss(tp
, -1, IFSCOPE_NONE
); 
1140                 tp
->snd_up 
= tp
->snd_una 
+ so
->so_snd
.sb_cc
; 
1141                 tp
->t_flagsext 
|= TF_FORCE
; 
1142                 error 
= tcp_output(tp
); 
1143                 tp
->t_flagsext 
&= ~TF_FORCE
; 
1148          * We wait for the socket to successfully connect before returning. 
1149          * This allows us to signal a timeout to the application. 
1151         if (so
->so_state 
& SS_ISCONNECTING
) { 
1152                 if (so
->so_state 
& SS_NBIO
) 
1153                         error 
= EWOULDBLOCK
; 
1155                         error 
= sbwait(&so
->so_snd
); 
1158         COMMON_END((flags 
& PRUS_OOB
) ? PRU_SENDOOB 
:  
1159                    ((flags 
& PRUS_EOF
) ? PRU_SEND_EOF 
: PRU_SEND
)); 
1166 tcp_usr_abort(struct socket 
*so
) 
1169         struct inpcb 
*inp 
= sotoinpcb(so
); 
1173         /* In case we got disconnected from the peer */ 
1176         tp 
= tcp_drop(tp
, ECONNABORTED
); 
1177         VERIFY(so
->so_usecount 
> 0); 
1179         COMMON_END(PRU_ABORT
); 
1183  * Receive out-of-band data. 
1185  * Returns:     0                       Success 
1186  *              EINVAL [COMMON_START] 
1191 tcp_usr_rcvoob(struct socket 
*so
, struct mbuf 
*m
, int flags
) 
1194         struct inpcb 
*inp 
= sotoinpcb(so
); 
1198         if ((so
->so_oobmark 
== 0 && 
1199              (so
->so_state 
& SS_RCVATMARK
) == 0) || 
1200             so
->so_options 
& SO_OOBINLINE 
|| 
1201             tp
->t_oobflags 
& TCPOOB_HADDATA
) { 
1205         if ((tp
->t_oobflags 
& TCPOOB_HAVEDATA
) == 0) { 
1206                 error 
= EWOULDBLOCK
; 
1210         *mtod(m
, caddr_t
) = tp
->t_iobc
; 
1211         so
->so_state 
&= ~SS_RCVATMARK
; 
1212         if ((flags 
& MSG_PEEK
) == 0) 
1213                 tp
->t_oobflags 
^= (TCPOOB_HAVEDATA 
| TCPOOB_HADDATA
); 
1214         COMMON_END(PRU_RCVOOB
); 
1218 tcp_usr_preconnect(struct socket 
*so
) 
1220         struct inpcb 
*inp 
= sotoinpcb(so
); 
1224         if (necp_socket_should_use_flow_divert(inp
)) { 
1225                 /* May happen, if in tcp_usr_connect we did not had a chance 
1226                  * to set the usrreqs (due to some error). So, let's get out 
1233         error 
= tcp_output(sototcpcb(so
)); 
1235         /* One read has been done. This was enough. Get back to "normal" behavior. */ 
1236         so
->so_flags1 
&= ~SOF1_PRECONNECT_DATA
; 
1238         COMMON_END(PRU_PRECONNECT
); 
1241 /* xxx - should be const */ 
1242 struct pr_usrreqs tcp_usrreqs 
= { 
1243         .pru_abort 
=            tcp_usr_abort
, 
1244         .pru_accept 
=           tcp_usr_accept
, 
1245         .pru_attach 
=           tcp_usr_attach
, 
1246         .pru_bind 
=             tcp_usr_bind
, 
1247         .pru_connect 
=          tcp_usr_connect
, 
1248         .pru_connectx 
=         tcp_usr_connectx
, 
1249         .pru_control 
=          in_control
, 
1250         .pru_detach 
=           tcp_usr_detach
, 
1251         .pru_disconnect 
=       tcp_usr_disconnect
, 
1252         .pru_disconnectx 
=      tcp_usr_disconnectx
, 
1253         .pru_listen 
=           tcp_usr_listen
, 
1254         .pru_peeraddr 
=         in_getpeeraddr
, 
1255         .pru_rcvd 
=             tcp_usr_rcvd
, 
1256         .pru_rcvoob 
=           tcp_usr_rcvoob
, 
1257         .pru_send 
=             tcp_usr_send
, 
1258         .pru_shutdown 
=         tcp_usr_shutdown
, 
1259         .pru_sockaddr 
=         in_getsockaddr
, 
1260         .pru_sosend 
=           sosend
, 
1261         .pru_soreceive 
=        soreceive
, 
1262         .pru_preconnect 
=       tcp_usr_preconnect
, 
1266 struct pr_usrreqs tcp6_usrreqs 
= { 
1267         .pru_abort 
=            tcp_usr_abort
, 
1268         .pru_accept 
=           tcp6_usr_accept
, 
1269         .pru_attach 
=           tcp_usr_attach
, 
1270         .pru_bind 
=             tcp6_usr_bind
, 
1271         .pru_connect 
=          tcp6_usr_connect
, 
1272         .pru_connectx 
=         tcp6_usr_connectx
, 
1273         .pru_control 
=          in6_control
, 
1274         .pru_detach 
=           tcp_usr_detach
, 
1275         .pru_disconnect 
=       tcp_usr_disconnect
, 
1276         .pru_disconnectx 
=      tcp_usr_disconnectx
, 
1277         .pru_listen 
=           tcp6_usr_listen
, 
1278         .pru_peeraddr 
=         in6_mapped_peeraddr
, 
1279         .pru_rcvd 
=             tcp_usr_rcvd
, 
1280         .pru_rcvoob 
=           tcp_usr_rcvoob
, 
1281         .pru_send 
=             tcp_usr_send
, 
1282         .pru_shutdown 
=         tcp_usr_shutdown
, 
1283         .pru_sockaddr 
=         in6_mapped_sockaddr
, 
1284         .pru_sosend 
=           sosend
, 
1285         .pru_soreceive 
=        soreceive
, 
1286         .pru_preconnect 
=       tcp_usr_preconnect
, 
1291  * Common subroutine to open a TCP connection to remote host specified 
1292  * by struct sockaddr_in in mbuf *nam.  Call in_pcbbind to assign a local 
1293  * port number if needed.  Call in_pcbladdr to do the routing and to choose 
1294  * a local host address (interface).  If there is an existing incarnation 
1295  * of the same connection in TIME-WAIT state and if the remote host was 
1296  * sending CC options and if the connection duration was < MSL, then 
1297  * truncate the previous TIME-WAIT state and proceed. 
1298  * Initialize connection parameters and enter SYN-SENT state. 
1300  * Returns:     0                       Success 
1303  *      in_pcbbind:EADDRNOTAVAIL        Address not available. 
1304  *      in_pcbbind:EINVAL               Invalid argument 
1305  *      in_pcbbind:EAFNOSUPPORT         Address family not supported [notdef] 
1306  *      in_pcbbind:EACCES               Permission denied 
1307  *      in_pcbbind:EADDRINUSE           Address in use 
1308  *      in_pcbbind:EAGAIN               Resource unavailable, try again 
1309  *      in_pcbbind:EPERM                Operation not permitted 
1310  *      in_pcbladdr:EINVAL              Invalid argument 
1311  *      in_pcbladdr:EAFNOSUPPORT        Address family not supported 
1312  *      in_pcbladdr:EADDRNOTAVAIL       Address not available 
1315 tcp_connect(struct tcpcb 
*tp
, struct sockaddr 
*nam
, struct proc 
*p
) 
1317         struct inpcb 
*inp 
= tp
->t_inpcb
, *oinp
; 
1318         struct socket 
*so 
= inp
->inp_socket
; 
1320         struct sockaddr_in 
*sin 
= (struct sockaddr_in 
*)(void *)nam
; 
1321         struct in_addr laddr
; 
1323         struct ifnet 
*outif 
= NULL
; 
1325         if (inp
->inp_lport 
== 0) { 
1326                 error 
= in_pcbbind(inp
, NULL
, p
); 
1332          * Cannot simply call in_pcbconnect, because there might be an 
1333          * earlier incarnation of this same connection still in 
1334          * TIME_WAIT state, creating an ADDRINUSE error. 
1336         error 
= in_pcbladdr(inp
, nam
, &laddr
, IFSCOPE_NONE
, &outif
, 0); 
1340         tcp_unlock(inp
->inp_socket
, 0, 0); 
1341         oinp 
= in_pcblookup_hash(inp
->inp_pcbinfo
, 
1342             sin
->sin_addr
, sin
->sin_port
, 
1343             inp
->inp_laddr
.s_addr 
!= INADDR_ANY 
? inp
->inp_laddr 
: laddr
, 
1344             inp
->inp_lport
,  0, NULL
); 
1346         tcp_lock(inp
->inp_socket
, 0, 0); 
1348                 if (oinp 
!= inp
) /* 4143933: avoid deadlock if inp == oinp */ 
1349                         tcp_lock(oinp
->inp_socket
, 1, 0); 
1350                 if (in_pcb_checkstate(oinp
, WNT_RELEASE
, 1) == WNT_STOPUSING
) { 
1352                                 tcp_unlock(oinp
->inp_socket
, 1, 0); 
1356                 if (oinp 
!= inp 
&& (otp 
= intotcpcb(oinp
)) != NULL 
&& 
1357                     otp
->t_state 
== TCPS_TIME_WAIT 
&& 
1358                     ((int)(tcp_now 
- otp
->t_starttime
)) < tcp_msl 
&& 
1359                     (otp
->t_flags 
& TF_RCVD_CC
)) { 
1360                         otp 
= tcp_close(otp
); 
1362                         printf("tcp_connect: inp=0x%llx err=EADDRINUSE\n", 
1363                             (uint64_t)VM_KERNEL_ADDRPERM(inp
)); 
1365                                 tcp_unlock(oinp
->inp_socket
, 1, 0); 
1370                         tcp_unlock(oinp
->inp_socket
, 1, 0); 
1373         if ((inp
->inp_laddr
.s_addr 
== INADDR_ANY 
? laddr
.s_addr 
: 
1374             inp
->inp_laddr
.s_addr
) == sin
->sin_addr
.s_addr 
&& 
1375             inp
->inp_lport 
== sin
->sin_port
) { 
1379         if (!lck_rw_try_lock_exclusive(inp
->inp_pcbinfo
->ipi_lock
)) { 
1380                 /*lock inversion issue, mostly with udp multicast packets */ 
1381                 socket_unlock(inp
->inp_socket
, 0); 
1382                 lck_rw_lock_exclusive(inp
->inp_pcbinfo
->ipi_lock
); 
1383                 socket_lock(inp
->inp_socket
, 0); 
1385         if (inp
->inp_laddr
.s_addr 
== INADDR_ANY
) { 
1386                 inp
->inp_laddr 
= laddr
; 
1387                 /* no reference needed */ 
1388                 inp
->inp_last_outifp 
= outif
; 
1389                 inp
->inp_flags 
|= INP_INADDR_ANY
; 
1391         inp
->inp_faddr 
= sin
->sin_addr
; 
1392         inp
->inp_fport 
= sin
->sin_port
; 
1394         lck_rw_done(inp
->inp_pcbinfo
->ipi_lock
); 
1396         if (inp
->inp_flowhash 
== 0) 
1397                 inp
->inp_flowhash 
= inp_calc_flowhash(inp
); 
1399         tcp_set_max_rwinscale(tp
, so
, TCP_AUTORCVBUF_MAX(outif
)); 
1402         tcpstat
.tcps_connattempt
++; 
1403         tp
->t_state 
= TCPS_SYN_SENT
; 
1404         tp
->t_timer
[TCPT_KEEP
] = OFFSET_FROM_START(tp
, TCP_CONN_KEEPINIT(tp
)); 
1405         tp
->iss 
= tcp_new_isn(tp
); 
1406         tcp_sendseqinit(tp
); 
1408                 nstat_route_connect_attempt(inp
->inp_route
.ro_rt
); 
1412                 ifnet_release(outif
); 
1419 tcp6_connect(struct tcpcb 
*tp
, struct sockaddr 
*nam
, struct proc 
*p
) 
1421         struct inpcb 
*inp 
= tp
->t_inpcb
, *oinp
; 
1422         struct socket 
*so 
= inp
->inp_socket
; 
1424         struct sockaddr_in6 
*sin6 
= (struct sockaddr_in6 
*)(void *)nam
; 
1425         struct in6_addr addr6
; 
1427         struct ifnet 
*outif 
= NULL
; 
1429         if (inp
->inp_lport 
== 0) { 
1430                 error 
= in6_pcbbind(inp
, NULL
, p
); 
1436          * Cannot simply call in_pcbconnect, because there might be an 
1437          * earlier incarnation of this same connection still in 
1438          * TIME_WAIT state, creating an ADDRINUSE error. 
1440          * in6_pcbladdr() might return an ifp with its reference held 
1441          * even in the error case, so make sure that it's released 
1442          * whenever it's non-NULL. 
1444         error 
= in6_pcbladdr(inp
, nam
, &addr6
, &outif
); 
1447         tcp_unlock(inp
->inp_socket
, 0, 0); 
1448         oinp 
= in6_pcblookup_hash(inp
->inp_pcbinfo
, 
1449                                   &sin6
->sin6_addr
, sin6
->sin6_port
, 
1450                                   IN6_IS_ADDR_UNSPECIFIED(&inp
->in6p_laddr
) 
1453                                   inp
->inp_lport
,  0, NULL
); 
1454         tcp_lock(inp
->inp_socket
, 0, 0); 
1456                 if (oinp 
!= inp 
&& (otp 
= intotcpcb(oinp
)) != NULL 
&& 
1457                     otp
->t_state 
== TCPS_TIME_WAIT 
&& 
1458                     ((int)(tcp_now 
- otp
->t_starttime
)) < tcp_msl 
&& 
1459                     (otp
->t_flags 
& TF_RCVD_CC
)) { 
1460                         otp 
= tcp_close(otp
); 
1466         if (!lck_rw_try_lock_exclusive(inp
->inp_pcbinfo
->ipi_lock
)) { 
1467                 /*lock inversion issue, mostly with udp multicast packets */ 
1468                 socket_unlock(inp
->inp_socket
, 0); 
1469                 lck_rw_lock_exclusive(inp
->inp_pcbinfo
->ipi_lock
); 
1470                 socket_lock(inp
->inp_socket
, 0); 
1472         if (IN6_IS_ADDR_UNSPECIFIED(&inp
->in6p_laddr
)) { 
1473                 inp
->in6p_laddr 
= addr6
; 
1474                 inp
->in6p_last_outifp 
= outif
;  /* no reference needed */ 
1475                 inp
->in6p_flags 
|= INP_IN6ADDR_ANY
; 
1477         inp
->in6p_faddr 
= sin6
->sin6_addr
; 
1478         inp
->inp_fport 
= sin6
->sin6_port
; 
1479         if ((sin6
->sin6_flowinfo 
& IPV6_FLOWINFO_MASK
) != 0) 
1480                 inp
->inp_flow 
= sin6
->sin6_flowinfo
; 
1482         lck_rw_done(inp
->inp_pcbinfo
->ipi_lock
); 
1484         if (inp
->inp_flowhash 
== 0) 
1485                 inp
->inp_flowhash 
= inp_calc_flowhash(inp
); 
1486         /* update flowinfo - RFC 6437 */ 
1487         if (inp
->inp_flow 
== 0 && inp
->in6p_flags 
& IN6P_AUTOFLOWLABEL
) { 
1488                 inp
->inp_flow 
&= ~IPV6_FLOWLABEL_MASK
; 
1490                     (htonl(inp
->inp_flowhash
) & IPV6_FLOWLABEL_MASK
); 
1493         tcp_set_max_rwinscale(tp
, so
, TCP_AUTORCVBUF_MAX(outif
)); 
1496         tcpstat
.tcps_connattempt
++; 
1497         tp
->t_state 
= TCPS_SYN_SENT
; 
1498         tp
->t_timer
[TCPT_KEEP
] = OFFSET_FROM_START(tp
,  
1499                 TCP_CONN_KEEPINIT(tp
)); 
1500         tp
->iss 
= tcp_new_isn(tp
); 
1501         tcp_sendseqinit(tp
); 
1503                 nstat_route_connect_attempt(inp
->inp_route
.ro_rt
); 
1507                 ifnet_release(outif
); 
1514  * Export TCP internal state information via a struct tcp_info 
1516 __private_extern__ 
void 
1517 tcp_fill_info(struct tcpcb 
*tp
, struct tcp_info 
*ti
) 
1519         struct inpcb 
*inp 
= tp
->t_inpcb
; 
1521         bzero(ti
, sizeof(*ti
)); 
1523         ti
->tcpi_state 
= tp
->t_state
; 
1524         ti
->tcpi_flowhash 
= inp
->inp_flowhash
; 
1526         if (tp
->t_state 
> TCPS_LISTEN
) { 
1527                 if (TSTMP_SUPPORTED(tp
)) 
1528                         ti
->tcpi_options 
|= TCPI_OPT_TIMESTAMPS
; 
1529                 if (SACK_ENABLED(tp
)) 
1530                         ti
->tcpi_options 
|= TCPI_OPT_SACK
; 
1531                 if (TCP_WINDOW_SCALE_ENABLED(tp
)) { 
1532                         ti
->tcpi_options 
|= TCPI_OPT_WSCALE
; 
1533                         ti
->tcpi_snd_wscale 
= tp
->snd_scale
; 
1534                         ti
->tcpi_rcv_wscale 
= tp
->rcv_scale
; 
1536                 if (TCP_ECN_ENABLED(tp
)) 
1537                         ti
->tcpi_options 
|= TCPI_OPT_ECN
; 
1539                 /* Are we in retranmission episode */ 
1540                 if (IN_FASTRECOVERY(tp
) || tp
->t_rxtshift 
> 0) 
1541                         ti
->tcpi_flags 
|= TCPI_FLAG_LOSSRECOVERY
; 
1543                 if (tp
->t_flags 
& TF_STREAMING_ON
) 
1544                         ti
->tcpi_flags 
|= TCPI_FLAG_STREAMING_ON
; 
1546                 ti
->tcpi_rto 
= tp
->t_timer
[TCPT_REXMT
] ? tp
->t_rxtcur 
: 0; 
1547                 ti
->tcpi_snd_mss 
= tp
->t_maxseg
; 
1548                 ti
->tcpi_rcv_mss 
= tp
->t_maxseg
; 
1550                 ti
->tcpi_rttcur 
= tp
->t_rttcur
; 
1551                 ti
->tcpi_srtt 
= tp
->t_srtt 
>> TCP_RTT_SHIFT
; 
1552                 ti
->tcpi_rttvar 
= tp
->t_rttvar 
>> TCP_RTTVAR_SHIFT
; 
1553                 ti
->tcpi_rttbest 
= tp
->t_rttbest 
>> TCP_RTT_SHIFT
; 
1555                 ti
->tcpi_snd_ssthresh 
= tp
->snd_ssthresh
; 
1556                 ti
->tcpi_snd_cwnd 
= tp
->snd_cwnd
; 
1557                 ti
->tcpi_snd_sbbytes 
= inp
->inp_socket
->so_snd
.sb_cc
; 
1559                 ti
->tcpi_rcv_space 
= tp
->rcv_wnd
; 
1561                 ti
->tcpi_snd_wnd 
= tp
->snd_wnd
; 
1562                 ti
->tcpi_snd_nxt 
= tp
->snd_nxt
; 
1563                 ti
->tcpi_rcv_nxt 
= tp
->rcv_nxt
; 
1565                 /* convert bytes/msec to bits/sec */ 
1566                 if ((tp
->t_flagsext 
& TF_MEASURESNDBW
) != 0 && 
1567                         tp
->t_bwmeas 
!= NULL
) { 
1568                         ti
->tcpi_snd_bw 
= (tp
->t_bwmeas
->bw_sndbw 
* 8000); 
1571                 ti
->tcpi_last_outif 
= (tp
->t_inpcb
->inp_last_outifp 
== NULL
) ? 0 : 
1572                     tp
->t_inpcb
->inp_last_outifp
->if_index
; 
1574                 //atomic_get_64(ti->tcpi_txbytes, &inp->inp_stat->txbytes); 
1575                 ti
->tcpi_txpackets 
= inp
->inp_stat
->txpackets
; 
1576                 ti
->tcpi_txbytes 
= inp
->inp_stat
->txbytes
; 
1577                 ti
->tcpi_txretransmitbytes 
= tp
->t_stat
.txretransmitbytes
; 
1578                 ti
->tcpi_txunacked 
= tp
->snd_max 
- tp
->snd_una
; 
1580                 //atomic_get_64(ti->tcpi_rxbytes, &inp->inp_stat->rxbytes); 
1581                 ti
->tcpi_rxpackets 
= inp
->inp_stat
->rxpackets
; 
1582                 ti
->tcpi_rxbytes 
= inp
->inp_stat
->rxbytes
; 
1583                 ti
->tcpi_rxduplicatebytes 
= tp
->t_stat
.rxduplicatebytes
; 
1584                 ti
->tcpi_rxoutoforderbytes 
= tp
->t_stat
.rxoutoforderbytes
; 
1586                 if (tp
->t_state 
> TCPS_LISTEN
) { 
1587                         ti
->tcpi_synrexmits 
= tp
->t_stat
.synrxtshift
; 
1589                 ti
->tcpi_cell_rxpackets 
= inp
->inp_cstat
->rxpackets
; 
1590                 ti
->tcpi_cell_rxbytes 
= inp
->inp_cstat
->rxbytes
; 
1591                 ti
->tcpi_cell_txpackets 
= inp
->inp_cstat
->txpackets
; 
1592                 ti
->tcpi_cell_txbytes 
= inp
->inp_cstat
->txbytes
; 
1594                 ti
->tcpi_wifi_rxpackets 
= inp
->inp_wstat
->rxpackets
; 
1595                 ti
->tcpi_wifi_rxbytes 
= inp
->inp_wstat
->rxbytes
; 
1596                 ti
->tcpi_wifi_txpackets 
= inp
->inp_wstat
->txpackets
; 
1597                 ti
->tcpi_wifi_txbytes 
= inp
->inp_wstat
->txbytes
; 
1599                 ti
->tcpi_wired_rxpackets 
= inp
->inp_Wstat
->rxpackets
; 
1600                 ti
->tcpi_wired_rxbytes 
= inp
->inp_Wstat
->rxbytes
; 
1601                 ti
->tcpi_wired_txpackets 
= inp
->inp_Wstat
->txpackets
; 
1602                 ti
->tcpi_wired_txbytes 
= inp
->inp_Wstat
->txbytes
; 
1603                 tcp_get_connectivity_status(tp
, &ti
->tcpi_connstatus
); 
1605                 ti
->tcpi_tfo_syn_data_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_SYNDATA_RCV
); 
1606                 ti
->tcpi_tfo_cookie_req_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIEREQ_RECV
); 
1607                 ti
->tcpi_tfo_cookie_sent 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_SENT
); 
1608                 ti
->tcpi_tfo_cookie_invalid 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_INVALID
); 
1610                 ti
->tcpi_tfo_cookie_req 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_REQ
); 
1611                 ti
->tcpi_tfo_cookie_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_RCV
); 
1612                 ti
->tcpi_tfo_syn_data_sent 
= !!(tp
->t_tfo_stats 
& TFO_S_SYN_DATA_SENT
); 
1613                 ti
->tcpi_tfo_syn_data_acked 
= !!(tp
->t_tfo_stats 
& TFO_S_SYN_DATA_ACKED
); 
1614                 ti
->tcpi_tfo_syn_loss 
= !!(tp
->t_tfo_stats 
& TFO_S_SYN_LOSS
); 
1615                 ti
->tcpi_tfo_cookie_wrong 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_WRONG
); 
1616                 ti
->tcpi_tfo_no_cookie_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_NO_COOKIE_RCV
); 
1617                 ti
->tcpi_tfo_heuristics_disable 
= !!(tp
->t_tfo_stats 
& TFO_S_HEURISTICS_DISABLE
); 
1618                 ti
->tcpi_tfo_send_blackhole 
= !!(tp
->t_tfo_stats 
& TFO_S_SEND_BLACKHOLE
); 
1619                 ti
->tcpi_tfo_recv_blackhole 
= !!(tp
->t_tfo_stats 
& TFO_S_RECV_BLACKHOLE
); 
1621                 ti
->tcpi_ecn_client_setup 
= !!(tp
->ecn_flags 
& TE_SETUPSENT
); 
1622                 ti
->tcpi_ecn_server_setup 
= !!(tp
->ecn_flags 
& TE_SETUPRECEIVED
); 
1623                 ti
->tcpi_ecn_success 
= (tp
->ecn_flags 
& TE_ECN_ON
) == TE_ECN_ON 
? 1 : 0; 
1624                 ti
->tcpi_ecn_lost_syn 
= !!(tp
->ecn_flags 
& TE_LOST_SYN
); 
1625                 ti
->tcpi_ecn_lost_synack 
= !!(tp
->ecn_flags 
& TE_LOST_SYNACK
); 
1627                 ti
->tcpi_local_peer 
= !!(tp
->t_flags 
& TF_LOCAL
); 
1629                 if (tp
->t_inpcb
->inp_last_outifp 
!= NULL
) { 
1630                         if (IFNET_IS_CELLULAR(tp
->t_inpcb
->inp_last_outifp
)) 
1631                                 ti
->tcpi_if_cell 
= 1; 
1632                         else if (IFNET_IS_WIFI(tp
->t_inpcb
->inp_last_outifp
)) 
1633                                 ti
->tcpi_if_wifi 
= 1; 
1636                 ti
->tcpi_ecn_recv_ce 
= tp
->t_ecn_recv_ce
; 
1637                 ti
->tcpi_ecn_recv_cwr 
= tp
->t_ecn_recv_cwr
; 
1639                 ti
->tcpi_rcvoopack 
= tp
->t_rcvoopack
; 
1640                 ti
->tcpi_pawsdrop 
= tp
->t_pawsdrop
; 
1641                 ti
->tcpi_sack_recovery_episode 
= tp
->t_sack_recovery_episode
; 
1642                 ti
->tcpi_reordered_pkts 
= tp
->t_reordered_pkts
; 
1643                 ti
->tcpi_dsack_sent 
= tp
->t_dsack_sent
; 
1644                 ti
->tcpi_dsack_recvd 
= tp
->t_dsack_recvd
; 
1648 __private_extern__ errno_t
 
1649 tcp_fill_info_for_info_tuple(struct info_tuple 
*itpl
, struct tcp_info 
*ti
) 
1651         struct inpcbinfo 
*pcbinfo 
= NULL
; 
1652         struct inpcb 
*inp 
= NULL
; 
1656         if (itpl
->itpl_proto 
== IPPROTO_TCP
) 
1661         if (itpl
->itpl_local_sa
.sa_family 
== AF_INET 
&& 
1662                 itpl
->itpl_remote_sa
.sa_family 
== AF_INET
) { 
1663                 inp 
= in_pcblookup_hash(pcbinfo
,  
1664                         itpl
->itpl_remote_sin
.sin_addr
, 
1665                         itpl
->itpl_remote_sin
.sin_port
, 
1666                         itpl
->itpl_local_sin
.sin_addr
, 
1667                         itpl
->itpl_local_sin
.sin_port
, 
1669         } else if (itpl
->itpl_local_sa
.sa_family 
== AF_INET6 
&& 
1670                 itpl
->itpl_remote_sa
.sa_family 
== AF_INET6
) { 
1671                 struct in6_addr ina6_local
; 
1672                 struct in6_addr ina6_remote
; 
1674                 ina6_local 
= itpl
->itpl_local_sin6
.sin6_addr
; 
1675                 if (IN6_IS_SCOPE_LINKLOCAL(&ina6_local
) &&  
1676                         itpl
->itpl_local_sin6
.sin6_scope_id
) 
1677                         ina6_local
.s6_addr16
[1] = htons(itpl
->itpl_local_sin6
.sin6_scope_id
); 
1679                 ina6_remote 
= itpl
->itpl_remote_sin6
.sin6_addr
; 
1680                 if (IN6_IS_SCOPE_LINKLOCAL(&ina6_remote
) &&  
1681                         itpl
->itpl_remote_sin6
.sin6_scope_id
) 
1682                         ina6_remote
.s6_addr16
[1] = htons(itpl
->itpl_remote_sin6
.sin6_scope_id
); 
1684                 inp 
= in6_pcblookup_hash(pcbinfo
,  
1686                         itpl
->itpl_remote_sin6
.sin6_port
, 
1688                         itpl
->itpl_local_sin6
.sin6_port
, 
1693         if (inp 
== NULL 
|| (so 
= inp
->inp_socket
) == NULL
) 
1697         if (in_pcb_checkstate(inp
, WNT_RELEASE
, 1) == WNT_STOPUSING
) { 
1698                 socket_unlock(so
, 0); 
1701         tp 
= intotcpcb(inp
); 
1703         tcp_fill_info(tp
, ti
); 
1704         socket_unlock(so
, 0); 
1710 tcp_connection_fill_info(struct tcpcb 
*tp
, struct tcp_connection_info 
*tci
) 
1712         struct inpcb 
*inp 
= tp
->t_inpcb
; 
1714         bzero(tci
, sizeof(*tci
)); 
1715         tci
->tcpi_state 
= tp
->t_state
; 
1716         if (tp
->t_state 
> TCPS_LISTEN
) { 
1717                 if (TSTMP_SUPPORTED(tp
)) 
1718                         tci
->tcpi_options 
|= TCPCI_OPT_TIMESTAMPS
; 
1719                 if (SACK_ENABLED(tp
)) 
1720                         tci
->tcpi_options 
|= TCPCI_OPT_SACK
; 
1721                 if (TCP_WINDOW_SCALE_ENABLED(tp
)) { 
1722                         tci
->tcpi_options 
|= TCPCI_OPT_WSCALE
; 
1723                         tci
->tcpi_snd_wscale 
= tp
->snd_scale
; 
1724                         tci
->tcpi_rcv_wscale 
= tp
->rcv_scale
; 
1726                 if (TCP_ECN_ENABLED(tp
)) 
1727                         tci
->tcpi_options 
|= TCPCI_OPT_ECN
; 
1728                 if (IN_FASTRECOVERY(tp
) || tp
->t_rxtshift 
> 0) 
1729                         tci
->tcpi_flags 
|= TCPCI_FLAG_LOSSRECOVERY
; 
1730                 if (tp
->t_flagsext 
& TF_PKTS_REORDERED
) 
1731                         tci
->tcpi_flags 
|= TCPCI_FLAG_REORDERING_DETECTED
; 
1732                 tci
->tcpi_rto 
= (tp
->t_timer
[TCPT_REXMT
] > 0) ? 
1734                 tci
->tcpi_maxseg 
= tp
->t_maxseg
; 
1735                 tci
->tcpi_snd_ssthresh 
= tp
->snd_ssthresh
; 
1736                 tci
->tcpi_snd_cwnd 
= tp
->snd_cwnd
; 
1737                 tci
->tcpi_snd_wnd 
= tp
->snd_wnd
; 
1738                 tci
->tcpi_snd_sbbytes 
= inp
->inp_socket
->so_snd
.sb_cc
; 
1739                 tci
->tcpi_rcv_wnd 
= tp
->rcv_wnd
; 
1740                 tci
->tcpi_rttcur 
= tp
->t_rttcur
; 
1741                 tci
->tcpi_srtt 
= (tp
->t_srtt 
>> TCP_RTT_SHIFT
); 
1742                 tci
->tcpi_rttvar 
= (tp
->t_rttvar 
>> TCP_RTTVAR_SHIFT
); 
1743                 tci
->tcpi_txpackets 
= inp
->inp_stat
->txpackets
; 
1744                 tci
->tcpi_txbytes 
= inp
->inp_stat
->txbytes
; 
1745                 tci
->tcpi_txretransmitbytes 
= tp
->t_stat
.txretransmitbytes
; 
1746                 tci
->tcpi_rxpackets 
= inp
->inp_stat
->rxpackets
; 
1747                 tci
->tcpi_rxbytes 
= inp
->inp_stat
->rxbytes
; 
1748                 tci
->tcpi_rxoutoforderbytes 
= tp
->t_stat
.rxoutoforderbytes
; 
1750                 tci
->tcpi_tfo_syn_data_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_SYNDATA_RCV
); 
1751                 tci
->tcpi_tfo_cookie_req_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIEREQ_RECV
); 
1752                 tci
->tcpi_tfo_cookie_sent 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_SENT
); 
1753                 tci
->tcpi_tfo_cookie_invalid 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_INVALID
); 
1754                 tci
->tcpi_tfo_cookie_req 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_REQ
); 
1755                 tci
->tcpi_tfo_cookie_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_RCV
); 
1756                 tci
->tcpi_tfo_syn_data_sent 
= !!(tp
->t_tfo_stats 
& TFO_S_SYN_DATA_SENT
); 
1757                 tci
->tcpi_tfo_syn_data_acked 
= !!(tp
->t_tfo_stats 
& TFO_S_SYN_DATA_ACKED
); 
1758                 tci
->tcpi_tfo_syn_loss 
= !!(tp
->t_tfo_stats 
& TFO_S_SYN_LOSS
); 
1759                 tci
->tcpi_tfo_cookie_wrong 
= !!(tp
->t_tfo_stats 
& TFO_S_COOKIE_WRONG
); 
1760                 tci
->tcpi_tfo_no_cookie_rcv 
= !!(tp
->t_tfo_stats 
& TFO_S_NO_COOKIE_RCV
); 
1761                 tci
->tcpi_tfo_heuristics_disable 
= !!(tp
->t_tfo_stats 
& TFO_S_HEURISTICS_DISABLE
); 
1762                 tci
->tcpi_tfo_send_blackhole 
= !!(tp
->t_tfo_stats 
& TFO_S_SEND_BLACKHOLE
); 
1763                 tci
->tcpi_tfo_recv_blackhole 
= !!(tp
->t_tfo_stats 
& TFO_S_RECV_BLACKHOLE
); 
1768 __private_extern__ 
int  
1769 tcp_sysctl_info(__unused 
struct sysctl_oid 
*oidp
, __unused 
void *arg1
, __unused 
int arg2
, struct sysctl_req 
*req
) 
1773         struct info_tuple itpl
; 
1774         proc_t caller 
= PROC_NULL
; 
1775         proc_t caller_parent 
= PROC_NULL
; 
1776         char command_name
[MAXCOMLEN 
+ 1] = ""; 
1777         char parent_name
[MAXCOMLEN 
+ 1] = ""; 
1779         if ((caller 
= proc_self()) != PROC_NULL
) { 
1780                 /* get process name */ 
1781                 strlcpy(command_name
, caller
->p_comm
, sizeof(command_name
)); 
1783                 /* get parent process name if possible */ 
1784                 if ((caller_parent 
= proc_find(caller
->p_ppid
)) != PROC_NULL
) { 
1785                         strlcpy(parent_name
, caller_parent
->p_comm
, 
1786                             sizeof(parent_name
)); 
1787                         proc_rele(caller_parent
); 
1790                 if ((escape_str(command_name
, strlen(command_name
), 
1791                     sizeof(command_name
)) == 0) && 
1792                     (escape_str(parent_name
, strlen(parent_name
), 
1793                     sizeof(parent_name
)) == 0)) { 
1794                         kern_asl_msg(LOG_DEBUG
, "messagetracer", 
1796                             "com.apple.message.domain", 
1797                             "com.apple.kernel.tcpstat", /* 1 */ 
1798                             "com.apple.message.signature", 
1800                             "com.apple.message.signature2", command_name
, /* 3 */ 
1801                             "com.apple.message.signature3", parent_name
, /* 4 */ 
1802                             "com.apple.message.summarize", "YES", /* 5 */ 
1807         if (caller 
!= PROC_NULL
) 
1810         if (req
->newptr 
== USER_ADDR_NULL
) { 
1813         if (req
->newlen 
< sizeof(struct info_tuple
)) { 
1816         error 
= SYSCTL_IN(req
, &itpl
, sizeof(struct info_tuple
)); 
1820         error 
= tcp_fill_info_for_info_tuple(&itpl
, &ti
); 
1824         error 
= SYSCTL_OUT(req
, &ti
, sizeof(struct tcp_info
)); 
1833 tcp_lookup_peer_pid_locked(struct socket 
*so
, pid_t 
*out_pid
) 
1835         int error 
= EHOSTUNREACH
; 
1837         if ((so
->so_state 
& SS_ISCONNECTED
) == 0) return ENOTCONN
; 
1839         struct inpcb    
*inp 
= (struct inpcb
*)so
->so_pcb
; 
1840         uint16_t                lport 
= inp
->inp_lport
; 
1841         uint16_t                fport 
= inp
->inp_fport
; 
1842         struct inpcb    
*finp 
= NULL
; 
1844         if (inp
->inp_vflag 
& INP_IPV6
) { 
1845                 struct  in6_addr        laddr6 
= inp
->in6p_laddr
; 
1846                 struct  in6_addr        faddr6 
= inp
->in6p_faddr
; 
1847                 socket_unlock(so
, 0); 
1848                 finp 
= in6_pcblookup_hash(&tcbinfo
, &laddr6
, lport
, &faddr6
, fport
, 0, NULL
); 
1850         } else if (inp
->inp_vflag 
& INP_IPV4
) { 
1851                 struct  in_addr laddr4 
= inp
->inp_laddr
; 
1852                 struct  in_addr faddr4 
= inp
->inp_faddr
; 
1853                 socket_unlock(so
, 0); 
1854                 finp 
= in_pcblookup_hash(&tcbinfo
, laddr4
, lport
, faddr4
, fport
, 0, NULL
); 
1859                 *out_pid 
= finp
->inp_socket
->last_pid
; 
1861                 in_pcb_checkstate(finp
, WNT_RELEASE
, 0); 
1868 tcp_getconninfo(struct socket 
*so
, struct conninfo_tcp 
*tcp_ci
) 
1870         (void) tcp_lookup_peer_pid_locked(so
, &tcp_ci
->tcpci_peer_pid
); 
1871         tcp_fill_info(sototcpcb(so
), &tcp_ci
->tcpci_tcp_info
); 
1875  * The new sockopt interface makes it possible for us to block in the 
1876  * copyin/out step (if we take a page fault).  Taking a page fault at 
1877  * splnet() is probably a Bad Thing.  (Since sockets and pcbs both now 
1878  * use TSM, there probably isn't any need for this function to run at 
1879  * splnet() any more.  This needs more examination.) 
1882 tcp_ctloutput(struct socket 
*so
, struct sockopt 
*sopt
) 
1884         int     error
, opt
, optval
; 
1889         inp 
= sotoinpcb(so
); 
1891                 return (ECONNRESET
); 
1893         /* Allow <SOL_SOCKET,SO_FLUSH/SO_TRAFFIC_MGT_BACKGROUND> at this level */ 
1894         if (sopt
->sopt_level 
!= IPPROTO_TCP 
&& 
1895             !(sopt
->sopt_level 
== SOL_SOCKET 
&& (sopt
->sopt_name 
== SO_FLUSH 
|| 
1896             sopt
->sopt_name 
== SO_TRAFFIC_MGT_BACKGROUND
))) { 
1898                 if (SOCK_CHECK_DOM(so
, PF_INET6
)) 
1899                         error 
= ip6_ctloutput(so
, sopt
); 
1902                 error 
= ip_ctloutput(so
, sopt
); 
1905         tp 
= intotcpcb(inp
); 
1907                 return (ECONNRESET
); 
1910         calculate_tcp_clock(); 
1912         switch (sopt
->sopt_dir
) { 
1914                 switch (sopt
->sopt_name
) { 
1918                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
1923                         switch (sopt
->sopt_name
) { 
1934                                 opt 
= 0; /* dead code to fool gcc */ 
1941                                 tp
->t_flags 
&= ~opt
; 
1943                 case TCP_RXT_FINDROP
: 
1944                 case TCP_NOTIMEWAIT
: 
1945                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
1949                         switch (sopt
->sopt_name
) { 
1950                         case TCP_RXT_FINDROP
: 
1951                                 opt 
= TF_RXTFINDROP
; 
1953                         case TCP_NOTIMEWAIT
: 
1954                                 opt 
= TF_NOTIMEWAIT
; 
1961                                 tp
->t_flagsext 
|= opt
; 
1963                                 tp
->t_flagsext 
&= ~opt
; 
1965                 case TCP_MEASURE_SND_BW
: 
1966                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
1970                         opt 
= TF_MEASURESNDBW
; 
1972                                 if (tp
->t_bwmeas 
== NULL
) { 
1973                                         tp
->t_bwmeas 
= tcp_bwmeas_alloc(tp
); 
1974                                         if (tp
->t_bwmeas 
== NULL
) { 
1979                                 tp
->t_flagsext 
|= opt
; 
1981                                 tp
->t_flagsext 
&= ~opt
; 
1982                                 /* Reset snd bw measurement state */ 
1983                                 tp
->t_flagsext 
&= ~(TF_BWMEAS_INPROGRESS
); 
1984                                 if (tp
->t_bwmeas 
!= NULL
) { 
1985                                         tcp_bwmeas_free(tp
); 
1989                 case TCP_MEASURE_BW_BURST
: { 
1990                         struct tcp_measure_bw_burst in
; 
1991                         uint32_t minpkts
, maxpkts
; 
1992                         bzero(&in
, sizeof(in
)); 
1994                         error 
= sooptcopyin(sopt
, &in
, sizeof(in
), 
1998                         if ((tp
->t_flagsext 
& TF_MEASURESNDBW
) == 0 || 
1999                                 tp
->t_bwmeas 
== NULL
) { 
2003                         minpkts 
= (in
.min_burst_size 
!= 0) ? in
.min_burst_size 
:  
2004                                 tp
->t_bwmeas
->bw_minsizepkts
; 
2005                         maxpkts 
= (in
.max_burst_size 
!= 0) ? in
.max_burst_size 
: 
2006                                 tp
->t_bwmeas
->bw_maxsizepkts
; 
2007                         if (minpkts 
> maxpkts
) { 
2011                         tp
->t_bwmeas
->bw_minsizepkts 
= minpkts
; 
2012                         tp
->t_bwmeas
->bw_maxsizepkts 
= maxpkts
; 
2013                         tp
->t_bwmeas
->bw_minsize 
= (minpkts 
* tp
->t_maxseg
); 
2014                         tp
->t_bwmeas
->bw_maxsize 
= (maxpkts 
* tp
->t_maxseg
); 
2018                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
2023                         if (optval 
> 0 && optval 
<= tp
->t_maxseg 
&& 
2024                             optval 
+ 40 >= tcp_minmss
) 
2025                                 tp
->t_maxseg 
= optval
; 
2031                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
2035                         if (optval 
< 0 || optval 
> UINT32_MAX
/TCP_RETRANSHZ
) { 
2038                                 tp
->t_keepidle 
= optval 
* TCP_RETRANSHZ
; 
2039                                 /* reset the timer to new value */ 
2040                                 tp
->t_timer
[TCPT_KEEP
] = OFFSET_FROM_START(tp
,  
2041                                         TCP_CONN_KEEPIDLE(tp
)); 
2042                                 tcp_check_timer_state(tp
); 
2046                 case TCP_CONNECTIONTIMEOUT
: 
2047                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
2051                         if (optval 
< 0 || optval 
> UINT32_MAX
/TCP_RETRANSHZ
) { 
2054                                 tp
->t_keepinit 
= optval 
* TCP_RETRANSHZ
; 
2055                                 if (tp
->t_state 
== TCPS_SYN_RECEIVED 
|| 
2056                                         tp
->t_state 
== TCPS_SYN_SENT
) { 
2057                                         tp
->t_timer
[TCPT_KEEP
] = OFFSET_FROM_START(tp
, 
2058                                                 TCP_CONN_KEEPINIT(tp
)); 
2059                                         tcp_check_timer_state(tp
); 
2065                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2069                         if (optval 
< 0 || optval 
> UINT32_MAX
/TCP_RETRANSHZ
) { 
2072                                 tp
->t_keepintvl 
= optval 
* TCP_RETRANSHZ
; 
2073                                 if (tp
->t_state 
== TCPS_FIN_WAIT_2 
&& 
2074                                         TCP_CONN_MAXIDLE(tp
) > 0) { 
2075                                         tp
->t_timer
[TCPT_2MSL
] = OFFSET_FROM_START(tp
, 
2076                                                 TCP_CONN_MAXIDLE(tp
)); 
2077                                         tcp_check_timer_state(tp
); 
2083                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2087                         if (optval 
< 0 || optval 
> INT32_MAX
) { 
2090                                 tp
->t_keepcnt 
= optval
; 
2091                                 if (tp
->t_state 
== TCPS_FIN_WAIT_2 
&& 
2092                                         TCP_CONN_MAXIDLE(tp
) > 0) { 
2093                                         tp
->t_timer
[TCPT_2MSL
] = OFFSET_FROM_START(tp
, 
2094                                                 TCP_CONN_MAXIDLE(tp
)); 
2095                                         tcp_check_timer_state(tp
); 
2100                 case TCP_KEEPALIVE_OFFLOAD
: 
2101                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2105                         if (optval 
< 0 || optval 
> INT32_MAX
) { 
2110                                 inp
->inp_flags2 
|= INP2_KEEPALIVE_OFFLOAD
; 
2112                                 inp
->inp_flags2 
&= ~INP2_KEEPALIVE_OFFLOAD
; 
2115                 case PERSIST_TIMEOUT
: 
2116                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
2123                                 tp
->t_persist_timeout 
= optval 
* TCP_RETRANSHZ
; 
2125                 case TCP_RXT_CONNDROPTIME
: 
2126                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2133                                 tp
->t_rxt_conndroptime 
= optval 
* TCP_RETRANSHZ
; 
2135                 case TCP_NOTSENT_LOWAT
: 
2136                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2145                                         so
->so_flags 
&= ~(SOF_NOTSENT_LOWAT
); 
2146                                         tp
->t_notsent_lowat 
= 0; 
2148                                         so
->so_flags 
|= SOF_NOTSENT_LOWAT
; 
2149                                         tp
->t_notsent_lowat 
= optval
; 
2153                 case TCP_ADAPTIVE_READ_TIMEOUT
: 
2154                         error 
= sooptcopyin(sopt
, &optval
, sizeof (optval
), 
2159                             optval 
> TCP_ADAPTIVE_TIMEOUT_MAX
) { 
2162                         } else if (optval 
== 0) { 
2163                                 tp
->t_adaptive_rtimo 
= 0; 
2164                                 tcp_keepalive_reset(tp
); 
2166                                 tp
->t_adaptive_rtimo 
= optval
; 
2169                 case TCP_ADAPTIVE_WRITE_TIMEOUT
: 
2170                         error 
= sooptcopyin(sopt
, &optval
, sizeof (optval
), 
2175                             optval 
> TCP_ADAPTIVE_TIMEOUT_MAX
) { 
2179                                 tp
->t_adaptive_wtimo 
= optval
; 
2182                 case TCP_ENABLE_MSGS
: 
2183                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2187                         if (optval 
< 0 || optval 
> 1) { 
2189                         } else if (optval 
== 1) { 
2191                                  * Check if messages option is already 
2192                                  * enabled, if so return. 
2194                                 if (so
->so_flags 
& SOF_ENABLE_MSGS
) { 
2195                                         VERIFY(so
->so_msg_state 
!= NULL
); 
2200                                  * allocate memory for storing message 
2203                                 VERIFY(so
->so_msg_state 
== NULL
); 
2204                                 MALLOC(so
->so_msg_state
, 
2206                                         sizeof(struct msg_state
), 
2207                                         M_TEMP
, M_WAITOK 
| M_ZERO
); 
2208                                 if (so
->so_msg_state 
== NULL
) { 
2213                                 /* Enable message delivery */ 
2214                                 so
->so_flags 
|= SOF_ENABLE_MSGS
; 
2217                                  * Can't disable message delivery on socket 
2218                                  * because of restrictions imposed by 
2224                 case TCP_SENDMOREACKS
: 
2225                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2229                         if (optval 
< 0 || optval 
> 1) { 
2231                         } else if (optval 
== 0) { 
2232                                 tp
->t_flagsext 
&= ~(TF_NOSTRETCHACK
); 
2234                                 tp
->t_flagsext 
|= TF_NOSTRETCHACK
; 
2237                 case TCP_DISABLE_BLACKHOLE_DETECTION
: 
2238                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2242                         if (optval 
< 0 || optval 
> 1) { 
2244                         } else if (optval 
== 0) { 
2245                                 tp
->t_flagsext 
&= ~TF_NOBLACKHOLE_DETECTION
; 
2247                                 tp
->t_flagsext 
|= TF_NOBLACKHOLE_DETECTION
; 
2248                                 if ((tp
->t_flags 
& TF_BLACKHOLE
) && 
2249                                     tp
->t_pmtud_saved_maxopd 
> 0) 
2250                                         tcp_pmtud_revert_segment_size(tp
); 
2254                         if (!(tcp_fastopen 
& TCP_FASTOPEN_SERVER
)) { 
2259                         error 
= sooptcopyin(sopt
, &optval
, sizeof(optval
), 
2263                         if (optval 
< 0 || optval 
> 1) { 
2267                         if (tp
->t_state 
!= TCPS_LISTEN
) { 
2272                                 tp
->t_flagsext 
|= TF_FASTOPEN
; 
2274                                 tcp_disable_tfo(tp
); 
2276                 case TCP_ENABLE_ECN
: 
2277                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
2282                                 tp
->ecn_flags 
|= TE_ECN_MODE_ENABLE
; 
2283                                 tp
->ecn_flags 
&= ~TE_ECN_MODE_DISABLE
; 
2285                                 tp
->ecn_flags 
&= ~TE_ECN_MODE_ENABLE
; 
2289                         error 
= sooptcopyin(sopt
, &optval
, sizeof optval
, 
2293                         if (optval 
== ECN_MODE_DEFAULT
) { 
2294                                 tp
->ecn_flags 
&= ~TE_ECN_MODE_ENABLE
; 
2295                                 tp
->ecn_flags 
&= ~TE_ECN_MODE_DISABLE
; 
2296                         } else if (optval 
== ECN_MODE_ENABLE
) { 
2297                                 tp
->ecn_flags 
|= TE_ECN_MODE_ENABLE
; 
2298                                 tp
->ecn_flags 
&= ~TE_ECN_MODE_DISABLE
; 
2299                         } else if (optval 
== ECN_MODE_DISABLE
) { 
2300                                 tp
->ecn_flags 
&= ~TE_ECN_MODE_ENABLE
; 
2301                                 tp
->ecn_flags 
|= TE_ECN_MODE_DISABLE
; 
2306                 case TCP_NOTIFY_ACKNOWLEDGEMENT
: 
2307                         error 
= sooptcopyin(sopt
, &optval
, 
2308                             sizeof(optval
), sizeof(optval
)); 
2315                         if (tp
->t_notify_ack_count 
>= TCP_MAX_NOTIFY_ACK
) { 
2316                                 error 
= ETOOMANYREFS
; 
2321                          * validate that the given marker id is not 
2322                          * a duplicate to avoid ambiguity 
2324                         if ((error 
= tcp_notify_ack_id_valid(tp
, so
, 
2328                         error 
= tcp_add_notify_ack_marker(tp
, optval
); 
2331                         if ((error 
= sooptcopyin(sopt
, &optval
, sizeof (optval
), 
2332                             sizeof (optval
))) != 0) 
2335                         error 
= inp_flush(inp
, optval
); 
2338                 case SO_TRAFFIC_MGT_BACKGROUND
: 
2339                         if ((error 
= sooptcopyin(sopt
, &optval
, sizeof (optval
), 
2340                             sizeof (optval
))) != 0) 
2344                                 socket_set_traffic_mgt_flags_locked(so
, 
2345                                     TRAFFIC_MGT_SO_BACKGROUND
); 
2347                                 socket_clear_traffic_mgt_flags_locked(so
, 
2348                                     TRAFFIC_MGT_SO_BACKGROUND
); 
2353                         error 
= ENOPROTOOPT
; 
2359                 switch (sopt
->sopt_name
) { 
2361                         optval 
= tp
->t_flags 
& TF_NODELAY
; 
2364                         optval 
= tp
->t_maxseg
; 
2367                         if (tp
->t_keepidle 
> 0) 
2368                                 optval 
= tp
->t_keepidle 
/ TCP_RETRANSHZ
; 
2370                                 optval 
= tcp_keepidle  
/ TCP_RETRANSHZ
; 
2373                         if (tp
->t_keepintvl 
> 0) 
2374                                 optval 
= tp
->t_keepintvl 
/ TCP_RETRANSHZ
; 
2376                                 optval 
= tcp_keepintvl 
/ TCP_RETRANSHZ
; 
2379                         if (tp
->t_keepcnt 
> 0) 
2380                                 optval 
= tp
->t_keepcnt
; 
2382                                 optval 
= tcp_keepcnt
; 
2384                 case TCP_KEEPALIVE_OFFLOAD
: 
2385                         optval 
= !!(inp
->inp_flags2 
& INP2_KEEPALIVE_OFFLOAD
); 
2388                         optval 
= tp
->t_flags 
& TF_NOOPT
; 
2391                         optval 
= tp
->t_flags 
& TF_NOPUSH
; 
2393                 case TCP_ENABLE_ECN
: 
2394                         optval 
= (tp
->ecn_flags 
& TE_ECN_MODE_ENABLE
) ? 1 : 0; 
2397                         if (tp
->ecn_flags 
& TE_ECN_MODE_ENABLE
) 
2398                                 optval 
= ECN_MODE_ENABLE
; 
2399                         else if (tp
->ecn_flags 
& TE_ECN_MODE_DISABLE
) 
2400                                 optval 
= ECN_MODE_DISABLE
; 
2402                                 optval 
= ECN_MODE_DEFAULT
; 
2404                 case TCP_CONNECTIONTIMEOUT
: 
2405                         optval 
= tp
->t_keepinit 
/ TCP_RETRANSHZ
; 
2407                 case PERSIST_TIMEOUT
: 
2408                         optval 
= tp
->t_persist_timeout 
/ TCP_RETRANSHZ
; 
2410                 case TCP_RXT_CONNDROPTIME
: 
2411                         optval 
= tp
->t_rxt_conndroptime 
/ TCP_RETRANSHZ
; 
2413                 case TCP_RXT_FINDROP
: 
2414                         optval 
= tp
->t_flagsext 
& TF_RXTFINDROP
; 
2416                 case TCP_NOTIMEWAIT
: 
2417                         optval 
= (tp
->t_flagsext 
& TF_NOTIMEWAIT
) ? 1 : 0; 
2420                         if (tp
->t_state 
!= TCPS_LISTEN 
|| 
2421                             !(tcp_fastopen 
& TCP_FASTOPEN_SERVER
)) { 
2425                         optval 
= tfo_enabled(tp
); 
2427                 case TCP_MEASURE_SND_BW
: 
2428                         optval 
= tp
->t_flagsext 
& TF_MEASURESNDBW
; 
2433                         tcp_fill_info(tp
, &ti
); 
2434                         error 
= sooptcopyout(sopt
, &ti
, sizeof(struct tcp_info
)); 
2438                 case TCP_CONNECTION_INFO
: { 
2439                         struct tcp_connection_info tci
; 
2440                         tcp_connection_fill_info(tp
, &tci
); 
2441                         error 
= sooptcopyout(sopt
, &tci
, 
2442                             sizeof(struct tcp_connection_info
)); 
2445                 case TCP_MEASURE_BW_BURST
: { 
2446                         struct tcp_measure_bw_burst out
; 
2447                         if ((tp
->t_flagsext 
& TF_MEASURESNDBW
) == 0 || 
2448                                 tp
->t_bwmeas 
== NULL
) { 
2452                         out
.min_burst_size 
= tp
->t_bwmeas
->bw_minsizepkts
; 
2453                         out
.max_burst_size 
= tp
->t_bwmeas
->bw_maxsizepkts
; 
2454                         error 
= sooptcopyout(sopt
, &out
, sizeof(out
)); 
2457                 case TCP_NOTSENT_LOWAT
: 
2458                         if ((so
->so_flags 
& SOF_NOTSENT_LOWAT
) != 0) { 
2459                                 optval 
= tp
->t_notsent_lowat
; 
2465                 case TCP_ENABLE_MSGS
: 
2466                         if (so
->so_flags 
& SOF_ENABLE_MSGS
) { 
2472                 case TCP_SENDMOREACKS
: 
2473                         if (tp
->t_flagsext 
& TF_NOSTRETCHACK
) 
2478                 case TCP_DISABLE_BLACKHOLE_DETECTION
: 
2479                         if (tp
->t_flagsext 
& TF_NOBLACKHOLE_DETECTION
) 
2484                 case TCP_PEER_PID
: { 
2486                         error 
= tcp_lookup_peer_pid_locked(so
, &pid
); 
2488                                 error 
= sooptcopyout(sopt
, &pid
, sizeof(pid
)); 
2491                 case TCP_ADAPTIVE_READ_TIMEOUT
: 
2492                         optval 
= tp
->t_adaptive_rtimo
; 
2494                 case TCP_ADAPTIVE_WRITE_TIMEOUT
: 
2495                         optval 
= tp
->t_adaptive_wtimo
; 
2497                 case SO_TRAFFIC_MGT_BACKGROUND
: 
2498                         optval 
= (so
->so_flags1 
& 
2499                             SOF1_TRAFFIC_MGT_SO_BACKGROUND
) ? 1 : 0; 
2501                 case TCP_NOTIFY_ACKNOWLEDGEMENT
: { 
2502                         struct tcp_notify_ack_complete retid
; 
2504                         if (sopt
->sopt_valsize 
!= sizeof (retid
)) { 
2508                         bzero(&retid
, sizeof (retid
)); 
2509                         tcp_get_notify_ack_count(tp
, &retid
); 
2510                         if (retid
.notify_complete_count 
> 0) 
2511                                 tcp_get_notify_ack_ids(tp
, &retid
); 
2513                         error 
= sooptcopyout(sopt
, &retid
, sizeof (retid
)); 
2517                         error 
= ENOPROTOOPT
; 
2521                         error 
= sooptcopyout(sopt
, &optval
, sizeof optval
); 
2529  * tcp_sendspace and tcp_recvspace are the default send and receive window 
2530  * sizes, respectively.  These are obsolescent (this information should 
2531  * be set by the route). 
2533 u_int32_t       tcp_sendspace 
= 1448*256; 
2534 u_int32_t       tcp_recvspace 
= 1448*384; 
2536 /* During attach, the size of socket buffer allocated is limited to 
2537  * sb_max in sbreserve. Disallow setting the tcp send and recv space 
2538  * to be more than sb_max because that will cause tcp_attach to fail 
2539  * (see radar 5713060) 
2542 sysctl_tcp_sospace(struct sysctl_oid 
*oidp
, __unused 
void *arg1
, 
2543         __unused 
int arg2
, struct sysctl_req 
*req
) { 
2544         u_int32_t new_value 
= 0, *space_p 
= NULL
; 
2545         int changed 
= 0, error 
= 0; 
2546         u_quad_t sb_effective_max 
= (sb_max 
/ (MSIZE
+MCLBYTES
)) * MCLBYTES
; 
2548         switch (oidp
->oid_number
) { 
2549                 case TCPCTL_SENDSPACE
: 
2550                         space_p 
= &tcp_sendspace
; 
2552                 case TCPCTL_RECVSPACE
: 
2553                         space_p 
= &tcp_recvspace
; 
2558         error 
= sysctl_io_number(req
, *space_p
, sizeof(u_int32_t
), 
2559                 &new_value
, &changed
); 
2561                 if (new_value 
> 0 && new_value 
<= sb_effective_max
) { 
2562                         *space_p 
= new_value
; 
2570 SYSCTL_PROC(_net_inet_tcp
, TCPCTL_SENDSPACE
, sendspace
, CTLTYPE_INT 
| CTLFLAG_RW 
| CTLFLAG_LOCKED
, 
2571     &tcp_sendspace 
, 0, &sysctl_tcp_sospace
, "IU", "Maximum outgoing TCP datagram size"); 
2572 SYSCTL_PROC(_net_inet_tcp
, TCPCTL_RECVSPACE
, recvspace
, CTLTYPE_INT 
| CTLFLAG_RW 
| CTLFLAG_LOCKED
, 
2573     &tcp_recvspace 
, 0, &sysctl_tcp_sospace
, "IU", "Maximum incoming TCP datagram size"); 
2576  * Attach TCP protocol to socket, allocating 
2577  * internet protocol control block, tcp control block, 
2578  * bufer space, and entering LISTEN state if to accept connections. 
2580  * Returns:     0                       Success 
2581  *      in_pcballoc:ENOBUFS 
2582  *      in_pcballoc:ENOMEM 
2583  *      in_pcballoc:???                 [IPSEC specific] 
2587 tcp_attach(struct socket 
*so
, struct proc 
*p
) 
2593         int isipv6 
= SOCK_CHECK_DOM(so
, PF_INET6
) != 0; 
2596         error 
= in_pcballoc(so
, &tcbinfo
, p
); 
2600         inp 
= sotoinpcb(so
); 
2602         if (so
->so_snd
.sb_hiwat 
== 0 || so
->so_rcv
.sb_hiwat 
== 0) { 
2603                 error 
= soreserve(so
, tcp_sendspace
, tcp_recvspace
); 
2608         if (so
->so_snd
.sb_preconn_hiwat 
== 0) { 
2609                 soreserve_preconnect(so
, 2048); 
2612         if ((so
->so_rcv
.sb_flags 
& SB_USRSIZE
) == 0) 
2613                 so
->so_rcv
.sb_flags 
|= SB_AUTOSIZE
; 
2614         if ((so
->so_snd
.sb_flags 
& SB_USRSIZE
) == 0) 
2615                 so
->so_snd
.sb_flags 
|= SB_AUTOSIZE
; 
2619                 inp
->inp_vflag 
|= INP_IPV6
; 
2620                 inp
->in6p_hops 
= -1;    /* use kernel default */ 
2624         inp
->inp_vflag 
|= INP_IPV4
; 
2625         tp 
= tcp_newtcpcb(inp
); 
2627                 int nofd 
= so
->so_state 
& SS_NOFDREF
;   /* XXX */ 
2629                 so
->so_state 
&= ~SS_NOFDREF
;    /* don't free the socket yet */ 
2636                 so
->so_state 
|= nofd
; 
2640                 nstat_tcp_new_pcb(inp
); 
2641         tp
->t_state 
= TCPS_CLOSED
; 
2646  * Initiate (or continue) disconnect. 
2647  * If embryonic state, just send reset (once). 
2648  * If in ``let data drain'' option and linger null, just drop. 
2649  * Otherwise (hard), mark socket disconnecting and drop 
2650  * current input data; switch states based on user close, and 
2651  * send segment to peer (with FIN). 
2653 static struct tcpcb 
* 
2654 tcp_disconnect(struct tcpcb 
*tp
) 
2656         struct socket 
*so 
= tp
->t_inpcb
->inp_socket
; 
2658         if (tp
->t_state 
< TCPS_ESTABLISHED
) 
2660         else if ((so
->so_options 
& SO_LINGER
) && so
->so_linger 
== 0) 
2661                 tp 
= tcp_drop(tp
, 0); 
2663                 soisdisconnecting(so
); 
2664                 sbflush(&so
->so_rcv
); 
2665                 tp 
= tcp_usrclosed(tp
); 
2667                 /* A reset has been sent but socket exists, do not send FIN */ 
2668                 if ((so
->so_flags 
& SOF_MP_SUBFLOW
) && 
2669                     (tp
) && (tp
->t_mpflags 
& TMPF_RESET
)) 
2673                         (void) tcp_output(tp
); 
2679  * User issued close, and wish to trail through shutdown states: 
2680  * if never received SYN, just forget it.  If got a SYN from peer, 
2681  * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 
2682  * If already got a FIN from peer, then almost done; go to LAST_ACK 
2683  * state.  In all other cases, have already sent FIN to peer (e.g. 
2684  * after PRU_SHUTDOWN), and just have to play tedious game waiting 
2685  * for peer to send FIN or not respond to keep-alives, etc. 
2686  * We can let the user exit from the close as soon as the FIN is acked. 
2688 static struct tcpcb 
* 
2689 tcp_usrclosed(struct tcpcb 
*tp
) 
2691         switch (tp
->t_state
) { 
2699         case TCPS_SYN_RECEIVED
: 
2700                 tp
->t_flags 
|= TF_NEEDFIN
; 
2703         case TCPS_ESTABLISHED
: 
2704                 DTRACE_TCP4(state__change
, void, NULL
,  
2705                         struct inpcb 
*, tp
->t_inpcb
, 
2707                         int32_t, TCPS_FIN_WAIT_1
); 
2708                 tp
->t_state 
= TCPS_FIN_WAIT_1
; 
2711         case TCPS_CLOSE_WAIT
: 
2712                 DTRACE_TCP4(state__change
, void, NULL
,  
2713                         struct inpcb 
*, tp
->t_inpcb
, 
2715                         int32_t, TCPS_LAST_ACK
); 
2716                 tp
->t_state 
= TCPS_LAST_ACK
; 
2719         if (tp 
&& tp
->t_state 
>= TCPS_FIN_WAIT_2
) { 
2720                 soisdisconnected(tp
->t_inpcb
->inp_socket
); 
2721                 /* To prevent the connection hanging in FIN_WAIT_2 forever. */ 
2722                 if (tp
->t_state 
== TCPS_FIN_WAIT_2
) 
2723                         tp
->t_timer
[TCPT_2MSL
] = OFFSET_FROM_START(tp
,  
2724                                 TCP_CONN_MAXIDLE(tp
)); 
2730 tcp_in_cksum_stats(u_int32_t len
) 
2732         tcpstat
.tcps_rcv_swcsum
++; 
2733         tcpstat
.tcps_rcv_swcsum_bytes 
+= len
; 
2737 tcp_out_cksum_stats(u_int32_t len
) 
2739         tcpstat
.tcps_snd_swcsum
++; 
2740         tcpstat
.tcps_snd_swcsum_bytes 
+= len
; 
2745 tcp_in6_cksum_stats(u_int32_t len
) 
2747         tcpstat
.tcps_rcv6_swcsum
++; 
2748         tcpstat
.tcps_rcv6_swcsum_bytes 
+= len
; 
2752 tcp_out6_cksum_stats(u_int32_t len
) 
2754         tcpstat
.tcps_snd6_swcsum
++; 
2755         tcpstat
.tcps_snd6_swcsum_bytes 
+= len
; 
2759  * When messages are enabled on a TCP socket, the message priority 
2760  * is sent as a control message. This function will extract it. 
2763 tcp_get_msg_priority(struct mbuf 
*control
, uint32_t *msgpri
)  
2766         if (control 
== NULL
) 
2769         for (cm 
= M_FIRST_CMSGHDR(control
); cm
; 
2770                 cm 
= M_NXT_CMSGHDR(control
, cm
)) { 
2771                 if (cm
->cmsg_len 
< sizeof(struct cmsghdr
) || 
2772                         cm
->cmsg_len 
> control
->m_len
) { 
2775                 if (cm
->cmsg_level 
== SOL_SOCKET 
&& 
2776                         cm
->cmsg_type 
== SCM_MSG_PRIORITY
) { 
2777                         *msgpri 
= *(unsigned int *)(void *)CMSG_DATA(cm
); 
2782         VERIFY(*msgpri 
>= MSG_PRI_MIN 
&& *msgpri 
<= MSG_PRI_MAX
);