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

📄 res_findzonecut.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(lint) && !defined(SABER)static const char rcsid[] = "$Id: res_findzonecut.c,v 1.2.2.3.4.2 2004/03/16 12:34:18 marka Exp $";#endif /* not lint *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1999 by 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. *//* Import. */#include "port_before.h"#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <errno.h>#include <limits.h>#include <netdb.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <isc/list.h>#include "port_after.h"#include <resolv.h>/* Data structures. */typedef struct rr_a {	LINK(struct rr_a)	link;	union res_sockaddr_union addr;} rr_a;typedef LIST(rr_a) rrset_a;typedef struct rr_ns {	LINK(struct rr_ns)	link;	const char *		name;	unsigned int		flags;	rrset_a			addrs;} rr_ns;typedef LIST(rr_ns) rrset_ns;#define	RR_NS_HAVE_V4		0x01#define	RR_NS_HAVE_V6		0x02/* Forward. */static int	satisfy(res_state, const char *, rrset_ns *,			union res_sockaddr_union *, int);static int	add_addrs(res_state, rr_ns *,			  union res_sockaddr_union *, int);static int	get_soa(res_state, const char *, ns_class, int,			char *, size_t, char *, size_t,			rrset_ns *);static int	get_ns(res_state, const char *, ns_class, int, rrset_ns *);static int	get_glue(res_state, ns_class, int, rrset_ns *);static int	save_ns(res_state, ns_msg *, ns_sect,			const char *, ns_class, int, rrset_ns *);static int	save_a(res_state, ns_msg *, ns_sect,		       const char *, ns_class, int, rr_ns *);static void	free_nsrrset(rrset_ns *);static void	free_nsrr(rrset_ns *, rr_ns *);static rr_ns *	find_ns(rrset_ns *, const char *);static int	do_query(res_state, const char *, ns_class, ns_type,			 u_char *, ns_msg *);static void	res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2);/* Macros. */#define DPRINTF(x) do {\		int save_errno = errno; \		if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \		errno = save_errno; \	} while (0)/* Public. *//* * int * res_findzonecut(res, dname, class, zname, zsize, addrs, naddrs) *	find enclosing zone for a <dname,class>, and some server addresses * parameters: *	res - resolver context to work within (is modified) *	dname - domain name whose enclosing zone is desired *	class - class of dname (and its enclosing zone) *	zname - found zone name *	zsize - allocated size of zname *	addrs - found server addresses *	naddrs - max number of addrs * return values: *	< 0 - an error occurred (check errno) *	= 0 - zname is now valid, but addrs[] wasn't changed *	> 0 - zname is now valid, and return value is number of addrs[] found * notes: *	this function calls res_nsend() which means it depends on correctly *	functioning recursive nameservers (usually defined in /etc/resolv.conf *	or its local equivilent). * *	we start by asking for an SOA<dname,class>.  if we get one as an *	answer, that just means <dname,class> is a zone top, which is fine. *	more than likely we'll be told to go pound sand, in the form of a *	negative answer. * *	note that we are not prepared to deal with referrals since that would *	only come from authority servers and our correctly functioning local *	recursive server would have followed the referral and got us something *	more definite. * *	if the authority section contains an SOA, this SOA should also be the *	closest enclosing zone, since any intermediary zone cuts would've been *	returned as referrals and dealt with by our correctly functioning local *	recursive name server.  but an SOA in the authority section should NOT *	match our dname (since that would have been returned in the answer *	section).  an authority section SOA has to be "above" our dname. * *	however, since authority section SOA's were once optional, it's *	possible that we'll have to go hunting for the enclosing SOA by *	ripping labels off the front of our dname -- this is known as "doing *	it the hard way." * *	ultimately we want some server addresses, which are ideally the ones *	pertaining to the SOA.MNAME, but only if there is a matching NS RR. *	so the second phase (after we find an SOA) is to go looking for the *	NS RRset for that SOA's zone. * *	no answer section processed by this code is allowed to contain CNAME *	or DNAME RR's.  for the SOA query this means we strip a label and *	keep going.  for the NS and A queries this means we just give up. */intres_findzonecut(res_state statp, const char *dname, ns_class class, int opts,		char *zname, size_t zsize, struct in_addr *addrs, int naddrs){	int result, i;	union res_sockaddr_union *u;		opts |= RES_IPV4ONLY;	opts &= ~RES_IPV6ONLY;	u = calloc(naddrs, sizeof(*u));	if (u == NULL)		return(-1);	result = res_findzonecut2(statp, dname, class, opts, zname, zsize,				  u, naddrs);	for (i = 0; i < result; i++) {		addrs[i] = u[i].sin.sin_addr;	}	free(u);	return (result);}intres_findzonecut2(res_state statp, const char *dname, ns_class class, int opts,		 char *zname, size_t zsize, union res_sockaddr_union *addrs,		 int naddrs){	char mname[NS_MAXDNAME];	u_long save_pfcode;	rrset_ns nsrrs;	int n;	DPRINTF(("START dname='%s' class=%s, zsize=%ld, naddrs=%d",		 dname, p_class(class), (long)zsize, naddrs));	save_pfcode = statp->pfcode;	statp->pfcode |= RES_PRF_HEAD2 | RES_PRF_HEAD1 | RES_PRF_HEADX |			 RES_PRF_QUES | RES_PRF_ANS |			 RES_PRF_AUTH | RES_PRF_ADD;	INIT_LIST(nsrrs);	DPRINTF(("get the soa, and see if it has enough glue"));	if ((n = get_soa(statp, dname, class, opts, zname, zsize,			 mname, sizeof mname, &nsrrs)) < 0 ||	    ((opts & RES_EXHAUSTIVE) == 0 &&	     (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0))		goto done;	DPRINTF(("get the ns rrset and see if it has enough glue"));	if ((n = get_ns(statp, zname, class, opts, &nsrrs)) < 0 ||	    ((opts & RES_EXHAUSTIVE) == 0 &&	     (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0))		goto done;	DPRINTF(("get the missing glue and see if it's finally enough"));	if ((n = get_glue(statp, class, opts, &nsrrs)) >= 0)		n = satisfy(statp, mname, &nsrrs, addrs, naddrs); done:	DPRINTF(("FINISH n=%d (%s)", n, (n < 0) ? strerror(errno) : "OK"));	free_nsrrset(&nsrrs);	statp->pfcode = save_pfcode;	return (n);}/* Private. */static intsatisfy(res_state statp, const char *mname, rrset_ns *nsrrsp,	union res_sockaddr_union *addrs, int naddrs){	rr_ns *nsrr;	int n, x;	n = 0;	nsrr = find_ns(nsrrsp, mname);	if (nsrr != NULL) {		x = add_addrs(statp, nsrr, addrs, naddrs);		addrs += x;		naddrs -= x;		n += x;	}	for (nsrr = HEAD(*nsrrsp);	     nsrr != NULL && naddrs > 0;	     nsrr = NEXT(nsrr, link))		if (ns_samename(nsrr->name, mname) != 1) {			x = add_addrs(statp, nsrr, addrs, naddrs);			addrs += x;			naddrs -= x;			n += x;		}	DPRINTF(("satisfy(%s): %d", mname, n));	return (n);}static intadd_addrs(res_state statp, rr_ns *nsrr,	  union res_sockaddr_union *addrs, int naddrs){	rr_a *arr;	int n = 0;	for (arr = HEAD(nsrr->addrs); arr != NULL; arr = NEXT(arr, link)) {		if (naddrs <= 0)			return (0);		*addrs++ = arr->addr;		naddrs--;		n++;	}	DPRINTF(("add_addrs: %d", n));	return (n);}static intget_soa(res_state statp, const char *dname, ns_class class, int opts,	char *zname, size_t zsize, char *mname, size_t msize,	rrset_ns *nsrrsp){	char tname[NS_MAXDNAME];	u_char *resp = NULL;	int n, i, ancount, nscount;	ns_sect sect;	ns_msg msg;	u_int rcode;	/*	 * Find closest enclosing SOA, even if it's for the root zone.	 */	/* First canonicalize dname (exactly one unescaped trailing "."). */	if (ns_makecanon(dname, tname, sizeof tname) < 0)		goto cleanup;	dname = tname;	resp = malloc(NS_MAXMSG);	if (resp == NULL)		goto cleanup;	/* Now grovel the subdomains, hunting for an SOA answer or auth. */	for (;;) {		/* Leading or inter-label '.' are skipped here. */		while (*dname == '.')			dname++;		/* Is there an SOA? */		n = do_query(statp, dname, class, ns_t_soa, resp, &msg);		if (n < 0) {			DPRINTF(("get_soa: do_query('%s', %s) failed (%d)",				 dname, p_class(class), n));			goto cleanup;		}		if (n > 0) {			DPRINTF(("get_soa: CNAME or DNAME found"));			sect = ns_s_max, n = 0;		} else {			rcode = ns_msg_getflag(msg, ns_f_rcode);			ancount = ns_msg_count(msg, ns_s_an);			nscount = ns_msg_count(msg, ns_s_ns);			if (ancount > 0 && rcode == ns_r_noerror)				sect = ns_s_an, n = ancount;			else if (nscount > 0)				sect = ns_s_ns, n = nscount;			else				sect = ns_s_max, n = 0;		}		for (i = 0; i < n; i++) {			const char *t;			const u_char *rdata;			int rdlen;			ns_rr rr;			if (ns_parserr(&msg, sect, i, &rr) < 0) {				DPRINTF(("get_soa: ns_parserr(%s, %d) failed",					 p_section(sect, ns_o_query), i));				goto cleanup;			}			if (ns_rr_type(rr) == ns_t_cname ||			    ns_rr_type(rr) == ns_t_dname)				break;			if (ns_rr_type(rr) != ns_t_soa ||			    ns_rr_class(rr) != class)				continue;			t = ns_rr_name(rr);			switch (sect) {			case ns_s_an:				if (ns_samedomain(dname, t) == 0) {					DPRINTF(				    ("get_soa: ns_samedomain('%s', '%s') == 0",						dname, t)						);					errno = EPROTOTYPE;					goto cleanup;				}				break;			case ns_s_ns:				if (ns_samename(dname, t) == 1 ||				    ns_samedomain(dname, t) == 0) {					DPRINTF(		       ("get_soa: ns_samename() || !ns_samedomain('%s', '%s')",						dname, t)						);					errno = EPROTOTYPE;					goto cleanup;				}				break;			default:				abort();			}			if (strlen(t) + 1 > zsize) {

⌨️ 快捷键说明

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