af_unix: selftest: Fix the size of the parameter to connect()
[platform/kernel/linux-rpi.git] / tools / testing / selftests / net / af_unix / test_unix_oob.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/socket.h>
5 #include <arpa/inet.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <fcntl.h>
9 #include <sys/ioctl.h>
10 #include <errno.h>
11 #include <netinet/tcp.h>
12 #include <sys/un.h>
13 #include <sys/signal.h>
14 #include <sys/poll.h>
15
16 static int pipefd[2];
17 static int signal_recvd;
18 static pid_t producer_id;
19 static char sock_name[32];
20
21 static void sig_hand(int sn, siginfo_t *si, void *p)
22 {
23         signal_recvd = sn;
24 }
25
26 static int set_sig_handler(int signal)
27 {
28         struct sigaction sa;
29
30         sa.sa_sigaction = sig_hand;
31         sigemptyset(&sa.sa_mask);
32         sa.sa_flags = SA_SIGINFO | SA_RESTART;
33
34         return sigaction(signal, &sa, NULL);
35 }
36
37 static void set_filemode(int fd, int set)
38 {
39         int flags = fcntl(fd, F_GETFL, 0);
40
41         if (set)
42                 flags &= ~O_NONBLOCK;
43         else
44                 flags |= O_NONBLOCK;
45         fcntl(fd, F_SETFL, flags);
46 }
47
48 static void signal_producer(int fd)
49 {
50         char cmd;
51
52         cmd = 'S';
53         write(fd, &cmd, sizeof(cmd));
54 }
55
56 static void wait_for_signal(int fd)
57 {
58         char buf[5];
59
60         read(fd, buf, 5);
61 }
62
63 static void die(int status)
64 {
65         fflush(NULL);
66         unlink(sock_name);
67         kill(producer_id, SIGTERM);
68         exit(status);
69 }
70
71 int is_sioctatmark(int fd)
72 {
73         int ans = -1;
74
75         if (ioctl(fd, SIOCATMARK, &ans, sizeof(ans)) < 0) {
76 #ifdef DEBUG
77                 perror("SIOCATMARK Failed");
78 #endif
79         }
80         return ans;
81 }
82
83 void read_oob(int fd, char *c)
84 {
85
86         *c = ' ';
87         if (recv(fd, c, sizeof(*c), MSG_OOB) < 0) {
88 #ifdef DEBUG
89                 perror("Reading MSG_OOB Failed");
90 #endif
91         }
92 }
93
94 int read_data(int pfd, char *buf, int size)
95 {
96         int len = 0;
97
98         memset(buf, size, '0');
99         len = read(pfd, buf, size);
100 #ifdef DEBUG
101         if (len < 0)
102                 perror("read failed");
103 #endif
104         return len;
105 }
106
107 static void wait_for_data(int pfd, int event)
108 {
109         struct pollfd pfds[1];
110
111         pfds[0].fd = pfd;
112         pfds[0].events = event;
113         poll(pfds, 1, -1);
114 }
115
116 void producer(struct sockaddr_un *consumer_addr)
117 {
118         int cfd;
119         char buf[64];
120         int i;
121
122         memset(buf, 'x', sizeof(buf));
123         cfd = socket(AF_UNIX, SOCK_STREAM, 0);
124
125         wait_for_signal(pipefd[0]);
126         if (connect(cfd, (struct sockaddr *)consumer_addr,
127                      sizeof(*consumer_addr)) != 0) {
128                 perror("Connect failed");
129                 kill(0, SIGTERM);
130                 exit(1);
131         }
132
133         for (i = 0; i < 2; i++) {
134                 /* Test 1: Test for SIGURG and OOB */
135                 wait_for_signal(pipefd[0]);
136                 memset(buf, 'x', sizeof(buf));
137                 buf[63] = '@';
138                 send(cfd, buf, sizeof(buf), MSG_OOB);
139
140                 wait_for_signal(pipefd[0]);
141
142                 /* Test 2: Test for OOB being overwitten */
143                 memset(buf, 'x', sizeof(buf));
144                 buf[63] = '%';
145                 send(cfd, buf, sizeof(buf), MSG_OOB);
146
147                 memset(buf, 'x', sizeof(buf));
148                 buf[63] = '#';
149                 send(cfd, buf, sizeof(buf), MSG_OOB);
150
151                 wait_for_signal(pipefd[0]);
152
153                 /* Test 3: Test for SIOCATMARK */
154                 memset(buf, 'x', sizeof(buf));
155                 buf[63] = '@';
156                 send(cfd, buf, sizeof(buf), MSG_OOB);
157
158                 memset(buf, 'x', sizeof(buf));
159                 buf[63] = '%';
160                 send(cfd, buf, sizeof(buf), MSG_OOB);
161
162                 memset(buf, 'x', sizeof(buf));
163                 send(cfd, buf, sizeof(buf), 0);
164
165                 wait_for_signal(pipefd[0]);
166
167                 /* Test 4: Test for 1byte OOB msg */
168                 memset(buf, 'x', sizeof(buf));
169                 buf[0] = '@';
170                 send(cfd, buf, 1, MSG_OOB);
171         }
172 }
173
174 int
175 main(int argc, char **argv)
176 {
177         int lfd, pfd;
178         struct sockaddr_un consumer_addr, paddr;
179         socklen_t len = sizeof(consumer_addr);
180         char buf[1024];
181         int on = 0;
182         char oob;
183         int flags;
184         int atmark;
185         char *tmp_file;
186
187         lfd = socket(AF_UNIX, SOCK_STREAM, 0);
188         memset(&consumer_addr, 0, sizeof(consumer_addr));
189         consumer_addr.sun_family = AF_UNIX;
190         sprintf(sock_name, "unix_oob_%d", getpid());
191         unlink(sock_name);
192         strcpy(consumer_addr.sun_path, sock_name);
193
194         if ((bind(lfd, (struct sockaddr *)&consumer_addr,
195                   sizeof(consumer_addr))) != 0) {
196                 perror("socket bind failed");
197                 exit(1);
198         }
199
200         pipe(pipefd);
201
202         listen(lfd, 1);
203
204         producer_id = fork();
205         if (producer_id == 0) {
206                 producer(&consumer_addr);
207                 exit(0);
208         }
209
210         set_sig_handler(SIGURG);
211         signal_producer(pipefd[1]);
212
213         pfd = accept(lfd, (struct sockaddr *) &paddr, &len);
214         fcntl(pfd, F_SETOWN, getpid());
215
216         signal_recvd = 0;
217         signal_producer(pipefd[1]);
218
219         /* Test 1:
220          * veriyf that SIGURG is
221          * delivered, 63 bytes are
222          * read, oob is '@', and POLLPRI works.
223          */
224         wait_for_data(pfd, POLLPRI);
225         read_oob(pfd, &oob);
226         len = read_data(pfd, buf, 1024);
227         if (!signal_recvd || len != 63 || oob != '@') {
228                 fprintf(stderr, "Test 1 failed sigurg %d len %d %c\n",
229                          signal_recvd, len, oob);
230                         die(1);
231         }
232
233         signal_recvd = 0;
234         signal_producer(pipefd[1]);
235
236         /* Test 2:
237          * Verify that the first OOB is over written by
238          * the 2nd one and the first OOB is returned as
239          * part of the read, and sigurg is received.
240          */
241         wait_for_data(pfd, POLLIN | POLLPRI);
242         len = 0;
243         while (len < 70)
244                 len = recv(pfd, buf, 1024, MSG_PEEK);
245         len = read_data(pfd, buf, 1024);
246         read_oob(pfd, &oob);
247         if (!signal_recvd || len != 127 || oob != '#') {
248                 fprintf(stderr, "Test 2 failed, sigurg %d len %d OOB %c\n",
249                 signal_recvd, len, oob);
250                 die(1);
251         }
252
253         signal_recvd = 0;
254         signal_producer(pipefd[1]);
255
256         /* Test 3:
257          * verify that 2nd oob over writes
258          * the first one and read breaks at
259          * oob boundary returning 127 bytes
260          * and sigurg is received and atmark
261          * is set.
262          * oob is '%' and second read returns
263          * 64 bytes.
264          */
265         len = 0;
266         wait_for_data(pfd, POLLIN | POLLPRI);
267         while (len < 150)
268                 len = recv(pfd, buf, 1024, MSG_PEEK);
269         len = read_data(pfd, buf, 1024);
270         atmark = is_sioctatmark(pfd);
271         read_oob(pfd, &oob);
272
273         if (!signal_recvd || len != 127 || oob != '%' || atmark != 1) {
274                 fprintf(stderr,
275                         "Test 3 failed, sigurg %d len %d OOB %c atmark %d\n",
276                         signal_recvd, len, oob, atmark);
277                 die(1);
278         }
279
280         signal_recvd = 0;
281
282         len = read_data(pfd, buf, 1024);
283         if (len != 64) {
284                 fprintf(stderr, "Test 3.1 failed, sigurg %d len %d OOB %c\n",
285                         signal_recvd, len, oob);
286                 die(1);
287         }
288
289         signal_recvd = 0;
290         signal_producer(pipefd[1]);
291
292         /* Test 4:
293          * verify that a single byte
294          * oob message is delivered.
295          * set non blocking mode and
296          * check proper error is
297          * returned and sigurg is
298          * received and correct
299          * oob is read.
300          */
301
302         set_filemode(pfd, 0);
303
304         wait_for_data(pfd, POLLIN | POLLPRI);
305         len = read_data(pfd, buf, 1024);
306         if ((len == -1) && (errno == 11))
307                 len = 0;
308
309         read_oob(pfd, &oob);
310
311         if (!signal_recvd || len != 0 || oob != '@') {
312                 fprintf(stderr, "Test 4 failed, sigurg %d len %d OOB %c\n",
313                          signal_recvd, len, oob);
314                 die(1);
315         }
316
317         set_filemode(pfd, 1);
318
319         /* Inline Testing */
320
321         on = 1;
322         if (setsockopt(pfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on))) {
323                 perror("SO_OOBINLINE");
324                 die(1);
325         }
326
327         signal_recvd = 0;
328         signal_producer(pipefd[1]);
329
330         /* Test 1 -- Inline:
331          * Check that SIGURG is
332          * delivered and 63 bytes are
333          * read and oob is '@'
334          */
335
336         wait_for_data(pfd, POLLIN | POLLPRI);
337         len = read_data(pfd, buf, 1024);
338
339         if (!signal_recvd || len != 63) {
340                 fprintf(stderr, "Test 1 Inline failed, sigurg %d len %d\n",
341                         signal_recvd, len);
342                 die(1);
343         }
344
345         len = read_data(pfd, buf, 1024);
346
347         if (len != 1) {
348                 fprintf(stderr,
349                          "Test 1.1 Inline failed, sigurg %d len %d oob %c\n",
350                          signal_recvd, len, oob);
351                 die(1);
352         }
353
354         signal_recvd = 0;
355         signal_producer(pipefd[1]);
356
357         /* Test 2 -- Inline:
358          * Verify that the first OOB is over written by
359          * the 2nd one and read breaks correctly on
360          * 2nd OOB boundary with the first OOB returned as
361          * part of the read, and sigurg is delivered and
362          * siocatmark returns true.
363          * next read returns one byte, the oob byte
364          * and siocatmark returns false.
365          */
366         len = 0;
367         wait_for_data(pfd, POLLIN | POLLPRI);
368         while (len < 70)
369                 len = recv(pfd, buf, 1024, MSG_PEEK);
370         len = read_data(pfd, buf, 1024);
371         atmark = is_sioctatmark(pfd);
372         if (len != 127 || atmark != 1 || !signal_recvd) {
373                 fprintf(stderr, "Test 2 Inline failed, len %d atmark %d\n",
374                          len, atmark);
375                 die(1);
376         }
377
378         len = read_data(pfd, buf, 1024);
379         atmark = is_sioctatmark(pfd);
380         if (len != 1 || buf[0] != '#' || atmark == 1) {
381                 fprintf(stderr, "Test 2.1 Inline failed, len %d data %c atmark %d\n",
382                         len, buf[0], atmark);
383                 die(1);
384         }
385
386         signal_recvd = 0;
387         signal_producer(pipefd[1]);
388
389         /* Test 3 -- Inline:
390          * verify that 2nd oob over writes
391          * the first one and read breaks at
392          * oob boundary returning 127 bytes
393          * and sigurg is received and siocatmark
394          * is true after the read.
395          * subsequent read returns 65 bytes
396          * because of oob which should be '%'.
397          */
398         len = 0;
399         wait_for_data(pfd, POLLIN | POLLPRI);
400         while (len < 126)
401                 len = recv(pfd, buf, 1024, MSG_PEEK);
402         len = read_data(pfd, buf, 1024);
403         atmark = is_sioctatmark(pfd);
404         if (!signal_recvd || len != 127 || !atmark) {
405                 fprintf(stderr,
406                          "Test 3 Inline failed, sigurg %d len %d data %c\n",
407                          signal_recvd, len, buf[0]);
408                 die(1);
409         }
410
411         len = read_data(pfd, buf, 1024);
412         atmark = is_sioctatmark(pfd);
413         if (len != 65 || buf[0] != '%' || atmark != 0) {
414                 fprintf(stderr,
415                          "Test 3.1 Inline failed, len %d oob %c atmark %d\n",
416                          len, buf[0], atmark);
417                 die(1);
418         }
419
420         signal_recvd = 0;
421         signal_producer(pipefd[1]);
422
423         /* Test 4 -- Inline:
424          * verify that a single
425          * byte oob message is delivered
426          * and read returns one byte, the oob
427          * byte and sigurg is received
428          */
429         wait_for_data(pfd, POLLIN | POLLPRI);
430         len = read_data(pfd, buf, 1024);
431         if (!signal_recvd || len != 1 || buf[0] != '@') {
432                 fprintf(stderr,
433                         "Test 4 Inline failed, signal %d len %d data %c\n",
434                 signal_recvd, len, buf[0]);
435                 die(1);
436         }
437         die(0);
438 }