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 | |
15 | FIXTURE(unix_connect) |
16 | { |
17 | int server, client; |
18 | int family; |
19 | }; |
20 | |
21 | FIXTURE_VARIANT(unix_connect) |
22 | { |
23 | int type; |
24 | char sun_path[8]; |
25 | int len; |
26 | int flags; |
27 | int err; |
28 | }; |
29 | |
30 | FIXTURE_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 | |
39 | FIXTURE_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 | |
48 | FIXTURE_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 | |
57 | FIXTURE_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 | |
66 | FIXTURE_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 | |
75 | FIXTURE_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 | |
84 | FIXTURE_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 | |
93 | FIXTURE_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 | |
102 | FIXTURE_SETUP(unix_connect) |
103 | { |
104 | self->family = AF_UNIX; |
105 | } |
106 | |
107 | FIXTURE_TEARDOWN(unix_connect) |
108 | { |
109 | close(self->server); |
110 | close(self->client); |
111 | |
112 | if (variant->sun_path[0]) |
113 | remove("test" ); |
114 | } |
115 | |
116 | TEST_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 | |
148 | TEST_HARNESS_MAIN |
149 | |