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

📄 message.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
		ISC_LIST_INIT(rdatalist->rdata);		dns_rdataset_init(rdataset);		result = dns_rdatalist_tordataset(rdatalist, rdataset);		if (result != ISC_R_SUCCESS)			goto cleanup;		rdataset->attributes |= DNS_RDATASETATTR_QUESTION;		ISC_LIST_APPEND(name->list, rdataset, link);		rdataset = NULL;	}	if (seen_problem)		return (DNS_R_RECOVERABLE);	return (ISC_R_SUCCESS); cleanup:	if (rdataset != NULL) {		INSIST(!dns_rdataset_isassociated(rdataset));		isc_mempool_put(msg->rdspool, rdataset);	}#if 0	if (rdatalist != NULL)		isc_mempool_put(msg->rdlpool, rdatalist);#endif	if (free_name)		isc_mempool_put(msg->namepool, name);	return (result);}static isc_boolean_tupdate(dns_section_t section, dns_rdataclass_t rdclass) {	if (section == DNS_SECTION_PREREQUISITE)		return (ISC_TF(rdclass == dns_rdataclass_any ||			       rdclass == dns_rdataclass_none));	if (section == DNS_SECTION_UPDATE)		return (ISC_TF(rdclass == dns_rdataclass_any));	return (ISC_FALSE);}static isc_result_tgetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,	   dns_section_t sectionid, unsigned int options){	isc_region_t r;	unsigned int count, rdatalen;	dns_name_t *name;	dns_name_t *name2;	dns_offsets_t *offsets;	dns_rdataset_t *rdataset;	dns_rdatalist_t *rdatalist;	isc_result_t result;	dns_rdatatype_t rdtype, covers;	dns_rdataclass_t rdclass;	dns_rdata_t *rdata;	dns_ttl_t ttl;	dns_namelist_t *section;	isc_boolean_t free_name, free_rdataset;	isc_boolean_t preserve_order, best_effort, seen_problem;	isc_boolean_t issigzero;	preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);	best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);	seen_problem = ISC_FALSE;	for (count = 0; count < msg->counts[sectionid]; count++) {		int recstart = source->current;		isc_boolean_t skip_name_search, skip_type_search;		section = &msg->sections[sectionid];		skip_name_search = ISC_FALSE;		skip_type_search = ISC_FALSE;		free_name = ISC_FALSE;		free_rdataset = ISC_FALSE;		name = isc_mempool_get(msg->namepool);		if (name == NULL)			return (ISC_R_NOMEMORY);		free_name = ISC_TRUE;		offsets = newoffsets(msg);		if (offsets == NULL) {			result = ISC_R_NOMEMORY;			goto cleanup;		}		dns_name_init(name, *offsets);		/*		 * Parse the name out of this packet.		 */		isc_buffer_remainingregion(source, &r);		isc_buffer_setactive(source, r.length);		result = getname(name, source, msg, dctx);		if (result != ISC_R_SUCCESS)			goto cleanup;		/*		 * Get type, class, ttl, and rdatalen.  Verify that at least		 * rdatalen bytes remain.  (Some of this is deferred to		 * later.)		 */		isc_buffer_remainingregion(source, &r);		if (r.length < 2 + 2 + 4 + 2) {			result = ISC_R_UNEXPECTEDEND;			goto cleanup;		}		rdtype = isc_buffer_getuint16(source);		rdclass = isc_buffer_getuint16(source);		/*		 * If there was no question section, we may not yet have		 * established a class.  Do so now.		 */		if (msg->state == DNS_SECTION_ANY &&		    rdtype != dns_rdatatype_opt &&	/* class is UDP SIZE */		    rdtype != dns_rdatatype_tsig &&	/* class is ANY */		    rdtype != dns_rdatatype_tkey) {	/* class is undefined */			msg->rdclass = rdclass;			msg->state = DNS_SECTION_QUESTION;		}		/*		 * If this class is different than the one in the question		 * section, bail.		 */		if (msg->opcode != dns_opcode_update		    && rdtype != dns_rdatatype_tsig		    && rdtype != dns_rdatatype_opt		    && rdtype != dns_rdatatype_dnskey /* in a TKEY query */		    && rdtype != dns_rdatatype_sig /* SIG(0) */		    && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */		    && msg->rdclass != rdclass)			DO_FORMERR;		/*		 * Special type handling for TSIG, OPT, and TKEY.		 */		if (rdtype == dns_rdatatype_tsig) {			/*			 * If it is a tsig, verify that it is in the			 * additional data section.			 */			if (sectionid != DNS_SECTION_ADDITIONAL ||			    rdclass != dns_rdataclass_any ||			    count != msg->counts[sectionid]  - 1)				DO_FORMERR;			msg->sigstart = recstart;			skip_name_search = ISC_TRUE;			skip_type_search = ISC_TRUE;		} else if (rdtype == dns_rdatatype_opt) {			/*			 * The name of an OPT record must be ".", it			 * must be in the additional data section, and			 * it must be the first OPT we've seen.			 */			if (!dns_name_equal(dns_rootname, name) ||			    msg->opt != NULL)				DO_FORMERR;			skip_name_search = ISC_TRUE;			skip_type_search = ISC_TRUE;		} else if (rdtype == dns_rdatatype_tkey) {			/*			 * A TKEY must be in the additional section if this			 * is a query, and the answer section if this is a			 * response.  Unless it's a Win2000 client.			 *			 * Its class is ignored.			 */			dns_section_t tkeysection;			if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)				tkeysection = DNS_SECTION_ADDITIONAL;			else				tkeysection = DNS_SECTION_ANSWER;			if (sectionid != tkeysection &&			    sectionid != DNS_SECTION_ANSWER)				DO_FORMERR;		}		/*		 * ... now get ttl and rdatalen, and check buffer.		 */		ttl = isc_buffer_getuint32(source);		rdatalen = isc_buffer_getuint16(source);		r.length -= (2 + 2 + 4 + 2);		if (r.length < rdatalen) {			result = ISC_R_UNEXPECTEDEND;			goto cleanup;		}		/*		 * Read the rdata from the wire format.  Interpret the		 * rdata according to its actual class, even if it had a		 * DynDNS meta-class in the packet (unless this is a TSIG).		 * Then put the meta-class back into the finished rdata.		 */		rdata = newrdata(msg);		if (rdata == NULL) {			result = ISC_R_NOMEMORY;			goto cleanup;		}		if (msg->opcode == dns_opcode_update &&		    update(sectionid, rdclass)) {			if (rdatalen != 0) {				result = DNS_R_FORMERR;				goto cleanup;			}			/*			 * When the rdata is empty, the data pointer is			 * never dereferenced, but it must still be non-NULL. 			 * Casting 1 rather than "" avoids warnings about			 * discarding the const attribute of a string,			 * for compilers that would warn about such things.			 */			rdata->data = (unsigned char *)1;			rdata->length = 0;			rdata->rdclass = rdclass;			rdata->type = rdtype;			rdata->flags = DNS_RDATA_UPDATE;			result = ISC_R_SUCCESS;		} else if (rdtype == dns_rdatatype_tsig)			result = getrdata(source, msg, dctx, rdclass,					  rdtype, rdatalen, rdata);		else			result = getrdata(source, msg, dctx, msg->rdclass,					  rdtype, rdatalen, rdata);		if (result != ISC_R_SUCCESS)			goto cleanup;		rdata->rdclass = rdclass;		issigzero = ISC_FALSE;		if (rdtype == dns_rdatatype_rrsig  &&		    rdata->flags == 0) {			covers = dns_rdata_covers(rdata);			if (covers == 0)				DO_FORMERR;		} else if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&			   rdata->flags == 0) {			covers = dns_rdata_covers(rdata);			if (covers == 0) {				if (sectionid != DNS_SECTION_ADDITIONAL ||				    count != msg->counts[sectionid]  - 1)					DO_FORMERR;				msg->sigstart = recstart;				skip_name_search = ISC_TRUE;				skip_type_search = ISC_TRUE;				issigzero = ISC_TRUE;			}		} else			covers = 0;		/*		 * If we are doing a dynamic update or this is a meta-type,		 * don't bother searching for a name, just append this one		 * to the end of the message.		 */		if (preserve_order || msg->opcode == dns_opcode_update ||		    skip_name_search) {			if (rdtype != dns_rdatatype_opt &&			    rdtype != dns_rdatatype_tsig &&			    !issigzero)			{				ISC_LIST_APPEND(*section, name, link);				free_name = ISC_FALSE;			}		} else {			/*			 * Run through the section, looking to see if this name			 * is already there.  If it is found, put back the			 * allocated name since we no longer need it, and set			 * our name pointer to point to the name we found.			 */			result = findname(&name2, name, section);			/*			 * If it is a new name, append to the section.			 */			if (result == ISC_R_SUCCESS) {				isc_mempool_put(msg->namepool, name);				name = name2;			} else {				ISC_LIST_APPEND(*section, name, link);			}			free_name = ISC_FALSE;		}		/*		 * Search name for the particular type and class.		 * Skip this stage if in update mode or this is a meta-type.		 */		if (preserve_order || msg->opcode == dns_opcode_update ||		    skip_type_search)			result = ISC_R_NOTFOUND;		else {			/*			 * If this is a type that can only occur in			 * the question section, fail.			 */			if (dns_rdatatype_questiononly(rdtype))				DO_FORMERR;			rdataset = NULL;			result = dns_message_findtype(name, rdtype, covers,						      &rdataset);		}		/*		 * If we found an rdataset that matches, we need to		 * append this rdata to that set.  If we did not, we need		 * to create a new rdatalist, store the important bits there,		 * convert it to an rdataset, and link the latter to the name.		 * Yuck.  When appending, make certain that the type isn't		 * a singleton type, such as SOA or CNAME.		 *		 * Note that this check will be bypassed when preserving order,		 * the opcode is an update, or the type search is skipped.		 */		if (result == ISC_R_SUCCESS) {			if (dns_rdatatype_issingleton(rdtype))				DO_FORMERR;		}		if (result == ISC_R_NOTFOUND) {			rdataset = isc_mempool_get(msg->rdspool);			if (rdataset == NULL) {				result = ISC_R_NOMEMORY;				goto cleanup;			}			free_rdataset = ISC_TRUE;			rdatalist = newrdatalist(msg);			if (rdatalist == NULL) {				result = ISC_R_NOMEMORY;				goto cleanup;			}			rdatalist->type = rdtype;			rdatalist->covers = covers;			rdatalist->rdclass = rdclass;			rdatalist->ttl = ttl;			ISC_LIST_INIT(rdatalist->rdata);			dns_rdataset_init(rdataset);			RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,							       rdataset)				      == ISC_R_SUCCESS);			if (rdtype != dns_rdatatype_opt && 			    rdtype != dns_rdatatype_tsig &&			    !issigzero)			{				ISC_LIST_APPEND(name->list, rdataset, link);				free_rdataset = ISC_FALSE;			}		}		/*		 * Minimize TTLs.		 *		 * Section 5.2 of RFC 2181 says we should drop		 * nonauthoritative rrsets where the TTLs differ, but we		 * currently treat them the as if they were authoritative and		 * minimize them.		 */		if (ttl != rdataset->ttl) {			rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;			if (ttl < rdataset->ttl)				rdataset->ttl = ttl;		}		/*		 * XXXMLG Perform a totally ugly hack here to pull		 * the rdatalist out of the private field in the rdataset,		 * and append this rdata to the rdatalist's linked list		 * of rdata.		 */		rdatalist = (dns_rdatalist_t *)(rdataset->private1);		ISC_LIST_APPEND(rdatalist->rdata, rdata, link);		/*		 * If this is an OPT record, remember it.  Also, set		 * the extended rcode.  Note that msg->opt will only be set		 * if best-effort parsing is enabled.		 */		if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {			dns_rcode_t ercode;			msg->opt = rdataset;			rdataset = NULL;			free_rdataset = ISC_FALSE;			ercode = (dns_rcode_t)				((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)				 >> 20);			msg->rcode |= ercode;			isc_mempool_put(msg->namepool, name);			free_name = ISC_FALSE;		}		/*		 * If this is an SIG(0) or TSIG record, remember it.  Note		 * that msg->sig0 or msg->tsig will only be set if best-effort		 * parsing is enabled.		 */		if (issigzero && msg->sig0 == NULL) {			msg->sig0 = rdataset;			msg->sig0name = name;			rdataset = NULL;			free_rdataset = ISC_FALSE;			free_name = ISC_FALSE;		} else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {			msg->tsig = rdataset;			msg->tsigname = name;			rdataset = NULL;			free_rdataset = ISC_FALSE;			free_name = ISC_FALSE;		}		INSIST(free_name == ISC_FALSE);		INSIST(free_rdataset == ISC_FALSE);	}	if (seen_problem)		return (DNS_R_RECOVERABLE);	return (ISC_R_SUCCESS); cleanup:	if (free_name)		isc_mempool_put(msg->namepool, name);	if (free_rdataset)		isc_mempool_put(msg->rdspool, rdataset);	return (result);}isc_result_tdns_message_parse(dns_message_t *msg, isc_buffer_t *source,		  unsigned int options){	isc_region_t r;	dns_decompress_t dctx;	isc_result_t ret;	isc_uint16_t tmpflags;	isc_buffer_t origsource;	isc_boolean_t seen_problem;	isc_boolean_t ignore_tc;	REQUIRE(DNS_MESSAGE_VALID(msg));	REQUIRE(source != NULL);	REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);	seen_problem = ISC_FALSE;	ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);	origsource = *source;	msg->header_ok = 0;	msg->question_ok = 0;	isc_buffer_remainingregion(source, &r);	if (r.length < DNS_MESSAGE_HEADERLEN)		return (ISC_R_UNEXPECTEDEND);	msg->id = isc_buffer_getuint16(source);	tmpflags = isc_buffer_getuint16(source);	msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)		       >> DNS_MESSAGE_OPCODE_SHIFT);	msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK);	msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK);	msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);	msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);	msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);	msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);	msg->header_ok = 1;	/*	 * -1 means no EDNS.	 */	dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);	dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);	ret = getquestions(source, msg, &dctx, options);	if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)		goto truncated;	if (ret == DNS_R_RECOVERABLE) {		seen_problem = ISC_TRUE;		ret = ISC_R_SUCCESS;	}	if (ret != ISC_R_SUCCESS)		return (ret);	msg->question_ok = 1;	ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);	if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)		goto truncated;	if (ret == DNS_R_RECOVERABLE) {		seen_problem = ISC_TRUE;		ret = ISC_R_SUCCESS;	}	if (ret != ISC_R_SUCCESS)		return (ret);	ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);	if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)		goto truncated;	if (ret == DNS_R_RECOVERABLE) {		seen_problem = ISC_TRUE;		ret = ISC_R_SUCCESS;	}	if (ret != ISC_R_SUCCESS)		return (ret);	ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);	if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)		goto truncated;	if (ret == DNS_R_RECOVERABLE) {		seen_problem = ISC_TRUE;		ret = ISC_R_SUCCESS;	}	if (ret != ISC_R_SUCCESS)		return (ret);	isc_buffer_remainingregion(source, &r);	if (r.length != 0) {		isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,

⌨️ 快捷键说明

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