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

📄 interfacemgr.c

📁 非常好的dns解析软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (ISC_R_SUCCESS);}static isc_boolean_tlistenon_is_ip6_any(ns_listenelt_t *elt) {	if (elt->acl->length != 1)		return (ISC_FALSE);	if (elt->acl->elements[0].negative == ISC_FALSE &&	    elt->acl->elements[0].type == dns_aclelementtype_any)		return (ISC_TRUE);  /* listen-on-v6 { any; } */	return (ISC_FALSE); /* All others */}static isc_result_tsetup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) {	isc_result_t result;	dns_aclelement_t elt;	unsigned int family;	unsigned int prefixlen;	family = interface->address.family;		elt.type = dns_aclelementtype_ipprefix;	elt.negative = ISC_FALSE;	elt.u.ip_prefix.address = interface->address;	elt.u.ip_prefix.prefixlen = (family == AF_INET) ? 32 : 128;	result = dns_acl_appendelement(mgr->aclenv.localhost, &elt);	if (result != ISC_R_SUCCESS)		return (result);	result = isc_netaddr_masktoprefixlen(&interface->netmask,					     &prefixlen);	/* Non contigious netmasks not allowed by IPv6 arch. */	if (result != ISC_R_SUCCESS && family == AF_INET6)		return (result);	if (result != ISC_R_SUCCESS) {		isc_log_write(IFMGR_COMMON_LOGARGS,			      ISC_LOG_WARNING,			      "omitting IPv4 interface %s from "			      "localnets ACL: %s",			      interface->name,			      isc_result_totext(result));	} else {		elt.u.ip_prefix.prefixlen = prefixlen;		if (dns_acl_elementmatch(mgr->aclenv.localnets, &elt,					 NULL) == ISC_R_NOTFOUND) {			result = dns_acl_appendelement(mgr->aclenv.localnets,						       &elt);			if (result != ISC_R_SUCCESS)				return (result);		}	}	return (ISC_R_SUCCESS);}static voidsetup_listenon(ns_interfacemgr_t *mgr, isc_interface_t *interface,	       in_port_t port){ 	isc_sockaddr_t *addr;	isc_sockaddr_t *old;	addr = isc_mem_get(mgr->mctx, sizeof(*addr));	if (addr == NULL)		return;	isc_sockaddr_fromnetaddr(addr, &interface->address, port);	for (old = ISC_LIST_HEAD(mgr->listenon);	     old != NULL;	     old = ISC_LIST_NEXT(old, link))		if (isc_sockaddr_equal(addr, old))			break;		if (old != NULL)		isc_mem_put(mgr->mctx, addr, sizeof(*addr));	else		ISC_LIST_APPEND(mgr->listenon, addr, link);}static voidclearlistenon(ns_interfacemgr_t *mgr) {	isc_sockaddr_t *old;	old = ISC_LIST_HEAD(mgr->listenon);	while (old != NULL) {		ISC_LIST_UNLINK(mgr->listenon, old, link);		isc_mem_put(mgr->mctx, old, sizeof(*old));		old = ISC_LIST_HEAD(mgr->listenon);	}}static isc_result_tdo_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,	isc_boolean_t verbose){	isc_interfaceiter_t *iter = NULL;	isc_boolean_t scan_ipv4 = ISC_FALSE;	isc_boolean_t scan_ipv6 = ISC_FALSE;	isc_boolean_t adjusting = ISC_FALSE;	isc_boolean_t ipv6only = ISC_TRUE;	isc_boolean_t ipv6pktinfo = ISC_TRUE;	isc_result_t result;	isc_netaddr_t zero_address, zero_address6;	ns_listenelt_t *le;	isc_sockaddr_t listen_addr;	ns_interface_t *ifp;	isc_boolean_t log_explicit = ISC_FALSE;	isc_boolean_t dolistenon;	if (ext_listen != NULL)		adjusting = ISC_TRUE;	if (isc_net_probeipv6() == ISC_R_SUCCESS)		scan_ipv6 = ISC_TRUE;#ifdef WANT_IPV6	else		isc_log_write(IFMGR_COMMON_LOGARGS,			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),			      "no IPv6 interfaces found");#endif	if (isc_net_probeipv4() == ISC_R_SUCCESS)		scan_ipv4 = ISC_TRUE;	else		isc_log_write(IFMGR_COMMON_LOGARGS,			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),			      "no IPv4 interfaces found");	/*	 * A special, but typical case; listen-on-v6 { any; }.	 * When we can make the socket IPv6-only, open a single wildcard	 * socket for IPv6 communication.  Otherwise, make separate socket	 * for each IPv6 address in order to avoid accepting IPv4 packets	 * as the form of mapped addresses unintentionally unless explicitly	 * allowed.	 */#ifndef ISC_ALLOW_MAPPED	if (scan_ipv6 == ISC_TRUE &&	    isc_net_probe_ipv6only() != ISC_R_SUCCESS) {		ipv6only = ISC_FALSE;		log_explicit = ISC_TRUE;	}#endif	if (scan_ipv6 == ISC_TRUE &&	    isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) {		ipv6pktinfo = ISC_FALSE;		log_explicit = ISC_TRUE;	}	if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) {		for (le = ISC_LIST_HEAD(mgr->listenon6->elts);		     le != NULL;		     le = ISC_LIST_NEXT(le, link)) {			struct in6_addr in6a;			if (!listenon_is_ip6_any(le))				continue;			in6a = in6addr_any;			isc_sockaddr_fromin6(&listen_addr, &in6a, le->port);			ifp = find_matching_interface(mgr, &listen_addr);			if (ifp != NULL) {				ifp->generation = mgr->generation;			} else {				isc_log_write(IFMGR_COMMON_LOGARGS,					      ISC_LOG_INFO,					      "listening on IPv6 "					      "interfaces, port %u",					      le->port);				result = ns_interface_setup(mgr, &listen_addr,							    "<any>", &ifp,							    ISC_TRUE);				if (result == ISC_R_SUCCESS)					ifp->flags |= NS_INTERFACEFLAG_ANYADDR;				else					isc_log_write(IFMGR_COMMON_LOGARGS,						      ISC_LOG_ERROR,						      "listening on all IPv6 "						      "interfaces failed");				/* Continue. */			}		}	}	isc_netaddr_any(&zero_address);	isc_netaddr_any6(&zero_address6);	result = isc_interfaceiter_create(mgr->mctx, &iter);	if (result != ISC_R_SUCCESS)		return (result);	if (adjusting == ISC_FALSE) {		result = clearacl(mgr->mctx, &mgr->aclenv.localhost);		if (result != ISC_R_SUCCESS)			goto cleanup_iter;		result = clearacl(mgr->mctx, &mgr->aclenv.localnets);		if (result != ISC_R_SUCCESS)			goto cleanup_iter;		clearlistenon(mgr);	}	for (result = isc_interfaceiter_first(iter);	     result == ISC_R_SUCCESS;	     result = isc_interfaceiter_next(iter))	{		isc_interface_t interface;		ns_listenlist_t *ll;		unsigned int family; 		result = isc_interfaceiter_current(iter, &interface);		if (result != ISC_R_SUCCESS)			break;		family = interface.address.family;		if (family != AF_INET && family != AF_INET6)			continue;		if (scan_ipv4 == ISC_FALSE && family == AF_INET)			continue;		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)			continue;		/*		 * Test for the address being nonzero rather than testing		 * INTERFACE_F_UP, because on some systems the latter		 * follows the media state and we could end up ignoring		 * the interface for an entire rescan interval due to		 * a temporary media glitch at rescan time.		 */		if (family == AF_INET &&		    isc_netaddr_equal(&interface.address, &zero_address)) {			continue;		}		if (family == AF_INET6 &&		    isc_netaddr_equal(&interface.address, &zero_address6)) {			continue;		}		if (adjusting == ISC_FALSE) {			result = setup_locals(mgr, &interface);			if (result != ISC_R_SUCCESS)				goto ignore_interface;		}		ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;		dolistenon = ISC_TRUE;		for (le = ISC_LIST_HEAD(ll->elts);		     le != NULL;		     le = ISC_LIST_NEXT(le, link))		{			int match;			isc_boolean_t ipv6_wildcard = ISC_FALSE;			isc_netaddr_t listen_netaddr;			isc_sockaddr_t listen_sockaddr;			/*			 * Construct a socket address for this IP/port			 * combination.			 */			if (family == AF_INET) {				isc_netaddr_fromin(&listen_netaddr,						   &interface.address.type.in);			} else {				isc_netaddr_fromin6(&listen_netaddr,						    &interface.address.type.in6);				isc_netaddr_setzone(&listen_netaddr,						    interface.address.zone);			}			isc_sockaddr_fromnetaddr(&listen_sockaddr,						 &listen_netaddr,						 le->port);			/*			 * See if the address matches the listen-on statement;			 * if not, ignore the interface.			 */			(void)dns_acl_match(&listen_netaddr, NULL, le->acl,					    &mgr->aclenv, &match, NULL);			if (match <= 0)				continue;			if (adjusting == ISC_FALSE && dolistenon == ISC_TRUE) {				setup_listenon(mgr, &interface, le->port);				dolistenon = ISC_FALSE;			}			/*			 * The case of "any" IPv6 address will require			 * special considerations later, so remember it.			 */			if (family == AF_INET6 && ipv6only && ipv6pktinfo &&			    listenon_is_ip6_any(le))				ipv6_wildcard = ISC_TRUE;			/*			 * When adjusting interfaces with extra a listening			 * list, see if the address matches the extra list.			 * If it does, and is also covered by a wildcard			 * interface, we need to listen on the address			 * explicitly.			 */			if (adjusting == ISC_TRUE) {				ns_listenelt_t *ele;				match = 0;				for (ele = ISC_LIST_HEAD(ext_listen->elts);				     ele != NULL;				     ele = ISC_LIST_NEXT(ele, link)) {					(void)dns_acl_match(&listen_netaddr,							    NULL, ele->acl,							    NULL, &match, NULL);					if (match > 0 && ele->port == le->port)						break;					else						match = 0;				}				if (ipv6_wildcard == ISC_TRUE && match == 0)					continue;			}			ifp = find_matching_interface(mgr, &listen_sockaddr);			if (ifp != NULL) {				ifp->generation = mgr->generation;			} else {				char sabuf[ISC_SOCKADDR_FORMATSIZE];				if (adjusting == ISC_FALSE &&				    ipv6_wildcard == ISC_TRUE)					continue;				if (log_explicit && family == AF_INET6 &&				    !adjusting && listenon_is_ip6_any(le)) {					isc_log_write(IFMGR_COMMON_LOGARGS,						      verbose ? ISC_LOG_INFO :							      ISC_LOG_DEBUG(1),						      "IPv6 socket API is "						      "incomplete; explicitly "						      "binding to each IPv6 "						      "address separately");					log_explicit = ISC_FALSE;				}				isc_sockaddr_format(&listen_sockaddr,						    sabuf, sizeof(sabuf));				isc_log_write(IFMGR_COMMON_LOGARGS,					      ISC_LOG_INFO,					      "%s"					      "listening on %s interface "					      "%s, %s",					      (adjusting == ISC_TRUE) ?					      "additionally " : "",					      (family == AF_INET) ?					      "IPv4" : "IPv6",					      interface.name, sabuf);				result = ns_interface_setup(mgr,							    &listen_sockaddr,							    interface.name,							    &ifp,							    (adjusting == ISC_TRUE) ?							    ISC_FALSE :							    ISC_TRUE);				if (result != ISC_R_SUCCESS) {					isc_log_write(IFMGR_COMMON_LOGARGS,						      ISC_LOG_ERROR,						      "creating %s interface "						      "%s failed; interface "						      "ignored",						      (family == AF_INET) ?						      "IPv4" : "IPv6",						      interface.name);				}				/* Continue. */			}		}		continue;	ignore_interface:		isc_log_write(IFMGR_COMMON_LOGARGS,			      ISC_LOG_ERROR,			      "ignoring %s interface %s: %s",			      (family == AF_INET) ? "IPv4" : "IPv6",			      interface.name, isc_result_totext(result));		continue;	}	if (result != ISC_R_NOMORE)		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "interface iteration failed: %s",				 isc_result_totext(result));	else 		result = ISC_R_SUCCESS; cleanup_iter:	isc_interfaceiter_destroy(&iter);	return (result);}static voidns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,		      isc_boolean_t verbose){	isc_boolean_t purge = ISC_TRUE;	REQUIRE(NS_INTERFACEMGR_VALID(mgr));	mgr->generation++;	/* Increment the generation count. */	if (do_scan(mgr, ext_listen, verbose) != ISC_R_SUCCESS)		purge = ISC_FALSE;	/*	 * Now go through the interface list and delete anything that	 * does not have the current generation number.  This is	 * how we catch interfaces that go away or change their	 * addresses.	 */	if (purge)		purge_old_interfaces(mgr);	/*	 * Warn if we are not listening on any interface, unless	 * we're in lwresd-only mode, in which case that is to 	 * be expected.	 */	if (ext_listen == NULL &&	    ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) {		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING,			      "not listening on any interfaces");	}}voidns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {	ns_interfacemgr_scan0(mgr, NULL, verbose);}voidns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list,		       isc_boolean_t verbose){	ns_interfacemgr_scan0(mgr, list, verbose);}voidns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {	LOCK(&mgr->lock);	ns_listenlist_detach(&mgr->listenon4);	ns_listenlist_attach(value, &mgr->listenon4);	UNLOCK(&mgr->lock);}voidns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {	LOCK(&mgr->lock);	ns_listenlist_detach(&mgr->listenon6);	ns_listenlist_attach(value, &mgr->listenon6);	UNLOCK(&mgr->lock);}voidns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) {	ns_interface_t *interface;	LOCK(&mgr->lock);	interface = ISC_LIST_HEAD(mgr->interfaces);	while (interface != NULL) {		if (interface->clientmgr != NULL)			ns_client_dumprecursing(f, interface->clientmgr);		interface = ISC_LIST_NEXT(interface, link);	}	UNLOCK(&mgr->lock);}isc_boolean_tns_interfacemgr_listeningon(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {	isc_sockaddr_t *old;	old = ISC_LIST_HEAD(mgr->listenon);	for (old = ISC_LIST_HEAD(mgr->listenon);	     old != NULL;	     old = ISC_LIST_NEXT(old, link))		if (isc_sockaddr_equal(old, addr))			return (ISC_TRUE);	return (ISC_FALSE);}

⌨️ 快捷键说明

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