version 1.1.1.1, 2013/07/29 19:37:40
|
version 1.1.1.2, 2014/06/15 16:31:38
|
Line 1
|
Line 1
|
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley | /* dnsmasq is Copyright (c) 2000-2014 Simon Kelley |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
Line 50 int main (int argc, char **argv)
|
Line 50 int main (int argc, char **argv)
|
#if defined(HAVE_LINUX_NETWORK) |
#if defined(HAVE_LINUX_NETWORK) |
cap_user_header_t hdr = NULL; |
cap_user_header_t hdr = NULL; |
cap_user_data_t data = NULL; |
cap_user_data_t data = NULL; |
|
char *bound_device = NULL; |
|
int did_bind = 0; |
#endif |
#endif |
|
#if defined(HAVE_DHCP) || defined(HAVE_DHCP6) |
struct dhcp_context *context; |
struct dhcp_context *context; |
|
struct dhcp_relay *relay; |
|
#endif |
|
|
#ifdef LOCALEDIR |
#ifdef LOCALEDIR |
setlocale(LC_ALL, ""); |
setlocale(LC_ALL, ""); |
Line 76 int main (int argc, char **argv)
|
Line 81 int main (int argc, char **argv)
|
umask(022); /* known umask, create leases and pid files as 0644 */ |
umask(022); /* known umask, create leases and pid files as 0644 */ |
|
|
read_opts(argc, argv, compile_opts); |
read_opts(argc, argv, compile_opts); |
| |
if (daemon->edns_pktsz < PACKETSZ) |
if (daemon->edns_pktsz < PACKETSZ) |
daemon->edns_pktsz = PACKETSZ; |
daemon->edns_pktsz = PACKETSZ; |
|
#ifdef HAVE_DNSSEC |
|
/* Enforce min packet big enough for DNSSEC */ |
|
if (option_bool(OPT_DNSSEC_VALID) && daemon->edns_pktsz < EDNS_PKTSZ) |
|
daemon->edns_pktsz = EDNS_PKTSZ; |
|
#endif |
|
|
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? |
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? |
daemon->edns_pktsz : DNSMASQ_PACKETSZ; |
daemon->edns_pktsz : DNSMASQ_PACKETSZ; |
daemon->packet = safe_malloc(daemon->packet_buff_sz); |
daemon->packet = safe_malloc(daemon->packet_buff_sz); |
| |
daemon->addrbuff = safe_malloc(ADDRSTRLEN); |
daemon->addrbuff = safe_malloc(ADDRSTRLEN); |
|
|
|
#ifdef HAVE_DNSSEC |
|
if (option_bool(OPT_DNSSEC_VALID)) |
|
{ |
|
daemon->keyname = safe_malloc(MAXDNAME); |
|
daemon->workspacename = safe_malloc(MAXDNAME); |
|
} |
|
#endif |
|
|
|
|
#ifdef HAVE_DHCP |
#ifdef HAVE_DHCP |
if (!daemon->lease_file) |
if (!daemon->lease_file) |
{ |
{ |
Line 126 int main (int argc, char **argv)
|
Line 144 int main (int argc, char **argv)
|
} |
} |
#endif |
#endif |
|
|
|
if (option_bool(OPT_DNSSEC_VALID)) |
|
{ |
|
#ifdef HAVE_DNSSEC |
|
if (!daemon->ds) |
|
die(_("No trust anchors provided for DNSSEC"), NULL, EC_BADCONF); |
|
|
|
if (daemon->cachesize < CACHESIZ) |
|
die(_("Cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF); |
|
#else |
|
die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF); |
|
#endif |
|
} |
|
|
#ifndef HAVE_TFTP |
#ifndef HAVE_TFTP |
if (option_bool(OPT_TFTP)) |
if (option_bool(OPT_TFTP)) |
die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF); |
die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF); |
Line 166 int main (int argc, char **argv)
|
Line 197 int main (int argc, char **argv)
|
daemon->soa_sn = now; |
daemon->soa_sn = now; |
#endif |
#endif |
|
|
#ifdef HAVE_DHCP | #ifdef HAVE_DHCP6 |
if (daemon->dhcp || daemon->dhcp6) | if (daemon->dhcp6) |
{ | { |
| daemon->doing_ra = option_bool(OPT_RA); |
|
|
# ifdef HAVE_DHCP6 | for (context = daemon->dhcp6; context; context = context->next) |
if (daemon->dhcp6) | |
{ |
{ |
daemon->doing_ra = option_bool(OPT_RA); | if (context->flags & CONTEXT_DHCP) |
| daemon->doing_dhcp6 = 1; |
for (context = daemon->dhcp6; context; context = context->next) | if (context->flags & CONTEXT_RA) |
{ | daemon->doing_ra = 1; |
if (context->flags & CONTEXT_DHCP) | #if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK) |
daemon->doing_dhcp6 = 1; | if (context->flags & CONTEXT_TEMPLATE) |
if (context->flags & CONTEXT_RA) | die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF); |
daemon->doing_ra = 1; | |
#ifndef HAVE_LINUX_NETWORK | |
if (context->flags & CONTEXT_TEMPLATE) | |
die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF); | |
#endif |
#endif |
} |
|
} |
} |
# endif | } |
| #endif |
/* Note that order matters here, we must call lease_init before | |
creating any file descriptors which shouldn't be leaked | #ifdef HAVE_DHCP |
to the lease-script init process. We need to call common_init | /* Note that order matters here, we must call lease_init before |
before lease_init to allocate buffers it uses.*/ | creating any file descriptors which shouldn't be leaked |
| to the lease-script init process. We need to call common_init |
| before lease_init to allocate buffers it uses.*/ |
| if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || daemon->relay6) |
| { |
| dhcp_common_init(); |
if (daemon->dhcp || daemon->doing_dhcp6) |
if (daemon->dhcp || daemon->doing_dhcp6) |
{ | lease_init(now); |
dhcp_common_init(); | } |
lease_init(now); | |
} | if (daemon->dhcp || daemon->relay4) |
| dhcp_init(); |
if (daemon->dhcp) | |
dhcp_init(); | |
| |
# ifdef HAVE_DHCP6 |
# ifdef HAVE_DHCP6 |
if (daemon->doing_ra) | if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6) |
ra_init(now); | ra_init(now); |
| |
if (daemon->doing_dhcp6) | if (daemon->doing_dhcp6 || daemon->relay6) |
dhcp6_init(); | dhcp6_init(); |
# endif |
# endif |
} |
|
|
|
#endif |
#endif |
|
|
Line 218 int main (int argc, char **argv)
|
Line 246 int main (int argc, char **argv)
|
ipset_init(); |
ipset_init(); |
#endif |
#endif |
|
|
#ifdef HAVE_LINUX_NETWORK | #if defined(HAVE_LINUX_NETWORK) |
netlink_init(); |
netlink_init(); |
| #elif defined(HAVE_BSD_NETWORK) |
if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND)) | route_init(); |
die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF); | |
#endif |
#endif |
|
|
if (!enumerate_interfaces()) | if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND)) |
| die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF); |
| |
| if (!enumerate_interfaces(1) || !enumerate_interfaces(0)) |
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC); |
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC); |
|
|
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) |
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) |
Line 239 int main (int argc, char **argv)
|
Line 269 int main (int argc, char **argv)
|
|
|
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP) |
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP) |
/* after enumerate_interfaces() */ |
/* after enumerate_interfaces() */ |
|
bound_device = whichdevice(); |
|
|
if (daemon->dhcp) |
if (daemon->dhcp) |
{ |
{ |
bindtodevice(daemon->dhcpfd); | if (!daemon->relay4 && bound_device) |
if (daemon->enable_pxe) | { |
bindtodevice(daemon->pxefd); | bindtodevice(bound_device, daemon->dhcpfd); |
| did_bind = 1; |
| } |
| if (daemon->enable_pxe && bound_device) |
| { |
| bindtodevice(bound_device, daemon->pxefd); |
| did_bind = 1; |
| } |
} |
} |
#endif |
#endif |
|
|
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6) |
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6) |
if (daemon->dhcp6) | if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device) |
bindtodevice(daemon->dhcp6fd); | { |
| bindtodevice(bound_device, daemon->dhcp6fd); |
| did_bind = 1; |
| } |
#endif |
#endif |
} |
} |
else |
else |
Line 257 int main (int argc, char **argv)
|
Line 299 int main (int argc, char **argv)
|
|
|
#ifdef HAVE_DHCP6 |
#ifdef HAVE_DHCP6 |
/* after enumerate_interfaces() */ |
/* after enumerate_interfaces() */ |
if (daemon->doing_dhcp6 || daemon->doing_ra) | if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra) |
join_multicast(1); |
join_multicast(1); |
|
|
|
/* After netlink_init() and before create_helper() */ |
|
lease_make_duid(now); |
#endif |
#endif |
|
|
if (daemon->port != 0) |
if (daemon->port != 0) |
cache_init(); | { |
| cache_init(); |
| #ifdef HAVE_DNSSEC |
| blockdata_init(); |
| #endif |
| } |
|
|
if (option_bool(OPT_DBUS)) |
if (option_bool(OPT_DBUS)) |
#ifdef HAVE_DBUS |
#ifdef HAVE_DBUS |
Line 347 int main (int argc, char **argv)
|
Line 397 int main (int argc, char **argv)
|
piperead = pipefd[0]; |
piperead = pipefd[0]; |
pipewrite = pipefd[1]; |
pipewrite = pipefd[1]; |
/* prime the pipe to load stuff first time. */ |
/* prime the pipe to load stuff first time. */ |
send_event(pipewrite, EVENT_RELOAD, 0, NULL); | send_event(pipewrite, EVENT_INIT, 0, NULL); |
|
|
err_pipe[1] = -1; |
err_pipe[1] = -1; |
|
|
Line 612 int main (int argc, char **argv)
|
Line 662 int main (int argc, char **argv)
|
} |
} |
#endif |
#endif |
|
|
|
if (option_bool(OPT_LOCAL_SERVICE)) |
|
my_syslog(LOG_INFO, _("DNS service limited to local subnets")); |
|
|
|
#ifdef HAVE_DNSSEC |
|
if (option_bool(OPT_DNSSEC_VALID)) |
|
{ |
|
my_syslog(LOG_INFO, _("DNSSEC validation enabled")); |
|
if (option_bool(OPT_DNSSEC_TIME)) |
|
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload")); |
|
} |
|
#endif |
|
|
if (log_err != 0) |
if (log_err != 0) |
my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), |
my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), |
daemon->log_file, strerror(log_err)); |
daemon->log_file, strerror(log_err)); |
| |
if (bind_fallback) |
if (bind_fallback) |
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations")); |
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations")); |
|
|
|
if (option_bool(OPT_NOWILD)) |
|
warn_bound_listeners(); |
|
|
|
warn_int_names(); |
|
|
if (!option_bool(OPT_NOWILD)) |
if (!option_bool(OPT_NOWILD)) |
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) |
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) |
Line 641 int main (int argc, char **argv)
|
Line 708 int main (int argc, char **argv)
|
for (context = daemon->dhcp; context; context = context->next) |
for (context = daemon->dhcp; context; context = context->next) |
log_context(AF_INET, context); |
log_context(AF_INET, context); |
|
|
|
for (relay = daemon->relay4; relay; relay = relay->next) |
|
log_relay(AF_INET, relay); |
|
|
# ifdef HAVE_DHCP6 |
# ifdef HAVE_DHCP6 |
for (context = daemon->dhcp6; context; context = context->next) |
for (context = daemon->dhcp6; context; context = context->next) |
log_context(AF_INET6, context); |
log_context(AF_INET6, context); |
|
|
|
for (relay = daemon->relay6; relay; relay = relay->next) |
|
log_relay(AF_INET6, relay); |
|
|
if (daemon->doing_dhcp6 || daemon->doing_ra) |
if (daemon->doing_dhcp6 || daemon->doing_ra) |
dhcp_construct_contexts(now); |
dhcp_construct_contexts(now); |
|
|
Line 652 int main (int argc, char **argv)
|
Line 725 int main (int argc, char **argv)
|
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled")); |
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled")); |
# endif |
# endif |
|
|
|
# ifdef HAVE_LINUX_NETWORK |
|
if (did_bind) |
|
my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device); |
|
# endif |
|
|
/* after dhcp_contruct_contexts */ |
/* after dhcp_contruct_contexts */ |
if (daemon->dhcp || daemon->doing_dhcp6) |
if (daemon->dhcp || daemon->doing_dhcp6) |
lease_find_interfaces(now); |
lease_find_interfaces(now); |
Line 749 int main (int argc, char **argv)
|
Line 827 int main (int argc, char **argv)
|
#endif |
#endif |
|
|
#ifdef HAVE_DHCP |
#ifdef HAVE_DHCP |
if (daemon->dhcp) | if (daemon->dhcp || daemon->relay4) |
{ |
{ |
FD_SET(daemon->dhcpfd, &rset); |
FD_SET(daemon->dhcpfd, &rset); |
bump_maxfd(daemon->dhcpfd, &maxfd); |
bump_maxfd(daemon->dhcpfd, &maxfd); |
Line 762 int main (int argc, char **argv)
|
Line 840 int main (int argc, char **argv)
|
#endif |
#endif |
|
|
#ifdef HAVE_DHCP6 |
#ifdef HAVE_DHCP6 |
if (daemon->doing_dhcp6) | if (daemon->doing_dhcp6 || daemon->relay6) |
{ |
{ |
FD_SET(daemon->dhcp6fd, &rset); |
FD_SET(daemon->dhcp6fd, &rset); |
bump_maxfd(daemon->dhcp6fd, &maxfd); |
bump_maxfd(daemon->dhcp6fd, &maxfd); |
Line 775 int main (int argc, char **argv)
|
Line 853 int main (int argc, char **argv)
|
} |
} |
#endif |
#endif |
|
|
#ifdef HAVE_LINUX_NETWORK | #if defined(HAVE_LINUX_NETWORK) |
FD_SET(daemon->netlinkfd, &rset); |
FD_SET(daemon->netlinkfd, &rset); |
bump_maxfd(daemon->netlinkfd, &maxfd); |
bump_maxfd(daemon->netlinkfd, &maxfd); |
|
#elif defined(HAVE_BSD_NETWORK) |
|
FD_SET(daemon->routefd, &rset); |
|
bump_maxfd(daemon->routefd, &maxfd); |
#endif |
#endif |
| |
FD_SET(piperead, &rset); |
FD_SET(piperead, &rset); |
bump_maxfd(piperead, &maxfd); |
bump_maxfd(piperead, &maxfd); |
|
|
Line 820 int main (int argc, char **argv)
|
Line 901 int main (int argc, char **argv)
|
now = dnsmasq_time(); |
now = dnsmasq_time(); |
|
|
check_log_writer(&wset); |
check_log_writer(&wset); |
| |
| /* prime. */ |
| enumerate_interfaces(1); |
| |
/* Check the interfaces to see if any have exited DAD state |
/* Check the interfaces to see if any have exited DAD state |
and if so, bind the address. */ |
and if so, bind the address. */ |
if (is_dad_listeners()) |
if (is_dad_listeners()) |
{ |
{ |
enumerate_interfaces(); | enumerate_interfaces(0); |
/* NB, is_dad_listeners() == 1 --> we're binding interfaces */ |
/* NB, is_dad_listeners() == 1 --> we're binding interfaces */ |
create_bound_listeners(0); |
create_bound_listeners(0); |
|
warn_bound_listeners(); |
} |
} |
|
|
#ifdef HAVE_LINUX_NETWORK | #if defined(HAVE_LINUX_NETWORK) |
if (FD_ISSET(daemon->netlinkfd, &rset)) |
if (FD_ISSET(daemon->netlinkfd, &rset)) |
netlink_multicast(now); |
netlink_multicast(now); |
|
#elif defined(HAVE_BSD_NETWORK) |
|
if (FD_ISSET(daemon->routefd, &rset)) |
|
route_sock(now); |
#endif |
#endif |
|
|
/* Check for changes to resolv files once per second max. */ |
/* Check for changes to resolv files once per second max. */ |
Line 871 int main (int argc, char **argv)
|
Line 959 int main (int argc, char **argv)
|
#endif |
#endif |
|
|
#ifdef HAVE_DHCP |
#ifdef HAVE_DHCP |
if (daemon->dhcp) | if (daemon->dhcp || daemon->relay4) |
{ |
{ |
if (FD_ISSET(daemon->dhcpfd, &rset)) |
if (FD_ISSET(daemon->dhcpfd, &rset)) |
dhcp_packet(now, 0); |
dhcp_packet(now, 0); |
Line 880 int main (int argc, char **argv)
|
Line 968 int main (int argc, char **argv)
|
} |
} |
|
|
#ifdef HAVE_DHCP6 |
#ifdef HAVE_DHCP6 |
if (daemon->doing_dhcp6 && FD_ISSET(daemon->dhcp6fd, &rset)) | if ((daemon->doing_dhcp6 || daemon->relay6) && FD_ISSET(daemon->dhcp6fd, &rset)) |
dhcp6_packet(now); |
dhcp6_packet(now); |
|
|
if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset)) |
if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset)) |
Line 1036 static void async_event(int pipe, time_t now)
|
Line 1124 static void async_event(int pipe, time_t now)
|
{ |
{ |
pid_t p; |
pid_t p; |
struct event_desc ev; |
struct event_desc ev; |
int i; | int i, check = 0; |
char *msg; |
char *msg; |
|
|
/* NOTE: the memory used to return msg is leaked: use msgs in events only |
/* NOTE: the memory used to return msg is leaked: use msgs in events only |
Line 1046 static void async_event(int pipe, time_t now)
|
Line 1134 static void async_event(int pipe, time_t now)
|
switch (ev.event) |
switch (ev.event) |
{ |
{ |
case EVENT_RELOAD: |
case EVENT_RELOAD: |
|
#ifdef HAVE_DNSSEC |
|
if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME)) |
|
{ |
|
my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps")); |
|
reset_option_bool(OPT_DNSSEC_TIME); |
|
} |
|
#endif |
|
/* fall through */ |
|
|
|
case EVENT_INIT: |
clear_cache_and_reload(now); |
clear_cache_and_reload(now); |
if (daemon->port != 0 && daemon->resolv_files && option_bool(OPT_NO_POLL)) | |
| if (daemon->port != 0) |
{ |
{ |
reload_servers(daemon->resolv_files->name); | if (daemon->resolv_files && option_bool(OPT_NO_POLL)) |
check_servers(); | { |
| reload_servers(daemon->resolv_files->name); |
| check = 1; |
| } |
| |
| if (daemon->servers_file) |
| { |
| read_servers_file(); |
| check = 1; |
| } |
| |
| if (check) |
| check_servers(); |
} |
} |
|
|
#ifdef HAVE_DHCP |
#ifdef HAVE_DHCP |
rerun_scripts(); |
rerun_scripts(); |
#endif |
#endif |
Line 1223 void poll_resolv(int force, int do_reload, time_t now)
|
Line 1335 void poll_resolv(int force, int do_reload, time_t now)
|
|
|
void clear_cache_and_reload(time_t now) |
void clear_cache_and_reload(time_t now) |
{ |
{ |
|
(void)now; |
|
|
if (daemon->port != 0) |
if (daemon->port != 0) |
cache_reload(); |
cache_reload(); |
|
|
Line 1265 static int set_dns_listeners(time_t now, fd_set *set,
|
Line 1379 static int set_dns_listeners(time_t now, fd_set *set,
|
|
|
/* will we be able to get memory? */ |
/* will we be able to get memory? */ |
if (daemon->port != 0) |
if (daemon->port != 0) |
get_new_frec(now, &wait); | get_new_frec(now, &wait, 0); |
|
|
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next) |
for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next) |
{ |
{ |
Line 1352 static void check_dns_listeners(fd_set *set, time_t no
|
Line 1466 static void check_dns_listeners(fd_set *set, time_t no
|
|
|
if (confd == -1) |
if (confd == -1) |
continue; |
continue; |
| |
if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1) |
if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1) |
{ |
{ |
close(confd); |
close(confd); |
continue; |
continue; |
} |
} |
|
|
|
/* Make sure that the interface list is up-to-date. |
|
|
|
We do this here as we may need the results below, and |
|
the DNS code needs them for --interface-name stuff. |
|
|
if (option_bool(OPT_NOWILD)) | Multiple calls to enumerate_interfaces() per select loop are |
iface = listener->iface; /* May be NULL */ | inhibited, so calls to it in the child process (which doesn't select()) |
else | have no effect. This avoids two processes reading from the same |
{ | netlink fd and screwing the pooch entirely. |
int if_index; | */ |
char intr_name[IF_NAMESIZE]; | |
|
|
/* In full wildcard mode, need to refresh interface list. | enumerate_interfaces(0); |
This happens automagically in CLEVERBIND */ | |
if (!option_bool(OPT_CLEVERBIND)) | if (option_bool(OPT_NOWILD)) |
enumerate_interfaces(); | iface = listener->iface; /* May be NULL */ |
| else |
/* if we can find the arrival interface, check it's one that's allowed */ | { |
if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 && | int if_index; |
indextoname(listener->tcpfd, if_index, intr_name)) | char intr_name[IF_NAMESIZE]; |
{ | |
struct all_addr addr; | /* if we can find the arrival interface, check it's one that's allowed */ |
addr.addr.addr4 = tcp_addr.in.sin_addr; | if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 && |
| indextoname(listener->tcpfd, if_index, intr_name)) |
| { |
| struct all_addr addr; |
| addr.addr.addr4 = tcp_addr.in.sin_addr; |
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
if (tcp_addr.sa.sa_family == AF_INET6) | if (tcp_addr.sa.sa_family == AF_INET6) |
addr.addr.addr6 = tcp_addr.in6.sin6_addr; | addr.addr.addr6 = tcp_addr.in6.sin6_addr; |
#endif |
#endif |
| |
for (iface = daemon->interfaces; iface; iface = iface->next) | for (iface = daemon->interfaces; iface; iface = iface->next) |
if (iface->index == if_index) | if (iface->index == if_index) |
break; | break; |
| |
if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name)) | if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name)) |
client_ok = 0; | client_ok = 0; |
} | } |
| |
if (option_bool(OPT_CLEVERBIND)) | if (option_bool(OPT_CLEVERBIND)) |
iface = listener->iface; /* May be NULL */ | iface = listener->iface; /* May be NULL */ |
else | else |
{ | { |
/* Check for allowed interfaces when binding the wildcard address: | /* Check for allowed interfaces when binding the wildcard address: |
we do this by looking for an interface with the same address as | we do this by looking for an interface with the same address as |
the local address of the TCP connection, then looking to see if that's | the local address of the TCP connection, then looking to see if that's |
an allowed interface. As a side effect, we get the netmask of the | an allowed interface. As a side effect, we get the netmask of the |
interface too, for localisation. */ | interface too, for localisation. */ |
| |
for (iface = daemon->interfaces; iface; iface = iface->next) | for (iface = daemon->interfaces; iface; iface = iface->next) |
if (sockaddr_isequal(&iface->addr, &tcp_addr)) | if (sockaddr_isequal(&iface->addr, &tcp_addr)) |
break; | break; |
| |
if (!iface) | if (!iface) |
client_ok = 0; | client_ok = 0; |
} | } |
} | } |
| |
if (!client_ok) |
if (!client_ok) |
{ |
{ |
shutdown(confd, SHUT_RDWR); |
shutdown(confd, SHUT_RDWR); |