feat: add CLM request for channel level list (message ID 1025) - #3725
feat: add CLM request for channel level list (message ID 1025)#3725mcfnord wants to merge 6 commits into
Conversation
Adds PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST (1028): a connectionless request that causes the server to immediately reply with the existing PROTMESSID_CLM_CHANNEL_LEVEL_LIST (1015) response. This follows the established CLM request/response pattern used by CLReqConnClientsList (1014 → 1013), CLReqVersionAndOS (1012 → 1011), and CLReqServerList (1007 → 1002). The implementation is zero-cost: vecChannelLevels is already computed every server tick in OnTimer(). The handler simply forwards that existing data to the requesting address. Use case: external monitors can poll silence/activity level on any Jamulus server by sending a single UDP datagram to the server's game port, without establishing an audio connection or requiring additional open ports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Yes, much better! |
|
It says there are branch conflicts that must be resolved, and it says there's a C-like coding style failure. I can try to fix those if it's inherently a PR you'd merge. I've found a strong case for the feature, but I plan to try accomplishing similar results on a very lean use of message 28, as recommended here but drawing criticism here. |
|
If the usecase is beneficial and a simple approach, it would not be rejected by me. However, you want to detect bots/listeners? Then please make clear why you need this. Do we want the client to mark those clients? Does it have any information leakage/privacy concerns? |
Yes, I want to identify silent connections. Maybe it's a listener, maybe it's a bot that doesn't actually listen, but the thing important to me is: it's not a signal in the sense that we, an audio platform, think about signals. I use this data in an immediate sense, where it detects someone who maybe has stayed connected while walking away for a while, and also in a long-term sense where I can determine that account xyz is always silent and might not be an active musician (so a perma-listener or a bot).
Maybe! https://jamulus.live marks server cards with the "no sound" emoji (🔇) when I determine that every connection on the server is silent. This would be a helpful navigation aide in the Connection dialog. It could be per-connection, although that seems overwhelming. So maybe it just shows that the whole server is silent at the moment. Notice how people roam around looking for activity... they end up popping in on small groups or singletons to determine if they're active connections. With the "no sound" emoji, I can look at 5 small groups on 5 servers, and see that one is actually making sound. This directs users to the active connection. If the Jamulus client indicated silence this way, it would have the same beneficial effect on navigation.
I can't think of any. It's just a bit, silent or not-silent. Doesn't present an audio sample or additional metadata. It reveals "level of audio" which might have some application somehow, but I can't think of a malicious use for that detail. I have added this feature to my own server binary and deployed it to about 20 Jamulus servers. I also get the same information through existing connected lounge lobby bots (mostly Thailand). It provides a helpful clue that the server is silent. |
Not always a beneficial impact, to be fair. Five drummers, four bass players, three guitarists, flute, violin, tabor and harp - and still no singer... They may not be silent but they'd probably make a better stab at fun if they split up a bit. In my view. |
|
I also thought about having a bot instrument... (I know it's only partly related) |
|
This would be cool, let's merge this. |
| #define PROTMESSID_CLM_REGISTER_SERVER_RESP 1016 // status of server registration request | ||
| #define PROTMESSID_CLM_REGISTER_SERVER_EX 1017 // register server with extended information | ||
| #define PROTMESSID_CLM_RED_SERVER_LIST 1018 // reduced server list | ||
| #define PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST 1028 // request channel level list (connectionless) |
There was a problem hiding this comment.
It's a bit weird to have a jump to 1028 here.
There was a problem hiding this comment.
Agreed -- next sequential is 1023 and should be added sequentially.
There was a problem hiding this comment.
🤖 AI: I figured if the connected-mode message is 28, then the connectionless one could be 1028. But 1025 is alright, too. Not 1023, though: #3636 already takes 1023 for PROTMESSID_CLM_TCP_OFFERED and 1024 for PROTMESSID_CLM_CLIENT_ID, so 1025 is the next one actually free.
1023 and 1024 are taken by the open TCP PR jamulussoftware#3636 (PROTMESSID_CLM_TCP_OFFERED, PROTMESSID_CLM_CLIENT_ID), so 1025 is the lowest CLM ID free on main and unclaimed by any open PR. The define also moves to the end of the CLM block so the list stays in numeric order. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019KZHjFTo73t39UURauvXvg
Every other connectionless message has an entry in the protocol documentation block at the top of protocol.cpp; this one did not. The entry follows the PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST form: no payload, plus the one line of behaviour the handler implements (one PROTMESSID_CLM_CHANNEL_LEVEL_LIST back to the requesting address). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019KZHjFTo73t39UURauvXvg
|
Actually - after thinking a bit more, I think that we should allow the server admin disable this and expose via the server capabilities if this feature is enabled/disabled for privacy reasons. Default enabled. Maybe with --blacklist-messages/--blacklist-features '' which can then be extended in future? |
I second that. Furthermore I'd like to repeat that we might want to log requests like this so admins can monitor activity on their servers and decide whether to block or allow such traffic. |
…ing the #define order Review asked that the new message keep the same position as its #define (the last entry in the CLM block) everywhere it appears, and that the connect() block in server.cpp keep one blank line between entries. This moves the Evaluate declaration and the signal in protocol.h, the switch case and the Evaluate definition in protocol.cpp, the connect() in server.cpp, and the slot in server.h to follow the PROTMESSID_CLM_REQ_WELCOME_MESSAGE entry in each block. No behaviour change: a headless build of this commit answers a 1025 request with one 1015 reply and still answers 1014 with 1013. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8KACM96jgMTGCLbqqta9Z
|
🤖 AI: @ann0see — the control belongs with the user, not the operator. An operator who wants to refuse this traffic already has the right layer for it — the kernel: firewall and packet filtering, outside the application, where a host's policy over its own machine sits. A So the gate, if there is one, is a client checkbox: the user opts out, the client carries the choice, the server honors it in the level reply — the decision staying with the person the signal describes. It also scopes cleanly. This is a separate feature from the request itself, which stays as it is. |
Yes - but the privacy implications should be solved before this gets merged. |
|
In your view, does unregulated disclosure of name/instrument/nation present the same concerns? |
|
No since the user sets them willingly or not. |
|
Server side blocking is easier. This I proposed this. |
I totally disagree here. In my perception internal data mustn't be shared. I still don't like this feature and I think we shouldn't merge this at all because it is actually not even a Jamulus feature. It's a third-party app feature. |
Yes. One could imagine that it's possible to infer parts of conversations or similar from it. If that's possible, users would never know that this happened.
Yes. But we should still be somewhat nice to external apps. A human - be it the server admin or enduser should be able to decide what kind of data he/she shares -> needs blacklisting or whitelisting. |
|
It should be a Jamulus feature. A silent gathering should show it's silent. |
I think this is an important point. I was against opening up Jamulus to JSON-RPC on this basis. It was, eventually, agreed that Jamulus itself would only support exposing the current state of the Client and the Server locally via JSON-RPC. (This still doesn't protect a Client user from having information exposed without their knowledge, of course, and the Server operator can then expose everything if they proxy the information out to the wider internet by whatever means.) Of course, it's always been possible to request information about Servers and Clients using the existing (connectionless) protocol messages - but these are the same ones, exposing the same information, as expose that information to all Jamulus users. We recently added the welcome message connectionless request, information which previously required a connection. I can see the use of it. It seems harmless enough... ...But it then does open up the floor to requests for other state information to be passed to unknown remote servers without Client or Server operator intervention, that Client users currently think of as known only to others within the session they're connected to. Is it a line that should be held or crossed? ("Ghost probes" can, of course, already retrieve any connected information -- if there is a slot available on the Server. That was why the welcome message request was allowed. It appeared to be a legitimate need to retrieve information about the Server itself, rather than connection-oriented session state.) |
|
@mcfnord. Please exactly describe which problem you want to solve then on your app. Is it finding servers which are just silent such that you can hide them? |
|
I mean, we could add "minutes since overall server sound level went above -48dB" to the connect dialog. That's enough to tell if the server is silent without publishing every Client level (and needing to sample it frequently to have it make any sense). (A tiny thread similar to the recorder could take a push of the levels, do the maths and signal back the sum every so often. Clients with an extended server list poll could have this included... we do need a more extensible format... let's switch to a JSON blob.) |
🤖 AI: Adds
PROTMESSID_CLM_REQ_CHANNEL_LEVEL_LIST(ID 1025): a new connectionless message that causes a server to immediately reply with the existingPROTMESSID_CLM_CHANNEL_LEVEL_LIST(ID 1015) response.This follows the established CLM request/response pattern used by:
CLReqConnClientsList(1014) →CLConnClientsList(1013)CLReqVersionAndOS(1012) →CLVersionAndOS(1011)CLReqServerList(1007) →CLRedServerList(1018) andCLServerList(1006)Numbered 1025: the CLM block runs 1001 to 1022 with no gaps, and 1023 and 1024 are taken by #3636.
The name is not new. The protocol documentation in
protocol.cpphas referred toPROTMESSID_CLM_REQ_CHANNEL_LEVEL_LISTsince a7a1549 (2020), at lines 437 and 440, for a message that was never defined. Message 28 is its connected-mode counterpart:CClient::OnNewConnectionstill sends it, and it is kept only for servers 3.4.6 to 3.5.12.Implementation
4 files, 28 lines:
protocol.h— define ID 1025, declare evaluator, declare signalprotocol.cpp— document the message in the reference block, add switch case, and one-lineEvaluateCLReqChannelLevelListMesthat emits the signalserver.h— one-lineOnCLReqChannelLevelListslot that calls the existingCreateCLChannelLevelListMesserver.cpp— connect signal to slotZero additional computation.
vecChannelLevelsis already computed every server tick inOnTimer(). The handler simply forwards that existing data to the requester.Use case
A monitoring tool can poll the activity level on any Jamulus server by sending a single UDP datagram to the server's game port and reading the nibble-packed level list in the 1015 response. No audio connection, no additional open ports, no configuration required.
The 1015 response already encodes the number of connected clients implicitly (the list length), so the caller can detect idle servers (no clients) versus quiet ones (clients present but all levels ≤ threshold).
Relation to prior PR
This supersedes #3724.
🤖 This message was written by AI and reviewed by @mcfnord.