]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/tcp_usrreq.c
xnu-3247.1.106.tar.gz
[apple/xnu.git] / bsd / netinet / tcp_usrreq.c
1 /*
2 * Copyright (c) 2000-2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (c) 1982, 1986, 1988, 1993
30 * The Regents of the University of California. All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
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.
47 *
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
58 * SUCH DAMAGE.
59 *
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 $
62 */
63
64
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
68 #include <sys/sysctl.h>
69 #include <sys/mbuf.h>
70 #if INET6
71 #include <sys/domain.h>
72 #endif /* INET6 */
73 #include <sys/kasl.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #include <sys/protosw.h>
77 #include <sys/syslog.h>
78
79 #include <net/if.h>
80 #include <net/route.h>
81 #include <net/ntstat.h>
82 #include <net/content_filter.h>
83
84 #include <netinet/in.h>
85 #include <netinet/in_systm.h>
86 #if INET6
87 #include <netinet/ip6.h>
88 #endif
89 #include <netinet/in_pcb.h>
90 #if INET6
91 #include <netinet6/in6_pcb.h>
92 #endif
93 #include <netinet/in_var.h>
94 #include <netinet/ip_var.h>
95 #if INET6
96 #include <netinet6/ip6_var.h>
97 #endif
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>
105 #if TCPDEBUG
106 #include <netinet/tcp_debug.h>
107 #endif
108 #if MPTCP
109 #include <netinet/mptcp_var.h>
110 #endif /* MPTCP */
111
112 #if IPSEC
113 #include <netinet6/ipsec.h>
114 #endif /*IPSEC*/
115
116 #if FLOW_DIVERT
117 #include <netinet/flow_divert.h>
118 #endif /* FLOW_DIVERT */
119
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 *);
122
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);
126
127 /*
128 * TCP protocol interface to socket abstraction.
129 */
130 extern char *tcpstates[]; /* XXX ??? */
131
132 static int tcp_attach(struct socket *, struct proc *);
133 static int tcp_connect(struct tcpcb *, struct sockaddr *, struct proc *);
134 #if INET6
135 static int tcp6_connect(struct tcpcb *, struct sockaddr *, struct proc *);
136 static int tcp6_usr_connect(struct socket *, struct sockaddr *,
137 struct proc *);
138 #endif /* INET6 */
139 static struct tcpcb *
140 tcp_disconnect(struct tcpcb *);
141 static struct tcpcb *
142 tcp_usrclosed(struct tcpcb *);
143
144 extern uint32_t tcp_autorcvbuf_max;
145
146 extern void tcp_sbrcv_trim(struct tcpcb *tp, struct sockbuf *sb);
147
148 #if TCPDEBUG
149 #define TCPDEBUG0 int ostate = 0
150 #define TCPDEBUG1() ostate = tp ? tp->t_state : 0
151 #define TCPDEBUG2(req) if (tp && (so->so_options & SO_DEBUG)) \
152 tcp_trace(TA_USER, ostate, tp, 0, 0, req)
153 #else
154 #define TCPDEBUG0
155 #define TCPDEBUG1()
156 #define TCPDEBUG2(req)
157 #endif
158
159 SYSCTL_PROC(_net_inet_tcp, OID_AUTO, info,
160 CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_ANYBODY | CTLFLAG_KERN,
161 0 , 0, tcp_sysctl_info, "S", "TCP info per tuple");
162
163 /*
164 * TCP attaches to socket via pru_attach(), reserving space,
165 * and an internet control block.
166 *
167 * Returns: 0 Success
168 * EISCONN
169 * tcp_attach:ENOBUFS
170 * tcp_attach:ENOMEM
171 * tcp_attach:??? [IPSEC specific]
172 */
173 static int
174 tcp_usr_attach(struct socket *so, __unused int proto, struct proc *p)
175 {
176 int error;
177 struct inpcb *inp = sotoinpcb(so);
178 struct tcpcb *tp = 0;
179 TCPDEBUG0;
180
181 TCPDEBUG1();
182 if (inp) {
183 error = EISCONN;
184 goto out;
185 }
186
187 error = tcp_attach(so, p);
188 if (error)
189 goto out;
190
191 if ((so->so_options & SO_LINGER) && so->so_linger == 0)
192 so->so_linger = TCP_LINGERTIME * hz;
193 tp = sototcpcb(so);
194 out:
195 TCPDEBUG2(PRU_ATTACH);
196 return error;
197 }
198
199 /*
200 * pru_detach() detaches the TCP protocol from the socket.
201 * If the protocol state is non-embryonic, then can't
202 * do this directly: have to initiate a pru_disconnect(),
203 * which may finish later; embryonic TCB's can just
204 * be discarded here.
205 */
206 static int
207 tcp_usr_detach(struct socket *so)
208 {
209 int error = 0;
210 struct inpcb *inp = sotoinpcb(so);
211 struct tcpcb *tp;
212 TCPDEBUG0;
213
214 if (inp == 0 || (inp->inp_state == INPCB_STATE_DEAD)) {
215 return EINVAL; /* XXX */
216 }
217 lck_mtx_assert(&((struct inpcb *)so->so_pcb)->inpcb_mtx, LCK_MTX_ASSERT_OWNED);
218 tp = intotcpcb(inp);
219 /* In case we got disconnected from the peer */
220 if (tp == NULL)
221 goto out;
222 TCPDEBUG1();
223
224 calculate_tcp_clock();
225
226 tp = tcp_disconnect(tp);
227 out:
228 TCPDEBUG2(PRU_DETACH);
229 return error;
230 }
231
232 #if NECP
233 #define COMMON_START() TCPDEBUG0; \
234 do { \
235 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD) \
236 return (EINVAL); \
237 if (necp_socket_should_use_flow_divert(inp)) \
238 return (EPROTOTYPE); \
239 tp = intotcpcb(inp); \
240 TCPDEBUG1(); \
241 calculate_tcp_clock(); \
242 } while (0)
243 #else /* NECP */
244 #define COMMON_START() TCPDEBUG0; \
245 do { \
246 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD) \
247 return (EINVAL); \
248 tp = intotcpcb(inp); \
249 TCPDEBUG1(); \
250 calculate_tcp_clock(); \
251 } while (0)
252 #endif /* !NECP */
253
254 #define COMMON_END(req) out: TCPDEBUG2(req); return error; goto out
255
256
257 /*
258 * Give the socket an address.
259 *
260 * Returns: 0 Success
261 * EINVAL Invalid argument [COMMON_START]
262 * EAFNOSUPPORT Address family not supported
263 * in_pcbbind:EADDRNOTAVAIL Address not available.
264 * in_pcbbind:EINVAL Invalid argument
265 * in_pcbbind:EAFNOSUPPORT Address family not supported [notdef]
266 * in_pcbbind:EACCES Permission denied
267 * in_pcbbind:EADDRINUSE Address in use
268 * in_pcbbind:EAGAIN Resource unavailable, try again
269 * in_pcbbind:EPERM Operation not permitted
270 */
271 static int
272 tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
273 {
274 int error = 0;
275 struct inpcb *inp = sotoinpcb(so);
276 struct tcpcb *tp;
277 struct sockaddr_in *sinp;
278
279 COMMON_START();
280
281 if (nam->sa_family != 0 && nam->sa_family != AF_INET) {
282 error = EAFNOSUPPORT;
283 goto out;
284 }
285
286 /*
287 * Must check for multicast addresses and disallow binding
288 * to them.
289 */
290 sinp = (struct sockaddr_in *)(void *)nam;
291 if (sinp->sin_family == AF_INET &&
292 IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
293 error = EAFNOSUPPORT;
294 goto out;
295 }
296 error = in_pcbbind(inp, nam, p);
297 if (error)
298 goto out;
299 COMMON_END(PRU_BIND);
300
301 }
302
303 #if INET6
304 static int
305 tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
306 {
307 int error = 0;
308 struct inpcb *inp = sotoinpcb(so);
309 struct tcpcb *tp;
310 struct sockaddr_in6 *sin6p;
311
312 COMMON_START();
313
314 if (nam->sa_family != 0 && nam->sa_family != AF_INET6) {
315 error = EAFNOSUPPORT;
316 goto out;
317 }
318
319 /*
320 * Must check for multicast addresses and disallow binding
321 * to them.
322 */
323 sin6p = (struct sockaddr_in6 *)(void *)nam;
324 if (sin6p->sin6_family == AF_INET6 &&
325 IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
326 error = EAFNOSUPPORT;
327 goto out;
328 }
329 inp->inp_vflag &= ~INP_IPV4;
330 inp->inp_vflag |= INP_IPV6;
331 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
332 if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr))
333 inp->inp_vflag |= INP_IPV4;
334 else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
335 struct sockaddr_in sin;
336
337 in6_sin6_2_sin(&sin, sin6p);
338 inp->inp_vflag |= INP_IPV4;
339 inp->inp_vflag &= ~INP_IPV6;
340 error = in_pcbbind(inp, (struct sockaddr *)&sin, p);
341 goto out;
342 }
343 }
344 error = in6_pcbbind(inp, nam, p);
345 if (error)
346 goto out;
347 COMMON_END(PRU_BIND);
348 }
349 #endif /* INET6 */
350
351 /*
352 * Prepare to accept connections.
353 *
354 * Returns: 0 Success
355 * EINVAL [COMMON_START]
356 * in_pcbbind:EADDRNOTAVAIL Address not available.
357 * in_pcbbind:EINVAL Invalid argument
358 * in_pcbbind:EAFNOSUPPORT Address family not supported [notdef]
359 * in_pcbbind:EACCES Permission denied
360 * in_pcbbind:EADDRINUSE Address in use
361 * in_pcbbind:EAGAIN Resource unavailable, try again
362 * in_pcbbind:EPERM Operation not permitted
363 */
364 static int
365 tcp_usr_listen(struct socket *so, struct proc *p)
366 {
367 int error = 0;
368 struct inpcb *inp = sotoinpcb(so);
369 struct tcpcb *tp;
370
371 COMMON_START();
372 if (inp->inp_lport == 0)
373 error = in_pcbbind(inp, NULL, p);
374 if (error == 0)
375 tp->t_state = TCPS_LISTEN;
376 COMMON_END(PRU_LISTEN);
377 }
378
379 #if INET6
380 static int
381 tcp6_usr_listen(struct socket *so, struct proc *p)
382 {
383 int error = 0;
384 struct inpcb *inp = sotoinpcb(so);
385 struct tcpcb *tp;
386
387 COMMON_START();
388 if (inp->inp_lport == 0) {
389 inp->inp_vflag &= ~INP_IPV4;
390 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
391 inp->inp_vflag |= INP_IPV4;
392 error = in6_pcbbind(inp, NULL, p);
393 }
394 if (error == 0)
395 tp->t_state = TCPS_LISTEN;
396 COMMON_END(PRU_LISTEN);
397 }
398 #endif /* INET6 */
399
400 static int
401 tcp_connect_complete(struct socket *so)
402 {
403 struct tcpcb *tp = sototcpcb(so);
404 int error = 0;
405
406 /* TFO delays the tcp_output until later, when the app calls write() */
407 if (so->so_flags1 & SOF1_PRECONNECT_DATA) {
408 if (!necp_socket_is_allowed_to_send_recv(sotoinpcb(so), NULL, NULL))
409 return (EHOSTUNREACH);
410
411 /* Initialize enough state so that we can actually send data */
412 tcp_mss(tp, -1, IFSCOPE_NONE);
413 tp->snd_wnd = tp->t_maxseg;
414 } else {
415 error = tcp_output(tp);
416 }
417
418 return (error);
419 }
420
421 /*
422 * Initiate connection to peer.
423 * Create a template for use in transmissions on this connection.
424 * Enter SYN_SENT state, and mark socket as connecting.
425 * Start keep-alive timer, and seed output sequence space.
426 * Send initial segment on connection.
427 */
428 static int
429 tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
430 {
431 int error = 0;
432 struct inpcb *inp = sotoinpcb(so);
433 struct tcpcb *tp;
434 struct sockaddr_in *sinp;
435
436 TCPDEBUG0;
437 if (inp == NULL) {
438 return EINVAL;
439 } else if (inp->inp_state == INPCB_STATE_DEAD) {
440 if (so->so_error) {
441 error = so->so_error;
442 so->so_error = 0;
443 return error;
444 } else
445 return EINVAL;
446 }
447 #if NECP
448 #if FLOW_DIVERT
449 else if (necp_socket_should_use_flow_divert(inp)) {
450 uint32_t fd_ctl_unit = necp_socket_get_flow_divert_control_unit(inp);
451 if (fd_ctl_unit > 0) {
452 error = flow_divert_pcb_init(so, fd_ctl_unit);
453 if (error == 0) {
454 error = flow_divert_connect_out(so, nam, p);
455 }
456 } else {
457 error = ENETDOWN;
458 }
459
460 /* Disable PRECONNECT_DATA, as we don't need to send a SYN anymore. */
461 so->so_flags1 &= ~SOF1_PRECONNECT_DATA;
462 return error;
463 }
464 #endif /* FLOW_DIVERT */
465 #if CONTENT_FILTER
466 error = cfil_sock_attach(so);
467 if (error != 0)
468 return error;
469 #endif /* CONTENT_FILTER */
470 #endif /* NECP */
471 tp = intotcpcb(inp);
472 TCPDEBUG1();
473
474 calculate_tcp_clock();
475
476 if (nam->sa_family != 0 && nam->sa_family != AF_INET) {
477 error = EAFNOSUPPORT;
478 goto out;
479 }
480 /*
481 * Must disallow TCP ``connections'' to multicast addresses.
482 */
483 sinp = (struct sockaddr_in *)(void *)nam;
484 if (sinp->sin_family == AF_INET
485 && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
486 error = EAFNOSUPPORT;
487 goto out;
488 }
489
490 if ((error = tcp_connect(tp, nam, p)) != 0)
491 goto out;
492
493 error = tcp_connect_complete(so);
494
495 COMMON_END(PRU_CONNECT);
496 }
497
498 static int
499 tcp_usr_connectx_common(struct socket *so, int af,
500 struct sockaddr_list **src_sl, struct sockaddr_list **dst_sl,
501 struct proc *p, uint32_t ifscope, sae_associd_t aid, sae_connid_t *pcid,
502 uint32_t flags, void *arg, uint32_t arglen, struct uio *auio,
503 user_ssize_t *bytes_written)
504 {
505 #pragma unused(aid)
506 #if !MPTCP
507 #pragma unused(flags, arg, arglen)
508 #endif /* !MPTCP */
509 struct sockaddr_entry *src_se = NULL, *dst_se = NULL;
510 struct inpcb *inp = sotoinpcb(so);
511 int error;
512 user_ssize_t datalen = 0;
513
514 if (inp == NULL)
515 return (EINVAL);
516
517 VERIFY(dst_sl != NULL);
518
519 /* select source (if specified) and destination addresses */
520 error = in_selectaddrs(af, src_sl, &src_se, dst_sl, &dst_se);
521 if (error != 0)
522 return (error);
523
524 VERIFY(*dst_sl != NULL && dst_se != NULL);
525 VERIFY(src_se == NULL || *src_sl != NULL);
526 VERIFY(dst_se->se_addr->sa_family == af);
527 VERIFY(src_se == NULL || src_se->se_addr->sa_family == af);
528
529 #if NECP
530 inp_update_necp_policy(inp, src_se ? src_se->se_addr : NULL, dst_se ? dst_se->se_addr : NULL, ifscope);
531 #endif /* NECP */
532
533 if ((so->so_flags1 & SOF1_DATA_IDEMPOTENT) &&
534 (tcp_fastopen & TCP_FASTOPEN_CLIENT))
535 sototcpcb(so)->t_flagsext |= TF_FASTOPEN;
536
537 /*
538 * We get here for 2 cases:
539 *
540 * a. From MPTCP, to connect a subflow. There is no need to
541 * bind the socket to the source address and/or interface,
542 * since everything has been taken care of by MPTCP. We
543 * simply check whether or not this is for the initial
544 * MPTCP connection attempt, or to join an existing one.
545 *
546 * b. From the socket layer, to connect a TCP. Perform the
547 * bind to source address and/or interface as necessary.
548 */
549 #if MPTCP
550 if (flags & CONNREQF_MPTCP) {
551 struct mptsub_connreq *mpcr = arg;
552
553 /* Check to make sure this came down from MPTCP */
554 if (arg == NULL || arglen != sizeof (*mpcr))
555 return (EOPNOTSUPP);
556
557 switch (mpcr->mpcr_type) {
558 case MPTSUB_CONNREQ_MP_ENABLE:
559 break;
560 case MPTSUB_CONNREQ_MP_ADD:
561 break;
562 default:
563 return (EOPNOTSUPP);
564 }
565 } else
566 #endif /* MPTCP */
567 {
568 /* bind socket to the specified interface, if requested */
569 if (ifscope != IFSCOPE_NONE &&
570 (error = inp_bindif(inp, ifscope, NULL)) != 0)
571 return (error);
572
573 /* if source address and/or port is specified, bind to it */
574 if (src_se != NULL) {
575 struct sockaddr *sa = src_se->se_addr;
576 error = sobindlock(so, sa, 0); /* already locked */
577 if (error != 0)
578 return (error);
579 }
580 }
581
582 switch (af) {
583 case AF_INET:
584 error = tcp_usr_connect(so, dst_se->se_addr, p);
585 break;
586 #if INET6
587 case AF_INET6:
588 error = tcp6_usr_connect(so, dst_se->se_addr, p);
589 break;
590 #endif /* INET6 */
591 default:
592 VERIFY(0);
593 /* NOTREACHED */
594 }
595
596 if (error != 0)
597 return (error);
598
599 /* if there is data, copy it */
600 if (auio != NULL) {
601 socket_unlock(so, 0);
602
603 VERIFY(bytes_written != NULL);
604
605 datalen = uio_resid(auio);
606 error = so->so_proto->pr_usrreqs->pru_sosend(so, NULL,
607 (uio_t)auio, NULL, NULL, 0);
608 socket_lock(so, 0);
609
610 if (error == 0 || error == EWOULDBLOCK)
611 *bytes_written = datalen - uio_resid(auio);
612
613 /*
614 * sosend returns EWOULDBLOCK if it's a non-blocking
615 * socket or a timeout occured (this allows to return
616 * the amount of queued data through sendit()).
617 *
618 * However, connectx() returns EINPROGRESS in case of a
619 * blocking socket. So we change the return value here.
620 */
621 if (error == EWOULDBLOCK)
622 error = EINPROGRESS;
623 }
624
625 if (error == 0 && pcid != NULL)
626 *pcid = 1; /* there is only one connection in regular TCP */
627
628 return (error);
629 }
630
631 static int
632 tcp_usr_connectx(struct socket *so, struct sockaddr_list **src_sl,
633 struct sockaddr_list **dst_sl, struct proc *p, uint32_t ifscope,
634 sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
635 uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
636 {
637 return (tcp_usr_connectx_common(so, AF_INET, src_sl, dst_sl,
638 p, ifscope, aid, pcid, flags, arg, arglen, uio,
639 bytes_written));
640 }
641
642 #if INET6
643 static int
644 tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
645 {
646 int error = 0;
647 struct inpcb *inp = sotoinpcb(so);
648 struct tcpcb *tp;
649 struct sockaddr_in6 *sin6p;
650
651 TCPDEBUG0;
652 if (inp == NULL) {
653 return EINVAL;
654 } else if (inp->inp_state == INPCB_STATE_DEAD) {
655 if (so->so_error) {
656 error = so->so_error;
657 so->so_error = 0;
658 return error;
659 } else
660 return EINVAL;
661 }
662 #if NECP
663 #if FLOW_DIVERT
664 else if (necp_socket_should_use_flow_divert(inp)) {
665 uint32_t fd_ctl_unit = necp_socket_get_flow_divert_control_unit(inp);
666 if (fd_ctl_unit > 0) {
667 error = flow_divert_pcb_init(so, fd_ctl_unit);
668 if (error == 0) {
669 error = flow_divert_connect_out(so, nam, p);
670 }
671 } else {
672 error = ENETDOWN;
673 }
674 return error;
675 }
676 #endif /* FLOW_DIVERT */
677 #if CONTENT_FILTER
678 error = cfil_sock_attach(so);
679 if (error != 0)
680 return error;
681 #endif /* CONTENT_FILTER */
682 #endif /* NECP */
683
684 tp = intotcpcb(inp);
685 TCPDEBUG1();
686
687 calculate_tcp_clock();
688
689 if (nam->sa_family != 0 && nam->sa_family != AF_INET6) {
690 error = EAFNOSUPPORT;
691 goto out;
692 }
693
694 /*
695 * Must disallow TCP ``connections'' to multicast addresses.
696 */
697 sin6p = (struct sockaddr_in6 *)(void *)nam;
698 if (sin6p->sin6_family == AF_INET6
699 && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
700 error = EAFNOSUPPORT;
701 goto out;
702 }
703
704 if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
705 struct sockaddr_in sin;
706
707 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)
708 return (EINVAL);
709
710 in6_sin6_2_sin(&sin, sin6p);
711 inp->inp_vflag |= INP_IPV4;
712 inp->inp_vflag &= ~INP_IPV6;
713 if ((error = tcp_connect(tp, (struct sockaddr *)&sin, p)) != 0)
714 goto out;
715
716 error = tcp_connect_complete(so);
717 goto out;
718 }
719 inp->inp_vflag &= ~INP_IPV4;
720 inp->inp_vflag |= INP_IPV6;
721 if ((error = tcp6_connect(tp, nam, p)) != 0)
722 goto out;
723
724 error = tcp_connect_complete(so);
725 COMMON_END(PRU_CONNECT);
726 }
727
728 static int
729 tcp6_usr_connectx(struct socket *so, struct sockaddr_list **src_sl,
730 struct sockaddr_list **dst_sl, struct proc *p, uint32_t ifscope,
731 sae_associd_t aid, sae_connid_t *pcid, uint32_t flags, void *arg,
732 uint32_t arglen, struct uio *uio, user_ssize_t *bytes_written)
733 {
734 return (tcp_usr_connectx_common(so, AF_INET6, src_sl, dst_sl,
735 p, ifscope, aid, pcid, flags, arg, arglen, uio,
736 bytes_written));
737 }
738 #endif /* INET6 */
739
740 /*
741 * Initiate disconnect from peer.
742 * If connection never passed embryonic stage, just drop;
743 * else if don't need to let data drain, then can just drop anyways,
744 * else have to begin TCP shutdown process: mark socket disconnecting,
745 * drain unread data, state switch to reflect user close, and
746 * send segment (e.g. FIN) to peer. Socket will be really disconnected
747 * when peer sends FIN and acks ours.
748 *
749 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
750 */
751 static int
752 tcp_usr_disconnect(struct socket *so)
753 {
754 int error = 0;
755 struct inpcb *inp = sotoinpcb(so);
756 struct tcpcb *tp;
757
758 lck_mtx_assert(&((struct inpcb *)so->so_pcb)->inpcb_mtx,
759 LCK_MTX_ASSERT_OWNED);
760 COMMON_START();
761 /* In case we got disconnected from the peer */
762 if (tp == NULL)
763 goto out;
764 tp = tcp_disconnect(tp);
765 COMMON_END(PRU_DISCONNECT);
766 }
767
768 /*
769 * User-protocol pru_disconnectx callback.
770 */
771 static int
772 tcp_usr_disconnectx(struct socket *so, sae_associd_t aid, sae_connid_t cid)
773 {
774 #pragma unused(cid)
775 if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL)
776 return (EINVAL);
777
778 return (tcp_usr_disconnect(so));
779 }
780
781 /*
782 * Accept a connection. Essentially all the work is
783 * done at higher levels; just return the address
784 * of the peer, storing through addr.
785 */
786 static int
787 tcp_usr_accept(struct socket *so, struct sockaddr **nam)
788 {
789 int error = 0;
790 struct inpcb *inp = sotoinpcb(so);
791 struct tcpcb *tp = NULL;
792 TCPDEBUG0;
793
794 in_getpeeraddr(so, nam);
795
796 if (so->so_state & SS_ISDISCONNECTED) {
797 error = ECONNABORTED;
798 goto out;
799 }
800 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD)
801 return (EINVAL);
802 #if NECP
803 else if (necp_socket_should_use_flow_divert(inp))
804 return (EPROTOTYPE);
805 #if CONTENT_FILTER
806 error = cfil_sock_attach(so);
807 if (error != 0)
808 return (error);
809 #endif /* CONTENT_FILTER */
810 #endif /* NECP */
811
812 tp = intotcpcb(inp);
813 TCPDEBUG1();
814
815 calculate_tcp_clock();
816
817 COMMON_END(PRU_ACCEPT);
818 }
819
820 #if INET6
821 static int
822 tcp6_usr_accept(struct socket *so, struct sockaddr **nam)
823 {
824 int error = 0;
825 struct inpcb *inp = sotoinpcb(so);
826 struct tcpcb *tp = NULL;
827 TCPDEBUG0;
828
829 if (so->so_state & SS_ISDISCONNECTED) {
830 error = ECONNABORTED;
831 goto out;
832 }
833 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD)
834 return (EINVAL);
835 #if NECP
836 else if (necp_socket_should_use_flow_divert(inp))
837 return (EPROTOTYPE);
838 #if CONTENT_FILTER
839 error = cfil_sock_attach(so);
840 if (error != 0)
841 return (error);
842 #endif /* CONTENT_FILTER */
843 #endif /* NECP */
844
845 tp = intotcpcb(inp);
846 TCPDEBUG1();
847
848 calculate_tcp_clock();
849
850 in6_mapped_peeraddr(so, nam);
851 COMMON_END(PRU_ACCEPT);
852 }
853 #endif /* INET6 */
854
855 /*
856 * Mark the connection as being incapable of further output.
857 *
858 * Returns: 0 Success
859 * EINVAL [COMMON_START]
860 * tcp_output:EADDRNOTAVAIL
861 * tcp_output:ENOBUFS
862 * tcp_output:EMSGSIZE
863 * tcp_output:EHOSTUNREACH
864 * tcp_output:ENETUNREACH
865 * tcp_output:ENETDOWN
866 * tcp_output:ENOMEM
867 * tcp_output:EACCES
868 * tcp_output:EMSGSIZE
869 * tcp_output:ENOBUFS
870 * tcp_output:??? [ignorable: mostly IPSEC/firewall/DLIL]
871 */
872 static int
873 tcp_usr_shutdown(struct socket *so)
874 {
875 int error = 0;
876 struct inpcb *inp = sotoinpcb(so);
877 struct tcpcb *tp;
878
879 TCPDEBUG0;
880 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD)
881 return (EINVAL);
882
883 socantsendmore(so);
884
885 /*
886 * In case we got disconnected from the peer, or if this is
887 * a socket that is to be flow-diverted (but not yet).
888 */
889 tp = intotcpcb(inp);
890 TCPDEBUG1();
891
892 if (tp == NULL
893 #if NECP
894 || (necp_socket_should_use_flow_divert(inp))
895 #endif /* NECP */
896 ) {
897 if (tp != NULL)
898 error = EPROTOTYPE;
899 goto out;
900 }
901
902 calculate_tcp_clock();
903
904 tp = tcp_usrclosed(tp);
905 #if MPTCP
906 /* A reset has been sent but socket exists, do not send FIN */
907 if ((so->so_flags & SOF_MP_SUBFLOW) &&
908 (tp) && (tp->t_mpflags & TMPF_RESET)) {
909 goto out;
910 }
911 #endif
912 #if CONTENT_FILTER
913 /* Don't send a FIN yet */
914 if (tp && !(so->so_state & SS_ISDISCONNECTED) &&
915 cfil_sock_data_pending(&so->so_snd))
916 goto out;
917 #endif /* CONTENT_FILTER */
918 if (tp)
919 error = tcp_output(tp);
920 COMMON_END(PRU_SHUTDOWN);
921 }
922
923 /*
924 * After a receive, possibly send window update to peer.
925 */
926 static int
927 tcp_usr_rcvd(struct socket *so, __unused int flags)
928 {
929 int error = 0;
930 struct inpcb *inp = sotoinpcb(so);
931 struct tcpcb *tp;
932
933 COMMON_START();
934 /* In case we got disconnected from the peer */
935 if (tp == NULL)
936 goto out;
937 tcp_sbrcv_trim(tp, &so->so_rcv);
938
939 /*
940 * This tcp_output is solely there to trigger window-updates.
941 * However, we really do not want these window-updates while we
942 * are still in SYN_SENT or SYN_RECEIVED.
943 */
944 if (TCPS_HAVEESTABLISHED(tp->t_state))
945 tcp_output(tp);
946
947 #if CONTENT_FILTER
948 cfil_sock_buf_update(&so->so_rcv);
949 #endif /* CONTENT_FILTER */
950
951 COMMON_END(PRU_RCVD);
952 }
953
954 /*
955 * Do a send by putting data in output queue and updating urgent
956 * marker if URG set. Possibly send more data. Unlike the other
957 * pru_*() routines, the mbuf chains are our responsibility. We
958 * must either enqueue them or free them. The other pru_* routines
959 * generally are caller-frees.
960 *
961 * Returns: 0 Success
962 * ECONNRESET
963 * EINVAL
964 * ENOBUFS
965 * tcp_connect:EADDRINUSE Address in use
966 * tcp_connect:EADDRNOTAVAIL Address not available.
967 * tcp_connect:EINVAL Invalid argument
968 * tcp_connect:EAFNOSUPPORT Address family not supported [notdef]
969 * tcp_connect:EACCES Permission denied
970 * tcp_connect:EAGAIN Resource unavailable, try again
971 * tcp_connect:EPERM Operation not permitted
972 * tcp_output:EADDRNOTAVAIL
973 * tcp_output:ENOBUFS
974 * tcp_output:EMSGSIZE
975 * tcp_output:EHOSTUNREACH
976 * tcp_output:ENETUNREACH
977 * tcp_output:ENETDOWN
978 * tcp_output:ENOMEM
979 * tcp_output:EACCES
980 * tcp_output:EMSGSIZE
981 * tcp_output:ENOBUFS
982 * tcp_output:??? [ignorable: mostly IPSEC/firewall/DLIL]
983 * tcp6_connect:??? [IPV6 only]
984 */
985 static int
986 tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
987 struct sockaddr *nam, struct mbuf *control, struct proc *p)
988 {
989 int error = 0;
990 struct inpcb *inp = sotoinpcb(so);
991 struct tcpcb *tp;
992 uint32_t msgpri = MSG_PRI_DEFAULT;
993 #if INET6
994 int isipv6;
995 #endif
996 TCPDEBUG0;
997
998 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD
999 #if NECP
1000 || (necp_socket_should_use_flow_divert(inp))
1001 #endif /* NECP */
1002 ) {
1003 /*
1004 * OOPS! we lost a race, the TCP session got reset after
1005 * we checked SS_CANTSENDMORE, eg: while doing uiomove or a
1006 * network interrupt in the non-splnet() section of sosend().
1007 */
1008 if (m != NULL)
1009 m_freem(m);
1010 if (control != NULL) {
1011 m_freem(control);
1012 control = NULL;
1013 }
1014
1015 if (inp == NULL)
1016 error = ECONNRESET; /* XXX EPIPE? */
1017 else
1018 error = EPROTOTYPE;
1019 tp = NULL;
1020 TCPDEBUG1();
1021 goto out;
1022 }
1023 #if INET6
1024 isipv6 = nam && nam->sa_family == AF_INET6;
1025 #endif /* INET6 */
1026 tp = intotcpcb(inp);
1027 TCPDEBUG1();
1028
1029 calculate_tcp_clock();
1030
1031 if (control != NULL) {
1032 if (so->so_flags & SOF_ENABLE_MSGS) {
1033 /* Get the msg priority from control mbufs */
1034 error = tcp_get_msg_priority(control, &msgpri);
1035 if (error) {
1036 m_freem(control);
1037 if (m != NULL)
1038 m_freem(m);
1039 control = NULL;
1040 m = NULL;
1041 goto out;
1042 }
1043 m_freem(control);
1044 control = NULL;
1045 } else if (control->m_len) {
1046 /*
1047 * if not unordered, TCP should not have
1048 * control mbufs
1049 */
1050 m_freem(control);
1051 if (m != NULL)
1052 m_freem(m);
1053 control = NULL;
1054 m = NULL;
1055 error = EINVAL;
1056 goto out;
1057 }
1058 }
1059
1060 if (so->so_flags & SOF_ENABLE_MSGS) {
1061 VERIFY(m->m_flags & M_PKTHDR);
1062 m->m_pkthdr.msg_pri = msgpri;
1063 }
1064
1065 /* MPTCP sublow socket buffers must not be compressed */
1066 VERIFY(!(so->so_flags & SOF_MP_SUBFLOW) ||
1067 (so->so_snd.sb_flags & SB_NOCOMPRESS));
1068
1069 if(!(flags & PRUS_OOB) || (so->so_flags1 & SOF1_PRECONNECT_DATA)) {
1070 /* Call msg send if message delivery is enabled */
1071 if (so->so_flags & SOF_ENABLE_MSGS)
1072 sbappendmsg_snd(&so->so_snd, m);
1073 else
1074 sbappendstream(&so->so_snd, m);
1075
1076 if (nam && tp->t_state < TCPS_SYN_SENT) {
1077
1078 /*
1079 * Do implied connect if not yet connected,
1080 * initialize window to default value, and
1081 * initialize maxseg/maxopd using peer's cached
1082 * MSS.
1083 */
1084 #if INET6
1085 if (isipv6)
1086 error = tcp6_connect(tp, nam, p);
1087 else
1088 #endif /* INET6 */
1089 error = tcp_connect(tp, nam, p);
1090 if (error)
1091 goto out;
1092 tp->snd_wnd = TTCP_CLIENT_SND_WND;
1093 tcp_mss(tp, -1, IFSCOPE_NONE);
1094 }
1095
1096 if (flags & PRUS_EOF) {
1097 /*
1098 * Close the send side of the connection after
1099 * the data is sent.
1100 */
1101 socantsendmore(so);
1102 tp = tcp_usrclosed(tp);
1103 }
1104 if (tp != NULL) {
1105 if (flags & PRUS_MORETOCOME)
1106 tp->t_flags |= TF_MORETOCOME;
1107 error = tcp_output(tp);
1108 if (flags & PRUS_MORETOCOME)
1109 tp->t_flags &= ~TF_MORETOCOME;
1110 }
1111 } else {
1112 if (sbspace(&so->so_snd) == 0) {
1113 /* if no space is left in sockbuf,
1114 * do not try to squeeze in OOB traffic */
1115 m_freem(m);
1116 error = ENOBUFS;
1117 goto out;
1118 }
1119 /*
1120 * According to RFC961 (Assigned Protocols),
1121 * the urgent pointer points to the last octet
1122 * of urgent data. We continue, however,
1123 * to consider it to indicate the first octet
1124 * of data past the urgent section.
1125 * Otherwise, snd_up should be one lower.
1126 */
1127 sbappendstream(&so->so_snd, m);
1128 if (nam && tp->t_state < TCPS_SYN_SENT) {
1129 /*
1130 * Do implied connect if not yet connected,
1131 * initialize window to default value, and
1132 * initialize maxseg/maxopd using peer's cached
1133 * MSS.
1134 */
1135 #if INET6
1136 if (isipv6)
1137 error = tcp6_connect(tp, nam, p);
1138 else
1139 #endif /* INET6 */
1140 error = tcp_connect(tp, nam, p);
1141 if (error)
1142 goto out;
1143 tp->snd_wnd = TTCP_CLIENT_SND_WND;
1144 tcp_mss(tp, -1, IFSCOPE_NONE);
1145 }
1146 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
1147 tp->t_flagsext |= TF_FORCE;
1148 error = tcp_output(tp);
1149 tp->t_flagsext &= ~TF_FORCE;
1150 }
1151
1152
1153 /*
1154 * We wait for the socket to successfully connect before returning.
1155 * This allows us to signal a timeout to the application.
1156 */
1157 if (so->so_state & SS_ISCONNECTING) {
1158 if (so->so_state & SS_NBIO)
1159 error = EWOULDBLOCK;
1160 else
1161 error = sbwait(&so->so_snd);
1162 }
1163
1164 COMMON_END((flags & PRUS_OOB) ? PRU_SENDOOB :
1165 ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
1166 }
1167
1168 /*
1169 * Abort the TCP.
1170 */
1171 static int
1172 tcp_usr_abort(struct socket *so)
1173 {
1174 int error = 0;
1175 struct inpcb *inp = sotoinpcb(so);
1176 struct tcpcb *tp;
1177
1178 COMMON_START();
1179 /* In case we got disconnected from the peer */
1180 if (tp == NULL)
1181 goto out;
1182 tp = tcp_drop(tp, ECONNABORTED);
1183 so->so_usecount--;
1184 COMMON_END(PRU_ABORT);
1185 }
1186
1187 /*
1188 * Receive out-of-band data.
1189 *
1190 * Returns: 0 Success
1191 * EINVAL [COMMON_START]
1192 * EINVAL
1193 * EWOULDBLOCK
1194 */
1195 static int
1196 tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
1197 {
1198 int error = 0;
1199 struct inpcb *inp = sotoinpcb(so);
1200 struct tcpcb *tp;
1201
1202 COMMON_START();
1203 if ((so->so_oobmark == 0 &&
1204 (so->so_state & SS_RCVATMARK) == 0) ||
1205 so->so_options & SO_OOBINLINE ||
1206 tp->t_oobflags & TCPOOB_HADDATA) {
1207 error = EINVAL;
1208 goto out;
1209 }
1210 if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
1211 error = EWOULDBLOCK;
1212 goto out;
1213 }
1214 m->m_len = 1;
1215 *mtod(m, caddr_t) = tp->t_iobc;
1216 if ((flags & MSG_PEEK) == 0)
1217 tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
1218 COMMON_END(PRU_RCVOOB);
1219 }
1220
1221 static int
1222 tcp_usr_preconnect(struct socket *so)
1223 {
1224 int error = tcp_output(sototcpcb(so));
1225
1226 /* One read has been done. This was enough. Get back to "normal" behavior. */
1227 so->so_flags1 &= ~SOF1_PRECONNECT_DATA;
1228
1229 COMMON_END(PRU_PRECONNECT);
1230 }
1231
1232 /* xxx - should be const */
1233 struct pr_usrreqs tcp_usrreqs = {
1234 .pru_abort = tcp_usr_abort,
1235 .pru_accept = tcp_usr_accept,
1236 .pru_attach = tcp_usr_attach,
1237 .pru_bind = tcp_usr_bind,
1238 .pru_connect = tcp_usr_connect,
1239 .pru_connectx = tcp_usr_connectx,
1240 .pru_control = in_control,
1241 .pru_detach = tcp_usr_detach,
1242 .pru_disconnect = tcp_usr_disconnect,
1243 .pru_disconnectx = tcp_usr_disconnectx,
1244 .pru_listen = tcp_usr_listen,
1245 .pru_peeraddr = in_getpeeraddr,
1246 .pru_rcvd = tcp_usr_rcvd,
1247 .pru_rcvoob = tcp_usr_rcvoob,
1248 .pru_send = tcp_usr_send,
1249 .pru_shutdown = tcp_usr_shutdown,
1250 .pru_sockaddr = in_getsockaddr,
1251 .pru_sosend = sosend,
1252 .pru_soreceive = soreceive,
1253 .pru_preconnect = tcp_usr_preconnect,
1254 };
1255
1256 #if INET6
1257 struct pr_usrreqs tcp6_usrreqs = {
1258 .pru_abort = tcp_usr_abort,
1259 .pru_accept = tcp6_usr_accept,
1260 .pru_attach = tcp_usr_attach,
1261 .pru_bind = tcp6_usr_bind,
1262 .pru_connect = tcp6_usr_connect,
1263 .pru_connectx = tcp6_usr_connectx,
1264 .pru_control = in6_control,
1265 .pru_detach = tcp_usr_detach,
1266 .pru_disconnect = tcp_usr_disconnect,
1267 .pru_disconnectx = tcp_usr_disconnectx,
1268 .pru_listen = tcp6_usr_listen,
1269 .pru_peeraddr = in6_mapped_peeraddr,
1270 .pru_rcvd = tcp_usr_rcvd,
1271 .pru_rcvoob = tcp_usr_rcvoob,
1272 .pru_send = tcp_usr_send,
1273 .pru_shutdown = tcp_usr_shutdown,
1274 .pru_sockaddr = in6_mapped_sockaddr,
1275 .pru_sosend = sosend,
1276 .pru_soreceive = soreceive,
1277 .pru_preconnect = tcp_usr_preconnect,
1278 };
1279 #endif /* INET6 */
1280
1281 /*
1282 * Common subroutine to open a TCP connection to remote host specified
1283 * by struct sockaddr_in in mbuf *nam. Call in_pcbbind to assign a local
1284 * port number if needed. Call in_pcbladdr to do the routing and to choose
1285 * a local host address (interface). If there is an existing incarnation
1286 * of the same connection in TIME-WAIT state and if the remote host was
1287 * sending CC options and if the connection duration was < MSL, then
1288 * truncate the previous TIME-WAIT state and proceed.
1289 * Initialize connection parameters and enter SYN-SENT state.
1290 *
1291 * Returns: 0 Success
1292 * EADDRINUSE
1293 * EINVAL
1294 * in_pcbbind:EADDRNOTAVAIL Address not available.
1295 * in_pcbbind:EINVAL Invalid argument
1296 * in_pcbbind:EAFNOSUPPORT Address family not supported [notdef]
1297 * in_pcbbind:EACCES Permission denied
1298 * in_pcbbind:EADDRINUSE Address in use
1299 * in_pcbbind:EAGAIN Resource unavailable, try again
1300 * in_pcbbind:EPERM Operation not permitted
1301 * in_pcbladdr:EINVAL Invalid argument
1302 * in_pcbladdr:EAFNOSUPPORT Address family not supported
1303 * in_pcbladdr:EADDRNOTAVAIL Address not available
1304 */
1305 static int
1306 tcp_connect(tp, nam, p)
1307 register struct tcpcb *tp;
1308 struct sockaddr *nam;
1309 struct proc *p;
1310 {
1311 struct inpcb *inp = tp->t_inpcb, *oinp;
1312 struct socket *so = inp->inp_socket;
1313 struct tcpcb *otp;
1314 struct sockaddr_in *sin = (struct sockaddr_in *)(void *)nam;
1315 struct in_addr laddr;
1316 struct rmxp_tao *taop;
1317 struct rmxp_tao tao_noncached;
1318 int error = 0;
1319 struct ifnet *outif = NULL;
1320
1321 if (inp->inp_lport == 0) {
1322 error = in_pcbbind(inp, NULL, p);
1323 if (error)
1324 goto done;
1325 }
1326
1327 /*
1328 * Cannot simply call in_pcbconnect, because there might be an
1329 * earlier incarnation of this same connection still in
1330 * TIME_WAIT state, creating an ADDRINUSE error.
1331 */
1332 error = in_pcbladdr(inp, nam, &laddr, IFSCOPE_NONE, &outif);
1333 if (error)
1334 goto done;
1335
1336 tcp_unlock(inp->inp_socket, 0, 0);
1337 oinp = in_pcblookup_hash(inp->inp_pcbinfo,
1338 sin->sin_addr, sin->sin_port,
1339 inp->inp_laddr.s_addr != INADDR_ANY ? inp->inp_laddr : laddr,
1340 inp->inp_lport, 0, NULL);
1341
1342 tcp_lock(inp->inp_socket, 0, 0);
1343 if (oinp) {
1344 if (oinp != inp) /* 4143933: avoid deadlock if inp == oinp */
1345 tcp_lock(oinp->inp_socket, 1, 0);
1346 if (in_pcb_checkstate(oinp, WNT_RELEASE, 1) == WNT_STOPUSING) {
1347 if (oinp != inp)
1348 tcp_unlock(oinp->inp_socket, 1, 0);
1349 goto skip_oinp;
1350 }
1351
1352 if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
1353 otp->t_state == TCPS_TIME_WAIT &&
1354 ((int)(tcp_now - otp->t_starttime)) < tcp_msl &&
1355 (otp->t_flags & TF_RCVD_CC)) {
1356 otp = tcp_close(otp);
1357 } else {
1358 printf("tcp_connect: inp=0x%llx err=EADDRINUSE\n",
1359 (uint64_t)VM_KERNEL_ADDRPERM(inp));
1360 if (oinp != inp)
1361 tcp_unlock(oinp->inp_socket, 1, 0);
1362 error = EADDRINUSE;
1363 goto done;
1364 }
1365 if (oinp != inp)
1366 tcp_unlock(oinp->inp_socket, 1, 0);
1367 }
1368 skip_oinp:
1369 if ((inp->inp_laddr.s_addr == INADDR_ANY ? laddr.s_addr :
1370 inp->inp_laddr.s_addr) == sin->sin_addr.s_addr &&
1371 inp->inp_lport == sin->sin_port) {
1372 error = EINVAL;
1373 goto done;
1374 }
1375 if (!lck_rw_try_lock_exclusive(inp->inp_pcbinfo->ipi_lock)) {
1376 /*lock inversion issue, mostly with udp multicast packets */
1377 socket_unlock(inp->inp_socket, 0);
1378 lck_rw_lock_exclusive(inp->inp_pcbinfo->ipi_lock);
1379 socket_lock(inp->inp_socket, 0);
1380 }
1381 if (inp->inp_laddr.s_addr == INADDR_ANY) {
1382 inp->inp_laddr = laddr;
1383 /* no reference needed */
1384 inp->inp_last_outifp = outif;
1385 inp->inp_flags |= INP_INADDR_ANY;
1386 }
1387 inp->inp_faddr = sin->sin_addr;
1388 inp->inp_fport = sin->sin_port;
1389 in_pcbrehash(inp);
1390 lck_rw_done(inp->inp_pcbinfo->ipi_lock);
1391
1392 if (inp->inp_flowhash == 0)
1393 inp->inp_flowhash = inp_calc_flowhash(inp);
1394
1395 tcp_set_max_rwinscale(tp, so);
1396
1397 soisconnecting(so);
1398 tcpstat.tcps_connattempt++;
1399 tp->t_state = TCPS_SYN_SENT;
1400 tp->t_timer[TCPT_KEEP] = OFFSET_FROM_START(tp, TCP_CONN_KEEPINIT(tp));
1401 tp->iss = tcp_new_isn(tp);
1402 tcp_sendseqinit(tp);
1403 if (nstat_collect)
1404 nstat_route_connect_attempt(inp->inp_route.ro_rt);
1405
1406 /*
1407 * Generate a CC value for this connection and
1408 * check whether CC or CCnew should be used.
1409 */
1410 if ((taop = tcp_gettaocache(tp->t_inpcb)) == NULL) {
1411 taop = &tao_noncached;
1412 bzero(taop, sizeof(*taop));
1413 }
1414
1415 tp->cc_send = CC_INC(tcp_ccgen);
1416 if (taop->tao_ccsent != 0 &&
1417 CC_GEQ(tp->cc_send, taop->tao_ccsent)) {
1418 taop->tao_ccsent = tp->cc_send;
1419 } else {
1420 taop->tao_ccsent = 0;
1421 tp->t_flags |= TF_SENDCCNEW;
1422 }
1423
1424 done:
1425 if (outif != NULL)
1426 ifnet_release(outif);
1427
1428 return (error);
1429 }
1430
1431 #if INET6
1432 static int
1433 tcp6_connect(tp, nam, p)
1434 register struct tcpcb *tp;
1435 struct sockaddr *nam;
1436 struct proc *p;
1437 {
1438 struct inpcb *inp = tp->t_inpcb, *oinp;
1439 struct socket *so = inp->inp_socket;
1440 struct tcpcb *otp;
1441 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(void *)nam;
1442 struct in6_addr addr6;
1443 struct rmxp_tao *taop;
1444 struct rmxp_tao tao_noncached;
1445 int error = 0;
1446 struct ifnet *outif = NULL;
1447
1448 if (inp->inp_lport == 0) {
1449 error = in6_pcbbind(inp, NULL, p);
1450 if (error)
1451 goto done;
1452 }
1453
1454 /*
1455 * Cannot simply call in_pcbconnect, because there might be an
1456 * earlier incarnation of this same connection still in
1457 * TIME_WAIT state, creating an ADDRINUSE error.
1458 *
1459 * in6_pcbladdr() might return an ifp with its reference held
1460 * even in the error case, so make sure that it's released
1461 * whenever it's non-NULL.
1462 */
1463 error = in6_pcbladdr(inp, nam, &addr6, &outif);
1464 if (error)
1465 goto done;
1466 tcp_unlock(inp->inp_socket, 0, 0);
1467 oinp = in6_pcblookup_hash(inp->inp_pcbinfo,
1468 &sin6->sin6_addr, sin6->sin6_port,
1469 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)
1470 ? &addr6
1471 : &inp->in6p_laddr,
1472 inp->inp_lport, 0, NULL);
1473 tcp_lock(inp->inp_socket, 0, 0);
1474 if (oinp) {
1475 if (oinp != inp && (otp = intotcpcb(oinp)) != NULL &&
1476 otp->t_state == TCPS_TIME_WAIT &&
1477 ((int)(tcp_now - otp->t_starttime)) < tcp_msl &&
1478 (otp->t_flags & TF_RCVD_CC)) {
1479 otp = tcp_close(otp);
1480 } else {
1481 error = EADDRINUSE;
1482 goto done;
1483 }
1484 }
1485 if (!lck_rw_try_lock_exclusive(inp->inp_pcbinfo->ipi_lock)) {
1486 /*lock inversion issue, mostly with udp multicast packets */
1487 socket_unlock(inp->inp_socket, 0);
1488 lck_rw_lock_exclusive(inp->inp_pcbinfo->ipi_lock);
1489 socket_lock(inp->inp_socket, 0);
1490 }
1491 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
1492 inp->in6p_laddr = addr6;
1493 inp->in6p_last_outifp = outif; /* no reference needed */
1494 inp->in6p_flags |= INP_IN6ADDR_ANY;
1495 }
1496 inp->in6p_faddr = sin6->sin6_addr;
1497 inp->inp_fport = sin6->sin6_port;
1498 if ((sin6->sin6_flowinfo & IPV6_FLOWINFO_MASK) != 0)
1499 inp->inp_flow = sin6->sin6_flowinfo;
1500 in_pcbrehash(inp);
1501 lck_rw_done(inp->inp_pcbinfo->ipi_lock);
1502
1503 if (inp->inp_flowhash == 0)
1504 inp->inp_flowhash = inp_calc_flowhash(inp);
1505 /* update flowinfo - RFC 6437 */
1506 if (inp->inp_flow == 0 && inp->in6p_flags & IN6P_AUTOFLOWLABEL) {
1507 inp->inp_flow &= ~IPV6_FLOWLABEL_MASK;
1508 inp->inp_flow |=
1509 (htonl(inp->inp_flowhash) & IPV6_FLOWLABEL_MASK);
1510 }
1511
1512 tcp_set_max_rwinscale(tp, so);
1513
1514 soisconnecting(so);
1515 tcpstat.tcps_connattempt++;
1516 tp->t_state = TCPS_SYN_SENT;
1517 tp->t_timer[TCPT_KEEP] = OFFSET_FROM_START(tp,
1518 TCP_CONN_KEEPINIT(tp));
1519 tp->iss = tcp_new_isn(tp);
1520 tcp_sendseqinit(tp);
1521 if (nstat_collect)
1522 nstat_route_connect_attempt(inp->inp_route.ro_rt);
1523
1524 /*
1525 * Generate a CC value for this connection and
1526 * check whether CC or CCnew should be used.
1527 */
1528 if ((taop = tcp_gettaocache(tp->t_inpcb)) == NULL) {
1529 taop = &tao_noncached;
1530 bzero(taop, sizeof(*taop));
1531 }
1532
1533 tp->cc_send = CC_INC(tcp_ccgen);
1534 if (taop->tao_ccsent != 0 &&
1535 CC_GEQ(tp->cc_send, taop->tao_ccsent)) {
1536 taop->tao_ccsent = tp->cc_send;
1537 } else {
1538 taop->tao_ccsent = 0;
1539 tp->t_flags |= TF_SENDCCNEW;
1540 }
1541
1542 done:
1543 if (outif != NULL)
1544 ifnet_release(outif);
1545
1546 return (error);
1547 }
1548 #endif /* INET6 */
1549
1550 /*
1551 * Export TCP internal state information via a struct tcp_info
1552 */
1553 __private_extern__ void
1554 tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
1555 {
1556 struct inpcb *inp = tp->t_inpcb;
1557
1558 bzero(ti, sizeof(*ti));
1559
1560 ti->tcpi_state = tp->t_state;
1561
1562 if (tp->t_state > TCPS_LISTEN) {
1563 if (TSTMP_SUPPORTED(tp))
1564 ti->tcpi_options |= TCPI_OPT_TIMESTAMPS;
1565 if (SACK_ENABLED(tp))
1566 ti->tcpi_options |= TCPI_OPT_SACK;
1567 if (TCP_WINDOW_SCALE_ENABLED(tp)) {
1568 ti->tcpi_options |= TCPI_OPT_WSCALE;
1569 ti->tcpi_snd_wscale = tp->snd_scale;
1570 ti->tcpi_rcv_wscale = tp->rcv_scale;
1571 }
1572
1573 /* Are we in retranmission episode */
1574 if (IN_FASTRECOVERY(tp) || tp->t_rxtshift > 0)
1575 ti->tcpi_flags |= TCPI_FLAG_LOSSRECOVERY;
1576
1577 ti->tcpi_rto = tp->t_timer[TCPT_REXMT] ? tp->t_rxtcur : 0;
1578 ti->tcpi_snd_mss = tp->t_maxseg;
1579 ti->tcpi_rcv_mss = tp->t_maxseg;
1580
1581 ti->tcpi_rttcur = tp->t_rttcur;
1582 ti->tcpi_srtt = tp->t_srtt >> TCP_RTT_SHIFT;
1583 ti->tcpi_rttvar = tp->t_rttvar >> TCP_RTTVAR_SHIFT;
1584 ti->tcpi_rttbest = tp->t_rttbest >> TCP_RTT_SHIFT;
1585
1586 ti->tcpi_snd_ssthresh = tp->snd_ssthresh;
1587 ti->tcpi_snd_cwnd = tp->snd_cwnd;
1588 ti->tcpi_snd_sbbytes = inp->inp_socket->so_snd.sb_cc;
1589
1590 ti->tcpi_rcv_space = tp->rcv_wnd;
1591
1592 ti->tcpi_snd_wnd = tp->snd_wnd;
1593 ti->tcpi_snd_nxt = tp->snd_nxt;
1594 ti->tcpi_rcv_nxt = tp->rcv_nxt;
1595
1596 /* convert bytes/msec to bits/sec */
1597 if ((tp->t_flagsext & TF_MEASURESNDBW) != 0 &&
1598 tp->t_bwmeas != NULL) {
1599 ti->tcpi_snd_bw = (tp->t_bwmeas->bw_sndbw * 8000);
1600 }
1601
1602 ti->tcpi_last_outif = (tp->t_inpcb->inp_last_outifp == NULL) ? 0 :
1603 tp->t_inpcb->inp_last_outifp->if_index;
1604
1605 //atomic_get_64(ti->tcpi_txbytes, &inp->inp_stat->txbytes);
1606 ti->tcpi_txpackets = inp->inp_stat->txpackets;
1607 ti->tcpi_txbytes = inp->inp_stat->txbytes;
1608 ti->tcpi_txretransmitbytes = tp->t_stat.txretransmitbytes;
1609 ti->tcpi_txunacked = tp->snd_max - tp->snd_una;
1610
1611 //atomic_get_64(ti->tcpi_rxbytes, &inp->inp_stat->rxbytes);
1612 ti->tcpi_rxpackets = inp->inp_stat->rxpackets;
1613 ti->tcpi_rxbytes = inp->inp_stat->rxbytes;
1614 ti->tcpi_rxduplicatebytes = tp->t_stat.rxduplicatebytes;
1615 ti->tcpi_rxoutoforderbytes = tp->t_stat.rxoutoforderbytes;
1616
1617 if (tp->t_state > TCPS_LISTEN) {
1618 ti->tcpi_synrexmits = tp->t_stat.synrxtshift;
1619 }
1620 ti->tcpi_cell_rxpackets = inp->inp_cstat->rxpackets;
1621 ti->tcpi_cell_rxbytes = inp->inp_cstat->rxbytes;
1622 ti->tcpi_cell_txpackets = inp->inp_cstat->txpackets;
1623 ti->tcpi_cell_txbytes = inp->inp_cstat->txbytes;
1624
1625 ti->tcpi_wifi_rxpackets = inp->inp_wstat->rxpackets;
1626 ti->tcpi_wifi_rxbytes = inp->inp_wstat->rxbytes;
1627 ti->tcpi_wifi_txpackets = inp->inp_wstat->txpackets;
1628 ti->tcpi_wifi_txbytes = inp->inp_wstat->txbytes;
1629
1630 ti->tcpi_wired_rxpackets = inp->inp_Wstat->rxpackets;
1631 ti->tcpi_wired_rxbytes = inp->inp_Wstat->rxbytes;
1632 ti->tcpi_wired_txpackets = inp->inp_Wstat->txpackets;
1633 ti->tcpi_wired_txbytes = inp->inp_Wstat->txbytes;
1634 tcp_get_connectivity_status(tp, &ti->tcpi_connstatus);
1635
1636 ti->tcpi_tfo_syn_data_rcv = !!(tp->t_tfo_stats & TFO_S_SYNDATA_RCV);
1637 ti->tcpi_tfo_cookie_req_rcv = !!(tp->t_tfo_stats & TFO_S_COOKIEREQ_RECV);
1638 ti->tcpi_tfo_cookie_sent = !!(tp->t_tfo_stats & TFO_S_COOKIE_SENT);
1639 ti->tcpi_tfo_cookie_invalid = !!(tp->t_tfo_stats & TFO_S_COOKIE_INVALID);
1640
1641 ti->tcpi_tfo_cookie_req = !!(tp->t_tfo_stats & TFO_S_COOKIE_REQ);
1642 ti->tcpi_tfo_cookie_rcv = !!(tp->t_tfo_stats & TFO_S_COOKIE_RCV);
1643 ti->tcpi_tfo_syn_data_sent = !!(tp->t_tfo_stats & TFO_S_SYN_DATA_SENT);
1644 ti->tcpi_tfo_syn_data_acked = !!(tp->t_tfo_stats & TFO_S_SYN_DATA_ACKED);
1645 ti->tcpi_tfo_syn_loss = !!(tp->t_tfo_stats & TFO_S_SYN_LOSS);
1646 }
1647 }
1648
1649 __private_extern__ errno_t
1650 tcp_fill_info_for_info_tuple(struct info_tuple *itpl, struct tcp_info *ti)
1651 {
1652 struct inpcbinfo *pcbinfo = NULL;
1653 struct inpcb *inp = NULL;
1654 struct socket *so;
1655 struct tcpcb *tp;
1656
1657 if (itpl->itpl_proto == IPPROTO_TCP)
1658 pcbinfo = &tcbinfo;
1659 else
1660 return EINVAL;
1661
1662 if (itpl->itpl_local_sa.sa_family == AF_INET &&
1663 itpl->itpl_remote_sa.sa_family == AF_INET) {
1664 inp = in_pcblookup_hash(pcbinfo,
1665 itpl->itpl_remote_sin.sin_addr,
1666 itpl->itpl_remote_sin.sin_port,
1667 itpl->itpl_local_sin.sin_addr,
1668 itpl->itpl_local_sin.sin_port,
1669 0, NULL);
1670 } else if (itpl->itpl_local_sa.sa_family == AF_INET6 &&
1671 itpl->itpl_remote_sa.sa_family == AF_INET6) {
1672 struct in6_addr ina6_local;
1673 struct in6_addr ina6_remote;
1674
1675 ina6_local = itpl->itpl_local_sin6.sin6_addr;
1676 if (IN6_IS_SCOPE_LINKLOCAL(&ina6_local) &&
1677 itpl->itpl_local_sin6.sin6_scope_id)
1678 ina6_local.s6_addr16[1] = htons(itpl->itpl_local_sin6.sin6_scope_id);
1679
1680 ina6_remote = itpl->itpl_remote_sin6.sin6_addr;
1681 if (IN6_IS_SCOPE_LINKLOCAL(&ina6_remote) &&
1682 itpl->itpl_remote_sin6.sin6_scope_id)
1683 ina6_remote.s6_addr16[1] = htons(itpl->itpl_remote_sin6.sin6_scope_id);
1684
1685 inp = in6_pcblookup_hash(pcbinfo,
1686 &ina6_remote,
1687 itpl->itpl_remote_sin6.sin6_port,
1688 &ina6_local,
1689 itpl->itpl_local_sin6.sin6_port,
1690 0, NULL);
1691 } else {
1692 return EINVAL;
1693 }
1694 if (inp == NULL || (so = inp->inp_socket) == NULL)
1695 return ENOENT;
1696
1697 socket_lock(so, 0);
1698 if (in_pcb_checkstate(inp, WNT_RELEASE, 1) == WNT_STOPUSING) {
1699 socket_unlock(so, 0);
1700 return ENOENT;
1701 }
1702 tp = intotcpcb(inp);
1703
1704 tcp_fill_info(tp, ti);
1705 socket_unlock(so, 0);
1706
1707 return 0;
1708 }
1709
1710 static void
1711 tcp_connection_fill_info(struct tcpcb *tp, struct tcp_connection_info *tci)
1712 {
1713 struct inpcb *inp = tp->t_inpcb;
1714
1715 bzero(tci, sizeof(*tci));
1716 tci->tcpi_state = tp->t_state;
1717 if (tp->t_state > TCPS_LISTEN) {
1718 if (TSTMP_SUPPORTED(tp))
1719 tci->tcpi_options |= TCPCI_OPT_TIMESTAMPS;
1720 if (SACK_ENABLED(tp))
1721 tci->tcpi_options |= TCPCI_OPT_SACK;
1722 if (TCP_WINDOW_SCALE_ENABLED(tp)) {
1723 tci->tcpi_options |= TCPCI_OPT_WSCALE;
1724 tci->tcpi_snd_wscale = tp->snd_scale;
1725 tci->tcpi_rcv_wscale = tp->rcv_scale;
1726 }
1727 if (TCP_ECN_ENABLED(tp))
1728 tci->tcpi_options |= TCPCI_OPT_ECN;
1729 if (IN_FASTRECOVERY(tp) || tp->t_rxtshift > 0)
1730 tci->tcpi_flags |= TCPCI_FLAG_LOSSRECOVERY;
1731 if (tp->t_flagsext & TF_PKTS_REORDERED)
1732 tci->tcpi_flags |= TCPCI_FLAG_REORDERING_DETECTED;
1733 tci->tcpi_rto = (tp->t_timer[TCPT_REXMT] > 0) ?
1734 tp->t_rxtcur : 0;
1735 tci->tcpi_maxseg = tp->t_maxseg;
1736 tci->tcpi_snd_ssthresh = tp->snd_ssthresh;
1737 tci->tcpi_snd_cwnd = tp->snd_cwnd;
1738 tci->tcpi_snd_wnd = tp->snd_wnd;
1739 tci->tcpi_snd_sbbytes = inp->inp_socket->so_snd.sb_cc;
1740 tci->tcpi_rcv_wnd = tp->rcv_wnd;
1741 tci->tcpi_rttcur = tp->t_rttcur;
1742 tci->tcpi_srtt = (tp->t_srtt >> TCP_RTT_SHIFT);
1743 tci->tcpi_rttvar = (tp->t_rttvar >> TCP_RTTVAR_SHIFT);
1744 tci->tcpi_txpackets = inp->inp_stat->txpackets;
1745 tci->tcpi_txbytes = inp->inp_stat->txbytes;
1746 tci->tcpi_txretransmitbytes = tp->t_stat.txretransmitbytes;
1747 tci->tcpi_rxpackets = inp->inp_stat->rxpackets;
1748 tci->tcpi_rxbytes = inp->inp_stat->rxbytes;
1749 tci->tcpi_rxoutoforderbytes = tp->t_stat.rxoutoforderbytes;
1750
1751 tci->tcpi_tfo_syn_data_rcv = !!(tp->t_tfo_stats & TFO_S_SYNDATA_RCV);
1752 tci->tcpi_tfo_cookie_req_rcv = !!(tp->t_tfo_stats & TFO_S_COOKIEREQ_RECV);
1753 tci->tcpi_tfo_cookie_sent = !!(tp->t_tfo_stats & TFO_S_COOKIE_SENT);
1754 tci->tcpi_tfo_cookie_invalid = !!(tp->t_tfo_stats & TFO_S_COOKIE_INVALID);
1755 tci->tcpi_tfo_cookie_req = !!(tp->t_tfo_stats & TFO_S_COOKIE_REQ);
1756 tci->tcpi_tfo_cookie_rcv = !!(tp->t_tfo_stats & TFO_S_COOKIE_RCV);
1757 tci->tcpi_tfo_syn_data_sent = !!(tp->t_tfo_stats & TFO_S_SYN_DATA_SENT);
1758 tci->tcpi_tfo_syn_data_acked = !!(tp->t_tfo_stats & TFO_S_SYN_DATA_ACKED);
1759 tci->tcpi_tfo_syn_loss = !!(tp->t_tfo_stats & TFO_S_SYN_LOSS);
1760 }
1761 }
1762
1763
1764 __private_extern__ int
1765 tcp_sysctl_info(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
1766 {
1767 int error;
1768 struct tcp_info ti;
1769 struct info_tuple itpl;
1770 proc_t caller = PROC_NULL;
1771 proc_t caller_parent = PROC_NULL;
1772 char command_name[MAXCOMLEN + 1] = "";
1773 char parent_name[MAXCOMLEN + 1] = "";
1774
1775 if ((caller = proc_self()) != PROC_NULL) {
1776 /* get process name */
1777 strlcpy(command_name, caller->p_comm, sizeof(command_name));
1778
1779 /* get parent process name if possible */
1780 if ((caller_parent = proc_find(caller->p_ppid)) != PROC_NULL) {
1781 strlcpy(parent_name, caller_parent->p_comm,
1782 sizeof(parent_name));
1783 proc_rele(caller_parent);
1784 }
1785
1786 if ((escape_str(command_name, strlen(command_name),
1787 sizeof(command_name)) == 0) &&
1788 (escape_str(parent_name, strlen(parent_name),
1789 sizeof(parent_name)) == 0)) {
1790 kern_asl_msg(LOG_DEBUG, "messagetracer",
1791 5,
1792 "com.apple.message.domain",
1793 "com.apple.kernel.tcpstat", /* 1 */
1794 "com.apple.message.signature",
1795 "tcpinfo", /* 2 */
1796 "com.apple.message.signature2", command_name, /* 3 */
1797 "com.apple.message.signature3", parent_name, /* 4 */
1798 "com.apple.message.summarize", "YES", /* 5 */
1799 NULL);
1800 }
1801 }
1802
1803 if (caller != PROC_NULL)
1804 proc_rele(caller);
1805
1806 if (req->newptr == USER_ADDR_NULL) {
1807 return EINVAL;
1808 }
1809 if (req->newlen < sizeof(struct info_tuple)) {
1810 return EINVAL;
1811 }
1812 error = SYSCTL_IN(req, &itpl, sizeof(struct info_tuple));
1813 if (error != 0) {
1814 return error;
1815 }
1816 error = tcp_fill_info_for_info_tuple(&itpl, &ti);
1817 if (error != 0) {
1818 return error;
1819 }
1820 error = SYSCTL_OUT(req, &ti, sizeof(struct tcp_info));
1821 if (error != 0) {
1822 return error;
1823 }
1824
1825 return 0;
1826 }
1827
1828 static int
1829 tcp_lookup_peer_pid_locked(struct socket *so, pid_t *out_pid)
1830 {
1831 int error = EHOSTUNREACH;
1832 *out_pid = -1;
1833 if ((so->so_state & SS_ISCONNECTED) == 0) return ENOTCONN;
1834
1835 struct inpcb *inp = (struct inpcb*)so->so_pcb;
1836 uint16_t lport = inp->inp_lport;
1837 uint16_t fport = inp->inp_fport;
1838 struct inpcb *finp = NULL;
1839
1840 if (inp->inp_vflag & INP_IPV6) {
1841 struct in6_addr laddr6 = inp->in6p_laddr;
1842 struct in6_addr faddr6 = inp->in6p_faddr;
1843 socket_unlock(so, 0);
1844 finp = in6_pcblookup_hash(&tcbinfo, &laddr6, lport, &faddr6, fport, 0, NULL);
1845 socket_lock(so, 0);
1846 } else if (inp->inp_vflag & INP_IPV4) {
1847 struct in_addr laddr4 = inp->inp_laddr;
1848 struct in_addr faddr4 = inp->inp_faddr;
1849 socket_unlock(so, 0);
1850 finp = in_pcblookup_hash(&tcbinfo, laddr4, lport, faddr4, fport, 0, NULL);
1851 socket_lock(so, 0);
1852 }
1853
1854 if (finp) {
1855 *out_pid = finp->inp_socket->last_pid;
1856 error = 0;
1857 in_pcb_checkstate(finp, WNT_RELEASE, 0);
1858 }
1859
1860 return error;
1861 }
1862
1863 void
1864 tcp_getconninfo(struct socket *so, struct conninfo_tcp *tcp_ci)
1865 {
1866 (void) tcp_lookup_peer_pid_locked(so, &tcp_ci->tcpci_peer_pid);
1867 tcp_fill_info(sototcpcb(so), &tcp_ci->tcpci_tcp_info);
1868 }
1869
1870 /*
1871 * The new sockopt interface makes it possible for us to block in the
1872 * copyin/out step (if we take a page fault). Taking a page fault at
1873 * splnet() is probably a Bad Thing. (Since sockets and pcbs both now
1874 * use TSM, there probably isn't any need for this function to run at
1875 * splnet() any more. This needs more examination.)
1876 */
1877 int
1878 tcp_ctloutput(so, sopt)
1879 struct socket *so;
1880 struct sockopt *sopt;
1881 {
1882 int error, opt, optval;
1883 struct inpcb *inp;
1884 struct tcpcb *tp;
1885
1886 error = 0;
1887 inp = sotoinpcb(so);
1888 if (inp == NULL) {
1889 return (ECONNRESET);
1890 }
1891 /* Allow <SOL_SOCKET,SO_FLUSH/SO_TRAFFIC_MGT_BACKGROUND> at this level */
1892 if (sopt->sopt_level != IPPROTO_TCP &&
1893 !(sopt->sopt_level == SOL_SOCKET && (sopt->sopt_name == SO_FLUSH ||
1894 sopt->sopt_name == SO_TRAFFIC_MGT_BACKGROUND))) {
1895 #if INET6
1896 if (SOCK_CHECK_DOM(so, PF_INET6))
1897 error = ip6_ctloutput(so, sopt);
1898 else
1899 #endif /* INET6 */
1900 error = ip_ctloutput(so, sopt);
1901 return (error);
1902 }
1903 tp = intotcpcb(inp);
1904 if (tp == NULL) {
1905 return (ECONNRESET);
1906 }
1907
1908 calculate_tcp_clock();
1909
1910 switch (sopt->sopt_dir) {
1911 case SOPT_SET:
1912 switch (sopt->sopt_name) {
1913 case TCP_NODELAY:
1914 case TCP_NOOPT:
1915 case TCP_NOPUSH:
1916 case TCP_ENABLE_ECN:
1917 error = sooptcopyin(sopt, &optval, sizeof optval,
1918 sizeof optval);
1919 if (error)
1920 break;
1921
1922 switch (sopt->sopt_name) {
1923 case TCP_NODELAY:
1924 opt = TF_NODELAY;
1925 break;
1926 case TCP_NOOPT:
1927 opt = TF_NOOPT;
1928 break;
1929 case TCP_NOPUSH:
1930 opt = TF_NOPUSH;
1931 break;
1932 case TCP_ENABLE_ECN:
1933 opt = TF_ENABLE_ECN;
1934 break;
1935 default:
1936 opt = 0; /* dead code to fool gcc */
1937 break;
1938 }
1939
1940 if (optval)
1941 tp->t_flags |= opt;
1942 else
1943 tp->t_flags &= ~opt;
1944 break;
1945 case TCP_RXT_FINDROP:
1946 case TCP_NOTIMEWAIT:
1947 error = sooptcopyin(sopt, &optval, sizeof optval,
1948 sizeof optval);
1949 if (error)
1950 break;
1951 switch (sopt->sopt_name) {
1952 case TCP_RXT_FINDROP:
1953 opt = TF_RXTFINDROP;
1954 break;
1955 case TCP_NOTIMEWAIT:
1956 opt = TF_NOTIMEWAIT;
1957 break;
1958 default:
1959 opt = 0;
1960 break;
1961 }
1962 if (optval)
1963 tp->t_flagsext |= opt;
1964 else
1965 tp->t_flagsext &= ~opt;
1966 break;
1967 case TCP_MEASURE_SND_BW:
1968 error = sooptcopyin(sopt, &optval, sizeof optval,
1969 sizeof optval);
1970 if (error)
1971 break;
1972 opt = TF_MEASURESNDBW;
1973 if (optval) {
1974 if (tp->t_bwmeas == NULL) {
1975 tp->t_bwmeas = tcp_bwmeas_alloc(tp);
1976 if (tp->t_bwmeas == NULL) {
1977 error = ENOMEM;
1978 break;
1979 }
1980 }
1981 tp->t_flagsext |= opt;
1982 } else {
1983 tp->t_flagsext &= ~opt;
1984 /* Reset snd bw measurement state */
1985 tp->t_flagsext &= ~(TF_BWMEAS_INPROGRESS);
1986 if (tp->t_bwmeas != NULL) {
1987 tcp_bwmeas_free(tp);
1988 }
1989 }
1990 break;
1991 case TCP_MEASURE_BW_BURST: {
1992 struct tcp_measure_bw_burst in;
1993 uint32_t minpkts, maxpkts;
1994 bzero(&in, sizeof(in));
1995
1996 error = sooptcopyin(sopt, &in, sizeof(in),
1997 sizeof(in));
1998 if (error)
1999 break;
2000 if ((tp->t_flagsext & TF_MEASURESNDBW) == 0 ||
2001 tp->t_bwmeas == NULL) {
2002 error = EINVAL;
2003 break;
2004 }
2005 minpkts = (in.min_burst_size != 0) ? in.min_burst_size :
2006 tp->t_bwmeas->bw_minsizepkts;
2007 maxpkts = (in.max_burst_size != 0) ? in.max_burst_size :
2008 tp->t_bwmeas->bw_maxsizepkts;
2009 if (minpkts > maxpkts) {
2010 error = EINVAL;
2011 break;
2012 }
2013 tp->t_bwmeas->bw_minsizepkts = minpkts;
2014 tp->t_bwmeas->bw_maxsizepkts = maxpkts;
2015 tp->t_bwmeas->bw_minsize = (minpkts * tp->t_maxseg);
2016 tp->t_bwmeas->bw_maxsize = (maxpkts * tp->t_maxseg);
2017 break;
2018 }
2019 case TCP_MAXSEG:
2020 error = sooptcopyin(sopt, &optval, sizeof optval,
2021 sizeof optval);
2022 if (error)
2023 break;
2024
2025 if (optval > 0 && optval <= tp->t_maxseg &&
2026 optval + 40 >= tcp_minmss)
2027 tp->t_maxseg = optval;
2028 else
2029 error = EINVAL;
2030 break;
2031
2032 case TCP_KEEPALIVE:
2033 error = sooptcopyin(sopt, &optval, sizeof optval,
2034 sizeof optval);
2035 if (error)
2036 break;
2037 if (optval < 0 || optval > UINT32_MAX/TCP_RETRANSHZ) {
2038 error = EINVAL;
2039 } else {
2040 tp->t_keepidle = optval * TCP_RETRANSHZ;
2041 /* reset the timer to new value */
2042 tp->t_timer[TCPT_KEEP] = OFFSET_FROM_START(tp,
2043 TCP_CONN_KEEPIDLE(tp));
2044 tcp_check_timer_state(tp);
2045 }
2046 break;
2047
2048 case TCP_CONNECTIONTIMEOUT:
2049 error = sooptcopyin(sopt, &optval, sizeof optval,
2050 sizeof optval);
2051 if (error)
2052 break;
2053 if (optval < 0 || optval > UINT32_MAX/TCP_RETRANSHZ) {
2054 error = EINVAL;
2055 } else {
2056 tp->t_keepinit = optval * TCP_RETRANSHZ;
2057 if (tp->t_state == TCPS_SYN_RECEIVED ||
2058 tp->t_state == TCPS_SYN_SENT) {
2059 tp->t_timer[TCPT_KEEP] = OFFSET_FROM_START(tp,
2060 TCP_CONN_KEEPINIT(tp));
2061 tcp_check_timer_state(tp);
2062 }
2063 }
2064 break;
2065
2066 case TCP_KEEPINTVL:
2067 error = sooptcopyin(sopt, &optval, sizeof(optval),
2068 sizeof(optval));
2069 if (error)
2070 break;
2071 if (optval < 0 || optval > UINT32_MAX/TCP_RETRANSHZ) {
2072 error = EINVAL;
2073 } else {
2074 tp->t_keepintvl = optval * TCP_RETRANSHZ;
2075 if (tp->t_state == TCPS_FIN_WAIT_2 &&
2076 TCP_CONN_MAXIDLE(tp) > 0) {
2077 tp->t_timer[TCPT_2MSL] = OFFSET_FROM_START(tp,
2078 TCP_CONN_MAXIDLE(tp));
2079 tcp_check_timer_state(tp);
2080 }
2081 }
2082 break;
2083
2084 case TCP_KEEPCNT:
2085 error = sooptcopyin(sopt, &optval, sizeof(optval),
2086 sizeof(optval));
2087 if (error)
2088 break;
2089 if (optval < 0 || optval > INT32_MAX) {
2090 error = EINVAL;
2091 } else {
2092 tp->t_keepcnt = optval;
2093 if (tp->t_state == TCPS_FIN_WAIT_2 &&
2094 TCP_CONN_MAXIDLE(tp) > 0) {
2095 tp->t_timer[TCPT_2MSL] = OFFSET_FROM_START(tp,
2096 TCP_CONN_MAXIDLE(tp));
2097 tcp_check_timer_state(tp);
2098 }
2099 }
2100 break;
2101
2102 case PERSIST_TIMEOUT:
2103 error = sooptcopyin(sopt, &optval, sizeof optval,
2104 sizeof optval);
2105 if (error)
2106 break;
2107 if (optval < 0)
2108 error = EINVAL;
2109 else
2110 tp->t_persist_timeout = optval * TCP_RETRANSHZ;
2111 break;
2112 case TCP_RXT_CONNDROPTIME:
2113 error = sooptcopyin(sopt, &optval, sizeof(optval),
2114 sizeof(optval));
2115 if (error)
2116 break;
2117 if (optval < 0)
2118 error = EINVAL;
2119 else
2120 tp->t_rxt_conndroptime = optval * TCP_RETRANSHZ;
2121 break;
2122 case TCP_NOTSENT_LOWAT:
2123 error = sooptcopyin(sopt, &optval, sizeof(optval),
2124 sizeof(optval));
2125 if (error)
2126 break;
2127 if (optval < 0) {
2128 error = EINVAL;
2129 break;
2130 } else {
2131 if (optval == 0) {
2132 so->so_flags &= ~(SOF_NOTSENT_LOWAT);
2133 tp->t_notsent_lowat = 0;
2134 } else {
2135 so->so_flags |= SOF_NOTSENT_LOWAT;
2136 tp->t_notsent_lowat = optval;
2137 }
2138 }
2139 break;
2140 case TCP_ADAPTIVE_READ_TIMEOUT:
2141 error = sooptcopyin(sopt, &optval, sizeof (optval),
2142 sizeof(optval));
2143 if (error)
2144 break;
2145 if (optval < 0 ||
2146 optval > TCP_ADAPTIVE_TIMEOUT_MAX) {
2147 error = EINVAL;
2148 break;
2149 } else if (optval == 0) {
2150 tp->t_adaptive_rtimo = 0;
2151 tcp_keepalive_reset(tp);
2152 } else {
2153 tp->t_adaptive_rtimo = optval;
2154 }
2155 break;
2156 case TCP_ADAPTIVE_WRITE_TIMEOUT:
2157 error = sooptcopyin(sopt, &optval, sizeof (optval),
2158 sizeof (optval));
2159 if (error)
2160 break;
2161 if (optval < 0 ||
2162 optval > TCP_ADAPTIVE_TIMEOUT_MAX) {
2163 error = EINVAL;
2164 break;
2165 } else {
2166 tp->t_adaptive_wtimo = optval;
2167 }
2168 break;
2169 case TCP_ENABLE_MSGS:
2170 error = sooptcopyin(sopt, &optval, sizeof(optval),
2171 sizeof(optval));
2172 if (error)
2173 break;
2174 if (optval < 0 || optval > 1) {
2175 error = EINVAL;
2176 } else if (optval == 1) {
2177 /*
2178 * Check if messages option is already
2179 * enabled, if so return.
2180 */
2181 if (so->so_flags & SOF_ENABLE_MSGS) {
2182 VERIFY(so->so_msg_state != NULL);
2183 break;
2184 }
2185
2186 /*
2187 * allocate memory for storing message
2188 * related state
2189 */
2190 VERIFY(so->so_msg_state == NULL);
2191 MALLOC(so->so_msg_state,
2192 struct msg_state *,
2193 sizeof(struct msg_state),
2194 M_TEMP, M_WAITOK | M_ZERO);
2195 if (so->so_msg_state == NULL) {
2196 error = ENOMEM;
2197 break;
2198 }
2199
2200 /* Enable message delivery */
2201 so->so_flags |= SOF_ENABLE_MSGS;
2202 } else {
2203 /*
2204 * Can't disable message delivery on socket
2205 * because of restrictions imposed by
2206 * encoding/decoding
2207 */
2208 error = EINVAL;
2209 }
2210 break;
2211 case TCP_SENDMOREACKS:
2212 error = sooptcopyin(sopt, &optval, sizeof(optval),
2213 sizeof(optval));
2214 if (error)
2215 break;
2216 if (optval < 0 || optval > 1) {
2217 error = EINVAL;
2218 } else if (optval == 0) {
2219 tp->t_flagsext &= ~(TF_NOSTRETCHACK);
2220 } else {
2221 tp->t_flagsext |= TF_NOSTRETCHACK;
2222 }
2223 break;
2224 case TCP_DISABLE_BLACKHOLE_DETECTION:
2225 error = sooptcopyin(sopt, &optval, sizeof(optval),
2226 sizeof(optval));
2227 if (error)
2228 break;
2229 if (optval < 0 || optval > 1) {
2230 error = EINVAL;
2231 } else if (optval == 0) {
2232 tp->t_flagsext &= ~TF_NOBLACKHOLE_DETECTION;
2233 } else {
2234 tp->t_flagsext |= TF_NOBLACKHOLE_DETECTION;
2235 if ((tp->t_flags & TF_BLACKHOLE) &&
2236 tp->t_pmtud_saved_maxopd > 0)
2237 tcp_pmtud_revert_segment_size(tp);
2238 }
2239 break;
2240 case TCP_FASTOPEN:
2241 if (!(tcp_fastopen & TCP_FASTOPEN_SERVER)) {
2242 error = ENOTSUP;
2243 break;
2244 }
2245
2246 error = sooptcopyin(sopt, &optval, sizeof(optval),
2247 sizeof(optval));
2248 if (error)
2249 break;
2250 if (optval < 0 || optval > 1) {
2251 error = EINVAL;
2252 break;
2253 }
2254 if (tp->t_state != TCPS_LISTEN) {
2255 error = EINVAL;
2256 break;
2257 }
2258 if (optval)
2259 tp->t_flagsext |= TF_FASTOPEN;
2260 else
2261 tcp_disable_tfo(tp);
2262 break;
2263 case SO_FLUSH:
2264 if ((error = sooptcopyin(sopt, &optval, sizeof (optval),
2265 sizeof (optval))) != 0)
2266 break;
2267
2268 error = inp_flush(inp, optval);
2269 break;
2270
2271 case SO_TRAFFIC_MGT_BACKGROUND:
2272 if ((error = sooptcopyin(sopt, &optval, sizeof (optval),
2273 sizeof (optval))) != 0)
2274 break;
2275
2276 if (optval) {
2277 socket_set_traffic_mgt_flags_locked(so,
2278 TRAFFIC_MGT_SO_BACKGROUND);
2279 } else {
2280 socket_clear_traffic_mgt_flags_locked(so,
2281 TRAFFIC_MGT_SO_BACKGROUND);
2282 }
2283 break;
2284
2285 default:
2286 error = ENOPROTOOPT;
2287 break;
2288 }
2289 break;
2290
2291 case SOPT_GET:
2292 switch (sopt->sopt_name) {
2293 case TCP_NODELAY:
2294 optval = tp->t_flags & TF_NODELAY;
2295 break;
2296 case TCP_MAXSEG:
2297 optval = tp->t_maxseg;
2298 break;
2299 case TCP_KEEPALIVE:
2300 optval = tp->t_keepidle / TCP_RETRANSHZ;
2301 break;
2302 case TCP_KEEPINTVL:
2303 optval = tp->t_keepintvl / TCP_RETRANSHZ;
2304 break;
2305 case TCP_KEEPCNT:
2306 optval = tp->t_keepcnt;
2307 break;
2308 case TCP_NOOPT:
2309 optval = tp->t_flags & TF_NOOPT;
2310 break;
2311 case TCP_NOPUSH:
2312 optval = tp->t_flags & TF_NOPUSH;
2313 break;
2314 case TCP_ENABLE_ECN:
2315 optval = (tp->t_flags & TF_ENABLE_ECN) ? 1 : 0;
2316 break;
2317 case TCP_CONNECTIONTIMEOUT:
2318 optval = tp->t_keepinit / TCP_RETRANSHZ;
2319 break;
2320 case PERSIST_TIMEOUT:
2321 optval = tp->t_persist_timeout / TCP_RETRANSHZ;
2322 break;
2323 case TCP_RXT_CONNDROPTIME:
2324 optval = tp->t_rxt_conndroptime / TCP_RETRANSHZ;
2325 break;
2326 case TCP_RXT_FINDROP:
2327 optval = tp->t_flagsext & TF_RXTFINDROP;
2328 break;
2329 case TCP_NOTIMEWAIT:
2330 optval = (tp->t_flagsext & TF_NOTIMEWAIT) ? 1 : 0;
2331 break;
2332 case TCP_FASTOPEN:
2333 if (tp->t_state != TCPS_LISTEN ||
2334 !(tcp_fastopen & TCP_FASTOPEN_SERVER)) {
2335 error = ENOTSUP;
2336 break;
2337 }
2338 optval = tfo_enabled(tp);
2339 break;
2340 case TCP_MEASURE_SND_BW:
2341 optval = tp->t_flagsext & TF_MEASURESNDBW;
2342 break;
2343 case TCP_INFO: {
2344 struct tcp_info ti;
2345
2346 tcp_fill_info(tp, &ti);
2347 error = sooptcopyout(sopt, &ti, sizeof(struct tcp_info));
2348 goto done;
2349 /* NOT REACHED */
2350 }
2351 case TCP_CONNECTION_INFO: {
2352 struct tcp_connection_info tci;
2353 tcp_connection_fill_info(tp, &tci);
2354 error = sooptcopyout(sopt, &tci,
2355 sizeof(struct tcp_connection_info));
2356 goto done;
2357 }
2358 case TCP_MEASURE_BW_BURST: {
2359 struct tcp_measure_bw_burst out;
2360 if ((tp->t_flagsext & TF_MEASURESNDBW) == 0 ||
2361 tp->t_bwmeas == NULL) {
2362 error = EINVAL;
2363 break;
2364 }
2365 out.min_burst_size = tp->t_bwmeas->bw_minsizepkts;
2366 out.max_burst_size = tp->t_bwmeas->bw_maxsizepkts;
2367 error = sooptcopyout(sopt, &out, sizeof(out));
2368 goto done;
2369 }
2370 case TCP_NOTSENT_LOWAT:
2371 if ((so->so_flags & SOF_NOTSENT_LOWAT) != 0) {
2372 optval = tp->t_notsent_lowat;
2373 } else {
2374 optval = 0;
2375 }
2376 break;
2377
2378 case TCP_ENABLE_MSGS:
2379 if (so->so_flags & SOF_ENABLE_MSGS) {
2380 optval = 1;
2381 } else {
2382 optval = 0;
2383 }
2384 break;
2385 case TCP_SENDMOREACKS:
2386 if (tp->t_flagsext & TF_NOSTRETCHACK)
2387 optval = 1;
2388 else
2389 optval = 0;
2390 break;
2391 case TCP_DISABLE_BLACKHOLE_DETECTION:
2392 if (tp->t_flagsext & TF_NOBLACKHOLE_DETECTION)
2393 optval = 1;
2394 else
2395 optval = 0;
2396 break;
2397 case TCP_PEER_PID: {
2398 pid_t pid;
2399 error = tcp_lookup_peer_pid_locked(so, &pid);
2400 if (error == 0)
2401 error = sooptcopyout(sopt, &pid, sizeof(pid));
2402 goto done;
2403 }
2404 case TCP_ADAPTIVE_READ_TIMEOUT:
2405 optval = tp->t_adaptive_rtimo;
2406 break;
2407 case TCP_ADAPTIVE_WRITE_TIMEOUT:
2408 optval = tp->t_adaptive_wtimo;
2409 break;
2410 case SO_TRAFFIC_MGT_BACKGROUND:
2411 optval = (so->so_traffic_mgt_flags &
2412 TRAFFIC_MGT_SO_BACKGROUND) ? 1 : 0;
2413 break;
2414 default:
2415 error = ENOPROTOOPT;
2416 break;
2417 }
2418 if (error == 0)
2419 error = sooptcopyout(sopt, &optval, sizeof optval);
2420 break;
2421 }
2422 done:
2423 return (error);
2424 }
2425
2426 /*
2427 * tcp_sendspace and tcp_recvspace are the default send and receive window
2428 * sizes, respectively. These are obsolescent (this information should
2429 * be set by the route).
2430 */
2431 u_int32_t tcp_sendspace = 1448*256;
2432 u_int32_t tcp_recvspace = 1448*384;
2433
2434 /* During attach, the size of socket buffer allocated is limited to
2435 * sb_max in sbreserve. Disallow setting the tcp send and recv space
2436 * to be more than sb_max because that will cause tcp_attach to fail
2437 * (see radar 5713060)
2438 */
2439 static int
2440 sysctl_tcp_sospace(struct sysctl_oid *oidp, __unused void *arg1,
2441 __unused int arg2, struct sysctl_req *req) {
2442 u_int32_t new_value = 0, *space_p = NULL;
2443 int changed = 0, error = 0;
2444 u_quad_t sb_effective_max = (sb_max / (MSIZE+MCLBYTES)) * MCLBYTES;
2445
2446 switch (oidp->oid_number) {
2447 case TCPCTL_SENDSPACE:
2448 space_p = &tcp_sendspace;
2449 break;
2450 case TCPCTL_RECVSPACE:
2451 space_p = &tcp_recvspace;
2452 break;
2453 default:
2454 return EINVAL;
2455 }
2456 error = sysctl_io_number(req, *space_p, sizeof(u_int32_t),
2457 &new_value, &changed);
2458 if (changed) {
2459 if (new_value > 0 && new_value <= sb_effective_max) {
2460 *space_p = new_value;
2461 } else {
2462 error = ERANGE;
2463 }
2464 }
2465 return error;
2466 }
2467
2468 SYSCTL_PROC(_net_inet_tcp, TCPCTL_SENDSPACE, sendspace, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2469 &tcp_sendspace , 0, &sysctl_tcp_sospace, "IU", "Maximum outgoing TCP datagram size");
2470 SYSCTL_PROC(_net_inet_tcp, TCPCTL_RECVSPACE, recvspace, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
2471 &tcp_recvspace , 0, &sysctl_tcp_sospace, "IU", "Maximum incoming TCP datagram size");
2472
2473 /* Sysctl for testing and tuning the connectx with data api */
2474 #define TCP_PRECONNECT_SBSZ_MAX 1460
2475 #define TCP_PRECONNECT_SBSZ_MIN (TCP_MSS)
2476 #define TCP_PRECONNECT_SBSZ_DEF (TCP6_MSS)
2477 static int tcp_preconnect_sbspace = TCP_PRECONNECT_SBSZ_DEF;
2478 SYSCTL_INT(_net_inet_tcp, OID_AUTO, preconn_sbsz, CTLFLAG_RW | CTLFLAG_LOCKED,
2479 &tcp_preconnect_sbspace, 0, "Maximum preconnect space");
2480
2481
2482 /*
2483 * Attach TCP protocol to socket, allocating
2484 * internet protocol control block, tcp control block,
2485 * bufer space, and entering LISTEN state if to accept connections.
2486 *
2487 * Returns: 0 Success
2488 * in_pcballoc:ENOBUFS
2489 * in_pcballoc:ENOMEM
2490 * in_pcballoc:??? [IPSEC specific]
2491 * soreserve:ENOBUFS
2492 */
2493 static int
2494 tcp_attach(so, p)
2495 struct socket *so;
2496 struct proc *p;
2497 {
2498 register struct tcpcb *tp;
2499 struct inpcb *inp;
2500 int error;
2501 #if INET6
2502 int isipv6 = SOCK_CHECK_DOM(so, PF_INET6) != 0;
2503 #endif
2504
2505 error = in_pcballoc(so, &tcbinfo, p);
2506 if (error)
2507 return (error);
2508
2509 inp = sotoinpcb(so);
2510
2511 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
2512 error = soreserve(so, tcp_sendspace, tcp_recvspace);
2513 if (error)
2514 return (error);
2515 }
2516
2517 if (so->so_snd.sb_preconn_hiwat == 0) {
2518 soreserve_preconnect(so, imin(TCP_PRECONNECT_SBSZ_MAX,
2519 imax(tcp_preconnect_sbspace, TCP_PRECONNECT_SBSZ_MIN)));
2520 }
2521
2522 if ((so->so_rcv.sb_flags & SB_USRSIZE) == 0)
2523 so->so_rcv.sb_flags |= SB_AUTOSIZE;
2524 if ((so->so_snd.sb_flags & SB_USRSIZE) == 0)
2525 so->so_snd.sb_flags |= SB_AUTOSIZE;
2526
2527 #if INET6
2528 if (isipv6) {
2529 inp->inp_vflag |= INP_IPV6;
2530 inp->in6p_hops = -1; /* use kernel default */
2531 }
2532 else
2533 #endif /* INET6 */
2534 inp->inp_vflag |= INP_IPV4;
2535 tp = tcp_newtcpcb(inp);
2536 if (tp == NULL) {
2537 int nofd = so->so_state & SS_NOFDREF; /* XXX */
2538
2539 so->so_state &= ~SS_NOFDREF; /* don't free the socket yet */
2540 #if INET6
2541 if (isipv6)
2542 in6_pcbdetach(inp);
2543 else
2544 #endif /* INET6 */
2545 in_pcbdetach(inp);
2546 so->so_state |= nofd;
2547 return (ENOBUFS);
2548 }
2549 if (nstat_collect)
2550 nstat_tcp_new_pcb(inp);
2551 tp->t_state = TCPS_CLOSED;
2552 return (0);
2553 }
2554
2555 /*
2556 * Initiate (or continue) disconnect.
2557 * If embryonic state, just send reset (once).
2558 * If in ``let data drain'' option and linger null, just drop.
2559 * Otherwise (hard), mark socket disconnecting and drop
2560 * current input data; switch states based on user close, and
2561 * send segment to peer (with FIN).
2562 */
2563 static struct tcpcb *
2564 tcp_disconnect(tp)
2565 register struct tcpcb *tp;
2566 {
2567 struct socket *so = tp->t_inpcb->inp_socket;
2568
2569 if (tp->t_state < TCPS_ESTABLISHED)
2570 tp = tcp_close(tp);
2571 else if ((so->so_options & SO_LINGER) && so->so_linger == 0)
2572 tp = tcp_drop(tp, 0);
2573 else {
2574 soisdisconnecting(so);
2575 sbflush(&so->so_rcv);
2576 tp = tcp_usrclosed(tp);
2577 #if MPTCP
2578 /* A reset has been sent but socket exists, do not send FIN */
2579 if ((so->so_flags & SOF_MP_SUBFLOW) &&
2580 (tp) && (tp->t_mpflags & TMPF_RESET))
2581 return (tp);
2582 #endif
2583 if (tp)
2584 (void) tcp_output(tp);
2585 }
2586 return (tp);
2587 }
2588
2589 /*
2590 * User issued close, and wish to trail through shutdown states:
2591 * if never received SYN, just forget it. If got a SYN from peer,
2592 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN.
2593 * If already got a FIN from peer, then almost done; go to LAST_ACK
2594 * state. In all other cases, have already sent FIN to peer (e.g.
2595 * after PRU_SHUTDOWN), and just have to play tedious game waiting
2596 * for peer to send FIN or not respond to keep-alives, etc.
2597 * We can let the user exit from the close as soon as the FIN is acked.
2598 */
2599 static struct tcpcb *
2600 tcp_usrclosed(tp)
2601 register struct tcpcb *tp;
2602 {
2603
2604 switch (tp->t_state) {
2605
2606 case TCPS_CLOSED:
2607 case TCPS_LISTEN:
2608 tp = tcp_close(tp);
2609 break;
2610
2611 case TCPS_SYN_SENT:
2612 case TCPS_SYN_RECEIVED:
2613 tp->t_flags |= TF_NEEDFIN;
2614 break;
2615
2616 case TCPS_ESTABLISHED:
2617 DTRACE_TCP4(state__change, void, NULL,
2618 struct inpcb *, tp->t_inpcb,
2619 struct tcpcb *, tp,
2620 int32_t, TCPS_FIN_WAIT_1);
2621 tp->t_state = TCPS_FIN_WAIT_1;
2622 break;
2623
2624 case TCPS_CLOSE_WAIT:
2625 DTRACE_TCP4(state__change, void, NULL,
2626 struct inpcb *, tp->t_inpcb,
2627 struct tcpcb *, tp,
2628 int32_t, TCPS_LAST_ACK);
2629 tp->t_state = TCPS_LAST_ACK;
2630 break;
2631 }
2632 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) {
2633 soisdisconnected(tp->t_inpcb->inp_socket);
2634 /* To prevent the connection hanging in FIN_WAIT_2 forever. */
2635 if (tp->t_state == TCPS_FIN_WAIT_2)
2636 tp->t_timer[TCPT_2MSL] = OFFSET_FROM_START(tp,
2637 TCP_CONN_MAXIDLE(tp));
2638 }
2639 return (tp);
2640 }
2641
2642 void
2643 tcp_in_cksum_stats(u_int32_t len)
2644 {
2645 tcpstat.tcps_rcv_swcsum++;
2646 tcpstat.tcps_rcv_swcsum_bytes += len;
2647 }
2648
2649 void
2650 tcp_out_cksum_stats(u_int32_t len)
2651 {
2652 tcpstat.tcps_snd_swcsum++;
2653 tcpstat.tcps_snd_swcsum_bytes += len;
2654 }
2655
2656 #if INET6
2657 void
2658 tcp_in6_cksum_stats(u_int32_t len)
2659 {
2660 tcpstat.tcps_rcv6_swcsum++;
2661 tcpstat.tcps_rcv6_swcsum_bytes += len;
2662 }
2663
2664 void
2665 tcp_out6_cksum_stats(u_int32_t len)
2666 {
2667 tcpstat.tcps_snd6_swcsum++;
2668 tcpstat.tcps_snd6_swcsum_bytes += len;
2669 }
2670
2671 /*
2672 * When messages are enabled on a TCP socket, the message priority
2673 * is sent as a control message. This function will extract it.
2674 */
2675 int
2676 tcp_get_msg_priority(struct mbuf *control, uint32_t *msgpri)
2677 {
2678 struct cmsghdr *cm;
2679 if (control == NULL)
2680 return(EINVAL);
2681
2682 for (cm = M_FIRST_CMSGHDR(control); cm;
2683 cm = M_NXT_CMSGHDR(control, cm)) {
2684 if (cm->cmsg_len < sizeof(struct cmsghdr) ||
2685 cm->cmsg_len > control->m_len) {
2686 return (EINVAL);
2687 }
2688 if (cm->cmsg_level == SOL_SOCKET &&
2689 cm->cmsg_type == SCM_MSG_PRIORITY) {
2690 *msgpri = *(unsigned int *)(void *)CMSG_DATA(cm);
2691 break;
2692 }
2693 }
2694
2695 VERIFY(*msgpri >= MSG_PRI_MIN && *msgpri <= MSG_PRI_MAX);
2696 return (0);
2697 }
2698 #endif /* INET6 */