From 08cbfc1d7e80b5d81dbc7e1974251c40eb041300 Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Wed, 26 May 2010 22:34:56 +0000 Subject: [PATCH] add some debugging output for use with the DDNS code. [ISC-Bugs 20916] --- RELNOTES | 2 + common/dns.c | 13 ++++ common/print.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++- includes/dhcpd.h | 10 ++- includes/site.h | 5 ++ 5 files changed, 196 insertions(+), 4 deletions(-) diff --git a/RELNOTES b/RELNOTES index 4e4054c1b..0d643a1fe 100644 --- a/RELNOTES +++ b/RELNOTES @@ -63,6 +63,8 @@ work on other platforms. Please report any problems and suggested fixes to allocated in shared networks also now are not offered if the client has moved. [ISC-Bugs #21152] +- Add some debugging output for use with the DDNS code. [ISC-Bugs #20916] + Changes since 4.2.0a2 - Update the fsync code to work with the changes to the DDNS code. It now diff --git a/common/dns.c b/common/dns.c index 970d7cf9e..b9d6d2ac6 100644 --- a/common/dns.c +++ b/common/dns.c @@ -1245,6 +1245,11 @@ void ddns_interlude(isc_task_t *taskp, trace_ddns_input_write(ddns_cb, eresult); } #endif + +#if defined (DEBUG_DNS_UPDATES) + print_dns_status(DDNS_PRINT_INBOUND, ddns_cb, eresult); +#endif + /* This transaction is complete, clear the value */ dns_client_destroyupdatetrans(&ddns_cb->transaction); @@ -1469,6 +1474,10 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb) "address family not supported"); } +#if defined (DEBUG_DNS_UPDATES) + print_dns_status(DDNS_PRINT_OUTBOUND, ddns_cb, result); +#endif + cleanup: if (dataspace != NULL) { isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, @@ -1654,6 +1663,10 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb) "address family not supported"); } +#if defined (DEBUG_DNS_UPDATES) + print_dns_status(DDNS_PRINT_OUTBOUND, ddns_cb, result); +#endif + cleanup: if (dataspace != NULL) { isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, diff --git a/common/print.c b/common/print.c index 2f30c96e2..e57729672 100644 --- a/common/print.c +++ b/common/print.c @@ -1209,10 +1209,178 @@ void indent_spaces (FILE *file, int indent) } #if defined (NSUPDATE) +#if defined (DEBUG_DNS_UPDATES) /* - * Place holder for debug information for ddns. + * direction outbound (messages to the dns server) + * inbound (messages from the dns server) + * ddns_cb is the control block associated with the message + * result is the result from the dns code. For outbound calls + * it is from the call to pass the message to the dns library. + * For inbound calls it is from the event returned by the library. * + * For outbound messages we print whatever we think is interesting + * from the control block. + * For inbound messages we only print the transaction id pointer + * and the result and expect that the user will match them up as + * necessary. Note well: the transaction information is opaque to + * us so we simply print the pointer to it. This should be sufficient + * to match requests and replys in a short sequence but is awkward + * when trying to use it for longer sequences. */ +void +print_dns_status (int direction, + struct dhcp_ddns_cb *ddns_cb, + isc_result_t result) +{ + char obuf[1024]; + char *s = obuf, *end = &obuf[sizeof(obuf)-2]; + char *en; + const char *result_str; + char ddns_address[ + sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + + if (direction == DDNS_PRINT_INBOUND) { + log_info("DDNS reply: id ptr %p, result: %s", + ddns_cb->transaction, isc_result_totext(result)); + return; + } + + /* + * To avoid having to figure out if any of the strings + * aren't NULL terminated, just 0 the whole string + */ + memset(obuf, 0, 1024); + + en = "DDNS request: id ptr "; + if (s + strlen(en) + 16 < end) { + sprintf(s, "%s%p", en, ddns_cb->transaction); + s += strlen(s); + } else { + goto bailout; + } + + switch (ddns_cb->state) { + case DDNS_STATE_ADD_FW_NXDOMAIN: + en = " add forward "; + break; + case DDNS_STATE_ADD_FW_YXDHCID: + en = " modify forward "; + break; + + case DDNS_STATE_ADD_PTR: + en = " add reverse "; + break; + + case DDNS_STATE_REM_FW_YXDHCID: + en = " remove forward "; + break; + + case DDNS_STATE_REM_FW_NXRR: + en = " remove rrset "; + break; + + case DDNS_STATE_REM_PTR: + en = " remove reverse "; + break; + + case DDNS_STATE_CLEANUP: + en = " cleanup "; + break; + + default: + en = " unknown state "; + break; + } + + switch (ddns_cb->state) { + case DDNS_STATE_ADD_FW_NXDOMAIN: + case DDNS_STATE_ADD_FW_YXDHCID: + case DDNS_STATE_REM_FW_YXDHCID: + case DDNS_STATE_REM_FW_NXRR: + strcpy(ddns_address, piaddr(ddns_cb->address)); + if (s + strlen(en) + strlen(ddns_address) + + ddns_cb->fwd_name.len + 5 < end) { + sprintf(s, "%s%s for %.*s", en, ddns_address, + ddns_cb->fwd_name.len, + ddns_cb->fwd_name.data); + s += strlen(s); + } else { + goto bailout; + } + break; + + case DDNS_STATE_ADD_PTR: + case DDNS_STATE_REM_PTR: + if (s + strlen(en) + ddns_cb->fwd_name.len + + ddns_cb->rev_name.len + 5 < end) { + sprintf(s, "%s%.*s for %.*s", en, + ddns_cb->fwd_name.len, + ddns_cb->fwd_name.data, + ddns_cb->rev_name.len, + ddns_cb->rev_name.data); + s += strlen(s); + } else { + goto bailout; + } + break; + + case DDNS_STATE_CLEANUP: + default: + if (s + strlen(en) < end) { + sprintf(s, "%s", en); + s += strlen(s); + } else { + goto bailout; + } + break; + } + + en = " zone: "; + if (s + strlen(en) + strlen((char *)ddns_cb->zone_name) < end) { + sprintf(s, "%s%s", en, ddns_cb->zone_name); + s += strlen(s); + } else { + goto bailout; + } + + en = " dhcid: "; + if (s + strlen(en) + ddns_cb->dhcid.len < end) { + strcpy(s, en); + s += strlen(s); + strncpy(s, (char *)ddns_cb->dhcid.data + 1, + ddns_cb->dhcid.len - 1); + s += strlen(s); + } else { + goto bailout; + } + + en = " ttl: "; + if (s + strlen(en) + 10 < end) { + sprintf(s, "%s%ld", en, ddns_cb->ttl); + s += strlen(s); + } else { + goto bailout; + } + + en = " result: "; + result_str = isc_result_totext(result); + if (s + strlen(en) + strlen(result_str) < end) { + sprintf(s, "%s%s", en, result_str); + s += strlen(s); + } else { + goto bailout; + } + + bailout: + /* + * We either finished building the string or ran out + * of space, print whatever we have in case it is useful + */ + log_info("%s", obuf); + + return; +} +#endif #endif /* NSUPDATE */ /* Format the given time as "A; # B", where A is the format diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 28df6c86f..015f22ea5 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -1538,6 +1538,12 @@ struct ipv6_pool { #define DDNS_STATE_REM_FW_NXRR 18 #define DDNS_STATE_REM_PTR 19 +/* + * Flags for the dns print function + */ +#define DDNS_PRINT_INBOUND 1 +#define DDNS_PRINT_OUTBOUND 0 + struct dhcp_ddns_cb; typedef void (*ddns_action_t)(struct dhcp_ddns_cb *ddns_cb, @@ -2308,9 +2314,7 @@ int token_print_indent (FILE *, int, int, const char *, const char *, const char *); void indent_spaces (FILE *, int); #if defined (NSUPDATE) -#if 0 -void print_dns_status (int, ns_updque *); -#endif +void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t); #endif const char *print_time(TIME); diff --git a/includes/site.h b/includes/site.h index c77947d5d..2238fe7a3 100644 --- a/includes/site.h +++ b/includes/site.h @@ -103,6 +103,11 @@ /* #define DEBUG_DUMP_ALL_LEASES */ +/* Define this if you want to see the requests and replies between the + DHCP code and the DNS library code. */ + +/* #define DEBUG_DNS_UPDATES */ + /* Define this if you want DHCP failover protocol support in the DHCP server. */ -- 2.47.3