]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Fixed dhclient crash on lease renew when client is doing ddns
authortmarkwalder <tmark@isc.org>
Thu, 25 Jun 2015 11:26:34 +0000 (07:26 -0400)
committertmarkwalder <tmark@isc.org>
Thu, 25 Jun 2015 11:26:34 +0000 (07:26 -0400)
    Merged in 38639.

RELNOTES
client/dhclient.c

index 78a37304781e5fff8f551e690c25c1098f3e6884..f5ef5f0fa78350377803fd9174692ef2551e37c7 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -54,11 +54,6 @@ by Eric Young (eay@cryptsoft.com).
 
                        Changes since 4.3.2
 
-- Delayed-ack now works properly with Failover. Prior to this, bind updates
-  post startup were being queued but never delivered. Among other things, this
-  was causing leases to not transition from expired or released to free.
-  [ISC-Bugs #31474]
-
 - The server now does a better check to see if it can allocate the memory
   for large blocks of v4 leases and should provide a slightly better error
   message.  Note well: the server pre-allocates v4 addresses, if you use
@@ -131,10 +126,19 @@ by Eric Young (eay@cryptsoft.com).
   Thanks to Fernando Soto from BlueCat Networks for the patch.
   [ISC-Bugs #39078]
 
+- Delayed-ack now works properly with Failover. Prior to this, bind updates
+  post startup were being queued but never delivered. Among other things, this
+  was causing leases to not transition from expired or released to free.
+  [ISC-Bugs #31474]
+
 - Clean up parsing of v6 lease files a bit to avoid infinite loops if the
   lease file is corrupt in certain ways.
   [ISC-Bugs #39760]
 
+- Corrected a crash in dhclient that occurs during lease renewal if the
+  client is performing its own DNS updates.
+  [ISC-Bugs #38639]
+
                        Changes since 4.3.2rc2
 - None
 
index 2adf98d8fff86962d9083cb62074768dd37b82c9..d14a9cf7880f6afd131b2bf68d2377a1ce7ecc34 100644 (file)
@@ -101,6 +101,9 @@ static int check_domain_name_list(const char *ptr, size_t len, int dots);
 static int check_option_values(struct universe *universe, unsigned int opt,
                               const char *ptr, size_t len);
 
+static void dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb,
+                                   char* file, int line);
+
 #ifndef UNIT_TEST
 int
 main(int argc, char **argv) {
@@ -1241,7 +1244,7 @@ void bind_lease (client)
 
        /* Run the client script with the new parameters. */
        script_init(client, (client->state == S_REQUESTING ? "BOUND" :
-                            (client->state == S_RENEWING ? "RENEW" : 
+                            (client->state == S_RENEWING ? "RENEW" :
                              (client->state == S_REBOOTING ? "REBOOT" :
                               "REBIND"))),
                    client->new->medium);
@@ -1694,7 +1697,7 @@ struct client_lease *packet_to_lease (packet, client)
        lease->next_srv_addr.len = sizeof(packet->raw->siaddr);
        memcpy(lease->next_srv_addr.iabuf, &packet->raw->siaddr,
               lease->next_srv_addr.len);
-       
+
        memset(&data, 0, sizeof(data));
 
        if (client -> config -> vendor_space_name) {
@@ -2448,7 +2451,7 @@ make_client_options(struct client_state *client, struct client_lease *lease,
 
                /* Client-identifier type : 1 byte */
                *client_identifier.buffer->data = 255;
-               
+
                /* IAID : 4 bytes
                 * we use the low 4 bytes from the interface address
                 */
@@ -2462,7 +2465,7 @@ make_client_options(struct client_state *client, struct client_lease *lease,
                memcpy(&client_identifier.buffer->data + 5 - hw_len,
                       client->interface->hw_address.hbuf + hw_idx,
                       hw_len);
-       
+
                /* Add the default duid */
                memcpy(&client_identifier.buffer->data+(1+4),
                       default_duid.data, default_duid.len);
@@ -3965,7 +3968,7 @@ client_dns_remove_action(dhcp_ddns_cb_t *ddns_cb,
        }
 
        /* If we are done or have an error clean up */
-       ddns_cb_free(ddns_cb, MDL);
+       dhclient_ddns_cb_free(ddns_cb, MDL);
        return;
 }
 
@@ -3981,7 +3984,7 @@ client_dns_remove(struct client_state *client,
                ddns_cancel(client->ddns_cb, MDL);
                client->ddns_cb = NULL;
        }
-       
+
        ddns_cb = ddns_cb_alloc(MDL);
        if (ddns_cb != NULL) {
                ddns_cb->address = *addr;
@@ -3994,7 +3997,7 @@ client_dns_remove(struct client_state *client,
                result = client_dns_update(client, ddns_cb);
 
                if (result != ISC_R_TIMEDOUT) {
-                       ddns_cb_free(ddns_cb, MDL);
+                       dhclient_ddns_cb_free(ddns_cb, MDL);
                }
        }
 }
@@ -4091,10 +4094,7 @@ client_dns_update_timeout (void *cp)
         * the control block and should free it.
         */
        if (status != ISC_R_TIMEDOUT) {
-               if (client != NULL) {
-                       client->ddns_cb = NULL;
-               }
-               ddns_cb_free(ddns_cb, MDL);
+               dhclient_ddns_cb_free(ddns_cb, MDL);
        }
 }
 
@@ -4183,7 +4183,7 @@ client_dns_update_action(dhcp_ddns_cb_t *ddns_cb,
                return;
        }
 
-       ddns_cb_free(ddns_cb, MDL);
+       dhclient_ddns_cb_free(ddns_cb, MDL);
        return;
 }
 
@@ -4263,7 +4263,7 @@ client_dns_update(struct client_state *client, dhcp_ddns_cb_t *ddns_cb)
        }
        if (client->active_lease != NULL) {
                /* V6 request, get the client identifier, then
-                * construct the dhcid for either standard 
+                * construct the dhcid for either standard
                 * or interim */
                if (((oc = lookup_option(&dhcpv6_universe,
                                         client->sent_options,
@@ -4380,7 +4380,6 @@ dhclient_schedule_updates(struct client_state *client,
                ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_INCLUDE_RRSET;
 
                client->ddns_cb = ddns_cb;
-
                tv.tv_sec = cur_tv.tv_sec + offset;
                tv.tv_usec = cur_tv.tv_usec;
                add_timeout(&tv, client_dns_update_timeout,
@@ -4560,7 +4559,7 @@ static int check_option_values(struct universe *universe,
 static void
 add_reject(struct packet *packet) {
        struct iaddrmatchlist *list;
-       
+
        list = dmalloc(sizeof(struct iaddrmatchlist), MDL);
        if (!list)
                log_fatal ("no memory for reject list!");
@@ -4585,3 +4584,16 @@ add_reject(struct packet *packet) {
        log_info("Server added to list of rejected servers.");
 }
 
+/* Wrapper function around common ddns_cb_free function that ensures
+ * we set the client_state pointer to the control block to NULL. */
+static void
+dhclient_ddns_cb_free(dhcp_ddns_cb_t *ddns_cb, char* file, int line) {
+    if (ddns_cb) {
+        struct client_state *client = (struct client_state *)ddns_cb->lease;
+        if (client != NULL) {
+            client->ddns_cb = NULL;
+        }
+
+        ddns_cb_free(ddns_cb, file, line);
+    }
+}