doc: Extend zero-recv test with methods using msghdr

This test program verifies that we can receive and discard datagrams by
using recv() with a NULL buffer and zero-length.  Extend it to verify it
also works using recvmsg() and either an iov with a zero-length NULL
buffer or an iov that itself is NULL and zero-length.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[sbrivio: Fixed printf() message in main of recv-zero.c]
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2024-07-17 14:52:23 +10:00 committed by Stefano Brivio
parent 01e5611ec3
commit ba74b1fea1

View file

@ -23,11 +23,27 @@
#define DSTPORT 13257U #define DSTPORT 13257U
enum discard_method {
DISCARD_NULL_BUF,
DISCARD_ZERO_IOV,
DISCARD_NULL_IOV,
NUM_METHODS,
};
/* 127.0.0.1:DSTPORT */ /* 127.0.0.1:DSTPORT */
static const struct sockaddr_in lo_dst = SOCKADDR_INIT(INADDR_LOOPBACK, DSTPORT); static const struct sockaddr_in lo_dst = SOCKADDR_INIT(INADDR_LOOPBACK, DSTPORT);
static void test_discard(void) static void test_discard(enum discard_method method)
{ {
struct iovec zero_iov = { .iov_base = NULL, .iov_len = 0, };
struct msghdr mh_zero = {
.msg_iov = &zero_iov,
.msg_iovlen = 1,
};
struct msghdr mh_null = {
.msg_iov = NULL,
.msg_iovlen = 0,
};
long token1, token2; long token1, token2;
int recv_s, send_s; int recv_s, send_s;
ssize_t rc; ssize_t rc;
@ -46,11 +62,36 @@ static void test_discard(void)
send_token(send_s, token1); send_token(send_s, token1);
send_token(send_s, token2); send_token(send_s, token2);
/* cppcheck-suppress nullPointer */ switch (method) {
rc = recv(recv_s, NULL, 0, MSG_DONTWAIT); case DISCARD_NULL_BUF:
if (rc < 0) /* cppcheck-suppress nullPointer */
die("discarding recv(): %s\n", strerror(errno)); rc = recv(recv_s, NULL, 0, MSG_DONTWAIT);
if (rc < 0)
die("discarding recv(): %s\n", strerror(errno));
break;
case DISCARD_ZERO_IOV:
rc = recvmsg(recv_s, &mh_zero, MSG_DONTWAIT);
if (rc < 0)
die("recvmsg() with zero-length buffer: %s\n",
strerror(errno));
if (!((unsigned)mh_zero.msg_flags & MSG_TRUNC))
die("Missing MSG_TRUNC flag\n");
break;
case DISCARD_NULL_IOV:
rc = recvmsg(recv_s, &mh_null, MSG_DONTWAIT);
if (rc < 0)
die("recvmsg() with zero-length iov: %s\n",
strerror(errno));
if (!((unsigned)mh_null.msg_flags & MSG_TRUNC))
die("Missing MSG_TRUNC flag\n");
break;
default:
die("Bad method\n");
}
recv_token(recv_s, token2); recv_token(recv_s, token2);
/* cppcheck-suppress nullPointer */ /* cppcheck-suppress nullPointer */
@ -63,12 +104,15 @@ static void test_discard(void)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
enum discard_method method;
(void)argc; (void)argc;
(void)argv; (void)argv;
test_discard(); for (method = 0; method < NUM_METHODS; method++)
test_discard(method);
printf("Discarding datagrams with a 0-length recv() seems to work\n"); printf("Discarding datagrams with 0-length receives seems to work\n");
exit(0); exit(0);
} }