Commit 208b65c5 authored by Simon Kelley's avatar Simon Kelley

import of dnsmasq-2.33.tar.gz

parent 849a8357
......@@ -1883,7 +1883,55 @@ version 2.32
Fixed gcc-4.1 strict-alias compilation warning.
version 2.33
Remove bash-specific shellcode from the Makefile.
Fix breakage with some DHCP relay implementations which
was introduced in 2.28. Believing the source port in
DHCP requests and sending the reply there is sometimes a
bad thing to do, so I've reverted to always sending to
the relay on port 68. Thanks to Daniel Hamlin and Alex
(alde) for bug reports on this.
Moved the SuSe packaging files to contrib. I will no
longer attempt to maintain this in the source tarball. It
will be done externally, in the same way as packaging for
other distros. Suse packages are available from
ftp://ftp.suse.com/pub/people/ug/
Merged patch from Gentoo to honour $LDFLAGS environment.
Fix bug in resolv.conf processing when more than one file
is being checked.
Add --dns-forward-max option.
Warn if --resolv-file flags are ignored because of
--no-resolv. Thanks to Martin F Krafft for spotting this
one.
Add --leasefile-ro option which allows the use of an
external lease database. Many thanks to Steve Horbachuk
for assistance developing this feature.
Provide extra information to lease-change script via its
environment. If the host has a client-id, then
DNSMASQ_CLIENT_ID will be set. Either the lease length (in
DNSMASQ_LEASE_LENGTH) or lease expiry time (in
DNSMASQ_LEASE_EXPIRES) will be set, depending on the
HAVE_BROKEN_RTC compile-time option. This extra
information should make it possible to maintain the lease
database in external storage such as LDAP or a relational
database. Note that while leasefile-ro is set, the script
will be called with "old" events more often, since
changes to the client-id and lease length
(HAVE_BROKEN_RTC) or lease expiry time (otherwise)
are now flagged.
Add contrib/wrt/* which is an example implementation of an
external persistent lease database for *WRT distros with
the nvram command.
Add contrib/wrt/dhcp_release.c which is a small utility
which removes DHCP leases using DHCPRELEASE operation in
the DHCP protocol.
......@@ -42,10 +42,12 @@ Q: Will dnsmasq compile/run on non-Linux systems?
A: Yes, there is explicit support for *BSD and MacOS X. There are
start-up scripts for MacOS X Tiger and Panther in /contrib. Earlier
dnsmasq releases ran under Solaris, but that capability has
probably rotted. Dnsmasq will link with uclibc to provide small
rotted. Dnsmasq will link with uclibc to provide small
binaries suitable for use in embedded systems such as
routers. (There's special code to support machines with flash
filesystems and no battery-backed RTC.)
If you encounter make errors with *BSD, try installing gmake from
ports and building dnsmasq with "make MAKE=gmake"
For other systems, try altering the settings in config.h.
Q: My companies' nameserver knows about some names which aren't in the
......@@ -383,6 +385,16 @@ Q: Dnsmasq logs "running as root because setting capabilities failed"
A: Change your kernel configuration: either deselect CONFIG_SECURITY
_or_ select CONFIG_SECURITY_CAPABILITIES.
Q: Where can I get .rpms Suitable for Suse?
A: Dnsmasq is in Suse itself, and the latest releases are also
available at ftp://ftp.suse.com/pub/people/ug/
......
......@@ -9,12 +9,14 @@ MAN = man
CFLAGS?= -O2
all :
all : dnsmasq
dnsmasq :
$(MAKE) I18N=-DNO_GETTEXT -f ../bld/Makefile -C $(SRC) dnsmasq
clean :
rm -f *~ $(SRC)/*.mo contrib/*/*~ */*~ $(SRC)/*.pot
rm -f $(SRC)/*.o $(SRC)/dnsmasq core */core
rm -f $(SRC)/*.o $(SRC)/dnsmasq.a $(SRC)/dnsmasq core */core
install : all install-common
......@@ -26,7 +28,7 @@ install-common :
all-i18n :
$(MAKE) I18N=-DLOCALEDIR='\"$(LOCALEDIR)\"' -f ../bld/Makefile -C $(SRC) dnsmasq
cd $(PO); for f in *.po; do \
$(MAKE) -f ../bld/Makefile -C ../$(SRC) $${f/.po/.mo}; \
$(MAKE) -f ../bld/Makefile -C ../$(SRC) $${f%.po}.mo; \
done
install-i18n : all-i18n install-common
......
......@@ -9,8 +9,8 @@ OBJS = cache.o rfc1035.o util.o option.o forward.o isc.o network.o \
$(CC) $(CFLAGS) $(COPTS) $(I18N) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --cflags dbus-1` $(RPM_OPT_FLAGS) -Wall -W -c $<
dnsmasq : $(OBJS)
$(CC) -o $@ $(OBJS) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --libs dbus-1` $(LIBS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) `echo $(COPTS) | ../bld/pkg-wrapper $(PKG_CONFIG) --libs dbus-1` $(LIBS)
dnsmasq.pot : $(OBJS:.o=.c) dnsmasq.h config.h
xgettext -d dnsmasq --foreign-user --keyword=_ -o dnsmasq.pot -i $(OBJS:.o=.c)
......
#!/bin/sh
for f in *.mo; do
install -d $1/${f/.mo/}/LC_MESSAGES
install -m 644 $f $1/${f/.mo/}/LC_MESSAGES/dnsmasq.mo
echo installing $1/${f/.mo/}/LC_MESSAGES/dnsmasq.mo
install -d $1/${f%.mo}/LC_MESSAGES
install -m 644 $f $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
echo installing $1/${f%.mo}/LC_MESSAGES/dnsmasq.mo
done
This packaging is now unmaintained in the dnsmasq source: dnsmasq is
included in Suse proper, and up-to-date packages are now available
from
ftp://ftp.suse.com/pub/people/ug/
......@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.32
Version: 2.33
Release: 1
Copyright: GPL
Group: Productivity/Networking/DNS/Servers
......@@ -106,6 +106,6 @@ rm -rf $RPM_BUILD_ROOT
/usr/sbin/dnsmasq
/usr/share/locale/*/LC_MESSAGES/*
%doc %{_mandir}/man8/dnsmasq.8.gz
%doc %{_mandir}/*/man8/dnsmasq.8.gz
CFLAGS?= -O2
all: dhcp_release.c
$(CC) $(CFLAGS) $(RPM_OPT_FLAGS) -Wall -W dhcp_release.c -o dhcp_release
clean:
rm -f *~ *.o core dhcp_release
This script can be used to implement persistent leases on openWRT, DD-WRT
etc. Persistent leases are good: if the lease database is lost on a
reboot, then it will eventually be restored as hosts renew their
leases. Until a host renews (which may take hours/days) it will
not exist in the DNS if dnsmasq's DDNS function is in use.
*WRT systems remount all non-volatile fileystems read-only after boot,
so the normal leasefile will not work. They do, however have NV
storage, accessed with the nvram command:
/usr/lib # nvram
usage: nvram [get name] [set name=value] [unset name] [show]
The principle is that leases are kept in NV variable with data
corresponding to the line in a leasefile:
dnsmasq_lease_192.168.1.56=3600 00:41:4a:05:80:74 192.168.1.56 * *
By giving dnsmasq the leasefile-ro command, it no longer creates or writes a
leasefile; responsibility for maintaining the lease database transfers
to the lease change script. At startup, in leasefile-ro mode,
dnsmasq will run
"<lease_change_script> init"
and read whatever that command spits out, expecting it to
be in dnsmasq leasefile format.
So the lease change script, given "init" as argv[1] will
suck existing leases out of the NVRAM and emit them from
stdout in the correct format.
The second part of the problem is keeping the NVRAM up-to-date: this
is done by the lease-change script which dnsmasq runs when a lease is
updated. When it is called with argv[1] as "old", "add", or "del"
it updates the relevant nvram entry.
So, dnsmasq should be run as :
dnsmasq --leasefile-ro --dhcp-script=/path/to/lease_update.sh
or the same flags added to /etc/dnsmasq.conf
Notes:
This needs dnsmasq-2.33 or later to work.
This technique will work with, or without, compilation with
HAVE_BROKEN_RTC. Compiling with HAVE_BROKEN_RTC is
_highly_recommended_ for this application since is avoids problems
with the system clock being warped by NTP, and it vastly reduces the
number of writes to the NVRAM. With HAVE_BROKEN_RTC, NVRAM is updated
only when a lease is created or destroyed; without it, a write occurs
every time a lease is renewed.
It probably makes sense to restrict the number of active DHCP leases
to an appropriate number using dhcp-lease-max. On a new DD_WRT system,
there are about 10K bytes free in the NVRAM. Each lease record is
about 100 bytes, so restricting the number of leases to 50 will limit
use to half that. (The default limit in the distributed source is 150)
Any UI script which reads the dnsmasq leasefile will have to be
ammended, probably by changing it to read the output of
`lease_update init` instead.
Thanks:
To Steve Horbachuk for checks on the script and debugging beyond the
call of duty.
Simon Kelley
Fri Jul 28 11:51:13 BST 2006
/* Copyright (c) 2006 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_release <interface> <address> <MAC address> <client_id>
MUST be run as root - will fail otherwise. */
/* Send a DHCPRELEASE message via the specified interface
to tell the local DHCP server to delete a particular lease.
The interface argument is the interface in which a DHCP
request _would_ be received if it was coming from the client,
rather than being faked up here.
The address argument is a dotted-quad IP addresses and mandatory.
The MAC address is colon separated hex, and is mandatory. It may be
prefixed by an address-type byte followed by -, eg
10-11:22:33:44:55:66
but if the address-type byte is missing it is assumed to be 1, the type
for ethernet. This encoding is the one used in dnsmasq lease files.
The client-id is optional. If it is "*" then it treated as being missing.
*/
#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>
#define DHCP_CHADDR_MAX 16
#define BOOTREQUEST 1
#define DHCP_COOKIE 0x63825363
#define OPTION_SERVER_IDENTIFIER 54
#define OPTION_CLIENT_ID 61
#define OPTION_MESSAGE_TYPE 53
#define OPTION_END 255
#define DHCPRELEASE 7
#define DHCP_SERVER_PORT 67
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 int parse_hex(char *in, unsigned char *out, int maxlen, int *mac_type)
{
int i = 0;
char *r;
if (mac_type)
*mac_type = 0;
while (maxlen == -1 || i < maxlen)
{
for (r = in; *r != 0 && *r != ':' && *r != '-'; r++);
if (*r == 0)
maxlen = i;
if (r != in )
{
if (*r == '-' && i == 0 && mac_type)
{
*r = 0;
*mac_type = strtol(in, NULL, 16);
mac_type = NULL;
}
else
{
*r = 0;
out[i] = strtol(in, NULL, 16);
i++;
}
}
in = r+1;
}
return i;
}
int main(int argc, char **argv)
{
struct in_addr server, lease;
int mac_type;
struct dhcp_packet packet;
unsigned char *p = packet.options;
struct sockaddr_in dest;
struct ifreq ifr;
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (argc < 4 || argc > 5)
{
fprintf(stderr, "usage: dhcp_release <interface> <addr> <mac> [<client_id>]\n");
exit(1);
}
if (fd == -1)
{
perror("cannot create socket");
exit(1);
}
/* This voodoo fakes up a packet coming from the correct interface, which really matters for
a DHCP server */
strcpy(ifr.ifr_name, argv[1]);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(fd, SIOCGIFADDR, &ifr) == -1 || setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) == -1)
{
perror("cannot setup interface");
exit(1);
}
server = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
lease.s_addr = inet_addr(argv[2]);
memset(&packet, 0, sizeof(packet));
packet.hlen = parse_hex(argv[3], packet.chaddr, DHCP_CHADDR_MAX, &mac_type);
if (mac_type == 0)
packet.htype = ARPHRD_ETHER;
else
packet.htype = mac_type;
packet.op = BOOTREQUEST;
packet.ciaddr = lease;
packet.cookie = htonl(DHCP_COOKIE);
*(p++) = OPTION_MESSAGE_TYPE;
*(p++) = 1;
*(p++) = DHCPRELEASE;
*(p++) = OPTION_SERVER_IDENTIFIER;
*(p++) = sizeof(server);
memcpy(p, &server, sizeof(server));
p += sizeof(server);
if (argc == 5 && strcmp(argv[4], "*") != 0)
{
unsigned int clid_len = parse_hex(argv[4], p+2, 255, NULL);
*(p++) = OPTION_CLIENT_ID;
*(p++) = clid_len;
p += clid_len;
}
*(p++) = OPTION_END;
dest.sin_family = AF_INET;
dest.sin_port = ntohs(DHCP_SERVER_PORT);
dest.sin_addr = server;
if (sendto(fd, &packet, sizeof(packet), 0,
(struct sockaddr *)&dest, sizeof(dest)) == 1)
{
perror("sendto failed");
exit(1);
}
return 0;
}
#!/bin/sh
# Copyright (c) 2006 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.
# if $1 is add del or old, this is a dnsmasq-called lease-change
# script, update the nvram database. if $1 is init, emit a
# dnsmasq-format lease file to stdout representing the current state of the
# database, this is called by dnsmasq at startup.
NVRAM=/usr/sbin/nvram
PREFIX=dnsmasq_lease_
# Arguments.
# $1 is action (add, del, old)
# $2 is MAC
# $3 is address
# $4 is hostname (optional, may be unset)
# env.
# DNSMASQ_LEASE_LENGTH or DNSMASQ_LEASE_EXPIRES (which depends on HAVE_BROKEN_RTC)
# DNSMASQ_CLIENT_ID (optional, may be unset)
# File.
# length|expires MAC addr hostname|* CLID|*
# Primary key is address.
NVRAM=/usr/sbin/nvram
PREFIX=dnsmasq_lease_
if [ ${1} = init ] ; then
${NVRAM} show | sed -n -e "/^${PREFIX}.*/ s/^.*=//p"
else
if [ ${1} = del ] ; then
${NVRAM} unset ${PREFIX}${3}
fi
if [ ${1} = old ] || [ ${1} = add ] ; then
${NVRAM} set ${PREFIX}${3}="${DNSMASQ_LEASE_LENGTH:-}${DNSMASQ_LEASE_EXPIRES:-} ${2} ${3} ${4:-*} ${DNSMASQ_CLIENT_ID:-*}"
fi
${NVRAM} commit
fi
......@@ -326,6 +326,12 @@ Disable negative caching. Negative caching allows dnsmasq to remember
identical queries without forwarding them again. This flag disables
negative caching.
.TP
.B \-0, --dns-forward-max
Set the maximum number of concurrent DNS queries. Unanswered queries
time out after 20 seconds. If you sometimes see the log message
"forwarding table overflow: check for server loops." then it is worth
experimenting with this setting. The default value is 150.
.TP
.B \-F, --dhcp-range=[[net:]network-id,]<start-addr>,<end-addr>[[,<netmask>],<broadcast>][,<default lease time>]
Enable the DHCP server. Addresses will be given out from the range
<start-addr> to <end-addr> and from statically defined addresses given
......@@ -541,22 +547,27 @@ excluded from dnsmasq at compile time, in which case an error will
occur. In any case note that ISC leasefile integration is a deprecated
feature. It should not be used in new installations, and will be
removed in a future release.
.TP
.TP
.B \-6 --dhcp-script=<path>
Whenever a new DHCP lease is created, or an old one destroyed, the
binary specified by this option is run. The arguments to the binary
binary specified by this option is run. The arguments to the process
are "add", "old" or "del", the MAC
address of the host (or "<null>"), the IP address, and the hostname,
if known. "add" means a lease has been created, "del" means it has
been destroyed, "old" is a notification of an existing lease when
dnsmasq starts or a change to MAC address or hostname of an existing lease.
dnsmasq starts or a change to MAC address or hostname of an existing
lease (also, lease length or expiry and client-id, if leasefile-ro is set).
The process is run as any unprivileged user which dnsmasq
runs as, so it may be necessary to inhibit dropping of the root user,
using the
.B -u
directive, if the script needs root privs.
The environment is inherited from the invoker of dnsmasq,
and all file decriptors are
The environment is inherited from the invoker of dnsmasq, and if the
host provided a client-id, this is stored in the variable
DNSMASQ_CLIENT_ID. If dnsmasq was compiled with HAVE_BROKEN_RTC, then
the length of the lease (in seconds) is stored in
DNSMASQ_LEASE_LENGTH, otherwise the time of lease expiry is stored in DNSMASQ_LEASE_EXPIRES.
All file decriptors are
closed except stdin, stdout and stderr which are open to /dev/null
(except in debug mode).
The script is not invoked concurrently: if subsequent lease
......@@ -565,6 +576,20 @@ invokation exits. At dnsmasq startup, the script will be invoked for
all existing leases as they are read from the lease file. Expired
leases will be called with "del" and others with "old". <path>
must be an absolute pathname, no PATH search occurs.
.TP
.B \-9, --leasefile-ro
Completely suppress use of the lease database file. The file will not
be created, read, or written. Change the way the lease-change
script (if one is provided) is called, so that the lease database may
be maintained in external storage by the script. In addition to the
invokations given in
.B --dhcp-script
the lease-change script is called once, at dnsmasq startup, with the
single argument "init". When called like this the script should write
the saved state of the lease database, in dnsmasq leasefile format, to
stdout and exit with zero exit code. Setting this
option also forces the leasechange script to be called on changes
to the client-id and lease length and expiry time.
.TP
.B \-s, --domain=<domain>
Specifies the domain for the DHCP server. This has two effects;
......
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.
......@@ -10,9 +10,9 @@
GNU General Public License for more details.
*/
#define VERSION "2.32"
#define VERSION "2.33"
#define FTABSIZ 150 /* max number of outstanding requests */
#define FTABSIZ 150 /* max number of outstanding requests (default) */
#define MAX_PROCS 20 /* max no children for TCP requests */
#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
#define EDNS_PKTSZ 1280 /* default max EDNS.0 UDP packet from RFC2671 */
......
......@@ -227,15 +227,19 @@ void dhcp_packet(struct daemon *daemon, time_t now)
if (mess->giaddr.s_addr)
{
/* Send to BOOTP relay */
if (!dest.sin_port)
dest.sin_port = htons(DHCP_SERVER_PORT);
dest.sin_port = htons(DHCP_SERVER_PORT);
dest.sin_addr = mess->giaddr;
}
else if (mess->ciaddr.s_addr)
{
dest.sin_addr = mess->ciaddr;
if (!dest.sin_port)
dest.sin_port = htons(DHCP_CLIENT_PORT);
/* If the client's idea of its own address tallys with
the source address in the request packet, we believe the
source port too, and send back to that. */
if (dest.sin_addr.s_addr != mess->ciaddr.s_addr || !dest.sin_port)
{
dest.sin_port = htons(DHCP_CLIENT_PORT);
dest.sin_addr = mess->ciaddr;
}
}
#ifdef HAVE_LINUX_NETWORK
else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
......
......@@ -286,7 +286,7 @@ int main (int argc, char **argv)
#endif
if (daemon->dhcp &&
(i == fileno(daemon->lease_stream) ||
((daemon->lease_stream && i == fileno(daemon->lease_stream)) ||
#ifndef HAVE_LINUX_NETWORK
i == daemon->dhcp_raw_fd ||
i == daemon->dhcp_icmp_fd ||
......@@ -362,6 +362,13 @@ int main (int argc, char **argv)
if (if_tmp->name && !if_tmp->used)
syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
if (daemon->options & OPT_NO_RESOLV)
{
if (daemon->resolv_files && !daemon->resolv_files->is_default)
syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
daemon->resolv_files = NULL;
}
if (daemon->dhcp)
{
struct dhcp_context *dhcp_tmp;
......@@ -460,47 +467,50 @@ int main (int argc, char **argv)
if (!(daemon->options & OPT_NO_POLL))
{
struct resolvc *res = daemon->resolv_files, *latest = NULL;
struct resolvc *res, *latest;
struct stat statbuf;
time_t last_change = 0;
/* There may be more than one possible file.
Go through and find the one which changed _last_.
Warn of any which can't be read. */
while (res)
{
if (stat(res->name, &statbuf) == -1)
{
if (!res->logged)
syslog(LOG_WARNING, _("failed to access %s: %m"), res->name);
res->logged = 1;
}
else
{
res->logged = 0;
if (statbuf.st_mtime != res->mtime &&
difftime(statbuf.st_mtime, last_change) > 0.0)
{
last_change = statbuf.st_mtime;
latest = res;
}
}
res = res->next;
}
for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
if (stat(res->name, &statbuf) == -1)
{
if (!res->logged)
syslog(LOG_WARNING, _("failed to access %s: %m"), res->name);
res->logged = 1;
}
else
{
res->logged = 0;
if (statbuf.st_mtime != res->mtime)
{
res->mtime = statbuf.st_mtime;
if (difftime(statbuf.st_mtime, last_change) > 0.0)
{
last_change = statbuf.st_mtime;
latest = res;
}
}
}
if (latest)
{
static int warned = 0;
if (reload_servers(latest->name, daemon))
{
syslog(LOG_INFO, _("reading %s"), latest->name);
latest->mtime = last_change;
warned = 0;
check_servers(daemon);
}
else if (!warned)
else
{
syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
warned = 1;
latest->mtime = 0;
if (!warned)
{
syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
warned = 1;
}
}
}
}
......@@ -544,7 +554,7 @@ int main (int argc, char **argv)
if (daemon->tcp_pids[i] != 0)
kill(daemon->tcp_pids[i], SIGALRM);
if (daemon->dhcp)
if (daemon->lease_stream)
fclose(daemon->lease_stream);
exit(0);
......
......@@ -110,6 +110,7 @@ extern int capset(cap_user_header_t header, cap_user_data_t data);
#define OPT_DBUS 524288
#define OPT_BOOTP_DYNAMIC 1048576
#define OPT_NO_PING 2097152
#define OPT_LEASE_RO 4194304
struct all_addr {
union {
......@@ -290,7 +291,8 @@ struct dhcp_lease {
char *hostname, *fqdn; /* name from client-hostname option or config */
char auth_name; /* hostname came from config, not from client */
char new; /* newly created */
char old; /* read from leasefile */
char changed; /* modified */
char aux_changed; /* CLID or expiry changed */
time_t expires; /* lease expiry */
#ifdef HAVE_BROKEN_RTC
unsigned int length;
......@@ -422,7 +424,7 @@ struct daemon {
struct bogus_addr *bogus_addr;
struct server *servers;
int log_fac; /* log facility */
int cachesize;
int cachesize, ftabsize;
int port, query_port;
unsigned long local_ttl;
struct hostsfile *addn_hosts;
......
......@@ -14,7 +14,7 @@
static struct frec *frec_list = NULL;
static struct frec *get_new_frec(time_t now);
static struct frec *get_new_frec(struct daemon *daemon, time_t now);
static struct frec *lookup_frec(unsigned short id);
static struct frec *lookup_frec_by_sender(unsigned short id,
union mysockaddr *addr,
......@@ -232,7 +232,7 @@ static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *ud
if (gotname)
flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain);
if (!flags && !(forward = get_new_frec(now)))
if (!flags && !(forward = get_new_frec(daemon, now)))
/* table full - server failure. */
flags = F_NEG;
......@@ -837,7 +837,7 @@ unsigned char *tcp_request(struct daemon *daemon, int confd, time_t now,
}
}
static struct frec *get_new_frec(time_t now)
static struct frec *get_new_frec(struct daemon *daemon, time_t now)
{
struct frec *f = frec_list, *oldest = NULL;
time_t oldtime = now;
......@@ -870,7 +870,7 @@ static struct frec *get_new_frec(time_t now)
return oldest;
}
if (count > FTABSIZ)
if (count > daemon->ftabsize)
{ /* limit logging rate so syslog isn't DOSed either */
if (!warntime || difftime(now, warntime) > LOGRATE)
{
......
This diff is collapsed.
......@@ -24,7 +24,7 @@ struct myoption {
};
#endif
#define OPTSTRING "531yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:"
#define OPTSTRING "9531yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:4:6:7:8:0:"
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
......@@ -95,6 +95,8 @@ static const struct myoption opts[] =
{"dhcp-script", 1, 0, '6'},
{"conf-dir", 1, 0, '7'},
{"log-facility", 1, 0 ,'8'},
{"leasefile-ro", 0, 0, '9'},
{"dns-forward-max", 1, 0, '0'},
{ NULL, 0, 0, 0 }
};
......@@ -125,6 +127,7 @@ static const struct optflags optmap[] = {
{ '1', OPT_DBUS },
{ '3', OPT_BOOTP_DYNAMIC },
{ '5', OPT_NO_PING },
{ '9', OPT_LEASE_RO },
{ 'v', 0},
{ 'w', 0},
{ 0, 0 }
......@@ -195,7 +198,9 @@ static const struct {
{ "-5, --no-ping", gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL },
{ "-6, --dhcp-script=path", gettext_noop("Script to run on DHCP lease creation and destruction."), NULL },
{ "-7, --conf-dir=path", gettext_noop("Read configuration from all the files in this directory."), NULL },
{ "-8, --log-facility=facilty", gettext_noop("Log to this syslog facility."), NULL },
{ "-8, --log-facility=facilty", gettext_noop("Log to this syslog facility. (defaults to DAEMON)"), NULL },
{ "-9, --leasefile-ro", gettext_noop("Read leases at startup, but never write the lease file."), NULL },
{ "-0, --dns-forward-max=<queries>", gettext_noop("Maximum number of concurrent DNS queries. (defaults to %s)"), "!" },
{ NULL, NULL, NULL }
};
......@@ -324,6 +329,8 @@ static void do_usage(void)
sprintf(buff, "%d", EDNS_PKTSZ);
else if (strcmp(usage[i].arg, "&") == 0)
sprintf(buff, "%d", MAXLEASES);
else if (strcmp(usage[i].arg, "!") == 0)
sprintf(buff, "%d", FTABSIZ);
else
strcpy(buff, usage[i].arg);
}
......@@ -810,7 +817,12 @@ static char *one_opt(struct daemon *daemon, int option, char *arg, char *problem
if (!atoi_check(arg, &daemon->port))
option = '?';
break;
case '0':
if (!atoi_check(arg, &daemon->ftabsize))
option = '?';
break;
case 'P':
{
int i;
......@@ -1818,6 +1830,7 @@ struct daemon *read_opts(int argc, char **argv, char *compile_opts)
/* Set defaults - everything else is zero or NULL */
daemon->cachesize = CACHESIZ;
daemon->ftabsize = FTABSIZ;
daemon->port = NAMESERVER_PORT;
daemon->default_resolv.is_default = 1;
daemon->default_resolv.name = RESOLVFILE;
......@@ -1956,11 +1969,10 @@ struct daemon *read_opts(int argc, char **argv, char *compile_opts)
mx->target = daemon->mxtarget;
}
if (daemon->options & OPT_NO_RESOLV)
daemon->resolv_files = 0;
else if (daemon->resolv_files &&
(daemon->resolv_files)->next &&
(daemon->options & OPT_NO_POLL))
if (!(daemon->options & OPT_NO_RESOLV) &&
daemon->resolv_files &&
daemon->resolv_files->next &&
(daemon->options & OPT_NO_POLL))
die(_("only one resolv.conf file allowed in no-poll mode."), NULL);
if (daemon->options & OPT_RESOLV_DOMAIN)
......@@ -1968,11 +1980,13 @@ struct daemon *read_opts(int argc, char **argv, char *compile_opts)
char *line;
FILE *f;
if (!daemon->resolv_files || (daemon->resolv_files)->next)
if ((daemon->options & OPT_NO_RESOLV) ||
!daemon->resolv_files ||
(daemon->resolv_files)->next)
die(_("must have exactly one resolv.conf to read domain from."), NULL);
if (!(f = fopen((daemon->resolv_files)->name, "r")))
die(_("failed to read %s: %m"), (daemon->resolv_files)->name);
die(_("failed to read %s: %s"), (daemon->resolv_files)->name);
while ((line = fgets(buff, MAXDNAME, f)))
{
......
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