Coverage Report

Created: 2026-07-30 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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);