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