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

📄 message.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003  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. *//* $Id: message.c,v 1.194.2.10.2.17 2004/05/05 01:32:16 marka Exp $ *//*** *** Imports ***/#include <config.h>#include <isc/buffer.h>#include <isc/mem.h>#include <isc/print.h>#include <isc/string.h>		/* Required for HP/UX (and others?) */#include <isc/util.h>#include <dns/dnssec.h>#include <dns/keyvalues.h>#include <dns/log.h>#include <dns/masterdump.h>#include <dns/message.h>#include <dns/opcode.h>#include <dns/rdata.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatastruct.h>#include <dns/result.h>#include <dns/tsig.h>#include <dns/view.h>#define DNS_MESSAGE_OPCODE_MASK		0x7800U#define DNS_MESSAGE_OPCODE_SHIFT	11#define DNS_MESSAGE_RCODE_MASK		0x000fU#define DNS_MESSAGE_FLAG_MASK		0x8ff0U#define DNS_MESSAGE_EDNSRCODE_MASK	0xff000000U#define DNS_MESSAGE_EDNSRCODE_SHIFT	24#define DNS_MESSAGE_EDNSVERSION_MASK	0x00ff0000U#define DNS_MESSAGE_EDNSVERSION_SHIFT	16#define VALID_NAMED_SECTION(s)  (((s) > DNS_SECTION_ANY) \				 && ((s) < DNS_SECTION_MAX))#define VALID_SECTION(s)	(((s) >= DNS_SECTION_ANY) \				 && ((s) < DNS_SECTION_MAX))#define ADD_STRING(b, s)	{if (strlen(s) >= \				   isc_buffer_availablelength(b)) \				       return(ISC_R_NOSPACE); else \				       isc_buffer_putstr(b, s);}#define VALID_PSEUDOSECTION(s)	(((s) >= DNS_PSEUDOSECTION_ANY) \				 && ((s) < DNS_PSEUDOSECTION_MAX))/* * This is the size of each individual scratchpad buffer, and the numbers * of various block allocations used within the server. * XXXMLG These should come from a config setting. */#define SCRATCHPAD_SIZE		512#define NAME_COUNT		  8#define OFFSET_COUNT		  4#define RDATA_COUNT		  8#define RDATALIST_COUNT		  8#define RDATASET_COUNT		 RDATALIST_COUNT/* * Text representation of the different items, for message_totext * functions. */static const char *sectiontext[] = {	"QUESTION",	"ANSWER",	"AUTHORITY",	"ADDITIONAL"};static const char *updsectiontext[] = {	"ZONE",	"PREREQUISITE",	"UPDATE",	"ADDITIONAL"};static const char *opcodetext[] = {	"QUERY",	"IQUERY",	"STATUS",	"RESERVED3",	"NOTIFY",	"UPDATE",	"RESERVED6",	"RESERVED7",	"RESERVED8",	"RESERVED9",	"RESERVED10",	"RESERVED11",	"RESERVED12",	"RESERVED13",	"RESERVED14",	"RESERVED15"};static const char *rcodetext[] = {	"NOERROR",	"FORMERR",	"SERVFAIL",	"NXDOMAIN",	"NOTIMP",	"REFUSED",	"YXDOMAIN",	"YXRRSET",	"NXRRSET",	"NOTAUTH",	"NOTZONE",	"RESERVED11",	"RESERVED12",	"RESERVED13",	"RESERVED14",	"RESERVED15",	"BADVERS"};/* * "helper" type, which consists of a block of some type, and is linkable. * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer * size, or the allocated elements will not be alligned correctly. */struct dns_msgblock {	unsigned int			count;	unsigned int			remaining;	ISC_LINK(dns_msgblock_t)	link;}; /* dynamically sized */static inline dns_msgblock_t *msgblock_allocate(isc_mem_t *, unsigned int, unsigned int);#define msgblock_get(block, type) \	((type *)msgblock_internalget(block, sizeof(type)))static inline void *msgblock_internalget(dns_msgblock_t *, unsigned int);static inline voidmsgblock_reset(dns_msgblock_t *);static inline voidmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);/* * Allocate a new dns_msgblock_t, and return a pointer to it.  If no memory * is free, return NULL. */static inline dns_msgblock_t *msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,		  unsigned int count){	dns_msgblock_t *block;	unsigned int length;	length = sizeof(dns_msgblock_t) + (sizeof_type * count);	block = isc_mem_get(mctx, length);	if (block == NULL)		return (NULL);	block->count = count;	block->remaining = count;	ISC_LINK_INIT(block, link);	return (block);}/* * Return an element from the msgblock.  If no more are available, return * NULL. */static inline void *msgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {	void *ptr;	if (block == NULL || block->remaining == 0)		return (NULL);	block->remaining--;	ptr = (((unsigned char *)block)	       + sizeof(dns_msgblock_t)	       + (sizeof_type * block->remaining));	return (ptr);}static inline voidmsgblock_reset(dns_msgblock_t *block) {	block->remaining = block->count;}/* * Release memory associated with a message block. */static inline voidmsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type){	unsigned int length;	length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);	isc_mem_put(mctx, block, length);}/* * Allocate a new dynamic buffer, and attach it to this message as the * "current" buffer.  (which is always the last on the list, for our * uses) */static inline isc_result_tnewbuffer(dns_message_t *msg, unsigned int size) {	isc_result_t result;	isc_buffer_t *dynbuf;	dynbuf = NULL;	result = isc_buffer_allocate(msg->mctx, &dynbuf, size);	if (result != ISC_R_SUCCESS)		return (ISC_R_NOMEMORY);	ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);	return (ISC_R_SUCCESS);}static inline isc_buffer_t *currentbuffer(dns_message_t *msg) {	isc_buffer_t *dynbuf;	dynbuf = ISC_LIST_TAIL(msg->scratchpad);	INSIST(dynbuf != NULL);	return (dynbuf);}static inline voidreleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {	ISC_LIST_PREPEND(msg->freerdata, rdata, link);}static inline dns_rdata_t *newrdata(dns_message_t *msg) {	dns_msgblock_t *msgblock;	dns_rdata_t *rdata;	rdata = ISC_LIST_HEAD(msg->freerdata);	if (rdata != NULL) {		ISC_LIST_UNLINK(msg->freerdata, rdata, link);		return (rdata);	}	msgblock = ISC_LIST_TAIL(msg->rdatas);	rdata = msgblock_get(msgblock, dns_rdata_t);	if (rdata == NULL) {		msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),					     RDATA_COUNT);		if (msgblock == NULL)			return (NULL);		ISC_LIST_APPEND(msg->rdatas, msgblock, link);		rdata = msgblock_get(msgblock, dns_rdata_t);	}	dns_rdata_init(rdata);	return (rdata);}static inline voidreleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {	ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);}static inline dns_rdatalist_t *newrdatalist(dns_message_t *msg) {	dns_msgblock_t *msgblock;	dns_rdatalist_t *rdatalist;	rdatalist = ISC_LIST_HEAD(msg->freerdatalist);	if (rdatalist != NULL) {		ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);		return (rdatalist);	}	msgblock = ISC_LIST_TAIL(msg->rdatalists);	rdatalist = msgblock_get(msgblock, dns_rdatalist_t);	if (rdatalist == NULL) {		msgblock = msgblock_allocate(msg->mctx,					     sizeof(dns_rdatalist_t),					     RDATALIST_COUNT);		if (msgblock == NULL)			return (NULL);		ISC_LIST_APPEND(msg->rdatalists, msgblock, link);		rdatalist = msgblock_get(msgblock, dns_rdatalist_t);	}	return (rdatalist);}static inline dns_offsets_t *newoffsets(dns_message_t *msg) {	dns_msgblock_t *msgblock;	dns_offsets_t *offsets;	msgblock = ISC_LIST_TAIL(msg->offsets);	offsets = msgblock_get(msgblock, dns_offsets_t);	if (offsets == NULL) {		msgblock = msgblock_allocate(msg->mctx,					     sizeof(dns_offsets_t),					     OFFSET_COUNT);		if (msgblock == NULL)			return (NULL);		ISC_LIST_APPEND(msg->offsets, msgblock, link);		offsets = msgblock_get(msgblock, dns_offsets_t);	}	return (offsets);}static inline voidmsginitheader(dns_message_t *m) {	m->id = 0;	m->flags = 0;	m->rcode = 0;	m->opcode = 0;	m->rdclass = 0;}static inline voidmsginitprivate(dns_message_t *m) {	unsigned int i;	for (i = 0; i < DNS_SECTION_MAX; i++) {		m->cursors[i] = NULL;		m->counts[i] = 0;	}	m->opt = NULL;	m->sig0 = NULL;	m->sig0name = NULL;	m->tsig = NULL;	m->tsigname = NULL;	m->state = DNS_SECTION_ANY;  /* indicate nothing parsed or rendered */	m->opt_reserved = 0;	m->sig_reserved = 0;	m->reserved = 0;	m->buffer = NULL;}static inline voidmsginittsig(dns_message_t *m) {	m->tsigstatus = dns_rcode_noerror;	m->querytsigstatus = dns_rcode_noerror;	m->tsigkey = NULL;	m->tsigctx = NULL;	m->sigstart = -1;	m->sig0key = NULL;	m->sig0status = dns_rcode_noerror;	m->timeadjust = 0;}/* * Init elements to default state.  Used both when allocating a new element * and when resetting one. */static inline voidmsginit(dns_message_t *m) {	msginitheader(m);	msginitprivate(m);	msginittsig(m);	m->header_ok = 0;	m->question_ok = 0;	m->tcp_continuation = 0;	m->verified_sig = 0;	m->verify_attempted = 0;	m->order = NULL;	m->order_arg = NULL;	m->query.base = NULL;	m->query.length = 0;	m->free_query = 0;	m->saved.base = NULL;	m->saved.length = 0;	m->free_saved = 0;	m->querytsig = NULL;}static inline voidmsgresetnames(dns_message_t *msg, unsigned int first_section) {	unsigned int i;	dns_name_t *name, *next_name;	dns_rdataset_t *rds, *next_rds;	/*	 * Clean up name lists by calling the rdataset disassociate function.	 */	for (i = first_section; i < DNS_SECTION_MAX; i++) {		name = ISC_LIST_HEAD(msg->sections[i]);		while (name != NULL) {			next_name = ISC_LIST_NEXT(name, link);			ISC_LIST_UNLINK(msg->sections[i], name, link);			rds = ISC_LIST_HEAD(name->list);			while (rds != NULL) {				next_rds = ISC_LIST_NEXT(rds, link);				ISC_LIST_UNLINK(name->list, rds, link);				INSIST(dns_rdataset_isassociated(rds));				dns_rdataset_disassociate(rds);				isc_mempool_put(msg->rdspool, rds);				rds = next_rds;			}			if (dns_name_dynamic(name))				dns_name_free(name, msg->mctx);			isc_mempool_put(msg->namepool, name);			name = next_name;		}	}}static voidmsgresetopt(dns_message_t *msg){	if (msg->opt != NULL) {		if (msg->opt_reserved > 0) {			dns_message_renderrelease(msg, msg->opt_reserved);			msg->opt_reserved = 0;		}		INSIST(dns_rdataset_isassociated(msg->opt));		dns_rdataset_disassociate(msg->opt);		isc_mempool_put(msg->rdspool, msg->opt);		msg->opt = NULL;	}}static voidmsgresetsigs(dns_message_t *msg, isc_boolean_t replying) {	if (msg->sig_reserved > 0) {		dns_message_renderrelease(msg, msg->sig_reserved);		msg->sig_reserved = 0;	}	if (msg->tsig != NULL) {		INSIST(dns_rdataset_isassociated(msg->tsig));		INSIST(msg->namepool != NULL);		if (replying) {			INSIST(msg->querytsig == NULL);			msg->querytsig = msg->tsig;		} else {			dns_rdataset_disassociate(msg->tsig);			isc_mempool_put(msg->rdspool, msg->tsig);			if (msg->querytsig != NULL) {				dns_rdataset_disassociate(msg->querytsig);				isc_mempool_put(msg->rdspool, msg->querytsig);			}		}		if (dns_name_dynamic(msg->tsigname))			dns_name_free(msg->tsigname, msg->mctx);		isc_mempool_put(msg->namepool, msg->tsigname);		msg->tsig = NULL;		msg->tsigname = NULL;	} else if (msg->querytsig != NULL && !replying) {		dns_rdataset_disassociate(msg->querytsig);		isc_mempool_put(msg->rdspool, msg->querytsig);		msg->querytsig = NULL;	}	if (msg->sig0 != NULL) {		INSIST(dns_rdataset_isassociated(msg->sig0));		dns_rdataset_disassociate(msg->sig0);		isc_mempool_put(msg->rdspool, msg->sig0);		if (msg->sig0name != NULL) {			if (dns_name_dynamic(msg->sig0name))				dns_name_free(msg->sig0name, msg->mctx);			isc_mempool_put(msg->namepool, msg->sig0name);		}		msg->sig0 = NULL;		msg->sig0name = NULL;	}}/* * Free all but one (or everything) for this message.  This is used by * both dns_message_reset() and dns_message_destroy(). */static voidmsgreset(dns_message_t *msg, isc_boolean_t everything) {	dns_msgblock_t *msgblock, *next_msgblock;	isc_buffer_t *dynbuf, *next_dynbuf;	dns_rdata_t *rdata;	dns_rdatalist_t *rdatalist;	msgresetnames(msg, 0);	msgresetopt(msg);	msgresetsigs(msg, ISC_FALSE);	/*	 * Clean up linked lists.	 */	/*	 * Run through the free lists, and just unlink anything found there.	 * The memory isn't lost since these are part of message blocks we	 * have allocated.	 */	rdata = ISC_LIST_HEAD(msg->freerdata);	while (rdata != NULL) {		ISC_LIST_UNLINK(msg->freerdata, rdata, link);		rdata = ISC_LIST_HEAD(msg->freerdata);	}	rdatalist = ISC_LIST_HEAD(msg->freerdatalist);

⌨️ 快捷键说明

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