xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/net/tls.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun #define _GNU_SOURCE
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <arpa/inet.h>
6*4882a593Smuzhiyun #include <errno.h>
7*4882a593Smuzhiyun #include <error.h>
8*4882a593Smuzhiyun #include <fcntl.h>
9*4882a593Smuzhiyun #include <poll.h>
10*4882a593Smuzhiyun #include <stdio.h>
11*4882a593Smuzhiyun #include <stdlib.h>
12*4882a593Smuzhiyun #include <unistd.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/tls.h>
15*4882a593Smuzhiyun #include <linux/tcp.h>
16*4882a593Smuzhiyun #include <linux/socket.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <sys/types.h>
19*4882a593Smuzhiyun #include <sys/sendfile.h>
20*4882a593Smuzhiyun #include <sys/socket.h>
21*4882a593Smuzhiyun #include <sys/stat.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "../kselftest_harness.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define TLS_PAYLOAD_MAX_LEN 16384
26*4882a593Smuzhiyun #define SOL_TLS 282
27*4882a593Smuzhiyun 
FIXTURE(tls_basic)28*4882a593Smuzhiyun FIXTURE(tls_basic)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	int fd, cfd;
31*4882a593Smuzhiyun 	bool notls;
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
FIXTURE_SETUP(tls_basic)34*4882a593Smuzhiyun FIXTURE_SETUP(tls_basic)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	struct sockaddr_in addr;
37*4882a593Smuzhiyun 	socklen_t len;
38*4882a593Smuzhiyun 	int sfd, ret;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	self->notls = false;
41*4882a593Smuzhiyun 	len = sizeof(addr);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	addr.sin_family = AF_INET;
44*4882a593Smuzhiyun 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
45*4882a593Smuzhiyun 	addr.sin_port = 0;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	self->fd = socket(AF_INET, SOCK_STREAM, 0);
48*4882a593Smuzhiyun 	sfd = socket(AF_INET, SOCK_STREAM, 0);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	ret = bind(sfd, &addr, sizeof(addr));
51*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
52*4882a593Smuzhiyun 	ret = listen(sfd, 10);
53*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	ret = getsockname(sfd, &addr, &len);
56*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	ret = connect(self->fd, &addr, sizeof(addr));
59*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	self->cfd = accept(sfd, &addr, &len);
62*4882a593Smuzhiyun 	ASSERT_GE(self->cfd, 0);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	close(sfd);
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
67*4882a593Smuzhiyun 	if (ret != 0) {
68*4882a593Smuzhiyun 		ASSERT_EQ(errno, ENOENT);
69*4882a593Smuzhiyun 		self->notls = true;
70*4882a593Smuzhiyun 		printf("Failure setting TCP_ULP, testing without tls\n");
71*4882a593Smuzhiyun 		return;
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
75*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
FIXTURE_TEARDOWN(tls_basic)78*4882a593Smuzhiyun FIXTURE_TEARDOWN(tls_basic)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	close(self->fd);
81*4882a593Smuzhiyun 	close(self->cfd);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /* Send some data through with ULP but no keys */
TEST_F(tls_basic,base_base)85*4882a593Smuzhiyun TEST_F(tls_basic, base_base)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	char const *test_str = "test_read";
88*4882a593Smuzhiyun 	int send_len = 10;
89*4882a593Smuzhiyun 	char buf[10];
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	ASSERT_EQ(strlen(test_str) + 1, send_len);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
94*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
95*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
96*4882a593Smuzhiyun };
97*4882a593Smuzhiyun 
FIXTURE(tls)98*4882a593Smuzhiyun FIXTURE(tls)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	int fd, cfd;
101*4882a593Smuzhiyun 	bool notls;
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
FIXTURE_VARIANT(tls)104*4882a593Smuzhiyun FIXTURE_VARIANT(tls)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	unsigned int tls_version;
107*4882a593Smuzhiyun };
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun FIXTURE_VARIANT_ADD(tls, 12)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	.tls_version = TLS_1_2_VERSION,
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun FIXTURE_VARIANT_ADD(tls, 13)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	.tls_version = TLS_1_3_VERSION,
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun 
FIXTURE_SETUP(tls)119*4882a593Smuzhiyun FIXTURE_SETUP(tls)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	struct tls12_crypto_info_aes_gcm_128 tls12;
122*4882a593Smuzhiyun 	struct sockaddr_in addr;
123*4882a593Smuzhiyun 	socklen_t len;
124*4882a593Smuzhiyun 	int sfd, ret;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	self->notls = false;
127*4882a593Smuzhiyun 	len = sizeof(addr);
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	memset(&tls12, 0, sizeof(tls12));
130*4882a593Smuzhiyun 	tls12.info.version = variant->tls_version;
131*4882a593Smuzhiyun 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	addr.sin_family = AF_INET;
134*4882a593Smuzhiyun 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
135*4882a593Smuzhiyun 	addr.sin_port = 0;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	self->fd = socket(AF_INET, SOCK_STREAM, 0);
138*4882a593Smuzhiyun 	sfd = socket(AF_INET, SOCK_STREAM, 0);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	ret = bind(sfd, &addr, sizeof(addr));
141*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
142*4882a593Smuzhiyun 	ret = listen(sfd, 10);
143*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	ret = getsockname(sfd, &addr, &len);
146*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	ret = connect(self->fd, &addr, sizeof(addr));
149*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
152*4882a593Smuzhiyun 	if (ret != 0) {
153*4882a593Smuzhiyun 		self->notls = true;
154*4882a593Smuzhiyun 		printf("Failure setting TCP_ULP, testing without tls\n");
155*4882a593Smuzhiyun 	}
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	if (!self->notls) {
158*4882a593Smuzhiyun 		ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12,
159*4882a593Smuzhiyun 				 sizeof(tls12));
160*4882a593Smuzhiyun 		ASSERT_EQ(ret, 0);
161*4882a593Smuzhiyun 	}
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	self->cfd = accept(sfd, &addr, &len);
164*4882a593Smuzhiyun 	ASSERT_GE(self->cfd, 0);
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	if (!self->notls) {
167*4882a593Smuzhiyun 		ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls",
168*4882a593Smuzhiyun 				 sizeof("tls"));
169*4882a593Smuzhiyun 		ASSERT_EQ(ret, 0);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 		ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12,
172*4882a593Smuzhiyun 				 sizeof(tls12));
173*4882a593Smuzhiyun 		ASSERT_EQ(ret, 0);
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	close(sfd);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
FIXTURE_TEARDOWN(tls)179*4882a593Smuzhiyun FIXTURE_TEARDOWN(tls)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun 	close(self->fd);
182*4882a593Smuzhiyun 	close(self->cfd);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
TEST_F(tls,sendfile)185*4882a593Smuzhiyun TEST_F(tls, sendfile)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	int filefd = open("/proc/self/exe", O_RDONLY);
188*4882a593Smuzhiyun 	struct stat st;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	EXPECT_GE(filefd, 0);
191*4882a593Smuzhiyun 	fstat(filefd, &st);
192*4882a593Smuzhiyun 	EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
TEST_F(tls,send_then_sendfile)195*4882a593Smuzhiyun TEST_F(tls, send_then_sendfile)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	int filefd = open("/proc/self/exe", O_RDONLY);
198*4882a593Smuzhiyun 	char const *test_str = "test_send";
199*4882a593Smuzhiyun 	int to_send = strlen(test_str) + 1;
200*4882a593Smuzhiyun 	char recv_buf[10];
201*4882a593Smuzhiyun 	struct stat st;
202*4882a593Smuzhiyun 	char *buf;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	EXPECT_GE(filefd, 0);
205*4882a593Smuzhiyun 	fstat(filefd, &st);
206*4882a593Smuzhiyun 	buf = (char *)malloc(st.st_size);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, to_send, 0), to_send);
209*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_buf, to_send, MSG_WAITALL), to_send);
210*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, recv_buf, to_send), 0);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
213*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, st.st_size, MSG_WAITALL), st.st_size);
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
chunked_sendfile(struct __test_metadata * _metadata,struct _test_data_tls * self,uint16_t chunk_size,uint16_t extra_payload_size)216*4882a593Smuzhiyun static void chunked_sendfile(struct __test_metadata *_metadata,
217*4882a593Smuzhiyun 			     struct _test_data_tls *self,
218*4882a593Smuzhiyun 			     uint16_t chunk_size,
219*4882a593Smuzhiyun 			     uint16_t extra_payload_size)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun 	char buf[TLS_PAYLOAD_MAX_LEN];
222*4882a593Smuzhiyun 	uint16_t test_payload_size;
223*4882a593Smuzhiyun 	int size = 0;
224*4882a593Smuzhiyun 	int ret;
225*4882a593Smuzhiyun 	char filename[] = "/tmp/mytemp.XXXXXX";
226*4882a593Smuzhiyun 	int fd = mkstemp(filename);
227*4882a593Smuzhiyun 	off_t offset = 0;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	unlink(filename);
230*4882a593Smuzhiyun 	ASSERT_GE(fd, 0);
231*4882a593Smuzhiyun 	EXPECT_GE(chunk_size, 1);
232*4882a593Smuzhiyun 	test_payload_size = chunk_size + extra_payload_size;
233*4882a593Smuzhiyun 	ASSERT_GE(TLS_PAYLOAD_MAX_LEN, test_payload_size);
234*4882a593Smuzhiyun 	memset(buf, 1, test_payload_size);
235*4882a593Smuzhiyun 	size = write(fd, buf, test_payload_size);
236*4882a593Smuzhiyun 	EXPECT_EQ(size, test_payload_size);
237*4882a593Smuzhiyun 	fsync(fd);
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	while (size > 0) {
240*4882a593Smuzhiyun 		ret = sendfile(self->fd, fd, &offset, chunk_size);
241*4882a593Smuzhiyun 		EXPECT_GE(ret, 0);
242*4882a593Smuzhiyun 		size -= ret;
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, test_payload_size, MSG_WAITALL),
246*4882a593Smuzhiyun 		  test_payload_size);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	close(fd);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
TEST_F(tls,multi_chunk_sendfile)251*4882a593Smuzhiyun TEST_F(tls, multi_chunk_sendfile)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 4096, 4096);
254*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 4096, 0);
255*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 4096, 1);
256*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 4096, 2048);
257*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 8192, 2048);
258*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 4096, 8192);
259*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 8192, 4096);
260*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 12288, 1024);
261*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 12288, 2000);
262*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 15360, 100);
263*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 15360, 300);
264*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 1, 4096);
265*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 2048, 4096);
266*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 2048, 8192);
267*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 4096, 8192);
268*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 1024, 12288);
269*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 2000, 12288);
270*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 100, 15360);
271*4882a593Smuzhiyun 	chunked_sendfile(_metadata, self, 300, 15360);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
TEST_F(tls,recv_max)274*4882a593Smuzhiyun TEST_F(tls, recv_max)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
277*4882a593Smuzhiyun 	char recv_mem[TLS_PAYLOAD_MAX_LEN];
278*4882a593Smuzhiyun 	char buf[TLS_PAYLOAD_MAX_LEN];
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	EXPECT_GE(send(self->fd, buf, send_len, 0), 0);
281*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
282*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun 
TEST_F(tls,recv_small)285*4882a593Smuzhiyun TEST_F(tls, recv_small)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	char const *test_str = "test_read";
288*4882a593Smuzhiyun 	int send_len = 10;
289*4882a593Smuzhiyun 	char buf[10];
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	send_len = strlen(test_str) + 1;
292*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
293*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
294*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
TEST_F(tls,msg_more)297*4882a593Smuzhiyun TEST_F(tls, msg_more)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun 	char const *test_str = "test_read";
300*4882a593Smuzhiyun 	int send_len = 10;
301*4882a593Smuzhiyun 	char buf[10 * 2];
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
304*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
305*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
306*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len * 2, MSG_WAITALL),
307*4882a593Smuzhiyun 		  send_len * 2);
308*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun 
TEST_F(tls,msg_more_unsent)311*4882a593Smuzhiyun TEST_F(tls, msg_more_unsent)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun 	char const *test_str = "test_read";
314*4882a593Smuzhiyun 	int send_len = 10;
315*4882a593Smuzhiyun 	char buf[10];
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
318*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
TEST_F(tls,sendmsg_single)321*4882a593Smuzhiyun TEST_F(tls, sendmsg_single)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun 	struct msghdr msg;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	char const *test_str = "test_sendmsg";
326*4882a593Smuzhiyun 	size_t send_len = 13;
327*4882a593Smuzhiyun 	struct iovec vec;
328*4882a593Smuzhiyun 	char buf[13];
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	vec.iov_base = (char *)test_str;
331*4882a593Smuzhiyun 	vec.iov_len = send_len;
332*4882a593Smuzhiyun 	memset(&msg, 0, sizeof(struct msghdr));
333*4882a593Smuzhiyun 	msg.msg_iov = &vec;
334*4882a593Smuzhiyun 	msg.msg_iovlen = 1;
335*4882a593Smuzhiyun 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
336*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_WAITALL), send_len);
337*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun #define MAX_FRAGS	64
341*4882a593Smuzhiyun #define SEND_LEN	13
TEST_F(tls,sendmsg_fragmented)342*4882a593Smuzhiyun TEST_F(tls, sendmsg_fragmented)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun 	char const *test_str = "test_sendmsg";
345*4882a593Smuzhiyun 	char buf[SEND_LEN * MAX_FRAGS];
346*4882a593Smuzhiyun 	struct iovec vec[MAX_FRAGS];
347*4882a593Smuzhiyun 	struct msghdr msg;
348*4882a593Smuzhiyun 	int i, frags;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	for (frags = 1; frags <= MAX_FRAGS; frags++) {
351*4882a593Smuzhiyun 		for (i = 0; i < frags; i++) {
352*4882a593Smuzhiyun 			vec[i].iov_base = (char *)test_str;
353*4882a593Smuzhiyun 			vec[i].iov_len = SEND_LEN;
354*4882a593Smuzhiyun 		}
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 		memset(&msg, 0, sizeof(struct msghdr));
357*4882a593Smuzhiyun 		msg.msg_iov = vec;
358*4882a593Smuzhiyun 		msg.msg_iovlen = frags;
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 		EXPECT_EQ(sendmsg(self->fd, &msg, 0), SEND_LEN * frags);
361*4882a593Smuzhiyun 		EXPECT_EQ(recv(self->cfd, buf, SEND_LEN * frags, MSG_WAITALL),
362*4882a593Smuzhiyun 			  SEND_LEN * frags);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 		for (i = 0; i < frags; i++)
365*4882a593Smuzhiyun 			EXPECT_EQ(memcmp(buf + SEND_LEN * i,
366*4882a593Smuzhiyun 					 test_str, SEND_LEN), 0);
367*4882a593Smuzhiyun 	}
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun #undef MAX_FRAGS
370*4882a593Smuzhiyun #undef SEND_LEN
371*4882a593Smuzhiyun 
TEST_F(tls,sendmsg_large)372*4882a593Smuzhiyun TEST_F(tls, sendmsg_large)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun 	void *mem = malloc(16384);
375*4882a593Smuzhiyun 	size_t send_len = 16384;
376*4882a593Smuzhiyun 	size_t sends = 128;
377*4882a593Smuzhiyun 	struct msghdr msg;
378*4882a593Smuzhiyun 	size_t recvs = 0;
379*4882a593Smuzhiyun 	size_t sent = 0;
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	memset(&msg, 0, sizeof(struct msghdr));
382*4882a593Smuzhiyun 	while (sent++ < sends) {
383*4882a593Smuzhiyun 		struct iovec vec = { (void *)mem, send_len };
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 		msg.msg_iov = &vec;
386*4882a593Smuzhiyun 		msg.msg_iovlen = 1;
387*4882a593Smuzhiyun 		EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len);
388*4882a593Smuzhiyun 	}
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	while (recvs++ < sends)
391*4882a593Smuzhiyun 		EXPECT_NE(recv(self->fd, mem, send_len, 0), -1);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	free(mem);
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
TEST_F(tls,sendmsg_multiple)396*4882a593Smuzhiyun TEST_F(tls, sendmsg_multiple)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun 	char const *test_str = "test_sendmsg_multiple";
399*4882a593Smuzhiyun 	struct iovec vec[5];
400*4882a593Smuzhiyun 	char *test_strs[5];
401*4882a593Smuzhiyun 	struct msghdr msg;
402*4882a593Smuzhiyun 	int total_len = 0;
403*4882a593Smuzhiyun 	int len_cmp = 0;
404*4882a593Smuzhiyun 	int iov_len = 5;
405*4882a593Smuzhiyun 	char *buf;
406*4882a593Smuzhiyun 	int i;
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 	memset(&msg, 0, sizeof(struct msghdr));
409*4882a593Smuzhiyun 	for (i = 0; i < iov_len; i++) {
410*4882a593Smuzhiyun 		test_strs[i] = (char *)malloc(strlen(test_str) + 1);
411*4882a593Smuzhiyun 		snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
412*4882a593Smuzhiyun 		vec[i].iov_base = (void *)test_strs[i];
413*4882a593Smuzhiyun 		vec[i].iov_len = strlen(test_strs[i]) + 1;
414*4882a593Smuzhiyun 		total_len += vec[i].iov_len;
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 	msg.msg_iov = vec;
417*4882a593Smuzhiyun 	msg.msg_iovlen = iov_len;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len);
420*4882a593Smuzhiyun 	buf = malloc(total_len);
421*4882a593Smuzhiyun 	EXPECT_NE(recv(self->fd, buf, total_len, 0), -1);
422*4882a593Smuzhiyun 	for (i = 0; i < iov_len; i++) {
423*4882a593Smuzhiyun 		EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp,
424*4882a593Smuzhiyun 				 strlen(test_strs[i])),
425*4882a593Smuzhiyun 			  0);
426*4882a593Smuzhiyun 		len_cmp += strlen(buf + len_cmp) + 1;
427*4882a593Smuzhiyun 	}
428*4882a593Smuzhiyun 	for (i = 0; i < iov_len; i++)
429*4882a593Smuzhiyun 		free(test_strs[i]);
430*4882a593Smuzhiyun 	free(buf);
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun 
TEST_F(tls,sendmsg_multiple_stress)433*4882a593Smuzhiyun TEST_F(tls, sendmsg_multiple_stress)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun 	char const *test_str = "abcdefghijklmno";
436*4882a593Smuzhiyun 	struct iovec vec[1024];
437*4882a593Smuzhiyun 	char *test_strs[1024];
438*4882a593Smuzhiyun 	int iov_len = 1024;
439*4882a593Smuzhiyun 	int total_len = 0;
440*4882a593Smuzhiyun 	char buf[1 << 14];
441*4882a593Smuzhiyun 	struct msghdr msg;
442*4882a593Smuzhiyun 	int len_cmp = 0;
443*4882a593Smuzhiyun 	int i;
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	memset(&msg, 0, sizeof(struct msghdr));
446*4882a593Smuzhiyun 	for (i = 0; i < iov_len; i++) {
447*4882a593Smuzhiyun 		test_strs[i] = (char *)malloc(strlen(test_str) + 1);
448*4882a593Smuzhiyun 		snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
449*4882a593Smuzhiyun 		vec[i].iov_base = (void *)test_strs[i];
450*4882a593Smuzhiyun 		vec[i].iov_len = strlen(test_strs[i]) + 1;
451*4882a593Smuzhiyun 		total_len += vec[i].iov_len;
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun 	msg.msg_iov = vec;
454*4882a593Smuzhiyun 	msg.msg_iovlen = iov_len;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len);
457*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	for (i = 0; i < iov_len; i++)
460*4882a593Smuzhiyun 		len_cmp += strlen(buf + len_cmp) + 1;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	for (i = 0; i < iov_len; i++)
463*4882a593Smuzhiyun 		free(test_strs[i]);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
TEST_F(tls,splice_from_pipe)466*4882a593Smuzhiyun TEST_F(tls, splice_from_pipe)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun 	int send_len = TLS_PAYLOAD_MAX_LEN;
469*4882a593Smuzhiyun 	char mem_send[TLS_PAYLOAD_MAX_LEN];
470*4882a593Smuzhiyun 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
471*4882a593Smuzhiyun 	int p[2];
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	ASSERT_GE(pipe(p), 0);
474*4882a593Smuzhiyun 	EXPECT_GE(write(p[1], mem_send, send_len), 0);
475*4882a593Smuzhiyun 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), 0);
476*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
477*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun 
TEST_F(tls,splice_from_pipe2)480*4882a593Smuzhiyun TEST_F(tls, splice_from_pipe2)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun 	int send_len = 16000;
483*4882a593Smuzhiyun 	char mem_send[16000];
484*4882a593Smuzhiyun 	char mem_recv[16000];
485*4882a593Smuzhiyun 	int p2[2];
486*4882a593Smuzhiyun 	int p[2];
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	ASSERT_GE(pipe(p), 0);
489*4882a593Smuzhiyun 	ASSERT_GE(pipe(p2), 0);
490*4882a593Smuzhiyun 	EXPECT_GE(write(p[1], mem_send, 8000), 0);
491*4882a593Smuzhiyun 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, 8000, 0), 0);
492*4882a593Smuzhiyun 	EXPECT_GE(write(p2[1], mem_send + 8000, 8000), 0);
493*4882a593Smuzhiyun 	EXPECT_GE(splice(p2[0], NULL, self->fd, NULL, 8000, 0), 0);
494*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
495*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun 
TEST_F(tls,send_and_splice)498*4882a593Smuzhiyun TEST_F(tls, send_and_splice)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun 	int send_len = TLS_PAYLOAD_MAX_LEN;
501*4882a593Smuzhiyun 	char mem_send[TLS_PAYLOAD_MAX_LEN];
502*4882a593Smuzhiyun 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
503*4882a593Smuzhiyun 	char const *test_str = "test_read";
504*4882a593Smuzhiyun 	int send_len2 = 10;
505*4882a593Smuzhiyun 	char buf[10];
506*4882a593Smuzhiyun 	int p[2];
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	ASSERT_GE(pipe(p), 0);
509*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len2, 0), send_len2);
510*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len2, MSG_WAITALL), send_len2);
511*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, send_len2), 0);
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	EXPECT_GE(write(p[1], mem_send, send_len), send_len);
514*4882a593Smuzhiyun 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), send_len);
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
517*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun 
TEST_F(tls,splice_to_pipe)520*4882a593Smuzhiyun TEST_F(tls, splice_to_pipe)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun 	int send_len = TLS_PAYLOAD_MAX_LEN;
523*4882a593Smuzhiyun 	char mem_send[TLS_PAYLOAD_MAX_LEN];
524*4882a593Smuzhiyun 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
525*4882a593Smuzhiyun 	int p[2];
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	ASSERT_GE(pipe(p), 0);
528*4882a593Smuzhiyun 	EXPECT_GE(send(self->fd, mem_send, send_len, 0), 0);
529*4882a593Smuzhiyun 	EXPECT_GE(splice(self->cfd, NULL, p[1], NULL, send_len, 0), 0);
530*4882a593Smuzhiyun 	EXPECT_GE(read(p[0], mem_recv, send_len), 0);
531*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
TEST_F(tls,recvmsg_single)534*4882a593Smuzhiyun TEST_F(tls, recvmsg_single)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun 	char const *test_str = "test_recvmsg_single";
537*4882a593Smuzhiyun 	int send_len = strlen(test_str) + 1;
538*4882a593Smuzhiyun 	char buf[20];
539*4882a593Smuzhiyun 	struct msghdr hdr;
540*4882a593Smuzhiyun 	struct iovec vec;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	memset(&hdr, 0, sizeof(hdr));
543*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
544*4882a593Smuzhiyun 	vec.iov_base = (char *)buf;
545*4882a593Smuzhiyun 	vec.iov_len = send_len;
546*4882a593Smuzhiyun 	hdr.msg_iovlen = 1;
547*4882a593Smuzhiyun 	hdr.msg_iov = &vec;
548*4882a593Smuzhiyun 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
549*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
TEST_F(tls,recvmsg_single_max)552*4882a593Smuzhiyun TEST_F(tls, recvmsg_single_max)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun 	int send_len = TLS_PAYLOAD_MAX_LEN;
555*4882a593Smuzhiyun 	char send_mem[TLS_PAYLOAD_MAX_LEN];
556*4882a593Smuzhiyun 	char recv_mem[TLS_PAYLOAD_MAX_LEN];
557*4882a593Smuzhiyun 	struct iovec vec;
558*4882a593Smuzhiyun 	struct msghdr hdr;
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, send_mem, send_len, 0), send_len);
561*4882a593Smuzhiyun 	vec.iov_base = (char *)recv_mem;
562*4882a593Smuzhiyun 	vec.iov_len = TLS_PAYLOAD_MAX_LEN;
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	hdr.msg_iovlen = 1;
565*4882a593Smuzhiyun 	hdr.msg_iov = &vec;
566*4882a593Smuzhiyun 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
567*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun 
TEST_F(tls,recvmsg_multiple)570*4882a593Smuzhiyun TEST_F(tls, recvmsg_multiple)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun 	unsigned int msg_iovlen = 1024;
573*4882a593Smuzhiyun 	unsigned int len_compared = 0;
574*4882a593Smuzhiyun 	struct iovec vec[1024];
575*4882a593Smuzhiyun 	char *iov_base[1024];
576*4882a593Smuzhiyun 	unsigned int iov_len = 16;
577*4882a593Smuzhiyun 	int send_len = 1 << 14;
578*4882a593Smuzhiyun 	char buf[1 << 14];
579*4882a593Smuzhiyun 	struct msghdr hdr;
580*4882a593Smuzhiyun 	int i;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, buf, send_len, 0), send_len);
583*4882a593Smuzhiyun 	for (i = 0; i < msg_iovlen; i++) {
584*4882a593Smuzhiyun 		iov_base[i] = (char *)malloc(iov_len);
585*4882a593Smuzhiyun 		vec[i].iov_base = iov_base[i];
586*4882a593Smuzhiyun 		vec[i].iov_len = iov_len;
587*4882a593Smuzhiyun 	}
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	hdr.msg_iovlen = msg_iovlen;
590*4882a593Smuzhiyun 	hdr.msg_iov = vec;
591*4882a593Smuzhiyun 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
592*4882a593Smuzhiyun 	for (i = 0; i < msg_iovlen; i++)
593*4882a593Smuzhiyun 		len_compared += iov_len;
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	for (i = 0; i < msg_iovlen; i++)
596*4882a593Smuzhiyun 		free(iov_base[i]);
597*4882a593Smuzhiyun }
598*4882a593Smuzhiyun 
TEST_F(tls,single_send_multiple_recv)599*4882a593Smuzhiyun TEST_F(tls, single_send_multiple_recv)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun 	unsigned int total_len = TLS_PAYLOAD_MAX_LEN * 2;
602*4882a593Smuzhiyun 	unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
603*4882a593Smuzhiyun 	char send_mem[TLS_PAYLOAD_MAX_LEN * 2];
604*4882a593Smuzhiyun 	char recv_mem[TLS_PAYLOAD_MAX_LEN * 2];
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
607*4882a593Smuzhiyun 	memset(recv_mem, 0, total_len);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
610*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, recv_mem + send_len, send_len, 0), -1);
611*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun 
TEST_F(tls,multiple_send_single_recv)614*4882a593Smuzhiyun TEST_F(tls, multiple_send_single_recv)
615*4882a593Smuzhiyun {
616*4882a593Smuzhiyun 	unsigned int total_len = 2 * 10;
617*4882a593Smuzhiyun 	unsigned int send_len = 10;
618*4882a593Smuzhiyun 	char recv_mem[2 * 10];
619*4882a593Smuzhiyun 	char send_mem[10];
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
622*4882a593Smuzhiyun 	EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
623*4882a593Smuzhiyun 	memset(recv_mem, 0, total_len);
624*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem, total_len, MSG_WAITALL), total_len);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
627*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0);
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun 
TEST_F(tls,single_send_multiple_recv_non_align)630*4882a593Smuzhiyun TEST_F(tls, single_send_multiple_recv_non_align)
631*4882a593Smuzhiyun {
632*4882a593Smuzhiyun 	const unsigned int total_len = 15;
633*4882a593Smuzhiyun 	const unsigned int recv_len = 10;
634*4882a593Smuzhiyun 	char recv_mem[recv_len * 2];
635*4882a593Smuzhiyun 	char send_mem[total_len];
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
638*4882a593Smuzhiyun 	memset(recv_mem, 0, total_len);
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem, recv_len, 0), recv_len);
641*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem + recv_len, recv_len, 0), 5);
642*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
643*4882a593Smuzhiyun }
644*4882a593Smuzhiyun 
TEST_F(tls,recv_partial)645*4882a593Smuzhiyun TEST_F(tls, recv_partial)
646*4882a593Smuzhiyun {
647*4882a593Smuzhiyun 	char const *test_str = "test_read_partial";
648*4882a593Smuzhiyun 	char const *test_str_first = "test_read";
649*4882a593Smuzhiyun 	char const *test_str_second = "_partial";
650*4882a593Smuzhiyun 	int send_len = strlen(test_str) + 1;
651*4882a593Smuzhiyun 	char recv_mem[18];
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	memset(recv_mem, 0, sizeof(recv_mem));
654*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
655*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_first),
656*4882a593Smuzhiyun 		       MSG_WAITALL), -1);
657*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str_first, recv_mem, strlen(test_str_first)), 0);
658*4882a593Smuzhiyun 	memset(recv_mem, 0, sizeof(recv_mem));
659*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_second),
660*4882a593Smuzhiyun 		       MSG_WAITALL), -1);
661*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str_second, recv_mem, strlen(test_str_second)),
662*4882a593Smuzhiyun 		  0);
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
TEST_F(tls,recv_nonblock)665*4882a593Smuzhiyun TEST_F(tls, recv_nonblock)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun 	char buf[4096];
668*4882a593Smuzhiyun 	bool err;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_DONTWAIT), -1);
671*4882a593Smuzhiyun 	err = (errno == EAGAIN || errno == EWOULDBLOCK);
672*4882a593Smuzhiyun 	EXPECT_EQ(err, true);
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun 
TEST_F(tls,recv_peek)675*4882a593Smuzhiyun TEST_F(tls, recv_peek)
676*4882a593Smuzhiyun {
677*4882a593Smuzhiyun 	char const *test_str = "test_read_peek";
678*4882a593Smuzhiyun 	int send_len = strlen(test_str) + 1;
679*4882a593Smuzhiyun 	char buf[15];
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
682*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
683*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
684*4882a593Smuzhiyun 	memset(buf, 0, sizeof(buf));
685*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
686*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun 
TEST_F(tls,recv_peek_multiple)689*4882a593Smuzhiyun TEST_F(tls, recv_peek_multiple)
690*4882a593Smuzhiyun {
691*4882a593Smuzhiyun 	char const *test_str = "test_read_peek";
692*4882a593Smuzhiyun 	int send_len = strlen(test_str) + 1;
693*4882a593Smuzhiyun 	unsigned int num_peeks = 100;
694*4882a593Smuzhiyun 	char buf[15];
695*4882a593Smuzhiyun 	int i;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
698*4882a593Smuzhiyun 	for (i = 0; i < num_peeks; i++) {
699*4882a593Smuzhiyun 		EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
700*4882a593Smuzhiyun 		EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
701*4882a593Smuzhiyun 		memset(buf, 0, sizeof(buf));
702*4882a593Smuzhiyun 	}
703*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
704*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun 
TEST_F(tls,recv_peek_multiple_records)707*4882a593Smuzhiyun TEST_F(tls, recv_peek_multiple_records)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun 	char const *test_str = "test_read_peek_mult_recs";
710*4882a593Smuzhiyun 	char const *test_str_first = "test_read_peek";
711*4882a593Smuzhiyun 	char const *test_str_second = "_mult_recs";
712*4882a593Smuzhiyun 	int len;
713*4882a593Smuzhiyun 	char buf[64];
714*4882a593Smuzhiyun 
715*4882a593Smuzhiyun 	len = strlen(test_str_first);
716*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	len = strlen(test_str_second) + 1;
719*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	len = strlen(test_str_first);
722*4882a593Smuzhiyun 	memset(buf, 0, len);
723*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_PEEK | MSG_WAITALL), len);
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	/* MSG_PEEK can only peek into the current record. */
726*4882a593Smuzhiyun 	len = strlen(test_str_first);
727*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str_first, buf, len), 0);
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	len = strlen(test_str) + 1;
730*4882a593Smuzhiyun 	memset(buf, 0, len);
731*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_WAITALL), len);
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	/* Non-MSG_PEEK will advance strparser (and therefore record)
734*4882a593Smuzhiyun 	 * however.
735*4882a593Smuzhiyun 	 */
736*4882a593Smuzhiyun 	len = strlen(test_str) + 1;
737*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	/* MSG_MORE will hold current record open, so later MSG_PEEK
740*4882a593Smuzhiyun 	 * will see everything.
741*4882a593Smuzhiyun 	 */
742*4882a593Smuzhiyun 	len = strlen(test_str_first);
743*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str_first, len, MSG_MORE), len);
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	len = strlen(test_str_second) + 1;
746*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	len = strlen(test_str) + 1;
749*4882a593Smuzhiyun 	memset(buf, 0, len);
750*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_PEEK | MSG_WAITALL), len);
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	len = strlen(test_str) + 1;
753*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun 
TEST_F(tls,recv_peek_large_buf_mult_recs)756*4882a593Smuzhiyun TEST_F(tls, recv_peek_large_buf_mult_recs)
757*4882a593Smuzhiyun {
758*4882a593Smuzhiyun 	char const *test_str = "test_read_peek_mult_recs";
759*4882a593Smuzhiyun 	char const *test_str_first = "test_read_peek";
760*4882a593Smuzhiyun 	char const *test_str_second = "_mult_recs";
761*4882a593Smuzhiyun 	int len;
762*4882a593Smuzhiyun 	char buf[64];
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 	len = strlen(test_str_first);
765*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	len = strlen(test_str_second) + 1;
768*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	len = strlen(test_str) + 1;
771*4882a593Smuzhiyun 	memset(buf, 0, len);
772*4882a593Smuzhiyun 	EXPECT_NE((len = recv(self->cfd, buf, len,
773*4882a593Smuzhiyun 			      MSG_PEEK | MSG_WAITALL)), -1);
774*4882a593Smuzhiyun 	len = strlen(test_str) + 1;
775*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun 
TEST_F(tls,recv_lowat)778*4882a593Smuzhiyun TEST_F(tls, recv_lowat)
779*4882a593Smuzhiyun {
780*4882a593Smuzhiyun 	char send_mem[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
781*4882a593Smuzhiyun 	char recv_mem[20];
782*4882a593Smuzhiyun 	int lowat = 8;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, send_mem, 10, 0), 10);
785*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, send_mem, 5, 0), 5);
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun 	memset(recv_mem, 0, 20);
788*4882a593Smuzhiyun 	EXPECT_EQ(setsockopt(self->cfd, SOL_SOCKET, SO_RCVLOWAT,
789*4882a593Smuzhiyun 			     &lowat, sizeof(lowat)), 0);
790*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem, 1, MSG_WAITALL), 1);
791*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem + 1, 6, MSG_WAITALL), 6);
792*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem + 7, 10, 0), 8);
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem, 10), 0);
795*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(send_mem, recv_mem + 10, 5), 0);
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun 
TEST_F(tls,bidir)798*4882a593Smuzhiyun TEST_F(tls, bidir)
799*4882a593Smuzhiyun {
800*4882a593Smuzhiyun 	char const *test_str = "test_read";
801*4882a593Smuzhiyun 	int send_len = 10;
802*4882a593Smuzhiyun 	char buf[10];
803*4882a593Smuzhiyun 	int ret;
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	if (!self->notls) {
806*4882a593Smuzhiyun 		struct tls12_crypto_info_aes_gcm_128 tls12;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 		memset(&tls12, 0, sizeof(tls12));
809*4882a593Smuzhiyun 		tls12.info.version = variant->tls_version;
810*4882a593Smuzhiyun 		tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 		ret = setsockopt(self->fd, SOL_TLS, TLS_RX, &tls12,
813*4882a593Smuzhiyun 				 sizeof(tls12));
814*4882a593Smuzhiyun 		ASSERT_EQ(ret, 0);
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 		ret = setsockopt(self->cfd, SOL_TLS, TLS_TX, &tls12,
817*4882a593Smuzhiyun 				 sizeof(tls12));
818*4882a593Smuzhiyun 		ASSERT_EQ(ret, 0);
819*4882a593Smuzhiyun 	}
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	ASSERT_EQ(strlen(test_str) + 1, send_len);
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
824*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
825*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	memset(buf, 0, sizeof(buf));
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	EXPECT_EQ(send(self->cfd, test_str, send_len, 0), send_len);
830*4882a593Smuzhiyun 	EXPECT_NE(recv(self->fd, buf, send_len, 0), -1);
831*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
832*4882a593Smuzhiyun };
833*4882a593Smuzhiyun 
TEST_F(tls,pollin)834*4882a593Smuzhiyun TEST_F(tls, pollin)
835*4882a593Smuzhiyun {
836*4882a593Smuzhiyun 	char const *test_str = "test_poll";
837*4882a593Smuzhiyun 	struct pollfd fd = { 0, 0, 0 };
838*4882a593Smuzhiyun 	char buf[10];
839*4882a593Smuzhiyun 	int send_len = 10;
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
842*4882a593Smuzhiyun 	fd.fd = self->cfd;
843*4882a593Smuzhiyun 	fd.events = POLLIN;
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	EXPECT_EQ(poll(&fd, 1, 20), 1);
846*4882a593Smuzhiyun 	EXPECT_EQ(fd.revents & POLLIN, 1);
847*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_WAITALL), send_len);
848*4882a593Smuzhiyun 	/* Test timing out */
849*4882a593Smuzhiyun 	EXPECT_EQ(poll(&fd, 1, 20), 0);
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun 
TEST_F(tls,poll_wait)852*4882a593Smuzhiyun TEST_F(tls, poll_wait)
853*4882a593Smuzhiyun {
854*4882a593Smuzhiyun 	char const *test_str = "test_poll_wait";
855*4882a593Smuzhiyun 	int send_len = strlen(test_str) + 1;
856*4882a593Smuzhiyun 	struct pollfd fd = { 0, 0, 0 };
857*4882a593Smuzhiyun 	char recv_mem[15];
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 	fd.fd = self->cfd;
860*4882a593Smuzhiyun 	fd.events = POLLIN;
861*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
862*4882a593Smuzhiyun 	/* Set timeout to inf. secs */
863*4882a593Smuzhiyun 	EXPECT_EQ(poll(&fd, 1, -1), 1);
864*4882a593Smuzhiyun 	EXPECT_EQ(fd.revents & POLLIN, 1);
865*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem, send_len, MSG_WAITALL), send_len);
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun 
TEST_F(tls,poll_wait_split)868*4882a593Smuzhiyun TEST_F(tls, poll_wait_split)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun 	struct pollfd fd = { 0, 0, 0 };
871*4882a593Smuzhiyun 	char send_mem[20] = {};
872*4882a593Smuzhiyun 	char recv_mem[15];
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 	fd.fd = self->cfd;
875*4882a593Smuzhiyun 	fd.events = POLLIN;
876*4882a593Smuzhiyun 	/* Send 20 bytes */
877*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, send_mem, sizeof(send_mem), 0),
878*4882a593Smuzhiyun 		  sizeof(send_mem));
879*4882a593Smuzhiyun 	/* Poll with inf. timeout */
880*4882a593Smuzhiyun 	EXPECT_EQ(poll(&fd, 1, -1), 1);
881*4882a593Smuzhiyun 	EXPECT_EQ(fd.revents & POLLIN, 1);
882*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), MSG_WAITALL),
883*4882a593Smuzhiyun 		  sizeof(recv_mem));
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun 	/* Now the remaining 5 bytes of record data are in TLS ULP */
886*4882a593Smuzhiyun 	fd.fd = self->cfd;
887*4882a593Smuzhiyun 	fd.events = POLLIN;
888*4882a593Smuzhiyun 	EXPECT_EQ(poll(&fd, 1, -1), 1);
889*4882a593Smuzhiyun 	EXPECT_EQ(fd.revents & POLLIN, 1);
890*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), 0),
891*4882a593Smuzhiyun 		  sizeof(send_mem) - sizeof(recv_mem));
892*4882a593Smuzhiyun }
893*4882a593Smuzhiyun 
TEST_F(tls,blocking)894*4882a593Smuzhiyun TEST_F(tls, blocking)
895*4882a593Smuzhiyun {
896*4882a593Smuzhiyun 	size_t data = 100000;
897*4882a593Smuzhiyun 	int res = fork();
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	EXPECT_NE(res, -1);
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	if (res) {
902*4882a593Smuzhiyun 		/* parent */
903*4882a593Smuzhiyun 		size_t left = data;
904*4882a593Smuzhiyun 		char buf[16384];
905*4882a593Smuzhiyun 		int status;
906*4882a593Smuzhiyun 		int pid2;
907*4882a593Smuzhiyun 
908*4882a593Smuzhiyun 		while (left) {
909*4882a593Smuzhiyun 			int res = send(self->fd, buf,
910*4882a593Smuzhiyun 				       left > 16384 ? 16384 : left, 0);
911*4882a593Smuzhiyun 
912*4882a593Smuzhiyun 			EXPECT_GE(res, 0);
913*4882a593Smuzhiyun 			left -= res;
914*4882a593Smuzhiyun 		}
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 		pid2 = wait(&status);
917*4882a593Smuzhiyun 		EXPECT_EQ(status, 0);
918*4882a593Smuzhiyun 		EXPECT_EQ(res, pid2);
919*4882a593Smuzhiyun 	} else {
920*4882a593Smuzhiyun 		/* child */
921*4882a593Smuzhiyun 		size_t left = data;
922*4882a593Smuzhiyun 		char buf[16384];
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 		while (left) {
925*4882a593Smuzhiyun 			int res = recv(self->cfd, buf,
926*4882a593Smuzhiyun 				       left > 16384 ? 16384 : left, 0);
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 			EXPECT_GE(res, 0);
929*4882a593Smuzhiyun 			left -= res;
930*4882a593Smuzhiyun 		}
931*4882a593Smuzhiyun 	}
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun 
TEST_F(tls,nonblocking)934*4882a593Smuzhiyun TEST_F(tls, nonblocking)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun 	size_t data = 100000;
937*4882a593Smuzhiyun 	int sendbuf = 100;
938*4882a593Smuzhiyun 	int flags;
939*4882a593Smuzhiyun 	int res;
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun 	flags = fcntl(self->fd, F_GETFL, 0);
942*4882a593Smuzhiyun 	fcntl(self->fd, F_SETFL, flags | O_NONBLOCK);
943*4882a593Smuzhiyun 	fcntl(self->cfd, F_SETFL, flags | O_NONBLOCK);
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 	/* Ensure nonblocking behavior by imposing a small send
946*4882a593Smuzhiyun 	 * buffer.
947*4882a593Smuzhiyun 	 */
948*4882a593Smuzhiyun 	EXPECT_EQ(setsockopt(self->fd, SOL_SOCKET, SO_SNDBUF,
949*4882a593Smuzhiyun 			     &sendbuf, sizeof(sendbuf)), 0);
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	res = fork();
952*4882a593Smuzhiyun 	EXPECT_NE(res, -1);
953*4882a593Smuzhiyun 
954*4882a593Smuzhiyun 	if (res) {
955*4882a593Smuzhiyun 		/* parent */
956*4882a593Smuzhiyun 		bool eagain = false;
957*4882a593Smuzhiyun 		size_t left = data;
958*4882a593Smuzhiyun 		char buf[16384];
959*4882a593Smuzhiyun 		int status;
960*4882a593Smuzhiyun 		int pid2;
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun 		while (left) {
963*4882a593Smuzhiyun 			int res = send(self->fd, buf,
964*4882a593Smuzhiyun 				       left > 16384 ? 16384 : left, 0);
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun 			if (res == -1 && errno == EAGAIN) {
967*4882a593Smuzhiyun 				eagain = true;
968*4882a593Smuzhiyun 				usleep(10000);
969*4882a593Smuzhiyun 				continue;
970*4882a593Smuzhiyun 			}
971*4882a593Smuzhiyun 			EXPECT_GE(res, 0);
972*4882a593Smuzhiyun 			left -= res;
973*4882a593Smuzhiyun 		}
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun 		EXPECT_TRUE(eagain);
976*4882a593Smuzhiyun 		pid2 = wait(&status);
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun 		EXPECT_EQ(status, 0);
979*4882a593Smuzhiyun 		EXPECT_EQ(res, pid2);
980*4882a593Smuzhiyun 	} else {
981*4882a593Smuzhiyun 		/* child */
982*4882a593Smuzhiyun 		bool eagain = false;
983*4882a593Smuzhiyun 		size_t left = data;
984*4882a593Smuzhiyun 		char buf[16384];
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun 		while (left) {
987*4882a593Smuzhiyun 			int res = recv(self->cfd, buf,
988*4882a593Smuzhiyun 				       left > 16384 ? 16384 : left, 0);
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 			if (res == -1 && errno == EAGAIN) {
991*4882a593Smuzhiyun 				eagain = true;
992*4882a593Smuzhiyun 				usleep(10000);
993*4882a593Smuzhiyun 				continue;
994*4882a593Smuzhiyun 			}
995*4882a593Smuzhiyun 			EXPECT_GE(res, 0);
996*4882a593Smuzhiyun 			left -= res;
997*4882a593Smuzhiyun 		}
998*4882a593Smuzhiyun 		EXPECT_TRUE(eagain);
999*4882a593Smuzhiyun 	}
1000*4882a593Smuzhiyun }
1001*4882a593Smuzhiyun 
1002*4882a593Smuzhiyun static void
test_mutliproc(struct __test_metadata * _metadata,struct _test_data_tls * self,bool sendpg,unsigned int n_readers,unsigned int n_writers)1003*4882a593Smuzhiyun test_mutliproc(struct __test_metadata *_metadata, struct _test_data_tls *self,
1004*4882a593Smuzhiyun 	       bool sendpg, unsigned int n_readers, unsigned int n_writers)
1005*4882a593Smuzhiyun {
1006*4882a593Smuzhiyun 	const unsigned int n_children = n_readers + n_writers;
1007*4882a593Smuzhiyun 	const size_t data = 6 * 1000 * 1000;
1008*4882a593Smuzhiyun 	const size_t file_sz = data / 100;
1009*4882a593Smuzhiyun 	size_t read_bias, write_bias;
1010*4882a593Smuzhiyun 	int i, fd, child_id;
1011*4882a593Smuzhiyun 	char buf[file_sz];
1012*4882a593Smuzhiyun 	pid_t pid;
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	/* Only allow multiples for simplicity */
1015*4882a593Smuzhiyun 	ASSERT_EQ(!(n_readers % n_writers) || !(n_writers % n_readers), true);
1016*4882a593Smuzhiyun 	read_bias = n_writers / n_readers ?: 1;
1017*4882a593Smuzhiyun 	write_bias = n_readers / n_writers ?: 1;
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 	/* prep a file to send */
1020*4882a593Smuzhiyun 	fd = open("/tmp/", O_TMPFILE | O_RDWR, 0600);
1021*4882a593Smuzhiyun 	ASSERT_GE(fd, 0);
1022*4882a593Smuzhiyun 
1023*4882a593Smuzhiyun 	memset(buf, 0xac, file_sz);
1024*4882a593Smuzhiyun 	ASSERT_EQ(write(fd, buf, file_sz), file_sz);
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	/* spawn children */
1027*4882a593Smuzhiyun 	for (child_id = 0; child_id < n_children; child_id++) {
1028*4882a593Smuzhiyun 		pid = fork();
1029*4882a593Smuzhiyun 		ASSERT_NE(pid, -1);
1030*4882a593Smuzhiyun 		if (!pid)
1031*4882a593Smuzhiyun 			break;
1032*4882a593Smuzhiyun 	}
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	/* parent waits for all children */
1035*4882a593Smuzhiyun 	if (pid) {
1036*4882a593Smuzhiyun 		for (i = 0; i < n_children; i++) {
1037*4882a593Smuzhiyun 			int status;
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 			wait(&status);
1040*4882a593Smuzhiyun 			EXPECT_EQ(status, 0);
1041*4882a593Smuzhiyun 		}
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 		return;
1044*4882a593Smuzhiyun 	}
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	/* Split threads for reading and writing */
1047*4882a593Smuzhiyun 	if (child_id < n_readers) {
1048*4882a593Smuzhiyun 		size_t left = data * read_bias;
1049*4882a593Smuzhiyun 		char rb[8001];
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun 		while (left) {
1052*4882a593Smuzhiyun 			int res;
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 			res = recv(self->cfd, rb,
1055*4882a593Smuzhiyun 				   left > sizeof(rb) ? sizeof(rb) : left, 0);
1056*4882a593Smuzhiyun 
1057*4882a593Smuzhiyun 			EXPECT_GE(res, 0);
1058*4882a593Smuzhiyun 			left -= res;
1059*4882a593Smuzhiyun 		}
1060*4882a593Smuzhiyun 	} else {
1061*4882a593Smuzhiyun 		size_t left = data * write_bias;
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 		while (left) {
1064*4882a593Smuzhiyun 			int res;
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 			ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
1067*4882a593Smuzhiyun 			if (sendpg)
1068*4882a593Smuzhiyun 				res = sendfile(self->fd, fd, NULL,
1069*4882a593Smuzhiyun 					       left > file_sz ? file_sz : left);
1070*4882a593Smuzhiyun 			else
1071*4882a593Smuzhiyun 				res = send(self->fd, buf,
1072*4882a593Smuzhiyun 					   left > file_sz ? file_sz : left, 0);
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 			EXPECT_GE(res, 0);
1075*4882a593Smuzhiyun 			left -= res;
1076*4882a593Smuzhiyun 		}
1077*4882a593Smuzhiyun 	}
1078*4882a593Smuzhiyun }
1079*4882a593Smuzhiyun 
TEST_F(tls,mutliproc_even)1080*4882a593Smuzhiyun TEST_F(tls, mutliproc_even)
1081*4882a593Smuzhiyun {
1082*4882a593Smuzhiyun 	test_mutliproc(_metadata, self, false, 6, 6);
1083*4882a593Smuzhiyun }
1084*4882a593Smuzhiyun 
TEST_F(tls,mutliproc_readers)1085*4882a593Smuzhiyun TEST_F(tls, mutliproc_readers)
1086*4882a593Smuzhiyun {
1087*4882a593Smuzhiyun 	test_mutliproc(_metadata, self, false, 4, 12);
1088*4882a593Smuzhiyun }
1089*4882a593Smuzhiyun 
TEST_F(tls,mutliproc_writers)1090*4882a593Smuzhiyun TEST_F(tls, mutliproc_writers)
1091*4882a593Smuzhiyun {
1092*4882a593Smuzhiyun 	test_mutliproc(_metadata, self, false, 10, 2);
1093*4882a593Smuzhiyun }
1094*4882a593Smuzhiyun 
TEST_F(tls,mutliproc_sendpage_even)1095*4882a593Smuzhiyun TEST_F(tls, mutliproc_sendpage_even)
1096*4882a593Smuzhiyun {
1097*4882a593Smuzhiyun 	test_mutliproc(_metadata, self, true, 6, 6);
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun 
TEST_F(tls,mutliproc_sendpage_readers)1100*4882a593Smuzhiyun TEST_F(tls, mutliproc_sendpage_readers)
1101*4882a593Smuzhiyun {
1102*4882a593Smuzhiyun 	test_mutliproc(_metadata, self, true, 4, 12);
1103*4882a593Smuzhiyun }
1104*4882a593Smuzhiyun 
TEST_F(tls,mutliproc_sendpage_writers)1105*4882a593Smuzhiyun TEST_F(tls, mutliproc_sendpage_writers)
1106*4882a593Smuzhiyun {
1107*4882a593Smuzhiyun 	test_mutliproc(_metadata, self, true, 10, 2);
1108*4882a593Smuzhiyun }
1109*4882a593Smuzhiyun 
TEST_F(tls,control_msg)1110*4882a593Smuzhiyun TEST_F(tls, control_msg)
1111*4882a593Smuzhiyun {
1112*4882a593Smuzhiyun 	if (self->notls)
1113*4882a593Smuzhiyun 		return;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	char cbuf[CMSG_SPACE(sizeof(char))];
1116*4882a593Smuzhiyun 	char const *test_str = "test_read";
1117*4882a593Smuzhiyun 	int cmsg_len = sizeof(char);
1118*4882a593Smuzhiyun 	char record_type = 100;
1119*4882a593Smuzhiyun 	struct cmsghdr *cmsg;
1120*4882a593Smuzhiyun 	struct msghdr msg;
1121*4882a593Smuzhiyun 	int send_len = 10;
1122*4882a593Smuzhiyun 	struct iovec vec;
1123*4882a593Smuzhiyun 	char buf[10];
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 	vec.iov_base = (char *)test_str;
1126*4882a593Smuzhiyun 	vec.iov_len = 10;
1127*4882a593Smuzhiyun 	memset(&msg, 0, sizeof(struct msghdr));
1128*4882a593Smuzhiyun 	msg.msg_iov = &vec;
1129*4882a593Smuzhiyun 	msg.msg_iovlen = 1;
1130*4882a593Smuzhiyun 	msg.msg_control = cbuf;
1131*4882a593Smuzhiyun 	msg.msg_controllen = sizeof(cbuf);
1132*4882a593Smuzhiyun 	cmsg = CMSG_FIRSTHDR(&msg);
1133*4882a593Smuzhiyun 	cmsg->cmsg_level = SOL_TLS;
1134*4882a593Smuzhiyun 	/* test sending non-record types. */
1135*4882a593Smuzhiyun 	cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
1136*4882a593Smuzhiyun 	cmsg->cmsg_len = CMSG_LEN(cmsg_len);
1137*4882a593Smuzhiyun 	*CMSG_DATA(cmsg) = record_type;
1138*4882a593Smuzhiyun 	msg.msg_controllen = cmsg->cmsg_len;
1139*4882a593Smuzhiyun 
1140*4882a593Smuzhiyun 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
1141*4882a593Smuzhiyun 	/* Should fail because we didn't provide a control message */
1142*4882a593Smuzhiyun 	EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
1143*4882a593Smuzhiyun 
1144*4882a593Smuzhiyun 	vec.iov_base = buf;
1145*4882a593Smuzhiyun 	EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL | MSG_PEEK), send_len);
1146*4882a593Smuzhiyun 
1147*4882a593Smuzhiyun 	cmsg = CMSG_FIRSTHDR(&msg);
1148*4882a593Smuzhiyun 	EXPECT_NE(cmsg, NULL);
1149*4882a593Smuzhiyun 	EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
1150*4882a593Smuzhiyun 	EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
1151*4882a593Smuzhiyun 	record_type = *((unsigned char *)CMSG_DATA(cmsg));
1152*4882a593Smuzhiyun 	EXPECT_EQ(record_type, 100);
1153*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	/* Recv the message again without MSG_PEEK */
1156*4882a593Smuzhiyun 	record_type = 0;
1157*4882a593Smuzhiyun 	memset(buf, 0, sizeof(buf));
1158*4882a593Smuzhiyun 
1159*4882a593Smuzhiyun 	EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL), send_len);
1160*4882a593Smuzhiyun 	cmsg = CMSG_FIRSTHDR(&msg);
1161*4882a593Smuzhiyun 	EXPECT_NE(cmsg, NULL);
1162*4882a593Smuzhiyun 	EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
1163*4882a593Smuzhiyun 	EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
1164*4882a593Smuzhiyun 	record_type = *((unsigned char *)CMSG_DATA(cmsg));
1165*4882a593Smuzhiyun 	EXPECT_EQ(record_type, 100);
1166*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
1167*4882a593Smuzhiyun }
1168*4882a593Smuzhiyun 
TEST_F(tls,shutdown)1169*4882a593Smuzhiyun TEST_F(tls, shutdown)
1170*4882a593Smuzhiyun {
1171*4882a593Smuzhiyun 	char const *test_str = "test_read";
1172*4882a593Smuzhiyun 	int send_len = 10;
1173*4882a593Smuzhiyun 	char buf[10];
1174*4882a593Smuzhiyun 
1175*4882a593Smuzhiyun 	ASSERT_EQ(strlen(test_str) + 1, send_len);
1176*4882a593Smuzhiyun 
1177*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
1178*4882a593Smuzhiyun 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
1179*4882a593Smuzhiyun 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
1180*4882a593Smuzhiyun 
1181*4882a593Smuzhiyun 	shutdown(self->fd, SHUT_RDWR);
1182*4882a593Smuzhiyun 	shutdown(self->cfd, SHUT_RDWR);
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
TEST_F(tls,shutdown_unsent)1185*4882a593Smuzhiyun TEST_F(tls, shutdown_unsent)
1186*4882a593Smuzhiyun {
1187*4882a593Smuzhiyun 	char const *test_str = "test_read";
1188*4882a593Smuzhiyun 	int send_len = 10;
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 	shutdown(self->fd, SHUT_RDWR);
1193*4882a593Smuzhiyun 	shutdown(self->cfd, SHUT_RDWR);
1194*4882a593Smuzhiyun }
1195*4882a593Smuzhiyun 
TEST_F(tls,shutdown_reuse)1196*4882a593Smuzhiyun TEST_F(tls, shutdown_reuse)
1197*4882a593Smuzhiyun {
1198*4882a593Smuzhiyun 	struct sockaddr_in addr;
1199*4882a593Smuzhiyun 	int ret;
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun 	shutdown(self->fd, SHUT_RDWR);
1202*4882a593Smuzhiyun 	shutdown(self->cfd, SHUT_RDWR);
1203*4882a593Smuzhiyun 	close(self->cfd);
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun 	addr.sin_family = AF_INET;
1206*4882a593Smuzhiyun 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
1207*4882a593Smuzhiyun 	addr.sin_port = 0;
1208*4882a593Smuzhiyun 
1209*4882a593Smuzhiyun 	ret = bind(self->fd, &addr, sizeof(addr));
1210*4882a593Smuzhiyun 	EXPECT_EQ(ret, 0);
1211*4882a593Smuzhiyun 	ret = listen(self->fd, 10);
1212*4882a593Smuzhiyun 	EXPECT_EQ(ret, -1);
1213*4882a593Smuzhiyun 	EXPECT_EQ(errno, EINVAL);
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	ret = connect(self->fd, &addr, sizeof(addr));
1216*4882a593Smuzhiyun 	EXPECT_EQ(ret, -1);
1217*4882a593Smuzhiyun 	EXPECT_EQ(errno, EISCONN);
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun 
TEST(non_established)1220*4882a593Smuzhiyun TEST(non_established) {
1221*4882a593Smuzhiyun 	struct tls12_crypto_info_aes_gcm_256 tls12;
1222*4882a593Smuzhiyun 	struct sockaddr_in addr;
1223*4882a593Smuzhiyun 	int sfd, ret, fd;
1224*4882a593Smuzhiyun 	socklen_t len;
1225*4882a593Smuzhiyun 
1226*4882a593Smuzhiyun 	len = sizeof(addr);
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 	memset(&tls12, 0, sizeof(tls12));
1229*4882a593Smuzhiyun 	tls12.info.version = TLS_1_2_VERSION;
1230*4882a593Smuzhiyun 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
1231*4882a593Smuzhiyun 
1232*4882a593Smuzhiyun 	addr.sin_family = AF_INET;
1233*4882a593Smuzhiyun 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
1234*4882a593Smuzhiyun 	addr.sin_port = 0;
1235*4882a593Smuzhiyun 
1236*4882a593Smuzhiyun 	fd = socket(AF_INET, SOCK_STREAM, 0);
1237*4882a593Smuzhiyun 	sfd = socket(AF_INET, SOCK_STREAM, 0);
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun 	ret = bind(sfd, &addr, sizeof(addr));
1240*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1241*4882a593Smuzhiyun 	ret = listen(sfd, 10);
1242*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1243*4882a593Smuzhiyun 
1244*4882a593Smuzhiyun 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1245*4882a593Smuzhiyun 	EXPECT_EQ(ret, -1);
1246*4882a593Smuzhiyun 	/* TLS ULP not supported */
1247*4882a593Smuzhiyun 	if (errno == ENOENT)
1248*4882a593Smuzhiyun 		return;
1249*4882a593Smuzhiyun 	EXPECT_EQ(errno, ENOTCONN);
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	ret = setsockopt(sfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1252*4882a593Smuzhiyun 	EXPECT_EQ(ret, -1);
1253*4882a593Smuzhiyun 	EXPECT_EQ(errno, ENOTCONN);
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	ret = getsockname(sfd, &addr, &len);
1256*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	ret = connect(fd, &addr, sizeof(addr));
1259*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1260*4882a593Smuzhiyun 
1261*4882a593Smuzhiyun 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1262*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1265*4882a593Smuzhiyun 	EXPECT_EQ(ret, -1);
1266*4882a593Smuzhiyun 	EXPECT_EQ(errno, EEXIST);
1267*4882a593Smuzhiyun 
1268*4882a593Smuzhiyun 	close(fd);
1269*4882a593Smuzhiyun 	close(sfd);
1270*4882a593Smuzhiyun }
1271*4882a593Smuzhiyun 
TEST(keysizes)1272*4882a593Smuzhiyun TEST(keysizes) {
1273*4882a593Smuzhiyun 	struct tls12_crypto_info_aes_gcm_256 tls12;
1274*4882a593Smuzhiyun 	struct sockaddr_in addr;
1275*4882a593Smuzhiyun 	int sfd, ret, fd, cfd;
1276*4882a593Smuzhiyun 	socklen_t len;
1277*4882a593Smuzhiyun 	bool notls;
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 	notls = false;
1280*4882a593Smuzhiyun 	len = sizeof(addr);
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	memset(&tls12, 0, sizeof(tls12));
1283*4882a593Smuzhiyun 	tls12.info.version = TLS_1_2_VERSION;
1284*4882a593Smuzhiyun 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
1285*4882a593Smuzhiyun 
1286*4882a593Smuzhiyun 	addr.sin_family = AF_INET;
1287*4882a593Smuzhiyun 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
1288*4882a593Smuzhiyun 	addr.sin_port = 0;
1289*4882a593Smuzhiyun 
1290*4882a593Smuzhiyun 	fd = socket(AF_INET, SOCK_STREAM, 0);
1291*4882a593Smuzhiyun 	sfd = socket(AF_INET, SOCK_STREAM, 0);
1292*4882a593Smuzhiyun 
1293*4882a593Smuzhiyun 	ret = bind(sfd, &addr, sizeof(addr));
1294*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1295*4882a593Smuzhiyun 	ret = listen(sfd, 10);
1296*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1297*4882a593Smuzhiyun 
1298*4882a593Smuzhiyun 	ret = getsockname(sfd, &addr, &len);
1299*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1300*4882a593Smuzhiyun 
1301*4882a593Smuzhiyun 	ret = connect(fd, &addr, sizeof(addr));
1302*4882a593Smuzhiyun 	ASSERT_EQ(ret, 0);
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1305*4882a593Smuzhiyun 	if (ret != 0) {
1306*4882a593Smuzhiyun 		notls = true;
1307*4882a593Smuzhiyun 		printf("Failure setting TCP_ULP, testing without tls\n");
1308*4882a593Smuzhiyun 	}
1309*4882a593Smuzhiyun 
1310*4882a593Smuzhiyun 	if (!notls) {
1311*4882a593Smuzhiyun 		ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
1312*4882a593Smuzhiyun 				 sizeof(tls12));
1313*4882a593Smuzhiyun 		EXPECT_EQ(ret, 0);
1314*4882a593Smuzhiyun 	}
1315*4882a593Smuzhiyun 
1316*4882a593Smuzhiyun 	cfd = accept(sfd, &addr, &len);
1317*4882a593Smuzhiyun 	ASSERT_GE(cfd, 0);
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun 	if (!notls) {
1320*4882a593Smuzhiyun 		ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls",
1321*4882a593Smuzhiyun 				 sizeof("tls"));
1322*4882a593Smuzhiyun 		EXPECT_EQ(ret, 0);
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun 		ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
1325*4882a593Smuzhiyun 				 sizeof(tls12));
1326*4882a593Smuzhiyun 		EXPECT_EQ(ret, 0);
1327*4882a593Smuzhiyun 	}
1328*4882a593Smuzhiyun 
1329*4882a593Smuzhiyun 	close(sfd);
1330*4882a593Smuzhiyun 	close(fd);
1331*4882a593Smuzhiyun 	close(cfd);
1332*4882a593Smuzhiyun }
1333*4882a593Smuzhiyun 
1334*4882a593Smuzhiyun TEST_HARNESS_MAIN
1335