From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 4068A5A0323 for ; Wed, 17 Jul 2024 06:52:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1721191945; bh=NFvHhjs9HZWmKOWutQFlJ/wz0a0xEq19IPFU61xvBYk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mF1Bbw0erAOb7eZtdV8abvX2S+X17GPATZ8pDn0rZW1j2AG9M/zWf4Ca8QfHHfS6p J6uLFt7heifX6JnCkNs7mx4AIbIHpajhCsRnI7zubHQs9E1uVitBcecVCjY3CrR+YJ 2GOtF9ZOYs8JIWmjgjAk27zhou39rMx6dyis/zc4ejNfyMIJ0RjTvSwjB3qc5TMLDH asvgi82qss0LeVhHrJTAFIiAlbMja+5Fva7hEn9vLIdTtsIylFmUwSsGqqwcLvGPXq gpyTo6li2+taMBE+LVsz/RriT4O1gDtNeJj9iLk2RpZIPnILdqJ5fjHsfLQ00vkT4Z eogSFcK02eXaw== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4WP3T54Gjbz4wcl; Wed, 17 Jul 2024 14:52:25 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 5/6] doc: Test behaviour of closing duplicate UDP sockets Date: Wed, 17 Jul 2024 14:52:22 +1000 Message-ID: <20240717045223.2309975-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240717045223.2309975-1-david@gibson.dropbear.id.au> References: <20240717045223.2309975-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 42W4B4EJUVQR42JVA4NFCPR77N3ABRU3 X-Message-ID-Hash: 42W4B4EJUVQR42JVA4NFCPR77N3ABRU3 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: To simplify lifetime management of "listening" UDP sockets, UDP flow support needs to duplicate existing bound sockets. Those duplicates will be close()d when their corresponding flow expires, but we expect the original to still receive datagrams as always. That is, we expect the close() on the duplicate to remove the duplicated fd, but not to close the underlying UDP socket. Add a test program to doc/platform-requirements to verify this requirement. Signed-off-by: David Gibson --- doc/platform-requirements/.gitignore | 1 + doc/platform-requirements/Makefile | 4 +- doc/platform-requirements/udp-close-dup.c | 105 ++++++++++++++++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 doc/platform-requirements/udp-close-dup.c diff --git a/doc/platform-requirements/.gitignore b/doc/platform-requirements/.gitignore index 555031d8..3b5a10ac 100644 --- a/doc/platform-requirements/.gitignore +++ b/doc/platform-requirements/.gitignore @@ -1,2 +1,3 @@ /reuseaddr-priority /recv-zero +/udp-close-dup diff --git a/doc/platform-requirements/Makefile b/doc/platform-requirements/Makefile index 82aaac29..6a7d3748 100644 --- a/doc/platform-requirements/Makefile +++ b/doc/platform-requirements/Makefile @@ -3,8 +3,8 @@ # Copyright Red Hat # Author: David Gibson -TARGETS = reuseaddr-priority recv-zero -SRCS = reuseaddr-priority.c recv-zero.c +TARGETS = reuseaddr-priority recv-zero udp-close-dup +SRCS = reuseaddr-priority.c recv-zero.c udp-close-dup.c CFLAGS = -Wall all: cppcheck clang-tidy $(TARGETS:%=check-%) diff --git a/doc/platform-requirements/udp-close-dup.c b/doc/platform-requirements/udp-close-dup.c new file mode 100644 index 00000000..99060fcb --- /dev/null +++ b/doc/platform-requirements/udp-close-dup.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* udp-close-dup.c + * + * Verify that closing one dup() of a UDP socket won't stop other dups from + * receiving packets. + * + * Copyright Red Hat + * Author: David Gibson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#define DSTPORT 13257U + +/* 127.0.0.1:DSTPORT */ +static const struct sockaddr_in lo_dst = SOCKADDR_INIT(INADDR_LOOPBACK, DSTPORT); + +enum dup_method { + DUP_DUP, + DUP_FCNTL, + NUM_METHODS, +}; + +static void test_close_dup(enum dup_method method) +{ + long token; + int s1, s2, send_s; + ssize_t rc; + + s1 = sock_reuseaddr(); + if (bind(s1, (struct sockaddr *)&lo_dst, sizeof(lo_dst)) < 0) + die("bind(): %s\n", strerror(errno)); + + send_s = sock_reuseaddr(); + if (connect(send_s, (struct sockaddr *)&lo_dst, sizeof(lo_dst)) < 0) + die("connect(): %s\n", strerror(errno)); + + /* Receive before duplicating */ + token = random(); + send_token(send_s, token); + recv_token(s1, token); + + switch (method) { + case DUP_DUP: + /* NOLINTNEXTLINE(android-cloexec-dup) */ + s2 = dup(s1); + if (s2 < 0) + die("dup(): %s\n", strerror(errno)); + break; + case DUP_FCNTL: + s2 = fcntl(s1, F_DUPFD_CLOEXEC, 0); + if (s2 < 0) + die("F_DUPFD_CLOEXEC: %s\n", strerror(errno)); + break; + default: + die("Bad method\n"); + } + + /* Receive via original handle */ + token = random(); + send_token(send_s, token); + recv_token(s1, token); + + /* Receive via duplicated handle */ + token = random(); + send_token(send_s, token); + recv_token(s2, token); + + /* Close duplicate */ + rc = close(s2); + if (rc < 0) + die("close() dup: %s\n", strerror(errno)); + + /* Receive after closing duplicate */ + token = random(); + send_token(send_s, token); + recv_token(s1, token); +} + +int main(int argc, char *argv[]) +{ + enum dup_method method; + + (void)argc; + (void)argv; + + for (method = 0; method < NUM_METHODS; method++) + test_close_dup(method); + + printf("Closing dup()ed UDP sockets seems to work as expected\n"); + + exit(0); +} -- 2.45.2