1// SPDX-License-Identifier: GPL-2.0 2 3#define _GNU_SOURCE 4#include <sched.h> 5 6#include <stddef.h> 7#include <stdio.h> 8#include <unistd.h> 9 10#include <sys/socket.h> 11#include <sys/un.h> 12 13#include "../../kselftest_harness.h" 14 15FIXTURE(unix_connect) 16{ 17 int server, client; 18 int family; 19}; 20 21FIXTURE_VARIANT(unix_connect) 22{ 23 int type; 24 char sun_path[8]; 25 int len; 26 int flags; 27 int err; 28}; 29 30FIXTURE_VARIANT_ADD(unix_connect, stream_pathname) 31{ 32 .type = SOCK_STREAM, 33 .sun_path = "test", 34 .len = 4 + 1, 35 .flags = 0, 36 .err = 0, 37}; 38 39FIXTURE_VARIANT_ADD(unix_connect, stream_abstract) 40{ 41 .type = SOCK_STREAM, 42 .sun_path = "\0test", 43 .len = 5, 44 .flags = 0, 45 .err = 0, 46}; 47 48FIXTURE_VARIANT_ADD(unix_connect, stream_pathname_netns) 49{ 50 .type = SOCK_STREAM, 51 .sun_path = "test", 52 .len = 4 + 1, 53 .flags = CLONE_NEWNET, 54 .err = 0, 55}; 56 57FIXTURE_VARIANT_ADD(unix_connect, stream_abstract_netns) 58{ 59 .type = SOCK_STREAM, 60 .sun_path = "\0test", 61 .len = 5, 62 .flags = CLONE_NEWNET, 63 .err = ECONNREFUSED, 64}; 65 66FIXTURE_VARIANT_ADD(unix_connect, dgram_pathname) 67{ 68 .type = SOCK_DGRAM, 69 .sun_path = "test", 70 .len = 4 + 1, 71 .flags = 0, 72 .err = 0, 73}; 74 75FIXTURE_VARIANT_ADD(unix_connect, dgram_abstract) 76{ 77 .type = SOCK_DGRAM, 78 .sun_path = "\0test", 79 .len = 5, 80 .flags = 0, 81 .err = 0, 82}; 83 84FIXTURE_VARIANT_ADD(unix_connect, dgram_pathname_netns) 85{ 86 .type = SOCK_DGRAM, 87 .sun_path = "test", 88 .len = 4 + 1, 89 .flags = CLONE_NEWNET, 90 .err = 0, 91}; 92 93FIXTURE_VARIANT_ADD(unix_connect, dgram_abstract_netns) 94{ 95 .type = SOCK_DGRAM, 96 .sun_path = "\0test", 97 .len = 5, 98 .flags = CLONE_NEWNET, 99 .err = ECONNREFUSED, 100}; 101 102FIXTURE_SETUP(unix_connect) 103{ 104 self->family = AF_UNIX; 105} 106 107FIXTURE_TEARDOWN(unix_connect) 108{ 109 close(self->server); 110 close(self->client); 111 112 if (variant->sun_path[0]) 113 remove("test"); 114} 115 116TEST_F(unix_connect, test) 117{ 118 socklen_t addrlen; 119 struct sockaddr_un addr = { 120 .sun_family = self->family, 121 }; 122 int err; 123 124 self->server = socket(self->family, variant->type, 0); 125 ASSERT_NE(-1, self->server); 126 127 addrlen = offsetof(struct sockaddr_un, sun_path) + variant->len; 128 memcpy(&addr.sun_path, variant->sun_path, variant->len); 129 130 err = bind(self->server, (struct sockaddr *)&addr, addrlen); 131 ASSERT_EQ(0, err); 132 133 if (variant->type == SOCK_STREAM) { 134 err = listen(self->server, 32); 135 ASSERT_EQ(0, err); 136 } 137 138 err = unshare(variant->flags); 139 ASSERT_EQ(0, err); 140 141 self->client = socket(self->family, variant->type, 0); 142 ASSERT_LT(0, self->client); 143 144 err = connect(self->client, (struct sockaddr *)&addr, addrlen); 145 ASSERT_EQ(variant->err, err == -1 ? errno : 0); 146} 147 148TEST_HARNESS_MAIN 149