xref: /linux/tools/testing/selftests/net/tls.c (revision 13bf99ab2130783e2b1988ef415585e3af7df97b)
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 
28291c53e4SJakub Kicinski struct tls_crypto_info_keys {
29291c53e4SJakub Kicinski 	union {
30291c53e4SJakub Kicinski 		struct tls12_crypto_info_aes_gcm_128 aes128;
31291c53e4SJakub Kicinski 		struct tls12_crypto_info_chacha20_poly1305 chacha20;
32e506342aSTianjia Zhang 		struct tls12_crypto_info_sm4_gcm sm4gcm;
33e506342aSTianjia Zhang 		struct tls12_crypto_info_sm4_ccm sm4ccm;
34d76c51f9SVadim Fedorenko 		struct tls12_crypto_info_aes_ccm_128 aesccm128;
35*13bf99abSVadim Fedorenko 		struct tls12_crypto_info_aes_gcm_256 aesgcm256;
36291c53e4SJakub Kicinski 	};
37291c53e4SJakub Kicinski 	size_t len;
38291c53e4SJakub Kicinski };
39291c53e4SJakub Kicinski 
40291c53e4SJakub Kicinski static void tls_crypto_info_init(uint16_t tls_version, uint16_t cipher_type,
41291c53e4SJakub Kicinski 				 struct tls_crypto_info_keys *tls12)
42291c53e4SJakub Kicinski {
43291c53e4SJakub Kicinski 	memset(tls12, 0, sizeof(*tls12));
44291c53e4SJakub Kicinski 
45291c53e4SJakub Kicinski 	switch (cipher_type) {
46291c53e4SJakub Kicinski 	case TLS_CIPHER_CHACHA20_POLY1305:
47291c53e4SJakub Kicinski 		tls12->len = sizeof(struct tls12_crypto_info_chacha20_poly1305);
48291c53e4SJakub Kicinski 		tls12->chacha20.info.version = tls_version;
49291c53e4SJakub Kicinski 		tls12->chacha20.info.cipher_type = cipher_type;
50291c53e4SJakub Kicinski 		break;
51291c53e4SJakub Kicinski 	case TLS_CIPHER_AES_GCM_128:
52291c53e4SJakub Kicinski 		tls12->len = sizeof(struct tls12_crypto_info_aes_gcm_128);
53291c53e4SJakub Kicinski 		tls12->aes128.info.version = tls_version;
54291c53e4SJakub Kicinski 		tls12->aes128.info.cipher_type = cipher_type;
55291c53e4SJakub Kicinski 		break;
56e506342aSTianjia Zhang 	case TLS_CIPHER_SM4_GCM:
57e506342aSTianjia Zhang 		tls12->len = sizeof(struct tls12_crypto_info_sm4_gcm);
58e506342aSTianjia Zhang 		tls12->sm4gcm.info.version = tls_version;
59e506342aSTianjia Zhang 		tls12->sm4gcm.info.cipher_type = cipher_type;
60e506342aSTianjia Zhang 		break;
61e506342aSTianjia Zhang 	case TLS_CIPHER_SM4_CCM:
62e506342aSTianjia Zhang 		tls12->len = sizeof(struct tls12_crypto_info_sm4_ccm);
63e506342aSTianjia Zhang 		tls12->sm4ccm.info.version = tls_version;
64e506342aSTianjia Zhang 		tls12->sm4ccm.info.cipher_type = cipher_type;
65e506342aSTianjia Zhang 		break;
66d76c51f9SVadim Fedorenko 	case TLS_CIPHER_AES_CCM_128:
67d76c51f9SVadim Fedorenko 		tls12->len = sizeof(struct tls12_crypto_info_aes_ccm_128);
68d76c51f9SVadim Fedorenko 		tls12->aesccm128.info.version = tls_version;
69d76c51f9SVadim Fedorenko 		tls12->aesccm128.info.cipher_type = cipher_type;
70d76c51f9SVadim Fedorenko 		break;
71*13bf99abSVadim Fedorenko 	case TLS_CIPHER_AES_GCM_256:
72*13bf99abSVadim Fedorenko 		tls12->len = sizeof(struct tls12_crypto_info_aes_gcm_256);
73*13bf99abSVadim Fedorenko 		tls12->aesgcm256.info.version = tls_version;
74*13bf99abSVadim Fedorenko 		tls12->aesgcm256.info.cipher_type = cipher_type;
75*13bf99abSVadim Fedorenko 		break;
76291c53e4SJakub Kicinski 	default:
77291c53e4SJakub Kicinski 		break;
78291c53e4SJakub Kicinski 	}
79291c53e4SJakub Kicinski }
80291c53e4SJakub Kicinski 
81baa00119SJakub Kicinski static void memrnd(void *s, size_t n)
82baa00119SJakub Kicinski {
83baa00119SJakub Kicinski 	int *dword = s;
84baa00119SJakub Kicinski 	char *byte;
85baa00119SJakub Kicinski 
86baa00119SJakub Kicinski 	for (; n >= 4; n -= 4)
87baa00119SJakub Kicinski 		*dword++ = rand();
88baa00119SJakub Kicinski 	byte = (void *)dword;
89baa00119SJakub Kicinski 	while (n--)
90baa00119SJakub Kicinski 		*byte++ = rand();
91baa00119SJakub Kicinski }
92baa00119SJakub Kicinski 
93a125f91fSJakub Kicinski static void ulp_sock_pair(struct __test_metadata *_metadata,
94a125f91fSJakub Kicinski 			  int *fd, int *cfd, bool *notls)
95cf32526cSJakub Kicinski {
96cf32526cSJakub Kicinski 	struct sockaddr_in addr;
97cf32526cSJakub Kicinski 	socklen_t len;
98cf32526cSJakub Kicinski 	int sfd, ret;
99cf32526cSJakub Kicinski 
100a125f91fSJakub Kicinski 	*notls = false;
101cf32526cSJakub Kicinski 	len = sizeof(addr);
102cf32526cSJakub Kicinski 
103cf32526cSJakub Kicinski 	addr.sin_family = AF_INET;
104cf32526cSJakub Kicinski 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
105cf32526cSJakub Kicinski 	addr.sin_port = 0;
106cf32526cSJakub Kicinski 
107a125f91fSJakub Kicinski 	*fd = socket(AF_INET, SOCK_STREAM, 0);
108cf32526cSJakub Kicinski 	sfd = socket(AF_INET, SOCK_STREAM, 0);
109cf32526cSJakub Kicinski 
110cf32526cSJakub Kicinski 	ret = bind(sfd, &addr, sizeof(addr));
111cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
112cf32526cSJakub Kicinski 	ret = listen(sfd, 10);
113cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
114cf32526cSJakub Kicinski 
115cf32526cSJakub Kicinski 	ret = getsockname(sfd, &addr, &len);
116cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
117cf32526cSJakub Kicinski 
118a125f91fSJakub Kicinski 	ret = connect(*fd, &addr, sizeof(addr));
119cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
120cf32526cSJakub Kicinski 
121a125f91fSJakub Kicinski 	*cfd = accept(sfd, &addr, &len);
122a125f91fSJakub Kicinski 	ASSERT_GE(*cfd, 0);
123cf32526cSJakub Kicinski 
124cf32526cSJakub Kicinski 	close(sfd);
125cf32526cSJakub Kicinski 
126a125f91fSJakub Kicinski 	ret = setsockopt(*fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
127cf32526cSJakub Kicinski 	if (ret != 0) {
128e29903c4SJakub Kicinski 		ASSERT_EQ(errno, ENOENT);
129a125f91fSJakub Kicinski 		*notls = true;
130cf32526cSJakub Kicinski 		printf("Failure setting TCP_ULP, testing without tls\n");
131cf32526cSJakub Kicinski 		return;
132cf32526cSJakub Kicinski 	}
133cf32526cSJakub Kicinski 
134a125f91fSJakub Kicinski 	ret = setsockopt(*cfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
135cf32526cSJakub Kicinski 	ASSERT_EQ(ret, 0);
136cf32526cSJakub Kicinski }
137cf32526cSJakub Kicinski 
13831180adbSJakub Kicinski /* Produce a basic cmsg */
13931180adbSJakub Kicinski static int tls_send_cmsg(int fd, unsigned char record_type,
14031180adbSJakub Kicinski 			 void *data, size_t len, int flags)
14131180adbSJakub Kicinski {
14231180adbSJakub Kicinski 	char cbuf[CMSG_SPACE(sizeof(char))];
14331180adbSJakub Kicinski 	int cmsg_len = sizeof(char);
14431180adbSJakub Kicinski 	struct cmsghdr *cmsg;
14531180adbSJakub Kicinski 	struct msghdr msg;
14631180adbSJakub Kicinski 	struct iovec vec;
14731180adbSJakub Kicinski 
14831180adbSJakub Kicinski 	vec.iov_base = data;
14931180adbSJakub Kicinski 	vec.iov_len = len;
15031180adbSJakub Kicinski 	memset(&msg, 0, sizeof(struct msghdr));
15131180adbSJakub Kicinski 	msg.msg_iov = &vec;
15231180adbSJakub Kicinski 	msg.msg_iovlen = 1;
15331180adbSJakub Kicinski 	msg.msg_control = cbuf;
15431180adbSJakub Kicinski 	msg.msg_controllen = sizeof(cbuf);
15531180adbSJakub Kicinski 	cmsg = CMSG_FIRSTHDR(&msg);
15631180adbSJakub Kicinski 	cmsg->cmsg_level = SOL_TLS;
15731180adbSJakub Kicinski 	/* test sending non-record types. */
15831180adbSJakub Kicinski 	cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
15931180adbSJakub Kicinski 	cmsg->cmsg_len = CMSG_LEN(cmsg_len);
16031180adbSJakub Kicinski 	*CMSG_DATA(cmsg) = record_type;
16131180adbSJakub Kicinski 	msg.msg_controllen = cmsg->cmsg_len;
16231180adbSJakub Kicinski 
16331180adbSJakub Kicinski 	return sendmsg(fd, &msg, flags);
16431180adbSJakub Kicinski }
16531180adbSJakub Kicinski 
16631180adbSJakub Kicinski static int tls_recv_cmsg(struct __test_metadata *_metadata,
16731180adbSJakub Kicinski 			 int fd, unsigned char record_type,
16831180adbSJakub Kicinski 			 void *data, size_t len, int flags)
16931180adbSJakub Kicinski {
17031180adbSJakub Kicinski 	char cbuf[CMSG_SPACE(sizeof(char))];
17131180adbSJakub Kicinski 	struct cmsghdr *cmsg;
17231180adbSJakub Kicinski 	unsigned char ctype;
17331180adbSJakub Kicinski 	struct msghdr msg;
17431180adbSJakub Kicinski 	struct iovec vec;
17531180adbSJakub Kicinski 	int n;
17631180adbSJakub Kicinski 
17731180adbSJakub Kicinski 	vec.iov_base = data;
17831180adbSJakub Kicinski 	vec.iov_len = len;
17931180adbSJakub Kicinski 	memset(&msg, 0, sizeof(struct msghdr));
18031180adbSJakub Kicinski 	msg.msg_iov = &vec;
18131180adbSJakub Kicinski 	msg.msg_iovlen = 1;
18231180adbSJakub Kicinski 	msg.msg_control = cbuf;
18331180adbSJakub Kicinski 	msg.msg_controllen = sizeof(cbuf);
18431180adbSJakub Kicinski 
18531180adbSJakub Kicinski 	n = recvmsg(fd, &msg, flags);
18631180adbSJakub Kicinski 
18731180adbSJakub Kicinski 	cmsg = CMSG_FIRSTHDR(&msg);
18831180adbSJakub Kicinski 	EXPECT_NE(cmsg, NULL);
18931180adbSJakub Kicinski 	EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
19031180adbSJakub Kicinski 	EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
19131180adbSJakub Kicinski 	ctype = *((unsigned char *)CMSG_DATA(cmsg));
19231180adbSJakub Kicinski 	EXPECT_EQ(ctype, record_type);
19331180adbSJakub Kicinski 
19431180adbSJakub Kicinski 	return n;
19531180adbSJakub Kicinski }
19631180adbSJakub Kicinski 
197a125f91fSJakub Kicinski FIXTURE(tls_basic)
198a125f91fSJakub Kicinski {
199a125f91fSJakub Kicinski 	int fd, cfd;
200a125f91fSJakub Kicinski 	bool notls;
201a125f91fSJakub Kicinski };
202a125f91fSJakub Kicinski 
203a125f91fSJakub Kicinski FIXTURE_SETUP(tls_basic)
204a125f91fSJakub Kicinski {
205a125f91fSJakub Kicinski 	ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
206a125f91fSJakub Kicinski }
207a125f91fSJakub Kicinski 
208cf32526cSJakub Kicinski FIXTURE_TEARDOWN(tls_basic)
209cf32526cSJakub Kicinski {
210cf32526cSJakub Kicinski 	close(self->fd);
211cf32526cSJakub Kicinski 	close(self->cfd);
212cf32526cSJakub Kicinski }
213cf32526cSJakub Kicinski 
214cf32526cSJakub Kicinski /* Send some data through with ULP but no keys */
215cf32526cSJakub Kicinski TEST_F(tls_basic, base_base)
216cf32526cSJakub Kicinski {
217cf32526cSJakub Kicinski 	char const *test_str = "test_read";
218cf32526cSJakub Kicinski 	int send_len = 10;
219cf32526cSJakub Kicinski 	char buf[10];
220cf32526cSJakub Kicinski 
221cf32526cSJakub Kicinski 	ASSERT_EQ(strlen(test_str) + 1, send_len);
222cf32526cSJakub Kicinski 
223cf32526cSJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
224cf32526cSJakub Kicinski 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
225cf32526cSJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
226cf32526cSJakub Kicinski };
227cf32526cSJakub Kicinski 
2287f657d5bSDave Watson FIXTURE(tls)
2297f657d5bSDave Watson {
2307f657d5bSDave Watson 	int fd, cfd;
2317f657d5bSDave Watson 	bool notls;
2327f657d5bSDave Watson };
2337f657d5bSDave Watson 
2340feba221SJakub Kicinski FIXTURE_VARIANT(tls)
2350feba221SJakub Kicinski {
2363502bd9bSVadim Fedorenko 	uint16_t tls_version;
2373502bd9bSVadim Fedorenko 	uint16_t cipher_type;
2380feba221SJakub Kicinski };
2390feba221SJakub Kicinski 
240e506342aSTianjia Zhang FIXTURE_VARIANT_ADD(tls, 12_aes_gcm)
2410feba221SJakub Kicinski {
2420feba221SJakub Kicinski 	.tls_version = TLS_1_2_VERSION,
2434f336e88SVadim Fedorenko 	.cipher_type = TLS_CIPHER_AES_GCM_128,
2440feba221SJakub Kicinski };
2450feba221SJakub Kicinski 
246e506342aSTianjia Zhang FIXTURE_VARIANT_ADD(tls, 13_aes_gcm)
2470feba221SJakub Kicinski {
2480feba221SJakub Kicinski 	.tls_version = TLS_1_3_VERSION,
2494f336e88SVadim Fedorenko 	.cipher_type = TLS_CIPHER_AES_GCM_128,
2504f336e88SVadim Fedorenko };
2514f336e88SVadim Fedorenko 
2524f336e88SVadim Fedorenko FIXTURE_VARIANT_ADD(tls, 12_chacha)
2534f336e88SVadim Fedorenko {
2544f336e88SVadim Fedorenko 	.tls_version = TLS_1_2_VERSION,
2554f336e88SVadim Fedorenko 	.cipher_type = TLS_CIPHER_CHACHA20_POLY1305,
2564f336e88SVadim Fedorenko };
2574f336e88SVadim Fedorenko 
2584f336e88SVadim Fedorenko FIXTURE_VARIANT_ADD(tls, 13_chacha)
2594f336e88SVadim Fedorenko {
2604f336e88SVadim Fedorenko 	.tls_version = TLS_1_3_VERSION,
2614f336e88SVadim Fedorenko 	.cipher_type = TLS_CIPHER_CHACHA20_POLY1305,
2620feba221SJakub Kicinski };
2630feba221SJakub Kicinski 
264e506342aSTianjia Zhang FIXTURE_VARIANT_ADD(tls, 13_sm4_gcm)
265e506342aSTianjia Zhang {
266e506342aSTianjia Zhang 	.tls_version = TLS_1_3_VERSION,
267e506342aSTianjia Zhang 	.cipher_type = TLS_CIPHER_SM4_GCM,
268e506342aSTianjia Zhang };
269e506342aSTianjia Zhang 
270e506342aSTianjia Zhang FIXTURE_VARIANT_ADD(tls, 13_sm4_ccm)
271e506342aSTianjia Zhang {
272e506342aSTianjia Zhang 	.tls_version = TLS_1_3_VERSION,
273e506342aSTianjia Zhang 	.cipher_type = TLS_CIPHER_SM4_CCM,
274e506342aSTianjia Zhang };
275e506342aSTianjia Zhang 
276d76c51f9SVadim Fedorenko FIXTURE_VARIANT_ADD(tls, 12_aes_ccm)
277d76c51f9SVadim Fedorenko {
278d76c51f9SVadim Fedorenko 	.tls_version = TLS_1_2_VERSION,
279d76c51f9SVadim Fedorenko 	.cipher_type = TLS_CIPHER_AES_CCM_128,
280d76c51f9SVadim Fedorenko };
281d76c51f9SVadim Fedorenko 
282d76c51f9SVadim Fedorenko FIXTURE_VARIANT_ADD(tls, 13_aes_ccm)
283d76c51f9SVadim Fedorenko {
284d76c51f9SVadim Fedorenko 	.tls_version = TLS_1_3_VERSION,
285d76c51f9SVadim Fedorenko 	.cipher_type = TLS_CIPHER_AES_CCM_128,
286d76c51f9SVadim Fedorenko };
287d76c51f9SVadim Fedorenko 
288*13bf99abSVadim Fedorenko FIXTURE_VARIANT_ADD(tls, 12_aes_gcm_256)
289*13bf99abSVadim Fedorenko {
290*13bf99abSVadim Fedorenko 	.tls_version = TLS_1_2_VERSION,
291*13bf99abSVadim Fedorenko 	.cipher_type = TLS_CIPHER_AES_GCM_256,
292*13bf99abSVadim Fedorenko };
293*13bf99abSVadim Fedorenko 
294*13bf99abSVadim Fedorenko FIXTURE_VARIANT_ADD(tls, 13_aes_gcm_256)
295*13bf99abSVadim Fedorenko {
296*13bf99abSVadim Fedorenko 	.tls_version = TLS_1_3_VERSION,
297*13bf99abSVadim Fedorenko 	.cipher_type = TLS_CIPHER_AES_GCM_256,
298*13bf99abSVadim Fedorenko };
299*13bf99abSVadim Fedorenko 
3007f657d5bSDave Watson FIXTURE_SETUP(tls)
3017f657d5bSDave Watson {
302291c53e4SJakub Kicinski 	struct tls_crypto_info_keys tls12;
303a125f91fSJakub Kicinski 	int ret;
3047f657d5bSDave Watson 
305291c53e4SJakub Kicinski 	tls_crypto_info_init(variant->tls_version, variant->cipher_type,
306291c53e4SJakub Kicinski 			     &tls12);
3077f657d5bSDave Watson 
308a125f91fSJakub Kicinski 	ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
3097f657d5bSDave Watson 
310a125f91fSJakub Kicinski 	if (self->notls)
311a125f91fSJakub Kicinski 		return;
3127f657d5bSDave Watson 
313a125f91fSJakub Kicinski 	ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len);
3147f657d5bSDave Watson 	ASSERT_EQ(ret, 0);
3157f657d5bSDave Watson 
316a125f91fSJakub Kicinski 	ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, tls12.len);
3177f657d5bSDave Watson 	ASSERT_EQ(ret, 0);
3187f657d5bSDave Watson }
3197f657d5bSDave Watson 
3207f657d5bSDave Watson FIXTURE_TEARDOWN(tls)
3217f657d5bSDave Watson {
3227f657d5bSDave Watson 	close(self->fd);
3237f657d5bSDave Watson 	close(self->cfd);
3247f657d5bSDave Watson }
3257f657d5bSDave Watson 
3267f657d5bSDave Watson TEST_F(tls, sendfile)
3277f657d5bSDave Watson {
3287f657d5bSDave Watson 	int filefd = open("/proc/self/exe", O_RDONLY);
3297f657d5bSDave Watson 	struct stat st;
3307f657d5bSDave Watson 
3317f657d5bSDave Watson 	EXPECT_GE(filefd, 0);
3327f657d5bSDave Watson 	fstat(filefd, &st);
3337f657d5bSDave Watson 	EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
3347f657d5bSDave Watson }
3357f657d5bSDave Watson 
3367f657d5bSDave Watson TEST_F(tls, send_then_sendfile)
3377f657d5bSDave Watson {
3387f657d5bSDave Watson 	int filefd = open("/proc/self/exe", O_RDONLY);
3397f657d5bSDave Watson 	char const *test_str = "test_send";
3407f657d5bSDave Watson 	int to_send = strlen(test_str) + 1;
3417f657d5bSDave Watson 	char recv_buf[10];
3427f657d5bSDave Watson 	struct stat st;
3437f657d5bSDave Watson 	char *buf;
3447f657d5bSDave Watson 
3457f657d5bSDave Watson 	EXPECT_GE(filefd, 0);
3467f657d5bSDave Watson 	fstat(filefd, &st);
3477f657d5bSDave Watson 	buf = (char *)malloc(st.st_size);
3487f657d5bSDave Watson 
3497f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, to_send, 0), to_send);
3500185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, recv_buf, to_send, MSG_WAITALL), to_send);
3517f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, recv_buf, to_send), 0);
3527f657d5bSDave Watson 
3537f657d5bSDave Watson 	EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0);
3540185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, st.st_size, MSG_WAITALL), st.st_size);
3557f657d5bSDave Watson }
3567f657d5bSDave Watson 
3570e6fbe39SPooja Trivedi static void chunked_sendfile(struct __test_metadata *_metadata,
3580e6fbe39SPooja Trivedi 			     struct _test_data_tls *self,
3590e6fbe39SPooja Trivedi 			     uint16_t chunk_size,
3600e6fbe39SPooja Trivedi 			     uint16_t extra_payload_size)
3610e6fbe39SPooja Trivedi {
3620e6fbe39SPooja Trivedi 	char buf[TLS_PAYLOAD_MAX_LEN];
3630e6fbe39SPooja Trivedi 	uint16_t test_payload_size;
3640e6fbe39SPooja Trivedi 	int size = 0;
3650e6fbe39SPooja Trivedi 	int ret;
3660e6fbe39SPooja Trivedi 	char filename[] = "/tmp/mytemp.XXXXXX";
3670e6fbe39SPooja Trivedi 	int fd = mkstemp(filename);
3680e6fbe39SPooja Trivedi 	off_t offset = 0;
3690e6fbe39SPooja Trivedi 
3700e6fbe39SPooja Trivedi 	unlink(filename);
3710e6fbe39SPooja Trivedi 	ASSERT_GE(fd, 0);
3720e6fbe39SPooja Trivedi 	EXPECT_GE(chunk_size, 1);
3730e6fbe39SPooja Trivedi 	test_payload_size = chunk_size + extra_payload_size;
3740e6fbe39SPooja Trivedi 	ASSERT_GE(TLS_PAYLOAD_MAX_LEN, test_payload_size);
3750e6fbe39SPooja Trivedi 	memset(buf, 1, test_payload_size);
3760e6fbe39SPooja Trivedi 	size = write(fd, buf, test_payload_size);
3770e6fbe39SPooja Trivedi 	EXPECT_EQ(size, test_payload_size);
3780e6fbe39SPooja Trivedi 	fsync(fd);
3790e6fbe39SPooja Trivedi 
3800e6fbe39SPooja Trivedi 	while (size > 0) {
3810e6fbe39SPooja Trivedi 		ret = sendfile(self->fd, fd, &offset, chunk_size);
3820e6fbe39SPooja Trivedi 		EXPECT_GE(ret, 0);
3830e6fbe39SPooja Trivedi 		size -= ret;
3840e6fbe39SPooja Trivedi 	}
3850e6fbe39SPooja Trivedi 
3860e6fbe39SPooja Trivedi 	EXPECT_EQ(recv(self->cfd, buf, test_payload_size, MSG_WAITALL),
3870e6fbe39SPooja Trivedi 		  test_payload_size);
3880e6fbe39SPooja Trivedi 
3890e6fbe39SPooja Trivedi 	close(fd);
3900e6fbe39SPooja Trivedi }
3910e6fbe39SPooja Trivedi 
3920e6fbe39SPooja Trivedi TEST_F(tls, multi_chunk_sendfile)
3930e6fbe39SPooja Trivedi {
3940e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 4096, 4096);
3950e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 4096, 0);
3960e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 4096, 1);
3970e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 4096, 2048);
3980e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 8192, 2048);
3990e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 4096, 8192);
4000e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 8192, 4096);
4010e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 12288, 1024);
4020e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 12288, 2000);
4030e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 15360, 100);
4040e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 15360, 300);
4050e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 1, 4096);
4060e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 2048, 4096);
4070e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 2048, 8192);
4080e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 4096, 8192);
4090e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 1024, 12288);
4100e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 2000, 12288);
4110e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 100, 15360);
4120e6fbe39SPooja Trivedi 	chunked_sendfile(_metadata, self, 300, 15360);
4130e6fbe39SPooja Trivedi }
4140e6fbe39SPooja Trivedi 
4157f657d5bSDave Watson TEST_F(tls, recv_max)
4167f657d5bSDave Watson {
4177f657d5bSDave Watson 	unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
4187f657d5bSDave Watson 	char recv_mem[TLS_PAYLOAD_MAX_LEN];
4197f657d5bSDave Watson 	char buf[TLS_PAYLOAD_MAX_LEN];
4207f657d5bSDave Watson 
421baa00119SJakub Kicinski 	memrnd(buf, sizeof(buf));
422baa00119SJakub Kicinski 
4237f657d5bSDave Watson 	EXPECT_GE(send(self->fd, buf, send_len, 0), 0);
4247f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
4257f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0);
4267f657d5bSDave Watson }
4277f657d5bSDave Watson 
4287f657d5bSDave Watson TEST_F(tls, recv_small)
4297f657d5bSDave Watson {
4307f657d5bSDave Watson 	char const *test_str = "test_read";
4317f657d5bSDave Watson 	int send_len = 10;
4327f657d5bSDave Watson 	char buf[10];
4337f657d5bSDave Watson 
4347f657d5bSDave Watson 	send_len = strlen(test_str) + 1;
4357f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
4367f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
4377f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
4387f657d5bSDave Watson }
4397f657d5bSDave Watson 
4407f657d5bSDave Watson TEST_F(tls, msg_more)
4417f657d5bSDave Watson {
4427f657d5bSDave Watson 	char const *test_str = "test_read";
4437f657d5bSDave Watson 	int send_len = 10;
4447f657d5bSDave Watson 	char buf[10 * 2];
4457f657d5bSDave Watson 
4467f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
4477f657d5bSDave Watson 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
4487f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
4490185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len * 2, MSG_WAITALL),
4507f657d5bSDave Watson 		  send_len * 2);
4517f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
4527f657d5bSDave Watson }
4537f657d5bSDave Watson 
4548051bb7fSJakub Kicinski TEST_F(tls, msg_more_unsent)
4558051bb7fSJakub Kicinski {
4568051bb7fSJakub Kicinski 	char const *test_str = "test_read";
4578051bb7fSJakub Kicinski 	int send_len = 10;
4588051bb7fSJakub Kicinski 	char buf[10];
4598051bb7fSJakub Kicinski 
4608051bb7fSJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
4618051bb7fSJakub Kicinski 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1);
4628051bb7fSJakub Kicinski }
4638051bb7fSJakub Kicinski 
4647f657d5bSDave Watson TEST_F(tls, sendmsg_single)
4657f657d5bSDave Watson {
4667f657d5bSDave Watson 	struct msghdr msg;
4677f657d5bSDave Watson 
4687f657d5bSDave Watson 	char const *test_str = "test_sendmsg";
4697f657d5bSDave Watson 	size_t send_len = 13;
4707f657d5bSDave Watson 	struct iovec vec;
4717f657d5bSDave Watson 	char buf[13];
4727f657d5bSDave Watson 
4737f657d5bSDave Watson 	vec.iov_base = (char *)test_str;
4747f657d5bSDave Watson 	vec.iov_len = send_len;
4757f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
4767f657d5bSDave Watson 	msg.msg_iov = &vec;
4777f657d5bSDave Watson 	msg.msg_iovlen = 1;
4787f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len);
4790185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_WAITALL), send_len);
4807f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
4817f657d5bSDave Watson }
4827f657d5bSDave Watson 
48365190f77SJakub Kicinski #define MAX_FRAGS	64
48465190f77SJakub Kicinski #define SEND_LEN	13
48565190f77SJakub Kicinski TEST_F(tls, sendmsg_fragmented)
48665190f77SJakub Kicinski {
48765190f77SJakub Kicinski 	char const *test_str = "test_sendmsg";
48865190f77SJakub Kicinski 	char buf[SEND_LEN * MAX_FRAGS];
48965190f77SJakub Kicinski 	struct iovec vec[MAX_FRAGS];
49065190f77SJakub Kicinski 	struct msghdr msg;
49165190f77SJakub Kicinski 	int i, frags;
49265190f77SJakub Kicinski 
49365190f77SJakub Kicinski 	for (frags = 1; frags <= MAX_FRAGS; frags++) {
49465190f77SJakub Kicinski 		for (i = 0; i < frags; i++) {
49565190f77SJakub Kicinski 			vec[i].iov_base = (char *)test_str;
49665190f77SJakub Kicinski 			vec[i].iov_len = SEND_LEN;
49765190f77SJakub Kicinski 		}
49865190f77SJakub Kicinski 
49965190f77SJakub Kicinski 		memset(&msg, 0, sizeof(struct msghdr));
50065190f77SJakub Kicinski 		msg.msg_iov = vec;
50165190f77SJakub Kicinski 		msg.msg_iovlen = frags;
50265190f77SJakub Kicinski 
50365190f77SJakub Kicinski 		EXPECT_EQ(sendmsg(self->fd, &msg, 0), SEND_LEN * frags);
50465190f77SJakub Kicinski 		EXPECT_EQ(recv(self->cfd, buf, SEND_LEN * frags, MSG_WAITALL),
50565190f77SJakub Kicinski 			  SEND_LEN * frags);
50665190f77SJakub Kicinski 
50765190f77SJakub Kicinski 		for (i = 0; i < frags; i++)
50865190f77SJakub Kicinski 			EXPECT_EQ(memcmp(buf + SEND_LEN * i,
50965190f77SJakub Kicinski 					 test_str, SEND_LEN), 0);
51065190f77SJakub Kicinski 	}
51165190f77SJakub Kicinski }
51265190f77SJakub Kicinski #undef MAX_FRAGS
51365190f77SJakub Kicinski #undef SEND_LEN
51465190f77SJakub Kicinski 
5157f657d5bSDave Watson TEST_F(tls, sendmsg_large)
5167f657d5bSDave Watson {
5177f657d5bSDave Watson 	void *mem = malloc(16384);
5187f657d5bSDave Watson 	size_t send_len = 16384;
5197f657d5bSDave Watson 	size_t sends = 128;
5207f657d5bSDave Watson 	struct msghdr msg;
5217f657d5bSDave Watson 	size_t recvs = 0;
5227f657d5bSDave Watson 	size_t sent = 0;
5237f657d5bSDave Watson 
5247f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
5257f657d5bSDave Watson 	while (sent++ < sends) {
5267f657d5bSDave Watson 		struct iovec vec = { (void *)mem, send_len };
5277f657d5bSDave Watson 
5287f657d5bSDave Watson 		msg.msg_iov = &vec;
5297f657d5bSDave Watson 		msg.msg_iovlen = 1;
5307f657d5bSDave Watson 		EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len);
5317f657d5bSDave Watson 	}
5327f657d5bSDave Watson 
533f50688b4SKees Cook 	while (recvs++ < sends) {
5347f657d5bSDave Watson 		EXPECT_NE(recv(self->fd, mem, send_len, 0), -1);
535f50688b4SKees Cook 	}
5367f657d5bSDave Watson 
5377f657d5bSDave Watson 	free(mem);
5387f657d5bSDave Watson }
5397f657d5bSDave Watson 
5407f657d5bSDave Watson TEST_F(tls, sendmsg_multiple)
5417f657d5bSDave Watson {
5427f657d5bSDave Watson 	char const *test_str = "test_sendmsg_multiple";
5437f657d5bSDave Watson 	struct iovec vec[5];
5447f657d5bSDave Watson 	char *test_strs[5];
5457f657d5bSDave Watson 	struct msghdr msg;
5467f657d5bSDave Watson 	int total_len = 0;
5477f657d5bSDave Watson 	int len_cmp = 0;
5487f657d5bSDave Watson 	int iov_len = 5;
5497f657d5bSDave Watson 	char *buf;
5507f657d5bSDave Watson 	int i;
5517f657d5bSDave Watson 
5527f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
5537f657d5bSDave Watson 	for (i = 0; i < iov_len; i++) {
5547f657d5bSDave Watson 		test_strs[i] = (char *)malloc(strlen(test_str) + 1);
5557f657d5bSDave Watson 		snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
5567f657d5bSDave Watson 		vec[i].iov_base = (void *)test_strs[i];
5577f657d5bSDave Watson 		vec[i].iov_len = strlen(test_strs[i]) + 1;
5587f657d5bSDave Watson 		total_len += vec[i].iov_len;
5597f657d5bSDave Watson 	}
5607f657d5bSDave Watson 	msg.msg_iov = vec;
5617f657d5bSDave Watson 	msg.msg_iovlen = iov_len;
5627f657d5bSDave Watson 
5637f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len);
5647f657d5bSDave Watson 	buf = malloc(total_len);
5657f657d5bSDave Watson 	EXPECT_NE(recv(self->fd, buf, total_len, 0), -1);
5667f657d5bSDave Watson 	for (i = 0; i < iov_len; i++) {
5677f657d5bSDave Watson 		EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp,
5687f657d5bSDave Watson 				 strlen(test_strs[i])),
5697f657d5bSDave Watson 			  0);
5707f657d5bSDave Watson 		len_cmp += strlen(buf + len_cmp) + 1;
5717f657d5bSDave Watson 	}
5727f657d5bSDave Watson 	for (i = 0; i < iov_len; i++)
5737f657d5bSDave Watson 		free(test_strs[i]);
5747f657d5bSDave Watson 	free(buf);
5757f657d5bSDave Watson }
5767f657d5bSDave Watson 
5777f657d5bSDave Watson TEST_F(tls, sendmsg_multiple_stress)
5787f657d5bSDave Watson {
5797f657d5bSDave Watson 	char const *test_str = "abcdefghijklmno";
5807f657d5bSDave Watson 	struct iovec vec[1024];
5817f657d5bSDave Watson 	char *test_strs[1024];
5827f657d5bSDave Watson 	int iov_len = 1024;
5837f657d5bSDave Watson 	int total_len = 0;
5847f657d5bSDave Watson 	char buf[1 << 14];
5857f657d5bSDave Watson 	struct msghdr msg;
5867f657d5bSDave Watson 	int len_cmp = 0;
5877f657d5bSDave Watson 	int i;
5887f657d5bSDave Watson 
5897f657d5bSDave Watson 	memset(&msg, 0, sizeof(struct msghdr));
5907f657d5bSDave Watson 	for (i = 0; i < iov_len; i++) {
5917f657d5bSDave Watson 		test_strs[i] = (char *)malloc(strlen(test_str) + 1);
5927f657d5bSDave Watson 		snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str);
5937f657d5bSDave Watson 		vec[i].iov_base = (void *)test_strs[i];
5947f657d5bSDave Watson 		vec[i].iov_len = strlen(test_strs[i]) + 1;
5957f657d5bSDave Watson 		total_len += vec[i].iov_len;
5967f657d5bSDave Watson 	}
5977f657d5bSDave Watson 	msg.msg_iov = vec;
5987f657d5bSDave Watson 	msg.msg_iovlen = iov_len;
5997f657d5bSDave Watson 
6007f657d5bSDave Watson 	EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len);
6017f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1);
6027f657d5bSDave Watson 
6037f657d5bSDave Watson 	for (i = 0; i < iov_len; i++)
6047f657d5bSDave Watson 		len_cmp += strlen(buf + len_cmp) + 1;
6057f657d5bSDave Watson 
6067f657d5bSDave Watson 	for (i = 0; i < iov_len; i++)
6077f657d5bSDave Watson 		free(test_strs[i]);
6087f657d5bSDave Watson }
6097f657d5bSDave Watson 
6107f657d5bSDave Watson TEST_F(tls, splice_from_pipe)
6117f657d5bSDave Watson {
6127f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
6137f657d5bSDave Watson 	char mem_send[TLS_PAYLOAD_MAX_LEN];
6147f657d5bSDave Watson 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
6157f657d5bSDave Watson 	int p[2];
6167f657d5bSDave Watson 
6177f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
6187f657d5bSDave Watson 	EXPECT_GE(write(p[1], mem_send, send_len), 0);
6197f657d5bSDave Watson 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), 0);
6200ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
6217f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
6227f657d5bSDave Watson }
6237f657d5bSDave Watson 
6247f657d5bSDave Watson TEST_F(tls, splice_from_pipe2)
6257f657d5bSDave Watson {
6267f657d5bSDave Watson 	int send_len = 16000;
6277f657d5bSDave Watson 	char mem_send[16000];
6287f657d5bSDave Watson 	char mem_recv[16000];
6297f657d5bSDave Watson 	int p2[2];
6307f657d5bSDave Watson 	int p[2];
6317f657d5bSDave Watson 
6327f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
6337f657d5bSDave Watson 	ASSERT_GE(pipe(p2), 0);
6347f657d5bSDave Watson 	EXPECT_GE(write(p[1], mem_send, 8000), 0);
6357f657d5bSDave Watson 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, 8000, 0), 0);
6367f657d5bSDave Watson 	EXPECT_GE(write(p2[1], mem_send + 8000, 8000), 0);
6377f657d5bSDave Watson 	EXPECT_GE(splice(p2[0], NULL, self->fd, NULL, 8000, 0), 0);
6380185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
6397f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
6407f657d5bSDave Watson }
6417f657d5bSDave Watson 
6427f657d5bSDave Watson TEST_F(tls, send_and_splice)
6437f657d5bSDave Watson {
6447f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
6457f657d5bSDave Watson 	char mem_send[TLS_PAYLOAD_MAX_LEN];
6467f657d5bSDave Watson 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
6477f657d5bSDave Watson 	char const *test_str = "test_read";
6487f657d5bSDave Watson 	int send_len2 = 10;
6497f657d5bSDave Watson 	char buf[10];
6507f657d5bSDave Watson 	int p[2];
6517f657d5bSDave Watson 
6527f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
6537f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len2, 0), send_len2);
6540ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len2, MSG_WAITALL), send_len2);
6557f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len2), 0);
6567f657d5bSDave Watson 
6577f657d5bSDave Watson 	EXPECT_GE(write(p[1], mem_send, send_len), send_len);
6587f657d5bSDave Watson 	EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), send_len);
6597f657d5bSDave Watson 
6600ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, mem_recv, send_len, MSG_WAITALL), send_len);
6617f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
6627f657d5bSDave Watson }
6637f657d5bSDave Watson 
6647f657d5bSDave Watson TEST_F(tls, splice_to_pipe)
6657f657d5bSDave Watson {
6667f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
6677f657d5bSDave Watson 	char mem_send[TLS_PAYLOAD_MAX_LEN];
6687f657d5bSDave Watson 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
6697f657d5bSDave Watson 	int p[2];
6707f657d5bSDave Watson 
6717f657d5bSDave Watson 	ASSERT_GE(pipe(p), 0);
6727f657d5bSDave Watson 	EXPECT_GE(send(self->fd, mem_send, send_len, 0), 0);
6737f657d5bSDave Watson 	EXPECT_GE(splice(self->cfd, NULL, p[1], NULL, send_len, 0), 0);
6747f657d5bSDave Watson 	EXPECT_GE(read(p[0], mem_recv, send_len), 0);
6757f657d5bSDave Watson 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
6767f657d5bSDave Watson }
6777f657d5bSDave Watson 
678d87d67fdSJakub Kicinski TEST_F(tls, splice_cmsg_to_pipe)
679d87d67fdSJakub Kicinski {
680d87d67fdSJakub Kicinski 	char *test_str = "test_read";
681d87d67fdSJakub Kicinski 	char record_type = 100;
682d87d67fdSJakub Kicinski 	int send_len = 10;
683d87d67fdSJakub Kicinski 	char buf[10];
684d87d67fdSJakub Kicinski 	int p[2];
685d87d67fdSJakub Kicinski 
686d87d67fdSJakub Kicinski 	ASSERT_GE(pipe(p), 0);
687d87d67fdSJakub Kicinski 	EXPECT_EQ(tls_send_cmsg(self->fd, 100, test_str, send_len, 0), 10);
688d87d67fdSJakub Kicinski 	EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, send_len, 0), -1);
689d87d67fdSJakub Kicinski 	EXPECT_EQ(errno, EINVAL);
690d87d67fdSJakub Kicinski 	EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
691d87d67fdSJakub Kicinski 	EXPECT_EQ(errno, EIO);
692d87d67fdSJakub Kicinski 	EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
693d87d67fdSJakub Kicinski 				buf, sizeof(buf), MSG_WAITALL),
694d87d67fdSJakub Kicinski 		  send_len);
695d87d67fdSJakub Kicinski 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
696d87d67fdSJakub Kicinski }
697d87d67fdSJakub Kicinski 
698d87d67fdSJakub Kicinski TEST_F(tls, splice_dec_cmsg_to_pipe)
699d87d67fdSJakub Kicinski {
700d87d67fdSJakub Kicinski 	char *test_str = "test_read";
701d87d67fdSJakub Kicinski 	char record_type = 100;
702d87d67fdSJakub Kicinski 	int send_len = 10;
703d87d67fdSJakub Kicinski 	char buf[10];
704d87d67fdSJakub Kicinski 	int p[2];
705d87d67fdSJakub Kicinski 
706d87d67fdSJakub Kicinski 	ASSERT_GE(pipe(p), 0);
707d87d67fdSJakub Kicinski 	EXPECT_EQ(tls_send_cmsg(self->fd, 100, test_str, send_len, 0), 10);
708d87d67fdSJakub Kicinski 	EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
709d87d67fdSJakub Kicinski 	EXPECT_EQ(errno, EIO);
710d87d67fdSJakub Kicinski 	EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, send_len, 0), -1);
711d87d67fdSJakub Kicinski 	EXPECT_EQ(errno, EINVAL);
712d87d67fdSJakub Kicinski 	EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
713d87d67fdSJakub Kicinski 				buf, sizeof(buf), MSG_WAITALL),
714d87d67fdSJakub Kicinski 		  send_len);
715d87d67fdSJakub Kicinski 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
716d87d67fdSJakub Kicinski }
717d87d67fdSJakub Kicinski 
718274af0f9SJakub Kicinski TEST_F(tls, recv_and_splice)
719274af0f9SJakub Kicinski {
720274af0f9SJakub Kicinski 	int send_len = TLS_PAYLOAD_MAX_LEN;
721274af0f9SJakub Kicinski 	char mem_send[TLS_PAYLOAD_MAX_LEN];
722274af0f9SJakub Kicinski 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
723274af0f9SJakub Kicinski 	int half = send_len / 2;
724274af0f9SJakub Kicinski 	int p[2];
725274af0f9SJakub Kicinski 
726274af0f9SJakub Kicinski 	ASSERT_GE(pipe(p), 0);
727274af0f9SJakub Kicinski 	EXPECT_EQ(send(self->fd, mem_send, send_len, 0), send_len);
728274af0f9SJakub Kicinski 	/* Recv hald of the record, splice the other half */
729274af0f9SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, mem_recv, half, MSG_WAITALL), half);
730274af0f9SJakub Kicinski 	EXPECT_EQ(splice(self->cfd, NULL, p[1], NULL, half, SPLICE_F_NONBLOCK),
731274af0f9SJakub Kicinski 		  half);
732274af0f9SJakub Kicinski 	EXPECT_EQ(read(p[0], &mem_recv[half], half), half);
733274af0f9SJakub Kicinski 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
734274af0f9SJakub Kicinski }
735274af0f9SJakub Kicinski 
736274af0f9SJakub Kicinski TEST_F(tls, peek_and_splice)
737274af0f9SJakub Kicinski {
738274af0f9SJakub Kicinski 	int send_len = TLS_PAYLOAD_MAX_LEN;
739274af0f9SJakub Kicinski 	char mem_send[TLS_PAYLOAD_MAX_LEN];
740274af0f9SJakub Kicinski 	char mem_recv[TLS_PAYLOAD_MAX_LEN];
741274af0f9SJakub Kicinski 	int chunk = TLS_PAYLOAD_MAX_LEN / 4;
742274af0f9SJakub Kicinski 	int n, i, p[2];
743274af0f9SJakub Kicinski 
744274af0f9SJakub Kicinski 	memrnd(mem_send, sizeof(mem_send));
745274af0f9SJakub Kicinski 
746274af0f9SJakub Kicinski 	ASSERT_GE(pipe(p), 0);
747274af0f9SJakub Kicinski 	for (i = 0; i < 4; i++)
748274af0f9SJakub Kicinski 		EXPECT_EQ(send(self->fd, &mem_send[chunk * i], chunk, 0),
749274af0f9SJakub Kicinski 			  chunk);
750274af0f9SJakub Kicinski 
751274af0f9SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, mem_recv, chunk * 5 / 2,
752274af0f9SJakub Kicinski 		       MSG_WAITALL | MSG_PEEK),
753274af0f9SJakub Kicinski 		  chunk * 5 / 2);
754274af0f9SJakub Kicinski 	EXPECT_EQ(memcmp(mem_send, mem_recv, chunk * 5 / 2), 0);
755274af0f9SJakub Kicinski 
756274af0f9SJakub Kicinski 	n = 0;
757274af0f9SJakub Kicinski 	while (n < send_len) {
758274af0f9SJakub Kicinski 		i = splice(self->cfd, NULL, p[1], NULL, send_len - n, 0);
759274af0f9SJakub Kicinski 		EXPECT_GT(i, 0);
760274af0f9SJakub Kicinski 		n += i;
761274af0f9SJakub Kicinski 	}
762274af0f9SJakub Kicinski 	EXPECT_EQ(n, send_len);
763274af0f9SJakub Kicinski 	EXPECT_EQ(read(p[0], mem_recv, send_len), send_len);
764274af0f9SJakub Kicinski 	EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0);
765274af0f9SJakub Kicinski }
766274af0f9SJakub Kicinski 
7677f657d5bSDave Watson TEST_F(tls, recvmsg_single)
7687f657d5bSDave Watson {
7697f657d5bSDave Watson 	char const *test_str = "test_recvmsg_single";
7707f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
7717f657d5bSDave Watson 	char buf[20];
7727f657d5bSDave Watson 	struct msghdr hdr;
7737f657d5bSDave Watson 	struct iovec vec;
7747f657d5bSDave Watson 
7757f657d5bSDave Watson 	memset(&hdr, 0, sizeof(hdr));
7767f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
7777f657d5bSDave Watson 	vec.iov_base = (char *)buf;
7787f657d5bSDave Watson 	vec.iov_len = send_len;
7797f657d5bSDave Watson 	hdr.msg_iovlen = 1;
7807f657d5bSDave Watson 	hdr.msg_iov = &vec;
7817f657d5bSDave Watson 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
7827f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
7837f657d5bSDave Watson }
7847f657d5bSDave Watson 
7857f657d5bSDave Watson TEST_F(tls, recvmsg_single_max)
7867f657d5bSDave Watson {
7877f657d5bSDave Watson 	int send_len = TLS_PAYLOAD_MAX_LEN;
7887f657d5bSDave Watson 	char send_mem[TLS_PAYLOAD_MAX_LEN];
7897f657d5bSDave Watson 	char recv_mem[TLS_PAYLOAD_MAX_LEN];
7907f657d5bSDave Watson 	struct iovec vec;
7917f657d5bSDave Watson 	struct msghdr hdr;
7927f657d5bSDave Watson 
793baa00119SJakub Kicinski 	memrnd(send_mem, sizeof(send_mem));
794baa00119SJakub Kicinski 
7957f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, send_mem, send_len, 0), send_len);
7967f657d5bSDave Watson 	vec.iov_base = (char *)recv_mem;
7977f657d5bSDave Watson 	vec.iov_len = TLS_PAYLOAD_MAX_LEN;
7987f657d5bSDave Watson 
7997f657d5bSDave Watson 	hdr.msg_iovlen = 1;
8007f657d5bSDave Watson 	hdr.msg_iov = &vec;
8017f657d5bSDave Watson 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
8027f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
8037f657d5bSDave Watson }
8047f657d5bSDave Watson 
8057f657d5bSDave Watson TEST_F(tls, recvmsg_multiple)
8067f657d5bSDave Watson {
8077f657d5bSDave Watson 	unsigned int msg_iovlen = 1024;
8087f657d5bSDave Watson 	struct iovec vec[1024];
8097f657d5bSDave Watson 	char *iov_base[1024];
8107f657d5bSDave Watson 	unsigned int iov_len = 16;
8117f657d5bSDave Watson 	int send_len = 1 << 14;
8127f657d5bSDave Watson 	char buf[1 << 14];
8137f657d5bSDave Watson 	struct msghdr hdr;
8147f657d5bSDave Watson 	int i;
8157f657d5bSDave Watson 
816baa00119SJakub Kicinski 	memrnd(buf, sizeof(buf));
817baa00119SJakub Kicinski 
8187f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, buf, send_len, 0), send_len);
8197f657d5bSDave Watson 	for (i = 0; i < msg_iovlen; i++) {
8207f657d5bSDave Watson 		iov_base[i] = (char *)malloc(iov_len);
8217f657d5bSDave Watson 		vec[i].iov_base = iov_base[i];
8227f657d5bSDave Watson 		vec[i].iov_len = iov_len;
8237f657d5bSDave Watson 	}
8247f657d5bSDave Watson 
8257f657d5bSDave Watson 	hdr.msg_iovlen = msg_iovlen;
8267f657d5bSDave Watson 	hdr.msg_iov = vec;
8277f657d5bSDave Watson 	EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1);
8287f657d5bSDave Watson 
8297f657d5bSDave Watson 	for (i = 0; i < msg_iovlen; i++)
8307f657d5bSDave Watson 		free(iov_base[i]);
8317f657d5bSDave Watson }
8327f657d5bSDave Watson 
8337f657d5bSDave Watson TEST_F(tls, single_send_multiple_recv)
8347f657d5bSDave Watson {
8357f657d5bSDave Watson 	unsigned int total_len = TLS_PAYLOAD_MAX_LEN * 2;
8367f657d5bSDave Watson 	unsigned int send_len = TLS_PAYLOAD_MAX_LEN;
8377f657d5bSDave Watson 	char send_mem[TLS_PAYLOAD_MAX_LEN * 2];
8387f657d5bSDave Watson 	char recv_mem[TLS_PAYLOAD_MAX_LEN * 2];
8397f657d5bSDave Watson 
840baa00119SJakub Kicinski 	memrnd(send_mem, sizeof(send_mem));
841baa00119SJakub Kicinski 
8427f657d5bSDave Watson 	EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
8437f657d5bSDave Watson 	memset(recv_mem, 0, total_len);
8447f657d5bSDave Watson 
8457f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1);
8467f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, recv_mem + send_len, send_len, 0), -1);
8477f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
8487f657d5bSDave Watson }
8497f657d5bSDave Watson 
8507f657d5bSDave Watson TEST_F(tls, multiple_send_single_recv)
8517f657d5bSDave Watson {
8527f657d5bSDave Watson 	unsigned int total_len = 2 * 10;
8537f657d5bSDave Watson 	unsigned int send_len = 10;
8547f657d5bSDave Watson 	char recv_mem[2 * 10];
8557f657d5bSDave Watson 	char send_mem[10];
8567f657d5bSDave Watson 
8577f657d5bSDave Watson 	EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
8587f657d5bSDave Watson 	EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0);
8597f657d5bSDave Watson 	memset(recv_mem, 0, total_len);
8600185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, recv_mem, total_len, MSG_WAITALL), total_len);
8617f657d5bSDave Watson 
8627f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0);
8637f657d5bSDave Watson 	EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0);
8647f657d5bSDave Watson }
8657f657d5bSDave Watson 
866043556d0SJakub Kicinski TEST_F(tls, single_send_multiple_recv_non_align)
867043556d0SJakub Kicinski {
868043556d0SJakub Kicinski 	const unsigned int total_len = 15;
869043556d0SJakub Kicinski 	const unsigned int recv_len = 10;
870043556d0SJakub Kicinski 	char recv_mem[recv_len * 2];
871043556d0SJakub Kicinski 	char send_mem[total_len];
872043556d0SJakub Kicinski 
873043556d0SJakub Kicinski 	EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0);
874043556d0SJakub Kicinski 	memset(recv_mem, 0, total_len);
875043556d0SJakub Kicinski 
876043556d0SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, recv_len, 0), recv_len);
877043556d0SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem + recv_len, recv_len, 0), 5);
878043556d0SJakub Kicinski 	EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0);
879043556d0SJakub Kicinski }
880043556d0SJakub Kicinski 
8817f657d5bSDave Watson TEST_F(tls, recv_partial)
8827f657d5bSDave Watson {
8837f657d5bSDave Watson 	char const *test_str = "test_read_partial";
8847f657d5bSDave Watson 	char const *test_str_first = "test_read";
8857f657d5bSDave Watson 	char const *test_str_second = "_partial";
8867f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
8877f657d5bSDave Watson 	char recv_mem[18];
8887f657d5bSDave Watson 
8897f657d5bSDave Watson 	memset(recv_mem, 0, sizeof(recv_mem));
8907f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
891cea3bfb3SVakul Garg 	EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_first),
892cea3bfb3SVakul Garg 		       MSG_WAITALL), -1);
8937f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str_first, recv_mem, strlen(test_str_first)), 0);
8947f657d5bSDave Watson 	memset(recv_mem, 0, sizeof(recv_mem));
895cea3bfb3SVakul Garg 	EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_second),
896cea3bfb3SVakul Garg 		       MSG_WAITALL), -1);
8977f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str_second, recv_mem, strlen(test_str_second)),
8987f657d5bSDave Watson 		  0);
8997f657d5bSDave Watson }
9007f657d5bSDave Watson 
9017f657d5bSDave Watson TEST_F(tls, recv_nonblock)
9027f657d5bSDave Watson {
9037f657d5bSDave Watson 	char buf[4096];
9047f657d5bSDave Watson 	bool err;
9057f657d5bSDave Watson 
9067f657d5bSDave Watson 	EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_DONTWAIT), -1);
9077f657d5bSDave Watson 	err = (errno == EAGAIN || errno == EWOULDBLOCK);
9087f657d5bSDave Watson 	EXPECT_EQ(err, true);
9097f657d5bSDave Watson }
9107f657d5bSDave Watson 
9117f657d5bSDave Watson TEST_F(tls, recv_peek)
9127f657d5bSDave Watson {
9137f657d5bSDave Watson 	char const *test_str = "test_read_peek";
9147f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
9157f657d5bSDave Watson 	char buf[15];
9167f657d5bSDave Watson 
9177f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
9187f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
9197f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
9207f657d5bSDave Watson 	memset(buf, 0, sizeof(buf));
9217f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
9227f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
9237f657d5bSDave Watson }
9247f657d5bSDave Watson 
9257f657d5bSDave Watson TEST_F(tls, recv_peek_multiple)
9267f657d5bSDave Watson {
9277f657d5bSDave Watson 	char const *test_str = "test_read_peek";
9287f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
9297f657d5bSDave Watson 	unsigned int num_peeks = 100;
9307f657d5bSDave Watson 	char buf[15];
9317f657d5bSDave Watson 	int i;
9327f657d5bSDave Watson 
9337f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
9347f657d5bSDave Watson 	for (i = 0; i < num_peeks; i++) {
9357f657d5bSDave Watson 		EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1);
9367f657d5bSDave Watson 		EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
9377f657d5bSDave Watson 		memset(buf, 0, sizeof(buf));
9387f657d5bSDave Watson 	}
9397f657d5bSDave Watson 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
9407f657d5bSDave Watson 	EXPECT_EQ(memcmp(test_str, buf, send_len), 0);
9417f657d5bSDave Watson }
9427f657d5bSDave Watson 
94350c6b58aSDaniel Borkmann TEST_F(tls, recv_peek_multiple_records)
94450c6b58aSDaniel Borkmann {
94550c6b58aSDaniel Borkmann 	char const *test_str = "test_read_peek_mult_recs";
94650c6b58aSDaniel Borkmann 	char const *test_str_first = "test_read_peek";
94750c6b58aSDaniel Borkmann 	char const *test_str_second = "_mult_recs";
94850c6b58aSDaniel Borkmann 	int len;
94950c6b58aSDaniel Borkmann 	char buf[64];
95050c6b58aSDaniel Borkmann 
95150c6b58aSDaniel Borkmann 	len = strlen(test_str_first);
95250c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
95350c6b58aSDaniel Borkmann 
95450c6b58aSDaniel Borkmann 	len = strlen(test_str_second) + 1;
95550c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
95650c6b58aSDaniel Borkmann 
9570ed3015cSVakul Garg 	len = strlen(test_str_first);
95850c6b58aSDaniel Borkmann 	memset(buf, 0, len);
9590ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_PEEK | MSG_WAITALL), len);
96050c6b58aSDaniel Borkmann 
96150c6b58aSDaniel Borkmann 	/* MSG_PEEK can only peek into the current record. */
9620ed3015cSVakul Garg 	len = strlen(test_str_first);
96350c6b58aSDaniel Borkmann 	EXPECT_EQ(memcmp(test_str_first, buf, len), 0);
96450c6b58aSDaniel Borkmann 
9650ed3015cSVakul Garg 	len = strlen(test_str) + 1;
96650c6b58aSDaniel Borkmann 	memset(buf, 0, len);
9670ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_WAITALL), len);
96850c6b58aSDaniel Borkmann 
96950c6b58aSDaniel Borkmann 	/* Non-MSG_PEEK will advance strparser (and therefore record)
97050c6b58aSDaniel Borkmann 	 * however.
97150c6b58aSDaniel Borkmann 	 */
97250c6b58aSDaniel Borkmann 	len = strlen(test_str) + 1;
97350c6b58aSDaniel Borkmann 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
97450c6b58aSDaniel Borkmann 
97550c6b58aSDaniel Borkmann 	/* MSG_MORE will hold current record open, so later MSG_PEEK
97650c6b58aSDaniel Borkmann 	 * will see everything.
97750c6b58aSDaniel Borkmann 	 */
97850c6b58aSDaniel Borkmann 	len = strlen(test_str_first);
97950c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_first, len, MSG_MORE), len);
98050c6b58aSDaniel Borkmann 
98150c6b58aSDaniel Borkmann 	len = strlen(test_str_second) + 1;
98250c6b58aSDaniel Borkmann 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
98350c6b58aSDaniel Borkmann 
9840ed3015cSVakul Garg 	len = strlen(test_str) + 1;
98550c6b58aSDaniel Borkmann 	memset(buf, 0, len);
9860ed3015cSVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, len, MSG_PEEK | MSG_WAITALL), len);
98750c6b58aSDaniel Borkmann 
98850c6b58aSDaniel Borkmann 	len = strlen(test_str) + 1;
98950c6b58aSDaniel Borkmann 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
99050c6b58aSDaniel Borkmann }
99150c6b58aSDaniel Borkmann 
992c2ad647cSVakul Garg TEST_F(tls, recv_peek_large_buf_mult_recs)
993c2ad647cSVakul Garg {
994c2ad647cSVakul Garg 	char const *test_str = "test_read_peek_mult_recs";
995c2ad647cSVakul Garg 	char const *test_str_first = "test_read_peek";
996c2ad647cSVakul Garg 	char const *test_str_second = "_mult_recs";
997c2ad647cSVakul Garg 	int len;
998c2ad647cSVakul Garg 	char buf[64];
999c2ad647cSVakul Garg 
1000c2ad647cSVakul Garg 	len = strlen(test_str_first);
1001c2ad647cSVakul Garg 	EXPECT_EQ(send(self->fd, test_str_first, len, 0), len);
1002c2ad647cSVakul Garg 
1003c2ad647cSVakul Garg 	len = strlen(test_str_second) + 1;
1004c2ad647cSVakul Garg 	EXPECT_EQ(send(self->fd, test_str_second, len, 0), len);
1005c2ad647cSVakul Garg 
1006cea3bfb3SVakul Garg 	len = strlen(test_str) + 1;
1007c2ad647cSVakul Garg 	memset(buf, 0, len);
1008cea3bfb3SVakul Garg 	EXPECT_NE((len = recv(self->cfd, buf, len,
1009cea3bfb3SVakul Garg 			      MSG_PEEK | MSG_WAITALL)), -1);
1010c2ad647cSVakul Garg 	len = strlen(test_str) + 1;
1011c2ad647cSVakul Garg 	EXPECT_EQ(memcmp(test_str, buf, len), 0);
1012c2ad647cSVakul Garg }
1013c2ad647cSVakul Garg 
10147718a855SJakub Kicinski TEST_F(tls, recv_lowat)
10157718a855SJakub Kicinski {
10167718a855SJakub Kicinski 	char send_mem[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
10177718a855SJakub Kicinski 	char recv_mem[20];
10187718a855SJakub Kicinski 	int lowat = 8;
10197718a855SJakub Kicinski 
10207718a855SJakub Kicinski 	EXPECT_EQ(send(self->fd, send_mem, 10, 0), 10);
10217718a855SJakub Kicinski 	EXPECT_EQ(send(self->fd, send_mem, 5, 0), 5);
10227718a855SJakub Kicinski 
10237718a855SJakub Kicinski 	memset(recv_mem, 0, 20);
10247718a855SJakub Kicinski 	EXPECT_EQ(setsockopt(self->cfd, SOL_SOCKET, SO_RCVLOWAT,
10257718a855SJakub Kicinski 			     &lowat, sizeof(lowat)), 0);
10267718a855SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, 1, MSG_WAITALL), 1);
10277718a855SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem + 1, 6, MSG_WAITALL), 6);
10287718a855SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem + 7, 10, 0), 8);
10297718a855SJakub Kicinski 
10307718a855SJakub Kicinski 	EXPECT_EQ(memcmp(send_mem, recv_mem, 10), 0);
10317718a855SJakub Kicinski 	EXPECT_EQ(memcmp(send_mem, recv_mem + 10, 5), 0);
10327718a855SJakub Kicinski }
1033e366fa43SDavid S. Miller 
103465d41fb3SJakub Kicinski TEST_F(tls, bidir)
103565d41fb3SJakub Kicinski {
103665d41fb3SJakub Kicinski 	char const *test_str = "test_read";
103765d41fb3SJakub Kicinski 	int send_len = 10;
103865d41fb3SJakub Kicinski 	char buf[10];
103965d41fb3SJakub Kicinski 	int ret;
104065d41fb3SJakub Kicinski 
1041e29903c4SJakub Kicinski 	if (!self->notls) {
1042291c53e4SJakub Kicinski 		struct tls_crypto_info_keys tls12;
1043e29903c4SJakub Kicinski 
1044291c53e4SJakub Kicinski 		tls_crypto_info_init(variant->tls_version, variant->cipher_type,
1045291c53e4SJakub Kicinski 				     &tls12);
104665d41fb3SJakub Kicinski 
1047e29903c4SJakub Kicinski 		ret = setsockopt(self->fd, SOL_TLS, TLS_RX, &tls12,
1048291c53e4SJakub Kicinski 				 tls12.len);
104965d41fb3SJakub Kicinski 		ASSERT_EQ(ret, 0);
105065d41fb3SJakub Kicinski 
1051e29903c4SJakub Kicinski 		ret = setsockopt(self->cfd, SOL_TLS, TLS_TX, &tls12,
1052291c53e4SJakub Kicinski 				 tls12.len);
105365d41fb3SJakub Kicinski 		ASSERT_EQ(ret, 0);
1054e29903c4SJakub Kicinski 	}
105565d41fb3SJakub Kicinski 
105665d41fb3SJakub Kicinski 	ASSERT_EQ(strlen(test_str) + 1, send_len);
105765d41fb3SJakub Kicinski 
105865d41fb3SJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
105965d41fb3SJakub Kicinski 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
106065d41fb3SJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
106165d41fb3SJakub Kicinski 
106265d41fb3SJakub Kicinski 	memset(buf, 0, sizeof(buf));
106365d41fb3SJakub Kicinski 
106465d41fb3SJakub Kicinski 	EXPECT_EQ(send(self->cfd, test_str, send_len, 0), send_len);
106565d41fb3SJakub Kicinski 	EXPECT_NE(recv(self->fd, buf, send_len, 0), -1);
106665d41fb3SJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
106765d41fb3SJakub Kicinski };
106865d41fb3SJakub Kicinski 
10697f657d5bSDave Watson TEST_F(tls, pollin)
10707f657d5bSDave Watson {
10717f657d5bSDave Watson 	char const *test_str = "test_poll";
10727f657d5bSDave Watson 	struct pollfd fd = { 0, 0, 0 };
10737f657d5bSDave Watson 	char buf[10];
10747f657d5bSDave Watson 	int send_len = 10;
10757f657d5bSDave Watson 
10767f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
10777f657d5bSDave Watson 	fd.fd = self->cfd;
10787f657d5bSDave Watson 	fd.events = POLLIN;
10797f657d5bSDave Watson 
10807f657d5bSDave Watson 	EXPECT_EQ(poll(&fd, 1, 20), 1);
10817f657d5bSDave Watson 	EXPECT_EQ(fd.revents & POLLIN, 1);
10820185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_WAITALL), send_len);
10837f657d5bSDave Watson 	/* Test timing out */
10847f657d5bSDave Watson 	EXPECT_EQ(poll(&fd, 1, 20), 0);
10857f657d5bSDave Watson }
10867f657d5bSDave Watson 
10877f657d5bSDave Watson TEST_F(tls, poll_wait)
10887f657d5bSDave Watson {
10897f657d5bSDave Watson 	char const *test_str = "test_poll_wait";
10907f657d5bSDave Watson 	int send_len = strlen(test_str) + 1;
10917f657d5bSDave Watson 	struct pollfd fd = { 0, 0, 0 };
10927f657d5bSDave Watson 	char recv_mem[15];
10937f657d5bSDave Watson 
10947f657d5bSDave Watson 	fd.fd = self->cfd;
10957f657d5bSDave Watson 	fd.events = POLLIN;
10967f657d5bSDave Watson 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
10977f657d5bSDave Watson 	/* Set timeout to inf. secs */
10987f657d5bSDave Watson 	EXPECT_EQ(poll(&fd, 1, -1), 1);
10997f657d5bSDave Watson 	EXPECT_EQ(fd.revents & POLLIN, 1);
11000185e2e6SVakul Garg 	EXPECT_EQ(recv(self->cfd, recv_mem, send_len, MSG_WAITALL), send_len);
11017f657d5bSDave Watson }
11027f657d5bSDave Watson 
110381a89ef6SJakub Kicinski TEST_F(tls, poll_wait_split)
110481a89ef6SJakub Kicinski {
110581a89ef6SJakub Kicinski 	struct pollfd fd = { 0, 0, 0 };
110681a89ef6SJakub Kicinski 	char send_mem[20] = {};
110781a89ef6SJakub Kicinski 	char recv_mem[15];
110881a89ef6SJakub Kicinski 
110981a89ef6SJakub Kicinski 	fd.fd = self->cfd;
111081a89ef6SJakub Kicinski 	fd.events = POLLIN;
111181a89ef6SJakub Kicinski 	/* Send 20 bytes */
111281a89ef6SJakub Kicinski 	EXPECT_EQ(send(self->fd, send_mem, sizeof(send_mem), 0),
111381a89ef6SJakub Kicinski 		  sizeof(send_mem));
111481a89ef6SJakub Kicinski 	/* Poll with inf. timeout */
111581a89ef6SJakub Kicinski 	EXPECT_EQ(poll(&fd, 1, -1), 1);
111681a89ef6SJakub Kicinski 	EXPECT_EQ(fd.revents & POLLIN, 1);
111781a89ef6SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), MSG_WAITALL),
111881a89ef6SJakub Kicinski 		  sizeof(recv_mem));
111981a89ef6SJakub Kicinski 
112081a89ef6SJakub Kicinski 	/* Now the remaining 5 bytes of record data are in TLS ULP */
112181a89ef6SJakub Kicinski 	fd.fd = self->cfd;
112281a89ef6SJakub Kicinski 	fd.events = POLLIN;
112381a89ef6SJakub Kicinski 	EXPECT_EQ(poll(&fd, 1, -1), 1);
112481a89ef6SJakub Kicinski 	EXPECT_EQ(fd.revents & POLLIN, 1);
112581a89ef6SJakub Kicinski 	EXPECT_EQ(recv(self->cfd, recv_mem, sizeof(recv_mem), 0),
112681a89ef6SJakub Kicinski 		  sizeof(send_mem) - sizeof(recv_mem));
112781a89ef6SJakub Kicinski }
112881a89ef6SJakub Kicinski 
11297f657d5bSDave Watson TEST_F(tls, blocking)
11307f657d5bSDave Watson {
11317f657d5bSDave Watson 	size_t data = 100000;
11327f657d5bSDave Watson 	int res = fork();
11337f657d5bSDave Watson 
11347f657d5bSDave Watson 	EXPECT_NE(res, -1);
11357f657d5bSDave Watson 
11367f657d5bSDave Watson 	if (res) {
11377f657d5bSDave Watson 		/* parent */
11387f657d5bSDave Watson 		size_t left = data;
11397f657d5bSDave Watson 		char buf[16384];
11407f657d5bSDave Watson 		int status;
11417f657d5bSDave Watson 		int pid2;
11427f657d5bSDave Watson 
11437f657d5bSDave Watson 		while (left) {
11447f657d5bSDave Watson 			int res = send(self->fd, buf,
11457f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
11467f657d5bSDave Watson 
11477f657d5bSDave Watson 			EXPECT_GE(res, 0);
11487f657d5bSDave Watson 			left -= res;
11497f657d5bSDave Watson 		}
11507f657d5bSDave Watson 
11517f657d5bSDave Watson 		pid2 = wait(&status);
11527f657d5bSDave Watson 		EXPECT_EQ(status, 0);
11537f657d5bSDave Watson 		EXPECT_EQ(res, pid2);
11547f657d5bSDave Watson 	} else {
11557f657d5bSDave Watson 		/* child */
11567f657d5bSDave Watson 		size_t left = data;
11577f657d5bSDave Watson 		char buf[16384];
11587f657d5bSDave Watson 
11597f657d5bSDave Watson 		while (left) {
11607f657d5bSDave Watson 			int res = recv(self->cfd, buf,
11617f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
11627f657d5bSDave Watson 
11637f657d5bSDave Watson 			EXPECT_GE(res, 0);
11647f657d5bSDave Watson 			left -= res;
11657f657d5bSDave Watson 		}
11667f657d5bSDave Watson 	}
11677f657d5bSDave Watson }
11687f657d5bSDave Watson 
11697f657d5bSDave Watson TEST_F(tls, nonblocking)
11707f657d5bSDave Watson {
11717f657d5bSDave Watson 	size_t data = 100000;
11727f657d5bSDave Watson 	int sendbuf = 100;
11737f657d5bSDave Watson 	int flags;
11747f657d5bSDave Watson 	int res;
11757f657d5bSDave Watson 
11767f657d5bSDave Watson 	flags = fcntl(self->fd, F_GETFL, 0);
11777f657d5bSDave Watson 	fcntl(self->fd, F_SETFL, flags | O_NONBLOCK);
11787f657d5bSDave Watson 	fcntl(self->cfd, F_SETFL, flags | O_NONBLOCK);
11797f657d5bSDave Watson 
11807f657d5bSDave Watson 	/* Ensure nonblocking behavior by imposing a small send
11817f657d5bSDave Watson 	 * buffer.
11827f657d5bSDave Watson 	 */
11837f657d5bSDave Watson 	EXPECT_EQ(setsockopt(self->fd, SOL_SOCKET, SO_SNDBUF,
11847f657d5bSDave Watson 			     &sendbuf, sizeof(sendbuf)), 0);
11857f657d5bSDave Watson 
11867f657d5bSDave Watson 	res = fork();
11877f657d5bSDave Watson 	EXPECT_NE(res, -1);
11887f657d5bSDave Watson 
11897f657d5bSDave Watson 	if (res) {
11907f657d5bSDave Watson 		/* parent */
11917f657d5bSDave Watson 		bool eagain = false;
11927f657d5bSDave Watson 		size_t left = data;
11937f657d5bSDave Watson 		char buf[16384];
11947f657d5bSDave Watson 		int status;
11957f657d5bSDave Watson 		int pid2;
11967f657d5bSDave Watson 
11977f657d5bSDave Watson 		while (left) {
11987f657d5bSDave Watson 			int res = send(self->fd, buf,
11997f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
12007f657d5bSDave Watson 
12017f657d5bSDave Watson 			if (res == -1 && errno == EAGAIN) {
12027f657d5bSDave Watson 				eagain = true;
12037f657d5bSDave Watson 				usleep(10000);
12047f657d5bSDave Watson 				continue;
12057f657d5bSDave Watson 			}
12067f657d5bSDave Watson 			EXPECT_GE(res, 0);
12077f657d5bSDave Watson 			left -= res;
12087f657d5bSDave Watson 		}
12097f657d5bSDave Watson 
12107f657d5bSDave Watson 		EXPECT_TRUE(eagain);
12117f657d5bSDave Watson 		pid2 = wait(&status);
12127f657d5bSDave Watson 
12137f657d5bSDave Watson 		EXPECT_EQ(status, 0);
12147f657d5bSDave Watson 		EXPECT_EQ(res, pid2);
12157f657d5bSDave Watson 	} else {
12167f657d5bSDave Watson 		/* child */
12177f657d5bSDave Watson 		bool eagain = false;
12187f657d5bSDave Watson 		size_t left = data;
12197f657d5bSDave Watson 		char buf[16384];
12207f657d5bSDave Watson 
12217f657d5bSDave Watson 		while (left) {
12227f657d5bSDave Watson 			int res = recv(self->cfd, buf,
12237f657d5bSDave Watson 				       left > 16384 ? 16384 : left, 0);
12247f657d5bSDave Watson 
12257f657d5bSDave Watson 			if (res == -1 && errno == EAGAIN) {
12267f657d5bSDave Watson 				eagain = true;
12277f657d5bSDave Watson 				usleep(10000);
12287f657d5bSDave Watson 				continue;
12297f657d5bSDave Watson 			}
12307f657d5bSDave Watson 			EXPECT_GE(res, 0);
12317f657d5bSDave Watson 			left -= res;
12327f657d5bSDave Watson 		}
12337f657d5bSDave Watson 		EXPECT_TRUE(eagain);
12347f657d5bSDave Watson 	}
12357f657d5bSDave Watson }
12367f657d5bSDave Watson 
123741098af5SJakub Kicinski static void
123841098af5SJakub Kicinski test_mutliproc(struct __test_metadata *_metadata, struct _test_data_tls *self,
123941098af5SJakub Kicinski 	       bool sendpg, unsigned int n_readers, unsigned int n_writers)
124041098af5SJakub Kicinski {
124141098af5SJakub Kicinski 	const unsigned int n_children = n_readers + n_writers;
124241098af5SJakub Kicinski 	const size_t data = 6 * 1000 * 1000;
124341098af5SJakub Kicinski 	const size_t file_sz = data / 100;
124441098af5SJakub Kicinski 	size_t read_bias, write_bias;
124541098af5SJakub Kicinski 	int i, fd, child_id;
124641098af5SJakub Kicinski 	char buf[file_sz];
124741098af5SJakub Kicinski 	pid_t pid;
124841098af5SJakub Kicinski 
124941098af5SJakub Kicinski 	/* Only allow multiples for simplicity */
125041098af5SJakub Kicinski 	ASSERT_EQ(!(n_readers % n_writers) || !(n_writers % n_readers), true);
125141098af5SJakub Kicinski 	read_bias = n_writers / n_readers ?: 1;
125241098af5SJakub Kicinski 	write_bias = n_readers / n_writers ?: 1;
125341098af5SJakub Kicinski 
125441098af5SJakub Kicinski 	/* prep a file to send */
125541098af5SJakub Kicinski 	fd = open("/tmp/", O_TMPFILE | O_RDWR, 0600);
125641098af5SJakub Kicinski 	ASSERT_GE(fd, 0);
125741098af5SJakub Kicinski 
125841098af5SJakub Kicinski 	memset(buf, 0xac, file_sz);
125941098af5SJakub Kicinski 	ASSERT_EQ(write(fd, buf, file_sz), file_sz);
126041098af5SJakub Kicinski 
126141098af5SJakub Kicinski 	/* spawn children */
126241098af5SJakub Kicinski 	for (child_id = 0; child_id < n_children; child_id++) {
126341098af5SJakub Kicinski 		pid = fork();
126441098af5SJakub Kicinski 		ASSERT_NE(pid, -1);
126541098af5SJakub Kicinski 		if (!pid)
126641098af5SJakub Kicinski 			break;
126741098af5SJakub Kicinski 	}
126841098af5SJakub Kicinski 
126941098af5SJakub Kicinski 	/* parent waits for all children */
127041098af5SJakub Kicinski 	if (pid) {
127141098af5SJakub Kicinski 		for (i = 0; i < n_children; i++) {
127241098af5SJakub Kicinski 			int status;
127341098af5SJakub Kicinski 
127441098af5SJakub Kicinski 			wait(&status);
127541098af5SJakub Kicinski 			EXPECT_EQ(status, 0);
127641098af5SJakub Kicinski 		}
127741098af5SJakub Kicinski 
127841098af5SJakub Kicinski 		return;
127941098af5SJakub Kicinski 	}
128041098af5SJakub Kicinski 
128141098af5SJakub Kicinski 	/* Split threads for reading and writing */
128241098af5SJakub Kicinski 	if (child_id < n_readers) {
128341098af5SJakub Kicinski 		size_t left = data * read_bias;
128441098af5SJakub Kicinski 		char rb[8001];
128541098af5SJakub Kicinski 
128641098af5SJakub Kicinski 		while (left) {
128741098af5SJakub Kicinski 			int res;
128841098af5SJakub Kicinski 
128941098af5SJakub Kicinski 			res = recv(self->cfd, rb,
129041098af5SJakub Kicinski 				   left > sizeof(rb) ? sizeof(rb) : left, 0);
129141098af5SJakub Kicinski 
129241098af5SJakub Kicinski 			EXPECT_GE(res, 0);
129341098af5SJakub Kicinski 			left -= res;
129441098af5SJakub Kicinski 		}
129541098af5SJakub Kicinski 	} else {
129641098af5SJakub Kicinski 		size_t left = data * write_bias;
129741098af5SJakub Kicinski 
129841098af5SJakub Kicinski 		while (left) {
129941098af5SJakub Kicinski 			int res;
130041098af5SJakub Kicinski 
130141098af5SJakub Kicinski 			ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
130241098af5SJakub Kicinski 			if (sendpg)
130341098af5SJakub Kicinski 				res = sendfile(self->fd, fd, NULL,
130441098af5SJakub Kicinski 					       left > file_sz ? file_sz : left);
130541098af5SJakub Kicinski 			else
130641098af5SJakub Kicinski 				res = send(self->fd, buf,
130741098af5SJakub Kicinski 					   left > file_sz ? file_sz : left, 0);
130841098af5SJakub Kicinski 
130941098af5SJakub Kicinski 			EXPECT_GE(res, 0);
131041098af5SJakub Kicinski 			left -= res;
131141098af5SJakub Kicinski 		}
131241098af5SJakub Kicinski 	}
131341098af5SJakub Kicinski }
131441098af5SJakub Kicinski 
131541098af5SJakub Kicinski TEST_F(tls, mutliproc_even)
131641098af5SJakub Kicinski {
131741098af5SJakub Kicinski 	test_mutliproc(_metadata, self, false, 6, 6);
131841098af5SJakub Kicinski }
131941098af5SJakub Kicinski 
132041098af5SJakub Kicinski TEST_F(tls, mutliproc_readers)
132141098af5SJakub Kicinski {
132241098af5SJakub Kicinski 	test_mutliproc(_metadata, self, false, 4, 12);
132341098af5SJakub Kicinski }
132441098af5SJakub Kicinski 
132541098af5SJakub Kicinski TEST_F(tls, mutliproc_writers)
132641098af5SJakub Kicinski {
132741098af5SJakub Kicinski 	test_mutliproc(_metadata, self, false, 10, 2);
132841098af5SJakub Kicinski }
132941098af5SJakub Kicinski 
133041098af5SJakub Kicinski TEST_F(tls, mutliproc_sendpage_even)
133141098af5SJakub Kicinski {
133241098af5SJakub Kicinski 	test_mutliproc(_metadata, self, true, 6, 6);
133341098af5SJakub Kicinski }
133441098af5SJakub Kicinski 
133541098af5SJakub Kicinski TEST_F(tls, mutliproc_sendpage_readers)
133641098af5SJakub Kicinski {
133741098af5SJakub Kicinski 	test_mutliproc(_metadata, self, true, 4, 12);
133841098af5SJakub Kicinski }
133941098af5SJakub Kicinski 
134041098af5SJakub Kicinski TEST_F(tls, mutliproc_sendpage_writers)
134141098af5SJakub Kicinski {
134241098af5SJakub Kicinski 	test_mutliproc(_metadata, self, true, 10, 2);
134341098af5SJakub Kicinski }
134441098af5SJakub Kicinski 
13457f657d5bSDave Watson TEST_F(tls, control_msg)
13467f657d5bSDave Watson {
134731180adbSJakub Kicinski 	char *test_str = "test_read";
13487f657d5bSDave Watson 	char record_type = 100;
13497f657d5bSDave Watson 	int send_len = 10;
13507f657d5bSDave Watson 	char buf[10];
13517f657d5bSDave Watson 
135231180adbSJakub Kicinski 	if (self->notls)
135331180adbSJakub Kicinski 		SKIP(return, "no TLS support");
13547f657d5bSDave Watson 
135531180adbSJakub Kicinski 	EXPECT_EQ(tls_send_cmsg(self->fd, record_type, test_str, send_len, 0),
135631180adbSJakub Kicinski 		  send_len);
13577f657d5bSDave Watson 	/* Should fail because we didn't provide a control message */
13587f657d5bSDave Watson 	EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
13597f657d5bSDave Watson 
136031180adbSJakub Kicinski 	EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
136131180adbSJakub Kicinski 				buf, sizeof(buf), MSG_WAITALL | MSG_PEEK),
136231180adbSJakub Kicinski 		  send_len);
1363203ef5f1SVakul Garg 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
1364203ef5f1SVakul Garg 
1365203ef5f1SVakul Garg 	/* Recv the message again without MSG_PEEK */
1366203ef5f1SVakul Garg 	memset(buf, 0, sizeof(buf));
1367203ef5f1SVakul Garg 
136831180adbSJakub Kicinski 	EXPECT_EQ(tls_recv_cmsg(_metadata, self->cfd, record_type,
136931180adbSJakub Kicinski 				buf, sizeof(buf), MSG_WAITALL),
137031180adbSJakub Kicinski 		  send_len);
13717f657d5bSDave Watson 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
13727f657d5bSDave Watson }
13737f657d5bSDave Watson 
1374d4d34185SJakub Kicinski TEST_F(tls, shutdown)
1375d4d34185SJakub Kicinski {
1376d4d34185SJakub Kicinski 	char const *test_str = "test_read";
1377d4d34185SJakub Kicinski 	int send_len = 10;
1378d4d34185SJakub Kicinski 	char buf[10];
1379d4d34185SJakub Kicinski 
1380d4d34185SJakub Kicinski 	ASSERT_EQ(strlen(test_str) + 1, send_len);
1381d4d34185SJakub Kicinski 
1382d4d34185SJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len);
1383d4d34185SJakub Kicinski 	EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1);
1384d4d34185SJakub Kicinski 	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
1385d4d34185SJakub Kicinski 
1386d4d34185SJakub Kicinski 	shutdown(self->fd, SHUT_RDWR);
1387d4d34185SJakub Kicinski 	shutdown(self->cfd, SHUT_RDWR);
1388d4d34185SJakub Kicinski }
1389d4d34185SJakub Kicinski 
1390d4d34185SJakub Kicinski TEST_F(tls, shutdown_unsent)
1391d4d34185SJakub Kicinski {
1392d4d34185SJakub Kicinski 	char const *test_str = "test_read";
1393d4d34185SJakub Kicinski 	int send_len = 10;
1394d4d34185SJakub Kicinski 
1395d4d34185SJakub Kicinski 	EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len);
1396d4d34185SJakub Kicinski 
1397d4d34185SJakub Kicinski 	shutdown(self->fd, SHUT_RDWR);
1398d4d34185SJakub Kicinski 	shutdown(self->cfd, SHUT_RDWR);
1399d4d34185SJakub Kicinski }
1400d4d34185SJakub Kicinski 
1401cd114d2eSJakub Kicinski TEST_F(tls, shutdown_reuse)
1402cd114d2eSJakub Kicinski {
1403cd114d2eSJakub Kicinski 	struct sockaddr_in addr;
1404cd114d2eSJakub Kicinski 	int ret;
1405cd114d2eSJakub Kicinski 
1406cd114d2eSJakub Kicinski 	shutdown(self->fd, SHUT_RDWR);
1407cd114d2eSJakub Kicinski 	shutdown(self->cfd, SHUT_RDWR);
1408cd114d2eSJakub Kicinski 	close(self->cfd);
1409cd114d2eSJakub Kicinski 
1410cd114d2eSJakub Kicinski 	addr.sin_family = AF_INET;
1411cd114d2eSJakub Kicinski 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
1412cd114d2eSJakub Kicinski 	addr.sin_port = 0;
1413cd114d2eSJakub Kicinski 
1414cd114d2eSJakub Kicinski 	ret = bind(self->fd, &addr, sizeof(addr));
1415cd114d2eSJakub Kicinski 	EXPECT_EQ(ret, 0);
1416cd114d2eSJakub Kicinski 	ret = listen(self->fd, 10);
1417cd114d2eSJakub Kicinski 	EXPECT_EQ(ret, -1);
1418cd114d2eSJakub Kicinski 	EXPECT_EQ(errno, EINVAL);
1419cd114d2eSJakub Kicinski 
1420cd114d2eSJakub Kicinski 	ret = connect(self->fd, &addr, sizeof(addr));
1421cd114d2eSJakub Kicinski 	EXPECT_EQ(ret, -1);
1422cd114d2eSJakub Kicinski 	EXPECT_EQ(errno, EISCONN);
1423cd114d2eSJakub Kicinski }
1424cd114d2eSJakub Kicinski 
1425ef0fc0b3SJakub Kicinski FIXTURE(tls_err)
1426ef0fc0b3SJakub Kicinski {
1427ef0fc0b3SJakub Kicinski 	int fd, cfd;
1428ef0fc0b3SJakub Kicinski 	int fd2, cfd2;
1429ef0fc0b3SJakub Kicinski 	bool notls;
1430ef0fc0b3SJakub Kicinski };
1431ef0fc0b3SJakub Kicinski 
1432ef0fc0b3SJakub Kicinski FIXTURE_VARIANT(tls_err)
1433ef0fc0b3SJakub Kicinski {
1434ef0fc0b3SJakub Kicinski 	uint16_t tls_version;
1435ef0fc0b3SJakub Kicinski };
1436ef0fc0b3SJakub Kicinski 
1437ef0fc0b3SJakub Kicinski FIXTURE_VARIANT_ADD(tls_err, 12_aes_gcm)
1438ef0fc0b3SJakub Kicinski {
1439ef0fc0b3SJakub Kicinski 	.tls_version = TLS_1_2_VERSION,
1440ef0fc0b3SJakub Kicinski };
1441ef0fc0b3SJakub Kicinski 
1442ef0fc0b3SJakub Kicinski FIXTURE_VARIANT_ADD(tls_err, 13_aes_gcm)
1443ef0fc0b3SJakub Kicinski {
1444ef0fc0b3SJakub Kicinski 	.tls_version = TLS_1_3_VERSION,
1445ef0fc0b3SJakub Kicinski };
1446ef0fc0b3SJakub Kicinski 
1447ef0fc0b3SJakub Kicinski FIXTURE_SETUP(tls_err)
1448ef0fc0b3SJakub Kicinski {
1449ef0fc0b3SJakub Kicinski 	struct tls_crypto_info_keys tls12;
1450ef0fc0b3SJakub Kicinski 	int ret;
1451ef0fc0b3SJakub Kicinski 
1452ef0fc0b3SJakub Kicinski 	tls_crypto_info_init(variant->tls_version, TLS_CIPHER_AES_GCM_128,
1453ef0fc0b3SJakub Kicinski 			     &tls12);
1454ef0fc0b3SJakub Kicinski 
1455ef0fc0b3SJakub Kicinski 	ulp_sock_pair(_metadata, &self->fd, &self->cfd, &self->notls);
1456ef0fc0b3SJakub Kicinski 	ulp_sock_pair(_metadata, &self->fd2, &self->cfd2, &self->notls);
1457ef0fc0b3SJakub Kicinski 	if (self->notls)
1458ef0fc0b3SJakub Kicinski 		return;
1459ef0fc0b3SJakub Kicinski 
1460ef0fc0b3SJakub Kicinski 	ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, tls12.len);
1461ef0fc0b3SJakub Kicinski 	ASSERT_EQ(ret, 0);
1462ef0fc0b3SJakub Kicinski 
1463ef0fc0b3SJakub Kicinski 	ret = setsockopt(self->cfd2, SOL_TLS, TLS_RX, &tls12, tls12.len);
1464ef0fc0b3SJakub Kicinski 	ASSERT_EQ(ret, 0);
1465ef0fc0b3SJakub Kicinski }
1466ef0fc0b3SJakub Kicinski 
1467ef0fc0b3SJakub Kicinski FIXTURE_TEARDOWN(tls_err)
1468ef0fc0b3SJakub Kicinski {
1469ef0fc0b3SJakub Kicinski 	close(self->fd);
1470ef0fc0b3SJakub Kicinski 	close(self->cfd);
1471ef0fc0b3SJakub Kicinski 	close(self->fd2);
1472ef0fc0b3SJakub Kicinski 	close(self->cfd2);
1473ef0fc0b3SJakub Kicinski }
1474ef0fc0b3SJakub Kicinski 
1475ef0fc0b3SJakub Kicinski TEST_F(tls_err, bad_rec)
1476ef0fc0b3SJakub Kicinski {
1477ef0fc0b3SJakub Kicinski 	char buf[64];
1478ef0fc0b3SJakub Kicinski 
1479ef0fc0b3SJakub Kicinski 	if (self->notls)
1480ef0fc0b3SJakub Kicinski 		SKIP(return, "no TLS support");
1481ef0fc0b3SJakub Kicinski 
1482ef0fc0b3SJakub Kicinski 	memset(buf, 0x55, sizeof(buf));
1483ef0fc0b3SJakub Kicinski 	EXPECT_EQ(send(self->fd2, buf, sizeof(buf), 0), sizeof(buf));
1484ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1485ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EMSGSIZE);
1486ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), MSG_DONTWAIT), -1);
1487ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EAGAIN);
1488ef0fc0b3SJakub Kicinski }
1489ef0fc0b3SJakub Kicinski 
1490ef0fc0b3SJakub Kicinski TEST_F(tls_err, bad_auth)
1491ef0fc0b3SJakub Kicinski {
1492ef0fc0b3SJakub Kicinski 	char buf[128];
1493ef0fc0b3SJakub Kicinski 	int n;
1494ef0fc0b3SJakub Kicinski 
1495ef0fc0b3SJakub Kicinski 	if (self->notls)
1496ef0fc0b3SJakub Kicinski 		SKIP(return, "no TLS support");
1497ef0fc0b3SJakub Kicinski 
1498ef0fc0b3SJakub Kicinski 	memrnd(buf, sizeof(buf) / 2);
1499ef0fc0b3SJakub Kicinski 	EXPECT_EQ(send(self->fd, buf, sizeof(buf) / 2, 0), sizeof(buf) / 2);
1500ef0fc0b3SJakub Kicinski 	n = recv(self->cfd, buf, sizeof(buf), 0);
1501ef0fc0b3SJakub Kicinski 	EXPECT_GT(n, sizeof(buf) / 2);
1502ef0fc0b3SJakub Kicinski 
1503ef0fc0b3SJakub Kicinski 	buf[n - 1]++;
1504ef0fc0b3SJakub Kicinski 
1505ef0fc0b3SJakub Kicinski 	EXPECT_EQ(send(self->fd2, buf, n, 0), n);
1506ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1507ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EBADMSG);
1508ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1509ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EBADMSG);
1510ef0fc0b3SJakub Kicinski }
1511ef0fc0b3SJakub Kicinski 
1512ef0fc0b3SJakub Kicinski TEST_F(tls_err, bad_in_large_read)
1513ef0fc0b3SJakub Kicinski {
1514ef0fc0b3SJakub Kicinski 	char txt[3][64];
1515ef0fc0b3SJakub Kicinski 	char cip[3][128];
1516ef0fc0b3SJakub Kicinski 	char buf[3 * 128];
1517ef0fc0b3SJakub Kicinski 	int i, n;
1518ef0fc0b3SJakub Kicinski 
1519ef0fc0b3SJakub Kicinski 	if (self->notls)
1520ef0fc0b3SJakub Kicinski 		SKIP(return, "no TLS support");
1521ef0fc0b3SJakub Kicinski 
1522ef0fc0b3SJakub Kicinski 	/* Put 3 records in the sockets */
1523ef0fc0b3SJakub Kicinski 	for (i = 0; i < 3; i++) {
1524ef0fc0b3SJakub Kicinski 		memrnd(txt[i], sizeof(txt[i]));
1525ef0fc0b3SJakub Kicinski 		EXPECT_EQ(send(self->fd, txt[i], sizeof(txt[i]), 0),
1526ef0fc0b3SJakub Kicinski 			  sizeof(txt[i]));
1527ef0fc0b3SJakub Kicinski 		n = recv(self->cfd, cip[i], sizeof(cip[i]), 0);
1528ef0fc0b3SJakub Kicinski 		EXPECT_GT(n, sizeof(txt[i]));
1529ef0fc0b3SJakub Kicinski 		/* Break the third message */
1530ef0fc0b3SJakub Kicinski 		if (i == 2)
1531ef0fc0b3SJakub Kicinski 			cip[2][n - 1]++;
1532ef0fc0b3SJakub Kicinski 		EXPECT_EQ(send(self->fd2, cip[i], n, 0), n);
1533ef0fc0b3SJakub Kicinski 	}
1534ef0fc0b3SJakub Kicinski 
1535ef0fc0b3SJakub Kicinski 	/* We should be able to receive the first two messages */
1536ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), sizeof(txt[0]) * 2);
1537ef0fc0b3SJakub Kicinski 	EXPECT_EQ(memcmp(buf, txt[0], sizeof(txt[0])), 0);
1538ef0fc0b3SJakub Kicinski 	EXPECT_EQ(memcmp(buf + sizeof(txt[0]), txt[1], sizeof(txt[1])), 0);
1539ef0fc0b3SJakub Kicinski 	/* Third mesasge is bad */
1540ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1541ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EBADMSG);
1542ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1543ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EBADMSG);
1544ef0fc0b3SJakub Kicinski }
1545ef0fc0b3SJakub Kicinski 
1546ef0fc0b3SJakub Kicinski TEST_F(tls_err, bad_cmsg)
1547ef0fc0b3SJakub Kicinski {
1548ef0fc0b3SJakub Kicinski 	char *test_str = "test_read";
1549ef0fc0b3SJakub Kicinski 	int send_len = 10;
1550ef0fc0b3SJakub Kicinski 	char cip[128];
1551ef0fc0b3SJakub Kicinski 	char buf[128];
1552ef0fc0b3SJakub Kicinski 	char txt[64];
1553ef0fc0b3SJakub Kicinski 	int n;
1554ef0fc0b3SJakub Kicinski 
1555ef0fc0b3SJakub Kicinski 	if (self->notls)
1556ef0fc0b3SJakub Kicinski 		SKIP(return, "no TLS support");
1557ef0fc0b3SJakub Kicinski 
1558ef0fc0b3SJakub Kicinski 	/* Queue up one data record */
1559ef0fc0b3SJakub Kicinski 	memrnd(txt, sizeof(txt));
1560ef0fc0b3SJakub Kicinski 	EXPECT_EQ(send(self->fd, txt, sizeof(txt), 0), sizeof(txt));
1561ef0fc0b3SJakub Kicinski 	n = recv(self->cfd, cip, sizeof(cip), 0);
1562ef0fc0b3SJakub Kicinski 	EXPECT_GT(n, sizeof(txt));
1563ef0fc0b3SJakub Kicinski 	EXPECT_EQ(send(self->fd2, cip, n, 0), n);
1564ef0fc0b3SJakub Kicinski 
1565ef0fc0b3SJakub Kicinski 	EXPECT_EQ(tls_send_cmsg(self->fd, 100, test_str, send_len, 0), 10);
1566ef0fc0b3SJakub Kicinski 	n = recv(self->cfd, cip, sizeof(cip), 0);
1567ef0fc0b3SJakub Kicinski 	cip[n - 1]++; /* Break it */
1568ef0fc0b3SJakub Kicinski 	EXPECT_GT(n, send_len);
1569ef0fc0b3SJakub Kicinski 	EXPECT_EQ(send(self->fd2, cip, n, 0), n);
1570ef0fc0b3SJakub Kicinski 
1571ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), sizeof(txt));
1572ef0fc0b3SJakub Kicinski 	EXPECT_EQ(memcmp(buf, txt, sizeof(txt)), 0);
1573ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1574ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EBADMSG);
1575ef0fc0b3SJakub Kicinski 	EXPECT_EQ(recv(self->cfd2, buf, sizeof(buf), 0), -1);
1576ef0fc0b3SJakub Kicinski 	EXPECT_EQ(errno, EBADMSG);
1577ef0fc0b3SJakub Kicinski }
1578ef0fc0b3SJakub Kicinski 
157978b5dc3dSJakub Kicinski TEST(non_established) {
158078b5dc3dSJakub Kicinski 	struct tls12_crypto_info_aes_gcm_256 tls12;
158178b5dc3dSJakub Kicinski 	struct sockaddr_in addr;
158278b5dc3dSJakub Kicinski 	int sfd, ret, fd;
158378b5dc3dSJakub Kicinski 	socklen_t len;
158478b5dc3dSJakub Kicinski 
158578b5dc3dSJakub Kicinski 	len = sizeof(addr);
158678b5dc3dSJakub Kicinski 
158778b5dc3dSJakub Kicinski 	memset(&tls12, 0, sizeof(tls12));
158878b5dc3dSJakub Kicinski 	tls12.info.version = TLS_1_2_VERSION;
158978b5dc3dSJakub Kicinski 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
159078b5dc3dSJakub Kicinski 
159178b5dc3dSJakub Kicinski 	addr.sin_family = AF_INET;
159278b5dc3dSJakub Kicinski 	addr.sin_addr.s_addr = htonl(INADDR_ANY);
159378b5dc3dSJakub Kicinski 	addr.sin_port = 0;
159478b5dc3dSJakub Kicinski 
159578b5dc3dSJakub Kicinski 	fd = socket(AF_INET, SOCK_STREAM, 0);
159678b5dc3dSJakub Kicinski 	sfd = socket(AF_INET, SOCK_STREAM, 0);
159778b5dc3dSJakub Kicinski 
159878b5dc3dSJakub Kicinski 	ret = bind(sfd, &addr, sizeof(addr));
159978b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
160078b5dc3dSJakub Kicinski 	ret = listen(sfd, 10);
160178b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
160278b5dc3dSJakub Kicinski 
160378b5dc3dSJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
160478b5dc3dSJakub Kicinski 	EXPECT_EQ(ret, -1);
160578b5dc3dSJakub Kicinski 	/* TLS ULP not supported */
160678b5dc3dSJakub Kicinski 	if (errno == ENOENT)
160778b5dc3dSJakub Kicinski 		return;
16084a5cdc60SValentin Vidic 	EXPECT_EQ(errno, ENOTCONN);
160978b5dc3dSJakub Kicinski 
161078b5dc3dSJakub Kicinski 	ret = setsockopt(sfd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
161178b5dc3dSJakub Kicinski 	EXPECT_EQ(ret, -1);
16124a5cdc60SValentin Vidic 	EXPECT_EQ(errno, ENOTCONN);
161378b5dc3dSJakub Kicinski 
161478b5dc3dSJakub Kicinski 	ret = getsockname(sfd, &addr, &len);
161578b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
161678b5dc3dSJakub Kicinski 
161778b5dc3dSJakub Kicinski 	ret = connect(fd, &addr, sizeof(addr));
161878b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
161978b5dc3dSJakub Kicinski 
162078b5dc3dSJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
162178b5dc3dSJakub Kicinski 	ASSERT_EQ(ret, 0);
162278b5dc3dSJakub Kicinski 
162378b5dc3dSJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
162478b5dc3dSJakub Kicinski 	EXPECT_EQ(ret, -1);
162578b5dc3dSJakub Kicinski 	EXPECT_EQ(errno, EEXIST);
162678b5dc3dSJakub Kicinski 
162778b5dc3dSJakub Kicinski 	close(fd);
162878b5dc3dSJakub Kicinski 	close(sfd);
162978b5dc3dSJakub Kicinski }
163078b5dc3dSJakub Kicinski 
1631fb99bce7SDave Watson TEST(keysizes) {
1632fb99bce7SDave Watson 	struct tls12_crypto_info_aes_gcm_256 tls12;
1633a125f91fSJakub Kicinski 	int ret, fd, cfd;
1634fb99bce7SDave Watson 	bool notls;
1635fb99bce7SDave Watson 
1636fb99bce7SDave Watson 	memset(&tls12, 0, sizeof(tls12));
1637fb99bce7SDave Watson 	tls12.info.version = TLS_1_2_VERSION;
1638fb99bce7SDave Watson 	tls12.info.cipher_type = TLS_CIPHER_AES_GCM_256;
1639fb99bce7SDave Watson 
1640a125f91fSJakub Kicinski 	ulp_sock_pair(_metadata, &fd, &cfd, &notls);
1641fb99bce7SDave Watson 
1642fb99bce7SDave Watson 	if (!notls) {
1643fb99bce7SDave Watson 		ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12,
1644fb99bce7SDave Watson 				 sizeof(tls12));
1645fb99bce7SDave Watson 		EXPECT_EQ(ret, 0);
1646fb99bce7SDave Watson 
1647fb99bce7SDave Watson 		ret = setsockopt(cfd, SOL_TLS, TLS_RX, &tls12,
1648fb99bce7SDave Watson 				 sizeof(tls12));
1649fb99bce7SDave Watson 		EXPECT_EQ(ret, 0);
1650fb99bce7SDave Watson 	}
1651fb99bce7SDave Watson 
1652fb99bce7SDave Watson 	close(fd);
1653fb99bce7SDave Watson 	close(cfd);
1654fb99bce7SDave Watson }
1655fb99bce7SDave Watson 
1656f884a342SJakub Kicinski TEST(tls_v6ops) {
1657f884a342SJakub Kicinski 	struct tls_crypto_info_keys tls12;
1658f884a342SJakub Kicinski 	struct sockaddr_in6 addr, addr2;
1659f884a342SJakub Kicinski 	int sfd, ret, fd;
1660f884a342SJakub Kicinski 	socklen_t len, len2;
1661f884a342SJakub Kicinski 
1662f884a342SJakub Kicinski 	tls_crypto_info_init(TLS_1_2_VERSION, TLS_CIPHER_AES_GCM_128, &tls12);
1663f884a342SJakub Kicinski 
1664f884a342SJakub Kicinski 	addr.sin6_family = AF_INET6;
1665f884a342SJakub Kicinski 	addr.sin6_addr = in6addr_any;
1666f884a342SJakub Kicinski 	addr.sin6_port = 0;
1667f884a342SJakub Kicinski 
1668f884a342SJakub Kicinski 	fd = socket(AF_INET6, SOCK_STREAM, 0);
1669f884a342SJakub Kicinski 	sfd = socket(AF_INET6, SOCK_STREAM, 0);
1670f884a342SJakub Kicinski 
1671f884a342SJakub Kicinski 	ret = bind(sfd, &addr, sizeof(addr));
1672f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1673f884a342SJakub Kicinski 	ret = listen(sfd, 10);
1674f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1675f884a342SJakub Kicinski 
1676f884a342SJakub Kicinski 	len = sizeof(addr);
1677f884a342SJakub Kicinski 	ret = getsockname(sfd, &addr, &len);
1678f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1679f884a342SJakub Kicinski 
1680f884a342SJakub Kicinski 	ret = connect(fd, &addr, sizeof(addr));
1681f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1682f884a342SJakub Kicinski 
1683f884a342SJakub Kicinski 	len = sizeof(addr);
1684f884a342SJakub Kicinski 	ret = getsockname(fd, &addr, &len);
1685f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1686f884a342SJakub Kicinski 
1687f884a342SJakub Kicinski 	ret = setsockopt(fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls"));
1688f884a342SJakub Kicinski 	if (ret) {
1689f884a342SJakub Kicinski 		ASSERT_EQ(errno, ENOENT);
1690f884a342SJakub Kicinski 		SKIP(return, "no TLS support");
1691f884a342SJakub Kicinski 	}
1692f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1693f884a342SJakub Kicinski 
1694f884a342SJakub Kicinski 	ret = setsockopt(fd, SOL_TLS, TLS_TX, &tls12, tls12.len);
1695f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1696f884a342SJakub Kicinski 
1697f884a342SJakub Kicinski 	ret = setsockopt(fd, SOL_TLS, TLS_RX, &tls12, tls12.len);
1698f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1699f884a342SJakub Kicinski 
1700f884a342SJakub Kicinski 	len2 = sizeof(addr2);
1701f884a342SJakub Kicinski 	ret = getsockname(fd, &addr2, &len2);
1702f884a342SJakub Kicinski 	ASSERT_EQ(ret, 0);
1703f884a342SJakub Kicinski 
1704f884a342SJakub Kicinski 	EXPECT_EQ(len2, len);
1705f884a342SJakub Kicinski 	EXPECT_EQ(memcmp(&addr, &addr2, len), 0);
1706f884a342SJakub Kicinski 
1707f884a342SJakub Kicinski 	close(fd);
1708f884a342SJakub Kicinski 	close(sfd);
1709f884a342SJakub Kicinski }
1710f884a342SJakub Kicinski 
17117f657d5bSDave Watson TEST_HARNESS_MAIN
1712