]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-search-domain.c
macro: introduce DEFINE_TRIVIAL_REF_UNREF_FUNC() macro and friends
[thirdparty/systemd.git] / src / resolve / resolved-dns-search-domain.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a51c1048
LP
2
3#include "alloc-util.h"
4#include "dns-domain.h"
5#include "resolved-dns-search-domain.h"
6
7int dns_search_domain_new(
8 Manager *m,
9 DnsSearchDomain **ret,
10 DnsSearchDomainType type,
11 Link *l,
12 const char *name) {
13
14 _cleanup_free_ char *normalized = NULL;
eed857b7 15 DnsSearchDomain *d;
a51c1048
LP
16 int r;
17
18 assert(m);
19 assert((type == DNS_SEARCH_DOMAIN_LINK) == !!l);
20 assert(name);
21
22 r = dns_name_normalize(name, &normalized);
23 if (r < 0)
24 return r;
25
eed857b7
LP
26 if (l) {
27 if (l->n_search_domains >= LINK_SEARCH_DOMAINS_MAX)
28 return -E2BIG;
29 } else {
30 if (m->n_search_domains >= MANAGER_SEARCH_DOMAINS_MAX)
31 return -E2BIG;
32 }
33
a51c1048
LP
34 d = new0(DnsSearchDomain, 1);
35 if (!d)
36 return -ENOMEM;
37
38 d->n_ref = 1;
39 d->manager = m;
40 d->type = type;
ae2a15bc 41 d->name = TAKE_PTR(normalized);
a51c1048
LP
42
43 switch (type) {
44
45 case DNS_SEARCH_DOMAIN_LINK:
46 d->link = l;
eed857b7
LP
47 LIST_APPEND(domains, l->search_domains, d);
48 l->n_search_domains++;
a51c1048
LP
49 break;
50
51 case DNS_SERVER_SYSTEM:
eed857b7
LP
52 LIST_APPEND(domains, m->search_domains, d);
53 m->n_search_domains++;
a51c1048
LP
54 break;
55
56 default:
57 assert_not_reached("Unknown search domain type");
58 }
59
60 d->linked = true;
61
62 if (ret)
63 *ret = d;
64
65 return 0;
66}
67
68DnsSearchDomain* dns_search_domain_ref(DnsSearchDomain *d) {
69 if (!d)
70 return NULL;
71
72 assert(d->n_ref > 0);
73 d->n_ref++;
74
75 return d;
76}
77
78DnsSearchDomain* dns_search_domain_unref(DnsSearchDomain *d) {
79 if (!d)
80 return NULL;
81
82 assert(d->n_ref > 0);
83 d->n_ref--;
84
85 if (d->n_ref > 0)
86 return NULL;
87
88 free(d->name);
6b430fdb 89 return mfree(d);
a51c1048
LP
90}
91
92void dns_search_domain_unlink(DnsSearchDomain *d) {
93 assert(d);
94 assert(d->manager);
95
96 if (!d->linked)
97 return;
98
99 switch (d->type) {
100
101 case DNS_SEARCH_DOMAIN_LINK:
102 assert(d->link);
eed857b7 103 assert(d->link->n_search_domains > 0);
a51c1048 104 LIST_REMOVE(domains, d->link->search_domains, d);
eed857b7 105 d->link->n_search_domains--;
a51c1048
LP
106 break;
107
108 case DNS_SEARCH_DOMAIN_SYSTEM:
eed857b7 109 assert(d->manager->n_search_domains > 0);
a51c1048 110 LIST_REMOVE(domains, d->manager->search_domains, d);
eed857b7 111 d->manager->n_search_domains--;
a51c1048
LP
112 break;
113 }
114
115 d->linked = false;
116
117 dns_search_domain_unref(d);
118}
119
120void dns_search_domain_move_back_and_unmark(DnsSearchDomain *d) {
121 DnsSearchDomain *tail;
122
123 assert(d);
124
125 if (!d->marked)
126 return;
127
128 d->marked = false;
129
130 if (!d->linked || !d->domains_next)
131 return;
132
133 switch (d->type) {
134
135 case DNS_SEARCH_DOMAIN_LINK:
136 assert(d->link);
137 LIST_FIND_TAIL(domains, d, tail);
138 LIST_REMOVE(domains, d->link->search_domains, d);
139 LIST_INSERT_AFTER(domains, d->link->search_domains, tail, d);
140 break;
141
142 case DNS_SEARCH_DOMAIN_SYSTEM:
143 LIST_FIND_TAIL(domains, d, tail);
144 LIST_REMOVE(domains, d->manager->search_domains, d);
145 LIST_INSERT_AFTER(domains, d->manager->search_domains, tail, d);
146 break;
147
148 default:
149 assert_not_reached("Unknown search domain type");
150 }
151}
152
153void dns_search_domain_unlink_all(DnsSearchDomain *first) {
154 DnsSearchDomain *next;
155
156 if (!first)
157 return;
158
159 next = first->domains_next;
160 dns_search_domain_unlink(first);
161
162 dns_search_domain_unlink_all(next);
163}
164
165void dns_search_domain_unlink_marked(DnsSearchDomain *first) {
166 DnsSearchDomain *next;
167
168 if (!first)
169 return;
170
171 next = first->domains_next;
172
173 if (first->marked)
174 dns_search_domain_unlink(first);
175
176 dns_search_domain_unlink_marked(next);
177}
178
179void dns_search_domain_mark_all(DnsSearchDomain *first) {
180 if (!first)
181 return;
182
183 first->marked = true;
184 dns_search_domain_mark_all(first->domains_next);
185}
186
187int dns_search_domain_find(DnsSearchDomain *first, const char *name, DnsSearchDomain **ret) {
188 DnsSearchDomain *d;
189 int r;
190
191 assert(name);
192 assert(ret);
193
194 LIST_FOREACH(domains, d, first) {
195
196 r = dns_name_equal(name, d->name);
197 if (r < 0)
198 return r;
199 if (r > 0) {
200 *ret = d;
201 return 1;
202 }
203 }
204
205 *ret = NULL;
206 return 0;
207}