aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-10-24 18:36:51 +0200
committerMattias Andrée <maandree@kth.se>2017-10-24 18:36:51 +0200
commit9d1cde47a22d3f43e07a807d6dd183d3f768137d (patch)
treeb50b050446c50d793137eabacdf63f874735fd33
parentUse / instead of . (diff)
downloadsbus-9d1cde47a22d3f43e07a807d6dd183d3f768137d.tar.gz
sbus-9d1cde47a22d3f43e07a807d6dd183d3f768137d.tar.bz2
sbus-9d1cde47a22d3f43e07a807d6dd183d3f768137d.tar.xz
Add contol messages for flood control
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--README59
-rw-r--r--sbusd.c43
-rw-r--r--test.c1
3 files changed, 102 insertions, 1 deletions
diff --git a/README b/README
index eef3a3d..2fe8419 100644
--- a/README
+++ b/README
@@ -133,3 +133,62 @@ Secret messages:
B: Send B's credentials with routing key private to A.
A: Send a random message with routing key private to B.
B: Send back the message with routing key private to A.
+
+Flood control:
+ The following control messages can be sent to the server to
+ choose the server behaviour when messages cannot be delivered
+ without blocking. All control messages are optional and server
+ may choose to ignore them at any time, even if previously
+ honoured. Most recently sent control message that precedence.
+
+ ^CMSG blocking/soft/queue\(\x00.*\)*$
+
+ Delivering is preferable, the server should queue up
+ message that cannot be sent.
+
+ ^CMSG blocking/soft/discard\(\x00.*\)*$
+
+ Delivering is unimportant, the server should discard
+ message that cannot be sent.
+
+ ^CMSG blocking/soft/block\(\x00.*\)*$
+
+ Delivering is important, the server may block communication
+ to guarantee that messages are delivered.
+
+ ^CMSG blocking/soft/error\(\x00.*\)*$
+
+ The server may treat a client as misbehaving if message
+ cannot be sent.
+
+ ^CMSG blocking/hard/discard\(\x00.*\)*$
+
+ If the server has queued up too many message it should
+ start discarding new message instead of queuing them.
+
+ ^CMSG blocking/hard/block\(\x00.*\)*$
+
+ If the server has queued up too many message it should
+ start blocking communication until it can start queuing
+ messages again.
+
+ ^CMSG blocking/hard/error\(\x00.*\)*$
+
+ If the server has queued up too many message it should
+ start treating clients that are blocking as misbehaving.
+
+ ^CMSG order/queue\(\x00.*\)*$
+
+ If the client is blocking it is preferable that messages
+ are sent in order.
+
+ ^CMSG order/stack\(\x00.*\)*$
+
+ If the client is blocking it is preferable that messages
+ are sent in reverse order.
+
+ ^CMSG order/random\(\x00.*\)*$
+
+ If the client is blocking it is preferable that messages
+ are sent in such order that memory is freed up as fast
+ as possible.
diff --git a/sbusd.c b/sbusd.c
index 6a4e717..e2f3005 100644
--- a/sbusd.c
+++ b/sbusd.c
@@ -24,8 +24,26 @@
#define STYPE_MAX(T) (long long int)((1ULL << (8 * sizeof(T) - 1)) - 1)
#define eprintf(...) (weprintf(__VA_ARGS__), exit(1))
+enum blocking_mode {
+ BLOCKING_QUEUE,
+ BLOCKING_DISCARD,
+ BLOCKING_BLOCK,
+ BLOCKING_ERROR
+};
+
+enum order {
+ ORDER_QUEUE = 0,
+ ORDER_STACK = 1,
+ ORDER_RANDOM_QUEUE = 2,
+ ORDER_RANDOM_STACK = 3,
+};
+#define ORDER_RANDOM 2
+
struct client {
int fd;
+ enum blocking_mode soft_blocking_mode;
+ enum blocking_mode hard_blocking_mode;
+ enum order order;
char **subs;
size_t nsubs;
size_t subs_siz;
@@ -84,6 +102,9 @@ add_client(int fd)
if (!cl)
return NULL;
cl->fd = fd;
+ cl->soft_blocking_mode = BLOCKING_QUEUE;
+ cl->hard_blocking_mode = BLOCKING_DISCARD;
+ cl->order = ORDER_RANDOM_QUEUE;
cl->subs = NULL;
cl->nsubs = 0;
cl->subs_siz = 0;
@@ -266,7 +287,7 @@ remove_subscription(struct client *cl, const char *key)
static int
send_packet(struct client *cl, const char *buf, size_t n)
{
- /* TODO queue instead of block */
+ /* TODO honour cl->soft_blocking_mode, cl->hard_blocking_mode, and cl->order */
return -(send(cl->fd, buf, n, 0) < 0);
}
@@ -275,6 +296,26 @@ handle_cmsg(struct client *cl, const char *msg, size_t n)
{
if (!strcmp(msg, "CMSG !/cred/prefix")) {
n = sizeof("CMSG !/cred/prefix");
+ } else if (!strcmp(msg, "CMSG blocking/soft/queue")) {
+ cl->soft_blocking_mode = BLOCKING_QUEUE;
+ } else if (!strcmp(msg, "CMSG blocking/soft/discard")) {
+ cl->soft_blocking_mode = BLOCKING_DISCARD;
+ } else if (!strcmp(msg, "CMSG blocking/soft/block")) {
+ cl->soft_blocking_mode = BLOCKING_BLOCK;
+ } else if (!strcmp(msg, "CMSG blocking/soft/error")) {
+ cl->soft_blocking_mode = BLOCKING_ERROR;
+ } else if (!strcmp(msg, "CMSG blocking/hard/discard")) {
+ cl->hard_blocking_mode = BLOCKING_DISCARD;
+ } else if (!strcmp(msg, "CMSG blocking/hard/block")) {
+ cl->hard_blocking_mode = BLOCKING_BLOCK;
+ } else if (!strcmp(msg, "CMSG blocking/hard/error")) {
+ cl->hard_blocking_mode = BLOCKING_ERROR;
+ } else if (!strcmp(msg, "CMSG order/queue")) {
+ cl->order = ORDER_QUEUE;
+ } else if (!strcmp(msg, "CMSG order/stack")) {
+ cl->order = ORDER_STACK;
+ } else if (!strcmp(msg, "CMSG order/random")) {
+ cl->order |= ORDER_RANDOM;
} else {
return;
}
diff --git a/test.c b/test.c
index c2ba2a8..daaec35 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 test CMSG server */