Network Programming
UNIX domain sockets
What does the @ symbol denote in the beginning of a unix domain socket path in Linux
$ cat /proc/net/unix | grep mbim 0000000000000000: 00000002 00000000 00010000 0001 01 36005 @mbim-proxy 0000000000000000: 00000003 00000000 00000000 0001 03 37108 @mbim-proxy 0000000000000000: 00000003 00000000 00000000 0001 03 37109 @mbim-proxy $ sudo ss -a --unix -p | grep mbim Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process u_str LISTEN 0 10 @mbim-proxy 36005 * 0 users:(("mbim-proxy",pid=821,fd=5)) u_str ESTAB 0 0 @mbim-proxy 37108 * 36006 users:(("mbim-proxy",pid=821,fd=6)) u_str ESTAB 0 0 @mbim-proxy 37109 * 37890 users:(("mbim-proxy",pid=821,fd=8)) $ netstat -nxp | grep mbim Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 37108 - @mbim-proxy unix 3 [ ] STREAM CONNECTED 37109 - @mbim-proxy
SYNOPSIS
#include <sys/socket.h> #include <sys/un.h> unix_socket = socket(AF_UNIX, type, 0); error = socketpair(AF_UNIX, type, 0, int *sv);The AF_UNIX (also known as AF_LOCAL) socket family is used to communicate between processes on the same machine efficiently.
Traditionally, UNIX domain sockets can be either unnamed, or bound to a filesystem pathname (marked as being of type socket).
Linux also supports an abstract namespace which is independent of the filesystem.
Valid socket types in the UNIX domain are: SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET.
A UNIX domain socket address is represented in the following structure:
struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* Pathname */ };The sun_family field always contains AF_UNIX.
Three types of address are distinguished in the sockaddr_un structure:
- a pathname socket address a UNIX domain socket can be bound to a null-terminated filesystem pathname using bind(2)
- an unnamed socket address
- an abstract socket address To create an abstract binding, we specify the first byte of the sun_path field as a null byte (\0).
Displaying a leading null byte to denote such type of a socket may be difficult, so that is maybe the reason for the leading @ sign.
The @ indicates a socket held in an abstract namespace.
The so-called abstract namespace is a Linux-specific feature that allows us to bind a UNIX domain socket to a name without that name being created in the file system.
Abstract sockets automatically disappear when all open references to the socket are closed.
int sock; struct sockaddr_un addr; socklen_t socklen; const char *n = "mbim-proxy"; // define the abstract name sock = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); if (sock == -1) { return -1; } addr.sun_family = AF_UNIX; memcpy(addr.sun_path + 1, n, strlen(n)); // append the abstract name to the 1st byte addr.sun_path[0] = '\0'; // set the 1st byte to be NULL byte, it will be translated to be @ by the application to indicate the NULL socklen = offsetof(struct sockaddr_un, sun_path) + strlen(n) + 1;
留言