[Libwebsockets] should I use LWS_ADOPT_SOCKET for AF_UNIX socket?

Andy Green andy at warmcat.com
Sun Feb 16 05:08:39 CET 2020

On February 15, 2020 10:20:04 PM GMT, Per Bothner <per at bothner.com> wrote:
>tl;dr: If for a AF_UNIX socket I just want to use lws to multiplex
>listening to a connection, should I use LWS_ADOPT_SOCKET? It seems not.

Not really... you can take that kind of approach with udp, since they're 'bidirectional'... just having a wsi on the udp socket lets you do 'be the server' or 'be the client' interchangeably.

But for unix domain sockets, they are like tcp sockets in that they have a stateful connection concept and are either istening or making connections.  For that reason if you want to listen with one, it's fine but the way follows tcp listen / serving in lws... create a vhost and use the vhost option LWS_SERVER_OPTION_UNIX_SOCK, you set the uds path in .iface IIRC.

This stuff is in use with gitohashi on https://libwebsockets.org/git ... gitohashi is actually a separate process also using lws to serve over a unix domain socket, lwsws proxies it back out over h1 or h2 to the remote client.

>Details:  For DomTerm I use Unix domain sockets to communicate between
>a client making
>a request to the server, which listens on an AF_UNIX socket. For
>example if you type
>     domterm status
>at the command line the (client) domterm will try to connect to the
>server domterm and
>send it a request to "print" various information about the server
>status.  This information
>is sent back to the client command, which prints it on its stdout.
>In the server I use lws_adopt_descriptor_vhost on the listening socket.
>Currently, the 2nd argument is 0 - but should it be LWS_ADOPT_SOCKET?
>On Linux it works fine with passing 0 to lws_adopt_descriptor_vhost:
>The corresponding callback handler in my code handles
>by calling accept on the socket, followed by recvmsg to receive the
>request from the client.

IIUI it'll be ok just defining a vhost listening on the uds with LWS_SERVER_OPTION_UNIX_SOCK option.

>On MacOS this doesn't work.  The connection is made, in the sense that
>the client calls connect, and the server accept returns.  However.
>the client hangs in the connect command.  The server recmsg fails
>to receive anything - since the client is hanging.
>I wrote a simple test program that does *not* use lws, and that worked
>fine on both Linux and MacOS.
>If I pass LWS_ADOPT_SOCKET to lws_adopt_descriptor_vhost then things
>get a bit further: The connect in the client returns.  However, the
>rops_handle_POLLIN_raw_skt calls lws_buflist_aware_read, which calls
>recvfrom, which fails.
>All I want to do is tie in the "listen for connection" state into the
>lws polling/event framework (I'm using the default/builtin polling).
>I do not want lws to do recvfrom or other hand-shaking.

Right... you should literally do that as described above.

I don't know what the hang on OSX is about, but lws doesn't expect adopted sockets to be in listen or doing accepts... if it's still coming if you use the official vhost listen path I'll try to look at it.


>Am I correct in concluding I should *not* be passing LWS_ADOPT_SOCKET
>to lws_adopt_descriptor_vhost in this situation?
>If you have any guess why the connect call hangs on MacOS (but not on
>and not if using LWS_ADOPT_SOCKET) that would be fabulous.  I tried
>adding a call:
>    fcntl(csocket.filefd, F_SETFL, O_NONBLOCK);
>but that didn't seem to make a difference.

More information about the Libwebsockets mailing list