From ac05b0c1571e517b53dee6a03ba6a58ab4b30f10 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 9 Nov 2017 18:46:52 +0100 Subject: Add echo control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- README | 17 +++++++++++++++++ sbusd.c | 21 +++++++++++++++++---- test.c | 1 + 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/README b/README index b538c68..5703c46 100644 --- a/README +++ b/README @@ -197,3 +197,20 @@ Flood control: If the client is blocking it is preferable that messages are sent in such order that memory is freed up as fast as possible. + +Echos: + By default, if a client sends a message with a routing key it is + subscribed to, that client will receive that message. The server + may however choose to implement control messages for selecting + whether this happens. Disabling echoing is useful for implementing + slave servers that only send messages upwords in the server + hierarchy when necessary. The control messages for controlling + echoing are + + ^CMSG echo/off\(\x00.*\)*$ + + Disable echoing. + + ^CMSG echo/on\(\x00.*\)*$ + + Reenable echoing. diff --git a/sbusd.c b/sbusd.c index 6f8ac2e..d60aaae 100644 --- a/sbusd.c +++ b/sbusd.c @@ -28,11 +28,16 @@ enum order { }; #define ORDER_RANDOM 2 +enum client_flags { + ECHO_OFF = 1 +}; + struct client { int fd; enum blocking_mode soft_blocking_mode; enum blocking_mode hard_blocking_mode; enum order order; + enum client_flags flags; char **subs; size_t nsubs; size_t subs_siz; @@ -49,6 +54,7 @@ static struct sockaddr_un addr; static uid_t *users; static size_t nusers = 0; static const char *pidfile = "/run/sbus.pid"; +static const char *credprefix = ""; static void usage(void) @@ -81,6 +87,7 @@ add_client(int fd) cl->soft_blocking_mode = BLOCKING_QUEUE; cl->hard_blocking_mode = BLOCKING_DISCARD; cl->order = ORDER_RANDOM_QUEUE; + cl->flags = 0; cl->subs = NULL; cl->nsubs = 0; cl->subs_siz = 0; @@ -121,7 +128,7 @@ static int is_subscription_acceptable(struct client *cl, const char *key) { if (!strncmp(key, "!/cred/", sizeof("!/cred/") - 1)) - return libsbusd_iscredok(cl->fd, key, ""); + return libsbusd_iscredok(cl->fd, key, credprefix); return 1; } @@ -195,7 +202,7 @@ handle_cmsg(struct client *cl, char *buf, size_t n) int r; if (!strcmp(buf, "CMSG !/cred/whoami")) { n = sizeof("CMSG !/cred/whoami"); - n += (size_t)(r = libsbusd_who(cl->fd, &buf[n], "")); + n += (size_t)(r = libsbusd_who(cl->fd, &buf[n], credprefix)); if (r < 0) { remove_client(cl); return; @@ -224,14 +231,20 @@ handle_cmsg(struct client *cl, char *buf, size_t n) cl->order = ORDER_STACK; } else if (!strcmp(buf, "CMSG order/random")) { cl->order |= ORDER_RANDOM; + } else if (!strcmp(buf, "CMSG echo/off")) { + cl->flags |= ECHO_OFF; + } else if (!strcmp(buf, "CMSG echo/on")) { + cl->flags &= ~ECHO_OFF; } } static void -broadcast(const char *msg, size_t n) +broadcast(const char *msg, size_t n, struct client *ignore) { struct client *cl = head.next, *tmp; for (; cl->next; cl = cl->next) { + if (cl == ignore) + continue; if (!libsbusd_issubed(cl->subs, cl->nsubs, &msg[4])) continue; if (send_packet(cl, msg, n)) { @@ -258,7 +271,7 @@ handle_message(struct client *cl) buf[r] = '\0'; if (!strncmp(buf, "MSG ", 4)) { - broadcast(buf, r); + broadcast(buf, r, (cl->flags & ECHO_OFF) ? cl : NULL); } else if (!strncmp(buf, "UNSUB ", 6)) { remove_subscription(cl, &buf[6]); } else if (!strncmp(buf, "SUB ", 4)) { diff --git a/test.c b/test.c index c2ba2a8..debd8a3 100644 --- a/test.c +++ b/test.c @@ -355,3 +355,4 @@ main(void) /* TODO untested sbusd flags: -p[/dev/null] (-f) -u */ /* TODO test credentials */ +/* TODO CMSG echo/{off,on} */ -- cgit v1.2.3-70-g09d2