summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--README34
-rw-r--r--RELNOTES138
-rw-r--r--client/clparse.c17
-rw-r--r--client/dhclient-script.819
-rw-r--r--client/dhclient.817
-rw-r--r--client/dhclient.c41
-rw-r--r--common/alloc.c4
-rw-r--r--common/comapi.c4
-rw-r--r--common/conflex.c20
-rw-r--r--common/discover.c16
-rw-r--r--common/dispatch.c6
-rw-r--r--common/dns.c45
-rw-r--r--common/execute.c4
-rw-r--r--common/options.c196
-rw-r--r--common/parse.c9
-rw-r--r--common/print.c4
-rw-r--r--common/resolv.c5
-rw-r--r--common/tables.c26
-rw-r--r--common/tr.c12
-rw-r--r--common/tree.c4
-rw-r--r--dhcpctl/omshell.c6
-rw-r--r--includes/cf/linux.h9
-rw-r--r--includes/cf/sunos5-5.h11
-rw-r--r--includes/dhcp.h5
-rw-r--r--includes/dhcpd.h16
-rw-r--r--includes/dhctoken.h3
-rw-r--r--includes/omapip/trace.h4
-rw-r--r--includes/osdep.h14
-rw-r--r--omapip/alloc.c31
-rw-r--r--omapip/array.c7
-rw-r--r--omapip/buffer.c6
-rw-r--r--omapip/generic.c7
-rw-r--r--omapip/handle.c7
-rw-r--r--omapip/hash.c4
-rw-r--r--omapip/protocol.c7
-rw-r--r--omapip/support.c7
-rw-r--r--omapip/trace.c13
-rw-r--r--relay/dhcrelay.c154
-rw-r--r--server/confpars.c11
-rw-r--r--server/db.c47
-rw-r--r--server/dhcp.c280
-rw-r--r--server/dhcpd.825
-rw-r--r--server/dhcpd.conf.58
-rw-r--r--server/failover.c157
-rw-r--r--server/mdb.c87
-rw-r--r--server/omapi.c69
-rw-r--r--server/salloc.c4
48 files changed, 1170 insertions, 452 deletions
diff --git a/LICENSE b/LICENSE
index b737de68..c912b639 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-# Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+# Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
# Copyright (c) 1995-2003 by Internet Software Consortium
#
# Permission to use, copy, modify, and distribute this software for any
diff --git a/README b/README
index 6f8fd178..96f886c7 100644
--- a/README
+++ b/README
@@ -367,6 +367,18 @@ Linux 2.1 and later kernels do not use SO_BINDTODEVICE or require the
broadcast address hack, but do support multiple interfaces, using the
Linux Packet Filter.
+ LINUX: 802.1q VLAN INTERFACES
+
+If you're using 802.1q vlan interfaces on Linux, it is necessary to
+vconfig the subinterface(s) to rewrite the 802.1q information out of
+packets received by the dhcpd daemon via LPF:
+
+ vconfig set_flag eth1.523 1 1
+
+Note that this may affect the performance of your system, since the
+Linux kernel must rewrite packets received via this interface. For
+more information, consult the vconfig man pages.
+
SCO
SCO has the same problem as Linux (described earlier). The thing is,
@@ -446,18 +458,24 @@ systems, although it may occur with other systems as well. If you
encounter this symptom, and you are running the DHCP server on a
machine with a single broadcast network interface, you may wish to
edit the includes/site.h file and uncomment the #define USE_SOCKETS
-line. Then type ``make clean; make''.
+line. Then type ``make clean; make''. As an alternative workaround,
+it has been reported that running 'snoop' will cause the dhcp server
+to start receiving packets. So the practice reported to us is to run
+snoop at dhcpd startup time, with arguments to cause it to receive one
+packet and exit.
+
+ snoop -c 1 udp port 67 > /dev/null &
The DHCP client on Solaris will only work with DLPI. If you run it
and it just keeps saying it's sending DHCPREQUEST packets, but never
gets a response, you may be having DLPI trouble as described above.
-If so, we have no solution to offer at this time. Also, because
-Solaris requires you to "plumb" an interface before it can be detected
-by the DHCP client, you must either specify the name(s) of the
-interface(s) you want to configure on the command line, or must plumb
-the interfaces prior to invoking the DHCP client. This can be done
-with ``ifconfig iface plumb'', where iface is the name of the
-interface (e.g., ``ifconfig hme0 plumb'').
+If so, we have no solution to offer at this time, aside from the above
+workaround which should also work here. Also, because Solaris requires
+you to "plumb" an interface before it can be detected by the DHCP client,
+you must either specify the name(s) of the interface(s) you want to
+configure on the command line, or must plumb the interfaces prior to
+invoking the DHCP client. This can be done with ``ifconfig iface plumb'',
+where iface is the name of the interface (e.g., ``ifconfig hme0 plumb'').
It should be noted that Solaris versions from 2.6 onward include a
DHCP client that you can run with ``/sbin/ifconfig iface dhcp start''
diff --git a/RELNOTES b/RELNOTES
index 38aac4d8..692af08e 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -63,6 +63,144 @@ and for prodding me into improving it.
- RFC3942 compliance, site-local option spaces start at 224 now, not 128.
||| THIS NEEDS TO BE SPELLED OUT IN THE NEW FEATURES LIST |||
+
+ Changes since 3.0.4b2
+
+- Null-termination sensing for certain clients that unfortunatley require
+ it in DHCPINFORM processing was repaired.
+
+- The host-name option and a few others were moved from "X" format to "t"
+ format to be compatible with new NULL handling functions.
+
+- DHCPINFORM processing is a little more careful about return addressing
+ its responses, or if responding via a relay. The INFORM related
+ messages also log the 'effective client ip address' rather than the
+ client's supplied ciaddr (since some clients produce null ciaddrs).
+
+- The server was inappropriately sending leases to the RESET state in the
+ event that multiple active leases were found to match a singly-identified
+ client. This was changed to RELEASED (by accepting a different, ACTIVE
+ binding, the client is implicitly releasing its lease). This repairs a
+ bug wherein secondary servers in failover pairs detecting this condition
+ move leases to RESET, and primaries refuse to accept that state
+ transition (properly).
+
+- The memset-after-dmalloc() changes made in 3.0.4b1 have been backed out.
+
+ Changes since 3.0.4b1
+
+- Command line parsing in omshell was repaired - it no longer closes
+ STDIN after reading one line.
+
+- The resolver library no longer closes the /etc/resolv.conf file
+ descriptor it opened twice.
+
+- Changes to trailing NULL removal in 't' option-atoms has been rethought,
+ it now includes 'd' (domain name) types, and tries hard not to rewind an
+ option beyond the start of the text field it is un-terminating.
+
+ Changes since 3.0.3
+
+- A DDNS update handling function was misusing the DNS error codes, rather
+ than the internal generic result enumeration. The result is a confusing
+ syslog line, logging the wrong condition.
+
+- The DHCP Server was not checking pool balance in the case where it brought
+ a non-ACTIVE lease out of storage for a client that was returning to use
+ a lease it once had long ago, and had since expired.
+
+- Failover peers no longer bother to look for free leases to allocate when
+ they already found the client's ACTIVE lease. DISCOVERs are load balanced
+ wether freely-allocated or not, unless the server doubts the peer has
+ leases to allocate.
+
+- Fixed a bug in dhcrelay agent addition code that suppressed trailing
+ PAD options - it was suppressing only one trailng PAD option, rather
+ than the entire block of them.
+
+- Fixed some unlikely overlapping-region memcpy() bugs in dhcrelay agent
+ option addition and stripping code. Added a few sanity checks.
+
+- Added some sanity checks to OMAPI connection/authentication code.
+
+- dmalloc() memset()'s the non-debug (data) portion of the allocated
+ memory to zero. Code that memset()'s the result returned by dmalloc() to
+ zero is redundant. These redundancies were removed.
+
+- Some type declaration corrections to u_int16_t were made in common/tr.c
+ (Token Ring support) thanks to a patch from Jason Vas Dias at RedHat.
+
+- A failover bug that was allowing leases that EXPIRED or were RELEASED
+ where tsfp and tstp are identical timestamps to languish in these
+ transitional states has been repaired. As a side effect, lease
+ databases should be kept more consistent overall, not just for these
+ transitional states.
+
+- If the lease db is deleted out from under the daemon, and it moves to rewrite
+ the db, it will go ahead with the operation and move the new db into place
+ once it detects the old db does not exist.
+
+- dhclient now ignores IRDA, SIT, and IEEE1394 network interfaces, as it
+ is either nonsensical or (in the case of IEEE1394) is not known to support
+ these interfaces. Thanks to Marius Gedminas and Andrew Pollock of Debian.
+
+- Some previously undocumented reasons for dhclient-script invoking has
+ been doucmented in the dhclient-script.8 manpage.
+
+- Failover potential expiry calculations (TSTP) have been corrected. Results
+ should be substantially more consistent, and proper given the constraints.
+
+- Adjusted lease state validation checks in potential-conflict, to
+ account for possible clock skew similarly to normal state, and several
+ previously illegal transitions were made legal (ex: active->released).
+
+- An impossible sanity check was removed from omapi/buffer.c, thanks to a
+ patch from 'infamous42md'.
+
+- An OMAPI host/network byte order problem in lease time values has been
+ repaired.
+
+- Several minor bugs, largely relating to treating 8-byte time values as
+ 4-byte entities, have been repaired after careful review of the FreeBSD
+ ports collection's patch set. Thanks to the nameless entities who have
+ contributed to the FreeBSD ports.
+
+- When writing a trace file, the file is now created with permissions 0600,
+ to help administrators avoid accidentally publicising sensitive config
+ data.
+
+- The calculation of the maximum size of DHCP packets no longer includes
+ Ethernet framing overhead. The result is that the 'Maximum Message
+ Size' option advertised by clients, or the default value 576, is no
+ longer reduced by 14 bytes, and instead directly reflects the IP level
+ MTU (and the default, minimum allowed IP MTU of 576).
+
+- The special status of RELEASED/EXPIRED/RESET leases when a server
+ is operating in partner-down was fixed. It no longer requires a
+ lease be twice the MCLT beyond STOS to 'reallocate', and the expiry
+ event to turn these into FREE leases without peer acknowledgement
+ (after STOS+MCLT) has been repaired.
+
+- Compilation on older Solaris systems (lacking /usr/include/sys/int_types.h)
+ has been repaired.
+
+- "append"ing a string onto the end of a "t" type option (such as the
+ domain-name field) that had been improperly NULL-terminated by the
+ DHCP server will no longer result in a truncated string containing
+ only the option from the server, and not the expected appended value.
+ Thanks to a patch from Jason Vas Dias at RedHat.
+
+- File handlers on configuration state (config files and lease dbs) should
+ be treated consistently, regardless of wether TRACING is defined or not.
+
+- The linux build environment has had some minor improvements - better
+ sensing of 64-bit pointer sizes (only used for establishing an icmp_id),
+ and corrections to #if operators regarding LINUX_MAJOR should it ever
+ move to 3.[01].x.
+
+- The server now tries harder to survive the condition where it is unable
+ to open a new lease file to rewrite the lease state database.
+
Changes since 3.0.3b3
- dhclient.conf documentation for interface {} was updated to reflect recent
diff --git a/client/clparse.c b/client/clparse.c
index 32d82d02..dbd54ebe 100644
--- a/client/clparse.c
+++ b/client/clparse.c
@@ -3,7 +3,7 @@
Parser for dhclient config and lease files... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: clparse.c,v 1.64 2005/03/17 20:14:55 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: clparse.c,v 1.65 2006/02/24 23:16:27 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -173,7 +173,6 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
status = (cfile -> warnings_occurred
? ISC_R_BADPARSE
: ISC_R_SUCCESS);
- close (file);
end_parse (&cfile);
return status;
}
@@ -210,7 +209,6 @@ void read_client_leases ()
} while (1);
- close (file);
end_parse (&cfile);
}
@@ -774,7 +772,13 @@ int interface_or_dummy (struct interface_info **pi, const char *name)
if ((status = interface_allocate (&ip, MDL)) != ISC_R_SUCCESS)
log_fatal ("Can't record interface %s: %s",
name, isc_result_totext (status));
- strcpy (ip -> name, name);
+
+ if (strlen(name) >= sizeof(ip->name)) {
+ interface_dereference(&ip, MDL);
+ return 0;
+ }
+ strcpy(ip->name, name);
+
if (dummy_interfaces) {
interface_reference (&ip -> next,
dummy_interfaces, MDL);
@@ -994,7 +998,8 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp)
skip_to_semi (cfile);
break;
}
- interface_or_dummy (ipp, val);
+ if (!interface_or_dummy (ipp, val))
+ log_fatal ("Can't allocate interface %s.", val);
break;
case NAME:
diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
index 078dfe3c..214bff79 100644
--- a/client/dhclient-script.8
+++ b/client/dhclient-script.8
@@ -1,6 +1,6 @@
.\" dhclient-script.8
.\"
-.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -28,7 +28,7 @@
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
.\" ``http://www.nominum.com''.
.\"
-.\" $Id: dhclient-script.8,v 1.10 2005/03/17 20:14:55 dhankins Exp $
+.\" $Id: dhclient-script.8,v 1.11 2006/02/24 23:16:27 dhankins Exp $
.\"
.TH dhclient-script 8
.SH NAME
@@ -97,7 +97,8 @@ defines a set of variables in the environment, and then invokes
.B CLIENTBINDIR/dhclient-script.
In all cases, $reason is set to the name of the reason why the script
has been invoked. The following reasons are currently defined:
-MEDIUM, PREINIT, BOUND, RENEW, REBIND, REBOOT, EXPIRE, FAIL and TIMEOUT.
+MEDIUM, PREINIT, BOUND, RENEW, REBIND, REBOOT, EXPIRE, FAIL, STOP, RELEASE,
+NBI and TIMEOUT.
.PP
.SH MEDIUM
The DHCP client is requesting that an interface's media type
@@ -175,6 +176,18 @@ The DHCP client has been unable to contact any DHCP servers, and any
leases that have been tested have not proved to be valid. The
parameters from the last lease tested should be deconfigured. This
can be handled in the same way as EXPIRE.
+.SH STOP
+The dhclient has been informed to shut down gracefully, the
+dhclient-script should unconfigure or shutdown the interface as
+appropriate.
+.SH RELEASE
+The dhclient has been executed using the -r flag, indicating that the
+administrator wishes it to release its lease(s). dhclient-script should
+unconfigure or shutdown the interface.
+.SH NBI
+No-Broadcast-Interfaces...dhclient was unable to find any interfaces
+upon which it believed it should commence DHCP. What dhclient-script
+should do in this situation is entirely up to the implementor.
.SH TIMEOUT
The DHCP client has been unable to contact any DHCP servers.
However, an old lease has been identified, and its parameters have
diff --git a/client/dhclient.8 b/client/dhclient.8
index 9c00737c..65f56c0c 100644
--- a/client/dhclient.8
+++ b/client/dhclient.8
@@ -24,7 +24,7 @@
.\" Support and other services are available for ISC products - see
.\" http://www.isc.org for more information.
.\"
-.\" $Id: dhclient.8,v 1.17 2005/03/17 20:14:55 dhankins Exp $
+.\" $Id: dhclient.8,v 1.18 2006/02/24 23:16:27 dhankins Exp $
.\"
.TH dhclient 8
.SH NAME
@@ -39,6 +39,10 @@ dhclient - Dynamic Host Configuration Protocol Client
.B -d
]
[
+.B -e
+.I VAR=value
+]
+[
.B -q
]
[
@@ -188,6 +192,15 @@ flag should be specified. This is useful when running the client
under a debugger, or when running it out of inittab on System V
systems.
.PP
+The dhclient daemon creates its own environment when executing the
+dhclient-script to do the grunt work of interface configuration.
+To define extra environment variables and their values, use the
+.B -e
+flag, followed by the environment variable name and value assignment,
+just as one would assign a variable in a shell. Eg:
+.B -e
+.I IF_METRIC=1
+.PP
The client normally prints a startup message and displays the
protocol sequence to the standard error descriptor until it has
acquired an address, and then only logs messages using the
@@ -238,7 +251,7 @@ broadcast interface may be added after system startup. The
.B -w
flag can be used to cause the client not to exit when it doesn't find
any such interfaces. The
-.B omshell (8)
+.B omshell (1)
program can then be used to notify the client when a network interface
has been added or removed, so that the client can attempt to configure an IP
address on that interface.
diff --git a/client/dhclient.c b/client/dhclient.c
index 3f31650e..762d6d76 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -3,7 +3,7 @@
DHCP Client. */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,7 +32,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhclient.c,v 1.132 2005/03/17 20:14:55 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: dhclient.c,v 1.133 2006/02/24 23:16:27 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -212,10 +212,10 @@ int main (argc, argv, envp)
if (status != ISC_R_SUCCESS)
log_fatal ("Can't record interface %s:%s",
argv [i], isc_result_totext (status));
- if (strlen (argv [i]) > sizeof tmp -> name)
- log_fatal ("%s: interface name too long (max %ld)",
- argv [i], (long)strlen (argv [i]));
- strcpy (tmp -> name, argv [i]);
+ if (strlen(argv[i]) >= sizeof(tmp->name))
+ log_fatal("%s: interface name too long (is %ld)",
+ argv [i], (long)strlen(argv[i]));
+ strcpy(tmp->name, argv[i]);
if (interfaces) {
interface_reference (&tmp -> next,
interfaces, MDL);
@@ -789,11 +789,9 @@ void dhcpack (packet)
client -> new -> renewal = TIME_MAX;
/* Now introduce some randomness to the renewal time: */
- if (client -> new -> renewal <= TIME_MAX / 3 - 3)
- client -> new -> renewal =
- (((client -> new -> renewal + 3) * 3 / 4) +
- (random () % /* XXX NUMS */
- ((client -> new -> renewal + 3) / 4)));
+ if (client->new->renewal <= ((TIME_MAX / 3) - 3))
+ client->new->renewal = (((client->new->renewal * 3) + 3) / 4) +
+ (((random() % client->new->renewal) + 3) / 4);
/* Same deal with the rebind time. */
oc = lookup_option (&dhcp_universe, client -> new -> options,
@@ -1404,22 +1402,17 @@ void send_discover (cpp)
between zero and two times itself. On average, this means
that it will double with every transmission. */
if (increase) {
- if (!client -> interval)
- client -> interval =
- client -> config -> initial_interval;
+ if (!client->interval)
+ client->interval = client->config->initial_interval;
else
- client -> interval += ((random () >> 2) %
- (2 * client -> interval));
+ client->interval += random() % (2 * client->interval);
/* Don't backoff past cutoff. */
- if (client -> interval >
- client -> config -> backoff_cutoff)
- client -> interval =
- ((client -> config -> backoff_cutoff / 2)
- + ((random () >> 2) %
- client -> config -> backoff_cutoff));
- } else if (!client -> interval)
- client -> interval = client -> config -> initial_interval;
+ if (client->interval > client->config->backoff_cutoff)
+ client->interval = (client->config->backoff_cutoff / 2)
+ + (random() % client->config->backoff_cutoff);
+ } else if (!client->interval)
+ client->interval = client->config->initial_interval;
/* If the backoff would take us to the panic timeout, just use that
as the interval. */
diff --git a/common/alloc.c b/common/alloc.c
index deed7b6e..a3bf7418 100644
--- a/common/alloc.c
+++ b/common/alloc.c
@@ -3,7 +3,7 @@
Memory allocation... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: alloc.c,v 1.55 2005/03/17 20:14:56 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: alloc.c,v 1.56 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
diff --git a/common/comapi.c b/common/comapi.c
index bdeb990a..4efae78f 100644
--- a/common/comapi.c
+++ b/common/comapi.c
@@ -3,7 +3,7 @@
OMAPI object interfaces for the DHCP server. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -41,7 +41,7 @@
#ifndef lint
static char copyright[] =
-"$Id: comapi.c,v 1.11 2005/03/17 20:14:57 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: comapi.c,v 1.12 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
diff --git a/common/conflex.c b/common/conflex.c
index 509b9911..55b8face 100644
--- a/common/conflex.c
+++ b/common/conflex.c
@@ -3,7 +3,7 @@
Lexical scanner for dhcpd config file... */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: conflex.c,v 1.95 2005/03/17 20:14:57 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: conflex.c,v 1.96 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -95,10 +95,14 @@ isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
isc_result_t end_parse (cfile)
struct parse **cfile;
{
- if ((*cfile) -> bufsiz)
- dfree ((*cfile) -> inbuf, MDL);
- dfree (*cfile, MDL);
- *cfile = (struct parse *)0;
+ /* "Memory" config files have no file. */
+ if ((*cfile)->file != -1)
+ close((*cfile)->file);
+
+ if ((*cfile)->bufsiz)
+ dfree((*cfile)->inbuf, MDL);
+ dfree(*cfile, MDL);
+ *cfile = NULL;
return ISC_R_SUCCESS;
}
@@ -464,7 +468,7 @@ static enum dhcp_token read_number (c, cfile)
log_fatal("read_number():%s:%d: impossible case", MDL);
}
#else /* OLD_LEXER */
- if (!seenx && (c == 'x') {
+ if (!seenx && (c == 'x')) {
seenx = 1;
} else if (!isascii (c) || !isxdigit (c)) {
if (c != EOF) {
@@ -573,6 +577,8 @@ static enum dhcp_token intern (atom, dfv)
return ADDRESS;
if (!strcasecmp (atom + 1, "ctive"))
return TOKEN_ACTIVE;
+ if (!strcasecmp (atom + 1, "tsfp"))
+ return ATSFP;
break;
case 'b':
if (!strcasecmp (atom + 1, "ackup"))
diff --git a/common/discover.c b/common/discover.c
index 9c8a5ca4..16796d78 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -3,7 +3,7 @@
Network input dispatcher... */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: discover.c,v 1.48 2005/03/17 20:14:57 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: discover.c,v 1.49 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -463,6 +463,18 @@ void discover_interfaces (state)
#ifdef HAVE_ARPHRD_ROSE
case ARPHRD_ROSE:
#endif
+#ifdef HAVE_ARPHRD_IRDA
+ case ARPHRD_IRDA:
+ /* ignore infrared interfaces. */
+#endif
+#ifdef HAVE_ARPHRD_SIT
+ case ARPHRD_SIT:
+ /* ignore IPv6-in-IPv4 interfaces. */
+#endif
+#ifdef HAVE_ARPHRD_IEEE1394
+ case ARPHRD_IEEE1394:
+ /* ignore IEEE1394 interfaces. */
+#endif
#ifdef HAVE_ARPHRD_LOOPBACK
case ARPHRD_LOOPBACK:
/* ignore loopback interface */
diff --git a/common/dispatch.c b/common/dispatch.c
index ce9d1ba3..60a05251 100644
--- a/common/dispatch.c
+++ b/common/dispatch.c
@@ -3,7 +3,7 @@
Network input dispatcher... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dispatch.c,v 1.65 2005/03/17 20:14:57 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: dispatch.c,v 1.66 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -42,7 +42,7 @@ static char copyright[] =
struct timeout *timeouts;
static struct timeout *free_timeouts;
-void set_time (u_int32_t t)
+void set_time(TIME t)
{
/* Do any outstanding timeouts. */
if (cur_time != t) {
diff --git a/common/dns.c b/common/dns.c
index b6ad19e2..fed20889 100644
--- a/common/dns.c
+++ b/common/dns.c
@@ -3,7 +3,7 @@
Domain Name Service subroutines. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -33,7 +33,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dns.c,v 1.37 2005/03/17 20:14:58 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: dns.c,v 1.38 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -527,6 +527,7 @@ isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
ns_updrec *updrec;
isc_result_t result;
char ddns_address [16];
+ const char *logstr;
if (ddns_addr.len != 4)
return ISC_R_INVALIDARG;
@@ -712,24 +713,36 @@ isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
*/
result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
- if (result != ISC_R_SUCCESS) {
- if (result == YXRRSET || result == YXDOMAIN ||
- result == NXRRSET || result == NXDOMAIN)
- log_error ("Forward map from %.*s to %s already in use",
- (int)ddns_fwd_name -> len,
- (const char *)ddns_fwd_name -> data,
- ddns_address);
- else
- log_error ("Can't update forward map %.*s to %s: %s",
+ switch (result) {
+ case ISC_R_SUCCESS:
+ logstr = NULL;
+ break;
+
+ case ISC_R_YXRRSET:
+ case ISC_R_YXDOMAIN:
+ logstr = "DHCID mismatch, belongs to another client.";
+ break;
+
+ case ISC_R_NXRRSET:
+ case ISC_R_NXDOMAIN:
+ logstr = "Has an A record but no DHCID, not mine.";
+ break;
+
+ default:
+ logstr = isc_result_totext(result);
+ break;
+ }
+
+ if (logstr != NULL)
+ log_error("Forward map from %.*s to %s FAILED: %s",
(int)ddns_fwd_name -> len,
(const char *)ddns_fwd_name -> data,
- ddns_address, isc_result_totext (result));
-
- } else {
- log_info ("Added new forward map from %.*s to %s",
+ ddns_address, logstr);
+ else
+ log_info("Added new forward map from %.*s to %s",
(int)ddns_fwd_name -> len,
(const char *)ddns_fwd_name -> data, ddns_address);
- }
+
#if defined (DEBUG_DNS_UPDATES)
print_dns_status ((int)result, &updqueue);
#endif
diff --git a/common/execute.c b/common/execute.c
index cc5a6ba6..a5fc03a4 100644
--- a/common/execute.c
+++ b/common/execute.c
@@ -3,7 +3,7 @@
Support for executable statements. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1998-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: execute.c,v 1.47 2005/03/17 20:14:58 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: execute.c,v 1.48 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
diff --git a/common/options.c b/common/options.c
index 4d291402..28066ed0 100644
--- a/common/options.c
+++ b/common/options.c
@@ -3,7 +3,7 @@
DHCP options parsing and reassembly. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: options.c,v 1.88 2005/03/17 20:14:59 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: options.c,v 1.89 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
@@ -486,7 +486,7 @@ int cons_options (inpacket, outpacket, lease, client_state,
unsigned priority_list [PRIORITY_COUNT];
int priority_len;
unsigned char buffer [4096]; /* Really big buffer... */
- unsigned main_buffer_size;
+ unsigned main_buffer_size, mb_max;
unsigned mainbufix, bufix, agentix;
int fileix;
int snameix;
@@ -546,8 +546,10 @@ int cons_options (inpacket, outpacket, lease, client_state,
main_buffer_size = 576 - DHCP_FIXED_LEN;
/* Set a hard limit at the size of the output buffer. */
- if (main_buffer_size > sizeof buffer)
- main_buffer_size = sizeof buffer;
+ mb_max = sizeof(buffer) - (((overload & 1) ? DHCP_FILE_LEN : 0) +
+ ((overload & 2) ? DHCP_SNAME_LEN : 0));
+ if (main_buffer_size > mb_max)
+ main_buffer_size = mb_max;
/* Preload the option priority list with mandatory options. */
priority_len = 0;
@@ -721,14 +723,14 @@ int cons_options (inpacket, outpacket, lease, client_state,
priority_len = 1;
agentix +=
store_options (0, &outpacket -> options [agentix],
- 1500 - DHCP_FIXED_LEN - agentix,
+ DHCP_OPTION_LEN - agentix,
inpacket, lease, client_state,
in_options, cfg_options, scope,
priority_list, priority_len,
0, 0, 0, (char *)0);
/* Tack a DHO_END option onto the packet if we need to. */
- if (agentix < 1500 - DHCP_FIXED_LEN && need_endopt)
+ if (agentix < DHCP_OPTION_LEN && need_endopt)
outpacket -> options [agentix++] = DHO_END;
/* Figure out the length. */
@@ -961,7 +963,7 @@ int store_options (ocount, buffer, buflen, packet, lease, client_state,
unsigned incr = length;
int consumed = 0;
int *pix;
- char *base;
+ unsigned char *base;
/* Try to fit it in the options buffer. */
if (!splitup &&
@@ -1063,6 +1065,169 @@ int store_options (ocount, buffer, buflen, packet, lease, client_state,
return bufix;
}
+/* Return true if the format string has a variable length text option
+ * ("t"), return false otherwise.
+ */
+
+int
+format_has_text(format)
+ const char *format;
+{
+ const char *p;
+ int retval = 0;
+
+ p = format;
+ while (*p != '\0') {
+ switch (*p++) {
+ case 'd':
+ case 't':
+ return 1;
+
+ /* These symbols are arbitrary, not fixed or
+ * determinable length...text options with them is
+ * invalid.
+ */
+ case 'A':
+ case 'a':
+ case 'X':
+ case 'x':
+ return 0;
+
+ /* 'E' is variable length, but not arbitrary...you
+ * can find its length if you can find an END option.
+ * N is one-byte in length but trails a name of a
+ * space defining the enumeration values. So treat
+ * both the same - valid, fixed-length fields.
+ */
+ case 'E':
+ case 'N':
+ /* Consume the space name. */
+ while ((*p != '\0') && (*p++ != '.'))
+ ;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* Determine the minimum length of a DHCP option prior to any variable
+ * or inconsistent length formats, according to its configured format
+ * variable (and possibly from supplied option cache contents for variable
+ * length format symbols).
+ */
+
+int
+format_min_length(format, oc)
+ const char *format;
+ struct option_cache *oc;
+{
+ const char *p;
+ int min_len = 0;
+ int last_size = 0;
+
+ p = format;
+ while (*p != '\0') {
+ switch (*p++) {
+ case 'I': /* IPv4 Address */
+ case 'l': /* int32_t */
+ case 'L': /* uint32_t */
+ case 'T': /* Lease Time, uint32_t equivalent */
+ min_len += 4;
+ last_size = 4;
+ break;
+
+ case 's': /* int16_t */
+ case 'S': /* uint16_t */
+ min_len += 2;
+ last_size = 2;
+ break;
+
+ case 'N': /* Enumeration in 1-byte values. */
+ /* Consume space name. */
+ while ((*p != '\0') && (*p++ != '.'))
+ ;
+
+ /* Fall Through to handle as one-byte field */
+
+ case 'b': /* int8_t */
+ case 'B': /* uint8_t */
+ case 'F': /* Flag that is always true. */
+ case 'f': /* Flag */
+ min_len++;
+ last_size = 1;
+ break;
+
+ case 'o': /* Last argument is optional. */
+ min_len -= last_size;
+ case 'e': /* Encapsulation hint (there is an 'E' later). */
+ last_size = 0;
+ break;
+
+ case 'E': /* Encapsulated options. */
+ /* Consume space name. */
+ while ((*p != '\0') && (*p++ != '.'))
+ ;
+
+ /* Find an end option, or find that the encaps options
+ * go all the way to the end (or beyond) of the data
+ * portion of the option.
+ */
+ last_size = 0;
+ while (min_len < oc->data.len) {
+ if (oc->data.data[min_len] == DHO_END) {
+ min_len++;
+ last_size++;
+ break;
+ } else if (oc->data.data[min_len] == DHO_PAD) {
+ min_len++;
+ last_size++;
+ } else if ((min_len + 1) < oc->data.len) {
+ min_len += oc->data.data[min_len+1]+2;
+ last_size += oc->data.data[min_len+1]+2;
+ } else {
+ /* Suboption length is out of bounds,
+ * advance beyond the code/length pair
+ * to trigger below error conditonal.
+ */
+ min_len += 2;
+ last_size += 2;
+ break;
+ }
+ }
+
+ if (min_len > oc->data.len) {
+ log_error("format_min_length(%s): "
+ "Encapsulated options exceed "
+ "supplied buffer.", format);
+ return INT_MAX;
+ }
+
+ break;
+
+ case 'd': /* "Domain name" */
+ case 't': /* "ASCII Text" */
+ case 'X': /* "ASCII or Hex Conditional */
+ case 'x': /* "Hex" */
+ case 'A': /* Array of all that precedes. */
+ case 'a': /* Array of preceding symbol. */
+ return min_len;
+
+ default:
+ /* No safe value is known. */
+ log_error("format_min_length(%s): No safe value "
+ "for unknown format symbols.", format);
+ return INT_MAX;
+ }
+ }
+
+ return min_len;
+}
+
+
/* Format the specified option so that a human can easily read it. */
const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
@@ -1517,6 +1682,21 @@ int save_option_buffer (struct universe *universe,
op -> option = option;
+ /* If this option is ultimately a text option, null determinate to
+ * comply with RFC2132 section 2. Mark a flag so this can be sensed
+ * later to echo NULLs back to clients that supplied them (they
+ * probably expect them).
+ */
+ if (format_has_text(option->format)) {
+ int min_len = format_min_length(option->format, op);
+
+ while ((op->data.len > min_len) &&
+ (op->data.data[op->data.len-1] == '\0')) {
+ op->data.len--;
+ op->flags |= OPTION_HAD_NULLS;
+ }
+ }
+
/* Now store the option. */
save_option (universe, options, op);
diff --git a/common/parse.c b/common/parse.c
index 7b425f09..9882c150 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -3,7 +3,7 @@
Common parser code for dhcpd and dhclient. */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.106 2005/03/17 20:14:59 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.107 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -405,6 +405,7 @@ void parse_lease_time (cfile, timep)
{
const char *val;
enum dhcp_token token;
+ u_int32_t num;
token = next_token (&val, (unsigned *)0, cfile);
if (token != NUMBER) {
@@ -412,9 +413,9 @@ void parse_lease_time (cfile, timep)
skip_to_semi (cfile);
return;
}
- convert_num (cfile, (unsigned char *)timep, val, 10, 32);
+ convert_num(cfile, (unsigned char *)&num, val, 10, 32);
/* Unswap the number - convert_num returns stuff in NBO. */
- *timep = ntohl (*timep); /* XXX */
+ *timep = ntohl(num);
parse_semi (cfile);
}
diff --git a/common/print.c b/common/print.c
index f46d8c55..60e029b7 100644
--- a/common/print.c
+++ b/common/print.c
@@ -3,7 +3,7 @@
Turn data structures into printable text. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: print.c,v 1.57 2005/03/17 20:14:59 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: print.c,v 1.58 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
diff --git a/common/resolv.c b/common/resolv.c
index 61ff3a7d..5f34f78b 100644
--- a/common/resolv.c
+++ b/common/resolv.c
@@ -3,7 +3,7 @@
Parser for /etc/resolv.conf file. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: resolv.c,v 1.17 2005/03/17 20:15:00 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: resolv.c,v 1.18 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -172,7 +172,6 @@ void read_resolv_conf (parse_time)
} else
dl = dp;
}
- close (file);
end_parse (&cfile);
}
diff --git a/common/tables.c b/common/tables.c
index 66021bb8..6f177b0b 100644
--- a/common/tables.c
+++ b/common/tables.c
@@ -3,7 +3,7 @@
Tables of information... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: tables.c,v 1.53 2005/03/17 20:15:00 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: tables.c,v 1.54 2006/02/24 23:16:28 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -58,6 +58,9 @@ HASH_FUNCTIONS (option, const char *, struct option, option_hash_t, 0, 0)
b - 8-bit signed integer
B - 8-bit unsigned integer
t - ASCII text
+ T - Lease Time, 32-bit unsigned integer implying a number of seconds from
+ some event. The special all-ones value means 'infinite'. May either
+ be printed as a decimal, eg, "3600", or as this name, eg, "infinite".
f - flag (true or false)
A - array of whatever precedes (e.g., IA means array of IP addresses)
a - array of the preceding character (e.g., IIa means two or more IP
@@ -102,7 +105,7 @@ struct option dhcp_options [256] = {
{ "lpr-servers", "IA", &dhcp_universe, 9 },
{ "impress-servers", "IA", &dhcp_universe, 10 },
{ "resource-location-servers", "IA", &dhcp_universe, 11 },
- { "host-name", "X", &dhcp_universe, 12 },
+ { "host-name", "t", &dhcp_universe, 12 },
{ "boot-size", "S", &dhcp_universe, 13 },
{ "merit-dump", "t", &dhcp_universe, 14 },
{ "domain-name", "t", &dhcp_universe, 15 },
@@ -152,7 +155,7 @@ struct option dhcp_options [256] = {
{ "dhcp-rebinding-time", "L", &dhcp_universe, 59 },
{ "vendor-class-identifier", "X", &dhcp_universe, 60 },
{ "dhcp-client-identifier", "X", &dhcp_universe, 61 },
- { "nwip-domain", "X", &dhcp_universe, 62 },
+ { "nwip-domain", "t", &dhcp_universe, 62 },
{ "nwip-suboptions", "Enwip.", &dhcp_universe, 63 },
{ "nisplus-domain", "t", &dhcp_universe, 64 },
{ "nisplus-servers", "IA", &dhcp_universe, 65 },
@@ -176,8 +179,8 @@ struct option dhcp_options [256] = {
{ "unknown-83", "X", &dhcp_universe, 83 },
{ "unknown-84", "X", &dhcp_universe, 84 },
{ "nds-servers", "IA", &dhcp_universe, 85 },
- { "nds-tree-name", "X", &dhcp_universe, 86 },
- { "nds-context", "X", &dhcp_universe, 87 },
+ { "nds-tree-name", "t", &dhcp_universe, 86 },
+ { "nds-context", "t", &dhcp_universe, 87 },
{ "unknown-88", "X", &dhcp_universe, 88 },
{ "unknown-89", "X", &dhcp_universe, 89 },
{ "unknown-90", "X", &dhcp_universe, 90 },
@@ -208,7 +211,7 @@ struct option dhcp_options [256] = {
{ "unknown-115", "X", &dhcp_universe, 115 },
{ "unknown-116", "X", &dhcp_universe, 116 },
{ "unknown-117", "X", &dhcp_universe, 117 },
- { "subnet-selection", "X", &dhcp_universe, 118 },
+ { "subnet-selection", "I", &dhcp_universe, 118 },
{ "unknown-119", "X", &dhcp_universe, 119 },
{ "unknown-120", "X", &dhcp_universe, 120 },
{ "unknown-121", "X", &dhcp_universe, 121 },
@@ -608,6 +611,15 @@ struct option nwip_options [256] = {
{ "unknown-end", "e", &nwip_universe, 255 },
};
+/* Note that the "FQDN suboption space" does not reflect the FQDN option
+ * format - rather, this is a handy "virtualization" of a flat option
+ * which makes manual configuration and presentation of some of its
+ * contents easier (each of these suboptions is a fixed-space field within
+ * the fqdn contents - domain and host names are derived from a common field,
+ * and differ in the left and right hand side of the leftmost dot, fqdn is
+ * the combination of the two).
+ */
+
struct universe fqdn_universe;
struct option fqdn_options [256] = {
{ "pad", "", &fqdn_universe, 0 },
diff --git a/common/tr.c b/common/tr.c
index f653ed6c..b246b113 100644
--- a/common/tr.c
+++ b/common/tr.c
@@ -4,7 +4,7 @@
Contributed in May of 1999 by Andrew Chittenden */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -28,7 +28,7 @@
#ifndef lint
static char copyright[] =
-"$Id: tr.c,v 1.8 2005/03/17 20:15:01 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: tr.c,v 1.9 2006/02/24 23:16:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -59,8 +59,8 @@ struct routing_entry {
struct routing_entry *next;
unsigned char addr[TR_ALEN];
unsigned char iface[5];
- __u16 rcf; /* route control field */
- __u16 rseg[8]; /* routing registers */
+ u_int16_t rcf; /* route control field */
+ u_int16_t rseg[8]; /* routing registers */
unsigned long access_time; /* time we last used this entry */
};
@@ -217,7 +217,7 @@ static int insert_source_routing (trh, interface)
if (rover != NULL) {
/* success: route that frame */
if ((rover->rcf & TR_RCF_LEN_MASK) >> 8) {
- __u16 rcf = rover->rcf;
+ u_int16_t rcf = rover->rcf;
memcpy(trh->rseg,rover->rseg,sizeof(trh->rseg));
rcf ^= TR_RCF_DIR_BIT;
rcf &= ~TR_RCF_BROADCAST_MASK;
@@ -254,7 +254,7 @@ static void save_source_routing(trh, interface)
struct routing_entry *rover;
struct timeval now;
unsigned char saddr[TR_ALEN];
- __u16 rcf = 0;
+ u_int16_t rcf = 0;
gettimeofday(&now, NULL);
diff --git a/common/tree.c b/common/tree.c
index b302a363..e1988641 100644
--- a/common/tree.c
+++ b/common/tree.c
@@ -3,7 +3,7 @@
Routines for manipulating parse trees... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: tree.c,v 1.103 2005/03/17 20:15:01 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: tree.c,v 1.104 2006/02/24 23:16:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c
index bf28ed49..afac88ac 100644
--- a/dhcpctl/omshell.c
+++ b/dhcpctl/omshell.c
@@ -3,7 +3,7 @@
Examine and modify omapi objects. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: omshell.c,v 1.10 2005/03/17 20:15:04 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: omshell.c,v 1.11 2006/02/24 23:16:29 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include <time.h>
@@ -180,7 +180,7 @@ int main (int argc, char **argv, char **envp)
if (fgets (buf, sizeof(buf), stdin) == NULL)
break;
- status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>", 1);
+ status = new_parse (&cfile, -1, buf, strlen(buf), "<STDIN>", 1);
check(status, "new_parse()");
token = next_token (&val, (unsigned *)0, cfile);
diff --git a/includes/cf/linux.h b/includes/cf/linux.h
index 6cefbd0e..1028a9ca 100644
--- a/includes/cf/linux.h
+++ b/includes/cf/linux.h
@@ -5,7 +5,7 @@
Based on a configuration originally supplied by Jonathan Stone. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -98,6 +98,11 @@ extern int h_errno;
#define VOIDPTR void *
+#if defined(__alpha__) || defined(__amd64__) || defined(__ia64__) || \
+ defined(__sparc64__)
+# define PTRSIZE_64BIT
+#endif
+
#define EOL '\n'
/* Time stuff... */
@@ -108,7 +113,7 @@ extern int h_errno;
#define GET_TIME(x) time ((x))
#if (LINUX_MAJOR >= 2)
-# if (LINUX_MINOR >= 1)
+# if ((LINUX_MAJOR > 2) || (LINUX_MINOR >= 1))
# if defined (USE_DEFAULT_NETWORK)
# define USE_LPF
# endif
diff --git a/includes/cf/sunos5-5.h b/includes/cf/sunos5-5.h
index 8a1e416b..e9789d60 100644
--- a/includes/cf/sunos5-5.h
+++ b/includes/cf/sunos5-5.h
@@ -3,7 +3,7 @@
System dependencies for Solaris 2.x (tested on 2.5 with gcc)... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,9 +34,18 @@
/* SunOS defines uint*_t and int*_t, but not u_int*_t. */
+#if defined(_SYS_INT_TYPES_H)
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
+#else /* Older SunOS has no idea what these things mean. */
+typedef int8_t char
+typedef int16_t short
+typedef int32_t int /* If _LP64, long is 64-bit, int is still 32. */
+typedef u_int8_t unsigned char
+typedef u_int16_t unsigned short
+typedef u_int32_t unsigned int
+#endif /* defined(_SYS_INT_TYPES_H) */
/* The jmp_buf type is an array on Solaris, so we can't dereference it
and must declare it differently. */
diff --git a/includes/dhcp.h b/includes/dhcp.h
index 76dd07bb..38a594ea 100644
--- a/includes/dhcp.h
+++ b/includes/dhcp.h
@@ -3,7 +3,7 @@
Protocol structures... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -30,8 +30,7 @@
* To learn more about Vixie Enterprises, see ``http://www.vix.com''.
*/
-#define DHCP_UDP_OVERHEAD (14 + /* Ethernet header */ \
- 20 + /* IP header */ \
+#define DHCP_UDP_OVERHEAD (20 + /* IP header */ \
8) /* UDP header */
#define DHCP_SNAME_LEN 64
#define DHCP_FILE_LEN 128
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index dc3f52e8..d9c911fc 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -187,6 +187,9 @@ struct option_cache {
struct expression *expression;
struct option *option;
struct data_string data;
+
+ #define OPTION_HAD_NULLS 0x00000001
+ u_int32_t flags;
};
struct option_state {
@@ -313,8 +316,15 @@ struct lease {
struct lease_state *state;
+ /* 'tsfp' is more of an 'effective' tsfp. It may be calculated from
+ * stos+mclt for example if it's an expired lease and the server is
+ * in partner-down state. 'atsfp' is zeroed whenever a lease is
+ * updated - and only set when the peer acknowledges it. This
+ * ensures every state change is transmitted.
+ */
TIME tstp; /* Time sent to partner. */
TIME tsfp; /* Time sent from partner. */
+ TIME atsfp; /* Actual time sent from partner. */
TIME cltt; /* Client last transaction time. */
struct lease *next_pending;
};
@@ -331,7 +341,7 @@ struct lease_state {
struct option_state *options;
struct data_string parameter_request_list;
int max_message_size;
- u_int32_t expiry, renewal, rebind;
+ TIME expiry, renewal, rebind;
struct data_string filename, server_name;
int got_requested_address;
int got_server_identifier;
@@ -993,6 +1003,8 @@ int store_options PROTO ((int *, unsigned char *, unsigned, struct packet *,
struct option_state *, struct binding_scope **,
unsigned *, int, unsigned, unsigned,
int, const char *));
+int format_has_text(const char *);
+int format_min_length(const char *, struct option_cache *);
const char *pretty_print_option PROTO ((struct option *, const unsigned char *,
unsigned, int, int));
int get_option (struct data_string *, struct universe *,
@@ -1769,7 +1781,7 @@ int if_readsocket PROTO ((omapi_object_t *));
void reinitialize_interfaces PROTO ((void));
/* dispatch.c */
-void set_time (u_int32_t);
+void set_time(TIME);
struct timeval *process_outstanding_timeouts (struct timeval *);
void dispatch PROTO ((void));
isc_result_t got_one PROTO ((omapi_object_t *));
diff --git a/includes/dhctoken.h b/includes/dhctoken.h
index 858e3c98..da8da3d4 100644
--- a/includes/dhctoken.h
+++ b/includes/dhctoken.h
@@ -308,7 +308,8 @@ enum dhcp_token {
REFRESH = 612,
DOMAIN_NAME = 613,
DO_FORWARD_UPDATE = 614,
- KNOWN_CLIENTS = 615
+ KNOWN_CLIENTS = 615,
+ ATSFP = 616
};
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
diff --git a/includes/omapip/trace.h b/includes/omapip/trace.h
index d48c3700..028798f8 100644
--- a/includes/omapip/trace.h
+++ b/includes/omapip/trace.h
@@ -3,7 +3,7 @@
Definitions for omapi tracing facility... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -90,7 +90,7 @@ typedef struct {
void trace_free_all (void);
int trace_playback (void);
int trace_record (void);
-isc_result_t trace_init (void (*set_time) (u_int32_t), const char *, int);
+isc_result_t trace_init (void (*set_time) (TIME), const char *, int);
isc_result_t trace_begin (const char *, const char *, int);
isc_result_t trace_write_packet (trace_type_t *, unsigned, const char *,
const char *, int);
diff --git a/includes/osdep.h b/includes/osdep.h
index 5d1bc912..d5f47a76 100644
--- a/includes/osdep.h
+++ b/includes/osdep.h
@@ -3,7 +3,7 @@
Operating system dependencies... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -271,6 +271,18 @@
# define HAVE_ARPHRD_ROSE
#endif
+#if defined (ARPHRD_IRDA) && !defined (HAVE_ARPHRD_IRDA)
+# define HAVE_ARPHRD_IRDA
+#endif
+
+#if defined (ARPHRD_SIT) && !defined (HAVE_ARPHRD_SIT)
+# define HAVE_ARPHRD_SIT
+#endif
+
+#if defined (ARPHRD_IEEE1394) & !defined (HAVE_ARPHRD_IEEE1394)
+# define HAVE_ARPHRD_IEEE1394
+#endif
+
#if defined (ARPHRD_IEEE802) && !defined (HAVE_ARPHRD_IEEE802)
# define HAVE_ARPHRD_IEEE802
#endif
diff --git a/omapip/alloc.c b/omapip/alloc.c
index 46c0bc38..c1c47283 100644
--- a/omapip/alloc.c
+++ b/omapip/alloc.c
@@ -4,7 +4,7 @@
protocol... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -33,6 +33,11 @@
* ``http://www.nominum.com''.
*/
+#ifndef lint
+static char copyright[] =
+"$Id: alloc.c,v 1.26 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium, Inc. All rights reserved.\n";
+#endif /* not lint */
+
#include <omapip/omapip_p.h>
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
@@ -59,13 +64,21 @@ VOIDPTR dmalloc (size, file, line)
const char *file;
int line;
{
- unsigned char *foo = malloc (size + DMDSIZE);
+ unsigned char *foo;
+ unsigned len;
int i;
VOIDPTR *bar;
#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
struct dmalloc_preamble *dp;
#endif
+
+ len = size + DMDSIZE;
+ if (len < size)
+ return (VOIDPTR)0;
+
+ foo = malloc(len);
+
if (!foo)
return (VOIDPTR)0;
bar = (VOIDPTR)(foo + DMDOFFSET);
@@ -804,10 +817,18 @@ isc_result_t omapi_typed_data_new (const char *file, int line,
s = va_arg (l, char *);
val = strlen (s);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
+ if (len < val) {
+ va_end(l);
+ return ISC_R_INVALIDARG;
+ }
break;
case omapi_datatype_data:
val = va_arg (l, unsigned);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
+ if (len < val) {
+ va_end(l);
+ return ISC_R_INVALIDARG;
+ }
break;
case omapi_datatype_object:
len = OMAPI_TYPED_DATA_OBJECT_LEN;
@@ -923,8 +944,12 @@ isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
const char *file, int line)
{
omapi_data_string_t *new;
+ unsigned nlen;
- new = dmalloc (OMAPI_DATA_STRING_EMPTY_SIZE + len, file, line);
+ nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len;
+ if (nlen < len)
+ return ISC_R_INVALIDARG;
+ new = dmalloc (nlen, file, line);
if (!new)
return ISC_R_NOMEMORY;
memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
diff --git a/omapip/array.c b/omapip/array.c
index ac92afc1..246d9b78 100644
--- a/omapip/array.c
+++ b/omapip/array.c
@@ -3,7 +3,7 @@
Subroutines that support the omapi extensible array type. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,6 +32,11 @@
* ``http://www.nominum.com''.
*/
+#ifndef lint
+static char ocopyright[] =
+"$Id: array.c,v 1.4 2006/02/24 23:16:30 dhankins Exp $ Copyright 2004-2006 Internet Systems Consortium.";
+#endif
+
#include <omapip/omapip_p.h>
/* Allocate a new extensible array. */
diff --git a/omapip/buffer.c b/omapip/buffer.c
index 74f53dae..6b751eff 100644
--- a/omapip/buffer.c
+++ b/omapip/buffer.c
@@ -3,7 +3,7 @@
Buffer access functions for the object management protocol... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -154,10 +154,6 @@ static isc_result_t omapi_connection_reader_trace (omapi_object_t *h,
return ISC_R_INVALIDARG;
c = (omapi_connection_object_t *)h;
- /* Make sure c -> bytes_needed is valid. */
- if (c -> bytes_needed < 0)
- return ISC_R_INVALIDARG;
-
/* See if there are enough bytes. */
if (c -> in_bytes >= OMAPI_BUF_SIZE - 1 &&
c -> in_bytes > c -> bytes_needed)
diff --git a/omapip/generic.c b/omapip/generic.c
index 8b9446f9..aaf0058c 100644
--- a/omapip/generic.c
+++ b/omapip/generic.c
@@ -3,7 +3,7 @@
Subroutines that support the generic object. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,6 +32,11 @@
* ``http://www.nominum.com''.
*/
+#ifndef lint
+static char ocopyright[] =
+"$Id: generic.c,v 1.12 2006/02/24 23:16:30 dhankins Exp $ Copyright 2004-2006 Internet Systems Consortium.";
+#endif
+
#include <omapip/omapip_p.h>
OMAPI_OBJECT_ALLOC (omapi_generic,
diff --git a/omapip/handle.c b/omapip/handle.c
index cffa4d60..e1298354 100644
--- a/omapip/handle.c
+++ b/omapip/handle.c
@@ -3,7 +3,7 @@
Functions for maintaining handles on objects. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,6 +32,11 @@
* ``http://www.nominum.com''.
*/
+#ifndef lint
+static char ocopyright[] =
+"$Id: handle.c,v 1.8 2006/02/24 23:16:30 dhankins Exp $ Copyright 2004-2006 Internet Systems Consortium.";
+#endif
+
#include <omapip/omapip_p.h>
/* The handle table is a hierarchical tree designed for quick mapping
diff --git a/omapip/hash.c b/omapip/hash.c
index 1bd5e124..4b1833b9 100644
--- a/omapip/hash.c
+++ b/omapip/hash.c
@@ -3,7 +3,7 @@
Routines for manipulating hash tables... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: hash.c,v 1.6 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: hash.c,v 1.7 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include <omapip/omapip_p.h>
diff --git a/omapip/protocol.c b/omapip/protocol.c
index a9d76f75..f5bbb0c7 100644
--- a/omapip/protocol.c
+++ b/omapip/protocol.c
@@ -3,7 +3,7 @@
Functions supporting the object management protocol... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,6 +32,11 @@
* ``http://www.nominum.com''.
*/
+#ifndef lint
+static char ocopyright[] =
+"$Id: protocol.c,v 1.30 2006/02/24 23:16:30 dhankins Exp $ Copyright 2004-2006 Internet Systems Consortium.";
+#endif
+
#include <omapip/omapip_p.h>
OMAPI_OBJECT_ALLOC (omapi_protocol, omapi_protocol_object_t,
diff --git a/omapip/support.c b/omapip/support.c
index 4efde414..4f5538ec 100644
--- a/omapip/support.c
+++ b/omapip/support.c
@@ -3,7 +3,7 @@
Subroutines providing general support for objects. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,6 +32,11 @@
* ``http://www.nominum.com''.
*/
+#ifndef lint
+static char ocopyright[] =
+"$Id: support.c,v 1.28 2006/02/24 23:16:30 dhankins Exp $ Copyright 2004-2006 Internet Systems Consortium.";
+#endif
+
#include <omapip/omapip_p.h>
omapi_object_type_t *omapi_type_connection;
diff --git a/omapip/trace.c b/omapip/trace.c
index 9245d27a..8d3ce623 100644
--- a/omapip/trace.c
+++ b/omapip/trace.c
@@ -5,7 +5,7 @@
transactions... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 2001-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -32,10 +32,15 @@
* learn more about Nominum, Inc., see ``http://www.nominum.com''.
*/
+#ifndef lint
+static char ocopyright[] =
+"$Id: trace.c,v 1.12 2006/02/24 23:16:30 dhankins Exp $ Copyright 2004-2006 Internet Systems Consortium.";
+#endif
+
#include <omapip/omapip_p.h>
#if defined (TRACING)
-void (*trace_set_time_hook) (u_int32_t);
+void (*trace_set_time_hook) (TIME);
static int tracing_stopped;
static int traceoutfile;
static int traceindex;
@@ -97,7 +102,7 @@ int trace_record ()
return 0;
}
-isc_result_t trace_init (void (*set_time) (u_int32_t),
+isc_result_t trace_init (void (*set_time) (TIME),
const char *file, int line)
{
trace_type_t *root_type;
@@ -136,7 +141,7 @@ isc_result_t trace_begin (const char *filename,
return ISC_R_INVALIDARG;
}
- traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0644);
+ traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600);
if (traceoutfile < 0) {
log_error ("%s(%d): trace_begin: %s: %m",
file, line, filename);
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
index a6ec87b1..452724b1 100644
--- a/relay/dhcrelay.c
+++ b/relay/dhcrelay.c
@@ -3,7 +3,7 @@
DHCP/BOOTP Relay Agent. */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1997-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhcrelay.c,v 1.53 2005/03/17 20:15:24 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: dhcrelay.c,v 1.54 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -537,7 +537,7 @@ int strip_relay_agent_options (in, out, packet, length)
unsigned length;
{
int is_dhcp = 0;
- u_int8_t *op, *sp, *max;
+ u_int8_t *op, *nextop, *sp, *max;
int good_agent_option = 0;
int status;
@@ -583,6 +583,13 @@ int strip_relay_agent_options (in, out, packet, length)
if (!is_dhcp)
goto skip;
+ /* Do not process an agent option if it exceeds the
+ * buffer. Fail this packet.
+ */
+ nextop = op + op[1] + 2;
+ if (nextop > max)
+ return 0;
+
status = find_interface_by_agent_option (packet,
out, op + 2,
op [1]);
@@ -590,16 +597,26 @@ int strip_relay_agent_options (in, out, packet, length)
return 0;
if (status)
good_agent_option = 1;
- op += op [1] + 2;
+ op = nextop;
break;
skip:
/* Skip over other options. */
default:
- if (sp != op)
- memcpy (sp, op, (unsigned)(op [1] + 2));
- sp += op [1] + 2;
- op += op [1] + 2;
+ /* Fail if processing this option will exceed the
+ * buffer (op[1] is malformed).
+ */
+ nextop = op + op[1] + 2;
+ if (nextop > max)
+ return 0;
+
+ if (sp != op) {
+ memmove(sp, op, op[1] + 2);
+ sp += op[1] + 2;
+ op = nextop;
+ } else
+ op = sp = nextop;
+
break;
}
}
@@ -627,7 +644,7 @@ int strip_relay_agent_options (in, out, packet, length)
/* Make sure the packet isn't short (this is unlikely,
but WTH) */
if (length < BOOTP_MIN_LEN) {
- memset (sp, 0, BOOTP_MIN_LEN - length);
+ memset (sp, DHO_PAD, BOOTP_MIN_LEN - length);
length = BOOTP_MIN_LEN;
}
}
@@ -718,7 +735,8 @@ int add_relay_agent_options (ip, packet, length, giaddr)
struct in_addr giaddr;
{
int is_dhcp = 0, agent_options_present = 0;
- u_int8_t *op, *sp, *max, *end_pad = 0;
+ unsigned optlen;
+ u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL;
/* If we're not adding agent options to packets, we can skip
this. */
@@ -727,21 +745,35 @@ int add_relay_agent_options (ip, packet, length, giaddr)
/* If there's no cookie, it's a bootp packet, so we should just
forward it unchanged. */
- if (memcmp (packet -> options, DHCP_OPTIONS_COOKIE, 4))
+ if (memcmp(packet->options, DHCP_OPTIONS_COOKIE, 4))
return length;
max = ((u_int8_t *)packet) + length;
- sp = op = &packet -> options [4];
+
+ /* Commence processing after the cookie. */
+ sp = op = &packet->options[4];
while (op < max) {
switch (*op) {
/* Skip padding... */
case DHO_PAD:
- end_pad = sp;
+ /* Remember the first pad byte so we can commandeer
+ * padded space.
+ *
+ * XXX: Is this really a good idea? Sure, we can
+ * seemingly reduce the packet while we're looking,
+ * but if the packet was signed by the client then
+ * this padding is part of the checksum (RFC3118),
+ * and its nonpresence would break authentication.
+ */
+ if (end_pad == NULL)
+ end_pad = sp;
+
if (sp != op)
- *sp = *op;
- ++op;
- ++sp;
+ *sp++ = *op++;
+ else
+ sp = ++op;
+
continue;
/* If we see a message type, it's a DHCP packet. */
@@ -760,7 +792,8 @@ int add_relay_agent_options (ip, packet, length, giaddr)
but if we do, we have to leave it alone. */
if (!is_dhcp)
goto skip;
- end_pad = 0;
+
+ end_pad = NULL;
/* There's already a Relay Agent Information option
in this packet. How embarrassing. Decide what
@@ -780,17 +813,28 @@ int add_relay_agent_options (ip, packet, length, giaddr)
/* Skip over the agent option and start copying
if we aren't copying already. */
- op += op [1] + 2;
+ op += op[1] + 2;
break;
skip:
/* Skip over other options. */
default:
- end_pad = 0;
- if (sp != op)
- memcpy (sp, op, (unsigned)(op [1] + 2));
- sp += op [1] + 2;
- op += op [1] + 2;
+ /* Fail if processing this option will exceed the
+ * buffer (op[1] is malformed).
+ */
+ nextop = op + op[1] + 2;
+ if (nextop > max)
+ return 0;
+
+ end_pad = NULL;
+
+ if (sp != op) {
+ memmove(sp, op, op[1] + 2);
+ sp += op[1] + 2;
+ op = nextop;
+ } else
+ op = sp = nextop;
+
break;
}
}
@@ -803,50 +847,56 @@ int add_relay_agent_options (ip, packet, length, giaddr)
/* If the packet was padded out, we can store the agent option
at the beginning of the padding. */
- if (end_pad)
+ if (end_pad != NULL)
sp = end_pad;
/* Remember where the end of the packet was after parsing
it. */
op = sp;
- /* XXX Is there room? */
+ /* Sanity check. Had better not ever happen. */
+ if ((ip->circuit_id_len > 255) || (ip->circuit_id_len < 1))
+ log_fatal("circuit id length %d out of range [1-255] on "
+ "%s\n", ip->circuit_id_len, ip->name);
+ optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */
+
+ if (ip->remote_id) {
+ if (ip->remote_id_len > 255 || ip->remote_id_len < 1)
+ log_fatal("remote id length %d out of range [1-255] "
+ "on %s\n", ip->circuit_id_len, ip->name);
+ optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */
+ }
+
+ /* We do not support relay option fragmenting (multiple options to
+ * support an option data exceeding 255 bytes).
+ */
+ if ((optlen < 3) || (optlen > 255))
+ log_fatal ("total agent option length (%u) out of range "
+ "[3 - 255] on %s\n", optlen, ip->name);
+
+ /* Is there room for the option, its code+len, and DHO_END? */
+ if ((sp > max) || (max - sp < optlen + 3))
+ return 0;
/* Okay, cons up *our* Relay Agent Information option. */
*sp++ = DHO_DHCP_AGENT_OPTIONS;
- *sp++ = 0; /* Dunno... */
+ *sp++ = optlen;
/* Copy in the circuit id... */
*sp++ = RAI_CIRCUIT_ID;
- /* Sanity check. Had better not every happen. */
- if (ip -> circuit_id_len > 255 || ip -> circuit_id_len < 1)
- log_fatal ("completely bogus circuit id length %d on %s\n",
- ip -> circuit_id_len, ip -> name);
- *sp++ = ip -> circuit_id_len;
- memcpy (sp, ip -> circuit_id, ip -> circuit_id_len);
- sp += ip -> circuit_id_len;
+ *sp++ = ip->circuit_id_len;
+ memcpy(sp, ip->circuit_id, ip->circuit_id_len);
+ sp += ip->circuit_id_len;
/* Copy in remote ID... */
- if (ip -> remote_id) {
+ if (ip->remote_id) {
*sp++ = RAI_REMOTE_ID;
- if (ip -> remote_id_len > 255 || ip -> remote_id_len < 1)
- log_fatal ("bogus remote id length %d on %s\n",
- ip -> circuit_id_len, ip -> name);
- *sp++ = ip -> remote_id_len;
- memcpy (sp, ip -> remote_id, ip -> remote_id_len);
- sp += ip -> remote_id_len;
+ *sp++ = ip->remote_id_len;
+ memcpy(sp, ip->remote_id, ip->remote_id_len);
+ sp += ip->remote_id_len;
}
- /* Relay option's total length shouldn't ever get to be more than
- 257 bytes. */
- if (sp - op > 257)
- log_fatal ("total agent option length exceeds 257 (%ld) on %s\n",
- (long)(sp - op), ip -> name);
-
- /* Calculate length of RAI option. */
- op [1] = sp - op - 2;
-
- /* Deposit an END token. */
+ /* Deposit an END option. */
*sp++ = DHO_END;
/* Recalculate total packet length. */
@@ -854,8 +904,8 @@ int add_relay_agent_options (ip, packet, length, giaddr)
/* Make sure the packet isn't short (this is unlikely, but WTH) */
if (length < BOOTP_MIN_LEN) {
- memset (sp, 0, BOOTP_MIN_LEN - length);
- length = BOOTP_MIN_LEN;
+ memset(sp, DHO_PAD, BOOTP_MIN_LEN - length);
+ return BOOTP_MIN_LEN;
}
return length;
diff --git a/server/confpars.c b/server/confpars.c
index b66567e1..e17e8ba5 100644
--- a/server/confpars.c
+++ b/server/confpars.c
@@ -3,7 +3,7 @@
Parser for dhcpd config file... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: confpars.c,v 1.149 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: confpars.c,v 1.150 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -162,7 +162,6 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
new_parse (&cfile, -1, fbuf, ulen, filename, 0); /* XXX */
#else
new_parse (&cfile, file, (char *)0, 0, filename, 0);
- close (file);
#endif
if (leasep)
status = lease_file_subparse (cfile);
@@ -2624,6 +2623,7 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
case TIMESTAMP:
case TSTP:
case TSFP:
+ case ATSFP:
case CLTT:
t = parse_date (cfile);
switch (token) {
@@ -2651,6 +2651,11 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
seenbit = 131072;
lease -> tsfp = t;
break;
+
+ case ATSFP:
+ seenbit = 262144;
+ lease->atsfp = t;
+ break;
case CLTT:
seenbit = 524288;
diff --git a/server/db.c b/server/db.c
index 80066007..55302820 100644
--- a/server/db.c
+++ b/server/db.c
@@ -3,7 +3,7 @@
Persistent database management routines for DHCPD... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: db.c,v 1.69 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: db.c,v 1.70 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -133,6 +133,14 @@ int write_lease (lease)
++errors;
}
}
+ if (lease->atsfp) {
+ t = gmtime(&lease->atsfp);
+ if (fprintf(db_file,
+ "\n atsfp %d %d/%02d/%02d %02d:%02d:%02d;",
+ t->tm_wday, t->tm_year + 1900, t->tm_mon + 1,
+ t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec) <= 0)
+ ++errors;
+ }
if (lease -> cltt) {
t = gmtime (&lease -> cltt);
errno = 0;
@@ -848,12 +856,7 @@ int new_lease_file ()
char backfname [512];
TIME t;
int db_fd;
-
- /* If we already have an open database, close it. */
- if (db_file) {
- fclose (db_file);
- db_file = (FILE *)0;
- }
+ FILE *new_db_file;
/* Make a temporary lease file... */
GET_TIME (&t);
@@ -873,11 +876,17 @@ int new_lease_file ()
log_error ("Can't create new lease file: %m");
return 0;
}
- if ((db_file = fdopen (db_fd, "w")) == NULL) {
- log_error ("Can't fdopen new lease file!");
- goto fail;
+ if ((new_db_file = fdopen(db_fd, "w")) == NULL) {
+ log_error("Can't fdopen new lease file: %m");
+ close(db_fd);
+ goto fdfail;
}
+ /* Close previous database, if any. */
+ if (db_file)
+ fclose(db_file);
+ db_file = new_db_file;
+
/* Write an introduction so people don't complain about time
being off. */
errno = 0;
@@ -933,10 +942,15 @@ int new_lease_file ()
backfname);
goto fail;
}
- if (link (path_dhcpd_db, backfname) < 0) {
- log_error ("Can't backup lease database %s to %s: %m",
- path_dhcpd_db, backfname);
- goto fail;
+ if (link(path_dhcpd_db, backfname) < 0) {
+ if (errno == ENOENT) {
+ log_error("%s is missing - no lease db to backup.",
+ path_dhcpd_db);
+ } else {
+ log_error("Can't backup lease database %s to %s: %m",
+ path_dhcpd_db, backfname);
+ goto fail;
+ }
}
#if defined (TRACING)
}
@@ -954,8 +968,9 @@ int new_lease_file ()
return 1;
fail:
- unlink (newfname);
lease_file_is_corrupt = 1;
+ fdfail:
+ unlink (newfname);
return 0;
}
diff --git a/server/dhcp.c b/server/dhcp.c
index 3cc266cf..8eb7524b 100644
--- a/server/dhcp.c
+++ b/server/dhcp.c
@@ -3,7 +3,7 @@
DHCP Protocol engine. */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dhcp.c,v 1.199 2005/09/30 19:15:55 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: dhcp.c,v 1.200 2006/02/24 23:16:30 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -188,17 +188,16 @@ void dhcp (packet)
}
nolease:
- /* Classify the client. */
+ /* If a client null terminates options it sends, it probably
+ * expects the server to reciprocate.
+ */
if ((oc = lookup_option (&dhcp_universe, packet -> options,
DHO_HOST_NAME))) {
if (!oc -> expression)
- while (oc -> data.len &&
- oc -> data.data [oc -> data.len - 1] == 0) {
- ms_nulltp = 1;
- oc -> data.len--;
- }
+ ms_nulltp = oc->flags & OPTION_HAD_NULLS;
}
+ /* Classify the client. */
classify_client (packet);
switch (packet -> packet_type) {
@@ -245,15 +244,13 @@ void dhcpdiscover (packet, ms_nulltp)
char msgbuf [1024]; /* XXX */
TIME when;
const char *s;
- int allocatedp = 0;
int peer_has_leases = 0;
- int alloc_lease_called = 0;
#if defined (FAILOVER_PROTOCOL)
dhcp_failover_state_t *peer;
#endif
find_lease (&lease, packet, packet -> shared_network,
- 0, &allocatedp, (struct lease *)0, MDL);
+ 0, &peer_has_leases, (struct lease *)0, MDL);
if (lease && lease -> client_hostname) {
if ((strlen (lease -> client_hostname) <= 64) &&
@@ -292,22 +289,20 @@ void dhcpdiscover (packet, ms_nulltp)
if (lease && lease -> pool && lease -> pool -> failover_peer) {
peer = lease -> pool -> failover_peer;
- /* If the lease is ours to allocate, then allocate it,
- but set the allocatedp flag. */
- if (lease_mine_to_reallocate (lease))
- allocatedp = 1;
+ /* If the lease is ours to allocate, then allocate it. */
+ if (lease_mine_to_reallocate(lease)) {
+ if (lease->pool && lease->pool->failover_peer)
+ dhcp_failover_pool_check(lease->pool);
- /* If the lease is active, do load balancing to see who
- allocates the lease (if it's active, it already belongs
- to the client, or we wouldn't have gotten it from
- find_lease (). */
- else if (lease -> binding_state == FTS_ACTIVE &&
- (peer -> service_state != cooperating ||
- load_balance_mine (packet, peer)))
- ;
+ /* If the lease is active, it belongs to the client. This
+ * is the right lease, if we are to offer one. We decide
+ * wether or not to offer later on.
+ */
+ } else if (lease->binding_state == FTS_ACTIVE) {
+ ; /* This space intentionally left blank. */
/* Otherwise, we can't let the client have this lease. */
- else {
+ } else {
#if defined (DEBUG_FIND_LEASE)
log_debug ("discarding %s - %s",
piaddr (lease -> ip_addr),
@@ -336,8 +331,6 @@ void dhcpdiscover (packet, ms_nulltp)
if (lease -> pool && lease -> pool -> failover_peer)
dhcp_failover_pool_check (lease -> pool);
#endif
- allocatedp = 1;
- alloc_lease_called = 1;
}
#if defined (FAILOVER_PROTOCOL)
@@ -353,26 +346,15 @@ void dhcpdiscover (packet, ms_nulltp)
peer = (dhcp_failover_state_t *)0;
/* Do load balancing if configured. */
- /* If the lease is newly allocated, and we're not the server that
- the client would normally get with load balancing, and the
- failover protocol state is normal, let the other server get this.
- XXX Check protocol spec to make sure that predicating this on
- XXX allocatedp is okay - I'm doing this so that the client won't
- XXX be forced to switch servers (and IP addresses) just because
- XXX of bad luck, when it's possible for it to get the address it
- XXX is requesting. Not sure this is allowed. */
- if (allocatedp && peer && (peer -> service_state == cooperating) &&
+ if (peer && (peer -> service_state == cooperating) &&
!load_balance_mine (packet, peer)) {
- /* peer_has_leases only has a chance to be set if we called
- * allocate_lease() above.
- */
- if (!alloc_lease_called || peer_has_leases) {
+ if (peer_has_leases) {
log_debug ("%s: load balance to peer %s",
msgbuf, peer -> name);
goto out;
} else {
- log_debug ("cancel load balance to peer %s - %s",
- peer -> name, "no free leases");
+ log_debug ("%s: cancel load balance to peer %s - %s",
+ msgbuf, peer -> name, "no free leases");
}
}
#endif
@@ -442,8 +424,6 @@ void dhcprequest (packet, ms_nulltp, ip_lease)
if (find_subnet (&subnet, cip, MDL))
find_lease (&lease, packet,
subnet -> shared_network, &ours, 0, ip_lease, MDL);
- /* XXX consider using allocatedp arg to find_lease to see
- XXX that this isn't a compliant DHCPREQUEST. */
if (lease && lease -> client_hostname) {
if ((strlen (lease -> client_hostname) <= 64) &&
@@ -953,7 +933,7 @@ void dhcpinform (packet, ms_nulltp)
struct packet outgoing;
unsigned char dhcpack = DHCPACK;
struct subnet *subnet = (struct subnet *)0;
- struct iaddr cip;
+ struct iaddr cip, gip;
unsigned i, j;
int nulltp;
struct sockaddr_in to;
@@ -970,11 +950,19 @@ void dhcpinform (packet, ms_nulltp)
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
}
+ if (packet->raw->giaddr.s_addr) {
+ gip.len = 4;
+ memcpy(gip.iabuf, &packet->raw->giaddr, 4);
+ } else
+ gip.len = 0;
+
/* %Audit% This is log output. %2004.06.17,Safe%
* If we truncate we hope the user can get a hint from the log.
*/
snprintf (msgbuf, sizeof msgbuf, "DHCPINFORM from %s via %s",
- piaddr (cip), packet -> interface -> name);
+ piaddr (cip), packet->raw->giaddr.s_addr ?
+ inet_ntoa(packet->raw->giaddr) :
+ packet -> interface -> name);
/* If the IP source address is zero, don't respond. */
if (!memcmp (cip.iabuf, "\0\0\0", 4)) {
@@ -983,13 +971,18 @@ void dhcpinform (packet, ms_nulltp)
}
/* Find the subnet that the client is on. */
- oc = (struct option_cache *)0;
- find_subnet (&subnet , cip, MDL);
+ if (gip.len) {
+ /* XXX - do subnet selection relay agent suboption here */
+ find_subnet(&subnet, gip, MDL);
+ } else {
+ /* XXX - do subnet selection (not relay agent) option here */
+ find_subnet(&subnet, cip, MDL);
+ }
/* Sourceless packets don't make sense here. */
if (!subnet) {
- log_info ("%s: unknown subnet %s",
- msgbuf, inet_ntoa (packet -> raw -> giaddr));
+ log_info ("%s: unknown subnet for address %s",
+ msgbuf, gip.len ? piaddr(gip) : piaddr(cip));
return;
}
@@ -1018,7 +1011,6 @@ void dhcpinform (packet, ms_nulltp)
return;
}
- memset (&d1, 0, sizeof d1);
option_state_allocate (&options, MDL);
memset (&outgoing, 0, sizeof outgoing);
memset (&raw, 0, sizeof raw);
@@ -1080,14 +1072,8 @@ void dhcpinform (packet, ms_nulltp)
nulltp = 0;
if ((oc = lookup_option (&dhcp_universe, packet -> options,
DHO_HOST_NAME))) {
- if (evaluate_option_cache (&d1, packet, (struct lease *)0,
- (struct client_state *)0,
- packet -> options, options,
- &global_scope, oc, MDL)) {
- if (d1.data [d1.len - 1] == '\0')
- nulltp = 1;
- data_string_forget (&d1, MDL);
- }
+ if (!oc->expression)
+ nulltp = oc->flags & OPTION_HAD_NULLS;
}
/* Put in DHCP-specific options. */
@@ -1250,9 +1236,6 @@ void dhcpinform (packet, ms_nulltp)
raw.hops = packet -> raw -> hops;
raw.op = BOOTREPLY;
- /* Report what we're sending... */
- log_info ("DHCPACK to %s", inet_ntoa (raw.ciaddr));
-
#ifdef DEBUG_PACKET
dump_packet (&outgoing);
dump_raw ((unsigned char *)&raw, outgoing.packet_length);
@@ -1265,9 +1248,47 @@ void dhcpinform (packet, ms_nulltp)
#endif
memset (to.sin_zero, 0, sizeof to.sin_zero);
- /* Use the IP address we derived for the client. */
- memcpy (&to.sin_addr, cip.iabuf, 4);
- to.sin_port = remote_port;
+ /* RFC2131 states the server SHOULD unciast to ciaddr.
+ * There are two wrinkles - relays, and when ciaddr is zero.
+ * There's actually no mention of relays at all in rfc2131.
+ * I think it's best to use relays where present...a relay is
+ * a bit more trustworthy about getting the message to a client
+ * than a client might be (it's better to send to a relay than
+ * to, say, a link-local address the client has selected).
+ *
+ * Where ciaddr is zero, which actually does happen quite frequently
+ * even though rfc2131 is unequivocal on the subject, we try to help
+ * by using the IP source address.
+ *
+ * Where ciaddr is zero AND we got it via a relay, the IP source
+ * address is the relay - and we're transmitting to the client
+ * port. This might cause a loop.
+ *
+ * So, overall, this is neater if the relay is selected first,
+ * treated like a relay, client addressing taken second. Since
+ * a relay possibly has no way of knowing how to reach the client
+ * if chaddr is zero (equally as common as ciaddr being zeroed),
+ * set the broadcast bit to try and help.
+ */
+ if (gip.len) {
+ memcpy(&to.sin_addr, gip.iabuf, 4);
+ to.sin_port = local_port;
+
+ if (!raw.hlen)
+ raw.flags |= htons(BOOTP_BROADCAST);
+ } else {
+ memcpy(&to.sin_addr, cip.iabuf, 4);
+ to.sin_port = remote_port;
+ }
+
+ /* Report what we're sending. */
+ snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
+ (packet->raw->htype && packet->raw->hlen) ?
+ print_hw_addr(packet->raw->htype, packet->raw->hlen,
+ packet->raw->chaddr) :
+ "<no client hardware address>");
+ log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
+ packet->interface->name);
errno = 0;
send_packet ((fallback_interface
@@ -2011,57 +2032,57 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
#if defined (FAILOVER_PROTOCOL)
/* Okay, we know the lease duration. Now check the
failover state, if any. */
- if (lease -> tsfp) {
- lt ->tsfp = lease ->tsfp;
- }
if (lease -> pool && lease -> pool -> failover_peer) {
+ TIME new_lease_time = lease_time;
dhcp_failover_state_t *peer =
lease -> pool -> failover_peer;
- /* If the lease time we arrived at exceeds what
- the peer has, we can only issue a lease of
- peer -> mclt, but we can tell the peer we
- want something longer in the future. */
- /* XXX This may result in updates that only push
- XXX the peer's expiry time for this lease up
- XXX by a few seconds - think about this again
- XXX later. */
- if (lease_time > peer -> mclt &&
- cur_time + lease_time > lease -> tsfp) {
- /* Here we're assuming that if we don't have
- to update tstp, there's already an update
- queued. May want to revisit this. */
- if (peer -> me.state != partner_down &&
- cur_time + lease_time > lease -> tstp)
- lt -> tstp = (cur_time + lease_time +
- peer -> mclt / 2);
-
- /* Now choose a lease time that is either
- MCLT, for a lease that's never before been
- assigned, or TSFP + MCLT for a lease that
- has.
- XXX Note that TSFP may be < cur_time.
- XXX What do we do in this case?
- XXX should the expiry timer on the lease
- XXX set tsfp and tstp to zero? */
- if (lease -> tsfp < cur_time) {
- lease_time = peer -> mclt;
- } else {
- lease_time = (lease -> tsfp - cur_time
- + peer -> mclt);
- }
- } else {
- if (cur_time + lease_time > lease -> tsfp &&
- lease_time > peer -> mclt / 2) {
- lt -> tstp = (cur_time + lease_time +
- peer -> mclt / 2);
- } else {
- lt -> tstp = (cur_time + lease_time +
- lease_time / 2);
- }
+ /* Copy previous lease failover ack-state. */
+ lt->tsfp = lease->tsfp;
+ lt->atsfp = lease->atsfp;
+
+ /* Update Client Last Transaction Time. */
+ lt->cltt = cur_time;
+
+ /* Lease times less than MCLT are not a concern. */
+ if (lease_time > peer->mclt) {
+ /* Each server can only offer a lease time
+ * that is either equal to MCLT (at least),
+ * or up to TSFP+MCLT. Only if the desired
+ * lease time falls within TSFP+MCLT, can
+ * the server allow it.
+ */
+ if (lt->tsfp <= cur_time)
+ new_lease_time = peer->mclt;
+ else if ((cur_time + lease_time) >
+ (lt->tsfp + peer->mclt))
+ new_lease_time = (lt->tsfp - cur_time)
+ + peer->mclt;
}
- lt -> cltt = cur_time;
+ /* Update potential expiry. Allow for the desired
+ * lease time plus one half the actual (wether
+ * modified downward or not) lease time, which is
+ * actually an estimate of when the client will
+ * renew. This way, the client will be able to get
+ * the desired lease time upon renewal.
+ */
+ if (offer == DHCPACK) {
+ lt->tstp = cur_time + lease_time +
+ (new_lease_time / 2);
+
+ /* If we reduced the potential expiry time,
+ * make sure we don't offer an old-expiry-time
+ * lease for this lease before the change is
+ * ack'd.
+ */
+ if (lt->tstp < lt->tsfp)
+ lt->tsfp = lt->tstp;
+ } else
+ lt->tstp = lease->tstp;
+
+ /* Use failover-modified lease time. */
+ lease_time = new_lease_time;
}
#endif /* FAILOVER_PROTOCOL */
@@ -2933,7 +2954,7 @@ void dhcp_reply (lease)
int find_lease (struct lease **lp,
struct packet *packet, struct shared_network *share, int *ours,
- int *allocatedp, struct lease *ip_lease_in,
+ int *peer_has_leases, struct lease *ip_lease_in,
const char *file, int line)
{
struct lease *uid_lease = (struct lease *)0;
@@ -2952,6 +2973,22 @@ int find_lease (struct lease **lp,
int status;
struct hardware h;
+ /* Quick check to see if the peer has leases. */
+ if (peer_has_leases) {
+ struct pool *pool;
+
+ for (pool = share->pools ; pool ; pool = pool->next) {
+ dhcp_failover_state_t *peer = pool->failover_peer;
+
+ if (peer &&
+ ((peer->i_am == primary && pool->backup_leases) ||
+ (peer->i_am == secondary && pool->free_leases))) {
+ *peer_has_leases = 1;
+ break;
+ }
+ }
+ }
+
if (packet -> raw -> ciaddr.s_addr) {
cip.len = 4;
memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
@@ -3257,9 +3294,7 @@ int find_lease (struct lease **lp,
if (ours && ip_lease -> binding_state != FTS_ACTIVE)
*ours = 0;
lease_dereference (&ip_lease, MDL);
- } else
- if (allocatedp)
- *allocatedp = 1;
+ }
}
/* If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
@@ -3310,7 +3345,7 @@ int find_lease (struct lease **lp,
(share ==
uid_lease -> subnet -> shared_network) &&
packet -> packet_type == DHCPREQUEST)
- dissociate_lease (uid_lease);
+ release_lease (uid_lease, packet);
}
lease_dereference (&uid_lease, MDL);
lease_reference (&uid_lease, ip_lease, MDL);
@@ -3380,8 +3415,10 @@ int find_lease (struct lease **lp,
permitted (packet, ip_lease -> pool -> prohibit_list)) ||
(ip_lease -> pool -> permit_list &&
!permitted (packet, ip_lease -> pool -> permit_list)))) {
- if (!packet -> raw -> ciaddr.s_addr)
+ if (!packet->raw->ciaddr.s_addr &&
+ (ip_lease->binding_state == FTS_ACTIVE))
release_lease (ip_lease, packet);
+
lease_dereference (&ip_lease, MDL);
}
@@ -3458,11 +3495,19 @@ int find_lease (struct lease **lp,
the lease that matched the client identifier. */
if (uid_lease) {
if (lease) {
+ log_error("uid lease %s for client %s is duplicate "
+ "on %s",
+ piaddr(uid_lease->ip_addr),
+ print_hw_addr(packet->raw->htype,
+ packet->raw->hlen,
+ packet->raw->chaddr),
+ uid_lease->subnet->shared_network->name);
+
if (!packet -> raw -> ciaddr.s_addr &&
packet -> packet_type == DHCPREQUEST &&
(uid_lease -> binding_state == FTS_ACTIVE ||
uid_lease -> binding_state == FTS_BOOTP))
- dissociate_lease (uid_lease);
+ release_lease(uid_lease, packet);
#if defined (DEBUG_FIND_LEASE)
log_info ("not choosing uid lease.");
#endif
@@ -3556,9 +3601,6 @@ int find_lease (struct lease **lp,
lease_dereference (&lease, MDL);
}
- if (lease && allocatedp && lease -> ends <= cur_time)
- *allocatedp = 1;
-
out:
if (have_client_identifier)
data_string_forget (&client_identifier, MDL);
diff --git a/server/dhcpd.8 b/server/dhcpd.8
index 9b9fdc84..11be0532 100644
--- a/server/dhcpd.8
+++ b/server/dhcpd.8
@@ -1,6 +1,6 @@
.\" dhcpd.8
.\"
-.\" Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -28,7 +28,7 @@
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
.\" ``http://www.nominum.com''.
.\"
-.\" $Id: dhcpd.8,v 1.22 2005/03/17 20:15:27 dhankins Exp $
+.\" $Id: dhcpd.8,v 1.23 2006/02/24 23:16:31 dhankins Exp $
.\"
.TH dhcpd 8
.SH NAME
@@ -62,6 +62,10 @@ dhcpd - Dynamic Host Configuration Protocol Server
.I lease-file
]
[
+.B -pf
+.I pid-file
+]
+[
.B -tf
.I trace-output-file
]
@@ -193,8 +197,10 @@ LOG_DAEMON.
.PP
Dhcpd can be made to use an alternate configuration file with the
.B -cf
-flag, or an alternate lease file with the
+flag, an alternate lease file with the
.B -lf
+flag, or an alternate pid file with the
+.B -pf
flag. Because of the importance of using the same lease database at
all times when running dhcpd in production, these options should be
used \fBonly\fR for testing lease files or database files in a
@@ -463,9 +469,16 @@ server.
.RE
.B tsfp \fItime\fR examine
.RS 0.5i
-the time when the lease's current state ends, as understood by the
-failover peer (if there is no failover peer, this value is
-undefined).
+the adjusted time when the lease's current state ends, as understood by
+the failover peer (if there is no failover peer, this value is
+undefined). Generally this value is only adjusted for expired, released,
+or reset leases while the server is operating in partner-down state, and
+otherwise is simply the value supplied by the peer.
+.RE
+.B atsfp \fItime\fR examine
+.RS 0.5i
+the actual tsfp value sent from the peer. This value is forgotten when a
+lease binding state change is made, to facillitate retransmission logic.
.RE
.PP
.B cltt \fItime\fR examine
diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
index a50a6ff2..5a91d861 100644
--- a/server/dhcpd.conf.5
+++ b/server/dhcpd.conf.5
@@ -1,6 +1,6 @@
.\" dhcpd.conf.5
.\"
-.\" Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (c) 1996-2003 by Internet Software Consortium
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -28,7 +28,7 @@
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
.\" ``http://www.nominum.com''.
.\"
-.\" $Id: dhcpd.conf.5,v 1.69 2005/09/30 19:15:55 dhankins Exp $
+.\" $Id: dhcpd.conf.5,v 1.70 2006/02/24 23:16:31 dhankins Exp $
.\"
.TH dhcpd.conf 5
.SH NAME
@@ -2108,9 +2108,7 @@ statement
The \fInext-server\fR statement is used to specify the host address of
the server from which the initial boot file (specified in the
\fIfilename\fR statement) is to be loaded. \fIServer-name\fR should
-be a numeric IP address or a domain name. If no \fInext-server\fR
-parameter applies to a given client, the DHCP server's IP address is
-used.
+be a numeric IP address or a domain name.
.RE
.PP
The
diff --git a/server/failover.c b/server/failover.c
index c7b31936..cc42d5d5 100644
--- a/server/failover.c
+++ b/server/failover.c
@@ -3,7 +3,7 @@
Failover protocol support code... */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: failover.c,v 1.58 2005/03/17 20:15:28 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: failover.c,v 1.59 2006/02/24 23:16:32 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -1780,23 +1780,26 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
case partner_down:
/* For every expired lease, set a timeout for it to become free. */
- for (s = shared_networks; s; s = s -> next) {
- for (p = s -> pools; p; p = p -> next) {
+ for (s = shared_networks; s; s = s -> next) {
+ for (p = s -> pools; p; p = p -> next) {
if (p -> failover_peer == state) {
- for (l = p -> expired; l; l = l -> next)
- l -> tsfp = state -> me.stos + state -> mclt;
- if (p -> next_event_time >
- state -> me.stos + state -> mclt) {
- p -> next_event_time =
- state -> me.stos + state -> mclt;
+ for (l = p->expired ; l ; l = l->next) {
+ l->tsfp = state->me.stos + state->mclt;
+ l->sort_time = (l->tsfp > l->ends) ?
+ l->tsfp : l->ends;
+ }
+ if (p->expired &&
+ (p->expired->sort_time < p->next_event_time)) {
+
+ p->next_event_time = p->expired->sort_time;
#if defined (DEBUG_FAILOVER_TIMING)
log_info ("add_timeout +%d %s",
- (int)(cur_time - p -> next_event_time),
+ (int)(cur_time - p->next_event_time),
"pool_timer");
#endif
- add_timeout (p -> next_event_time, pool_timer, p,
- (tvref_t)pool_reference,
- (tvunref_t)pool_dereference);
+ add_timeout(p->next_event_time, pool_timer, p,
+ (tvref_t)pool_reference,
+ (tvunref_t)pool_dereference);
}
}
}
@@ -4496,7 +4499,7 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
goto bad;
}
if (msg -> chaddr.count > sizeof lt -> hardware_addr.hbuf) {
- message = "chaddr to long";
+ message = "chaddr too long";
goto bad;
}
lt -> hardware_addr.hlen = msg -> chaddr.count;
@@ -4571,8 +4574,8 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state,
if (msg -> options_present & FTB_CLTT) {
lt -> cltt = msg -> client_ltt;
}
- if (msg -> options_present & FTB_POTENTIAL_EXPIRY) {
- lt -> tsfp = msg -> potential_expiry;
+ if (msg->options_present & FTB_POTENTIAL_EXPIRY) {
+ lt->atsfp = lt->tsfp = msg->potential_expiry;
}
if (msg -> options_present & FTB_BINDING_STATUS) {
@@ -4680,20 +4683,20 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state,
if (msg -> options_present & FTB_POTENTIAL_EXPIRY) {
/* XXX it could be a problem to do this directly if the
XXX lease is sorted by tsfp. */
+ lease->atsfp = lease->tsfp = msg->potential_expiry;
+
if ((lease -> binding_state == FTS_EXPIRED ||
lease -> binding_state == FTS_RESET ||
lease -> binding_state == FTS_RELEASED) &&
(msg -> options_present & FTB_BINDING_STATUS) &&
msg -> binding_status == FTS_FREE)
{
- lease -> tsfp = msg -> potential_expiry;
lease -> next_binding_state = FTS_FREE;
supersede_lease (lease, (struct lease *)0, 0, 0, 0);
write_lease (lease);
if (state -> me.state == normal)
commit_leases ();
} else {
- lease -> tsfp = msg -> potential_expiry;
if ((lease -> desired_binding_state !=
lease -> binding_state) &&
(msg -> options_present & FTB_BINDING_STATUS) &&
@@ -4811,6 +4814,9 @@ isc_result_t dhcp_failover_generate_update_queue (dhcp_failover_state_t *state,
expiry routine on the pool. */
for (s = shared_networks; s; s = s -> next) {
for (p = s -> pools; p; p = p -> next) {
+ if (p->failover_peer != state)
+ continue;
+
lptr [FREE_LEASES] = &p -> free;
lptr [ACTIVE_LEASES] = &p -> active;
lptr [EXPIRED_LEASES] = &p -> expired;
@@ -4819,11 +4825,11 @@ isc_result_t dhcp_failover_generate_update_queue (dhcp_failover_state_t *state,
for (i = FREE_LEASES; i <= BACKUP_LEASES; i++) {
for (l = *(lptr [i]); l; l = l -> next) {
- if (p -> failover_peer == state &&
- ((everythingp &&
- (l -> starts != MIN_TIME ||
- l -> ends != MIN_TIME)) ||
- l -> tstp > l -> tsfp)) {
+ if ((everythingp &&
+ (l->starts != MIN_TIME ||
+ l->ends != MIN_TIME)) ||
+ (l->tstp > l->atsfp) ||
+ (i == EXPIRED_LEASES)) {
l -> desired_binding_state = l -> binding_state;
dhcp_failover_queue_update (l, 0);
}
@@ -5281,21 +5287,29 @@ conflict_binding_state_transition_check (struct lease *lease,
switch (binding_state) {
case FTS_FREE:
case FTS_BACKUP:
- case FTS_ABANDONED:
new_state = lease -> binding_state;
break;
case FTS_EXPIRED:
- case FTS_RELEASED:
- case FTS_RESET:
- if (lease -> ends > cur_time)
- new_state =
- lease -> binding_state;
+ /* If we don't agree about expiry, it's
+ * invalid. 65 should allow for max
+ * clock skew (60) plus some fudge.
+ * XXX: should we refetch cur_time?
+ */
+ if ((lease->ends - 65) > cur_time)
+ new_state = lease->binding_state;
else
new_state = binding_state;
break;
- case FTS_ACTIVE:
+ /* RELEASED, RESET, and ABANDONED indicate
+ * that our partner has information about
+ * this lease that we did not witness. Our
+ * partner wins.
+ */
+ case FTS_RELEASED:
+ case FTS_RESET:
+ case FTS_ABANDONED:
new_state = binding_state;
break;
@@ -5333,48 +5347,77 @@ int lease_mine_to_reallocate (struct lease *lease)
{
dhcp_failover_state_t *peer;
- if (lease && lease -> pool &&
- lease -> pool -> failover_peer) {
- peer = lease -> pool -> failover_peer;
- switch (lease -> binding_state) {
+ if (lease && lease->pool &&
+ (peer = lease->pool->failover_peer)) {
+ switch (lease->binding_state) {
case FTS_ACTIVE:
+ /* ACTIVE leases may not be reallocated. */
return 0;
case FTS_FREE:
+ case FTS_ABANDONED:
+ /* FREE leases may only be allocated by the primary,
+ * unless the secondary is acting in partner_down
+ * state and stos+mclt or tsfp+mclt has expired,
+ * whichever is greater.
+ *
+ * ABANDONED are treated the same as FREE for all
+ * purposes here. Note that servers will only try
+ * for ABANDONED leases as a last resort anyway.
+ */
if (peer -> i_am == primary)
return 1;
- if (peer -> service_state == service_partner_down &&
- (lease -> tsfp < peer -> me.stos
- ? peer -> me.stos + peer -> mclt < cur_time
- : lease -> tsfp + peer -> mclt < cur_time))
- return 1;
- return 0;
- case FTS_ABANDONED:
+ return(peer->service_state == service_partner_down &&
+ ((lease->tsfp < peer->me.stos) ?
+ (peer->me.stos + peer->mclt < cur_time) :
+ (lease->tsfp + peer->mclt < cur_time)));
+
case FTS_RESET:
case FTS_RELEASED:
case FTS_EXPIRED:
- if (peer -> service_state == service_partner_down &&
- (lease -> tsfp < peer -> me.stos
- ? peer -> me.stos + peer -> mclt < cur_time
- : lease -> tsfp + peer -> mclt < cur_time))
- return 1;
- return 0;
+ /* These three lease states go onto the 'expired'
+ * queue. Upon entry into partner-down state, this
+ * queue of leases has their tsfp values modified
+ * to equal stos+mclt, the point at which the server
+ * is allowed to remove them from these transitional
+ * states without an acknowledgement.
+ *
+ * Note that although tsfp has been possibly extended
+ * past the actual tsfp we received from the peer, we
+ * don't have to take any special action. Since tsfp
+ * is now in the past (or now), we can guarantee that
+ * this server will only allocate a lease time equal
+ * to MCLT, rather than a TSFP-optimal lease, which is
+ * the only danger for a lease in one of these states.
+ */
+ return((peer->service_state == service_partner_down) &&
+ (lease->tsfp < cur_time));
+
case FTS_BACKUP:
- if (peer -> i_am == secondary)
- return 1;
- if (peer -> service_state == service_partner_down &&
- (lease -> tsfp < peer -> me.stos
- ? peer -> me.stos + peer -> mclt < cur_time
- : lease -> tsfp + peer -> mclt < cur_time))
+ /* Only the secondary may allocate BACKUP leases,
+ * unless in partner_down state in which case at
+ * least TSFP+MCLT or STOS+MCLT must have expired,
+ * whichever is greater.
+ */
+ if (peer->i_am == secondary)
return 1;
- return 0;
+
+ return((peer->service_state == service_partner_down) &&
+ ((lease->tsfp < peer->me.stos) ?
+ (peer->me.stos + peer->mclt < cur_time) :
+ (lease->tsfp + peer->mclt < cur_time)));
+
+ default:
+ /* All lease states appear above. */
+ log_fatal("Impossible case at %s:%d.", MDL);
+ break;
}
return 0;
}
if (lease)
- return !(lease -> binding_state != FTS_FREE &&
- lease -> binding_state != FTS_BACKUP);
+ return(lease->binding_state == FTS_FREE ||
+ lease->binding_state == FTS_BACKUP);
else
return 0;
}
diff --git a/server/mdb.c b/server/mdb.c
index 52e09fff..c7768c1a 100644
--- a/server/mdb.c
+++ b/server/mdb.c
@@ -3,7 +3,7 @@
Server-specific in-memory database support. */
/*
- * Copyright (c) 2004-2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: mdb.c,v 1.73 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
+"$Id: mdb.c,v 1.74 2006/02/24 23:16:32 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -921,7 +921,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
comp -> uid = (unsigned char *)0;
} else
enter_uid = 1;
-
+
if (comp -> hardware_addr.hlen &&
((comp -> hardware_addr.hlen !=
lease -> hardware_addr.hlen) ||
@@ -932,7 +932,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
enter_hwaddr = 1;
} else if (!comp -> hardware_addr.hlen)
enter_hwaddr = 1;
-
+
/* If the lease has been billed to a class, remove the billing. */
if (comp -> billing_class != lease -> billing_class) {
if (comp -> billing_class)
@@ -1019,26 +1019,36 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
executable_statement_reference (&comp -> on_release,
lease -> on_release, MDL);
}
-
+
/* Record the lease in the uid hash if necessary. */
if (enter_uid && comp -> uid) {
uid_hash_add (comp);
}
-
+
/* Record it in the hardware address hash if necessary. */
if (enter_hwaddr && lease -> hardware_addr.hlen) {
hw_hash_add (comp);
}
-
+
#if defined (FAILOVER_PROTOCOL)
- comp -> cltt = lease -> cltt;
- comp -> tstp = lease -> tstp;
- comp -> tsfp = lease -> tsfp;
+ comp->cltt = lease->cltt;
+ comp->tstp = lease->tstp;
+ comp->tsfp = lease->tsfp;
+ comp->atsfp = lease->atsfp;
#endif /* FAILOVER_PROTOCOL */
- comp -> ends = lease -> ends;
- comp -> next_binding_state = lease -> next_binding_state;
+ comp->ends = lease->ends;
+ comp->next_binding_state = lease->next_binding_state;
just_move_it:
+#if defined (FAILOVER_PROTOCOL)
+ /* Atsfp should be cleared upon any state change that implies
+ * propogation wether supersede_lease was given a copy lease
+ * structure or not (often from the pool_timer()).
+ */
+ if (propogate)
+ comp->atsfp = 0;
+#endif /* FAILOVER_PROTOCOL */
+
if (!comp -> pool) {
log_error ("Supersede_lease: lease %s with no pool.",
piaddr (comp -> ip_addr));
@@ -1082,6 +1092,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
/* Remove the lease from its current place in its current
timer sequence. */
+ /* XXX this is horrid. */
prev = (struct lease *)0;
for (lp = *lq; lp; lp = lp -> next) {
if (lp == comp)
@@ -1398,14 +1409,15 @@ int lease_copy (struct lease **lp,
executable_statement_reference (&lt -> on_release,
lease -> on_release,
file, line);
- lt -> flags = lease -> flags;
- lt -> tstp = lease -> tstp;
- lt -> tsfp = lease -> tsfp;
- lt -> cltt = lease -> cltt;
- lt -> binding_state = lease -> binding_state;
- lt -> next_binding_state = lease -> next_binding_state;
- status = lease_reference (lp, lt, file, line);
- lease_dereference (&lt, MDL);
+ lt->flags = lease->flags;
+ lt->tstp = lease->tstp;
+ lt->tsfp = lease->tsfp;
+ lt->atsfp = lease->atsfp;
+ lt->cltt = lease -> cltt;
+ lt->binding_state = lease->binding_state;
+ lt->next_binding_state = lease->next_binding_state;
+ status = lease_reference(lp, lt, file, line);
+ lease_dereference(&lt, MDL);
return status == ISC_R_SUCCESS;
}
@@ -1924,6 +1936,18 @@ int write_leases ()
return 1;
}
+/* In addition to placing this lease upon a lease queue depending on its
+ * state, it also keeps track of the number of FREE and BACKUP leases in
+ * existence, and sets the sort_time on the lease.
+ *
+ * Sort_time is used in pool_timer() to determine when the lease will
+ * bubble to the top of the list and be supersede_lease()'d into its next
+ * state (possibly, if all goes well). Example, ACTIVE leases move to
+ * EXPIRED state when the 'ends' value is reached, so that is its sort
+ * time. Most queues are sorted by 'ends', since it is generally best
+ * practice to re-use the oldest lease, to reduce address collision
+ * chances.
+ */
int lease_enqueue (struct lease *comp)
{
struct lease **lq, *prev, *lp;
@@ -1949,7 +1973,26 @@ int lease_enqueue (struct lease *comp)
case FTS_RELEASED:
case FTS_RESET:
lq = &comp -> pool -> expired;
- comp -> sort_time = comp -> ends;
+#if defined(FAILOVER_PROTOCOL)
+ /* In partner_down, tsfp is the time at which the lease
+ * may be reallocated (stos+mclt). We can do that with
+ * lease_mine_to_reallocate() anywhere between tsfp and
+ * ends. But we prefer to wait until ends before doing it
+ * automatically (choose the greater of the two). Note
+ * that 'ends' is usually a historic timestamp in the
+ * case of expired leases, is really only in the future
+ * on released leases, and if we know a lease to be released
+ * the peer might still know it to be active...in which case
+ * it's possible the peer has renewed this lease, so avoid
+ * doing that.
+ */
+ if (comp->pool->failover_peer &&
+ comp->pool->failover_peer->me.state == partner_down)
+ comp->sort_time = (comp->tsfp > comp->ends) ?
+ comp->tsfp : comp->ends;
+ else
+#endif
+ comp->sort_time = comp->ends;
break;
@@ -2096,7 +2139,7 @@ void expire_all_pools ()
}
#if defined (FAILOVER_PROTOCOL)
if (p -> failover_peer &&
- l -> tstp > l -> tsfp &&
+ l -> tstp > l -> atsfp &&
!(l -> flags & ON_UPDATE_QUEUE)) {
l -> desired_binding_state = l -> binding_state;
dhcp_failover_queue_update (l, 1);
diff --git a/server/omapi.c b/server/omapi.c
index 74deaf75..41e87f47 100644
--- a/server/omapi.c
+++ b/server/omapi.c
@@ -3,7 +3,7 @@
OMAPI object interfaces for the DHCP server. */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1999-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -41,7 +41,7 @@
#ifndef lint
static char copyright[] =
-"$Id: omapi.c,v 1.54 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: omapi.c,v 1.55 2006/02/24 23:16:32 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -482,6 +482,7 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
omapi_object_t *id,
omapi_object_t *h)
{
+ u_int32_t bouncer;
struct lease *lease;
isc_result_t status;
@@ -604,63 +605,79 @@ isc_result_t dhcp_lease_stuff_values (omapi_object_t *c,
return status;
}
+ /* TIME values may be 64-bit, depending on system architecture.
+ * OMAPI must be system independent, both in terms of transmitting
+ * bytes on the wire in network byte order, and in terms of being
+ * readable and usable by both systems.
+ *
+ * XXX: In a future feature release, a put_int64() should be made
+ * to exist, and perhaps a put_time() wrapper that selects which
+ * to use based upon sizeof(TIME). In the meantime, use existing,
+ * 32-bit, code.
+ */
+ bouncer = (u_int32_t)lease->ends;
+ status = omapi_connection_put_name(c, "ends");
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_put_uint32(c, sizeof(bouncer));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_put_uint32(c, bouncer);
+ if (status != ISC_R_SUCCESS)
+ return status;
- status = omapi_connection_put_name (c, "ends");
+ bouncer = (u_int32_t)lease->starts;
+ status = omapi_connection_put_name(c, "starts");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof (TIME));
+ status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
- status = (omapi_connection_copyin
- (c, (const unsigned char *)&(lease -> ends), sizeof(TIME)));
+ status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_name (c, "starts");
+ bouncer = (u_int32_t)lease->tstp;
+ status = omapi_connection_put_name(c, "tstp");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof (TIME));
+ status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
- status = (omapi_connection_copyin
- (c,
- (const unsigned char *)&(lease -> starts), sizeof (TIME)));
+ status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_name (c, "tstp");
+ bouncer = (u_int32_t)lease->tsfp;
+ status = omapi_connection_put_name(c, "tsfp");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof (TIME));
+ status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
- status = (omapi_connection_copyin
- (c,
- (const unsigned char *)&(lease -> tstp), sizeof (TIME)));
+ status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_name (c, "tsfp");
+ bouncer = (u_int32_t)lease->atsfp;
+ status = omapi_connection_put_name(c, "atsfp");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof (TIME));
+ status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
- status = (omapi_connection_copyin
- (c,
- (const unsigned char *)&(lease -> tsfp), sizeof (TIME)));
+ status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_name (c, "cltt");
+ bouncer = (u_int32_t)lease->cltt;
+ status = omapi_connection_put_name(c, "cltt");
if (status != ISC_R_SUCCESS)
return status;
- status = omapi_connection_put_uint32 (c, sizeof (TIME));
+ status = omapi_connection_put_uint32(c, sizeof(bouncer));
if (status != ISC_R_SUCCESS)
return status;
- status = (omapi_connection_copyin
- (c,
- (const unsigned char *)&(lease -> cltt), sizeof (TIME)));
+ status = omapi_connection_put_uint32(c, bouncer);
if (status != ISC_R_SUCCESS)
return status;
diff --git a/server/salloc.c b/server/salloc.c
index 49228e4b..efaa7f0e 100644
--- a/server/salloc.c
+++ b/server/salloc.c
@@ -3,7 +3,7 @@
Memory allocation for the DHCP server... */
/*
- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: salloc.c,v 1.5 2005/03/17 20:15:29 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: salloc.c,v 1.6 2006/02/24 23:16:32 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"