Fix idle spin on client (excessive CPU usage while panel is polling)

This commit is contained in:
mueller_minki
2026-10-04 10:36:03 +02:00
parent 8e83a98ef4
commit 797558ab80

View File

@@ -77,12 +77,14 @@ static char token[PB_TOKEN_LEN + 1];
static int hub_port; static int hub_port;
static int hello_done; static int hello_done;
static long last_svc, last_retry; static long last_svc, last_retry;
static long ctl_last_rx; // last control data; the hub PINGs every 30 s
static volatile sig_atomic_t sig_stop; static volatile sig_atomic_t sig_stop;
#define BUF_LIMIT (256 * 1024) #define BUF_LIMIT (256 * 1024)
#define UDP_IDLE 120 #define UDP_IDLE 120
#define READ_CHUNK 65536 #define READ_CHUNK 65536
#define CTL_TIMEOUT 90
static long now_s(void) static long now_s(void)
{ {
@@ -687,8 +689,14 @@ static int process_ctl_input(void)
{ {
char line[PB_MAX_LINE]; char line[PB_MAX_LINE];
int rc; int rc;
if (ctl && ctl->from_ch.len)
ctl_last_rx = now_s();
while (ctl && (rc = line_next(&ctl->from_ch, line, sizeof(line))) == 1) while (ctl && (rc = line_next(&ctl->from_ch, line, sizeof(line))) == 1)
ctl_line(line); ctl_line(line);
if (now_s() - ctl_last_rx > CTL_TIMEOUT) {
log_warn("no data from target for %d s", CTL_TIMEOUT);
return -1;
}
if (ctl && ctl->ch_eof) { if (ctl && ctl->ch_eof) {
log_warn("control channel closed by target"); log_warn("control channel closed by target");
return -1; return -1;
@@ -861,7 +869,10 @@ static int session_open(void)
ctl->ch = ch; ctl->ch = ch;
ctl->state = S_ACTIVE; ctl->state = S_ACTIVE;
libssh2_keepalive_config(sess, 1, 30); // No reply requested: replies are never read and would pile up in
// libssh2's packet queue. Liveness comes from the hub's PINGs instead.
libssh2_keepalive_config(sess, 0, 30);
ctl_last_rx = now_s();
libssh2_session_set_blocking(sess, 0); libssh2_session_set_blocking(sess, 0);
log_info("connected to %s:%d as %s", cfg->target_host, cfg->target_port, cfg->ssh_user); log_info("connected to %s:%d as %s", cfg->target_host, cfg->target_port, cfg->ssh_user);
return 0; return 0;
@@ -921,10 +932,12 @@ static int ssh_pass(int *data)
} }
// True if libssh2 already holds decrypted data for a channel we can accept. // True if libssh2 already holds decrypted data for a channel we can accept.
// libssh2_poll_channel_read() returns a negative error for short packets in
// the queue, so only 1 counts.
static int ssh_buffered(void) static int ssh_buffered(void)
{ {
for (struct cc *c = ccs; c; c = c->next) for (struct cc *c = ccs; c; c = c->next)
if (c->state == S_ACTIVE && c->ch && c->from_ch.len < BUF_LIMIT && libssh2_poll_channel_read(c->ch, 0)) if (c->state == S_ACTIVE && c->ch && c->from_ch.len < BUF_LIMIT && libssh2_poll_channel_read(c->ch, 0) == 1)
return 1; return 1;
return 0; return 0;
} }