Extend the so_peek_off selftest to validate behavior after MSG_PEEK. After exercising SO_PEEK_OFF via MSG_PEEK, drain the receive queue with a non-peek recv() and verify that it can receive all the content in the buffer and SO_PEEK_OFF returns back to 0. This improvement is suggested by Miao Wang when the so_peek_off selftest was added. Link: https://lore.kernel.org/all/7B657CC7-B5CA-46D2-8A4B-8AB5FB83C6DA@gmail.com/ Suggested-by: Miao Wang Signed-off-by: Soichiro Ueda --- .../selftests/net/af_unix/so_peek_off.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tools/testing/selftests/net/af_unix/so_peek_off.c b/tools/testing/selftests/net/af_unix/so_peek_off.c index 86e7b0fb522d..813e3b3655d3 100644 --- a/tools/testing/selftests/net/af_unix/so_peek_off.c +++ b/tools/testing/selftests/net/af_unix/so_peek_off.c @@ -76,6 +76,19 @@ FIXTURE_TEARDOWN(so_peek_off) ASSERT_STREQ(str, buf); \ } while (0) +#define peekoffeq(fd, expected) \ + do { \ + int off = -1; \ + socklen_t optlen = sizeof(off); \ + int ret; \ + \ + ret = getsockopt(fd, SOL_SOCKET, SO_PEEK_OFF, \ + &off, &optlen); \ + ASSERT_EQ(0, ret); \ + ASSERT_EQ((socklen_t)sizeof(off), optlen); \ + ASSERT_EQ(expected, off); \ + } while (0) + #define async \ for (pid_t pid = (pid = fork(), \ pid < 0 ? \ @@ -92,6 +105,14 @@ TEST_F(so_peek_off, single_chunk) recveq(self->fd[1], "aaaa", 4, MSG_PEEK); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); + + if (variant->type == SOCK_STREAM) { + recveq(self->fd[1], "aaaa", 4, 0); + recveq(self->fd[1], "bbbb", 100, 0); + } else { + recveq(self->fd[1], "aaaabbbb", 100, 0); + } + peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks) @@ -101,6 +122,13 @@ TEST_F(so_peek_off, two_chunks) recveq(self->fd[1], "aaaa", 4, MSG_PEEK); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); + + if (variant->type == SOCK_STREAM) + recveq(self->fd[1], "aaaa", 4, 0); + else + recveq(self->fd[1], "aaaa", 100, 0); + recveq(self->fd[1], "bbbb", 100, 0); + peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks_blocking) @@ -119,6 +147,13 @@ TEST_F(so_peek_off, two_chunks_blocking) /* goto again; -> goto redo; in unix_stream_read_generic(). */ recveq(self->fd[1], "bbbb", 100, MSG_PEEK); + + if (variant->type == SOCK_STREAM) + recveq(self->fd[1], "aaaa", 4, 0); + else + recveq(self->fd[1], "aaaa", 100, 0); + recveq(self->fd[1], "bbbb", 100, 0); + peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks_overlap) @@ -137,6 +172,13 @@ TEST_F(so_peek_off, two_chunks_overlap) recveq(self->fd[1], "aa", 100, MSG_PEEK); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); } + + if (variant->type == SOCK_STREAM) + recveq(self->fd[1], "aaaa", 4, 0); + else + recveq(self->fd[1], "aaaa", 100, 0); + recveq(self->fd[1], "bbbb", 100, 0); + peekoffeq(self->fd[1], 0); } TEST_F(so_peek_off, two_chunks_overlap_blocking) @@ -157,6 +199,13 @@ TEST_F(so_peek_off, two_chunks_overlap_blocking) recveq(self->fd[1], "aa", 100, MSG_PEEK); recveq(self->fd[1], "bbbb", 100, MSG_PEEK); + + if (variant->type == SOCK_STREAM) + recveq(self->fd[1], "aaaa", 4, 0); + else + recveq(self->fd[1], "aaaa", 100, 0); + recveq(self->fd[1], "bbbb", 100, 0); + peekoffeq(self->fd[1], 0); } TEST_HARNESS_MAIN -- 2.52.0