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
);