xref: /linux/tools/testing/selftests/net/tls.c (revision cd114d2e81f632104b3f1e804104060b97337410)
17f657d5bSDave Watson // SPDX-License-Identifier: GPL-2.0
27f657d5bSDave Watson 
37f657d5bSDave Watson #define _GNU_SOURCE
47f657d5bSDave Watson 
57f657d5bSDave Watson #include <arpa/inet.h>
67f657d5bSDave Watson #include <errno.h>
77f657d5bSDave Watson #include <error.h>
87f657d5bSDave Watson #include <fcntl.h>
97f657d5bSDave Watson #include <poll.h>
107f657d5bSDave Watson #include <stdio.h>
117f657d5bSDave Watson #include <stdlib.h>
127f657d5bSDave Watson #include <unistd.h>
137f657d5bSDave Watson 
147f657d5bSDave Watson #include <linux/tls.h>
157f657d5bSDave Watson #include <linux/tcp.h>
167f657d5bSDave Watson #include <linux/socket.h>
177f657d5bSDave Watson 
187f657d5bSDave Watson #include <sys/types.h>
197f657d5bSDave Watson #include <sys/sendfile.h>
207f657d5bSDave Watson #include <sys/socket.h>
217f657d5bSDave Watson #include <sys/stat.h>
227f657d5bSDave Watson 
237f657d5bSDave Watson #include "../kselftest_harness.h"
247f657d5bSDave Watson 
257f657d5bSDave Watson #define TLS_PAYLOAD_MAX_LEN 16384
267f657d5bSDave Watson #define SOL_TLS 282
277f657d5bSDave Watson 
28cf32526cSJakub Kicinski #ifndef ENOTSUPP
29cf32526cSJakub Kicinski #define ENOTSUPP 524
30cf32526cSJakub Kicinski #endif
31cf32526cSJakub Kicinski 
32cf32526cSJakub Kicinski FIXTURE(tls_basic)
33cf32526cSJakub Kicinski {
34cf32526cSJakub Kicinski 	int fd, cfd;
35cf32526cSJakub Kicinski 	bool notls;
36cf32526cSJakub Kicinski };
37cf32526cSJakub Kicinski 
38cf32526cSJakub Kicinski FIXTURE_SETUP(tls_basic)
39cf32526cSJakub Kicinski {
40cf32526cSJakub Kicinski 	struct sockaddr_in addr;
41cf32526cSJakub Kicinski 	socklen_t len;
42cf32526cSJakub Kicinski 	int sfd, ret;
43cf32526cSJakub Kicinski 
44cf32526cSJakub Kicinski 	self->notls = false;
45cf32526cSJakub Kicinski 	len = sizeof(addr);
46cf32526cSJakub Kicinski 
47cf32526cSJakub Kicinski 	addr.sin_family = AF_INET;
48cf32526cSJakub Kicinski 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
49cf32526cSJakub Kicinski 	addr.sin_port = 0;
50cf32526cSJakub Kicinski 
51cf32526cSJakub Kicinski 	self->fd = socket(AF_INET, SOCK_STREAM, 0);
52cf32526cSJakub Kicinski 	sfd = socket(AF_INET, SOCK_STREAM, 0);
53cf32526cSJakub Kicinski 
54cf32526cSJakub Kicinski 	ret = bind(sfd, &addr, sizeof(addr));
55cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
56cf32526cSJakub Kicinski 	ret = listen(sfd, 10);
57cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
58cf32526cSJakub Kicinski 
59cf32526cSJakub Kicinski 	ret = getsockname(sfd, &addr, &len);
60cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
61cf32526cSJakub Kicinski 
62cf32526cSJakub Kicinski 	ret = connect(self->fd, &addr, sizeof(addr));
63cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
64cf32526cSJakub Kicinski 
65cf32526cSJakub Kicinski 	self->cfd = accept(sfd, &addr, &len);
66cf32526cSJakub Kicinski 	ASSERT_GE(self->cfd, 0);
67cf32526cSJakub Kicinski 
68cf32526cSJakub Kicinski 	close(sfd);
69cf32526cSJakub Kicinski 
70cf32526cSJakub Kicinski 	ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
71cf32526cSJakub Kicinski 	if (ret != 0) {
72e29903c4SJakub Kicinski 		ASSERT_EQ(errno, ENOENT);
73cf32526cSJakub Kicinski 		self->notls = true;
74cf32526cSJakub Kicinski 		printf("Failure setting TCP_ULP, testing without tls\n");
75cf32526cSJakub Kicinski 		return;
76cf32526cSJakub Kicinski 	}
77cf32526cSJakub Kicinski 
78cf32526cSJakub Kicinski 	ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
79cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
80cf32526cSJakub Kicinski }
81cf32526cSJakub Kicinski 
82cf32526cSJakub Kicinski FIXTURE_TEARDOWN(tls_basic)
83cf32526cSJakub Kicinski {
84cf32526cSJakub Kicinski 	close(self->fd);
85cf32526cSJakub Kicinski 	close(self->cfd);
86cf32526cSJakub Kicinski }
87cf32526cSJakub Kicinski 
88cf32526cSJakub Kicinski /* Send some data through with ULP but no keys */
89cf32526cSJakub Kicinski TEST_F(tls_basic, base_base)
90cf32526cSJakub Kicinski {
91cf32526cSJakub Kicinski 	char const *test_str = "test_read";
92cf32526cSJakub Kicinski 	int send_len = 10;
93cf32526cSJakub Kicinski 	char buf[10];
94cf32526cSJakub Kicinski 
95cf32526cSJakub Kicinski 	ASSERT_EQ(strlen(test_str) + 1, send_len);
96cf32526cSJakub Kicinski 
97cf32526cSJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
98cf32526cSJakub Kicinski 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
99cf32526cSJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
100cf32526cSJakub Kicinski };
101cf32526cSJakub Kicinski 
1027f657d5bSDave Watson FIXTURE(tls)
1037f657d5bSDave Watson {
1047f657d5bSDave Watson 	int fd, cfd;
1057f657d5bSDave Watson 	bool notls;
1067f657d5bSDave Watson };
1077f657d5bSDave Watson 
1087f657d5bSDave Watson FIXTURE_SETUP(tls)
1097f657d5bSDave Watson {
1107f657d5bSDave Watson 	struct tls12_crypto_info_aes_gcm_128 tls12;
1117f657d5bSDave Watson 	struct sockaddr_in addr;
1127f657d5bSDave Watson 	socklen_t len;
1137f657d5bSDave Watson 	int sfd, ret;
1147f657d5bSDave Watson 
1157f657d5bSDave Watson 	self->notls = false;
1167f657d5bSDave Watson 	len = sizeof(addr);
1177f657d5bSDave Watson 
1187f657d5bSDave Watson 	memset(&tls12, 0, sizeof(tls12));
1198debd67eSDave Watson 	tls12.info.version = TLS_1_3_VERSION;
1207f657d5bSDave Watson 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
1217f657d5bSDave Watson 
1227f657d5bSDave Watson 	addr.sin_family = AF_INET;
1237f657d5bSDave Watson 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
1247f657d5bSDave Watson 	addr.sin_port = 0;
1257f657d5bSDave Watson 
1267f657d5bSDave Watson 	self->fd = socket(AF_INET, SOCK_STREAM, 0);
1277f657d5bSDave Watson 	sfd = socket(AF_INET, SOCK_STREAM, 0);
1287f657d5bSDave Watson 
1297f657d5bSDave Watson 	ret = bind(sfd, &addr, sizeof(addr));
1307f657d5bSDave Watson 	ASSERT_EQ(ret, 0);
1317f657d5bSDave Watson 	ret = listen(sfd, 10);
1327f657d5bSDave Watson 	ASSERT_EQ(ret, 0);
1337f657d5bSDave Watson 
1347f657d5bSDave Watson 	ret = getsockname(sfd, &addr, &len);
1357f657d5bSDave Watson 	ASSERT_EQ(ret, 0);
1367f657d5bSDave Watson 
1377f657d5bSDave Watson 	ret = connect(self->fd, &addr, sizeof(addr));
1387f657d5bSDave Watson 	ASSERT_EQ(ret, 0);
1397f657d5bSDave Watson 
1407f657d5bSDave Watson 	ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1417f657d5bSDave Watson 	if (ret != 0) {
1427f657d5bSDave Watson 		self->notls = true;
1437f657d5bSDave Watson 		printf("Failure setting TCP_ULP, testing without tls\n");
1447f657d5bSDave Watson 	}
1457f657d5bSDave Watson 
1467f657d5bSDave Watson 	if (!self->notls) {
1477f657d5bSDave Watson 		ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12,
1487f657d5bSDave Watson 				 sizeof(tls12));
1497f657d5bSDave Watson 		ASSERT_EQ(ret, 0);
1507f657d5bSDave Watson 	}
1517f657d5bSDave Watson 
1527f657d5bSDave Watson 	self->cfd = accept(sfd, &addr, &len);
1537f657d5bSDave Watson 	ASSERT_GE(self->cfd, 0);
1547f657d5bSDave Watson 
1557f657d5bSDave Watson 	if (!self->notls) {
1567f657d5bSDave Watson 		ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls",
1577f657d5bSDave Watson 				 sizeof("tls"));
1587f657d5bSDave Watson 		ASSERT_EQ(ret, 0);
1597f657d5bSDave Watson 
1607f657d5bSDave Watson 		ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12,
1617f657d5bSDave Watson 				 sizeof(tls12));
1627f657d5bSDave Watson 		ASSERT_EQ(ret, 0);
1637f657d5bSDave Watson 	}
1647f657d5bSDave Watson 
1657f657d5bSDave Watson 	close(sfd);
1667f657d5bSDave Watson }
1677f657d5bSDave Watson 
1687f657d5bSDave Watson FIXTURE_TEARDOWN(tls)
1697f657d5bSDave Watson {
1707f657d5bSDave Watson 	close(self->fd);
1717f657d5bSDave Watson 	close(self->cfd);
1727f657d5bSDave Watson }
1737f657d5bSDave Watson 
1747f657d5bSDave Watson TEST_F(tls, sendfile)
1757f657d5bSDave Watson {
1767f657d5bSDave Watson 	int filefd = open("/proc/self/exe", O_RDONLY);
1777f657d5bSDave Watson 	struct stat st;
1787f657d5bSDave Watson 
1797f657d5bSDave Watson 	EXPECT_GE(filefd, 0);
1807f657d5bSDave Watson 	fstat(filefd, &st);
1817f657d5bSDave Watson 	EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
1827f657d5bSDave Watson }
1837f657d5bSDave Watson 
1847f657d5bSDave Watson TEST_F(tls, send_then_sendfile)
1857f657d5bSDave Watson {
1867f657d5bSDave Watson 	int filefd = open("/proc/self/exe", O_RDONLY);
1877f657d5bSDave Watson 	char const *test_str = "test_send";
1887f657d5bSDave Watson 	int to_send = strlen(test_str) + 1;
1897f657d5bSDave Watson 	char recv_buf[10];
1907f657d5bSDave Watson 	struct stat st;
1917f657d5bSDave Watson 	char *buf;
1927f657d5bSDave Watson 
1937f657d5bSDave Watson 	EXPECT_GE(filefd, 0);
1947f657d5bSDave Watson 	fstat(filefd, &st);
1957f657d5bSDave Watson 	buf = (char *)malloc(st.st_size);
1967f657d5bSDave Watson 
1977f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, to_send, 0), to_send);
1980185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, recv_buf, to_send, MSG_WAITALL), to_send);
1997f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, recv_buf, to_send), 0);
2007f657d5bSDave Watson 
2017f657d5bSDave Watson 	EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
2020185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, st.st_size, MSG_WAITALL), st.st_size);
2037f657d5bSDave Watson }
2047f657d5bSDave Watson 
2057f657d5bSDave Watson TEST_F(tls, recv_max)
2067f657d5bSDave Watson {
2077f657d5bSDave Watson 	unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
2087f657d5bSDave Watson 	char recv_mem[TLS_PAYLOAD_MAX_LEN];
2097f657d5bSDave Watson 	char buf[TLS_PAYLOAD_MAX_LEN];
2107f657d5bSDave Watson 
2117f657d5bSDave Watson 	EXPECT_GE(send(self->fd, buf, send_len, 0), 0);
2127f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
2137f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0);
2147f657d5bSDave Watson }
2157f657d5bSDave Watson 
2167f657d5bSDave Watson TEST_F(tls, recv_small)
2177f657d5bSDave Watson {
2187f657d5bSDave Watson 	char const *test_str = "test_read";
2197f657d5bSDave Watson 	int send_len = 10;
2207f657d5bSDave Watson 	char buf[10];
2217f657d5bSDave Watson 
2227f657d5bSDave Watson 	send_len = strlen(test_str) + 1;
2237f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
2247f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
2257f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
2267f657d5bSDave Watson }
2277f657d5bSDave Watson 
2287f657d5bSDave Watson TEST_F(tls, msg_more)
2297f657d5bSDave Watson {
2307f657d5bSDave Watson 	char const *test_str = "test_read";
2317f657d5bSDave Watson 	int send_len = 10;
2327f657d5bSDave Watson 	char buf[10 * 2];
2337f657d5bSDave Watson 
2347f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
2357f657d5bSDave Watson 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
2367f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
2370185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len * 2, MSG_WAITALL),
2387f657d5bSDave Watson 		  send_len * 2);
2397f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
2407f657d5bSDave Watson }
2417f657d5bSDave Watson 
2428051bb7fSJakub Kicinski TEST_F(tls, msg_more_unsent)
2438051bb7fSJakub Kicinski {
2448051bb7fSJakub Kicinski 	char const *test_str = "test_read";
2458051bb7fSJakub Kicinski 	int send_len = 10;
2468051bb7fSJakub Kicinski 	char buf[10];
2478051bb7fSJakub Kicinski 
2488051bb7fSJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
2498051bb7fSJakub Kicinski 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
2508051bb7fSJakub Kicinski }
2518051bb7fSJakub Kicinski 
2527f657d5bSDave Watson TEST_F(tls, sendmsg_single)
2537f657d5bSDave Watson {
2547f657d5bSDave Watson 	struct msghdr msg;
2557f657d5bSDave Watson 
2567f657d5bSDave Watson 	char const *test_str = "test_sendmsg";
2577f657d5bSDave Watson 	size_t send_len = 13;
2587f657d5bSDave Watson 	struct iovec vec;
2597f657d5bSDave Watson 	char buf[13];
2607f657d5bSDave Watson 
2617f657d5bSDave Watson 	vec.iov_base = (char *)test_str;
2627f657d5bSDave Watson 	vec.iov_len = send_len;
2637f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
2647f657d5bSDave Watson 	msg.msg_iov = &vec;
2657f657d5bSDave Watson 	msg.msg_iovlen = 1;
2667f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
2670185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_WAITALL), send_len);
2687f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
2697f657d5bSDave Watson }
2707f657d5bSDave Watson 
2717f657d5bSDave Watson TEST_F(tls, sendmsg_large)
2727f657d5bSDave Watson {
2737f657d5bSDave Watson 	void *mem = malloc(16384);
2747f657d5bSDave Watson 	size_t send_len = 16384;
2757f657d5bSDave Watson 	size_t sends = 128;
2767f657d5bSDave Watson 	struct msghdr msg;
2777f657d5bSDave Watson 	size_t recvs = 0;
2787f657d5bSDave Watson 	size_t sent = 0;
2797f657d5bSDave Watson 
2807f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
2817f657d5bSDave Watson 	while (sent++ < sends) {
2827f657d5bSDave Watson 		struct iovec vec = { (void *)mem, send_len };
2837f657d5bSDave Watson 
2847f657d5bSDave Watson 		msg.msg_iov = &vec;
2857f657d5bSDave Watson 		msg.msg_iovlen = 1;
2867f657d5bSDave Watson 		EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len);
2877f657d5bSDave Watson 	}
2887f657d5bSDave Watson 
2897f657d5bSDave Watson 	while (recvs++ < sends)
2907f657d5bSDave Watson 		EXPECT_NE(recv(self->fd, mem, send_len, 0), -1);
2917f657d5bSDave Watson 
2927f657d5bSDave Watson 	free(mem);
2937f657d5bSDave Watson }
2947f657d5bSDave Watson 
2957f657d5bSDave Watson TEST_F(tls, sendmsg_multiple)
2967f657d5bSDave Watson {
2977f657d5bSDave Watson 	char const *test_str = "test_sendmsg_multiple";
2987f657d5bSDave Watson 	struct iovec vec[5];
2997f657d5bSDave Watson 	char *test_strs[5];
3007f657d5bSDave Watson 	struct msghdr msg;
3017f657d5bSDave Watson 	int total_len = 0;
3027f657d5bSDave Watson 	int len_cmp = 0;
3037f657d5bSDave Watson 	int iov_len = 5;
3047f657d5bSDave Watson 	char *buf;
3057f657d5bSDave Watson 	int i;
3067f657d5bSDave Watson 
3077f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
3087f657d5bSDave Watson 	for (i = 0; i < iov_len; i++) {
3097f657d5bSDave Watson 		test_strs[i] = (char *)malloc(strlen(test_str) + 1);
3107f657d5bSDave Watson 		snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
3117f657d5bSDave Watson 		vec[i].iov_base = (void *)test_strs[i];
3127f657d5bSDave Watson 		vec[i].iov_len = strlen(test_strs[i]) + 1;
3137f657d5bSDave Watson 		total_len += vec[i].iov_len;
3147f657d5bSDave Watson 	}
3157f657d5bSDave Watson 	msg.msg_iov = vec;
3167f657d5bSDave Watson 	msg.msg_iovlen = iov_len;
3177f657d5bSDave Watson 
3187f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len);
3197f657d5bSDave Watson 	buf = malloc(total_len);
3207f657d5bSDave Watson 	EXPECT_NE(recv(self->fd, buf, total_len, 0), -1);
3217f657d5bSDave Watson 	for (i = 0; i < iov_len; i++) {
3227f657d5bSDave Watson 		EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp,
3237f657d5bSDave Watson 				 strlen(test_strs[i])),
3247f657d5bSDave Watson 			  0);
3257f657d5bSDave Watson 		len_cmp += strlen(buf + len_cmp) + 1;
3267f657d5bSDave Watson 	}
3277f657d5bSDave Watson 	for (i = 0; i < iov_len; i++)
3287f657d5bSDave Watson 		free(test_strs[i]);
3297f657d5bSDave Watson 	free(buf);
3307f657d5bSDave Watson }
3317f657d5bSDave Watson 
3327f657d5bSDave Watson TEST_F(tls, sendmsg_multiple_stress)
3337f657d5bSDave Watson {
3347f657d5bSDave Watson 	char const *test_str = "abcdefghijklmno";
3357f657d5bSDave Watson 	struct iovec vec[1024];
3367f657d5bSDave Watson 	char *test_strs[1024];
3377f657d5bSDave Watson 	int iov_len = 1024;
3387f657d5bSDave Watson 	int total_len = 0;
3397f657d5bSDave Watson 	char buf[1 << 14];
3407f657d5bSDave Watson 	struct msghdr msg;
3417f657d5bSDave Watson 	int len_cmp = 0;
3427f657d5bSDave Watson 	int i;
3437f657d5bSDave Watson 
3447f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
3457f657d5bSDave Watson 	for (i = 0; i < iov_len; i++) {
3467f657d5bSDave Watson 		test_strs[i] = (char *)malloc(strlen(test_str) + 1);
3477f657d5bSDave Watson 		snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
3487f657d5bSDave Watson 		vec[i].iov_base = (void *)test_strs[i];
3497f657d5bSDave Watson 		vec[i].iov_len = strlen(test_strs[i]) + 1;
3507f657d5bSDave Watson 		total_len += vec[i].iov_len;
3517f657d5bSDave Watson 	}
3527f657d5bSDave Watson 	msg.msg_iov = vec;
3537f657d5bSDave Watson 	msg.msg_iovlen = iov_len;
3547f657d5bSDave Watson 
3557f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len);
3567f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1);
3577f657d5bSDave Watson 
3587f657d5bSDave Watson 	for (i = 0; i < iov_len; i++)
3597f657d5bSDave Watson 		len_cmp += strlen(buf + len_cmp) + 1;
3607f657d5bSDave Watson 
3617f657d5bSDave Watson 	for (i = 0; i < iov_len; i++)
3627f657d5bSDave Watson 		free(test_strs[i]);
3637f657d5bSDave Watson }
3647f657d5bSDave Watson 
3657f657d5bSDave Watson TEST_F(tls, splice_from_pipe)
3667f657d5bSDave Watson {
3677f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
3687f657d5bSDave Watson 	char mem_send[TLS_PAYLOAD_MAX_LEN];
3697f657d5bSDave Watson 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
3707f657d5bSDave Watson 	int p[2];
3717f657d5bSDave Watson 
3727f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
3737f657d5bSDave Watson 	EXPECT_GE(write(p[1], mem_send, send_len), 0);
3747f657d5bSDave Watson 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), 0);
3750ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
3767f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
3777f657d5bSDave Watson }
3787f657d5bSDave Watson 
3797f657d5bSDave Watson TEST_F(tls, splice_from_pipe2)
3807f657d5bSDave Watson {
3817f657d5bSDave Watson 	int send_len = 16000;
3827f657d5bSDave Watson 	char mem_send[16000];
3837f657d5bSDave Watson 	char mem_recv[16000];
3847f657d5bSDave Watson 	int p2[2];
3857f657d5bSDave Watson 	int p[2];
3867f657d5bSDave Watson 
3877f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
3887f657d5bSDave Watson 	ASSERT_GE(pipe(p2), 0);
3897f657d5bSDave Watson 	EXPECT_GE(write(p[1], mem_send, 8000), 0);
3907f657d5bSDave Watson 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, 8000, 0), 0);
3917f657d5bSDave Watson 	EXPECT_GE(write(p2[1], mem_send + 8000, 8000), 0);
3927f657d5bSDave Watson 	EXPECT_GE(splice(p2[0], NULL, self->fd, NULL, 8000, 0), 0);
3930185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
3947f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
3957f657d5bSDave Watson }
3967f657d5bSDave Watson 
3977f657d5bSDave Watson TEST_F(tls, send_and_splice)
3987f657d5bSDave Watson {
3997f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
4007f657d5bSDave Watson 	char mem_send[TLS_PAYLOAD_MAX_LEN];
4017f657d5bSDave Watson 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
4027f657d5bSDave Watson 	char const *test_str = "test_read";
4037f657d5bSDave Watson 	int send_len2 = 10;
4047f657d5bSDave Watson 	char buf[10];
4057f657d5bSDave Watson 	int p[2];
4067f657d5bSDave Watson 
4077f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
4087f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len2, 0), send_len2);
4090ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len2, MSG_WAITALL), send_len2);
4107f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len2), 0);
4117f657d5bSDave Watson 
4127f657d5bSDave Watson 	EXPECT_GE(write(p[1], mem_send, send_len), send_len);
4137f657d5bSDave Watson 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), send_len);
4147f657d5bSDave Watson 
4150ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
4167f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
4177f657d5bSDave Watson }
4187f657d5bSDave Watson 
4197f657d5bSDave Watson TEST_F(tls, splice_to_pipe)
4207f657d5bSDave Watson {
4217f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
4227f657d5bSDave Watson 	char mem_send[TLS_PAYLOAD_MAX_LEN];
4237f657d5bSDave Watson 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
4247f657d5bSDave Watson 	int p[2];
4257f657d5bSDave Watson 
4267f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
4277f657d5bSDave Watson 	EXPECT_GE(send(self->fd, mem_send, send_len, 0), 0);
4287f657d5bSDave Watson 	EXPECT_GE(splice(self->cfd, NULL, p[1], NULL, send_len, 0), 0);
4297f657d5bSDave Watson 	EXPECT_GE(read(p[0], mem_recv, send_len), 0);
4307f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
4317f657d5bSDave Watson }
4327f657d5bSDave Watson 
4337f657d5bSDave Watson TEST_F(tls, recvmsg_single)
4347f657d5bSDave Watson {
4357f657d5bSDave Watson 	char const *test_str = "test_recvmsg_single";
4367f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
4377f657d5bSDave Watson 	char buf[20];
4387f657d5bSDave Watson 	struct msghdr hdr;
4397f657d5bSDave Watson 	struct iovec vec;
4407f657d5bSDave Watson 
4417f657d5bSDave Watson 	memset(&hdr, 0, sizeof(hdr));
4427f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
4437f657d5bSDave Watson 	vec.iov_base = (char *)buf;
4447f657d5bSDave Watson 	vec.iov_len = send_len;
4457f657d5bSDave Watson 	hdr.msg_iovlen = 1;
4467f657d5bSDave Watson 	hdr.msg_iov = &vec;
4477f657d5bSDave Watson 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
4487f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
4497f657d5bSDave Watson }
4507f657d5bSDave Watson 
4517f657d5bSDave Watson TEST_F(tls, recvmsg_single_max)
4527f657d5bSDave Watson {
4537f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
4547f657d5bSDave Watson 	char send_mem[TLS_PAYLOAD_MAX_LEN];
4557f657d5bSDave Watson 	char recv_mem[TLS_PAYLOAD_MAX_LEN];
4567f657d5bSDave Watson 	struct iovec vec;
4577f657d5bSDave Watson 	struct msghdr hdr;
4587f657d5bSDave Watson 
4597f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, send_mem, send_len, 0), send_len);
4607f657d5bSDave Watson 	vec.iov_base = (char *)recv_mem;
4617f657d5bSDave Watson 	vec.iov_len = TLS_PAYLOAD_MAX_LEN;
4627f657d5bSDave Watson 
4637f657d5bSDave Watson 	hdr.msg_iovlen = 1;
4647f657d5bSDave Watson 	hdr.msg_iov = &vec;
4657f657d5bSDave Watson 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
4667f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
4677f657d5bSDave Watson }
4687f657d5bSDave Watson 
4697f657d5bSDave Watson TEST_F(tls, recvmsg_multiple)
4707f657d5bSDave Watson {
4717f657d5bSDave Watson 	unsigned int msg_iovlen = 1024;
4727f657d5bSDave Watson 	unsigned int len_compared = 0;
4737f657d5bSDave Watson 	struct iovec vec[1024];
4747f657d5bSDave Watson 	char *iov_base[1024];
4757f657d5bSDave Watson 	unsigned int iov_len = 16;
4767f657d5bSDave Watson 	int send_len = 1 << 14;
4777f657d5bSDave Watson 	char buf[1 << 14];
4787f657d5bSDave Watson 	struct msghdr hdr;
4797f657d5bSDave Watson 	int i;
4807f657d5bSDave Watson 
4817f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, buf, send_len, 0), send_len);
4827f657d5bSDave Watson 	for (i = 0; i < msg_iovlen; i++) {
4837f657d5bSDave Watson 		iov_base[i] = (char *)malloc(iov_len);
4847f657d5bSDave Watson 		vec[i].iov_base = iov_base[i];
4857f657d5bSDave Watson 		vec[i].iov_len = iov_len;
4867f657d5bSDave Watson 	}
4877f657d5bSDave Watson 
4887f657d5bSDave Watson 	hdr.msg_iovlen = msg_iovlen;
4897f657d5bSDave Watson 	hdr.msg_iov = vec;
4907f657d5bSDave Watson 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
4917f657d5bSDave Watson 	for (i = 0; i < msg_iovlen; i++)
4927f657d5bSDave Watson 		len_compared += iov_len;
4937f657d5bSDave Watson 
4947f657d5bSDave Watson 	for (i = 0; i < msg_iovlen; i++)
4957f657d5bSDave Watson 		free(iov_base[i]);
4967f657d5bSDave Watson }
4977f657d5bSDave Watson 
4987f657d5bSDave Watson TEST_F(tls, single_send_multiple_recv)
4997f657d5bSDave Watson {
5007f657d5bSDave Watson 	unsigned int total_len = TLS_PAYLOAD_MAX_LEN * 2;
5017f657d5bSDave Watson 	unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
5027f657d5bSDave Watson 	char send_mem[TLS_PAYLOAD_MAX_LEN * 2];
5037f657d5bSDave Watson 	char recv_mem[TLS_PAYLOAD_MAX_LEN * 2];
5047f657d5bSDave Watson 
5057f657d5bSDave Watson 	EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
5067f657d5bSDave Watson 	memset(recv_mem, 0, total_len);
5077f657d5bSDave Watson 
5087f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
5097f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, recv_mem + send_len, send_len, 0), -1);
5107f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
5117f657d5bSDave Watson }
5127f657d5bSDave Watson 
5137f657d5bSDave Watson TEST_F(tls, multiple_send_single_recv)
5147f657d5bSDave Watson {
5157f657d5bSDave Watson 	unsigned int total_len = 2 * 10;
5167f657d5bSDave Watson 	unsigned int send_len = 10;
5177f657d5bSDave Watson 	char recv_mem[2 * 10];
5187f657d5bSDave Watson 	char send_mem[10];
5197f657d5bSDave Watson 
5207f657d5bSDave Watson 	EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
5217f657d5bSDave Watson 	EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
5227f657d5bSDave Watson 	memset(recv_mem, 0, total_len);
5230185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, recv_mem, total_len, MSG_WAITALL), total_len);
5247f657d5bSDave Watson 
5257f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
5267f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0);
5277f657d5bSDave Watson }
5287f657d5bSDave Watson 
529043556d0SJakub Kicinski TEST_F(tls, single_send_multiple_recv_non_align)
530043556d0SJakub Kicinski {
531043556d0SJakub Kicinski 	const unsigned int total_len = 15;
532043556d0SJakub Kicinski 	const unsigned int recv_len = 10;
533043556d0SJakub Kicinski 	char recv_mem[recv_len * 2];
534043556d0SJakub Kicinski 	char send_mem[total_len];
535043556d0SJakub Kicinski 
536043556d0SJakub Kicinski 	EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
537043556d0SJakub Kicinski 	memset(recv_mem, 0, total_len);
538043556d0SJakub Kicinski 
539043556d0SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, recv_len, 0), recv_len);
540043556d0SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem + recv_len, recv_len, 0), 5);
541043556d0SJakub Kicinski 	EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
542043556d0SJakub Kicinski }
543043556d0SJakub Kicinski 
5447f657d5bSDave Watson TEST_F(tls, recv_partial)
5457f657d5bSDave Watson {
5467f657d5bSDave Watson 	char const *test_str = "test_read_partial";
5477f657d5bSDave Watson 	char const *test_str_first = "test_read";
5487f657d5bSDave Watson 	char const *test_str_second = "_partial";
5497f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
5507f657d5bSDave Watson 	char recv_mem[18];
5517f657d5bSDave Watson 
5527f657d5bSDave Watson 	memset(recv_mem, 0, sizeof(recv_mem));
5537f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
554cea3bfb3SVakul Garg 	EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_first),
555cea3bfb3SVakul Garg 		       MSG_WAITALL), -1);
5567f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str_first, recv_mem, strlen(test_str_first)), 0);
5577f657d5bSDave Watson 	memset(recv_mem, 0, sizeof(recv_mem));
558cea3bfb3SVakul Garg 	EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_second),
559cea3bfb3SVakul Garg 		       MSG_WAITALL), -1);
5607f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str_second, recv_mem, strlen(test_str_second)),
5617f657d5bSDave Watson 		  0);
5627f657d5bSDave Watson }
5637f657d5bSDave Watson 
5647f657d5bSDave Watson TEST_F(tls, recv_nonblock)
5657f657d5bSDave Watson {
5667f657d5bSDave Watson 	char buf[4096];
5677f657d5bSDave Watson 	bool err;
5687f657d5bSDave Watson 
5697f657d5bSDave Watson 	EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_DONTWAIT), -1);
5707f657d5bSDave Watson 	err = (errno == EAGAIN || errno == EWOULDBLOCK);
5717f657d5bSDave Watson 	EXPECT_EQ(err, true);
5727f657d5bSDave Watson }
5737f657d5bSDave Watson 
5747f657d5bSDave Watson TEST_F(tls, recv_peek)
5757f657d5bSDave Watson {
5767f657d5bSDave Watson 	char const *test_str = "test_read_peek";
5777f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
5787f657d5bSDave Watson 	char buf[15];
5797f657d5bSDave Watson 
5807f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
5817f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
5827f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
5837f657d5bSDave Watson 	memset(buf, 0, sizeof(buf));
5847f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
5857f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
5867f657d5bSDave Watson }
5877f657d5bSDave Watson 
5887f657d5bSDave Watson TEST_F(tls, recv_peek_multiple)
5897f657d5bSDave Watson {
5907f657d5bSDave Watson 	char const *test_str = "test_read_peek";
5917f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
5927f657d5bSDave Watson 	unsigned int num_peeks = 100;
5937f657d5bSDave Watson 	char buf[15];
5947f657d5bSDave Watson 	int i;
5957f657d5bSDave Watson 
5967f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
5977f657d5bSDave Watson 	for (i = 0; i < num_peeks; i++) {
5987f657d5bSDave Watson 		EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
5997f657d5bSDave Watson 		EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
6007f657d5bSDave Watson 		memset(buf, 0, sizeof(buf));
6017f657d5bSDave Watson 	}
6027f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
6037f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
6047f657d5bSDave Watson }
6057f657d5bSDave Watson 
60650c6b58aSDaniel Borkmann TEST_F(tls, recv_peek_multiple_records)
60750c6b58aSDaniel Borkmann {
60850c6b58aSDaniel Borkmann 	char const *test_str = "test_read_peek_mult_recs";
60950c6b58aSDaniel Borkmann 	char const *test_str_first = "test_read_peek";
61050c6b58aSDaniel Borkmann 	char const *test_str_second = "_mult_recs";
61150c6b58aSDaniel Borkmann 	int len;
61250c6b58aSDaniel Borkmann 	char buf[64];
61350c6b58aSDaniel Borkmann 
61450c6b58aSDaniel Borkmann 	len = strlen(test_str_first);
61550c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
61650c6b58aSDaniel Borkmann 
61750c6b58aSDaniel Borkmann 	len = strlen(test_str_second) + 1;
61850c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
61950c6b58aSDaniel Borkmann 
6200ed3015cSVakul Garg 	len = strlen(test_str_first);
62150c6b58aSDaniel Borkmann 	memset(buf, 0, len);
6220ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_PEEK | MSG_WAITALL), len);
62350c6b58aSDaniel Borkmann 
62450c6b58aSDaniel Borkmann 	/* MSG_PEEK can only peek into the current record. */
6250ed3015cSVakul Garg 	len = strlen(test_str_first);
62650c6b58aSDaniel Borkmann 	EXPECT_EQ(memcmp(test_str_first, buf, len), 0);
62750c6b58aSDaniel Borkmann 
6280ed3015cSVakul Garg 	len = strlen(test_str) + 1;
62950c6b58aSDaniel Borkmann 	memset(buf, 0, len);
6300ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_WAITALL), len);
63150c6b58aSDaniel Borkmann 
63250c6b58aSDaniel Borkmann 	/* Non-MSG_PEEK will advance strparser (and therefore record)
63350c6b58aSDaniel Borkmann 	 * however.
63450c6b58aSDaniel Borkmann 	 */
63550c6b58aSDaniel Borkmann 	len = strlen(test_str) + 1;
63650c6b58aSDaniel Borkmann 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
63750c6b58aSDaniel Borkmann 
63850c6b58aSDaniel Borkmann 	/* MSG_MORE will hold current record open, so later MSG_PEEK
63950c6b58aSDaniel Borkmann 	 * will see everything.
64050c6b58aSDaniel Borkmann 	 */
64150c6b58aSDaniel Borkmann 	len = strlen(test_str_first);
64250c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_first, len, MSG_MORE), len);
64350c6b58aSDaniel Borkmann 
64450c6b58aSDaniel Borkmann 	len = strlen(test_str_second) + 1;
64550c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
64650c6b58aSDaniel Borkmann 
6470ed3015cSVakul Garg 	len = strlen(test_str) + 1;
64850c6b58aSDaniel Borkmann 	memset(buf, 0, len);
6490ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_PEEK | MSG_WAITALL), len);
65050c6b58aSDaniel Borkmann 
65150c6b58aSDaniel Borkmann 	len = strlen(test_str) + 1;
65250c6b58aSDaniel Borkmann 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
65350c6b58aSDaniel Borkmann }
65450c6b58aSDaniel Borkmann 
655c2ad647cSVakul Garg TEST_F(tls, recv_peek_large_buf_mult_recs)
656c2ad647cSVakul Garg {
657c2ad647cSVakul Garg 	char const *test_str = "test_read_peek_mult_recs";
658c2ad647cSVakul Garg 	char const *test_str_first = "test_read_peek";
659c2ad647cSVakul Garg 	char const *test_str_second = "_mult_recs";
660c2ad647cSVakul Garg 	int len;
661c2ad647cSVakul Garg 	char buf[64];
662c2ad647cSVakul Garg 
663c2ad647cSVakul Garg 	len = strlen(test_str_first);
664c2ad647cSVakul Garg 	EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
665c2ad647cSVakul Garg 
666c2ad647cSVakul Garg 	len = strlen(test_str_second) + 1;
667c2ad647cSVakul Garg 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
668c2ad647cSVakul Garg 
669cea3bfb3SVakul Garg 	len = strlen(test_str) + 1;
670c2ad647cSVakul Garg 	memset(buf, 0, len);
671cea3bfb3SVakul Garg 	EXPECT_NE((len = recv(self->cfd, buf, len,
672cea3bfb3SVakul Garg 			      MSG_PEEK | MSG_WAITALL)), -1);
673c2ad647cSVakul Garg 	len = strlen(test_str) + 1;
674c2ad647cSVakul Garg 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
675c2ad647cSVakul Garg }
676c2ad647cSVakul Garg 
6777718a855SJakub Kicinski TEST_F(tls, recv_lowat)
6787718a855SJakub Kicinski {
6797718a855SJakub Kicinski 	char send_mem[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
6807718a855SJakub Kicinski 	char recv_mem[20];
6817718a855SJakub Kicinski 	int lowat = 8;
6827718a855SJakub Kicinski 
6837718a855SJakub Kicinski 	EXPECT_EQ(send(self->fd, send_mem, 10, 0), 10);
6847718a855SJakub Kicinski 	EXPECT_EQ(send(self->fd, send_mem, 5, 0), 5);
6857718a855SJakub Kicinski 
6867718a855SJakub Kicinski 	memset(recv_mem, 0, 20);
6877718a855SJakub Kicinski 	EXPECT_EQ(setsockopt(self->cfd, SOL_SOCKET, SO_RCVLOWAT,
6887718a855SJakub Kicinski 			     &lowat, sizeof(lowat)), 0);
6897718a855SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, 1, MSG_WAITALL), 1);
6907718a855SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem + 1, 6, MSG_WAITALL), 6);
6917718a855SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem + 7, 10, 0), 8);
6927718a855SJakub Kicinski 
6937718a855SJakub Kicinski 	EXPECT_EQ(memcmp(send_mem, recv_mem, 10), 0);
6947718a855SJakub Kicinski 	EXPECT_EQ(memcmp(send_mem, recv_mem + 10, 5), 0);
6957718a855SJakub Kicinski }
696e366fa43SDavid S. Miller 
69765d41fb3SJakub Kicinski TEST_F(tls, bidir)
69865d41fb3SJakub Kicinski {
69965d41fb3SJakub Kicinski 	char const *test_str = "test_read";
70065d41fb3SJakub Kicinski 	int send_len = 10;
70165d41fb3SJakub Kicinski 	char buf[10];
70265d41fb3SJakub Kicinski 	int ret;
70365d41fb3SJakub Kicinski 
704e29903c4SJakub Kicinski 	if (!self->notls) {
705e29903c4SJakub Kicinski 		struct tls12_crypto_info_aes_gcm_128 tls12;
706e29903c4SJakub Kicinski 
70765d41fb3SJakub Kicinski 		memset(&tls12, 0, sizeof(tls12));
70865d41fb3SJakub Kicinski 		tls12.info.version = TLS_1_3_VERSION;
70965d41fb3SJakub Kicinski 		tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
71065d41fb3SJakub Kicinski 
711e29903c4SJakub Kicinski 		ret = setsockopt(self->fd, SOL_TLS, TLS_RX, &tls12,
712e29903c4SJakub Kicinski 				 sizeof(tls12));
71365d41fb3SJakub Kicinski 		ASSERT_EQ(ret, 0);
71465d41fb3SJakub Kicinski 
715e29903c4SJakub Kicinski 		ret = setsockopt(self->cfd, SOL_TLS, TLS_TX, &tls12,
716e29903c4SJakub Kicinski 				 sizeof(tls12));
71765d41fb3SJakub Kicinski 		ASSERT_EQ(ret, 0);
718e29903c4SJakub Kicinski 	}
71965d41fb3SJakub Kicinski 
72065d41fb3SJakub Kicinski 	ASSERT_EQ(strlen(test_str) + 1, send_len);
72165d41fb3SJakub Kicinski 
72265d41fb3SJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
72365d41fb3SJakub Kicinski 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
72465d41fb3SJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
72565d41fb3SJakub Kicinski 
72665d41fb3SJakub Kicinski 	memset(buf, 0, sizeof(buf));
72765d41fb3SJakub Kicinski 
72865d41fb3SJakub Kicinski 	EXPECT_EQ(send(self->cfd, test_str, send_len, 0), send_len);
72965d41fb3SJakub Kicinski 	EXPECT_NE(recv(self->fd, buf, send_len, 0), -1);
73065d41fb3SJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
73165d41fb3SJakub Kicinski };
73265d41fb3SJakub Kicinski 
7337f657d5bSDave Watson TEST_F(tls, pollin)
7347f657d5bSDave Watson {
7357f657d5bSDave Watson 	char const *test_str = "test_poll";
7367f657d5bSDave Watson 	struct pollfd fd = { 0, 0, 0 };
7377f657d5bSDave Watson 	char buf[10];
7387f657d5bSDave Watson 	int send_len = 10;
7397f657d5bSDave Watson 
7407f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
7417f657d5bSDave Watson 	fd.fd = self->cfd;
7427f657d5bSDave Watson 	fd.events = POLLIN;
7437f657d5bSDave Watson 
7447f657d5bSDave Watson 	EXPECT_EQ(poll(&fd, 1, 20), 1);
7457f657d5bSDave Watson 	EXPECT_EQ(fd.revents & POLLIN, 1);
7460185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_WAITALL), send_len);
7477f657d5bSDave Watson 	/* Test timing out */
7487f657d5bSDave Watson 	EXPECT_EQ(poll(&fd, 1, 20), 0);
7497f657d5bSDave Watson }
7507f657d5bSDave Watson 
7517f657d5bSDave Watson TEST_F(tls, poll_wait)
7527f657d5bSDave Watson {
7537f657d5bSDave Watson 	char const *test_str = "test_poll_wait";
7547f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
7557f657d5bSDave Watson 	struct pollfd fd = { 0, 0, 0 };
7567f657d5bSDave Watson 	char recv_mem[15];
7577f657d5bSDave Watson 
7587f657d5bSDave Watson 	fd.fd = self->cfd;
7597f657d5bSDave Watson 	fd.events = POLLIN;
7607f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
7617f657d5bSDave Watson 	/* Set timeout to inf. secs */
7627f657d5bSDave Watson 	EXPECT_EQ(poll(&fd, 1, -1), 1);
7637f657d5bSDave Watson 	EXPECT_EQ(fd.revents & POLLIN, 1);
7640185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, recv_mem, send_len, MSG_WAITALL), send_len);
7657f657d5bSDave Watson }
7667f657d5bSDave Watson 
76781a89ef6SJakub Kicinski TEST_F(tls, poll_wait_split)
76881a89ef6SJakub Kicinski {
76981a89ef6SJakub Kicinski 	struct pollfd fd = { 0, 0, 0 };
77081a89ef6SJakub Kicinski 	char send_mem[20] = {};
77181a89ef6SJakub Kicinski 	char recv_mem[15];
77281a89ef6SJakub Kicinski 
77381a89ef6SJakub Kicinski 	fd.fd = self->cfd;
77481a89ef6SJakub Kicinski 	fd.events = POLLIN;
77581a89ef6SJakub Kicinski 	/* Send 20 bytes */
77681a89ef6SJakub Kicinski 	EXPECT_EQ(send(self->fd, send_mem, sizeof(send_mem), 0),
77781a89ef6SJakub Kicinski 		  sizeof(send_mem));
77881a89ef6SJakub Kicinski 	/* Poll with inf. timeout */
77981a89ef6SJakub Kicinski 	EXPECT_EQ(poll(&fd, 1, -1), 1);
78081a89ef6SJakub Kicinski 	EXPECT_EQ(fd.revents & POLLIN, 1);
78181a89ef6SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), MSG_WAITALL),
78281a89ef6SJakub Kicinski 		  sizeof(recv_mem));
78381a89ef6SJakub Kicinski 
78481a89ef6SJakub Kicinski 	/* Now the remaining 5 bytes of record data are in TLS ULP */
78581a89ef6SJakub Kicinski 	fd.fd = self->cfd;
78681a89ef6SJakub Kicinski 	fd.events = POLLIN;
78781a89ef6SJakub Kicinski 	EXPECT_EQ(poll(&fd, 1, -1), 1);
78881a89ef6SJakub Kicinski 	EXPECT_EQ(fd.revents & POLLIN, 1);
78981a89ef6SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), 0),
79081a89ef6SJakub Kicinski 		  sizeof(send_mem) - sizeof(recv_mem));
79181a89ef6SJakub Kicinski }
79281a89ef6SJakub Kicinski 
7937f657d5bSDave Watson TEST_F(tls, blocking)
7947f657d5bSDave Watson {
7957f657d5bSDave Watson 	size_t data = 100000;
7967f657d5bSDave Watson 	int res = fork();
7977f657d5bSDave Watson 
7987f657d5bSDave Watson 	EXPECT_NE(res, -1);
7997f657d5bSDave Watson 
8007f657d5bSDave Watson 	if (res) {
8017f657d5bSDave Watson 		/* parent */
8027f657d5bSDave Watson 		size_t left = data;
8037f657d5bSDave Watson 		char buf[16384];
8047f657d5bSDave Watson 		int status;
8057f657d5bSDave Watson 		int pid2;
8067f657d5bSDave Watson 
8077f657d5bSDave Watson 		while (left) {
8087f657d5bSDave Watson 			int res = send(self->fd, buf,
8097f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
8107f657d5bSDave Watson 
8117f657d5bSDave Watson 			EXPECT_GE(res, 0);
8127f657d5bSDave Watson 			left -= res;
8137f657d5bSDave Watson 		}
8147f657d5bSDave Watson 
8157f657d5bSDave Watson 		pid2 = wait(&status);
8167f657d5bSDave Watson 		EXPECT_EQ(status, 0);
8177f657d5bSDave Watson 		EXPECT_EQ(res, pid2);
8187f657d5bSDave Watson 	} else {
8197f657d5bSDave Watson 		/* child */
8207f657d5bSDave Watson 		size_t left = data;
8217f657d5bSDave Watson 		char buf[16384];
8227f657d5bSDave Watson 
8237f657d5bSDave Watson 		while (left) {
8247f657d5bSDave Watson 			int res = recv(self->cfd, buf,
8257f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
8267f657d5bSDave Watson 
8277f657d5bSDave Watson 			EXPECT_GE(res, 0);
8287f657d5bSDave Watson 			left -= res;
8297f657d5bSDave Watson 		}
8307f657d5bSDave Watson 	}
8317f657d5bSDave Watson }
8327f657d5bSDave Watson 
8337f657d5bSDave Watson TEST_F(tls, nonblocking)
8347f657d5bSDave Watson {
8357f657d5bSDave Watson 	size_t data = 100000;
8367f657d5bSDave Watson 	int sendbuf = 100;
8377f657d5bSDave Watson 	int flags;
8387f657d5bSDave Watson 	int res;
8397f657d5bSDave Watson 
8407f657d5bSDave Watson 	flags = fcntl(self->fd, F_GETFL, 0);
8417f657d5bSDave Watson 	fcntl(self->fd, F_SETFL, flags | O_NONBLOCK);
8427f657d5bSDave Watson 	fcntl(self->cfd, F_SETFL, flags | O_NONBLOCK);
8437f657d5bSDave Watson 
8447f657d5bSDave Watson 	/* Ensure nonblocking behavior by imposing a small send
8457f657d5bSDave Watson 	 * buffer.
8467f657d5bSDave Watson 	 */
8477f657d5bSDave Watson 	EXPECT_EQ(setsockopt(self->fd, SOL_SOCKET, SO_SNDBUF,
8487f657d5bSDave Watson 			     &sendbuf, sizeof(sendbuf)), 0);
8497f657d5bSDave Watson 
8507f657d5bSDave Watson 	res = fork();
8517f657d5bSDave Watson 	EXPECT_NE(res, -1);
8527f657d5bSDave Watson 
8537f657d5bSDave Watson 	if (res) {
8547f657d5bSDave Watson 		/* parent */
8557f657d5bSDave Watson 		bool eagain = false;
8567f657d5bSDave Watson 		size_t left = data;
8577f657d5bSDave Watson 		char buf[16384];
8587f657d5bSDave Watson 		int status;
8597f657d5bSDave Watson 		int pid2;
8607f657d5bSDave Watson 
8617f657d5bSDave Watson 		while (left) {
8627f657d5bSDave Watson 			int res = send(self->fd, buf,
8637f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
8647f657d5bSDave Watson 
8657f657d5bSDave Watson 			if (res == -1 && errno == EAGAIN) {
8667f657d5bSDave Watson 				eagain = true;
8677f657d5bSDave Watson 				usleep(10000);
8687f657d5bSDave Watson 				continue;
8697f657d5bSDave Watson 			}
8707f657d5bSDave Watson 			EXPECT_GE(res, 0);
8717f657d5bSDave Watson 			left -= res;
8727f657d5bSDave Watson 		}
8737f657d5bSDave Watson 
8747f657d5bSDave Watson 		EXPECT_TRUE(eagain);
8757f657d5bSDave Watson 		pid2 = wait(&status);
8767f657d5bSDave Watson 
8777f657d5bSDave Watson 		EXPECT_EQ(status, 0);
8787f657d5bSDave Watson 		EXPECT_EQ(res, pid2);
8797f657d5bSDave Watson 	} else {
8807f657d5bSDave Watson 		/* child */
8817f657d5bSDave Watson 		bool eagain = false;
8827f657d5bSDave Watson 		size_t left = data;
8837f657d5bSDave Watson 		char buf[16384];
8847f657d5bSDave Watson 
8857f657d5bSDave Watson 		while (left) {
8867f657d5bSDave Watson 			int res = recv(self->cfd, buf,
8877f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
8887f657d5bSDave Watson 
8897f657d5bSDave Watson 			if (res == -1 && errno == EAGAIN) {
8907f657d5bSDave Watson 				eagain = true;
8917f657d5bSDave Watson 				usleep(10000);
8927f657d5bSDave Watson 				continue;
8937f657d5bSDave Watson 			}
8947f657d5bSDave Watson 			EXPECT_GE(res, 0);
8957f657d5bSDave Watson 			left -= res;
8967f657d5bSDave Watson 		}
8977f657d5bSDave Watson 		EXPECT_TRUE(eagain);
8987f657d5bSDave Watson 	}
8997f657d5bSDave Watson }
9007f657d5bSDave Watson 
9017f657d5bSDave Watson TEST_F(tls, control_msg)
9027f657d5bSDave Watson {
9037f657d5bSDave Watson 	if (self->notls)
9047f657d5bSDave Watson 		return;
9057f657d5bSDave Watson 
9067f657d5bSDave Watson 	char cbuf[CMSG_SPACE(sizeof(char))];
9077f657d5bSDave Watson 	char const *test_str = "test_read";
9087f657d5bSDave Watson 	int cmsg_len = sizeof(char);
9097f657d5bSDave Watson 	char record_type = 100;
9107f657d5bSDave Watson 	struct cmsghdr *cmsg;
9117f657d5bSDave Watson 	struct msghdr msg;
9127f657d5bSDave Watson 	int send_len = 10;
9137f657d5bSDave Watson 	struct iovec vec;
9147f657d5bSDave Watson 	char buf[10];
9157f657d5bSDave Watson 
9167f657d5bSDave Watson 	vec.iov_base = (char *)test_str;
9177f657d5bSDave Watson 	vec.iov_len = 10;
9187f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
9197f657d5bSDave Watson 	msg.msg_iov = &vec;
9207f657d5bSDave Watson 	msg.msg_iovlen = 1;
9217f657d5bSDave Watson 	msg.msg_control = cbuf;
9227f657d5bSDave Watson 	msg.msg_controllen = sizeof(cbuf);
9237f657d5bSDave Watson 	cmsg = CMSG_FIRSTHDR(&msg);
9247f657d5bSDave Watson 	cmsg->cmsg_level = SOL_TLS;
9257f657d5bSDave Watson 	/* test sending non-record types. */
9267f657d5bSDave Watson 	cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
9277f657d5bSDave Watson 	cmsg->cmsg_len = CMSG_LEN(cmsg_len);
9287f657d5bSDave Watson 	*CMSG_DATA(cmsg) = record_type;
9297f657d5bSDave Watson 	msg.msg_controllen = cmsg->cmsg_len;
9307f657d5bSDave Watson 
9317f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
9327f657d5bSDave Watson 	/* Should fail because we didn't provide a control message */
9337f657d5bSDave Watson 	EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
9347f657d5bSDave Watson 
9357f657d5bSDave Watson 	vec.iov_base = buf;
936203ef5f1SVakul Garg 	EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL | MSG_PEEK), send_len);
937203ef5f1SVakul Garg 
938203ef5f1SVakul Garg 	cmsg = CMSG_FIRSTHDR(&msg);
939203ef5f1SVakul Garg 	EXPECT_NE(cmsg, NULL);
940203ef5f1SVakul Garg 	EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
941203ef5f1SVakul Garg 	EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
942203ef5f1SVakul Garg 	record_type = *((unsigned char *)CMSG_DATA(cmsg));
943203ef5f1SVakul Garg 	EXPECT_EQ(record_type, 100);
944203ef5f1SVakul Garg 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
945203ef5f1SVakul Garg 
946203ef5f1SVakul Garg 	/* Recv the message again without MSG_PEEK */
947203ef5f1SVakul Garg 	record_type = 0;
948203ef5f1SVakul Garg 	memset(buf, 0, sizeof(buf));
949203ef5f1SVakul Garg 
9500185e2e6SVakul Garg 	EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL), send_len);
9517f657d5bSDave Watson 	cmsg = CMSG_FIRSTHDR(&msg);
9527f657d5bSDave Watson 	EXPECT_NE(cmsg, NULL);
9537f657d5bSDave Watson 	EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
9547f657d5bSDave Watson 	EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
9557f657d5bSDave Watson 	record_type = *((unsigned char *)CMSG_DATA(cmsg));
9567f657d5bSDave Watson 	EXPECT_EQ(record_type, 100);
9577f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
9587f657d5bSDave Watson }
9597f657d5bSDave Watson 
960d4d34185SJakub Kicinski TEST_F(tls, shutdown)
961d4d34185SJakub Kicinski {
962d4d34185SJakub Kicinski 	char const *test_str = "test_read";
963d4d34185SJakub Kicinski 	int send_len = 10;
964d4d34185SJakub Kicinski 	char buf[10];
965d4d34185SJakub Kicinski 
966d4d34185SJakub Kicinski 	ASSERT_EQ(strlen(test_str) + 1, send_len);
967d4d34185SJakub Kicinski 
968d4d34185SJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
969d4d34185SJakub Kicinski 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
970d4d34185SJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
971d4d34185SJakub Kicinski 
972d4d34185SJakub Kicinski 	shutdown(self->fd, SHUT_RDWR);
973d4d34185SJakub Kicinski 	shutdown(self->cfd, SHUT_RDWR);
974d4d34185SJakub Kicinski }
975d4d34185SJakub Kicinski 
976d4d34185SJakub Kicinski TEST_F(tls, shutdown_unsent)
977d4d34185SJakub Kicinski {
978d4d34185SJakub Kicinski 	char const *test_str = "test_read";
979d4d34185SJakub Kicinski 	int send_len = 10;
980d4d34185SJakub Kicinski 
981d4d34185SJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
982d4d34185SJakub Kicinski 
983d4d34185SJakub Kicinski 	shutdown(self->fd, SHUT_RDWR);
984d4d34185SJakub Kicinski 	shutdown(self->cfd, SHUT_RDWR);
985d4d34185SJakub Kicinski }
986d4d34185SJakub Kicinski 
987*cd114d2eSJakub Kicinski TEST_F(tls, shutdown_reuse)
988*cd114d2eSJakub Kicinski {
989*cd114d2eSJakub Kicinski 	struct sockaddr_in addr;
990*cd114d2eSJakub Kicinski 	int ret;
991*cd114d2eSJakub Kicinski 
992*cd114d2eSJakub Kicinski 	shutdown(self->fd, SHUT_RDWR);
993*cd114d2eSJakub Kicinski 	shutdown(self->cfd, SHUT_RDWR);
994*cd114d2eSJakub Kicinski 	close(self->cfd);
995*cd114d2eSJakub Kicinski 
996*cd114d2eSJakub Kicinski 	addr.sin_family = AF_INET;
997*cd114d2eSJakub Kicinski 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
998*cd114d2eSJakub Kicinski 	addr.sin_port = 0;
999*cd114d2eSJakub Kicinski 
1000*cd114d2eSJakub Kicinski 	ret = bind(self->fd, &addr, sizeof(addr));
1001*cd114d2eSJakub Kicinski 	EXPECT_EQ(ret, 0);
1002*cd114d2eSJakub Kicinski 	ret = listen(self->fd, 10);
1003*cd114d2eSJakub Kicinski 	EXPECT_EQ(ret, -1);
1004*cd114d2eSJakub Kicinski 	EXPECT_EQ(errno, EINVAL);
1005*cd114d2eSJakub Kicinski 
1006*cd114d2eSJakub Kicinski 	ret = connect(self->fd, &addr, sizeof(addr));
1007*cd114d2eSJakub Kicinski 	EXPECT_EQ(ret, -1);
1008*cd114d2eSJakub Kicinski 	EXPECT_EQ(errno, EISCONN);
1009*cd114d2eSJakub Kicinski }
1010*cd114d2eSJakub Kicinski 
101178b5dc3dSJakub Kicinski TEST(non_established) {
101278b5dc3dSJakub Kicinski 	struct tls12_crypto_info_aes_gcm_256 tls12;
101378b5dc3dSJakub Kicinski 	struct sockaddr_in addr;
101478b5dc3dSJakub Kicinski 	int sfd, ret, fd;
101578b5dc3dSJakub Kicinski 	socklen_t len;
101678b5dc3dSJakub Kicinski 
101778b5dc3dSJakub Kicinski 	len = sizeof(addr);
101878b5dc3dSJakub Kicinski 
101978b5dc3dSJakub Kicinski 	memset(&tls12, 0, sizeof(tls12));
102078b5dc3dSJakub Kicinski 	tls12.info.version = TLS_1_2_VERSION;
102178b5dc3dSJakub Kicinski 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
102278b5dc3dSJakub Kicinski 
102378b5dc3dSJakub Kicinski 	addr.sin_family = AF_INET;
102478b5dc3dSJakub Kicinski 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
102578b5dc3dSJakub Kicinski 	addr.sin_port = 0;
102678b5dc3dSJakub Kicinski 
102778b5dc3dSJakub Kicinski 	fd = socket(AF_INET, SOCK_STREAM, 0);
102878b5dc3dSJakub Kicinski 	sfd = socket(AF_INET, SOCK_STREAM, 0);
102978b5dc3dSJakub Kicinski 
103078b5dc3dSJakub Kicinski 	ret = bind(sfd, &addr, sizeof(addr));
103178b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
103278b5dc3dSJakub Kicinski 	ret = listen(sfd, 10);
103378b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
103478b5dc3dSJakub Kicinski 
103578b5dc3dSJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
103678b5dc3dSJakub Kicinski 	EXPECT_EQ(ret, -1);
103778b5dc3dSJakub Kicinski 	/* TLS ULP not supported */
103878b5dc3dSJakub Kicinski 	if (errno == ENOENT)
103978b5dc3dSJakub Kicinski 		return;
104078b5dc3dSJakub Kicinski 	EXPECT_EQ(errno, ENOTSUPP);
104178b5dc3dSJakub Kicinski 
104278b5dc3dSJakub Kicinski 	ret = setsockopt(sfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
104378b5dc3dSJakub Kicinski 	EXPECT_EQ(ret, -1);
104478b5dc3dSJakub Kicinski 	EXPECT_EQ(errno, ENOTSUPP);
104578b5dc3dSJakub Kicinski 
104678b5dc3dSJakub Kicinski 	ret = getsockname(sfd, &addr, &len);
104778b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
104878b5dc3dSJakub Kicinski 
104978b5dc3dSJakub Kicinski 	ret = connect(fd, &addr, sizeof(addr));
105078b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
105178b5dc3dSJakub Kicinski 
105278b5dc3dSJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
105378b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
105478b5dc3dSJakub Kicinski 
105578b5dc3dSJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
105678b5dc3dSJakub Kicinski 	EXPECT_EQ(ret, -1);
105778b5dc3dSJakub Kicinski 	EXPECT_EQ(errno, EEXIST);
105878b5dc3dSJakub Kicinski 
105978b5dc3dSJakub Kicinski 	close(fd);
106078b5dc3dSJakub Kicinski 	close(sfd);
106178b5dc3dSJakub Kicinski }
106278b5dc3dSJakub Kicinski 
1063fb99bce7SDave Watson TEST(keysizes) {
1064fb99bce7SDave Watson 	struct tls12_crypto_info_aes_gcm_256 tls12;
1065fb99bce7SDave Watson 	struct sockaddr_in addr;
1066fb99bce7SDave Watson 	int sfd, ret, fd, cfd;
1067fb99bce7SDave Watson 	socklen_t len;
1068fb99bce7SDave Watson 	bool notls;
1069fb99bce7SDave Watson 
1070fb99bce7SDave Watson 	notls = false;
1071fb99bce7SDave Watson 	len = sizeof(addr);
1072fb99bce7SDave Watson 
1073fb99bce7SDave Watson 	memset(&tls12, 0, sizeof(tls12));
1074fb99bce7SDave Watson 	tls12.info.version = TLS_1_2_VERSION;
1075fb99bce7SDave Watson 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
1076fb99bce7SDave Watson 
1077fb99bce7SDave Watson 	addr.sin_family = AF_INET;
1078fb99bce7SDave Watson 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
1079fb99bce7SDave Watson 	addr.sin_port = 0;
1080fb99bce7SDave Watson 
1081fb99bce7SDave Watson 	fd = socket(AF_INET, SOCK_STREAM, 0);
1082fb99bce7SDave Watson 	sfd = socket(AF_INET, SOCK_STREAM, 0);
1083fb99bce7SDave Watson 
1084fb99bce7SDave Watson 	ret = bind(sfd, &addr, sizeof(addr));
1085fb99bce7SDave Watson 	ASSERT_EQ(ret, 0);
1086fb99bce7SDave Watson 	ret = listen(sfd, 10);
1087fb99bce7SDave Watson 	ASSERT_EQ(ret, 0);
1088fb99bce7SDave Watson 
1089fb99bce7SDave Watson 	ret = getsockname(sfd, &addr, &len);
1090fb99bce7SDave Watson 	ASSERT_EQ(ret, 0);
1091fb99bce7SDave Watson 
1092fb99bce7SDave Watson 	ret = connect(fd, &addr, sizeof(addr));
1093fb99bce7SDave Watson 	ASSERT_EQ(ret, 0);
1094fb99bce7SDave Watson 
1095fb99bce7SDave Watson 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1096fb99bce7SDave Watson 	if (ret != 0) {
1097fb99bce7SDave Watson 		notls = true;
1098fb99bce7SDave Watson 		printf("Failure setting TCP_ULP, testing without tls\n");
1099fb99bce7SDave Watson 	}
1100fb99bce7SDave Watson 
1101fb99bce7SDave Watson 	if (!notls) {
1102fb99bce7SDave Watson 		ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
1103fb99bce7SDave Watson 				 sizeof(tls12));
1104fb99bce7SDave Watson 		EXPECT_EQ(ret, 0);
1105fb99bce7SDave Watson 	}
1106fb99bce7SDave Watson 
1107fb99bce7SDave Watson 	cfd = accept(sfd, &addr, &len);
1108fb99bce7SDave Watson 	ASSERT_GE(cfd, 0);
1109fb99bce7SDave Watson 
1110fb99bce7SDave Watson 	if (!notls) {
1111fb99bce7SDave Watson 		ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls",
1112fb99bce7SDave Watson 				 sizeof("tls"));
1113fb99bce7SDave Watson 		EXPECT_EQ(ret, 0);
1114fb99bce7SDave Watson 
1115fb99bce7SDave Watson 		ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
1116fb99bce7SDave Watson 				 sizeof(tls12));
1117fb99bce7SDave Watson 		EXPECT_EQ(ret, 0);
1118fb99bce7SDave Watson 	}
1119fb99bce7SDave Watson 
1120fb99bce7SDave Watson 	close(sfd);
1121fb99bce7SDave Watson 	close(fd);
1122fb99bce7SDave Watson 	close(cfd);
1123fb99bce7SDave Watson }
1124fb99bce7SDave Watson 
11258debd67eSDave Watson TEST(tls12) {
11268debd67eSDave Watson 	int fd, cfd;
11278debd67eSDave Watson 	bool notls;
11288debd67eSDave Watson 
11298debd67eSDave Watson 	struct tls12_crypto_info_aes_gcm_128 tls12;
11308debd67eSDave Watson 	struct sockaddr_in addr;
11318debd67eSDave Watson 	socklen_t len;
11328debd67eSDave Watson 	int sfd, ret;
11338debd67eSDave Watson 
11348debd67eSDave Watson 	notls = false;
11358debd67eSDave Watson 	len = sizeof(addr);
11368debd67eSDave Watson 
11378debd67eSDave Watson 	memset(&tls12, 0, sizeof(tls12));
11388debd67eSDave Watson 	tls12.info.version = TLS_1_2_VERSION;
11398debd67eSDave Watson 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128;
11408debd67eSDave Watson 
11418debd67eSDave Watson 	addr.sin_family = AF_INET;
11428debd67eSDave Watson 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
11438debd67eSDave Watson 	addr.sin_port = 0;
11448debd67eSDave Watson 
11458debd67eSDave Watson 	fd = socket(AF_INET, SOCK_STREAM, 0);
11468debd67eSDave Watson 	sfd = socket(AF_INET, SOCK_STREAM, 0);
11478debd67eSDave Watson 
11488debd67eSDave Watson 	ret = bind(sfd, &addr, sizeof(addr));
11498debd67eSDave Watson 	ASSERT_EQ(ret, 0);
11508debd67eSDave Watson 	ret = listen(sfd, 10);
11518debd67eSDave Watson 	ASSERT_EQ(ret, 0);
11528debd67eSDave Watson 
11538debd67eSDave Watson 	ret = getsockname(sfd, &addr, &len);
11548debd67eSDave Watson 	ASSERT_EQ(ret, 0);
11558debd67eSDave Watson 
11568debd67eSDave Watson 	ret = connect(fd, &addr, sizeof(addr));
11578debd67eSDave Watson 	ASSERT_EQ(ret, 0);
11588debd67eSDave Watson 
11598debd67eSDave Watson 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
11608debd67eSDave Watson 	if (ret != 0) {
11618debd67eSDave Watson 		notls = true;
11628debd67eSDave Watson 		printf("Failure setting TCP_ULP, testing without tls\n");
11638debd67eSDave Watson 	}
11648debd67eSDave Watson 
11658debd67eSDave Watson 	if (!notls) {
11668debd67eSDave Watson 		ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
11678debd67eSDave Watson 				 sizeof(tls12));
11688debd67eSDave Watson 		ASSERT_EQ(ret, 0);
11698debd67eSDave Watson 	}
11708debd67eSDave Watson 
11718debd67eSDave Watson 	cfd = accept(sfd, &addr, &len);
11728debd67eSDave Watson 	ASSERT_GE(cfd, 0);
11738debd67eSDave Watson 
11748debd67eSDave Watson 	if (!notls) {
11758debd67eSDave Watson 		ret = setsockopt(cfd, IPPROTO_TCP, TCP_ULP, "tls",
11768debd67eSDave Watson 				 sizeof("tls"));
11778debd67eSDave Watson 		ASSERT_EQ(ret, 0);
11788debd67eSDave Watson 
11798debd67eSDave Watson 		ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
11808debd67eSDave Watson 				 sizeof(tls12));
11818debd67eSDave Watson 		ASSERT_EQ(ret, 0);
11828debd67eSDave Watson 	}
11838debd67eSDave Watson 
11848debd67eSDave Watson 	close(sfd);
11858debd67eSDave Watson 
11868debd67eSDave Watson 	char const *test_str = "test_read";
11878debd67eSDave Watson 	int send_len = 10;
11888debd67eSDave Watson 	char buf[10];
11898debd67eSDave Watson 
11908debd67eSDave Watson 	send_len = strlen(test_str) + 1;
11918debd67eSDave Watson 	EXPECT_EQ(send(fd, test_str, send_len, 0), send_len);
11928debd67eSDave Watson 	EXPECT_NE(recv(cfd, buf, send_len, 0), -1);
11938debd67eSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
11948debd67eSDave Watson 
11958debd67eSDave Watson 	close(fd);
11968debd67eSDave Watson 	close(cfd);
11978debd67eSDave Watson }
11988debd67eSDave Watson 
11997f657d5bSDave Watson TEST_HARNESS_MAIN
1200