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;    
        

留言

熱門文章