1*c2c26c8bSAndroid Build Coastguard Worker /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
2*c2c26c8bSAndroid Build Coastguard Worker
3*c2c26c8bSAndroid Build Coastguard Worker This program is free software; you can redistribute it and/or modify
4*c2c26c8bSAndroid Build Coastguard Worker it under the terms of the GNU General Public License as published by
5*c2c26c8bSAndroid Build Coastguard Worker the Free Software Foundation; version 2 dated June, 1991, or
6*c2c26c8bSAndroid Build Coastguard Worker (at your option) version 3 dated 29 June, 2007.
7*c2c26c8bSAndroid Build Coastguard Worker
8*c2c26c8bSAndroid Build Coastguard Worker This program is distributed in the hope that it will be useful,
9*c2c26c8bSAndroid Build Coastguard Worker but WITHOUT ANY WARRANTY; without even the implied warranty of
10*c2c26c8bSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11*c2c26c8bSAndroid Build Coastguard Worker GNU General Public License for more details.
12*c2c26c8bSAndroid Build Coastguard Worker
13*c2c26c8bSAndroid Build Coastguard Worker You should have received a copy of the GNU General Public License
14*c2c26c8bSAndroid Build Coastguard Worker along with this program. If not, see <http://www.gnu.org/licenses/>.
15*c2c26c8bSAndroid Build Coastguard Worker */
16*c2c26c8bSAndroid Build Coastguard Worker
17*c2c26c8bSAndroid Build Coastguard Worker #include "dnsmasq.h"
18*c2c26c8bSAndroid Build Coastguard Worker
19*c2c26c8bSAndroid Build Coastguard Worker static const char SEPARATOR[] = "|";
20*c2c26c8bSAndroid Build Coastguard Worker
21*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_NETWORK
22*c2c26c8bSAndroid Build Coastguard Worker
indextoname(int fd,int index,char * name)23*c2c26c8bSAndroid Build Coastguard Worker int indextoname(int fd, int index, char* name) {
24*c2c26c8bSAndroid Build Coastguard Worker struct ifreq ifr;
25*c2c26c8bSAndroid Build Coastguard Worker
26*c2c26c8bSAndroid Build Coastguard Worker if (index == 0) return 0;
27*c2c26c8bSAndroid Build Coastguard Worker
28*c2c26c8bSAndroid Build Coastguard Worker ifr.ifr_ifindex = index;
29*c2c26c8bSAndroid Build Coastguard Worker if (ioctl(fd, SIOCGIFNAME, &ifr) == -1) return 0;
30*c2c26c8bSAndroid Build Coastguard Worker
31*c2c26c8bSAndroid Build Coastguard Worker strncpy(name, ifr.ifr_name, IF_NAMESIZE);
32*c2c26c8bSAndroid Build Coastguard Worker
33*c2c26c8bSAndroid Build Coastguard Worker return 1;
34*c2c26c8bSAndroid Build Coastguard Worker }
35*c2c26c8bSAndroid Build Coastguard Worker
36*c2c26c8bSAndroid Build Coastguard Worker #else
37*c2c26c8bSAndroid Build Coastguard Worker
indextoname(int fd,int index,char * name)38*c2c26c8bSAndroid Build Coastguard Worker int indextoname(int fd, int index, char* name) {
39*c2c26c8bSAndroid Build Coastguard Worker if (index == 0 || !if_indextoname(index, name)) return 0;
40*c2c26c8bSAndroid Build Coastguard Worker
41*c2c26c8bSAndroid Build Coastguard Worker return 1;
42*c2c26c8bSAndroid Build Coastguard Worker }
43*c2c26c8bSAndroid Build Coastguard Worker
44*c2c26c8bSAndroid Build Coastguard Worker #endif
45*c2c26c8bSAndroid Build Coastguard Worker
iface_check(int family,struct all_addr * addr,char * name,int * indexp)46*c2c26c8bSAndroid Build Coastguard Worker int iface_check(int family, struct all_addr* addr, char* name, int* indexp) {
47*c2c26c8bSAndroid Build Coastguard Worker struct iname* tmp;
48*c2c26c8bSAndroid Build Coastguard Worker int ret = 1;
49*c2c26c8bSAndroid Build Coastguard Worker
50*c2c26c8bSAndroid Build Coastguard Worker /* Note: have to check all and not bail out early, so that we set the
51*c2c26c8bSAndroid Build Coastguard Worker "used" flags. */
52*c2c26c8bSAndroid Build Coastguard Worker
53*c2c26c8bSAndroid Build Coastguard Worker if (indexp) {
54*c2c26c8bSAndroid Build Coastguard Worker /* One form of bridging on BSD has the property that packets
55*c2c26c8bSAndroid Build Coastguard Worker can be recieved on bridge interfaces which do not have an IP address.
56*c2c26c8bSAndroid Build Coastguard Worker We allow these to be treated as aliases of another interface which does have
57*c2c26c8bSAndroid Build Coastguard Worker an IP address with --dhcp-bridge=interface,alias,alias */
58*c2c26c8bSAndroid Build Coastguard Worker struct dhcp_bridge *bridge, *alias;
59*c2c26c8bSAndroid Build Coastguard Worker for (bridge = daemon->bridges; bridge; bridge = bridge->next) {
60*c2c26c8bSAndroid Build Coastguard Worker for (alias = bridge->alias; alias; alias = alias->next)
61*c2c26c8bSAndroid Build Coastguard Worker if (strncmp(name, alias->iface, IF_NAMESIZE) == 0) {
62*c2c26c8bSAndroid Build Coastguard Worker int newindex;
63*c2c26c8bSAndroid Build Coastguard Worker
64*c2c26c8bSAndroid Build Coastguard Worker if (!(newindex = if_nametoindex(bridge->iface))) {
65*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
66*c2c26c8bSAndroid Build Coastguard Worker return 0;
67*c2c26c8bSAndroid Build Coastguard Worker } else {
68*c2c26c8bSAndroid Build Coastguard Worker *indexp = newindex;
69*c2c26c8bSAndroid Build Coastguard Worker strncpy(name, bridge->iface, IF_NAMESIZE);
70*c2c26c8bSAndroid Build Coastguard Worker break;
71*c2c26c8bSAndroid Build Coastguard Worker }
72*c2c26c8bSAndroid Build Coastguard Worker }
73*c2c26c8bSAndroid Build Coastguard Worker if (alias) break;
74*c2c26c8bSAndroid Build Coastguard Worker }
75*c2c26c8bSAndroid Build Coastguard Worker }
76*c2c26c8bSAndroid Build Coastguard Worker
77*c2c26c8bSAndroid Build Coastguard Worker if (daemon->if_names || (addr && daemon->if_addrs)) {
78*c2c26c8bSAndroid Build Coastguard Worker ret = 0;
79*c2c26c8bSAndroid Build Coastguard Worker
80*c2c26c8bSAndroid Build Coastguard Worker for (tmp = daemon->if_names; tmp; tmp = tmp->next)
81*c2c26c8bSAndroid Build Coastguard Worker if (tmp->name && (strcmp(tmp->name, name) == 0)) ret = tmp->used = 1;
82*c2c26c8bSAndroid Build Coastguard Worker
83*c2c26c8bSAndroid Build Coastguard Worker for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
84*c2c26c8bSAndroid Build Coastguard Worker if (addr && tmp->addr.sa.sa_family == family) {
85*c2c26c8bSAndroid Build Coastguard Worker if (family == AF_INET && tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
86*c2c26c8bSAndroid Build Coastguard Worker ret = tmp->used = 1;
87*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
88*c2c26c8bSAndroid Build Coastguard Worker else if (family == AF_INET6 &&
89*c2c26c8bSAndroid Build Coastguard Worker IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6) &&
90*c2c26c8bSAndroid Build Coastguard Worker (!IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6) ||
91*c2c26c8bSAndroid Build Coastguard Worker (tmp->addr.in6.sin6_scope_id == (uint32_t) *indexp)))
92*c2c26c8bSAndroid Build Coastguard Worker ret = tmp->used = 1;
93*c2c26c8bSAndroid Build Coastguard Worker #endif
94*c2c26c8bSAndroid Build Coastguard Worker }
95*c2c26c8bSAndroid Build Coastguard Worker }
96*c2c26c8bSAndroid Build Coastguard Worker
97*c2c26c8bSAndroid Build Coastguard Worker for (tmp = daemon->if_except; tmp; tmp = tmp->next)
98*c2c26c8bSAndroid Build Coastguard Worker if (tmp->name && (strcmp(tmp->name, name) == 0)) ret = 0;
99*c2c26c8bSAndroid Build Coastguard Worker
100*c2c26c8bSAndroid Build Coastguard Worker return ret;
101*c2c26c8bSAndroid Build Coastguard Worker }
102*c2c26c8bSAndroid Build Coastguard Worker
iface_allowed(struct irec ** irecp,int if_index,union mysockaddr * addr,struct in_addr netmask)103*c2c26c8bSAndroid Build Coastguard Worker static int iface_allowed(struct irec** irecp, int if_index, union mysockaddr* addr,
104*c2c26c8bSAndroid Build Coastguard Worker struct in_addr netmask) {
105*c2c26c8bSAndroid Build Coastguard Worker struct irec* iface;
106*c2c26c8bSAndroid Build Coastguard Worker int fd, mtu = 0, loopback;
107*c2c26c8bSAndroid Build Coastguard Worker struct ifreq ifr;
108*c2c26c8bSAndroid Build Coastguard Worker int dhcp_ok = 1;
109*c2c26c8bSAndroid Build Coastguard Worker struct iname* tmp;
110*c2c26c8bSAndroid Build Coastguard Worker
111*c2c26c8bSAndroid Build Coastguard Worker /* check whether the interface IP has been added already
112*c2c26c8bSAndroid Build Coastguard Worker we call this routine multiple times. */
113*c2c26c8bSAndroid Build Coastguard Worker for (iface = *irecp; iface; iface = iface->next)
114*c2c26c8bSAndroid Build Coastguard Worker if (sockaddr_isequal(&iface->addr, addr)) return 1;
115*c2c26c8bSAndroid Build Coastguard Worker
116*c2c26c8bSAndroid Build Coastguard Worker if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 || !indextoname(fd, if_index, ifr.ifr_name) ||
117*c2c26c8bSAndroid Build Coastguard Worker ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
118*c2c26c8bSAndroid Build Coastguard Worker if (fd != -1) {
119*c2c26c8bSAndroid Build Coastguard Worker int errsave = errno;
120*c2c26c8bSAndroid Build Coastguard Worker close(fd);
121*c2c26c8bSAndroid Build Coastguard Worker errno = errsave;
122*c2c26c8bSAndroid Build Coastguard Worker }
123*c2c26c8bSAndroid Build Coastguard Worker return 0;
124*c2c26c8bSAndroid Build Coastguard Worker }
125*c2c26c8bSAndroid Build Coastguard Worker
126*c2c26c8bSAndroid Build Coastguard Worker loopback = ifr.ifr_flags & IFF_LOOPBACK;
127*c2c26c8bSAndroid Build Coastguard Worker
128*c2c26c8bSAndroid Build Coastguard Worker if (ioctl(fd, SIOCGIFMTU, &ifr) != -1) mtu = ifr.ifr_mtu;
129*c2c26c8bSAndroid Build Coastguard Worker
130*c2c26c8bSAndroid Build Coastguard Worker close(fd);
131*c2c26c8bSAndroid Build Coastguard Worker
132*c2c26c8bSAndroid Build Coastguard Worker /* If we are restricting the set of interfaces to use, make
133*c2c26c8bSAndroid Build Coastguard Worker sure that loopback interfaces are in that set. */
134*c2c26c8bSAndroid Build Coastguard Worker if (daemon->if_names && loopback) {
135*c2c26c8bSAndroid Build Coastguard Worker struct iname* lo;
136*c2c26c8bSAndroid Build Coastguard Worker for (lo = daemon->if_names; lo; lo = lo->next)
137*c2c26c8bSAndroid Build Coastguard Worker if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0) {
138*c2c26c8bSAndroid Build Coastguard Worker lo->isloop = 1;
139*c2c26c8bSAndroid Build Coastguard Worker break;
140*c2c26c8bSAndroid Build Coastguard Worker }
141*c2c26c8bSAndroid Build Coastguard Worker
142*c2c26c8bSAndroid Build Coastguard Worker if (!lo && (lo = whine_malloc(sizeof(struct iname))) &&
143*c2c26c8bSAndroid Build Coastguard Worker (lo->name = whine_malloc(strlen(ifr.ifr_name) + 1))) {
144*c2c26c8bSAndroid Build Coastguard Worker strcpy(lo->name, ifr.ifr_name);
145*c2c26c8bSAndroid Build Coastguard Worker lo->isloop = lo->used = 1;
146*c2c26c8bSAndroid Build Coastguard Worker lo->next = daemon->if_names;
147*c2c26c8bSAndroid Build Coastguard Worker daemon->if_names = lo;
148*c2c26c8bSAndroid Build Coastguard Worker }
149*c2c26c8bSAndroid Build Coastguard Worker }
150*c2c26c8bSAndroid Build Coastguard Worker
151*c2c26c8bSAndroid Build Coastguard Worker if (addr->sa.sa_family == AF_INET &&
152*c2c26c8bSAndroid Build Coastguard Worker !iface_check(AF_INET, (struct all_addr*) &addr->in.sin_addr, ifr.ifr_name, NULL))
153*c2c26c8bSAndroid Build Coastguard Worker return 1;
154*c2c26c8bSAndroid Build Coastguard Worker
155*c2c26c8bSAndroid Build Coastguard Worker for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
156*c2c26c8bSAndroid Build Coastguard Worker if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) dhcp_ok = 0;
157*c2c26c8bSAndroid Build Coastguard Worker
158*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
159*c2c26c8bSAndroid Build Coastguard Worker int ifindex = (int) addr->in6.sin6_scope_id;
160*c2c26c8bSAndroid Build Coastguard Worker if (addr->sa.sa_family == AF_INET6 &&
161*c2c26c8bSAndroid Build Coastguard Worker !iface_check(AF_INET6, (struct all_addr*) &addr->in6.sin6_addr, ifr.ifr_name, &ifindex))
162*c2c26c8bSAndroid Build Coastguard Worker return 1;
163*c2c26c8bSAndroid Build Coastguard Worker #endif
164*c2c26c8bSAndroid Build Coastguard Worker
165*c2c26c8bSAndroid Build Coastguard Worker /* add to list */
166*c2c26c8bSAndroid Build Coastguard Worker if ((iface = whine_malloc(sizeof(struct irec)))) {
167*c2c26c8bSAndroid Build Coastguard Worker iface->addr = *addr;
168*c2c26c8bSAndroid Build Coastguard Worker iface->netmask = netmask;
169*c2c26c8bSAndroid Build Coastguard Worker iface->dhcp_ok = dhcp_ok;
170*c2c26c8bSAndroid Build Coastguard Worker iface->mtu = mtu;
171*c2c26c8bSAndroid Build Coastguard Worker iface->next = *irecp;
172*c2c26c8bSAndroid Build Coastguard Worker *irecp = iface;
173*c2c26c8bSAndroid Build Coastguard Worker return 1;
174*c2c26c8bSAndroid Build Coastguard Worker }
175*c2c26c8bSAndroid Build Coastguard Worker
176*c2c26c8bSAndroid Build Coastguard Worker errno = ENOMEM;
177*c2c26c8bSAndroid Build Coastguard Worker return 0;
178*c2c26c8bSAndroid Build Coastguard Worker }
179*c2c26c8bSAndroid Build Coastguard Worker
180*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
iface_allowed_v6(struct in6_addr * local,int scope,int if_index,void * vparam)181*c2c26c8bSAndroid Build Coastguard Worker static int iface_allowed_v6(struct in6_addr* local, int scope, int if_index, void* vparam) {
182*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr;
183*c2c26c8bSAndroid Build Coastguard Worker struct in_addr netmask; /* unused */
184*c2c26c8bSAndroid Build Coastguard Worker
185*c2c26c8bSAndroid Build Coastguard Worker netmask.s_addr = 0;
186*c2c26c8bSAndroid Build Coastguard Worker
187*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
188*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_family = AF_INET6;
189*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_addr = *local;
190*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_port = htons(daemon->port);
191*c2c26c8bSAndroid Build Coastguard Worker /**
192*c2c26c8bSAndroid Build Coastguard Worker * Only populate the scope ID if the address is link-local.
193*c2c26c8bSAndroid Build Coastguard Worker * Scope IDs are not meaningful for global addresses. Also, we do not want to
194*c2c26c8bSAndroid Build Coastguard Worker * think that two addresses are different if they differ only in scope ID,
195*c2c26c8bSAndroid Build Coastguard Worker * because the kernel will treat them as if they are the same.
196*c2c26c8bSAndroid Build Coastguard Worker */
197*c2c26c8bSAndroid Build Coastguard Worker if (IN6_IS_ADDR_LINKLOCAL(local)) {
198*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_scope_id = scope;
199*c2c26c8bSAndroid Build Coastguard Worker }
200*c2c26c8bSAndroid Build Coastguard Worker
201*c2c26c8bSAndroid Build Coastguard Worker return iface_allowed((struct irec**) vparam, if_index, &addr, netmask);
202*c2c26c8bSAndroid Build Coastguard Worker }
203*c2c26c8bSAndroid Build Coastguard Worker #endif
204*c2c26c8bSAndroid Build Coastguard Worker
iface_allowed_v4(struct in_addr local,int if_index,struct in_addr netmask,struct in_addr broadcast,void * vparam)205*c2c26c8bSAndroid Build Coastguard Worker static int iface_allowed_v4(struct in_addr local, int if_index, struct in_addr netmask,
206*c2c26c8bSAndroid Build Coastguard Worker struct in_addr broadcast, void* vparam) {
207*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr;
208*c2c26c8bSAndroid Build Coastguard Worker
209*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
210*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_family = AF_INET;
211*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_addr = broadcast; /* warning */
212*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_addr = local;
213*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_port = htons(daemon->port);
214*c2c26c8bSAndroid Build Coastguard Worker
215*c2c26c8bSAndroid Build Coastguard Worker return iface_allowed((struct irec**) vparam, if_index, &addr, netmask);
216*c2c26c8bSAndroid Build Coastguard Worker }
217*c2c26c8bSAndroid Build Coastguard Worker
enumerate_interfaces(void)218*c2c26c8bSAndroid Build Coastguard Worker int enumerate_interfaces(void) {
219*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
220*c2c26c8bSAndroid Build Coastguard Worker return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
221*c2c26c8bSAndroid Build Coastguard Worker #else
222*c2c26c8bSAndroid Build Coastguard Worker return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
223*c2c26c8bSAndroid Build Coastguard Worker #endif
224*c2c26c8bSAndroid Build Coastguard Worker }
225*c2c26c8bSAndroid Build Coastguard Worker
226*c2c26c8bSAndroid Build Coastguard Worker /* set NONBLOCK bit on fd: See Stevens 16.6 */
fix_fd(int fd)227*c2c26c8bSAndroid Build Coastguard Worker int fix_fd(int fd) {
228*c2c26c8bSAndroid Build Coastguard Worker int flags;
229*c2c26c8bSAndroid Build Coastguard Worker
230*c2c26c8bSAndroid Build Coastguard Worker if ((flags = fcntl(fd, F_GETFL)) == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
231*c2c26c8bSAndroid Build Coastguard Worker return 0;
232*c2c26c8bSAndroid Build Coastguard Worker
233*c2c26c8bSAndroid Build Coastguard Worker return 1;
234*c2c26c8bSAndroid Build Coastguard Worker }
235*c2c26c8bSAndroid Build Coastguard Worker
236*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_IPV6)
create_ipv6_listener(struct listener ** link,int port)237*c2c26c8bSAndroid Build Coastguard Worker static int create_ipv6_listener(struct listener** link, int port) {
238*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr;
239*c2c26c8bSAndroid Build Coastguard Worker int tcpfd, fd;
240*c2c26c8bSAndroid Build Coastguard Worker struct listener* l;
241*c2c26c8bSAndroid Build Coastguard Worker int opt = 1;
242*c2c26c8bSAndroid Build Coastguard Worker
243*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
244*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_family = AF_INET6;
245*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_addr = in6addr_any;
246*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_port = htons(port);
247*c2c26c8bSAndroid Build Coastguard Worker
248*c2c26c8bSAndroid Build Coastguard Worker /* No error of the kernel doesn't support IPv6 */
249*c2c26c8bSAndroid Build Coastguard Worker if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
250*c2c26c8bSAndroid Build Coastguard Worker return (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT || errno == EINVAL);
251*c2c26c8bSAndroid Build Coastguard Worker
252*c2c26c8bSAndroid Build Coastguard Worker if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) return 0;
253*c2c26c8bSAndroid Build Coastguard Worker
254*c2c26c8bSAndroid Build Coastguard Worker if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
255*c2c26c8bSAndroid Build Coastguard Worker setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
256*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
257*c2c26c8bSAndroid Build Coastguard Worker setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 || !fix_fd(fd) ||
258*c2c26c8bSAndroid Build Coastguard Worker !fix_fd(tcpfd) ||
259*c2c26c8bSAndroid Build Coastguard Worker #ifdef IPV6_RECVPKTINFO
260*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
261*c2c26c8bSAndroid Build Coastguard Worker #else
262*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
263*c2c26c8bSAndroid Build Coastguard Worker #endif
264*c2c26c8bSAndroid Build Coastguard Worker bind(tcpfd, (struct sockaddr*) &addr, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 ||
265*c2c26c8bSAndroid Build Coastguard Worker bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == -1)
266*c2c26c8bSAndroid Build Coastguard Worker return 0;
267*c2c26c8bSAndroid Build Coastguard Worker
268*c2c26c8bSAndroid Build Coastguard Worker l = safe_malloc(sizeof(struct listener));
269*c2c26c8bSAndroid Build Coastguard Worker l->fd = fd;
270*c2c26c8bSAndroid Build Coastguard Worker l->tcpfd = tcpfd;
271*c2c26c8bSAndroid Build Coastguard Worker l->family = AF_INET6;
272*c2c26c8bSAndroid Build Coastguard Worker l->iface = NULL;
273*c2c26c8bSAndroid Build Coastguard Worker l->next = NULL;
274*c2c26c8bSAndroid Build Coastguard Worker *link = l;
275*c2c26c8bSAndroid Build Coastguard Worker
276*c2c26c8bSAndroid Build Coastguard Worker return 1;
277*c2c26c8bSAndroid Build Coastguard Worker }
278*c2c26c8bSAndroid Build Coastguard Worker #endif
279*c2c26c8bSAndroid Build Coastguard Worker
create_wildcard_listeners(void)280*c2c26c8bSAndroid Build Coastguard Worker struct listener* create_wildcard_listeners(void) {
281*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr;
282*c2c26c8bSAndroid Build Coastguard Worker int opt = 1;
283*c2c26c8bSAndroid Build Coastguard Worker struct listener *l, *l6 = NULL;
284*c2c26c8bSAndroid Build Coastguard Worker int tcpfd = -1, fd = -1;
285*c2c26c8bSAndroid Build Coastguard Worker
286*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
287*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_family = AF_INET;
288*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_addr.s_addr = INADDR_ANY;
289*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_port = htons(daemon->port);
290*c2c26c8bSAndroid Build Coastguard Worker
291*c2c26c8bSAndroid Build Coastguard Worker if (daemon->port != 0) {
292*c2c26c8bSAndroid Build Coastguard Worker if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
293*c2c26c8bSAndroid Build Coastguard Worker (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
294*c2c26c8bSAndroid Build Coastguard Worker return NULL;
295*c2c26c8bSAndroid Build Coastguard Worker
296*c2c26c8bSAndroid Build Coastguard Worker if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
297*c2c26c8bSAndroid Build Coastguard Worker bind(tcpfd, (struct sockaddr*) &addr, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 ||
298*c2c26c8bSAndroid Build Coastguard Worker !fix_fd(tcpfd) ||
299*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
300*c2c26c8bSAndroid Build Coastguard Worker !create_ipv6_listener(&l6, daemon->port) ||
301*c2c26c8bSAndroid Build Coastguard Worker #endif
302*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd) ||
303*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_NETWORK)
304*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
305*c2c26c8bSAndroid Build Coastguard Worker #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
306*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
307*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
308*c2c26c8bSAndroid Build Coastguard Worker #endif
309*c2c26c8bSAndroid Build Coastguard Worker bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == -1)
310*c2c26c8bSAndroid Build Coastguard Worker return NULL;
311*c2c26c8bSAndroid Build Coastguard Worker
312*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
313*c2c26c8bSAndroid Build Coastguard Worker uint32_t mark = daemon->listen_mark;
314*c2c26c8bSAndroid Build Coastguard Worker if (mark != 0 && (setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
315*c2c26c8bSAndroid Build Coastguard Worker setsockopt(tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
316*c2c26c8bSAndroid Build Coastguard Worker setsockopt(l6->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
317*c2c26c8bSAndroid Build Coastguard Worker setsockopt(l6->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)) {
318*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_WARNING, _("setsockopt(SO_MARK, 0x%x: %s"), mark, strerror(errno));
319*c2c26c8bSAndroid Build Coastguard Worker close(fd);
320*c2c26c8bSAndroid Build Coastguard Worker close(tcpfd);
321*c2c26c8bSAndroid Build Coastguard Worker close(l6->fd);
322*c2c26c8bSAndroid Build Coastguard Worker close(l6->tcpfd);
323*c2c26c8bSAndroid Build Coastguard Worker return NULL;
324*c2c26c8bSAndroid Build Coastguard Worker }
325*c2c26c8bSAndroid Build Coastguard Worker }
326*c2c26c8bSAndroid Build Coastguard Worker #endif /* __ANDROID__ */
327*c2c26c8bSAndroid Build Coastguard Worker
328*c2c26c8bSAndroid Build Coastguard Worker l = safe_malloc(sizeof(struct listener));
329*c2c26c8bSAndroid Build Coastguard Worker l->family = AF_INET;
330*c2c26c8bSAndroid Build Coastguard Worker l->fd = fd;
331*c2c26c8bSAndroid Build Coastguard Worker l->tcpfd = tcpfd;
332*c2c26c8bSAndroid Build Coastguard Worker l->iface = NULL;
333*c2c26c8bSAndroid Build Coastguard Worker l->next = l6;
334*c2c26c8bSAndroid Build Coastguard Worker
335*c2c26c8bSAndroid Build Coastguard Worker return l;
336*c2c26c8bSAndroid Build Coastguard Worker }
337*c2c26c8bSAndroid Build Coastguard Worker
338*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
339*c2c26c8bSAndroid Build Coastguard Worker /**
340*c2c26c8bSAndroid Build Coastguard Worker * for a single given irec (interface name and address) create
341*c2c26c8bSAndroid Build Coastguard Worker * a set of sockets listening. This is a copy of the code inside the loop
342*c2c26c8bSAndroid Build Coastguard Worker * of create_bound_listeners below and is added here to allow us
343*c2c26c8bSAndroid Build Coastguard Worker * to create just a single new listener dynamically when our interface
344*c2c26c8bSAndroid Build Coastguard Worker * list is changed.
345*c2c26c8bSAndroid Build Coastguard Worker *
346*c2c26c8bSAndroid Build Coastguard Worker * iface - input of the new interface details to listen on
347*c2c26c8bSAndroid Build Coastguard Worker * listeners - output. Creates a new struct listener and inserts at head of the list
348*c2c26c8bSAndroid Build Coastguard Worker *
349*c2c26c8bSAndroid Build Coastguard Worker * die's on errors, so don't pass bad data.
350*c2c26c8bSAndroid Build Coastguard Worker */
create_bound_listener(struct listener ** listeners,struct irec * iface)351*c2c26c8bSAndroid Build Coastguard Worker void create_bound_listener(struct listener** listeners, struct irec* iface) {
352*c2c26c8bSAndroid Build Coastguard Worker int rc, opt = 1;
353*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
354*c2c26c8bSAndroid Build Coastguard Worker static int dad_count = 0;
355*c2c26c8bSAndroid Build Coastguard Worker #endif
356*c2c26c8bSAndroid Build Coastguard Worker
357*c2c26c8bSAndroid Build Coastguard Worker struct listener* new = safe_malloc(sizeof(struct listener));
358*c2c26c8bSAndroid Build Coastguard Worker new->family = iface->addr.sa.sa_family;
359*c2c26c8bSAndroid Build Coastguard Worker new->iface = iface;
360*c2c26c8bSAndroid Build Coastguard Worker new->next = *listeners;
361*c2c26c8bSAndroid Build Coastguard Worker new->tcpfd = -1;
362*c2c26c8bSAndroid Build Coastguard Worker new->fd = -1;
363*c2c26c8bSAndroid Build Coastguard Worker
364*c2c26c8bSAndroid Build Coastguard Worker if (daemon->port != 0) {
365*c2c26c8bSAndroid Build Coastguard Worker if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
366*c2c26c8bSAndroid Build Coastguard Worker (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
367*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
368*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
369*c2c26c8bSAndroid Build Coastguard Worker !fix_fd(new->tcpfd) || !fix_fd(new->fd))
370*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
371*c2c26c8bSAndroid Build Coastguard Worker
372*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
373*c2c26c8bSAndroid Build Coastguard Worker if (iface->addr.sa.sa_family == AF_INET6) {
374*c2c26c8bSAndroid Build Coastguard Worker if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
375*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
376*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
377*c2c26c8bSAndroid Build Coastguard Worker }
378*c2c26c8bSAndroid Build Coastguard Worker #endif
379*c2c26c8bSAndroid Build Coastguard Worker
380*c2c26c8bSAndroid Build Coastguard Worker /* Unless the IPv6 address is added with IFA_F_NODAD, bind() can fail even if DAD
381*c2c26c8bSAndroid Build Coastguard Worker is disabled on the interface. This is because without IFA_F_NODAD the IPv6
382*c2c26c8bSAndroid Build Coastguard Worker address creation call moves the IPv6 address to tentative. A timer will
383*c2c26c8bSAndroid Build Coastguard Worker fire to immediately remove the tentative flag, but this is not sufficient to
384*c2c26c8bSAndroid Build Coastguard Worker avoid a race condition (see comments in tun_interface.cpp and iproute.py). */
385*c2c26c8bSAndroid Build Coastguard Worker while (1) {
386*c2c26c8bSAndroid Build Coastguard Worker if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break;
387*c2c26c8bSAndroid Build Coastguard Worker
388*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
389*c2c26c8bSAndroid Build Coastguard Worker /* An interface may have an IPv6 address which is still undergoing DAD.
390*c2c26c8bSAndroid Build Coastguard Worker If so, the bind will fail until the DAD completes, so we try again
391*c2c26c8bSAndroid Build Coastguard Worker before failing. */
392*c2c26c8bSAndroid Build Coastguard Worker /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so
393*c2c26c8bSAndroid Build Coastguard Worker bind() will only fail if the address has already failed DAD, in which case retrying
394*c2c26c8bSAndroid Build Coastguard Worker won't help. */
395*c2c26c8bSAndroid Build Coastguard Worker if (iface->addr.sa.sa_family == AF_INET6 &&
396*c2c26c8bSAndroid Build Coastguard Worker (errno == ENODEV || errno == EADDRNOTAVAIL) && dad_count++ < DAD_WAIT) {
397*c2c26c8bSAndroid Build Coastguard Worker sleep(1);
398*c2c26c8bSAndroid Build Coastguard Worker continue;
399*c2c26c8bSAndroid Build Coastguard Worker }
400*c2c26c8bSAndroid Build Coastguard Worker #endif
401*c2c26c8bSAndroid Build Coastguard Worker break;
402*c2c26c8bSAndroid Build Coastguard Worker }
403*c2c26c8bSAndroid Build Coastguard Worker
404*c2c26c8bSAndroid Build Coastguard Worker if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) {
405*c2c26c8bSAndroid Build Coastguard Worker prettyprint_addr(&iface->addr, daemon->namebuff);
406*c2c26c8bSAndroid Build Coastguard Worker close(new->fd);
407*c2c26c8bSAndroid Build Coastguard Worker close(new->tcpfd);
408*c2c26c8bSAndroid Build Coastguard Worker free(new);
409*c2c26c8bSAndroid Build Coastguard Worker syslog(LOG_ERR, _("failed to bind listening socket for %s"), daemon->namebuff);
410*c2c26c8bSAndroid Build Coastguard Worker return;
411*c2c26c8bSAndroid Build Coastguard Worker }
412*c2c26c8bSAndroid Build Coastguard Worker
413*c2c26c8bSAndroid Build Coastguard Worker uint32_t mark = daemon->listen_mark;
414*c2c26c8bSAndroid Build Coastguard Worker if (mark != 0 && (setsockopt(new->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
415*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1))
416*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to set SO_MARK on listen socket: %s"), NULL, EC_BADNET);
417*c2c26c8bSAndroid Build Coastguard Worker
418*c2c26c8bSAndroid Build Coastguard Worker if (listen(new->tcpfd, 5) == -1) die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
419*c2c26c8bSAndroid Build Coastguard Worker }
420*c2c26c8bSAndroid Build Coastguard Worker *listeners = new;
421*c2c26c8bSAndroid Build Coastguard Worker }
422*c2c26c8bSAndroid Build Coastguard Worker
423*c2c26c8bSAndroid Build Coastguard Worker /**
424*c2c26c8bSAndroid Build Coastguard Worker * If a listener has a struct irec pointer whose address matches the newly
425*c2c26c8bSAndroid Build Coastguard Worker * malloc()d struct irec's address, update its pointer to refer to this new
426*c2c26c8bSAndroid Build Coastguard Worker * struct irec instance.
427*c2c26c8bSAndroid Build Coastguard Worker *
428*c2c26c8bSAndroid Build Coastguard Worker * Otherwise, any listeners that are preserved across interface list changes
429*c2c26c8bSAndroid Build Coastguard Worker * will point at interface structures that are free()d at the end of
430*c2c26c8bSAndroid Build Coastguard Worker * set_interfaces(), and can get overwritten by subsequent memory allocations.
431*c2c26c8bSAndroid Build Coastguard Worker *
432*c2c26c8bSAndroid Build Coastguard Worker * See b/17475756 for further discussion.
433*c2c26c8bSAndroid Build Coastguard Worker */
fixup_possible_existing_listener(struct irec * new_iface)434*c2c26c8bSAndroid Build Coastguard Worker void fixup_possible_existing_listener(struct irec* new_iface) {
435*c2c26c8bSAndroid Build Coastguard Worker /* find the listener, if present */
436*c2c26c8bSAndroid Build Coastguard Worker struct listener* l;
437*c2c26c8bSAndroid Build Coastguard Worker for (l = daemon->listeners; l; l = l->next) {
438*c2c26c8bSAndroid Build Coastguard Worker struct irec* listener_iface = l->iface;
439*c2c26c8bSAndroid Build Coastguard Worker if (listener_iface) {
440*c2c26c8bSAndroid Build Coastguard Worker if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
441*c2c26c8bSAndroid Build Coastguard Worker l->iface = new_iface;
442*c2c26c8bSAndroid Build Coastguard Worker return;
443*c2c26c8bSAndroid Build Coastguard Worker }
444*c2c26c8bSAndroid Build Coastguard Worker }
445*c2c26c8bSAndroid Build Coastguard Worker }
446*c2c26c8bSAndroid Build Coastguard Worker }
447*c2c26c8bSAndroid Build Coastguard Worker
448*c2c26c8bSAndroid Build Coastguard Worker /**
449*c2c26c8bSAndroid Build Coastguard Worker * Closes the sockets of the specified listener, deletes it from the list, and frees it.
450*c2c26c8bSAndroid Build Coastguard Worker *
451*c2c26c8bSAndroid Build Coastguard Worker */
delete_listener(struct listener ** l)452*c2c26c8bSAndroid Build Coastguard Worker int delete_listener(struct listener** l) {
453*c2c26c8bSAndroid Build Coastguard Worker struct listener* listener = *l;
454*c2c26c8bSAndroid Build Coastguard Worker if (listener == NULL) return 0;
455*c2c26c8bSAndroid Build Coastguard Worker
456*c2c26c8bSAndroid Build Coastguard Worker if (listener->iface) {
457*c2c26c8bSAndroid Build Coastguard Worker int port = prettyprint_addr(&listener->iface->addr, daemon->namebuff);
458*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_INFO, _("Closing listener [%s]:%d"), daemon->namebuff, port);
459*c2c26c8bSAndroid Build Coastguard Worker } else {
460*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_INFO, _("Closing wildcard listener family=%d"), listener->family);
461*c2c26c8bSAndroid Build Coastguard Worker }
462*c2c26c8bSAndroid Build Coastguard Worker
463*c2c26c8bSAndroid Build Coastguard Worker if (listener->tcpfd != -1) {
464*c2c26c8bSAndroid Build Coastguard Worker close(listener->tcpfd);
465*c2c26c8bSAndroid Build Coastguard Worker listener->tcpfd = -1;
466*c2c26c8bSAndroid Build Coastguard Worker }
467*c2c26c8bSAndroid Build Coastguard Worker if (listener->fd != -1) {
468*c2c26c8bSAndroid Build Coastguard Worker close(listener->fd);
469*c2c26c8bSAndroid Build Coastguard Worker listener->fd = -1;
470*c2c26c8bSAndroid Build Coastguard Worker }
471*c2c26c8bSAndroid Build Coastguard Worker *l = listener->next;
472*c2c26c8bSAndroid Build Coastguard Worker free(listener);
473*c2c26c8bSAndroid Build Coastguard Worker return -1;
474*c2c26c8bSAndroid Build Coastguard Worker }
475*c2c26c8bSAndroid Build Coastguard Worker
476*c2c26c8bSAndroid Build Coastguard Worker /**
477*c2c26c8bSAndroid Build Coastguard Worker * Close the sockets listening on the given interface
478*c2c26c8bSAndroid Build Coastguard Worker *
479*c2c26c8bSAndroid Build Coastguard Worker * This new function is needed as we're dynamically changing the interfaces
480*c2c26c8bSAndroid Build Coastguard Worker * we listen on. Before they'd be opened once in create_bound_listeners and stay
481*c2c26c8bSAndroid Build Coastguard Worker * until we exited. Now, if an interface moves off the to-listen list we need to
482*c2c26c8bSAndroid Build Coastguard Worker * close out the listeners and keep trucking.
483*c2c26c8bSAndroid Build Coastguard Worker *
484*c2c26c8bSAndroid Build Coastguard Worker * interface - input of the interface details to listen on
485*c2c26c8bSAndroid Build Coastguard Worker */
close_bound_listener(struct irec * iface)486*c2c26c8bSAndroid Build Coastguard Worker int close_bound_listener(struct irec* iface) {
487*c2c26c8bSAndroid Build Coastguard Worker /* find the listener */
488*c2c26c8bSAndroid Build Coastguard Worker int ret = 0;
489*c2c26c8bSAndroid Build Coastguard Worker struct listener** l = &daemon->listeners;
490*c2c26c8bSAndroid Build Coastguard Worker while (*l) {
491*c2c26c8bSAndroid Build Coastguard Worker struct irec* listener_iface = (*l)->iface;
492*c2c26c8bSAndroid Build Coastguard Worker struct listener** next = &((*l)->next);
493*c2c26c8bSAndroid Build Coastguard Worker if (iface && listener_iface && sockaddr_isequal(&listener_iface->addr, &iface->addr)) {
494*c2c26c8bSAndroid Build Coastguard Worker // Listener bound to an IP address. There can be only one of these.
495*c2c26c8bSAndroid Build Coastguard Worker ret = delete_listener(l);
496*c2c26c8bSAndroid Build Coastguard Worker break;
497*c2c26c8bSAndroid Build Coastguard Worker }
498*c2c26c8bSAndroid Build Coastguard Worker if (iface == NULL && listener_iface == NULL) {
499*c2c26c8bSAndroid Build Coastguard Worker // Wildcard listener. There is one of these per address family.
500*c2c26c8bSAndroid Build Coastguard Worker ret = delete_listener(l);
501*c2c26c8bSAndroid Build Coastguard Worker continue;
502*c2c26c8bSAndroid Build Coastguard Worker }
503*c2c26c8bSAndroid Build Coastguard Worker l = next;
504*c2c26c8bSAndroid Build Coastguard Worker }
505*c2c26c8bSAndroid Build Coastguard Worker return ret;
506*c2c26c8bSAndroid Build Coastguard Worker }
507*c2c26c8bSAndroid Build Coastguard Worker #endif /* __ANDROID__ */
508*c2c26c8bSAndroid Build Coastguard Worker
create_bound_listeners(void)509*c2c26c8bSAndroid Build Coastguard Worker struct listener* create_bound_listeners(void) {
510*c2c26c8bSAndroid Build Coastguard Worker struct listener* listeners = NULL;
511*c2c26c8bSAndroid Build Coastguard Worker struct irec* iface;
512*c2c26c8bSAndroid Build Coastguard Worker #ifndef __ANDROID__
513*c2c26c8bSAndroid Build Coastguard Worker int rc, opt = 1;
514*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
515*c2c26c8bSAndroid Build Coastguard Worker static int dad_count = 0;
516*c2c26c8bSAndroid Build Coastguard Worker #endif
517*c2c26c8bSAndroid Build Coastguard Worker #endif
518*c2c26c8bSAndroid Build Coastguard Worker
519*c2c26c8bSAndroid Build Coastguard Worker for (iface = daemon->interfaces; iface; iface = iface->next) {
520*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
521*c2c26c8bSAndroid Build Coastguard Worker create_bound_listener(&listeners, iface);
522*c2c26c8bSAndroid Build Coastguard Worker #else
523*c2c26c8bSAndroid Build Coastguard Worker struct listener* new = safe_malloc(sizeof(struct listener));
524*c2c26c8bSAndroid Build Coastguard Worker new->family = iface->addr.sa.sa_family;
525*c2c26c8bSAndroid Build Coastguard Worker new->iface = iface;
526*c2c26c8bSAndroid Build Coastguard Worker new->next = listeners;
527*c2c26c8bSAndroid Build Coastguard Worker new->tcpfd = -1;
528*c2c26c8bSAndroid Build Coastguard Worker new->fd = -1;
529*c2c26c8bSAndroid Build Coastguard Worker listeners = new;
530*c2c26c8bSAndroid Build Coastguard Worker
531*c2c26c8bSAndroid Build Coastguard Worker if (daemon->port != 0) {
532*c2c26c8bSAndroid Build Coastguard Worker if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
533*c2c26c8bSAndroid Build Coastguard Worker (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
534*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
535*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
536*c2c26c8bSAndroid Build Coastguard Worker !fix_fd(new->tcpfd) || !fix_fd(new->fd))
537*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
538*c2c26c8bSAndroid Build Coastguard Worker
539*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
540*c2c26c8bSAndroid Build Coastguard Worker if (iface->addr.sa.sa_family == AF_INET6) {
541*c2c26c8bSAndroid Build Coastguard Worker if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
542*c2c26c8bSAndroid Build Coastguard Worker setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
543*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to set IPV6 options on listening socket: %s"), NULL,
544*c2c26c8bSAndroid Build Coastguard Worker EC_BADNET);
545*c2c26c8bSAndroid Build Coastguard Worker }
546*c2c26c8bSAndroid Build Coastguard Worker #endif
547*c2c26c8bSAndroid Build Coastguard Worker
548*c2c26c8bSAndroid Build Coastguard Worker while (1) {
549*c2c26c8bSAndroid Build Coastguard Worker if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break;
550*c2c26c8bSAndroid Build Coastguard Worker
551*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
552*c2c26c8bSAndroid Build Coastguard Worker /* An interface may have an IPv6 address which is still undergoing DAD.
553*c2c26c8bSAndroid Build Coastguard Worker If so, the bind will fail until the DAD completes, so we try over 20 seconds
554*c2c26c8bSAndroid Build Coastguard Worker before failing. */
555*c2c26c8bSAndroid Build Coastguard Worker if (iface->addr.sa.sa_family == AF_INET6 &&
556*c2c26c8bSAndroid Build Coastguard Worker (errno == ENODEV || errno == EADDRNOTAVAIL) && dad_count++ < DAD_WAIT) {
557*c2c26c8bSAndroid Build Coastguard Worker sleep(1);
558*c2c26c8bSAndroid Build Coastguard Worker continue;
559*c2c26c8bSAndroid Build Coastguard Worker }
560*c2c26c8bSAndroid Build Coastguard Worker #endif
561*c2c26c8bSAndroid Build Coastguard Worker break;
562*c2c26c8bSAndroid Build Coastguard Worker }
563*c2c26c8bSAndroid Build Coastguard Worker
564*c2c26c8bSAndroid Build Coastguard Worker if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) {
565*c2c26c8bSAndroid Build Coastguard Worker prettyprint_addr(&iface->addr, daemon->namebuff);
566*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to bind listening socket for %s: %s"), daemon->namebuff,
567*c2c26c8bSAndroid Build Coastguard Worker EC_BADNET);
568*c2c26c8bSAndroid Build Coastguard Worker }
569*c2c26c8bSAndroid Build Coastguard Worker
570*c2c26c8bSAndroid Build Coastguard Worker if (listen(new->tcpfd, 5) == -1)
571*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
572*c2c26c8bSAndroid Build Coastguard Worker }
573*c2c26c8bSAndroid Build Coastguard Worker #endif /* !__ANDROID */
574*c2c26c8bSAndroid Build Coastguard Worker }
575*c2c26c8bSAndroid Build Coastguard Worker
576*c2c26c8bSAndroid Build Coastguard Worker return listeners;
577*c2c26c8bSAndroid Build Coastguard Worker }
578*c2c26c8bSAndroid Build Coastguard Worker
579*c2c26c8bSAndroid Build Coastguard Worker /* return a UDP socket bound to a random port, have to cope with straying into
580*c2c26c8bSAndroid Build Coastguard Worker occupied port nos and reserved ones. */
random_sock(int family)581*c2c26c8bSAndroid Build Coastguard Worker int random_sock(int family) {
582*c2c26c8bSAndroid Build Coastguard Worker int fd;
583*c2c26c8bSAndroid Build Coastguard Worker
584*c2c26c8bSAndroid Build Coastguard Worker if ((fd = socket(family, SOCK_DGRAM, 0)) != -1) {
585*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr;
586*c2c26c8bSAndroid Build Coastguard Worker unsigned int ports_avail = 65536u - (unsigned short) daemon->min_port;
587*c2c26c8bSAndroid Build Coastguard Worker int tries = ports_avail < 30 ? 3 * ports_avail : 100;
588*c2c26c8bSAndroid Build Coastguard Worker
589*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
590*c2c26c8bSAndroid Build Coastguard Worker addr.sa.sa_family = family;
591*c2c26c8bSAndroid Build Coastguard Worker
592*c2c26c8bSAndroid Build Coastguard Worker /* don't loop forever if all ports in use. */
593*c2c26c8bSAndroid Build Coastguard Worker
594*c2c26c8bSAndroid Build Coastguard Worker if (fix_fd(fd))
595*c2c26c8bSAndroid Build Coastguard Worker while (tries--) {
596*c2c26c8bSAndroid Build Coastguard Worker unsigned short port = rand16();
597*c2c26c8bSAndroid Build Coastguard Worker
598*c2c26c8bSAndroid Build Coastguard Worker if (daemon->min_port != 0)
599*c2c26c8bSAndroid Build Coastguard Worker port = htons(daemon->min_port + (port % ((unsigned short) ports_avail)));
600*c2c26c8bSAndroid Build Coastguard Worker
601*c2c26c8bSAndroid Build Coastguard Worker if (family == AF_INET) {
602*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_addr.s_addr = INADDR_ANY;
603*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_port = port;
604*c2c26c8bSAndroid Build Coastguard Worker } else {
605*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_addr = in6addr_any;
606*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_port = port;
607*c2c26c8bSAndroid Build Coastguard Worker }
608*c2c26c8bSAndroid Build Coastguard Worker
609*c2c26c8bSAndroid Build Coastguard Worker if (bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == 0) return fd;
610*c2c26c8bSAndroid Build Coastguard Worker
611*c2c26c8bSAndroid Build Coastguard Worker if (errno != EADDRINUSE && errno != EACCES) break;
612*c2c26c8bSAndroid Build Coastguard Worker }
613*c2c26c8bSAndroid Build Coastguard Worker
614*c2c26c8bSAndroid Build Coastguard Worker close(fd);
615*c2c26c8bSAndroid Build Coastguard Worker }
616*c2c26c8bSAndroid Build Coastguard Worker
617*c2c26c8bSAndroid Build Coastguard Worker return -1;
618*c2c26c8bSAndroid Build Coastguard Worker }
619*c2c26c8bSAndroid Build Coastguard Worker
local_bind(int fd,union mysockaddr * addr,char * intname,uint32_t mark,int is_tcp)620*c2c26c8bSAndroid Build Coastguard Worker int local_bind(int fd, union mysockaddr* addr, char* intname, uint32_t mark, int is_tcp) {
621*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr_copy = *addr;
622*c2c26c8bSAndroid Build Coastguard Worker
623*c2c26c8bSAndroid Build Coastguard Worker /* cannot set source _port_ for TCP connections. */
624*c2c26c8bSAndroid Build Coastguard Worker if (is_tcp) {
625*c2c26c8bSAndroid Build Coastguard Worker if (addr_copy.sa.sa_family == AF_INET) addr_copy.in.sin_port = 0;
626*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
627*c2c26c8bSAndroid Build Coastguard Worker else
628*c2c26c8bSAndroid Build Coastguard Worker addr_copy.in6.sin6_port = 0;
629*c2c26c8bSAndroid Build Coastguard Worker #endif
630*c2c26c8bSAndroid Build Coastguard Worker }
631*c2c26c8bSAndroid Build Coastguard Worker
632*c2c26c8bSAndroid Build Coastguard Worker if (bind(fd, (struct sockaddr*) &addr_copy, sa_len(&addr_copy)) == -1) return 0;
633*c2c26c8bSAndroid Build Coastguard Worker
634*c2c26c8bSAndroid Build Coastguard Worker #if defined(SO_BINDTODEVICE)
635*c2c26c8bSAndroid Build Coastguard Worker if (intname[0] != 0 &&
636*c2c26c8bSAndroid Build Coastguard Worker setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
637*c2c26c8bSAndroid Build Coastguard Worker return 0;
638*c2c26c8bSAndroid Build Coastguard Worker #endif
639*c2c26c8bSAndroid Build Coastguard Worker
640*c2c26c8bSAndroid Build Coastguard Worker if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1) return 0;
641*c2c26c8bSAndroid Build Coastguard Worker
642*c2c26c8bSAndroid Build Coastguard Worker return 1;
643*c2c26c8bSAndroid Build Coastguard Worker }
644*c2c26c8bSAndroid Build Coastguard Worker
allocate_sfd(union mysockaddr * addr,char * intname,uint32_t mark)645*c2c26c8bSAndroid Build Coastguard Worker static struct serverfd* allocate_sfd(union mysockaddr* addr, char* intname, uint32_t mark) {
646*c2c26c8bSAndroid Build Coastguard Worker struct serverfd* sfd;
647*c2c26c8bSAndroid Build Coastguard Worker int errsave;
648*c2c26c8bSAndroid Build Coastguard Worker
649*c2c26c8bSAndroid Build Coastguard Worker /* when using random ports, servers which would otherwise use
650*c2c26c8bSAndroid Build Coastguard Worker the INADDR_ANY/port0 socket have sfd set to NULL */
651*c2c26c8bSAndroid Build Coastguard Worker if (!daemon->osport && intname[0] == 0) {
652*c2c26c8bSAndroid Build Coastguard Worker errno = 0;
653*c2c26c8bSAndroid Build Coastguard Worker
654*c2c26c8bSAndroid Build Coastguard Worker if (addr->sa.sa_family == AF_INET && addr->in.sin_addr.s_addr == INADDR_ANY &&
655*c2c26c8bSAndroid Build Coastguard Worker addr->in.sin_port == htons(0))
656*c2c26c8bSAndroid Build Coastguard Worker return NULL;
657*c2c26c8bSAndroid Build Coastguard Worker
658*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
659*c2c26c8bSAndroid Build Coastguard Worker if (addr->sa.sa_family == AF_INET6 &&
660*c2c26c8bSAndroid Build Coastguard Worker memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
661*c2c26c8bSAndroid Build Coastguard Worker addr->in6.sin6_port == htons(0))
662*c2c26c8bSAndroid Build Coastguard Worker return NULL;
663*c2c26c8bSAndroid Build Coastguard Worker #endif
664*c2c26c8bSAndroid Build Coastguard Worker }
665*c2c26c8bSAndroid Build Coastguard Worker
666*c2c26c8bSAndroid Build Coastguard Worker /* may have a suitable one already */
667*c2c26c8bSAndroid Build Coastguard Worker for (sfd = daemon->sfds; sfd; sfd = sfd->next)
668*c2c26c8bSAndroid Build Coastguard Worker if (sockaddr_isequal(&sfd->source_addr, addr) && mark == sfd->mark &&
669*c2c26c8bSAndroid Build Coastguard Worker strcmp(intname, sfd->interface) == 0)
670*c2c26c8bSAndroid Build Coastguard Worker return sfd;
671*c2c26c8bSAndroid Build Coastguard Worker
672*c2c26c8bSAndroid Build Coastguard Worker /* need to make a new one. */
673*c2c26c8bSAndroid Build Coastguard Worker errno = ENOMEM; /* in case malloc fails. */
674*c2c26c8bSAndroid Build Coastguard Worker if (!(sfd = whine_malloc(sizeof(struct serverfd)))) return NULL;
675*c2c26c8bSAndroid Build Coastguard Worker
676*c2c26c8bSAndroid Build Coastguard Worker if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1) {
677*c2c26c8bSAndroid Build Coastguard Worker free(sfd);
678*c2c26c8bSAndroid Build Coastguard Worker return NULL;
679*c2c26c8bSAndroid Build Coastguard Worker }
680*c2c26c8bSAndroid Build Coastguard Worker
681*c2c26c8bSAndroid Build Coastguard Worker if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd)) {
682*c2c26c8bSAndroid Build Coastguard Worker errsave = errno; /* save error from bind. */
683*c2c26c8bSAndroid Build Coastguard Worker close(sfd->fd);
684*c2c26c8bSAndroid Build Coastguard Worker free(sfd);
685*c2c26c8bSAndroid Build Coastguard Worker errno = errsave;
686*c2c26c8bSAndroid Build Coastguard Worker return NULL;
687*c2c26c8bSAndroid Build Coastguard Worker }
688*c2c26c8bSAndroid Build Coastguard Worker
689*c2c26c8bSAndroid Build Coastguard Worker strcpy(sfd->interface, intname);
690*c2c26c8bSAndroid Build Coastguard Worker sfd->source_addr = *addr;
691*c2c26c8bSAndroid Build Coastguard Worker sfd->mark = mark;
692*c2c26c8bSAndroid Build Coastguard Worker sfd->next = daemon->sfds;
693*c2c26c8bSAndroid Build Coastguard Worker daemon->sfds = sfd;
694*c2c26c8bSAndroid Build Coastguard Worker return sfd;
695*c2c26c8bSAndroid Build Coastguard Worker }
696*c2c26c8bSAndroid Build Coastguard Worker
697*c2c26c8bSAndroid Build Coastguard Worker /* create upstream sockets during startup, before root is dropped which may be needed
698*c2c26c8bSAndroid Build Coastguard Worker this allows query_port to be a low port and interface binding */
pre_allocate_sfds(void)699*c2c26c8bSAndroid Build Coastguard Worker void pre_allocate_sfds(void) {
700*c2c26c8bSAndroid Build Coastguard Worker struct server* srv;
701*c2c26c8bSAndroid Build Coastguard Worker
702*c2c26c8bSAndroid Build Coastguard Worker if (daemon->query_port != 0) {
703*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr;
704*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
705*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_family = AF_INET;
706*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_addr.s_addr = INADDR_ANY;
707*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_port = htons(daemon->query_port);
708*c2c26c8bSAndroid Build Coastguard Worker allocate_sfd(&addr, "", 0);
709*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
710*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
711*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_family = AF_INET6;
712*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_addr = in6addr_any;
713*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_port = htons(daemon->query_port);
714*c2c26c8bSAndroid Build Coastguard Worker allocate_sfd(&addr, "", 0);
715*c2c26c8bSAndroid Build Coastguard Worker #endif
716*c2c26c8bSAndroid Build Coastguard Worker }
717*c2c26c8bSAndroid Build Coastguard Worker
718*c2c26c8bSAndroid Build Coastguard Worker for (srv = daemon->servers; srv; srv = srv->next)
719*c2c26c8bSAndroid Build Coastguard Worker if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
720*c2c26c8bSAndroid Build Coastguard Worker !allocate_sfd(&srv->source_addr, srv->interface, srv->mark) && errno != 0 &&
721*c2c26c8bSAndroid Build Coastguard Worker (daemon->options & OPT_NOWILD)) {
722*c2c26c8bSAndroid Build Coastguard Worker prettyprint_addr(&srv->addr, daemon->namebuff);
723*c2c26c8bSAndroid Build Coastguard Worker if (srv->interface[0] != 0) {
724*c2c26c8bSAndroid Build Coastguard Worker strcat(daemon->namebuff, " ");
725*c2c26c8bSAndroid Build Coastguard Worker strcat(daemon->namebuff, srv->interface);
726*c2c26c8bSAndroid Build Coastguard Worker }
727*c2c26c8bSAndroid Build Coastguard Worker die(_("failed to bind server socket for %s: %s"), daemon->namebuff, EC_BADNET);
728*c2c26c8bSAndroid Build Coastguard Worker }
729*c2c26c8bSAndroid Build Coastguard Worker }
730*c2c26c8bSAndroid Build Coastguard Worker
check_servers(void)731*c2c26c8bSAndroid Build Coastguard Worker void check_servers(void) {
732*c2c26c8bSAndroid Build Coastguard Worker struct irec* iface;
733*c2c26c8bSAndroid Build Coastguard Worker struct server* new, *tmp, *ret = NULL;
734*c2c26c8bSAndroid Build Coastguard Worker int port = 0;
735*c2c26c8bSAndroid Build Coastguard Worker
736*c2c26c8bSAndroid Build Coastguard Worker for (new = daemon->servers; new; new = tmp) {
737*c2c26c8bSAndroid Build Coastguard Worker tmp = new->next;
738*c2c26c8bSAndroid Build Coastguard Worker
739*c2c26c8bSAndroid Build Coastguard Worker if (!(new->flags&(SERV_LITERAL_ADDRESS | SERV_NO_ADDR))) {
740*c2c26c8bSAndroid Build Coastguard Worker port = prettyprint_addr(&new->addr, daemon->namebuff);
741*c2c26c8bSAndroid Build Coastguard Worker
742*c2c26c8bSAndroid Build Coastguard Worker /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
743*c2c26c8bSAndroid Build Coastguard Worker if (new->addr.sa.sa_family == AF_INET && new->addr.in.sin_addr.s_addr == 0) {
744*c2c26c8bSAndroid Build Coastguard Worker free(new);
745*c2c26c8bSAndroid Build Coastguard Worker continue;
746*c2c26c8bSAndroid Build Coastguard Worker }
747*c2c26c8bSAndroid Build Coastguard Worker
748*c2c26c8bSAndroid Build Coastguard Worker for (iface = daemon->interfaces; iface; iface = iface->next)
749*c2c26c8bSAndroid Build Coastguard Worker if (sockaddr_isequal(&new->addr, &iface->addr)) break;
750*c2c26c8bSAndroid Build Coastguard Worker if (iface) {
751*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"),
752*c2c26c8bSAndroid Build Coastguard Worker daemon->namebuff);
753*c2c26c8bSAndroid Build Coastguard Worker free(new);
754*c2c26c8bSAndroid Build Coastguard Worker continue;
755*c2c26c8bSAndroid Build Coastguard Worker }
756*c2c26c8bSAndroid Build Coastguard Worker
757*c2c26c8bSAndroid Build Coastguard Worker /* Do we need a socket set? */
758*c2c26c8bSAndroid Build Coastguard Worker if (!new->sfd &&
759*c2c26c8bSAndroid Build Coastguard Worker !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
760*c2c26c8bSAndroid Build Coastguard Worker errno != 0) {
761*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_WARNING, _("ignoring nameserver %s - cannot make/bind socket: %s"),
762*c2c26c8bSAndroid Build Coastguard Worker daemon->namebuff, strerror(errno));
763*c2c26c8bSAndroid Build Coastguard Worker free(new);
764*c2c26c8bSAndroid Build Coastguard Worker continue;
765*c2c26c8bSAndroid Build Coastguard Worker }
766*c2c26c8bSAndroid Build Coastguard Worker }
767*c2c26c8bSAndroid Build Coastguard Worker
768*c2c26c8bSAndroid Build Coastguard Worker /* reverse order - gets it right. */
769*c2c26c8bSAndroid Build Coastguard Worker new->next = ret;
770*c2c26c8bSAndroid Build Coastguard Worker ret = new;
771*c2c26c8bSAndroid Build Coastguard Worker
772*c2c26c8bSAndroid Build Coastguard Worker if (new->flags&(SERV_HAS_DOMAIN | SERV_FOR_NODOTS)) {
773*c2c26c8bSAndroid Build Coastguard Worker char *s1, *s2;
774*c2c26c8bSAndroid Build Coastguard Worker if (!(new->flags& SERV_HAS_DOMAIN))
775*c2c26c8bSAndroid Build Coastguard Worker s1 = _("unqualified"), s2 = _("names");
776*c2c26c8bSAndroid Build Coastguard Worker else if (strlen(new->domain) == 0)
777*c2c26c8bSAndroid Build Coastguard Worker s1 = _("default"), s2 = "";
778*c2c26c8bSAndroid Build Coastguard Worker else
779*c2c26c8bSAndroid Build Coastguard Worker s1 = _("domain"), s2 = new->domain;
780*c2c26c8bSAndroid Build Coastguard Worker
781*c2c26c8bSAndroid Build Coastguard Worker if (new->flags & SERV_NO_ADDR)
782*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
783*c2c26c8bSAndroid Build Coastguard Worker else if (!(new->flags& SERV_LITERAL_ADDRESS))
784*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port,
785*c2c26c8bSAndroid Build Coastguard Worker s1, s2);
786*c2c26c8bSAndroid Build Coastguard Worker } else if (new->interface[0] != 0)
787*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port,
788*c2c26c8bSAndroid Build Coastguard Worker new->interface);
789*c2c26c8bSAndroid Build Coastguard Worker else
790*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
791*c2c26c8bSAndroid Build Coastguard Worker }
792*c2c26c8bSAndroid Build Coastguard Worker
793*c2c26c8bSAndroid Build Coastguard Worker daemon->servers = ret;
794*c2c26c8bSAndroid Build Coastguard Worker }
795*c2c26c8bSAndroid Build Coastguard Worker
796*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
797*c2c26c8bSAndroid Build Coastguard Worker /* #define __ANDROID_DEBUG__ 1 */
798*c2c26c8bSAndroid Build Coastguard Worker /*
799*c2c26c8bSAndroid Build Coastguard Worker * Ingests a new list of interfaces and starts to listen on them, adding only the new
800*c2c26c8bSAndroid Build Coastguard Worker * and stopping to listen to any interfaces not on the new list.
801*c2c26c8bSAndroid Build Coastguard Worker *
802*c2c26c8bSAndroid Build Coastguard Worker * interfaces - input in the format "bt-pan|eth0|wlan0|..>" up to 1024 bytes long
803*c2c26c8bSAndroid Build Coastguard Worker */
set_interfaces(const char * interfaces)804*c2c26c8bSAndroid Build Coastguard Worker void set_interfaces(const char* interfaces) {
805*c2c26c8bSAndroid Build Coastguard Worker struct iname* if_tmp;
806*c2c26c8bSAndroid Build Coastguard Worker struct iname* prev_if_names;
807*c2c26c8bSAndroid Build Coastguard Worker struct irec *old_iface, *new_iface, *prev_interfaces;
808*c2c26c8bSAndroid Build Coastguard Worker char s[1024];
809*c2c26c8bSAndroid Build Coastguard Worker char* next = s;
810*c2c26c8bSAndroid Build Coastguard Worker char* interface;
811*c2c26c8bSAndroid Build Coastguard Worker int was_wild = 0;
812*c2c26c8bSAndroid Build Coastguard Worker
813*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID_DEBUG__
814*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_DEBUG, _("set_interfaces(%s)"), interfaces);
815*c2c26c8bSAndroid Build Coastguard Worker #endif
816*c2c26c8bSAndroid Build Coastguard Worker prev_if_names = daemon->if_names;
817*c2c26c8bSAndroid Build Coastguard Worker daemon->if_names = NULL;
818*c2c26c8bSAndroid Build Coastguard Worker
819*c2c26c8bSAndroid Build Coastguard Worker prev_interfaces = daemon->interfaces;
820*c2c26c8bSAndroid Build Coastguard Worker daemon->interfaces = NULL;
821*c2c26c8bSAndroid Build Coastguard Worker
822*c2c26c8bSAndroid Build Coastguard Worker if (strlen(interfaces) > sizeof(s)) {
823*c2c26c8bSAndroid Build Coastguard Worker die(_("interface string too long: %s"), NULL, EC_BADNET);
824*c2c26c8bSAndroid Build Coastguard Worker }
825*c2c26c8bSAndroid Build Coastguard Worker strncpy(s, interfaces, sizeof(s));
826*c2c26c8bSAndroid Build Coastguard Worker while ((interface = strsep(&next, SEPARATOR))) {
827*c2c26c8bSAndroid Build Coastguard Worker if (!if_nametoindex(interface)) {
828*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_ERR, _("interface given in %s: '%s' has no ifindex; ignoring"),
829*c2c26c8bSAndroid Build Coastguard Worker __FUNCTION__, interface);
830*c2c26c8bSAndroid Build Coastguard Worker continue;
831*c2c26c8bSAndroid Build Coastguard Worker }
832*c2c26c8bSAndroid Build Coastguard Worker if_tmp = safe_malloc(sizeof(struct iname));
833*c2c26c8bSAndroid Build Coastguard Worker memset(if_tmp, 0, sizeof(struct iname));
834*c2c26c8bSAndroid Build Coastguard Worker if ((if_tmp->name = strdup(interface)) == NULL) {
835*c2c26c8bSAndroid Build Coastguard Worker die(_("malloc failure in set_interfaces: %s"), NULL, EC_BADNET);
836*c2c26c8bSAndroid Build Coastguard Worker }
837*c2c26c8bSAndroid Build Coastguard Worker if_tmp->next = daemon->if_names;
838*c2c26c8bSAndroid Build Coastguard Worker daemon->if_names = if_tmp;
839*c2c26c8bSAndroid Build Coastguard Worker }
840*c2c26c8bSAndroid Build Coastguard Worker
841*c2c26c8bSAndroid Build Coastguard Worker /*
842*c2c26c8bSAndroid Build Coastguard Worker * Enumerate IP addresses (via RTM_GETADDR), adding IP entries to
843*c2c26c8bSAndroid Build Coastguard Worker * daemon->interfaces for interface names listed in daemon->if_names.
844*c2c26c8bSAndroid Build Coastguard Worker * The sockets are created by the create_bound_listener call below.
845*c2c26c8bSAndroid Build Coastguard Worker * Only do this if at least one interface was found. Otherwise,
846*c2c26c8bSAndroid Build Coastguard Worker * enumerate_interfaces will start listening on all interfaces on
847*c2c26c8bSAndroid Build Coastguard Worker * the system.
848*c2c26c8bSAndroid Build Coastguard Worker */
849*c2c26c8bSAndroid Build Coastguard Worker if (daemon->if_names != NULL && !enumerate_interfaces()) {
850*c2c26c8bSAndroid Build Coastguard Worker die(_("enumerate interfaces error in set_interfaces: %s"), NULL, EC_BADNET);
851*c2c26c8bSAndroid Build Coastguard Worker }
852*c2c26c8bSAndroid Build Coastguard Worker
853*c2c26c8bSAndroid Build Coastguard Worker for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) {
854*c2c26c8bSAndroid Build Coastguard Worker if (if_tmp->name && !if_tmp->used) {
855*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_ERR, _("unknown interface given %s in set_interfaces()"), if_tmp->name);
856*c2c26c8bSAndroid Build Coastguard Worker }
857*c2c26c8bSAndroid Build Coastguard Worker }
858*c2c26c8bSAndroid Build Coastguard Worker
859*c2c26c8bSAndroid Build Coastguard Worker /* success! - setup to free the old */
860*c2c26c8bSAndroid Build Coastguard Worker /* check for any that have been removed */
861*c2c26c8bSAndroid Build Coastguard Worker for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
862*c2c26c8bSAndroid Build Coastguard Worker int found = 0;
863*c2c26c8bSAndroid Build Coastguard Worker for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
864*c2c26c8bSAndroid Build Coastguard Worker if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
865*c2c26c8bSAndroid Build Coastguard Worker found = 1;
866*c2c26c8bSAndroid Build Coastguard Worker break;
867*c2c26c8bSAndroid Build Coastguard Worker }
868*c2c26c8bSAndroid Build Coastguard Worker }
869*c2c26c8bSAndroid Build Coastguard Worker
870*c2c26c8bSAndroid Build Coastguard Worker if (found) {
871*c2c26c8bSAndroid Build Coastguard Worker fixup_possible_existing_listener(new_iface);
872*c2c26c8bSAndroid Build Coastguard Worker } else {
873*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID_DEBUG__
874*c2c26c8bSAndroid Build Coastguard Worker char debug_buff[MAXDNAME];
875*c2c26c8bSAndroid Build Coastguard Worker prettyprint_addr(&old_iface->addr, debug_buff);
876*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
877*c2c26c8bSAndroid Build Coastguard Worker #endif
878*c2c26c8bSAndroid Build Coastguard Worker
879*c2c26c8bSAndroid Build Coastguard Worker close_bound_listener(old_iface);
880*c2c26c8bSAndroid Build Coastguard Worker }
881*c2c26c8bSAndroid Build Coastguard Worker }
882*c2c26c8bSAndroid Build Coastguard Worker
883*c2c26c8bSAndroid Build Coastguard Worker /* remove wildchar listeners */
884*c2c26c8bSAndroid Build Coastguard Worker was_wild = close_bound_listener(NULL);
885*c2c26c8bSAndroid Build Coastguard Worker if (was_wild) daemon->options |= OPT_NOWILD;
886*c2c26c8bSAndroid Build Coastguard Worker
887*c2c26c8bSAndroid Build Coastguard Worker /* check for any that have been added */
888*c2c26c8bSAndroid Build Coastguard Worker for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
889*c2c26c8bSAndroid Build Coastguard Worker int found = 0;
890*c2c26c8bSAndroid Build Coastguard Worker
891*c2c26c8bSAndroid Build Coastguard Worker /* if the previous setup used a wildchar, then add any current interfaces */
892*c2c26c8bSAndroid Build Coastguard Worker if (!was_wild) {
893*c2c26c8bSAndroid Build Coastguard Worker for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
894*c2c26c8bSAndroid Build Coastguard Worker if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
895*c2c26c8bSAndroid Build Coastguard Worker found = -1;
896*c2c26c8bSAndroid Build Coastguard Worker break;
897*c2c26c8bSAndroid Build Coastguard Worker }
898*c2c26c8bSAndroid Build Coastguard Worker }
899*c2c26c8bSAndroid Build Coastguard Worker }
900*c2c26c8bSAndroid Build Coastguard Worker if (!found) {
901*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID_DEBUG__
902*c2c26c8bSAndroid Build Coastguard Worker char debug_buff[MAXDNAME];
903*c2c26c8bSAndroid Build Coastguard Worker prettyprint_addr(&new_iface->addr, debug_buff);
904*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
905*c2c26c8bSAndroid Build Coastguard Worker #endif
906*c2c26c8bSAndroid Build Coastguard Worker create_bound_listener(&(daemon->listeners), new_iface);
907*c2c26c8bSAndroid Build Coastguard Worker }
908*c2c26c8bSAndroid Build Coastguard Worker }
909*c2c26c8bSAndroid Build Coastguard Worker
910*c2c26c8bSAndroid Build Coastguard Worker while (prev_if_names) {
911*c2c26c8bSAndroid Build Coastguard Worker if (prev_if_names->name) free(prev_if_names->name);
912*c2c26c8bSAndroid Build Coastguard Worker if_tmp = prev_if_names->next;
913*c2c26c8bSAndroid Build Coastguard Worker free(prev_if_names);
914*c2c26c8bSAndroid Build Coastguard Worker prev_if_names = if_tmp;
915*c2c26c8bSAndroid Build Coastguard Worker }
916*c2c26c8bSAndroid Build Coastguard Worker while (prev_interfaces) {
917*c2c26c8bSAndroid Build Coastguard Worker struct irec* tmp_irec = prev_interfaces->next;
918*c2c26c8bSAndroid Build Coastguard Worker free(prev_interfaces);
919*c2c26c8bSAndroid Build Coastguard Worker prev_interfaces = tmp_irec;
920*c2c26c8bSAndroid Build Coastguard Worker }
921*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID_DEBUG__
922*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_DEBUG, _("done with setInterfaces"));
923*c2c26c8bSAndroid Build Coastguard Worker #endif
924*c2c26c8bSAndroid Build Coastguard Worker }
925*c2c26c8bSAndroid Build Coastguard Worker
926*c2c26c8bSAndroid Build Coastguard Worker /*
927*c2c26c8bSAndroid Build Coastguard Worker * Takes a string in the format "0x100b|1.2.3.4|1.2.3.4|..." - up to 1024 bytes in length
928*c2c26c8bSAndroid Build Coastguard Worker * - The first element is the socket mark to set on sockets that forward DNS queries.
929*c2c26c8bSAndroid Build Coastguard Worker * - The subsequent elements are the DNS servers to forward queries to.
930*c2c26c8bSAndroid Build Coastguard Worker */
set_servers(const char * servers)931*c2c26c8bSAndroid Build Coastguard Worker int set_servers(const char* servers) {
932*c2c26c8bSAndroid Build Coastguard Worker char s[1024];
933*c2c26c8bSAndroid Build Coastguard Worker struct server* old_servers = NULL;
934*c2c26c8bSAndroid Build Coastguard Worker struct server* new_servers = NULL;
935*c2c26c8bSAndroid Build Coastguard Worker struct server* serv;
936*c2c26c8bSAndroid Build Coastguard Worker char* mark_string;
937*c2c26c8bSAndroid Build Coastguard Worker uint32_t mark;
938*c2c26c8bSAndroid Build Coastguard Worker
939*c2c26c8bSAndroid Build Coastguard Worker strncpy(s, servers, sizeof(s));
940*c2c26c8bSAndroid Build Coastguard Worker
941*c2c26c8bSAndroid Build Coastguard Worker /* move old servers to free list - we can reuse the memory
942*c2c26c8bSAndroid Build Coastguard Worker and not risk malloc if there are the same or fewer new servers.
943*c2c26c8bSAndroid Build Coastguard Worker Servers which were specced on the command line go to the new list. */
944*c2c26c8bSAndroid Build Coastguard Worker for (serv = daemon->servers; serv;) {
945*c2c26c8bSAndroid Build Coastguard Worker struct server* tmp = serv->next;
946*c2c26c8bSAndroid Build Coastguard Worker if (serv->flags & SERV_FROM_RESOLV) {
947*c2c26c8bSAndroid Build Coastguard Worker serv->next = old_servers;
948*c2c26c8bSAndroid Build Coastguard Worker old_servers = serv;
949*c2c26c8bSAndroid Build Coastguard Worker /* forward table rules reference servers, so have to blow them away */
950*c2c26c8bSAndroid Build Coastguard Worker server_gone(serv);
951*c2c26c8bSAndroid Build Coastguard Worker } else {
952*c2c26c8bSAndroid Build Coastguard Worker serv->next = new_servers;
953*c2c26c8bSAndroid Build Coastguard Worker new_servers = serv;
954*c2c26c8bSAndroid Build Coastguard Worker }
955*c2c26c8bSAndroid Build Coastguard Worker serv = tmp;
956*c2c26c8bSAndroid Build Coastguard Worker }
957*c2c26c8bSAndroid Build Coastguard Worker
958*c2c26c8bSAndroid Build Coastguard Worker char* next = s;
959*c2c26c8bSAndroid Build Coastguard Worker char* saddr;
960*c2c26c8bSAndroid Build Coastguard Worker
961*c2c26c8bSAndroid Build Coastguard Worker /* Parse the mark. */
962*c2c26c8bSAndroid Build Coastguard Worker mark_string = strsep(&next, SEPARATOR);
963*c2c26c8bSAndroid Build Coastguard Worker mark = strtoul(mark_string, NULL, 0);
964*c2c26c8bSAndroid Build Coastguard Worker
965*c2c26c8bSAndroid Build Coastguard Worker while ((saddr = strsep(&next, SEPARATOR))) {
966*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr, source_addr;
967*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
968*c2c26c8bSAndroid Build Coastguard Worker memset(&source_addr, 0, sizeof(source_addr));
969*c2c26c8bSAndroid Build Coastguard Worker
970*c2c26c8bSAndroid Build Coastguard Worker if (parse_addr(AF_INET, saddr, &addr) == 0) {
971*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_port = htons(NAMESERVER_PORT);
972*c2c26c8bSAndroid Build Coastguard Worker source_addr.in.sin_family = AF_INET;
973*c2c26c8bSAndroid Build Coastguard Worker source_addr.in.sin_addr.s_addr = INADDR_ANY;
974*c2c26c8bSAndroid Build Coastguard Worker source_addr.in.sin_port = htons(daemon->query_port);
975*c2c26c8bSAndroid Build Coastguard Worker }
976*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
977*c2c26c8bSAndroid Build Coastguard Worker else if (parse_addr(AF_INET6, saddr, &addr) == 0) {
978*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_port = htons(NAMESERVER_PORT);
979*c2c26c8bSAndroid Build Coastguard Worker source_addr.in6.sin6_family = AF_INET6;
980*c2c26c8bSAndroid Build Coastguard Worker source_addr.in6.sin6_addr = in6addr_any;
981*c2c26c8bSAndroid Build Coastguard Worker source_addr.in6.sin6_port = htons(daemon->query_port);
982*c2c26c8bSAndroid Build Coastguard Worker }
983*c2c26c8bSAndroid Build Coastguard Worker #endif /* IPV6 */
984*c2c26c8bSAndroid Build Coastguard Worker else
985*c2c26c8bSAndroid Build Coastguard Worker continue;
986*c2c26c8bSAndroid Build Coastguard Worker
987*c2c26c8bSAndroid Build Coastguard Worker if (old_servers) {
988*c2c26c8bSAndroid Build Coastguard Worker serv = old_servers;
989*c2c26c8bSAndroid Build Coastguard Worker old_servers = old_servers->next;
990*c2c26c8bSAndroid Build Coastguard Worker } else if (!(serv = whine_malloc(sizeof(struct server))))
991*c2c26c8bSAndroid Build Coastguard Worker continue;
992*c2c26c8bSAndroid Build Coastguard Worker
993*c2c26c8bSAndroid Build Coastguard Worker /* this list is reverse ordered:
994*c2c26c8bSAndroid Build Coastguard Worker it gets reversed again in check_servers */
995*c2c26c8bSAndroid Build Coastguard Worker serv->next = new_servers;
996*c2c26c8bSAndroid Build Coastguard Worker new_servers = serv;
997*c2c26c8bSAndroid Build Coastguard Worker serv->addr = addr;
998*c2c26c8bSAndroid Build Coastguard Worker serv->source_addr = source_addr;
999*c2c26c8bSAndroid Build Coastguard Worker serv->domain = NULL;
1000*c2c26c8bSAndroid Build Coastguard Worker serv->interface[0] = 0;
1001*c2c26c8bSAndroid Build Coastguard Worker serv->mark = mark;
1002*c2c26c8bSAndroid Build Coastguard Worker serv->sfd = NULL;
1003*c2c26c8bSAndroid Build Coastguard Worker serv->flags = SERV_FROM_RESOLV;
1004*c2c26c8bSAndroid Build Coastguard Worker serv->queries = serv->failed_queries = 0;
1005*c2c26c8bSAndroid Build Coastguard Worker }
1006*c2c26c8bSAndroid Build Coastguard Worker
1007*c2c26c8bSAndroid Build Coastguard Worker /* Free any memory not used. */
1008*c2c26c8bSAndroid Build Coastguard Worker while (old_servers) {
1009*c2c26c8bSAndroid Build Coastguard Worker struct server* tmp = old_servers->next;
1010*c2c26c8bSAndroid Build Coastguard Worker free(old_servers);
1011*c2c26c8bSAndroid Build Coastguard Worker old_servers = tmp;
1012*c2c26c8bSAndroid Build Coastguard Worker }
1013*c2c26c8bSAndroid Build Coastguard Worker
1014*c2c26c8bSAndroid Build Coastguard Worker daemon->servers = new_servers;
1015*c2c26c8bSAndroid Build Coastguard Worker return 0;
1016*c2c26c8bSAndroid Build Coastguard Worker }
1017*c2c26c8bSAndroid Build Coastguard Worker #endif
1018*c2c26c8bSAndroid Build Coastguard Worker
1019*c2c26c8bSAndroid Build Coastguard Worker /* Return zero if no servers found, in that case we keep polling.
1020*c2c26c8bSAndroid Build Coastguard Worker This is a protection against an update-time/write race on resolv.conf */
reload_servers(char * fname)1021*c2c26c8bSAndroid Build Coastguard Worker int reload_servers(char* fname) {
1022*c2c26c8bSAndroid Build Coastguard Worker FILE* f;
1023*c2c26c8bSAndroid Build Coastguard Worker char* line;
1024*c2c26c8bSAndroid Build Coastguard Worker struct server* old_servers = NULL;
1025*c2c26c8bSAndroid Build Coastguard Worker struct server* new_servers = NULL;
1026*c2c26c8bSAndroid Build Coastguard Worker struct server* serv;
1027*c2c26c8bSAndroid Build Coastguard Worker int gotone = 0;
1028*c2c26c8bSAndroid Build Coastguard Worker
1029*c2c26c8bSAndroid Build Coastguard Worker /* buff happens to be MAXDNAME long... */
1030*c2c26c8bSAndroid Build Coastguard Worker if (!(f = fopen(fname, "r"))) {
1031*c2c26c8bSAndroid Build Coastguard Worker my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1032*c2c26c8bSAndroid Build Coastguard Worker return 0;
1033*c2c26c8bSAndroid Build Coastguard Worker }
1034*c2c26c8bSAndroid Build Coastguard Worker
1035*c2c26c8bSAndroid Build Coastguard Worker /* move old servers to free list - we can reuse the memory
1036*c2c26c8bSAndroid Build Coastguard Worker and not risk malloc if there are the same or fewer new servers.
1037*c2c26c8bSAndroid Build Coastguard Worker Servers which were specced on the command line go to the new list. */
1038*c2c26c8bSAndroid Build Coastguard Worker for (serv = daemon->servers; serv;) {
1039*c2c26c8bSAndroid Build Coastguard Worker struct server* tmp = serv->next;
1040*c2c26c8bSAndroid Build Coastguard Worker if (serv->flags & SERV_FROM_RESOLV) {
1041*c2c26c8bSAndroid Build Coastguard Worker serv->next = old_servers;
1042*c2c26c8bSAndroid Build Coastguard Worker old_servers = serv;
1043*c2c26c8bSAndroid Build Coastguard Worker /* forward table rules reference servers, so have to blow them away */
1044*c2c26c8bSAndroid Build Coastguard Worker server_gone(serv);
1045*c2c26c8bSAndroid Build Coastguard Worker } else {
1046*c2c26c8bSAndroid Build Coastguard Worker serv->next = new_servers;
1047*c2c26c8bSAndroid Build Coastguard Worker new_servers = serv;
1048*c2c26c8bSAndroid Build Coastguard Worker }
1049*c2c26c8bSAndroid Build Coastguard Worker serv = tmp;
1050*c2c26c8bSAndroid Build Coastguard Worker }
1051*c2c26c8bSAndroid Build Coastguard Worker
1052*c2c26c8bSAndroid Build Coastguard Worker while ((line = fgets(daemon->namebuff, MAXDNAME, f))) {
1053*c2c26c8bSAndroid Build Coastguard Worker union mysockaddr addr, source_addr;
1054*c2c26c8bSAndroid Build Coastguard Worker char* token = strtok(line, " \t\n\r");
1055*c2c26c8bSAndroid Build Coastguard Worker
1056*c2c26c8bSAndroid Build Coastguard Worker if (!token) continue;
1057*c2c26c8bSAndroid Build Coastguard Worker if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0) continue;
1058*c2c26c8bSAndroid Build Coastguard Worker if (!(token = strtok(NULL, " \t\n\r"))) continue;
1059*c2c26c8bSAndroid Build Coastguard Worker
1060*c2c26c8bSAndroid Build Coastguard Worker memset(&addr, 0, sizeof(addr));
1061*c2c26c8bSAndroid Build Coastguard Worker memset(&source_addr, 0, sizeof(source_addr));
1062*c2c26c8bSAndroid Build Coastguard Worker
1063*c2c26c8bSAndroid Build Coastguard Worker if (parse_addr(AF_INET, token, &addr) == 0) {
1064*c2c26c8bSAndroid Build Coastguard Worker addr.in.sin_port = htons(NAMESERVER_PORT);
1065*c2c26c8bSAndroid Build Coastguard Worker source_addr.in.sin_family = AF_INET;
1066*c2c26c8bSAndroid Build Coastguard Worker source_addr.in.sin_addr.s_addr = INADDR_ANY;
1067*c2c26c8bSAndroid Build Coastguard Worker source_addr.in.sin_port = htons(daemon->query_port);
1068*c2c26c8bSAndroid Build Coastguard Worker }
1069*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_IPV6
1070*c2c26c8bSAndroid Build Coastguard Worker else if (parse_addr(AF_INET6, token, &addr) == 0) {
1071*c2c26c8bSAndroid Build Coastguard Worker addr.in6.sin6_port = htons(NAMESERVER_PORT);
1072*c2c26c8bSAndroid Build Coastguard Worker source_addr.in6.sin6_family = AF_INET6;
1073*c2c26c8bSAndroid Build Coastguard Worker source_addr.in6.sin6_addr = in6addr_any;
1074*c2c26c8bSAndroid Build Coastguard Worker source_addr.in6.sin6_port = htons(daemon->query_port);
1075*c2c26c8bSAndroid Build Coastguard Worker }
1076*c2c26c8bSAndroid Build Coastguard Worker #endif /* IPV6 */
1077*c2c26c8bSAndroid Build Coastguard Worker else
1078*c2c26c8bSAndroid Build Coastguard Worker continue;
1079*c2c26c8bSAndroid Build Coastguard Worker
1080*c2c26c8bSAndroid Build Coastguard Worker if (old_servers) {
1081*c2c26c8bSAndroid Build Coastguard Worker serv = old_servers;
1082*c2c26c8bSAndroid Build Coastguard Worker old_servers = old_servers->next;
1083*c2c26c8bSAndroid Build Coastguard Worker } else if (!(serv = whine_malloc(sizeof(struct server))))
1084*c2c26c8bSAndroid Build Coastguard Worker continue;
1085*c2c26c8bSAndroid Build Coastguard Worker
1086*c2c26c8bSAndroid Build Coastguard Worker /* this list is reverse ordered:
1087*c2c26c8bSAndroid Build Coastguard Worker it gets reversed again in check_servers */
1088*c2c26c8bSAndroid Build Coastguard Worker serv->next = new_servers;
1089*c2c26c8bSAndroid Build Coastguard Worker new_servers = serv;
1090*c2c26c8bSAndroid Build Coastguard Worker serv->addr = addr;
1091*c2c26c8bSAndroid Build Coastguard Worker serv->source_addr = source_addr;
1092*c2c26c8bSAndroid Build Coastguard Worker serv->domain = NULL;
1093*c2c26c8bSAndroid Build Coastguard Worker serv->interface[0] = 0;
1094*c2c26c8bSAndroid Build Coastguard Worker serv->mark = 0;
1095*c2c26c8bSAndroid Build Coastguard Worker serv->sfd = NULL;
1096*c2c26c8bSAndroid Build Coastguard Worker serv->flags = SERV_FROM_RESOLV;
1097*c2c26c8bSAndroid Build Coastguard Worker serv->queries = serv->failed_queries = 0;
1098*c2c26c8bSAndroid Build Coastguard Worker gotone = 1;
1099*c2c26c8bSAndroid Build Coastguard Worker }
1100*c2c26c8bSAndroid Build Coastguard Worker
1101*c2c26c8bSAndroid Build Coastguard Worker /* Free any memory not used. */
1102*c2c26c8bSAndroid Build Coastguard Worker while (old_servers) {
1103*c2c26c8bSAndroid Build Coastguard Worker struct server* tmp = old_servers->next;
1104*c2c26c8bSAndroid Build Coastguard Worker free(old_servers);
1105*c2c26c8bSAndroid Build Coastguard Worker old_servers = tmp;
1106*c2c26c8bSAndroid Build Coastguard Worker }
1107*c2c26c8bSAndroid Build Coastguard Worker
1108*c2c26c8bSAndroid Build Coastguard Worker daemon->servers = new_servers;
1109*c2c26c8bSAndroid Build Coastguard Worker fclose(f);
1110*c2c26c8bSAndroid Build Coastguard Worker
1111*c2c26c8bSAndroid Build Coastguard Worker return gotone;
1112*c2c26c8bSAndroid Build Coastguard Worker }
1113*c2c26c8bSAndroid Build Coastguard Worker
1114*c2c26c8bSAndroid Build Coastguard Worker /* Use an IPv4 listener socket for ioctling */
get_ifaddr(char * intr)1115*c2c26c8bSAndroid Build Coastguard Worker struct in_addr get_ifaddr(char* intr) {
1116*c2c26c8bSAndroid Build Coastguard Worker struct listener* l;
1117*c2c26c8bSAndroid Build Coastguard Worker struct ifreq ifr;
1118*c2c26c8bSAndroid Build Coastguard Worker
1119*c2c26c8bSAndroid Build Coastguard Worker for (l = daemon->listeners; l && l->family != AF_INET; l = l->next)
1120*c2c26c8bSAndroid Build Coastguard Worker ;
1121*c2c26c8bSAndroid Build Coastguard Worker
1122*c2c26c8bSAndroid Build Coastguard Worker strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
1123*c2c26c8bSAndroid Build Coastguard Worker ifr.ifr_addr.sa_family = AF_INET;
1124*c2c26c8bSAndroid Build Coastguard Worker
1125*c2c26c8bSAndroid Build Coastguard Worker if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
1126*c2c26c8bSAndroid Build Coastguard Worker ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr = -1;
1127*c2c26c8bSAndroid Build Coastguard Worker
1128*c2c26c8bSAndroid Build Coastguard Worker return ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
1129*c2c26c8bSAndroid Build Coastguard Worker }
1130