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

📄 resolve.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************************************	$Id: resolve.c,v 1.59 2006/01/18 20:46:47 bboy Exp $	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>	This program is free software; you can redistribute it and/or modify	it under the terms of the GNU General Public License as published by	the Free Software Foundation; either version 2 of the License, or	(at Your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**************************************************************************************************/#include "named.h"/* Make this nonzero to enable debugging for this source file */#define	DEBUG_RESOLVE	1#if DEBUG_ENABLED && DEBUG_RESOLVE/* Strings describing the datasections */char *resolve_datasection_str[] = { "QUESTION", "ANSWER", "AUTHORITY", "ADDITIONAL" };#endif#if STATUS_ENABLEDextern int remote_status(TASK *t);#endif/**************************************************************************************************	RESOLVE_SOA	Adds SOA record to the specified section.  If that section is ANSWER, assume this is a SOA	query.  Returns number of records inserted, or -1 if an error occurred.**************************************************************************************************/static intresolve_soa(TASK *t, datasection_t section, char *fqdn){	MYDNS_SOA *soa = find_soa(t, fqdn, NULL);	if (soa)	{		t->zone = soa->id;		t->minimum_ttl = soa->minimum;		/* Don't cache replies for SOA with a 0 second TTL */		if (!soa->minimum && !soa->ttl)			t->reply_cache_ok = 0;		/* This is a SOA request - handle things a tiny bit differently */		if (t->qtype == DNS_QTYPE_SOA && section == ANSWER)		{			/* If the fqdn does not exactly match, put the SOA in AUTHORITY instead of ANSWER */			if (strcmp(fqdn, soa->origin))			{				rrlist_add(t, AUTHORITY, DNS_RRTYPE_SOA, (void *)soa, soa->origin);				t->sort_level++;			}			else			{				/* SOA in ANSWER - also add authoritative nameservers */				rrlist_add(t, section, DNS_RRTYPE_SOA, (void *)soa, soa->origin);				t->sort_level++;				(void)resolve(t, AUTHORITY, DNS_QTYPE_NS, soa->origin, 0);			}		}		else		{			rrlist_add(t, section, DNS_RRTYPE_SOA, (void *)soa, soa->origin);			t->sort_level++;		}		mydns_soa_free(soa);		if (section == ANSWER)									/* We are authoritative; Set `aa' flag */			t->hdr.aa = 1;		return (1);	}	return (section == ANSWER ? dnserror(t, DNS_RCODE_REFUSED, ERR_ZONE_NOT_FOUND) : 0);}/*--- resolve_soa() -----------------------------------------------------------------------------*//**************************************************************************************************	CNAME_RECURSE	If task has a dominant matching CNAME record, recurse into it.	Returns the number of records added.**************************************************************************************************/static intcname_recurse(TASK *t, datasection_t section, dns_qtype_t qtype,				  char *fqdn, MYDNS_SOA *soa, char *label, MYDNS_RR *cname, int level){	register int n;	if (level >= MAX_CNAME_LEVEL)		return (1);	/* Add the CNAME record to the answer section */	if (section == ANSWER && level)		rrlist_add(t, ADDITIONAL, DNS_RRTYPE_RR, (void *)cname, fqdn);	else		rrlist_add(t, section, DNS_RRTYPE_RR, (void *)cname, fqdn);	t->sort_level++;	/* If the request was for CNAME records, this is the answer; we are done. */	if (t->qtype == DNS_QTYPE_CNAME)		return (1);	/* Check `Cnames' list; if we are looping, stop.  Otherwise add this to the array. */	for (n = 0; n < level; n++)		if (t->Cnames[n] == cname->id)		{			/* CNAME loop: Send what we have so far and consider the resolution complete */			Verbose("%s: %s: %s %s %s (depth %d)", desctask(t), _("CNAME loop detected"),					cname->name, mydns_qtype_str(cname->type), cname->data, level);			return (1);		}	t->Cnames[level] = cname->id;#if DEBUG_ENABLED && DEBUG_RESOLVE	Debug("%s: CNAME -> `%s'", desctask(t), cname->data);#endif	/* Resolve with this new CNAME record as the FQDN */	return resolve(t, section, qtype, cname->data, level+1);}/*--- cname_recurse() ---------------------------------------------------------------------------*//**************************************************************************************************	PROCESS_RR	Process the resource record list.  Returns number of records added.**************************************************************************************************/static intprocess_rr(TASK *t, datasection_t section, dns_qtype_t qtype, char *fqdn,			  MYDNS_SOA *soa, char *label, MYDNS_RR *rr, int level){	register MYDNS_RR *r;	register int rv = 0;	register int add_ns = (section == ANSWER && !t->ns.size && qtype != DNS_QTYPE_NS && qtype != DNS_QTYPE_ANY);	t->name_ok = 1;#if DEBUG_ENABLED && DEBUG_RESOLVE	Debug("%s: process_rr(%s, %s, \"%s\", (%s), \"%s\", %d)",			desctask(t), resolve_datasection_str[section], mydns_qtype_str(qtype), fqdn,			soa->origin, label, level);	Debug("%s: matched `%s%s%s'", desctask(t), label, *label ? "." : "", soa->origin);#endif	/* If the data section calls for a FQDN, and we just get a hostname, append the origin */	for (r = rr; r; r = r->next)		if (r->type == DNS_QTYPE_NS || r->type == DNS_QTYPE_CNAME || r->type == DNS_QTYPE_MX)		{			register int len = strlen(r->data);			if (r->data[len-1] == '.')				continue;#if DEBUG_ENABLED && DEBUG_RESOLVE			Debug("Appending origin (%s) to data section (%s)", soa->origin, r->data);#endif			if (len + strlen(soa->origin) + 1 <= DNS_MAXNAMELEN)			{				r->data[len] = '.';				strcpy(r->data + len + 1, soa->origin);			}		}	/* If the RR list returned contains a CNAME record, follow the CNAME. */	for (r = rr; r; r = r->next)		if (r->type == DNS_QTYPE_CNAME)			return cname_recurse(t, section, qtype, fqdn, soa, label, r, level);	/* Find RRs matching QTYPE */	for (r = rr; r; r = r->next)		if (r->type == qtype || qtype == DNS_QTYPE_ANY)		{#if ALIAS_ENABLED			/* If the RR is an ALIAS then follow it, otherwise just add it. */			if (r->alias)				rv += alias_recurse(t, section, fqdn, soa, label, r);			else			{				rrlist_add(t, section, DNS_RRTYPE_RR, (void *)r, fqdn);				rv++;			}#else			rrlist_add(t, section, DNS_RRTYPE_RR, (void *)r, fqdn);			rv++;#endif		}	t->sort_level++;	/* If we found no matching RR's but there are NS records, and the name isn't empty		or '*' (which I think is probably wrong, but...) treat as delegation -- set 'rv'		to make the caller return, then set 'add_ns' to fill the AUTHORITY */	if (!rv && *label && *label != '*')		for (r = rr; !rv && r; r = r->next)			if (r->type == DNS_QTYPE_NS)				rv = add_ns = 1;	/* If we found some results, go ahead and put nameserver records into AUTHORITY */	for (r = rr; rv && r; r = r->next)		if (r->type == DNS_QTYPE_NS && add_ns)		{			char ns[DNS_MAXNAMELEN+1];			/* If the rr is for something like "*.bboy.net.", show the labelized name */			if (r->name[0] == '*' && r->name[1] == '.' && r->name[2])				snprintf(ns, sizeof(ns), "%s.%s", r->name+2, soa->origin);			else if (r->name[0] && r->name[0] != '*')				snprintf(ns, sizeof(ns), "%s.%s", r->name, soa->origin);			else				strncpy(ns, soa->origin, sizeof(ns)-1);#if DEBUG_ENABLED && DEBUG_RESOLVE			Debug("%s: Adding AUTHORITY for NS \"%s\"", desctask(t), ns);#endif			rrlist_add(t, AUTHORITY, DNS_RRTYPE_RR, (void *)r, ns);			/* If the NS data is a FQDN, look in THIS zone for an A record.  That way glue				records can be stored out of bailiwick a la BIND */			if (LASTCHAR(r->data) == '.')			{				MYDNS_RR *A = find_rr(t, soa, DNS_QTYPE_A, r->data);				if (A)				{					register MYDNS_RR *a;					for (a = A; a; a = a->next)						rrlist_add(t, ADDITIONAL, DNS_RRTYPE_RR, (void *)a, r->data);					mydns_rr_free(A);				}			}			rv++;		}	t->sort_level++;	/* We DID find matches for this label; thus, reply success but with no records in the		ANSWER section. */	if (!rv && section == ANSWER)	{#if DEBUG_ENABLED && DEBUG_RESOLVE		Debug("%s: no RRs match", desctask(t));#endif		if (!t->ns.size)			rrlist_add(t, AUTHORITY, DNS_RRTYPE_SOA, (void *)soa, soa->origin);		rv++;		t->sort_level++;	}

⌨️ 快捷键说明

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