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 instructions to libguac.
Adds two new protocol instructions in libguac:
* "req" - id, name
* "done" - id, status
"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"
or "error".
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).
Both 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_user_req_handler and guac_user_done_handler typedefs in
user-fntypes.h. Both handlers receive the assembled body via
(void* body, int body_len), owned by libguac and valid only during
the call.
* req_handler and done_handler callback fields on guac_user in
user.h.
* __guac_handle_req and __guac_handle_done 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.
Unit tests cover the wire format for send_req and send_done, dispatch
of inbound req and done, the single-slot pending semantics
(end_handler drop-and-replace, req without preceding pipe), and the
new stream destructor (per-free-stream, disconnect-cleanup, opt-in
no-op when unset, and the regression case where __init_input_stream
must reset destructor on slot reuse).
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