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