From nobody Fri Dec 19 02:50:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747835744; cv=none; d=zohomail.com; s=zohoarc; b=jHaHQbEmuHMMQ10l/qPCIDGiU/hrjXpkkMMNkN8+tSQJno37E8Esa0mxYa5tNRrnCa8cEVbOBde+IZOjVNK8cpVINkGY92jwikoJSIPY4teffyOT6yqDItpg9OlNWQo1vKq0POLIKvhBu999J9hBdLyok/j4GxOBI3oneF+Z2uU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747835744; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=KVKDOWFdrwGJNR46YeE3iOgMzM7afZeL0i/xV90sWQg=; b=GDTGXEGPDupkTTXbnEZq6alzFzkkh2uSB/EooFuXBMuLQ/rprU/aTCwbqTjxcj3sLEfZ0EXAts5UEJW8I2RUSYhkxoGOLWnqTLZ5u6zwY9pqrAJcwzEtEAJ2Vzn/3oecYjkOq4XQOGSOfkPK1pwC/Ere0+L6H5u5P0nH3wZlIDE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747835744838452.5508023406395; Wed, 21 May 2025 06:55:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHjuq-0008C8-62; Wed, 21 May 2025 09:55:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuY-000848-J5 for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:10 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuW-00073l-Nq for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:10 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-576-8U5x5RFUNdmBuPgYwwSbwQ-1; Wed, 21 May 2025 09:55:04 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A9F1A1956050; Wed, 21 May 2025 13:55:03 +0000 (UTC) Received: from fedora.brq.redhat.com (unknown [10.43.2.64]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D601619560AB; Wed, 21 May 2025 13:55:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747835708; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KVKDOWFdrwGJNR46YeE3iOgMzM7afZeL0i/xV90sWQg=; b=hGlsg0Y9BfY3Soby+rMJxr7HpFLGCeqKpSbFzJdMlvyJgiRFk7wbC9VRosZhaEKs9/WvdC qhxth7FVpfhRe72wA8MjWawuNh+HZw1nR0CCeMcjbSyunFPksENpzUuNX460bQabgt7U04 KieCzITs+fLLvL6sr+0SUgOlW9xKNM0= X-MC-Unique: 8U5x5RFUNdmBuPgYwwSbwQ-1 X-Mimecast-MFC-AGG-ID: 8U5x5RFUNdmBuPgYwwSbwQ_1747835703 From: Juraj Marcin To: qemu-devel@nongnu.org Cc: Juraj Marcin , vsementsov@yandex-team.ru, =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini Subject: [PATCH v5 1/6] io: Fix partial struct copy in qio_dns_resolver_lookup_sync_inet() Date: Wed, 21 May 2025 15:52:30 +0200 Message-ID: <20250521135240.3941598-2-jmarcin@redhat.com> In-Reply-To: <20250521135240.3941598-1-jmarcin@redhat.com> References: <20250521135240.3941598-1-jmarcin@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=jmarcin@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.184, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747835746422116600 From: Juraj Marcin Commit aec21d3175 (qapi: Add InetSocketAddress member keep-alive) introduces the keep-alive flag, but this flag is not copied together with other options in qio_dns_resolver_lookup_sync_inet(). This patch fixes this issue and also prevents future ones by copying the entire structure first and only then overriding a few attributes that need to be different. Fixes: aec21d31756c (qapi: Add InetSocketAddress member keep-alive) Signed-off-by: Juraj Marcin Reviewed-by: Daniel P. Berrang=C3=A9 --- io/dns-resolver.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/io/dns-resolver.c b/io/dns-resolver.c index 53b0e8407a..3712438f82 100644 --- a/io/dns-resolver.c +++ b/io/dns-resolver.c @@ -111,22 +111,11 @@ static int qio_dns_resolver_lookup_sync_inet(QIODNSRe= solver *resolver, uaddr, INET6_ADDRSTRLEN, uport, 32, NI_NUMERICHOST | NI_NUMERICSERV); =20 - newaddr->u.inet =3D (InetSocketAddress){ - .host =3D g_strdup(uaddr), - .port =3D g_strdup(uport), - .has_numeric =3D true, - .numeric =3D true, - .has_to =3D iaddr->has_to, - .to =3D iaddr->to, - .has_ipv4 =3D iaddr->has_ipv4, - .ipv4 =3D iaddr->ipv4, - .has_ipv6 =3D iaddr->has_ipv6, - .ipv6 =3D iaddr->ipv6, -#ifdef HAVE_IPPROTO_MPTCP - .has_mptcp =3D iaddr->has_mptcp, - .mptcp =3D iaddr->mptcp, -#endif - }; + newaddr->u.inet =3D *iaddr; + newaddr->u.inet.host =3D g_strdup(uaddr), + newaddr->u.inet.port =3D g_strdup(uport), + newaddr->u.inet.has_numeric =3D true, + newaddr->u.inet.numeric =3D true, =20 (*addrs)[i] =3D newaddr; } --=20 2.49.0 From nobody Fri Dec 19 02:50:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747835737; cv=none; d=zohomail.com; s=zohoarc; b=XAkUpMyZUWuTSLWtI3UpUQVl3aXoxUwt8BZnLq2KE2E48fdlzANMz5/K9RzMa4T4c1+h+KzFQCJ88JybhBoAiViH9xgkWXdCFXqKyrXKzL6nDRF7gn28SMWFY94pPwJtjDqVyhf7fa/c6l2xpvsfvGz95Z8HHEV3Wpj8wzGruKw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747835737; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bpjRNdJvEkALUk3Tj5/8rWMF6LVblsPcOhESNvpNl5E=; b=Kt4n76ngrgKcsrWf/g4TSUIz9dviuGN8qk6lakeDqhpjON8WSmDgUmrTPfd4wXpZCow+fXc6ape+lpe18UiYTczyjywNwLPgIMa6SVwTdn8/uKi98gobdigTjtId5ZPK+ySq3pyWbDJGM7f8C8+KVG3cHxhAW8BxqRudWv3VNr4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747835737453199.93835751355834; Wed, 21 May 2025 06:55:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHjus-0008F0-W0; Wed, 21 May 2025 09:55:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuf-00089r-JU for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:20 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjud-00074O-5l for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:16 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-464-qSHIT9HgNAigomyGZ7B_kA-1; Wed, 21 May 2025 09:55:11 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D7C0218004AD; Wed, 21 May 2025 13:55:09 +0000 (UTC) Received: from fedora.brq.redhat.com (unknown [10.43.2.64]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 401B31955E83; Wed, 21 May 2025 13:55:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747835714; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bpjRNdJvEkALUk3Tj5/8rWMF6LVblsPcOhESNvpNl5E=; b=T38+oI5lBnPJxZdYZtrgHrvjZRo4eWi3ze+tc24G0qKXcEv7ErEnymkdPI9AhOg6luuhkV J5BUxxolRaLCY0fwQ7qOfLX/QsHZVknVhGca9aoiK3Rc0W/m8Vk3lRF4APnQWPRAPS/2Zy fSnZo8AZHoOqXhlEr6rq6eyuHOyewNA= X-MC-Unique: qSHIT9HgNAigomyGZ7B_kA-1 X-Mimecast-MFC-AGG-ID: qSHIT9HgNAigomyGZ7B_kA_1747835710 From: Juraj Marcin To: qemu-devel@nongnu.org Cc: Juraj Marcin , vsementsov@yandex-team.ru, =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini Subject: [PATCH v5 2/6] util/qemu-sockets: Refactor setting client sockopts into a separate function Date: Wed, 21 May 2025 15:52:31 +0200 Message-ID: <20250521135240.3941598-3-jmarcin@redhat.com> In-Reply-To: <20250521135240.3941598-1-jmarcin@redhat.com> References: <20250521135240.3941598-1-jmarcin@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=jmarcin@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.184, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747835738267116600 From: Juraj Marcin This is done in preparation for enabling the SO_KEEPALIVE support for server sockets and adding settings for more TCP keep-alive socket options. Signed-off-by: Juraj Marcin Reviewed-by: Daniel P. Berrang=C3=A9 --- util/qemu-sockets.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 77477c1cd5..4a878e0527 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -205,6 +205,22 @@ static int try_bind(int socket, InetSocketAddress *sad= dr, struct addrinfo *e) #endif } =20 +static int inet_set_sockopts(int sock, InetSocketAddress *saddr, Error **e= rrp) +{ + if (saddr->keep_alive) { + int keep_alive =3D 1; + int ret =3D setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, + &keep_alive, sizeof(keep_alive)); + + if (ret < 0) { + error_setg_errno(errp, errno, + "Unable to set keep-alive option on socket"); + return -1; + } + } + return 0; +} + static int inet_listen_saddr(InetSocketAddress *saddr, int port_offset, int num, @@ -475,16 +491,9 @@ int inet_connect_saddr(InetSocketAddress *saddr, Error= **errp) return sock; } =20 - if (saddr->keep_alive) { - int val =3D 1; - int ret =3D setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, - &val, sizeof(val)); - - if (ret < 0) { - error_setg_errno(errp, errno, "Unable to set KEEPALIVE"); - close(sock); - return -1; - } + if (inet_set_sockopts(sock, saddr, errp) < 0) { + close(sock); + return -1; } =20 return sock; --=20 2.49.0 From nobody Fri Dec 19 02:50:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747835783; cv=none; d=zohomail.com; s=zohoarc; b=kaCeHwALNFELWOADoNf3WzYgA7dc4DxtvU/IpEyQGtspKCu2Bz2Rd1vbsXCMsHrupjO4TnxFuKpkPxePznDdXWMLokofsu00BmC7B7GLBzhL0z0aqYSpcPwzH3msdx4HGDRrUOegdc8dAKLhZ0/tBAW2Q246uvUIul3lLa1VTnU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747835783; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=py+TZoPFweDXa675c5l/OIWhVyVWlz3r43R1tVyvdH0=; b=FTraNrVuSk4qKGHGFSw5T5WVN9tkjbSVndqqdI9jzc/Edyl1czpe4eOUtLG6+lBhoqqrv9csJRuRYykXvluNtIRugrj2oSkZtRhRUypm326Xwaw0lRxE85NlE93gM2PUXqYHuO9VfpM+kb3IK1qEs7K4JBML4FtWN2y0eQZwBBs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747835783441877.913802954231; Wed, 21 May 2025 06:56:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHjuv-0008JA-BT; Wed, 21 May 2025 09:55:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjum-0008C0-M1 for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:26 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuk-00074p-Gj for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:24 -0400 Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-528-kIaDzSJAO3aUzBBICWgEOg-1; Wed, 21 May 2025 09:55:16 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9BA1D1954207; Wed, 21 May 2025 13:55:15 +0000 (UTC) Received: from fedora.brq.redhat.com (unknown [10.43.2.64]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 03BDC19560AB; Wed, 21 May 2025 13:55:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747835721; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=py+TZoPFweDXa675c5l/OIWhVyVWlz3r43R1tVyvdH0=; b=Yk4+nW1Po67FbH6YOx3Cnu2lbuLHyeGl5l8g9khhufxzllFHsMWb1ndUVr4d7CUaY+XBym Ry5HvtptMHvOH/TxjjTcbu9jLYKQOTfWe6/rpDI/wEpCfYYchrYsDs0AvuGlpS88p3I2+N IqkBUKLc277s/29NJ/nenOUny6NeRgs= X-MC-Unique: kIaDzSJAO3aUzBBICWgEOg-1 X-Mimecast-MFC-AGG-ID: kIaDzSJAO3aUzBBICWgEOg_1747835716 From: Juraj Marcin To: qemu-devel@nongnu.org Cc: Juraj Marcin , vsementsov@yandex-team.ru, =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini Subject: [PATCH v5 3/6] util/qemu-sockets: Refactor success and failure paths in inet_listen_saddr() Date: Wed, 21 May 2025 15:52:32 +0200 Message-ID: <20250521135240.3941598-4-jmarcin@redhat.com> In-Reply-To: <20250521135240.3941598-1-jmarcin@redhat.com> References: <20250521135240.3941598-1-jmarcin@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=jmarcin@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.184, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747835787010116600 From: Juraj Marcin To get a listening socket, we need to first create a socket, try binding it to a certain port, and lastly starting listening to it. Each of these operations can fail due to various reasons, one of them being that the requested address/port is already in use. In such case, the function tries the same process with a new port number. This patch refactors the port number loop, so the success path is no longer buried inside the 'if' statements in the middle of the loop. Now, the success path is not nested and ends at the end of the iteration after successful socket creation, binding, and listening. In case any of the operations fails, it either continues to the next iteration (and the next port) or jumps out of the loop to handle the error and exits the function. Signed-off-by: Juraj Marcin Reviewed-by: Daniel P. Berrang=C3=A9 --- util/qemu-sockets.c | 51 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 4a878e0527..329fdbfd97 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -303,11 +303,20 @@ static int inet_listen_saddr(InetSocketAddress *saddr, port_min =3D inet_getport(e); port_max =3D saddr->has_to ? saddr->to + port_offset : port_min; for (p =3D port_min; p <=3D port_max; p++) { + if (slisten >=3D 0) { + /* + * We have a socket we tried with the previous port. It ca= nnot + * be rebound, we need to close it and create a new one. + */ + close(slisten); + slisten =3D -1; + } inet_setport(e, p); =20 slisten =3D create_fast_reuse_socket(e); if (slisten < 0) { - /* First time we expect we might fail to create the socket + /* + * First time we expect we might fail to create the socket * eg if 'e' has AF_INET6 but ipv6 kmod is not loaded. * Later iterations should always succeed if first iterati= on * worked though, so treat that as fatal. @@ -317,40 +326,38 @@ static int inet_listen_saddr(InetSocketAddress *saddr, } else { error_setg_errno(errp, errno, "Failed to recreate failed listening = socket"); - goto listen_failed; + goto fail; } } socket_created =3D true; =20 rc =3D try_bind(slisten, saddr, e); if (rc < 0) { - if (errno !=3D EADDRINUSE) { - error_setg_errno(errp, errno, "Failed to bind socket"); - goto listen_failed; + if (errno =3D=3D EADDRINUSE) { + /* This port is already used, try the next one */ + continue; } - } else { - if (!listen(slisten, num)) { - goto listen_ok; - } - if (errno !=3D EADDRINUSE) { - error_setg_errno(errp, errno, "Failed to listen on soc= ket"); - goto listen_failed; + error_setg_errno(errp, errno, "Failed to bind socket"); + goto fail; + } + if (listen(slisten, num)) { + if (errno =3D=3D EADDRINUSE) { + /* This port is already used, try the next one */ + continue; } + error_setg_errno(errp, errno, "Failed to listen on socket"= ); + goto fail; } - /* Someone else managed to bind to the same port and beat us - * to listen on it! Socket semantics does not allow us to - * recover from this situation, so we need to recreate the - * socket to allow bind attempts for subsequent ports: - */ - close(slisten); - slisten =3D -1; + /* We have a listening socket */ + freeaddrinfo(res); + return slisten; } } error_setg_errno(errp, errno, socket_created ? "Failed to find an available port" : "Failed to create a socket"); -listen_failed: +fail: saved_errno =3D errno; if (slisten >=3D 0) { close(slisten); @@ -358,10 +365,6 @@ listen_failed: freeaddrinfo(res); errno =3D saved_errno; return -1; - -listen_ok: - freeaddrinfo(res); - return slisten; } =20 #ifdef _WIN32 --=20 2.49.0 From nobody Fri Dec 19 02:50:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747835797; cv=none; d=zohomail.com; s=zohoarc; b=H1HNJeApTBCOQ2RoNVzha9TS2Pxc0Ibhc+LLRAPNU9un9hmiE2ekZ9mI+uZ2gxfut/sfT2C6EHCt7dBhq63tBBEekNLNvJ49Yv8pa6sVJEm0GnJS1JJX1mewJgZXByUtUGC7DSKJgXEYBdE3Znwtm49Jh99VP8/c6N7F0oDK/BM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747835797; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=B3+EyUCTIK9FqId1wl+BA9m2aXuQYDWfJ5AScKo9HVI=; b=dI+NKNH6j/8lcFb85RHoR9aaGt3+tZkc9aikxqKnNjwoRsKfAm93ssNAMyxWpbzg8Xxh1CdGwosv3MYqoTLN9jdlkCiXJDXY04ZAWJTi+47/c9ZvbFnTCImYiUTzwVor0rzIouFIuBcvVkbfesSibXzTP+IzQThZJ0D2/VPQkLQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747835797689693.0067348843091; Wed, 21 May 2025 06:56:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHjux-0008MG-6Q; Wed, 21 May 2025 09:55:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuo-0008D6-Oc for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:27 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjun-000754-0Q for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:26 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-626-wTsbBlX3MB-rVFMW-97xmA-1; Wed, 21 May 2025 09:55:22 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 095FD18004AD; Wed, 21 May 2025 13:55:21 +0000 (UTC) Received: from fedora.brq.redhat.com (unknown [10.43.2.64]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 66A3F19560AB; Wed, 21 May 2025 13:55:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747835723; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=B3+EyUCTIK9FqId1wl+BA9m2aXuQYDWfJ5AScKo9HVI=; b=cNPzTLVqoVqxnhyVdopk+1Hk66Zy5EHrjuJ9r7cR3xgfr6BehON/VrGy738DDSGJXx+oqL yWSn/JZzLqPH1vN6N7OWQyksdXAEkxdiFgyYHMNor1a4/BbmMJkS3wUbNvySyukD68lfgQ jpMVVz61+TZmlPvVXu9jX+coQWGhwok= X-MC-Unique: wTsbBlX3MB-rVFMW-97xmA-1 X-Mimecast-MFC-AGG-ID: wTsbBlX3MB-rVFMW-97xmA_1747835721 From: Juraj Marcin To: qemu-devel@nongnu.org Cc: Juraj Marcin , vsementsov@yandex-team.ru, =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini Subject: [PATCH v5 4/6] util/qemu-sockets: Add support for keep-alive flag to passive sockets Date: Wed, 21 May 2025 15:52:33 +0200 Message-ID: <20250521135240.3941598-5-jmarcin@redhat.com> In-Reply-To: <20250521135240.3941598-1-jmarcin@redhat.com> References: <20250521135240.3941598-1-jmarcin@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=jmarcin@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.184, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747835798862116600 From: Juraj Marcin Commit aec21d3175 (qapi: Add InetSocketAddress member keep-alive) introduces the keep-alive flag, which enables the SO_KEEPALIVE socket option, but only on client-side sockets. However, this option is also useful for server-side sockets, so they can check if a client is still reachable or drop the connection otherwise. This patch enables the SO_KEEPALIVE socket option on passive server-side sockets if the keep-alive flag is enabled. This socket option is then inherited by active server-side sockets communicating with connected clients. Signed-off-by: Juraj Marcin Reviewed-by: Daniel P. Berrang=C3=A9 --- qapi/sockets.json | 4 ++-- util/qemu-sockets.c | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/qapi/sockets.json b/qapi/sockets.json index 6a95023315..62797cd027 100644 --- a/qapi/sockets.json +++ b/qapi/sockets.json @@ -56,8 +56,8 @@ # @ipv6: whether to accept IPv6 addresses, default try both IPv4 and # IPv6 # -# @keep-alive: enable keep-alive when connecting to this socket. Not -# supported for passive sockets. (Since 4.2) +# @keep-alive: enable keep-alive when connecting to/listening on this sock= et. +# (Since 4.2, not supported for listening sockets until 10.1) # # @mptcp: enable multi-path TCP. (Since 6.1) # diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 329fdbfd97..4fbf1ed5bf 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -236,12 +236,6 @@ static int inet_listen_saddr(InetSocketAddress *saddr, int saved_errno =3D 0; bool socket_created =3D false; =20 - if (saddr->keep_alive) { - error_setg(errp, "keep-alive option is not supported for passive " - "sockets"); - return -1; - } - memset(&ai,0, sizeof(ai)); ai.ai_flags =3D AI_PASSIVE; if (saddr->has_numeric && saddr->numeric) { @@ -349,6 +343,9 @@ static int inet_listen_saddr(InetSocketAddress *saddr, goto fail; } /* We have a listening socket */ + if (inet_set_sockopts(slisten, saddr, errp) < 0) { + goto fail; + } freeaddrinfo(res); return slisten; } --=20 2.49.0 From nobody Fri Dec 19 02:50:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747835826; cv=none; d=zohomail.com; s=zohoarc; b=nUQ/0eNAL7upNxtrVv+pjA/tIW7Fom+I1Uup0zkSeZiZ2JTadwFFKC5AM8VjYLr42JYgpP8nOzUHEMOyImpdc9uDy2JgSrB6uGog9irX5h/7PJ5xsEdUssZlLpy9HwImrNdsAKowhIOf6nzEhGICLxVyNzVrdVLqS0hE3k5o/Is= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747835826; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zcDve3oQvRJolk/sF06L0Z5HFPQUmLIPk/w0wJEutfU=; b=hZUm0pxrw7dXW1AQ9zAhKWtw6ibtmSRVNYNfS9eAyXrmycZ3M++CSvp54hiwhZpbj3O6wvz2kMpQJWm209987H4SlZweby2gnpJMv6QPhfD/yzcMb4wGIKHTL9gYrGPT+ylKiXFi4PiqwHc+ybEV5pz1nASV+X2wsH/5Vw9qCK8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747835826487573.3785942983604; Wed, 21 May 2025 06:57:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHjv6-0000Hf-12; Wed, 21 May 2025 09:55:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjv3-0000EE-BW for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjv0-000767-2G for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:40 -0400 Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-259--_wsRSRJO-ibg3EK8rQzqA-1; Wed, 21 May 2025 09:55:26 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B85D1180036D; Wed, 21 May 2025 13:55:25 +0000 (UTC) Received: from fedora.brq.redhat.com (unknown [10.43.2.64]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E2CC819560AB; Wed, 21 May 2025 13:55:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747835737; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zcDve3oQvRJolk/sF06L0Z5HFPQUmLIPk/w0wJEutfU=; b=ASMknDuZKd/LnRfsb9RI6wY8ExZmMi3X+kiSBGO/hySF1H3iJUbz7O1LthNJZeITDVx2lZ Vb1qCKce3bv4qvhqJtyg8RZc8v3a3TUPnAm3iG4fEv/ooqzP+waL/b3dt1Ojw7kdsq7Ufk 2yjL7dbHEhmxvasMwqGdUY8lQSAJZtI= X-MC-Unique: -_wsRSRJO-ibg3EK8rQzqA-1 X-Mimecast-MFC-AGG-ID: -_wsRSRJO-ibg3EK8rQzqA_1747835726 From: Juraj Marcin To: qemu-devel@nongnu.org Cc: Juraj Marcin , vsementsov@yandex-team.ru, =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini Subject: [PATCH v5 5/6] util/qemu-sockets: Refactor inet_parse() to use QemuOpts Date: Wed, 21 May 2025 15:52:34 +0200 Message-ID: <20250521135240.3941598-6-jmarcin@redhat.com> In-Reply-To: <20250521135240.3941598-1-jmarcin@redhat.com> References: <20250521135240.3941598-1-jmarcin@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=jmarcin@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.184, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747835827513116600 From: Juraj Marcin Currently, the inet address parser cannot handle multiple options where one is prefixed with the name of the other. For example, with the 'keep-alive-idle' option added, the current parser cannot parse '127.0.0.1:5000,keep-alive-idle=3D60,keep-alive' correctly. Instead, it fails with "error parsing 'keep-alive' flag '-idle=3D60,keep-alive'". To resolve these issues, this patch rewrites the inet address parsing using the QemuOpts parser, which the inet_parse_flag() function tries to mimic. This new parser supports all previously supported options and on top of that the 'numeric' flag is now also supported. The only difference is, the new parser produces an error if an unknown option is passed, instead of silently ignoring it. Signed-off-by: Juraj Marcin Reviewed-by: Daniel P. Berrang=C3=A9 --- tests/unit/test-util-sockets.c | 195 +++++++++++++++++++++++++++++++++ util/qemu-sockets.c | 158 +++++++++++++------------- 2 files changed, 269 insertions(+), 84 deletions(-) diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c index 4c9dd0b271..cca609fd90 100644 --- a/tests/unit/test-util-sockets.c +++ b/tests/unit/test-util-sockets.c @@ -332,6 +332,176 @@ static void test_socket_unix_abstract(void) =20 #endif /* CONFIG_LINUX */ =20 +static void inet_parse_test_helper(const char *str, InetSocketAddress *exp= _addr, bool success) +{ + InetSocketAddress addr; + Error *error =3D NULL; + + int rc =3D inet_parse(&addr, str, &error); + + if (success) { + g_assert_cmpint(rc, =3D=3D, 0); + } else { + g_assert_cmpint(rc, <, 0); + } + if (exp_addr !=3D NULL) { + g_assert_cmpstr(addr.host, =3D=3D, exp_addr->host); + g_assert_cmpstr(addr.port, =3D=3D, exp_addr->port); + /* Own members: */ + g_assert_cmpint(addr.has_numeric, =3D=3D, exp_addr->has_numeric); + g_assert_cmpint(addr.numeric, =3D=3D, exp_addr->numeric); + g_assert_cmpint(addr.has_to, =3D=3D, exp_addr->has_to); + g_assert_cmpint(addr.to, =3D=3D, exp_addr->to); + g_assert_cmpint(addr.has_ipv4, =3D=3D, exp_addr->has_ipv4); + g_assert_cmpint(addr.ipv4, =3D=3D, exp_addr->ipv4); + g_assert_cmpint(addr.has_ipv6, =3D=3D, exp_addr->has_ipv6); + g_assert_cmpint(addr.ipv6, =3D=3D, exp_addr->ipv6); + g_assert_cmpint(addr.has_keep_alive, =3D=3D, exp_addr->has_keep_al= ive); + g_assert_cmpint(addr.keep_alive, =3D=3D, exp_addr->keep_alive); +#ifdef HAVE_IPPROTO_MPTCP + g_assert_cmpint(addr.has_mptcp, =3D=3D, exp_addr->has_mptcp); + g_assert_cmpint(addr.mptcp, =3D=3D, exp_addr->mptcp); +#endif + } + + g_free(addr.host); + g_free(addr.port); +} + +static void test_inet_parse_nohost_good(void) +{ + char host[] =3D ""; + char port[] =3D "5000"; + InetSocketAddress exp_addr =3D { + .host =3D host, + .port =3D port, + }; + inet_parse_test_helper(":5000", &exp_addr, true); +} + +static void test_inet_parse_empty_bad(void) +{ + inet_parse_test_helper("", NULL, false); +} + +static void test_inet_parse_only_colon_bad(void) +{ + inet_parse_test_helper(":", NULL, false); +} + +static void test_inet_parse_ipv4_good(void) +{ + char host[] =3D "127.0.0.1"; + char port[] =3D "5000"; + InetSocketAddress exp_addr =3D { + .host =3D host, + .port =3D port, + }; + inet_parse_test_helper("127.0.0.1:5000", &exp_addr, true); +} + +static void test_inet_parse_ipv4_noport_bad(void) +{ + inet_parse_test_helper("127.0.0.1", NULL, false); +} + +static void test_inet_parse_ipv6_good(void) +{ + char host[] =3D "::1"; + char port[] =3D "5000"; + InetSocketAddress exp_addr =3D { + .host =3D host, + .port =3D port, + }; + inet_parse_test_helper("[::1]:5000", &exp_addr, true); +} + +static void test_inet_parse_ipv6_noend_bad(void) +{ + inet_parse_test_helper("[::1", NULL, false); +} + +static void test_inet_parse_ipv6_noport_bad(void) +{ + inet_parse_test_helper("[::1]:", NULL, false); +} + +static void test_inet_parse_ipv6_empty_bad(void) +{ + inet_parse_test_helper("[]:5000", NULL, false); +} + +static void test_inet_parse_hostname_good(void) +{ + char host[] =3D "localhost"; + char port[] =3D "5000"; + InetSocketAddress exp_addr =3D { + .host =3D host, + .port =3D port, + }; + inet_parse_test_helper("localhost:5000", &exp_addr, true); +} + +static void test_inet_parse_all_options_good(void) +{ + char host[] =3D "::1"; + char port[] =3D "5000"; + InetSocketAddress exp_addr =3D { + .host =3D host, + .port =3D port, + .has_numeric =3D true, + .numeric =3D true, + .has_to =3D true, + .to =3D 5006, + .has_ipv4 =3D true, + .ipv4 =3D false, + .has_ipv6 =3D true, + .ipv6 =3D true, + .has_keep_alive =3D true, + .keep_alive =3D true, +#ifdef HAVE_IPPROTO_MPTCP + .has_mptcp =3D true, + .mptcp =3D false, +#endif + }; + inet_parse_test_helper( + "[::1]:5000,numeric=3Don,to=3D5006,ipv4=3Doff,ipv6=3Don,keep-alive= =3Don" +#ifdef HAVE_IPPROTO_MPTCP + ",mptcp=3Doff" +#endif + , &exp_addr, true); +} + +static void test_inet_parse_all_implicit_bool_good(void) +{ + char host[] =3D "::1"; + char port[] =3D "5000"; + InetSocketAddress exp_addr =3D { + .host =3D host, + .port =3D port, + .has_numeric =3D true, + .numeric =3D true, + .has_to =3D true, + .to =3D 5006, + .has_ipv4 =3D true, + .ipv4 =3D true, + .has_ipv6 =3D true, + .ipv6 =3D true, + .has_keep_alive =3D true, + .keep_alive =3D true, +#ifdef HAVE_IPPROTO_MPTCP + .has_mptcp =3D true, + .mptcp =3D true, +#endif + }; + inet_parse_test_helper( + "[::1]:5000,numeric,to=3D5006,ipv4,ipv6,keep-alive" +#ifdef HAVE_IPPROTO_MPTCP + ",mptcp" +#endif + , &exp_addr, true); +} + int main(int argc, char **argv) { bool has_ipv4, has_ipv6; @@ -377,6 +547,31 @@ int main(int argc, char **argv) test_socket_unix_abstract); #endif =20 + g_test_add_func("/util/socket/inet-parse/nohost-good", + test_inet_parse_nohost_good); + g_test_add_func("/util/socket/inet-parse/empty-bad", + test_inet_parse_empty_bad); + g_test_add_func("/util/socket/inet-parse/only-colon-bad", + test_inet_parse_only_colon_bad); + g_test_add_func("/util/socket/inet-parse/ipv4-good", + test_inet_parse_ipv4_good); + g_test_add_func("/util/socket/inet-parse/ipv4-noport-bad", + test_inet_parse_ipv4_noport_bad); + g_test_add_func("/util/socket/inet-parse/ipv6-good", + test_inet_parse_ipv6_good); + g_test_add_func("/util/socket/inet-parse/ipv6-noend-bad", + test_inet_parse_ipv6_noend_bad); + g_test_add_func("/util/socket/inet-parse/ipv6-noport-bad", + test_inet_parse_ipv6_noport_bad); + g_test_add_func("/util/socket/inet-parse/ipv6-empty-bad", + test_inet_parse_ipv6_empty_bad); + g_test_add_func("/util/socket/inet-parse/hostname-good", + test_inet_parse_hostname_good); + g_test_add_func("/util/socket/inet-parse/all-options-good", + test_inet_parse_all_options_good); + g_test_add_func("/util/socket/inet-parse/all-bare-bool-good", + test_inet_parse_all_implicit_bool_good); + end: return g_test_run(); } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 4fbf1ed5bf..403dc26b36 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -30,6 +30,7 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qemu/cutils.h" +#include "qemu/option.h" #include "trace.h" =20 #ifndef AI_ADDRCONFIG @@ -600,115 +601,104 @@ err: return -1; } =20 -/* compatibility wrapper */ -static int inet_parse_flag(const char *flagname, const char *optstr, bool = *val, - Error **errp) -{ - char *end; - size_t len; - - end =3D strstr(optstr, ","); - if (end) { - if (end[1] =3D=3D ',') { /* Reject 'ipv6=3Don,,foo' */ - error_setg(errp, "error parsing '%s' flag '%s'", flagname, opt= str); - return -1; - } - len =3D end - optstr; - } else { - len =3D strlen(optstr); - } - if (len =3D=3D 0 || (len =3D=3D 3 && strncmp(optstr, "=3Don", len) =3D= =3D 0)) { - *val =3D true; - } else if (len =3D=3D 4 && strncmp(optstr, "=3Doff", len) =3D=3D 0) { - *val =3D false; - } else { - error_setg(errp, "error parsing '%s' flag '%s'", flagname, optstr); - return -1; - } - return 0; -} +static QemuOptsList inet_opts =3D { + .name =3D "InetSocketAddress", + .head =3D QTAILQ_HEAD_INITIALIZER(inet_opts.head), + .implied_opt_name =3D "addr", + .desc =3D { + { + .name =3D "addr", + .type =3D QEMU_OPT_STRING, + }, + { + .name =3D "numeric", + .type =3D QEMU_OPT_BOOL, + }, + { + .name =3D "to", + .type =3D QEMU_OPT_NUMBER, + }, + { + .name =3D "ipv4", + .type =3D QEMU_OPT_BOOL, + }, + { + .name =3D "ipv6", + .type =3D QEMU_OPT_BOOL, + }, + { + .name =3D "keep-alive", + .type =3D QEMU_OPT_BOOL, + }, +#ifdef HAVE_IPPROTO_MPTCP + { + .name =3D "mptcp", + .type =3D QEMU_OPT_BOOL, + }, +#endif + { /* end of list */ } + }, +}; =20 int inet_parse(InetSocketAddress *addr, const char *str, Error **errp) { - const char *optstr, *h; - char host[65]; - char port[33]; - int to; - int pos; - char *begin; - + QemuOpts *opts =3D qemu_opts_parse(&inet_opts, str, true, errp); + if (!opts) { + return -1; + } memset(addr, 0, sizeof(*addr)); =20 /* parse address */ - if (str[0] =3D=3D ':') { - /* no host given */ - host[0] =3D '\0'; - if (sscanf(str, ":%32[^,]%n", port, &pos) !=3D 1) { - error_setg(errp, "error parsing port in address '%s'", str); - return -1; - } - } else if (str[0] =3D=3D '[') { + const char *addr_str =3D qemu_opt_get(opts, "addr"); + if (!addr_str) { + error_setg(errp, "error parsing address ''"); + return -1; + } + if (str[0] =3D=3D '[') { /* IPv6 addr */ - if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) !=3D 2) { - error_setg(errp, "error parsing IPv6 address '%s'", str); + const char *ip_end =3D strstr(addr_str, "]:"); + if (!ip_end || ip_end - addr_str < 2 || strlen(ip_end) < 3) { + error_setg(errp, "error parsing IPv6 address '%s'", addr_str); return -1; } + addr->host =3D g_strndup(addr_str + 1, ip_end - addr_str - 1); + addr->port =3D g_strdup(ip_end + 2); } else { - /* hostname or IPv4 addr */ - if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) !=3D 2) { - error_setg(errp, "error parsing address '%s'", str); + /* no host, hostname or IPv4 addr */ + const char *port =3D strchr(addr_str, ':'); + if (!port || strlen(port) < 2) { + error_setg(errp, "error parsing address '%s'", addr_str); return -1; } + addr->host =3D g_strndup(addr_str, port - addr_str); + addr->port =3D g_strdup(port + 1); } =20 - addr->host =3D g_strdup(host); - addr->port =3D g_strdup(port); - /* parse options */ - optstr =3D str + pos; - h =3D strstr(optstr, ",to=3D"); - if (h) { - h +=3D 4; - if (sscanf(h, "%d%n", &to, &pos) !=3D 1 || - (h[pos] !=3D '\0' && h[pos] !=3D ',')) { - error_setg(errp, "error parsing to=3D argument"); - return -1; - } + if (qemu_opt_find(opts, "numeric")) { + addr->has_numeric =3D true, + addr->numeric =3D qemu_opt_get_bool(opts, "numeric", false); + } + if (qemu_opt_find(opts, "to")) { addr->has_to =3D true; - addr->to =3D to; + addr->to =3D qemu_opt_get_number(opts, "to", 0); } - begin =3D strstr(optstr, ",ipv4"); - if (begin) { - if (inet_parse_flag("ipv4", begin + 5, &addr->ipv4, errp) < 0) { - return -1; - } + if (qemu_opt_find(opts, "ipv4")) { addr->has_ipv4 =3D true; + addr->ipv4 =3D qemu_opt_get_bool(opts, "ipv4", false); } - begin =3D strstr(optstr, ",ipv6"); - if (begin) { - if (inet_parse_flag("ipv6", begin + 5, &addr->ipv6, errp) < 0) { - return -1; - } + if (qemu_opt_find(opts, "ipv6")) { addr->has_ipv6 =3D true; + addr->ipv6 =3D qemu_opt_get_bool(opts, "ipv6", false); } - begin =3D strstr(optstr, ",keep-alive"); - if (begin) { - if (inet_parse_flag("keep-alive", begin + strlen(",keep-alive"), - &addr->keep_alive, errp) < 0) - { - return -1; - } + if (qemu_opt_find(opts, "keep-alive")) { addr->has_keep_alive =3D true; + addr->keep_alive =3D qemu_opt_get_bool(opts, "keep-alive", false); } #ifdef HAVE_IPPROTO_MPTCP - begin =3D strstr(optstr, ",mptcp"); - if (begin) { - if (inet_parse_flag("mptcp", begin + strlen(",mptcp"), - &addr->mptcp, errp) < 0) - { - return -1; - } + if (qemu_opt_find(opts, "mptcp")) { addr->has_mptcp =3D true; + addr->mptcp =3D qemu_opt_get_bool(opts, "mptcp", 0); } #endif return 0; --=20 2.49.0 From nobody Fri Dec 19 02:50:52 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1747835823; cv=none; d=zohomail.com; s=zohoarc; b=Qodow4xv1GiWy7L2e6geMYXBOjvt54terJMRQxKZTdbstEgeCQocBZzWVZoSacctFSyfqbvALczhc4BKFyyZu6p5BUeNOk6E4/SVUnKJQgrWMOPRhTQiKdCqp0QzDaCih7NtEIRFqAXTf9tXe1jmiwobVY8sNLJFMtNpyDe2Gpw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747835823; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BL05b1wqQ7FN+wTvyszSTfR+QUxn43lIBl73uDpbO7g=; b=MhnhQGNGARtEc/oeKMk60jEsmzZe/Cnzmw3WwJrgoDgHjOUf+pK8e5vagL4mz6NkHZw5vvdYbjpvWsofrrSiamHr/7m0wakvOzG8/W8zZoJEQwDYgZzJBE6vgJ/5bySrcePugfSJRy4fdXhGizWldy0cHCaWn92mdeZ89AW7uZw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747835823290660.6468882234198; Wed, 21 May 2025 06:57:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uHjv0-00005r-Gf; Wed, 21 May 2025 09:55:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuy-0008T2-PZ for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:36 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uHjuw-00075j-6n for qemu-devel@nongnu.org; Wed, 21 May 2025 09:55:36 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-547-fJp7WiNjMhCRvUKTpU54-g-1; Wed, 21 May 2025 09:55:30 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1B5C31800772; Wed, 21 May 2025 13:55:30 +0000 (UTC) Received: from fedora.brq.redhat.com (unknown [10.43.2.64]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 47BE119560AB; Wed, 21 May 2025 13:55:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747835733; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BL05b1wqQ7FN+wTvyszSTfR+QUxn43lIBl73uDpbO7g=; b=XH9Ntq75sCRPIL5kjYz3nyzw8rR8W0qYTMiYEPTIaewoVHghFMKhfUcgo1+tSpScH1Pi7G ic9452O1v48ooeRYsD2PGbiyJTHyH+i7tJDl8+MDGQzuVV3mo69v3tRJ08CW0KoD+CMtvu 1FeGUgvX2x6eJoL8RVRk6MvZMmpt8Kk= X-MC-Unique: fJp7WiNjMhCRvUKTpU54-g-1 X-Mimecast-MFC-AGG-ID: fJp7WiNjMhCRvUKTpU54-g_1747835730 From: Juraj Marcin To: qemu-devel@nongnu.org Cc: Juraj Marcin , vsementsov@yandex-team.ru, =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Paolo Bonzini Subject: [PATCH v5 6/6] util/qemu-sockets: Introduce inet socket options controlling TCP keep-alive Date: Wed, 21 May 2025 15:52:35 +0200 Message-ID: <20250521135240.3941598-7-jmarcin@redhat.com> In-Reply-To: <20250521135240.3941598-1-jmarcin@redhat.com> References: <20250521135240.3941598-1-jmarcin@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=jmarcin@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.184, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1747835825122116600 From: Juraj Marcin With the default TCP stack configuration, it could be even 2 hours before the connection times out due to the other side not being reachable. However, in some cases, the application needs to be aware of a connection issue much sooner. This is the case, for example, for postcopy live migration. If there is no traffic from the migration destination guest (server-side) to the migration source guest (client-side), the destination keeps waiting for pages indefinitely and does not switch to the postcopy-paused state. This can happen, for example, if the destination QEMU instance is started with the '-S' command line option and the machine is not started yet, or if the machine is idle and produces no new page faults for not-yet-migrated pages. This patch introduces new inet socket parameters that control count, idle period, and interval of TCP keep-alive packets before the connection is considered broken. These parameters are available on systems where the respective TCP socket options are defined, that includes Linux, Windows, macOS, but not OpenBSD. Additionally, macOS defines TCP_KEEPIDLE as TCP_KEEPALIVE instead, so the patch supplies its own definition. The default value for all is 0, which means the system configuration is used. Signed-off-by: Juraj Marcin Reviewed-by: Daniel P. Berrang=C3=A9 --- meson.build | 30 +++++++++++++ qapi/sockets.json | 19 ++++++++ tests/unit/test-util-sockets.c | 33 ++++++++++++++ util/qemu-sockets.c | 80 ++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+) diff --git a/meson.build b/meson.build index ad2053f968..fdad3fb528 100644 --- a/meson.build +++ b/meson.build @@ -2760,6 +2760,36 @@ if linux_io_uring.found() config_host_data.set('HAVE_IO_URING_PREP_WRITEV2', cc.has_header_symbol('liburing.h', 'io_uring_prep_w= ritev2')) endif +config_host_data.set('HAVE_TCP_KEEPCNT', + cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPCNT') = or + cc.compiles(''' + #include + #ifndef TCP_KEEPCNT + #error + #endif + int main(void) { return 0; }''', + name: 'Win32 TCP_KEEPCNT')) +# On Darwin TCP_KEEPIDLE is available under different name, TCP_KEEPALIVE. +# https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp.= 4#L172 +config_host_data.set('HAVE_TCP_KEEPIDLE', + cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPIDLE')= or + cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPALIVE'= ) or + cc.compiles(''' + #include + #ifndef TCP_KEEPIDLE + #error + #endif + int main(void) { return 0; }''', + name: 'Win32 TCP_KEEPIDLE')) +config_host_data.set('HAVE_TCP_KEEPINTVL', + cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPINTVL'= ) or + cc.compiles(''' + #include + #ifndef TCP_KEEPINTVL + #error + #endif + int main(void) { return 0; }''', + name: 'Win32 TCP_KEEPINTVL')) =20 # has_member config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', diff --git a/qapi/sockets.json b/qapi/sockets.json index 62797cd027..f9f559daba 100644 --- a/qapi/sockets.json +++ b/qapi/sockets.json @@ -59,6 +59,22 @@ # @keep-alive: enable keep-alive when connecting to/listening on this sock= et. # (Since 4.2, not supported for listening sockets until 10.1) # +# @keep-alive-count: number of keep-alive packets sent before the connecti= on is +# closed. Only supported for TCP sockets on systems where TCP_KEEPCNT +# socket option is defined (this includes Linux, Windows, macOS, FreeB= SD, +# but not OpenBSD). When set to 0, system setting is used. (Since 10= .1) +# +# @keep-alive-idle: time in seconds the connection needs to be idle before +# sending a keepalive packet. Only supported for TCP sockets on syste= ms +# where TCP_KEEPIDLE socket option is defined (this includes Linux, +# Windows, macOS, FreeBSD, but not OpenBSD). When set to 0, system se= tting +# is used. (Since 10.1) +# +# @keep-alive-interval: time in seconds between keep-alive packets. Only +# supported for TCP sockets on systems where TCP_KEEPINTVL is defined = (this +# includes Linux, Windows, macOS, FreeBSD, but not OpenBSD). When set= to +# 0, system setting is used. (Since 10.1) +# # @mptcp: enable multi-path TCP. (Since 6.1) # # Since: 1.3 @@ -71,6 +87,9 @@ '*ipv4': 'bool', '*ipv6': 'bool', '*keep-alive': 'bool', + '*keep-alive-count': { 'type': 'uint32', 'if': 'HAVE_TCP_KEEPCNT' }, + '*keep-alive-idle': { 'type': 'uint32', 'if': 'HAVE_TCP_KEEPIDLE' }, + '*keep-alive-interval': { 'type': 'uint32', 'if': 'HAVE_TCP_KEEPINTVL'= }, '*mptcp': { 'type': 'bool', 'if': 'HAVE_IPPROTO_MPTCP' } } } =20 ## diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c index cca609fd90..af8e6e6af9 100644 --- a/tests/unit/test-util-sockets.c +++ b/tests/unit/test-util-sockets.c @@ -358,6 +358,18 @@ static void inet_parse_test_helper(const char *str, In= etSocketAddress *exp_addr, g_assert_cmpint(addr.ipv6, =3D=3D, exp_addr->ipv6); g_assert_cmpint(addr.has_keep_alive, =3D=3D, exp_addr->has_keep_al= ive); g_assert_cmpint(addr.keep_alive, =3D=3D, exp_addr->keep_alive); +#ifdef HAVE_TCP_KEEPCNT + g_assert_cmpint(addr.has_keep_alive_count, =3D=3D, exp_addr->has_k= eep_alive_count); + g_assert_cmpint(addr.keep_alive_count, =3D=3D, exp_addr->keep_aliv= e_count); +#endif +#ifdef HAVE_TCP_KEEPIDLE + g_assert_cmpint(addr.has_keep_alive_idle, =3D=3D, exp_addr->has_ke= ep_alive_idle); + g_assert_cmpint(addr.keep_alive_idle, =3D=3D, exp_addr->keep_alive= _idle); +#endif +#ifdef HAVE_TCP_KEEPINTVL + g_assert_cmpint(addr.has_keep_alive_interval, =3D=3D, exp_addr->ha= s_keep_alive_interval); + g_assert_cmpint(addr.keep_alive_interval, =3D=3D, exp_addr->keep_a= live_interval); +#endif #ifdef HAVE_IPPROTO_MPTCP g_assert_cmpint(addr.has_mptcp, =3D=3D, exp_addr->has_mptcp); g_assert_cmpint(addr.mptcp, =3D=3D, exp_addr->mptcp); @@ -459,6 +471,18 @@ static void test_inet_parse_all_options_good(void) .ipv6 =3D true, .has_keep_alive =3D true, .keep_alive =3D true, +#ifdef HAVE_TCP_KEEPCNT + .has_keep_alive_count =3D true, + .keep_alive_count =3D 10, +#endif +#ifdef HAVE_TCP_KEEPIDLE + .has_keep_alive_idle =3D true, + .keep_alive_idle =3D 60, +#endif +#ifdef HAVE_TCP_KEEPINTVL + .has_keep_alive_interval =3D true, + .keep_alive_interval =3D 30, +#endif #ifdef HAVE_IPPROTO_MPTCP .has_mptcp =3D true, .mptcp =3D false, @@ -466,6 +490,15 @@ static void test_inet_parse_all_options_good(void) }; inet_parse_test_helper( "[::1]:5000,numeric=3Don,to=3D5006,ipv4=3Doff,ipv6=3Don,keep-alive= =3Don" +#ifdef HAVE_TCP_KEEPCNT + ",keep-alive-count=3D10" +#endif +#ifdef HAVE_TCP_KEEPIDLE + ",keep-alive-idle=3D60" +#endif +#ifdef HAVE_TCP_KEEPINTVL + ",keep-alive-interval=3D30" +#endif #ifdef HAVE_IPPROTO_MPTCP ",mptcp=3Doff" #endif diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 403dc26b36..4773755fd5 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -45,6 +45,14 @@ # define AI_NUMERICSERV 0 #endif =20 +/* + * On macOS TCP_KEEPIDLE is available under a different name, TCP_KEEPALIV= E. + * https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp= .4#L172 + */ +#if defined(TCP_KEEPALIVE) && !defined(TCP_KEEPIDLE) +# define TCP_KEEPIDLE TCP_KEEPALIVE +#endif + =20 static int inet_getport(struct addrinfo *e) { @@ -218,6 +226,42 @@ static int inet_set_sockopts(int sock, InetSocketAddre= ss *saddr, Error **errp) "Unable to set keep-alive option on socket"); return -1; } +#ifdef HAVE_TCP_KEEPCNT + if (saddr->has_keep_alive_count && saddr->keep_alive_count) { + int keep_count =3D saddr->keep_alive_count; + ret =3D setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keep_count, + sizeof(keep_count)); + if (ret < 0) { + error_setg_errno(errp, errno, + "Unable to set TCP keep-alive count optio= n on socket"); + return -1; + } + } +#endif +#ifdef HAVE_TCP_KEEPIDLE + if (saddr->has_keep_alive_idle && saddr->keep_alive_idle) { + int keep_idle =3D saddr->keep_alive_idle; + ret =3D setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle, + sizeof(keep_idle)); + if (ret < 0) { + error_setg_errno(errp, errno, + "Unable to set TCP keep-alive idle option= on socket"); + return -1; + } + } +#endif +#ifdef HAVE_TCP_KEEPINTVL + if (saddr->has_keep_alive_interval && saddr->keep_alive_interval) { + int keep_interval =3D saddr->keep_alive_interval; + ret =3D setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keep_int= erval, + sizeof(keep_interval)); + if (ret < 0) { + error_setg_errno(errp, errno, + "Unable to set TCP keep-alive interval op= tion on socket"); + return -1; + } + } +#endif } return 0; } @@ -630,6 +674,24 @@ static QemuOptsList inet_opts =3D { .name =3D "keep-alive", .type =3D QEMU_OPT_BOOL, }, +#ifdef HAVE_TCP_KEEPCNT + { + .name =3D "keep-alive-count", + .type =3D QEMU_OPT_NUMBER, + }, +#endif +#ifdef HAVE_TCP_KEEPIDLE + { + .name =3D "keep-alive-idle", + .type =3D QEMU_OPT_NUMBER, + }, +#endif +#ifdef HAVE_TCP_KEEPINTVL + { + .name =3D "keep-alive-interval", + .type =3D QEMU_OPT_NUMBER, + }, +#endif #ifdef HAVE_IPPROTO_MPTCP { .name =3D "mptcp", @@ -695,6 +757,24 @@ int inet_parse(InetSocketAddress *addr, const char *st= r, Error **errp) addr->has_keep_alive =3D true; addr->keep_alive =3D qemu_opt_get_bool(opts, "keep-alive", false); } +#ifdef HAVE_TCP_KEEPCNT + if (qemu_opt_find(opts, "keep-alive-count")) { + addr->has_keep_alive_count =3D true; + addr->keep_alive_count =3D qemu_opt_get_number(opts, "keep-alive-c= ount", 0); + } +#endif +#ifdef HAVE_TCP_KEEPIDLE + if (qemu_opt_find(opts, "keep-alive-idle")) { + addr->has_keep_alive_idle =3D true; + addr->keep_alive_idle =3D qemu_opt_get_number(opts, "keep-alive-id= le", 0); + } +#endif +#ifdef HAVE_TCP_KEEPINTVL + if (qemu_opt_find(opts, "keep-alive-interval")) { + addr->has_keep_alive_interval =3D true; + addr->keep_alive_interval =3D qemu_opt_get_number(opts, "keep-aliv= e-interval", 0); + } +#endif #ifdef HAVE_IPPROTO_MPTCP if (qemu_opt_find(opts, "mptcp")) { addr->has_mptcp =3D true; --=20 2.49.0