You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GUACAMOLE-2281: Add generic req/done/cancel instructions to libguac.
Adds three new protocol instructions in libguac:
* "req" - id, name
* "done" - id, status
* "cancel" - id
"req" starts a typed request/response exchange with a correlation id
and a method name (by convention "<feature>.<verb>"). The peer settles
it with a "done" carrying the same id and a status, typically "ok",
"error", or "canceled". Either side can issue a "cancel" with the
matching id to abort an in-flight exchange.
The bodies of "req" and "done" ride a paired pipe whose name is the
correlation id and whose mimetype is GUAC_USER_RPC_PAYLOAD_MIMETYPE
("application/x-guacamole-rpc-payload"). libguac buffers the body
under that id and hands it to the user's req or done handler when the
matching instruction arrives. Only one body can be in flight per user;
senders should emit the pipe, its blobs, the end, and the trailing
req or done back to back. The body is capped at
GUAC_USER_MAX_RPC_BODY_LENGTH (64 KiB).
All three send functions take guac_user, so each RPC exchange targets
one specific user rather than broadcasting via the client socket. This
avoids the N-done-per-req problem in shared sessions where every
joined user would otherwise receive the same req.
API surface:
* guac_protocol_send_req(user, id, name, body, body_len) and
guac_protocol_send_done(user, id, status, body, body_len) in
protocol.h / protocol.c. Each allocates a stream against the user,
ships the body over the paired pipe via user->socket, then sends
the trailing instruction. Body may be NULL with body_len 0.
* guac_protocol_send_cancel(user, id) for the abort case.
* guac_user_req_handler, guac_user_done_handler, and
guac_user_cancel_handler typedefs in user-fntypes.h. req and done
handlers receive the assembled body via (void* body, int body_len),
owned by libguac and valid only during the call.
* req_handler, done_handler, and cancel_handler callback fields on
guac_user in user.h.
* __guac_handle_req, __guac_handle_done, and __guac_handle_cancel
dispatchers in user-handlers.c, registered in the instruction
handler map. __guac_handle_pipe intercepts the reserved mimetype
and assembles the body into per-user pending fields.
Also adds an optional destructor callback on guac_stream, called from
guac_user_free_stream and guac_client_free_stream, and from
guac_user_free and guac_client_free for any streams still open at
disconnect. The RPC body assembly installs the destructor when it
allocates, so an in-progress body that never reaches end is freed at
disconnect. Existing handlers are unaffected since the field defaults
to NULL.
The instructions carry no feature-specific semantics. The first
consumer is WebAuthn passthrough using "webauthn.create" and
"webauthn.get"; other RPC-style features can reuse the same plumbing.
0 commit comments