summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2022-12-10 17:32:42 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2022-12-10 17:32:42 +0100
commit4c19a8a984c39c7269cf497808735f147243800b (patch)
tree62ae5d14b3225a8366b62d8451c1b55a27aa5986 /sysdep
parent1124f39f731610687eb8fdd6d7079c20063809c1 (diff)
CLI: Fix for long-lived sessions during high loads
When there is a continuos stream of CLI commands, cli_get_command() always returns 1 (there is a new command). Anyway, the socket receive buffer was reset only when there was no command at all, leading to a strange behavior: after a while, the CLI receive buffer came to its end, then read() was called with zero size buffer, it returned 0 which was interpreted as EOF. The patch fixes that by resetting the buffer position after each command and moving remaining data at the beginning of buffer. Thanks to Maria Matejka for examining the bug and for the original bugfix.
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/unix/main.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index 18fd4e44..627d7a4a 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -441,7 +441,7 @@ int
cli_get_command(cli *c)
{
sock *s = c->priv;
- byte *t = c->rx_aux ? : s->rbuf;
+ byte *t = s->rbuf;
byte *tend = s->rpos;
byte *d = c->rx_pos;
byte *dend = c->rx_buf + CLI_RX_BUF_SIZE - 2;
@@ -452,16 +452,22 @@ cli_get_command(cli *c)
t++;
else if (*t == '\n')
{
+ *d = 0;
t++;
+
+ /* Move remaining data and reset pointers */
+ uint rest = (t < tend) ? (tend - t) : 0;
+ memmove(s->rbuf, t, rest);
+ s->rpos = s->rbuf + rest;
c->rx_pos = c->rx_buf;
- c->rx_aux = t;
- *d = 0;
+
return (d < dend) ? 1 : -1;
}
else if (d < dend)
*d++ = *t++;
}
- c->rx_aux = s->rpos = s->rbuf;
+
+ s->rpos = s->rbuf;
c->rx_pos = d;
return 0;
}
@@ -508,7 +514,6 @@ cli_connect(sock *s, uint size UNUSED)
s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */
s->fast_rx = 1;
c->rx_pos = c->rx_buf;
- c->rx_aux = NULL;
rmove(s, c->pool);
return 1;
}