store match rules per client
This commit is contained in:
parent
2a07d8dd38
commit
0d5385f295
3 changed files with 53 additions and 46 deletions
1
match.c
1
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++) {
|
||||
|
|
87
server.c
87
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;
|
||||
|
|
11
server.h
11
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];
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue