store match rules per client

This commit is contained in:
hippoz 2022-12-31 17:55:32 +02:00
parent 2a07d8dd38
commit 0d5385f295
Signed by: hippoz
GPG key ID: 56C4E02A85F2FBED
3 changed files with 53 additions and 46 deletions

View file

@ -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]; wire_message_body_string_t strings[MATCH_RULE_MAX_ARG];
memset(strings, 0, sizeof(strings)); memset(strings, 0, sizeof(strings));
/* TODO: handle failure */
TRYST(wire_collect_strings(ctx, msg, strings, MATCH_RULE_MAX_ARG)); TRYST(wire_collect_strings(ctx, msg, strings, MATCH_RULE_MAX_ARG));
for (int i = 0; i < MATCH_RULE_MAX_ARG; i++) { for (int i = 0; i < MATCH_RULE_MAX_ARG; i++) {

View file

@ -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->clients[i].state = JB_CLIENT_STATE_WAIT_AUTH;
s->fds[i].fd = fd; s->fds[i].fd = fd;
s->fds[i].events = POLLIN; s->fds[i].events = POLLIN;
s->clients_count++;
return i; return i;
} }
} }
@ -93,12 +94,14 @@ int jb_server_name_add(struct jb_server *s, char *name, int client_index)
return -1; 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++) { for (int i = 0; i < JB_MAX_MATCH; i++) {
if (s->matches[i].client_index < 0) { if (!c->matches[i]) {
s->matches[i].rule = match_rule_from_string(match); c->matches[i] = match_rule_from_string(match);
s->matches[i].client_index = client_index; c->match_count++;
return 0; 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) void jb_server_client_remove(struct jb_server *s, int i)
{ {
if (s->clients[i].fd >= 0) { struct jb_client *c = &s->clients[i];
close(s->clients[i].fd);
if (c->fd >= 0) {
close(c->fd);
} }
// TODO: slow
for (int i = 0; i < JB_MAX_MATCH; i++) { for (int i = 0; i < JB_MAX_MATCH; i++) {
if (s->matches[i].client_index == i) { if (c->matches[i]) {
s->matches[i].client_index = -1; match_rule_free(c->matches[i]);
match_rule_free(s->matches[i].rule); c->matches[i] = NULL;
s->matches[i].rule = NULL;
} }
} }
jb_server_name_remove(s, s->clients[i].unique_name_index); jb_server_name_remove(s, c->unique_name_index);
jb_server_name_remove(s, s->clients[i].owned_name_index); jb_server_name_remove(s, c->owned_name_index);
s->clients[i].unique_name_index = -1; c->unique_name_index = -1;
s->clients[i].owned_name_index = -1; c->owned_name_index = -1;
s->clients[i].fd = -1; c->match_count = 0;
s->clients[i].state = JB_CLIENT_STATE_NONE; c->fd = -1;
c->state = JB_CLIENT_STATE_NONE;
s->fds[i].fd = -1; s->fds[i].fd = -1;
s->fds[i].events = 0; s->fds[i].events = 0;
s->fds[i].revents = 0; s->fds[i].revents = 0;
s->clients_count--;
} }
void jb_server_client_error(struct jb_server *s, int i, const char *msg) 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) 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++) { int left = s->clients_count;
if (s->matches[i].rule) { for (int i = 0; i < JB_MAX_CLIENTS && left > 0; i++) {
if (match_rule_check(s->matches[i].rule, msg, ctx) >= 0) { if (s->clients[i].match_count <= 0) {
struct jb_client *client = &s->clients[s->matches[i].client_index]; 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]; uint8_t reply_data[4096];
memset(reply_data, 0, 4096); memset(reply_data, 0, 4096);
wire_context_t reply_ctx = { 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(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; 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); 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) return;
if (s->sock_fd) close(s->sock_fd); if (s->sock_fd) close(s->sock_fd);
// names are allocated on the heap // freeing all clients will also free all matches and names
for (int i = 0; i < JB_MAX_NAMES; i++) { for (int i = 0; i < JB_MAX_CLIENTS; i++) {
if (s->names[i].name) { jb_server_client_remove(s, i);
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);
}
} }
free(s); 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].owned_name_index = -1;
s->clients[i].unique_name_index = -1; s->clients[i].unique_name_index = -1;
s->clients[i].state = JB_CLIENT_STATE_NONE; s->clients[i].state = JB_CLIENT_STATE_NONE;
s->clients[i].match_count = 0;
s->fds[i].fd = -1; s->fds[i].fd = -1;
s->fds[i].events = 0; s->fds[i].events = 0;
s->fds[i].revents = 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++) { 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[i].name = NULL;
} }
s->names_count = 0; s->names_count = 0;
s->clients_count = 0;
for (int i = 0; i < JB_MAX_MATCH; i++) {
s->matches[i].client_index = -1;
s->matches[i].rule = NULL;
}
s->fds[JB_MAX_CLIENTS].fd = s->sock_fd; s->fds[JB_MAX_CLIENTS].fd = s->sock_fd;
s->fds[JB_MAX_CLIENTS].events = POLLIN; s->fds[JB_MAX_CLIENTS].events = POLLIN;

View file

@ -8,7 +8,7 @@
// TODO: dynamically size the arrays // TODO: dynamically size the arrays
#define JB_MAX_CLIENTS 256 #define JB_MAX_CLIENTS 256
#define JB_MAX_NAMES 512 #define JB_MAX_NAMES 512
#define JB_MAX_MATCH 512 #define JB_MAX_MATCH 12
#define JB_BACKLOG 12 #define JB_BACKLOG 12
enum { enum {
@ -23,6 +23,8 @@ struct jb_client {
uint8_t state; uint8_t state;
int16_t unique_name_index; int16_t unique_name_index;
int16_t owned_name_index; int16_t owned_name_index;
int8_t match_count;
match_rule_t *matches[JB_MAX_MATCH];
}; };
struct jb_name { struct jb_name {
@ -30,19 +32,14 @@ struct jb_name {
int32_t client_index; int32_t client_index;
}; };
struct jb_match {
match_rule_t *rule;
int32_t client_index;
};
struct jb_server { struct jb_server {
int sock_fd; int sock_fd;
int fd_num; int fd_num;
int names_count; int names_count;
int clients_count;
struct jb_client clients[JB_MAX_CLIENTS]; struct jb_client clients[JB_MAX_CLIENTS];
struct jb_name names[JB_MAX_NAMES]; struct jb_name names[JB_MAX_NAMES];
struct pollfd fds[JB_MAX_CLIENTS + 1]; struct pollfd fds[JB_MAX_CLIENTS + 1];
struct jb_match matches[JB_MAX_MATCH];
}; };