Annotation of embedaddon/dnsmasq/src/network.c, revision 1.1.1.4
1.1.1.4 ! misho 1: /* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
1.1 misho 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:
21: int 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:
1.1.1.4 ! misho 32: safe_strncpy(name, ifr.ifr_name, IF_NAMESIZE);
1.1 misho 33:
34: return 1;
35: }
36:
37:
38: #elif defined(HAVE_SOLARIS_NETWORK)
39:
40: #include <zone.h>
41: #include <alloca.h>
42: #ifndef LIFC_UNDER_IPMP
43: # define LIFC_UNDER_IPMP 0
44: #endif
45:
46: int indextoname(int fd, int index, char *name)
47: {
48: int64_t lifc_flags;
49: struct lifnum lifn;
50: int numifs, bufsize, i;
51: struct lifconf lifc;
52: struct lifreq *lifrp;
53:
54: if (index == 0)
55: return 0;
56:
57: if (getzoneid() == GLOBAL_ZONEID)
58: {
59: if (!if_indextoname(index, name))
60: return 0;
61: return 1;
62: }
63:
64: lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
65: lifn.lifn_family = AF_UNSPEC;
66: lifn.lifn_flags = lifc_flags;
67: if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0)
68: return 0;
69:
70: numifs = lifn.lifn_count;
71: bufsize = numifs * sizeof(struct lifreq);
72:
73: lifc.lifc_family = AF_UNSPEC;
74: lifc.lifc_flags = lifc_flags;
75: lifc.lifc_len = bufsize;
76: lifc.lifc_buf = alloca(bufsize);
77:
78: if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0)
79: return 0;
80:
81: lifrp = lifc.lifc_req;
82: for (i = lifc.lifc_len / sizeof(struct lifreq); i; i--, lifrp++)
83: {
84: struct lifreq lifr;
1.1.1.4 ! misho 85: safe_strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
1.1 misho 86: if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0)
87: return 0;
88:
89: if (lifr.lifr_index == index) {
1.1.1.4 ! misho 90: safe_strncpy(name, lifr.lifr_name, IF_NAMESIZE);
1.1 misho 91: return 1;
92: }
93: }
94: return 0;
95: }
96:
97:
98: #else
99:
100: int indextoname(int fd, int index, char *name)
101: {
1.1.1.2 misho 102: (void)fd;
103:
1.1 misho 104: if (index == 0 || !if_indextoname(index, name))
105: return 0;
106:
107: return 1;
108: }
109:
110: #endif
111:
1.1.1.4 ! misho 112: int iface_check(int family, union all_addr *addr, char *name, int *auth)
1.1 misho 113: {
114: struct iname *tmp;
1.1.1.2 misho 115: int ret = 1, match_addr = 0;
1.1 misho 116:
117: /* Note: have to check all and not bail out early, so that we set the
1.1.1.2 misho 118: "used" flags.
119:
120: May be called with family == AF_LOCALto check interface by name only. */
1.1 misho 121:
122: if (auth)
123: *auth = 0;
124:
125: if (daemon->if_names || daemon->if_addrs)
126: {
127: ret = 0;
128:
129: for (tmp = daemon->if_names; tmp; tmp = tmp->next)
130: if (tmp->name && wildcard_match(tmp->name, name))
131: ret = tmp->used = 1;
132:
133: if (addr)
134: for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
135: if (tmp->addr.sa.sa_family == family)
136: {
137: if (family == AF_INET &&
1.1.1.4 ! misho 138: tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1.1.2 misho 139: ret = match_addr = tmp->used = 1;
1.1 misho 140: else if (family == AF_INET6 &&
141: IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
1.1.1.4 ! misho 142: &addr->addr6))
1.1.1.2 misho 143: ret = match_addr = tmp->used = 1;
1.1 misho 144: }
145: }
146:
1.1.1.2 misho 147: if (!match_addr)
148: for (tmp = daemon->if_except; tmp; tmp = tmp->next)
149: if (tmp->name && wildcard_match(tmp->name, name))
150: ret = 0;
1.1 misho 151:
152:
153: for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
154: if (tmp->name)
155: {
1.1.1.2 misho 156: if (strcmp(tmp->name, name) == 0 &&
157: (tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
1.1 misho 158: break;
159: }
160: else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
1.1.1.4 ! misho 161: tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1 misho 162: break;
163: else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
1.1.1.4 ! misho 164: IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6))
1.1 misho 165: break;
166:
167: if (tmp && auth)
168: {
169: *auth = 1;
170: ret = 1;
171: }
172:
173: return ret;
174: }
175:
176:
1.1.1.4 ! misho 177: /* Fix for problem that the kernel sometimes reports the loopback interface as the
1.1 misho 178: arrival interface when a packet originates locally, even when sent to address of
179: an interface other than the loopback. Accept packet if it arrived via a loopback
180: interface, even when we're not accepting packets that way, as long as the destination
181: address is one we're believing. Interface list must be up-to-date before calling. */
1.1.1.4 ! misho 182: int loopback_exception(int fd, int family, union all_addr *addr, char *name)
1.1 misho 183: {
184: struct ifreq ifr;
185: struct irec *iface;
186:
1.1.1.4 ! misho 187: safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
1.1 misho 188: if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1 &&
189: ifr.ifr_flags & IFF_LOOPBACK)
190: {
191: for (iface = daemon->interfaces; iface; iface = iface->next)
192: if (iface->addr.sa.sa_family == family)
193: {
194: if (family == AF_INET)
195: {
1.1.1.4 ! misho 196: if (iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1 misho 197: return 1;
198: }
1.1.1.4 ! misho 199: else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr6))
1.1 misho 200: return 1;
201: }
202: }
203: return 0;
204: }
205:
1.1.1.2 misho 206: /* If we're configured with something like --interface=eth0:0 then we'll listen correctly
207: on the relevant address, but the name of the arrival interface, derived from the
208: index won't match the config. Check that we found an interface address for the arrival
209: interface: daemon->interfaces must be up-to-date. */
1.1.1.4 ! misho 210: int label_exception(int index, int family, union all_addr *addr)
1.1 misho 211: {
212: struct irec *iface;
1.1.1.2 misho 213:
214: /* labels only supported on IPv4 addresses. */
215: if (family != AF_INET)
216: return 0;
217:
218: for (iface = daemon->interfaces; iface; iface = iface->next)
219: if (iface->index == index && iface->addr.sa.sa_family == AF_INET &&
1.1.1.4 ! misho 220: iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr)
1.1.1.2 misho 221: return 1;
222:
223: return 0;
224: }
225:
226: struct iface_param {
227: struct addrlist *spare;
228: int fd;
229: };
230:
231: static int iface_allowed(struct iface_param *param, int if_index, char *label,
1.1.1.3 misho 232: union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags)
1.1.1.2 misho 233: {
234: struct irec *iface;
235: int mtu = 0, loopback;
1.1 misho 236: struct ifreq ifr;
237: int tftp_ok = !!option_bool(OPT_TFTP);
238: int dhcp_ok = 1;
239: int auth_dns = 0;
1.1.1.4 ! misho 240: int is_label = 0;
1.1.1.2 misho 241: #if defined(HAVE_DHCP) || defined(HAVE_TFTP)
1.1 misho 242: struct iname *tmp;
243: #endif
244:
1.1.1.2 misho 245: (void)prefixlen;
1.1 misho 246:
1.1.1.2 misho 247: if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
248: ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
249: return 0;
1.1 misho 250:
251: loopback = ifr.ifr_flags & IFF_LOOPBACK;
252:
253: if (loopback)
1.1.1.2 misho 254: dhcp_ok = 0;
255:
256: if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
1.1 misho 257: mtu = ifr.ifr_mtu;
258:
1.1.1.2 misho 259: if (!label)
260: label = ifr.ifr_name;
1.1.1.4 ! misho 261: else
! 262: is_label = strcmp(label, ifr.ifr_name);
1.1.1.2 misho 263:
264: /* maintain a list of all addresses on all interfaces for --local-service option */
265: if (option_bool(OPT_LOCAL_SERVICE))
266: {
267: struct addrlist *al;
268:
269: if (param->spare)
270: {
271: al = param->spare;
272: param->spare = al->next;
273: }
274: else
275: al = whine_malloc(sizeof(struct addrlist));
276:
277: if (al)
278: {
279: al->next = daemon->interface_addrs;
280: daemon->interface_addrs = al;
281: al->prefixlen = prefixlen;
282:
283: if (addr->sa.sa_family == AF_INET)
284: {
1.1.1.4 ! misho 285: al->addr.addr4 = addr->in.sin_addr;
1.1.1.2 misho 286: al->flags = 0;
287: }
288: else
289: {
1.1.1.4 ! misho 290: al->addr.addr6 = addr->in6.sin6_addr;
1.1.1.2 misho 291: al->flags = ADDRLIST_IPV6;
292: }
293: }
294: }
1.1 misho 295:
1.1.1.2 misho 296: if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
297: {
298: struct interface_name *int_name;
299: struct addrlist *al;
300: #ifdef HAVE_AUTH
301: struct auth_zone *zone;
302: struct auth_name_list *name;
303:
304: /* Find subnets in auth_zones */
305: for (zone = daemon->auth_zones; zone; zone = zone->next)
306: for (name = zone->interface_names; name; name = name->next)
307: if (wildcard_match(name->name, label))
308: {
309: if (addr->sa.sa_family == AF_INET && (name->flags & AUTH4))
310: {
311: if (param->spare)
312: {
313: al = param->spare;
314: param->spare = al->next;
315: }
316: else
317: al = whine_malloc(sizeof(struct addrlist));
318:
319: if (al)
320: {
321: al->next = zone->subnet;
322: zone->subnet = al;
323: al->prefixlen = prefixlen;
1.1.1.4 ! misho 324: al->addr.addr4 = addr->in.sin_addr;
1.1.1.2 misho 325: al->flags = 0;
326: }
327: }
328:
329: if (addr->sa.sa_family == AF_INET6 && (name->flags & AUTH6))
330: {
331: if (param->spare)
332: {
333: al = param->spare;
334: param->spare = al->next;
335: }
336: else
337: al = whine_malloc(sizeof(struct addrlist));
338:
339: if (al)
340: {
341: al->next = zone->subnet;
342: zone->subnet = al;
343: al->prefixlen = prefixlen;
1.1.1.4 ! misho 344: al->addr.addr6 = addr->in6.sin6_addr;
1.1.1.2 misho 345: al->flags = ADDRLIST_IPV6;
346: }
347: }
348: }
349: #endif
350:
351: /* Update addresses from interface_names. These are a set independent
352: of the set we're listening on. */
353: for (int_name = daemon->int_names; int_name; int_name = int_name->next)
354: if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 &&
355: (addr->sa.sa_family == int_name->family || int_name->family == 0))
356: {
357: if (param->spare)
358: {
359: al = param->spare;
360: param->spare = al->next;
361: }
362: else
363: al = whine_malloc(sizeof(struct addrlist));
364:
365: if (al)
366: {
367: al->next = int_name->addr;
368: int_name->addr = al;
369:
370: if (addr->sa.sa_family == AF_INET)
371: {
1.1.1.4 ! misho 372: al->addr.addr4 = addr->in.sin_addr;
1.1.1.2 misho 373: al->flags = 0;
374: }
375: else
376: {
1.1.1.4 ! misho 377: al->addr.addr6 = addr->in6.sin6_addr;
1.1.1.2 misho 378: al->flags = ADDRLIST_IPV6;
1.1.1.3 misho 379: /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
380: don't appear in forward queries, but will in reverse ones. */
381: if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
382: al->flags |= ADDRLIST_REVONLY;
1.1.1.2 misho 383: }
384: }
385: }
386: }
387:
388: /* check whether the interface IP has been added already
389: we call this routine multiple times. */
390: for (iface = daemon->interfaces; iface; iface = iface->next)
1.1.1.4 ! misho 391: if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
1.1.1.2 misho 392: {
1.1.1.3 misho 393: iface->dad = !!(iface_flags & IFACE_TENTATIVE);
1.1.1.2 misho 394: iface->found = 1; /* for garbage collection */
1.1.1.4 ! misho 395: iface->netmask = netmask;
1.1.1.2 misho 396: return 1;
397: }
398:
399: /* If we are restricting the set of interfaces to use, make
1.1 misho 400: sure that loopback interfaces are in that set. */
401: if (daemon->if_names && loopback)
402: {
403: struct iname *lo;
404: for (lo = daemon->if_names; lo; lo = lo->next)
405: if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
406: break;
407:
408: if (!lo && (lo = whine_malloc(sizeof(struct iname))))
409: {
410: if ((lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
411: {
412: strcpy(lo->name, ifr.ifr_name);
413: lo->used = 1;
414: lo->next = daemon->if_names;
415: daemon->if_names = lo;
416: }
417: else
418: free(lo);
419: }
420: }
421:
422: if (addr->sa.sa_family == AF_INET &&
1.1.1.4 ! misho 423: !iface_check(AF_INET, (union all_addr *)&addr->in.sin_addr, label, &auth_dns))
1.1 misho 424: return 1;
425:
426: if (addr->sa.sa_family == AF_INET6 &&
1.1.1.4 ! misho 427: !iface_check(AF_INET6, (union all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
1.1 misho 428: return 1;
429:
430: #ifdef HAVE_DHCP
431: /* No DHCP where we're doing auth DNS. */
432: if (auth_dns)
433: {
434: tftp_ok = 0;
435: dhcp_ok = 0;
436: }
437: else
438: for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
439: if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
440: {
441: tftp_ok = 0;
442: dhcp_ok = 0;
443: }
444: #endif
445:
1.1.1.2 misho 446:
447: #ifdef HAVE_TFTP
448: if (daemon->tftp_interfaces)
449: {
450: /* dedicated tftp interface list */
451: tftp_ok = 0;
452: for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
453: if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
454: tftp_ok = 1;
455: }
456: #endif
457:
1.1 misho 458: /* add to list */
459: if ((iface = whine_malloc(sizeof(struct irec))))
460: {
461: iface->addr = *addr;
462: iface->netmask = netmask;
463: iface->tftp_ok = tftp_ok;
464: iface->dhcp_ok = dhcp_ok;
465: iface->dns_auth = auth_dns;
466: iface->mtu = mtu;
1.1.1.3 misho 467: iface->dad = !!(iface_flags & IFACE_TENTATIVE);
1.1.1.2 misho 468: iface->found = 1;
469: iface->done = iface->multicast_done = iface->warned = 0;
1.1 misho 470: iface->index = if_index;
1.1.1.4 ! misho 471: iface->label = is_label;
1.1 misho 472: if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
473: {
474: strcpy(iface->name, ifr.ifr_name);
1.1.1.2 misho 475: iface->next = daemon->interfaces;
476: daemon->interfaces = iface;
1.1 misho 477: return 1;
478: }
479: free(iface);
480:
481: }
482:
483: errno = ENOMEM;
484: return 0;
485: }
486:
487: static int iface_allowed_v6(struct in6_addr *local, int prefix,
488: int scope, int if_index, int flags,
489: int preferred, int valid, void *vparam)
490: {
491: union mysockaddr addr;
492: struct in_addr netmask; /* dummy */
493: netmask.s_addr = 0;
494:
495: (void)scope; /* warning */
496: (void)preferred;
497: (void)valid;
498:
499: memset(&addr, 0, sizeof(addr));
500: #ifdef HAVE_SOCKADDR_SA_LEN
501: addr.in6.sin6_len = sizeof(addr.in6);
502: #endif
503: addr.in6.sin6_family = AF_INET6;
504: addr.in6.sin6_addr = *local;
505: addr.in6.sin6_port = htons(daemon->port);
1.1.1.2 misho 506: /* FreeBSD insists this is zero for non-linklocal addresses */
507: if (IN6_IS_ADDR_LINKLOCAL(local))
508: addr.in6.sin6_scope_id = if_index;
509: else
510: addr.in6.sin6_scope_id = 0;
1.1 misho 511:
1.1.1.3 misho 512: return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
1.1 misho 513: }
514:
1.1.1.2 misho 515: static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
1.1 misho 516: struct in_addr netmask, struct in_addr broadcast, void *vparam)
517: {
518: union mysockaddr addr;
1.1.1.2 misho 519: int prefix, bit;
1.1.1.3 misho 520:
521: (void)broadcast; /* warning */
1.1 misho 522:
523: memset(&addr, 0, sizeof(addr));
524: #ifdef HAVE_SOCKADDR_SA_LEN
525: addr.in.sin_len = sizeof(addr.in);
526: #endif
527: addr.in.sin_family = AF_INET;
528: addr.in.sin_addr = local;
529: addr.in.sin_port = htons(daemon->port);
530:
1.1.1.2 misho 531: /* determine prefix length from netmask */
532: for (prefix = 32, bit = 1; (bit & ntohl(netmask.s_addr)) == 0 && prefix != 0; bit = bit << 1, prefix--);
533:
534: return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
1.1 misho 535: }
1.1.1.4 ! misho 536:
! 537: /*
! 538: * Clean old interfaces no longer found.
! 539: */
! 540: static void clean_interfaces()
! 541: {
! 542: struct irec *iface;
! 543: struct irec **up = &daemon->interfaces;
! 544:
! 545: for (iface = *up; iface; iface = *up)
! 546: {
! 547: if (!iface->found && !iface->done)
! 548: {
! 549: *up = iface->next;
! 550: free(iface->name);
! 551: free(iface);
! 552: }
! 553: else
! 554: {
! 555: up = &iface->next;
! 556: }
! 557: }
! 558: }
! 559:
! 560: /** Release listener if no other interface needs it.
! 561: *
! 562: * @return 1 if released, 0 if still required
! 563: */
! 564: static int release_listener(struct listener *l)
! 565: {
! 566: if (l->used > 1)
! 567: {
! 568: struct irec *iface;
! 569: for (iface = daemon->interfaces; iface; iface = iface->next)
! 570: if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
! 571: {
! 572: if (iface->found)
! 573: {
! 574: /* update listener to point to active interface instead */
! 575: if (!l->iface->found)
! 576: l->iface = iface;
! 577: }
! 578: else
! 579: {
! 580: l->used--;
! 581: iface->done = 0;
! 582: }
! 583: }
! 584:
! 585: /* Someone is still using this listener, skip its deletion */
! 586: if (l->used > 0)
! 587: return 0;
! 588: }
! 589:
! 590: if (l->iface->done)
! 591: {
! 592: int port;
! 593:
! 594: port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
! 595: my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"),
! 596: l->iface->name, l->iface->index, daemon->addrbuff, port);
! 597: /* In case it ever returns */
! 598: l->iface->done = 0;
! 599: }
! 600:
! 601: if (l->fd != -1)
! 602: close(l->fd);
! 603: if (l->tcpfd != -1)
! 604: close(l->tcpfd);
! 605: if (l->tftpfd != -1)
! 606: close(l->tftpfd);
! 607:
! 608: free(l);
! 609: return 1;
! 610: }
! 611:
1.1.1.2 misho 612: int enumerate_interfaces(int reset)
1.1 misho 613: {
1.1.1.2 misho 614: static struct addrlist *spare = NULL;
1.1.1.3 misho 615: static int done = 0;
1.1.1.2 misho 616: struct iface_param param;
617: int errsave, ret = 1;
618: struct addrlist *addr, *tmp;
619: struct interface_name *intname;
620: struct irec *iface;
621: #ifdef HAVE_AUTH
622: struct auth_zone *zone;
623: #endif
624:
625: /* Do this max once per select cycle - also inhibits netlink socket use
626: in TCP child processes. */
627:
628: if (reset)
629: {
630: done = 0;
631: return 1;
632: }
633:
1.1.1.3 misho 634: if (done)
1.1.1.2 misho 635: return 1;
636:
637: done = 1;
638:
639: if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
640: return 0;
641:
642: /* Mark interfaces for garbage collection */
643: for (iface = daemon->interfaces; iface; iface = iface->next)
644: iface->found = 0;
645:
646: /* remove addresses stored against interface_names */
647: for (intname = daemon->int_names; intname; intname = intname->next)
648: {
649: for (addr = intname->addr; addr; addr = tmp)
650: {
651: tmp = addr->next;
652: addr->next = spare;
653: spare = addr;
654: }
655:
656: intname->addr = NULL;
657: }
658:
659: /* Remove list of addresses of local interfaces */
660: for (addr = daemon->interface_addrs; addr; addr = tmp)
661: {
662: tmp = addr->next;
663: addr->next = spare;
664: spare = addr;
665: }
666: daemon->interface_addrs = NULL;
667:
668: #ifdef HAVE_AUTH
669: /* remove addresses stored against auth_zone subnets, but not
670: ones configured as address literals */
671: for (zone = daemon->auth_zones; zone; zone = zone->next)
672: if (zone->interface_names)
673: {
674: struct addrlist **up;
675: for (up = &zone->subnet, addr = zone->subnet; addr; addr = tmp)
676: {
677: tmp = addr->next;
678: if (addr->flags & ADDRLIST_LITERAL)
679: up = &addr->next;
680: else
681: {
682: *up = addr->next;
683: addr->next = spare;
684: spare = addr;
685: }
686: }
687: }
688: #endif
689:
690: param.spare = spare;
691:
692: ret = iface_enumerate(AF_INET6, ¶m, iface_allowed_v6);
1.1 misho 693:
1.1.1.2 misho 694: if (ret)
695: ret = iface_enumerate(AF_INET, ¶m, iface_allowed_v4);
696:
697: errsave = errno;
698: close(param.fd);
699:
700: if (option_bool(OPT_CLEVERBIND))
701: {
702: /* Garbage-collect listeners listening on addresses that no longer exist.
703: Does nothing when not binding interfaces or for listeners on localhost,
704: since the ->iface field is NULL. Note that this needs the protections
1.1.1.4 ! misho 705: against reentrancy, hence it's here. It also means there's a possibility,
1.1.1.2 misho 706: in OPT_CLEVERBIND mode, that at listener will just disappear after
707: a call to enumerate_interfaces, this is checked OK on all calls. */
708: struct listener *l, *tmp, **up;
1.1.1.4 ! misho 709: int freed = 0;
1.1.1.2 misho 710:
711: for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
712: {
713: tmp = l->next;
714:
715: if (!l->iface || l->iface->found)
716: up = &l->next;
1.1.1.4 ! misho 717: else if (release_listener(l))
1.1.1.2 misho 718: {
1.1.1.4 ! misho 719: *up = tmp;
! 720: freed = 1;
1.1.1.2 misho 721: }
722: }
1.1.1.4 ! misho 723:
! 724: if (freed)
! 725: clean_interfaces();
1.1.1.2 misho 726: }
1.1.1.4 ! misho 727:
1.1.1.2 misho 728: errno = errsave;
729: spare = param.spare;
1.1.1.3 misho 730:
1.1.1.2 misho 731: return ret;
1.1 misho 732: }
733:
734: /* set NONBLOCK bit on fd: See Stevens 16.6 */
735: int fix_fd(int fd)
736: {
737: int flags;
738:
739: if ((flags = fcntl(fd, F_GETFL)) == -1 ||
740: fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
741: return 0;
742:
743: return 1;
744: }
745:
746: static int make_sock(union mysockaddr *addr, int type, int dienow)
747: {
748: int family = addr->sa.sa_family;
749: int fd, rc, opt = 1;
750:
751: if ((fd = socket(family, type, 0)) == -1)
752: {
1.1.1.4 ! misho 753: int port, errsave;
1.1 misho 754: char *s;
755:
756: /* No error if the kernel just doesn't support this IP flavour */
757: if (errno == EPROTONOSUPPORT ||
758: errno == EAFNOSUPPORT ||
759: errno == EINVAL)
760: return -1;
761:
762: err:
1.1.1.4 ! misho 763: errsave = errno;
1.1 misho 764: port = prettyprint_addr(addr, daemon->addrbuff);
765: if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
766: sprintf(daemon->addrbuff, "port %d", port);
767: s = _("failed to create listening socket for %s: %s");
768:
769: if (fd != -1)
770: close (fd);
1.1.1.2 misho 771:
1.1.1.4 ! misho 772: errno = errsave;
1.1.1.2 misho 773:
1.1 misho 774: if (dienow)
775: {
776: /* failure to bind addresses given by --listen-address at this point
777: is OK if we're doing bind-dynamic */
778: if (!option_bool(OPT_CLEVERBIND))
779: die(s, daemon->addrbuff, EC_BADNET);
780: }
781: else
782: my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
783:
784: return -1;
785: }
786:
787: if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
788: goto err;
789:
790: if (family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
791: goto err;
792:
793: if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1)
794: goto err;
795:
796: if (type == SOCK_STREAM)
797: {
1.1.1.4 ! misho 798: #ifdef TCP_FASTOPEN
! 799: int qlen = 5;
! 800: setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
! 801: #endif
! 802:
! 803: if (listen(fd, TCP_BACKLOG) == -1)
1.1 misho 804: goto err;
805: }
1.1.1.2 misho 806: else if (family == AF_INET)
1.1 misho 807: {
1.1.1.2 misho 808: if (!option_bool(OPT_NOWILD))
1.1 misho 809: {
810: #if defined(HAVE_LINUX_NETWORK)
811: if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1)
812: goto err;
813: #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
814: if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
815: setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1)
816: goto err;
817: #endif
818: }
1.1.1.2 misho 819: }
820: else if (!set_ipv6pktinfo(fd))
821: goto err;
1.1 misho 822:
823: return fd;
824: }
825:
826: int set_ipv6pktinfo(int fd)
827: {
828: int opt = 1;
829:
830: /* The API changed around Linux 2.6.14 but the old ABI is still supported:
831: handle all combinations of headers and kernel.
832: OpenWrt note that this fixes the problem addressed by your very broken patch. */
833: daemon->v6pktinfo = IPV6_PKTINFO;
834:
835: #ifdef IPV6_RECVPKTINFO
836: if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opt, sizeof(opt)) != -1)
837: return 1;
838: # ifdef IPV6_2292PKTINFO
839: else if (errno == ENOPROTOOPT && setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTINFO, &opt, sizeof(opt)) != -1)
840: {
841: daemon->v6pktinfo = IPV6_2292PKTINFO;
842: return 1;
843: }
844: # endif
845: #else
846: if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &opt, sizeof(opt)) != -1)
847: return 1;
848: #endif
849:
850: return 0;
851: }
852:
853:
854: /* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
855: int tcp_interface(int fd, int af)
856: {
1.1.1.4 ! misho 857: (void)fd; /* suppress potential unused warning */
! 858: (void)af; /* suppress potential unused warning */
1.1 misho 859: int if_index = 0;
860:
861: #ifdef HAVE_LINUX_NETWORK
862: int opt = 1;
863: struct cmsghdr *cmptr;
864: struct msghdr msg;
1.1.1.3 misho 865: socklen_t len;
1.1 misho 866:
1.1.1.3 misho 867: /* use mshdr so that the CMSDG_* macros are available */
1.1 misho 868: msg.msg_control = daemon->packet;
1.1.1.3 misho 869: msg.msg_controllen = len = daemon->packet_buff_sz;
1.1 misho 870:
871: /* we overwrote the buffer... */
872: daemon->srv_save = NULL;
873:
874: if (af == AF_INET)
875: {
876: if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
1.1.1.3 misho 877: getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, &len) != -1)
878: {
879: msg.msg_controllen = len;
880: for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
881: if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
882: {
883: union {
884: unsigned char *c;
885: struct in_pktinfo *p;
886: } p;
887:
888: p.c = CMSG_DATA(cmptr);
889: if_index = p.p->ipi_ifindex;
890: }
891: }
1.1 misho 892: }
893: else
894: {
895: /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
896: it was removed in RFC-3542 !!!!
897:
898: Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always
899: uses the old ABI, and should work with pre- and post-3542 kernel headers */
900:
901: #ifdef IPV6_2292PKTOPTIONS
902: # define PKTOPTIONS IPV6_2292PKTOPTIONS
903: #else
904: # define PKTOPTIONS IPV6_PKTOPTIONS
905: #endif
906:
907: if (set_ipv6pktinfo(fd) &&
1.1.1.3 misho 908: getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
1.1 misho 909: {
1.1.1.3 misho 910: msg.msg_controllen = len;
911: for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
1.1 misho 912: if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
913: {
914: union {
915: unsigned char *c;
916: struct in6_pktinfo *p;
917: } p;
918: p.c = CMSG_DATA(cmptr);
919:
920: if_index = p.p->ipi6_ifindex;
921: }
922: }
923: }
924: #endif /* Linux */
925:
926: return if_index;
927: }
928:
929: static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
930: {
931: struct listener *l = NULL;
932: int fd = -1, tcpfd = -1, tftpfd = -1;
933:
1.1.1.2 misho 934: (void)do_tftp;
935:
1.1 misho 936: if (daemon->port != 0)
937: {
938: fd = make_sock(addr, SOCK_DGRAM, dienow);
939: tcpfd = make_sock(addr, SOCK_STREAM, dienow);
940: }
941:
942: #ifdef HAVE_TFTP
943: if (do_tftp)
944: {
945: if (addr->sa.sa_family == AF_INET)
946: {
947: /* port must be restored to DNS port for TCP code */
948: short save = addr->in.sin_port;
949: addr->in.sin_port = htons(TFTP_PORT);
950: tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
951: addr->in.sin_port = save;
952: }
953: else
954: {
955: short save = addr->in6.sin6_port;
956: addr->in6.sin6_port = htons(TFTP_PORT);
957: tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
958: addr->in6.sin6_port = save;
959: }
960: }
961: #endif
962:
963: if (fd != -1 || tcpfd != -1 || tftpfd != -1)
964: {
965: l = safe_malloc(sizeof(struct listener));
966: l->next = NULL;
967: l->fd = fd;
968: l->tcpfd = tcpfd;
1.1.1.4 ! misho 969: l->tftpfd = tftpfd;
! 970: l->addr = *addr;
! 971: l->used = 1;
1.1.1.2 misho 972: l->iface = NULL;
1.1 misho 973: }
974:
975: return l;
976: }
977:
978: void create_wildcard_listeners(void)
979: {
980: union mysockaddr addr;
981: struct listener *l, *l6;
982:
983: memset(&addr, 0, sizeof(addr));
984: #ifdef HAVE_SOCKADDR_SA_LEN
985: addr.in.sin_len = sizeof(addr.in);
986: #endif
987: addr.in.sin_family = AF_INET;
988: addr.in.sin_addr.s_addr = INADDR_ANY;
989: addr.in.sin_port = htons(daemon->port);
990:
991: l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
992:
993: memset(&addr, 0, sizeof(addr));
1.1.1.4 ! misho 994: #ifdef HAVE_SOCKADDR_SA_LEN
1.1 misho 995: addr.in6.sin6_len = sizeof(addr.in6);
1.1.1.4 ! misho 996: #endif
1.1 misho 997: addr.in6.sin6_family = AF_INET6;
998: addr.in6.sin6_addr = in6addr_any;
999: addr.in6.sin6_port = htons(daemon->port);
1000:
1001: l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
1002: if (l)
1003: l->next = l6;
1004: else
1005: l = l6;
1006:
1007: daemon->listeners = l;
1008: }
1009:
1.1.1.4 ! misho 1010: static struct listener *find_listener(union mysockaddr *addr)
! 1011: {
! 1012: struct listener *l;
! 1013: for (l = daemon->listeners; l; l = l->next)
! 1014: if (sockaddr_isequal(&l->addr, addr))
! 1015: return l;
! 1016: return NULL;
! 1017: }
! 1018:
1.1 misho 1019: void create_bound_listeners(int dienow)
1020: {
1021: struct listener *new;
1022: struct irec *iface;
1023: struct iname *if_tmp;
1.1.1.4 ! misho 1024: struct listener *existing;
1.1 misho 1025:
1026: for (iface = daemon->interfaces; iface; iface = iface->next)
1.1.1.4 ! misho 1027: if (!iface->done && !iface->dad && iface->found)
1.1 misho 1028: {
1.1.1.4 ! misho 1029: existing = find_listener(&iface->addr);
! 1030: if (existing)
! 1031: {
! 1032: iface->done = 1;
! 1033: existing->used++; /* increase usage counter */
! 1034: }
! 1035: else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
! 1036: {
! 1037: new->iface = iface;
! 1038: new->next = daemon->listeners;
! 1039: daemon->listeners = new;
! 1040: iface->done = 1;
! 1041:
! 1042: /* Don't log the initial set of listen addresses created
! 1043: at startup, since this is happening before the logging
! 1044: system is initialised and the sign-on printed. */
! 1045: if (!dienow)
! 1046: {
! 1047: int port = prettyprint_addr(&iface->addr, daemon->addrbuff);
! 1048: my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"),
! 1049: iface->name, iface->index, daemon->addrbuff, port);
! 1050: }
! 1051: }
1.1 misho 1052: }
1053:
1054: /* Check for --listen-address options that haven't been used because there's
1055: no interface with a matching address. These may be valid: eg it's possible
1056: to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
1057:
1058: If the address isn't valid the bind() will fail and we'll die()
1059: (except in bind-dynamic mode, when we'll complain but keep trying.)
1060:
1061: The resulting listeners have the ->iface field NULL, and this has to be
1062: handled by the DNS and TFTP code. It disables --localise-queries processing
1063: (no netmask) and some MTU login the tftp code. */
1064:
1065: for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
1066: if (!if_tmp->used &&
1067: (new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
1068: {
1069: new->next = daemon->listeners;
1070: daemon->listeners = new;
1.1.1.4 ! misho 1071:
! 1072: if (!dienow)
! 1073: {
! 1074: int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
! 1075: my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port);
! 1076: }
1.1 misho 1077: }
1078: }
1079:
1.1.1.2 misho 1080: /* In --bind-interfaces, the only access control is the addresses we're listening on.
1081: There's nothing to avoid a query to the address of an internal interface arriving via
1082: an external interface where we don't want to accept queries, except that in the usual
1083: case the addresses of internal interfaces are RFC1918. When bind-interfaces in use,
1084: and we listen on an address that looks like it's probably globally routeable, shout.
1085:
1086: The fix is to use --bind-dynamic, which actually checks the arrival interface too.
1087: Tough if your platform doesn't support this.
1088:
1089: Note that checking the arrival interface is supported in the standard IPv6 API and
1090: always done, so we don't warn about any IPv6 addresses here.
1091: */
1092:
1093: void warn_bound_listeners(void)
1094: {
1095: struct irec *iface;
1096: int advice = 0;
1097:
1098: for (iface = daemon->interfaces; iface; iface = iface->next)
1099: if (!iface->dns_auth)
1100: {
1101: if (iface->addr.sa.sa_family == AF_INET)
1102: {
1103: if (!private_net(iface->addr.in.sin_addr, 1))
1104: {
1105: inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
1106: iface->warned = advice = 1;
1107: my_syslog(LOG_WARNING,
1108: _("LOUD WARNING: listening on %s may accept requests via interfaces other than %s"),
1109: daemon->addrbuff, iface->name);
1110: }
1111: }
1112: }
1113:
1114: if (advice)
1115: my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"));
1116: }
1117:
1.1.1.4 ! misho 1118: void warn_wild_labels(void)
! 1119: {
! 1120: struct irec *iface;
! 1121:
! 1122: for (iface = daemon->interfaces; iface; iface = iface->next)
! 1123: if (iface->found && iface->name && iface->label)
! 1124: my_syslog(LOG_WARNING, _("warning: using interface %s instead"), iface->name);
! 1125: }
! 1126:
1.1.1.2 misho 1127: void warn_int_names(void)
1128: {
1129: struct interface_name *intname;
1130:
1131: for (intname = daemon->int_names; intname; intname = intname->next)
1132: if (!intname->addr)
1133: my_syslog(LOG_WARNING, _("warning: no addresses found for interface %s"), intname->intr);
1134: }
1135:
1.1 misho 1136: int is_dad_listeners(void)
1137: {
1138: struct irec *iface;
1139:
1140: if (option_bool(OPT_NOWILD))
1141: for (iface = daemon->interfaces; iface; iface = iface->next)
1142: if (iface->dad && !iface->done)
1143: return 1;
1144:
1145: return 0;
1146: }
1147:
1148: #ifdef HAVE_DHCP6
1149: void join_multicast(int dienow)
1150: {
1151: struct irec *iface, *tmp;
1152:
1153: for (iface = daemon->interfaces; iface; iface = iface->next)
1154: if (iface->addr.sa.sa_family == AF_INET6 && iface->dhcp_ok && !iface->multicast_done)
1155: {
1156: /* There's an irec per address but we only want to join for multicast
1157: once per interface. Weed out duplicates. */
1158: for (tmp = daemon->interfaces; tmp; tmp = tmp->next)
1159: if (tmp->multicast_done && tmp->index == iface->index)
1160: break;
1161:
1162: iface->multicast_done = 1;
1163:
1164: if (!tmp)
1165: {
1166: struct ipv6_mreq mreq;
1167: int err = 0;
1168:
1169: mreq.ipv6mr_interface = iface->index;
1170:
1171: inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
1172:
1.1.1.2 misho 1173: if ((daemon->doing_dhcp6 || daemon->relay6) &&
1.1 misho 1174: setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1.1.1.3 misho 1175: err = errno;
1.1 misho 1176:
1177: inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
1178:
1179: if (daemon->doing_dhcp6 &&
1180: setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1.1.1.3 misho 1181: err = errno;
1.1 misho 1182:
1183: inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
1184:
1185: if (daemon->doing_ra &&
1186: setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1.1.1.3 misho 1187: err = errno;
1.1 misho 1188:
1189: if (err)
1190: {
1191: char *s = _("interface %s failed to join DHCPv6 multicast group: %s");
1.1.1.3 misho 1192: errno = err;
1193:
1194: #ifdef HAVE_LINUX_NETWORK
1195: if (errno == ENOMEM)
1196: my_syslog(LOG_ERR, _("try increasing /proc/sys/net/core/optmem_max"));
1197: #endif
1198:
1.1 misho 1199: if (dienow)
1200: die(s, iface->name, EC_BADNET);
1201: else
1202: my_syslog(LOG_ERR, s, iface->name, strerror(errno));
1203: }
1204: }
1205: }
1206: }
1207: #endif
1208:
1209: /* return a UDP socket bound to a random port, have to cope with straying into
1210: occupied port nos and reserved ones. */
1211: int random_sock(int family)
1212: {
1213: int fd;
1214:
1215: if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
1216: {
1217: union mysockaddr addr;
1.1.1.3 misho 1218: unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
1.1 misho 1219: int tries = ports_avail < 30 ? 3 * ports_avail : 100;
1220:
1221: memset(&addr, 0, sizeof(addr));
1222: addr.sa.sa_family = family;
1223:
1224: /* don't loop forever if all ports in use. */
1225:
1226: if (fix_fd(fd))
1227: while(tries--)
1228: {
1.1.1.4 ! misho 1229: unsigned short port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
1.1 misho 1230:
1231: if (family == AF_INET)
1232: {
1233: addr.in.sin_addr.s_addr = INADDR_ANY;
1234: addr.in.sin_port = port;
1235: #ifdef HAVE_SOCKADDR_SA_LEN
1236: addr.in.sin_len = sizeof(struct sockaddr_in);
1237: #endif
1238: }
1239: else
1240: {
1241: addr.in6.sin6_addr = in6addr_any;
1242: addr.in6.sin6_port = port;
1243: #ifdef HAVE_SOCKADDR_SA_LEN
1244: addr.in6.sin6_len = sizeof(struct sockaddr_in6);
1245: #endif
1246: }
1247:
1248: if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
1249: return fd;
1250:
1251: if (errno != EADDRINUSE && errno != EACCES)
1252: break;
1253: }
1254:
1255: close(fd);
1256: }
1257:
1258: return -1;
1259: }
1260:
1261:
1.1.1.4 ! misho 1262: int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp)
1.1 misho 1263: {
1264: union mysockaddr addr_copy = *addr;
1.1.1.4 ! misho 1265: unsigned short port;
! 1266: int tries = 1, done = 0;
! 1267: unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
! 1268:
! 1269: if (addr_copy.sa.sa_family == AF_INET)
! 1270: port = addr_copy.in.sin_port;
! 1271: else
! 1272: port = addr_copy.in6.sin6_port;
1.1 misho 1273:
1274: /* cannot set source _port_ for TCP connections. */
1275: if (is_tcp)
1.1.1.4 ! misho 1276: port = 0;
! 1277:
! 1278: /* Bind a random port within the range given by min-port and max-port */
! 1279: if (port == 0)
! 1280: {
! 1281: tries = ports_avail < 30 ? 3 * ports_avail : 100;
! 1282: port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
! 1283: }
! 1284:
! 1285: while (tries--)
1.1 misho 1286: {
1287: if (addr_copy.sa.sa_family == AF_INET)
1.1.1.4 ! misho 1288: addr_copy.in.sin_port = port;
1.1 misho 1289: else
1.1.1.4 ! misho 1290: addr_copy.in6.sin6_port = port;
! 1291:
! 1292: if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
! 1293: {
! 1294: done = 1;
! 1295: break;
! 1296: }
! 1297:
! 1298: if (errno != EADDRINUSE && errno != EACCES)
! 1299: return 0;
! 1300:
! 1301: port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
1.1 misho 1302: }
1.1.1.4 ! misho 1303:
! 1304: if (!done)
1.1 misho 1305: return 0;
1.1.1.4 ! misho 1306:
! 1307: if (!is_tcp && ifindex > 0)
! 1308: {
! 1309: #if defined(IP_UNICAST_IF)
! 1310: if (addr_copy.sa.sa_family == AF_INET)
! 1311: {
! 1312: uint32_t ifindex_opt = htonl(ifindex);
! 1313: return setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
! 1314: }
! 1315: #endif
! 1316: #if defined (IPV6_UNICAST_IF)
! 1317: if (addr_copy.sa.sa_family == AF_INET6)
! 1318: {
! 1319: uint32_t ifindex_opt = htonl(ifindex);
! 1320: return setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_opt, sizeof(ifindex_opt)) == 0;
! 1321: }
! 1322: #endif
! 1323: }
! 1324:
! 1325: (void)intname; /* suppress potential unused warning */
1.1 misho 1326: #if defined(SO_BINDTODEVICE)
1327: if (intname[0] != 0 &&
1328: setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
1329: return 0;
1330: #endif
1331:
1332: return 1;
1333: }
1334:
1335: static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
1336: {
1337: struct serverfd *sfd;
1.1.1.4 ! misho 1338: unsigned int ifindex = 0;
1.1 misho 1339: int errsave;
1.1.1.4 ! misho 1340: int opt = 1;
! 1341:
1.1 misho 1342: /* when using random ports, servers which would otherwise use
1343: the INADDR_ANY/port0 socket have sfd set to NULL */
1344: if (!daemon->osport && intname[0] == 0)
1345: {
1346: errno = 0;
1347:
1348: if (addr->sa.sa_family == AF_INET &&
1349: addr->in.sin_addr.s_addr == INADDR_ANY &&
1350: addr->in.sin_port == htons(0))
1351: return NULL;
1352:
1353: if (addr->sa.sa_family == AF_INET6 &&
1354: memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
1355: addr->in6.sin6_port == htons(0))
1356: return NULL;
1357: }
1.1.1.4 ! misho 1358:
! 1359: if (intname && strlen(intname) != 0)
! 1360: ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
1.1 misho 1361:
1362: /* may have a suitable one already */
1363: for (sfd = daemon->sfds; sfd; sfd = sfd->next )
1364: if (sockaddr_isequal(&sfd->source_addr, addr) &&
1.1.1.4 ! misho 1365: strcmp(intname, sfd->interface) == 0 &&
! 1366: ifindex == sfd->ifindex)
1.1 misho 1367: return sfd;
1368:
1369: /* need to make a new one. */
1370: errno = ENOMEM; /* in case malloc fails. */
1371: if (!(sfd = whine_malloc(sizeof(struct serverfd))))
1372: return NULL;
1373:
1374: if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
1375: {
1376: free(sfd);
1377: return NULL;
1378: }
1.1.1.4 ! misho 1379:
! 1380: if ((addr->sa.sa_family == AF_INET6 && setsockopt(sfd->fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1) ||
! 1381: !local_bind(sfd->fd, addr, intname, ifindex, 0) || !fix_fd(sfd->fd))
1.1 misho 1382: {
1.1.1.4 ! misho 1383: errsave = errno; /* save error from bind/setsockopt. */
1.1 misho 1384: close(sfd->fd);
1385: free(sfd);
1386: errno = errsave;
1387: return NULL;
1388: }
1.1.1.4 ! misho 1389:
! 1390: safe_strncpy(sfd->interface, intname, sizeof(sfd->interface));
1.1 misho 1391: sfd->source_addr = *addr;
1392: sfd->next = daemon->sfds;
1.1.1.4 ! misho 1393: sfd->ifindex = ifindex;
! 1394: sfd->preallocated = 0;
1.1 misho 1395: daemon->sfds = sfd;
1.1.1.4 ! misho 1396:
1.1 misho 1397: return sfd;
1398: }
1399:
1400: /* create upstream sockets during startup, before root is dropped which may be needed
1401: this allows query_port to be a low port and interface binding */
1402: void pre_allocate_sfds(void)
1403: {
1404: struct server *srv;
1.1.1.4 ! misho 1405: struct serverfd *sfd;
1.1 misho 1406:
1407: if (daemon->query_port != 0)
1408: {
1409: union mysockaddr addr;
1410: memset(&addr, 0, sizeof(addr));
1411: addr.in.sin_family = AF_INET;
1412: addr.in.sin_addr.s_addr = INADDR_ANY;
1413: addr.in.sin_port = htons(daemon->query_port);
1414: #ifdef HAVE_SOCKADDR_SA_LEN
1415: addr.in.sin_len = sizeof(struct sockaddr_in);
1416: #endif
1.1.1.4 ! misho 1417: if ((sfd = allocate_sfd(&addr, "")))
! 1418: sfd->preallocated = 1;
! 1419:
1.1 misho 1420: memset(&addr, 0, sizeof(addr));
1421: addr.in6.sin6_family = AF_INET6;
1422: addr.in6.sin6_addr = in6addr_any;
1423: addr.in6.sin6_port = htons(daemon->query_port);
1424: #ifdef HAVE_SOCKADDR_SA_LEN
1425: addr.in6.sin6_len = sizeof(struct sockaddr_in6);
1426: #endif
1.1.1.4 ! misho 1427: if ((sfd = allocate_sfd(&addr, "")))
! 1428: sfd->preallocated = 1;
1.1 misho 1429: }
1430:
1431: for (srv = daemon->servers; srv; srv = srv->next)
1432: if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
1433: !allocate_sfd(&srv->source_addr, srv->interface) &&
1434: errno != 0 &&
1435: option_bool(OPT_NOWILD))
1436: {
1.1.1.4 ! misho 1437: (void)prettyprint_addr(&srv->source_addr, daemon->namebuff);
1.1 misho 1438: if (srv->interface[0] != 0)
1439: {
1440: strcat(daemon->namebuff, " ");
1441: strcat(daemon->namebuff, srv->interface);
1442: }
1443: die(_("failed to bind server socket for %s: %s"),
1444: daemon->namebuff, EC_BADNET);
1445: }
1446: }
1447:
1.1.1.2 misho 1448: void mark_servers(int flag)
1449: {
1450: struct server *serv;
1451:
1452: /* mark everything with argument flag */
1453: for (serv = daemon->servers; serv; serv = serv->next)
1.1.1.3 misho 1454: {
1455: if (serv->flags & flag)
1456: serv->flags |= SERV_MARK;
1457: #ifdef HAVE_LOOP
1458: /* Give looped servers another chance */
1459: serv->flags &= ~SERV_LOOP;
1460: #endif
1461: }
1.1.1.2 misho 1462: }
1463:
1464: void cleanup_servers(void)
1465: {
1466: struct server *serv, *tmp, **up;
1467:
1468: /* unlink and free anything still marked. */
1469: for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
1470: {
1471: tmp = serv->next;
1472: if (serv->flags & SERV_MARK)
1473: {
1474: server_gone(serv);
1475: *up = serv->next;
1476: if (serv->domain)
1477: free(serv->domain);
1478: free(serv);
1479: }
1480: else
1481: up = &serv->next;
1482: }
1.1.1.3 misho 1483:
1484: #ifdef HAVE_LOOP
1485: /* Now we have a new set of servers, test for loops. */
1486: loop_send_probes();
1487: #endif
1.1.1.2 misho 1488: }
1489:
1490: void add_update_server(int flags,
1491: union mysockaddr *addr,
1492: union mysockaddr *source_addr,
1493: const char *interface,
1494: const char *domain)
1495: {
1496: struct server *serv, *next = NULL;
1497: char *domain_str = NULL;
1498:
1499: /* See if there is a suitable candidate, and unmark */
1500: for (serv = daemon->servers; serv; serv = serv->next)
1501: if (serv->flags & SERV_MARK)
1502: {
1503: if (domain)
1504: {
1505: if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
1506: continue;
1507: }
1508: else
1509: {
1510: if (serv->flags & SERV_HAS_DOMAIN)
1511: continue;
1512: }
1513:
1514: break;
1515: }
1516:
1517: if (serv)
1518: {
1519: domain_str = serv->domain;
1520: next = serv->next;
1521: }
1522: else if ((serv = whine_malloc(sizeof (struct server))))
1523: {
1524: /* Not found, create a new one. */
1525: if (domain && !(domain_str = whine_malloc(strlen(domain)+1)))
1526: {
1527: free(serv);
1528: serv = NULL;
1529: }
1530: else
1531: {
1532: struct server *s;
1533: /* Add to the end of the chain, for order */
1534: if (!daemon->servers)
1535: daemon->servers = serv;
1536: else
1537: {
1538: for (s = daemon->servers; s->next; s = s->next);
1539: s->next = serv;
1540: }
1541: if (domain)
1542: strcpy(domain_str, domain);
1543: }
1544: }
1545:
1546: if (serv)
1547: {
1548: memset(serv, 0, sizeof(struct server));
1549: serv->flags = flags;
1550: serv->domain = domain_str;
1551: serv->next = next;
1552: serv->queries = serv->failed_queries = 0;
1.1.1.3 misho 1553: #ifdef HAVE_LOOP
1554: serv->uid = rand32();
1555: #endif
1556:
1.1.1.2 misho 1557: if (domain)
1558: serv->flags |= SERV_HAS_DOMAIN;
1559:
1560: if (interface)
1.1.1.4 ! misho 1561: safe_strncpy(serv->interface, interface, sizeof(serv->interface));
1.1.1.2 misho 1562: if (addr)
1563: serv->addr = *addr;
1564: if (source_addr)
1565: serv->source_addr = *source_addr;
1566: }
1567: }
1.1 misho 1568:
1569: void check_servers(void)
1570: {
1571: struct irec *iface;
1.1.1.2 misho 1572: struct server *serv;
1.1.1.4 ! misho 1573: struct serverfd *sfd, *tmp, **up;
1.1.1.3 misho 1574: int port = 0, count;
1.1.1.4 ! misho 1575: int locals = 0;
1.1 misho 1576:
1577: /* interface may be new since startup */
1578: if (!option_bool(OPT_NOWILD))
1.1.1.2 misho 1579: enumerate_interfaces(0);
1.1.1.4 ! misho 1580:
! 1581: /* don't garbage collect pre-allocated sfds. */
! 1582: for (sfd = daemon->sfds; sfd; sfd = sfd->next)
! 1583: sfd->used = sfd->preallocated;
1.1.1.3 misho 1584:
1585: for (count = 0, serv = daemon->servers; serv; serv = serv->next)
1.1 misho 1586: {
1.1.1.3 misho 1587: if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
1.1 misho 1588: {
1.1.1.3 misho 1589: /* Init edns_pktsz for newly created server records. */
1590: if (serv->edns_pktsz == 0)
1591: serv->edns_pktsz = daemon->edns_pktsz;
1592:
1593: #ifdef HAVE_DNSSEC
1594: if (option_bool(OPT_DNSSEC_VALID))
1595: {
1.1.1.4 ! misho 1596: if (!(serv->flags & SERV_FOR_NODOTS))
! 1597: serv->flags |= SERV_DO_DNSSEC;
! 1598:
! 1599: /* Disable DNSSEC validation when using server=/domain/.... servers
! 1600: unless there's a configured trust anchor. */
1.1.1.3 misho 1601: if (serv->flags & SERV_HAS_DOMAIN)
1602: {
1603: struct ds_config *ds;
1604: char *domain = serv->domain;
1605:
1606: /* .example.com is valid */
1607: while (*domain == '.')
1608: domain++;
1609:
1610: for (ds = daemon->ds; ds; ds = ds->next)
1611: if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
1612: break;
1613:
1614: if (!ds)
1615: serv->flags &= ~SERV_DO_DNSSEC;
1616: }
1617: }
1618: #endif
1.1 misho 1619:
1.1.1.3 misho 1620: port = prettyprint_addr(&serv->addr, daemon->namebuff);
1621:
1.1 misho 1622: /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
1.1.1.2 misho 1623: if (serv->addr.sa.sa_family == AF_INET &&
1624: serv->addr.in.sin_addr.s_addr == 0)
1.1 misho 1625: {
1.1.1.2 misho 1626: serv->flags |= SERV_MARK;
1.1 misho 1627: continue;
1628: }
1629:
1630: for (iface = daemon->interfaces; iface; iface = iface->next)
1.1.1.2 misho 1631: if (sockaddr_isequal(&serv->addr, &iface->addr))
1.1 misho 1632: break;
1633: if (iface)
1634: {
1635: my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
1.1.1.2 misho 1636: serv->flags |= SERV_MARK;
1.1 misho 1637: continue;
1638: }
1639:
1640: /* Do we need a socket set? */
1.1.1.2 misho 1641: if (!serv->sfd &&
1642: !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
1.1 misho 1643: errno != 0)
1644: {
1645: my_syslog(LOG_WARNING,
1646: _("ignoring nameserver %s - cannot make/bind socket: %s"),
1647: daemon->namebuff, strerror(errno));
1.1.1.2 misho 1648: serv->flags |= SERV_MARK;
1.1 misho 1649: continue;
1650: }
1.1.1.4 ! misho 1651:
! 1652: if (serv->sfd)
! 1653: serv->sfd->used = 1;
1.1 misho 1654: }
1655:
1.1.1.3 misho 1656: if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
1.1 misho 1657: {
1.1.1.3 misho 1658: if (++count > SERVERS_LOGGED)
1659: continue;
1660:
1.1.1.2 misho 1661: if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
1.1 misho 1662: {
1.1.1.3 misho 1663: char *s1, *s2, *s3 = "";
1664: #ifdef HAVE_DNSSEC
1665: if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
1666: s3 = _("(no DNSSEC)");
1667: #endif
1.1.1.2 misho 1668: if (!(serv->flags & SERV_HAS_DOMAIN))
1.1 misho 1669: s1 = _("unqualified"), s2 = _("names");
1.1.1.2 misho 1670: else if (strlen(serv->domain) == 0)
1.1 misho 1671: s1 = _("default"), s2 = "";
1672: else
1.1.1.2 misho 1673: s1 = _("domain"), s2 = serv->domain;
1.1 misho 1674:
1.1.1.2 misho 1675: if (serv->flags & SERV_NO_ADDR)
1.1.1.4 ! misho 1676: {
! 1677: count--;
! 1678: if (++locals <= LOCALS_LOGGED)
! 1679: my_syslog(LOG_INFO, _("using only locally-known addresses for %s %s"), s1, s2);
! 1680: }
1.1.1.2 misho 1681: else if (serv->flags & SERV_USE_RESOLV)
1.1 misho 1682: my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
1.1.1.3 misho 1683: else
1684: my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
1.1 misho 1685: }
1.1.1.3 misho 1686: #ifdef HAVE_LOOP
1687: else if (serv->flags & SERV_LOOP)
1688: my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port);
1689: #endif
1.1.1.2 misho 1690: else if (serv->interface[0] != 0)
1691: my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface);
1.1 misho 1692: else
1693: my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
1694: }
1695: }
1.1.1.3 misho 1696:
1.1.1.4 ! misho 1697: if (locals > LOCALS_LOGGED)
! 1698: my_syslog(LOG_INFO, _("using %d more local addresses"), locals - LOCALS_LOGGED);
1.1.1.3 misho 1699: if (count - 1 > SERVERS_LOGGED)
1700: my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
1.1.1.2 misho 1701:
1.1.1.4 ! misho 1702: /* Remove unused sfds */
! 1703: for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
! 1704: {
! 1705: tmp = sfd->next;
! 1706: if (!sfd->used)
! 1707: {
! 1708: *up = sfd->next;
! 1709: close(sfd->fd);
! 1710: free(sfd);
! 1711: }
! 1712: else
! 1713: up = &sfd->next;
! 1714: }
! 1715:
1.1.1.2 misho 1716: cleanup_servers();
1.1 misho 1717: }
1718:
1719: /* Return zero if no servers found, in that case we keep polling.
1720: This is a protection against an update-time/write race on resolv.conf */
1721: int reload_servers(char *fname)
1722: {
1723: FILE *f;
1724: char *line;
1725: int gotone = 0;
1726:
1727: /* buff happens to be MAXDNAME long... */
1728: if (!(f = fopen(fname, "r")))
1729: {
1730: my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1731: return 0;
1732: }
1.1.1.2 misho 1733:
1734: mark_servers(SERV_FROM_RESOLV);
1735:
1.1 misho 1736: while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1737: {
1738: union mysockaddr addr, source_addr;
1739: char *token = strtok(line, " \t\n\r");
1740:
1741: if (!token)
1742: continue;
1743: if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
1744: continue;
1745: if (!(token = strtok(NULL, " \t\n\r")))
1746: continue;
1747:
1748: memset(&addr, 0, sizeof(addr));
1749: memset(&source_addr, 0, sizeof(source_addr));
1750:
1751: if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
1752: {
1753: #ifdef HAVE_SOCKADDR_SA_LEN
1754: source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1755: #endif
1756: source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1757: addr.in.sin_port = htons(NAMESERVER_PORT);
1758: source_addr.in.sin_addr.s_addr = INADDR_ANY;
1759: source_addr.in.sin_port = htons(daemon->query_port);
1760: }
1761: else
1762: {
1763: int scope_index = 0;
1764: char *scope_id = strchr(token, '%');
1765:
1766: if (scope_id)
1767: {
1768: *(scope_id++) = 0;
1769: scope_index = if_nametoindex(scope_id);
1770: }
1771:
1772: if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
1773: {
1774: #ifdef HAVE_SOCKADDR_SA_LEN
1775: source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1776: #endif
1777: source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1778: source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
1779: addr.in6.sin6_port = htons(NAMESERVER_PORT);
1780: addr.in6.sin6_scope_id = scope_index;
1781: source_addr.in6.sin6_addr = in6addr_any;
1782: source_addr.in6.sin6_port = htons(daemon->query_port);
1783: source_addr.in6.sin6_scope_id = 0;
1784: }
1785: else
1786: continue;
1787: }
1788:
1.1.1.2 misho 1789: add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
1.1 misho 1790: gotone = 1;
1791: }
1792:
1793: fclose(f);
1.1.1.2 misho 1794: cleanup_servers();
1.1 misho 1795:
1796: return gotone;
1797: }
1798:
1.1.1.2 misho 1799: /* Called when addresses are added or deleted from an interface */
1800: void newaddress(time_t now)
1801: {
1802: (void)now;
1803:
1804: if (option_bool(OPT_CLEVERBIND) || option_bool(OPT_LOCAL_SERVICE) ||
1805: daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
1806: enumerate_interfaces(0);
1.1 misho 1807:
1.1.1.2 misho 1808: if (option_bool(OPT_CLEVERBIND))
1809: create_bound_listeners(0);
1.1 misho 1810:
1.1.1.2 misho 1811: #ifdef HAVE_DHCP6
1812: if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
1813: join_multicast(0);
1.1 misho 1814:
1.1.1.2 misho 1815: if (daemon->doing_dhcp6 || daemon->doing_ra)
1816: dhcp_construct_contexts(now);
1.1 misho 1817:
1.1.1.2 misho 1818: if (daemon->doing_dhcp6)
1819: lease_find_interfaces(now);
1820: #endif
1.1 misho 1821: }
1822:
1.1.1.2 misho 1823:
1824:
1.1 misho 1825:
1826:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>