]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-search-domain.c
Merge pull request #6918 from ssahani/issue-5625
[thirdparty/systemd.git] / src / resolve / resolved-dns-search-domain.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
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
25 int 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;
33 DnsSearchDomain *d;
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
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
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;
66 LIST_APPEND(domains, l->search_domains, d);
67 l->n_search_domains++;
68 break;
69
70 case DNS_SERVER_SYSTEM:
71 LIST_APPEND(domains, m->search_domains, d);
72 m->n_search_domains++;
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
87 DnsSearchDomain* 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
97 DnsSearchDomain* 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);
108 return mfree(d);
109 }
110
111 void 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);
122 assert(d->link->n_search_domains > 0);
123 LIST_REMOVE(domains, d->link->search_domains, d);
124 d->link->n_search_domains--;
125 break;
126
127 case DNS_SEARCH_DOMAIN_SYSTEM:
128 assert(d->manager->n_search_domains > 0);
129 LIST_REMOVE(domains, d->manager->search_domains, d);
130 d->manager->n_search_domains--;
131 break;
132 }
133
134 d->linked = false;
135
136 dns_search_domain_unref(d);
137 }
138
139 void 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
172 void 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
184 void 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
198 void 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
206 int 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 }