/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley

   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
   the Free Software Foundation; version 2 dated June, 1991, or
   (at your option) version 3 dated 29 June, 2007.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "dnsmasq.h"

static const char SEPARATOR[] = "|";

#ifdef HAVE_LINUX_NETWORK

int indextoname(int fd, int index, char* name) {
    struct ifreq ifr;

    if (index == 0) return 0;

    ifr.ifr_ifindex = index;
    if (ioctl(fd, SIOCGIFNAME, &ifr) == -1) return 0;

    strncpy(name, ifr.ifr_name, IF_NAMESIZE);

    return 1;
}

#else

int indextoname(int fd, int index, char* name) {
    if (index == 0 || !if_indextoname(index, name)) return 0;

    return 1;
}

#endif

int iface_check(int family, struct all_addr* addr, char* name, int* indexp) {
    struct iname* tmp;
    int ret = 1;

    /* Note: have to check all and not bail out early, so that we set the
       "used" flags. */

    if (indexp) {
        /* One form of bridging on BSD has the property that packets
       can be recieved on bridge interfaces which do not have an IP address.
       We allow these to be treated as aliases of another interface which does have
       an IP address with --dhcp-bridge=interface,alias,alias */
        struct dhcp_bridge *bridge, *alias;
        for (bridge = daemon->bridges; bridge; bridge = bridge->next) {
            for (alias = bridge->alias; alias; alias = alias->next)
                if (strncmp(name, alias->iface, IF_NAMESIZE) == 0) {
                    int newindex;

                    if (!(newindex = if_nametoindex(bridge->iface))) {
                        my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), name);
                        return 0;
                    } else {
                        *indexp = newindex;
                        strncpy(name, bridge->iface, IF_NAMESIZE);
                        break;
                    }
                }
            if (alias) break;
        }
    }

    if (daemon->if_names || (addr && daemon->if_addrs)) {
        ret = 0;

        for (tmp = daemon->if_names; tmp; tmp = tmp->next)
            if (tmp->name && (strcmp(tmp->name, name) == 0)) ret = tmp->used = 1;

        for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
            if (addr && tmp->addr.sa.sa_family == family) {
                if (family == AF_INET && tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
                    ret = tmp->used = 1;
#ifdef HAVE_IPV6
                else if (family == AF_INET6 &&
                         IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6) &&
                         (!IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6) ||
                          (tmp->addr.in6.sin6_scope_id == (uint32_t) *indexp)))
                    ret = tmp->used = 1;
#endif
            }
    }

    for (tmp = daemon->if_except; tmp; tmp = tmp->next)
        if (tmp->name && (strcmp(tmp->name, name) == 0)) ret = 0;

    return ret;
}

static int iface_allowed(struct irec** irecp, int if_index, union mysockaddr* addr,
                         struct in_addr netmask) {
    struct irec* iface;
    int fd, mtu = 0, loopback;
    struct ifreq ifr;
    int dhcp_ok = 1;
    struct iname* tmp;

    /* check whether the interface IP has been added already
       we call this routine multiple times. */
    for (iface = *irecp; iface; iface = iface->next)
        if (sockaddr_isequal(&iface->addr, addr)) return 1;

    if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1 || !indextoname(fd, if_index, ifr.ifr_name) ||
        ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
        if (fd != -1) {
            int errsave = errno;
            close(fd);
            errno = errsave;
        }
        return 0;
    }

    loopback = ifr.ifr_flags & IFF_LOOPBACK;

    if (ioctl(fd, SIOCGIFMTU, &ifr) != -1) mtu = ifr.ifr_mtu;

    close(fd);

    /* If we are restricting the set of interfaces to use, make
       sure that loopback interfaces are in that set. */
    if (daemon->if_names && loopback) {
        struct iname* lo;
        for (lo = daemon->if_names; lo; lo = lo->next)
            if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0) {
                lo->isloop = 1;
                break;
            }

        if (!lo && (lo = whine_malloc(sizeof(struct iname))) &&
            (lo->name = whine_malloc(strlen(ifr.ifr_name) + 1))) {
            strcpy(lo->name, ifr.ifr_name);
            lo->isloop = lo->used = 1;
            lo->next = daemon->if_names;
            daemon->if_names = lo;
        }
    }

    if (addr->sa.sa_family == AF_INET &&
        !iface_check(AF_INET, (struct all_addr*) &addr->in.sin_addr, ifr.ifr_name, NULL))
        return 1;

    for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
        if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) dhcp_ok = 0;

#ifdef HAVE_IPV6
    int ifindex = (int) addr->in6.sin6_scope_id;
    if (addr->sa.sa_family == AF_INET6 &&
        !iface_check(AF_INET6, (struct all_addr*) &addr->in6.sin6_addr, ifr.ifr_name, &ifindex))
        return 1;
#endif

    /* add to list */
    if ((iface = whine_malloc(sizeof(struct irec)))) {
        iface->addr = *addr;
        iface->netmask = netmask;
        iface->dhcp_ok = dhcp_ok;
        iface->mtu = mtu;
        iface->next = *irecp;
        *irecp = iface;
        return 1;
    }

    errno = ENOMEM;
    return 0;
}

#ifdef HAVE_IPV6
static int iface_allowed_v6(struct in6_addr* local, int scope, int if_index, void* vparam) {
    union mysockaddr addr;
    struct in_addr netmask; /* dummy */

    netmask.s_addr = 0;

    memset(&addr, 0, sizeof(addr));
    addr.in6.sin6_family = AF_INET6;
    addr.in6.sin6_addr = *local;
    addr.in6.sin6_port = htons(daemon->port);
    /**
     * Only populate the scope ID if the address is link-local.
     * Scope IDs are not meaningful for global addresses. Also, we do not want to
     * think that two addresses are different if they differ only in scope ID,
     * because the kernel will treat them as if they are the same.
     */
    if (IN6_IS_ADDR_LINKLOCAL(local)) {
        addr.in6.sin6_scope_id = scope;
    }

    return iface_allowed((struct irec**) vparam, if_index, &addr, netmask);
}
#endif

static int iface_allowed_v4(struct in_addr local, int if_index, struct in_addr netmask,
                            struct in_addr broadcast, void* vparam) {
    union mysockaddr addr;

    memset(&addr, 0, sizeof(addr));
    addr.in.sin_family = AF_INET;
    addr.in.sin_addr = broadcast; /* warning */
    addr.in.sin_addr = local;
    addr.in.sin_port = htons(daemon->port);

    return iface_allowed((struct irec**) vparam, if_index, &addr, netmask);
}

int enumerate_interfaces(void) {
#ifdef HAVE_IPV6
    return iface_enumerate(&daemon->interfaces, iface_allowed_v4, iface_allowed_v6);
#else
    return iface_enumerate(&daemon->interfaces, iface_allowed_v4, NULL);
#endif
}

/* set NONBLOCK bit on fd: See Stevens 16.6 */
int fix_fd(int fd) {
    int flags;

    if ((flags = fcntl(fd, F_GETFL)) == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
        return 0;

    return 1;
}

#if defined(HAVE_IPV6)
static int create_ipv6_listener(struct listener** link, int port) {
    union mysockaddr addr;
    int tcpfd, fd;
    struct listener* l;
    int opt = 1;

    memset(&addr, 0, sizeof(addr));
    addr.in6.sin6_family = AF_INET6;
    addr.in6.sin6_addr = in6addr_any;
    addr.in6.sin6_port = htons(port);

    /* No error of the kernel doesn't support IPv6 */
    if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
        return (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT || errno == EINVAL);

    if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) return 0;

    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
        setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
        setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
        setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 || !fix_fd(fd) ||
        !fix_fd(tcpfd) ||
#ifdef IPV6_RECVPKTINFO
        setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
#else
        setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
#endif
        bind(tcpfd, (struct sockaddr*) &addr, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 ||
        bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == -1)
        return 0;

    l = safe_malloc(sizeof(struct listener));
    l->fd = fd;
    l->tcpfd = tcpfd;
    l->family = AF_INET6;
    l->iface = NULL;
    l->next = NULL;
    *link = l;

    return 1;
}
#endif

struct listener* create_wildcard_listeners(void) {
    union mysockaddr addr;
    int opt = 1;
    struct listener *l, *l6 = NULL;
    int tcpfd = -1, fd = -1;

    memset(&addr, 0, sizeof(addr));
    addr.in.sin_family = AF_INET;
    addr.in.sin_addr.s_addr = INADDR_ANY;
    addr.in.sin_port = htons(daemon->port);

    if (daemon->port != 0) {
        if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
            (tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
            return NULL;

        if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
            bind(tcpfd, (struct sockaddr*) &addr, sa_len(&addr)) == -1 || listen(tcpfd, 5) == -1 ||
            !fix_fd(tcpfd) ||
#ifdef HAVE_IPV6
            !create_ipv6_listener(&l6, daemon->port) ||
#endif
            setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd) ||
#if defined(HAVE_LINUX_NETWORK)
            setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 ||
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
            setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
            setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 ||
#endif
            bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == -1)
            return NULL;

#ifdef __ANDROID__
        uint32_t mark = daemon->listen_mark;
        if (mark != 0 && (setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
                          setsockopt(tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
                          setsockopt(l6->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
                          setsockopt(l6->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1)) {
            my_syslog(LOG_WARNING, _("setsockopt(SO_MARK, 0x%x: %s"), mark, strerror(errno));
            close(fd);
            close(tcpfd);
            close(l6->fd);
            close(l6->tcpfd);
            return NULL;
        }
    }
#endif /* __ANDROID__ */

    l = safe_malloc(sizeof(struct listener));
    l->family = AF_INET;
    l->fd = fd;
    l->tcpfd = tcpfd;
    l->iface = NULL;
    l->next = l6;

    return l;
}

#ifdef __ANDROID__
/**
 * for a single given irec (interface name and address) create
 * a set of sockets listening.  This is a copy of the code inside the loop
 * of create_bound_listeners below and is added here to allow us
 * to create just a single new listener dynamically when our interface
 * list is changed.
 *
 * iface - input of the new interface details to listen on
 * listeners - output.  Creates a new struct listener and inserts at head of the list
 *
 * die's on errors, so don't pass bad data.
 */
void create_bound_listener(struct listener** listeners, struct irec* iface) {
    int rc, opt = 1;
#ifdef HAVE_IPV6
    static int dad_count = 0;
#endif

    struct listener* new = safe_malloc(sizeof(struct listener));
    new->family = iface->addr.sa.sa_family;
    new->iface = iface;
    new->next = *listeners;
    new->tcpfd = -1;
    new->fd = -1;
    *listeners = new;

    if (daemon->port != 0) {
        if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
            (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
            setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
            setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
            !fix_fd(new->tcpfd) || !fix_fd(new->fd))
            die(_("failed to create listening socket: %s"), NULL, EC_BADNET);

#ifdef HAVE_IPV6
        if (iface->addr.sa.sa_family == AF_INET6) {
            if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
                setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
                die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
        }
#endif

        while (1) {
            if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break;

#ifdef HAVE_IPV6
            /* An interface may have an IPv6 address which is still undergoing DAD.
               If so, the bind will fail until the DAD completes, so we try over 20 seconds
               before failing. */
            /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so
               bind() will only fail if the address has already failed DAD, in which case retrying
               won't help. */
            if (iface->addr.sa.sa_family == AF_INET6 &&
                (errno == ENODEV || errno == EADDRNOTAVAIL) && dad_count++ < DAD_WAIT) {
                sleep(1);
                continue;
            }
#endif
            break;
        }

        if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) {
            prettyprint_addr(&iface->addr, daemon->namebuff);
            die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET);
        }

        uint32_t mark = daemon->listen_mark;
        if (mark != 0 && (setsockopt(new->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1 ||
                          setsockopt(new->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1))
            die(_("failed to set SO_MARK on listen socket: %s"), NULL, EC_BADNET);

        if (listen(new->tcpfd, 5) == -1) die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
    }
}

/**
 * If a listener has a struct irec pointer whose address matches the newly
 * malloc()d struct irec's address, update its pointer to refer to this new
 * struct irec instance.
 *
 * Otherwise, any listeners that are preserved across interface list changes
 * will point at interface structures that are free()d at the end of
 * set_interfaces(), and can get overwritten by subsequent memory allocations.
 *
 * See b/17475756 for further discussion.
 */
void fixup_possible_existing_listener(struct irec* new_iface) {
    /* find the listener, if present */
    struct listener* l;
    for (l = daemon->listeners; l; l = l->next) {
        struct irec* listener_iface = l->iface;
        if (listener_iface) {
            if (sockaddr_isequal(&listener_iface->addr, &new_iface->addr)) {
                l->iface = new_iface;
                return;
            }
        }
    }
}

/**
 * Closes the sockets of the specified listener, deletes it from the list, and frees it.
 *
 */
int delete_listener(struct listener** l) {
    struct listener* listener = *l;
    if (listener == NULL) return 0;

    if (listener->iface) {
        int port = prettyprint_addr(&listener->iface->addr, daemon->namebuff);
        my_syslog(LOG_INFO, _("Closing listener [%s]:%d"), daemon->namebuff, port);
    } else {
        my_syslog(LOG_INFO, _("Closing wildcard listener family=%d"), listener->family);
    }

    if (listener->tcpfd != -1) {
        close(listener->tcpfd);
        listener->tcpfd = -1;
    }
    if (listener->fd != -1) {
        close(listener->fd);
        listener->fd = -1;
    }
    *l = listener->next;
    free(listener);
    return -1;
}

/**
 * Close the sockets listening on the given interface
 *
 * This new function is needed as we're dynamically changing the interfaces
 * we listen on.  Before they'd be opened once in create_bound_listeners and stay
 * until we exited.  Now, if an interface moves off the to-listen list we need to
 * close out the listeners and keep trucking.
 *
 * interface - input of the interface details to listen on
 */
int close_bound_listener(struct irec* iface) {
    /* find the listener */
    int ret = 0;
    struct listener** l = &daemon->listeners;
    while (*l) {
        struct irec* listener_iface = (*l)->iface;
        struct listener** next = &((*l)->next);
        if (iface && listener_iface && sockaddr_isequal(&listener_iface->addr, &iface->addr)) {
            // Listener bound to an IP address. There can be only one of these.
            ret = delete_listener(l);
            break;
        }
        if (iface == NULL && listener_iface == NULL) {
            // Wildcard listener. There is one of these per address family.
            ret = delete_listener(l);
            continue;
        }
        l = next;
    }
    return ret;
}
#endif /* __ANDROID__ */

struct listener* create_bound_listeners(void) {
    struct listener* listeners = NULL;
    struct irec* iface;
#ifndef __ANDROID__
    int rc, opt = 1;
#ifdef HAVE_IPV6
    static int dad_count = 0;
#endif
#endif

    for (iface = daemon->interfaces; iface; iface = iface->next) {
#ifdef __ANDROID__
        create_bound_listener(&listeners, iface);
#else
            struct listener* new = safe_malloc(sizeof(struct listener));
            new->family = iface->addr.sa.sa_family;
            new->iface = iface;
            new->next = listeners;
            new->tcpfd = -1;
            new->fd = -1;
            listeners = new;

            if (daemon->port != 0) {
                if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 ||
                    (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 ||
                    setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
                    setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 ||
                    !fix_fd(new->tcpfd) || !fix_fd(new->fd))
                    die(_("failed to create listening socket: %s"), NULL, EC_BADNET);

#ifdef HAVE_IPV6
                if (iface->addr.sa.sa_family == AF_INET6) {
                    if (setsockopt(new->fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
                        setsockopt(new->tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
                        die(_("failed to set IPV6 options on listening socket: %s"), NULL,
                            EC_BADNET);
                }
#endif

                while (1) {
                    if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break;

#ifdef HAVE_IPV6
                    /* An interface may have an IPv6 address which is still undergoing DAD.
                   If so, the bind will fail until the DAD completes, so we try over 20 seconds
                   before failing. */
                    if (iface->addr.sa.sa_family == AF_INET6 &&
                        (errno == ENODEV || errno == EADDRNOTAVAIL) && dad_count++ < DAD_WAIT) {
                        sleep(1);
                        continue;
                    }
#endif
                    break;
                }

                if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) {
                    prettyprint_addr(&iface->addr, daemon->namebuff);
                    die(_("failed to bind listening socket for %s: %s"), daemon->namebuff,
                        EC_BADNET);
                }

                if (listen(new->tcpfd, 5) == -1)
                    die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
            }
#endif /* !__ANDROID */
    }

    return listeners;
}

/* return a UDP socket bound to a random port, have to cope with straying into
   occupied port nos and reserved ones. */
int random_sock(int family) {
    int fd;

    if ((fd = socket(family, SOCK_DGRAM, 0)) != -1) {
        union mysockaddr addr;
        unsigned int ports_avail = 65536u - (unsigned short) daemon->min_port;
        int tries = ports_avail < 30 ? 3 * ports_avail : 100;

        memset(&addr, 0, sizeof(addr));
        addr.sa.sa_family = family;

        /* don't loop forever if all ports in use. */

        if (fix_fd(fd))
            while (tries--) {
                unsigned short port = rand16();

                if (daemon->min_port != 0)
                    port = htons(daemon->min_port + (port % ((unsigned short) ports_avail)));

                if (family == AF_INET) {
                    addr.in.sin_addr.s_addr = INADDR_ANY;
                    addr.in.sin_port = port;
                } else {
                    addr.in6.sin6_addr = in6addr_any;
                    addr.in6.sin6_port = port;
                }

                if (bind(fd, (struct sockaddr*) &addr, sa_len(&addr)) == 0) return fd;

                if (errno != EADDRINUSE && errno != EACCES) break;
            }

        close(fd);
    }

    return -1;
}

int local_bind(int fd, union mysockaddr* addr, char* intname, uint32_t mark, int is_tcp) {
    union mysockaddr addr_copy = *addr;

    /* cannot set source _port_ for TCP connections. */
    if (is_tcp) {
        if (addr_copy.sa.sa_family == AF_INET) addr_copy.in.sin_port = 0;
#ifdef HAVE_IPV6
        else
            addr_copy.in6.sin6_port = 0;
#endif
    }

    if (bind(fd, (struct sockaddr*) &addr_copy, sa_len(&addr_copy)) == -1) return 0;

#if defined(SO_BINDTODEVICE)
    if (intname[0] != 0 &&
        setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, strlen(intname)) == -1)
        return 0;
#endif

    if (mark != 0 && setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1) return 0;

    return 1;
}

static struct serverfd* allocate_sfd(union mysockaddr* addr, char* intname, uint32_t mark) {
    struct serverfd* sfd;
    int errsave;

    /* when using random ports, servers which would otherwise use
       the INADDR_ANY/port0 socket have sfd set to NULL */
    if (!daemon->osport && intname[0] == 0) {
        errno = 0;

        if (addr->sa.sa_family == AF_INET && addr->in.sin_addr.s_addr == INADDR_ANY &&
            addr->in.sin_port == htons(0))
            return NULL;

#ifdef HAVE_IPV6
        if (addr->sa.sa_family == AF_INET6 &&
            memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
            addr->in6.sin6_port == htons(0))
            return NULL;
#endif
    }

    /* may have a suitable one already */
    for (sfd = daemon->sfds; sfd; sfd = sfd->next)
        if (sockaddr_isequal(&sfd->source_addr, addr) && mark == sfd->mark &&
            strcmp(intname, sfd->interface) == 0)
            return sfd;

    /* need to make a new one. */
    errno = ENOMEM; /* in case malloc fails. */
    if (!(sfd = whine_malloc(sizeof(struct serverfd)))) return NULL;

    if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1) {
        free(sfd);
        return NULL;
    }

    if (!local_bind(sfd->fd, addr, intname, mark, 0) || !fix_fd(sfd->fd)) {
        errsave = errno; /* save error from bind. */
        close(sfd->fd);
        free(sfd);
        errno = errsave;
        return NULL;
    }

    strcpy(sfd->interface, intname);
    sfd->source_addr = *addr;
    sfd->mark = mark;
    sfd->next = daemon->sfds;
    daemon->sfds = sfd;
    return sfd;
}

/* create upstream sockets during startup, before root is dropped which may be needed
   this allows query_port to be a low port and interface binding */
void pre_allocate_sfds(void) {
    struct server* srv;

    if (daemon->query_port != 0) {
        union mysockaddr addr;
        memset(&addr, 0, sizeof(addr));
        addr.in.sin_family = AF_INET;
        addr.in.sin_addr.s_addr = INADDR_ANY;
        addr.in.sin_port = htons(daemon->query_port);
        allocate_sfd(&addr, "", 0);
#ifdef HAVE_IPV6
        memset(&addr, 0, sizeof(addr));
        addr.in6.sin6_family = AF_INET6;
        addr.in6.sin6_addr = in6addr_any;
        addr.in6.sin6_port = htons(daemon->query_port);
        allocate_sfd(&addr, "", 0);
#endif
    }

    for (srv = daemon->servers; srv; srv = srv->next)
        if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
            !allocate_sfd(&srv->source_addr, srv->interface, srv->mark) && errno != 0 &&
            (daemon->options & OPT_NOWILD)) {
            prettyprint_addr(&srv->addr, daemon->namebuff);
            if (srv->interface[0] != 0) {
                strcat(daemon->namebuff, " ");
                strcat(daemon->namebuff, srv->interface);
            }
            die(_("failed to bind server socket for %s: %s"), daemon->namebuff, EC_BADNET);
        }
}

void check_servers(void) {
    struct irec* iface;
    struct server* new, *tmp, *ret = NULL;
    int port = 0;

    for (new = daemon->servers; new; new = tmp) {
        tmp = new->next;

        if (!(new->flags&(SERV_LITERAL_ADDRESS | SERV_NO_ADDR))) {
            port = prettyprint_addr(&new->addr, daemon->namebuff);

            /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
            if (new->addr.sa.sa_family == AF_INET && new->addr.in.sin_addr.s_addr == 0) {
                free(new);
                continue;
            }

            for (iface = daemon->interfaces; iface; iface = iface->next)
                if (sockaddr_isequal(&new->addr, &iface->addr)) break;
            if (iface) {
                my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"),
                          daemon->namebuff);
                free(new);
                continue;
            }

            /* Do we need a socket set? */
            if (!new->sfd &&
                !(new->sfd = allocate_sfd(&new->source_addr, new->interface, new->mark)) &&
                errno != 0) {
                my_syslog(LOG_WARNING, _("ignoring nameserver %s - cannot make/bind socket: %s"),
                          daemon->namebuff, strerror(errno));
                free(new);
                continue;
            }
        }

        /* reverse order - gets it right. */
        new->next = ret;
        ret = new;

        if (new->flags&(SERV_HAS_DOMAIN | SERV_FOR_NODOTS)) {
            char *s1, *s2;
            if (!(new->flags& SERV_HAS_DOMAIN))
                s1 = _("unqualified"), s2 = _("names");
            else if (strlen(new->domain) == 0)
                s1 = _("default"), s2 = "";
            else
                s1 = _("domain"), s2 = new->domain;

            if (new->flags & SERV_NO_ADDR)
                my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
            else if (!(new->flags& SERV_LITERAL_ADDRESS))
                my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port,
                          s1, s2);
        } else if (new->interface[0] != 0)
            my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port,
                      new->interface);
        else
            my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
    }

    daemon->servers = ret;
}

#ifdef __ANDROID__
/* #define __ANDROID_DEBUG__ 1 */
/*
 * Ingests a new list of interfaces and starts to listen on them, adding only the new
 * and stopping to listen to any interfaces not on the new list.
 *
 * interfaces - input in the format "bt-pan|eth0|wlan0|..>" up to 1024 bytes long
 */
void set_interfaces(const char* interfaces) {
    struct iname* if_tmp;
    struct iname* prev_if_names;
    struct irec *old_iface, *new_iface, *prev_interfaces;
    char s[1024];
    char* next = s;
    char* interface;
    int was_wild = 0;

#ifdef __ANDROID_DEBUG__
    my_syslog(LOG_DEBUG, _("set_interfaces(%s)"), interfaces);
#endif
    prev_if_names = daemon->if_names;
    daemon->if_names = NULL;

    prev_interfaces = daemon->interfaces;
    daemon->interfaces = NULL;

    if (strlen(interfaces) > sizeof(s)) {
        die(_("interface string too long: %s"), NULL, EC_BADNET);
    }
    strncpy(s, interfaces, sizeof(s));
    while ((interface = strsep(&next, SEPARATOR))) {
        if (!if_nametoindex(interface)) {
            my_syslog(LOG_ERR, _("interface given in %s: '%s' has no ifindex; ignoring"),
                      __FUNCTION__, interface);
            continue;
        }
        if_tmp = safe_malloc(sizeof(struct iname));
        memset(if_tmp, 0, sizeof(struct iname));
        if ((if_tmp->name = strdup(interface)) == NULL) {
            die(_("malloc failure in set_interfaces: %s"), NULL, EC_BADNET);
        }
        if_tmp->next = daemon->if_names;
        daemon->if_names = if_tmp;
    }

    /*
     * Enumerate IP addresses (via RTM_GETADDR), adding IP entries to
     * daemon->interfaces for interface names listed in daemon->if_names.
     * The sockets are created by the create_bound_listener call below.
     * Only do this if at least one interface was found. Otherwise,
     * enumerate_interfaces will start listening on all interfaces on
     * the system.
     */
    if (daemon->if_names != NULL && !enumerate_interfaces()) {
        die(_("enumerate interfaces error in set_interfaces: %s"), NULL, EC_BADNET);
    }

    for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next) {
        if (if_tmp->name && !if_tmp->used) {
            my_syslog(LOG_ERR, _("unknown interface given %s in set_interfaces()"), if_tmp->name);
        }
    }

    /* success! - setup to free the old */
    /* check for any that have been removed */
    for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
        int found = 0;
        for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
            if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
                found = 1;
                break;
            }
        }

        if (found) {
            fixup_possible_existing_listener(new_iface);
        } else {
#ifdef __ANDROID_DEBUG__
            char debug_buff[MAXDNAME];
            prettyprint_addr(&old_iface->addr, debug_buff);
            my_syslog(LOG_DEBUG, _("closing listener for %s"), debug_buff);
#endif

            close_bound_listener(old_iface);
        }
    }

    /* remove wildchar listeners */
    was_wild = close_bound_listener(NULL);
    if (was_wild) daemon->options |= OPT_NOWILD;

    /* check for any that have been added */
    for (new_iface = daemon->interfaces; new_iface; new_iface = new_iface->next) {
        int found = 0;

        /* if the previous setup used a wildchar, then add any current interfaces */
        if (!was_wild) {
            for (old_iface = prev_interfaces; old_iface; old_iface = old_iface->next) {
                if (sockaddr_isequal(&old_iface->addr, &new_iface->addr)) {
                    found = -1;
                    break;
                }
            }
        }
        if (!found) {
#ifdef __ANDROID_DEBUG__
            char debug_buff[MAXDNAME];
            prettyprint_addr(&new_iface->addr, debug_buff);
            my_syslog(LOG_DEBUG, _("adding listener for %s"), debug_buff);
#endif
            create_bound_listener(&(daemon->listeners), new_iface);
        }
    }

    while (prev_if_names) {
        if (prev_if_names->name) free(prev_if_names->name);
        if_tmp = prev_if_names->next;
        free(prev_if_names);
        prev_if_names = if_tmp;
    }
    while (prev_interfaces) {
        struct irec* tmp_irec = prev_interfaces->next;
        free(prev_interfaces);
        prev_interfaces = tmp_irec;
    }
#ifdef __ANDROID_DEBUG__
    my_syslog(LOG_DEBUG, _("done with setInterfaces"));
#endif
}

/*
 * Takes a string in the format "0x100b|1.2.3.4|1.2.3.4|..." - up to 1024 bytes in length
 *  - The first element is the socket mark to set on sockets that forward DNS queries.
 *  - The subsequent elements are the DNS servers to forward queries to.
 */
int set_servers(const char* servers) {
    char s[1024];
    struct server* old_servers = NULL;
    struct server* new_servers = NULL;
    struct server* serv;
    char* mark_string;
    uint32_t mark;

    strncpy(s, servers, sizeof(s));

    /* move old servers to free list - we can reuse the memory
       and not risk malloc if there are the same or fewer new servers.
       Servers which were specced on the command line go to the new list. */
    for (serv = daemon->servers; serv;) {
        struct server* tmp = serv->next;
        if (serv->flags & SERV_FROM_RESOLV) {
            serv->next = old_servers;
            old_servers = serv;
            /* forward table rules reference servers, so have to blow them away */
            server_gone(serv);
        } else {
            serv->next = new_servers;
            new_servers = serv;
        }
        serv = tmp;
    }

    char* next = s;
    char* saddr;

    /* Parse the mark. */
    mark_string = strsep(&next, SEPARATOR);
    mark = strtoul(mark_string, NULL, 0);

    while ((saddr = strsep(&next, SEPARATOR))) {
        union mysockaddr addr, source_addr;
        memset(&addr, 0, sizeof(addr));
        memset(&source_addr, 0, sizeof(source_addr));

        if (parse_addr(AF_INET, saddr, &addr) == 0) {
            addr.in.sin_port = htons(NAMESERVER_PORT);
            source_addr.in.sin_family = AF_INET;
            source_addr.in.sin_addr.s_addr = INADDR_ANY;
            source_addr.in.sin_port = htons(daemon->query_port);
        }
#ifdef HAVE_IPV6
        else if (parse_addr(AF_INET6, saddr, &addr) == 0) {
            addr.in6.sin6_port = htons(NAMESERVER_PORT);
            source_addr.in6.sin6_family = AF_INET6;
            source_addr.in6.sin6_addr = in6addr_any;
            source_addr.in6.sin6_port = htons(daemon->query_port);
        }
#endif /* IPV6 */
        else
            continue;

        if (old_servers) {
            serv = old_servers;
            old_servers = old_servers->next;
        } else if (!(serv = whine_malloc(sizeof(struct server))))
            continue;

        /* this list is reverse ordered:
       it gets reversed again in check_servers */
        serv->next = new_servers;
        new_servers = serv;
        serv->addr = addr;
        serv->source_addr = source_addr;
        serv->domain = NULL;
        serv->interface[0] = 0;
        serv->mark = mark;
        serv->sfd = NULL;
        serv->flags = SERV_FROM_RESOLV;
        serv->queries = serv->failed_queries = 0;
    }

    /* Free any memory not used. */
    while (old_servers) {
        struct server* tmp = old_servers->next;
        free(old_servers);
        old_servers = tmp;
    }

    daemon->servers = new_servers;
    return 0;
}
#endif

/* Return zero if no servers found, in that case we keep polling.
   This is a protection against an update-time/write race on resolv.conf */
int reload_servers(char* fname) {
    FILE* f;
    char* line;
    struct server* old_servers = NULL;
    struct server* new_servers = NULL;
    struct server* serv;
    int gotone = 0;

    /* buff happens to be MAXDNAME long... */
    if (!(f = fopen(fname, "r"))) {
        my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
        return 0;
    }

    /* move old servers to free list - we can reuse the memory
       and not risk malloc if there are the same or fewer new servers.
       Servers which were specced on the command line go to the new list. */
    for (serv = daemon->servers; serv;) {
        struct server* tmp = serv->next;
        if (serv->flags & SERV_FROM_RESOLV) {
            serv->next = old_servers;
            old_servers = serv;
            /* forward table rules reference servers, so have to blow them away */
            server_gone(serv);
        } else {
            serv->next = new_servers;
            new_servers = serv;
        }
        serv = tmp;
    }

    while ((line = fgets(daemon->namebuff, MAXDNAME, f))) {
        union mysockaddr addr, source_addr;
        char* token = strtok(line, " \t\n\r");

        if (!token) continue;
        if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0) continue;
        if (!(token = strtok(NULL, " \t\n\r"))) continue;

        memset(&addr, 0, sizeof(addr));
        memset(&source_addr, 0, sizeof(source_addr));

        if (parse_addr(AF_INET, token, &addr) == 0) {
            addr.in.sin_port = htons(NAMESERVER_PORT);
            source_addr.in.sin_family = AF_INET;
            source_addr.in.sin_addr.s_addr = INADDR_ANY;
            source_addr.in.sin_port = htons(daemon->query_port);
        }
#ifdef HAVE_IPV6
        else if (parse_addr(AF_INET6, token, &addr) == 0) {
            addr.in6.sin6_port = htons(NAMESERVER_PORT);
            source_addr.in6.sin6_family = AF_INET6;
            source_addr.in6.sin6_addr = in6addr_any;
            source_addr.in6.sin6_port = htons(daemon->query_port);
        }
#endif /* IPV6 */
        else
            continue;

        if (old_servers) {
            serv = old_servers;
            old_servers = old_servers->next;
        } else if (!(serv = whine_malloc(sizeof(struct server))))
            continue;

        /* this list is reverse ordered:
       it gets reversed again in check_servers */
        serv->next = new_servers;
        new_servers = serv;
        serv->addr = addr;
        serv->source_addr = source_addr;
        serv->domain = NULL;
        serv->interface[0] = 0;
        serv->mark = 0;
        serv->sfd = NULL;
        serv->flags = SERV_FROM_RESOLV;
        serv->queries = serv->failed_queries = 0;
        gotone = 1;
    }

    /* Free any memory not used. */
    while (old_servers) {
        struct server* tmp = old_servers->next;
        free(old_servers);
        old_servers = tmp;
    }

    daemon->servers = new_servers;
    fclose(f);

    return gotone;
}

/* Use an IPv4 listener socket for ioctling */
struct in_addr get_ifaddr(char* intr) {
    struct listener* l;
    struct ifreq ifr;

    for (l = daemon->listeners; l && l->family != AF_INET; l = l->next)
        ;

    strncpy(ifr.ifr_name, intr, IF_NAMESIZE);
    ifr.ifr_addr.sa_family = AF_INET;

    if (!l || ioctl(l->fd, SIOCGIFADDR, &ifr) == -1)
        ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr = -1;

    return ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr;
}
