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