4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2019 Joyent, Inc.
25 * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
26 * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
27 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
28 */
29 /* Copyright (c) 1990 Mentat Inc. */
30
31 #include <sys/types.h>
32 #include <sys/stream.h>
33 #include <sys/strsun.h>
34 #include <sys/strsubr.h>
35 #include <sys/stropts.h>
36 #include <sys/strlog.h>
37 #define _SUN_TPI_VERSION 2
38 #include <sys/tihdr.h>
39 #include <sys/timod.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42 #include <sys/suntpi.h>
43 #include <sys/xti_inet.h>
44 #include <sys/cmn_err.h>
45 #include <sys/debug.h>
46 #include <sys/sdt.h>
47 #include <sys/vtrace.h>
1002 tcp->tcp_timer_tid = TCP_TIMER(tcp, tcp_timer,
1003 delta ? delta : 1);
1004 }
1005 } else {
1006 tcp_closei_local(tcp);
1007 CONN_DEC_REF(connp);
1008 }
1009 finish:
1010 tcp->tcp_detached = B_TRUE;
1011 connp->conn_rq = NULL;
1012 connp->conn_wq = NULL;
1013
1014 /* Signal closing thread that it can complete close */
1015 mutex_enter(&tcp->tcp_closelock);
1016 tcp->tcp_closed = 1;
1017 cv_signal(&tcp->tcp_closecv);
1018 mutex_exit(&tcp->tcp_closelock);
1019
1020 /* If we have an upper handle (socket), release it */
1021 if (IPCL_IS_NONSTR(connp)) {
1022 ASSERT(connp->conn_upper_handle != NULL);
1023 (*connp->conn_upcalls->su_closed)(connp->conn_upper_handle);
1024 connp->conn_upper_handle = NULL;
1025 connp->conn_upcalls = NULL;
1026 }
1027 }
1028
1029 void
1030 tcp_close_common(conn_t *connp, int flags)
1031 {
1032 tcp_t *tcp = connp->conn_tcp;
1033 mblk_t *mp = &tcp->tcp_closemp;
1034 boolean_t conn_ioctl_cleanup_reqd = B_FALSE;
1035 mblk_t *bp;
1036
1037 ASSERT(connp->conn_ref >= 2);
1038
1039 /*
1040 * Mark the conn as closing. ipsq_pending_mp_add will not
1041 * add any mp to the pending mp list, after this conn has
1042 * started closing.
1043 */
1044 mutex_enter(&connp->conn_lock);
1045 connp->conn_state_flags |= CONN_CLOSING;
1404 ASSERT(tcp->tcp_rthdrlen == 0);
1405
1406 /*
1407 * Following is really a blowing away a union.
1408 * It happens to have exactly two members of identical size
1409 * the following code is enough.
1410 */
1411 tcp_close_mpp(&tcp->tcp_conn.tcp_eager_conn_ind);
1412
1413 /* Allow the CC algorithm to clean up after itself. */
1414 if (tcp->tcp_cc_algo != NULL && tcp->tcp_cc_algo->cb_destroy != NULL)
1415 tcp->tcp_cc_algo->cb_destroy(&tcp->tcp_ccv);
1416
1417 /*
1418 * If this is a non-STREAM socket still holding on to an upper
1419 * handle, release it. As a result of fallback we might also see
1420 * STREAMS based conns with upper handles, in which case there is
1421 * nothing to do other than clearing the field.
1422 */
1423 if (connp->conn_upper_handle != NULL) {
1424 if (IPCL_IS_NONSTR(connp)) {
1425 (*connp->conn_upcalls->su_closed)(
1426 connp->conn_upper_handle);
1427 tcp->tcp_detached = B_TRUE;
1428 }
1429 connp->conn_upper_handle = NULL;
1430 connp->conn_upcalls = NULL;
1431 }
1432 }
1433
1434 /*
1435 * tcp_get_conn/tcp_free_conn
1436 *
1437 * tcp_get_conn is used to get a clean tcp connection structure.
1438 * It tries to reuse the connections put on the freelist by the
1439 * time_wait_collector failing which it goes to kmem_cache. This
1440 * way has two benefits compared to just allocating from and
1441 * freeing to kmem_cache.
1442 * 1) The time_wait_collector can free (which includes the cleanup)
1443 * outside the squeue. So when the interrupt comes, we have a clean
1444 * connection sitting in the freelist. Obviously, this buys us
1445 * performance.
1446 *
1447 * 2) Defence against DOS attack. Allocating a tcp/conn in tcp_input_listener
1448 * has multiple disadvantages - tying up the squeue during alloc.
1449 * But allocating the conn/tcp in IP land is also not the best since
1450 * we can't check the 'q' and 'q0' which are protected by squeue and
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
26 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
27 * Copyright 2020 Joyent, Inc.
28 */
29 /* Copyright (c) 1990 Mentat Inc. */
30
31 #include <sys/types.h>
32 #include <sys/stream.h>
33 #include <sys/strsun.h>
34 #include <sys/strsubr.h>
35 #include <sys/stropts.h>
36 #include <sys/strlog.h>
37 #define _SUN_TPI_VERSION 2
38 #include <sys/tihdr.h>
39 #include <sys/timod.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42 #include <sys/suntpi.h>
43 #include <sys/xti_inet.h>
44 #include <sys/cmn_err.h>
45 #include <sys/debug.h>
46 #include <sys/sdt.h>
47 #include <sys/vtrace.h>
1002 tcp->tcp_timer_tid = TCP_TIMER(tcp, tcp_timer,
1003 delta ? delta : 1);
1004 }
1005 } else {
1006 tcp_closei_local(tcp);
1007 CONN_DEC_REF(connp);
1008 }
1009 finish:
1010 tcp->tcp_detached = B_TRUE;
1011 connp->conn_rq = NULL;
1012 connp->conn_wq = NULL;
1013
1014 /* Signal closing thread that it can complete close */
1015 mutex_enter(&tcp->tcp_closelock);
1016 tcp->tcp_closed = 1;
1017 cv_signal(&tcp->tcp_closecv);
1018 mutex_exit(&tcp->tcp_closelock);
1019
1020 /* If we have an upper handle (socket), release it */
1021 if (IPCL_IS_NONSTR(connp)) {
1022 sock_upcalls_t *upcalls = connp->conn_upcalls;
1023 sock_upper_handle_t handle = connp->conn_upper_handle;
1024
1025 ASSERT(upcalls != NULL);
1026 ASSERT(upcalls->su_closed != NULL);
1027 ASSERT(handle != NULL);
1028 /*
1029 * Set these to NULL first because closed() will free upper
1030 * structures. Acquire conn_lock because an external caller
1031 * like conn_get_socket_info() will upcall if these are
1032 * non-NULL.
1033 */
1034 mutex_enter(&connp->conn_lock);
1035 connp->conn_upper_handle = NULL;
1036 connp->conn_upcalls = NULL;
1037 mutex_exit(&connp->conn_lock);
1038 upcalls->su_closed(handle);
1039 }
1040 }
1041
1042 void
1043 tcp_close_common(conn_t *connp, int flags)
1044 {
1045 tcp_t *tcp = connp->conn_tcp;
1046 mblk_t *mp = &tcp->tcp_closemp;
1047 boolean_t conn_ioctl_cleanup_reqd = B_FALSE;
1048 mblk_t *bp;
1049
1050 ASSERT(connp->conn_ref >= 2);
1051
1052 /*
1053 * Mark the conn as closing. ipsq_pending_mp_add will not
1054 * add any mp to the pending mp list, after this conn has
1055 * started closing.
1056 */
1057 mutex_enter(&connp->conn_lock);
1058 connp->conn_state_flags |= CONN_CLOSING;
1417 ASSERT(tcp->tcp_rthdrlen == 0);
1418
1419 /*
1420 * Following is really a blowing away a union.
1421 * It happens to have exactly two members of identical size
1422 * the following code is enough.
1423 */
1424 tcp_close_mpp(&tcp->tcp_conn.tcp_eager_conn_ind);
1425
1426 /* Allow the CC algorithm to clean up after itself. */
1427 if (tcp->tcp_cc_algo != NULL && tcp->tcp_cc_algo->cb_destroy != NULL)
1428 tcp->tcp_cc_algo->cb_destroy(&tcp->tcp_ccv);
1429
1430 /*
1431 * If this is a non-STREAM socket still holding on to an upper
1432 * handle, release it. As a result of fallback we might also see
1433 * STREAMS based conns with upper handles, in which case there is
1434 * nothing to do other than clearing the field.
1435 */
1436 if (connp->conn_upper_handle != NULL) {
1437 sock_upcalls_t *upcalls = connp->conn_upcalls;
1438 sock_upper_handle_t handle = connp->conn_upper_handle;
1439
1440 /*
1441 * Set these to NULL first because closed() will free upper
1442 * structures. Acquire conn_lock because an external caller
1443 * like conn_get_socket_info() will upcall if these are
1444 * non-NULL.
1445 */
1446 mutex_enter(&connp->conn_lock);
1447 connp->conn_upper_handle = NULL;
1448 connp->conn_upcalls = NULL;
1449 mutex_exit(&connp->conn_lock);
1450 if (IPCL_IS_NONSTR(connp)) {
1451 ASSERT(upcalls != NULL);
1452 ASSERT(upcalls->su_closed != NULL);
1453 ASSERT(handle != NULL);
1454 upcalls->su_closed(handle);
1455 tcp->tcp_detached = B_TRUE;
1456 }
1457 }
1458 }
1459
1460 /*
1461 * tcp_get_conn/tcp_free_conn
1462 *
1463 * tcp_get_conn is used to get a clean tcp connection structure.
1464 * It tries to reuse the connections put on the freelist by the
1465 * time_wait_collector failing which it goes to kmem_cache. This
1466 * way has two benefits compared to just allocating from and
1467 * freeing to kmem_cache.
1468 * 1) The time_wait_collector can free (which includes the cleanup)
1469 * outside the squeue. So when the interrupt comes, we have a clean
1470 * connection sitting in the freelist. Obviously, this buys us
1471 * performance.
1472 *
1473 * 2) Defence against DOS attack. Allocating a tcp/conn in tcp_input_listener
1474 * has multiple disadvantages - tying up the squeue during alloc.
1475 * But allocating the conn/tcp in IP land is also not the best since
1476 * we can't check the 'q' and 'q0' which are protected by squeue and
|