From bf2a39b4012f4efaff88cb701b35a845179681e3 Mon Sep 17 00:00:00 2001 From: Michael Pfeifroth Date: Fri, 7 Aug 2026 11:24:33 +0200 Subject: [PATCH] session: make rpc_session_get() a pure lookup and add "notouch" to session/access The rpcd session idle timer (sessiontime) is meant to expire a session after N seconds of inactivity, but it is currently refreshed by every "session get" and "session access" ubus call, and by every RPC in every loadable plugin (uci, luci-rpc, ...) that calls rpc_session_access() to verify permissions. Because LuCI polls its status pages every few seconds, the timer is refreshed continuously and never expires: the "idle timeout" behaves as an absolute session lifetime instead. Split the two concerns: * rpc_session_get() becomes a pure AVL lookup with no side effects. All internal lookups (uci/luci-rpc permission checks, session data accessors, etc.) no longer keep the session alive on their own. * The top-level session/access ubus method is the only path that still touches the session, and it does so only when the new optional "notouch" boolean argument is absent or false. Callers that want to distinguish real user activity from background polling (uhttpd's /ubus/ handler when it sees LuCI's _luci_bg=1 marker) pass notouch=1 and the timer keeps counting down. The rpcd HTTP entry point (uhttpd) already invokes session/access on every request to authorise the call, so it stays the single natural "keep alive" signal for the session -- exactly what an idle timeout needs -- without duplicating touches from every downstream plugin. The "notouch" argument is optional and defaults to false, so existing callers see no behaviour change. Signed-off-by: Michael Pfeifroth --- session.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/session.c b/session.c index 2dbc13b099..858f1acd07 100644 --- a/session.c +++ b/session.c @@ -93,6 +93,7 @@ enum { RPC_SP_SCOPE, RPC_SP_OBJECT, RPC_SP_FUNCTION, + RPC_SP_NOTOUCH, __RPC_SP_MAX, }; static const struct blobmsg_policy perm_policy[__RPC_SP_MAX] = { @@ -100,6 +101,7 @@ static const struct blobmsg_policy perm_policy[__RPC_SP_MAX] = { [RPC_SP_SCOPE] = { .name = "scope", .type = BLOBMSG_TYPE_STRING }, [RPC_SP_OBJECT] = { .name = "object", .type = BLOBMSG_TYPE_STRING }, [RPC_SP_FUNCTION] = { .name = "function", .type = BLOBMSG_TYPE_STRING }, + [RPC_SP_NOTOUCH] = { .name = "notouch", .type = BLOBMSG_TYPE_BOOL }, }; enum { @@ -373,7 +375,6 @@ rpc_session_get(const char *id) if (!ses) return NULL; - rpc_touch_session(ses); return ses; } @@ -630,6 +631,9 @@ rpc_handle_access(struct ubus_context *ctx, struct ubus_object *obj, if (!ses) return UBUS_STATUS_NOT_FOUND; + if (!tb[RPC_SP_NOTOUCH] || !blobmsg_get_bool(tb[RPC_SP_NOTOUCH])) + rpc_touch_session(ses); + blob_buf_init(&buf, 0); if (tb[RPC_SP_OBJECT] && tb[RPC_SP_FUNCTION])