From nobody Tue Feb 10 17:30:42 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1517253394449370.74563548060974; Mon, 29 Jan 2018 11:16:34 -0800 (PST) Received: from localhost ([::1]:59848 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egEuv-0007DY-KR for importer@patchew.org; Mon, 29 Jan 2018 14:16:33 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46273) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egEsu-0005qR-SF for qemu-devel@nongnu.org; Mon, 29 Jan 2018 14:14:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egEst-0008UN-EQ for qemu-devel@nongnu.org; Mon, 29 Jan 2018 14:14:28 -0500 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]:38107) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1egEst-0008Tu-6X for qemu-devel@nongnu.org; Mon, 29 Jan 2018 14:14:27 -0500 Received: by mail-pf0-x241.google.com with SMTP id k19so6231192pfj.5 for ; Mon, 29 Jan 2018 11:14:27 -0800 (PST) Received: from fma-X550VB.lan ([218.193.183.120]) by smtp.gmail.com with ESMTPSA id d8sm1135316pfh.93.2018.01.29.11.14.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 29 Jan 2018 11:14:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=R8ilajGOd1tCZ88oMi+CbQMuKyffI4OXy9YrnZozHzs=; b=dC267Sz8OteU8/AEcEqLw7C5HoH8JyyW6HO4hQGp92CAuxgiaKwZW+yshJwkwt0XqU S+3kV6TAU7iX8OFKzb4tM0D/Zh2P16cq8dWqzCCiPtJBugJe4OayqKcXGGTrcNvJA9b/ Arcgji5dLAcEBD96wUjWktLQ5/AKSezG7d3cePVo1C+ZbTTF+xjlF48WKRKDROQvv7v4 xIn3h+rqvOdShYoiMxEXpFF2CqgTV7s6G58z2abDhj831j34gghHjDCzYoYUVKpYwU3L eD/73p+zHHJMNc3yWw6O7e0xWp1D0PhOPBgJxZbw1MGk/1xzmXNoDqe9WnZFsyMP5Ock BSeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R8ilajGOd1tCZ88oMi+CbQMuKyffI4OXy9YrnZozHzs=; b=Z7xmVp4kSCHmyfY0r46I/gN36lTcl91kZBptfMcl8n0M+zi5tgbQCdfg3cSos100Yu y+ckCk5jsyXcVF4kY25jd6GjOtesxzr0F6m7ko35IlspcCxUnRmCdlXBqJo1mss4LfyJ QSyy4/TAmvt9bj/owxwiOTPm0S+gcXgjqTSaJgXZW9hTCUMMDsRpV6d8rGJ5xreqdUtA T8Ohm1jeB8RtdK+eGaXDXIYoXRcYOBMDRnnXMUN/DNVi+F21fPS4fE0GRVRL2dO3xsLI YywkVvRlll+GUGP2XF+Q597D76Twu0VeCHB7mJ0SRTDmucc4M4Y/tnUDFibo9y/35jAa a+Ag== X-Gm-Message-State: AKwxyte9I5yD5Cj0RBLz6C+8hOtB10p4mBv38GC2hZPM3TO8XUBJnHOe QNc8GmvsR03/ajtRaClY8oOaG6BvJu8= X-Google-Smtp-Source: AH8x226wJmz9TnQbSA6PsTvR0+dmfIdvV5q+uKOROJ9OzOA+iPfnxzzpYzNJ/k3b9U5rbTMlKCWV5A== X-Received: by 10.99.129.199 with SMTP id t190mr13641508pgd.120.1517253266114; Mon, 29 Jan 2018 11:14:26 -0800 (PST) From: Zihan Yang To: qemu-devel@nongnu.org Date: Tue, 30 Jan 2018 03:13:41 +0800 Message-Id: <1517253224-14361-2-git-send-email-whois.zihan.yang@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1517253224-14361-1-git-send-email-whois.zihan.yang@gmail.com> References: <1517253224-14361-1-git-send-email-whois.zihan.yang@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::241 Subject: [Qemu-devel] [RFC 1/4] qemu-socket: Allow custom socket option in socket_listen X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Gerd Hoffmann , Zihan Yang , Michael Roth Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Currently, socket_listen does not allow caller to set custom socket options, which is inconvenient when the caller wants a non-blocking socket or wants to set TCP_NODELAY. Therefore, two new structs are added and an extra parameter is provided to socket_listen. Existing functions are unaffected by providing a NULL pointer. Signed-off-by: Zihan Yang --- include/qemu/sockets.h | 17 +++++++++++- io/channel-socket.c | 2 +- qga/channel-posix.c | 2 +- util/qemu-sockets.c | 74 ++++++++++++++++++++++++++++++++++++++++++----= ---- 4 files changed, 81 insertions(+), 14 deletions(-) diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 8889bcb..ab06943 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -11,6 +11,21 @@ int inet_aton(const char *cp, struct in_addr *ia); =20 #include "qapi-types.h" =20 +struct QemuSocketOption { + int level; + int optname; + void *optval; + socklen_t optlen; + struct QemuSocketOption *next; +}; +typedef struct QemuSocketOption QemuSocketOption; + +struct QemuSocketConfig { + bool nonblocking; + QemuSocketOption *options; +}; +typedef struct QemuSocketConfig QemuSocketConfig; + /* misc helpers */ int qemu_socket(int domain, int type, int protocol); int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); @@ -40,7 +55,7 @@ int unix_connect(const char *path, Error **errp); =20 SocketAddress *socket_parse(const char *str, Error **errp); int socket_connect(SocketAddress *addr, Error **errp); -int socket_listen(SocketAddress *addr, Error **errp); +int socket_listen(SocketAddress *addr, Error **errp, QemuSocketConfig *sco= nf); void socket_listen_cleanup(int fd, Error **errp); int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp= ); =20 diff --git a/io/channel-socket.c b/io/channel-socket.c index 563e297..9942cf0 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -198,7 +198,7 @@ int qio_channel_socket_listen_sync(QIOChannelSocket *io= c, int fd; =20 trace_qio_channel_socket_listen_sync(ioc, addr); - fd =3D socket_listen(addr, errp); + fd =3D socket_listen(addr, errp, NULL); if (fd < 0) { trace_qio_channel_socket_listen_fail(ioc); return -1; diff --git a/qga/channel-posix.c b/qga/channel-posix.c index b812bf4..16c8524 100644 --- a/qga/channel-posix.c +++ b/qga/channel-posix.c @@ -215,7 +215,7 @@ static gboolean ga_channel_open(GAChannel *c, const gch= ar *path, return false; } =20 - fd =3D socket_listen(addr, &local_err); + fd =3D socket_listen(addr, &local_err, NULL); qapi_free_SocketAddress(addr); if (local_err !=3D NULL) { g_critical("%s", error_get_pretty(local_err)); diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index d6a1e17..b171f23 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -43,7 +43,6 @@ # define AI_NUMERICSERV 0 #endif =20 - static int inet_getport(struct addrinfo *e) { struct sockaddr_in *i4; @@ -196,9 +195,40 @@ static int try_bind(int socket, InetSocketAddress *sad= dr, struct addrinfo *e) #endif } =20 +static int parse_socket_options(int fd, + Error **errp, + QemuSocketConfig *sconf) +{ + QemuSocketOption *sopt; + + if(!sconf) { + /* No extra socket options are defined */ + return fd; + } + + if(sconf->nonblocking) { + qemu_set_nonblock(fd); + }=20 + + for(sopt =3D sconf->options; sopt; sopt =3D sopt->next) { + if(sopt->level < IPPROTO_IP || sopt->optname < SO_DEBUG ||=20 + !sopt->optval || sopt->optlen <=3D 0) { + error_setg(errp, "Invalid socket option:\n" + "level=3D%d, optname=3D%d, optval=3D%p, optle= n=3D%d\n", + sopt->level, sopt->optname, sopt->optval, sopt->optlen= ); + return -1; + } + qemu_setsockopt(fd, sopt->level, sopt->optname,=20 + sopt->optval, sopt->optlen); + } + + return fd; +} + static int inet_listen_saddr(InetSocketAddress *saddr, int port_offset, - Error **errp) + Error **errp, + QemuSocketConfig *sconf) { struct addrinfo ai,*res,*e; char port[33]; @@ -287,6 +317,11 @@ static int inet_listen_saddr(InetSocketAddress *saddr, } socket_created =3D true; =20 + if(parse_socket_options(slisten, errp, sconf) < 0) { + error_setg_errno(errp, errno, "Failed to set socket option= s"); + goto listen_failed; + } + rc =3D try_bind(slisten, saddr, e); if (rc < 0) { if (errno !=3D EADDRINUSE) { @@ -701,7 +736,8 @@ static int vsock_connect_saddr(VsockSocketAddress *vadd= r, Error **errp) } =20 static int vsock_listen_saddr(VsockSocketAddress *vaddr, - Error **errp) + Error **errp, + QemuSocketConfig *sconf) { struct sockaddr_vm svm; int slisten; @@ -716,6 +752,12 @@ static int vsock_listen_saddr(VsockSocketAddress *vadd= r, return -1; } =20 + if(parse_socket_options(slisten, errp, sconf) < 0) { + error_setg_errno(errp, errno, "Failed to set socket options"); + closesocket(slisten); + return -1; + } + if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) !=3D 0) { error_setg_errno(errp, errno, "Failed to bind socket"); closesocket(slisten); @@ -763,7 +805,8 @@ static int vsock_connect_saddr(VsockSocketAddress *vadd= r, Error **errp) } =20 static int vsock_listen_saddr(VsockSocketAddress *vaddr, - Error **errp) + Error **errp, + QemuSocketConfig *sconf) { vsock_unsupported(errp); return -1; @@ -780,7 +823,8 @@ static int vsock_parse(VsockSocketAddress *addr, const = char *str, #ifndef _WIN32 =20 static int unix_listen_saddr(UnixSocketAddress *saddr, - Error **errp) + Error **errp, + QemuSocketConfig *sconf) { struct sockaddr_un un; int sock, fd; @@ -793,6 +837,12 @@ static int unix_listen_saddr(UnixSocketAddress *saddr, return -1; } =20 + if(parse_socket_options(sock, errp, sconf) < 0) { + error_setg_errno(errp, errno, "Failed to set socket option"); + closesocket(sock); + return -1; + } + if (saddr->path && saddr->path[0]) { path =3D saddr->path; } else { @@ -904,7 +954,8 @@ static int unix_connect_saddr(UnixSocketAddress *saddr,= Error **errp) #else =20 static int unix_listen_saddr(UnixSocketAddress *saddr, - Error **errp) + Error **errp, + QemuSocketConfig *sconf) { error_setg(errp, "unix sockets are not available on windows"); errno =3D ENOTSUP; @@ -940,7 +991,7 @@ int unix_listen(const char *str, Error **errp) saddr->path =3D g_strdup(str); } =20 - sock =3D unix_listen_saddr(saddr, errp); + sock =3D unix_listen_saddr(saddr, errp, NULL); =20 qapi_free_UnixSocketAddress(saddr); return sock; @@ -1025,17 +1076,18 @@ int socket_connect(SocketAddress *addr, Error **err= p) return fd; } =20 -int socket_listen(SocketAddress *addr, Error **errp) +int socket_listen(SocketAddress *addr, Error **errp, + QemuSocketConfig *sconf) { int fd; =20 switch (addr->type) { case SOCKET_ADDRESS_TYPE_INET: - fd =3D inet_listen_saddr(&addr->u.inet, 0, errp); + fd =3D inet_listen_saddr(&addr->u.inet, 0, errp, sconf); break; =20 case SOCKET_ADDRESS_TYPE_UNIX: - fd =3D unix_listen_saddr(&addr->u.q_unix, errp); + fd =3D unix_listen_saddr(&addr->u.q_unix, errp, sconf); break; =20 case SOCKET_ADDRESS_TYPE_FD: @@ -1043,7 +1095,7 @@ int socket_listen(SocketAddress *addr, Error **errp) break; =20 case SOCKET_ADDRESS_TYPE_VSOCK: - fd =3D vsock_listen_saddr(&addr->u.vsock, errp); + fd =3D vsock_listen_saddr(&addr->u.vsock, errp, sconf); break; =20 default: --=20 2.7.4