diff --git a/RELNOTES b/RELNOTES index 83485959..0a8e70ee 100644 --- a/RELNOTES +++ b/RELNOTES @@ -198,6 +198,11 @@ work on other platforms. Please report any problems and suggested fixes to option 6rd 16 10 2001:: 1.2.3.4, 5.6.7.8; +- Handle some DDNS corner cases better. Maintain the DDNS transaction + information when updating a lease and cancel any existing transactions + when removing the ddns information. + [ISC-Bugs #23103] + Changes since 4.2.0b2 - Add declaration for variable in debug code in alloc.c. [ISC-Bugs #21472] diff --git a/server/ddns.c b/server/ddns.c index 10a2c03c..cfbdd04e 100644 --- a/server/ddns.c +++ b/server/ddns.c @@ -4,7 +4,7 @@ /* * - * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009-2011 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2000-2003 by Internet Software Consortium * @@ -109,7 +109,7 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old, } } else if (lease6 != NULL) { if ((old6 != NULL) && (old6->ddns_cb != NULL)) { - ddns_cancel(old->ddns_cb); + ddns_cancel(old6->ddns_cb); old6->ddns_cb = NULL; } } else { @@ -1304,9 +1304,24 @@ ddns_removals(struct lease *lease, isc_result_t rcode, execute_add = ISC_R_FAILURE; struct binding_scope **scope = NULL; int result = 0; - dhcp_ddns_cb_t *ddns_cb; + 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. + */ + 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; + } else + goto cleanup; + /* allocate our control block */ ddns_cb = ddns_cb_alloc(MDL); if (ddns_cb == NULL) { @@ -1467,7 +1482,8 @@ ddns_removals(struct lease *lease, * we allocated here. */ ddns_fwd_srv_connector(lease, lease6, scope, add_ddns_cb, execute_add); - ddns_cb_free(ddns_cb, MDL); + if (ddns_cb != NULL) + ddns_cb_free(ddns_cb, MDL); return(result); } diff --git a/server/mdb.c b/server/mdb.c index adcfe063..53c1b309 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -3,6 +3,7 @@ Server-specific in-memory database support. */ /* + * Copyright (c) 2011 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * @@ -1225,8 +1226,15 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate) comp->ends = lease->ends; comp->next_binding_state = lease->next_binding_state; - /* move the ddns control block information */ - comp->ddns_cb = lease->ddns_cb; + /* + * If we have a control block pointer copy it in. + * We don't zero out an older ponter as it is still + * in use. We shouldn't need to overwrite an + * old pointer with a new one as the old transaction + * should have been cancelled before getting here. + */ + if (lease->ddns_cb != NULL) + comp->ddns_cb = lease->ddns_cb; just_move_it: #if defined (FAILOVER_PROTOCOL)