~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/af_unix/msg_oob.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* Copyright Amazon.com Inc. or its affiliates. */
  3 
  4 #include <fcntl.h>
  5 #include <string.h>
  6 #include <unistd.h>
  7 
  8 #include <netinet/in.h>
  9 #include <sys/epoll.h>
 10 #include <sys/ioctl.h>
 11 #include <sys/signalfd.h>
 12 #include <sys/socket.h>
 13 
 14 #include "../../kselftest_harness.h"
 15 
 16 #define BUF_SZ  32
 17 
 18 FIXTURE(msg_oob)
 19 {
 20         int fd[4];              /* 0: AF_UNIX sender
 21                                  * 1: AF_UNIX receiver
 22                                  * 2: TCP sender
 23                                  * 3: TCP receiver
 24                                  */
 25         int signal_fd;
 26         int epoll_fd[2];        /* 0: AF_UNIX receiver
 27                                  * 1: TCP receiver
 28                                  */
 29         bool tcp_compliant;
 30 };
 31 
 32 FIXTURE_VARIANT(msg_oob)
 33 {
 34         bool peek;
 35 };
 36 
 37 FIXTURE_VARIANT_ADD(msg_oob, no_peek)
 38 {
 39         .peek = false,
 40 };
 41 
 42 FIXTURE_VARIANT_ADD(msg_oob, peek)
 43 {
 44         .peek = true
 45 };
 46 
 47 static void create_unix_socketpair(struct __test_metadata *_metadata,
 48                                    FIXTURE_DATA(msg_oob) *self)
 49 {
 50         int ret;
 51 
 52         ret = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, self->fd);
 53         ASSERT_EQ(ret, 0);
 54 }
 55 
 56 static void create_tcp_socketpair(struct __test_metadata *_metadata,
 57                                   FIXTURE_DATA(msg_oob) *self)
 58 {
 59         struct sockaddr_in addr;
 60         socklen_t addrlen;
 61         int listen_fd;
 62         int ret;
 63 
 64         listen_fd = socket(AF_INET, SOCK_STREAM, 0);
 65         ASSERT_GE(listen_fd, 0);
 66 
 67         ret = listen(listen_fd, -1);
 68         ASSERT_EQ(ret, 0);
 69 
 70         addrlen = sizeof(addr);
 71         ret = getsockname(listen_fd, (struct sockaddr *)&addr, &addrlen);
 72         ASSERT_EQ(ret, 0);
 73 
 74         self->fd[2] = socket(AF_INET, SOCK_STREAM, 0);
 75         ASSERT_GE(self->fd[2], 0);
 76 
 77         ret = connect(self->fd[2], (struct sockaddr *)&addr, addrlen);
 78         ASSERT_EQ(ret, 0);
 79 
 80         self->fd[3] = accept(listen_fd, (struct sockaddr *)&addr, &addrlen);
 81         ASSERT_GE(self->fd[3], 0);
 82 
 83         ret = fcntl(self->fd[3], F_SETFL, O_NONBLOCK);
 84         ASSERT_EQ(ret, 0);
 85 }
 86 
 87 static void setup_sigurg(struct __test_metadata *_metadata,
 88                          FIXTURE_DATA(msg_oob) *self)
 89 {
 90         struct signalfd_siginfo siginfo;
 91         int pid = getpid();
 92         sigset_t mask;
 93         int i, ret;
 94 
 95         for (i = 0; i < 2; i++) {
 96                 ret = ioctl(self->fd[i * 2 + 1], FIOSETOWN, &pid);
 97                 ASSERT_EQ(ret, 0);
 98         }
 99 
100         ret = sigemptyset(&mask);
101         ASSERT_EQ(ret, 0);
102 
103         ret = sigaddset(&mask, SIGURG);
104         ASSERT_EQ(ret, 0);
105 
106         ret = sigprocmask(SIG_BLOCK, &mask, NULL);
107         ASSERT_EQ(ret, 0);
108 
109         self->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK);
110         ASSERT_GE(self->signal_fd, 0);
111 
112         ret = read(self->signal_fd, &siginfo, sizeof(siginfo));
113         ASSERT_EQ(ret, -1);
114 }
115 
116 static void setup_epollpri(struct __test_metadata *_metadata,
117                            FIXTURE_DATA(msg_oob) *self)
118 {
119         struct epoll_event event = {
120                 .events = EPOLLPRI,
121         };
122         int i;
123 
124         for (i = 0; i < 2; i++) {
125                 int ret;
126 
127                 self->epoll_fd[i] = epoll_create1(0);
128                 ASSERT_GE(self->epoll_fd[i], 0);
129 
130                 ret = epoll_ctl(self->epoll_fd[i], EPOLL_CTL_ADD, self->fd[i * 2 + 1], &event);
131                 ASSERT_EQ(ret, 0);
132         }
133 }
134 
135 static void close_sockets(FIXTURE_DATA(msg_oob) *self)
136 {
137         int i;
138 
139         for (i = 0; i < 4; i++)
140                 close(self->fd[i]);
141 }
142 
143 FIXTURE_SETUP(msg_oob)
144 {
145         create_unix_socketpair(_metadata, self);
146         create_tcp_socketpair(_metadata, self);
147 
148         setup_sigurg(_metadata, self);
149         setup_epollpri(_metadata, self);
150 
151         self->tcp_compliant = true;
152 }
153 
154 FIXTURE_TEARDOWN(msg_oob)
155 {
156         close_sockets(self);
157 }
158 
159 static void __epollpair(struct __test_metadata *_metadata,
160                         FIXTURE_DATA(msg_oob) *self,
161                         bool oob_remaining)
162 {
163         struct epoll_event event[2] = {};
164         int i, ret[2];
165 
166         for (i = 0; i < 2; i++)
167                 ret[i] = epoll_wait(self->epoll_fd[i], &event[i], 1, 0);
168 
169         ASSERT_EQ(ret[0], oob_remaining);
170 
171         if (self->tcp_compliant)
172                 ASSERT_EQ(ret[0], ret[1]);
173 
174         if (oob_remaining) {
175                 ASSERT_EQ(event[0].events, EPOLLPRI);
176 
177                 if (self->tcp_compliant)
178                         ASSERT_EQ(event[0].events, event[1].events);
179         }
180 }
181 
182 static void __sendpair(struct __test_metadata *_metadata,
183                        FIXTURE_DATA(msg_oob) *self,
184                        const void *buf, size_t len, int flags)
185 {
186         int i, ret[2];
187 
188         for (i = 0; i < 2; i++) {
189                 struct signalfd_siginfo siginfo = {};
190                 int bytes;
191 
192                 ret[i] = send(self->fd[i * 2], buf, len, flags);
193 
194                 bytes = read(self->signal_fd, &siginfo, sizeof(siginfo));
195 
196                 if (flags & MSG_OOB) {
197                         ASSERT_EQ(bytes, sizeof(siginfo));
198                         ASSERT_EQ(siginfo.ssi_signo, SIGURG);
199 
200                         bytes = read(self->signal_fd, &siginfo, sizeof(siginfo));
201                 }
202 
203                 ASSERT_EQ(bytes, -1);
204         }
205 
206         ASSERT_EQ(ret[0], len);
207         ASSERT_EQ(ret[0], ret[1]);
208 }
209 
210 static void __recvpair(struct __test_metadata *_metadata,
211                        FIXTURE_DATA(msg_oob) *self,
212                        const char *expected_buf, int expected_len,
213                        int buf_len, int flags)
214 {
215         int i, ret[2], recv_errno[2], expected_errno = 0;
216         char recv_buf[2][BUF_SZ] = {};
217         bool printed = false;
218 
219         ASSERT_GE(BUF_SZ, buf_len);
220 
221         errno = 0;
222 
223         for (i = 0; i < 2; i++) {
224                 ret[i] = recv(self->fd[i * 2 + 1], recv_buf[i], buf_len, flags);
225                 recv_errno[i] = errno;
226         }
227 
228         if (expected_len < 0) {
229                 expected_errno = -expected_len;
230                 expected_len = -1;
231         }
232 
233         if (ret[0] != expected_len || recv_errno[0] != expected_errno) {
234                 TH_LOG("AF_UNIX :%s", ret[0] < 0 ? strerror(recv_errno[0]) : recv_buf[0]);
235                 TH_LOG("Expected:%s", expected_errno ? strerror(expected_errno) : expected_buf);
236 
237                 ASSERT_EQ(ret[0], expected_len);
238                 ASSERT_EQ(recv_errno[0], expected_errno);
239         }
240 
241         if (ret[0] != ret[1] || recv_errno[0] != recv_errno[1]) {
242                 TH_LOG("AF_UNIX :%s", ret[0] < 0 ? strerror(recv_errno[0]) : recv_buf[0]);
243                 TH_LOG("TCP     :%s", ret[1] < 0 ? strerror(recv_errno[1]) : recv_buf[1]);
244 
245                 printed = true;
246 
247                 if (self->tcp_compliant) {
248                         ASSERT_EQ(ret[0], ret[1]);
249                         ASSERT_EQ(recv_errno[0], recv_errno[1]);
250                 }
251         }
252 
253         if (expected_len >= 0) {
254                 int cmp;
255 
256                 cmp = strncmp(expected_buf, recv_buf[0], expected_len);
257                 if (cmp) {
258                         TH_LOG("AF_UNIX :%s", ret[0] < 0 ? strerror(recv_errno[0]) : recv_buf[0]);
259                         TH_LOG("Expected:%s", expected_errno ? strerror(expected_errno) : expected_buf);
260 
261                         ASSERT_EQ(cmp, 0);
262                 }
263 
264                 cmp = strncmp(recv_buf[0], recv_buf[1], expected_len);
265                 if (cmp) {
266                         if (!printed) {
267                                 TH_LOG("AF_UNIX :%s", ret[0] < 0 ? strerror(recv_errno[0]) : recv_buf[0]);
268                                 TH_LOG("TCP     :%s", ret[1] < 0 ? strerror(recv_errno[1]) : recv_buf[1]);
269                         }
270 
271                         if (self->tcp_compliant)
272                                 ASSERT_EQ(cmp, 0);
273                 }
274         }
275 }
276 
277 static void __setinlinepair(struct __test_metadata *_metadata,
278                             FIXTURE_DATA(msg_oob) *self)
279 {
280         int i, oob_inline = 1;
281 
282         for (i = 0; i < 2; i++) {
283                 int ret;
284 
285                 ret = setsockopt(self->fd[i * 2 + 1], SOL_SOCKET, SO_OOBINLINE,
286                                  &oob_inline, sizeof(oob_inline));
287                 ASSERT_EQ(ret, 0);
288         }
289 }
290 
291 static void __siocatmarkpair(struct __test_metadata *_metadata,
292                              FIXTURE_DATA(msg_oob) *self,
293                              bool oob_head)
294 {
295         int answ[2] = {};
296         int i;
297 
298         for (i = 0; i < 2; i++) {
299                 int ret;
300 
301                 ret = ioctl(self->fd[i * 2 + 1], SIOCATMARK, &answ[i]);
302                 ASSERT_EQ(ret, 0);
303         }
304 
305         ASSERT_EQ(answ[0], oob_head);
306 
307         if (self->tcp_compliant)
308                 ASSERT_EQ(answ[0], answ[1]);
309 }
310 
311 #define sendpair(buf, len, flags)                                       \
312         __sendpair(_metadata, self, buf, len, flags)
313 
314 #define recvpair(expected_buf, expected_len, buf_len, flags)            \
315         do {                                                            \
316                 if (variant->peek)                                      \
317                         __recvpair(_metadata, self,                     \
318                                    expected_buf, expected_len,          \
319                                    buf_len, (flags) | MSG_PEEK);        \
320                 __recvpair(_metadata, self,                             \
321                            expected_buf, expected_len, buf_len, flags); \
322         } while (0)
323 
324 #define epollpair(oob_remaining)                                        \
325         __epollpair(_metadata, self, oob_remaining)
326 
327 #define siocatmarkpair(oob_head)                                        \
328         __siocatmarkpair(_metadata, self, oob_head)
329 
330 #define setinlinepair()                                                 \
331         __setinlinepair(_metadata, self)
332 
333 #define tcp_incompliant                                                 \
334         for (self->tcp_compliant = false;                               \
335              self->tcp_compliant == false;                              \
336              self->tcp_compliant = true)
337 
338 TEST_F(msg_oob, non_oob)
339 {
340         sendpair("x", 1, 0);
341         epollpair(false);
342         siocatmarkpair(false);
343 
344         recvpair("", -EINVAL, 1, MSG_OOB);
345         epollpair(false);
346         siocatmarkpair(false);
347 }
348 
349 TEST_F(msg_oob, oob)
350 {
351         sendpair("x", 1, MSG_OOB);
352         epollpair(true);
353         siocatmarkpair(true);
354 
355         recvpair("x", 1, 1, MSG_OOB);
356         epollpair(false);
357         siocatmarkpair(true);
358 }
359 
360 TEST_F(msg_oob, oob_drop)
361 {
362         sendpair("x", 1, MSG_OOB);
363         epollpair(true);
364         siocatmarkpair(true);
365 
366         recvpair("", -EAGAIN, 1, 0);            /* Drop OOB. */
367         epollpair(false);
368         siocatmarkpair(false);
369 
370         recvpair("", -EINVAL, 1, MSG_OOB);
371         epollpair(false);
372         siocatmarkpair(false);
373 }
374 
375 TEST_F(msg_oob, oob_ahead)
376 {
377         sendpair("hello", 5, MSG_OOB);
378         epollpair(true);
379         siocatmarkpair(false);
380 
381         recvpair("o", 1, 1, MSG_OOB);
382         epollpair(false);
383         siocatmarkpair(false);
384 
385         recvpair("hell", 4, 4, 0);
386         epollpair(false);
387         siocatmarkpair(true);
388 }
389 
390 TEST_F(msg_oob, oob_break)
391 {
392         sendpair("hello", 5, MSG_OOB);
393         epollpair(true);
394         siocatmarkpair(false);
395 
396         recvpair("hell", 4, 5, 0);              /* Break at OOB even with enough buffer. */
397         epollpair(true);
398         siocatmarkpair(true);
399 
400         recvpair("o", 1, 1, MSG_OOB);
401         epollpair(false);
402         siocatmarkpair(true);
403 
404         recvpair("", -EAGAIN, 1, 0);
405         siocatmarkpair(false);
406 }
407 
408 TEST_F(msg_oob, oob_ahead_break)
409 {
410         sendpair("hello", 5, MSG_OOB);
411         epollpair(true);
412         siocatmarkpair(false);
413 
414         sendpair("world", 5, 0);
415         epollpair(true);
416         siocatmarkpair(false);
417 
418         recvpair("o", 1, 1, MSG_OOB);
419         epollpair(false);
420         siocatmarkpair(false);
421 
422         recvpair("hell", 4, 9, 0);              /* Break at OOB even after it's recv()ed. */
423         epollpair(false);
424         siocatmarkpair(true);
425 
426         recvpair("world", 5, 5, 0);
427         epollpair(false);
428         siocatmarkpair(false);
429 }
430 
431 TEST_F(msg_oob, oob_break_drop)
432 {
433         sendpair("hello", 5, MSG_OOB);
434         epollpair(true);
435         siocatmarkpair(false);
436 
437         sendpair("world", 5, 0);
438         epollpair(true);
439         siocatmarkpair(false);
440 
441         recvpair("hell", 4, 10, 0);             /* Break at OOB even with enough buffer. */
442         epollpair(true);
443         siocatmarkpair(true);
444 
445         recvpair("world", 5, 10, 0);            /* Drop OOB and recv() the next skb. */
446         epollpair(false);
447         siocatmarkpair(false);
448 
449         recvpair("", -EINVAL, 1, MSG_OOB);
450         epollpair(false);
451         siocatmarkpair(false);
452 }
453 
454 TEST_F(msg_oob, ex_oob_break)
455 {
456         sendpair("hello", 5, MSG_OOB);
457         epollpair(true);
458         siocatmarkpair(false);
459 
460         sendpair("wor", 3, MSG_OOB);
461         epollpair(true);
462         siocatmarkpair(false);
463 
464         sendpair("ld", 2, 0);
465         epollpair(true);
466         siocatmarkpair(false);
467 
468         recvpair("hellowo", 7, 10, 0);          /* Break at OOB but not at ex-OOB. */
469         epollpair(true);
470         siocatmarkpair(true);
471 
472         recvpair("r", 1, 1, MSG_OOB);
473         epollpair(false);
474         siocatmarkpair(true);
475 
476         recvpair("ld", 2, 2, 0);
477         epollpair(false);
478         siocatmarkpair(false);
479 }
480 
481 TEST_F(msg_oob, ex_oob_drop)
482 {
483         sendpair("x", 1, MSG_OOB);
484         epollpair(true);
485         siocatmarkpair(true);
486 
487         sendpair("y", 1, MSG_OOB);              /* TCP drops "x" at this moment. */
488         epollpair(true);
489 
490         tcp_incompliant {
491                 siocatmarkpair(false);
492 
493                 recvpair("x", 1, 1, 0);         /* TCP drops "y" by passing through it. */
494                 epollpair(true);
495                 siocatmarkpair(true);
496 
497                 recvpair("y", 1, 1, MSG_OOB);   /* TCP returns -EINVAL. */
498                 epollpair(false);
499                 siocatmarkpair(true);
500         }
501 }
502 
503 TEST_F(msg_oob, ex_oob_drop_2)
504 {
505         sendpair("x", 1, MSG_OOB);
506         epollpair(true);
507         siocatmarkpair(true);
508 
509         sendpair("y", 1, MSG_OOB);              /* TCP drops "x" at this moment. */
510         epollpair(true);
511 
512         tcp_incompliant {
513                 siocatmarkpair(false);
514         }
515 
516         recvpair("y", 1, 1, MSG_OOB);
517         epollpair(false);
518 
519         tcp_incompliant {
520                 siocatmarkpair(false);
521 
522                 recvpair("x", 1, 1, 0);         /* TCP returns -EAGAIN. */
523                 epollpair(false);
524                 siocatmarkpair(true);
525         }
526 }
527 
528 TEST_F(msg_oob, ex_oob_oob)
529 {
530         sendpair("x", 1, MSG_OOB);
531         epollpair(true);
532         siocatmarkpair(true);
533 
534         recvpair("x", 1, 1, MSG_OOB);
535         epollpair(false);
536         siocatmarkpair(true);
537 
538         sendpair("y", 1, MSG_OOB);
539         epollpair(true);
540         siocatmarkpair(true);
541 
542         recvpair("", -EAGAIN, 1, 0);
543         epollpair(false);
544         siocatmarkpair(false);
545 
546         recvpair("", -EINVAL, 1, MSG_OOB);
547         epollpair(false);
548         siocatmarkpair(false);
549 }
550 
551 TEST_F(msg_oob, ex_oob_ahead_break)
552 {
553         sendpair("hello", 5, MSG_OOB);
554         epollpair(true);
555         siocatmarkpair(false);
556 
557         sendpair("wor", 3, MSG_OOB);
558         epollpair(true);
559         siocatmarkpair(false);
560 
561         recvpair("r", 1, 1, MSG_OOB);
562         epollpair(false);
563         siocatmarkpair(false);
564 
565         sendpair("ld", 2, MSG_OOB);
566         epollpair(true);
567         siocatmarkpair(false);
568 
569         tcp_incompliant {
570                 recvpair("hellowol", 8, 10, 0); /* TCP recv()s "helloworl", why "r" ?? */
571         }
572 
573         epollpair(true);
574         siocatmarkpair(true);
575 
576         recvpair("d", 1, 1, MSG_OOB);
577         epollpair(false);
578         siocatmarkpair(true);
579 }
580 
581 TEST_F(msg_oob, ex_oob_siocatmark)
582 {
583         sendpair("hello", 5, MSG_OOB);
584         epollpair(true);
585         siocatmarkpair(false);
586 
587         recvpair("o", 1, 1, MSG_OOB);
588         epollpair(false);
589         siocatmarkpair(false);
590 
591         sendpair("world", 5, MSG_OOB);
592         epollpair(true);
593         siocatmarkpair(false);
594 
595         recvpair("hell", 4, 4, 0);              /* Intentionally stop at ex-OOB. */
596         epollpair(true);
597         siocatmarkpair(false);
598 }
599 
600 TEST_F(msg_oob, inline_oob)
601 {
602         setinlinepair();
603 
604         sendpair("x", 1, MSG_OOB);
605         epollpair(true);
606         siocatmarkpair(true);
607 
608         recvpair("", -EINVAL, 1, MSG_OOB);
609         epollpair(true);
610         siocatmarkpair(true);
611 
612         recvpair("x", 1, 1, 0);
613         epollpair(false);
614         siocatmarkpair(false);
615 }
616 
617 TEST_F(msg_oob, inline_oob_break)
618 {
619         setinlinepair();
620 
621         sendpair("hello", 5, MSG_OOB);
622         epollpair(true);
623         siocatmarkpair(false);
624 
625         recvpair("", -EINVAL, 1, MSG_OOB);
626         epollpair(true);
627         siocatmarkpair(false);
628 
629         recvpair("hell", 4, 5, 0);              /* Break at OOB but not at ex-OOB. */
630         epollpair(true);
631         siocatmarkpair(true);
632 
633         recvpair("o", 1, 1, 0);
634         epollpair(false);
635         siocatmarkpair(false);
636 }
637 
638 TEST_F(msg_oob, inline_oob_ahead_break)
639 {
640         sendpair("hello", 5, MSG_OOB);
641         epollpair(true);
642         siocatmarkpair(false);
643 
644         sendpair("world", 5, 0);
645         epollpair(true);
646         siocatmarkpair(false);
647 
648         recvpair("o", 1, 1, MSG_OOB);
649         epollpair(false);
650         siocatmarkpair(false);
651 
652         setinlinepair();
653 
654         recvpair("hell", 4, 9, 0);              /* Break at OOB even with enough buffer. */
655         epollpair(false);
656         siocatmarkpair(true);
657 
658         tcp_incompliant {
659                 recvpair("world", 5, 6, 0);     /* TCP recv()s "oworld", ... "o" ??? */
660         }
661 
662         epollpair(false);
663         siocatmarkpair(false);
664 }
665 
666 TEST_F(msg_oob, inline_ex_oob_break)
667 {
668         sendpair("hello", 5, MSG_OOB);
669         epollpair(true);
670         siocatmarkpair(false);
671 
672         sendpair("wor", 3, MSG_OOB);
673         epollpair(true);
674         siocatmarkpair(false);
675 
676         sendpair("ld", 2, 0);
677         epollpair(true);
678         siocatmarkpair(false);
679 
680         setinlinepair();
681 
682         recvpair("hellowo", 7, 10, 0);          /* Break at OOB but not at ex-OOB. */
683         epollpair(true);
684         siocatmarkpair(true);
685 
686         recvpair("rld", 3, 3, 0);
687         epollpair(false);
688         siocatmarkpair(false);
689 }
690 
691 TEST_F(msg_oob, inline_ex_oob_no_drop)
692 {
693         sendpair("x", 1, MSG_OOB);
694         epollpair(true);
695         siocatmarkpair(true);
696 
697         setinlinepair();
698 
699         sendpair("y", 1, MSG_OOB);              /* TCP does NOT drops "x" at this moment. */
700         epollpair(true);
701         siocatmarkpair(false);
702 
703         recvpair("x", 1, 1, 0);
704         epollpair(true);
705         siocatmarkpair(true);
706 
707         recvpair("y", 1, 1, 0);
708         epollpair(false);
709         siocatmarkpair(false);
710 }
711 
712 TEST_F(msg_oob, inline_ex_oob_drop)
713 {
714         sendpair("x", 1, MSG_OOB);
715         epollpair(true);
716         siocatmarkpair(true);
717 
718         sendpair("y", 1, MSG_OOB);              /* TCP drops "x" at this moment. */
719         epollpair(true);
720 
721         setinlinepair();
722 
723         tcp_incompliant {
724                 siocatmarkpair(false);
725 
726                 recvpair("x", 1, 1, 0);         /* TCP recv()s "y". */
727                 epollpair(true);
728                 siocatmarkpair(true);
729 
730                 recvpair("y", 1, 1, 0);         /* TCP returns -EAGAIN. */
731                 epollpair(false);
732                 siocatmarkpair(false);
733         }
734 }
735 
736 TEST_F(msg_oob, inline_ex_oob_siocatmark)
737 {
738         sendpair("hello", 5, MSG_OOB);
739         epollpair(true);
740         siocatmarkpair(false);
741 
742         recvpair("o", 1, 1, MSG_OOB);
743         epollpair(false);
744         siocatmarkpair(false);
745 
746         setinlinepair();
747 
748         sendpair("world", 5, MSG_OOB);
749         epollpair(true);
750         siocatmarkpair(false);
751 
752         recvpair("hell", 4, 4, 0);              /* Intentionally stop at ex-OOB. */
753         epollpair(true);
754         siocatmarkpair(false);
755 }
756 
757 TEST_HARNESS_MAIN
758 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php