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

📄 res_send.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1985, 1989, 1993 *    The Regents of the University of California.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: * 	This product includes software developed by the University of * 	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * Portions Copyright (c) 1993 by Digital Equipment Corporation. *  * 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, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. *  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION 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. *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-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. */#if defined(LIBC_SCCS) && !defined(lint)static const char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";static const char rcsid[] = "$Id: res_send.c,v 1.5.2.2.4.5 2004/08/10 02:19:56 marka Exp $";#endif /* LIBC_SCCS and not lint *//* * Send query to name server and wait for reply. */#include "port_before.h"#include "fd_setsize.h"#include <sys/types.h>#include <sys/param.h>#include <sys/time.h>#include <sys/socket.h>#include <sys/uio.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <arpa/inet.h>#include <errno.h>#include <netdb.h>#include <resolv.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <isc/eventlib.h>#include "port_after.h"/* Options.  Leave them on. */#define DEBUG#include "res_debug.h"#include "res_private.h"#define EXT(res) ((res)->_u._ext)static const int highestFD = FD_SETSIZE - 1;/* Forward. */static int		get_salen __P((const struct sockaddr *));static struct sockaddr * get_nsaddr __P((res_state, size_t));static int		send_vc(res_state, const u_char *, int,				u_char *, int, int *, int);static int		send_dg(res_state, const u_char *, int,				u_char *, int, int *, int,				int *, int *);static void		Aerror(const res_state, FILE *, const char *, int,			       const struct sockaddr *, int);static void		Perror(const res_state, FILE *, const char *, int);static int		sock_eq(struct sockaddr *, struct sockaddr *);#ifdef NEED_PSELECTstatic int		pselect(int, void *, void *, void *,				struct timespec *,				const sigset_t *);#endifvoid res_pquery(const res_state, const u_char *, int, FILE *);static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;/* Public. *//* int * res_isourserver(ina) *	looks up "ina" in _res.ns_addr_list[] * returns: *	0  : not found *	>0 : found * author: *	paul vixie, 29may94 */intres_ourserver_p(const res_state statp, const struct sockaddr *sa) {	const struct sockaddr_in *inp, *srv;	const struct sockaddr_in6 *in6p, *srv6;	int ns;	switch (sa->sa_family) {	case AF_INET:		inp = (const struct sockaddr_in *)sa;		for (ns = 0;  ns < statp->nscount;  ns++) {			srv = (struct sockaddr_in *)get_nsaddr(statp, ns);			if (srv->sin_family == inp->sin_family &&			    srv->sin_port == inp->sin_port &&			    (srv->sin_addr.s_addr == INADDR_ANY ||			     srv->sin_addr.s_addr == inp->sin_addr.s_addr))				return (1);		}		break;	case AF_INET6:		if (EXT(statp).ext == NULL)			break;		in6p = (const struct sockaddr_in6 *)sa;		for (ns = 0;  ns < statp->nscount;  ns++) {			srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);			if (srv6->sin6_family == in6p->sin6_family &&			    srv6->sin6_port == in6p->sin6_port &&#ifdef HAVE_SIN6_SCOPE_ID			    (srv6->sin6_scope_id == 0 ||			     srv6->sin6_scope_id == in6p->sin6_scope_id) &&#endif			    (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||			     IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))				return (1);		}		break;	default:		break;	}	return (0);}/* int * res_nameinquery(name, type, class, buf, eom) *	look for (name,type,class) in the query section of packet (buf,eom) * requires: *	buf + HFIXEDSZ <= eom * returns: *	-1 : format error *	0  : not found *	>0 : found * author: *	paul vixie, 29may94 */intres_nameinquery(const char *name, int type, int class,		const u_char *buf, const u_char *eom){	const u_char *cp = buf + HFIXEDSZ;	int qdcount = ntohs(((const HEADER*)buf)->qdcount);	while (qdcount-- > 0) {		char tname[MAXDNAME+1];		int n, ttype, tclass;		n = dn_expand(buf, eom, cp, tname, sizeof tname);		if (n < 0)			return (-1);		cp += n;		if (cp + 2 * INT16SZ > eom)			return (-1);		ttype = ns_get16(cp); cp += INT16SZ;		tclass = ns_get16(cp); cp += INT16SZ;		if (ttype == type && tclass == class &&		    ns_samename(tname, name) == 1)			return (1);	}	return (0);}/* int * res_queriesmatch(buf1, eom1, buf2, eom2) *	is there a 1:1 mapping of (name,type,class) *	in (buf1,eom1) and (buf2,eom2)? * returns: *	-1 : format error *	0  : not a 1:1 mapping *	>0 : is a 1:1 mapping * author: *	paul vixie, 29may94 */intres_queriesmatch(const u_char *buf1, const u_char *eom1,		 const u_char *buf2, const u_char *eom2){	const u_char *cp = buf1 + HFIXEDSZ;	int qdcount = ntohs(((const HEADER*)buf1)->qdcount);	if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)		return (-1);	/*	 * Only header section present in replies to	 * dynamic update packets.	 */	if ((((const HEADER *)buf1)->opcode == ns_o_update) &&	    (((const HEADER *)buf2)->opcode == ns_o_update))		return (1);	if (qdcount != ntohs(((const HEADER*)buf2)->qdcount))		return (0);	while (qdcount-- > 0) {		char tname[MAXDNAME+1];		int n, ttype, tclass;		n = dn_expand(buf1, eom1, cp, tname, sizeof tname);		if (n < 0)			return (-1);		cp += n;		if (cp + 2 * INT16SZ > eom1)			return (-1);		ttype = ns_get16(cp);	cp += INT16SZ;		tclass = ns_get16(cp); cp += INT16SZ;		if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))			return (0);	}	return (1);}intres_nsend(res_state statp,	  const u_char *buf, int buflen, u_char *ans, int anssiz){	int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;	char abuf[NI_MAXHOST];	if (statp->nscount == 0) {		errno = ESRCH;		return (-1);	}	if (anssiz < HFIXEDSZ) {		errno = EINVAL;		return (-1);	}	DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),		(stdout, ";; res_send()\n"), buf, buflen);	v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;	gotsomewhere = 0;	terrno = ETIMEDOUT;	/*	 * If the ns_addr_list in the resolver context has changed, then	 * invalidate our cached copy and the associated timing data.	 */	if (EXT(statp).nscount != 0) {		int needclose = 0;		struct sockaddr_storage peer;		ISC_SOCKLEN_T peerlen;		if (EXT(statp).nscount != statp->nscount)			needclose++;		else			for (ns = 0; ns < statp->nscount; ns++) {				if (statp->nsaddr_list[ns].sin_family &&				    !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],					     (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {					needclose++;					break;				}				if (EXT(statp).nssocks[ns] == -1)					continue;				peerlen = sizeof(peer);				if (getsockname(EXT(statp).nssocks[ns],				    (struct sockaddr *)&peer, &peerlen) < 0) {					needclose++;					break;				}				if (!sock_eq((struct sockaddr *)&peer,				    get_nsaddr(statp, ns))) {					needclose++;					break;				}			}		if (needclose) {			res_nclose(statp);			EXT(statp).nscount = 0;		}	}	/*	 * Maybe initialize our private copy of the ns_addr_list.	 */	if (EXT(statp).nscount == 0) {		for (ns = 0; ns < statp->nscount; ns++) {			EXT(statp).nstimes[ns] = RES_MAXTIME;			EXT(statp).nssocks[ns] = -1;			if (!statp->nsaddr_list[ns].sin_family)				continue;			EXT(statp).ext->nsaddrs[ns].sin =				 statp->nsaddr_list[ns];		}		EXT(statp).nscount = statp->nscount;	}	/*	 * Some resolvers want to even out the load on their nameservers.	 * Note that RES_BLAST overrides RES_ROTATE.	 */	if ((statp->options & RES_ROTATE) != 0U &&	    (statp->options & RES_BLAST) == 0U) {		union res_sockaddr_union inu;		struct sockaddr_in ina;		int lastns = statp->nscount - 1;		int fd;		u_int16_t nstime;		if (EXT(statp).ext != NULL)			inu = EXT(statp).ext->nsaddrs[0];		ina = statp->nsaddr_list[0];		fd = EXT(statp).nssocks[0];		nstime = EXT(statp).nstimes[0];		for (ns = 0; ns < lastns; ns++) {			if (EXT(statp).ext != NULL)                                EXT(statp).ext->nsaddrs[ns] = 					EXT(statp).ext->nsaddrs[ns + 1];			statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];			EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];			EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];		}		if (EXT(statp).ext != NULL)			EXT(statp).ext->nsaddrs[lastns] = inu;		statp->nsaddr_list[lastns] = ina;		EXT(statp).nssocks[lastns] = fd;		EXT(statp).nstimes[lastns] = nstime;	}	/*	 * Send request, RETRY times, or until successful.	 */	for (try = 0; try < statp->retry; try++) {	    for (ns = 0; ns < statp->nscount; ns++) {		struct sockaddr *nsap;		int nsaplen;		nsap = get_nsaddr(statp, ns);		nsaplen = get_salen(nsap);		statp->_flags &= ~RES_F_LASTMASK;		statp->_flags |= (ns << RES_F_LASTSHIFT); same_ns:		if (statp->qhook) {			int done = 0, loops = 0;			do {				res_sendhookact act;				act = (*statp->qhook)(&nsap, &buf, &buflen,						      ans, anssiz, &resplen);				switch (act) {				case res_goahead:					done = 1;					break;				case res_nextns:					res_nclose(statp);					goto next_ns;				case res_done:					return (resplen);				case res_modified:					/* give the hook another try */					if (++loops < 42) /*doug adams*/						break;					/*FALLTHROUGH*/				case res_error:					/*FALLTHROUGH*/				default:					goto fail;				}			} while (!done);		}		Dprint(((statp->options & RES_DEBUG) &&			getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),				    NULL, 0, niflags) == 0),		       (stdout, ";; Querying server (# %d) address = %s\n",			ns + 1, abuf));		if (v_circuit) {			/* Use VC; at most one attempt per server. */			try = statp->retry;			n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,				    ns);			if (n < 0)				goto fail;			if (n == 0)				goto next_ns;			resplen = n;		} else {			/* Use datagrams. */			n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,				    ns, &v_circuit, &gotsomewhere);			if (n < 0)				goto fail;			if (n == 0)				goto next_ns;			if (v_circuit)				goto same_ns;			resplen = n;		}		Dprint((statp->options & RES_DEBUG) ||		       ((statp->pfcode & RES_PRF_REPLY) &&			(statp->pfcode & RES_PRF_HEAD1)),		       (stdout, ";; got answer:\n"));		DprintQ((statp->options & RES_DEBUG) ||			(statp->pfcode & RES_PRF_REPLY),			(stdout, "%s", ""),			ans, (resplen > anssiz) ? anssiz : resplen);		/*		 * If we have temporarily opened a virtual circuit,		 * or if we haven't been asked to keep a socket open,		 * close the socket.		 */		if ((v_circuit && (statp->options & RES_USEVC) == 0U) ||		    (statp->options & RES_STAYOPEN) == 0U) {			res_nclose(statp);		}		if (statp->rhook) {			int done = 0, loops = 0;			do {				res_sendhookact act;				act = (*statp->rhook)(nsap, buf, buflen,						      ans, anssiz, &resplen);				switch (act) {				case res_goahead:				case res_done:					done = 1;					break;				case res_nextns:					res_nclose(statp);					goto next_ns;				case res_modified:					/* give the hook another try */					if (++loops < 42) /*doug adams*/						break;					/*FALLTHROUGH*/				case res_error:					/*FALLTHROUGH*/				default:					goto fail;				}			} while (!done);		}		return (resplen); next_ns: ;	   } /*foreach ns*/	} /*foreach retry*/	res_nclose(statp);	if (!v_circuit) {		if (!gotsomewhere)			errno = ECONNREFUSED;	/* no nameservers found */		else			errno = ETIMEDOUT;	/* no answer obtained */	} else		errno = terrno;	return (-1); fail:	res_nclose(statp);	return (-1);}/* Private */static intget_salen(sa)	const struct sockaddr *sa;{

⌨️ 快捷键说明

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