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

📄 xfrin.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Build an *XFR request and send its length prefix. */static isc_result_txfrin_send_request(dns_xfrin_ctx_t *xfr) {	isc_result_t result;	isc_region_t region;	isc_region_t lregion;	dns_rdataset_t *qrdataset = NULL;	dns_message_t *msg = NULL;	unsigned char length[2];	dns_difftuple_t *soatuple = NULL;	dns_name_t *qname = NULL;	dns_dbversion_t *ver = NULL;	dns_name_t *msgsoaname = NULL;	/* Create the request message */	CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));	CHECK(dns_message_settsigkey(msg, xfr->tsigkey));	/* Create a name for the question section. */	CHECK(dns_message_gettempname(msg, &qname));	dns_name_init(qname, NULL);	dns_name_clone(&xfr->name, qname);	/* Formulate the question and attach it to the question name. */	CHECK(dns_message_gettemprdataset(msg, &qrdataset));	dns_rdataset_init(qrdataset);	dns_rdataset_makequestion(qrdataset, xfr->rdclass, xfr->reqtype);	ISC_LIST_APPEND(qname->list, qrdataset, link);	qrdataset = NULL;	dns_message_addname(msg, qname, DNS_SECTION_QUESTION);	qname = NULL;	if (xfr->reqtype == dns_rdatatype_ixfr) {		/* Get the SOA and add it to the authority section. */		/* XXX is using the current version the right thing? */		dns_db_currentversion(xfr->db, &ver);		CHECK(dns_db_createsoatuple(xfr->db, ver, xfr->mctx,					    DNS_DIFFOP_EXISTS, &soatuple));		xfr->ixfr.request_serial = dns_soa_getserial(&soatuple->rdata);		xfr->ixfr.current_serial = xfr->ixfr.request_serial;		xfrin_log(xfr, ISC_LOG_DEBUG(3),			  "requesting IXFR for serial %u",			  xfr->ixfr.request_serial);		CHECK(tuple2msgname(soatuple, msg, &msgsoaname));		dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY);	}	xfr->checkid = ISC_TRUE;	xfr->id++;	msg->id = xfr->id;	CHECK(render(msg, xfr->mctx, &xfr->qbuffer));	/*	 * Free the last tsig, if there is one.	 */	if (xfr->lasttsig != NULL)		isc_buffer_free(&xfr->lasttsig);	/*	 * Save the query TSIG and don't let message_destroy free it.	 */	CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));	isc_buffer_usedregion(&xfr->qbuffer, &region);	INSIST(region.length <= 65535);	length[0] = region.length >> 8;	length[1] = region.length & 0xFF;	lregion.base = length;	lregion.length = 2;	CHECK(isc_socket_send(xfr->socket, &lregion, xfr->task,			      xfrin_sendlen_done, xfr));	xfr->sends++; failure:	if (qname != NULL)		dns_message_puttempname(msg, &qname);	if (qrdataset != NULL)		dns_message_puttemprdataset(msg, &qrdataset);	if (msg != NULL)		dns_message_destroy(&msg);	if (soatuple != NULL)		dns_difftuple_free(&soatuple);	if (ver != NULL)		dns_db_closeversion(xfr->db, &ver, ISC_FALSE);	return (result);}/* XXX there should be library support for sending DNS TCP messages */static voidxfrin_sendlen_done(isc_task_t *task, isc_event_t *event) {	isc_socketevent_t *sev = (isc_socketevent_t *) event;	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;	isc_result_t evresult = sev->result;	isc_result_t result;	isc_region_t region;	REQUIRE(VALID_XFRIN(xfr));	UNUSED(task);	INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);	isc_event_free(&event);	xfr->sends--;	if (xfr->shuttingdown) {		maybe_free(xfr);		return;	}	xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request length prefix");	CHECK(evresult);	isc_buffer_usedregion(&xfr->qbuffer, &region);	CHECK(isc_socket_send(xfr->socket, &region, xfr->task,			      xfrin_send_done, xfr));	xfr->sends++; failure:	if (result != ISC_R_SUCCESS)		xfrin_fail(xfr, result, "failed sending request length prefix");}static voidxfrin_send_done(isc_task_t *task, isc_event_t *event) {	isc_socketevent_t *sev = (isc_socketevent_t *) event;	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;	isc_result_t result;	REQUIRE(VALID_XFRIN(xfr));	UNUSED(task);	INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);	xfr->sends--;	xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request data");	CHECK(sev->result);	CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,				     xfrin_recv_done, xfr));	xfr->recvs++; failure:	isc_event_free(&event);	if (result != ISC_R_SUCCESS)		xfrin_fail(xfr, result, "failed sending request data");}static voidxfrin_recv_done(isc_task_t *task, isc_event_t *ev) {	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->ev_arg;	isc_result_t result;	dns_message_t *msg = NULL;	dns_name_t *name;	dns_tcpmsg_t *tcpmsg;	dns_name_t *tsigowner = NULL;	REQUIRE(VALID_XFRIN(xfr));	UNUSED(task);	INSIST(ev->ev_type == DNS_EVENT_TCPMSG);	tcpmsg = ev->ev_sender;	isc_event_free(&ev);	xfr->recvs--;	if (xfr->shuttingdown) {		maybe_free(xfr);		return;	}	CHECK(tcpmsg->result);	xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes",		  tcpmsg->buffer.used);	CHECK(isc_timer_touch(xfr->timer));	CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));	CHECK(dns_message_settsigkey(msg, xfr->tsigkey));	CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));	msg->tsigctx = xfr->tsigctx;	if (xfr->nmsg > 0)		msg->tcp_continuation = 1;	result = dns_message_parse(msg, &tcpmsg->buffer,				   DNS_MESSAGEPARSE_PRESERVEORDER);	if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||	    (xfr->checkid && msg->id != xfr->id)) {		if (result == ISC_R_SUCCESS)			result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/		if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)			result = DNS_R_UNEXPECTEDID;		if (xfr->reqtype == dns_rdatatype_axfr ||		    xfr->reqtype == dns_rdatatype_soa)			FAIL(result);		xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",		       isc_result_totext(result)); try_axfr:		dns_message_destroy(&msg);		xfrin_reset(xfr);		xfr->reqtype = dns_rdatatype_axfr;		xfr->state = XFRST_INITIALSOA;		(void)xfrin_start(xfr);		return;	}	/*	 * Does the server know about IXFR?  If it doesn't we will get	 * a message with a empty answer section or a potentially a CNAME /	 * DNAME, the later is handled by xfr_rr() which will return FORMERR	 * if the first RR in the answer section is not a SOA record.	 */	if (xfr->reqtype == dns_rdatatype_ixfr &&	    xfr->state == XFRST_INITIALSOA &&	    msg->counts[DNS_SECTION_ANSWER] == 0) {		xfrin_log(xfr, ISC_LOG_DEBUG(3),			  "empty answer section, retrying with AXFR");		goto try_axfr;	}	if (xfr->reqtype == dns_rdatatype_soa &&	    (msg->flags & DNS_MESSAGEFLAG_AA) == 0) {		FAIL(DNS_R_NOTAUTHORITATIVE);	}	result = dns_message_checksig(msg, dns_zone_getview(xfr->zone));	if (result != ISC_R_SUCCESS) {		xfrin_log(xfr, ISC_LOG_DEBUG(3), "TSIG check failed: %s",		       isc_result_totext(result));		FAIL(result);	}	for (result = dns_message_firstname(msg, DNS_SECTION_ANSWER);	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(msg, DNS_SECTION_ANSWER))	{		dns_rdataset_t *rds;		name = NULL;		dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);		for (rds = ISC_LIST_HEAD(name->list);		     rds != NULL;		     rds = ISC_LIST_NEXT(rds, link))		{			for (result = dns_rdataset_first(rds);			     result == ISC_R_SUCCESS;			     result = dns_rdataset_next(rds))			{				dns_rdata_t rdata = DNS_RDATA_INIT;				dns_rdataset_current(rds, &rdata);				CHECK(xfr_rr(xfr, name, rds->ttl, &rdata));			}		}	}	if (result != ISC_R_NOMORE)		goto failure;	if (dns_message_gettsig(msg, &tsigowner) != NULL) {		/*		 * Reset the counter.		 */		xfr->sincetsig = 0;		/*		 * Free the last tsig, if there is one.		 */		if (xfr->lasttsig != NULL)			isc_buffer_free(&xfr->lasttsig);		/*		 * Update the last tsig pointer.		 */		CHECK(dns_message_getquerytsig(msg, xfr->mctx,					       &xfr->lasttsig));	} else if (dns_message_gettsigkey(msg) != NULL) {		xfr->sincetsig++;		if (xfr->sincetsig > 100 ||		    xfr->nmsg == 0 || xfr->state == XFRST_END)		{			result = DNS_R_EXPECTEDTSIG;			goto failure;		}	}	/*	 * Update the number of messages received.	 */	xfr->nmsg++;	/*	 * Copy the context back.	 */	xfr->tsigctx = msg->tsigctx;	dns_message_destroy(&msg);	if (xfr->state == XFRST_END) {		/*		 * Inform the caller we succeeded.		 */		if (xfr->done != NULL) {			(xfr->done)(xfr->zone, ISC_R_SUCCESS);			xfr->done = NULL;		}		/*		 * We should have no outstanding events at this		 * point, thus maybe_free() should succeed.		 */		xfr->shuttingdown = ISC_TRUE;		maybe_free(xfr);	} else {		/*		 * Read the next message.		 */		CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,					     xfrin_recv_done, xfr));		xfr->recvs++;	}	return; failure:	if (msg != NULL)		dns_message_destroy(&msg);	if (result != ISC_R_SUCCESS)		xfrin_fail(xfr, result, "failed while receiving responses");}static voidxfrin_timeout(isc_task_t *task, isc_event_t *event) {	dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->ev_arg;	REQUIRE(VALID_XFRIN(xfr));	UNUSED(task);	isc_event_free(&event);	/*	 * This will log "giving up: timeout".	 */	xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");}static voidmaybe_free(dns_xfrin_ctx_t *xfr) {	REQUIRE(VALID_XFRIN(xfr));	if (! xfr->shuttingdown || xfr->refcount != 0 ||	    xfr->connects != 0 || xfr->sends != 0 ||	    xfr->recvs != 0)		return;	xfrin_log(xfr, ISC_LOG_INFO, "end of transfer");	if (xfr->socket != NULL)		isc_socket_detach(&xfr->socket);	if (xfr->timer != NULL)		isc_timer_detach(&xfr->timer);	if (xfr->task != NULL)		isc_task_detach(&xfr->task);	if (xfr->tsigkey != NULL)		dns_tsigkey_detach(&xfr->tsigkey);	if (xfr->lasttsig != NULL)		isc_buffer_free(&xfr->lasttsig);	dns_diff_clear(&xfr->diff);	if (xfr->ixfr.journal != NULL)		dns_journal_destroy(&xfr->ixfr.journal);	if (xfr->axfr.add_private != NULL)		(void)dns_db_endload(xfr->db, &xfr->axfr.add_private);	if (xfr->tcpmsg_valid)		dns_tcpmsg_invalidate(&xfr->tcpmsg);	if ((xfr->name.attributes & DNS_NAMEATTR_DYNAMIC) != 0)		dns_name_free(&xfr->name, xfr->mctx);	if (xfr->ver != NULL)		dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);	if (xfr->db != NULL)		dns_db_detach(&xfr->db);	if (xfr->zone != NULL)		dns_zone_idetach(&xfr->zone);	isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));}/* * Log incoming zone transfer messages in a format like * transfer of <zone> from <address>: <message> */static voidxfrin_logv(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,	   isc_sockaddr_t *masteraddr, const char *fmt, va_list ap){	char zntext[DNS_NAME_FORMATSIZE];	char mastertext[ISC_SOCKADDR_FORMATSIZE];	char classtext[DNS_RDATACLASS_FORMATSIZE];	char msgtext[2048];	dns_name_format(zonename, zntext, sizeof(zntext));	dns_rdataclass_format(rdclass, classtext, sizeof(classtext));	isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext));	vsnprintf(msgtext, sizeof(msgtext), fmt, ap);	isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN,		      DNS_LOGMODULE_XFER_IN, level,		      "transfer of '%s/%s' from %s: %s",		      zntext, classtext, mastertext, msgtext);}/* * Logging function for use when a xfrin_ctx_t has not yet been created. */static voidxfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,	   isc_sockaddr_t *masteraddr, const char *fmt, ...){	va_list ap;	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)		return;	va_start(ap, fmt);	xfrin_logv(level, zonename, rdclass, masteraddr, fmt, ap);	va_end(ap);}/* * Logging function for use when there is a xfrin_ctx_t. */static voidxfrin_log(dns_xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...){	va_list ap;	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)		return;	va_start(ap, fmt);	xfrin_logv(level, &xfr->name, xfr->rdclass, &xfr->masteraddr, fmt, ap);	va_end(ap);}

⌨️ 快捷键说明

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