sd-varlink: do not call disconnect callback for incomplete connection
The connect callback is called after sd_varlink_server_add_connection() succeeds. Do not call the disconnect callback for connections that have not been established yet.
This commit is contained in:
@@ -1773,7 +1773,7 @@ _public_ int sd_varlink_flush(sd_varlink *v) {
|
||||
return json_stream_flush(&v->stream);
|
||||
}
|
||||
|
||||
static void varlink_detach_server(sd_varlink *v) {
|
||||
static void varlink_detach_server(sd_varlink *v, bool connected) {
|
||||
sd_varlink_server *saved_server;
|
||||
|
||||
assert(v);
|
||||
@@ -1808,7 +1808,7 @@ static void varlink_detach_server(sd_varlink *v) {
|
||||
|
||||
saved_server = TAKE_PTR(v->server);
|
||||
|
||||
if (saved_server->disconnect_callback)
|
||||
if (saved_server->disconnect_callback && connected)
|
||||
saved_server->disconnect_callback(saved_server, v, saved_server->userdata);
|
||||
|
||||
varlink_server_test_exit_on_idle(saved_server);
|
||||
@@ -1822,12 +1822,14 @@ _public_ int sd_varlink_close(sd_varlink *v) {
|
||||
if (v->state == VARLINK_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
bool connected = v->state >= 0;
|
||||
|
||||
varlink_set_state(v, VARLINK_DISCONNECTED);
|
||||
|
||||
/* Let's take a reference first, since varlink_detach_server() might drop the final (dangling) ref
|
||||
* which would destroy us before we can call varlink_clear() */
|
||||
sd_varlink_ref(v);
|
||||
varlink_detach_server(v);
|
||||
varlink_detach_server(v, connected);
|
||||
varlink_clear(v);
|
||||
sd_varlink_unref(v);
|
||||
|
||||
@@ -3462,8 +3464,6 @@ _public_ int sd_varlink_server_add_connection_pair(
|
||||
(void) sd_varlink_set_allow_fd_passing_input(v, FLAGS_SET(server->flags, SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT));
|
||||
(void) sd_varlink_set_allow_fd_passing_output(v, FLAGS_SET(server->flags, SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT));
|
||||
|
||||
varlink_set_state(v, VARLINK_IDLE_SERVER);
|
||||
|
||||
if (server->event) {
|
||||
r = sd_varlink_attach_event(v, server->event, server->event_priority);
|
||||
if (r < 0) {
|
||||
@@ -3479,6 +3479,8 @@ _public_ int sd_varlink_server_add_connection_pair(
|
||||
}
|
||||
}
|
||||
|
||||
varlink_set_state(v, VARLINK_IDLE_SERVER);
|
||||
|
||||
(void) mark_varlink_socket(input_fd, /* path= */ NULL, "server");
|
||||
|
||||
if (ret)
|
||||
|
||||
@@ -1504,6 +1504,12 @@ TEST(ctrunc) {
|
||||
ASSERT_OK(r);
|
||||
}
|
||||
|
||||
static void disconnect_callback(sd_varlink_server *server, sd_varlink *link, void *userdata) {
|
||||
unsigned *counter = ASSERT_PTR(userdata);
|
||||
|
||||
(*counter)++;
|
||||
}
|
||||
|
||||
TEST(add_connection_failure_cleanup) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
|
||||
_cleanup_close_pair_ int fds[2] = EBADF_PAIR;
|
||||
@@ -1514,6 +1520,11 @@ TEST(add_connection_failure_cleanup) {
|
||||
};
|
||||
|
||||
ASSERT_OK(sd_varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID));
|
||||
|
||||
unsigned c = 0;
|
||||
ASSERT_OK(sd_varlink_server_bind_disconnect(s, disconnect_callback));
|
||||
ASSERT_NULL(sd_varlink_server_set_userdata(s, &c));
|
||||
|
||||
ASSERT_OK(sd_varlink_server_set_connections_per_uid_max(s, 1));
|
||||
ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds));
|
||||
|
||||
@@ -1522,15 +1533,18 @@ TEST(add_connection_failure_cleanup) {
|
||||
|
||||
ASSERT_ERROR(sd_varlink_server_add_connection_pair(s, fds[0], bad_fd, &ucred, /* ret= */ NULL), EBADF);
|
||||
ASSERT_EQ(sd_varlink_server_current_connections(s), 0U);
|
||||
ASSERT_EQ(c, 0U); /* The disconnect callback is not called. */
|
||||
|
||||
sd_varlink *v = NULL;
|
||||
ASSERT_OK(sd_varlink_server_add_connection(s, fds[0], &v));
|
||||
TAKE_FD(fds[0]);
|
||||
ASSERT_NOT_NULL(v);
|
||||
ASSERT_EQ(sd_varlink_server_current_connections(s), 1U);
|
||||
ASSERT_EQ(c, 0U); /* The disconnect callback is not called yet. */
|
||||
|
||||
ASSERT_OK_POSITIVE(sd_varlink_close(v));
|
||||
ASSERT_EQ(sd_varlink_server_current_connections(s), 0U);
|
||||
ASSERT_EQ(c, 1U); /* The disconnect callback is called when the connection is closed. */
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
||||
Reference in New Issue
Block a user