mirror of
https://github.com/libuv/libuv
synced 2025-03-28 21:13:16 +00:00
linux: fix bind/connect for abstract sockets (#4266)
The `\0` character has no special significance in abstract sockets, so the addrlen field in both `bind()` and `connect()` should take that into account.
This commit is contained in:
parent
8861a97efa
commit
1dd0ab1315
@ -66,6 +66,7 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
char* pipe_fname;
|
||||
int sockfd;
|
||||
int err;
|
||||
socklen_t addrlen;
|
||||
|
||||
pipe_fname = NULL;
|
||||
|
||||
@ -100,12 +101,15 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
* We unlink the file later but abstract sockets disappear
|
||||
* automatically since they're not real file system entities.
|
||||
*/
|
||||
if (*name != '\0') {
|
||||
if (*name == '\0') {
|
||||
addrlen = offsetof(struct sockaddr_un, sun_path) + namelen;
|
||||
} else {
|
||||
pipe_fname = uv__malloc(namelen + 1);
|
||||
if (pipe_fname == NULL)
|
||||
return UV_ENOMEM;
|
||||
memcpy(pipe_fname, name, namelen);
|
||||
pipe_fname[namelen] = '\0';
|
||||
addrlen = sizeof saddr;
|
||||
}
|
||||
|
||||
err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
@ -117,7 +121,7 @@ int uv_pipe_bind2(uv_pipe_t* handle,
|
||||
memcpy(&saddr.sun_path, name, namelen);
|
||||
saddr.sun_family = AF_UNIX;
|
||||
|
||||
if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
|
||||
if (bind(sockfd, (struct sockaddr*)&saddr, addrlen)) {
|
||||
err = UV__ERR(errno);
|
||||
/* Convert ENOENT to EACCES for compatibility with Windows. */
|
||||
if (err == UV_ENOENT)
|
||||
@ -251,6 +255,7 @@ int uv_pipe_connect2(uv_connect_t* req,
|
||||
int new_sock;
|
||||
int err;
|
||||
int r;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (flags & ~UV_PIPE_NO_TRUNCATE)
|
||||
return UV_EINVAL;
|
||||
@ -285,9 +290,13 @@ int uv_pipe_connect2(uv_connect_t* req,
|
||||
memcpy(&saddr.sun_path, name, namelen);
|
||||
saddr.sun_family = AF_UNIX;
|
||||
|
||||
if (*name == '\0')
|
||||
addrlen = offsetof(struct sockaddr_un, sun_path) + namelen;
|
||||
else
|
||||
addrlen = sizeof saddr;
|
||||
|
||||
do {
|
||||
r = connect(uv__stream_fd(handle),
|
||||
(struct sockaddr*)&saddr, sizeof saddr);
|
||||
r = connect(uv__stream_fd(handle), (struct sockaddr*)&saddr, addrlen);
|
||||
}
|
||||
while (r == -1 && errno == EINTR);
|
||||
|
||||
|
@ -60,8 +60,8 @@ static void pipe_client_connect_cb(uv_connect_t* req, int status) {
|
||||
|
||||
if (*buf == '\0') { /* Linux abstract socket. */
|
||||
const char expected[] = "\0" TEST_PIPENAME;
|
||||
ASSERT_GE(len, sizeof(expected));
|
||||
ASSERT_MEM_EQ(buf, expected, sizeof(expected));
|
||||
ASSERT_EQ(len, sizeof(expected) - 1);
|
||||
ASSERT_MEM_EQ(buf, expected, len);
|
||||
} else {
|
||||
ASSERT_NE(0, buf[len - 1]);
|
||||
ASSERT_MEM_EQ(buf, TEST_PIPENAME, len);
|
||||
@ -191,7 +191,8 @@ TEST_IMPL(pipe_getsockname_abstract) {
|
||||
ASSERT_OK(uv_pipe_init(uv_default_loop(), &pipe_server, 0));
|
||||
ASSERT_OK(uv_pipe_bind2(&pipe_server, name, sizeof(name) - 1, 0));
|
||||
ASSERT_OK(uv_pipe_getsockname(&pipe_server, buf, &buflen));
|
||||
ASSERT_MEM_EQ(name, buf, sizeof(name));
|
||||
ASSERT_UINT64_EQ(sizeof(name) - 1, buflen);
|
||||
ASSERT_MEM_EQ(name, buf, buflen);
|
||||
ASSERT_OK(uv_listen((uv_stream_t*) &pipe_server,
|
||||
0,
|
||||
pipe_server_connection_cb));
|
||||
|
Loading…
x
Reference in New Issue
Block a user