"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/network.c" between
dnsmasq-2.84.tar.xz and dnsmasq-2.85.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

network.c  (dnsmasq-2.84.tar.xz):network.c  (dnsmasq-2.85.tar.xz)
skipping to change at line 231 skipping to change at line 231
struct iface_param { struct iface_param {
struct addrlist *spare; struct addrlist *spare;
int fd; int fd;
}; };
static int iface_allowed(struct iface_param *param, int if_index, char *label, static int iface_allowed(struct iface_param *param, int if_index, char *label,
union mysockaddr *addr, struct in_addr netmask, int pref ixlen, int iface_flags) union mysockaddr *addr, struct in_addr netmask, int pref ixlen, int iface_flags)
{ {
struct irec *iface; struct irec *iface;
int mtu = 0, loopback; int loopback;
struct ifreq ifr; struct ifreq ifr;
int tftp_ok = !!option_bool(OPT_TFTP); int tftp_ok = !!option_bool(OPT_TFTP);
int dhcp_ok = 1; int dhcp_ok = 1;
int auth_dns = 0; int auth_dns = 0;
int is_label = 0; int is_label = 0;
#if defined(HAVE_DHCP) || defined(HAVE_TFTP) #if defined(HAVE_DHCP) || defined(HAVE_TFTP)
struct iname *tmp; struct iname *tmp;
#endif #endif
(void)prefixlen; (void)prefixlen;
if (!indextoname(param->fd, if_index, ifr.ifr_name) || if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1) ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
return 0; return 0;
loopback = ifr.ifr_flags & IFF_LOOPBACK; loopback = ifr.ifr_flags & IFF_LOOPBACK;
if (loopback) if (loopback)
dhcp_ok = 0; dhcp_ok = 0;
if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
mtu = ifr.ifr_mtu;
if (!label) if (!label)
label = ifr.ifr_name; label = ifr.ifr_name;
else else
is_label = strcmp(label, ifr.ifr_name); is_label = strcmp(label, ifr.ifr_name);
/* maintain a list of all addresses on all interfaces for --local-service opti on */ /* maintain a list of all addresses on all interfaces for --local-service opti on */
if (option_bool(OPT_LOCAL_SERVICE)) if (option_bool(OPT_LOCAL_SERVICE))
{ {
struct addrlist *al; struct addrlist *al;
skipping to change at line 350 skipping to change at line 347
al->addr.addr6 = addr->in6.sin6_addr; al->addr.addr6 = addr->in6.sin6_addr;
al->flags = ADDRLIST_IPV6; al->flags = ADDRLIST_IPV6;
} }
} }
} }
#endif #endif
/* Update addresses from interface_names. These are a set independent /* Update addresses from interface_names. These are a set independent
of the set we're listening on. */ of the set we're listening on. */
for (int_name = daemon->int_names; int_name; int_name = int_name->next) for (int_name = daemon->int_names; int_name; int_name = int_name->next)
if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 && if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)
(addr->sa.sa_family == int_name->family || int_name->family == 0))
{ {
if (param->spare) struct addrlist *lp;
al = NULL;
if (addr->sa.sa_family == AF_INET && (int_name->flags & (IN4 | INP4))
)
{ {
al = param->spare; struct in_addr newaddr = addr->in.sin_addr;
param->spare = al->next;
if (int_name->flags & INP4)
{
if (netmask.s_addr == 0xffff)
continue;
newaddr.s_addr = (addr->in.sin_addr.s_addr & netmask.s_addr)
|
(int_name->proto4.s_addr & ~netmask.s_addr);
}
/* check for duplicates. */
for (lp = int_name->addr; lp; lp = lp->next)
if (lp->flags == 0 && lp->addr.addr4.s_addr == newaddr.s_addr)
break;
if (!lp)
{
if (param->spare)
{
al = param->spare;
param->spare = al->next;
}
else
al = whine_malloc(sizeof(struct addrlist));
if (al)
{
al->flags = 0;
al->addr.addr4 = newaddr;
}
}
} }
else
al = whine_malloc(sizeof(struct addrlist));
if (al) if (addr->sa.sa_family == AF_INET6 && (int_name->flags & (IN6 | INP6) ))
{ {
al->next = int_name->addr; struct in6_addr newaddr = addr->in6.sin6_addr;
int_name->addr = al;
if (int_name->flags & INP6)
{
int i;
/* No sense in doing /128. */
if (prefixlen == 128)
continue;
for (i = 0; i < 16; i++)
{
int bits = ((i+1)*8) - prefixlen;
if (bits >= 8)
newaddr.s6_addr[i] = int_name->proto6.s6_addr[i];
else if (bits >= 0)
{
unsigned char mask = 0xff << bits;
newaddr.s6_addr[i] =
(addr->in6.sin6_addr.s6_addr[i] & mask) |
(int_name->proto6.s6_addr[i] & ~mask);
}
}
}
if (addr->sa.sa_family == AF_INET) /* check for duplicates. */
for (lp = int_name->addr; lp; lp = lp->next)
if ((lp->flags & ADDRLIST_IPV6) &&
IN6_ARE_ADDR_EQUAL(&lp->addr.addr6, &newaddr))
break;
if (!lp)
{ {
al->addr.addr4 = addr->in.sin_addr; if (param->spare)
al->flags = 0; {
al = param->spare;
param->spare = al->next;
}
else
al = whine_malloc(sizeof(struct addrlist));
if (al)
{
al->flags = ADDRLIST_IPV6;
al->addr.addr6 = newaddr;
/* Privacy addresses and addresses still undergoing DAD a
nd deprecated addresses
don't appear in forward queries, but will in reverse o
nes. */
if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (I
FACE_DEPRECATED | IFACE_TENTATIVE)))
al->flags |= ADDRLIST_REVONLY;
}
} }
else }
{
al->addr.addr6 = addr->in6.sin6_addr; if (al)
al->flags = ADDRLIST_IPV6; {
/* Privacy addresses and addresses still undergoing DAD and d al->next = int_name->addr;
eprecated addresses int_name->addr = al;
don't appear in forward queries, but will in reverse ones.
*/
if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE
_DEPRECATED | IFACE_TENTATIVE)))
al->flags |= ADDRLIST_REVONLY;
}
} }
} }
} }
/* check whether the interface IP has been added already /* check whether the interface IP has been added already
we call this routine multiple times. */ we call this routine multiple times. */
for (iface = daemon->interfaces; iface; iface = iface->next) for (iface = daemon->interfaces; iface; iface = iface->next)
if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index) if (sockaddr_isequal(&iface->addr, addr) && iface->index == if_index)
{ {
iface->dad = !!(iface_flags & IFACE_TENTATIVE); iface->dad = !!(iface_flags & IFACE_TENTATIVE);
skipping to change at line 456 skipping to change at line 526
tftp_ok = 0; tftp_ok = 0;
for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next) for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name)) if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
tftp_ok = 1; tftp_ok = 1;
} }
#endif #endif
/* add to list */ /* add to list */
if ((iface = whine_malloc(sizeof(struct irec)))) if ((iface = whine_malloc(sizeof(struct irec))))
{ {
int mtu = 0;
if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
mtu = ifr.ifr_mtu;
iface->addr = *addr; iface->addr = *addr;
iface->netmask = netmask; iface->netmask = netmask;
iface->tftp_ok = tftp_ok; iface->tftp_ok = tftp_ok;
iface->dhcp_ok = dhcp_ok; iface->dhcp_ok = dhcp_ok;
iface->dns_auth = auth_dns; iface->dns_auth = auth_dns;
iface->mtu = mtu; iface->mtu = mtu;
iface->dad = !!(iface_flags & IFACE_TENTATIVE); iface->dad = !!(iface_flags & IFACE_TENTATIVE);
iface->found = 1; iface->found = 1;
iface->done = iface->multicast_done = iface->warned = 0; iface->done = iface->multicast_done = iface->warned = 0;
iface->index = if_index; iface->index = if_index;
skipping to change at line 590 skipping to change at line 665
/* Someone is still using this listener, skip its deletion */ /* Someone is still using this listener, skip its deletion */
if (l->used > 0) if (l->used > 0)
return 0; return 0;
} }
if (l->iface->done) if (l->iface->done)
{ {
int port; int port;
port = prettyprint_addr(&l->iface->addr, daemon->addrbuff); port = prettyprint_addr(&l->iface->addr, daemon->addrbuff);
my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s port %d"), my_syslog(LOG_DEBUG|MS_DEBUG, _("stopped listening on %s(#%d): %s port %d" ),
l->iface->name, l->iface->index, daemon->addrbuff, port); l->iface->name, l->iface->index, daemon->addrbuff, port);
/* In case it ever returns */ /* In case it ever returns */
l->iface->done = 0; l->iface->done = 0;
} }
if (l->fd != -1) if (l->fd != -1)
close(l->fd); close(l->fd);
if (l->tcpfd != -1) if (l->tcpfd != -1)
close(l->tcpfd); close(l->tcpfd);
if (l->tftpfd != -1) if (l->tftpfd != -1)
skipping to change at line 619 skipping to change at line 694
static struct addrlist *spare = NULL; static struct addrlist *spare = NULL;
static int done = 0; static int done = 0;
struct iface_param param; struct iface_param param;
int errsave, ret = 1; int errsave, ret = 1;
struct addrlist *addr, *tmp; struct addrlist *addr, *tmp;
struct interface_name *intname; struct interface_name *intname;
struct irec *iface; struct irec *iface;
#ifdef HAVE_AUTH #ifdef HAVE_AUTH
struct auth_zone *zone; struct auth_zone *zone;
#endif #endif
struct server *serv;
/* Do this max once per select cycle - also inhibits netlink socket use /* Do this max once per select cycle - also inhibits netlink socket use
in TCP child processes. */ in TCP child processes. */
if (reset) if (reset)
{ {
done = 0; done = 0;
return 1; return 1;
} }
if (done) if (done)
return 1; return 1;
done = 1; done = 1;
if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
return 0; return 0;
/* iface indexes can change when interfaces are created/destroyed.
We use them in the main forwarding control path, when the path
to a server is specified by an interface, so cache them.
Update the cache here. */
for (serv = daemon->servers; serv; serv = serv->next)
if (serv->interface[0] != 0)
{
#ifdef HAVE_LINUX_NETWORK
struct ifreq ifr;
safe_strncpy(ifr.ifr_name, serv->interface, IF_NAMESIZE);
if (ioctl(param.fd, SIOCGIFINDEX, &ifr) != -1)
serv->ifindex = ifr.ifr_ifindex;
#else
serv->ifindex = if_nametoindex(serv->interface);
#endif
}
again:
/* Mark interfaces for garbage collection */ /* Mark interfaces for garbage collection */
for (iface = daemon->interfaces; iface; iface = iface->next) for (iface = daemon->interfaces; iface; iface = iface->next)
iface->found = 0; iface->found = 0;
/* remove addresses stored against interface_names */ /* remove addresses stored against interface_names */
for (intname = daemon->int_names; intname; intname = intname->next) for (intname = daemon->int_names; intname; intname = intname->next)
{ {
for (addr = intname->addr; addr; addr = tmp) for (addr = intname->addr; addr; addr = tmp)
{ {
tmp = addr->next; tmp = addr->next;
skipping to change at line 688 skipping to change at line 783
addr->next = spare; addr->next = spare;
spare = addr; spare = addr;
} }
} }
} }
#endif #endif
param.spare = spare; param.spare = spare;
ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6); ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
if (ret < 0)
if (ret) goto again;
ret = iface_enumerate(AF_INET, &param, iface_allowed_v4); else if (ret)
{
ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
if (ret < 0)
goto again;
}
errsave = errno; errsave = errno;
close(param.fd); close(param.fd);
if (option_bool(OPT_CLEVERBIND)) if (option_bool(OPT_CLEVERBIND))
{ {
/* Garbage-collect listeners listening on addresses that no longer exist. /* Garbage-collect listeners listening on addresses that no longer exist.
Does nothing when not binding interfaces or for listeners on localhost, Does nothing when not binding interfaces or for listeners on localhost,
since the ->iface field is NULL. Note that this needs the protections since the ->iface field is NULL. Note that this needs the protections
against reentrancy, hence it's here. It also means there's a possibilit y, against reentrancy, hence it's here. It also means there's a possibilit y,
skipping to change at line 1042 skipping to change at line 1142
new->next = daemon->listeners; new->next = daemon->listeners;
daemon->listeners = new; daemon->listeners = new;
iface->done = 1; iface->done = 1;
/* Don't log the initial set of listen addresses created /* Don't log the initial set of listen addresses created
at startup, since this is happening before the logging at startup, since this is happening before the logging
system is initialised and the sign-on printed. */ system is initialised and the sign-on printed. */
if (!dienow) if (!dienow)
{ {
int port = prettyprint_addr(&iface->addr, daemon->addrbuff); int port = prettyprint_addr(&iface->addr, daemon->addrbuff);
my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s port %d"), my_syslog(LOG_DEBUG|MS_DEBUG, _("listening on %s(#%d): %s port %d "),
iface->name, iface->index, daemon->addrbuff, port); iface->name, iface->index, daemon->addrbuff, port);
} }
} }
} }
/* Check for --listen-address options that haven't been used because there's /* Check for --listen-address options that haven't been used because there's
no interface with a matching address. These may be valid: eg it's possible no interface with a matching address. These may be valid: eg it's possible
to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1 to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
If the address isn't valid the bind() will fail and we'll die() If the address isn't valid the bind() will fail and we'll die()
skipping to change at line 1069 skipping to change at line 1169
for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next) for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
if (!if_tmp->used && if (!if_tmp->used &&
(new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow))) (new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
{ {
new->next = daemon->listeners; new->next = daemon->listeners;
daemon->listeners = new; daemon->listeners = new;
if (!dienow) if (!dienow)
{ {
int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff); int port = prettyprint_addr(&if_tmp->addr, daemon->addrbuff);
my_syslog(LOG_DEBUG, _("listening on %s port %d"), daemon->addrbuff, port); my_syslog(LOG_DEBUG|MS_DEBUG, _("listening on %s port %d"), daemon->a ddrbuff, port);
} }
} }
} }
/* In --bind-interfaces, the only access control is the addresses we're listenin g on. /* In --bind-interfaces, the only access control is the addresses we're listenin g on.
There's nothing to avoid a query to the address of an internal interface arri ving via There's nothing to avoid a query to the address of an internal interface arri ving via
an external interface where we don't want to accept queries, except that in t he usual an external interface where we don't want to accept queries, except that in t he usual
case the addresses of internal interfaces are RFC1918. When bind-interfaces i n use, case the addresses of internal interfaces are RFC1918. When bind-interfaces i n use,
and we listen on an address that looks like it's probably globally routeable, shout. and we listen on an address that looks like it's probably globally routeable, shout.
skipping to change at line 1203 skipping to change at line 1303
if (dienow) if (dienow)
die(s, iface->name, EC_BADNET); die(s, iface->name, EC_BADNET);
else else
my_syslog(LOG_ERR, s, iface->name, strerror(errno)); my_syslog(LOG_ERR, s, iface->name, strerror(errno));
} }
} }
} }
} }
#endif #endif
/* 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 = ((unsigned short)daemon->max_port - (unsigned s
hort)daemon->min_port) + 1;
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 = htons(daemon->min_port + (rand16() % ((unsigned
short)ports_avail)));
if (family == AF_INET)
{
addr.in.sin_addr.s_addr = INADDR_ANY;
addr.in.sin_port = port;
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in.sin_len = sizeof(struct sockaddr_in);
#endif
}
else
{
addr.in6.sin6_addr = in6addr_any;
addr.in6.sin6_port = port;
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
#endif
}
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, unsigned int ifind ex, int is_tcp) int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifind ex, int is_tcp)
{ {
union mysockaddr addr_copy = *addr; union mysockaddr addr_copy = *addr;
unsigned short port; unsigned short port;
int tries = 1, done = 0; int tries = 1;
unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short unsigned short ports_avail = 1;
)daemon->min_port) + 1;
if (addr_copy.sa.sa_family == AF_INET) if (addr_copy.sa.sa_family == AF_INET)
port = addr_copy.in.sin_port; port = addr_copy.in.sin_port;
else else
port = addr_copy.in6.sin6_port; port = addr_copy.in6.sin6_port;
/* cannot set source _port_ for TCP connections. */ /* cannot set source _port_ for TCP connections. */
if (is_tcp) if (is_tcp)
port = 0; port = 0;
else if (port == 0 && daemon->max_port != 0)
/* Bind a random port within the range given by min-port and max-port */
if (port == 0)
{ {
/* Bind a random port within the range given by min-port and max-port if e
ither
or both are set. Otherwise use the OS's random ephemeral port allocation
by
leaving port == 0 and tries == 1 */
ports_avail = daemon->max_port - daemon->min_port + 1;
tries = ports_avail < 30 ? 3 * ports_avail : 100; tries = ports_avail < 30 ? 3 * ports_avail : 100;
port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)) ); port = htons(daemon->min_port + (rand16() % ports_avail));
} }
while (tries--) while (1)
{ {
/* elide bind() call if it's to port 0, address 0 */
if (addr_copy.sa.sa_family == AF_INET) if (addr_copy.sa.sa_family == AF_INET)
addr_copy.in.sin_port = port; {
if (port == 0 && addr_copy.in.sin_addr.s_addr == 0)
break;
addr_copy.in.sin_port = port;
}
else else
addr_copy.in6.sin6_port = port;
if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
{ {
done = 1; if (port == 0 && IN6_IS_ADDR_UNSPECIFIED(&addr_copy.in6.sin6_addr))
break; break;
addr_copy.in6.sin6_port = port;
} }
if (errno != EADDRINUSE && errno != EACCES) if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) != -1)
break;
if (errno != EADDRINUSE && errno != EACCES)
return 0;
if (--tries == 0)
return 0; return 0;
port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)) ); port = htons(daemon->min_port + (rand16() % ports_avail));
} }
if (!done)
return 0;
if (!is_tcp && ifindex > 0) if (!is_tcp && ifindex > 0)
{ {
#if defined(IP_UNICAST_IF) #if defined(IP_UNICAST_IF)
if (addr_copy.sa.sa_family == AF_INET) if (addr_copy.sa.sa_family == AF_INET)
{ {
uint32_t ifindex_opt = htonl(ifindex); uint32_t ifindex_opt = htonl(ifindex);
return setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_opt, sizeof( ifindex_opt)) == 0; return setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_opt, sizeof( ifindex_opt)) == 0;
} }
#endif #endif
#if defined (IPV6_UNICAST_IF) #if defined (IPV6_UNICAST_IF)
skipping to change at line 1328 skipping to change at line 1384
(void)intname; /* suppress potential unused warning */ (void)intname; /* suppress potential unused warning */
#if defined(SO_BINDTODEVICE) #if defined(SO_BINDTODEVICE)
if (intname[0] != 0 && if (intname[0] != 0 &&
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1) setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
return 0; return 0;
#endif #endif
return 1; return 1;
} }
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname) static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname, unsi gned int ifindex)
{ {
struct serverfd *sfd; struct serverfd *sfd;
unsigned int ifindex = 0;
int errsave; int errsave;
int opt = 1; int opt = 1;
/* when using random ports, servers which would otherwise use /* when using random ports, servers which would otherwise use
the INADDR_ANY/port0 socket have sfd set to NULL */ the INADDR_ANY/port0 socket have sfd set to NULL, this is
if (!daemon->osport && intname[0] == 0) anything without an explictly set source port. */
if (!daemon->osport)
{ {
errno = 0; errno = 0;
if (addr->sa.sa_family == AF_INET && if (addr->sa.sa_family == AF_INET &&
addr->in.sin_addr.s_addr == INADDR_ANY &&
addr->in.sin_port == htons(0)) addr->in.sin_port == htons(0))
return NULL; return NULL;
if (addr->sa.sa_family == AF_INET6 && if (addr->sa.sa_family == AF_INET6 &&
memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
addr->in6.sin6_port == htons(0)) addr->in6.sin6_port == htons(0))
return NULL; return NULL;
} }
if (intname && strlen(intname) != 0)
ifindex = if_nametoindex(intname); /* index == 0 when not binding to an inte
rface */
/* may have a suitable one already */ /* may have a suitable one already */
for (sfd = daemon->sfds; sfd; sfd = sfd->next ) for (sfd = daemon->sfds; sfd; sfd = sfd->next )
if (sockaddr_isequal(&sfd->source_addr, addr) && if (ifindex == sfd->ifindex &&
strcmp(intname, sfd->interface) == 0 && sockaddr_isequal(&sfd->source_addr, addr) &&
ifindex == sfd->ifindex) strcmp(intname, sfd->interface) == 0)
return sfd; return sfd;
/* need to make a new one. */ /* need to make a new one. */
errno = ENOMEM; /* in case malloc fails. */ errno = ENOMEM; /* in case malloc fails. */
if (!(sfd = whine_malloc(sizeof(struct serverfd)))) if (!(sfd = whine_malloc(sizeof(struct serverfd))))
return NULL; return NULL;
if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1) if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
{ {
free(sfd); free(sfd);
skipping to change at line 1410 skipping to change at line 1461
if (daemon->query_port != 0) if (daemon->query_port != 0)
{ {
union mysockaddr addr; union mysockaddr addr;
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.in.sin_family = AF_INET; addr.in.sin_family = AF_INET;
addr.in.sin_addr.s_addr = INADDR_ANY; addr.in.sin_addr.s_addr = INADDR_ANY;
addr.in.sin_port = htons(daemon->query_port); addr.in.sin_port = htons(daemon->query_port);
#ifdef HAVE_SOCKADDR_SA_LEN #ifdef HAVE_SOCKADDR_SA_LEN
addr.in.sin_len = sizeof(struct sockaddr_in); addr.in.sin_len = sizeof(struct sockaddr_in);
#endif #endif
if ((sfd = allocate_sfd(&addr, ""))) if ((sfd = allocate_sfd(&addr, "", 0)))
sfd->preallocated = 1; sfd->preallocated = 1;
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.in6.sin6_family = AF_INET6; addr.in6.sin6_family = AF_INET6;
addr.in6.sin6_addr = in6addr_any; addr.in6.sin6_addr = in6addr_any;
addr.in6.sin6_port = htons(daemon->query_port); addr.in6.sin6_port = htons(daemon->query_port);
#ifdef HAVE_SOCKADDR_SA_LEN #ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(struct sockaddr_in6); addr.in6.sin6_len = sizeof(struct sockaddr_in6);
#endif #endif
if ((sfd = allocate_sfd(&addr, ""))) if ((sfd = allocate_sfd(&addr, "", 0)))
sfd->preallocated = 1; sfd->preallocated = 1;
} }
for (srv = daemon->servers; srv; srv = srv->next) for (srv = daemon->servers; srv; srv = srv->next)
if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) && if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
!allocate_sfd(&srv->source_addr, srv->interface) && !allocate_sfd(&srv->source_addr, srv->interface, srv->ifindex) &&
errno != 0 && errno != 0 &&
option_bool(OPT_NOWILD)) option_bool(OPT_NOWILD))
{ {
(void)prettyprint_addr(&srv->source_addr, daemon->namebuff); (void)prettyprint_addr(&srv->source_addr, daemon->namebuff);
if (srv->interface[0] != 0) if (srv->interface[0] != 0)
{ {
strcat(daemon->namebuff, " "); strcat(daemon->namebuff, " ");
strcat(daemon->namebuff, srv->interface); strcat(daemon->namebuff, srv->interface);
} }
die(_("failed to bind server socket for %s: %s"), die(_("failed to bind server socket for %s: %s"),
skipping to change at line 1635 skipping to change at line 1686
break; break;
if (iface) if (iface)
{ {
my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface" ), daemon->namebuff); my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface" ), daemon->namebuff);
serv->flags |= SERV_MARK; serv->flags |= SERV_MARK;
continue; continue;
} }
/* Do we need a socket set? */ /* Do we need a socket set? */
if (!serv->sfd && if (!serv->sfd &&
!(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) && !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface, ser v->ifindex)) &&
errno != 0) errno != 0)
{ {
my_syslog(LOG_WARNING, my_syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %s") , _("ignoring nameserver %s - cannot make/bind socket: %s") ,
daemon->namebuff, strerror(errno)); daemon->namebuff, strerror(errno));
serv->flags |= SERV_MARK; serv->flags |= SERV_MARK;
continue; continue;
} }
if (serv->sfd) if (serv->sfd)
 End of changes. 42 change blocks. 
125 lines changed or deleted 176 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)