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