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

📄 res_send.c

📁 一个C源代码分析器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ++Copyright++ 1985, 1989, 1993 * - * 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-- */#if defined(LIBC_SCCS) && !defined(lint)static char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";static char rcsid[] = "$Id: res_send.c,v 1.2 1994/07/28 21:56:28 roland Exp $";#endif /* LIBC_SCCS and not lint */	/* change this to "0"	 * if you talk to a lot	 * of multi-homed SunOS	 * ("broken") name servers.	 */#define	CHECK_SRVR_ADDR	1	/* XXX - should be in options.h *//* * Send query to name server and wait for reply. */#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 <stdio.h>#include <errno.h>#include <resolv.h>#if defined(BSD) && (BSD >= 199306)# include <stdlib.h># include <string.h>#else# include "../conf/portability.h"#endif#if defined(USE_OPTIONS_H)# include <../conf/options.h>#endifvoid _res_close __P((void));static int s = -1;	/* socket used for communications */static int connected = 0;	/* is the socket connected */static int vc = 0;	/* is the socket a virtual ciruit? */#ifndef FD_SET/* XXX - should be in portability.h */#define	NFDBITS		32#define	FD_SETSIZE	32#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))#define FD_ZERO(p)	bzero((char *)(p), sizeof(*(p)))#endif#ifndef DEBUG#   define Dprint(cond, args) /*empty*/#   define DprintQ(cond, args, query) /*empty*/#   define Aerror(file, string, error, address) /*empty*/#   define Perror(file, string, error) /*empty*/#else#   define Dprint(cond, args) if (cond) {fprintf args;} else {}#   define DprintQ(cond, args, query) if (cond) {\			fprintf args;\			__p_query(query);\		} else {}    static void    Aerror(file, string, error, address)	FILE *file;	char *string;	int error;	struct sockaddr_in address;    {	int save = errno;	if (_res.options & RES_DEBUG) {		fprintf(file, "res_send: %s ([%s].%d): %s\n",			string,			inet_ntoa(address.sin_addr),			address.sin_port,			strerror(error));	}	errno = save;    }    static void    Perror(file, string, error)	FILE *file;	char *string;	int error;    {	int save = errno;	if (_res.options & RES_DEBUG) {		fprintf(file, "res_send: %s: %s\n",			string, strerror(error));	}	errno = save;    }#endifstatic res_send_qhook Qhook = NULL;static res_send_rhook Rhook = NULL;voidres_send_setqhook(hook)	res_send_qhook hook;{	Qhook = hook;}voidres_send_setrhook(hook)	res_send_rhook hook;{	Rhook = hook;}/* int * our_server(ina) *	looks up "ina" in _res.ns_addr_list[] * returns: *	0  : not found *	>0 : found * author: *	paul vixie, 29may94 */static intour_server(inp)	const struct sockaddr_in *inp;{	struct sockaddr_in ina;	register int ns, ret;	ina = *inp;	ret = 0;	for (ns = 0;  ns < _res.nscount;  ns++) {		register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];		if (srv->sin_family == ina.sin_family &&		    srv->sin_port == ina.sin_port &&		    (srv->sin_addr.s_addr == INADDR_ANY ||		     srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {			ret++;			break;		}	}	return (ret);}/* int * name_in_query(name, type, class, buf, eom) *	look for (name,type,class) in the query section of packet (buf,eom) * returns: *	-1 : format error *	0  : not found *	>0 : found */static intname_in_query(name, type, class, buf, eom)	const char *name;	register int type, class;	const u_char *buf, *eom;{	register const u_char *cp = buf + HFIXEDSZ;	int qdcount = ntohs(((HEADER*)buf)->qdcount);	while (qdcount-- > 0) {		char tname[MAXDNAME+1];		register int n, ttype, tclass;		n = dn_expand(buf, eom, cp, tname, sizeof tname);		if (n < 0)			return (-1);		cp += n;		ttype = _getshort(cp);	cp += INT16SZ;		tclass = _getshort(cp); cp += INT16SZ;		if (ttype == type &&		    tclass == class &&		    strcasecmp(tname, name) == 0)			return (1);	}	return (0);}/* int * queries_match(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 */static intqueries_match(buf1, eom1, buf2, eom2)	const u_char *buf1, *eom1;	const u_char *buf2, *eom2;{	register const u_char *cp = buf1 + HFIXEDSZ;	int qdcount = ntohs(((HEADER*)buf1)->qdcount);	if (qdcount != ntohs(((HEADER*)buf2)->qdcount))		return (0);	while (qdcount-- > 0) {		char tname[MAXDNAME+1];		register int n, ttype, tclass;		n = dn_expand(buf1, eom1, cp, tname, sizeof tname);		if (n < 0)			return (-1);		cp += n;		ttype = _getshort(cp);	cp += INT16SZ;		tclass = _getshort(cp); cp += INT16SZ;		if (!name_in_query(tname, ttype, tclass, buf2, eom2))			return (0);	}	return (1);}intres_send(buf, buflen, ans, anssiz)	const u_char	*buf;	int		buflen;	u_char		*ans;	int		anssiz;{	HEADER		*hp = (HEADER *) buf;	HEADER		*anhp = (HEADER *) ans;	int		gotsomewhere = 0,			connreset = 0,			terrno = ETIMEDOUT;	register int	n;	int		try, v_circuit, resplen, ns;	u_int		badns;	/* XXX NSMAX can't exceed #/bits in this var */	DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),		(stdout, ";; res_send()\n"), buf);	if (!(_res.options & RES_INIT)) {		if (res_init() == -1)			return (-1);	}	v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;	badns = 0;	/*	 * Send request, RETRY times, or until successful	 */	for (try = 0; try < _res.retry; try++) {	    for (ns = 0; ns < _res.nscount; ns++) {		struct sockaddr_in *nsap = &_res.nsaddr_list[ns];    same_ns:		if (badns & (1<<ns)) {			_res_close();			goto next_ns;		}		if (Qhook) {			int done = 0, loops = 0;			do {				res_sendhookact act;				act = (*Qhook)(&nsap,					       &buf,					       &buflen,					       ans,					       anssiz,					       &resplen);				switch (act) {				case res_goahead:					done = 1;					break;				case res_nextns:					_res_close();					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:					return (-1);				}			} while (!done);		}		Dprint(_res.options & RES_DEBUG,		       (stdout, ";; Querying server (# %d) address = %s\n",			ns+1, inet_ntoa(nsap->sin_addr)));		if (v_circuit) {			int		truncated;			struct iovec	iov[2];			u_short		len;			u_char		*cp;			/*			 * Use virtual circuit;			 * at most one attempt per server.			 */			try = _res.retry;			truncated = 0;			if ((s < 0) || (!vc)) {				if (s >= 0)					_res_close();				s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);				if (s < 0) {					terrno = errno;					Perror(stderr, "socket(vc)", errno);					return (-1);				}				if (connect(s,					    (struct sockaddr *)nsap,					    sizeof(struct sockaddr))				    < 0) {					terrno = errno;					Aerror(stderr, "connect/vc",					       errno, *nsap);					badns |= (1<<ns);

⌨️ 快捷键说明

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