Commit f2621c7f authored by Simon Kelley's avatar Simon Kelley

import of dnsmasq-2.39.tar.gz

parent 6b01084f
...@@ -2151,4 +2151,86 @@ release 2.38 ...@@ -2151,4 +2151,86 @@ release 2.38
probably needs an infinite DHCP lease and some bad luck to probably needs an infinite DHCP lease and some bad luck to
trigger. Thanks to Detlef Reichelt for bug reports and testing. trigger. Thanks to Detlef Reichelt for bug reports and testing.
release 2.39
Apply patch from Mike Baker/OpenWRT to ensure that names
like "localhost." in /etc/hosts with trailing period
are treated as fully-qualified.
Tolerate and ignore spaces around commas in the
configuration file in all circumstances. Note that this
may change the meaning of a few existing config files, for
instance
txt-record=mydomain.com, string
would have a leading space in the string before, and now
will not. To get the old behaviour back, use quotes:
txt-record=mydomain.com," string"
/a is no longer a valid escape in quoted strings.
Added symbolic DHCP option names. Instead of
dhcp-option = 3, 1.2.3.4
it is now possible to do
dhcp-option = option:router, 1.2.3.4
To see the list of known DHCP options, use the
command "dnsmasq --help dhcp"
Thanks to Luigi Rizzo for a patch and good work on this.
Overhauled the log code so that logging can be asynchronous;
dnsmasq then no longer blocks waiting for the syslog() library
call. This is important on systems where syslog
is being used to log over the network (and therefore doing
DNS lookups) and syslog is using dnsmasq as its DNS
server. Having dnsmasq block awaiting syslog under
such circumstances can lead to syslog and dnsmasq
deadlocking. The new behaviour is enabled with a new
--log-async flag, which can also be used to tune the
queue length. Paul Chambers found and diagnosed
this trap for the unwary. He also did much testing of
the solution along with Carlos Carvalho.
--log-facility can now take a file-name instead of a
facility name. When this is done, dnsmasq logs to the
file and not via syslog. (Failures early in startup,
whilst reading configuration, will still go to syslog,
and syslog is used as a log-of-last-resort if the file
cannot be written.)
Added --log-dhcp flag. Suggestion from Carlos Carvalho.
Made BINDIR, MANDIR and LOCALEDIR independently
over-rideable in the makefile. Suggestion from Thomas
Klausner.
Added 127.0.0.0/8 and 169.254.0.0/16 to the address
ranges affected by --bogus-priv. Thanks to Paul
Chambers for the patch.
Fixed failure of TFTP server with --listen-address. Thanks
to William Dinkel for the bug report.
Added --dhcp-circuitid and --dhcp-remoteid for RFC3046
relay agent data matching.
Added --dhcp-subscrid for RFC3993 subscriber-id relay
agent data matching.
Correctly garbage-collect connections when upstream
servers go away as a result of DBus transactions.
Allow absolute paths for TFTP transfers even when
--tftp-root is set, as long as the path matches the root,
so /var/ftp/myfile is OK with tftp-root=/var/ftp.
Thanks for Thomas Mizzi for the patch.
Updated Spanish translation - thanks to Chris Chatham.
Updated French translation - thanks to Gildas Le Nadan.
Added to example conf file example of routing PTR queries
for a subnet to a different nameserver. Suggestion from
Jon Nicholson.
Added --interface-name option. This provides a facility
to add a domain name with a dynamic IP address taken from
the address of a local network interface. Useful for
networks with dynamic IPs.
...@@ -409,6 +409,27 @@ A: Yes, as a DNS server, dnsmasq will just work in a vserver. ...@@ -409,6 +409,27 @@ A: Yes, as a DNS server, dnsmasq will just work in a vserver.
refer to the vserver documentation for more information). refer to the vserver documentation for more information).
Q: What's the problem with syslog and dnsmasq?
A: In almost all cases: none. If you have the normal arrangement with
local daemons logging to a local syslog, which then writes to disk,
then there's never a problem. If you use network logging, then
there's a potential problem with deadlock: the syslog daemon will
do DNS lookups so that it can log the source of log messages,
these lookups will (depending on exact configuration) go through
dnsmasq, which also sends log messages. With bad timing, you can
arrive at a situation where syslog is waiting for dnsmasq, and
dnsmasq is waiting for syslog; they will both wait forever. This
problem is fixed from dnsmasq-2.39, which introduces asynchronous
logging: dnsmasq no longer waits for syslog and the deadlock is
broken. There is a remaining problem in 2.39, where "log-queries"
is in use. In this case most DNS queries generate two log lines, if
these go to a syslog which is doing a DNS lookup for each log line,
then those queries will in turn generate two more log lines, and a
chain reaction runaway will occur. To avoid this, use syslog-ng
and turn on syslog-ng's dns-cache function.
......
PREFIX?=/usr/local PREFIX ?= /usr/local
BINDIR = ${PREFIX}/sbin BINDIR ?= ${PREFIX}/sbin
MANDIR = ${PREFIX}/share/man MANDIR ?= ${PREFIX}/share/man
LOCALEDIR = ${PREFIX}/share/locale LOCALEDIR ?= ${PREFIX}/share/locale
SRC = src SRC = src
PO = po PO = po
......
...@@ -3,7 +3,8 @@ PKG_CONFIG ?= pkg-config ...@@ -3,7 +3,8 @@ PKG_CONFIG ?= pkg-config
OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \ OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o helper.o tftp.o dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
helper.o tftp.o log.o
.c.o: .c.o:
$(CC) $(CFLAGS) $(COPTS) $(I18N) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $< $(CC) $(CFLAGS) $(COPTS) $(I18N) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $<
......
...@@ -48,6 +48,10 @@ ...@@ -48,6 +48,10 @@
# non-public domains. # non-public domains.
#server=/localnet/192.168.0.1 #server=/localnet/192.168.0.1
# Example of routing PTR queries to nameservers: this will send all
# address->name queries for 192.168.3/24 to nameserver 10.1.2.3
#server=/3.168.192.in-addr.arpa/10.1.2.3
# Add local-only domains here, queries in these domains are answered # Add local-only domains here, queries in these domains are answered
# from /etc/hosts or DHCP only. # from /etc/hosts or DHCP only.
#local=/localnet/ #local=/localnet/
...@@ -196,23 +200,22 @@ ...@@ -196,23 +200,22 @@
# Send options to hosts which ask for a DHCP lease. # Send options to hosts which ask for a DHCP lease.
# See RFC 2132 for details of available options. # See RFC 2132 for details of available options.
# Common options can be given to dnsmasq by name:
# run "dnsmasq --help dhcp" to get a list.
# Note that all the common settings, such as netmask and # Note that all the common settings, such as netmask and
# broadcast address, DNS server and default route, are given # broadcast address, DNS server and default route, are given
# sane defaults by dnsmasq. You very likely will not need any # sane defaults by dnsmasq. You very likely will not need any
# any dhcp-options. If you use Windows clients and Samba, there # any dhcp-options. If you use Windows clients and Samba, there
# are some options which are recommended, they are detailed at the # are some options which are recommended, they are detailed at the
# end of this section. # end of this section.
# For reference, the common options are:
# subnet mask - 1
# default router - 3
# DNS server - 6
# hostname - 12
# broadcast address - 28
# Override the default route supplied by dnsmasq, which assumes the # Override the default route supplied by dnsmasq, which assumes the
# router is the same machine as the one running dnsmasq. # router is the same machine as the one running dnsmasq.
#dhcp-option=3,1.2.3.4 #dhcp-option=3,1.2.3.4
# Do the same thing, but using the option name
#dhcp-option=option:router,1.2.3.4
# Override the default route supplied by dnsmasq and send no default # Override the default route supplied by dnsmasq and send no default
# route at all. Note that this only works for the options sent by # route at all. Note that this only works for the options sent by
# default (1, 3, 6, 12, 28) the same line will send a zero-length option # default (1, 3, 6, 12, 28) the same line will send a zero-length option
...@@ -220,7 +223,7 @@ ...@@ -220,7 +223,7 @@
#dhcp-option=3 #dhcp-option=3
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5 # Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
#dhcp-option=42,192.168.0.4,10.10.0.5 #dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
# Set the NTP time server address to be the same machine as # Set the NTP time server address to be the same machine as
# is running dnsmasq # is running dnsmasq
...@@ -241,7 +244,8 @@ ...@@ -241,7 +244,8 @@
# Specify an option which will only be sent to the "red" network # Specify an option which will only be sent to the "red" network
# (see dhcp-range for the declaration of the "red" network) # (see dhcp-range for the declaration of the "red" network)
#dhcp-option=red,42,192.168.1.1 # Note that the net: part must precede the option: part.
#dhcp-option = net:red, option:ntp-server, 192.168.1.1
# The following DHCP options set up dnsmasq in the same way as is specified # The following DHCP options set up dnsmasq in the same way as is specified
# for the ISC dhcpcd in # for the ISC dhcpcd in
...@@ -257,7 +261,7 @@ ...@@ -257,7 +261,7 @@
# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client # Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client
# probably doesn't support this...... # probably doesn't support this......
#dhcp-option=119,eng.apple.com,marketing.apple.com #dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com
# Send RFC-3442 classless static routes (note the netmask encoding) # Send RFC-3442 classless static routes (note the netmask encoding)
#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8 #dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8
...@@ -434,6 +438,9 @@ ...@@ -434,6 +438,9 @@
# dnsmasq. # dnsmasq.
#log-queries #log-queries
# Log lots of extra information about DHCP transactions.
#log-dhcp
# Include a another lot of configuration options. # Include a another lot of configuration options.
#conf-file=/etc/dnsmasq.more.conf #conf-file=/etc/dnsmasq.more.conf
#conf-dir=/etc/dnsmasq.d #conf-dir=/etc/dnsmasq.d
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -73,8 +73,8 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len, ...@@ -73,8 +73,8 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
/* Only know how to do ethernet on *BSD */ /* Only know how to do ethernet on *BSD */
if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN) if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN)
{ {
syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"), my_syslog(LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
mess->htype, ifr->ifr_name); mess->htype, ifr->ifr_name);
return; return;
} }
......
...@@ -691,7 +691,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -691,7 +691,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
if (!f) if (!f)
{ {
syslog(LOG_ERR, _("failed to load names from %s: %m"), filename); my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
return 0; return 0;
} }
...@@ -725,7 +725,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -725,7 +725,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
#endif #endif
else else
{ {
syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno); my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
continue; continue;
} }
...@@ -749,10 +749,11 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -749,10 +749,11 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
while ((token = strtok(NULL, " \t\n\r")) && (*token != '#')) while ((token = strtok(NULL, " \t\n\r")) && (*token != '#'))
{ {
struct crec *cache; struct crec *cache;
int fqdn = !!strchr(token, '.');
if (canonicalise(token)) if (canonicalise(token))
{ {
/* If set, add a version of the name with a default domain appended */ /* If set, add a version of the name with a default domain appended */
if ((opts & OPT_EXPAND) && domain_suffix && !strchr(token, '.') && if ((opts & OPT_EXPAND) && domain_suffix && !fqdn &&
(cache = malloc(sizeof(struct crec) + (cache = malloc(sizeof(struct crec) +
strlen(token)+2+strlen(domain_suffix)-SMALLDNAME))) strlen(token)+2+strlen(domain_suffix)-SMALLDNAME)))
{ {
...@@ -771,14 +772,14 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -771,14 +772,14 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
} }
} }
else else
syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno); my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
} }
} }
fclose(f); fclose(f);
rehash(name_count); rehash(name_count);
syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count); my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
return name_count; return name_count;
} }
...@@ -816,7 +817,7 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a ...@@ -816,7 +817,7 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a
if ((opts & OPT_NO_HOSTS) && !addn_hosts) if ((opts & OPT_NO_HOSTS) && !addn_hosts)
{ {
if (cache_size > 0) if (cache_size > 0)
syslog(LOG_INFO, _("cleared cache")); my_syslog(LOG_INFO, _("cleared cache"));
return; return;
} }
...@@ -862,11 +863,11 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, ...@@ -862,11 +863,11 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr) if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr)
{ {
strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4)); strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4));
syslog(LOG_WARNING, my_syslog(LOG_WARNING,
_("not giving name %s to the DHCP lease of %s because " _("not giving name %s to the DHCP lease of %s because "
"the name exists in %s with address %s"), "the name exists in %s with address %s"),
host_name, inet_ntoa(*host_address), host_name, inet_ntoa(*host_address),
record_source(daemon->addn_hosts, crec->uid), daemon->namebuff); record_source(daemon->addn_hosts, crec->uid), daemon->namebuff);
} }
return; return;
} }
...@@ -903,62 +904,63 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, ...@@ -903,62 +904,63 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
void dump_cache(struct daemon *daemon, time_t now) void dump_cache(struct daemon *daemon, time_t now)
{ {
syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."), my_syslog(LOG_INFO, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
(unsigned long)now, daemon->cachesize, cache_live_freed, cache_inserted); (unsigned long)now, daemon->cachesize, cache_live_freed, cache_inserted);
if ((daemon->options & (OPT_DEBUG | OPT_LOG)) && if ((daemon->options & (OPT_DEBUG | OPT_LOG)) &&
(addrbuff || (addrbuff = malloc(ADDRSTRLEN)))) (addrbuff || (addrbuff = malloc(ADDRSTRLEN))))
{ {
struct crec *cache ; struct crec *cache ;
int i; int i;
syslog(LOG_DEBUG, "Host Address Flags Expires"); my_syslog(LOG_DEBUG, "Host Address Flags Expires");
for (i=0; i<hash_size; i++) for (i=0; i<hash_size; i++)
for (cache = hash_table[i]; cache; cache = cache->hash_next) for (cache = hash_table[i]; cache; cache = cache->hash_next)
{ {
char *a, *p = daemon->namebuff;
p += sprintf(p, "%-40.40s ", cache_get_name(cache));
if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD)) if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD))
addrbuff[0] = 0; a = "";
else if (cache->flags & F_CNAME) else if (cache->flags & F_CNAME)
{ {
addrbuff[0] = 0; a = "";
addrbuff[ADDRSTRLEN-1] = 0;
if (!is_outdated_cname_pointer(cache)) if (!is_outdated_cname_pointer(cache))
strncpy(addrbuff, cache_get_name(cache->addr.cname.cache), ADDRSTRLEN); a = cache_get_name(cache->addr.cname.cache);
} }
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if (cache->flags & F_IPV4) else
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN); {
else if (cache->flags & F_IPV6) a = addrbuff;
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN); if (cache->flags & F_IPV4)
inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
else if (cache->flags & F_IPV6)
inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
}
#else #else
else else
strcpy(addrbuff, inet_ntoa(cache->addr.addr.addr.addr4)); a = inet_ntoa(cache->addr.addr.addr.addr4);
#endif
syslog(LOG_DEBUG,
#ifdef HAVE_BROKEN_RTC
"%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %lu",
#else
"%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %s",
#endif #endif
cache_get_name(cache), addrbuff, p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s%s ", a,
cache->flags & F_IPV4 ? "4" : "", cache->flags & F_IPV4 ? "4" : "",
cache->flags & F_IPV6 ? "6" : "", cache->flags & F_IPV6 ? "6" : "",
cache->flags & F_CNAME ? "C" : "", cache->flags & F_CNAME ? "C" : "",
cache->flags & F_FORWARD ? "F" : " ", cache->flags & F_FORWARD ? "F" : " ",
cache->flags & F_REVERSE ? "R" : " ", cache->flags & F_REVERSE ? "R" : " ",
cache->flags & F_IMMORTAL ? "I" : " ", cache->flags & F_IMMORTAL ? "I" : " ",
cache->flags & F_DHCP ? "D" : " ", cache->flags & F_DHCP ? "D" : " ",
cache->flags & F_NEG ? "N" : " ", cache->flags & F_NEG ? "N" : " ",
cache->flags & F_NXDOMAIN ? "X" : " ", cache->flags & F_NXDOMAIN ? "X" : " ",
cache->flags & F_HOSTS ? "H" : " ", cache->flags & F_HOSTS ? "H" : " ");
#ifdef HAVE_BROKEN_RTC #ifdef HAVE_BROKEN_RTC
cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now) p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
#else #else
cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)) p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
/* ctime includes trailing \n - eat it */
*(p-1) = 0;
#endif #endif
); my_syslog(LOG_DEBUG, daemon->namebuff);
} }
} }
} }
static char *record_source(struct hostsfile *addn_hosts, int index) static char *record_source(struct hostsfile *addn_hosts, int index)
...@@ -1063,8 +1065,8 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr, ...@@ -1063,8 +1065,8 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr,
name = "."; name = ".";
if ((flags & F_FORWARD) | (flags & F_NEG)) if ((flags & F_FORWARD) | (flags & F_NEG))
syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff); my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff);
else if (flags & F_REVERSE) else if (flags & F_REVERSE)
syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name); my_syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name);
} }
/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley /* dnsmasq is Copyright (c) 2000-2007 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
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
GNU General Public License for more details. GNU General Public License for more details.
*/ */
#define VERSION "2.38" #define VERSION "2.39"
#define FTABSIZ 150 /* max number of outstanding requests (default) */ #define FTABSIZ 150 /* max number of outstanding requests (default) */
#define MAX_PROCS 20 /* max no children for TCP requests */ #define MAX_PROCS 20 /* max no children for TCP requests */
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#define DHCP_CLIENT_PORT 68 #define DHCP_CLIENT_PORT 68
#define TFTP_PORT 69 #define TFTP_PORT 69
#define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */ #define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
#define LOG_MAX 5 /* log-queue length */
/* DBUS interface specifics */ /* DBUS interface specifics */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq" #define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
......
...@@ -109,7 +109,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message) ...@@ -109,7 +109,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
} }
#ifndef HAVE_IPV6 #ifndef HAVE_IPV6
syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support")); my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support"));
#else #else
if (i == sizeof(struct in6_addr)-1) if (i == sizeof(struct in6_addr)-1)
{ {
...@@ -208,6 +208,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message) ...@@ -208,6 +208,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
tmp = serv->next; tmp = serv->next;
if (serv->flags & SERV_MARK) if (serv->flags & SERV_MARK)
{ {
server_gone(daemon, serv);
*up = serv->next; *up = serv->next;
free(serv); free(serv);
} }
...@@ -235,7 +236,7 @@ DBusHandlerResult message_handler(DBusConnection *connection, ...@@ -235,7 +236,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
} }
else if (strcmp(method, "SetServers") == 0) else if (strcmp(method, "SetServers") == 0)
{ {
syslog(LOG_INFO, _("setting upstream servers from DBus")); my_syslog(LOG_INFO, _("setting upstream servers from DBus"));
dbus_read_servers(daemon, message); dbus_read_servers(daemon, message);
check_servers(daemon); check_servers(daemon);
} }
......
...@@ -216,7 +216,7 @@ void dhcp_packet(struct daemon *daemon, time_t now) ...@@ -216,7 +216,7 @@ void dhcp_packet(struct daemon *daemon, time_t now)
{ {
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1) if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1)
{ {
syslog(LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name); my_syslog(LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
return; return;
} }
else else
...@@ -347,8 +347,8 @@ static int complete_context(struct daemon *daemon, struct in_addr local, int if_ ...@@ -347,8 +347,8 @@ static int complete_context(struct daemon *daemon, struct in_addr local, int if_
{ {
strcpy(daemon->dhcp_buff, inet_ntoa(context->start)); strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
strcpy(daemon->dhcp_buff2, inet_ntoa(context->end)); strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
syslog(LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"), my_syslog(LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask)); daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
} }
context->netmask = netmask; context->netmask = netmask;
} }
...@@ -664,7 +664,7 @@ void dhcp_read_ethers(struct daemon *daemon) ...@@ -664,7 +664,7 @@ void dhcp_read_ethers(struct daemon *daemon)
if (!f) if (!f)
{ {
syslog(LOG_ERR, _("failed to read %s:%m"), ETHERSFILE); my_syslog(LOG_ERR, _("failed to read %s:%s"), ETHERSFILE, strerror(errno));
return; return;
} }
...@@ -699,7 +699,7 @@ void dhcp_read_ethers(struct daemon *daemon) ...@@ -699,7 +699,7 @@ void dhcp_read_ethers(struct daemon *daemon)
*ip = 0; *ip = 0;
if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN) if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
{ {
syslog(LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno); my_syslog(LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
continue; continue;
} }
...@@ -712,7 +712,7 @@ void dhcp_read_ethers(struct daemon *daemon) ...@@ -712,7 +712,7 @@ void dhcp_read_ethers(struct daemon *daemon)
{ {
if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1) if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
{ {
syslog(LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno); my_syslog(LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
continue; continue;
} }
...@@ -726,7 +726,7 @@ void dhcp_read_ethers(struct daemon *daemon) ...@@ -726,7 +726,7 @@ void dhcp_read_ethers(struct daemon *daemon)
{ {
if (!canonicalise(ip)) if (!canonicalise(ip))
{ {
syslog(LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno); my_syslog(LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
continue; continue;
} }
...@@ -780,7 +780,7 @@ void dhcp_read_ethers(struct daemon *daemon) ...@@ -780,7 +780,7 @@ void dhcp_read_ethers(struct daemon *daemon)
fclose(f); fclose(f);
syslog(LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count); my_syslog(LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
} }
void dhcp_update_configs(struct dhcp_config *configs) void dhcp_update_configs(struct dhcp_config *configs)
...@@ -806,8 +806,8 @@ void dhcp_update_configs(struct dhcp_config *configs) ...@@ -806,8 +806,8 @@ void dhcp_update_configs(struct dhcp_config *configs)
(crec->flags & F_HOSTS)) (crec->flags & F_HOSTS))
{ {
if (config_find_by_address(configs, crec->addr.addr.addr.addr4)) if (config_find_by_address(configs, crec->addr.addr.addr.addr4))
syslog(LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"), my_syslog(LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
inet_ntoa(crec->addr.addr.addr.addr4), config->hostname); inet_ntoa(crec->addr.addr.addr.addr4), config->hostname);
else else
{ {
config->addr = crec->addr.addr.addr.addr4; config->addr = crec->addr.addr.addr.addr4;
...@@ -842,7 +842,7 @@ char *strip_hostname(struct daemon *daemon, char *hostname) ...@@ -842,7 +842,7 @@ char *strip_hostname(struct daemon *daemon, char *hostname)
{ {
if (!daemon->domain_suffix || !hostname_isequal(dot+1, daemon->domain_suffix)) if (!daemon->domain_suffix || !hostname_isequal(dot+1, daemon->domain_suffix))
{ {
syslog(LOG_WARNING, _("Ignoring DHCP host name %s because it has an illegal domain part"), hostname); my_syslog(LOG_WARNING, _("Ignoring DHCP host name %s because it has an illegal domain part"), hostname);
hostname = NULL; hostname = NULL;
} }
else else
......
...@@ -59,7 +59,7 @@ int main (int argc, char **argv) ...@@ -59,7 +59,7 @@ int main (int argc, char **argv)
time_t now, last = 0; time_t now, last = 0;
struct sigaction sigact; struct sigaction sigact;
struct iname *if_tmp; struct iname *if_tmp;
int piperead, pipefd[2]; int piperead, pipefd[2], log_fd;
unsigned char sig; unsigned char sig;
#ifndef NO_GETTEXT #ifndef NO_GETTEXT
...@@ -84,6 +84,7 @@ int main (int argc, char **argv) ...@@ -84,6 +84,7 @@ int main (int argc, char **argv)
sigaction(SIGPIPE, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL);
daemon = read_opts(argc, argv, compile_opts); daemon = read_opts(argc, argv, compile_opts);
log_fd = log_start(daemon);
if (daemon->edns_pktsz < PACKETSZ) if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ; daemon->edns_pktsz = PACKETSZ;
...@@ -250,7 +251,7 @@ int main (int argc, char **argv) ...@@ -250,7 +251,7 @@ int main (int argc, char **argv)
#endif #endif
for (i=0; i<64; i++) for (i=0; i<64; i++)
{ {
if (i == piperead || i == pipewrite) if (i == piperead || i == pipewrite || i == log_fd)
continue; continue;
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
...@@ -279,8 +280,8 @@ int main (int argc, char **argv) ...@@ -279,8 +280,8 @@ int main (int argc, char **argv)
} }
/* if we are to run scripts, we need to fork a helper before dropping root. */ /* if we are to run scripts, we need to fork a helper before dropping root. */
daemon->helperfd = create_helper(daemon); daemon->helperfd = create_helper(daemon, log_fd);
if (!(daemon->options & OPT_DEBUG)) if (!(daemon->options & OPT_DEBUG))
{ {
/* UID changing, etc */ /* UID changing, etc */
...@@ -335,47 +336,48 @@ int main (int argc, char **argv) ...@@ -335,47 +336,48 @@ int main (int argc, char **argv)
} }
} }
log_start(daemon);
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
if (daemon->options & OPT_DEBUG) if (daemon->options & OPT_DEBUG)
prctl(PR_SET_DUMPABLE, 1); prctl(PR_SET_DUMPABLE, 1);
#endif #endif
if (daemon->cachesize != 0) if (daemon->cachesize != 0)
syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize); my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
else else
syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION); my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
syslog(LOG_INFO, _("compile time options: %s"), compile_opts); my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
#ifdef HAVE_DBUS #ifdef HAVE_DBUS
if (daemon->options & OPT_DBUS) if (daemon->options & OPT_DBUS)
{ {
if (daemon->dbus) if (daemon->dbus)
syslog(LOG_INFO, _("DBus support enabled: connected to system bus")); my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
else else
syslog(LOG_INFO, _("DBus support enabled: bus connection pending")); my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
} }
#endif #endif
if (bind_fallback) if (bind_fallback)
syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations")); my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
if (!(daemon->options & OPT_NOWILD)) if (!(daemon->options & 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)
if (if_tmp->name && !if_tmp->used) if (if_tmp->name && !if_tmp->used)
syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name); my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
if (daemon->options & OPT_NO_RESOLV) if (daemon->options & OPT_NO_RESOLV)
{ {
if (daemon->resolv_files && !daemon->resolv_files->is_default) if (daemon->resolv_files && !daemon->resolv_files->is_default)
syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set")); my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
daemon->resolv_files = NULL; daemon->resolv_files = NULL;
if (!daemon->servers) if (!daemon->servers)
syslog(LOG_WARNING, _("warning: no upstream servers configured")); my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
} }
if (daemon->max_logs != 0)
my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
if (daemon->dhcp) if (daemon->dhcp)
{ {
struct dhcp_context *dhcp_tmp; struct dhcp_context *dhcp_tmp;
...@@ -384,11 +386,11 @@ int main (int argc, char **argv) ...@@ -384,11 +386,11 @@ int main (int argc, char **argv)
{ {
prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time); prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start)); strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
syslog(LOG_INFO, my_syslog(LOG_INFO,
(dhcp_tmp->flags & CONTEXT_STATIC) ? (dhcp_tmp->flags & CONTEXT_STATIC) ?
_("DHCP, static leases only on %.0s%s, lease time %s") : _("DHCP, static leases only on %.0s%s, lease time %s") :
_("DHCP, IP range %s -- %s, lease time %s"), _("DHCP, IP range %s -- %s, lease time %s"),
daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2); daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
} }
} }
...@@ -402,13 +404,13 @@ int main (int argc, char **argv) ...@@ -402,13 +404,13 @@ int main (int argc, char **argv)
max_fd = FD_SETSIZE; max_fd = FD_SETSIZE;
#endif #endif
syslog(LOG_INFO, "TFTP %s%s %s", my_syslog(LOG_INFO, "TFTP %s%s %s",
daemon->tftp_prefix ? _("root is ") : _("enabled"), daemon->tftp_prefix ? _("root is ") : _("enabled"),
daemon->tftp_prefix ? daemon->tftp_prefix: "", daemon->tftp_prefix ? daemon->tftp_prefix: "",
daemon->options & OPT_TFTP_SECURE ? _("secure mode") : ""); daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
/* This is a guess, it assumes that for small limits, /* This is a guess, it assumes that for small limits,
disjoint files might be servered, but for large limits, disjoint files might be served, but for large limits,
a single file will be sent to may clients (the file only needs a single file will be sent to may clients (the file only needs
one fd). */ one fd). */
...@@ -424,9 +426,9 @@ int main (int argc, char **argv) ...@@ -424,9 +426,9 @@ int main (int argc, char **argv)
if (daemon->tftp_max > max_fd) if (daemon->tftp_max > max_fd)
{ {
daemon->tftp_max = max_fd; daemon->tftp_max = max_fd;
syslog(LOG_WARNING, my_syslog(LOG_WARNING,
_("restricting maximum simultaneous TFTP transfers to %d"), _("restricting maximum simultaneous TFTP transfers to %d"),
daemon->tftp_max); daemon->tftp_max);
} }
} }
#endif #endif
...@@ -434,11 +436,9 @@ int main (int argc, char **argv) ...@@ -434,11 +436,9 @@ int main (int argc, char **argv)
if (!(daemon->options & OPT_DEBUG) && (getuid() == 0 || geteuid() == 0)) if (!(daemon->options & OPT_DEBUG) && (getuid() == 0 || geteuid() == 0))
{ {
if (bad_capabilities) if (bad_capabilities)
{ my_syslog(LOG_WARNING, _("warning: setting capabilities failed: %s"), strerror(bad_capabilities));
errno = bad_capabilities;
syslog(LOG_WARNING, _("warning: setting capabilities failed: %m")); my_syslog(LOG_WARNING, _("running as root"));
}
syslog(LOG_WARNING, _("running as root"));
} }
check_servers(daemon); check_servers(daemon);
...@@ -498,7 +498,11 @@ int main (int argc, char **argv) ...@@ -498,7 +498,11 @@ int main (int argc, char **argv)
FD_SET(daemon->helperfd, &wset); FD_SET(daemon->helperfd, &wset);
bump_maxfd(daemon->helperfd, &maxfd); bump_maxfd(daemon->helperfd, &maxfd);
} }
/* must do this just before select(), when we know no
more calls to my_syslog() can occur */
set_log_writer(&wset, &maxfd);
if (select(maxfd+1, &rset, &wset, &eset, tp) < 0) if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
{ {
/* otherwise undefined after error */ /* otherwise undefined after error */
...@@ -507,6 +511,8 @@ int main (int argc, char **argv) ...@@ -507,6 +511,8 @@ int main (int argc, char **argv)
now = dnsmasq_time(); now = dnsmasq_time();
check_log_writer(&wset);
/* Check for changes to resolv files once per second max. */ /* Check for changes to resolv files once per second max. */
/* Don't go silent for long periods if the clock goes backwards. */ /* Don't go silent for long periods if the clock goes backwards. */
if (last == 0 || difftime(now, last) > 1.0 || difftime(now, last) < -1.0) if (last == 0 || difftime(now, last) > 1.0 || difftime(now, last) < -1.0)
...@@ -530,7 +536,7 @@ int main (int argc, char **argv) ...@@ -530,7 +536,7 @@ int main (int argc, char **argv)
if (stat(res->name, &statbuf) == -1) if (stat(res->name, &statbuf) == -1)
{ {
if (!res->logged) if (!res->logged)
syslog(LOG_WARNING, _("failed to access %s: %m"), res->name); my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
res->logged = 1; res->logged = 1;
} }
else else
...@@ -552,7 +558,7 @@ int main (int argc, char **argv) ...@@ -552,7 +558,7 @@ int main (int argc, char **argv)
static int warned = 0; static int warned = 0;
if (reload_servers(latest->name, daemon)) if (reload_servers(latest->name, daemon))
{ {
syslog(LOG_INFO, _("reading %s"), latest->name); my_syslog(LOG_INFO, _("reading %s"), latest->name);
warned = 0; warned = 0;
check_servers(daemon); check_servers(daemon);
if (daemon->options & OPT_RELOAD) if (daemon->options & OPT_RELOAD)
...@@ -563,7 +569,7 @@ int main (int argc, char **argv) ...@@ -563,7 +569,7 @@ int main (int argc, char **argv)
latest->mtime = 0; latest->mtime = 0;
if (!warned) if (!warned)
{ {
syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name); my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
warned = 1; warned = 1;
} }
} }
...@@ -622,7 +628,7 @@ int main (int argc, char **argv) ...@@ -622,7 +628,7 @@ int main (int argc, char **argv)
if (daemon->lease_stream) if (daemon->lease_stream)
fclose(daemon->lease_stream); fclose(daemon->lease_stream);
syslog(LOG_INFO, _("exiting on receipt of SIGTERM")); my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
exit(0); exit(0);
} }
...@@ -657,9 +663,9 @@ int main (int argc, char **argv) ...@@ -657,9 +663,9 @@ int main (int argc, char **argv)
{ {
char *err; char *err;
if ((err = dbus_init(daemon))) if ((err = dbus_init(daemon)))
syslog(LOG_WARNING, _("DBus error: %s"), err); my_syslog(LOG_WARNING, _("DBus error: %s"), err);
if (daemon->dbus) if (daemon->dbus)
syslog(LOG_INFO, _("connected to system DBus")); my_syslog(LOG_INFO, _("connected to system DBus"));
} }
check_dbus_listeners(daemon, &rset, &wset, &eset); check_dbus_listeners(daemon, &rset, &wset, &eset);
#endif #endif
...@@ -969,7 +975,7 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr) ...@@ -969,7 +975,7 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr)
difftime(now, start) < (float)PING_WAIT;) difftime(now, start) < (float)PING_WAIT;)
{ {
struct timeval tv; struct timeval tv;
fd_set rset; fd_set rset, wset;
struct sockaddr_in faddr; struct sockaddr_in faddr;
int maxfd = fd; int maxfd = fd;
socklen_t len = sizeof(faddr); socklen_t len = sizeof(faddr);
...@@ -978,13 +984,20 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr) ...@@ -978,13 +984,20 @@ int icmp_ping(struct daemon *daemon, struct in_addr addr)
tv.tv_sec = 0; tv.tv_sec = 0;
FD_ZERO(&rset); FD_ZERO(&rset);
FD_ZERO(&wset);
FD_SET(fd, &rset); FD_SET(fd, &rset);
set_dns_listeners(daemon, now, &rset, &maxfd); set_dns_listeners(daemon, now, &rset, &maxfd);
set_log_writer(&wset, &maxfd);
if (select(maxfd+1, &rset, NULL, NULL, &tv) < 0)
FD_ZERO(&rset); if (select(maxfd+1, &rset, &wset, NULL, &tv) < 0)
{
FD_ZERO(&rset);
FD_ZERO(&wset);
}
now = dnsmasq_time(); now = dnsmasq_time();
check_log_writer(&wset);
check_dns_listeners(daemon, &rset, now); check_dns_listeners(daemon, &rset, now);
#ifdef HAVE_TFTP #ifdef HAVE_TFTP
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <sys/select.h> #include <sys/select.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/un.h>
#include <limits.h> #include <limits.h>
#include <net/if.h> #include <net/if.h>
#include <unistd.h> #include <unistd.h>
...@@ -115,6 +116,7 @@ extern int capset(cap_user_header_t header, cap_user_data_t data); ...@@ -115,6 +116,7 @@ extern int capset(cap_user_header_t header, cap_user_data_t data);
#define OPT_TFTP (1<<25) #define OPT_TFTP (1<<25)
#define OPT_TFTP_SECURE (1<<26) #define OPT_TFTP_SECURE (1<<26)
#define OPT_TFTP_NOBLOCK (1<<27) #define OPT_TFTP_NOBLOCK (1<<27)
#define OPT_LOG_OPTS (1<<28)
struct all_addr { struct all_addr {
union { union {
...@@ -154,6 +156,12 @@ struct ptr_record { ...@@ -154,6 +156,12 @@ struct ptr_record {
struct ptr_record *next; struct ptr_record *next;
}; };
struct interface_name {
char *name; /* domain name */
char *intr; /* interface name */
struct interface_name *next;
};
union bigname { union bigname {
char name[MAXDNAME]; char name[MAXDNAME];
union bigname *next; /* freelist */ union bigname *next; /* freelist */
...@@ -377,8 +385,15 @@ struct dhcp_boot { ...@@ -377,8 +385,15 @@ struct dhcp_boot {
struct dhcp_boot *next; struct dhcp_boot *next;
}; };
#define MATCH_VENDOR 1
#define MATCH_USER 2
#define MATCH_CIRCUIT 3
#define MATCH_REMOTE 4
#define MATCH_SUBSCRIBER 5
/* vendorclass, userclass, remote-id or cicuit-id */
struct dhcp_vendor { struct dhcp_vendor {
int len, is_vendor; int len, match_type;
char *data; char *data;
struct dhcp_netid netid; struct dhcp_netid netid;
struct dhcp_vendor *next; struct dhcp_vendor *next;
...@@ -461,6 +476,7 @@ struct daemon { ...@@ -461,6 +476,7 @@ struct daemon {
struct mx_srv_record *mxnames; struct mx_srv_record *mxnames;
struct txt_record *txt; struct txt_record *txt;
struct ptr_record *ptr; struct ptr_record *ptr;
struct interface_name *int_names;
char *mxtarget; char *mxtarget;
char *lease_file; char *lease_file;
char *username, *groupname; char *username, *groupname;
...@@ -471,6 +487,8 @@ struct daemon { ...@@ -471,6 +487,8 @@ struct daemon {
struct bogus_addr *bogus_addr; struct bogus_addr *bogus_addr;
struct server *servers; struct server *servers;
int log_fac; /* log facility */ int log_fac; /* log facility */
char *log_file; /* optional log file */
int max_logs; /* queue limit */
int cachesize, ftabsize; int cachesize, ftabsize;
int port, query_port; int port, query_port;
unsigned long local_ttl; unsigned long local_ttl;
...@@ -569,8 +587,6 @@ unsigned short rand16(void); ...@@ -569,8 +587,6 @@ unsigned short rand16(void);
int legal_char(char c); int legal_char(char c);
int canonicalise(char *s); int canonicalise(char *s);
unsigned char *do_rfc1035_name(unsigned char *p, char *sval); unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
void die(char *message, char *arg1);
void complain(char *message, int lineno, char *file);
void *safe_malloc(size_t size); void *safe_malloc(size_t size);
int sa_len(union mysockaddr *addr); int sa_len(union mysockaddr *addr);
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2); int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
...@@ -587,11 +603,18 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len, ...@@ -587,11 +603,18 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len,
int expand_buf(struct iovec *iov, size_t size); int expand_buf(struct iovec *iov, size_t size);
char *print_mac(struct daemon *daemon, unsigned char *mac, int len); char *print_mac(struct daemon *daemon, unsigned char *mac, int len);
void bump_maxfd(int fd, int *max); void bump_maxfd(int fd, int *max);
void log_start(struct daemon *daemon);
int read_write(int fd, unsigned char *packet, int size, int rw); int read_write(int fd, unsigned char *packet, int size, int rw);
/* log.c */
void die(char *message, char *arg1);
int log_start(struct daemon *daemon);
void my_syslog(int priority, const char *format, ...);
void set_log_writer(fd_set *set, int *maxfdp);
void check_log_writer(fd_set *set);
/* option.c */ /* option.c */
struct daemon *read_opts (int argc, char **argv, char *compile_opts); struct daemon *read_opts (int argc, char **argv, char *compile_opts);
char *option_string(unsigned char opt);
/* forward.c */ /* forward.c */
void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now); void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now);
...@@ -611,6 +634,7 @@ struct listener *create_bound_listeners(struct daemon *daemon); ...@@ -611,6 +634,7 @@ struct listener *create_bound_listeners(struct daemon *daemon);
int iface_check(struct daemon *daemon, int family, struct all_addr *addr, int iface_check(struct daemon *daemon, int family, struct all_addr *addr,
struct ifreq *ifr, int *indexp); struct ifreq *ifr, int *indexp);
int fix_fd(int fd); int fix_fd(int fd);
struct in_addr get_ifaddr(struct daemon* daemon, char *intr);
/* dhcp.c */ /* dhcp.c */
void dhcp_init(struct daemon *daemon); void dhcp_init(struct daemon *daemon);
...@@ -690,7 +714,7 @@ void set_dbus_listeners(struct daemon *daemon, int *maxfdp, ...@@ -690,7 +714,7 @@ void set_dbus_listeners(struct daemon *daemon, int *maxfdp,
#endif #endif
/* helper.c */ /* helper.c */
int create_helper(struct daemon *daemon); int create_helper(struct daemon *daemon, int log_fd);
void helper_write(struct daemon *daemon); void helper_write(struct daemon *daemon);
void queue_script(struct daemon *daemon, int action, void queue_script(struct daemon *daemon, int action,
struct dhcp_lease *lease, char *hostname); struct dhcp_lease *lease, char *hostname);
......
...@@ -373,7 +373,7 @@ static size_t process_reply(struct daemon *daemon, HEADER *header, time_t now, ...@@ -373,7 +373,7 @@ static size_t process_reply(struct daemon *daemon, HEADER *header, time_t now,
server && !(server->flags & SERV_WARNED_RECURSIVE)) server && !(server->flags & SERV_WARNED_RECURSIVE))
{ {
prettyprint_addr(&server->addr, daemon->namebuff); prettyprint_addr(&server->addr, daemon->namebuff);
syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff); my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
if (!(daemon->options & OPT_LOG)) if (!(daemon->options & OPT_LOG))
server->flags |= SERV_WARNED_RECURSIVE; server->flags |= SERV_WARNED_RECURSIVE;
} }
......
...@@ -40,7 +40,7 @@ struct script_data ...@@ -40,7 +40,7 @@ struct script_data
static struct script_data *buf; static struct script_data *buf;
static size_t bytes_in_buf, buf_size; static size_t bytes_in_buf, buf_size;
int create_helper(struct daemon *daemon) int create_helper(struct daemon *daemon, int log_fd)
{ {
pid_t pid; pid_t pid;
int i, pipefd[2]; int i, pipefd[2];
...@@ -72,11 +72,8 @@ int create_helper(struct daemon *daemon) ...@@ -72,11 +72,8 @@ int create_helper(struct daemon *daemon)
/* close all the sockets etc, we don't need them here */ /* close all the sockets etc, we don't need them here */
for (i = 0; i < 64; i++) for (i = 0; i < 64; i++)
if (i != STDOUT_FILENO && i != STDERR_FILENO && if (i != STDOUT_FILENO && i != STDERR_FILENO &&
i != STDIN_FILENO && i != pipefd[0]) i != STDIN_FILENO && i != pipefd[0] && i != log_fd)
close(i); close(i);
/* we open our own log connection. */
log_start(daemon);
/* don't give our end of the pipe to our children */ /* don't give our end of the pipe to our children */
if ((i = fcntl(pipefd[0], F_GETFD)) != -1) if ((i = fcntl(pipefd[0], F_GETFD)) != -1)
...@@ -142,9 +139,9 @@ int create_helper(struct daemon *daemon) ...@@ -142,9 +139,9 @@ int create_helper(struct daemon *daemon)
int status; int status;
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
if (WIFSIGNALED(status)) if (WIFSIGNALED(status))
syslog(LOG_WARNING, _("child process killed by signal %d"), WTERMSIG(status)); my_syslog(LOG_WARNING, _("child process killed by signal %d"), WTERMSIG(status));
else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
syslog(LOG_WARNING, _("child process exited with status %d"), WEXITSTATUS(status)); my_syslog(LOG_WARNING, _("child process exited with status %d"), WEXITSTATUS(status));
continue; continue;
} }
...@@ -213,8 +210,8 @@ int create_helper(struct daemon *daemon) ...@@ -213,8 +210,8 @@ int create_helper(struct daemon *daemon)
action_str, daemon->dhcp_buff, inet_ntoa(data.addr), hostname, (char*)NULL); action_str, daemon->dhcp_buff, inet_ntoa(data.addr), hostname, (char*)NULL);
/* log socket should still be open, right? */ /* log socket should still be open, right? */
syslog(LOG_ERR, _("failed to execute %s: %m"), my_syslog(LOG_ERR, _("failed to execute %s: %s"),
daemon->lease_change_command); daemon->lease_change_command, strerror(errno));
_exit(0); _exit(0);
} }
} }
......
...@@ -70,7 +70,7 @@ void load_dhcp(struct daemon *daemon, time_t now) ...@@ -70,7 +70,7 @@ void load_dhcp(struct daemon *daemon, time_t now)
if (stat(daemon->lease_file, &statbuf) == -1) if (stat(daemon->lease_file, &statbuf) == -1)
{ {
if (!logged_lease) if (!logged_lease)
syslog(LOG_WARNING, _("failed to access %s: %m"), daemon->lease_file); my_syslog(LOG_WARNING, _("failed to access %s: %s"), daemon->lease_file, strerror(errno));
logged_lease = 1; logged_lease = 1;
return; return;
} }
...@@ -86,11 +86,11 @@ void load_dhcp(struct daemon *daemon, time_t now) ...@@ -86,11 +86,11 @@ void load_dhcp(struct daemon *daemon, time_t now)
if (!(fp = fopen (daemon->lease_file, "r"))) if (!(fp = fopen (daemon->lease_file, "r")))
{ {
syslog (LOG_ERR, _("failed to load %s: %m"), daemon->lease_file); my_syslog (LOG_ERR, _("failed to load %s: %s"), daemon->lease_file, strerror(errno));
return; return;
} }
syslog (LOG_INFO, _("reading %s"), daemon->lease_file); my_syslog (LOG_INFO, _("reading %s"), daemon->lease_file);
while ((next_token(token, MAXTOK, fp))) while ((next_token(token, MAXTOK, fp)))
{ {
...@@ -112,7 +112,7 @@ void load_dhcp(struct daemon *daemon, time_t now) ...@@ -112,7 +112,7 @@ void load_dhcp(struct daemon *daemon, time_t now)
if (!canonicalise(hostname)) if (!canonicalise(hostname))
{ {
*hostname = 0; *hostname = 0;
syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file); my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
} }
} }
else if ((strcmp(token, "ends") == 0) || else if ((strcmp(token, "ends") == 0) ||
...@@ -173,9 +173,9 @@ void load_dhcp(struct daemon *daemon, time_t now) ...@@ -173,9 +173,9 @@ void load_dhcp(struct daemon *daemon, time_t now)
{ {
if (!daemon->domain_suffix || hostname_isequal(dot+1, daemon->domain_suffix)) if (!daemon->domain_suffix || hostname_isequal(dot+1, daemon->domain_suffix))
{ {
syslog(LOG_WARNING, my_syslog(LOG_WARNING,
_("Ignoring DHCP lease for %s because it has an illegal domain part"), _("Ignoring DHCP lease for %s because it has an illegal domain part"),
hostname); hostname);
continue; continue;
} }
*dot = 0; *dot = 0;
......
...@@ -214,9 +214,9 @@ void lease_update_file(struct daemon *daemon, time_t now) ...@@ -214,9 +214,9 @@ void lease_update_file(struct daemon *daemon, time_t now)
if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0) if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
next_event = LEASE_RETRY + now; next_event = LEASE_RETRY + now;
syslog(LOG_ERR, _("failed to write %s: %s (retry in %us)"), my_syslog(LOG_ERR, _("failed to write %s: %s (retry in %us)"),
daemon->lease_file, strerror(err), daemon->lease_file, strerror(err),
(unsigned int)difftime(next_event, now)); (unsigned int)difftime(next_event, now));
} }
if (next_event != 0) if (next_event != 0)
......
This diff is collapsed.
...@@ -229,7 +229,7 @@ static void nl_err(struct nlmsghdr *h) ...@@ -229,7 +229,7 @@ static void nl_err(struct nlmsghdr *h)
{ {
struct nlmsgerr *err = NLMSG_DATA(h); struct nlmsgerr *err = NLMSG_DATA(h);
if (err->error != 0) if (err->error != 0)
syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error))); my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
} }
/* We arrange to receive netlink multicast messages whenever the network route is added. /* We arrange to receive netlink multicast messages whenever the network route is added.
......
...@@ -38,7 +38,7 @@ int iface_check(struct daemon *daemon, int family, struct all_addr *addr, ...@@ -38,7 +38,7 @@ int iface_check(struct daemon *daemon, int family, struct all_addr *addr,
if (!(newindex = if_nametoindex(bridge->iface))) if (!(newindex = if_nametoindex(bridge->iface)))
{ {
syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name); my_syslog(LOG_WARNING, _("unknown interface %s in bridge-interface"), ifr->ifr_name);
return 0; return 0;
} }
else else
...@@ -492,7 +492,7 @@ void check_servers(struct daemon *daemon) ...@@ -492,7 +492,7 @@ void check_servers(struct daemon *daemon)
break; break;
if (iface) if (iface)
{ {
syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff); my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
free(new); free(new);
continue; continue;
} }
...@@ -500,8 +500,9 @@ void check_servers(struct daemon *daemon) ...@@ -500,8 +500,9 @@ void check_servers(struct daemon *daemon)
/* Do we need a socket set? */ /* Do we need a socket set? */
if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds))) if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds)))
{ {
syslog(LOG_WARNING, my_syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %m"), daemon->namebuff); _("ignoring nameserver %s - cannot make/bind socket: %s"),
daemon->namebuff, strerror(errno));
free(new); free(new);
continue; continue;
} }
...@@ -520,12 +521,12 @@ void check_servers(struct daemon *daemon) ...@@ -520,12 +521,12 @@ void check_servers(struct daemon *daemon)
s1 = _("unqualified"), s2 = _("domains"); s1 = _("unqualified"), s2 = _("domains");
if (new->flags & SERV_NO_ADDR) if (new->flags & SERV_NO_ADDR)
syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2); my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
else if (!(new->flags & SERV_LITERAL_ADDRESS)) else if (!(new->flags & SERV_LITERAL_ADDRESS))
syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2); my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
} }
else else
syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port); my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
} }
daemon->servers = ret; daemon->servers = ret;
...@@ -545,7 +546,7 @@ int reload_servers(char *fname, struct daemon *daemon) ...@@ -545,7 +546,7 @@ int reload_servers(char *fname, struct daemon *daemon)
/* buff happens to be MAXDNAME long... */ /* buff happens to be MAXDNAME long... */
if (!(f = fopen(fname, "r"))) if (!(f = fopen(fname, "r")))
{ {
syslog(LOG_ERR, _("failed to read %s: %m"), fname); my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
return 0; return 0;
} }
...@@ -644,8 +645,22 @@ int reload_servers(char *fname, struct daemon *daemon) ...@@ -644,8 +645,22 @@ int reload_servers(char *fname, struct daemon *daemon)
} }
/* Use an IPv4 listener socket for ioctling */
struct in_addr get_ifaddr(struct daemon* daemon, 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;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -106,7 +106,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now) ...@@ -106,7 +106,8 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
if (addr.sin_addr.s_addr == 0) if (addr.sin_addr.s_addr == 0)
return; return;
if (!iface_check(daemon, AF_INET, (struct all_addr *)&addr, &ifr, &if_index)) if (!iface_check(daemon, AF_INET, (struct all_addr *)&addr.sin_addr,
&ifr, &if_index))
return; return;
/* allowed interfaces are the same as for DHCP */ /* allowed interfaces are the same as for DHCP */
...@@ -179,18 +180,26 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now) ...@@ -179,18 +180,26 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
} }
} }
strcpy(daemon->namebuff, "/");
if (daemon->tftp_prefix) if (daemon->tftp_prefix)
{ {
strncpy(daemon->namebuff, daemon->tftp_prefix, MAXDNAME); if (daemon->tftp_prefix[0] == '/')
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/' && daemon->namebuff[0] = 0;
filename[0] != '/') strncat(daemon->namebuff, daemon->tftp_prefix, MAXDNAME);
if (daemon->tftp_prefix[strlen(daemon->tftp_prefix)-1] != '/')
strncat(daemon->namebuff, "/", MAXDNAME); strncat(daemon->namebuff, "/", MAXDNAME);
/* Absolute pathnames OK if they match prefix */
if (filename[0] == '/')
{
if (strstr(filename, daemon->namebuff) == filename)
daemon->namebuff[0] = 0;
else
filename++;
}
} }
else if (filename[0] != '/') else if (filename[0] == '/')
strncpy(daemon->namebuff, "/", MAXDNAME);
else
daemon->namebuff[0] = 0; daemon->namebuff[0] = 0;
strncat(daemon->namebuff, filename, MAXDNAME); strncat(daemon->namebuff, filename, MAXDNAME);
daemon->namebuff[MAXDNAME-1] = 0; daemon->namebuff[MAXDNAME-1] = 0;
...@@ -227,7 +236,7 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now) ...@@ -227,7 +236,7 @@ void tftp_request(struct listener *listen, struct daemon *daemon, time_t now)
free_transfer(transfer); free_transfer(transfer);
else else
{ {
syslog(LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr)); my_syslog(LOG_INFO, _("TFTP sent %s to %s"), daemon->namebuff, inet_ntoa(peer.sin_addr));
transfer->next = daemon->tftp_trans; transfer->next = daemon->tftp_trans;
daemon->tftp_trans = transfer; daemon->tftp_trans = transfer;
} }
...@@ -350,9 +359,9 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now) ...@@ -350,9 +359,9 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now)
*(q++) = *r; *(q++) = *r;
*q = 0; *q = 0;
} }
syslog(LOG_ERR, _("TFTP error %d %s received from %s"), my_syslog(LOG_ERR, _("TFTP error %d %s received from %s"),
(int)ntohs(mess->block), err, (int)ntohs(mess->block), err,
inet_ntoa(transfer->peer.sin_addr)); inet_ntoa(transfer->peer.sin_addr));
/* Got err, ensure we take abort */ /* Got err, ensure we take abort */
transfer->timeout = now; transfer->timeout = now;
...@@ -381,8 +390,8 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now) ...@@ -381,8 +390,8 @@ void check_tftp_listeners(struct daemon *daemon, fd_set *rset, time_t now)
/* don't complain about timeout when we're awaiting the last /* don't complain about timeout when we're awaiting the last
ACK, some clients never send it */ ACK, some clients never send it */
if (len != 0) if (len != 0)
syslog(LOG_ERR, _("TFTP failed sending %s to %s"), my_syslog(LOG_ERR, _("TFTP failed sending %s to %s"),
transfer->file->filename, inet_ntoa(transfer->peer.sin_addr)); transfer->file->filename, inet_ntoa(transfer->peer.sin_addr));
len = 0; len = 0;
} }
...@@ -441,7 +450,7 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file) ...@@ -441,7 +450,7 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
mess->err = htons(err); mess->err = htons(err);
ret += (snprintf(mess->message, 500, message, file, errstr) + 1); ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
if (err != ERR_FNF) if (err != ERR_FNF)
syslog(LOG_ERR, "TFTP %s", mess->message); my_syslog(LOG_ERR, "TFTP %s", mess->message);
return ret; return ret;
} }
......
...@@ -156,35 +156,6 @@ void *safe_malloc(size_t size) ...@@ -156,35 +156,6 @@ void *safe_malloc(size_t size)
return ret; return ret;
} }
static void log_err(char *message, char *arg1)
{
char *errmess = strerror(errno);
if (!arg1)
arg1 = errmess;
fprintf(stderr, "dnsmasq: ");
fprintf(stderr, message, arg1, errmess);
fprintf(stderr, "\n");
syslog(LOG_CRIT, message, arg1, errmess);
}
void complain(char *message, int lineno, char *file)
{
char buff[256];
sprintf(buff, _("%s at line %d of %%s"), message, lineno);
log_err(buff, file);
}
void die(char *message, char *arg1)
{
log_err(message, arg1);
syslog(LOG_CRIT, _("FAILED to start up"));
exit(1);
}
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2) int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
{ {
if (s1->sa.sa_family == s2->sa.sa_family) if (s1->sa.sa_family == s2->sa.sa_family)
...@@ -418,20 +389,6 @@ void bump_maxfd(int fd, int *max) ...@@ -418,20 +389,6 @@ void bump_maxfd(int fd, int *max)
*max = fd; *max = fd;
} }
void log_start(struct daemon *daemon)
{
if (daemon->options & OPT_DEBUG)
{
#ifdef LOG_PERROR
openlog("dnsmasq", LOG_PERROR, daemon->log_fac);
#else
openlog("dnsmasq", 0, daemon->log_fac);
#endif
}
else
openlog("dnsmasq", LOG_PID, daemon->log_fac);
}
int read_write(int fd, unsigned char *packet, int size, int rw) int read_write(int fd, unsigned char *packet, int size, int rw)
{ {
ssize_t n, done; ssize_t n, done;
......
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