qemu-devel
[Top][All Lists]
Advanced

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

Re: socket.c added support for unix domain socket datagram transport


From: Daniel P . Berrangé
Subject: Re: socket.c added support for unix domain socket datagram transport
Date: Mon, 26 Apr 2021 13:56:40 +0100
User-agent: Mutt/2.0.6 (2021-03-06)

On Fri, Apr 23, 2021 at 06:54:08PM +0200, Stefano Brivio wrote:
> On Fri, 23 Apr 2021 17:21:38 +0100
> Daniel P. Berrangé <berrange@redhat.com> wrote:
> > The current IP socket impl for the net socket backend uses SOCK_DGRAM,
> > so from a consistency POV it feels sensible todo the same for UNIX
> > sockets too.
> 
> That's just for UDP though -- it also supports TCP with the "connect="
> parameter, and given that a stream-oriented AF_UNIX socket behaves very
> similarly, I recycled that parameter and just extended that bit of
> documentation.
> 
> > None the less, your last point in particular about wanting to know
> > about disconnects feels valid, and if its useful to you for UNIX
> > sockets, then it ought to be useful for IP sockets too.
> > 
> > IOW, I wonder if  we should use DGRAM for UNIX sockets too by default
> > to match current behaviour, but then also add a CLI option that allows
> > choice of DGRAM vs STREAM, and wire that up for IP & UNIX sockets.
> 
> The choice would only apply to AF_UNIX (that is, not to TCP and UDP).
> 
> The current situation isn't entirely consistent, because for TCP you
> have "connect=", for UDP it's "udp=" or "mcast=", and I'm extending the
> "connect=" case to support stream-oriented AF_UNIX, which I think is
> consistent.
> 
> However, to have it symmetric for the datagram-oriented case
> (UDP and AF_UNIX), ideally it should be changed to
> "dgram=host:port|path" -- which I guess we can't do.
> 
> I see two alternatives:
> 
> 1.
>   - "connect=" (TCP only)
>   - "unix=path,type=dgram|stream"
>   - "udp=" (UDP only)

This doesn't work when you need the UNIX server to be a
listener socket, as we've no way to express that, without
adding yet another parameter.

> 2.
>   - "connect=" (TCP and AF_UNIX stream)
>   - "unix_dgram="
>   - "udp=" (UDP only)

Also needs

   "listen=" (TCP and AF_UNIX stream)

"udp" has a corresponding optional "localaddr" for the sending
address.

Also overloading "connect" means we have to parse the value
to guess whether its a UNIX path or a IP addr:port pair.

I doubt people will have UNIX paths called "127.0.0.1:3333"
but if we can avoid such ambiguity by design, it is better.

> The major thing I like of 2. is that we save some code and a further
> option, but other than that I don't have a strong preference.

The pain we're feeling is largely because the design of the net
option syntax is one of the oldest parts of QEMU and has only
been very partially improved upon. It is certainly not using
QAPI best practice, if we look at this:

  { 'struct': 'NetdevSocketOptions',
    'data': {
      '*fd':        'str',
      '*listen':    'str',
      '*connect':   'str',
      '*mcast':     'str',
      '*localaddr': 'str',
      '*udp':       'str' } }

Then some things come to mind

 - We're not provinding a way to say what kind of "fd" is
   passed in - is it a UDP/TCP FD, is it a listener or
   client FD, is it unicast or multicast FD. Though QEMU
   can interogate the socket to discover this I guess.

 - All of the properties there except "fd" are encoding two values
   in a single property - address + port. This is an anti-pattern

 - No support for ipv4=on|off and ipv6=on|off flags to control
   dual-stack usage.

 - Redundancy of separate parameters for "mcast" and "udp" when
   it is distinguishable based on the address given AFAIR.

 - No support for UNIX sockets


The "right" way to fix most of this long term is a radical change
to introduce use of the SocketAddress struct.

I could envisage something like this

  { 'enum': 'NetdevSocketMode',
    'data':  ['dgram', 'client', 'server'] }

  { 'struct': 'NetdevSocketOptions',
    'data': {
      'addr':      'SocketAddress',
      '*localaddr': 'SocketAddress',
      '*mode':      'NetdevSocketMode' } }


 - A TCP client

      addr.type = inet
      addr.host = 192.168.1.1
      mode = client

 - A TCP server on all interfaces

      addr.type = inet
      addr.host = 
      mode = server

 - A TCP server on a specific interface

      addr.type = inet
      addr.host = 192.168.1.1
      mode = server

 - A TCP server on all interfaces, without IPv4

      addr.type = inet
      addr.host = 
      addr.has_ipv4 = true
      addr.ipv4 = false
      mode = server

 - A UDP unicast transport

      addr.type = inet
      addr.host = 192.168.1.1
      mode = dgram

 - A UDP unicast transport with local addr

      addr.type = inet
      addr.host = 192.168.1.1
      localaddr.type = inet
      localaddr.host = 192.168.1.2
      mode = dgram

 - A UDP multicast transport

     addr.type = inet
     addr.host = 224.0.23.166
     mode = dgram

 - A UNIX stream client

      addr.type = unix
      addr.path = /some/socket
      mode = client

 - A UNIX stream server

      addr.type = unix
      addr.path = /some/socket
      mode = server

 - A UNIX dgram transport

      addr.type = unix
      addr.path = /some/socket
      mode = dgram


Now, of course you're just interested in adding UNIX socket support.

This design I've outlined above is very much "boiling the ocean".
Thus I'm not requesting you implement this, unless you have a strong
desire to get heavily involved in some QEMU refactoring work.

The key question is whether we try to graft UNIX socket support onto
the existing args ("connect"/"listen") or try to do something more
explicit.

Given the desire to have both dgram + stream support, I'd be inclined
to do something more explicit, that's slightly more aligned with a
possible future best praactice QAPI design


IOW, we could take a simplified variant of the above as follows:


  { 'enum': 'NetdevSocketMode',
    'data':  ['dgram', 'client', 'server'] }

  { 'struct': 'NetdevSocketOptions',
    'data': {
      '*fd':        'str',
      '*listen':    'str',
      '*connect':   'str',
      '*mcast':     'str',
      '*localaddr': 'str',
      '*udp':       'str',
      '*path':      'str' } }
      '*localpath': 'str' } }


Cli examples:

 * Unix stream client

  -netdev socket,path=/wibble,mode=client


 * Unix stream server
 
  -netdev socket,path=/wibble,mode=server

 * Unix datagram 

  -netdev socket,path=/wibble,mode=dgram
  -netdev socket,path=/wibble,localpath=/fish,mode=dgram




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]