Automated naming of AF_UNIX local datagram sockets? Automated naming of AF_UNIX local datagram sockets? unix unix

Automated naming of AF_UNIX local datagram sockets?


The unix(7) man page I referenced had this information about autobind UNIX sockets:

If a bind(2) call specifies addrlen as sizeof(sa_family_t), or the SO_PASSCRED socket option was specified for a socket that was not explicitly bound to an address, then the socket is autobound to an abstract address.

This is why the Linux kernel checks the address length is equal to sizeof(short) because sa_family_t is a short. The other unix(7) man page referenced by Rob's great answer says that client sockets are always autobound on connect, but because SOCK_DGRAM sockets are connectionless (despite calling connect on them) I believe this only applies to SOCK_STREAM sockets.

Also note that when supplying your own abstract namespace socket names, the socket's address in this namespace is given by the additional bytes in sun_path that are covered by the specified length of the address structure.

struct sockaddr_un me;const char name[] = "\0myabstractsocket";me.sun_family = AF_UNIX;// size-1 because abstract socket names are not null terminatedmemcpy(me.sun_path, name, sizeof(name) - 1);int result = bind(fd, (void*)&me, sizeof(me.sun_family) + sizeof(name) - 1);

sendto() should likewise limit the address length, and not pass sizeof(sockaddr_un).


I assume that you are running Linux; I don't know if this advice applies to SunOS or any UNIX.

First, the answer: after the socket() and before the connect() or first sendto(), try adding this code:

struct sockaddr_un me;me.sun_family = AF_UNIX;int result = bind(fd, (void*)&me, sizeof(short));

Now, the explanation: the the unix(7) man page says this:

When a socket is connected and it doesn’t already have a local address a unique address in the abstract namespace will be generated automatically.

Sadly, the man page lies.

Examining the Linux source code, we see that unix_dgram_connect() only calls unix_autobind() if SOCK_PASSCRED is set in the socket flags. Since I don't know what SOCK_PASSCRED is, and it is now 1:00AM, I need to look for another solution.

Examining unix_bind, I notice that unix_bind calls unix_autobind if the passed-in size is equal to "sizeof(short)". Thus, the solution above.

Good luck, and good morning.

Rob


A bit of a late response, but for whomever finds this using google as I did. Rob Adam's answer helped me get the 'real' answer to this: simply use set (level SO_SOCKET, see man 7 unix) to set SO_PASSCRED to 1. No need for a silly bind.

I used this in PHP, but it doesn't have SO_PASSCRED defined (stupid PHP). It does still work, though, if you define it yourself. On my computer it has the value of 16, and I reckon that it will work quite portably.