]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-search-domain.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / resolve / resolved-dns-search-domain.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a51c1048
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2015 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include "alloc-util.h"
22#include "dns-domain.h"
23#include "resolved-dns-search-domain.h"
24
25int dns_search_domain_new(
26 Manager *m,
27 DnsSearchDomain **ret,
28 DnsSearchDomainType type,
29 Link *l,
30 const char *name) {
31
32 _cleanup_free_ char *normalized = NULL;
eed857b7 33 DnsSearchDomain *d;
a51c1048
LP
34 int r;
35
36 assert(m);
37 assert((type == DNS_SEARCH_DOMAIN_LINK) == !!l);
38 assert(name);
39
40 r = dns_name_normalize(name, &normalized);
41 if (r < 0)
42 return r;
43
eed857b7
LP
44 if (l) {
45 if (l->n_search_domains >= LINK_SEARCH_DOMAINS_MAX)
46 return -E2BIG;
47 } else {
48 if (m->n_search_domains >= MANAGER_SEARCH_DOMAINS_MAX)
49 return -E2BIG;
50 }
51
a51c1048
LP
52 d = new0(DnsSearchDomain, 1);
53 if (!d)
54 return -ENOMEM;
55
56 d->n_ref = 1;
57 d->manager = m;
58 d->type = type;
59 d->name = normalized;
60 normalized = NULL;
61
62 switch (type) {
63
64 case DNS_SEARCH_DOMAIN_LINK:
65 d->link = l;
eed857b7
LP
66 LIST_APPEND(domains, l->search_domains, d);
67 l->n_search_domains++;
a51c1048
LP
68 break;
69
70 case DNS_SERVER_SYSTEM:
eed857b7
LP
71 LIST_APPEND(domains, m->search_domains, d);
72 m->n_search_domains++;
a51c1048
LP
73 break;
74
75 default:
76 assert_not_reached("Unknown search domain type");
77 }
78
79 d->linked = true;
80
81 if (ret)
82 *ret = d;
83
84 return 0;
85}
86
87DnsSearchDomain* dns_search_domain_ref(DnsSearchDomain *d) {
88 if (!d)
89 return NULL;
90
91 assert(d->n_ref > 0);
92 d->n_ref++;
93
94 return d;
95}
96
97DnsSearchDomain* dns_search_domain_unref(DnsSearchDomain *d) {
98 if (!d)
99 return NULL;
100
101 assert(d->n_ref > 0);
102 d->n_ref--;
103
104 if (d->n_ref > 0)
105 return NULL;
106
107 free(d->name);
6b430fdb 108 return mfree(d);
a51c1048
LP
109}
110
111void dns_search_domain_unlink(DnsSearchDomain *d) {
112 assert(d);
113 assert(d->manager);
114
115 if (!d->linked)
116 return;
117
118 switch (d->type) {
119
120 case DNS_SEARCH_DOMAIN_LINK:
121 assert(d->link);
eed857b7 122 assert(d->link->n_search_domains > 0);
a51c1048 123 LIST_REMOVE(domains, d->link->search_domains, d);
eed857b7 124 d->link->n_search_domains--;
a51c1048
LP
125 break;
126
127 case DNS_SEARCH_DOMAIN_SYSTEM:
eed857b7 128 assert(d->manager->n_search_domains > 0);
a51c1048 129 LIST_REMOVE(domains, d->manager->search_domains, d);
eed857b7 130 d->manager->n_search_domains--;
a51c1048
LP
131 break;
132 }
133
134 d->linked = false;
135
136 dns_search_domain_unref(d);
137}
138
139void dns_search_domain_move_back_and_unmark(DnsSearchDomain *d) {
140 DnsSearchDomain *tail;
141
142 assert(d);
143
144 if (!d->marked)
145 return;
146
147 d->marked = false;
148
149 if (!d->linked || !d->domains_next)
150 return;
151
152 switch (d->type) {
153
154 case DNS_SEARCH_DOMAIN_LINK:
155 assert(d->link);
156 LIST_FIND_TAIL(domains, d, tail);
157 LIST_REMOVE(domains, d->link->search_domains, d);
158 LIST_INSERT_AFTER(domains, d->link->search_domains, tail, d);
159 break;
160
161 case DNS_SEARCH_DOMAIN_SYSTEM:
162 LIST_FIND_TAIL(domains, d, tail);
163 LIST_REMOVE(domains, d->manager->search_domains, d);
164 LIST_INSERT_AFTER(domains, d->manager->search_domains, tail, d);
165 break;
166
167 default:
168 assert_not_reached("Unknown search domain type");
169 }
170}
171
172void dns_search_domain_unlink_all(DnsSearchDomain *first) {
173 DnsSearchDomain *next;
174
175 if (!first)
176 return;
177
178 next = first->domains_next;
179 dns_search_domain_unlink(first);
180
181 dns_search_domain_unlink_all(next);
182}
183
184void dns_search_domain_unlink_marked(DnsSearchDomain *first) {
185 DnsSearchDomain *next;
186
187 if (!first)
188 return;
189
190 next = first->domains_next;
191
192 if (first->marked)
193 dns_search_domain_unlink(first);
194
195 dns_search_domain_unlink_marked(next);
196}
197
198void dns_search_domain_mark_all(DnsSearchDomain *first) {
199 if (!first)
200 return;
201
202 first->marked = true;
203 dns_search_domain_mark_all(first->domains_next);
204}
205
206int dns_search_domain_find(DnsSearchDomain *first, const char *name, DnsSearchDomain **ret) {
207 DnsSearchDomain *d;
208 int r;
209
210 assert(name);
211 assert(ret);
212
213 LIST_FOREACH(domains, d, first) {
214
215 r = dns_name_equal(name, d->name);
216 if (r < 0)
217 return r;
218 if (r > 0) {
219 *ret = d;
220 return 1;
221 }
222 }
223
224 *ret = NULL;
225 return 0;
226}