/src/systemd/src/libsystemd/sd-varlink/varlink-internal.h
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | #pragma once |
3 | | |
4 | | #include <sys/socket.h> |
5 | | |
6 | | #include "sd-varlink.h" |
7 | | |
8 | | #include "json-stream.h" |
9 | | #include "list.h" |
10 | | #include "pidref.h" |
11 | | #include "forward.h" |
12 | | |
13 | | typedef enum VarlinkState { |
14 | | /* Client side states */ |
15 | | VARLINK_IDLE_CLIENT, |
16 | | VARLINK_AWAITING_REPLY, |
17 | | VARLINK_AWAITING_REPLY_MORE, |
18 | | VARLINK_CALLING, |
19 | | VARLINK_CALLED, |
20 | | VARLINK_COLLECTING, |
21 | | VARLINK_COLLECTING_REPLY, |
22 | | VARLINK_PROCESSING_REPLY, |
23 | | |
24 | | /* Server side states */ |
25 | | VARLINK_IDLE_SERVER, |
26 | | VARLINK_PROCESSING_METHOD, |
27 | | VARLINK_PROCESSING_METHOD_MORE, |
28 | | VARLINK_PROCESSING_METHOD_ONEWAY, |
29 | | VARLINK_PROCESSING_METHOD_UPGRADE, |
30 | | VARLINK_PROCESSED_METHOD, |
31 | | VARLINK_PROCESSED_METHOD_UPGRADE, |
32 | | VARLINK_PENDING_METHOD, |
33 | | VARLINK_PENDING_METHOD_MORE, |
34 | | VARLINK_PENDING_METHOD_UPGRADE, |
35 | | VARLINK_UPGRADING, |
36 | | |
37 | | /* Common states (only during shutdown) */ |
38 | | VARLINK_PENDING_DISCONNECT, |
39 | | VARLINK_PENDING_TIMEOUT, |
40 | | VARLINK_PROCESSING_DISCONNECT, |
41 | | VARLINK_PROCESSING_TIMEOUT, |
42 | | VARLINK_PROCESSING_FAILURE, |
43 | | VARLINK_DISCONNECTED, |
44 | | |
45 | | _VARLINK_STATE_MAX, |
46 | | _VARLINK_STATE_INVALID = -EINVAL, |
47 | | } VarlinkState; |
48 | | |
49 | | /* Tests whether we are not yet disconnected. Note that this is true during all states where the connection |
50 | | * is still good for something, and false only when it's dead for good. This means: when we are |
51 | | * asynchronously connecting to a peer and the connect() is still pending, then this will return 'true', as |
52 | | * the connection is still good, and we are likely to be able to properly operate on it soon. */ |
53 | | #define VARLINK_STATE_IS_ALIVE(state) \ |
54 | 2.07M | IN_SET(state, \ |
55 | 7.19k | VARLINK_IDLE_CLIENT, \ |
56 | 7.19k | VARLINK_AWAITING_REPLY, \ |
57 | 7.19k | VARLINK_AWAITING_REPLY_MORE, \ |
58 | 7.19k | VARLINK_CALLING, \ |
59 | 7.19k | VARLINK_CALLED, \ |
60 | 7.19k | VARLINK_COLLECTING, \ |
61 | 7.19k | VARLINK_COLLECTING_REPLY, \ |
62 | 7.19k | VARLINK_PROCESSING_REPLY, \ |
63 | 7.19k | VARLINK_IDLE_SERVER, \ |
64 | 7.19k | VARLINK_PROCESSING_METHOD, \ |
65 | 7.19k | VARLINK_PROCESSING_METHOD_MORE, \ |
66 | 7.19k | VARLINK_PROCESSING_METHOD_ONEWAY, \ |
67 | 7.19k | VARLINK_PROCESSING_METHOD_UPGRADE, \ |
68 | 7.19k | VARLINK_PROCESSED_METHOD, \ |
69 | 7.19k | VARLINK_PROCESSED_METHOD_UPGRADE, \ |
70 | 7.19k | VARLINK_PENDING_METHOD, \ |
71 | 7.19k | VARLINK_PENDING_METHOD_MORE, \ |
72 | 7.19k | VARLINK_PENDING_METHOD_UPGRADE, \ |
73 | 7.19k | VARLINK_UPGRADING) |
74 | | |
75 | | /* Tests whether we are expected to generate a method call reply, i.e. are processing a method call, except |
76 | | * one with the ONEWAY flag set. */ |
77 | | #define VARLINK_STATE_WANTS_REPLY(state) \ |
78 | 382k | IN_SET(state, \ |
79 | 273k | VARLINK_PROCESSING_METHOD, \ |
80 | 273k | VARLINK_PROCESSING_METHOD_MORE, \ |
81 | 273k | VARLINK_PROCESSING_METHOD_UPGRADE) |
82 | | |
83 | | typedef struct sd_varlink { |
84 | | unsigned n_ref; |
85 | | |
86 | | VarlinkState state; |
87 | | sd_varlink_server *server; |
88 | | |
89 | | /* Transport layer: input/output buffers, fd passing, output queue, read/write/parse |
90 | | * step functions, sd-event integration (input/output/time event sources, idle |
91 | | * timeout, description, peer credentials). The varlink-level state machine and |
92 | | * dispatch logic live in sd-varlink.c; everything else about moving bytes is |
93 | | * delegated. */ |
94 | | JsonStream stream; |
95 | | |
96 | | unsigned n_pending; |
97 | | |
98 | | sd_varlink_reply_t reply_callback; |
99 | | sd_varlink_upgrade_t upgrade_callback; |
100 | | |
101 | | sd_json_variant *current; |
102 | | sd_json_variant *current_collected; |
103 | | sd_varlink_reply_flags_t current_reply_flags; |
104 | | sd_varlink_symbol *current_method; |
105 | | |
106 | | int *pushed_fds; |
107 | | size_t n_pushed_fds; |
108 | | |
109 | | sd_json_variant *previous; |
110 | | int *previous_fds; |
111 | | size_t n_previous_fds; |
112 | | char *sentinel; |
113 | | |
114 | | void *userdata; |
115 | | |
116 | | sd_event_source *quit_event_source; |
117 | | sd_event_source *defer_event_source; |
118 | | |
119 | | PidRef exec_pidref; |
120 | | } sd_varlink; |
121 | | |
122 | | typedef struct VarlinkServerSocket VarlinkServerSocket; |
123 | | |
124 | | struct VarlinkServerSocket { |
125 | | sd_varlink_server *server; |
126 | | |
127 | | int fd; |
128 | | char *address; |
129 | | |
130 | | sd_event_source *event_source; |
131 | | |
132 | | LIST_FIELDS(VarlinkServerSocket, sockets); |
133 | | }; |
134 | | |
135 | | typedef struct sd_varlink_server { |
136 | | unsigned n_ref; |
137 | | sd_varlink_server_flags_t flags; |
138 | | |
139 | | LIST_HEAD(VarlinkServerSocket, sockets); |
140 | | |
141 | | Hashmap *methods; /* Fully qualified symbol name of a method → sd_varlink_method_t */ |
142 | | Hashmap *fiber_methods; /* Fully qualified symbol name of a fiber method → sd_varlink_method_t */ |
143 | | Hashmap *interfaces; /* Fully qualified interface name → VarlinkInterface* */ |
144 | | Hashmap *symbols; /* Fully qualified symbol name of method/error → VarlinkSymbol* */ |
145 | | sd_varlink_connect_t connect_callback; |
146 | | sd_varlink_disconnect_t disconnect_callback; |
147 | | |
148 | | sd_event *event; |
149 | | int64_t event_priority; |
150 | | |
151 | | Hashmap *by_uid; /* UID_TO_PTR(uid) → UINT_TO_PTR(n_connections) */ |
152 | | unsigned n_connections; |
153 | | unsigned connections_max; |
154 | | unsigned connections_per_uid_max; |
155 | | |
156 | | bool exit_on_idle; |
157 | | |
158 | | void *userdata; |
159 | | |
160 | | char *description; |
161 | | char *vendor; |
162 | | char *product; |
163 | | char *version; |
164 | | char *url; |
165 | | } sd_varlink_server; |
166 | | |
167 | | #define varlink_log_errno(v, error, fmt, ...) \ |
168 | 8.50M | log_debug_errno(error, "%s: " fmt, varlink_description(v), ##__VA_ARGS__) |
169 | | |
170 | | #define varlink_log(v, fmt, ...) \ |
171 | 2.01M | log_debug("%s: " fmt, varlink_description(v), ##__VA_ARGS__) |
172 | | |
173 | | #define varlink_server_log_errno(s, error, fmt, ...) \ |
174 | 1.73k | log_debug_errno(error, "%s: " fmt, varlink_server_description(s), ##__VA_ARGS__) |
175 | | |
176 | | #define varlink_server_log(s, fmt, ...) \ |
177 | 0 | log_debug("%s: " fmt, varlink_server_description(s), ##__VA_ARGS__) |
178 | | |
179 | 0 | static inline const char* varlink_description(sd_varlink *v) { |
180 | 0 | return (v ? json_stream_get_description(&v->stream) : NULL) ?: "varlink"; |
181 | 0 | } Unexecuted instantiation: varlink-serialize.c:varlink_description Unexecuted instantiation: sd-varlink.c:varlink_description Unexecuted instantiation: varlink-util.c:varlink_description |
182 | | |
183 | 6.67k | static inline const char* varlink_server_description(sd_varlink_server *s) { |
184 | 6.67k | return (s ? s->description : NULL) ?: "varlink"; |
185 | 6.67k | } varlink-serialize.c:varlink_server_description Line | Count | Source | 183 | 607 | static inline const char* varlink_server_description(sd_varlink_server *s) { | 184 | 607 | return (s ? s->description : NULL) ?: "varlink"; | 185 | 607 | } |
sd-varlink.c:varlink_server_description Line | Count | Source | 183 | 6.06k | static inline const char* varlink_server_description(sd_varlink_server *s) { | 184 | 6.06k | return (s ? s->description : NULL) ?: "varlink"; | 185 | 6.06k | } |
Unexecuted instantiation: varlink-util.c:varlink_server_description |
186 | | |
187 | | VarlinkServerSocket* varlink_server_socket_free(VarlinkServerSocket *ss); |
188 | | DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServerSocket *, varlink_server_socket_free); |
189 | | |
190 | | int varlink_server_add_socket_event_source(sd_varlink_server *s, VarlinkServerSocket *ss); |