aboutgitcodebugslistschat
path: root/contrib/qemu/0001-net-Allow-also-UNIX-domain-sockets-to-be-used-as-net.patch
blob: 9e71f88b5a23080edeada17f6c9219c8812c27ff (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                                                                      
                                         
                                     







                                                                              
                                                                   

                                          

                                                                       

                                        
                                   

                  
                                                                             









                                                                 
 




                                                           


                                                       
      














                                                                            

                                               




                                                                           
      
                    





















                                                                               


                         
                                                                              







                                                 


                                                                 
 

                                 
                                                           
                       


                                                       
                      
                                        

              















                                                                            
                                        







                                                                     
                                                                            







                                                                     
                                                                             

















                                                                            
   
      
 
From 83c3f76b8fe6b4a6bb45dcf5cfad65ec6f98a10e Mon Sep 17 00:00:00 2001
From: Stefano Brivio <sbrivio@redhat.com>
Date: Wed, 26 Jan 2022 16:45:15 +0100
Subject: [PATCH 1/2] net: Allow also UNIX domain sockets to be used as -netdev
 socket

It has lower overhead compared to TCP, doesn't need a free port
and the adaptation is trivial.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
SPDX-FileCopyrightText: 2020-2022 Red Hat GmbH <sbrivio@redhat.com>
SPDX-License-Identifier: AGPL-3.0-or-later

 net/socket.c | 106 ++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 87 insertions(+), 19 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 2e5f3ac923..b901e22836 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -511,26 +511,59 @@ static int net_socket_listen_init(NetClientState *peer,
 {
     NetClientState *nc;
     NetSocketState *s;
-    struct sockaddr_in saddr;
-    int fd, ret;
+    struct sockaddr_storage saddr;
+    struct sockaddr_in *saddr_in = (struct sockaddr_in *)&saddr;
+    struct sockaddr_un *saddr_un = (struct sockaddr_un *)&saddr;
+    size_t saddr_size;
+    int fd, ret, pf;
+
+#ifndef WIN32
+    if (strchr(host_str, ':')) {
+#endif
+        if (parse_host_port(saddr_in, host_str, errp) < 0)
+            return -1;
 
-    if (parse_host_port(&saddr, host_str, errp) < 0) {
-        return -1;
-    }
+        pf = PF_INET;
+        saddr_size = sizeof(*saddr_in);
+#ifndef WIN32
+    } else {
+        struct stat sb;
+
+        if (stat(host_str, &sb) == -1) {
+            error_setg_errno(errp, errno, "can't stat socket path");
+            return -1;
+        }
+
+        if ((sb.st_mode & S_IFMT) != S_IFSOCK) {
+            error_setg_errno(errp, errno, "path provided is not a socket");
+            return -1;
+        }
 
-    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
+        saddr_un->sun_family = PF_UNIX;
+        strncpy(saddr_un->sun_path, host_str, sizeof(saddr_un->sun_path));
+
+        pf = PF_UNIX;
+        saddr_size = sizeof(*saddr_un);
+    }
+#endif /* !WIN32 */
+    fd = qemu_socket(pf, SOCK_STREAM, 0);
     if (fd < 0) {
         error_setg_errno(errp, errno, "can't create stream socket");
         return -1;
     }
     qemu_set_nonblock(fd);
 
-    socket_set_fast_reuse(fd);
+    if (pf == PF_INET)
+        socket_set_fast_reuse(fd);
 
-    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
+    ret = bind(fd, (struct sockaddr *)&saddr, saddr_size);
     if (ret < 0) {
-        error_setg_errno(errp, errno, "can't bind ip=%s to socket",
-                         inet_ntoa(saddr.sin_addr));
+        if (pf == PF_INET)
+            error_setg_errno(errp, errno, "can't bind ip=%s to socket",
+                             inet_ntoa(saddr_in->sin_addr));
+        else if (pf == PF_UNIX)
+            error_setg_errno(errp, errno, "can't create socket with path: %s",
+                             host_str);
         closesocket(fd);
         return -1;
     }
@@ -559,14 +592,43 @@ static int net_socket_connect_init(NetClientState *peer,
                                    Error **errp)
 {
     NetSocketState *s;
-    int fd, connected, ret;
-    struct sockaddr_in saddr;
+    int fd, connected, ret, pf;
+    struct sockaddr_storage saddr;
+    size_t saddr_size;
+    struct sockaddr_in *saddr_in = (struct sockaddr_in *)&saddr;
+#ifndef WIN32
+    struct sockaddr_un *saddr_un = (struct sockaddr_un *)&saddr;
+
+    if (strchr(host_str, ':')) {
+#endif
+        if (parse_host_port(saddr_in, host_str, errp) < 0)
+            return -1;
 
-    if (parse_host_port(&saddr, host_str, errp) < 0) {
-        return -1;
+        pf = PF_INET;
+        saddr_size = sizeof(*saddr_in);
+#ifndef WIN32
+    } else {
+        struct stat sb;
+
+        if (stat(host_str, &sb) == -1) {
+            error_setg_errno(errp, errno, "can't stat socket path");
+            return -1;
+        }
+
+        if ((sb.st_mode & S_IFMT) != S_IFSOCK) {
+            error_setg_errno(errp, errno, "provided path is not a socket");
+            return -1;
+        }
+
+        saddr_un->sun_family = PF_UNIX;
+        strncpy(saddr_un->sun_path, host_str, sizeof(saddr_un->sun_path));
+
+        pf = PF_UNIX;
+        saddr_size = sizeof(*saddr_un);
     }
+#endif /* !WIN32 */
 
-    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
+    fd = qemu_socket(pf, SOCK_STREAM, 0);
     if (fd < 0) {
         error_setg_errno(errp, errno, "can't create stream socket");
         return -1;
@@ -575,7 +637,7 @@ static int net_socket_connect_init(NetClientState *peer,
 
     connected = 0;
     for(;;) {
-        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
+        ret = connect(fd, (struct sockaddr *)&saddr, saddr_size);
         if (ret < 0) {
             if (errno == EINTR || errno == EWOULDBLOCK) {
                 /* continue */
@@ -597,9 +659,15 @@ static int net_socket_connect_init(NetClientState *peer,
         return -1;
     }
 
-    snprintf(s->nc.info_str, sizeof(s->nc.info_str),
-             "socket: connect to %s:%d",
-             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
+    if (pf == PF_INET) {
+        snprintf(s->nc.info_str, sizeof(s->nc.info_str),
+                 "socket: connect to %s:%d",
+                 inet_ntoa(saddr_in->sin_addr), ntohs(saddr_in->sin_port));
+    } else if (pf == PF_UNIX) {
+        snprintf(s->nc.info_str, sizeof(s->nc.info_str),
+                 "socket: connect to %s", saddr_un->sun_path);
+    }
+
     return 0;
 }
 
-- 
2.28.0