aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-11-09 18:46:52 +0100
committerMattias Andrée <maandree@kth.se>2017-11-09 18:46:52 +0100
commitac05b0c1571e517b53dee6a03ba6a58ab4b30f10 (patch)
tree99cb5780ee9d9aa0d7a36d35d10aa06ed226bca5
parentUpdate makefile (diff)
downloadsbus-ac05b0c1571e517b53dee6a03ba6a58ab4b30f10.tar.gz
sbus-ac05b0c1571e517b53dee6a03ba6a58ab4b30f10.tar.bz2
sbus-ac05b0c1571e517b53dee6a03ba6a58ab4b30f10.tar.xz
Add echo control
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--README17
-rw-r--r--sbusd.c21
-rw-r--r--test.c1
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} */