| SD_VARLINK_REPLY_AND_UPGRADE(3) | sd_varlink_reply_and_upgrade | SD_VARLINK_REPLY_AND_UPGRADE(3) |
.SH "NAME" sd_varlink_reply_and_upgrade,
sd_varlink_respond_and_upgrade, sd_varlink_respond_and_upgradeb,
sd_varlink_respond_and_upgradebo, sd_varlink_bind_upgrade,
sd_varlink_upgrade_t - Reply to a Varlink method call and take over the
connection for a raw protocol
.SH "SYNOPSIS"
#include <systemd/sd-varlink.h>
typedef int (*sd_varlink_upgrade_t)(sd_varlink *link, int input_fd, int output_fd, void *userdata);
.HP 792u int
sd_varlink_reply_and_upgrade(sd_varlink *link,
sd_json_variant *parameters,
int *ret_input_fd,
int *ret_output_fd);
.HP 840u int
sd_varlink_respond_and_upgrade(sd_varlink *link,
sd_json_variant *parameters);
.HP 864u int
sd_varlink_respond_and_upgradeb(sd_varlink *link,
...);
.HP 888u int
sd_varlink_respond_and_upgradebo(sd_varlink *link,
...);
.HP 672u int
sd_varlink_bind_upgrade(sd_varlink *link,
sd_varlink_upgrade_t callback);
.SH "DESCRIPTION"
.PP These functions implement the server side of a Varlink protocol
upgrade. A Varlink client may request an upgrade when invoking a method
(see sd_varlink_call(3) and the SD_VARLINK_METHOD_UPGRADE flag
passed to method callbacks). If a method is invoked this way, the server may
send one final reply and then abandon the Varlink protocol on the connection
entirely, handing the underlying socket or pipe file descriptors back to the
caller so that an arbitrary, non-Varlink ("raw") protocol may be
spoken over them instead. This is useful for methods that negotiate a switch
to a streaming or binary protocol, in a manner similar to the Upgrade:
mechanism of HTTP.
.PP sd_varlink_reply_and_upgrade() sends a final reply to the
currently processed method call and then takes over the connection's file
descriptors synchronously. It takes the Varlink connection object, a
JSON object with the reply parameters (which may be NULL), and two
output pointers for the file descriptors. The parameters object is
validated against the method's declared reply signature, if known. The reply
is flushed to the connection before the file descriptors are returned, so
that the client has received the full reply before the caller starts
speaking the upgraded protocol. On success the connection is detached from
its event loop (if any) and disconnected, and ownership of the file
descriptors is transferred to the caller, which is responsible for
eventually closing them with close(2).
.PP The returned file descriptors are switched to blocking mode. For
bidirectional sockets a single underlying file descriptor carries both
directions; in this case ret_input_fd and ret_output_fd are
returned as two independent (duplicated) descriptors referring to the same
socket, so they may be closed separately. For transports backed by a pair of
pipes the two descriptors differ and refer to the distinct read and write
ends. Either ret_input_fd or ret_output_fd (but not both) may
be NULL; in that case the unwanted direction is shut down (if they
refer to the same socket, see shutdown(2)) or closed (if separate
file descriptors) rather than returned.
.PP Note that sd_varlink_reply_and_upgrade() blocks synchronously
until the reply has been flushed to the socket. A misbehaving or adversarial
client that stops reading could stall the caller. It should hence not be
used in servers that multiplex many Varlink connections in a single event
loop, as one stalled connection would block progress on all others. Use
sd_varlink_respond_and_upgrade() in that case instead.
.PP sd_varlink_respond_and_upgrade() is the asynchronous
counterpart of sd_varlink_reply_and_upgrade(). It enqueues the final
reply and returns immediately, without blocking and without returning the
file descriptors directly. The reply is subsequently flushed by the event
loop during regular sd_varlink_process(3) invocations. Once the reply
has been fully flushed, the connection's file descriptors are handed to the
upgrade callback previously registered with
sd_varlink_bind_upgrade(), and the Varlink connection is
disconnected. This variant is the right choice for servers that handle many
connections concurrently, as it never blocks on a single client.
.PP sd_varlink_respond_and_upgradeb() is similar to
sd_varlink_respond_and_upgrade(), but instead of expecting a fully
constructed sd_json_variant object carrying the reply parameters,
this object is constructed on-the-fly from the variadic argument list, in a
style identical to sd_json_build(3).
sd_varlink_respond_and_upgradebo() is identical to
sd_varlink_respond_and_upgradeb(), but an enclosing JSON object is
added implicitly, so that the argument list is expected to consist of object
field pairs only, in a style identical to sd_json_buildo(3).
.PP sd_varlink_bind_upgrade() registers the upgrade callback
that is invoked once a reply enqueued via
sd_varlink_respond_and_upgrade() (or one of its variants) has been
flushed to the connection. The callback is of type
sd_varlink_upgrade_t and receives the Varlink connection object, the
input and output file descriptors of the (now upgraded) connection, and the
userdata pointer associated with the connection (see
sd_varlink_set_userdata(3)). Ownership of the two file descriptors is
transferred to the callback (regardless if the callback later fails or not).
The descriptor semantics (blocking mode, duplication for bidirectional
sockets, distinct ends for pipe pairs) match those described for
sd_varlink_reply_and_upgrade() above. Passing NULL as
callback removes a previously registered callback.
.SH "RETURN VALUE"
.PP On success, sd_varlink_reply_and_upgrade(),
sd_varlink_respond_and_upgrade(),
sd_varlink_respond_and_upgradeb() and
sd_varlink_respond_and_upgradebo() return a positive integer.
sd_varlink_bind_upgrade() returns a non-negative integer on success.
On failure, they all return a negative errno-style error code.
.SS "Errors"
.PP Returned errors may indicate the following problems:
.PP -EINVAL
An argument is invalid.
.RE
.PP -ENOTCONN
The Varlink connection object is not connected.
.RE
.PP -EBUSY
The connection is not currently processing a method call, so there is no
reply to send. When returned by sd_varlink_bind_upgrade(), a
different upgrade callback was already registered on the connection.
.RE
.PP -EPROTO
The currently processed method call did not request a protocol upgrade, hence
the connection may not be taken over.
.RE
.PP -EBADMSG
The client sent unexpected data before the upgrade completed, i.e. it
pipelined raw protocol data before receiving the upgrade reply.
.RE
.PP -ENOMEM
Memory allocation failed.
.RE
.SH "NOTES"
.PP Functions described here are available as a shared library, which can be
compiled against and linked to with the
libsystemd pkg-config(1) file.
.PP The code described here uses getenv(3), which is declared to be
not multi-thread-safe. This means that the code calling the functions
described here must not call setenv(3) from a parallel thread. It is
recommended to only do calls to setenv() from an early phase of the
program when no other threads have been started.
.SH "HISTORY"
.PP sd_varlink_reply_and_upgrade() was added in version 261.
.PP sd_varlink_respond_and_upgrade(),
sd_varlink_respond_and_upgradeb(),
sd_varlink_respond_and_upgradebo() and
sd_varlink_bind_upgrade() were added in version 262.
.SH "SEE ALSO"
.PP systemd(1), sd-varlink(3), sd_varlink_reply(3),
sd_varlink_call(3), sd_varlink_call_and_upgrade(3),
sd_varlink_process(3), sd_varlink_set_userdata(3),
sd_json_build(3)
| systemd 262.2 |