抽象ソケットアドレス abstract socket address

抽象ソケットアドレス abstract socket address について 2011年にエントリを書いていた

d.hatena.ne.jp

しばらく存在を忘れていたのだけど、社内 slack に話題が上がって思い出した。以下のような UNXI ソケットの亜種である。

abstract (抽象): 抽象ソケットアドレスは、 sun_path[0] がヌルバイト ('\0') であることから区別できる。 sun_path の残りの全バイトによりソケットの「名前」が定義される (名前中のヌルバイトには特別な意味はない)。 この名前はファイルシステムのパス名とは何の関係もない。 この名前空間におけるソケットのアドレスは、 sun_path の残りのバイトで表される。 getsockname(2), getpeername(2), accept(2) が抽象ソケットのアドレスを返す際には、その長さは sizeof(struct sockaddr_un) であり、 sun_path に抽象名前空間の名前が格納される。 ソケットの抽象名前空間Linux による拡張であり、移植性はない。

Man page of UNIX

straec でトレースした場合

strace では @ 付きで表示される

vagrant@vagrant:~$ strace -econnect socat - abstract-connect:"hoge"
connect(5, {sa_family=AF_LOCAL, sun_path=@"hoge"}, 7) = -1 ECONNREFUSED (Connection refused)

うっかり @ ナルト を見落としてしまいそう

strace の実装

sockaddr.c に表示のロジックが書いてあります

static void
print_sockaddr_data_un(const void *const buf, const int addrlen)
{
        const struct sockaddr_un *const sa_un = buf;
        const int un_len = addrlen > (int) sizeof(*sa_un)
                           ? (int) sizeof(*sa_un) : addrlen;
        const int path_len = un_len - SIZEOF_SA_FAMILY;

        tprints("sun_path="); 
        if (sa_un->sun_path[0]) {
                print_quoted_string(sa_un->sun_path, path_len + 1,
                                    QUOTE_0_TERMINATED);
        } else {
                tprints("@"); 👈
                print_quoted_string(sa_un->sun_path + 1, path_len - 1, 0); 
        }   
}

ユースケース

web アプリケーションを作ってる時は特に必要とされるユースケースを見出せない。特殊なミドルウェアを実装する際に便利な使い方ができそう ( 社内 slack では D-Bbus の話題としてとりあげられていた ).

ファイルシステムに依存しないソケットとして扱える一方、セキュリティモデルはどう扱うべきなのだろうか