2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00

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.
This commit is contained in:
Shawn Routhier 2010-02-11 23:55:36 +00:00
parent fdfebedf3e
commit 7aa153b882
12 changed files with 380 additions and 828 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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, "<keydata>");
s+=strlen("<keydata>");
}
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

View File

@ -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 *);

View File

@ -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);

View File

@ -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)

View File

@ -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
* <info@isc.org>
* 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 <omapip/omapip_p.h>
#include "minires.h"
#include "arpa/nameser.h"
#include <errno.h>
#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

View File

@ -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. */

View File

@ -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;

View File

@ -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)