Linux内核模块通过UNIX套接字与用户空间通信

huangapple go评论66阅读模式
英文:

Linux kernel module communicate with user space through UNIX socket

问题

我正在尝试使用UNIX套接字使内核模块能够与用户空间通信,其中内核模块充当客户端,而用户空间程序充当服务器。

我注意到UNIX套接字有三种类型的地址(参考"man 7 unix")。

当我使用路径名类型的地址时,它正常工作。但是当我使用抽象类型的地址时,内核模块无法连接到服务器。它返回-ECONNREFUSED。

我的代码有什么问题吗?

内核代码

    struct sockaddr_un s_addr;

    ret = sock_create_kern(&init_net, AF_LOCAL, SOCK_STREAM, 0, &cl_sock);
    if (ret < 0) {
        /*...*/
    }

    memset(&s_addr, 0, sizeof(struct sockaddr_un));
    s_addr.sun_family = AF_LOCAL;
    s_addr.sun_path[0] = 0;
    strncpy(s_addr.sun_path + 1, "my_test", sizeof(s_addr.sun_path) - 1);

    ret = cl_sock->ops->connect(cl_sock, (struct sockaddr *)&s_addr, sizeof(s_addr), 0);
    if (ret < 0) {
        /*...*/
    }

服务器代码

 server_socket = socket_local_server("my_test", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
 if (server_socket < 0) {
 	/*...*/
 }
 accept(server_socket , NULL, NULL);

我期望使用抽象类型的地址连接到服务器。

英文:

I'm trying to use UNIX socket to make kernel module can communicate with user space which the kernel module act as client while the user space program act as server.

I have noticed that UNIX socket has three types of address(refer to "man 7 unix").

When I use the pathname type address, it works normally. But when I use abstract type address, the kernel module cannot connect to the server. It returns -ECONNREFUSED.

Is there anything wrong with my code?

Kernel code

    struct sockaddr_un s_addr;

    ret = sock_create_kern(&amp;init_net, AF_LOCAL, SOCK_STREAM, 0, &amp;cl_sock);
    if (ret &lt; 0) {
        /*...*/
    }

    memset(&amp;s_addr, 0, sizeof(struct sockaddr_un));
    s_addr.sun_family = AF_LOCAL;
    s_addr.sun_path[0] = 0;
    strncpy(s_addr.sun_path + 1, &quot;my_test&quot;, sizeof(s_addr.sun_path) - 1);

    ret = cl_sock-&gt;ops-&gt;connect(cl_sock, (struct sockaddr *)&amp;s_addr, sizeof(s_addr), 0);
    if (ret &lt; 0) {
        /*...*/
    }

server code

 server_socket = socket_local_server(&quot;my_test&quot;, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
 if (server_socket &lt; 0) {
 	/*...*/
 }
 accept(server_socket , NULL, NULL);

I expect to use abstract type address to connect to server.

答案1

得分: 1

Here is the translation of the provided code and text:

尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
my_test
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
..."` —— 一个不同的套接字。
(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
"`和`"/tmp/my_test
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
尝试这个:

        socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                        strlen("my_test");
        ret = cl_sock->ops->connect(cl_sock,
                                    (struct sockaddr *)&s_addr,
                                    len, // <-- 不是sizeof(s_addr)
                                    0);


在抽象命名空间中,您必须计算_sun_path_中地址的确切长度作为_sockaddr_大小的一部分。您所需的地址是`"\0my_test"`,但您传入了完整的`sizeof(s_addr)`,这意味着指定的地址类似于`"\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."` —— 一个不同的套接字。

(相比之下,路径名本地套接字被理解为具有终止的空字节。`"/tmp/my_test\0"`和`"/tmp/my_test\0\0\0\0..."`都指的是套接字文件`/tmp/my_test`。)

Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
..."`都指的是套接字文件`/tmp/my_test`。)
Linux [unix套接字手册页](https://www.man7.org/linux/man-pages/man7/unix.7.html)在处理AF_UNIX地址格式时涉及到了这一点,尽管也许不像匆忙的程序员希望的那么清晰。
英文:

Try this:

    socklen_t len = offsetof(struct sockaddr_un, sun_path) + 1 +
                    strlen(&quot;my_test&quot;);
    ret = cl_sock-&gt;ops-&gt;connect(cl_sock,
                                (struct sockaddr *)&amp;s_addr,
                                len, // &lt;-- not sizeof(s_addr)
                                0);

In the abstract namespace, you must compute the exact length of the address in sun_path as part of the size of the sockaddr. Your desired address is &quot;\0my_test&quot;, but you pass in the full sizeof(s_addr), which means the address as specified is something like &quot;\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0...&quot; — a different socket.

(By contrast, pathname local sockets are understood to have a terminating null byte. Both &quot;/tmp/my_test\0&quot; and &quot;/tmp/my_test\0\0\0\0...&quot; refer to the socket file /tmp/my_test.)

The Linux man page for unix sockets addresses this in its treatment of AF_UNIX address formats, though perhaps not as clearly as the hurried programmer would like.

huangapple
  • 本文由 发表于 2023年6月26日 17:29:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76555367.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定