66#include <unistd.h>
77
88#include <netinet/in.h>
9+ #include <sys/epoll.h>
910#include <sys/ioctl.h>
1011#include <sys/signalfd.h>
1112#include <sys/socket.h>
@@ -22,6 +23,9 @@ FIXTURE(msg_oob)
2223 * 3: TCP receiver
2324 */
2425 int signal_fd ;
26+ int epoll_fd [2 ]; /* 0: AF_UNIX receiver
27+ * 1: TCP receiver
28+ */
2529 bool tcp_compliant ;
2630};
2731
@@ -109,6 +113,25 @@ static void setup_sigurg(struct __test_metadata *_metadata,
109113 ASSERT_EQ (ret , -1 );
110114}
111115
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+
112135static void close_sockets (FIXTURE_DATA (msg_oob ) * self )
113136{
114137 int i ;
@@ -123,6 +146,7 @@ FIXTURE_SETUP(msg_oob)
123146 create_tcp_socketpair (_metadata , self );
124147
125148 setup_sigurg (_metadata , self );
149+ setup_epollpri (_metadata , self );
126150
127151 self -> tcp_compliant = true;
128152}
@@ -132,6 +156,29 @@ FIXTURE_TEARDOWN(msg_oob)
132156 close_sockets (self );
133157}
134158
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+
135182static void __sendpair (struct __test_metadata * _metadata ,
136183 FIXTURE_DATA (msg_oob ) * self ,
137184 const void * buf , size_t len , int flags )
@@ -254,6 +301,9 @@ static void __setinlinepair(struct __test_metadata *_metadata,
254301 expected_buf, expected_len, buf_len, flags); \
255302 } while (0)
256303
304+ #define epollpair (oob_remaining ) \
305+ __epollpair(_metadata, self, oob_remaining)
306+
257307#define setinlinepair () \
258308 __setinlinepair(_metadata, self)
259309
@@ -265,182 +315,279 @@ static void __setinlinepair(struct __test_metadata *_metadata,
265315TEST_F (msg_oob , non_oob )
266316{
267317 sendpair ("x" , 1 , 0 );
318+ epollpair (false);
268319
269320 recvpair ("" , - EINVAL , 1 , MSG_OOB );
321+ epollpair (false);
270322}
271323
272324TEST_F (msg_oob , oob )
273325{
274326 sendpair ("x" , 1 , MSG_OOB );
327+ epollpair (true);
275328
276329 recvpair ("x" , 1 , 1 , MSG_OOB );
330+ epollpair (false);
277331}
278332
279333TEST_F (msg_oob , oob_drop )
280334{
281335 sendpair ("x" , 1 , MSG_OOB );
336+ epollpair (true);
282337
283338 recvpair ("" , - EAGAIN , 1 , 0 ); /* Drop OOB. */
339+ epollpair (false);
340+
284341 recvpair ("" , - EINVAL , 1 , MSG_OOB );
342+ epollpair (false);
285343}
286344
287345TEST_F (msg_oob , oob_ahead )
288346{
289347 sendpair ("hello" , 5 , MSG_OOB );
348+ epollpair (true);
290349
291350 recvpair ("o" , 1 , 1 , MSG_OOB );
351+ epollpair (false);
352+
292353 recvpair ("hell" , 4 , 4 , 0 );
354+ epollpair (false);
293355}
294356
295357TEST_F (msg_oob , oob_break )
296358{
297359 sendpair ("hello" , 5 , MSG_OOB );
360+ epollpair (true);
298361
299362 recvpair ("hell" , 4 , 5 , 0 ); /* Break at OOB even with enough buffer. */
363+ epollpair (true);
364+
300365 recvpair ("o" , 1 , 1 , MSG_OOB );
366+ epollpair (false);
301367}
302368
303369TEST_F (msg_oob , oob_ahead_break )
304370{
305371 sendpair ("hello" , 5 , MSG_OOB );
372+ epollpair (true);
373+
306374 sendpair ("world" , 5 , 0 );
375+ epollpair (true);
307376
308377 recvpair ("o" , 1 , 1 , MSG_OOB );
378+ epollpair (false);
379+
309380 recvpair ("hell" , 4 , 9 , 0 ); /* Break at OOB even after it's recv()ed. */
381+ epollpair (false);
382+
310383 recvpair ("world" , 5 , 5 , 0 );
384+ epollpair (false);
311385}
312386
313387TEST_F (msg_oob , oob_break_drop )
314388{
315389 sendpair ("hello" , 5 , MSG_OOB );
390+ epollpair (true);
391+
316392 sendpair ("world" , 5 , 0 );
393+ epollpair (true);
317394
318395 recvpair ("hell" , 4 , 10 , 0 ); /* Break at OOB even with enough buffer. */
396+ epollpair (true);
397+
319398 recvpair ("world" , 5 , 10 , 0 ); /* Drop OOB and recv() the next skb. */
399+ epollpair (false);
400+
320401 recvpair ("" , - EINVAL , 1 , MSG_OOB );
402+ epollpair (false);
321403}
322404
323405TEST_F (msg_oob , ex_oob_break )
324406{
325407 sendpair ("hello" , 5 , MSG_OOB );
408+ epollpair (true);
409+
326410 sendpair ("wor" , 3 , MSG_OOB );
411+ epollpair (true);
412+
327413 sendpair ("ld" , 2 , 0 );
414+ epollpair (true);
328415
329416 recvpair ("hellowo" , 7 , 10 , 0 ); /* Break at OOB but not at ex-OOB. */
417+ epollpair (true);
418+
330419 recvpair ("r" , 1 , 1 , MSG_OOB );
420+ epollpair (false);
421+
331422 recvpair ("ld" , 2 , 2 , 0 );
423+ epollpair (false);
332424}
333425
334426TEST_F (msg_oob , ex_oob_drop )
335427{
336428 sendpair ("x" , 1 , MSG_OOB );
429+ epollpair (true);
430+
337431 sendpair ("y" , 1 , MSG_OOB ); /* TCP drops "x" at this moment. */
432+ epollpair (true);
338433
339434 tcp_incompliant {
340435 recvpair ("x" , 1 , 1 , 0 ); /* TCP drops "y" by passing through it. */
436+ epollpair (true);
437+
341438 recvpair ("y" , 1 , 1 , MSG_OOB ); /* TCP returns -EINVAL. */
439+ epollpair (false);
342440 }
343441}
344442
345443TEST_F (msg_oob , ex_oob_drop_2 )
346444{
347445 sendpair ("x" , 1 , MSG_OOB );
446+ epollpair (true);
447+
348448 sendpair ("y" , 1 , MSG_OOB ); /* TCP drops "x" at this moment. */
449+ epollpair (true);
349450
350451 recvpair ("y" , 1 , 1 , MSG_OOB );
452+ epollpair (false);
351453
352454 tcp_incompliant {
353455 recvpair ("x" , 1 , 1 , 0 ); /* TCP returns -EAGAIN. */
456+ epollpair (false);
354457 }
355458}
356459
357460TEST_F (msg_oob , ex_oob_ahead_break )
358461{
359462 sendpair ("hello" , 5 , MSG_OOB );
463+ epollpair (true);
464+
360465 sendpair ("wor" , 3 , MSG_OOB );
466+ epollpair (true);
361467
362468 recvpair ("r" , 1 , 1 , MSG_OOB );
469+ epollpair (false);
363470
364471 sendpair ("ld" , 2 , MSG_OOB );
472+ epollpair (true);
365473
366474 tcp_incompliant {
367475 recvpair ("hellowol" , 8 , 10 , 0 ); /* TCP recv()s "helloworl", why "r" ?? */
368476 }
369477
478+ epollpair (true);
479+
370480 recvpair ("d" , 1 , 1 , MSG_OOB );
481+ epollpair (false);
371482}
372483
373484TEST_F (msg_oob , inline_oob )
374485{
375486 setinlinepair ();
376487
377488 sendpair ("x" , 1 , MSG_OOB );
489+ epollpair (true);
378490
379491 recvpair ("" , - EINVAL , 1 , MSG_OOB );
492+ epollpair (true);
493+
380494 recvpair ("x" , 1 , 1 , 0 );
495+ epollpair (false);
381496}
382497
383498TEST_F (msg_oob , inline_oob_break )
384499{
385500 setinlinepair ();
386501
387502 sendpair ("hello" , 5 , MSG_OOB );
503+ epollpair (true);
388504
389505 recvpair ("" , - EINVAL , 1 , MSG_OOB );
506+ epollpair (true);
507+
390508 recvpair ("hell" , 4 , 5 , 0 ); /* Break at OOB but not at ex-OOB. */
509+ epollpair (true);
510+
391511 recvpair ("o" , 1 , 1 , 0 );
512+ epollpair (false);
392513}
393514
394515TEST_F (msg_oob , inline_oob_ahead_break )
395516{
396517 sendpair ("hello" , 5 , MSG_OOB );
518+ epollpair (true);
519+
397520 sendpair ("world" , 5 , 0 );
521+ epollpair (true);
398522
399523 recvpair ("o" , 1 , 1 , MSG_OOB );
524+ epollpair (false);
400525
401526 setinlinepair ();
402527
403528 recvpair ("hell" , 4 , 9 , 0 ); /* Break at OOB even with enough buffer. */
529+ epollpair (false);
404530
405531 tcp_incompliant {
406532 recvpair ("world" , 5 , 6 , 0 ); /* TCP recv()s "oworld", ... "o" ??? */
407533 }
534+
535+ epollpair (false);
408536}
409537
410538TEST_F (msg_oob , inline_ex_oob_break )
411539{
412540 sendpair ("hello" , 5 , MSG_OOB );
541+ epollpair (true);
542+
413543 sendpair ("wor" , 3 , MSG_OOB );
544+ epollpair (true);
545+
414546 sendpair ("ld" , 2 , 0 );
547+ epollpair (true);
415548
416549 setinlinepair ();
417550
418551 recvpair ("hellowo" , 7 , 10 , 0 ); /* Break at OOB but not at ex-OOB. */
552+ epollpair (true);
553+
419554 recvpair ("rld" , 3 , 3 , 0 );
555+ epollpair (false);
420556}
421557
422558TEST_F (msg_oob , inline_ex_oob_no_drop )
423559{
424560 sendpair ("x" , 1 , MSG_OOB );
561+ epollpair (true);
425562
426563 setinlinepair ();
427564
428565 sendpair ("y" , 1 , MSG_OOB ); /* TCP does NOT drops "x" at this moment. */
566+ epollpair (true);
429567
430568 recvpair ("x" , 1 , 1 , 0 );
569+ epollpair (true);
570+
431571 recvpair ("y" , 1 , 1 , 0 );
572+ epollpair (false);
432573}
433574
434575TEST_F (msg_oob , inline_ex_oob_drop )
435576{
436577 sendpair ("x" , 1 , MSG_OOB );
578+ epollpair (true);
579+
437580 sendpair ("y" , 1 , MSG_OOB ); /* TCP drops "x" at this moment. */
581+ epollpair (true);
438582
439583 setinlinepair ();
440584
441585 tcp_incompliant {
442586 recvpair ("x" , 1 , 1 , 0 ); /* TCP recv()s "y". */
587+ epollpair (true);
588+
443589 recvpair ("y" , 1 , 1 , 0 ); /* TCP returns -EAGAIN. */
590+ epollpair (false);
444591 }
445592}
446593
0 commit comments