Coverage Report

Created: 2026-08-08 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/systemd/src/resolve/resolved-dns-search-domain.c
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include "sd-json.h"
4
5
#include "alloc-util.h"
6
#include "dns-domain.h"
7
#include "resolved-dns-delegate.h"
8
#include "resolved-dns-search-domain.h"
9
#include "resolved-link.h"
10
#include "resolved-manager.h"
11
12
int dns_search_domain_new(
13
                Manager *m,
14
                DnsSearchDomain **ret,
15
                DnsSearchDomainType type,
16
                Link *link,
17
                DnsDelegate *delegate,
18
0
                const char *name) {
19
20
0
        _cleanup_free_ char *normalized = NULL;
21
0
        DnsSearchDomain *d;
22
0
        int r;
23
24
0
        assert(m);
25
0
        assert((type == DNS_SEARCH_DOMAIN_LINK) == !!link);
26
0
        assert((type == DNS_SEARCH_DOMAIN_DELEGATE) == !!delegate);
27
0
        assert(name);
28
29
0
        r = dns_name_normalize(name, 0, &normalized);
30
0
        if (r < 0)
31
0
                return r;
32
33
0
        if (link) {
34
0
                if (link->n_search_domains >= LINK_SEARCH_DOMAINS_MAX)
35
0
                        return -E2BIG;
36
0
        } else if (delegate) {
37
0
                if (delegate->n_search_domains >= DELEGATE_SEARCH_DOMAINS_MAX)
38
0
                        return -E2BIG;
39
0
        } else {
40
0
                if (m->n_search_domains >= MANAGER_SEARCH_DOMAINS_MAX)
41
0
                        return -E2BIG;
42
0
        }
43
44
0
        d = new(DnsSearchDomain, 1);
45
0
        if (!d)
46
0
                return -ENOMEM;
47
48
0
        *d = (DnsSearchDomain) {
49
0
                .n_ref = 1,
50
0
                .manager = m,
51
0
                .type = type,
52
0
                .name = TAKE_PTR(normalized),
53
0
        };
54
55
0
        switch (type) {
56
57
0
        case DNS_SEARCH_DOMAIN_LINK:
58
0
                d->link = link;
59
0
                LIST_APPEND(domains, link->search_domains, d);
60
0
                link->n_search_domains++;
61
0
                break;
62
63
0
        case DNS_SEARCH_DOMAIN_SYSTEM:
64
0
                LIST_APPEND(domains, m->search_domains, d);
65
0
                m->n_search_domains++;
66
0
                break;
67
68
0
        case DNS_SEARCH_DOMAIN_DELEGATE:
69
0
                d->delegate = delegate;
70
0
                LIST_APPEND(domains, delegate->search_domains, d);
71
0
                delegate->n_search_domains++;
72
0
                break;
73
74
0
        default:
75
0
                assert_not_reached();
76
0
        }
77
78
0
        d->linked = true;
79
80
0
        if (ret)
81
0
                *ret = d;
82
83
0
        return 0;
84
0
}
85
86
0
static DnsSearchDomain* dns_search_domain_free(DnsSearchDomain *d) {
87
0
        assert(d);
88
89
0
        free(d->name);
90
0
        return mfree(d);
91
0
}
92
93
0
DEFINE_TRIVIAL_REF_UNREF_FUNC(DnsSearchDomain, dns_search_domain, dns_search_domain_free);
Unexecuted instantiation: dns_search_domain_ref
Unexecuted instantiation: dns_search_domain_unref
94
0
95
0
void dns_search_domain_unlink(DnsSearchDomain *d) {
96
0
        assert(d);
97
0
        assert(d->manager);
98
99
0
        if (!d->linked)
100
0
                return;
101
102
0
        switch (d->type) {
103
104
0
        case DNS_SEARCH_DOMAIN_LINK:
105
0
                assert(d->link);
106
0
                assert(d->link->n_search_domains > 0);
107
0
                LIST_REMOVE(domains, d->link->search_domains, d);
108
0
                d->link->n_search_domains--;
109
0
                break;
110
111
0
        case DNS_SEARCH_DOMAIN_SYSTEM:
112
0
                assert(d->manager->n_search_domains > 0);
113
0
                LIST_REMOVE(domains, d->manager->search_domains, d);
114
0
                d->manager->n_search_domains--;
115
0
                break;
116
117
0
        case DNS_SEARCH_DOMAIN_DELEGATE:
118
0
                assert(d->delegate);
119
0
                assert(d->delegate->n_search_domains > 0);
120
0
                LIST_REMOVE(domains, d->delegate->search_domains, d);
121
0
                d->delegate->n_search_domains--;
122
0
                break;
123
0
        }
124
125
0
        d->linked = false;
126
127
0
        dns_search_domain_unref(d);
128
0
}
129
130
0
void dns_search_domain_move_back_and_unmark(DnsSearchDomain *d) {
131
0
        DnsSearchDomain *tail;
132
133
0
        assert(d);
134
135
0
        if (!d->marked)
136
0
                return;
137
138
0
        d->marked = false;
139
140
0
        if (!d->linked || !d->domains_next)
141
0
                return;
142
143
0
        switch (d->type) {
144
145
0
        case DNS_SEARCH_DOMAIN_LINK:
146
0
                assert(d->link);
147
0
                tail = LIST_FIND_TAIL(domains, d);
148
0
                LIST_REMOVE(domains, d->link->search_domains, d);
149
0
                LIST_INSERT_AFTER(domains, d->link->search_domains, tail, d);
150
0
                break;
151
152
0
        case DNS_SEARCH_DOMAIN_SYSTEM:
153
0
                tail = LIST_FIND_TAIL(domains, d);
154
0
                LIST_REMOVE(domains, d->manager->search_domains, d);
155
0
                LIST_INSERT_AFTER(domains, d->manager->search_domains, tail, d);
156
0
                break;
157
158
0
        case DNS_SEARCH_DOMAIN_DELEGATE:
159
0
                assert(d->delegate);
160
0
                tail = LIST_FIND_TAIL(domains, d);
161
0
                LIST_REMOVE(domains, d->delegate->search_domains, d);
162
0
                LIST_INSERT_AFTER(domains, d->delegate->search_domains, tail, d);
163
0
                break;
164
165
0
        default:
166
0
                assert_not_reached();
167
0
        }
168
0
}
169
170
0
void dns_search_domain_unlink_all(DnsSearchDomain *first) {
171
0
        DnsSearchDomain *next;
172
173
0
        if (!first)
174
0
                return;
175
176
0
        next = first->domains_next;
177
0
        dns_search_domain_unlink(first);
178
179
0
        dns_search_domain_unlink_all(next);
180
0
}
181
182
0
bool dns_search_domain_unlink_marked(DnsSearchDomain *first) {
183
0
        DnsSearchDomain *next;
184
0
        bool changed;
185
186
0
        if (!first)
187
0
                return false;
188
189
0
        next = first->domains_next;
190
191
0
        if (first->marked) {
192
0
                dns_search_domain_unlink(first);
193
0
                changed = true;
194
0
        } else
195
0
                changed = false;
196
197
0
        return dns_search_domain_unlink_marked(next) || changed;
198
0
}
199
200
0
void dns_search_domain_mark_all(DnsSearchDomain *first) {
201
0
        if (!first)
202
0
                return;
203
204
0
        first->marked = true;
205
0
        dns_search_domain_mark_all(first->domains_next);
206
0
}
207
208
0
int dns_search_domain_find(DnsSearchDomain *first, const char *name, DnsSearchDomain **ret) {
209
0
        int r;
210
211
0
        assert(name);
212
0
        assert(ret);
213
214
0
        LIST_FOREACH(domains, d, first) {
215
216
0
                r = dns_name_equal(name, d->name);
217
0
                if (r < 0)
218
0
                        return r;
219
0
                if (r > 0) {
220
0
                        *ret = d;
221
0
                        return 1;
222
0
                }
223
0
        }
224
225
0
        *ret = NULL;
226
0
        return 0;
227
0
}
228
229
0
int dns_search_domain_dump_to_json(DnsSearchDomain *domain, sd_json_variant **ret) {
230
0
        int ifindex = 0;
231
232
0
        assert(domain);
233
0
        assert(ret);
234
235
0
        if (domain->type == DNS_SEARCH_DOMAIN_LINK) {
236
0
                assert(domain->link);
237
0
                ifindex = domain->link->ifindex;
238
0
        }
239
240
0
        return sd_json_buildo(
241
0
                        ret,
242
0
                        SD_JSON_BUILD_PAIR_STRING("name", domain->name),
243
0
                        SD_JSON_BUILD_PAIR_BOOLEAN("routeOnly", domain->route_only),
244
0
                        SD_JSON_BUILD_PAIR_CONDITION(ifindex > 0, "ifindex", SD_JSON_BUILD_UNSIGNED(ifindex)));
245
0
}