Commit 5aabfc78 authored by Simon Kelley's avatar Simon Kelley

import of dnsmasq-2.40.tar.gz

parent f2621c7f
...@@ -2234,3 +2234,114 @@ release 2.39 ...@@ -2234,3 +2234,114 @@ release 2.39
to add a domain name with a dynamic IP address taken from to add a domain name with a dynamic IP address taken from
the address of a local network interface. Useful for the address of a local network interface. Useful for
networks with dynamic IPs. networks with dynamic IPs.
version 2.40
Make SIGUSR2 close-and-reopen the logfile when logging
direct to a file. Thanks to Carlos Carvalho for
suggesting this. When a logfile is created, change
its ownership to the user dnsmasq will run as, don't
leave it owned by root.
Set a special tag, "known" for hosts which are matched by
a dhcp-host or /etc/ethers line. This is especially
useful to be able to do --dhcp-ignore=#known, like ISCs
"deny unknown-clients".
Explicitly set a umask before creating the leases file,
rather than relying on whatever we inherited. The
permissions are set to 644.
Fix handling of fully-qualified names in --dhcp-host
directives and in /etc/ethers. These are now rejected
if the domain doesn't match that given by --domain,
and used correctly otherwise. Before, putting
a FQDN here could cause the whole FQDN to be used as
hostname. Thanks to Michael Heimpold for the bug report.
Massive but trivial edit to make the "daemon" variable
global, instead of copying the same value around as the
first argument to half the functions in the program.
Updated Spanish manpage and message catalog. Thanks
to Chris Chatham.
Added patch for support of DNS LOC records in
contrib/dns-loc. Thanks to Lorenz Schori.
Fixed error in manpage: dhcp-ignore-name ->
dhcp-ignore-names. Thanks to Daniel Mentz for spotting
this.
Use client-id as hash-seed for DHCP address allocation
with Firewire and Infiniband, as these don't supply an MAC
address.
Tweaked TFTP file-open code to make it behave sensibly
when the filesystem changes under its feet.
Added DNSMASQ_TIME_REMAINING environment variable to the
lease-script.
Always send replies to DHCPINFORM requests to the source
of the request and not to the address in ciaddr. This
allows third-party queries.
Return "lease time remaining" in the reply to a DHCPINFORM
request if there exists a lease for the host sending the
request.
Added --dhcp-hostsfile option. This gives a superset of
the functionality provided by /etc/ethers. Thanks to
Greg Kurtzer for the suggestion.
Accept keyword "server" as a synonym for "nameserver" in
resolv.conf. Thanks to Andrew Bartlett for the report.
Add --tftp-unique-root option. Suggestion from Dermot
Bradley.
Tweak TFTP retry timer to avoid problems with difficult
clients. Thanks to Dermot Bradley for assistance with
this.
Continue to use unqualified hostnames provided by DHCP
clients, even if the domain part is illegal. (The domain
is ignored, and an error logged.) Previously in this
situation, the whole name whould have been
rejected. Thanks to Jima for the patch.
Handle EINTR returns from wait() correctly and reap
our children's children if necessary. This fixes
a problem with zombie-creation under *BSD when using
--dhcp-script.
Escape spaces in hostnames when they are stored in the
leases file and passed to the lease-change
script. Suggestion from Ben Voigt.
Re-run the lease chamge script with an "old" event for
each lease when dnsmasq receives a SIGHUP.
Added more useful exit codes, including passing on a
non-zero exit code from the lease-script "init" call when
--leasefile-ro is set.
Log memory allocation failure whilst the daemon is
running. Allocation failures during startup are fatal,
but lack of memory whilst running is worked around.
This used to be silent, but now is logged.
Fixed misaligned memory access which caused problems on
Blackfin CPUs. Thanks to Alex Landau for the patch.
Don't include (useless) script-calling code when NO_FORK
is set. Since this tends to be used on very small uclinux
systems, it's worth-while to save some code-size.
Don't set REUSEADDR on TFTP listening socket. There's no
need to do so, and it creates confusing behaviour when
inetd is also listening on the same port. Thanks to Erik
Brown for spotting the problem.
Hi Simon
Here is a patch against dnsmasq 2.39 which provides support for LOC
entries in order to assign location information to dns records
(rfc1876). I tested it on OSX and on OpenWRT.
Cheers
Lorenz
More info:
http://www.ckdhr.com/dns-loc/
http://www.faqs.org/rfcs/rfc1876.html
This diff is collapsed.
...@@ -23,6 +23,6 @@ ...@@ -23,6 +23,6 @@
# will port forward port 53 UDP and TCP from this host to port 53 on dnsserver. # will port forward port 53 UDP and TCP from this host to port 53 on dnsserver.
# #
# Port forwards will recreated when dnsmasq restarts after a reboot, and # Port forwards will recreated when dnsmasq restarts after a reboot, and
# removed when DHCP leases expire. After editing this file, restart dnsmasq # removed when DHCP leases expire. After editing this file, send
# to install new iptables entries in the kernel. # SIGHUP to dnsmasq to install new iptables entries in the kernel.
CFLAGS?= -O2 CFLAGS?= -O2 -Wall -W
all: dhcp_release.c all: dhcp_release dhcp_lease_time
$(CC) $(CFLAGS) $(RPM_OPT_FLAGS) -Wall -W dhcp_release.c -o dhcp_release
clean: clean:
rm -f *~ *.o core dhcp_release rm -f *~ *.o core dhcp_release dhcp_lease_time
/* Copyright (c) 2007 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.
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.
*/
/* dhcp_lease_time <address> */
/* Send a DHCPINFORM message to a dnsmasq server running on the local host
and print (to stdout) the time remaining in any lease for the given
address. The time is given as string printed to stdout.
If an error occurs or no lease exists for the given address,
nothing is sent to stdout a message is sent to stderr and a
non-zero error code is returned.
Requires dnsmasq 2.40 or later.
*/
#include <sys/types.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <errno.h>
#define DHCP_CHADDR_MAX 16
#define BOOTREQUEST 1
#define DHCP_COOKIE 0x63825363
#define OPTION_PAD 0
#define OPTION_LEASE_TIME 51
#define OPTION_OVERLOAD 52
#define OPTION_MESSAGE_TYPE 53
#define OPTION_END 255
#define DHCPINFORM 8
#define DHCP_SERVER_PORT 67
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
#define option_ptr(opt) ((void *)&(((unsigned char *)(opt))[2]))
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
struct dhcp_packet {
u8 op, htype, hlen, hops;
u32 xid;
u16 secs, flags;
struct in_addr ciaddr, yiaddr, siaddr, giaddr;
u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
u32 cookie;
unsigned char options[308];
};
static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
{
while (*p != OPTION_END)
{
if (p >= end)
return NULL; /* malformed packet */
else if (*p == OPTION_PAD)
p++;
else
{
int opt_len;
if (p >= end - 2)
return NULL; /* malformed packet */
opt_len = option_len(p);
if (p >= end - (2 + opt_len))
return NULL; /* malformed packet */
if (*p == opt && opt_len >= minsize)
return p;
p += opt_len + 2;
}
}
return opt == OPTION_END ? p : NULL;
}
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize)
{
unsigned char *ret, *overload;
/* skip over DHCP cookie; */
if ((ret = option_find1(&mess->options[0], ((unsigned char *)mess) + size, opt_type, minsize)))
return ret;
/* look for overload option. */
if (!(overload = option_find1(&mess->options[0], ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1)))
return NULL;
/* Can we look in filename area ? */
if ((overload[2] & 1) &&
(ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
return ret;
/* finally try sname area */
if ((overload[2] & 2) &&
(ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
return ret;
return NULL;
}
static unsigned int option_uint(unsigned char *opt, int size)
{
/* this worries about unaligned data and byte order */
unsigned int ret = 0;
int i;
unsigned char *p = option_ptr(opt);
for (i = 0; i < size; i++)
ret = (ret << 8) | *p++;
return ret;
}
int main(int argc, char **argv)
{
struct in_addr lease;
struct dhcp_packet packet;
unsigned char *p = packet.options;
struct sockaddr_in dest;
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
ssize_t rc;
if (argc < 2)
{
fprintf(stderr, "usage: dhcp_lease_time <address>\n");
exit(1);
}
if (fd == -1)
{
perror("cannot create socket");
exit(1);
}
lease.s_addr = inet_addr(argv[1]);
memset(&packet, 0, sizeof(packet));
packet.hlen = 0;
packet.htype = 0;
packet.op = BOOTREQUEST;
packet.ciaddr = lease;
packet.cookie = htonl(DHCP_COOKIE);
*(p++) = OPTION_MESSAGE_TYPE;
*(p++) = 1;
*(p++) = DHCPINFORM;
*(p++) = OPTION_END;
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr("127.0.0.1");
dest.sin_port = ntohs(DHCP_SERVER_PORT);
if (sendto(fd, &packet, sizeof(packet), 0,
(struct sockaddr *)&dest, sizeof(dest)) == -1)
{
perror("sendto failed");
exit(1);
}
alarm(3); /* noddy timeout. */
rc = recv(fd, &packet, sizeof(packet), 0);
if (rc < (ssize_t)(sizeof(packet) - sizeof(packet.options)))
{
perror("recv failed");
exit(1);
}
if ((p = option_find(&packet, (size_t)rc, OPTION_LEASE_TIME, 4)))
{
unsigned int t = option_uint(p, 4);
if (t == 0xffffffff)
printf("infinite");
else
{
unsigned int x;
if ((x = t/86400))
printf("%dd", x);
if ((x = (t/3600)%24))
printf("%dh", x);
if ((x = (t/60)%60))
printf("%dm", x);
if ((x = t%60))
printf("%ds", x);
}
return 0;
}
return 1; /* no lease */
}
...@@ -180,6 +180,12 @@ ...@@ -180,6 +180,12 @@
# any machine with ethernet address starting 11:22:33: # any machine with ethernet address starting 11:22:33:
#dhcp-host=11:22:33:*:*:*,net:red #dhcp-host=11:22:33:*:*:*,net:red
# Ignore any clients which are specified in dhcp-host lines
# or /etc/ethers. Equivalent to ISC "deny unkown-clients".
# This relies on the special "known" tag which is set when
# a host is matched.
#dhcp-ignore=#known
# Send extra options which are tagged as "red" to any machine whose # Send extra options which are tagged as "red" to any machine whose
# DHCP vendorclass string includes the substring "Linux" # DHCP vendorclass string includes the substring "Linux"
#dhcp-vendorclass=red,Linux #dhcp-vendorclass=red,Linux
...@@ -204,7 +210,7 @@ ...@@ -204,7 +210,7 @@
# run "dnsmasq --help dhcp" to get a list. # 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 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.
...@@ -333,7 +339,7 @@ ...@@ -333,7 +339,7 @@
# whether it has a record of the lease or not. This avoids long timeouts # whether it has a record of the lease or not. This avoids long timeouts
# when a machine wakes up on a new network. DO NOT enable this if there's # when a machine wakes up on a new network. DO NOT enable this if there's
# the slighest chance that you might end up accidentally configuring a DHCP # the slighest chance that you might end up accidentally configuring a DHCP
# server for your campus/company accidentally. The ISC server uses the same # server for your campus/company accidentally. The ISC server uses
# the same option, and this URL provides more information: # the same option, and this URL provides more information:
# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php # http://www.isc.org/index.pl?/sw/dhcp/authoritative.php
#dhcp-authoritative #dhcp-authoritative
......
...@@ -6,8 +6,8 @@ dnsmasq \- A lightweight DHCP and caching DNS server. ...@@ -6,8 +6,8 @@ dnsmasq \- A lightweight DHCP and caching DNS server.
.I [OPTION]... .I [OPTION]...
.SH "DESCRIPTION" .SH "DESCRIPTION"
.BR dnsmasq .BR dnsmasq
is a lightweight DNS, TFTP and DHCP server. It is intended to provide coupled DNS and DHCP service to a is a lightweight DNS, TFTP and DHCP server. It is intended to provide
LAN. coupled DNS and DHCP service to a LAN.
.PP .PP
Dnsmasq accepts DNS queries and either answers them from a small, local, Dnsmasq accepts DNS queries and either answers them from a small, local,
cache or forwards them to a real, recursive, DNS server. It loads the cache or forwards them to a real, recursive, DNS server. It loads the
...@@ -73,7 +73,9 @@ the facilty given contains at least one '/' character, it is taken to ...@@ -73,7 +73,9 @@ the facilty given contains at least one '/' character, it is taken to
be a filename, and dnsmasq logs to the given file, instead of be a filename, and dnsmasq logs to the given file, instead of
syslog. (Errors whilst reading configuration will still go to syslog, syslog. (Errors whilst reading configuration will still go to syslog,
but all output from a successful startup, and all output whilst but all output from a successful startup, and all output whilst
running, will go exclusively to the file.) running, will go exclusively to the file.) When logging to a file,
dnsmasq will close and reopen the file when it receives SIGUSR2. This
allows the log file to be rotated without stopping dnsmasq.
.TP .TP
.B --log-async[=<lines>] .B --log-async[=<lines>]
Enable asynchronous logging and optionally set the limit on the Enable asynchronous logging and optionally set the limit on the
...@@ -252,7 +254,7 @@ or domain parts, to upstream nameservers. If the name is not known ...@@ -252,7 +254,7 @@ or domain parts, to upstream nameservers. If the name is not known
from /etc/hosts or DHCP then a "not found" answer is returned. from /etc/hosts or DHCP then a "not found" answer is returned.
.TP .TP
.B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source>[#<port>]]] .B \-S, --local, --server=[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source>[#<port>]]]
Specify IP address of upstream severs directly. Setting this flag does Specify IP address of upstream servers directly. Setting this flag does
not suppress reading of /etc/resolv.conf, use -R to do that. If one or not suppress reading of /etc/resolv.conf, use -R to do that. If one or
more more
optional domains are given, that server is used only for those domains optional domains are given, that server is used only for those domains
...@@ -364,8 +366,7 @@ Set the size of dnsmasq's cache. The default is 150 names. Setting the cache siz ...@@ -364,8 +366,7 @@ Set the size of dnsmasq's cache. The default is 150 names. Setting the cache siz
.B \-N, --no-negcache .B \-N, --no-negcache
Disable negative caching. Negative caching allows dnsmasq to remember Disable negative caching. Negative caching allows dnsmasq to remember
"no such domain" answers from upstream nameservers and answer "no such domain" answers from upstream nameservers and answer
identical queries without forwarding them again. This flag disables identical queries without forwarding them again.
negative caching.
.TP .TP
.B \-0, --dns-forward-max=<queries> .B \-0, --dns-forward-max=<queries>
Set the maximum number of concurrent DNS queries. The default value is Set the maximum number of concurrent DNS queries. The default value is
...@@ -441,9 +442,12 @@ instance ...@@ -441,9 +442,12 @@ instance
This is This is
useful when there is another DHCP server on the network which should useful when there is another DHCP server on the network which should
be used by some machines. The net:<network-id> sets the network-id tag be used by some machines. The net:<network-id> sets the network-id tag
whenever this dhcp-host directive is in use. whenever this dhcp-host directive is in use.This can be used to
This can be used to selectively send DHCP options just selectively send DHCP options just for this host. When a host matches any
for this host. dhcp-host directive (or one implied by /etc/ethers) then the special
network-id tag "known" is set. This allows dnsmasq to be configured to
ignore requests from unknown machines using
.B --dhcp-ignore=#known
Ethernet addresses (but not client-ids) may have Ethernet addresses (but not client-ids) may have
wildcard bytes, so for example wildcard bytes, so for example
.B --dhcp-host=00:20:e0:3b:13:*,ignore .B --dhcp-host=00:20:e0:3b:13:*,ignore
...@@ -456,6 +460,13 @@ ARP type by preceding them with the ARP-type (in HEX) and "-". so ...@@ -456,6 +460,13 @@ ARP type by preceding them with the ARP-type (in HEX) and "-". so
will only match a will only match a
Token-Ring hardware address, since the ARP-address type for token ring Token-Ring hardware address, since the ARP-address type for token ring
is 6. is 6.
.TP
.B --dhcp-hostsfile=<file>
Read DHCP host information from the specified file. The file contains
information about one host per line. The format of a line is the same
as text to the right of '=' in --dhcp-host. The advantage of storing DHCP host information
in this file is that it can be changed without re-starting dnsmasq:
the file will be re-read when dnsmasq receives SIGHUP.
.TP .TP
.B \-Z, --read-ethers .B \-Z, --read-ethers
Read /etc/ethers for information about hosts for the DHCP server. The Read /etc/ethers for information about hosts for the DHCP server. The
...@@ -463,7 +474,8 @@ format of /etc/ethers is a hardware address, followed by either a ...@@ -463,7 +474,8 @@ format of /etc/ethers is a hardware address, followed by either a
hostname or dotted-quad IP address. When read by dnsmasq these lines hostname or dotted-quad IP address. When read by dnsmasq these lines
have exactly the same effect as have exactly the same effect as
.B --dhcp-host .B --dhcp-host
options containing the same information. options containing the same information. /etc/ethers is re-read when
dnsmasq receives SIGHUP.
.TP .TP
.B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],][<opt>|option:<opt-name>],[<value>[,<value>]] .B \-O, --dhcp-option=[<network-id>,[<network-id>,]][vendor:[<vendor-class>],][<opt>|option:<opt-name>],[<value>[,<value>]]
Specify different or extra options to DHCP clients. By default, Specify different or extra options to DHCP clients. By default,
...@@ -577,7 +589,7 @@ When all the given network-ids match the set of network-ids derived ...@@ -577,7 +589,7 @@ When all the given network-ids match the set of network-ids derived
from the net, host, vendor and user classes, ignore the host and do from the net, host, vendor and user classes, ignore the host and do
not allocate it a DHCP lease. not allocate it a DHCP lease.
.TP .TP
.B --dhcp-ignore-name[=<network-id>[,<network-id>]] .B --dhcp-ignore-names[=<network-id>[,<network-id>]]
When all the given network-ids match the set of network-ids derived When all the given network-ids match the set of network-ids derived
from the net, host, vendor and user classes, ignore any hostname from the net, host, vendor and user classes, ignore any hostname
provided by the host. Note that, unlike dhcp-ignore, it is permissable provided by the host. Note that, unlike dhcp-ignore, it is permissable
...@@ -660,7 +672,9 @@ since these data are not held in dnsmasq's lease ...@@ -660,7 +672,9 @@ since these data are not held in dnsmasq's lease
database. If dnsmasq was compiled with HAVE_BROKEN_RTC, then database. If dnsmasq was compiled with HAVE_BROKEN_RTC, then
the length of the lease (in seconds) is stored in the length of the lease (in seconds) is stored in
DNSMASQ_LEASE_LENGTH, otherwise the time of lease expiry is stored in DNSMASQ_LEASE_LENGTH, otherwise the time of lease expiry is stored in
DNSMASQ_LEASE_EXPIRES. If a lease used to have a hostname, which is DNSMASQ_LEASE_EXPIRES. The number of seconds until lease expiry is
always stored in DNSMASQ_TIME_REMAINING.
If a lease used to have a hostname, which is
removed, an "old" event is generated with the new state of the lease, removed, an "old" event is generated with the new state of the lease,
ie no name, and the former name is provided in the environment ie no name, and the former name is provided in the environment
variable DNSMASQ_OLD_HOSTNAME. variable DNSMASQ_OLD_HOSTNAME.
...@@ -672,7 +686,9 @@ changes occur, the script is not invoked again until any existing ...@@ -672,7 +686,9 @@ changes occur, the script is not invoked again until any existing
invocation exits. At dnsmasq startup, the script will be invoked for invocation exits. At dnsmasq startup, the script will be invoked for
all existing leases as they are read from the lease file. Expired all existing leases as they are read from the lease file. Expired
leases will be called with "del" and others with "old". <path> leases will be called with "del" and others with "old". <path>
must be an absolute pathname, no PATH search occurs. must be an absolute pathname, no PATH search occurs. When dnsmasq
receives a HUP signal, the script will be invoked for existing leases
with an "old " event.
.TP .TP
.B \-9, --leasefile-ro .B \-9, --leasefile-ro
Completely suppress use of the lease database file. The file will not Completely suppress use of the lease database file. The file will not
...@@ -726,8 +742,15 @@ rejected, to stop clients getting outside the specified root. ...@@ -726,8 +742,15 @@ rejected, to stop clients getting outside the specified root.
Absolute paths (starting with /) are allowed, but they must be within Absolute paths (starting with /) are allowed, but they must be within
the tftp-root. the tftp-root.
.TP .TP
.B --tftp-unique-root
Add the IP address of the TFTP client as a path component on the end
of the TFTP-root (in standard dotted-quad format). Only valid if a
tftp-root is set and the directory exists. For instance, if tftp-root is "/tftp" and client
1.2.3.4 requests file "myfile" then the effective path will be
"/tftp/1.2.3.4/myfile" if /tftp/1.2.3.4 exists or /tftp/myfile otherwise.
.TP
.B --tftp-secure .B --tftp-secure
Enable TFTP secure mode: without this, any file which is readble by Enable TFTP secure mode: without this, any file which is readable by
the dnsmasq process under normal unix access-control rules is the dnsmasq process under normal unix access-control rules is
available via TFTP. When the --tftp-secure flag is given, only files available via TFTP. When the --tftp-secure flag is given, only files
owned by the user running the dnsmasq process are accessible. If owned by the user running the dnsmasq process are accessible. If
...@@ -783,8 +806,12 @@ corresponding to tab, bell, backspace, return and newline. ...@@ -783,8 +806,12 @@ corresponding to tab, bell, backspace, return and newline.
When it receives a SIGHUP, When it receives a SIGHUP,
.B dnsmasq .B dnsmasq
clears its cache and then re-loads clears its cache and then re-loads
.I /etc/hosts and /etc/ethers. .I /etc/hosts
If and
.I /etc/ethers
and any file given by --dhcp-hostsfile.
The dhcp lease change script is called for all
existing DHCP leases. If
.B .B
--no-poll --no-poll
is set SIGHUP also re-reads is set SIGHUP also re-reads
...@@ -799,7 +826,29 @@ the number of names which have had to removed from the cache before ...@@ -799,7 +826,29 @@ the number of names which have had to removed from the cache before
they expired in order to make room for new names and the total number they expired in order to make room for new names and the total number
of names that have been inserted into the cache. In of names that have been inserted into the cache. In
.B --no-daemon .B --no-daemon
mode or when full logging is enabled (-q), a complete dump of the contents of the cache is made. mode or when full logging is enabled (-q), a complete dump of the
contents of the cache is made.
.PP
When it receives SIGUSR2 and it is logging direct to a file (see
.B --log-facility
)
.B dnsmasq
will close and reopen the log file. Note that during this operation,
dnsmasq will not be running as root. When it first creates the logfile
dnsmasq changes the ownership of the file to the non-root user it will run
as. Logrotate should be configured to create a new log file with
the ownership which matches the exising one before sending SIGUSR2.
If TCP DNS queries are in progress, the old logfile will remain open in
child processes which are handling TCP queries and may continue to be
written. There is a limit of 150 seconds, after which all existing TCP
processes will have expired: for this reason, it is not wise to
configure logfile compression for logfiles which have just been
rotated. Using logrotate, the required options are
.B create
and
.B delaycompress.
.PP .PP
Dnsmasq is a DNS query forwarder: it it not capable of recursively Dnsmasq is a DNS query forwarder: it it not capable of recursively
answering arbitrary queries starting from the root servers but answering arbitrary queries starting from the root servers but
...@@ -903,6 +952,27 @@ parameter in a BOOTP request is matched against netids in ...@@ -903,6 +952,27 @@ parameter in a BOOTP request is matched against netids in
configurations, as is the tag "bootp", allowing some control over the options returned to configurations, as is the tag "bootp", allowing some control over the options returned to
different classes of hosts. different classes of hosts.
.SH EXIT CODES
.PP
0 - Dnsmasq successfully forked into the background, or terminated
normally if backgrounding is not enabled.
.PP
1 - A problem with configuration was detected.
.PP
2 - A problem with network access occurred (address in use, attempt
to use privileged ports without permission).
.PP
3 - A problem occured with a filesystem operation (missing
file/directory, permissions).
.PP
4 - Memory allocation failure.
.PP
5 - Other miscellaneous problem.
.PP
11 or greater - a non zero return code was received from the
lease-script process "init" call. The exit code from dnsmasq is the
script's exit code with 10 added.
.SH LIMITS .SH LIMITS
The default values for resource limits in dnsmasq are generally The default values for resource limits in dnsmasq are generally
conservative, and appropriate for embedded router type devices with conservative, and appropriate for embedded router type devices with
......
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.
...@@ -26,7 +26,7 @@ static struct iovec ifreq = { ...@@ -26,7 +26,7 @@ static struct iovec ifreq = {
.iov_len = 0 .iov_len = 0
}; };
void init_bpf(struct daemon *daemon) void init_bpf(void)
{ {
int i = 0; int i = 0;
...@@ -37,19 +37,14 @@ void init_bpf(struct daemon *daemon) ...@@ -37,19 +37,14 @@ void init_bpf(struct daemon *daemon)
{ {
sprintf(ifreq.iov_base, "/dev/bpf%d", i++); sprintf(ifreq.iov_base, "/dev/bpf%d", i++);
if ((daemon->dhcp_raw_fd = open(ifreq.iov_base, O_RDWR, 0)) != -1) if ((daemon->dhcp_raw_fd = open(ifreq.iov_base, O_RDWR, 0)) != -1)
{ return;
int flags = fcntl(daemon->dhcp_raw_fd, F_GETFD);
if (flags != -1)
fcntl(daemon->dhcp_raw_fd, F_SETFD, flags | FD_CLOEXEC);
return;
}
} }
if (errno != EBUSY) if (errno != EBUSY)
die(_("cannot create DHCP BPF socket: %s"), NULL); die(_("cannot create DHCP BPF socket: %s"), NULL, EC_BADNET);
} }
} }
void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len, void send_via_bpf(struct dhcp_packet *mess, size_t len,
struct in_addr iface_addr, struct ifreq *ifr) struct in_addr iface_addr, struct ifreq *ifr)
{ {
/* Hairy stuff, packet either has to go to the /* Hairy stuff, packet either has to go to the
...@@ -145,7 +140,7 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len, ...@@ -145,7 +140,7 @@ void send_via_bpf(struct daemon *daemon, struct dhcp_packet *mess, size_t len,
while (writev(daemon->dhcp_raw_fd, iov, 4) == -1 && retry_send()); while (writev(daemon->dhcp_raw_fd, iov, 4) == -1 && retry_send());
} }
int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), int (*ipv6_callback)()) int iface_enumerate(void *parm, int (*ipv4_callback)(), int (*ipv6_callback)())
{ {
char *ptr; char *ptr;
struct ifreq *ifr; struct ifreq *ifr;
...@@ -206,7 +201,7 @@ int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), i ...@@ -206,7 +201,7 @@ int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), i
netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr; netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
if (ioctl(fd, SIOCGIFBRDADDR, ifr) != -1) if (ioctl(fd, SIOCGIFBRDADDR, ifr) != -1)
broadcast = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr; broadcast = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
if (!((*ipv4_callback)(daemon, addr, if (!((*ipv4_callback)(addr,
(int)if_nametoindex(ifr->ifr_name), (int)if_nametoindex(ifr->ifr_name),
netmask, broadcast, netmask, broadcast,
parm))) parm)))
...@@ -222,7 +217,7 @@ int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), i ...@@ -222,7 +217,7 @@ int iface_enumerate(struct daemon *daemon, void *parm, int (*ipv4_callback)(), i
addr->s6_addr[2] = 0; addr->s6_addr[2] = 0;
addr->s6_addr[3] = 0; addr->s6_addr[3] = 0;
} }
if (!((*ipv6_callback)(daemon, addr, if (!((*ipv6_callback)(addr,
(int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id, (int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id,
(int)if_nametoindex(ifr->ifr_name), (int)if_nametoindex(ifr->ifr_name),
parm))) parm)))
......
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
#include "dnsmasq.h" #include "dnsmasq.h"
static struct crec *cache_head, *cache_tail, **hash_table; static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
static struct crec *dhcp_spare, *new_chain; static struct crec *dhcp_spare = NULL, *new_chain = NULL;
static int cache_inserted, cache_live_freed, insert_error; static int cache_inserted = 0, cache_live_freed = 0, insert_error;
static union bigname *big_free; static union bigname *big_free = NULL;
static int bignames_left, log_queries, cache_size, hash_size; static int bignames_left, hash_size;
static int uid; static int uid = 0;
static char *addrbuff; static char *addrbuff = NULL;
/* type->string mapping: this is also used by the name-hash function as a mixing table. */ /* type->string mapping: this is also used by the name-hash function as a mixing table. */
static const struct { static const struct {
...@@ -63,32 +63,21 @@ static char *record_source(struct hostsfile *add_hosts, int index); ...@@ -63,32 +63,21 @@ static char *record_source(struct hostsfile *add_hosts, int index);
static void rehash(int size); static void rehash(int size);
static void cache_hash(struct crec *crecp); static void cache_hash(struct crec *crecp);
void cache_init(int size, int logq) void cache_init(void)
{ {
struct crec *crecp; struct crec *crecp;
int i; int i;
if ((log_queries = logq)) if (daemon->options & OPT_LOG)
addrbuff = safe_malloc(ADDRSTRLEN); addrbuff = safe_malloc(ADDRSTRLEN);
else
addrbuff = NULL; bignames_left = daemon->cachesize/10;
cache_head = cache_tail = NULL; if (daemon->cachesize > 0)
dhcp_spare = NULL;
new_chain = NULL;
hash_table = NULL;
cache_size = size;
big_free = NULL;
bignames_left = size/10;
uid = 0;
cache_inserted = cache_live_freed = 0;
if (cache_size > 0)
{ {
crecp = safe_malloc(size*sizeof(struct crec)); crecp = safe_malloc(daemon->cachesize*sizeof(struct crec));
for (i=0; i<size; i++, crecp++) for (i=0; i < daemon->cachesize; i++, crecp++)
{ {
cache_link(crecp); cache_link(crecp);
crecp->flags = 0; crecp->flags = 0;
...@@ -97,7 +86,7 @@ void cache_init(int size, int logq) ...@@ -97,7 +86,7 @@ void cache_init(int size, int logq)
} }
/* create initial hash table*/ /* create initial hash table*/
rehash(cache_size); rehash(daemon->cachesize);
} }
/* In most cases, we create the hash table once here by calling this with (hash_table == NULL) /* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
...@@ -115,7 +104,7 @@ static void rehash(int size) ...@@ -115,7 +104,7 @@ static void rehash(int size)
/* must succeed in getting first instance, failure later is non-fatal */ /* must succeed in getting first instance, failure later is non-fatal */
if (!hash_table) if (!hash_table)
new = safe_malloc(new_size * sizeof(struct crec *)); new = safe_malloc(new_size * sizeof(struct crec *));
else if (new_size <= hash_size || !(new = malloc(new_size * sizeof(struct crec *)))) else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))
return; return;
for(i = 0; i < new_size; i++) for(i = 0; i < new_size; i++)
...@@ -238,17 +227,12 @@ char *cache_get_name(struct crec *crecp) ...@@ -238,17 +227,12 @@ char *cache_get_name(struct crec *crecp)
static int is_outdated_cname_pointer(struct crec *crecp) static int is_outdated_cname_pointer(struct crec *crecp)
{ {
struct crec *target = crecp->addr.cname.cache;
if (!(crecp->flags & F_CNAME)) if (!(crecp->flags & F_CNAME))
return 0; return 0;
if (!target) if (crecp->addr.cname.cache && crecp->addr.cname.uid == crecp->addr.cname.cache->uid)
return 1;
if (crecp->addr.cname.uid == target->uid)
return 0; return 0;
return 1; return 1;
} }
...@@ -368,21 +352,12 @@ void cache_start_insert(void) ...@@ -368,21 +352,12 @@ void cache_start_insert(void)
struct crec *cache_insert(char *name, struct all_addr *addr, struct crec *cache_insert(char *name, struct all_addr *addr,
time_t now, unsigned long ttl, unsigned short flags) time_t now, unsigned long ttl, unsigned short flags)
{ {
#ifdef HAVE_IPV6
int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ;
#else
int addrlen = INADDRSZ;
#endif
struct crec *new; struct crec *new;
union bigname *big_name = NULL; union bigname *big_name = NULL;
int freed_all = flags & F_REVERSE; int freed_all = flags & F_REVERSE;
log_query(flags | F_UPSTREAM, name, addr, 0, NULL, 0); log_query(flags | F_UPSTREAM, name, addr, 0, NULL, 0);
/* name is needed as workspace by log_query in this case */
if ((flags & F_NEG) && (flags & F_REVERSE))
name = NULL;
/* CONFIG bit no needed except for logging */ /* CONFIG bit no needed except for logging */
flags &= ~F_CONFIG; flags &= ~F_CONFIG;
...@@ -436,7 +411,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr, ...@@ -436,7 +411,7 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
big_free = big_free->next; big_free = big_free->next;
} }
else if (!bignames_left || else if (!bignames_left ||
!(big_name = (union bigname *)malloc(sizeof(union bigname)))) !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
{ {
insert_error = 1; insert_error = 1;
return NULL; return NULL;
...@@ -457,12 +432,14 @@ struct crec *cache_insert(char *name, struct all_addr *addr, ...@@ -457,12 +432,14 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
new->name.bname = big_name; new->name.bname = big_name;
new->flags |= F_BIGNAME; new->flags |= F_BIGNAME;
} }
if (name) if (name)
strcpy(cache_get_name(new), name); strcpy(cache_get_name(new), name);
else else
*cache_get_name(new) = 0; *cache_get_name(new) = 0;
if (addr) if (addr)
memcpy(&new->addr.addr, addr, addrlen); new->addr.addr = *addr;
else else
new->addr.cname.cache = NULL; new->addr.cname.cache = NULL;
...@@ -754,8 +731,8 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -754,8 +731,8 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
{ {
/* 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 && !fqdn && if ((opts & OPT_EXPAND) && domain_suffix && !fqdn &&
(cache = malloc(sizeof(struct crec) + (cache = whine_malloc(sizeof(struct crec) +
strlen(token)+2+strlen(domain_suffix)-SMALLDNAME))) strlen(token)+2+strlen(domain_suffix)-SMALLDNAME)))
{ {
strcpy(cache->name.sname, token); strcpy(cache->name.sname, token);
strcat(cache->name.sname, "."); strcat(cache->name.sname, ".");
...@@ -764,7 +741,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -764,7 +741,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
addr_dup = 1; addr_dup = 1;
name_count++; name_count++;
} }
if ((cache = malloc(sizeof(struct crec) + strlen(token)+1-SMALLDNAME))) if ((cache = whine_malloc(sizeof(struct crec) + strlen(token)+1-SMALLDNAME)))
{ {
strcpy(cache->name.sname, token); strcpy(cache->name.sname, token);
add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup); add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
...@@ -787,7 +764,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf ...@@ -787,7 +764,7 @@ static int read_hostsfile(char *filename, int opts, char *buff, char *domain_suf
void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *addn_hosts) void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *addn_hosts)
{ {
struct crec *cache, **up, *tmp; struct crec *cache, **up, *tmp;
int i, total_size = cache_size; int i, total_size = daemon->cachesize;
cache_inserted = cache_live_freed = 0; cache_inserted = cache_live_freed = 0;
...@@ -816,7 +793,7 @@ void cache_reload(int opts, char *buff, char *domain_suffix, struct hostsfile *a ...@@ -816,7 +793,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 (daemon->cachesize > 0)
my_syslog(LOG_INFO, _("cleared cache")); my_syslog(LOG_INFO, _("cleared cache"));
return; return;
} }
...@@ -847,7 +824,7 @@ void cache_unhash_dhcp(void) ...@@ -847,7 +824,7 @@ void cache_unhash_dhcp(void)
up = &cache->hash_next; up = &cache->hash_next;
} }
void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, void cache_add_dhcp_entry(char *host_name,
struct in_addr *host_address, time_t ttd) struct in_addr *host_address, time_t ttd)
{ {
struct crec *crec; struct crec *crec;
...@@ -887,7 +864,7 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, ...@@ -887,7 +864,7 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
if ((crec = dhcp_spare)) if ((crec = dhcp_spare))
dhcp_spare = dhcp_spare->next; dhcp_spare = dhcp_spare->next;
else /* need new one */ else /* need new one */
crec = malloc(sizeof(struct crec)); crec = whine_malloc(sizeof(struct crec));
if (crec) /* malloc may fail */ if (crec) /* malloc may fail */
{ {
...@@ -902,13 +879,13 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name, ...@@ -902,13 +879,13 @@ void cache_add_dhcp_entry(struct daemon *daemon, char *host_name,
} }
} }
void dump_cache(struct daemon *daemon, time_t now) void dump_cache(time_t now)
{ {
my_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 = whine_malloc(ADDRSTRLEN))))
{ {
struct crec *cache ; struct crec *cache ;
int i; int i;
...@@ -982,54 +959,60 @@ static char *record_source(struct hostsfile *addn_hosts, int index) ...@@ -982,54 +959,60 @@ static char *record_source(struct hostsfile *addn_hosts, int index)
void log_query(unsigned short flags, char *name, struct all_addr *addr, void log_query(unsigned short flags, char *name, struct all_addr *addr,
unsigned short type, struct hostsfile *addn_hosts, int index) unsigned short type, struct hostsfile *addn_hosts, int index)
{ {
char *source; char *source, *dest = addrbuff;
char *verb = "is"; char *verb = "is";
char types[20]; char types[20];
if (!log_queries) if (!(daemon->options & OPT_LOG))
return; return;
if (flags & F_NEG) if (addr)
{ {
if (flags & F_REVERSE)
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6, inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
addr, name, MAXDNAME); addr, addrbuff, ADDRSTRLEN);
#else #else
strcpy(name, inet_ntoa(addr->addr.addr4)); strncpy(addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN);
#endif #endif
}
if (flags & F_REVERSE)
{
dest = name;
name = addrbuff;
}
if (flags & F_NEG)
{
if (flags & F_NXDOMAIN) if (flags & F_NXDOMAIN)
strcpy(addrbuff, "<NXDOMAIN>"); {
if (flags & F_IPV4)
dest = "NXDOMAIN-IPv4";
else
dest = "NXDOMAIN-IPv6";
}
else else
strcpy(addrbuff, "<NODATA>"); {
if (flags & F_IPV4)
if (flags & F_IPV4) dest = "NODATA-IPv4";
strcat(addrbuff, "-IPv4"); else
else if (flags & F_IPV6) dest = "NODATA-IPv6";
strcat(addrbuff, "-IPv6"); }
} }
else if (flags & F_CNAME) else if (flags & F_CNAME)
{ {
/* nasty abuse of IPV4 and IPV6 flags */ /* nasty abuse of IPV4 and IPV6 flags */
if (flags & F_IPV4) if (flags & F_IPV4)
strcpy(addrbuff, "<MX>"); dest = "<MX>";
else if (flags & F_IPV6) else if (flags & F_IPV6)
strcpy(addrbuff, "<SRV>"); dest = "<SRV>";
else if (flags & F_NXDOMAIN) else if (flags & F_NXDOMAIN)
strcpy(addrbuff, "<TXT>"); dest = "<TXT>";
else if (flags & F_BIGNAME) else if (flags & F_BIGNAME)
strcpy(addrbuff, "<PTR>"); dest = "<PTR>";
else else
strcpy(addrbuff, "<CNAME>"); dest = "<CNAME>";
} }
else
#ifdef HAVE_IPV6
inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
addr, addrbuff, ADDRSTRLEN);
#else
strcpy(addrbuff, inet_ntoa(addr->addr.addr4));
#endif
if (flags & F_DHCP) if (flags & F_DHCP)
source = "DHCP"; source = "DHCP";
...@@ -1064,9 +1047,6 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr, ...@@ -1064,9 +1047,6 @@ void log_query(unsigned short flags, char *name, struct all_addr *addr,
if (strlen(name) == 0) if (strlen(name) == 0)
name = "."; name = ".";
if ((flags & F_FORWARD) | (flags & F_NEG)) my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, dest);
my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, addrbuff);
else if (flags & F_REVERSE)
my_syslog(LOG_DEBUG, "%s %s is %s", source, addrbuff, name);
} }
...@@ -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.39" #define VERSION "2.40"
#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 */
...@@ -199,7 +199,8 @@ NOTES: ...@@ -199,7 +199,8 @@ NOTES:
#undef HAVE_SOCKADDR_SA_LEN #undef HAVE_SOCKADDR_SA_LEN
/* Never use fork() on uClinux. Note that this is subtly different from the /* Never use fork() on uClinux. Note that this is subtly different from the
--keep-in-foreground option, since it also suppresses forking new --keep-in-foreground option, since it also suppresses forking new
processes for TCP connections. It's intended for use on MMU-less kernels. */ processes for TCP connections and disables the call-a-script on leasechange
system. It's intended for use on MMU-less kernels. */
#define NO_FORK #define NO_FORK
#elif defined(__UCLIBC__) #elif defined(__UCLIBC__)
......
...@@ -25,28 +25,25 @@ struct watch { ...@@ -25,28 +25,25 @@ struct watch {
static dbus_bool_t add_watch(DBusWatch *watch, void *data) static dbus_bool_t add_watch(DBusWatch *watch, void *data)
{ {
struct daemon *daemon = data;
struct watch *w; struct watch *w;
for (w = daemon->watches; w; w = w->next) for (w = daemon->watches; w; w = w->next)
if (w->watch == watch) if (w->watch == watch)
return TRUE; return TRUE;
if (!(w = malloc(sizeof(struct watch)))) if (!(w = whine_malloc(sizeof(struct watch))))
return FALSE; return FALSE;
w->watch = watch; w->watch = watch;
w->next = daemon->watches; w->next = daemon->watches;
daemon->watches = w; daemon->watches = w;
dbus_watch_set_data (watch, (void *)daemon, NULL); w = data; /* no warning */
return TRUE; return TRUE;
} }
static void remove_watch(DBusWatch *watch, void *data) static void remove_watch(DBusWatch *watch, void *data)
{ {
struct daemon *daemon = data;
struct watch **up, *w; struct watch **up, *w;
for (up = &(daemon->watches), w = daemon->watches; w; w = w->next) for (up = &(daemon->watches), w = daemon->watches; w; w = w->next)
...@@ -57,9 +54,11 @@ static void remove_watch(DBusWatch *watch, void *data) ...@@ -57,9 +54,11 @@ static void remove_watch(DBusWatch *watch, void *data)
} }
else else
up = &(w->next); up = &(w->next);
w = data; /* no warning */
} }
static void dbus_read_servers(struct daemon *daemon, DBusMessage *message) static void dbus_read_servers(DBusMessage *message)
{ {
struct server *serv, *tmp, **up; struct server *serv, *tmp, **up;
DBusMessageIter iter; DBusMessageIter iter;
...@@ -161,11 +160,11 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message) ...@@ -161,11 +160,11 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message)
} }
} }
if (!serv && (serv = malloc(sizeof (struct server)))) if (!serv && (serv = whine_malloc(sizeof (struct server))))
{ {
/* Not found, create a new one. */ /* Not found, create a new one. */
if (domain) if (domain)
serv->domain = malloc(strlen(domain)+1); serv->domain = whine_malloc(strlen(domain)+1);
if (domain && !serv->domain) if (domain && !serv->domain)
{ {
free(serv); free(serv);
...@@ -208,7 +207,7 @@ static void dbus_read_servers(struct daemon *daemon, DBusMessage *message) ...@@ -208,7 +207,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); server_gone(serv);
*up = serv->next; *up = serv->next;
free(serv); free(serv);
} }
...@@ -223,8 +222,7 @@ DBusHandlerResult message_handler(DBusConnection *connection, ...@@ -223,8 +222,7 @@ DBusHandlerResult message_handler(DBusConnection *connection,
void *user_data) void *user_data)
{ {
char *method = (char *)dbus_message_get_member(message); char *method = (char *)dbus_message_get_member(message);
struct daemon *daemon = (struct daemon *)user_data;
if (strcmp(method, "GetVersion") == 0) if (strcmp(method, "GetVersion") == 0)
{ {
char *v = VERSION; char *v = VERSION;
...@@ -237,21 +235,23 @@ DBusHandlerResult message_handler(DBusConnection *connection, ...@@ -237,21 +235,23 @@ DBusHandlerResult message_handler(DBusConnection *connection,
else if (strcmp(method, "SetServers") == 0) else if (strcmp(method, "SetServers") == 0)
{ {
my_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(message);
check_servers(daemon); check_servers();
} }
else if (strcmp(method, "ClearCache") == 0) else if (strcmp(method, "ClearCache") == 0)
clear_cache_and_reload(daemon, dnsmasq_time()); clear_cache_and_reload(dnsmasq_time());
else else
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
method = user_data; /* no warning */
return (DBUS_HANDLER_RESULT_HANDLED); return (DBUS_HANDLER_RESULT_HANDLED);
} }
/* returns NULL or error message, may fail silently if dbus daemon not yet up. */ /* returns NULL or error message, may fail silently if dbus daemon not yet up. */
char *dbus_init(struct daemon *daemon) char *dbus_init(void)
{ {
DBusConnection *connection = NULL; DBusConnection *connection = NULL;
DBusObjectPathVTable dnsmasq_vtable = {NULL, &message_handler, NULL, NULL, NULL, NULL }; DBusObjectPathVTable dnsmasq_vtable = {NULL, &message_handler, NULL, NULL, NULL, NULL };
...@@ -264,14 +264,14 @@ char *dbus_init(struct daemon *daemon) ...@@ -264,14 +264,14 @@ char *dbus_init(struct daemon *daemon)
dbus_connection_set_exit_on_disconnect(connection, FALSE); dbus_connection_set_exit_on_disconnect(connection, FALSE);
dbus_connection_set_watch_functions(connection, add_watch, remove_watch, dbus_connection_set_watch_functions(connection, add_watch, remove_watch,
NULL, (void *)daemon, NULL); NULL, NULL, NULL);
dbus_error_init (&dbus_error); dbus_error_init (&dbus_error);
dbus_bus_request_name (connection, DNSMASQ_SERVICE, 0, &dbus_error); dbus_bus_request_name (connection, DNSMASQ_SERVICE, 0, &dbus_error);
if (dbus_error_is_set (&dbus_error)) if (dbus_error_is_set (&dbus_error))
return (char *)dbus_error.message; return (char *)dbus_error.message;
if (!dbus_connection_register_object_path(connection, DNSMASQ_PATH, if (!dbus_connection_register_object_path(connection, DNSMASQ_PATH,
&dnsmasq_vtable, daemon)) &dnsmasq_vtable, NULL))
return _("could not register a DBus message handler"); return _("could not register a DBus message handler");
daemon->dbus = connection; daemon->dbus = connection;
...@@ -283,7 +283,7 @@ char *dbus_init(struct daemon *daemon) ...@@ -283,7 +283,7 @@ char *dbus_init(struct daemon *daemon)
} }
void set_dbus_listeners(struct daemon *daemon, int *maxfdp, void set_dbus_listeners(int *maxfdp,
fd_set *rset, fd_set *wset, fd_set *eset) fd_set *rset, fd_set *wset, fd_set *eset)
{ {
struct watch *w; struct watch *w;
...@@ -306,8 +306,7 @@ void set_dbus_listeners(struct daemon *daemon, int *maxfdp, ...@@ -306,8 +306,7 @@ void set_dbus_listeners(struct daemon *daemon, int *maxfdp,
} }
} }
void check_dbus_listeners(struct daemon *daemon, void check_dbus_listeners(fd_set *rset, fd_set *wset, fd_set *eset)
fd_set *rset, fd_set *wset, fd_set *eset)
{ {
DBusConnection *connection = (DBusConnection *)daemon->dbus; DBusConnection *connection = (DBusConnection *)daemon->dbus;
struct watch *w; struct watch *w;
......
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.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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