Commit 76dd75de authored by Simon Kelley's avatar Simon Kelley

Fix hang from new interface-name code, when using TCP.

parent 63fd27e3
...@@ -1355,63 +1355,71 @@ static void check_dns_listeners(fd_set *set, time_t now) ...@@ -1355,63 +1355,71 @@ static void check_dns_listeners(fd_set *set, time_t now)
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;
} }
if (option_bool(OPT_NOWILD)) /* Make sure that the interface list is up-to-date.
iface = listener->iface; /* May be NULL */
else We do this here as we may need the results below, and
{ the DNS code needs them for --interface-name stuff.
int if_index;
char intr_name[IF_NAMESIZE]; Multiple calls to enumerate_interfaces() per select loop are
inhibited, so calls to it in the child process (which doesn't select())
have no effect. This avoids two processes reading from the same
netlink fd and screwing the pooch entirely.
*/
/* 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(0); 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);
......
...@@ -438,7 +438,9 @@ int enumerate_interfaces(int reset) ...@@ -438,7 +438,9 @@ int enumerate_interfaces(int reset)
struct addrlist *addr, *tmp; struct addrlist *addr, *tmp;
struct interface_name *intname; struct interface_name *intname;
/* DO this max once per select cycle */ /* Do this max once per select cycle - also inhibits netlink socket use
in TCP child processes. */
if (reset) if (reset)
{ {
done = 0; done = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment