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

📄 getaddrinfo.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!strchr(hostname, '.') &&	    (cp = res_hostalias(net_data->res, hostname,				tmp, sizeof(tmp))))		hostname = cp;	result = (*ho->addrinfo)(ho, hostname, pai);	if (!net_data->ho_stayopen) {		(*ho->minimize)(ho);	}	if (result == NULL) {		int e = h_errno;		switch(e) {		case NETDB_INTERNAL:			error = EAI_SYSTEM;			break;		case TRY_AGAIN:			error = EAI_AGAIN;			break;		case NO_RECOVERY:			error = EAI_FAIL;			break;		case HOST_NOT_FOUND:		case NO_DATA:			error = EAI_NONAME;			break;		default:		case NETDB_SUCCESS: /* should be impossible... */			error = EAI_NONAME;			break;		}		goto free;	}	for (cur = result; cur; cur = cur->ai_next) {		GET_PORT(cur, servname); /* XXX: redundant lookups... */		/* canonname should already be filled. */	}	*res = result;	return(0);free:	if (result)		freeaddrinfo(result);	return error;}static intexplore_copy(pai, src0, res)	const struct addrinfo *pai;	/* seed */	const struct addrinfo *src0;	/* source */	struct addrinfo **res;{	int error;	struct addrinfo sentinel, *cur;	const struct addrinfo *src;	error = 0;	sentinel.ai_next = NULL;	cur = &sentinel;	for (src = src0; src != NULL; src = src->ai_next) {		if (src->ai_family != pai->ai_family)			continue;		cur->ai_next = copy_ai(src);		if (!cur->ai_next) {			error = EAI_MEMORY;			goto fail;		}		cur->ai_next->ai_socktype = pai->ai_socktype;		cur->ai_next->ai_protocol = pai->ai_protocol;		cur = cur->ai_next;	}	*res = sentinel.ai_next;	return 0;fail:	freeaddrinfo(sentinel.ai_next);	return error;}/* * hostname == NULL. * passive socket -> anyaddr (0.0.0.0 or ::) * non-passive socket -> localhost (127.0.0.1 or ::1) */static intexplore_null(pai, servname, res)	const struct addrinfo *pai;	const char *servname;	struct addrinfo **res;{	const struct afd *afd;	struct addrinfo *cur;	struct addrinfo sentinel;	int error;	*res = NULL;	sentinel.ai_next = NULL;	cur = &sentinel;	afd = find_afd(pai->ai_family);	if (afd == NULL)		return 0;	if (pai->ai_flags & AI_PASSIVE) {		GET_AI(cur->ai_next, afd, afd->a_addrany);		/* xxx meaningless?		 * GET_CANONNAME(cur->ai_next, "anyaddr");		 */		GET_PORT(cur->ai_next, servname);	} else {		GET_AI(cur->ai_next, afd, afd->a_loopback);		/* xxx meaningless?		 * GET_CANONNAME(cur->ai_next, "localhost");		 */		GET_PORT(cur->ai_next, servname);	}	cur = cur->ai_next;	*res = sentinel.ai_next;	return 0;free:	if (sentinel.ai_next)		freeaddrinfo(sentinel.ai_next);	return error;}/* * numeric hostname */static intexplore_numeric(pai, hostname, servname, res)	const struct addrinfo *pai;	const char *hostname;	const char *servname;	struct addrinfo **res;{	const struct afd *afd;	struct addrinfo *cur;	struct addrinfo sentinel;	int error;	char pton[PTON_MAX];	*res = NULL;	sentinel.ai_next = NULL;	cur = &sentinel;	afd = find_afd(pai->ai_family);	if (afd == NULL)		return 0;	switch (afd->a_af) {#if 0 /*X/Open spec*/	case AF_INET:		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {			if (pai->ai_family == afd->a_af ||			    pai->ai_family == PF_UNSPEC /*?*/) {				GET_AI(cur->ai_next, afd, pton);				GET_PORT(cur->ai_next, servname);				while (cur && cur->ai_next)					cur = cur->ai_next;			} else				ERR(EAI_FAMILY);	/*xxx*/		}		break;#endif	default:		if (inet_pton(afd->a_af, hostname, pton) == 1) {			if (pai->ai_family == afd->a_af ||			    pai->ai_family == PF_UNSPEC /*?*/) {				GET_AI(cur->ai_next, afd, pton);				GET_PORT(cur->ai_next, servname);				while (cur && cur->ai_next)					cur = cur->ai_next;			} else				ERR(EAI_FAMILY);	/*xxx*/		}		break;	}	*res = sentinel.ai_next;	return 0;free:bad:	if (sentinel.ai_next)		freeaddrinfo(sentinel.ai_next);	return error;}/* * numeric hostname with scope */static intexplore_numeric_scope(pai, hostname, servname, res)	const struct addrinfo *pai;	const char *hostname;	const char *servname;	struct addrinfo **res;{#ifndef SCOPE_DELIMITER	return explore_numeric(pai, hostname, servname, res);#else	const struct afd *afd;	struct addrinfo *cur;	int error;	char *cp, *hostname2 = NULL, *scope, *addr;	struct sockaddr_in6 *sin6;	afd = find_afd(pai->ai_family);	if (afd == NULL)		return 0;	if (!afd->a_scoped)		return explore_numeric(pai, hostname, servname, res);	cp = strchr(hostname, SCOPE_DELIMITER);	if (cp == NULL)		return explore_numeric(pai, hostname, servname, res);	/*	 * Handle special case of <scoped_address><delimiter><scope id>	 */	hostname2 = strdup(hostname);	if (hostname2 == NULL)		return EAI_MEMORY;	/* terminate at the delimiter */	hostname2[cp - hostname] = '\0';	addr = hostname2;	scope = cp + 1;	error = explore_numeric(pai, addr, servname, res);	if (error == 0) {		u_int32_t scopeid = 0;		for (cur = *res; cur; cur = cur->ai_next) {			if (cur->ai_family != AF_INET6)				continue;			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;			if (!ip6_str2scopeid(scope, sin6, &scopeid)) {				free(hostname2);				return(EAI_NONAME); /* XXX: is return OK? */			}#ifdef HAVE_SIN6_SCOPE_ID			sin6->sin6_scope_id = scopeid;#endif		}	}	free(hostname2);	return error;#endif}static intget_canonname(pai, ai, str)	const struct addrinfo *pai;	struct addrinfo *ai;	const char *str;{	if ((pai->ai_flags & AI_CANONNAME) != 0) {		ai->ai_canonname = (char *)malloc(strlen(str) + 1);		if (ai->ai_canonname == NULL)			return EAI_MEMORY;		strcpy(ai->ai_canonname, str);	}	return 0;}static struct addrinfo *get_ai(pai, afd, addr)	const struct addrinfo *pai;	const struct afd *afd;	const char *addr;{	char *p;	struct addrinfo *ai;	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)		+ (afd->a_socklen));	if (ai == NULL)		return NULL;	memcpy(ai, pai, sizeof(struct addrinfo));	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);#ifdef HAVE_SA_LEN	ai->ai_addr->sa_len = afd->a_socklen;#endif	ai->ai_addrlen = afd->a_socklen;	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;	p = (char *)(void *)(ai->ai_addr);	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);	return ai;}/* XXX need to malloc() the same way we do from other functions! */static struct addrinfo *copy_ai(pai)	const struct addrinfo *pai;{	struct addrinfo *ai;	size_t l;	l = sizeof(*ai) + pai->ai_addrlen;	if ((ai = (struct addrinfo *)malloc(l)) == NULL)		return NULL;	memset(ai, 0, l);	memcpy(ai, pai, sizeof(*ai));	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);	memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen);	if (pai->ai_canonname) {		l = strlen(pai->ai_canonname) + 1;		if ((ai->ai_canonname = malloc(l)) == NULL) {			free(ai);			return NULL;		}		strcpy(ai->ai_canonname, pai->ai_canonname);	/* (checked) */	} else {		/* just to make sure */		ai->ai_canonname = NULL;	}	ai->ai_next = NULL;	return ai;}static intget_portmatch(const struct addrinfo *ai, const char *servname) {	/* get_port does not touch first argument. when matchonly == 1. */	/* LINTED const cast */	return get_port((const struct addrinfo *)ai, servname, 1);}static intget_port(const struct addrinfo *ai, const char *servname, int matchonly) {	const char *proto;	struct servent *sp;	int port;	int allownumeric;	if (servname == NULL)		return 0;	switch (ai->ai_family) {	case AF_INET:#ifdef AF_INET6	case AF_INET6:#endif		break;	default:		return 0;	}	switch (ai->ai_socktype) {	case SOCK_RAW:		return EAI_SERVICE;	case SOCK_DGRAM:	case SOCK_STREAM:		allownumeric = 1;		break;	case ANY:		switch (ai->ai_family) {		case AF_INET:#ifdef AF_INET6		case AF_INET6:#endif			allownumeric = 1;			break;		default:			allownumeric = 0;			break;		}		break;	default:		return EAI_SOCKTYPE;	}	if (str_isnumber(servname)) {		if (!allownumeric)			return EAI_SERVICE;		port = atoi(servname);		if (port < 0 || port > 65535)			return EAI_SERVICE;		port = htons(port);	} else {		switch (ai->ai_socktype) {		case SOCK_DGRAM:			proto = "udp";			break;		case SOCK_STREAM:			proto = "tcp";			break;		default:			proto = NULL;			break;		}		if ((sp = getservbyname(servname, proto)) == NULL)			return EAI_SERVICE;		port = sp->s_port;	}	if (!matchonly) {		switch (ai->ai_family) {		case AF_INET:			((struct sockaddr_in *)(void *)			    ai->ai_addr)->sin_port = port;			break;		case AF_INET6:			((struct sockaddr_in6 *)(void *)			    ai->ai_addr)->sin6_port = port;			break;		}	}	return 0;}static const struct afd *find_afd(af)	int af;{	const struct afd *afd;	if (af == PF_UNSPEC)		return NULL;	for (afd = afdl; afd->a_af; afd++) {		if (afd->a_af == af)			return afd;	}	return NULL;}/* * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend * will take care of it. * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure * if the code is right or not. */static intaddrconfig(af)	int af;{	int s;	/* XXX errno */	s = socket(af, SOCK_DGRAM, 0);	if (s < 0) {		if (errno != EMFILE)			return 0;	} else		close(s);	return 1;}/* convert a string to a scope identifier. XXX: IPv6 specific */static intip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6,		u_int32_t *scopeidp){	u_int32_t scopeid;	u_long lscopeid;	struct in6_addr *a6 = &sin6->sin6_addr;	char *ep;		/* empty scopeid portion is invalid */	if (*scope == '\0')		return (0);#ifdef USE_IFNAMELINKID	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||	    IN6_IS_ADDR_MC_NODELOCAL(a6)) {		/*		 * Using interface names as link indices can be allowed		 * only when we can assume a one-to-one mappings between		 * links and interfaces.  See comments in getnameinfo.c.		 */		scopeid = if_nametoindex(scope);		if (scopeid == 0)			goto trynumeric;		*scopeidp = scopeid;		return (1);	}#endif	/* still unclear about literal, allow numeric only - placeholder */	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))		goto trynumeric;	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))		goto trynumeric;	else		goto trynumeric;	/* global */	/* try to convert to a numeric id as a last resort */trynumeric:	errno = 0;	lscopeid = strtoul(scope, &ep, 10);	scopeid = lscopeid & 0xffffffff;	if (errno == 0 && ep && *ep == '\0' && scopeid == lscopeid) {		*scopeidp = scopeid;		return (1);	} else		return (0);}struct addrinfo *hostent2addrinfo(hp, pai)	struct hostent *hp;	const struct addrinfo *pai;{	int i, af, error = 0;	char **aplist = NULL, *ap;	struct addrinfo sentinel, *cur;	const struct afd *afd;	af = hp->h_addrtype;	if (pai->ai_family != AF_UNSPEC && af != pai->ai_family)		return(NULL);	afd = find_afd(af);	if (afd == NULL)		return(NULL);	aplist = hp->h_addr_list;	memset(&sentinel, 0, sizeof(sentinel));	cur = &sentinel;	for (i = 0; (ap = aplist[i]) != NULL; i++) {#if 0				/* the trick seems too much */		af = hp->h_addr_list;		if (af == AF_INET6 &&		    IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {			af = AF_INET;			ap = ap + sizeof(struct in6_addr)				- sizeof(struct in_addr);		}		afd = find_afd(af);		if (afd == NULL)			continue;#endif /* 0 */		GET_AI(cur->ai_next, afd, ap);		/* GET_PORT(cur->ai_next, servname); */		if ((pai->ai_flags & AI_CANONNAME) != 0) {			/*			 * RFC2553 says that ai_canonname will be set only for			 * the first element.  we do it for all the elements,			 * just for convenience.			 */			GET_CANONNAME(cur->ai_next, hp->h_name);		}		while (cur && cur->ai_next) /* no need to loop, actually. */			cur = cur->ai_next;		continue;	free:		if (cur->ai_next)			freeaddrinfo(cur->ai_next);		cur->ai_next = NULL;		/* continue, without tht pointer CUR advanced. */	}	return(sentinel.ai_next);}struct addrinfo *addr2addrinfo(pai, cp)	const struct addrinfo *pai;	const char *cp;{	const struct afd *afd;	afd = find_afd(pai->ai_family);	if (afd == NULL)		return(NULL);	return(get_ai(pai, afd, cp));}static struct net_data *init(){	struct net_data *net_data;	if (!(net_data = net_data_init(NULL)))		goto error;	if (!net_data->ho) {		net_data->ho = (*net_data->irs->ho_map)(net_data->irs);		if (!net_data->ho || !net_data->res) {error:			errno = EIO;			if (net_data && net_data->res)				RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);			return (NULL);		}		(*net_data->ho->res_set)(net_data->ho, net_data->res, NULL);	}	return (net_data);}

⌨️ 快捷键说明

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