Issue
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(&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 code
server_socket = socket_local_server("my_test", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
if (server_socket < 0) {
/*...*/
}
accept(server_socket , NULL, NULL);
I expect to use abstract type address to connect to server.
Solution
Try this:
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, // <-- 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 "\0my_test"
, but you pass in the full sizeof(s_addr)
, which means the address as specified is something like "\0my_test\0\0\0\0\0\0\0\0\0\0\0\0\0..."
— a different socket.
(By contrast, pathname local sockets are understood to have a terminating null byte. Both "/tmp/my_test\0"
and "/tmp/my_test\0\0\0\0..."
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.
Answered By - pilcrow Answer Checked By - Timothy Miller (WPSolving Admin)