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].
+
Changes since 4.2.2
- Fix the code that checks for an existing DDNS transaction to cancel
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
/* 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;
}
/* 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;
}
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;
}
* 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;
/* 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;
}
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
*
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);
}
* 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);
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);
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 {
*/
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;
#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);
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;
#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);
}
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 */
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
//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"))
/*
*
- * 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
*
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 {
/* 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:
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;
}
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:
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:
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);
}
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;
}
/* 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;
}
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 */
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;
}
* - for example as part of a lease expiry - we won't.
*/
if ((lease != NULL) && (lease->ddns_cb != NULL)) {
- ddns_cancel(lease->ddns_cb);
+ ddns_cancel(lease->ddns_cb, MDL);
lease->ddns_cb = NULL;
} else if ((lease6 != NULL) && (lease6->ddns_cb != NULL)) {
- ddns_cancel(lease6->ddns_cb);
+ ddns_cancel(lease6->ddns_cb, MDL);
lease6->ddns_cb = NULL;
}
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);
result = 1;
}
- 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);