From: Shawn Routhier Date: Thu, 11 Feb 2010 23:55:36 +0000 (+0000) Subject: Primarly fix the trace code. This was broken during the modfictions of the X-Git-Tag: v4_2_0b1~3^2~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7aa153b882dc7076da256e506985571a474f944c;p=thirdparty%2Fdhcp.git Primarly fix the trace code. This was broken during the modfictions of the DDNS code to use the bind libraries. This patch fixes that breakage and includes support for the new DDNS code. This patch also deletes some dead code and neatens up some log messages. --- diff --git a/LICENSE b/LICENSE index 297a05719..10c0fbcb3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -# Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC") +# Copyright (c) 2004-2010 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 diff --git a/RELNOTES b/RELNOTES index ff8f5310f..23fbddbe6 100644 --- a/RELNOTES +++ b/RELNOTES @@ -59,6 +59,8 @@ work on other platforms. Please report any problems and suggested fixes to This is supported using a new 'rewind state' record on the dhcpd.leases entry for each lease. +- Fix the trace code which was broken by the changes to the DDNS code. + Changes since 4.1.0 (new features) - Failover port configuration can now be left to defaults (port 647) as diff --git a/common/dispatch.c b/common/dispatch.c index 564364215..fef2249f3 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -233,6 +233,45 @@ void add_timeout (when, where, what, ref, unref) q->when.tv_sec = when->tv_sec; q->when.tv_usec = when->tv_usec; +#if defined (TRACING) + if (trace_playback()) { + /* + * If we are doing playback we need to handle the timers + * within this code rather than having the isclib handle + * them for us. We need to keep the timer list in order + * to allow us to find the ones to timeout. + * + * By using a different timer setup in the playback we may + * have variations between the orginal and the playback but + * it's the best we can do for now. + */ + + /* Beginning of list? */ + if (!timeouts || (timeouts->when.tv_sec > q-> when.tv_sec) || + ((timeouts->when.tv_sec == q->when.tv_sec) && + (timeouts->when.tv_usec > q->when.tv_usec))) { + q->next = timeouts; + timeouts = q; + return; + } + + /* Middle of list? */ + for (t = timeouts; t->next; t = t->next) { + if ((t->next->when.tv_sec > q->when.tv_sec) || + ((t->next->when.tv_sec == q->when.tv_sec) && + (t->next->when.tv_usec > q->when.tv_usec))) { + q->next = t->next; + t->next = q; + return; + } + } + + /* End of list. */ + t->next = q; + q->next = (struct timeout *)0; + return; + } +#endif /* * Don't bother sorting the DHCP list, just add it to the front. * Eventually the list should be removed as we migrate the callers @@ -323,9 +362,19 @@ void cancel_timeout (where, what) t = q; } - /* If we found the timeout, cancel it and put it on the free list. */ + /* + * If we found the timeout, cancel it and put it on the free list. + * The TRACING stuff is ugly but we don't add a timer when doing + * playback so we don't want to remove them then either. + */ if (q) { - isc_timer_detach(&q->isc_timeout); +#if defined (TRACING) + if (!trace_playback()) { +#endif + isc_timer_detach(&q->isc_timeout); +#if defined (TRACING) + } +#endif if (q->unref) (*q->unref) (&q->what, MDL); diff --git a/common/dns.c b/common/dns.c index 2f7f998ce..c7c84134f 100644 --- a/common/dns.c +++ b/common/dns.c @@ -3,7 +3,8 @@ Domain Name Service subroutines. */ /* - * Copyright (c) 2004-2007, 2009 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2001-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any @@ -150,6 +151,285 @@ typedef struct dhcp_ddns_rdata { #if defined (NSUPDATE) +void ddns_interlude(isc_task_t *, isc_event_t *); + + +#if defined (TRACING) +/* + * Code to support tracing DDNS packets. We trace packets going to and + * coming from the libdns code but don't try to track the packets + * exchanged between the libdns code and the dns server(s) it contacts. + * + * The code is split into two sets of routines + * input refers to messages received from the dns module + * output refers to messages sent to the dns module + * Currently there are three routines in each set + * write is used to write information about the message to the trace file + * this routine is called directly from the proper place in the code. + * read is used to read information about a message from the trace file + * this routine is called from the trace loop as it reads through + * the file and is registered via the trace_type_register routine. + * When playing back a trace file we shall absorb records of output + * messages as part of processing the write function, therefore + * any output messages we encounter are flagged as errors. + * stop isn't currently used in this code but is needed for the register + * routine. + * + * We pass a pointer to a control block to the dns module which it returns + * to use as part of the result. As the pointer may vary between traces + * we need to map between those from the trace file and the new ones during + * playback. + * + * The mapping is complicated a little as a pointer could be 4 or 8 bytes + * long. We treat the old pointer as an 8 byte quantity and pad and compare + * as necessary. + */ + +/* + * Structure used to map old pointers to new pointers. + * Old pointers are 8 bytes long as we don't know if the trace was + * done on a 64 bit or 32 bit machine. + */ +#define TRACE_PTR_LEN 8 + +typedef struct dhcp_ddns_map { + char old_pointer[TRACE_PTR_LEN]; + void *new_pointer; + struct dhcp_ddns_map *next; +} dhcp_ddns_map_t; + +/* The starting point for the map structure */ +static dhcp_ddns_map_t *ddns_map; + +trace_type_t *trace_ddns_input; +trace_type_t *trace_ddns_output; + +/* + * The data written to the trace file is: + * 32 bits result from dns + * 64 bits pointer of cb + */ + +void +trace_ddns_input_write(dhcp_ddns_cb_t *ddns_cb, isc_result_t result) +{ + trace_iov_t iov[2]; + u_int32_t old_result; + char old_pointer[TRACE_PTR_LEN]; + + old_result = htonl((u_int32_t)result); + memset(old_pointer, 0, TRACE_PTR_LEN); + memcpy(old_pointer, &ddns_cb, sizeof(ddns_cb)); + + iov[0].len = sizeof(old_result); + iov[0].buf = (char *)&old_result; + iov[1].len = TRACE_PTR_LEN; + iov[1].buf = old_pointer; + trace_write_packet_iov(trace_ddns_input, 2, iov, MDL); +} + +/* + * Process the result and pointer from the trace file. + * We use the pointer map to find the proper pointer for this instance. + * Then we need to construct an event to pass along to the interlude + * function. + */ +static void +trace_ddns_input_read(trace_type_t *ttype, unsigned length, + char *buf) +{ + u_int32_t old_result; + char old_pointer[TRACE_PTR_LEN]; + dns_clientupdateevent_t *eventp; + void *new_pointer; + dhcp_ddns_map_t *ddns_map_ptr; + + if (length < (sizeof(old_result) + TRACE_PTR_LEN)) { + log_error("trace_ddns_input_read: data too short"); + return; + } + + memcpy(&old_result, buf, sizeof(old_result)); + memcpy(old_pointer, buf + sizeof(old_result), TRACE_PTR_LEN); + + /* map the old pointer to a new pointer */ + for (ddns_map_ptr = ddns_map; + ddns_map_ptr != NULL; + ddns_map_ptr = ddns_map_ptr->next) { + if ((ddns_map_ptr->new_pointer != NULL) && + memcmp(ddns_map_ptr->old_pointer, + old_pointer, TRACE_PTR_LEN) == 0) { + new_pointer = ddns_map_ptr->new_pointer; + ddns_map_ptr->new_pointer = NULL; + memset(ddns_map_ptr->old_pointer, 0, TRACE_PTR_LEN); + break; + } + } + if (ddns_map_ptr == NULL) { + log_error("trace_dns_input_read: unable to map cb pointer"); + return; + } + + eventp = (dns_clientupdateevent_t *) + isc_event_allocate(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.task, + 0, + ddns_interlude, + new_pointer, + sizeof(dns_clientupdateevent_t)); + if (eventp == NULL) { + log_error("trace_ddns_input_read: unable to allocate event"); + return; + } + eventp->result = ntohl(old_result); + + + ddns_interlude(dhcp_gbl_ctx.task, (isc_event_t *)eventp); + + return; +} + +static void +trace_ddns_input_stop(trace_type_t *ttype) +{ +} + +/* + * We use the same arguments as for the dns startupdate function to + * allows us to choose between the two via a macro. If tracing isn't + * in use we simply call the dns function directly. + * + * If we are doing playback we read the next packet from the file + * and compare the type. If it matches we extract the results and pointer + * from the trace file. The results are returned to the caller as if + * they had called the dns routine. The pointer is used to construct a + * map for when the "reply" is processed. + * + * The data written to trace file is: + * 32 bits result + * 64 bits pointer of cb (DDNS Control block) + * contents of cb + */ + +isc_result_t +trace_ddns_output_write(dns_client_t *client, dns_rdataclass_t rdclass, + dns_name_t *zonename, dns_namelist_t *prerequisites, + dns_namelist_t *updates, isc_sockaddrlist_t *servers, + dns_tsec_t *tsec, unsigned int options, + isc_task_t *task, isc_taskaction_t action, void *arg, + dns_clientupdatetrans_t **transp) +{ + isc_result_t result; + u_int32_t old_result; + char old_pointer[TRACE_PTR_LEN]; + dhcp_ddns_map_t *ddns_map_ptr; + + if (trace_playback() != 0) { + /* We are doing playback, extract the entry from the file */ + unsigned buflen = 0; + char *inbuf = NULL; + + result = trace_get_packet(&trace_ddns_output, + &buflen, &inbuf); + if (result != ISC_R_SUCCESS) { + log_error("trace_ddns_output_write: no input found"); + return (ISC_R_FAILURE); + } + if (buflen < (sizeof(old_result) + TRACE_PTR_LEN)) { + log_error("trace_ddns_output_write: data too short"); + dfree(inbuf, MDL); + return (ISC_R_FAILURE); + } + memcpy(&old_result, inbuf, sizeof(old_result)); + result = ntohl(old_result); + memcpy(old_pointer, inbuf + sizeof(old_result), TRACE_PTR_LEN); + dfree(inbuf, MDL); + + /* add the pointer to the pointer map */ + for (ddns_map_ptr = ddns_map; + ddns_map_ptr != NULL; + ddns_map_ptr = ddns_map_ptr->next) { + if (ddns_map_ptr->new_pointer == NULL) { + break; + } + } + + /* + * If we didn't find an empty entry, allocate an entry and + * link it into the list. The list isn't ordered. + */ + if (ddns_map_ptr == NULL) { + ddns_map_ptr = dmalloc(sizeof(*ddns_map_ptr), MDL); + if (ddns_map_ptr == NULL) { + log_error("trace_ddns_output_write: " + "unable to allocate map entry"); + return(ISC_R_FAILURE); + } + ddns_map_ptr->next = ddns_map; + ddns_map = ddns_map_ptr; + } + + memcpy(ddns_map_ptr->old_pointer, old_pointer, TRACE_PTR_LEN); + ddns_map_ptr->new_pointer = arg; + } + else { + /* We aren't doing playback, make the actual call */ + result = dns_client_startupdate(client, rdclass, zonename, + prerequisites, updates, + servers, tsec, options, + task, action, arg, transp); + } + + if (trace_record() != 0) { + /* We are recording, save the information to the file */ + trace_iov_t iov[3]; + old_result = htonl((u_int32_t)result); + memset(old_pointer, 0, TRACE_PTR_LEN); + memcpy(old_pointer, &arg, sizeof(arg)); + iov[0].len = sizeof(old_result); + iov[0].buf = (char *)&old_result; + iov[1].len = TRACE_PTR_LEN; + iov[1].buf = old_pointer; + + /* Write out the entire cb, in case we want to look at it */ + iov[2].len = sizeof(dhcp_ddns_cb_t); + iov[2].buf = (char *)arg; + + trace_write_packet_iov(trace_ddns_output, 3, iov, MDL); + } + + return(result); +} + +static void +trace_ddns_output_read(trace_type_t *ttype, unsigned length, + char *buf) +{ + log_error("unaccounted for ddns output."); +} + +static void +trace_ddns_output_stop(trace_type_t *ttype) +{ +} + +void +trace_ddns_init() +{ + trace_ddns_output = trace_type_register("ddns-output", NULL, + trace_ddns_output_read, + trace_ddns_output_stop, MDL); + trace_ddns_input = trace_type_register("ddns-input", NULL, + trace_ddns_input_read, + trace_ddns_input_stop, MDL); + ddns_map = NULL; +} + +#define ddns_update trace_ddns_output_write +#else +#define ddns_update dns_client_startupdate +#endif /* TRACING */ + /* * Code to allocate and free a dddns control block. This block is used * to pass and track the information associated with a DDNS update request. @@ -955,6 +1235,11 @@ void ddns_interlude(isc_task_t *taskp, * the event block.*/ isc_event_free(&eventp); +#if defined (TRACING) + if (trace_record()) { + trace_ddns_input_write(ddns_cb, eresult); + } +#endif /* This transaction is complete, clear the value */ ddns_cb->transaction = NULL; @@ -1165,15 +1450,15 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb) ISC_LIST_APPEND(updatelist, uname, link); /* send the message, cleanup and return the result */ - result = dns_client_startupdate(dhcp_gbl_ctx.dnsclient, - dns_rdataclass_in, zname, - &prereqlist, &updatelist, - zlist, tsec_key, - DNS_CLIENTRESOPT_ALLOWRUN, - dhcp_gbl_ctx.task, - ddns_interlude, - (void *)ddns_cb, - &ddns_cb->transaction); + result = ddns_update(dhcp_gbl_ctx.dnsclient, + dns_rdataclass_in, zname, + &prereqlist, &updatelist, + zlist, tsec_key, + DNS_CLIENTRESOPT_ALLOWRUN, + dhcp_gbl_ctx.task, + ddns_interlude, + (void *)ddns_cb, + &ddns_cb->transaction); cleanup: if (dataspace != NULL) { @@ -1347,14 +1632,15 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb) * and we wanted to retry it. */ /* send the message, cleanup and return the result */ - result = dns_client_startupdate((dns_client_t *)dhcp_gbl_ctx.dnsclient, - dns_rdataclass_in, zname, - NULL, &updatelist, - zlist, tsec_key, - DNS_CLIENTRESOPT_ALLOWRUN, - dhcp_gbl_ctx.task, - ddns_interlude, (void *)ddns_cb, - &ddns_cb->transaction); + result = ddns_update((dns_client_t *)dhcp_gbl_ctx.dnsclient, + dns_rdataclass_in, zname, + NULL, &updatelist, + zlist, tsec_key, + DNS_CLIENTRESOPT_ALLOWRUN, + dhcp_gbl_ctx.task, + ddns_interlude, (void *)ddns_cb, + &ddns_cb->transaction); + cleanup: if (dataspace != NULL) { isc_mem_put(dhcp_gbl_ctx.mctx, dataspace, diff --git a/common/print.c b/common/print.c index 791dfb4b9..f4dda1369 100644 --- a/common/print.c +++ b/common/print.c @@ -1208,254 +1208,10 @@ void indent_spaces (FILE *file, int indent) } #if defined (NSUPDATE) -#if 0 -void print_dns_status (int status, ns_updque *uq) -{ - char obuf [1024]; - char *s = &obuf [0], *end = &obuf [1022]; - ns_updrec *u; - int position; - int ttlp; - const char *predicate = "if", *en, *op; - int errorp; - - for (u = ISC_LIST_HEAD (*uq); u; u = ISC_LIST_NEXT (u, r_link)) { - ttlp = 0; - - switch (u -> r_opcode) - { - case NXRRSET: - op = "rrset doesn't exist"; - position = 1; - break; - case YXRRSET: - op = "rrset exists"; - position = 1; - break; - case NXDOMAIN: - op = "domain doesn't exist"; - position = 1; - break; - case YXDOMAIN: - op = "domain exists"; - position = 1; - break; - case ADD: - op = "add"; - position = 0; - ttlp = 1; - break; - case DELETE: - op = "delete"; - position = 0; - break; - default: - op = "unknown"; - position = 0; - break; - } - if (!position) { - if (s != &obuf [0] && s + 1 < end) - *s++ = ' '; - if (s + strlen (op) < end) { - strcpy (s, op); - s += strlen (s); - } - } else { - if (s != &obuf [0] && s + 1 < end) - *s++ = ' '; - if (s + strlen (predicate) < end) { - strcpy (s, predicate); - s += strlen (s); - } - predicate = "and"; - } - if (u -> r_dname) { - if (s + 1 < end) - *s++ = ' '; - if (s + strlen (u -> r_dname) < end) { - strcpy (s, u -> r_dname); - s += strlen (s); - } - } - if (ttlp) { - if (s + 1 < end) - *s++ = ' '; - /* 27 is as big as a ttl can get. */ - if (s + 27 < end) { - sprintf (s, "%lu", - (unsigned long)(u -> r_ttl)); - s += strlen (s); - } - } - switch (u -> r_class) { - case C_IN: - en = "IN"; - break; - case C_CHAOS: - en = "CHAOS"; - break; - case C_HS: - en = "HS"; - break; - default: - en = "UNKNOWN"; - break; - } - if (s + strlen (en) < end) { - if (s + 1 < end) - *s++ = ' '; - strcpy (s, en); - s += strlen (en); - } - switch (u -> r_type) { - case T_A: - en = "A"; - break; - case T_AAAA: - en = "AAAA"; - break; - case T_PTR: - en = "PTR"; - break; - case T_MX: - en = "MX"; - break; - case T_TXT: - en = "TXT"; - break; - case T_KEY: - en = "KEY"; - break; - case T_CNAME: - en = "CNAME"; - break; - default: - en = "UNKNOWN"; - break; - } - if (s + strlen (en) < end) { - if (s + 1 < end) - *s++ = ' '; - strcpy (s, en); - s += strlen (en); - } - if (u -> r_data) { - if (s + 1 < end) - *s++ = ' '; - if (u -> r_type == T_TXT) { - if (s + 1 < end) - *s++ = '"'; - } - if(u->r_type == T_KEY) { - strcat(s, ""); - s+=strlen(""); - } - else { - if (s + u -> r_size < end) { - memcpy (s, u -> r_data, u -> r_size); - s += u -> r_size; - if (u -> r_type == T_TXT) { - if (s + 1 < end) - *s++ = '"'; - } - } - } - } - if (position) { - if (s + 1 < end) - *s++ = ' '; - if (s + strlen (op) < end) { - strcpy (s, op); - s += strlen (s); - } - } - if (u == ISC_LIST_TAIL (*uq)) - break; - } - if (s == &obuf [0]) { - strcpy (s, "empty update"); - s += strlen (s); - } - if (status == NOERROR) - errorp = 0; - else - errorp = 1; - en = isc_result_totext (status); -#if 0 - switch (status) { - case -1: - en = "resolver failed"; - break; - - case FORMERR: - en = "format error"; - break; - - case NOERROR: - en = "succeeded"; - errorp = 0; - break; - - case NOTAUTH: - en = "not authorized"; - break; - - case NOTIMP: - en = "not implemented"; - break; - - case NOTZONE: - en = "not a single valid zone"; - break; - - case NXDOMAIN: - en = "no such domain"; - break; - - case NXRRSET: - en = "no such record"; - break; - - case REFUSED: - en = "refused"; - break; - - case SERVFAIL: - en = "server failed"; - break; - - case YXDOMAIN: - en = "domain exists"; - break; - - case YXRRSET: - en = "record exists"; - break; - - default: - en = "unknown error"; - break; - } -#endif - - if (s + 2 < end) { - *s++ = ':'; - *s++ = ' '; - } - if (s + strlen (en) < end) { - strcpy (s, en); - s += strlen (en); - } - if (s + 1 < end) - *s++ = '.'; - *s++ = 0; - if (errorp) - log_error ("%s", obuf); - else - log_info ("%s", obuf); -} -#endif +/* + * Place holder for debug information for ddns. + * + */ #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 21095bfa8..0c7037d7a 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -1844,6 +1844,9 @@ void parse_server_duid_conf(struct parse *cfile); int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *); int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *); +#if defined (TRACING) +void trace_ddns_init(void); +#endif /* parse.c */ void add_enumeration (struct enumeration *); diff --git a/includes/omapip/omapip_p.h b/includes/omapip/omapip_p.h index 03b40ed94..6376cdfa4 100644 --- a/includes/omapip/omapip_p.h +++ b/includes/omapip/omapip_p.h @@ -278,8 +278,6 @@ void omapi_connection_trace_setup (void); void omapi_buffer_trace_setup (void); void omapi_connection_register (omapi_connection_object_t *, const char *, int); -void trace_mr_init (void); - OMAPI_ARRAY_TYPE_DECL(omapi_listener, omapi_listener_object_t); OMAPI_ARRAY_TYPE_DECL(omapi_connection, omapi_connection_object_t); diff --git a/omapip/Makefile.am b/omapip/Makefile.am index 60aecf7f7..595950adb 100644 --- a/omapip/Makefile.am +++ b/omapip/Makefile.am @@ -4,7 +4,7 @@ noinst_PROGRAMS = svtest libomapi_a_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \ errwarn.c listener.c dispatch.c generic.c support.c \ handle.c message.c convert.c hash.c auth.c inet_addr.c \ - array.c trace.c mrtrace.c toisc.c iscprint.c isclib.c + array.c trace.c toisc.c iscprint.c isclib.c man_MANS = omapi.3 EXTRA_DIST = $(man_MANS) diff --git a/omapip/mrtrace.c b/omapip/mrtrace.c index e180472c3..e69de29bb 100644 --- a/omapip/mrtrace.c +++ b/omapip/mrtrace.c @@ -1,482 +0,0 @@ -/* mrtrace.c - - Subroutines that support minires tracing... */ - -/* - * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 2001-2003 by Internet Software Consortium - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Internet Systems Consortium, Inc. - * 950 Charter Street - * Redwood City, CA 94063 - * - * https://www.isc.org/ - * - * This software has been written for Internet Systems Consortium - * by Ted Lemon, as part of a project for Nominum, Inc. To learn more - * about Internet Systems Consortium, see https://www.isc.org/. To - * learn more about Nominum, Inc., see ``http://www.nominum.com''. - */ - -#include "dhcpd.h" -#include - -#include "minires.h" -#include "arpa/nameser.h" - -#include - -#if defined(TRACING) -static void trace_mr_output_input (trace_type_t *, unsigned, char *); -static void trace_mr_output_stop (trace_type_t *); -static void trace_mr_input_input (trace_type_t *, unsigned, char *); -static void trace_mr_input_stop (trace_type_t *); -static void trace_mr_statp_input (trace_type_t *, unsigned, char *); -static void trace_mr_statp_stop (trace_type_t *); -static void trace_mr_randomid_input (trace_type_t *, unsigned, char *); -static void trace_mr_randomid_stop (trace_type_t *); -#endif /* TRACING */ -trace_type_t *trace_mr_output; -trace_type_t *trace_mr_input; -trace_type_t *trace_mr_statp; -trace_type_t *trace_mr_randomid; -ssize_t trace_mr_send (int, void *, size_t, int); -ssize_t trace_mr_read_playback (struct sockaddr_in *, void *, size_t); -void trace_mr_read_record (struct sockaddr_in *, void *, ssize_t); -ssize_t trace_mr_recvfrom (int s, void *, size_t, int, - struct sockaddr *, SOCKLEN_T *); -ssize_t trace_mr_read (int, void *, size_t); -int trace_mr_connect (int s, struct sockaddr *, SOCKLEN_T); -int trace_mr_socket (int, int, int); -int trace_mr_bind (int, struct sockaddr *, SOCKLEN_T); -int trace_mr_close (int); -time_t trace_mr_time (time_t *); -int trace_mr_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); -unsigned int trace_mr_res_randomid (unsigned int); - -#if defined (TRACING) -void trace_mr_init () -{ - trace_mr_output = trace_type_register ("mr-output", (void *)0, - trace_mr_output_input, - trace_mr_output_stop, MDL); - trace_mr_input = trace_type_register ("mr-input", (void *)0, - trace_mr_input_input, - trace_mr_input_stop, MDL); - trace_mr_statp = trace_type_register ("mr-statp", (void *)0, - trace_mr_statp_input, - trace_mr_statp_stop, MDL); - trace_mr_randomid = trace_type_register ("mr-randomid", (void *)0, - trace_mr_randomid_input, - trace_mr_randomid_stop, MDL); -} - -#if 0 -void trace_mr_statp_setup (res_state statp) -{ - unsigned buflen = 0; - char *buf = (char *)0; - isc_result_t status; - int i; - - if (trace_playback ()) { - int nscount; - status = trace_get_packet (&trace_mr_statp, &buflen, &buf); - if (status != ISC_R_SUCCESS) { - log_error ("trace_mr_statp: no statp packet found."); - return; - } - nscount = buflen / sizeof (struct in_addr); - if (nscount * (sizeof (struct in_addr)) != buflen || - nscount < 1) { - log_error ("trace_mr_statp: bogus length: %d", - buflen); - return; - } - if (nscount > MAXNS) - nscount = MAXNS; - for (i = 0; i < nscount; i++) { -#if defined (HAVE_SA_LEN) - statp -> nsaddr_list [i].sin_len = - sizeof (struct sockaddr_in); -#endif - memset (&statp -> nsaddr_list [i].sin_zero, 0, - sizeof statp -> nsaddr_list [i].sin_zero); - statp -> nsaddr_list [i].sin_port = htons (53); /*XXX*/ - statp -> nsaddr_list [i].sin_family = AF_INET; - memcpy (&statp -> nsaddr_list [i].sin_addr, - (buf + i * (sizeof (struct in_addr))), - sizeof (struct in_addr)); - } - statp -> nscount = nscount; - dfree (buf, MDL); - buf = (char *)0; - } - if (trace_record ()) { - trace_iov_t *iov; - iov = dmalloc ((statp -> nscount * - sizeof (trace_iov_t)), MDL); - if (!iov) { - trace_stop (); - log_error ("No memory for statp iov."); - return; - } - for (i = 0; i < statp -> nscount; i++) { - iov [i].buf = - (char *)&statp -> nsaddr_list [i].sin_addr; - iov [i].len = sizeof (struct in_addr); - } - trace_write_packet_iov (trace_mr_statp, i, iov, MDL); - dfree (iov, MDL); - } -} -#endif -#endif - -ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags) -{ - ssize_t rv; -#if defined (TRACING) - isc_result_t status; - unsigned buflen = 0; - char *inbuf = (char *)0; - u_int32_t result; - u_int32_t sflags; - - if (trace_playback()) { - status = trace_get_packet (&trace_mr_output, &buflen, &inbuf); - if (status != ISC_R_SUCCESS) { - log_error ("trace_mr_recvfrom: no input found."); - errno = ECONNREFUSED; - return -1; - } - if (buflen < sizeof result) { - log_error ("trace_mr_recvfrom: data too short."); - errno = ECONNREFUSED; - dfree (inbuf, MDL); - return -1; - } - memcpy (&result, inbuf, sizeof result); - rv = ntohl (result); - dfree (inbuf, MDL); - } else -#endif - rv = send (fd, msg, len, flags); -#if defined (TRACING) - if (trace_record ()) { - trace_iov_t iov [3]; - result = htonl (rv); - sflags = htonl (flags); - iov [0].len = sizeof result; - iov [0].buf = (char *)&result; - iov [1].len = sizeof sflags; - iov [1].buf = (char *)&flags; - iov [2].len = len; - iov [2].buf = msg; - trace_write_packet_iov (trace_mr_output, 3, iov, MDL); - } -#endif - return rv; -} - -#if defined (TRACING) -ssize_t trace_mr_read_playback (struct sockaddr_in *from, - void *buf, size_t nbytes) -{ - isc_result_t status; - unsigned buflen = 0, left; - char *inbuf = (char *)0; - char *bufp; - u_int32_t result; - - status = trace_get_packet (&trace_mr_input, &buflen, &inbuf); - if (status != ISC_R_SUCCESS) { - log_error ("trace_mr_recvfrom: no input found."); - errno = ECONNREFUSED; - return -1; - } - if (buflen < sizeof result) { - log_error ("trace_mr_recvfrom: data too short."); - errno = ECONNREFUSED; - dfree (inbuf, MDL); - return -1; - } - bufp = inbuf; - left = buflen; - memcpy (&result, bufp, sizeof result); - result = ntohl (result); - bufp += sizeof result; - left -= sizeof result; - if (result == 0) { - if (left < ((sizeof from -> sin_port) + - sizeof (from -> sin_addr))) { - log_error ("trace_mr_recvfrom: data too short."); - errno = ECONNREFUSED; - dfree (inbuf, MDL); - return -1; - } - if (from) - memcpy (&from -> sin_addr, bufp, - sizeof from -> sin_addr); - bufp += sizeof from -> sin_addr; - left -= sizeof from -> sin_addr; - if (from) - memcpy (&from -> sin_port, bufp, - sizeof from -> sin_port); - bufp += sizeof from -> sin_port; - left -= sizeof from -> sin_port; - if (from) { - from -> sin_family = AF_INET; -#if defined(HAVE_SA_LEN) - from -> sin_len = sizeof (struct sockaddr_in); -#endif - memset (from -> sin_zero, 0, sizeof from -> sin_zero); - } - if (left > nbytes) { - log_error ("trace_mr_recvfrom: too much%s", - " data."); - errno = ECONNREFUSED; - dfree (inbuf, MDL); - return -1; - } - memcpy (buf, bufp, left); - dfree (inbuf, MDL); - return left; - } - errno = ECONNREFUSED; - return -1; -} - -void trace_mr_read_record (struct sockaddr_in *from, void *buf, ssize_t rv) -{ - trace_iov_t iov [4]; - u_int32_t result; - int iolen = 0; - static char zero [4] = { 0, 0, 0, 0 }; - - if (rv < 0) - result = htonl (errno); /* XXX */ - else - result = 0; - iov [iolen].buf = (char *)&result; - iov [iolen++].len = sizeof result; - if (rv > 0) { - if (from) { - iov [iolen].buf = (char *)&from -> sin_addr; - iov [iolen++].len = sizeof from -> sin_addr; - iov [iolen].buf = (char *)&from -> sin_port; - iov [iolen++].len = sizeof from -> sin_port; - } else { - iov [iolen].buf = zero; - iov [iolen++].len = sizeof from -> sin_addr; - iov [iolen].buf = zero; - iov [iolen++].len = sizeof from -> sin_port; - } - - iov [iolen].buf = buf; - iov [iolen++].len = rv; - } - trace_write_packet_iov (trace_mr_input, iolen, iov, MDL); -} -#endif - -ssize_t trace_mr_recvfrom (int s, void *buf, size_t len, int flags, - struct sockaddr *from, SOCKLEN_T *fromlen) -{ - ssize_t rv; - -#if defined (TRACING) - if (trace_playback ()) - rv = trace_mr_read_playback ((struct sockaddr_in *)from, - buf, len); - else -#endif - rv = recvfrom (s, buf, len, flags, from, fromlen); -#if defined (TRACING) - if (trace_record ()) { - trace_mr_read_record ((struct sockaddr_in *)from, buf, rv); - } -#endif - return rv; -} - -ssize_t trace_mr_read (int d, void *buf, size_t nbytes) -{ - ssize_t rv; - -#if defined (TRACING) - if (trace_playback ()) - rv = trace_mr_read_playback ((struct sockaddr_in *)0, - buf, nbytes); - else -#endif - rv = read (d, buf, nbytes); -#if defined (TRACING) - if (trace_record ()) { - trace_mr_read_record ((struct sockaddr_in *)0, buf, rv); - } -#endif - return rv; -} - -int trace_mr_connect (int s, struct sockaddr *name, SOCKLEN_T namelen) -{ -#if defined (TRACING) - if (!trace_playback ()) -#endif - return connect (s, name, namelen); -#if defined (TRACING) - return 0; -#endif -} - -int trace_mr_socket (int domain, int type, int protocol) -{ -#if defined (TRACING) - if (!trace_playback ()) -#endif - return socket (domain, type, protocol); -#if defined (TRACING) - return 100; -#endif -} - -int trace_mr_bind (int s, struct sockaddr *name, SOCKLEN_T namelen) -{ -#if defined (TRACING) - if (!trace_playback ()) -#endif - return bind (s, name, namelen); -#if defined (TRACING) - return 0; -#endif -} - -int trace_mr_close (int s) -{ -#if defined (TRACING) - if (!trace_playback ()) -#endif - return close (s); -#if defined (TRACING) - return 0; -#endif -} - -time_t trace_mr_time (time_t *tp) -{ -#if defined (TRACING) - if (trace_playback ()) { - if (tp) - *tp = cur_time; - return cur_time; - } -#endif - return time (tp); -} - -int trace_mr_select (int s, fd_set *r, fd_set *w, fd_set *x, struct timeval *t) -{ -#if defined (TRACING) - trace_type_t *ttp = (trace_type_t *)0; - - if (trace_playback ()) { - time_t nct = trace_snoop_time (&ttp); - time_t secr = t -> tv_sec; - t -> tv_sec = nct - cur_time; - if (t -> tv_sec > secr) - return 0; - if (ttp == trace_mr_input) - return 1; - return 0; - } -#endif - return select (s, r, w, x, t); -} - -unsigned int trace_mr_res_randomid (unsigned int oldid) -{ - int rid = oldid; -#if defined (TRACING) - u_int32_t id; - unsigned buflen = 0; - char *buf = (char *)0; - isc_result_t status; - - if (trace_playback ()) { - status = trace_get_packet (&trace_mr_randomid, &buflen, &buf); - if (status != ISC_R_SUCCESS) { - log_error ("trace_mr_statp: no statp packet found."); - return oldid; - } - if (buflen != sizeof id) { - log_error ("trace_mr_randomid: bogus length: %d", - buflen); - return oldid; - } - memcpy (&id, buf, sizeof id); - dfree (buf, MDL); - buf = (char *)0; - rid = ntohl (id); - } - if (trace_record ()) { - id = htonl (rid); - trace_write_packet (trace_mr_randomid, - sizeof id, (char *)&id, MDL); - } -#endif - return rid; -} - -#if defined (TRACING) -static void trace_mr_output_input (trace_type_t *ttype, - unsigned length, char *buf) -{ -} - -static void trace_mr_output_stop (trace_type_t *ttype) -{ -} - -static void trace_mr_input_input (trace_type_t *ttype, - unsigned length, char *buf) -{ - log_error ("unaccounted-for minires input."); -} - -static void trace_mr_input_stop (trace_type_t *ttype) -{ -} - -static void trace_mr_statp_input (trace_type_t *ttype, - unsigned length, char *buf) -{ - log_error ("unaccounted-for minires statp input."); -} - -static void trace_mr_statp_stop (trace_type_t *ttype) -{ -} - -static void trace_mr_randomid_input (trace_type_t *ttype, - unsigned length, char *buf) -{ - log_error ("unaccounted-for minires randomid input."); -} - -static void trace_mr_randomid_stop (trace_type_t *ttype) -{ -} -#endif diff --git a/omapip/support.c b/omapip/support.c index b3ab2d571..c82dcc8c3 100644 --- a/omapip/support.c +++ b/omapip/support.c @@ -190,7 +190,6 @@ isc_result_t omapi_init (void) omapi_listener_trace_setup (); omapi_connection_trace_setup (); omapi_buffer_trace_setup (); - trace_mr_init (); #endif /* This seems silly, but leave it. */ diff --git a/server/ddns.c b/server/ddns.c index 7ea409a42..b196147e0 100644 --- a/server/ddns.c +++ b/server/ddns.c @@ -775,75 +775,6 @@ ddns_update_lease_text(dhcp_ddns_cb_t *ddns_cb, return(ISC_R_SUCCESS); } - -#if 0 -isc_result_t -ddns_get_lease(dhcp_ddns_cb_t *ddns_cb) -{ - isc_result_t result = ISC_R_FAILURE; - - if (ddns_cb->address.len == 4) { - struct lease **lease = (struct lease **)(&(ddns_cb->lease)); - if (find_lease_by_ip_addr(lease, ddns_cb->address, MDL) != 0) { - ddns_cb->scope = &((*lease)->scope); - result = ISC_R_SUCCESS; - } - } - else if (ddns_cb->address.len == 16) { - struct ipv6_pool *pool = NULL; - struct iasubopt **lease = (struct iasubopt **)(&(ddns_cb->lease)); - struct in6_addr addr; - - memcpy(&addr, &ddns_cb->address.iabuf, 16); - if ((find_ipv6_pool(&pool, D6O_IA_TA, &addr) != - ISC_R_SUCCESS) && - (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != - ISC_R_SUCCESS)) { - return(ISC_R_FAILURE); - } - - if (iasubopt_hash_lookup(lease, pool->leases, - &addr, 16, MDL)) { - ddns_cb->scope = &((*lease)->scope); - result = ISC_R_SUCCESS; - } - ipv6_pool_dereference(&pool, MDL); - } - else { - log_fatal("Impossible condition at %s:%d.", MDL); - } - - return(result); -} - -isc_result_t -ddns_write_lease(dhcp_ddns_cb_t *ddns_cb) -{ - - if (ddns_cb->address.len == 4) { - struct lease **lease = (struct lease **)(&(ddns_cb->lease)); - - write_lease(*lease); - ddns_cb->scope = NULL; - lease_dereference(lease, MDL); - } - else if (ddns_cb->address.len == 16) { - struct iasubopt **lease = (struct iasubopt **)(&(ddns_cb->lease)); - /*sar*/ - /* Hmmm, this seems to be what we do elsewhere, but I'm - not sure this is writing the scope info */ - write_ia((*lease)->ia); - ddns_cb->scope = NULL; - iasubopt_dereference(lease, MDL); - } - else { - log_fatal("Impossible condition at %s:%d.", MDL); - } - - return(ISC_R_SUCCESS); -} -#endif - /* * Utility function to update the pointer to the DDNS control block * in a lease. @@ -913,7 +844,7 @@ ddns_ptr_add(dhcp_ddns_cb_t *ddns_cb, isc_result_t eresult) { if (eresult == ISC_R_SUCCESS) { - log_info("added reverse map from %.*s to %.*s", + log_info("Added reverse map from %.*s to %.*s", (int)ddns_cb->rev_name.len, (const char *)ddns_cb->rev_name.data, (int)ddns_cb->fwd_name.len, @@ -921,7 +852,7 @@ ddns_ptr_add(dhcp_ddns_cb_t *ddns_cb, ddns_update_lease_text(ddns_cb, NULL); } else { - log_error("unable to add reverse map from %.*s to %.*s: %s", + log_error("Unable to add reverse map from %.*s to %.*s: %s", (int)ddns_cb->rev_name.len, (const char *)ddns_cb->rev_name.data, (int)ddns_cb->fwd_name.len, @@ -960,7 +891,7 @@ ddns_ptr_remove(dhcp_ddns_cb_t *ddns_cb, switch(eresult) { case ISC_R_SUCCESS: - log_info("removed reverse map on %.*s", + log_info("Removed reverse map on %.*s", (int)ddns_cb->rev_name.len, (const char *)ddns_cb->rev_name.data); /* fall through */ @@ -976,7 +907,7 @@ ddns_ptr_remove(dhcp_ddns_cb_t *ddns_cb, break; default: - log_error("can't remove reverse map on %.*s: %s", + log_error("Can't remove reverse map on %.*s: %s", (int)ddns_cb->rev_name.len, (const char *)ddns_cb->rev_name.data, isc_result_totext (eresult)); @@ -1266,9 +1197,18 @@ ddns_fwd_srv_rem1(dhcp_ddns_cb_t *ddns_cb, isc_result_t eresult) { isc_result_t result = eresult; + char ddns_address[ + sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; switch(eresult) { case ISC_R_SUCCESS: + /* Construct a printable form of the address for logging */ + strcpy(ddns_address, piaddr(ddns_cb->address)); + log_info("Removed forward map from %.*s to %s", + (int)ddns_cb->fwd_name.len, + (const char*)ddns_cb->fwd_name.data, + ddns_address); + /* Do the second step of the FWD removal */ ddns_cb->state = DDNS_STATE_REM_FW_NXRR; ddns_cb->cur_func = ddns_fwd_srv_rem2; diff --git a/server/dhcpd.c b/server/dhcpd.c index 0bd8e1e7c..198436933 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -488,6 +488,7 @@ main(int argc, char **argv) { trace_srandom = trace_type_register ("random-seed", (void *)0, trace_seed_input, trace_seed_stop, MDL); + trace_ddns_init(); #endif #if defined (PARANOIA)