]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-server.c
sd-resolve: scale number of threads by queries currently being processed, rather...
[thirdparty/systemd.git] / src / resolve / resolved-dns-server.c
CommitLineData
74b2466e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 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
87f5a193
LP
22#include "siphash24.h"
23
74b2466e
LP
24#include "resolved-dns-server.h"
25
26int dns_server_new(
27 Manager *m,
28 DnsServer **ret,
4e945a6f 29 DnsServerType type,
74b2466e 30 Link *l,
0dd25fb9 31 int family,
3c0cf502 32 const union in_addr_union *in_addr) {
74b2466e
LP
33
34 DnsServer *s, *tail;
35
36 assert(m);
4e945a6f 37 assert((type == DNS_SERVER_LINK) == !!l);
74b2466e 38 assert(in_addr);
74b2466e
LP
39
40 s = new0(DnsServer, 1);
41 if (!s)
42 return -ENOMEM;
43
4e945a6f 44 s->type = type;
74b2466e
LP
45 s->family = family;
46 s->address = *in_addr;
47
4e945a6f 48 if (type == DNS_SERVER_LINK) {
6073b6f2
TG
49 LIST_FIND_TAIL(servers, l->dns_servers, tail);
50 LIST_INSERT_AFTER(servers, l->dns_servers, tail, s);
74b2466e 51 s->link = l;
4e945a6f 52 } else if (type == DNS_SERVER_SYSTEM) {
74b2466e
LP
53 LIST_FIND_TAIL(servers, m->dns_servers, tail);
54 LIST_INSERT_AFTER(servers, m->dns_servers, tail, s);
4e945a6f
LP
55 } else if (type == DNS_SERVER_FALLBACK) {
56 LIST_FIND_TAIL(servers, m->fallback_dns_servers, tail);
57 LIST_INSERT_AFTER(servers, m->fallback_dns_servers, tail, s);
58 } else
59 assert_not_reached("Unknown server type");
74b2466e
LP
60
61 s->manager = m;
62
4e945a6f
LP
63 /* A new DNS server that isn't fallback is added and the one
64 * we used so far was a fallback one? Then let's try to pick
65 * the new one */
66 if (type != DNS_SERVER_FALLBACK &&
67 s->manager->current_dns_server &&
68 s->manager->current_dns_server->type == DNS_SERVER_FALLBACK)
2c27fbca 69 manager_set_dns_server(s->manager, NULL);
4e945a6f 70
74b2466e
LP
71 if (ret)
72 *ret = s;
73
74 return 0;
75}
76
77DnsServer* dns_server_free(DnsServer *s) {
78 if (!s)
79 return NULL;
80
2f82f5ea 81 if (s->manager) {
4e945a6f 82 if (s->type == DNS_SERVER_LINK)
6073b6f2 83 LIST_REMOVE(servers, s->link->dns_servers, s);
4e945a6f 84 else if (s->type == DNS_SERVER_SYSTEM)
74b2466e 85 LIST_REMOVE(servers, s->manager->dns_servers, s);
4e945a6f
LP
86 else if (s->type == DNS_SERVER_FALLBACK)
87 LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
88 else
89 assert_not_reached("Unknown server type");
74b2466e
LP
90 }
91
92 if (s->link && s->link->current_dns_server == s)
2c27fbca 93 link_set_dns_server(s->link, NULL);
74b2466e
LP
94
95 if (s->manager && s->manager->current_dns_server == s)
2c27fbca 96 manager_set_dns_server(s->manager, NULL);
74b2466e
LP
97
98 free(s);
99
100 return NULL;
101}
87f5a193
LP
102
103unsigned long dns_server_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
104 const DnsServer *s = p;
105 uint64_t u;
106
107 siphash24((uint8_t*) &u, &s->address, FAMILY_ADDRESS_SIZE(s->family), hash_key);
108 u = u * hash_key[0] + u + s->family;
109
110 return u;
111}
112
113int dns_server_compare_func(const void *a, const void *b) {
114 const DnsServer *x = a, *y = b;
115
116 if (x->family < y->family)
117 return -1;
118 if (x->family > y->family)
119 return 1;
120
121 return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
122}