diff options
author | Bjørn Mork <bjorn@mork.no> | 2012-04-16 13:25:36 +0200 |
---|---|---|
committer | Bjørn Mork <bjorn@mork.no> | 2012-04-16 13:25:36 +0200 |
commit | aaf12f3264d8fa96c65a18efad8161368200f8e3 (patch) | |
tree | 05a9c405af9f5c0e10b6ed6ebbb86ff5fbb8013f | |
parent | 402b4a6e3f8c2f42fe326b0b90c5311d2edbb6f3 (diff) | |
parent | aa161a719e968da4be1a97b2b7ccf312dafad3dc (diff) |
51 files changed, 1589 insertions, 705 deletions
@@ -1,4 +1,4 @@ -# Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") +# Copyright (c) 2004-2012 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 @@ -1,6 +1,6 @@ Internet Systems Consortium DHCP Distribution - Version 4.2.3-P1 - 29 November 2011 + Version 4.2.4b1 + 12 April 2012 README FILE @@ -97,8 +97,7 @@ directory, it may not have up-to-date information). RELEASE STATUS -This is ISC DHCP 4.2.3-P1, a security release containing one security -patch to fix a potential DOS issue. +This is ISC DHCP 4.2.4b1, a beat of a maintenance release containing patches. In this release, the DHCPv6 server should be fully functional on Linux, Solaris, or any BSD. The DHCPv6 client should be similarly functional @@ -133,12 +132,12 @@ information. On Digital Unix, type ``man pfilt''. To build the DHCP Distribution, unpack the compressed tar file using the tar utility and the gzip command - type something like: - gunzip dhcp-4.2.3-P1.tar.gz - tar xvf dhcp-4.2.3-P1.tar + gunzip dhcp-4.2.4b1.tar.gz + tar xvf dhcp-4.2.4b1.tar CONFIGURING IT -Now, cd to the dhcp-4.2.3-P1 subdirectory that you've just created and +Now, cd to the dhcp-4.2.4b1 subdirectory that you've just created and configure the source tree by typing: ./configure @@ -1,6 +1,6 @@ Internet Systems Consortium DHCP Distribution - Version 4.2.3-P1 - 29 Novemberr 2011 + Version 4.2.4b1 + 12 April 2012 Release Notes @@ -42,12 +42,99 @@ work on other platforms. Please report any problems and suggested fixes to Changes since 4.2.3 ! Add a check for a null pointer before calling the regexec function. - Without out this check we could, under some circumstances, pass + Without this check we could, under some circumstances, pass a null pointer to the regexec function causing it to segfault. Thanks to a report from BlueCat Networks. [ISC-Bugs #26704]. CVE: CVE-2011-4539 +! Modify the DDNS handling code. In a previous patch we added logging + code to the DDNS handling. This code included a bug that caused it + to attempt to dereference a NULL pointer and eventually segfault. + While reviewing the code as we addressed this problem, we determined + that some of the updates to the lease structures would not work as + planned since the structures being updated were in the process of + being freed: these updates were removed. In addition we removed an + incorrect call to the DDNS removal function that could cause a failure + during the removal of DDNS information from the DNS server. + Thanks to Jasper Jongmans for reporting this issue. + [ISC-Bugs #27078] + CVE: CVE-2011-4868 + +- Fixed the code that checks if an address the server is planning + to hand out is in a reserved range. This would appear as + the server being out of addresses in pools with particular ranges. + [ISC-Bugs #26498] + +- In the DDNS code handle error conditions more gracefully and add more + logging code. The major change is to handle unexpected cancel events + from the DNS client code. + [ISC-Bugs #26287]. + +- Tidy up the receive calls and eliminate the need for found_pkt + [ISC-Bugs #25066] + +- Add support for Infiniband over sockets to the server and + relay code. We've tested this on Solaris and hope to expand + support for Infiniband in the future. This patch also corrects + some issues we found in the socket code. [ISC-Bugs #24245] + +- Add a compile time check for the presence of the noreturn attribute + and use it for log_fatal if it's available. This will help code + checking programs to eliminate false positives. + [ISC-Bugs #27539] + +- Fixed many compilation problems ("set, but not used" warnings) for + gcc 4.6 that may affect Ubuntu 11.10 users. [ISC-Bugs #27588] + +- Modify the code that determines if an outstanding DDNS request + should be cancelled. This patch results in cancelling the + outstanding request less often. It fixes the problem caused + by a client doing a release where the txt and ptr records + weren't removed from the DNS. + [ISC-BUGS #27858] + +- Use offsetof() instead of sizeof() to get the sizes for dhcpv6_relay_packet + and dhcpv6_packet in several more places. Thanks to a report from + Bruno Verstuyft and Vincent Demaertelaere of Excentis. + [ISC-Bugs #27941] + +- Remove outdated note in the bootp keyword about the option not satisfying + the requirement of failover peers for denying dynamic bootp clients. + [ISC-bugs #28574] + +- Multiple items to clean up IPv6 address processing. + When processing an IA that we've seen check to see if the + addresses are usable (not in use by somebody else) before + handing it out. + When reading in leases from the file discard expired addresses. + When picking an address for a client include the IA ID in + addition to the client ID to generally pick different addresses + for different IAs. + [ISC-Bugs #23138] [ISC-Bugs #27945] [ISC-Bugs #25586] + [ISC-Bugs #27684] + +- Remove unnecessary checks in the lease query code and clean up + several compiler issues (some dereferences of NULL and treating + an int as a boolean). + [ISC-Bugs #26203] + +- Fix the NA and PD allocation code to handle the case where a client + provides a preference and the server doesn't have any addresses or + prefixes available. Previoulsy the server ignored the request with + this patch it replies with a NoAddrsAvail or NoPrefixAvai respone. + By default the code performs according to the errata of August 2010 + for RFC 3315 section 17.2.2, to enable the previous style see the + seciton on RFC3315_PRE_ERRATA_2010_08 in includes/site.h. This option + may be removed in the future. + Thanks to Jiri Popelka at Red Hat for the patch. + [ISC-Bugs #22676] + +- Fix up some issues found by static analysis + A potential memory leak and NULL dereference in omapi. + The use of a boolean test instead of a bitwise test in dst. + [ISC-Bugs #28941] + Changes since 4.2.2 - Fix the code that checks for an existing DDNS transaction to cancel diff --git a/bind/Makefile b/bind/Makefile index 030759c..0fb676f 100644 --- a/bind/Makefile +++ b/bind/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2009-2010 by Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2009-2012 by Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.bind,v 1.2.2.7 2011-04-06 22:00:40 marka Exp $ +# $Id: Makefile.bind,v 1.2.2.8 2012-04-05 22:17:08 sar Exp $ # Configure and build the bind libraries for use by DHCP @@ -44,18 +44,31 @@ all: # Configure the export libraries # Currently disable the epoll and devpoll options as they don't interact # well with the DHCP code. - @echo Configuring BIND Export libraries for DHCP. - @(cd ${bindsrcdir} && ./configure --disable-kqueue --disable-epoll --disable-devpoll --without-openssl --without-libxml2 --enable-exportlib --enable-threads=no --with-export-includedir=${binddir}/include --with-export-libdir=${binddir}/lib --with-gssapi=no > ${binddir}/configure.log) - -# Build the export libraries - @echo Building BIND Export libraries - this takes some time. - @(cd ${bindsrcdir}/lib/export ; \ - echo building in `pwd` ; \ - MAKE=${GMAKE} ${GMAKE} > ${binddir}/build.log) +# If the top-level Bind Makefile exists we skip the configuration step +# as we assume it's done and won't change. Doing a make clean will +# reset things if necessary. + @if test -f ${bindsrcdir}/Makefile ; then \ + echo Bind export libraries already configured ; \ + else \ + echo Configuring BIND Export libraries for DHCP. ; \ + rm -rf ./lib ./include ./configure.log ./build.log ./install.log ; \ + (cd ${bindsrcdir} && ./configure --disable-kqueue --disable-epoll --disable-devpoll --without-openssl --without-libxml2 --enable-exportlib --enable-threads=no --with-export-includedir=${binddir}/include --with-export-libdir=${binddir}/lib --with-gssapi=no > ${binddir}/configure.log); \ + fi - @echo Installing BIND Export libraries to ${binddir}. - @(cd ${bindsrcdir}/lib/export ; \ - MAKE=${GMAKE} ${GMAKE} install > ${binddir}/install.log) +# Build and install the export libraries +# No need to do anything if we already have something installed. + @if test -d ${binddir}/lib ; then \ + echo Bind export libraries already installed ; \ + else \ + echo Building BIND Export libraries - this takes some time. ;\ + (cd ${bindsrcdir}/lib/export ; \ + echo building in `pwd` ; \ + MAKE=${GMAKE} ${GMAKE} > ${binddir}/build.log) ; \ + \ + echo Installing BIND Export libraries to ${binddir}. ; \ + (cd ${bindsrcdir}/lib/export ; \ + MAKE=${GMAKE} ${GMAKE} install > ${binddir}/install.log) ; \ + fi clean: @echo Cleaning BIND export library. @@ -73,3 +86,4 @@ install: check: +uninstall: diff --git a/bind/bind.tar.gz b/bind/bind.tar.gz Binary files differindex 040ba04..2275b24 100644 --- a/bind/bind.tar.gz +++ b/bind/bind.tar.gz diff --git a/bind/version.tmp b/bind/version.tmp index 249750e..aa5d40c 100644 --- a/bind/version.tmp +++ b/bind/version.tmp @@ -1,10 +1,10 @@ -# $Id: version,v 1.53.8.9.6.1 2011-11-16 09:32:07 marka Exp $ +# $Id$ # # This file must follow /bin/sh rules. It is imported directly via # configure. # MAJORVER=9 MINORVER=8 -PATCHVER=1 -RELEASETYPE=-P -RELEASEVER=1 +PATCHVER=2 +RELEASETYPE= +RELEASEVER= diff --git a/client/clparse.c b/client/clparse.c index 9de4ce2..c535d7b 100644 --- a/client/clparse.c +++ b/client/clparse.c @@ -3,7 +3,7 @@ Parser for dhclient config and lease files... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -59,10 +59,18 @@ isc_result_t read_client_conf () { struct client_config *config; struct interface_info *ip; - struct parse *parse; isc_result_t status; unsigned code; + /* + * TODO: LATER constant is very undescriptive. We should review it and + * change it to something more descriptive or even better remove it + * completely as it is currently not used. + */ +#ifdef LATER + struct parse *parse = NULL; +#endif + /* Initialize the default request list. */ memset(default_requested_options, 0, sizeof(default_requested_options)); @@ -159,7 +167,6 @@ isc_result_t read_client_conf () (struct interface_info *)0, &top_level_config); - parse = NULL; if (status != ISC_R_SUCCESS) { ; #ifdef LATER diff --git a/client/dhclient.c b/client/dhclient.c index 48707d1..fc60383 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -3,7 +3,7 @@ DHCP Client. */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -68,7 +68,7 @@ int duid_type = 0; #define ASSERT_STATE(state_is, state_shouldbe) {} static const char copyright[] = -"Copyright 2004-2011 Internet Systems Consortium."; +"Copyright 2004-2012 Internet Systems Consortium."; static const char arr [] = "All rights reserved."; static const char message [] = "Internet Systems Consortium DHCP Client"; static const char url [] = @@ -1901,11 +1901,14 @@ void send_discover (cpp) ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval)); /* Send out a packet. */ - result = send_packet (client -> interface, (struct packet *)0, - &client -> packet, - client -> packet_length, - inaddr_any, &sockaddr_broadcast, - (struct hardware *)0); + result = send_packet(client->interface, NULL, &client->packet, + client->packet_length, inaddr_any, + &sockaddr_broadcast, NULL); + if (result < 0) { + log_error("%s:%d: Failed to send %d byte long packet over %s " + "interface.", MDL, client->packet_length, + client->interface->name); + } /* * If we used 0 microseconds here, and there were other clients on the @@ -2168,20 +2171,29 @@ void send_request (cpp) ntohs (destination.sin_port)); if (destination.sin_addr.s_addr != INADDR_BROADCAST && - fallback_interface) - result = send_packet (fallback_interface, - (struct packet *)0, - &client -> packet, - client -> packet_length, - from, &destination, - (struct hardware *)0); - else + fallback_interface) { + result = send_packet(fallback_interface, NULL, &client->packet, + client->packet_length, from, &destination, + NULL); + if (result < 0) { + log_error("%s:%d: Failed to send %d byte long packet " + "over %s interface.", MDL, + client->packet_length, + fallback_interface->name); + } + } + else { /* Send out a packet. */ - result = send_packet (client -> interface, (struct packet *)0, - &client -> packet, - client -> packet_length, - from, &destination, - (struct hardware *)0); + result = send_packet(client->interface, NULL, &client->packet, + client->packet_length, from, &destination, + NULL); + if (result < 0) { + log_error("%s:%d: Failed to send %d byte long packet" + " over %s interface.", MDL, + client->packet_length, + client->interface->name); + } + } tv.tv_sec = cur_tv.tv_sec + client->interval; tv.tv_usec = ((tv.tv_sec - cur_tv.tv_sec) > 1) ? @@ -2197,16 +2209,19 @@ void send_decline (cpp) int result; log_info ("DHCPDECLINE on %s to %s port %d", - client -> name ? client -> name : client -> interface -> name, - inet_ntoa (sockaddr_broadcast.sin_addr), - ntohs (sockaddr_broadcast.sin_port)); + client->name ? client->name : client->interface->name, + inet_ntoa(sockaddr_broadcast.sin_addr), + ntohs(sockaddr_broadcast.sin_port)); /* Send out a packet. */ - result = send_packet (client -> interface, (struct packet *)0, - &client -> packet, - client -> packet_length, - inaddr_any, &sockaddr_broadcast, - (struct hardware *)0); + result = send_packet(client->interface, NULL, &client->packet, + client->packet_length, inaddr_any, + &sockaddr_broadcast, NULL); + if (result < 0) { + log_error("%s:%d: Failed to send %d byte long packet over %s" + " interface.", MDL, client->packet_length, + client->interface->name); + } } void send_release (cpp) @@ -2244,20 +2259,29 @@ void send_release (cpp) inet_ntoa (destination.sin_addr), ntohs (destination.sin_port)); - if (fallback_interface) - result = send_packet (fallback_interface, - (struct packet *)0, - &client -> packet, - client -> packet_length, - from, &destination, - (struct hardware *)0); - else + if (fallback_interface) { + result = send_packet(fallback_interface, NULL, &client->packet, + client->packet_length, from, &destination, + NULL); + if (result < 0) { + log_error("%s:%d: Failed to send %d byte long packet" + " over %s interface.", MDL, + client->packet_length, + fallback_interface->name); + } + } else { /* Send out a packet. */ - result = send_packet (client -> interface, (struct packet *)0, - &client -> packet, - client -> packet_length, - from, &destination, - (struct hardware *)0); + result = send_packet(client->interface, NULL, &client->packet, + client->packet_length, from, &destination, + NULL); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long packet" + " over %s interface.", MDL, + client->packet_length, + client->interface->name); + } + + } } void @@ -3221,7 +3245,6 @@ void script_write_params (client, prefix, lease) lease->server_name); } } - for (i = 0; i < lease -> options -> universe_count; i++) { option_space_foreach ((struct packet *)0, (struct lease *)0, @@ -3706,7 +3729,7 @@ client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb, /* Do the second stage of the FWD removal */ ddns_cb->state = DDNS_STATE_REM_FW_NXRR; - result = ddns_modify_fwd(ddns_cb); + result = ddns_modify_fwd(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } @@ -3726,7 +3749,7 @@ client_dns_remove(struct client_state *client, /* if we have an old ddns request for this client, cancel it */ if (client->ddns_cb != NULL) { - ddns_cancel(client->ddns_cb); + ddns_cancel(client->ddns_cb, MDL); client->ddns_cb = NULL; } @@ -3884,7 +3907,7 @@ client_dns_update_action(dhcp_ddns_cb_t *ddns_cb, ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID; ddns_cb->cur_func = client_dns_update_action; - result = ddns_modify_fwd(ddns_cb); + result = ddns_modify_fwd(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } @@ -4021,7 +4044,7 @@ client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb) * Perform updates. */ if (ddns_cb->fwd_name.len && ddns_cb->dhcid.len) { - rcode = ddns_modify_fwd(ddns_cb); + rcode = ddns_modify_fwd(ddns_cb, MDL); } else rcode = ISC_R_FAILURE; @@ -4054,7 +4077,7 @@ dhclient_schedule_updates(struct client_state *client, /* cancel any outstanding ddns requests */ if (client->ddns_cb != NULL) { - ddns_cancel(client->ddns_cb); + ddns_cancel(client->ddns_cb, MDL); client->ddns_cb = NULL; } diff --git a/client/dhclient.conf.5 b/client/dhclient.conf.5 index 1e376ca..ca5dec3 100644 --- a/client/dhclient.conf.5 +++ b/client/dhclient.conf.5 @@ -1,6 +1,6 @@ -.\" $Id: dhclient.conf.5,v 1.25.24.7 2011-04-21 14:08:14 tomasz Exp $ +.\" $Id: dhclient.conf.5,v 1.25.24.8 2012-01-24 22:23:01 sar Exp $ .\" -.\" Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 1996-2003 by Internet Software Consortium .\" @@ -147,7 +147,8 @@ they will not make their requests in lockstep. The .I backoff-cutoff statement determines the maximum amount of time that the client is allowed to back off, the actual value will be evaluated randomly between -1/2 to 1 1/2 times the \fItime\fR specified. It defaults to two minutes. +1/2 to 1 1/2 times the \fItime\fR specified. It defaults to fiftenn +secondss. .PP .I The .B initial-interval diff --git a/common/comapi.c b/common/comapi.c index c24b4a6..90d2262 100644 --- a/common/comapi.c +++ b/common/comapi.c @@ -3,6 +3,7 @@ OMAPI object interfaces for the DHCP server. */ /* + * Copyright (c) 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * @@ -435,7 +436,7 @@ isc_result_t dhcp_group_remove (omapi_object_t *lp, status = dhcp_group_destroy ((omapi_object_t *)group, MDL); - return ISC_R_SUCCESS; + return status; } isc_result_t dhcp_control_set_value (omapi_object_t *h, @@ -511,12 +512,12 @@ isc_result_t dhcp_control_destroy (omapi_object_t *h, isc_result_t dhcp_control_signal_handler (omapi_object_t *h, const char *name, va_list ap) { - dhcp_control_object_t *control; + /* In this function h should be a (dhcp_control_object_t *) */ + isc_result_t status; if (h -> type != dhcp_type_control) return DHCP_R_INVALIDARG; - control = (dhcp_control_object_t *)h; /* Try to find some inner object that can take the value. */ if (h -> inner && h -> inner -> type -> get_value) { @@ -572,11 +573,11 @@ isc_result_t dhcp_control_lookup (omapi_object_t **lp, status = omapi_get_value_str (ref, id, "handle", &tv); if (status == ISC_R_SUCCESS) { status = omapi_handle_td_lookup (lp, tv -> value); - + omapi_value_dereference (&tv, MDL); if (status != ISC_R_SUCCESS) return status; - + /* Don't return the object if the type is wrong. */ if ((*lp) -> type != dhcp_type_control) { omapi_object_dereference (lp, MDL); @@ -612,12 +613,12 @@ isc_result_t dhcp_subnet_set_value (omapi_object_t *h, omapi_data_string_t *name, omapi_typed_data_t *value) { - struct subnet *subnet; + /* In this function h should be a (struct subnet *) */ + isc_result_t status; if (h -> type != dhcp_type_subnet) return DHCP_R_INVALIDARG; - subnet = (struct subnet *)h; /* No values to set yet. */ @@ -628,7 +629,7 @@ isc_result_t dhcp_subnet_set_value (omapi_object_t *h, if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } - + return ISC_R_NOTFOUND; } @@ -637,12 +638,12 @@ isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value) { - struct subnet *subnet; + /* In this function h should be a (struct subnet *) */ + isc_result_t status; if (h -> type != dhcp_type_subnet) return DHCP_R_INVALIDARG; - subnet = (struct subnet *)h; /* No values to get yet. */ @@ -658,14 +659,17 @@ isc_result_t dhcp_subnet_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line) { +#if defined (DEBUG_MEMORY_LEAKAGE) || \ + defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) struct subnet *subnet; +#endif if (h -> type != dhcp_type_subnet) return DHCP_R_INVALIDARG; - subnet = (struct subnet *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + subnet = (struct subnet *)h; if (subnet -> next_subnet) subnet_dereference (&subnet -> next_subnet, file, line); if (subnet -> next_sibling) @@ -685,13 +689,13 @@ isc_result_t dhcp_subnet_destroy (omapi_object_t *h, const char *file, int line) isc_result_t dhcp_subnet_signal_handler (omapi_object_t *h, const char *name, va_list ap) { - struct subnet *subnet; + /* In this function h should be a (struct subnet *) */ + isc_result_t status; int updatep = 0; if (h -> type != dhcp_type_subnet) return DHCP_R_INVALIDARG; - subnet = (struct subnet *)h; /* Can't write subnets yet. */ @@ -711,12 +715,12 @@ isc_result_t dhcp_subnet_stuff_values (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) { - struct subnet *subnet; + /* In this function h should be a (struct subnet *) */ + isc_result_t status; if (h -> type != dhcp_type_subnet) return DHCP_R_INVALIDARG; - subnet = (struct subnet *)h; /* Can't stuff subnet values yet. */ @@ -761,12 +765,12 @@ isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, omapi_data_string_t *name, omapi_typed_data_t *value) { - struct shared_network *shared_network; + /* In this function h should be a (struct shared_network *) */ + isc_result_t status; if (h -> type != dhcp_type_shared_network) return DHCP_R_INVALIDARG; - shared_network = (struct shared_network *)h; /* No values to set yet. */ @@ -777,7 +781,7 @@ isc_result_t dhcp_shared_network_set_value (omapi_object_t *h, if (status == ISC_R_SUCCESS || status == DHCP_R_UNCHANGED) return status; } - + return ISC_R_NOTFOUND; } @@ -787,12 +791,12 @@ isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, omapi_data_string_t *name, omapi_value_t **value) { - struct shared_network *shared_network; + /* In this function h should be a (struct shared_network *) */ + isc_result_t status; if (h -> type != dhcp_type_shared_network) return DHCP_R_INVALIDARG; - shared_network = (struct shared_network *)h; /* No values to get yet. */ @@ -809,14 +813,19 @@ isc_result_t dhcp_shared_network_get_value (omapi_object_t *h, isc_result_t dhcp_shared_network_destroy (omapi_object_t *h, const char *file, int line) { + /* In this function h should be a (struct shared_network *) */ + +#if defined (DEBUG_MEMORY_LEAKAGE) || \ + defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) struct shared_network *shared_network; +#endif if (h -> type != dhcp_type_shared_network) return DHCP_R_INVALIDARG; - shared_network = (struct shared_network *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + shared_network = (struct shared_network *)h; if (shared_network -> next) shared_network_dereference (&shared_network -> next, file, line); @@ -849,13 +858,13 @@ isc_result_t dhcp_shared_network_signal_handler (omapi_object_t *h, const char *name, va_list ap) { - struct shared_network *shared_network; + /* In this function h should be a (struct shared_network *) */ + isc_result_t status; int updatep = 0; if (h -> type != dhcp_type_shared_network) return DHCP_R_INVALIDARG; - shared_network = (struct shared_network *)h; /* Can't write shared_networks yet. */ @@ -875,12 +884,12 @@ isc_result_t dhcp_shared_network_stuff_values (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) { - struct shared_network *shared_network; + /* In this function h should be a (struct shared_network *) */ + isc_result_t status; if (h -> type != dhcp_type_shared_network) return DHCP_R_INVALIDARG; - shared_network = (struct shared_network *)h; /* Can't stuff shared_network values yet. */ diff --git a/common/conflex.c b/common/conflex.c index 9c9ed66..0ae5e69 100644 --- a/common/conflex.c +++ b/common/conflex.c @@ -3,7 +3,7 @@ Lexical scanner for dhcpd config file... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -1043,6 +1043,8 @@ intern(char *atom, enum dhcp_token dfv) { return INCLUDE; if (!strcasecmp (atom + 1, "nteger")) return INTEGER; + if (!strcasecmp (atom + 1, "nfiniband")) + return TOKEN_INFINIBAND; if (!strcasecmp (atom + 1, "nfinite")) return INFINITE; if (!strcasecmp (atom + 1, "nfo")) diff --git a/common/dhcp-eval.5 b/common/dhcp-eval.5 index 788c969..db67009 100644 --- a/common/dhcp-eval.5 +++ b/common/dhcp-eval.5 @@ -1,4 +1,4 @@ -.\" $Id: dhcp-eval.5,v 1.29.24.2.4.1 2011-11-28 18:18:51 sar Exp $ +.\" $Id: dhcp-eval.5,v 1.29.24.3 2011-11-28 18:09:30 sar Exp $ .\" .\" Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC") .\" Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC") diff --git a/common/dns.c b/common/dns.c index 3992b6c..53e85a4 100644 --- a/common/dns.c +++ b/common/dns.c @@ -3,7 +3,7 @@ Domain Name Service subroutines. */ /* - * Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2001-2003 by Internet Software Consortium * @@ -813,6 +813,12 @@ void repudiate_zone (struct dns_zone **zone) XXX zones. This isn't a big problem since we're not yet XXX caching zones... :'} */ + /* verify that we have a pointer at least */ + if ((zone == NULL) || (*zone == NULL)) { + log_info("Null argument to repudiate zone"); + return; + } + (*zone) -> timeout = cur_time - 1; dns_zone_dereference (zone, MDL); } @@ -1319,6 +1325,24 @@ void ddns_interlude(isc_task_t *taskp, * need to clean up. */ if ((eresult == ISC_R_CANCELED) || ((ddns_cb->flags & DDNS_ABORT) != 0)) { +#if defined (DEBUG_DNS_UPDATES) + log_info("DDNS: completeing transaction cancellation cb=%p, " + "flags=%x, %s", + ddns_cb, ddns_cb->flags, isc_result_totext(eresult)); +#endif + if ((ddns_cb->flags & DDNS_ABORT) == 0) { + log_info("DDNS: cleaning up lease pointer for a cancel " + "cb=%p", ddns_cb); + /* + * We shouldn't actually be able to get here but + * we are. This means we haven't cleaned up + * the lease pointer so we need to do that before + * freeing the cb. + */ + ddns_cb->cur_func(ddns_cb, eresult); + return; + } + if (ddns_cb->next_op != NULL) { /* if necessary cleanup up next op block */ ddns_cb_free(ddns_cb->next_op, MDL); @@ -1333,6 +1357,8 @@ void ddns_interlude(isc_task_t *taskp, int i; /* Our zone information was questionable, * repudiate it and try again */ + log_error("DDNS: bad zone information, repudiating zone %s", + ddns_cb->zone_name); repudiate_zone(&ddns_cb->zone); ddns_cb->zone_name[0] = 0; ISC_LIST_INIT(ddns_cb->zone_server_list); @@ -1340,20 +1366,18 @@ void ddns_interlude(isc_task_t *taskp, ISC_LINK_INIT(&ddns_cb->zone_addrs[i], link); } - if ((ddns_cb->state & - (DDNS_STATE_ADD_PTR | DDNS_STATE_REM_PTR)) != 0) { - result = ddns_modify_ptr(ddns_cb); + if ((ddns_cb->state == DDNS_STATE_ADD_PTR) || + (ddns_cb->state == DDNS_STATE_REM_PTR)) { + result = ddns_modify_ptr(ddns_cb, MDL); } else { - result = ddns_modify_fwd(ddns_cb); + result = ddns_modify_fwd(ddns_cb, MDL); } if (result != ISC_R_SUCCESS) { - /* if we couldn't redo the query toss it */ - if (ddns_cb->next_op != NULL) { - /* cleanup up next op block */ - ddns_cb_free(ddns_cb->next_op, MDL); - } - ddns_cb_free(ddns_cb, MDL); + /* if we couldn't redo the query log it and + * let the next function clean it up */ + log_info("DDNS: Failed to retry after zone failure"); + ddns_cb->cur_func(ddns_cb, result); } return; } else { @@ -1371,7 +1395,7 @@ void ddns_interlude(isc_task_t *taskp, */ isc_result_t -ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb) +ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line) { isc_result_t result; dns_tsec_t *tsec_key = NULL; @@ -1541,6 +1565,13 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb) #endif cleanup: +#if defined (DEBUG_DNS_UPDATES) + if (result != ISC_R_SUCCESS) { + log_info("DDNS: %s(%d): error in ddns_modify_fwd %s for %p", + file, line, isc_result_totext(result), ddns_cb); + } +#endif + if (dataspace != NULL) { isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, sizeof(*dataspace) * 4); @@ -1550,7 +1581,7 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb) isc_result_t -ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb) +ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line) { isc_result_t result; dns_tsec_t *tsec_key = NULL; @@ -1730,6 +1761,13 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb) #endif cleanup: +#if defined (DEBUG_DNS_UPDATES) + if (result != ISC_R_SUCCESS) { + log_info("DDNS: %s(%d): error in ddns_modify_ptr %s for %p", + file, line, isc_result_totext(result), ddns_cb); + } +#endif + if (dataspace != NULL) { isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, sizeof(*dataspace) * 2); @@ -1738,13 +1776,18 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb) } void -ddns_cancel(dhcp_ddns_cb_t *ddns_cb) { +ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line) { ddns_cb->flags |= DDNS_ABORT; if (ddns_cb->transaction != NULL) { dns_client_cancelupdate((dns_clientupdatetrans_t *) ddns_cb->transaction); } ddns_cb->lease = NULL; + +#if defined (DEBUG_DNS_UPDATES) + log_info("DDNS: %s(%d): cancelling transaction for %p", + file, line, ddns_cb); +#endif } #endif /* NSUPDATE */ diff --git a/common/execute.c b/common/execute.c index 9d08207..363ffa6 100644 --- a/common/execute.c +++ b/common/execute.c @@ -3,7 +3,8 @@ Support for executable statements. */ /* - * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2007 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 @@ -327,66 +328,66 @@ int execute_statements (result, packet, lease, client_state, case set_statement: case define_statement: if (!scope) { - log_error ("set %s: no scope", - r -> data.set.name); + log_error("set %s: no scope", + r->data.set.name); status = 0; break; } if (!*scope) { - if (!binding_scope_allocate (scope, MDL)) { - log_error ("set %s: can't allocate scope", - r -> data.set.name); + if (!binding_scope_allocate(scope, MDL)) { + log_error("set %s: can't allocate scope", + r->data.set.name); status = 0; break; } } - binding = find_binding (*scope, r -> data.set.name); + binding = find_binding(*scope, r->data.set.name); #if defined (DEBUG_EXPRESSIONS) - log_debug ("exec: set %s", r -> data.set.name); + log_debug("exec: set %s", r->data.set.name); #endif - if (!binding) { - binding = dmalloc (sizeof *binding, MDL); - if (binding) { - memset (binding, 0, sizeof *binding); - binding -> name = - dmalloc (strlen - (r -> data.set.name) + 1, - MDL); - if (binding -> name) { - strcpy (binding -> name, - r -> data.set.name); - binding -> next = (*scope) -> bindings; - (*scope) -> bindings = binding; + if (binding == NULL) { + binding = dmalloc(sizeof(*binding), MDL); + if (binding != NULL) { + memset(binding, 0, sizeof(*binding)); + binding->name = + dmalloc(strlen + (r->data.set.name) + 1, + MDL); + if (binding->name != NULL) { + strcpy(binding->name, r->data.set.name); + binding->next = (*scope)->bindings; + (*scope)->bindings = binding; } else { - dfree (binding, MDL); - binding = (struct binding *)0; + dfree(binding, MDL); + binding = NULL; } } } - if (binding) { - if (binding -> value) + if (binding != NULL) { + if (binding->value != NULL) binding_value_dereference - (&binding -> value, MDL); - if (r -> op == set_statement) { + (&binding->value, MDL); + if (r->op == set_statement) { status = (evaluate_expression - (&binding -> value, packet, + (&binding->value, packet, lease, client_state, in_options, out_options, - scope, r -> data.set.expr, + scope, r->data.set.expr, MDL)); } else { if (!(binding_value_allocate - (&binding -> value, MDL))) { - dfree (binding, MDL); - binding = (struct binding *)0; + (&binding->value, MDL))) { + dfree(binding, MDL); + binding = NULL; } - if (binding -> value) { - binding -> value -> type = - binding_function; - (fundef_reference - (&binding -> value -> value.fundef, - r -> data.set.expr -> data.func, - MDL)); + if ((binding != NULL) && + (binding->value != NULL)) { + binding->value->type = + binding_function; + (fundef_reference + (&binding->value->value.fundef, + r->data.set.expr->data.func, + MDL)); } } } diff --git a/common/options.c b/common/options.c index 80fd8db..e485222 100644 --- a/common/options.c +++ b/common/options.c @@ -3,7 +3,7 @@ DHCP options parsing and reassembly. */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -2361,7 +2361,7 @@ prepare_option_buffer(struct universe *universe, struct buffer *bp, cleanup: option_dereference(&option, MDL); - return 1; + return status; } static void @@ -3845,6 +3845,7 @@ do_packet6(struct interface_info *interface, const char *packet, msg_type = packet[0]; if ((msg_type == DHCPV6_RELAY_FORW) || (msg_type == DHCPV6_RELAY_REPL)) { + int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options)); relay = (const struct dhcpv6_relay_packet *)packet; decoded_packet->dhcpv6_msg_type = relay->msg_type; @@ -3856,7 +3857,7 @@ do_packet6(struct interface_info *interface, const char *packet, relay->peer_address, sizeof(relay->peer_address)); if (!parse_option_buffer(decoded_packet->options, - relay->options, len-sizeof(*relay), + relay->options, len - relaylen, &dhcpv6_universe)) { /* no logging here, as parse_option_buffer() logs all cases where it fails */ @@ -3864,6 +3865,7 @@ do_packet6(struct interface_info *interface, const char *packet, return; } } else { + int msglen = (int)(offsetof(struct dhcpv6_packet, options)); msg = (const struct dhcpv6_packet *)packet; decoded_packet->dhcpv6_msg_type = msg->msg_type; @@ -3873,7 +3875,7 @@ do_packet6(struct interface_info *interface, const char *packet, sizeof(decoded_packet->dhcpv6_transaction_id)); if (!parse_option_buffer(decoded_packet->options, - msg->options, len-sizeof(*msg), + msg->options, len - msglen, &dhcpv6_universe)) { /* no logging here, as parse_option_buffer() logs all cases where it fails */ diff --git a/common/packet.c b/common/packet.c index 42bca69..45e96e8 100644 --- a/common/packet.c +++ b/common/packet.c @@ -3,7 +3,8 @@ Packet assembly code, originally contributed by Archie Cobbs. */ /* - * Copyright (c) 2004,2005,2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2005,2007 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 @@ -105,18 +106,25 @@ void assemble_hw_header (interface, buf, bufix, to) unsigned *bufix; struct hardware *to; { -#if defined (HAVE_TR_SUPPORT) - if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802) - assemble_tr_header (interface, buf, bufix, to); - else + switch (interface->hw_address.hbuf[0]) { +#if defined(HAVE_TR_SUPPORT) + case HTYPE_IEEE802: + assemble_tr_header(interface, buf, bufix, to); + break; #endif #if defined (DEC_FDDI) - if (interface -> hw_address.hbuf [0] == HTYPE_FDDI) - assemble_fddi_header (interface, buf, bufix, to); - else + case HTYPE_FDDI: + assemble_fddi_header(interface, buf, bufix, to); + break; #endif - assemble_ethernet_header (interface, buf, bufix, to); - + case HTYPE_INFINIBAND: + log_error("Attempt to assemble hw header for infiniband"); + break; + case HTYPE_ETHER: + default: + assemble_ethernet_header(interface, buf, bufix, to); + break; + } } /* UDP header and IP header assembled together for convenience. */ @@ -184,7 +192,9 @@ void assemble_udp_ip_header (interface, buf, bufix, #ifdef PACKET_DECODING /* Decode a hardware header... */ -/* XXX currently only supports ethernet; doesn't check for other types. */ +/* Support for ethernet, TR and FDDI + * Doesn't support infiniband yet as the supported oses shouldn't get here + */ ssize_t decode_hw_header (interface, buf, bufix, from) struct interface_info *interface; @@ -192,17 +202,22 @@ ssize_t decode_hw_header (interface, buf, bufix, from) unsigned bufix; struct hardware *from; { + switch(interface->hw_address.hbuf[0]) { #if defined (HAVE_TR_SUPPORT) - if (interface -> hw_address.hbuf [0] == HTYPE_IEEE802) - return decode_tr_header (interface, buf, bufix, from); - else + case HTYPE_IEEE802: + return (decode_tr_header(interface, buf, bufix, from)); #endif #if defined (DEC_FDDI) - if (interface -> hw_address.hbuf [0] == HTYPE_FDDI) - return decode_fddi_header (interface, buf, bufix, from); - else + case HTYPE_FDDI: + return (decode_fddi_header(interface, buf, bufix, from)); #endif - return decode_ethernet_header (interface, buf, bufix, from); + case HTYPE_INFINIBAND: + log_error("Attempt to decode hw header for infiniband"); + return (0); + case HTYPE_ETHER: + default: + return (decode_ethernet_header(interface, buf, bufix, from)); + } } /* UDP header and IP header decoded together for convenience. */ diff --git a/common/parse.c b/common/parse.c index 61488c1..434085a 100644 --- a/common/parse.c +++ b/common/parse.c @@ -3,7 +3,7 @@ Common parser code for dhcpd and dhclient. */ /* - * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -569,7 +569,9 @@ parse_ip_addr_with_subnet(cfile, match) /* * hardware-parameter :== HARDWARE hardware-type colon-separated-hex-list SEMI - * hardware-type :== ETHERNET | TOKEN_RING | TOKEN_FDDI + * hardware-type :== ETHERNET | TOKEN_RING | TOKEN_FDDI | INFINIBAND + * Note that INFINIBAND may not be useful for some items, such as classification + * as the hardware address won't always be available. */ void parse_hardware_param (cfile, hardware) @@ -581,24 +583,27 @@ void parse_hardware_param (cfile, hardware) unsigned hlen; unsigned char *t; - token = next_token (&val, (unsigned *)0, cfile); + token = next_token(&val, NULL, cfile); switch (token) { case ETHERNET: - hardware -> hbuf [0] = HTYPE_ETHER; + hardware->hbuf[0] = HTYPE_ETHER; break; case TOKEN_RING: - hardware -> hbuf [0] = HTYPE_IEEE802; + hardware->hbuf[0] = HTYPE_IEEE802; break; case TOKEN_FDDI: - hardware -> hbuf [0] = HTYPE_FDDI; + hardware->hbuf[0] = HTYPE_FDDI; + break; + case TOKEN_INFINIBAND: + hardware->hbuf[0] = HTYPE_INFINIBAND; break; default: - if (!strncmp (val, "unknown-", 8)) { - hardware -> hbuf [0] = atoi (&val [8]); + if (!strncmp(val, "unknown-", 8)) { + hardware->hbuf[0] = atoi(&val[8]); } else { - parse_warn (cfile, - "expecting a network hardware type"); - skip_to_semi (cfile); + parse_warn(cfile, + "expecting a network hardware type"); + skip_to_semi(cfile); return; } @@ -612,34 +617,33 @@ void parse_hardware_param (cfile, hardware) that data in the lease file rather than simply failing on such clients. Yuck. */ hlen = 0; - token = peek_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token == SEMI) { - hardware -> hlen = 1; + hardware->hlen = 1; goto out; } - t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen, - COLON, 16, 8); - if (!t) { - hardware -> hlen = 1; + t = parse_numeric_aggregate(cfile, NULL, &hlen, COLON, 16, 8); + if (t == NULL) { + hardware->hlen = 1; return; } - if (hlen + 1 > sizeof hardware -> hbuf) { - dfree (t, MDL); - parse_warn (cfile, "hardware address too long"); + if (hlen + 1 > sizeof(hardware->hbuf)) { + dfree(t, MDL); + parse_warn(cfile, "hardware address too long"); } else { - hardware -> hlen = hlen + 1; - memcpy ((unsigned char *)&hardware -> hbuf [1], t, hlen); - if (hlen + 1 < sizeof hardware -> hbuf) - memset (&hardware -> hbuf [hlen + 1], 0, - (sizeof hardware -> hbuf) - hlen - 1); - dfree (t, MDL); + hardware->hlen = hlen + 1; + memcpy((unsigned char *)&hardware->hbuf[1], t, hlen); + if (hlen + 1 < sizeof(hardware->hbuf)) + memset(&hardware->hbuf[hlen + 1], 0, + (sizeof(hardware->hbuf)) - hlen - 1); + dfree(t, MDL); } out: - token = next_token (&val, (unsigned *)0, cfile); + token = next_token(&val, NULL, cfile); if (token != SEMI) { - parse_warn (cfile, "expecting semicolon."); - skip_to_semi (cfile); + parse_warn(cfile, "expecting semicolon."); + skip_to_semi(cfile); } } @@ -903,7 +907,7 @@ parse_date_core(cfile) struct parse *cfile; { int guess; - int tzoff, wday, year, mon, mday, hour, min, sec; + int tzoff, year, mon, mday, hour, min, sec; const char *val; enum dhcp_token token; static int months[11] = { 31, 59, 90, 120, 151, 181, @@ -941,7 +945,7 @@ parse_date_core(cfile) return((TIME)0); } token = next_token(&val, NULL, cfile); /* consume day of week */ - wday = atoi(val); + /* we are not using this for anything */ /* Year... */ token = peek_token(&val, NULL, cfile); @@ -3386,11 +3390,10 @@ int parse_boolean_expression (expr, cfile, lose) int parse_boolean (cfile) struct parse *cfile; { - enum dhcp_token token; const char *val; int rv; - token = next_token (&val, (unsigned *)0, cfile); + (void)next_token(&val, NULL, cfile); if (!strcasecmp (val, "true") || !strcasecmp (val, "on")) rv = 1; diff --git a/common/print.c b/common/print.c index e8eac79..d5d0ae0 100644 --- a/common/print.c +++ b/common/print.c @@ -3,7 +3,7 @@ Turn data structures into printable text. */ /* - * Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * @@ -479,10 +479,9 @@ char *print_dotted_quads (len, data) { static char dq_buf [DQLEN + 1]; int i; - char *s, *last; + char *s; s = &dq_buf [0]; - last = s; i = 0; diff --git a/common/socket.c b/common/socket.c index a48404b..f95665c 100644 --- a/common/socket.c +++ b/common/socket.c @@ -3,7 +3,7 @@ BSD socket interface code... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -51,6 +51,7 @@ #include <net/if.h> #include <sys/sockio.h> #include <net/if_dl.h> +#include <sys/dlpi.h> #endif #ifdef USE_SOCKET_FALLBACK @@ -765,7 +766,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) struct sockaddr_in *from; struct hardware *hfrom; { -#if !defined(USE_V4_PKTINFO) +#if !(defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)) SOCKLEN_T flen = sizeof *from; #endif int result; @@ -788,7 +789,6 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) struct cmsghdr *cmsg; struct in_pktinfo *pktinfo; unsigned int ifindex; - int found_pktinfo; /* * If necessary allocate space for the control message header. @@ -831,7 +831,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) * We set up some space for a "control message". We have * previously asked the kernel to give us packet * information (when we initialized the interface), so we - * should get the destination address from that. + * should get the interface index from that. */ m.msg_control = control_buf; m.msg_controllen = control_buf_len; @@ -842,12 +842,8 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) /* * If we did read successfully, then we need to loop * through the control messages we received and - * find the one with our destination address. - * - * We also keep a flag to see if we found it. If we - * didn't, then we consider this to be an error. + * find the one with our inteface index. */ - found_pktinfo = 0; cmsg = CMSG_FIRSTHDR(&m); while (cmsg != NULL) { if ((cmsg->cmsg_level == IPPROTO_IP) && @@ -861,18 +857,21 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) * the discover code. */ memcpy(hfrom->hbuf, &ifindex, sizeof(ifindex)); - found_pktinfo = 1; + return (result); } cmsg = CMSG_NXTHDR(&m, cmsg); } - if (!found_pktinfo) { - result = -1; - errno = EIO; - } + + /* + * We didn't find the necessary control message + * flag it as an error + */ + result = -1; + errno = EIO; } #else - result = recvfrom (interface -> rfdesc, (char *)buf, len, 0, - (struct sockaddr *)from, &flen); + result = recvfrom(interface -> rfdesc, (char *)buf, len, 0, + (struct sockaddr *)from, &flen); #endif /* IP_PKTINFO ... */ #ifdef IGNORE_HOSTUNREACH } while (result < 0 && @@ -880,7 +879,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) errno == ECONNREFUSED) && retry++ < 10); #endif - return result; + return (result); } #endif /* USE_SOCKET_RECEIVE */ @@ -897,7 +896,6 @@ receive_packet6(struct interface_info *interface, int result; struct cmsghdr *cmsg; struct in6_pktinfo *pktinfo; - int found_pktinfo; /* * If necessary allocate space for the control message header. @@ -952,11 +950,7 @@ receive_packet6(struct interface_info *interface, * If we did read successfully, then we need to loop * through the control messages we received and * find the one with our destination address. - * - * We also keep a flag to see if we found it. If we - * didn't, then we consider this to be an error. */ - found_pktinfo = 0; cmsg = CMSG_FIRSTHDR(&m); while (cmsg != NULL) { if ((cmsg->cmsg_level == IPPROTO_IPV6) && @@ -964,17 +958,21 @@ receive_packet6(struct interface_info *interface, pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); *to_addr = pktinfo->ipi6_addr; *if_idx = pktinfo->ipi6_ifindex; - found_pktinfo = 1; + + return (result); } cmsg = CMSG_NXTHDR(&m, cmsg); } - if (!found_pktinfo) { - result = -1; - errno = EIO; - } + + /* + * We didn't find the necessary control message + * flag is as an error + */ + result = -1; + errno = EIO; } - return result; + return (result); } #endif /* DHCPv6 */ @@ -1002,6 +1000,9 @@ isc_result_t fallback_discard (object) log_error ("fallback_discard: %m"); return ISC_R_UNEXPECTED; } +#else + /* ignore the fact that status value is never used */ + IGNORE_UNUSED(status); #endif return ISC_R_SUCCESS; } @@ -1070,7 +1071,7 @@ void maybe_setup_fallback () void get_hw_addr(const char *name, struct hardware *hw) { struct sockaddr_dl *dladdrp; - int rv, sock, i; + int sock, i; struct lifreq lifr; memset(&lifr, 0, sizeof (lifr)); @@ -1104,7 +1105,8 @@ get_hw_addr(const char *name, struct hardware *hw) { hw->hlen = sizeof (hw->hbuf); srandom((long)gethrtime()); - for (i = 0; i < hw->hlen; ++i) { + hw->hbuf[0] = HTYPE_IPMP; + for (i = 1; i < hw->hlen; ++i) { hw->hbuf[i] = random() % 256; } @@ -1117,8 +1119,27 @@ get_hw_addr(const char *name, struct hardware *hw) { log_fatal("Couldn't get interface hardware address for %s: %m", name); dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr; - hw->hlen = dladdrp->sdl_alen; - memcpy(hw->hbuf, LLADDR(dladdrp), hw->hlen); + hw->hlen = dladdrp->sdl_alen+1; + switch (dladdrp->sdl_type) { + case DL_CSMACD: /* IEEE 802.3 */ + case DL_ETHER: + hw->hbuf[0] = HTYPE_ETHER; + break; + case DL_TPR: + hw->hbuf[0] = HTYPE_IEEE802; + break; + case DL_FDDI: + hw->hbuf[0] = HTYPE_FDDI; + break; + case DL_IB: + hw->hbuf[0] = HTYPE_INFINIBAND; + break; + default: + log_fatal("%s: unsupported DLPI MAC type %lu", name, + (unsigned long)dladdrp->sdl_type); + } + + memcpy(hw->hbuf+1, LLADDR(dladdrp), hw->hlen-1); if (sock != -1) (void) close(sock); diff --git a/common/tables.c b/common/tables.c index 10e2ce0..c820d83 100644 --- a/common/tables.c +++ b/common/tables.c @@ -3,6 +3,7 @@ Tables of information... */ /* + * Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * @@ -601,7 +602,7 @@ const char *hardware_types [] = { "unknown-29", "unknown-30", "unknown-31", - "unknown-32", + "infiniband", "unknown-33", "unknown-34", "unknown-35", @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for DHCP 4.2.3-P1. +# Generated by GNU Autoconf 2.61 for DHCP 4.2.4b1. # # Report bugs to <dhcp-users@isc.org>. # @@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='DHCP' PACKAGE_TARNAME='dhcp' -PACKAGE_VERSION='4.2.3-P1' -PACKAGE_STRING='DHCP 4.2.3-P1' +PACKAGE_VERSION='4.2.4b1' +PACKAGE_STRING='DHCP 4.2.4b1' PACKAGE_BUGREPORT='dhcp-users@isc.org' # Factoring default headers for most tests. @@ -1213,7 +1213,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures DHCP 4.2.3-P1 to adapt to many kinds of systems. +\`configure' configures DHCP 4.2.4b1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1279,7 +1279,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of DHCP 4.2.3-P1:";; + short | recursive ) echo "Configuration of DHCP 4.2.4b1:";; esac cat <<\_ACEOF @@ -1419,7 +1419,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -DHCP configure 4.2.3-P1 +DHCP configure 4.2.4b1 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1433,7 +1433,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by DHCP $as_me 4.2.3-P1, which was +It was created by DHCP $as_me 4.2.4b1, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2126,7 +2126,7 @@ fi # Define the identity of the package. PACKAGE='dhcp' - VERSION='4.2.3-P1' + VERSION='4.2.4b1' cat >>confdefs.h <<_ACEOF @@ -4799,9 +4799,9 @@ _ACEOF fi -# Check whether --enable-IPv4_PKTINFO was given. -if test "${enable_IPv4_PKTINFO+set}" = set; then - enableval=$enable_IPv4_PKTINFO; +# Check whether --enable-ipv4_pktinfo was given. +if test "${enable_ipv4_pktinfo+set}" = set; then + enableval=$enable_ipv4_pktinfo; fi @@ -4813,9 +4813,9 @@ _ACEOF fi -# Check whether --enable-USE_SOCKETS was given. -if test "${enable_USE_SOCKETS+set}" = set; then - enableval=$enable_USE_SOCKETS; +# Check whether --enable-use_sockets was given. +if test "${enable_use_sockets+set}" = set; then + enableval=$enable_use_sockets; fi @@ -6796,7 +6796,7 @@ fi then cat >>confdefs.h <<\_ACEOF -#define HAVE_BPF "" +#define HAVE_BPF 1 _ACEOF fi @@ -6974,6 +6974,65 @@ fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext +# +# check for GCC noreturn attribute +# +{ echo "$as_me:$LINENO: checking for GCC noreturn attribute" >&5 +echo $ECHO_N "checking for GCC noreturn attribute... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +void foo() __attribute__((noreturn)); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define ISC_DHCP_NORETURN __attribute__((noreturn)) +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define ISC_DHCP_NORETURN +_ACEOF + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # Look for optional headers. @@ -8119,7 +8178,7 @@ _ACEOF -# Solaris does not have the msg_control or msg_controlen members in +# Solaris does not have the msg_control or msg_controlen members # in the msghdr structure unless you define: # # _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, and __EXTENSIONS__ @@ -9082,7 +9141,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by DHCP $as_me 4.2.3-P1, which was +This file was extended by DHCP $as_me 4.2.4b1, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -9135,7 +9194,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -DHCP config.status 4.2.3-P1 +DHCP config.status 4.2.4b1 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.ac b/configure.ac index 0f3547a..bd84822 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([DHCP], [4.2.3-P1], [dhcp-users@isc.org]) +AC_INIT([DHCP], [4.2.4b1], [dhcp-users@isc.org]) # we specify "foreign" to avoid having to have the GNU mandated files, # like AUTHORS, COPYING, and such @@ -150,7 +150,7 @@ if test "$enable_early_chroot" = "yes" ; then [Define to any value to chroot() prior to loading config.]) fi -AC_ARG_ENABLE(IPv4_PKTINFO, +AC_ARG_ENABLE(ipv4_pktinfo, AC_HELP_STRING([--enable-ipv4-pktinfo], [enable use of pktinfo on IPv4 sockets (default is no)])) @@ -159,7 +159,7 @@ if test "$enable_ipv4_pktinfo" = "yes"; then [Define to 1 to enable IPv4 packet info support.]) fi -AC_ARG_ENABLE(USE_SOCKETS, +AC_ARG_ENABLE(use_sockets, AC_HELP_STRING([--enable-use-sockets], [use the standard BSD socket API (default is no)])) @@ -403,7 +403,7 @@ else AC_CHECK_HEADER(net/bpf.h, DO_BPF=1) if test -n "$DO_BPF" then - AC_DEFINE([HAVE_BPF], [""], + AC_DEFINE([HAVE_BPF], [1], [Define to 1 to use the Berkeley Packet Filter interface code.]) fi @@ -453,6 +453,18 @@ AC_TRY_LINK( [Define to 1 if the system has 'struct if_laddrreq'.])], [AC_MSG_RESULT(no)]) +# +# check for GCC noreturn attribute +# +AC_MSG_CHECKING(for GCC noreturn attribute) +AC_TRY_COMPILE([],[void foo() __attribute__((noreturn));], + [AC_MSG_RESULT(yes) + AC_DEFINE([ISC_DHCP_NORETURN], [__attribute__((noreturn))], + [Define to the string for a noreturn attribute.])], + [AC_MSG_RESULT(no) + AC_DEFINE([ISC_DHCP_NORETURN], [], + [Define to the string for a noreturn attribute.])]) + # Look for optional headers. AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h) @@ -488,7 +500,7 @@ AC_CHECK_SIZEOF(struct iaddr *, , [ #include <stdio.h> ]) -# Solaris does not have the msg_control or msg_controlen members in +# Solaris does not have the msg_control or msg_controlen members # in the msghdr structure unless you define: # # _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, and __EXTENSIONS__ diff --git a/doc/References.html b/doc/References.html index 9bf4dc4..b20b5aa 100644 --- a/doc/References.html +++ b/doc/References.html @@ -145,7 +145,7 @@ <tr><td class="header">ISC-DHCP-REFERENCES</td><td class="header">D. Hankins</td></tr> <tr><td class="header"> </td><td class="header">T. Mrugalski</td></tr> <tr><td class="header"> </td><td class="header">ISC</td></tr> -<tr><td class="header"> </td><td class="header">May 20, 2011</td></tr> +<tr><td class="header"> </td><td class="header">January 04, 2012</td></tr> </table></td></tr></table> <h1><br />ISC DHCP References Collection</h1> @@ -740,6 +740,10 @@ DHCPv6 Protocol References</h3> <p>Precisely how to correctly support the above conundrums has not quite yet been settled, so support is incomplete. </p> +<p><a class='info' href='#RFC5453'>[RFC5453]<span> (</span><span class='info'>Krishnan, S., “Reserved IPv6 Interface Identifiers,” February 2009.</span><span>)</span></a> creates a registry at IANA to reserve + interface identifiers and specifies a starting set. These IIDs should + not be used when constructing addresses to avoid possible conflicts. +</p> <a name="anchor20"></a><br /><hr /> <table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc"> TOC </a></td></tr></table> <a name="rfc.section.6.2"></a><h3>6.2. @@ -974,14 +978,16 @@ References</h3> <td class="author-text">Zeng, S., Volz, B., Kinnear, K., and J. Brzozowski, “<a href="http://tools.ietf.org/html/rfc4994">DHCPv6 Relay Agent Echo Request Option</a>,” RFC 4994, September 2007 (<a href="http://www.rfc-editor.org/rfc/rfc4994.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="RFC5007">[RFC5007]</a></td> <td class="author-text">Brzozowski, J., Kinnear, K., Volz, B., and S. Zeng, “<a href="http://tools.ietf.org/html/rfc5007">DHCPv6 Leasequery</a>,” RFC 5007, September 2007 (<a href="http://www.rfc-editor.org/rfc/rfc5007.txt">TXT</a>).</td></tr> +<tr><td class="author-text" valign="top"><a name="RFC5453">[RFC5453]</a></td> +<td class="author-text">Krishnan, S., “<a href="http://tools.ietf.org/html/rfc5453">Reserved IPv6 Interface Identifiers</a>,” RFC 5453, February 2009 (<a href="http://www.rfc-editor.org/rfc/rfc5453.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="RFC5460">[RFC5460]</a></td> <td class="author-text">Stapp, M., “<a href="http://tools.ietf.org/html/rfc5460">DHCPv6 Bulk Leasequery</a>,” RFC 5460, February 2009 (<a href="http://www.rfc-editor.org/rfc/rfc5460.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="I-D.ietf-mif-dhcpv6-route-option">[I-D.ietf-mif-dhcpv6-route-option]</a></td> -<td class="author-text">Dec, W., Mrugalski, T., Sun, T., and B. Sarikaya, “<a href="http://tools.ietf.org/html/draft-ietf-mif-dhcpv6-route-option-01">DHCPv6 Route Option</a>,” draft-ietf-mif-dhcpv6-route-option-01 (work in progress), March 2011 (<a href="http://www.ietf.org/internet-drafts/draft-ietf-mif-dhcpv6-route-option-01.txt">TXT</a>).</td></tr> +<td class="author-text">Dec, W., Mrugalski, T., Sun, T., and B. Sarikaya, “<a href="http://tools.ietf.org/html/draft-ietf-mif-dhcpv6-route-option-03">DHCPv6 Route Options</a>,” draft-ietf-mif-dhcpv6-route-option-03 (work in progress), September 2011 (<a href="http://www.ietf.org/internet-drafts/draft-ietf-mif-dhcpv6-route-option-03.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="I-D.ietf-dhc-dhcpv6-ldra">[I-D.ietf-dhc-dhcpv6-ldra]</a></td> <td class="author-text">Miles, D., Ooghe, S., Dec, W., Krishnan, S., and A. Kavanagh, “<a href="http://tools.ietf.org/html/draft-ietf-dhc-dhcpv6-ldra-03">Lightweight DHCPv6 Relay Agent</a>,” draft-ietf-dhc-dhcpv6-ldra-03 (work in progress), October 2010 (<a href="http://www.ietf.org/internet-drafts/draft-ietf-dhc-dhcpv6-ldra-03.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="I-D.ietf-dhc-dhcpv6-relay-supplied-options">[I-D.ietf-dhc-dhcpv6-relay-supplied-options]</a></td> -<td class="author-text">Lemon, T. and W. Wu, “<a href="http://tools.ietf.org/html/draft-ietf-dhc-dhcpv6-relay-supplied-options-06">Relay-Supplied DHCP Options</a>,” draft-ietf-dhc-dhcpv6-relay-supplied-options-06 (work in progress), May 2011 (<a href="http://www.ietf.org/internet-drafts/draft-ietf-dhc-dhcpv6-relay-supplied-options-06.txt">TXT</a>).</td></tr> +<td class="author-text">Lemon, T. and W. Wu, “<a href="http://tools.ietf.org/html/draft-ietf-dhc-dhcpv6-relay-supplied-options-09">Relay-Supplied DHCP Options</a>,” draft-ietf-dhc-dhcpv6-relay-supplied-options-09 (work in progress), September 2011 (<a href="http://www.ietf.org/internet-drafts/draft-ietf-dhc-dhcpv6-relay-supplied-options-09.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="I-D.ietf-dhc-pd-exclude">[I-D.ietf-dhc-pd-exclude]</a></td> <td class="author-text">Korhonen, J., Savolainen, T., Krishnan, S., and O. Troan, “<a href="http://tools.ietf.org/html/draft-ietf-dhc-pd-exclude-01">Prefix Exclude Option for DHCPv6-based Prefix Delegation</a>,” draft-ietf-dhc-pd-exclude-01 (work in progress), January 2011 (<a href="http://www.ietf.org/internet-drafts/draft-ietf-dhc-pd-exclude-01.txt">TXT</a>).</td></tr> <tr><td class="author-text" valign="top"><a name="I-D.ietf-dhc-secure-dhcpv6">[I-D.ietf-dhc-secure-dhcpv6]</a></td> diff --git a/doc/References.txt b/doc/References.txt index 9d28f23..2872726 100644 --- a/doc/References.txt +++ b/doc/References.txt @@ -4,7 +4,7 @@ ISC-DHCP-REFERENCES D. Hankins T. Mrugalski ISC - May 20, 2011 + January 04, 2012 ISC DHCP References Collection @@ -54,7 +54,7 @@ Copyright Notice Hankins & Mrugalski [Page 1] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 Table of Contents @@ -110,7 +110,7 @@ Table of Contents Hankins & Mrugalski [Page 2] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 1. Introduction @@ -166,7 +166,7 @@ Hankins & Mrugalski [Page 2] Hankins & Mrugalski [Page 3] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 o To produce new externally-visible behaviour, one must first @@ -222,7 +222,7 @@ Hankins & Mrugalski [Page 3] Hankins & Mrugalski [Page 4] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 address yet) interface. @@ -278,7 +278,7 @@ Hankins & Mrugalski [Page 4] Hankins & Mrugalski [Page 5] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 now unicast without ARP by inserting an entry into the ARP cache @@ -334,7 +334,7 @@ Hankins & Mrugalski [Page 5] Hankins & Mrugalski [Page 6] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 5. DHCPv4 Protocol References @@ -390,7 +390,7 @@ Hankins & Mrugalski [Page 6] Hankins & Mrugalski [Page 7] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 RFC2485 [RFC2485] defines the Open Group's UAP option. @@ -446,7 +446,7 @@ Hankins & Mrugalski [Page 7] Hankins & Mrugalski [Page 8] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 5.2.1. Relay Agent Information Option Options @@ -502,7 +502,7 @@ Hankins & Mrugalski [Page 8] Hankins & Mrugalski [Page 9] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 this document was edited, and the authors no longer show any interest @@ -558,7 +558,7 @@ Hankins & Mrugalski [Page 9] Hankins & Mrugalski [Page 10] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 IA_NAs within one packet from the client, our client only supports @@ -586,6 +586,10 @@ Hankins & Mrugalski [Page 10] Precisely how to correctly support the above conundrums has not quite yet been settled, so support is incomplete. + [RFC5453] creates a registry at IANA to reserve interface identifiers + and specifies a starting set. These IIDs should not be used when + constructing addresses to avoid possible conflicts. + 6.2. DHCPv6 Options References [RFC3319] defines the SIP server options for DHCPv6. @@ -605,18 +609,19 @@ Hankins & Mrugalski [Page 10] [RFC4242] defines the Information Refresh Time option, which advises DHCPv6 Information-Request clients to return for updated information. - [RFC4280] defines two BCMS server options for each protocol family. - - [RFC4580] defines a DHCPv6 subscriber-id option, which is similar in - principle to the DHCPv4 relay agent option of the same name. Hankins & Mrugalski [Page 11] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + [RFC4280] defines two BCMS server options for each protocol family. + + [RFC4580] defines a DHCPv6 subscriber-id option, which is similar in + principle to the DHCPv4 relay agent option of the same name. + [RFC4649] defines a DHCPv6 remote-id option, which is similar in principle to the DHCPv4 relay agent remote-id. @@ -661,18 +666,17 @@ Hankins & Mrugalski [Page 11] [RFC2485] Drach, S., "DHCP Option for The Open Group's User Authentication Protocol", RFC 2485, January 1999. - [RFC2563] Troll, R., "DHCP Option to Disable Stateless Auto- - Configuration in IPv4 Clients", RFC 2563, May 1999. - - [RFC2610] Perkins, C. and E. Guttman, "DHCP Options for Service - Hankins & Mrugalski [Page 12] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + [RFC2563] Troll, R., "DHCP Option to Disable Stateless Auto- + Configuration in IPv4 Clients", RFC 2563, May 1999. + + [RFC2610] Perkins, C. and E. Guttman, "DHCP Options for Service Location Protocol", RFC 2610, June 1999. [RFC2855] Fujisawa, K., "DHCP for IEEE 1394", RFC 2855, June 2000. @@ -717,18 +721,18 @@ Hankins & Mrugalski [Page 12] November 2002. [RFC3397] Aboba, B. and S. Cheshire, "Dynamic Host Configuration - Protocol (DHCP) Domain Search Option", RFC 3397, - November 2002. - - [RFC3442] Lemon, T., Cheshire, S., and B. Volz, "The Classless Hankins & Mrugalski [Page 13] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + + Protocol (DHCP) Domain Search Option", RFC 3397, + November 2002. + [RFC3442] Lemon, T., Cheshire, S., and B. Volz, "The Classless Static Route Option for Dynamic Host Configuration Protocol (DHCP) version 4", RFC 3442, December 2002. @@ -773,17 +777,18 @@ Hankins & Mrugalski [Page 13] Suboption for the Dynamic Host Configuration Protocol (DHCP) Relay Agent Option", RFC 3993, March 2005. - [RFC4014] Droms, R. and J. Schnizlein, "Remote Authentication - Dial-In User Service (RADIUS) Attributes Suboption for the - Dynamic Host Configuration Protocol (DHCP) Relay Agent - Information Option", RFC 4014, February 2005. Hankins & Mrugalski [Page 14] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + + [RFC4014] Droms, R. and J. Schnizlein, "Remote Authentication + Dial-In User Service (RADIUS) Attributes Suboption for the + Dynamic Host Configuration Protocol (DHCP) Relay Agent + Information Option", RFC 4014, February 2005. [RFC4030] Stapp, M. and T. Lemon, "The Authentication Suboption for the Dynamic Host Configuration Protocol (DHCP) Relay Agent @@ -829,18 +834,17 @@ Hankins & Mrugalski [Page 14] Configuration Protocol (DHCP) Clients", RFC 4703, October 2006. - [RFC5010] Kinnear, K., Normoyle, M., and M. Stapp, "The Dynamic Host - Configuration Protocol Version 4 (DHCPv4) Relay Agent - Flags Suboption", RFC 5010, September 2007. - - Hankins & Mrugalski [Page 15] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + [RFC5010] Kinnear, K., Normoyle, M., and M. Stapp, "The Dynamic Host + Configuration Protocol Version 4 (DHCPv4) Relay Agent + Flags Suboption", RFC 5010, September 2007. + [RFC5071] Hankins, D., "Dynamic Host Configuration Protocol Options Used by PXELINUX", RFC 5071, December 2007. @@ -885,18 +889,19 @@ Hankins & Mrugalski [Page 15] draft-ietf-dhc-leasequery-by-remote-id-09 (work in progress), December 2010. - [I-D.ietf-dhc-relay-id-suboption] - Stapp, M., "The DHCPv4 Relay Agent Identifier Suboption", - draft-ietf-dhc-relay-id-suboption-07 (work in progress), - July 2009. Hankins & Mrugalski [Page 16] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + [I-D.ietf-dhc-relay-id-suboption] + Stapp, M., "The DHCPv4 Relay Agent Identifier Suboption", + draft-ietf-dhc-relay-id-suboption-07 (work in progress), + July 2009. + [I-D.ietf-mip6-hiopt] Jang, H., Yegin, A., Chowdhury, K., and J. Choi, "DHCP Options for Home Information Discovery in MIPv6", @@ -941,18 +946,17 @@ Hankins & Mrugalski [Page 16] Location Information Server (LIS)", RFC 5986, September 2010. - [I-D.ietf-dhc-vpn-option] - Kinnear, K., Johnson, R., and M. Stapp, "Virtual Subnet - Selection Options for DHCPv4 and DHCPv6", - draft-ietf-dhc-vpn-option-12 (work in progress), - Hankins & Mrugalski [Page 17] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + [I-D.ietf-dhc-vpn-option] + Kinnear, K., Johnson, R., and M. Stapp, "Virtual Subnet + Selection Options for DHCPv4 and DHCPv6", + draft-ietf-dhc-vpn-option-12 (work in progress), October 2010. 7.3. Published DHCPv6 References @@ -997,18 +1001,18 @@ Hankins & Mrugalski [Page 17] [RFC4649] Volz, B., "Dynamic Host Configuration Protocol for IPv6 (DHCPv6) Relay Agent Remote-ID Option", RFC 4649, - August 2006. - - [RFC4704] Volz, B., "The Dynamic Host Configuration Protocol for - IPv6 (DHCPv6) Client Fully Qualified Domain Name (FQDN) Hankins & Mrugalski [Page 18] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + August 2006. + + [RFC4704] Volz, B., "The Dynamic Host Configuration Protocol for + IPv6 (DHCPv6) Client Fully Qualified Domain Name (FQDN) Option", RFC 4704, October 2006. [RFC4994] Zeng, S., Volz, B., Kinnear, K., and J. Brzozowski, @@ -1018,13 +1022,16 @@ Hankins & Mrugalski [Page 18] [RFC5007] Brzozowski, J., Kinnear, K., Volz, B., and S. Zeng, "DHCPv6 Leasequery", RFC 5007, September 2007. + [RFC5453] Krishnan, S., "Reserved IPv6 Interface Identifiers", + RFC 5453, February 2009. + [RFC5460] Stapp, M., "DHCPv6 Bulk Leasequery", RFC 5460, February 2009. [I-D.ietf-mif-dhcpv6-route-option] Dec, W., Mrugalski, T., Sun, T., and B. Sarikaya, "DHCPv6 - Route Option", draft-ietf-mif-dhcpv6-route-option-01 (work - in progress), March 2011. + Route Options", draft-ietf-mif-dhcpv6-route-option-03 + (work in progress), September 2011. [I-D.ietf-dhc-dhcpv6-ldra] Miles, D., Ooghe, S., Dec, W., Krishnan, S., and A. @@ -1034,8 +1041,8 @@ Hankins & Mrugalski [Page 18] [I-D.ietf-dhc-dhcpv6-relay-supplied-options] Lemon, T. and W. Wu, "Relay-Supplied DHCP Options", - draft-ietf-dhc-dhcpv6-relay-supplied-options-06 (work in - progress), May 2011. + draft-ietf-dhc-dhcpv6-relay-supplied-options-09 (work in + progress), September 2011. [I-D.ietf-dhc-pd-exclude] Korhonen, J., Savolainen, T., Krishnan, S., and O. Troan, @@ -1050,21 +1057,21 @@ Hankins & Mrugalski [Page 18] [I-D.ietf-mext-nemo-pd] Droms, R., Thubert, P., Dupont, F., Haddad, W., and C. - Bernardos, "DHCPv6 Prefix Delegation for NEMO", - draft-ietf-mext-nemo-pd-07 (work in progress), - December 2010. - - [I-D.ietf-dhc-duid-uuid] - Narten, T. and J. Johnson, "Definition of the UUID-based - DHCPv6 Unique Identifier (DUID-UUID)", Hankins & Mrugalski [Page 19] - ISC DHCP References Collection May 2011 + ISC DHCP References Collection January 2012 + Bernardos, "DHCPv6 Prefix Delegation for NEMO", + draft-ietf-mext-nemo-pd-07 (work in progress), + December 2010. + + [I-D.ietf-dhc-duid-uuid] + Narten, T. and J. Johnson, "Definition of the UUID-based + DHCPv6 Unique Identifier (DUID-UUID)", draft-ietf-dhc-duid-uuid-03 (work in progress), February 2011. @@ -1100,6 +1107,20 @@ Authors' Addresses Redwood City, CA 94063 + + + + + + + + + +Hankins & Mrugalski [Page 20] + + ISC DHCP References Collection January 2012 + + Tomasz Mrugalski Internet Systems Consortium, Inc. 950 Charter Street @@ -1116,5 +1137,40 @@ Authors' Addresses -Hankins & Mrugalski [Page 20] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Hankins & Mrugalski [Page 21] diff --git a/doc/References.xml b/doc/References.xml index de19fd0..c8a7739 100644 --- a/doc/References.xml +++ b/doc/References.xml @@ -1,6 +1,6 @@ <?xml version='1.0' ?> -<!-- $Id: References.xml,v 1.4.24.3 2011-07-05 16:57:20 sar Exp $ --> +<!-- $Id: References.xml,v 1.4.24.4 2012-01-05 00:02:51 sar Exp $ --> <?rfc private="ISC-DHCP-REFERENCES" ?> @@ -92,6 +92,8 @@ 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4702.xml'> <!ENTITY rfc4703 PUBLIC '' 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.4703.xml'> + <!ENTITY rfc5453 PUBLIC '' + 'http://xml.resource.org/public/rfc/bibxml/reference.RFC.5453.xml'> ]> @@ -133,7 +135,7 @@ </address> </author> - <date day="20" month="May" year="2011"/> + <date day="04" month="January" year="2012"/> <keyword>ISC</keyword> <keyword>DHCP</keyword> @@ -610,6 +612,10 @@ <t>Precisely how to correctly support the above conundrums has not quite yet been settled, so support is incomplete.</t> + + <t><xref target="RFC5453"/> creates a registry at IANA to reserve + interface identifiers and specifies a starting set. These IIDs should + not be used when constructing addresses to avoid possible conflicts.</t> </section> <section title="DHCPv6 Options References"> @@ -760,6 +766,7 @@ <?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.4704'?> <?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.4994'?> <?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5007'?> + <?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5453'?> <?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5460'?> <?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-mif-dhcpv6-route-option'?> <?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-dhc-dhcpv6-ldra'?> diff --git a/dst/dst_api.c b/dst/dst_api.c index 8925c66..7eac3a8 100644 --- a/dst/dst_api.c +++ b/dst/dst_api.c @@ -1,10 +1,11 @@ #ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/prod/DHCP/dst/dst_api.c,v 1.9 2009-10-29 00:46:48 sar Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/prod/DHCP/dst/dst_api.c,v 1.9.6.1 2012-04-11 15:43:55 sar Exp $"; #endif /* * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. * Portions Copyright (c) 2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -342,7 +343,7 @@ dst_read_key(const char *in_keyname, const unsigned in_id, in_alg)); return (NULL); } - if ((type && (DST_PUBLIC | DST_PRIVATE)) == 0) + if ((type & (DST_PUBLIC | DST_PRIVATE)) == 0) return (NULL); if (in_keyname == NULL) { EREPORT(("dst_read_private_key(): Null key name passed in\n")); diff --git a/dst/prandom.c b/dst/prandom.c index 4de3fe4..5efad8f 100644 --- a/dst/prandom.c +++ b/dst/prandom.c @@ -1,9 +1,9 @@ #ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/prod/DHCP/dst/prandom.c,v 1.8.6.1 2009-11-20 01:49:01 sar Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/prod/DHCP/dst/prandom.c,v 1.8.6.2 2012-03-09 11:28:11 tomasz Exp $"; #endif /* + * Portions Copyright (c) 2007,2009,2012 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. - * Portions Copyright (c) 2007,2009 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -694,7 +694,6 @@ own_random(dst_work *work) { int dir = 0, b; int bytes, n, cmd = 0, dig = 0; - int start =0; /* * now get the initial seed to put into the quick random function from * the address of the work structure @@ -709,7 +708,6 @@ own_random(dst_work *work) /* pick a random number in the range of 0..7 based on that random number * perform some operations that yield random data */ - start = work->filled; n = (dst_s_quick_random(bytes) >> DST_SHIFT) & 0x07; switch (n) { case 0: diff --git a/includes/cdefs.h b/includes/cdefs.h index 2f61ed7..eab1c4b 100644 --- a/includes/cdefs.h +++ b/includes/cdefs.h @@ -3,8 +3,8 @@ Standard C definitions... */ /* - * Copyright (c) 2011 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 2004,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2009,2011 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * Copyright (c) 1995 RadioMail Corporation. All rights reserved. * @@ -46,15 +46,25 @@ * the warning by the use of void. In conjunction with the use of -Werror * these warnings prohibit the compilation of the package. This macro * allows us to assign the return value to a variable and then ignore it. + * + * __attribute__((unused)) is added for avoiding another warning about set, + * but unused variable. This is produced by unused-but-set-variable switch + * that is enabled by default in gcc 4.6. */ #if !defined(__GNUC__) || (__GNUC__ < 4) #define IGNORE_RET(x) (void) x #else #define IGNORE_RET(x) \ do { \ - int ignore_return; \ - ignore_return = x; \ + int __attribute__((unused)) ignore_return ;\ + ignore_return = x; \ } while (0) #endif +/* This macro is defined to avoid unused-but-set-variable warning + * that is enabled in gcc 4.6 + */ + +#define IGNORE_UNUSED(x) { x = x; } + #endif /* __ISC_DHCP_CDEFS_H__ */ diff --git a/includes/config.h.in b/includes/config.h.in index 2e52f7d..b6014c3 100644 --- a/includes/config.h.in +++ b/includes/config.h.in @@ -91,6 +91,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to the string for a noreturn attribute. */ +#undef ISC_DHCP_NORETURN + /* Define to 1 if the system has 'struct if_laddrconf'. */ #undef ISC_PLATFORM_HAVEIF_LADDRCONF diff --git a/includes/dhcp.h b/includes/dhcp.h index 1af2adf..5eb1ad8 100644 --- a/includes/dhcp.h +++ b/includes/dhcp.h @@ -3,6 +3,7 @@ Protocol structures... */ /* + * Copyright (c) 2011-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-2003 by Internet Software Consortium * @@ -79,6 +80,10 @@ struct dhcp_packet { #define HTYPE_ETHER 1 /* Ethernet 10Mbps */ #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */ #define HTYPE_FDDI 8 /* FDDI... */ +#define HTYPE_INFINIBAND 32 /* IP over Infiniband */ +#define HTYPE_IPMP 255 /* IPMP - random hw address - there + * is no standard for this so we + * just steal a type */ /* Magic cookie validating dhcp options field (and bootp vendor extensions field). */ diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 863a149..f548648 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -3,7 +3,7 @@ Definitions for dhcpd... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -436,7 +436,7 @@ struct packet { struct hardware { u_int8_t hlen; - u_int8_t hbuf [17]; + u_int8_t hbuf[21]; }; #if defined(LDAP_CONFIGURATION) @@ -1557,7 +1557,7 @@ struct ipv6_pool { #define DDNS_EXECUTE_NEXT 0x20 #define DDNS_ABORT 0x40 #define DDNS_STATIC_LEASE 0x80 - +#define DDNS_ACTIVE_LEASE 0x100 /* * The following two groups are separate and we could reuse * values but not reusing them may be useful in the future. @@ -1598,7 +1598,7 @@ typedef struct dhcp_ddns_cb { int zone_addr_count; struct dns_zone *zone; - int flags; + u_int16_t flags; TIME timeout; int state; ddns_action_t cur_func; @@ -1950,7 +1950,8 @@ void parse_server_duid_conf(struct parse *cfile); /* ddns.c */ int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *); -int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *); +isc_result_t ddns_removals(struct lease *, struct iasubopt *, + struct dhcp_ddns_cb *, isc_boolean_t); #if defined (TRACING) void trace_ddns_init(void); #endif @@ -3243,7 +3244,10 @@ void make_binding_state_transition (struct lease *); int lease_copy (struct lease **, struct lease *, const char *, int); void release_lease (struct lease *, struct packet *); void abandon_lease (struct lease *, const char *); +#if 0 +/* this appears to be unused and I plan to remove it SAR */ void dissociate_lease (struct lease *); +#endif void pool_timer (void *); int find_lease_by_uid (struct lease **, const unsigned char *, unsigned, const char *, int); @@ -3509,9 +3513,13 @@ isc_result_t release_lease6(struct ipv6_pool *pool, struct iasubopt *lease); isc_result_t decline_lease6(struct ipv6_pool *pool, struct iasubopt *lease); isc_boolean_t lease6_exists(const struct ipv6_pool *pool, const struct in6_addr *addr); +isc_boolean_t lease6_usable(struct iasubopt *lease); +isc_result_t cleanup_lease6(ia_hash_t *ia_table, + struct ipv6_pool *pool, + struct iasubopt *lease, + struct ia_xx *ia); isc_result_t mark_lease_unavailble(struct ipv6_pool *pool, const struct in6_addr *addr); - isc_result_t create_prefix6(struct ipv6_pool *pool, struct iasubopt **pref, unsigned int *attempts, @@ -3543,13 +3551,13 @@ void ddns_cb_forget_zone (dhcp_ddns_cb_t *ddns_cb); //void *key_from_zone(struct dns_zone *zone); isc_result_t -ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb); +ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line); isc_result_t -ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb); +ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line); void -ddns_cancel(dhcp_ddns_cb_t *ddns_cb); +ddns_cancel(dhcp_ddns_cb_t *ddns_cb, const char *file, int line); #define MAX_ADDRESS_STRING_LEN \ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")) diff --git a/includes/dhctoken.h b/includes/dhctoken.h index 9911d70..6815da4 100644 --- a/includes/dhctoken.h +++ b/includes/dhctoken.h @@ -3,7 +3,7 @@ Tokens for config file lexer and parser. */ /* - * Copyright (c) 2004,2007-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2007-2012 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 @@ -363,7 +363,8 @@ enum dhcp_token { INITIAL_DELAY = 664, GETHOSTBYNAME = 665, PRIMARY6 = 666, - SECONDARY6 = 667 + SECONDARY6 = 667, + TOKEN_INFINIBAND = 668 }; #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/includes/omapip/omapip_p.h b/includes/omapip/omapip_p.h index 1fab5a9..51a7b90 100644 --- a/includes/omapip/omapip_p.h +++ b/includes/omapip/omapip_p.h @@ -289,7 +289,7 @@ extern int log_perror; extern void (*log_cleanup) (void); void log_fatal (const char *, ...) - __attribute__((__format__(__printf__,1,2))); + __attribute__((__format__(__printf__,1,2))) ISC_DHCP_NORETURN; int log_error (const char *, ...) __attribute__((__format__(__printf__,1,2))); int log_info (const char *, ...) diff --git a/includes/site.h b/includes/site.h index b78b537..89c77a9 100644 --- a/includes/site.h +++ b/includes/site.h @@ -227,3 +227,13 @@ future. */ #define ACCEPT_LIST_IN_DOMAIN_NAME + +/* In RFC3315 section 17.2.2 stated that if the server was not going + to be able to assign any addresses to any IAs in a subsequent Request + from a client that the server should not include any IAs. This + requirement was removed in an errata from August 2010. Define the + following if you want the pre-errata version. + You should only enable this option if you have clients that + require the original functionality. */ + +/* #define RFC3315_PRE_ERRATA_2010_08 */ diff --git a/omapip/handle.c b/omapip/handle.c index b69ef12..8405acf 100644 --- a/omapip/handle.c +++ b/omapip/handle.c @@ -3,7 +3,7 @@ Functions for maintaining handles on objects. */ /* - * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009-2010,2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * @@ -252,7 +252,6 @@ static isc_result_t omapi_handle_lookup_in (omapi_object_t **o, omapi_handle_table_t *table, int op) { - omapi_handle_table_t *inner; omapi_handle_t scale, index; if (!table || table->first > h || table->limit <= h) @@ -282,7 +281,6 @@ static isc_result_t omapi_handle_lookup_in (omapi_object_t **o, handle must be the subtable of this table whose index into this table's array of children is the handle divided by the scale. */ index = (h - table->first) / scale; - inner = table->children[index].table; return(omapi_handle_lookup_in(o, h, table->children[index].table, op)); } diff --git a/omapip/listener.c b/omapip/listener.c index 0c4dcb1..30259eb 100644 --- a/omapip/listener.c +++ b/omapip/listener.c @@ -3,6 +3,7 @@ Subroutines that support the generic listener object. */ /* + * Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999-2003 by Internet Software Consortium * @@ -124,7 +125,7 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, status = ISC_R_UNEXPECTED; goto error_exit; } - + #if defined (HAVE_SETFD) if (fcntl (obj -> socket, F_SETFD, 1) < 0) { status = ISC_R_UNEXPECTED; @@ -140,7 +141,7 @@ isc_result_t omapi_listen_addr (omapi_object_t *h, status = ISC_R_UNEXPECTED; goto error_exit; } - + /* Try to bind to the wildcard address using the port number we were given. */ i = bind (obj -> socket, @@ -369,6 +370,10 @@ static void trace_listener_accept_input (trace_type_t *ttype, obj = (omapi_connection_object_t *)0; status = omapi_listener_connect (&obj, lp, 0, &remote_addr); + if (status != ISC_R_SUCCESS) { + log_error("%s:%d: OMAPI: Failed to connect " + "a listener.", MDL); + } omapi_listener_dereference (&lp, MDL); return; } diff --git a/omapip/protocol.c b/omapip/protocol.c index 1a6d7e8..9906489 100644 --- a/omapip/protocol.c +++ b/omapip/protocol.c @@ -3,7 +3,8 @@ Functions supporting the object management protocol... */ /* - * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2007 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 @@ -926,12 +927,10 @@ isc_result_t omapi_protocol_destroy (omapi_object_t *h, dfree (p -> default_auth, file, line); while (p -> remote_auth_list) { - omapi_remote_auth_t *r = p -> remote_auth_list -> next; - p -> remote_auth_list = r; - if (r) { - omapi_object_dereference (&r -> a, file, line); - dfree (r, file, line); - } + omapi_remote_auth_t *r = p -> remote_auth_list; + p -> remote_auth_list = p -> remote_auth_list -> next; + omapi_object_dereference (&r -> a, file, line); + dfree (r, file, line); } return ISC_R_SUCCESS; } diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 8beeb93..812f838 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -3,7 +3,7 @@ DHCP/BOOTP Relay Agent. */ /* - * Copyright(c) 2004-2011 by Internet Systems Consortium, Inc.("ISC") + * Copyright(c) 2004-2012 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 @@ -136,7 +136,7 @@ static int strip_relay_agent_options(struct interface_info *, struct dhcp_packet *, unsigned); static const char copyright[] = -"Copyright 2004-2011 Internet Systems Consortium."; +"Copyright 2004-2012 Internet Systems Consortium."; static const char arr[] = "All rights reserved."; static const char message[] = "Internet Systems Consortium DHCP Relay Agent"; diff --git a/server/bootp.c b/server/bootp.c index c88fab8..f0b787c 100644 --- a/server/bootp.c +++ b/server/bootp.c @@ -3,7 +3,8 @@ BOOTP Protocol support. */ /* - * Copyright (c) 2004,2005,2007,2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004,2005,2007 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 @@ -176,11 +177,12 @@ void bootp (packet) } /* Execute the host statements. */ - execute_statements_in_scope ((struct binding_value **)0, - packet, lease, (struct client_state *)0, - packet -> options, options, - &lease -> scope, - hp -> group, lease -> subnet -> group); + if (hp != NULL) { + execute_statements_in_scope (NULL, packet, lease, NULL, + packet->options, options, + &lease->scope, + hp->group, lease->subnet->group); + } /* Drop the request if it's not allowed for this client. */ if ((oc = lookup_option (&server_universe, options, SV_ALLOW_BOOTP)) && @@ -361,15 +363,16 @@ void bootp (packet) } /* Report what we're doing... */ - log_info ("%s", msgbuf); - log_info ("BOOTREPLY for %s to %s (%s) via %s", - piaddr (lease->ip_addr), hp -> name, - print_hw_addr (packet -> raw -> htype, - packet -> raw -> hlen, - packet -> raw -> chaddr), - packet -> raw -> giaddr.s_addr - ? inet_ntoa (packet -> raw -> giaddr) - : packet -> interface -> name); + log_info("%s", msgbuf); + log_info("BOOTREPLY for %s to %s (%s) via %s", + piaddr(lease->ip_addr), + ((hp != NULL) && (hp->name != NULL)) ? hp -> name : "unknown", + print_hw_addr (packet->raw->htype, + packet->raw->hlen, + packet->raw->chaddr), + packet->raw->giaddr.s_addr + ? inet_ntoa (packet->raw->giaddr) + : packet->interface->name); /* Set up the parts of the address that are in common. */ to.sin_family = AF_INET; @@ -384,10 +387,16 @@ void bootp (packet) to.sin_port = local_port; if (fallback_interface) { - result = send_packet (fallback_interface, - (struct packet *)0, - &raw, outgoing.packet_length, - from, &to, &hto); + result = send_packet (fallback_interface, NULL, &raw, + outgoing.packet_length, from, + &to, &hto); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long " + "packet over %s interface.", MDL, + outgoing.packet_length, + fallback_interface->name); + } + goto out; } @@ -407,10 +416,16 @@ void bootp (packet) } errno = 0; - result = send_packet (packet -> interface, - packet, &raw, outgoing.packet_length, - from, &to, &hto); + result = send_packet(packet->interface, packet, &raw, + outgoing.packet_length, from, &to, &hto); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long packet over %s" + " interface.", MDL, outgoing.packet_length, + packet->interface->name); + } + out: + if (options) option_state_dereference (&options, MDL); if (lease) diff --git a/server/confpars.c b/server/confpars.c index c0742d4..1c9c480 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -3,7 +3,7 @@ Parser for dhcpd config file... */ /* - * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -2724,84 +2724,83 @@ void parse_group_declaration (cfile, group) enum dhcp_token token; struct group *g; int declaration = 0; - struct group_object *t; + struct group_object *t = NULL; isc_result_t status; char *name = NULL; int deletedp = 0; int dynamicp = 0; int staticp = 0; - g = (struct group *)0; - if (!clone_group (&g, group, MDL)) - log_fatal ("no memory for explicit group."); + g = NULL; + if (!clone_group(&g, group, MDL)) + log_fatal("no memory for explicit group."); - token = peek_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (is_identifier (token) || token == STRING) { - next_token (&val, (unsigned *)0, cfile); + next_token(&val, NULL, cfile); - name = dmalloc (strlen (val) + 1, MDL); + name = dmalloc(strlen(val) + 1, MDL); if (!name) - log_fatal ("no memory for group decl name %s", val); - strcpy (name, val); + log_fatal("no memory for group decl name %s", val); + strcpy(name, val); } - if (!parse_lbrace (cfile)) { - group_dereference (&g, MDL); + if (!parse_lbrace(cfile)) { + group_dereference(&g, MDL); return; } do { - token = peek_token (&val, (unsigned *)0, cfile); + token = peek_token(&val, NULL, cfile); if (token == RBRACE) { - token = next_token (&val, (unsigned *)0, cfile); + token = next_token(&val, NULL, cfile); break; } else if (token == END_OF_FILE) { - token = next_token (&val, (unsigned *)0, cfile); - parse_warn (cfile, "unexpected end of file"); + token = next_token(&val, NULL, cfile); + parse_warn(cfile, "unexpected end of file"); break; } else if (token == TOKEN_DELETED) { - token = next_token (&val, (unsigned *)0, cfile); - parse_semi (cfile); + token = next_token(&val, NULL, cfile); + parse_semi(cfile); deletedp = 1; } else if (token == DYNAMIC) { - token = next_token (&val, (unsigned *)0, cfile); - parse_semi (cfile); + token = next_token(&val, NULL, cfile); + parse_semi(cfile); dynamicp = 1; } else if (token == STATIC) { - token = next_token (&val, (unsigned *)0, cfile); - parse_semi (cfile); + token = next_token(&val, NULL, cfile); + parse_semi(cfile); staticp = 1; } - declaration = parse_statement (cfile, g, GROUP_DECL, - (struct host_decl *)0, - declaration); + declaration = parse_statement(cfile, g, GROUP_DECL, + NULL, declaration); } while (1); if (name) { if (deletedp) { if (group_name_hash) { - t = (struct group_object *)0; - if (group_hash_lookup (&t, group_name_hash, - name, - strlen (name), MDL)) { - delete_group (t, 0); + t = NULL; + if (group_hash_lookup(&t, group_name_hash, + name, + strlen(name), MDL)) { + delete_group(t, 0); } } } else { - t = (struct group_object *)0; - status = group_object_allocate (&t, MDL); + t = NULL; + status = group_object_allocate(&t, MDL); if (status != ISC_R_SUCCESS) - log_fatal ("no memory for group decl %s: %s", - val, isc_result_totext (status)); - group_reference (&t -> group, g, MDL); - t -> name = name; - t -> flags = ((staticp ? GROUP_OBJECT_STATIC : 0) | - (dynamicp ? GROUP_OBJECT_DYNAMIC : 0) | - (deletedp ? GROUP_OBJECT_DELETED : 0)); - supersede_group (t, 0); - } - if (t) - group_object_dereference (&t, MDL); + log_fatal("no memory for group decl %s: %s", + val, isc_result_totext(status)); + group_reference(&t->group, g, MDL); + t->name = name; + t->flags = ((staticp ? GROUP_OBJECT_STATIC : 0) | + (dynamicp ? GROUP_OBJECT_DYNAMIC : 0) | + (deletedp ? GROUP_OBJECT_DELETED : 0)); + supersede_group(t, 0); + } + if (t != NULL) + group_object_dereference(&t, MDL); } } @@ -4441,21 +4440,39 @@ parse_ia_na_declaration(struct parse *cfile) { binding_scope_dereference(&scope, MDL); } - /* add to our various structures */ - ia_add_iasubopt(ia, iaaddr, MDL); - ia_reference(&iaaddr->ia, ia, MDL); + /* find the pool this address is in */ pool = NULL; if (find_ipv6_pool(&pool, D6O_IA_NA, &iaaddr->addr) != ISC_R_SUCCESS) { inet_ntop(AF_INET6, &iaaddr->addr, addr_buf, sizeof(addr_buf)); - parse_warn(cfile, "no pool found for address %s", + parse_warn(cfile, "no pool found for address %s", addr_buf); return; } - add_lease6(pool, iaaddr, end_time); - ipv6_pool_dereference(&pool, MDL); + + /* remove old information */ + if (cleanup_lease6(ia_na_active, pool, + iaaddr, ia) != ISC_R_SUCCESS) { + inet_ntop(AF_INET6, &iaaddr->addr, + addr_buf, sizeof(addr_buf)); + parse_warn(cfile, "duplicate na lease for address %s", + addr_buf); + } + + /* + * if we like the lease we add it to our various structues + * otherwise we leave it and it will get cleaned when we + * do the iasubopt_dereference. + */ + if ((state == FTS_ACTIVE) || (state == FTS_ABANDONED)) { + ia_add_iasubopt(ia, iaaddr, MDL); + ia_reference(&iaaddr->ia, ia, MDL); + add_lease6(pool, iaaddr, end_time); + } + iasubopt_dereference(&iaaddr, MDL); + ipv6_pool_dereference(&pool, MDL); } /* @@ -4804,19 +4821,37 @@ parse_ia_ta_declaration(struct parse *cfile) { binding_scope_dereference(&scope, MDL); } - /* add to our various structures */ - ia_add_iasubopt(ia, iaaddr, MDL); - ia_reference(&iaaddr->ia, ia, MDL); + /* find the pool this address is in */ pool = NULL; if (find_ipv6_pool(&pool, D6O_IA_TA, &iaaddr->addr) != ISC_R_SUCCESS) { inet_ntop(AF_INET6, &iaaddr->addr, addr_buf, sizeof(addr_buf)); - parse_warn(cfile, "no pool found for address %s", + parse_warn(cfile, "no pool found for address %s", addr_buf); return; } - add_lease6(pool, iaaddr, end_time); + + /* remove old information */ + if (cleanup_lease6(ia_ta_active, pool, + iaaddr, ia) != ISC_R_SUCCESS) { + inet_ntop(AF_INET6, &iaaddr->addr, + addr_buf, sizeof(addr_buf)); + parse_warn(cfile, "duplicate ta lease for address %s", + addr_buf); + } + + /* + * if we like the lease we add it to our various structues + * otherwise we leave it and it will get cleaned when we + * do the iasubopt_dereference. + */ + if ((state == FTS_ACTIVE) || (state == FTS_ABANDONED)) { + ia_add_iasubopt(ia, iaaddr, MDL); + ia_reference(&iaaddr->ia, ia, MDL); + add_lease6(pool, iaaddr, end_time); + } + ipv6_pool_dereference(&pool, MDL); iasubopt_dereference(&iaaddr, MDL); } @@ -5168,19 +5203,37 @@ parse_ia_pd_declaration(struct parse *cfile) { binding_scope_dereference(&scope, MDL); } - /* add to our various structures */ - ia_add_iasubopt(ia, iapref, MDL); - ia_reference(&iapref->ia, ia, MDL); + /* find the pool this address is in */ pool = NULL; if (find_ipv6_pool(&pool, D6O_IA_PD, &iapref->addr) != ISC_R_SUCCESS) { inet_ntop(AF_INET6, &iapref->addr, addr_buf, sizeof(addr_buf)); - parse_warn(cfile, "no pool found for address %s", + parse_warn(cfile, "no pool found for address %s", addr_buf); return; } - add_lease6(pool, iapref, end_time); + + /* remove old information */ + if (cleanup_lease6(ia_pd_active, pool, + iapref, ia) != ISC_R_SUCCESS) { + inet_ntop(AF_INET6, &iapref->addr, + addr_buf, sizeof(addr_buf)); + parse_warn(cfile, "duplicate pd lease for address %s", + addr_buf); + } + + /* + * if we like the lease we add it to our various structues + * otherwise we leave it and it will get cleaned when we + * do the iasubopt_dereference. + */ + if ((state == FTS_ACTIVE) || (state == FTS_ABANDONED)) { + ia_add_iasubopt(ia, iapref, MDL); + ia_reference(&iapref->ia, ia, MDL); + add_lease6(pool, iapref, end_time); + } + ipv6_pool_dereference(&pool, MDL); iasubopt_dereference(&iapref, MDL); } diff --git a/server/db.c b/server/db.c index 107d0b6..d41aa48 100644 --- a/server/db.c +++ b/server/db.c @@ -3,7 +3,7 @@ Persistent database management routines for DHCPD... */ /* - * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2010,2012 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 @@ -1021,7 +1021,11 @@ void db_startup (testp) /* Read in the existing lease file... */ status = read_conf_file (path_dhcpd_db, (struct group *)0, 0, 1); - /* XXX ignore status? */ + if (status != ISC_R_SUCCESS) { + /* XXX ignore status? */ + ; + } + #if defined (TRACING) } #endif diff --git a/server/ddns.c b/server/ddns.c index 2387e04..0c93073 100644 --- a/server/ddns.c +++ b/server/ddns.c @@ -3,7 +3,7 @@ Dynamic DNS updates. */ /* - * Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2000-2003 by Internet Software Consortium * @@ -80,7 +80,6 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, struct option_cache *oc; int s1, s2; int result = 0; - isc_result_t rcode1 = ISC_R_SUCCESS; int server_updates_a = 1; //int server_updates_ptr = 1; struct buffer *bp = (struct buffer *)0; @@ -103,12 +102,12 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, if (lease != NULL) { if ((old != NULL) && (old->ddns_cb != NULL)) { - ddns_cancel(old->ddns_cb); + ddns_cancel(old->ddns_cb, MDL); old->ddns_cb = NULL; } } else if (lease6 != NULL) { if ((old6 != NULL) && (old6->ddns_cb != NULL)) { - ddns_cancel(old6->ddns_cb); + ddns_cancel(old6->ddns_cb, MDL); old6->ddns_cb = NULL; } } else { @@ -123,8 +122,12 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, if (ddns_cb == NULL) { return(0); } - /* assume that we shall update both the A and ptr records */ - ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR; + /* + * Assume that we shall update both the A and ptr records and, + * as this is an update, set the active flag + */ + ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR | + DDNS_ACTIVE_LEASE; /* * For v4 we flag static leases so we don't try @@ -329,7 +332,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, /* If desired do the removals */ if (do_remove != 0) { - (void) ddns_removals(lease, lease6, NULL); + (void) ddns_removals(lease, lease6, NULL, ISC_TRUE); } goto out; } @@ -531,7 +534,11 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, * the ddns messages. Currently we don't. */ if (do_remove) { - rcode1 = ddns_removals(lease, lease6, ddns_cb); + /* + * We should log a more specific error closer to the actual + * error if we want one. ddns_removal failure not logged here. + */ + (void) ddns_removals(lease, lease6, ddns_cb, ISC_TRUE); } else { ddns_fwd_srv_connector(lease, lease6, scope, ddns_cb, @@ -709,7 +716,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, return result; } -/* +/*%< * Utility function to update text strings within a lease. * * The first issue is to find the proper scope. Sometimes we shall be @@ -719,6 +726,19 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, * Lastly, if we needed to find the scope we write it out, if we used a * scope that was passed as an argument we don't write it, assuming that * our caller (or his ...) will do the write. + * + *\li ddns_cb - the control block for the DDNS request + * + *\li inscope - a pointer to the scope to update. This may be NULL + * in which case we use the control block to find the lease and + * then the scope. + * + * Returns + *\li ISC_R_SUCCESS + * + *\li ISC_R_FAILURE - The routine was unable to find an expected scope. + * In some cases (static and inactive leases) we don't expect a scope + * and return success. */ isc_result_t @@ -739,6 +759,14 @@ ddns_update_lease_text(dhcp_ddns_cb_t *ddns_cb, if (ddns_cb->flags & DDNS_STATIC_LEASE) return (ISC_R_SUCCESS); + /* + * If we are processing an expired or released v6 lease + * or some types of v4 leases we don't actually have a + * scope to update + */ + if ((ddns_cb->flags & DDNS_ACTIVE_LEASE) == 0) + return (ISC_R_SUCCESS); + if (inscope != NULL) { scope = inscope; } else if (ddns_cb->address.len == 4) { @@ -1084,6 +1112,15 @@ ddns_update_lease_ptr(struct lease *lease, return (ISC_R_SUCCESS); } + /* + * If we are processing an expired or released v6 lease + * we don't actually have a lease to update + */ + if ((ddns_cb->address.len == 16) && + ((ddns_cb->flags & DDNS_ACTIVE_LEASE) == 0)) { + return (ISC_R_SUCCESS); + } + if (lease != NULL) { safe_lease_update(lease, ddns_cb, ddns_cb_set, file, line); @@ -1131,7 +1168,7 @@ ddns_update_lease_ptr(struct lease *lease, ISC_R_SUCCESS) && (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != ISC_R_SUCCESS)) { - inet_ntop(AF_INET6, &lease6->addr, addrbuf, + inet_ntop(AF_INET6, &addr, addrbuf, MAX_ADDRESS_STRING_LEN); log_error("%s(%d): Pool for lease %s not found.", file, line, addrbuf); @@ -1151,7 +1188,7 @@ ddns_update_lease_ptr(struct lease *lease, find_lease6->ddns_cb = ddns_cb_set; iasubopt_dereference(&find_lease6, MDL); } else { - inet_ntop(AF_INET6, &lease6->addr, addrbuf, + inet_ntop(AF_INET6, &addr, addrbuf, MAX_ADDRESS_STRING_LEN); log_error("%s(%d): Lease %s not found within pool.", file, line, addrbuf); @@ -1240,6 +1277,11 @@ ddns_ptr_remove(dhcp_ddns_cb_t *ddns_cb, /* trigger any add operation */ result = ISC_R_SUCCESS; +#if defined (DEBUG_DNS_UPDATES) + log_info("DDNS: removed map or no reverse map to remove %.*s", + (int)ddns_cb->rev_name.len, + (const char *)ddns_cb->rev_name.data); +#endif break; default: @@ -1314,7 +1356,7 @@ ddns_fwd_srv_add2(dhcp_ddns_cb_t *ddns_cb, ddns_cb->state = DDNS_STATE_ADD_PTR; ddns_cb->cur_func = ddns_ptr_add; - result = ddns_modify_ptr(ddns_cb); + result = ddns_modify_ptr(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } @@ -1387,12 +1429,11 @@ ddns_fwd_srv_add1(dhcp_ddns_cb_t *ddns_cb, ddns_cb->state = DDNS_STATE_ADD_PTR; ddns_cb->cur_func = ddns_ptr_add; - result = ddns_modify_ptr(ddns_cb); + result = ddns_modify_ptr(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } } - break; case DNS_R_YXDOMAIN: @@ -1400,11 +1441,10 @@ ddns_fwd_srv_add1(dhcp_ddns_cb_t *ddns_cb, ddns_cb->state = DDNS_STATE_ADD_FW_YXDHCID; ddns_cb->cur_func = ddns_fwd_srv_add2; - result = ddns_modify_fwd(ddns_cb); + result = ddns_modify_fwd(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } - break; default: @@ -1455,12 +1495,12 @@ ddns_fwd_srv_connector(struct lease *lease, if (ddns_cb->flags & DDNS_UPDATE_ADDR) { ddns_cb->state = DDNS_STATE_ADD_FW_NXDOMAIN; ddns_cb->cur_func = ddns_fwd_srv_add1; - result = ddns_modify_fwd(ddns_cb); + result = ddns_modify_fwd(ddns_cb, MDL); } else if ((ddns_cb->flags & DDNS_UPDATE_PTR) && (ddns_cb->rev_name.len != 0)) { ddns_cb->state = DDNS_STATE_ADD_PTR; ddns_cb->cur_func = ddns_ptr_add; - result = ddns_modify_ptr(ddns_cb); + result = ddns_modify_ptr(ddns_cb, MDL); } else { ddns_update_lease_text(ddns_cb, inscope); } @@ -1505,7 +1545,7 @@ ddns_fwd_srv_rem2(dhcp_ddns_cb_t *ddns_cb, ddns_cb->state = DDNS_STATE_REM_PTR; ddns_cb->cur_func = ddns_ptr_remove; - eresult = ddns_modify_ptr(ddns_cb); + eresult = ddns_modify_ptr(ddns_cb, MDL); if (eresult == ISC_R_SUCCESS) { return; } @@ -1545,7 +1585,7 @@ ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb, /* Do the second step of the FWD removal */ ddns_cb->state = DDNS_STATE_REM_FW_NXRR; ddns_cb->cur_func = ddns_fwd_srv_rem2; - result = ddns_modify_fwd(ddns_cb); + result = ddns_modify_fwd(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } @@ -1555,6 +1595,10 @@ ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb, case DNS_R_NXDOMAIN: ddns_update_lease_text(ddns_cb, NULL); +#if defined (DEBUG_DNS_UPDATES) + log_info("DDNS: no forward map to remove. %p", ddns_cb); +#endif + /* Do the next operation */ if ((ddns_cb->flags & DDNS_UPDATE_PTR) != 0) { /* if we have zone information get rid of it */ @@ -1565,7 +1609,7 @@ ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb, ddns_cb->state = DDNS_STATE_REM_PTR; ddns_cb->cur_func = ddns_ptr_remove; - result = ddns_modify_ptr(ddns_cb); + result = ddns_modify_ptr(ddns_cb, MDL); if (result == ISC_R_SUCCESS) { return; } @@ -1585,39 +1629,124 @@ ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb, ddns_cb_free(ddns_cb, MDL); } - -/* +/*%< * Remove relevant entries from DNS. * - * Return values: - * 0 - badness occurred and we weren't able to do what was wanted - * 1 - we were able to do stuff but it's in progress + * \li lease - lease to start with if this is for v4 + * + * \li lease6 - lease to start with if this is for v6 + * + * \li add_ddns_cb - control block for additional DDNS work. This + * is used when the code is going to add a DDNS entry after removing + * the current entry. + * + * \li active - indication about the status of the lease. It is + * ISC_TRUE if the lease is still active, and FALSE if the lease + * is inactive. This is used to indicate if the lease is inactive or going + * to inactive so we can avoid trying to update the lease with cb pointers + * and text information if it isn't useful. + * + * Returns + * \li #ISC_R_FAILURE - badness occurred and we weren't able to do what was wanted + * \li #ISC_R_SUCCESS - we were able to do stuff but it's in progress + * * in both cases any additional block has been passed on to it's handler */ -int +isc_result_t ddns_removals(struct lease *lease, struct iasubopt *lease6, - dhcp_ddns_cb_t *add_ddns_cb) + dhcp_ddns_cb_t *add_ddns_cb, + isc_boolean_t active) { isc_result_t rcode, execute_add = ISC_R_FAILURE; struct binding_scope **scope = NULL; - int result = 0; + isc_result_t result = ISC_R_FAILURE; dhcp_ddns_cb_t *ddns_cb = NULL; struct data_string leaseid; /* - * Cancel any outstanding requests. When called - * from within the DNS code we probably will have - * already done the cancel but if called from outside - * - for example as part of a lease expiry - we won't. + * See if we need to cancel an outstanding request. Mostly this is + * used to handle the case where this routine is called twice for + * the same release or abandon event. + * + * When called from the dns code as part of an update request + * (add_ddns_cb != NULL) any outstanding requests will have already + * been cancelled. + * + * If the new request is just a removal and we have an outstanding + * request we have several options: + * + * - we are doing an update or we are doing a removal and the active + * flag has changed from TRUE to FALSE. In these cases we need to + * cancel the old request and start the new one. + * + * - other wise we are doing a removal with the active flag unchanged. + * In this case we can let the current removal continue and do not need + * to start a new one. If the old request included an update to be + * done after the removal we need to kill the update part of the + * request. */ - if ((lease != NULL) && (lease->ddns_cb != NULL)) { - ddns_cancel(lease->ddns_cb); - lease->ddns_cb = NULL; - } else if ((lease6 != NULL) && (lease6->ddns_cb != NULL)) { - ddns_cancel(lease6->ddns_cb); - lease6->ddns_cb = NULL; + + if (add_ddns_cb == NULL) { + if ((lease != NULL) && (lease->ddns_cb != NULL)) { + ddns_cb = lease->ddns_cb; + + /* + * Is the old request an update or did the + * the active flag change? + */ + if (((ddns_cb->state == DDNS_STATE_ADD_PTR) || + (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) || + (ddns_cb->state == DDNS_STATE_ADD_FW_YXDHCID)) || + ((active == ISC_FALSE) && + ((ddns_cb->flags & DDNS_ACTIVE_LEASE) != 0))) { + /* Cancel the current request */ + ddns_cancel(lease->ddns_cb, MDL); + lease->ddns_cb = NULL; + } else { + /* Remvoval, check and remove updates */ + if (ddns_cb->next_op != NULL) { + ddns_cb_free(ddns_cb->next_op, MDL); + ddns_cb->next_op = NULL; + } +#if defined (DEBUG_DNS_UPDATES) + log_info("DDNS %s(%d): removal already in " + "progress new ddns_cb=%p", + MDL, ddns_cb); +#endif + return (ISC_R_SUCCESS); + } + } else if ((lease6 != NULL) && (lease6->ddns_cb != NULL)) { + ddns_cb = lease6->ddns_cb; + + /* + * Is the old request an update or did the + * the active flag change? + */ + if (((ddns_cb->state == DDNS_STATE_ADD_PTR) || + (ddns_cb->state == DDNS_STATE_ADD_FW_NXDOMAIN) || + (ddns_cb->state == DDNS_STATE_ADD_FW_YXDHCID)) || + ((active == ISC_FALSE) && + ((ddns_cb->flags & DDNS_ACTIVE_LEASE) != 0))) { + /* Cancel the current request */ + ddns_cancel(lease6->ddns_cb, MDL); + lease6->ddns_cb = NULL; + } else { + /* Remvoval, check and remove updates */ + if (ddns_cb->next_op != NULL) { + ddns_cb_free(ddns_cb->next_op, MDL); + ddns_cb->next_op = NULL; + } +#if defined (DEBUG_DNS_UPDATES) + log_info("DDNS %s(%d): removal already in " + "progress new ddns_cb=%p", + MDL, ddns_cb); +#endif + return (ISC_R_SUCCESS); + } + } + ddns_cb = NULL; } /* allocate our control block */ @@ -1643,6 +1772,17 @@ ddns_removals(struct lease *lease, } else goto cleanup; + /* + * Set the flag bit if the lease is active, that is it isn't + * expired or released. This is used to determine if we need + * to update the scope information for both v4 and v6 and + * the lease information for v6 when the response + * from the DNS code is processed. + */ + if (active == ISC_TRUE) { + ddns_cb->flags |= DDNS_ACTIVE_LEASE; + } + /* No scope implies that DDNS has not been performed for this lease. */ if (*scope == NULL) goto cleanup; @@ -1727,11 +1867,11 @@ ddns_removals(struct lease *lease, ddns_cb->state = DDNS_STATE_REM_FW_YXDHCID; ddns_cb->cur_func = ddns_fwd_srv_rem1; - rcode = ddns_modify_fwd(ddns_cb); + rcode = ddns_modify_fwd(ddns_cb, MDL); if (rcode == ISC_R_SUCCESS) { ddns_update_lease_ptr(lease, lease6, ddns_cb, ddns_cb, MDL); - return(1); + return (ISC_R_SUCCESS); } /* @@ -1764,14 +1904,14 @@ ddns_removals(struct lease *lease, add_ddns_cb = NULL; } else { - result = 1; + result = ISC_R_SUCCESS; } - rcode = ddns_modify_ptr(ddns_cb); + rcode = ddns_modify_ptr(ddns_cb, MDL); if (rcode == ISC_R_SUCCESS) { ddns_update_lease_ptr(lease, lease6, ddns_cb, ddns_cb, MDL); - return(result); + return (result); } /* We weren't able to process the request tag the @@ -1791,7 +1931,7 @@ ddns_removals(struct lease *lease, if (ddns_cb != NULL) ddns_cb_free(ddns_cb, MDL); - return(result); + return (result); } #endif /* NSUPDATE */ diff --git a/server/dhcp.c b/server/dhcp.c index da4585f..2357175 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -3,7 +3,7 @@ DHCP Protocol engine. */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -419,7 +419,6 @@ void dhcprequest (packet, ms_nulltp, ip_lease) #if defined (FAILOVER_PROTOCOL) dhcp_failover_state_t *peer; #endif - int have_server_identifier = 0; int have_requested_addr = 0; oc = lookup_option (&dhcp_universe, packet -> options, @@ -473,7 +472,6 @@ void dhcprequest (packet, ms_nulltp, ip_lease) * safe. */ sprintf (smbuf, " (%s)", piaddr (sip)); - have_server_identifier = 1; } else smbuf [0] = 0; @@ -969,6 +967,8 @@ void dhcpinform (packet, ms_nulltp) struct sockaddr_in to; struct in_addr from; isc_boolean_t zeroed_ciaddr; + struct interface_info *interface; + int result; /* The client should set ciaddr to its IP address, but apparently it's common for clients not to do this, so we'll use their IP @@ -1169,7 +1169,7 @@ void dhcpinform (packet, ms_nulltp) packet -> options, options, &global_scope, oc, MDL)) { struct universe *u = (struct universe *)0; - + if (!universe_hash_lookup (&u, universe_hash, (const char *)d1.data, d1.len, MDL)) { @@ -1314,10 +1314,17 @@ void dhcpinform (packet, ms_nulltp) packet->interface->name); errno = 0; - send_packet ((fallback_interface - ? fallback_interface : packet -> interface), - &outgoing, &raw, outgoing.packet_length, - from, &to, (struct hardware *)0); + interface = (fallback_interface ? fallback_interface + : packet -> interface); + result = send_packet(interface, &outgoing, &raw, + outgoing.packet_length, from, &to, NULL); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long packet over %s " + "interface.", MDL, outgoing.packet_length, + interface->name); + } + + if (subnet) subnet_dereference (&subnet, MDL); } @@ -1464,6 +1471,13 @@ void nak_lease (packet, cip) result = send_packet(fallback_interface, packet, &raw, outgoing.packet_length, from, &to, NULL); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long " + "packet over %s interface.", MDL, + outgoing.packet_length, + fallback_interface->name); + } + return; } } else { @@ -1474,6 +1488,12 @@ void nak_lease (packet, cip) errno = 0; result = send_packet(packet->interface, packet, &raw, outgoing.packet_length, from, &to, NULL); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long packet over %s " + "interface.", MDL, outgoing.packet_length, + packet->interface->name); + } + } void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp) @@ -3164,11 +3184,16 @@ void dhcp_reply (lease) to.sin_port = remote_port; /* For debugging. */ if (fallback_interface) { - result = send_packet (fallback_interface, - (struct packet *)0, - &raw, packet_length, - raw.siaddr, &to, - (struct hardware *)0); + result = send_packet(fallback_interface, NULL, &raw, + packet_length, raw.siaddr, &to, + NULL); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long " + "packet over %s interface.", MDL, + packet_length, + fallback_interface->name); + } + free_lease_state (state, MDL); lease -> state = (struct lease_state *)0; @@ -3197,11 +3222,16 @@ void dhcp_reply (lease) to.sin_port = remote_port; if (fallback_interface) { - result = send_packet (fallback_interface, - (struct packet *)0, - &raw, packet_length, - raw.siaddr, &to, - (struct hardware *)0); + result = send_packet(fallback_interface, NULL, &raw, + packet_length, raw.siaddr, &to, + NULL); + if (result < 0) { + log_error("%s:%d: Failed to send %d byte long" + " packet over %s interface.", MDL, + packet_length, + fallback_interface->name); + } + free_lease_state (state, MDL); lease -> state = (struct lease_state *)0; return; @@ -3226,10 +3256,14 @@ void dhcp_reply (lease) memcpy (&from, state -> from.iabuf, sizeof from); - result = send_packet (state -> ip, - (struct packet *)0, &raw, packet_length, - from, &to, - unicastp ? &hto : (struct hardware *)0); + result = send_packet(state->ip, NULL, &raw, packet_length, + from, &to, unicastp ? &hto : NULL); + if (result < 0) { + log_error ("%s:%d: Failed to send %d byte long " + "packet over %s interface.", MDL, + packet_length, state->ip->name); + } + /* Free all of the entries in the option_state structure now that we're done with them. */ diff --git a/server/dhcpd.c b/server/dhcpd.c index 448e164..b5c28d4 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -3,7 +3,7 @@ DHCP Server Daemon. */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -33,7 +33,7 @@ */ static const char copyright[] = -"Copyright 2004-2011 Internet Systems Consortium."; +"Copyright 2004-2012 Internet Systems Consortium."; static const char arr [] = "All rights reserved."; static const char message [] = "Internet Systems Consortium DHCP Server"; static const char url [] = diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5 index 2da8d9e..d1d6295 100644 --- a/server/dhcpd.conf.5 +++ b/server/dhcpd.conf.5 @@ -1,6 +1,6 @@ .\" dhcpd.conf.5 .\" -.\" Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (c) 2004-2012 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 @@ -27,7 +27,7 @@ .\" Support and other services are available for ISC products - see .\" https://www.isc.org for more information or to learn more about ISC. .\" -.\" $Id: dhcpd.conf.5,v 1.106.18.7 2011-09-21 20:43:10 sar Exp $ +.\" $Id: dhcpd.conf.5,v 1.106.18.8 2012-04-02 22:51:02 sar Exp $ .\" .TH dhcpd.conf 5 .SH NAME @@ -1744,11 +1744,6 @@ The \fBbootp\fR flag is used to tell dhcpd whether or not to respond to bootp queries. Bootp queries are \fBallow\fRed by default. .PP -This option does not satisfy the requirement of failover peers for denying -dynamic bootp clients. The \fBdeny dynamic bootp clients;\fR option should -be used instead. See the ALLOW AND DENY WITHIN POOL DECLARATIONS section -of this man page for more details. -.PP .B The .I booting .B keyword diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c index 9daff89..09913c2 100644 --- a/server/dhcpleasequery.c +++ b/server/dhcpleasequery.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2011-2012 by Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2006-2007,2009 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any @@ -454,10 +455,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) { (lease_duration / 8); if (time_renewal > cur_time) { - if (time_renewal < cur_time) - time_renewal = 0; - else - time_renewal = htonl(time_renewal - cur_time); + time_renewal = htonl(time_renewal - cur_time); if (!add_option(options, DHO_DHCP_RENEWAL_TIME, @@ -487,15 +485,8 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) { } if (lease->ends > cur_time) { - if (time_expiry < cur_time) { - log_error("Impossible condition at %s:%d.", - MDL); - - option_state_dereference(&options, MDL); - lease_dereference(&lease, MDL); - return; - } time_expiry = htonl(lease->ends - cur_time); + if (!add_option(options, DHO_DHCP_LEASE_TIME, &time_expiry, diff --git a/server/dhcpv6.c b/server/dhcpv6.c index 4538882..70f3981 100644 --- a/server/dhcpv6.c +++ b/server/dhcpv6.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2006-2012 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1092,7 +1092,8 @@ try_client_v6_prefix(struct iasubopt **pref, return DHCP_R_INVALIDARG; } tmp_plen = (int) requested_pref->data[0]; - if ((tmp_plen < 3) || (tmp_plen > 128)) { + if ((tmp_plen < 3) || (tmp_plen > 128) || + ((int)tmp_plen != pool->units)) { return ISC_R_FAILURE; } memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref)); @@ -1105,9 +1106,8 @@ try_client_v6_prefix(struct iasubopt **pref, return ISC_R_FAILURE; } - if (((int)tmp_plen != pool->units) || - !ipv6_in_pool(&tmp_pref, pool)) { - return ISC_R_FAILURE; + if (!ipv6_in_pool(&tmp_pref, pool)) { + return ISC_R_ADDRNOTAVAIL; } if (prefix6_exists(pool, &tmp_pref, tmp_plen)) { @@ -1239,7 +1239,9 @@ lease_to_client(struct data_string *reply_ret, static struct reply_state reply; struct option_cache *oc; struct data_string packet_oro; - isc_boolean_t no_resources_avail; +#if defined (RFC3315_PRE_ERRATA_2010_08) + isc_boolean_t no_resources_avail = ISC_FALSE; +#endif /* Locate the client. */ if (shared_network_from_packet6(&reply.shared, @@ -1297,7 +1299,7 @@ lease_to_client(struct data_string *reply_ret, /* Process the client supplied IA's onto the reply buffer. */ reply.ia_count = 0; oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA); - no_resources_avail = ISC_FALSE; + for (; oc != NULL ; oc = oc->next) { isc_result_t status; @@ -1315,12 +1317,14 @@ lease_to_client(struct data_string *reply_ret, (status != ISC_R_NORESOURCES)) goto exit; +#if defined (RFC3315_PRE_ERRATA_2010_08) /* * If any address cannot be given to any IA, then set the * NoAddrsAvail status code. */ if (reply.client_resources == 0) no_resources_avail = ISC_TRUE; +#endif } oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA); for (; oc != NULL ; oc = oc->next) { @@ -1340,12 +1344,14 @@ lease_to_client(struct data_string *reply_ret, (status != ISC_R_NORESOURCES)) goto exit; +#if defined (RFC3315_PRE_ERRATA_2010_08) /* * If any address cannot be given to any IA, then set the * NoAddrsAvail status code. */ if (reply.client_resources == 0) no_resources_avail = ISC_TRUE; +#endif } /* Same for IA_PD's. */ @@ -1367,13 +1373,6 @@ lease_to_client(struct data_string *reply_ret, if ((status != ISC_R_SUCCESS) && (status != ISC_R_NORESOURCES)) goto exit; - - /* - * If any prefix cannot be given to any IA_PD, then - * set the NoPrefixAvail status code. - */ - if (reply.client_resources == 0) - no_resources_avail = ISC_TRUE; } /* @@ -1429,6 +1428,7 @@ lease_to_client(struct data_string *reply_ret, * the server. * Sends a Renew/Rebind if the IA is not in the Reply message. */ +#if defined (RFC3315_PRE_ERRATA_2010_08) if (no_resources_avail && (reply.ia_count != 0) && (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) { @@ -1459,36 +1459,6 @@ lease_to_client(struct data_string *reply_ret, reply.opt_state, reply.packet, required_opts_NAA, NULL); - } else if (no_resources_avail && (reply.ia_count == 0) && - (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) - { - /* Set the NoPrefixAvail status code. */ - if (!set_status_code(STATUS_NoPrefixAvail, - "No prefixes available for this " - "interface.", reply.opt_state)) { - log_error("lease_to_client: Unable to set " - "NoPrefixAvail status code."); - goto exit; - } - - /* Rewind the cursor to the start. */ - reply.cursor = REPLY_OPTIONS_INDEX; - - /* - * Produce an advertise that includes only: - * - * Status code. - * Server DUID. - * Client DUID. - */ - reply.buf.reply.msg_type = DHCPV6_ADVERTISE; - reply.cursor += store_options6((char *)reply.buf.data + - reply.cursor, - sizeof(reply.buf) - - reply.cursor, - reply.opt_state, reply.packet, - required_opts_NAA, - NULL); } else { /* * Having stored the client's IA's, store any options that @@ -1502,6 +1472,17 @@ lease_to_client(struct data_string *reply_ret, required_opts_solicit, &packet_oro); } +#else /* defined (RFC3315_PRE_ERRATA_2010_08) */ + /* + * Having stored the client's IA's, store any options that + * will fit in the remaining space. + */ + reply.cursor += store_options6((char *)reply.buf.data + reply.cursor, + sizeof(reply.buf) - reply.cursor, + reply.opt_state, reply.packet, + required_opts_solicit, + &packet_oro); +#endif /* defined (RFC3315_PRE_ERRATA_2010_08) */ /* Return our reply to the caller. */ reply_ret->len = reply.cursor; @@ -2228,13 +2209,13 @@ address_is_owned(struct reply_state *reply, struct iaddr *addr) { log_fatal("Impossible condition at %s:%d.", MDL); if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0) - return ISC_TRUE; + return (ISC_TRUE); - return ISC_FALSE; + return (ISC_FALSE); } if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0)) - return ISC_FALSE; + return (ISC_FALSE); for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) { struct iasubopt *tmp; @@ -2242,12 +2223,15 @@ address_is_owned(struct reply_state *reply, struct iaddr *addr) { tmp = reply->old_ia->iasubopt[i]; if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) { + if (lease6_usable(tmp) == ISC_FALSE) { + return (ISC_FALSE); + } iasubopt_reference(&reply->lease, tmp, MDL); - return ISC_TRUE; + return (ISC_TRUE); } } - return ISC_FALSE; + return (ISC_FALSE); } /* Process a client-supplied IA_TA. This may append options to the tail of @@ -2703,15 +2687,17 @@ find_client_temporaries(struct reply_state *reply) { */ static isc_result_t reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) { - isc_result_t status = ISC_R_NORESOURCES; + isc_result_t status = ISC_R_ADDRNOTAVAIL; struct ipv6_pool *pool; int i; struct data_string data_addr; if ((reply == NULL) || (reply->shared == NULL) || - (reply->shared->ipv6_pools == NULL) || (addr == NULL) || - (reply->lease != NULL)) - return DHCP_R_INVALIDARG; + (addr == NULL) || (reply->lease != NULL)) + return (DHCP_R_INVALIDARG); + + if (reply->shared->ipv6_pools == NULL) + return (ISC_R_ADDRNOTAVAIL); memset(&data_addr, 0, sizeof(data_addr)); data_addr.len = addr->len; @@ -2729,7 +2715,7 @@ reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) { /* Note that this is just pedantry. There is no allocation to free. */ data_string_forget(&data_addr, MDL); /* Return just the most recent status... */ - return status; + return (status); } /* Look around for an address to give the client. First, look through the @@ -2769,7 +2755,8 @@ find_client_address(struct reply_state *reply) { * Look for the best lease on the client's shared * network. */ - if (candidate_shared == reply->shared) { + if ((candidate_shared == reply->shared) && + (lease6_usable(lease) == ISC_TRUE)) { best_lease = lease_compare(lease, best_lease); } } @@ -2780,7 +2767,7 @@ find_client_address(struct reply_state *reply) { */ if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) { status = pick_v6_address(&reply->lease, reply->shared, - &reply->client_id); + &reply->ia->iaid_duid); } else if (best_lease != NULL) { iasubopt_reference(&reply->lease, best_lease, MDL); status = ISC_R_SUCCESS; @@ -3224,7 +3211,9 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) { if (status == ISC_R_CANCELED) break; - if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE)) + if ((status != ISC_R_SUCCESS) && + (status != ISC_R_ADDRINUSE) && + (status != ISC_R_ADDRNOTAVAIL)) goto cleanup; } @@ -3503,8 +3492,9 @@ reply_process_prefix(struct reply_state *reply, struct option_cache *pref) { status = reply_process_try_prefix(reply, &tmp_pref); /* Either error out or skip this prefix. */ - if ((status != ISC_R_SUCCESS) && - (status != ISC_R_ADDRINUSE)) + if ((status != ISC_R_SUCCESS) && + (status != ISC_R_ADDRINUSE) && + (status != ISC_R_ADDRNOTAVAIL)) goto cleanup; if (reply->lease == NULL) { @@ -3652,14 +3642,14 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { if ((pref->bits == l->cidrnet.bits) && (memcmp(pref->lo_addr.iabuf, l->cidrnet.lo_addr.iabuf, 16) == 0)) - return ISC_TRUE; + return (ISC_TRUE); } - return ISC_FALSE; + return (ISC_FALSE); } if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0)) - return ISC_FALSE; + return (ISC_FALSE); for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) { struct iasubopt *tmp; @@ -3667,13 +3657,16 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { tmp = reply->old_ia->iasubopt[i]; if ((pref->bits == (int) tmp->plen) && - memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0) { + (memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0)) { + if (lease6_usable(tmp) == ISC_FALSE) { + return (ISC_FALSE); + } iasubopt_reference(&reply->lease, tmp, MDL); - return ISC_TRUE; + return (ISC_TRUE); } } - return ISC_FALSE; + return (ISC_FALSE); } /* @@ -3683,21 +3676,23 @@ prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) { static isc_result_t reply_process_try_prefix(struct reply_state *reply, struct iaddrcidrnet *pref) { - isc_result_t status = ISC_R_NORESOURCES; + isc_result_t status = ISC_R_ADDRNOTAVAIL; struct ipv6_pool *pool; int i; struct data_string data_pref; if ((reply == NULL) || (reply->shared == NULL) || - (reply->shared->ipv6_pools == NULL) || (pref == NULL) || - (reply->lease != NULL)) - return DHCP_R_INVALIDARG; + (pref == NULL) || (reply->lease != NULL)) + return (DHCP_R_INVALIDARG); + + if (reply->shared->ipv6_pools == NULL) + return (ISC_R_ADDRNOTAVAIL); memset(&data_pref, 0, sizeof(data_pref)); data_pref.len = 17; if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) { log_error("reply_process_try_prefix: out of memory."); - return ISC_R_NOMEMORY; + return (ISC_R_NOMEMORY); } data_pref.data = data_pref.buffer->data; data_pref.buffer->data[0] = (u_int8_t) pref->bits; @@ -3716,7 +3711,7 @@ reply_process_try_prefix(struct reply_state *reply, data_string_forget(&data_pref, MDL); /* Return just the most recent status... */ - return status; + return (status); } /* Look around for a prefix to give the client. First, look through the old @@ -3767,8 +3762,9 @@ find_client_prefix(struct reply_state *reply) { * if it is scoped in a pool under the client's shared * network. */ - if (candidate_shared == NULL || - candidate_shared == reply->shared) { + if (((candidate_shared == NULL) || + (candidate_shared == reply->shared)) && + (lease6_usable(prefix) == ISC_TRUE)) { best_prefix = prefix_compare(reply, prefix, best_prefix); } @@ -4617,7 +4613,6 @@ iterate_over_ia_na(struct data_string *reply_ret, struct option_state *host_opt_state; struct data_string iaaddr; struct data_string fixed_addr; - int iaaddr_is_found; char reply_data[65536]; struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data; int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options)); @@ -4724,7 +4719,6 @@ iterate_over_ia_na(struct data_string *reply_ret, */ for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA); ia != NULL; ia = ia->next) { - iaaddr_is_found = 0; if (!get_encapsulated_IA_state(&cli_enc_opt_state, &cli_enc_opt_data, @@ -5136,7 +5130,6 @@ iterate_over_ia_pd(struct data_string *reply_ret, struct host_decl *host; struct option_state *host_opt_state; struct data_string iaprefix; - int iaprefix_is_found; char reply_data[65536]; int reply_ofs; struct iasubopt *prefix; @@ -5203,7 +5196,6 @@ iterate_over_ia_pd(struct data_string *reply_ret, */ for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD); ia != NULL; ia = ia->next) { - iaprefix_is_found = 0; if (!get_encapsulated_IA_state(&cli_enc_opt_state, &cli_enc_opt_data, @@ -5531,6 +5523,7 @@ dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) { msg_type = enc_opt_data.data[0]; if ((msg_type == DHCPV6_RELAY_FORW) || (msg_type == DHCPV6_RELAY_REPL)) { + int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options)); relay = (struct dhcpv6_relay_packet *)enc_opt_data.data; enc_packet->dhcpv6_msg_type = relay->msg_type; @@ -5543,13 +5536,14 @@ dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) { if (!parse_option_buffer(enc_packet->options, relay->options, - enc_opt_data.len-sizeof(*relay), + enc_opt_data.len - relaylen, &dhcpv6_universe)) { /* no logging here, as parse_option_buffer() logs all cases where it fails */ goto exit; } } else { + int msglen = (int)(offsetof(struct dhcpv6_packet, options)); msg = (struct dhcpv6_packet *)enc_opt_data.data; enc_packet->dhcpv6_msg_type = msg->msg_type; @@ -5560,7 +5554,7 @@ dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) { if (!parse_option_buffer(enc_packet->options, msg->options, - enc_opt_data.len-sizeof(*msg), + enc_opt_data.len - msglen, &dhcpv6_universe)) { /* no logging here, as parse_option_buffer() logs all cases where it fails */ diff --git a/server/failover.c b/server/failover.c index 97e7d73..45e6b62 100644 --- a/server/failover.c +++ b/server/failover.c @@ -3,7 +3,7 @@ Failover protocol support code... */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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,7 @@ * ``http://www.nominum.com''. */ +#include "cdefs.h" #include "dhcpd.h" #include <omapip/omapip_p.h> @@ -2412,7 +2413,8 @@ dhcp_failover_pool_dobalance(dhcp_failover_state_t *state, struct shared_network *s; struct pool *p; binding_state_t peer_lease_state; - binding_state_t my_lease_state; + /* binding_state_t my_lease_state; */ + /* XXX Why is this my_lease_state never used? */ struct lease **lq; int (*log_func)(const char *, ...); const char *result, *reqlog; @@ -2436,12 +2438,12 @@ dhcp_failover_pool_dobalance(dhcp_failover_state_t *state, if (p->failover_peer->i_am == primary) { lts = (p->free_leases - p->backup_leases) / 2; peer_lease_state = FTS_BACKUP; - my_lease_state = FTS_FREE; + /* my_lease_state = FTS_FREE; */ lq = &p->free; } else { lts = (p->backup_leases - p->free_leases) / 2; peer_lease_state = FTS_FREE; - my_lease_state = FTS_BACKUP; + /* my_lease_state = FTS_BACKUP; */ lq = &p->backup; } @@ -3257,13 +3259,13 @@ isc_result_t dhcp_failover_state_stuff (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) { + /* In this function c should be a (omapi_connection_object_t *) */ + dhcp_failover_state_t *s; - omapi_connection_object_t *conn; isc_result_t status; if (c -> type != omapi_type_connection) return DHCP_R_INVALIDARG; - conn = (omapi_connection_object_t *)c; if (h -> type != dhcp_type_failover_state) return DHCP_R_INVALIDARG; @@ -4306,6 +4308,8 @@ void dhcp_failover_send_contact (void *vstate) if (obufix) { log_debug ("%s", obuf); } +#else + IGNORE_UNUSED(status); #endif return; } @@ -4354,6 +4358,8 @@ isc_result_t dhcp_failover_send_state (dhcp_failover_state_t *state) if (obufix) { log_debug ("%s", obuf); } +#else + IGNORE_UNUSED(status); #endif return ISC_R_SUCCESS; } @@ -4490,7 +4496,6 @@ isc_result_t dhcp_failover_send_disconnect (omapi_object_t *l, const char *message) { dhcp_failover_link_t *link; - dhcp_failover_state_t *state; isc_result_t status; #if defined (DEBUG_FAILOVER_MESSAGES) char obuf [64]; @@ -4505,7 +4510,6 @@ isc_result_t dhcp_failover_send_disconnect (omapi_object_t *l, if (!l || l -> type != dhcp_type_failover_link) return DHCP_R_INVALIDARG; link = (dhcp_failover_link_t *)l; - state = link -> state_object; if (!l -> outer || l -> outer -> type != omapi_type_connection) return DHCP_R_INVALIDARG; @@ -5218,7 +5222,7 @@ isc_result_t dhcp_failover_process_bind_update (dhcp_failover_state_t *state, */ if (msg->binding_status == FTS_ACTIVE && (chaddr_changed || ident_changed)) { - ddns_removals(lease, NULL, NULL); + (void) ddns_removals(lease, NULL, NULL, ISC_FALSE); if (lease->scope != NULL) binding_scope_dereference(&lease->scope, MDL); diff --git a/server/mdb.c b/server/mdb.c index c5bf73e..5a3052a 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -3,7 +3,7 @@ Server-specific in-memory database support. */ /* - * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2012 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 @@ -1445,7 +1445,7 @@ void make_binding_state_transition (struct lease *lease) lease -> binding_state == FTS_ACTIVE && lease -> next_binding_state != FTS_RELEASED))) { #if defined (NSUPDATE) - ddns_removals(lease, NULL, NULL); + (void) ddns_removals(lease, NULL, NULL, ISC_TRUE); #endif if (lease -> on_expiry) { execute_statements ((struct binding_value **)0, @@ -1511,7 +1511,7 @@ void make_binding_state_transition (struct lease *lease) * release message. This is not true of expiry, where the * peer may have extended the lease. */ - ddns_removals(lease, NULL, NULL); + (void) ddns_removals(lease, NULL, NULL, ISC_TRUE); #endif if (lease -> on_release) { execute_statements ((struct binding_value **)0, @@ -1680,7 +1680,7 @@ void release_lease (lease, packet) /* If there are statements to execute when the lease is released, execute them. */ #if defined (NSUPDATE) - ddns_removals(lease, NULL, NULL); + (void) ddns_removals(lease, NULL, NULL, ISC_FALSE); #endif if (lease -> on_release) { execute_statements ((struct binding_value **)0, @@ -1754,7 +1754,7 @@ void abandon_lease (lease, message) { struct lease *lt = (struct lease *)0; #if defined (NSUPDATE) - ddns_removals(lease, NULL, NULL); + (void) ddns_removals(lease, NULL, NULL, ISC_FALSE); #endif if (!lease_copy (<, lease, MDL)) @@ -1778,6 +1778,14 @@ void abandon_lease (lease, message) lease_dereference (<, MDL); } +#if 0 +/* + * This doesn't appear to be in use for anything anymore. + * I'm ifdeffing it now and if there are no complaints in + * the future it will be removed. + * SAR + */ + /* Abandon the specified lease (set its timeout to infinity and its particulars to zero, and re-hash it as appropriate. */ @@ -1786,7 +1794,7 @@ void dissociate_lease (lease) { struct lease *lt = (struct lease *)0; #if defined (NSUPDATE) - ddns_removals(lease, NULL, NULL); + (void) ddns_removals(lease, NULL, NULL, ISC_FALSE); #endif if (!lease_copy (<, lease, MDL)) @@ -1811,6 +1819,7 @@ void dissociate_lease (lease) supersede_lease (lease, lt, 1, 1, 1); lease_dereference (<, MDL); } +#endif /* Timer called when a lease in a particular pool expires. */ void pool_timer (vpool) @@ -1961,9 +1970,17 @@ int find_lease_by_hw_addr (struct lease **lp, const char *file, int line) { if (hwlen == 0) - return 0; - return lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen, - file, line); + return (0); + + /* + * If it's an infiniband address don't bother + * as we don't have a useful address to hash. + */ + if ((hwlen == 1) && (hwaddr[0] == HTYPE_INFINIBAND)) + return (0); + + return (lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen, + file, line)); } /* If the lease is preferred over the candidate, return truth. The @@ -2128,6 +2145,8 @@ void uid_hash_delete (lease) } /* Add the specified lease to the hardware address hash. */ +/* We don't add leases with infiniband addresses to the + * hash as there isn't any address to hash on. */ void hw_hash_add(struct lease *lease) @@ -2137,6 +2156,14 @@ hw_hash_add(struct lease *lease) struct lease *prev = NULL; struct lease *next = NULL; + /* + * If it's an infiniband address don't bother + * as we don't have a useful address to hash. + */ + if ((lease->hardware_addr.hlen == 1) && + (lease->hardware_addr.hbuf[0] == HTYPE_INFINIBAND)) + return; + /* If it's not in the hash, just add it. */ if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, lease -> hardware_addr.hlen, MDL)) @@ -2208,6 +2235,14 @@ void hw_hash_delete (lease) struct lease *head = (struct lease *)0; struct lease *next = (struct lease *)0; + /* + * If it's an infiniband address don't bother + * as we don't have a useful address to hash. + */ + if ((lease->hardware_addr.hlen == 1) && + (lease->hardware_addr.hbuf[0] == HTYPE_INFINIBAND)) + return; + /* If it's not in the hash, we have no work to do. */ if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf, lease -> hardware_addr.hlen, MDL)) { diff --git a/server/mdb6.c b/server/mdb6.c index 9d410f5..e6d0a1a 100644 --- a/server/mdb6.c +++ b/server/mdb6.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007-2012 by Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,9 +14,68 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* TODO: assert() */ -/* TODO: simplify functions, as pool is now in iaaddr */ +/*! + * \todo assert() + * \todo simplify functions, as pool is now in iaaddr + */ +/*! \file server/mdb6.c + * + * \page ipv6structures IPv6 Structures Overview + * + * A brief description of the IPv6 structures as reverse engineered. + * + * There are three major data strucutes involved in the database: + * ipv6_pool - this contains information about a pool of addresses or prefixes + * that the server is using. This includes a hash table that + * tracks the active items and a pair of heap tables one for + * active items and one for non-active items. The heap tables + * are used to determine the next items to be modified due to + * timing events (expire mostly). + * ia_xx - this contains information about a single IA from a request + * normally it will contain one pointer to a lease for the client + * but it may contain more in some circumstances. There are 3 + * hash tables to aid in accessing these one each for NA, TA and PD + * iasubopt - the v6 lease structure. These are creaeted dynamically when + * a client asks for something and will eventually be destroyed + * if the client doesn't re-ask for that item. A lease has space + * for backpointers to the IA and to the pool to which it belongs. + * The pool backpointer is always filled, the IA pointer may not be + * + * In normal use we then have something like this: + * + * ia hash tables + * ia_na_active +----------------+ + * ia_ta_active +------------+ | pool | + * ia_pd_active | iasubopt |<--| active hash | + * +-----------------+ | aka lease |<--| active heap | + * | ia_xx | | pool ptr |-->| | + * | iasubopt array |<---| iaptr |<--| inactive heap | + * | lease ptr |--->| | | | + * +-----------------+ +------------+ +----------------+ + * + * For the pool either the inactive heap will have a pointer + * or both the active heap and the active hash will have pointers. + * + * I think there are several major items to notice. The first is + * that as a lease moves around it will be added to and removed + * from the address hash table in the pool and between the active + * and inactive hash tables. The hash table and the active heap + * are used when the lease is either active or abandoned. The + * inactive heap is used for all other states. In particular a + * lease that has expired or been released will be cleaned + * (DDNS removal etc) and then moved to the inactive heap. After + * some time period (currently 1 hour) it will be freed. + * + * The second is that when a client requests specific addresses, + * either because it previously owned them or if the server supplied + * them as part of a solicit, the server will try to lookup the ia_xx + * associated with the client and find the addresses there. If it + * does find appropriate leases it moves them from the old IA to + * a new IA and eventually replaces the old IA with the new IA + * in the IA hash tables. + * + */ #include "config.h" #include <sys/types.h> @@ -808,15 +867,14 @@ create_lease6(struct ipv6_pool *pool, struct iasubopt **addr, } /* - * Avoid reserved interface IDs. - * (cf. draft-krishnan-ipv6-reserved-iids-02.txt) + * Avoid reserved interface IDs. (cf. RFC 5453) */ reserved_iid = ISC_FALSE; - if (memcmp(&tmp.s6_addr[8], &rtany, 8) == 0) { + if (memcmp(&tmp.s6_addr[8], &rtany.s6_addr[8], 8) == 0) { reserved_iid = ISC_TRUE; } if (!reserved_iid && - (memcmp(&tmp.s6_addr[8], &resany, 7) == 0) && + (memcmp(&tmp.s6_addr[8], &resany.s6_addr[8], 7) == 0) && ((tmp.s6_addr[15] & 0x80) == 0x80)) { reserved_iid = ISC_TRUE; } @@ -875,6 +933,145 @@ create_lease6(struct ipv6_pool *pool, struct iasubopt **addr, return result; } + +/*! \file server/mdb6.c + * + * \brief Cleans up leases when reading from a lease file + * + * This function is only expected to be run when reading leases in from a file. + * It checks to see if a lease already exists for the new leases's address. + * We don't add expired leases to the structures when reading a lease file + * which limits what can happen. We have two variables the owners of the leases + * being the same or different and the new lease being active or non-active: + * Owners active + * same no remove old lease and its connections + * same yes nothing to do, other code will update the structures. + * diff no nothing to do + * diff yes this combination shouldn't happen, we should only have a + * single active lease per address at a time and that lease + * should move to non-active before any other lease can + * become active for that address. + * Currently we delete the previous lease and pass an error + * to the caller who should log an error. + * + * When we remove a lease we remove it from the hash table and active heap + * (remember only active leases are in the structures at this time) for the + * pool, and from the IA's array. If, after we've removed the pointer from + * IA's array to the lease, the IA has no more pointers we remove it from + * the appropriate hash table as well. + * + * \param[in] ia_table = the hash table for the IA + * \param[in] pool = the pool to update + * \param[in] lease = the new lease we want to add + * \param[in] ia = the new ia we are building + * + * \return + * ISC_R_SUCCESS = the incoming lease and any previous lease were in + * an expected state - one of the first 3 options above. + * If necessary the old lease was removed. + * ISC_R_FAILURE = there is already an active lease for the address in + * the incoming lease. This shouldn't happen if it does + * flag an error for the caller to log. + */ + +isc_result_t +cleanup_lease6(ia_hash_t *ia_table, + struct ipv6_pool *pool, + struct iasubopt *lease, + struct ia_xx *ia) { + + struct iasubopt *test_iasubopt, *tmp_iasubopt; + struct ia_xx *old_ia; + isc_result_t status = ISC_R_SUCCESS; + + test_iasubopt = NULL; + old_ia = NULL; + + /* + * Look up the address - if we don't find a lease + * we don't need to do anything. + */ + if (iasubopt_hash_lookup(&test_iasubopt, pool->leases, + &lease->addr, sizeof(lease->addr), + MDL) == 0) { + return (ISC_R_SUCCESS); + } + + if (test_iasubopt->ia == NULL) { + /* no old ia, no work to do */ + iasubopt_dereference(&test_iasubopt, MDL); + return (status); + } + + ia_reference(&old_ia, test_iasubopt->ia, MDL); + + if ((old_ia->iaid_duid.len == ia->iaid_duid.len) && + (memcmp((unsigned char *)ia->iaid_duid.data, + (unsigned char *)old_ia->iaid_duid.data, + ia->iaid_duid.len) == 0)) { + /* same IA */ + if ((lease->state == FTS_ACTIVE) || + (lease->state == FTS_ABANDONED)) { + /* still active, no need to delete */ + goto cleanup; + } + } else { + /* different IA */ + if ((lease->state != FTS_ACTIVE) && + (lease->state != FTS_ABANDONED)) { + /* new lease isn't active, no work */ + goto cleanup; + } + + /* + * We appear to have two active leases, this shouldn't happen. + * Before a second lease can be set to active the first lease + * should be set to inactive (released, expired etc). For now + * delete the previous lease and indicate a failure to the + * caller so it can generate a warning. + * In the future we may try and determine which is the better + * lease to keep. + */ + + status = ISC_R_FAILURE; + } + + /* + * Remove the old lease from the active heap and from the hash table + * then remove the lease from the IA and clean up the IA if necessary. + */ + isc_heap_delete(pool->active_timeouts, test_iasubopt->heap_index); + pool->num_active--; + + iasubopt_hash_delete(pool->leases, &test_iasubopt->addr, + sizeof(test_iasubopt->addr), MDL); + ia_remove_iasubopt(old_ia, test_iasubopt, MDL); + if (old_ia->num_iasubopt <= 0) { + ia_hash_delete(ia_table, + (unsigned char *)old_ia->iaid_duid.data, + old_ia->iaid_duid.len, MDL); + } + + /* + * We derefenrece the subopt here as we've just removed it from + * the hash table in the pool. We need to make a copy as we + * need to derefernece it again later. + */ + tmp_iasubopt = test_iasubopt; + iasubopt_dereference(&tmp_iasubopt, MDL); + + cleanup: + ia_dereference(&old_ia, MDL); + + /* + * Clean up the reference, this is in addition to the deference + * above after removing the entry from the hash table + */ + iasubopt_dereference(&test_iasubopt, MDL); + + return (status); +} + /* * Put a lease in the pool directly. This is intended to be used when * loading leases from the file. @@ -985,6 +1182,38 @@ lease6_exists(const struct ipv6_pool *pool, const struct in6_addr *addr) { } } +/*! + * + * \brief Check if address is available to a lease + * + * Determine if the address in the lease is available to that + * lease. Either the address isn't in use or it is in use + * but by that lease. + * + * \param[in] lease = lease to check + * + * \return + * ISC_TRUE = The lease is allowed to use that address + * ISC_FALSE = The lease isn't allowed to use that address + */ +isc_boolean_t +lease6_usable(struct iasubopt *lease) { + struct iasubopt *test_iaaddr; + isc_boolean_t status = ISC_TRUE; + + test_iaaddr = NULL; + if (iasubopt_hash_lookup(&test_iaaddr, lease->ipv6_pool->leases, + (void *)&lease->addr, + sizeof(lease->addr), MDL)) { + if (test_iaaddr != lease) { + status = ISC_FALSE; + } + iasubopt_dereference(&test_iaaddr, MDL); + } + + return (status); +} + /* * Put the lease on our active pool. */ @@ -1058,7 +1287,7 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease, #if defined (NSUPDATE) /* Process events upon expiration. */ if (pool->pool_type != D6O_IA_PD) { - ddns_removals(NULL, lease, NULL); + (void) ddns_removals(NULL, lease, NULL, ISC_FALSE); } #endif @@ -1466,6 +1695,11 @@ lease_timeout_support(void *vpool) { * Note that if there are no leases in the pool, * expire_lease6() will return ISC_R_SUCCESS with * a NULL lease. + * + * expire_lease6() will call move_lease_to_inactive() which + * calls ddns_removals() do we want that on the standard + * expiration timer or a special 'depref' timer? Original + * query from DH, moved here by SAR. */ lease = NULL; if (expire_lease6(&lease, pool, cur_time) != ISC_R_SUCCESS) { @@ -1475,18 +1709,6 @@ lease_timeout_support(void *vpool) { break; } - /* Look to see if there were ddns updates, and if - * so, drop them. - * - * DH: Do we want to do this on a special 'depref' - * timer rather than expiration timer? - */ -#if defined (NSUPDATE) - if (pool->pool_type != D6O_IA_PD) { - ddns_removals(NULL, lease, NULL); - } -#endif - write_ia(lease->ia); iasubopt_dereference(&lease, MDL); diff --git a/server/omapi.c b/server/omapi.c index bbddaf9..ca03cd1 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -3,7 +3,7 @@ OMAPI object interfaces for the DHCP server. */ /* - * Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2010,2012 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 @@ -480,12 +480,11 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line) isc_result_t dhcp_lease_signal_handler (omapi_object_t *h, const char *name, va_list ap) { - struct lease *lease; + /* h should point to (struct lease *) */ isc_result_t status; if (h -> type != dhcp_type_lease) return DHCP_R_INVALIDARG; - lease = (struct lease *)h; if (!strcmp (name, "updated")) return ISC_R_SUCCESS; @@ -985,20 +984,21 @@ isc_result_t dhcp_host_set_value (omapi_object_t *h, if (!omapi_ds_strcmp (name, "hardware-type")) { int type; - if (value && (value -> type == omapi_datatype_data && - value -> u.buffer.len == sizeof type)) { - if (value -> u.buffer.len > sizeof type) - return DHCP_R_INVALIDARG; - memcpy (&type, - value -> u.buffer.value, - value -> u.buffer.len); - type = ntohl (type); - } else if (value -> type == omapi_datatype_int) - type = value -> u.integer; + if ((value != NULL) && + ((value->type == omapi_datatype_data) && + (value->u.buffer.len == sizeof(type)))) { + if (value->u.buffer.len > sizeof(type)) + return (DHCP_R_INVALIDARG); + memcpy(&type, value->u.buffer.value, + value->u.buffer.len); + type = ntohl(type); + } else if ((value != NULL) && + (value->type == omapi_datatype_int)) + type = value->u.integer; else - return DHCP_R_INVALIDARG; - host -> interface.hbuf [0] = type; - return ISC_R_SUCCESS; + return (DHCP_R_INVALIDARG); + host->interface.hbuf[0] = type; + return (ISC_R_SUCCESS); } if (!omapi_ds_strcmp (name, "dhcp-client-identifier")) { @@ -1175,14 +1175,13 @@ isc_result_t dhcp_host_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t dhcp_host_destroy (omapi_object_t *h, const char *file, int line) { - struct host_decl *host; if (h -> type != dhcp_type_host) return DHCP_R_INVALIDARG; - host = (struct host_decl *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + struct host_decl *host = (struct host_decl *)h; if (host -> n_ipaddr) host_dereference (&host -> n_ipaddr, file, line); if (host -> n_dynamic) @@ -1388,7 +1387,7 @@ isc_result_t dhcp_host_lookup (omapi_object_t **lp, tv -> value -> u.buffer.value, tv -> value -> u.buffer.len, MDL); omapi_value_dereference (&tv, MDL); - + if (*lp && *lp != (omapi_object_t *)host) { omapi_object_dereference (lp, MDL); if (host) @@ -1594,12 +1593,11 @@ isc_result_t dhcp_pool_set_value (omapi_object_t *h, omapi_data_string_t *name, omapi_typed_data_t *value) { - struct pool *pool; + /* h should point to (struct pool *) */ isc_result_t status; if (h -> type != dhcp_type_pool) return DHCP_R_INVALIDARG; - pool = (struct pool *)h; /* No values to set yet. */ @@ -1619,12 +1617,11 @@ isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value) { - struct pool *pool; + /* h should point to (struct pool *) */ isc_result_t status; if (h -> type != dhcp_type_pool) return DHCP_R_INVALIDARG; - pool = (struct pool *)h; /* No values to get yet. */ @@ -1640,7 +1637,6 @@ isc_result_t dhcp_pool_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line) { - struct pool *pool; #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) struct permit *pc, *pn; @@ -1648,10 +1644,10 @@ isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line) if (h -> type != dhcp_type_pool) return DHCP_R_INVALIDARG; - pool = (struct pool *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + struct pool *pool = (struct pool *)h; if (pool -> next) pool_dereference (&pool -> next, file, line); if (pool -> group) @@ -1692,13 +1688,12 @@ isc_result_t dhcp_pool_destroy (omapi_object_t *h, const char *file, int line) isc_result_t dhcp_pool_signal_handler (omapi_object_t *h, const char *name, va_list ap) { - struct pool *pool; + /* h should point to (struct pool *) */ isc_result_t status; int updatep = 0; if (h -> type != dhcp_type_pool) return DHCP_R_INVALIDARG; - pool = (struct pool *)h; /* Can't write pools yet. */ @@ -1718,12 +1713,11 @@ isc_result_t dhcp_pool_stuff_values (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) { - struct pool *pool; + /* h should point to (struct pool *) */ isc_result_t status; if (h -> type != dhcp_type_pool) return DHCP_R_INVALIDARG; - pool = (struct pool *)h; /* Can't stuff pool values yet. */ @@ -1951,14 +1945,13 @@ isc_result_t dhcp_class_get_value (omapi_object_t *h, omapi_object_t *id, isc_result_t dhcp_class_destroy (omapi_object_t *h, const char *file, int line) { - struct class *class; if (h -> type != dhcp_type_class && h -> type != dhcp_type_subclass) return DHCP_R_INVALIDARG; - class = (struct class *)h; #if defined (DEBUG_MEMORY_LEAKAGE) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) + struct class *class = (struct class *)h; if (class -> nic) class_dereference (&class -> nic, file, line); if (class -> superclass) @@ -2065,7 +2058,7 @@ class_signal_handler(omapi_object_t *h, if (updatep) return ISC_R_SUCCESS; - + return ISC_R_NOTFOUND; } @@ -2083,12 +2076,11 @@ isc_result_t dhcp_class_stuff_values (omapi_object_t *c, omapi_object_t *id, omapi_object_t *h) { - struct class *class; + /* h should point to (struct class *) */ isc_result_t status; if (h -> type != dhcp_type_class) return DHCP_R_INVALIDARG; - class = (struct class *)h; /* Can't stuff class values yet. */ |