All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net: fix multicast support with BSD (macOS) socket implementations
@ 2022-05-02  0:38 Vitaly Cheptsov
  2022-05-03 13:13 ` Daniel P. Berrangé
  0 siblings, 1 reply; 4+ messages in thread
From: Vitaly Cheptsov @ 2022-05-02  0:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: Jason Wang, Vitaly Cheptsov, Daniel P . Berrange,
	Philippe Mathieu-Daudé

This patch fixes socket communication with QEMU -> host on macOS,
which was originally impossible due to QEMU and host program
having to bind to the same ip/port in a way not supported by BSD
sockets. The change was tested on both Linux and macOS.

As per BSD manual pages SO_REUSEPORT allows completely duplicate
bindings by multiple processes, permitting multiple instances of
a program to each receive UDP/IP multicast datagrams destined
for the bound port. Without this option macOS, unlike Linux,
which (ab)uses SO_REUSEADDR for this purpose, will return
"Address already in use" on bind().

As per BSD manual pages binding to any address, even one not bound
to any available network interface in the system, should be
IP_BINDANY. Without binding to INADDR_ANY macOS will return
"Can't assign requested address" on send().

Cc: Jason Wang <jasowang@redhat.com>
Cc: Daniel P. Berrange <berrange@redhat.com>
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Vitaly Cheptsov <cheptsov@ispras.ru>
---
 net/socket.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index ea5220a2eb..8b2c6c4bb8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -252,10 +252,24 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr,
         goto fail;
     }
 
-    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
+    val = 1;
+    ret = qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
+    if (ret < 0) {
+        error_setg_errno(errp, errno,
+                         "can't set socket option SO_REUSEPORT");
+        goto fail;
+    }
+
+    struct sockaddr_in bindaddr;
+    memset(&bindaddr, 0, sizeof(bindaddr));
+    bindaddr.sin_family = AF_INET;
+    bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    bindaddr.sin_port = mcastaddr->sin_port;
+    ret = bind(fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr));
+
     if (ret < 0) {
         error_setg_errno(errp, errno, "can't bind ip=%s to socket",
-                         inet_ntoa(mcastaddr->sin_addr));
+                         inet_ntoa(bindaddr.sin_addr));
         goto fail;
     }
 
-- 
2.32.0 (Apple Git-132)



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-05-16 15:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-02  0:38 [PATCH] net: fix multicast support with BSD (macOS) socket implementations Vitaly Cheptsov
2022-05-03 13:13 ` Daniel P. Berrangé
2022-05-03 16:10   ` Vitaly Cheptsov
2022-05-16 14:42     ` Vitaly Cheptsov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.