qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] net: fix multicast support with BSD (macOS) socket implement


From: Daniel P . Berrangé
Subject: Re: [PATCH] net: fix multicast support with BSD (macOS) socket implementations
Date: Tue, 3 May 2022 14:13:05 +0100
User-agent: Mutt/2.1.5 (2021-12-30)

On Mon, May 02, 2022 at 03:38:30AM +0300, Vitaly Cheptsov wrote:
> 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().


When looking in Google there's a comprehensive looking
description of SO_REUSEADDR + SO_REUSEPORT across all the
different OS which insists that SO_REUSEPORT and SO_REUSEADDR
are functionally equivalent for multicast IP addresses:

  
https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ

And AFAIK, macOS should behave the same way, which suggests
this patch is not needed.

Oddly though, I don't find this in the FreeBSD man page - its
description seems fairly clear that SO_REUSEPORT is needed for
multicast

[quote]
     SO_REUSEPORT allows completely duplicate bindings by multiple processes
     if they all set SO_REUSEPORT before binding the port.  This option
     permits multiple instances of a program to each receive UDP/IP multicast
     or broadcast datagrams destined for the bound port.
[/quote]


> 
> 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().

I didn't find a quote about this in the FreeBSD man pages I looked
at, and it feels dubious to me. If the user gives QEMU a address to
bind to, we should surely be honouring that, not changing it to
INADDR_ANY.

If using INADDR_ANY though, thsi could explain the need for
SO_REUSEPORT, since INADDR_ANY is not a designated mcast address.

> 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;
> +    }

AFAIK, this likely won't compile on Windows since it lacks SO_REUSEPORT

> +
> +    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;
>      }


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




reply via email to

[Prev in Thread] Current Thread [Next in Thread]