⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* trace.c   Subroutines that support tracing of OMAPI wire transactions and   provide a mechanism for programs using OMAPI to trace their own   transactions... *//* * Copyright (c) 2004 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> *   http://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 http://www.isc.org/.  To * learn more about Nominum, Inc., see ``http://www.nominum.com''. */#include <omapip/omapip_p.h>#if defined (TRACING)void (*trace_set_time_hook) (u_int32_t);static int tracing_stopped;static int traceoutfile;static int traceindex;static trace_type_t **trace_types;static int trace_type_count;static int trace_type_max;static trace_type_t *new_trace_types;static FILE *traceinfile;static tracefile_header_t tracefile_header;static int trace_playback_flag;trace_type_t trace_time_marker;#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)extern omapi_array_t *trace_listeners;extern omapi_array_t *omapi_connections;void trace_free_all (){	trace_type_t *tp;	int i;	tp = new_trace_types;	while (tp) {		new_trace_types = tp -> next;		if (tp -> name) {			dfree (tp -> name, MDL);			tp -> name = (char *)0;		}		dfree (tp, MDL);		tp = new_trace_types;	}	for (i = 0; i < trace_type_count; i++) {		if (trace_types [i]) {			if (trace_types [i] -> name)				dfree (trace_types [i] -> name, MDL);			dfree (trace_types [i], MDL);		}	}	dfree (trace_types, MDL);	trace_types = (trace_type_t **)0;	trace_type_count = trace_type_max = 0;	omapi_array_free (&trace_listeners, MDL);	omapi_array_free (&omapi_connections, MDL);}#endifstatic isc_result_t trace_type_record (trace_type_t *,				       unsigned, const char *, int);int trace_playback (){	return trace_playback_flag;}int trace_record (){	if (traceoutfile && !tracing_stopped)		return 1;	return 0;}isc_result_t trace_init (void (*set_time) (u_int32_t),			 const char *file, int line){	trace_type_t *root_type;	static int root_setup = 0;	if (root_setup)		return ISC_R_SUCCESS;	trace_set_time_hook = set_time;	root_type = trace_type_register ("trace-index-mapping",					 (void *)0, trace_index_map_input,					 trace_index_stop_tracing, file, line);	if (!root_type)		return ISC_R_UNEXPECTED;	if (new_trace_types == root_type)		new_trace_types = new_trace_types -> next;	root_type -> index = 0;	trace_type_stash (root_type);	root_setup = 1;	return ISC_R_SUCCESS;}isc_result_t trace_begin (const char *filename,			  const char *file, int line){	tracefile_header_t tfh;	int status;	trace_type_t *tptr, *next;	isc_result_t result;	if (traceoutfile) {		log_error ("%s(%d): trace_begin called twice",			   file, line);		return ISC_R_INVALIDARG;	}	traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0644);	if (traceoutfile < 0) {		log_error ("%s(%d): trace_begin: %s: %m",			   file, line, filename);		return ISC_R_UNEXPECTED;	}#if defined (HAVE_SETFD)	if (fcntl (traceoutfile, F_SETFD, 1) < 0)		log_error ("Can't set close-on-exec on %s: %m", filename);#endif	tfh.magic = htonl (TRACEFILE_MAGIC);	tfh.version = htonl (TRACEFILE_VERSION);	tfh.hlen = htonl (sizeof (tracefile_header_t));	tfh.phlen = htonl (sizeof (tracepacket_t));		status = write (traceoutfile, &tfh, sizeof tfh);	if (status < 0) {		log_error ("%s(%d): trace_begin write failed: %m", file, line);		return ISC_R_UNEXPECTED;	} else if (status != sizeof tfh) {		log_error ("%s(%d): trace_begin: short write (%d:%ld)",			   file, line, status, (long)(sizeof tfh));		trace_stop ();		return ISC_R_UNEXPECTED;	}	/* Stash all the types that have already been set up. */	if (new_trace_types) {		next = new_trace_types;		new_trace_types = (trace_type_t *)0;		for (tptr = next; tptr; tptr = next) {			next = tptr -> next;			if (tptr -> index != 0) {				result = (trace_type_record					  (tptr,					   strlen (tptr -> name), file, line));				if (result != ISC_R_SUCCESS)					return status;			}		}	}		return ISC_R_SUCCESS;}isc_result_t trace_write_packet (trace_type_t *ttype, unsigned length,				 const char *buf, const char *file, int line){	trace_iov_t iov;	iov.buf = buf;	iov.len = length;	return trace_write_packet_iov (ttype, 1, &iov, file, line);}isc_result_t trace_write_packet_iov (trace_type_t *ttype,				     int count, trace_iov_t *iov,				     const char *file, int line){	tracepacket_t tmp;	int status;	int i;	int length;	/* Really shouldn't get called here, but it may be hard to turn off	   tracing midstream if the trace file write fails or something. */	if (tracing_stopped)		return 0;	if (!ttype) {		log_error ("%s(%d): trace_write_packet with null trace type",			   file ? file : "<unknown file>", line);		return ISC_R_INVALIDARG;	}	if (!traceoutfile) {		log_error ("%s(%d): trace_write_packet with no tracefile.",			   file ? file : "<unknown file>", line);		return ISC_R_INVALIDARG;	}		/* Compute the total length of the iov. */	length = 0;	for (i = 0; i < count; i++)		length += iov [i].len;	/* We have to swap out the data, because it may be read back on a	   machine of different endianness. */	tmp.type_index = htonl (ttype -> index);	tmp.when = htonl (time ((time_t *)0)); /* XXX */	tmp.length = htonl (length);	status = write (traceoutfile, &tmp, sizeof tmp);	if (status < 0) {		log_error ("%s(%d): trace_write_packet write failed: %m",			   file, line);		return ISC_R_UNEXPECTED;	} else if (status != sizeof tmp) {		log_error ("%s(%d): trace_write_packet: short write (%d:%ld)",			   file, line, status, (long)(sizeof tmp));		trace_stop ();	}	for (i = 0; i < count; i++) {		status = write (traceoutfile, iov [i].buf, iov [i].len);		if (status < 0) {			log_error ("%s(%d): %s write failed: %m",				   file, line, "trace_write_packet");			return ISC_R_UNEXPECTED;		} else if (status != iov [i].len) {			log_error ("%s(%d): %s: short write (%d:%d)",				   file, line,				   "trace_write_packet", status, length);			trace_stop ();		}	}	/* Write padding on the end of the packet to align the next	   packet to an 8-byte boundary.   This is in case we decide to	   use mmap in some clever way later on. */	if (length % 8) {	    static char zero [] = { 0, 0, 0, 0, 0, 0, 0 };	    unsigned padl = 8 - (length % 8);			    status = write (traceoutfile, zero, padl);	    if (status < 0) {		log_error ("%s(%d): trace_write_packet write failed: %m",			   file, line);		return ISC_R_UNEXPECTED;	    } else if (status != padl) {		log_error ("%s(%d): trace_write_packet: short write (%d:%d)",			   file, line, status, padl);		trace_stop ();	    }	}	return ISC_R_SUCCESS;}void trace_type_stash (trace_type_t *tptr){	trace_type_t **vec;	int delta;	if (trace_type_max <= tptr -> index) {		delta = tptr -> index - trace_type_max + 10;		vec = dmalloc (((trace_type_max + delta) *				sizeof (trace_type_t *)), MDL);		if (!vec)			return;		memset (&vec [trace_type_max], 0,			(sizeof (trace_type_t *)) * delta);		trace_type_max += delta;		if (trace_types) {		    memcpy (vec, trace_types,			    trace_type_count * sizeof (trace_type_t *));		    dfree (trace_types, MDL);		}		trace_types = vec;	}	trace_types [tptr -> index] = tptr;	if (tptr -> index >= trace_type_count)		trace_type_count = tptr -> index + 1;}trace_type_t *trace_type_register (const char *name,				   void *baggage,				   void (*have_packet) (trace_type_t *,							unsigned, char *),				   void (*stop_tracing) (trace_type_t *),				   const char *file, int line){	trace_type_t *ttmp, *tptr;	unsigned slen = strlen (name);	isc_result_t status;	ttmp = dmalloc (sizeof *ttmp, file, line);	if (!ttmp)		return ttmp;	ttmp -> index = -1;	ttmp -> name = dmalloc (slen + 1, file, line);	if (!ttmp -> name) {		dfree (ttmp, file, line);		return (trace_type_t *)0;	}	strcpy (ttmp -> name, name);	ttmp -> have_packet = have_packet;	ttmp -> stop_tracing = stop_tracing;		if (traceoutfile) {		status = trace_type_record (ttmp, slen, file, line);		if (status != ISC_R_SUCCESS) {			dfree (ttmp -> name, file, line);			dfree (ttmp, file, line);			return (trace_type_t *)0;		}	} else {		ttmp -> next = new_trace_types;		new_trace_types = ttmp;	}	return ttmp;}						   static isc_result_t trace_type_record (trace_type_t *ttmp, unsigned slen,				       const char *file, int line){	trace_index_mapping_t *tim;	isc_result_t status;	tim = dmalloc (slen + TRACE_INDEX_MAPPING_SIZE, file, line);	if (!tim)		return ISC_R_NOMEMORY;	ttmp -> index = ++traceindex;	trace_type_stash (ttmp);	tim -> index = htonl (ttmp -> index);	memcpy (tim -> name, ttmp -> name, slen);	status = trace_write_packet (trace_types [0],

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -