diff --git a/LICENSE b/LICENSE index 297a0571..10c0fbcb 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 ff8f5310..23fbddbe 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 56436421..fef2249f 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 2f7f998c..c7c84134 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 791dfb4b..f4dda136 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 21095bfa..0c7037d7 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 03b40ed9..6376cdfa 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 60aecf7f..595950ad 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 e180472c..e69de29b 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 b3ab2d57..c82dcc8c 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 7ea409a4..b196147e 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 0bd8e1e7..19843693 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)