]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-search-domain.c
resolved: cache stringified transaction key once per transaction
[thirdparty/systemd.git] / src / resolve / resolved-dns-search-domain.c
CommitLineData
a51c1048
LP
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
26int 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;
eed857b7 34 DnsSearchDomain *d;
a51c1048
LP
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
dc477e73 45 if (dns_name_is_root(normalized))
a51c1048
LP
46 return -EINVAL;
47
eed857b7
LP
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
a51c1048
LP
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;
eed857b7
LP
70 LIST_APPEND(domains, l->search_domains, d);
71 l->n_search_domains++;
a51c1048
LP
72 break;
73
74 case DNS_SERVER_SYSTEM:
eed857b7
LP
75 LIST_APPEND(domains, m->search_domains, d);
76 m->n_search_domains++;
a51c1048
LP
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
91DnsSearchDomain* 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
101DnsSearchDomain* 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
117void 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);
eed857b7 128 assert(d->link->n_search_domains > 0);
a51c1048 129 LIST_REMOVE(domains, d->link->search_domains, d);
eed857b7 130 d->link->n_search_domains--;
a51c1048
LP
131 break;
132
133 case DNS_SEARCH_DOMAIN_SYSTEM:
eed857b7 134 assert(d->manager->n_search_domains > 0);
a51c1048 135 LIST_REMOVE(domains, d->manager->search_domains, d);
eed857b7 136 d->manager->n_search_domains--;
a51c1048
LP
137 break;
138 }
139
140 d->linked = false;
141
142 dns_search_domain_unref(d);
143}
144
145void 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
178void 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
190void 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
204void 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
212int 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}