]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- A new DDNS related server option, update-conflict-detection, has been
authorDavid Hankins <dhankins@isc.org>
Wed, 19 Jul 2006 17:14:55 +0000 (17:14 +0000)
committerDavid Hankins <dhankins@isc.org>
Wed, 19 Jul 2006 17:14:55 +0000 (17:14 +0000)
  added.  If this option is enabled, dhcpd will perform normal DHCID
  conflict resolution (the default).  If this option is disabled, it will
  instead trust the assigned name implicitly (removing any other bindings
  on that name).  This option has not been made available in dhclient.
  [ISC-Bugs #16165]

RELNOTES
client/dhclient.c
common/dns.c
includes/dhcpd.h
server/ddns.c
server/dhcpd.conf.5
server/stables.c

index 59675213144aaeeeffc9907783a74dbfd3b8b337..2b8e10bc1980117aaa6a620f18178cb9c0589dca 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -122,6 +122,12 @@ and for prodding me into improving it.
 - The DHCP Relay Agent Information Option / Link Selection Sub-Option
   is now supported.  (See RFC3527 for details).
 
+- A new DDNS related server option, update-conflict-detection, has been
+  added.  If this option is enabled, dhcpd will perform normal DHCID
+  conflict resolution (the default).  If this option is disabled, it will
+  instead trust the assigned name implicitly (removing any other bindings
+  on that name).  This option has not been made available in dhclient.
+
                        Changes since 3.0.4
 
 - A warning that host statements declared within subnet or shared-network
index fff2f3e1a9c13072cdc145ad17ca20f4a7a55020..53ac8317a1552ec614ebe6e65a0fa8cc85eb43dc 100644 (file)
@@ -32,7 +32,7 @@
 
 #ifndef lint
 static char ocopyright[] =
-"$Id: dhclient.c,v 1.141 2006/07/09 15:39:48 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: dhclient.c,v 1.142 2006/07/19 17:14:55 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -3178,7 +3178,7 @@ isc_result_t client_dns_update (struct client_state *client, int addp, int ttl)
                        rcode = ddns_update_a (&ddns_fwd_name,
                                               client -> active -> address,
                                               &ddns_dhcid, ttl,
-                                              1);
+                                              1, 1);
                else
                        rcode = ddns_remove_a (&ddns_fwd_name,
                                               client -> active -> address,
index 97804ec5ff44ddebb140c259ed30486da4d576f9..44efb7ee128b732994ad9deb5d16c40c906036a8 100644 (file)
@@ -33,7 +33,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: dns.c,v 1.39 2006/06/01 20:23:17 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: dns.c,v 1.40 2006/07/19 17:14:55 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -518,10 +518,10 @@ int get_dhcid (struct data_string *id,
 /* Now for the DDNS update code that is shared between client and
    server... */
 
-isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
-                           struct iaddr ddns_addr,
-                           struct data_string *ddns_dhcid,
-                           unsigned long ttl, int rrsetp)
+isc_result_t
+ddns_update_a(struct data_string *ddns_fwd_name, struct iaddr ddns_addr,
+             struct data_string *ddns_dhcid, unsigned long ttl,
+             unsigned rrsetp, unsigned conflict)
 {
        ns_updque updqueue;
        ns_updrec *updrec;
@@ -654,22 +654,44 @@ isc_result_t ddns_update_a (struct data_string *ddns_fwd_name,
                minires_freeupdrec (updrec);
        }
 
-       /*
-        * DHCID RR exists, and matches client identity.
+       /* If we're doing conflict resolution, we use a set of prereqs.  If
+        * not, we delete the DHCID in addition to all A rrsets.
         */
-       updrec = minires_mkupdrec (S_PREREQ,
-                                  (const char *)ddns_fwd_name -> data,
-                                  C_IN, T_DHCID, 0);
-       if (!updrec) {
-               result = ISC_R_NOMEMORY;
-               goto error;
-       }
+       if (conflict) {
+               /*
+                * DHCID RR exists, and matches client identity.
+                */
+               updrec = minires_mkupdrec (S_PREREQ,
+                                          (const char *)ddns_fwd_name -> data,
+                                          C_IN, T_DHCID, 0);
+               if (!updrec) {
+                       result = ISC_R_NOMEMORY;
+                       goto error;
+               }
+       
+               updrec -> r_data = ddns_dhcid -> data;
+               updrec -> r_size = ddns_dhcid -> len;
+               updrec -> r_opcode = YXRRSET;
 
-       updrec -> r_data = ddns_dhcid -> data;
-       updrec -> r_size = ddns_dhcid -> len;
-       updrec -> r_opcode = YXRRSET;
+               ISC_LIST_APPEND (updqueue, updrec, r_link);
+       } else {
+               /*
+                * Conflict detection override: delete DHCID RRs.
+                */
+               updrec = minires_mkupdrec(S_UPDATE, ddns_fwd_name->data,
+                                         C_IN, T_DHCID, 0);
+
+               if (!updrec) {
+                       result = ISC_R_NOMEMORY;
+                       goto error;
+               }
 
-       ISC_LIST_APPEND (updqueue, updrec, r_link);
+               updrec->r_data = NULL;
+               updrec->r_size = 0;
+               updrec->r_opcode = DELETE;
+
+               ISC_LIST_APPEND(updqueue, updrec, r_link);
+       }
 
 
        /*
index 4735be73e58de60bd389dbfe4f92c30ff76b6f29..a0cc560b29243c05ffb6846517c5a63120dfdf12 100644 (file)
@@ -510,6 +510,7 @@ struct lease_state {
 #define SV_DO_FORWARD_UPDATES          45
 #define SV_PING_TIMEOUT                        46
 #define SV_RESERVE_INFINITE            47
+#define SV_DDNS_CONFLICT_DETECT                48
 
 #if !defined (DEFAULT_PING_TIMEOUT)
 # define DEFAULT_PING_TIMEOUT 1
@@ -2186,8 +2187,9 @@ void forget_zone (struct dns_zone **);
 void repudiate_zone (struct dns_zone **);
 void cache_found_zone (ns_class, char *, struct in_addr *, int);
 int get_dhcid (struct data_string *, int, const u_int8_t *, unsigned);
-isc_result_t ddns_update_a (struct data_string *, struct iaddr,
-                           struct data_string *, unsigned long, int);
+isc_result_t ddns_update_a(struct data_string *, struct iaddr,
+                          struct data_string *, unsigned long, unsigned,
+                          unsigned);
 isc_result_t ddns_remove_a (struct data_string *,
                            struct iaddr, struct data_string *);
 #endif /* NSUPDATE */
index b28113245c50b21ec2e8f6cc132b8152774afa69..483d9a3f41f3869d9442e4ad1e65f5b8ac750cd3 100644 (file)
@@ -34,7 +34,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: ddns.c,v 1.19 2006/06/01 20:23:17 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: ddns.c,v 1.20 2006/07/19 17:14:55 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -548,9 +548,23 @@ int ddns_updates (struct packet *packet,
        /*
         * Perform updates.
         */
-       if (ddns_fwd_name.len && ddns_dhcid.len)
+       if (ddns_fwd_name.len && ddns_dhcid.len) {
+               unsigned conflict;
+
+               oc = lookup_option(&server_universe, state->options,
+                                  SV_DDNS_CONFLICT_DETECT);
+               if (!oc ||
+                   evaluate_boolean_option_cache(&ignorep, packet, lease,
+                                                 NULL, packet->options,
+                                                 state->options,
+                                                 &lease->scope, oc, MDL))
+                       conflict = 1;
+               else
+                       conflict = 0;
+
                rcode1 = ddns_update_a (&ddns_fwd_name, lease -> ip_addr,
-                                       &ddns_dhcid, ddns_ttl, 0);
+                                       &ddns_dhcid, ddns_ttl, 0, conflict);
+       }
        
        if (rcode1 == ISC_R_SUCCESS) {
                if (ddns_fwd_name.len && ddns_rev_name.len)
index 2119a600aed260ba93b5fd45c782aa9f1663c863..820f96bf7e52665c5dc5be4dde1066273c64af72 100644 (file)
@@ -28,7 +28,7 @@
 .\" see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
 .\" ``http://www.nominum.com''.
 .\"
-.\" $Id: dhcpd.conf.5,v 1.75 2006/07/09 15:01:19 dhankins Exp $
+.\" $Id: dhcpd.conf.5,v 1.76 2006/07/19 17:14:55 dhankins Exp $
 .\"
 .TH dhcpd.conf 5
 .SH NAME
@@ -2400,6 +2400,19 @@ directly to the server and not sent through a relay agent.
 .RE
 .PP
 The
+.I update-conflict-detection
+statement
+.RS 0.25i
+.PP
+.B update-conflict-detection \fIflag\fB;\fR
+.PP
+If the \fIupdate-conflict-detection\fR parameter is true, the server will
+perform standard DHCID multiple-client, one-name conflict detection.  If
+the parameter has been set false, the server will skip this check and
+instead simply tear down any previous bindings to install the new
+binding without question.  The default is true.
+.PP
+The
 .I update-optimization
 statement
 .RS 0.25i
index 7c7df5cabc8574d2a19264f31c7501cd0f3b6567..4bfbaf255de553cd30ec5045475e04183713d82a 100644 (file)
@@ -34,7 +34,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: stables.c,v 1.31 2006/07/17 15:16:43 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: stables.c,v 1.32 2006/07/19 17:14:55 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -233,6 +233,7 @@ static struct option server_options[] = {
        { "do-forward-updates", "f",            &server_universe,  45, 1 },
        { "ping-timeout", "T",                  &server_universe,  46, 1 },
        { "infinite-is-reserved", "f",          &server_universe,  47, 1 },
+       { "update-conflict-detection", "f",     &server_universe,  48, 1 },
        { NULL, NULL, NULL, 0, 0 }
 };