import of dnsmasq-2.9.tar.gz
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index fff2ff7..7ace797 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -37,15 +37,16 @@
int maxleases = MAXLEASES;
int query_port = 0;
int first_loop = 1;
+ int bind_fallback = 0;
unsigned long local_ttl = 0;
unsigned int options, min_leasetime;
char *runfile = RUNFILE;
time_t resolv_changed = 0;
time_t now, last = 0;
struct irec *interfaces = NULL;
- struct listener *listener, *listeners;
+ struct listener *listener, *listeners = NULL;
struct doctor *doctors = NULL;
- char *mxname = NULL;
+ struct mx_record *mxnames = NULL;
char *mxtarget = NULL;
char *lease_file = NULL;
char *addn_hosts = NULL;
@@ -106,7 +107,7 @@
packet = safe_malloc(DNSMASQ_PACKETSZ);
dhcp_next_server.s_addr = 0;
- options = read_opts(argc, argv, dnamebuff, &resolv, &mxname, &mxtarget, &lease_file,
+ options = read_opts(argc, argv, dnamebuff, &resolv, &mxnames, &mxtarget, &lease_file,
&username, &groupname, &domain_suffix, &runfile,
&if_names, &if_addrs, &if_except, &bogus_addr,
&serv_addrs, &cachesize, &port, &query_port, &local_ttl, &addn_hosts,
@@ -124,18 +125,41 @@
die("ISC dhcpd integration not available: set HAVE_ISC_READER in src/config.h", NULL);
#endif
-#ifndef HAVE_UDP_SRC_DST
- /* if we cannot support binding the wildcard address, set the "bind only
- interfaces in use" option */
- options |= OPT_NOWILD;
-#endif
-
interfaces = enumerate_interfaces(&if_names, &if_addrs, if_except, port);
- if (options & OPT_NOWILD)
- listeners = create_bound_listeners(interfaces);
- else
- listeners = create_wildcard_listeners(port);
+
+ if (!(options & OPT_NOWILD) && !(listeners = create_wildcard_listeners(port)))
+ {
+ bind_fallback = 1;
+ options |= OPT_NOWILD;
+ }
+ if (options & OPT_NOWILD)
+ {
+ struct iname *if_tmp;
+ listeners = create_bound_listeners(interfaces);
+
+ for (if_tmp = if_names; if_tmp; if_tmp = if_tmp->next)
+ if (if_tmp->name && !if_tmp->used)
+ die("unknown interface %s", if_tmp->name);
+
+ for (if_tmp = if_addrs; if_tmp; if_tmp = if_tmp->next)
+ if (!if_tmp->used)
+ {
+ char addrbuff[ADDRSTRLEN];
+#ifdef HAVE_IPV6
+ if (if_tmp->addr.sa.sa_family == AF_INET)
+ inet_ntop(AF_INET, &if_tmp->addr.in.sin_addr,
+ addrbuff, ADDRSTRLEN);
+ else
+ inet_ntop(AF_INET6, &if_tmp->addr.in6.sin6_addr,
+ addrbuff, ADDRSTRLEN);
+#else
+ strcpy(addrbuff, inet_ntoa(if_tmp->addr.in.sin_addr));
+#endif
+ die("no interface with address %s", addrbuff);
+ }
+ }
+
forward_init(1);
cache_init(cachesize, options & OPT_LOG);
@@ -148,6 +172,15 @@
if (dhcp)
{
+#if !defined(IP_PKTINFO) && !defined(IP_RECVIF)
+ int c;
+ struct iname *tmp;
+ for (c = 0, tmp = if_names; tmp; tmp = tmp->next)
+ if (!tmp->isloop)
+ c++;
+ if (c != 1)
+ die("must set exactly one interface on broken systems without IP_RECVIF", NULL);
+#endif
dhcp_init(&dhcpfd, &dhcp_raw_fd);
leasefd = lease_init(lease_file, domain_suffix, dnamebuff, packet, now, maxleases);
}
@@ -228,12 +261,9 @@
else
syslog(LOG_INFO, "started, version %s cache disabled", VERSION);
- if (options & OPT_LOCALMX)
- syslog(LOG_INFO, "serving MX record for local hosts target %s", mxtarget);
- else if (mxname)
- syslog(LOG_INFO, "serving MX record for mailhost %s target %s",
- mxname, mxtarget);
-
+ if (bind_fallback)
+ syslog(LOG_WARNING, "setting --bind-interfaces option because if OS limitations");
+
for (dhcp_tmp = dhcp; dhcp_tmp; dhcp_tmp = dhcp_tmp->next)
{
strcpy(dnamebuff, inet_ntoa(dhcp_tmp->start));
@@ -256,8 +286,9 @@
if (getuid() == 0 || geteuid() == 0)
syslog(LOG_WARNING, "failed to drop root privs");
- servers = last_server = check_servers(serv_addrs, interfaces, &sfds);
-
+ servers = check_servers(serv_addrs, interfaces, &sfds);
+ last_server = NULL;
+
while (sigterm == 0)
{
fd_set rset;
@@ -275,9 +306,11 @@
lease_update_dns();
}
if (resolv && (options & OPT_NO_POLL))
- servers = last_server =
- check_servers(reload_servers(resolv->name, dnamebuff, servers, query_port),
- interfaces, &sfds);
+ {
+ servers = check_servers(reload_servers(resolv->name, dnamebuff, servers, query_port),
+ interfaces, &sfds);
+ last_server = NULL;
+ }
sighup = 0;
}
@@ -373,7 +406,7 @@
else
{
res->logged = 0;
- if (statbuf.st_mtime > last_change)
+ if (difftime(statbuf.st_mtime, last_change) > 0.0)
{
last_change = statbuf.st_mtime;
latest = res;
@@ -382,20 +415,20 @@
res = res->next;
}
- if (latest && last_change > resolv_changed)
+ if (latest && difftime(last_change, resolv_changed) > 0.0)
{
resolv_changed = last_change;
- servers = last_server =
- check_servers(reload_servers(latest->name, dnamebuff, servers, query_port),
- interfaces, &sfds);
+ servers = check_servers(reload_servers(latest->name, dnamebuff, servers, query_port),
+ interfaces, &sfds);
+ last_server = NULL;
}
}
}
for (serverfdp = sfds; serverfdp; serverfdp = serverfdp->next)
if (FD_ISSET(serverfdp->fd, &rset))
- last_server = reply_query(serverfdp->fd, options, packet, now,
- dnamebuff, last_server, bogus_addr, doctors);
+ last_server = reply_query(serverfdp, options, packet, now,
+ dnamebuff, servers, last_server, bogus_addr, doctors);
if (dhcp && FD_ISSET(dhcpfd, &rset))
dhcp_packet(dhcp, packet, dhcp_options, dhcp_configs, dhcp_vendors,
@@ -406,7 +439,7 @@
for (listener = listeners; listener; listener = listener->next)
if (FD_ISSET(listener->fd, &rset))
last_server = receive_query(listener, packet,
- mxname, mxtarget, options, now, local_ttl, dnamebuff,
+ mxnames, mxtarget, options, now, local_ttl, dnamebuff,
if_names, if_addrs, if_except, last_server, servers);
}