1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 /* A minimal Varlink implementation. We only implement the minimal, obvious bits here though. No validation,
10 * no introspection, no name service, just the stuff actually needed.
12 * You might wonder why we aren't using libvarlink here? Varlink is a very simple protocol, which allows us
13 * to write our own implementation relatively easily. However, the main reasons are these:
15 * • We want to use our own JSON subsystem, with all the benefits that brings (i.e. accurate unsigned+signed
16 * 64bit integers, full fuzzing, logging during parsing and so on). If we'd want to use that with
17 * libvarlink we'd have to serialize and deserialize all the time from its own representation which is
18 * inefficient and nasty.
20 * • We want integration into sd-event, but also synchronous event-loop-less operation
22 * • We need proper per-UID accounting and access control, since we want to allow communication between
23 * unprivileged clients and privileged servers.
25 * • And of course, we don't want the name service and introspection stuff for now (though that might
29 typedef struct Varlink Varlink
;
30 typedef struct VarlinkServer VarlinkServer
;
32 typedef enum VarlinkReplyFlags
{
33 VARLINK_REPLY_ERROR
= 1 << 0,
34 VARLINK_REPLY_CONTINUES
= 1 << 1,
35 VARLINK_REPLY_LOCAL
= 1 << 2,
38 typedef enum VarlinkMethodFlags
{
39 VARLINK_METHOD_ONEWAY
= 1 << 0,
40 VARLINK_METHOD_MORE
= 2 << 1,
43 typedef enum VarlinkServerFlags
{
44 VARLINK_SERVER_ROOT_ONLY
= 1 << 0, /* Only accessible by root */
45 VARLINK_SERVER_MYSELF_ONLY
= 1 << 1, /* Only accessible by our own UID */
46 VARLINK_SERVER_ACCOUNT_UID
= 1 << 2, /* Do per user accounting */
48 _VARLINK_SERVER_FLAGS_ALL
= (1 << 3) - 1,
51 typedef int (*VarlinkMethod
)(Varlink
*link
, JsonVariant
*parameters
, VarlinkMethodFlags flags
, void *userdata
);
52 typedef int (*VarlinkReply
)(Varlink
*link
, JsonVariant
*parameters
, const char *error_id
, VarlinkReplyFlags flags
, void *userdata
);
53 typedef int (*VarlinkConnect
)(VarlinkServer
*server
, Varlink
*link
, void *userdata
);
55 int varlink_connect_address(Varlink
**ret
, const char *address
);
56 int varlink_connect_fd(Varlink
**ret
, int fd
);
58 Varlink
* varlink_ref(Varlink
*link
);
59 Varlink
* varlink_unref(Varlink
*v
);
61 int varlink_get_fd(Varlink
*v
);
62 int varlink_get_events(Varlink
*v
);
63 int varlink_get_timeout(Varlink
*v
, usec_t
*ret
);
65 int varlink_attach_event(Varlink
*v
, sd_event
*e
, int64_t priority
);
66 void varlink_detach_event(Varlink
*v
);
67 sd_event
*varlink_get_event(Varlink
*v
);
69 int varlink_process(Varlink
*v
);
70 int varlink_wait(Varlink
*v
, usec_t timeout
);
72 int varlink_flush(Varlink
*v
);
73 int varlink_close(Varlink
*v
);
75 Varlink
* varlink_flush_close_unref(Varlink
*v
);
77 /* Enqueue method call, not expecting a reply */
78 int varlink_send(Varlink
*v
, const char *method
, JsonVariant
*parameters
);
79 int varlink_sendb(Varlink
*v
, const char *method
, ...);
81 /* Send method call and wait for reply */
82 int varlink_call(Varlink
*v
, const char *method
, JsonVariant
*parameters
, JsonVariant
**ret_parameters
, const char **ret_error_id
, VarlinkReplyFlags
*ret_flags
);
83 int varlink_callb(Varlink
*v
, const char *method
, JsonVariant
**ret_parameters
, const char **ret_error_id
, VarlinkReplyFlags
*ret_flags
, ...);
85 /* Enqueue method call, expect a reply, which is eventually delivered to the reply callback */
86 int varlink_invoke(Varlink
*v
, const char *method
, JsonVariant
*parameters
);
87 int varlink_invokeb(Varlink
*v
, const char *method
, ...);
89 /* Enqueue a final reply */
90 int varlink_reply(Varlink
*v
, JsonVariant
*parameters
);
91 int varlink_replyb(Varlink
*v
, ...);
93 /* Enqueue a (final) error */
94 int varlink_error(Varlink
*v
, const char *error_id
, JsonVariant
*parameters
);
95 int varlink_errorb(Varlink
*v
, const char *error_id
, ...);
96 int varlink_error_invalid_parameter(Varlink
*v
, JsonVariant
*parameters
);
98 /* Enqueue a "more" reply */
99 int varlink_notify(Varlink
*v
, JsonVariant
*parameters
);
100 int varlink_notifyb(Varlink
*v
, ...);
102 /* Bind a disconnect, reply or timeout callback */
103 int varlink_bind_reply(Varlink
*v
, VarlinkReply reply
);
105 void* varlink_set_userdata(Varlink
*v
, void *userdata
);
106 void* varlink_get_userdata(Varlink
*v
);
108 int varlink_get_peer_uid(Varlink
*v
, uid_t
*ret
);
109 int varlink_get_peer_pid(Varlink
*v
, pid_t
*ret
);
111 int varlink_set_relative_timeout(Varlink
*v
, usec_t usec
);
113 VarlinkServer
* varlink_get_server(Varlink
*v
);
115 int varlink_set_description(Varlink
*v
, const char *d
);
117 /* Create a varlink server */
118 int varlink_server_new(VarlinkServer
**ret
, VarlinkServerFlags flags
);
119 VarlinkServer
*varlink_server_ref(VarlinkServer
*s
);
120 VarlinkServer
*varlink_server_unref(VarlinkServer
*s
);
122 /* Add addresses or fds to listen on */
123 int varlink_server_listen_address(VarlinkServer
*s
, const char *address
, mode_t mode
);
124 int varlink_server_listen_fd(VarlinkServer
*s
, int fd
);
125 int varlink_server_add_connection(VarlinkServer
*s
, int fd
, Varlink
**ret
);
128 int varlink_server_bind_method(VarlinkServer
*s
, const char *method
, VarlinkMethod callback
);
129 int varlink_server_bind_method_many_internal(VarlinkServer
*s
, ...);
130 #define varlink_server_bind_method_many(s, ...) varlink_server_bind_method_many_internal(s, __VA_ARGS__, NULL)
131 int varlink_server_bind_connect(VarlinkServer
*s
, VarlinkConnect connect
);
133 void* varlink_server_set_userdata(VarlinkServer
*s
, void *userdata
);
134 void* varlink_server_get_userdata(VarlinkServer
*s
);
136 int varlink_server_attach_event(VarlinkServer
*v
, sd_event
*e
, int64_t priority
);
137 int varlink_server_detach_event(VarlinkServer
*v
);
138 sd_event
*varlink_server_get_event(VarlinkServer
*v
);
140 int varlink_server_shutdown(VarlinkServer
*server
);
142 unsigned varlink_server_connections_max(VarlinkServer
*s
);
143 unsigned varlink_server_connections_per_uid_max(VarlinkServer
*s
);
145 int varlink_server_set_connections_per_uid_max(VarlinkServer
*s
, unsigned m
);
146 int varlink_server_set_connections_max(VarlinkServer
*s
, unsigned m
);
148 int varlink_server_set_description(VarlinkServer
*s
, const char *description
);
150 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink
*, varlink_unref
);
151 DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink
*, varlink_flush_close_unref
);
152 DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServer
*, varlink_server_unref
);
154 #define VARLINK_ERROR_DISCONNECTED "io.systemd.Disconnected"
155 #define VARLINK_ERROR_TIMEOUT "io.systemd.TimedOut"
156 #define VARLINK_ERROR_PROTOCOL "io.systemd.Protocol"
157 #define VARLINK_ERROR_SYSTEM "io.systemd.System"
159 #define VARLINK_ERROR_INTERFACE_NOT_FOUND "org.varlink.service.InterfaceNotFound"
160 #define VARLINK_ERROR_METHOD_NOT_FOUND "org.varlink.service.MethodNotFound"
161 #define VARLINK_ERROR_METHOD_NOT_IMPLEMENTED "org.varlink.service.MethodNotImplemented"
162 #define VARLINK_ERROR_INVALID_PARAMETER "org.varlink.service.InvalidParameter"