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

📄 update.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 4 页
字号:
	querylen = snprintf(query, sizeof(query),		"DELETE FROM %s WHERE zone=%u AND (name='%s' OR name='%s') AND type='%s'",							  mydns_rr_table_name, soa->id, xname, xhost, mydns_qtype_str(rr->type));#if DEBUG_UPDATE_SQL	Verbose("%s: DNS UPDATE: %s", desctask(t), query);#endif#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: DELETE RRSET: %s", desctask(t), query);#endif	Free(xname);	Free(xhost);	/* Execute the query */	if (sql_nrquery(sql, query, querylen) != 0)	{		WarnSQL(sql, "%s: %s", desctask(t), _("error deleting RRset via DNS UPDATE"));		return dnserror(t, DNS_RCODE_SERVFAIL, ERR_DB_ERROR);	}	sql_free(res);	/* Output info to verbose log */	snprintf(query, sizeof(query), "DELETE %s IN %s", rr->name, mydns_qtype_str(rr->type));	task_output_info(t, query);	t->update_done++;	return 0;}/*--- update_delete_rr() ------------------------------------------------------------------------*//**************************************************************************************************	PROCESS_UPDATE	Perform the requested update.	Returns 0 on success, -1 on failure.**************************************************************************************************/static intprocess_update(TASK *t, MYDNS_SOA *soa, UQ *q, UQRR *rr){#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: process_update: q->name=[%s], q->type=%s, q->class=%s", desctask(t),			q->name, mydns_qtype_str(q->type), mydns_class_str(q->class));	Debug("%s: DNS UPDATE: process_update: rr->name=[%s], rr->type=%s, rr->class=%s", desctask(t),			rr->name, mydns_qtype_str(rr->type), mydns_class_str(rr->class));#endif	/* 2.5.1: Add to an RRset */	if (rr->class == q->class)	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: 2.5.1: Add to an RRset", desctask(t));#endif		return update_add_rr(t, soa, q, rr);	}	/* 2.5.2: Delete an RRset */	if (rr->type != DNS_CLASS_ANY && !rr->rdlength)	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: 2.5.2: Delete an RRset", desctask(t));#endif		return update_delete_rrset(t, soa, q, rr);	}	/* 2.5.3: Delete all RRsets from a name */	if (rr->type == DNS_CLASS_ANY && !rr->rdlength)	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: 2.5.3: Delete all RRsets from a name", desctask(t));#endif		return update_delete_rrset_all(t, soa, q, rr);	}	/* 2.5.4: Delete an RR from an RRset */	if (rr->type != DNS_CLASS_ANY && rr->rdlength)	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: 2.5.4: Delete an RR from an RRset", desctask(t));#endif		return update_delete_rr(t, soa, q, rr);	}#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: process_update: no action", desctask(t));#endif	return 0;}/*--- process_update() --------------------------------------------------------------------------*//**************************************************************************************************	CHECK_TMPRR	Check the set of RRs described in q->tmprr -- each RRset must match exactly what's in the	database, else we send NXRRSET.  AN "RRset" is described as an unique <NAME,TYPE>.	Returns 0 on success, -1 on error.	RFC 2136, 3.2.3 says:	...build an RRset for each unique <NAME,TYPE> and compare each resulting RRset for set	equality (same members, no more, no less) with RRsets in the zone.  If any Prerequisite	RRset is not entirely and exactly matched by a zone RRset, signal NXRRSET to the requestor.	If any RR in this section has a CLASS other than ZCLASS or NONE or ANY, signal FORMERR	to the requestor.	The temporary prerequisite RRsets are stored in q->tmprr (the count in q->num_tmprr).	The algorithm used here is to loop through q->tmprr.	The <NAME,TYPE> is inspected, and each RR with that <NAME,TYPE> is marked as 'tmprr->checked=1'.	We then examine each <NAME,TYPE> of that sort in q->tmprr.	Then, if any members of that <NAME,TYPE> are not matched, or if the count of records	of that <NAME,TYPE> in the database does not match the number of records of that <NAME,TYPE>	in q->tmprr, we return NXRRSET.	The RFC isn't totally clear on AUX values, so I'm only checking AUX values on RR types where	they ought to be relevant (currently MX and SRV).**************************************************************************************************/static intcheck_tmprr(TASK *t, MYDNS_SOA *soa, UQ *q){	int n, i;#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: Checking prerequisite RRsets for exact match", desctask(t));#endif	/* Examine "tmprr" */	for (n = 0; n < q->num_tmprr; n++)	{		TMPRR *tmprr = q->tmprr[n];		char	*current_name = tmprr->name;					/* Current NAME being examined */		dns_qtype_t	current_type = tmprr->type;			/* Current TYPE being examined */		MYDNS_RR	*rr_first = NULL;								/* RRs for the current name/type */		MYDNS_RR	*rr;												/* Current RR */		int	total_prereq_rr = 0, total_db_rr = 0;		/* Total RRs in prereq and database */		if (tmprr->checked)										/* Ignore if already checked */		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: Skipping prerequisite RRsets for %s/%s (already checked)", desctask(t), current_name, mydns_qtype_str(current_type));#endif			continue;		}#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: Checking prerequisite RRsets for %s/%s", desctask(t), current_name, mydns_qtype_str(current_type));#endif		/* Load all RRs for this name/type */		if (mydns_rr_load(sql, &rr_first, soa->id, current_type, current_name, NULL, "") != 0)		{			sql_reopen();			if (mydns_rr_load(sql, &rr_first, soa->id, current_type, current_name, NULL, "") != 0)			{				WarnSQL(sql, _("error finding %s type resource records for name `%s' in zone %u"),						  mydns_qtype_str(current_type), current_name, soa->id);				sql_reopen();				return dnserror(t, DNS_RCODE_FORMERR, ERR_DB_ERROR);			}		}		/* If no RRs were found, return NXRRSET */		if (!rr_first)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: Found prerequisite RRsets for %s/%s, but none in database (NXRRSET)",					desctask(t), current_name, mydns_qtype_str(current_type));#endif			return dnserror(t, DNS_RCODE_NXRRSET, ERR_PREREQUISITE_FAILED);		}		/* Count the total number of RRs found in database */		for (rr = rr_first; rr; rr = rr->next)			total_db_rr++;#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: Found %d database RRsets for %s/%s", desctask(t), total_db_rr,					current_name, mydns_qtype_str(current_type));#endif		/* Mark all <NAME,TYPE> matches in tmprr with checked=1, and count the number of RRs */		for (i = 0; i < q->num_tmprr; i++)			if (q->tmprr[i]->type == current_type && !strcasecmp(q->tmprr[i]->name, current_name))			{				q->tmprr[i]->checked = 1;				total_prereq_rr++;			}#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: Found %d prerequisite RRsets for %s/%s", desctask(t), total_prereq_rr,				current_name, mydns_qtype_str(current_type));#endif		/* If total_db_rr doesn't equal total_prereq_rr, return NXRRSET */		if (total_db_rr != total_prereq_rr)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: Found %d prerequisite RRsets for %s/%s, but %d in database (NXRRSET)",					desctask(t), total_prereq_rr, current_name, mydns_qtype_str(current_type), total_db_rr);#endif			mydns_rr_free(rr_first);			return dnserror(t, DNS_RCODE_NXRRSET, ERR_PREREQUISITE_FAILED);		}		/* Also, for each matching <NAME,TYPE>, check to see if the record exists in the database.			If it does, set matched=1.  If it does not, return NXRRSET */		for (i = 0; i < q->num_tmprr; i++)			if (q->tmprr[i]->type == current_type && !strcasecmp(q->tmprr[i]->name, current_name))			{				int found_match = 0;								/* Did we find a match for this RR? */#if DEBUG_ENABLED && DEBUG_UPDATE				Debug("%s: DNS UPDATE: looking for tmprr[%d] = %s/%s/%u/%s in database", desctask(t),						i, q->tmprr[i]->name, mydns_qtype_str(q->tmprr[i]->type), q->tmprr[i]->aux, q->tmprr[i]->data);#endif				for (rr = rr_first; rr && !found_match; rr = rr->next)				{					/* See if the DATA (and possibly the AUX) matches */					if (!strcasecmp(rr->data, q->tmprr[i]->data))					{						if (current_type == DNS_QTYPE_MX || current_type == DNS_QTYPE_SRV)						{							if (q->tmprr[i]->aux == rr->aux)								found_match = 1;						}						else							found_match = 1;					}				}				/* No match found - return NXRRSET */				if (!found_match)				{#if DEBUG_ENABLED && DEBUG_UPDATE					Debug("%s: DNS UPDATE: No match for prerequisite %s/%s/%u/%s (NXRRSET)", desctask(t),							q->tmprr[i]->name, mydns_qtype_str(q->tmprr[i]->type), q->tmprr[i]->aux, q->tmprr[i]->data);#endif					mydns_rr_free(rr_first);					return dnserror(t, DNS_RCODE_NXRRSET, ERR_PREREQUISITE_FAILED);				}			}		mydns_rr_free(rr_first);	}	return 0;}/*--- check_tmprr() -----------------------------------------------------------------------------*//**************************************************************************************************	DNS_UPDATE	Process a DNS UPDATE query.**************************************************************************************************/intdns_update(TASK *t){	MYDNS_SOA	*soa;												/* SOA record for zone */	UQ				*q;												/* Update query data */	int			n;	/*add by zyl 20080331 --begin*/   char*  myip = (char*)malloc(16);   memset(myip,0,sizeof(myip));   iplong_to_ipchs(myip, 16, t->addr4.sin_addr.s_addr);   /*add by zyl 20080331 --end*/   /*add by zyl 20080408 --begin*/   int telecom_operator = 0;   int ipint = 0;   ipchs_to_ipuint32(&ipint,myip);   if(ipint)      get_telecom_operator(&telecom_operator,ipint);   /*add by zyl 20080408 --end*/   free(myip);	/* Try to load SOA for zone */	if (mydns_soa_load(sql, &soa, t->qname,telecom_operator) < 0)		//modi by zyl 080408		return dnserror(t, DNS_RCODE_SERVFAIL, ERR_DB_ERROR);	/* If there's no such zone, say REFUSED rather than NOTAUTH, to prevent "zone mining" */	if (!soa)		return dnserror(t, DNS_RCODE_REFUSED, ERR_ZONE_NOT_FOUND);#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: SOA id %u", desctask(t), soa->id);	Debug("%s: DNS UPDATE: ZOCOUNT=%d (Zone)", desctask(t), t->qdcount);	Debug("%s: DNS UPDATE: PRCOUNT=%d (Prerequisite)", desctask(t), t->ancount);	Debug("%s: DNS UPDATE: UPCOUNT=%d (Update)", desctask(t), t->nscount);	Debug("%s: DNS UPDATE: ADCOUNT=%d (Additional data)", desctask(t), t->arcount);#endif	/* Check the optional 'update' column if it exists */	if (check_update(t, soa) != 0)		return -1;	/* Parse the update query */	if (!(q = calloc(1, sizeof(UQ))))		Err(_("out of memory"));	if (parse_update_query(t, soa, q) != 0)	{#if DEBUG_ENABLED && DEBUG_UPDATE		Debug("%s: DNS UPDATE: parse_update_query failed", desctask(t));#endif		goto dns_update_error;	}	/* Check the prerequsites as described in RFC 2136 3.2 */	for (n = 0; n < q->numPR; n++)		if (check_prerequisite(t, soa, q, &q->PR[n]) != 0)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: check_prerequisite failed", desctask(t));#endif			goto dns_update_error;		}	/* Check the prerequisite RRsets -- RFC 2136 3.2.3 */	if (check_tmprr(t, soa, q) != 0)	{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: check_tmprr failed", desctask(t));#endif			goto dns_update_error;	}	/* Prescan the update section (RFC 2136 3.4.1) */	for (n = 0; n < q->numUP; n++)		if (prescan_update(t, soa, q, &q->UP[n]) != 0)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: prescan_update failed", desctask(t));#endif			goto dns_update_error;		}	/* Process the update section (RFC 2136 3.4.2) */	if (update_transaction(t, "BEGIN") != 0)				/* Start transaction */		goto dns_update_error;	for (n = 0; n < q->numUP; n++)	{		if (process_update(t, soa, q, &q->UP[n]) != 0)		{#if DEBUG_ENABLED && DEBUG_UPDATE			Debug("%s: DNS UPDATE: process_update failed", desctask(t));#endif			if (update_transaction(t, "ROLLBACK") != 0)	/* Rollback transaction */				goto dns_update_error;			goto dns_update_error;		}	}	if (update_transaction(t, "COMMIT") != 0)				/* Commit changes */		goto dns_update_error;	if (t->update_done)		t->info_already_out = 1;	/* Purge the cache for this zone */	cache_purge_zone(ZoneCache, soa->id);#if USE_NEGATIVE_CACHE	cache_purge_zone(NegativeCache, soa->id);#endif	cache_purge_zone(ReplyCache, soa->id);	/* Construct reply and set task status */	build_reply(t, 0);	t->status = NEED_WRITE;	/* Clean up and return */	free_uq(q);	mydns_soa_free(soa);	return 0;dns_update_error:	build_reply(t, 1);#if DEBUG_ENABLED && DEBUG_UPDATE	Debug("%s: DNS UPDATE: Went to dns_update_error", desctask(t));#endif	free_uq(q);	mydns_soa_free(soa);	return -1;}/*--- dns_update() ------------------------------------------------------------------------------*//* vi:set ts=3: */

⌨️ 快捷键说明

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