From 2fb13032abaa92213e72cc1f5975210a8a5b1097 Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Thu, 19 Jan 2023 03:40:37 +0200 Subject: [PATCH] massive refactor to stop passing around client index in server.c --- match.c | 15 ++-- match.h | 2 +- server.c | 243 +++++++++++++++++++++++++++---------------------------- server.h | 21 ++--- 4 files changed, 137 insertions(+), 144 deletions(-) diff --git a/match.c b/match.c index 84b8f25..7c03d9f 100644 --- a/match.c +++ b/match.c @@ -178,17 +178,16 @@ fail: } \ } while(0) -int match_check_sender(Bus *s, int sender_index, MatchRule *rule) +int match_check_sender(Bus *s, BusClient *sender_client, MatchRule *rule) { - BusClient *sender_client = &s->clients[sender_index]; if (rule->sender) { - if (sender_client->unique_name_index >= 0) { - if (strcmp(rule->sender, s->names[sender_client->unique_name_index].name) == 0) { + if (sender_client->unique_name) { + if (strcmp(rule->sender, sender_client->unique_name->name) == 0) { return 1; } } for (int i = 0; i < BUS_NAMES_PER_CLIENT; i++) { - if (sender_client->owned_names[i] >= 0 && strcmp(rule->sender, s->names[sender_client->owned_names[i]].name) == 0) { + if (sender_client->owned_names[i] && strcmp(rule->sender, sender_client->owned_names[i]->name) == 0) { return 1; } } @@ -197,19 +196,19 @@ int match_check_sender(Bus *s, int sender_index, MatchRule *rule) return -1; } -int match_rule_check(Bus *s, int sender_index, MatchRule *rule, WireMsg *msg, WireCtx *ctx) +int match_rule_check(Bus *s, BusClient *sender_client, MatchRule *rule, WireMsg *msg, WireCtx *ctx) { if (rule->type && msg->type != rule->type) { return -1; } - if (sender_index < 0) { + if (!sender_client) { // if the sender is negative, we assume the message is coming from the message bus if (rule->sender && strcmp(rule->sender, "org.freedesktop.DBus") != 0) { return -1; } } else { - if (match_check_sender(s, sender_index, rule) < 0) { + if (match_check_sender(s, sender_client, rule) < 0) { return -1; } } diff --git a/match.h b/match.h index 116fd8c..75f4fc1 100644 --- a/match.h +++ b/match.h @@ -8,6 +8,6 @@ void match_rule_free(MatchRule *rule); MatchRule *match_rule_from_string(char *d); -int match_rule_check(Bus *s, int sender_index, MatchRule *rule, WireMsg *msg, WireCtx *ctx); +int match_rule_check(Bus *s, BusClient *sender_client, MatchRule *rule, WireMsg *msg, WireCtx *ctx); #endif // _JITTERBUG__MATCH_H diff --git a/server.c b/server.c index 2bb3c4d..6a1397f 100644 --- a/server.c +++ b/server.c @@ -37,7 +37,7 @@ void bus_free(Bus *s) if (s->urandom_fd >= 0) close(s->urandom_fd); // freeing all clients will also free all matches and names for (int i = 0; i < BUS_MAX_CLIENTS; i++) { - bus_client_remove(s, i); + bus_client_remove(s, &s->clients[i]); } free(s); } @@ -86,9 +86,10 @@ Bus *bus_create(const char *socket_path) for (int i = 0; i < BUS_MAX_CLIENTS; i++) { s->clients[i].fd = -1; - s->clients[i].unique_name_index = -1; + s->clients[i].unique_name = NULL; s->clients[i].state = BUS_CLIENT_STATE_NONE; s->clients[i].match_count = 0; + s->clients[i].fd_index = i; s->fds[i].fd = -1; s->fds[i].events = 0; s->fds[i].revents = 0; @@ -96,12 +97,12 @@ Bus *bus_create(const char *socket_path) s->clients[i].matches[j] = NULL; } for (int j = 0; j < BUS_NAMES_PER_CLIENT; j++) { - s->clients[i].owned_names[j] = -1; + s->clients[i].owned_names[j] = NULL; } } for (int i = 0; i < BUS_MAX_NAMES; i++) { - s->names[i].client_index = -1; + s->names[i].client = NULL; s->names[i].name = NULL; } s->names_count = 0; @@ -126,7 +127,7 @@ int bus_client_add(Bus *s, int fd) for (int i = 0; i < BUS_MAX_CLIENTS; i++) { if (s->clients[i].fd < 0) { s->clients[i].fd = fd; - s->clients[i].unique_name_index = -1; + s->clients[i].unique_name = NULL; s->clients[i].state = BUS_CLIENT_STATE_WAIT_AUTH; s->fds[i].fd = fd; s->fds[i].events = POLLIN; @@ -157,48 +158,46 @@ BusClient *bus_name_find_client(Bus *s, char *name) return NULL; } - if (s->names[name_index].client_index < 0) { + if (!s->names[name_index].client) { return NULL; } - if (s->clients[s->names[name_index].client_index].state != BUS_CLIENT_STATE_READY) { + if (s->names[name_index].client->state != BUS_CLIENT_STATE_READY) { return NULL; } - return &s->clients[s->names[name_index].client_index]; + return s->names[name_index].client; } -int bus_name_add(Bus *s, char *name, int client_index) +BusName *bus_name_add(Bus *s, char *name, BusClient *client) { if (bus_name_find(s, name) >= 0) { - return -1; + return NULL; } int bucket = hashmap_hash(name, strlen(name), BUS_MAX_NAMES); for (int i = bucket; i < bucket + 12 && i < BUS_MAX_NAMES; i++) { - if (s->names[i].client_index == -1) { + if (!s->names[i].client) { for (int j = 0; j < BUS_NAMES_PER_CLIENT; j++) { - if (s->clients[client_index].owned_names[j] < 0) { - s->clients[client_index].owned_names[j] = i; - s->names[i].client_index = client_index; + if (!client->owned_names[j]) { + client->owned_names[j] = &s->names[i]; + s->names[i].client = client; s->names[i].name = name; s->names_count++; - return i; + return &s->names[i]; } } - return -1; + return NULL; } } - return -1; + return NULL; } -int bus_client_match_add(Bus *s, int client_index, char *match) +int bus_client_match_add(Bus *s, BusClient *c, char *match) { - BusClient *c = &s->clients[client_index]; - for (int i = 0; i < BUS_MAX_MATCH; i++) { if (!c->matches[i]) { c->matches[i] = match_rule_from_string(match); @@ -210,65 +209,66 @@ int bus_client_match_add(Bus *s, int client_index, char *match) return -1; } -int bus_client_assign_unique_name(Bus *s, int i) +BusName *bus_client_assign_unique_name(Bus *s, BusClient *client) { - BusClient *c = &s->clients[i]; - if (c->unique_name_index != -1) { - return -1; + if (client->unique_name) { + return NULL; } uint32_t id = 0; if (read(s->urandom_fd, &id, sizeof(uint32_t)) != sizeof(uint32_t)) { - return -1; + return NULL; } - char *name = malloc(sizeof(char) * 16); + char *name_str = malloc(sizeof(char) * 16); + if (!name_str) { + return NULL; + } + + if (snprintf(name_str, 16, ":1.%"PRIu32, id) < 0) { + free(name_str); + return NULL; + } + + BusName *name = bus_name_add(s, name_str, client); if (!name) { - return -1; + free(name_str); + return NULL; } + client->unique_name = name; - if (snprintf(name, 16, ":1.%"PRIu32, id) < 0) { - free(name); - return -1; - } - - int name_index = bus_name_add(s, name, i); - if (name_index < 0) { - free(name); - return -1; - } - c->unique_name_index = name_index; - - return name_index; + return name; } -int bus_client_assign_own_name(Bus *s, int i, char *name) +int bus_client_assign_own_name(Bus *s, BusClient *client, char *name) { if (!name || *name == ':' || *name == '\0') { return -1; } - TRYST(bus_name_add(s, name, i)); + TRYPTR(bus_name_add(s, name, client)); return 0; } -void bus_name_remove(Bus *s, int i) +void bus_name_remove(Bus *s, BusName *name) { - if (i >= 0) { - if (s->names[i].name) { - free(s->names[i].name); - s->names[i].name = NULL; - } - s->names[i].client_index = -1; - s->names_count--; + if (!name) { + return; } + + if (name->name) { + free(name->name); + name->name = NULL; + } + + name->client = NULL; + + s->names_count--; } -void bus_client_remove(Bus *s, int i) +void bus_client_remove(Bus *s, BusClient *c) { - BusClient *c = &s->clients[i]; - if (c->fd >= 0) { close(c->fd); } @@ -279,38 +279,34 @@ void bus_client_remove(Bus *s, int i) } } for (int j = 0; j < BUS_NAMES_PER_CLIENT; j++) { - if (c->owned_names[j] >= 0) { - bus_name_remove(s, c->owned_names[j]); - c->owned_names[j] = -1; - } + bus_name_remove(s, c->owned_names[j]); + c->owned_names[j] = NULL; } - c->unique_name_index = -1; + c->unique_name = NULL; c->match_count = 0; c->fd = -1; c->state = BUS_CLIENT_STATE_NONE; - s->fds[i].fd = -1; - s->fds[i].events = 0; - s->fds[i].revents = 0; + s->fds[c->fd_index].fd = -1; + s->fds[c->fd_index].events = 0; + s->fds[c->fd_index].revents = 0; s->clients_count--; } -void bus_client_error(Bus *s, int i, const char *msg) +void bus_client_error(Bus *s, BusClient *client, const char *msg) { - WARN("removing client %d due to error: %s\n", i, msg); - send(s->clients[i].fd, msg, strlen(msg), 0); - bus_client_remove(s, i); + WARN("removing client %d due to error: %s\n", client->fd_index, msg); + send(client->fd, msg, strlen(msg), 0); + bus_client_remove(s, client); } -int bus_broadcast_message(Bus *s, int sender_index, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) +int bus_broadcast_message(Bus *s, BusClient *sender_client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { uint32_t body_end = ctx->byte_cursor + msg->body_length; if (body_end >= ctx->data_len) { return -1; } - BusClient *sender_client = &s->clients[sender_index]; - int left = s->clients_count; for (int i = 0; i < BUS_MAX_CLIENTS && left > 0; i++) { if (s->clients[i].state != BUS_CLIENT_STATE_READY) { @@ -329,8 +325,8 @@ int bus_broadcast_message(Bus *s, int sender_index, WireMsg *msg, WireCtx *ctx, match_left--; uint32_t previous_cursor = ctx->byte_cursor; - if (match_rule_check(s, sender_index, c->matches[j], msg, ctx) >= 0) { - TRYST(wire_compose_unicast_reply(reply_ctx, ctx, msg, s->names[sender_client->unique_name_index].name)); + if (match_rule_check(s, sender_client, c->matches[j], msg, ctx) >= 0) { + TRYST(wire_compose_unicast_reply(reply_ctx, ctx, msg, sender_client->unique_name->name)); TRYST(send(c->fd, reply_ctx->data, reply_ctx->byte_cursor, 0)); // TODO? memset(reply_ctx->data, 0, reply_ctx->data_len); @@ -346,7 +342,7 @@ int bus_broadcast_message(Bus *s, int sender_index, WireMsg *msg, WireCtx *ctx, return 0; } -int bus_broadcast_signal(Bus *s, int sender_index, WireCtx *ctx, WireMsg *msg) +int bus_broadcast_signal(Bus *s, BusClient *client, WireCtx *ctx, WireMsg *msg) { int left = s->clients_count; for (int i = 0; i < BUS_MAX_CLIENTS && left > 0; i++) { @@ -364,7 +360,7 @@ int bus_broadcast_signal(Bus *s, int sender_index, WireCtx *ctx, WireMsg *msg) } match_left--; - if (match_rule_check(s, sender_index, c->matches[j], msg, ctx) >= 0) { + if (match_rule_check(s, client, c->matches[j], msg, ctx) >= 0) { uint32_t previous_cursor = ctx->byte_cursor; TRYST(send(c->fd, ctx->data, ctx->byte_cursor, 0)); ctx->byte_cursor = previous_cursor; @@ -399,7 +395,7 @@ int bus_unicast_message(Bus *s, WireMsg *msg, WireCtx *ctx, char *target_name, c #define _signal_end() \ *signal_body_length = signal_reply_ctx.byte_cursor - signal_body_start; \ - TRYST(bus_broadcast_signal(s, -1, &signal_reply_ctx, &signal_reply_msg)); \ + TRYST(bus_broadcast_signal(s, NULL, &signal_reply_ctx, &signal_reply_msg)); \ #define _reply_begin(M_sig) \ @@ -411,7 +407,7 @@ int bus_unicast_message(Bus *s, WireMsg *msg, WireCtx *ctx, char *target_name, c #define _reply_end() \ *body_length = reply_ctx->byte_cursor - body_start; \ - if (send(s->fds[i].fd, reply_ctx->data, reply_ctx->byte_cursor, 0) != reply_ctx->byte_cursor) { \ + if (send(client->fd, reply_ctx->data, reply_ctx->byte_cursor, 0) != reply_ctx->byte_cursor) { \ return -1; \ } \ VERBOSE("sent response of %d byte(s)\n", reply_ctx->byte_cursor); \ @@ -421,36 +417,36 @@ int bus_unicast_message(Bus *s, WireMsg *msg, WireCtx *ctx, char *target_name, c do { \ if (!(msg->flags & DBUS_FLAG_NO_REPLY_EXPECTED)) { \ TRYST(wire_compose_error(reply_ctx, msg, (message))); \ - if (send(s->fds[i].fd, reply_ctx->data, reply_ctx->byte_cursor, 0) != reply_ctx->byte_cursor) { \ + if (send(client->fd, reply_ctx->data, reply_ctx->byte_cursor, 0) != reply_ctx->byte_cursor) { \ return -1; \ } \ } \ } while(0) \ -int handle_hello(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_hello(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { (void)ctx; - int unique_name_index = TRYST(bus_client_assign_unique_name(s, i)); + BusName *name_entry = TRYPTR(bus_client_assign_unique_name(s, client)); _reply_begin("s") { - TRYPTR(wire_set_string(reply_ctx, s->names[unique_name_index].name)); + TRYPTR(wire_set_string(reply_ctx, name_entry->name)); } _reply_end() _signal_begin("sss", "NameOwnerChanged") { /* Name with a new owner */ - TRYPTR(wire_set_string(&signal_reply_ctx, s->names[unique_name_index].name)); + TRYPTR(wire_set_string(&signal_reply_ctx, name_entry->name)); /* Old owner or empty string if none */ TRYPTR(wire_set_string(&signal_reply_ctx, "")); /* New owner or empty string if none */ TRYPTR(wire_set_string(&signal_reply_ctx, "")); } _signal_end(); - VERBOSE("assigned unique name '%s' to connection %d\n", s->names[unique_name_index].name, i); + VERBOSE("assigned unique name '%s' to connection %d\n", name_entry->name, client->fd_index); return 0; } -int handle_request_name(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { - if (s->clients[i].unique_name_index < 0) { +int handle_request_name(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { + if (!client->unique_name) { return -1; } @@ -461,11 +457,11 @@ int handle_request_name(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *repl int status_code = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; - if (bus_client_assign_own_name(s, i, name_str) < 0) { + if (bus_client_assign_own_name(s, client, name_str) < 0) { // TODO: report the actual error status_code = DBUS_REQUEST_NAME_REPLY_IN_QUEUE; - WARN("client '%s' (index=%d) couldn't acquire name '%s'\n", s->names[s->clients[i].unique_name_index].name, i, name_str); + WARN("client '%s' (index=%d) couldn't acquire name '%s'\n", client->unique_name->name, client->fd_index, name_str); free(name_str); } @@ -481,30 +477,30 @@ int handle_request_name(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *repl /* Old owner or empty string if none */ TRYPTR(wire_set_string(&signal_reply_ctx, "")); /* New owner or empty string if none */ - TRYPTR(wire_set_string(&signal_reply_ctx, s->names[s->clients[i].unique_name_index].name)); + TRYPTR(wire_set_string(&signal_reply_ctx, client->unique_name->name)); } _signal_end(); - VERBOSE("client '%s' (index=%d) now owns name '%s'\n", s->names[s->clients[i].unique_name_index].name, i, name_str); + VERBOSE("client '%s' (index=%d) now owns name '%s'\n", client->unique_name->name, client->fd_index, name_str); } return 0; } -int handle_get_name_owner(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_get_name_owner(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { char *name = TRYPTR(wire_get_name_string(ctx)); BusClient *target = bus_name_find_client(s, name); - if (!target || target->unique_name_index < 0) { + if (!target || !target->unique_name) { _reply_error("org.freedesktop.DBus.Error.NameHasNoOwner"); return 0; } _reply_begin("s") { - TRYPTR(wire_set_string(reply_ctx, s->names[target->unique_name_index].name)); + TRYPTR(wire_set_string(reply_ctx, target->unique_name->name)); } _reply_end() return 0; } -int handle_name_has_owner(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_name_has_owner(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { char *name = TRYPTR(wire_get_name_string(ctx)); BusClient *target = bus_name_find_client(s, name); @@ -515,7 +511,7 @@ int handle_name_has_owner(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *re return 0; } -int handle_list_names(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_list_names(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { (void)ctx; _reply_begin("as") { @@ -530,7 +526,7 @@ int handle_list_names(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ int left = s->names_count; for (int j = 0; j < BUS_MAX_NAMES && left > 0; j++) { - if (s->names[j].name && s->names[j].client_index >= 0) { + if (s->names[j].name && s->names[j].client) { left--; TRYPTR(wire_set_string(reply_ctx, s->names[j].name)); } @@ -541,7 +537,7 @@ int handle_list_names(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ return 0; } -int handle_list_activatable_names(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_list_activatable_names(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { (void)ctx; STUB("handle_list_activatable_names", "always returns empty array"); @@ -554,7 +550,7 @@ int handle_list_activatable_names(Bus *s, int i, WireMsg *msg, WireCtx *ctx, Wir return 0; } -int handle_start_service_by_name(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_start_service_by_name(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { TRYPTR(wire_get_name_string(ctx)); /* unused flags value */ @@ -568,21 +564,20 @@ int handle_start_service_by_name(Bus *s, int i, WireMsg *msg, WireCtx *ctx, Wire return 0; } -int handle_add_match(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_add_match(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { char *match = TRYPTR(wire_get_string_check(ctx, 1, MATCH_RULE_MAX)); - VERBOSE("client index %d adding match rule: '%s'\n", i, match); + VERBOSE("client index %d adding match rule: '%s'\n", client->fd_index, match); - TRYST(bus_client_match_add(s, i, match)); + TRYST(bus_client_match_add(s, client, match)); _reply_begin("") {} _reply_end() return 0; } -int handle_remove_match(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_remove_match(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { char *match = TRYPTR(wire_get_string_check(ctx, 1, MATCH_RULE_MAX)); - BusClient *client = &s->clients[i]; int left = client->match_count; for (int j = 0; j < BUS_MAX_MATCH && left > 0; j++) { left--; @@ -599,7 +594,7 @@ int handle_remove_match(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *repl return 0; } -int handle_get_connection_stats(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_get_connection_stats(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { (void)ctx; TRYPTR(wire_get_name_string(ctx)); @@ -614,13 +609,13 @@ int handle_get_connection_stats(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireC return 0; } -int handle_get_connection_unix_process_id(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_get_connection_unix_process_id(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { (void)ctx; char *name = TRYPTR(wire_get_name_string(ctx)); BusClient *target = bus_name_find_client(s, name); - if (!target || target->unique_name_index < 0 || target->fd < 0) { + if (!target || !target->unique_name || target->fd < 0) { _reply_error("org.freedesktop.DBus.Error.NameHasNoOwner"); return 0; } @@ -639,7 +634,7 @@ int handle_get_connection_unix_process_id(Bus *s, int i, WireMsg *msg, WireCtx * return 0; } -int handle_get_all_match_rules(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { +int handle_get_all_match_rules(Bus *s, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx) { (void)ctx; _reply_begin("a{sas}") { uint32_t *outer_array_len = TRYPTR(wire_set_u32(reply_ctx, 0)); @@ -649,14 +644,14 @@ int handle_get_all_match_rules(Bus *s, int i, WireMsg *msg, WireCtx *ctx, WireCt int left = s->names_count; for (int j = 0; j < BUS_MAX_NAMES && left > 0; j++) { BusName *n = &s->names[j]; - if (!n->name || n->client_index < 0 || *n->name != ':') { + if (!n->name || !n->client || *n->name != ':') { continue; } left--; TRYPTR(wire_write_align(reply_ctx, 8)); /* structs always aligned to 8 */ - BusClient *c = &s->clients[s->names[j].client_index]; + BusClient *c = s->names[j].client; TRYPTR(wire_set_string(reply_ctx, s->names[j].name)); /* unique name */ @@ -703,16 +698,14 @@ static const int bus_method_handlers_count = sizeof(bus_method_handlers) / sizeo do { \ if (!(msg.flags & DBUS_FLAG_NO_REPLY_EXPECTED)) { \ TRYST(wire_compose_error(&reply_ctx, &msg, (message))); \ - if (send(s->fds[i].fd, reply_ctx.data, reply_ctx.byte_cursor, 0) != reply_ctx.byte_cursor) { \ + if (send(client->fd, reply_ctx.data, reply_ctx.byte_cursor, 0) != reply_ctx.byte_cursor) { \ return -1; \ } \ } \ } while(0) \ -int bus_client_process_message(Bus *s, int i, WireCtx *ctx) +int bus_client_process_message(Bus *s, BusClient *client, WireCtx *ctx) { - BusClient *client = &s->clients[i]; - WireMsg msg = {0}; TRYST(wire_parse_message(ctx, &msg)); @@ -737,7 +730,7 @@ int bus_client_process_message(Bus *s, int i, WireCtx *ctx) for (int j = 0; j < bus_method_handlers_count; j++) { const BusMethodHandler *handler = &bus_method_handlers[j]; if (strcmp(handler->name, member_field->t.str) == 0) { - TRYST(handler->handler(s, i, &msg, ctx, &reply_ctx)); + TRYST(handler->handler(s, client, &msg, ctx, &reply_ctx)); goto end_nonfatal; } } @@ -749,17 +742,17 @@ int bus_client_process_message(Bus *s, int i, WireCtx *ctx) // message needs to be routed // TODO: perform checks here like making sure all method calls have the 'member' field, etc. - if (client->unique_name_index < 0) { + if (!client->unique_name) { return -1; } if (destination_field->present) { - if (bus_unicast_message(s, &msg, ctx, destination_field->t.str, s->names[client->unique_name_index].name, &reply_ctx) < 0) { + if (bus_unicast_message(s, &msg, ctx, destination_field->t.str, client->unique_name->name, &reply_ctx) < 0) { _process_message_reply_error("xyz.hippoz.jitterbug.UnicastFailed"); goto end_nonfatal; } } else { - if (bus_broadcast_message(s, i, &msg, ctx, &reply_ctx) < 0) { + if (bus_broadcast_message(s, client, &msg, ctx, &reply_ctx) < 0) { _process_message_reply_error("xyz.hippoz.jitterbug.BroadcastFailed"); goto end_nonfatal; } @@ -785,7 +778,7 @@ end_nonfatal: return 0; } -int bus_client_drain_messages(Bus *s, int ci, uint8_t *data, uint32_t data_len) +int bus_client_drain_messages(Bus *s, BusClient *client, uint8_t *data, uint32_t data_len) { WireCtx ctx = { .byte_cursor = 0, @@ -793,7 +786,7 @@ int bus_client_drain_messages(Bus *s, int ci, uint8_t *data, uint32_t data_len) .data_len = data_len }; - TRYST(bus_client_process_message(s, ci, &ctx)); + TRYST(bus_client_process_message(s, client, &ctx)); int i = 0; for (; i < 10; i++) { @@ -804,7 +797,7 @@ int bus_client_drain_messages(Bus *s, int ci, uint8_t *data, uint32_t data_len) ctx.data = ctx.data + ctx.byte_cursor; ctx.data_len = ctx.data_len - ctx.byte_cursor; ctx.byte_cursor = 0; - TRYST(bus_client_process_message(s, ci, &ctx)); + TRYST(bus_client_process_message(s, client, &ctx)); } VERBOSE("processed %d messages - cursor:%d; data_len:%ld\n", i + 1, ctx.byte_cursor, ctx.data_len); @@ -812,7 +805,7 @@ int bus_client_drain_messages(Bus *s, int ci, uint8_t *data, uint32_t data_len) return 0; } -#define _client_die(m) do { bus_client_error(s,i,m); goto done; } while(0) +#define _client_die(m) do { bus_client_error(s, &s->clients[i], m); goto done; } while(0) int bus_turn(Bus *s) { static const char agree_unix_fd[] = "ERROR\r\n"; @@ -836,23 +829,23 @@ int bus_turn(Bus *s) for (int i = 0; i < s->fd_num; i++) { int fd = s->fds[i].fd; if (s->fds[i].revents & POLLNVAL) { - ERROR("Busurn: error: got POLLNVAL for fds[%d]. This is considered a bug in the server implementation.\n", i); + ERROR("bus_turn: error: got POLLNVAL for fds[%d]. This is considered a bug in the server implementation.\n", i); return -1; } if (s->fds[i].revents & POLLERR) { if (fd == s->sock_fd) { - ERROR("Busurn: error: got POLLERR for sock_fd\n"); + ERROR("bus_turn: error: got POLLERR for sock_fd\n"); return -1; } - bus_client_remove(s, i); + bus_client_remove(s, &s->clients[i]); continue; } if (s->fds[i].revents & POLLHUP) { if (fd == s->sock_fd) { - ERROR("Busurn: error: got POLLHUP for sock_fd\n"); + ERROR("bus_turn: error: got POLLHUP for sock_fd\n"); return -1; } - bus_client_remove(s, i); + bus_client_remove(s, &s->clients[i]); continue; } if (s->fds[i].revents & POLLIN) { @@ -876,7 +869,7 @@ int bus_turn(Bus *s) if (bytes <= 0) { // error during recv() OR client disconnected, disconnect the client // TODO: should we actually do this? - bus_client_remove(s, i); + bus_client_remove(s, &s->clients[i]); continue; } @@ -917,7 +910,7 @@ int bus_turn(Bus *s) char *first_message_begin = data + 7; /* 7 = length of "BEGIN\r\n" */ if (*first_message_begin == 'l' || *first_message_begin == 'B') { // This looks like a D-Bus message. Let's process it! - if (bus_client_drain_messages(s, i, (uint8_t *)first_message_begin, data_buffer_len - 7) < 0) { + if (bus_client_drain_messages(s, &s->clients[i], (uint8_t *)first_message_begin, data_buffer_len - 7) < 0) { _client_die("failed to process message"); } } @@ -930,7 +923,7 @@ int bus_turn(Bus *s) } break; case BUS_CLIENT_STATE_READY: { - if (bus_client_drain_messages(s, i, (uint8_t*)data, data_buffer_len) < 0) { + if (bus_client_drain_messages(s, &s->clients[i], (uint8_t*)data, data_buffer_len) < 0) { _client_die("failed to process message"); } } break; diff --git a/server.h b/server.h index 2eb8401..5d6503d 100644 --- a/server.h +++ b/server.h @@ -30,20 +30,21 @@ enum { BUS_CLIENT_STATE_READY }; -typedef struct { +typedef struct bus_name { + char *name; + struct bus_client *client; +} BusName; + +typedef struct bus_client { int fd; - int16_t unique_name_index; + BusName *unique_name; + int16_t fd_index; uint8_t state; int8_t match_count; MatchRule *matches[BUS_MAX_MATCH]; - int16_t owned_names[BUS_NAMES_PER_CLIENT]; + BusName *owned_names[BUS_NAMES_PER_CLIENT]; } BusClient; -typedef struct { - char *name; - int32_t client_index; -} BusName; - typedef struct { int sock_fd; int fd_num; @@ -57,12 +58,12 @@ typedef struct { typedef struct { const char *name; - int (*handler)(Bus *bus, int client_index, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx); + int (*handler)(Bus *bus, BusClient *client, WireMsg *msg, WireCtx *ctx, WireCtx *reply_ctx); } BusMethodHandler; int bus_client_add(Bus *s, int fd); -void bus_client_remove(Bus *s, int i); +void bus_client_remove(Bus *s, BusClient *client); void bus_free(Bus *s); Bus *bus_create(const char *socket_path); int bus_turn(Bus *s);