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