xref: /xnu-11215.41.3/tests/so_linger.c (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 2021 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 #include <sys/socket.h>
30 #include <sys/sysctl.h>
31 #include <sys/time.h>
32 
33 #include <darwintest.h>
34 
35 T_DECL(so_linger_negative, "SO_LINGER negative")
36 {
37 	int s = -1;
38 	T_ASSERT_POSIX_SUCCESS(s = socket(AF_LOCAL, SOCK_DGRAM, 0), "socket(AF_LOCAL, SOCK_DGRAM)");
39 
40 	struct linger set_l = {};
41 	set_l.l_onoff = 1;
42 	set_l.l_linger = -1;
43 	T_LOG("l_linger %d", set_l.l_linger);
44 	T_ASSERT_POSIX_SUCCESS(setsockopt(s, SOL_SOCKET, SO_LINGER,
45 	    &set_l, sizeof(struct linger)),
46 	    "setsockopt SO_LINGER");
47 
48 	struct linger get_l = {};
49 	socklen_t len = sizeof(struct linger);
50 	T_ASSERT_POSIX_SUCCESS(getsockopt(s, SOL_SOCKET, SO_LINGER,
51 	    &get_l, &len),
52 	    "getsockopt SO_LINGER");
53 
54 	T_EXPECT_EQ(set_l.l_linger, get_l.l_linger,
55 	    "SO_LINGER negative l_linger %d == %d", set_l.l_linger, get_l.l_linger);
56 }
57 
58 T_DECL(so_linger_overflow, "SO_LINGER overflow")
59 {
60 	int s = -1;
61 	T_ASSERT_POSIX_SUCCESS(s = socket(AF_LOCAL, SOCK_DGRAM, 0), "socket(AF_LOCAL, SOCK_DGRAM)");
62 
63 	struct linger set_l = {};
64 	set_l.l_onoff = 1;
65 	set_l.l_linger = SHRT_MAX + 1;
66 	T_LOG("l_linger %d", set_l.l_linger);
67 	T_ASSERT_POSIX_SUCCESS(setsockopt(s, SOL_SOCKET, SO_LINGER,
68 	    &set_l, sizeof(struct linger)),
69 	    "setsockopt SO_LINGER");
70 
71 	struct linger get_l = {};
72 	socklen_t len = sizeof(struct linger);
73 	T_ASSERT_POSIX_SUCCESS(getsockopt(s, SOL_SOCKET, SO_LINGER,
74 	    &get_l, &len),
75 	    "getsockopt SO_LINGER");
76 
77 	/*
78 	 * Test passes based on the knowledge that l_linger is stored
79 	 * as a short signed integer
80 	 */
81 	T_EXPECT_EQ((short)set_l.l_linger, (short)get_l.l_linger,
82 	    "SO_LINGER overflow l_linger (short) %d == (short) %d",
83 	    set_l.l_linger, get_l.l_linger);
84 }
85 
86 T_DECL(so_linger_500, "SO_LINGER 500")
87 {
88 	int s = -1;
89 	T_ASSERT_POSIX_SUCCESS(s = socket(AF_LOCAL, SOCK_DGRAM, 0), "socket(AF_LOCAL, SOCK_DGRAM)");
90 
91 	struct clockinfo clkinfo;
92 	size_t oldlen = sizeof(struct clockinfo);
93 	T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.clockrate", &clkinfo, &oldlen, NULL, 0),
94 	    "sysctlbyname(kern.clockrate)");
95 
96 	struct linger set_l = {};
97 	set_l.l_onoff = 1;
98 	set_l.l_linger = 500;
99 
100 	T_ASSERT_POSIX_SUCCESS(setsockopt(s, SOL_SOCKET, SO_LINGER,
101 	    &set_l, sizeof(struct linger)),
102 	    "setsockopt SO_LINGER");
103 
104 	struct linger get_l = {};
105 	socklen_t len = sizeof(struct linger);
106 	T_ASSERT_POSIX_SUCCESS(getsockopt(s, SOL_SOCKET, SO_LINGER,
107 	    &get_l, &len),
108 	    "getsockopt SO_LINGER");
109 
110 	T_EXPECT_EQ(set_l.l_linger, get_l.l_linger,
111 	    "SO_LINGER 500 l_linger %d == %d", set_l.l_linger, get_l.l_linger);
112 }
113 
114 T_DECL(so_linger_sec_negative, "SO_LINGER_SEC negative")
115 {
116 	int s = -1;
117 	T_ASSERT_POSIX_SUCCESS(s = socket(AF_LOCAL, SOCK_DGRAM, 0), "socket(AF_LOCAL, SOCK_DGRAM)");
118 
119 	struct clockinfo clkinfo;
120 	size_t oldlen = sizeof(struct clockinfo);
121 	T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.clockrate", &clkinfo, &oldlen, NULL, 0),
122 	    "sysctlbyname(kern.clockrate)");
123 
124 	struct linger set_l = {};
125 	set_l.l_onoff = 1;
126 	set_l.l_linger = -1;
127 	T_LOG("l_linger %d * clkinfo.hz %d = %d", set_l.l_linger, clkinfo.hz, (set_l.l_linger * clkinfo.hz));
128 
129 	T_ASSERT_POSIX_SUCCESS(setsockopt(s, SOL_SOCKET, SO_LINGER_SEC,
130 	    &set_l, sizeof(struct linger)),
131 	    "setsockopt SO_LINGER_SEC");
132 
133 	struct linger get_l = {};
134 	socklen_t len = sizeof(struct linger);
135 	T_ASSERT_POSIX_SUCCESS(getsockopt(s, SOL_SOCKET, SO_LINGER_SEC,
136 	    &get_l, &len),
137 	    "getsockopt SO_LINGER_SEC");
138 
139 	T_EXPECT_EQ(set_l.l_linger, get_l.l_linger,
140 	    "SO_LINGER_SEC negative l_linger %d == %d", set_l.l_linger, get_l.l_linger);
141 }
142 
143 T_DECL(so_linger_sec_5_seconds, "SO_LINGER_SEC 5 seconds")
144 {
145 	int s = -1;
146 	T_ASSERT_POSIX_SUCCESS(s = socket(AF_LOCAL, SOCK_DGRAM, 0), "socket(AF_LOCAL, SOCK_DGRAM)");
147 
148 	struct clockinfo clkinfo;
149 	size_t oldlen = sizeof(struct clockinfo);
150 	T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.clockrate", &clkinfo, &oldlen, NULL, 0),
151 	    "sysctlbyname(kern.clockrate)");
152 
153 	struct linger set_l = {};
154 	set_l.l_onoff = 1;
155 	set_l.l_linger = 5;
156 	T_LOG("l_linger %d * clkinfo.hz %d = %d", set_l.l_linger, clkinfo.hz, (set_l.l_linger * clkinfo.hz));
157 
158 	T_ASSERT_POSIX_SUCCESS(setsockopt(s, SOL_SOCKET, SO_LINGER_SEC,
159 	    &set_l, sizeof(struct linger)),
160 	    "setsockopt SO_LINGER_SEC");
161 
162 	struct linger get_l = {};
163 	socklen_t len = sizeof(struct linger);
164 	T_ASSERT_POSIX_SUCCESS(getsockopt(s, SOL_SOCKET, SO_LINGER_SEC,
165 	    &get_l, &len),
166 	    "getsockopt SO_LINGER_SEC");
167 
168 	T_EXPECT_EQ(set_l.l_linger, get_l.l_linger,
169 	    "SO_LINGER_SEC 5 seconds l_linger %d == %d", set_l.l_linger, get_l.l_linger);
170 }
171