From 0d5385f295c34e4c383317fc3be7f38f811aea1c Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Sat, 31 Dec 2022 17:55:32 +0200 Subject: [PATCH] store match rules per client --- match.c | 1 + server.c | 87 +++++++++++++++++++++++++++++++------------------------- server.h | 11 +++---- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/match.c b/match.c index 8d304be..4766d91 100644 --- a/match.c +++ b/match.c @@ -189,6 +189,7 @@ int match_rule_check(match_rule_t *rule, wire_message_t *msg, wire_context_t *ct wire_message_body_string_t strings[MATCH_RULE_MAX_ARG]; memset(strings, 0, sizeof(strings)); + /* TODO: handle failure */ TRYST(wire_collect_strings(ctx, msg, strings, MATCH_RULE_MAX_ARG)); for (int i = 0; i < MATCH_RULE_MAX_ARG; i++) { diff --git a/server.c b/server.c index 4c6cf53..b5463e4 100644 --- a/server.c +++ b/server.c @@ -36,6 +36,7 @@ int jb_server_client_add(struct jb_server *s, int fd) s->clients[i].state = JB_CLIENT_STATE_WAIT_AUTH; s->fds[i].fd = fd; s->fds[i].events = POLLIN; + s->clients_count++; return i; } } @@ -93,12 +94,14 @@ int jb_server_name_add(struct jb_server *s, char *name, int client_index) return -1; } -int jb_server_match_add(struct jb_server *s, char *match, int client_index) +int jb_server_client_match_add(struct jb_server *s, int client_index, char *match) { + struct jb_client *c = &s->clients[client_index]; + for (int i = 0; i < JB_MAX_MATCH; i++) { - if (s->matches[i].client_index < 0) { - s->matches[i].rule = match_rule_from_string(match); - s->matches[i].client_index = client_index; + if (!c->matches[i]) { + c->matches[i] = match_rule_from_string(match); + c->match_count++; return 0; } } @@ -171,26 +174,28 @@ void jb_server_name_remove(struct jb_server *s, int i) void jb_server_client_remove(struct jb_server *s, int i) { - if (s->clients[i].fd >= 0) { - close(s->clients[i].fd); + struct jb_client *c = &s->clients[i]; + + if (c->fd >= 0) { + close(c->fd); } - // TODO: slow for (int i = 0; i < JB_MAX_MATCH; i++) { - if (s->matches[i].client_index == i) { - s->matches[i].client_index = -1; - match_rule_free(s->matches[i].rule); - s->matches[i].rule = NULL; + if (c->matches[i]) { + match_rule_free(c->matches[i]); + c->matches[i] = NULL; } } - jb_server_name_remove(s, s->clients[i].unique_name_index); - jb_server_name_remove(s, s->clients[i].owned_name_index); - s->clients[i].unique_name_index = -1; - s->clients[i].owned_name_index = -1; - s->clients[i].fd = -1; - s->clients[i].state = JB_CLIENT_STATE_NONE; + jb_server_name_remove(s, c->unique_name_index); + jb_server_name_remove(s, c->owned_name_index); + c->unique_name_index = -1; + c->owned_name_index = -1; + c->match_count = 0; + c->fd = -1; + c->state = JB_CLIENT_STATE_NONE; s->fds[i].fd = -1; s->fds[i].events = 0; s->fds[i].revents = 0; + s->clients_count--; } void jb_server_client_error(struct jb_server *s, int i, const char *msg) @@ -211,11 +216,23 @@ ssize_t jb_server_client_recv(struct jb_server *s, int i, void *buf, size_t n) int jb_server_broadcast_message(struct jb_server *s, wire_message_t *msg, wire_context_t *ctx, char *sender_unique_name) { - for (int i = 0; i < JB_MAX_MATCH; i++) { - if (s->matches[i].rule) { - if (match_rule_check(s->matches[i].rule, msg, ctx) >= 0) { - struct jb_client *client = &s->clients[s->matches[i].client_index]; + int left = s->clients_count; + for (int i = 0; i < JB_MAX_CLIENTS && left > 0; i++) { + if (s->clients[i].match_count <= 0) { + continue; + } + left--; + + struct jb_client *c = &s->clients[i]; + int match_left = c->match_count; + for (int i = 0; i < JB_MAX_MATCH && match_left > 0; i++) { + if (!c->matches[i]) { + continue; + } + + match_left--; + if (match_rule_check(c->matches[i], msg, ctx) >= 0) { uint8_t reply_data[4096]; memset(reply_data, 0, 4096); wire_context_t reply_ctx = { @@ -225,7 +242,7 @@ int jb_server_broadcast_message(struct jb_server *s, wire_message_t *msg, wire_c }; TRYST(wire_compose_unicast_reply(&reply_ctx, ctx, msg, sender_unique_name)); - TRYST(send(client->fd, reply_data, reply_ctx.byte_cursor, 0)); + TRYST(send(c->fd, reply_data, reply_ctx.byte_cursor, 0)); } } } @@ -419,7 +436,7 @@ int jb_server_client_process_message(struct jb_server *s, int i, uint8_t *data, return -1; } - TRYST(jb_server_match_add(s, match, i)); + TRYST(jb_server_client_match_add(s, i, match)); printf("client index %d just added match rule: '%s'\n", i, match); @@ -487,17 +504,9 @@ void jb_server_free(struct jb_server *s) { if (!s) return; if (s->sock_fd) close(s->sock_fd); - // names are allocated on the heap - for (int i = 0; i < JB_MAX_NAMES; i++) { - if (s->names[i].name) { - free(s->names[i].name); - } - } - // matches are allocated on the heap - for (int i = 0; i < JB_MAX_MATCH; i++) { - if (s->matches[i].rule) { - match_rule_free(s->matches[i].rule); - } + // freeing all clients will also free all matches and names + for (int i = 0; i < JB_MAX_CLIENTS; i++) { + jb_server_client_remove(s, i); } free(s); } @@ -538,9 +547,13 @@ struct jb_server *jb_server_create(const char *socket_path) s->clients[i].owned_name_index = -1; s->clients[i].unique_name_index = -1; s->clients[i].state = JB_CLIENT_STATE_NONE; + s->clients[i].match_count = 0; s->fds[i].fd = -1; s->fds[i].events = 0; s->fds[i].revents = 0; + for (int j = 0; j < JB_MAX_MATCH; j++) { + s->clients[i].matches[j] = NULL; + } } for (int i = 0; i < JB_MAX_NAMES; i++) { @@ -548,11 +561,7 @@ struct jb_server *jb_server_create(const char *socket_path) s->names[i].name = NULL; } s->names_count = 0; - - for (int i = 0; i < JB_MAX_MATCH; i++) { - s->matches[i].client_index = -1; - s->matches[i].rule = NULL; - } + s->clients_count = 0; s->fds[JB_MAX_CLIENTS].fd = s->sock_fd; s->fds[JB_MAX_CLIENTS].events = POLLIN; diff --git a/server.h b/server.h index a95817b..190579a 100644 --- a/server.h +++ b/server.h @@ -8,7 +8,7 @@ // TODO: dynamically size the arrays #define JB_MAX_CLIENTS 256 #define JB_MAX_NAMES 512 -#define JB_MAX_MATCH 512 +#define JB_MAX_MATCH 12 #define JB_BACKLOG 12 enum { @@ -23,6 +23,8 @@ struct jb_client { uint8_t state; int16_t unique_name_index; int16_t owned_name_index; + int8_t match_count; + match_rule_t *matches[JB_MAX_MATCH]; }; struct jb_name { @@ -30,19 +32,14 @@ struct jb_name { int32_t client_index; }; -struct jb_match { - match_rule_t *rule; - int32_t client_index; -}; - struct jb_server { int sock_fd; int fd_num; int names_count; + int clients_count; struct jb_client clients[JB_MAX_CLIENTS]; struct jb_name names[JB_MAX_NAMES]; struct pollfd fds[JB_MAX_CLIENTS + 1]; - struct jb_match matches[JB_MAX_MATCH]; };