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, ¬ls); 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