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

📄 interfacemgr.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 2 页
字号:
static voidns_interface_destroy(ns_interface_t *ifp) {	isc_mem_t *mctx = ifp->mgr->mctx;	REQUIRE(NS_INTERFACE_VALID(ifp));	ns_interface_shutdown(ifp);	if (ifp->udpdispatch != NULL) {		dns_dispatch_changeattributes(ifp->udpdispatch, 0,					      DNS_DISPATCHATTR_NOLISTEN);		dns_dispatch_detach(&ifp->udpdispatch);	}	if (ifp->tcpsocket != NULL)		isc_socket_detach(&ifp->tcpsocket);	DESTROYLOCK(&ifp->lock);	ns_interfacemgr_detach(&ifp->mgr);	ifp->magic = 0;	isc_mem_put(mctx, ifp, sizeof(*ifp));}voidns_interface_attach(ns_interface_t *source, ns_interface_t **target) {	REQUIRE(NS_INTERFACE_VALID(source));	LOCK(&source->lock);	INSIST(source->references > 0);	source->references++;	UNLOCK(&source->lock);	*target = source;}voidns_interface_detach(ns_interface_t **targetp) {	isc_result_t need_destroy = ISC_FALSE;	ns_interface_t *target = *targetp;	REQUIRE(target != NULL);	REQUIRE(NS_INTERFACE_VALID(target));	LOCK(&target->lock);	REQUIRE(target->references > 0);	target->references--;	if (target->references == 0)		need_destroy = ISC_TRUE;	UNLOCK(&target->lock);	if (need_destroy)		ns_interface_destroy(target);	*targetp = NULL;}/* * Search the interface list for an interface whose address and port * both match those of 'addr'.  Return a pointer to it, or NULL if not found. */static ns_interface_t *find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {	ns_interface_t *ifp;	for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL;	     ifp = ISC_LIST_NEXT(ifp, link)) {		if (isc_sockaddr_equal(&ifp->addr, addr))			break;	}	return (ifp);}/* * Remove any interfaces whose generation number is not the current one. */static voidpurge_old_interfaces(ns_interfacemgr_t *mgr) {	ns_interface_t *ifp, *next;	for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) {		INSIST(NS_INTERFACE_VALID(ifp));		next = ISC_LIST_NEXT(ifp, link);		if (ifp->generation != mgr->generation) {			char sabuf[256];			ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);			isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));			isc_log_write(IFMGR_COMMON_LOGARGS,				      ISC_LOG_INFO,				      "no longer listening on %s", sabuf);			ns_interface_shutdown(ifp);			ns_interface_detach(&ifp);		}	}}static isc_result_tclearacl(isc_mem_t *mctx, dns_acl_t **aclp) {	dns_acl_t *newacl = NULL;	isc_result_t result;	result = dns_acl_create(mctx, 10, &newacl);	if (result != ISC_R_SUCCESS)		return (result);	dns_acl_detach(aclp);	dns_acl_attach(newacl, aclp);	dns_acl_detach(&newacl);	return (ISC_R_SUCCESS);}static isc_result_tdo_ipv4(ns_interfacemgr_t *mgr) {	isc_interfaceiter_t *iter = NULL;	isc_result_t result;	result = isc_interfaceiter_create(mgr->mctx, &iter);	if (result != ISC_R_SUCCESS)		return (result);	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;	for (result = isc_interfaceiter_first(iter);	     result == ISC_R_SUCCESS;	     result = isc_interfaceiter_next(iter))	{		ns_interface_t *ifp;		isc_interface_t interface;		ns_listenelt_t *le;		dns_aclelement_t elt;		unsigned int prefixlen;		result = isc_interfaceiter_current(iter, &interface);		if (result != ISC_R_SUCCESS)			break;		if (interface.address.family != AF_INET)			continue;		if ((interface.flags & INTERFACE_F_UP) == 0)			continue;		elt.type = dns_aclelementtype_ipprefix;		elt.negative = ISC_FALSE;		elt.u.ip_prefix.address = interface.address;		elt.u.ip_prefix.prefixlen = 32;		result = dns_acl_appendelement(mgr->aclenv.localhost, &elt);		if (result != ISC_R_SUCCESS)			goto ignore_interface;		result = isc_netaddr_masktoprefixlen(&interface.netmask,						     &prefixlen);		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;			/* XXX suppress duplicates */			result = dns_acl_appendelement(mgr->aclenv.localnets,						       &elt);			if (result != ISC_R_SUCCESS)				goto ignore_interface;		}		for (le = ISC_LIST_HEAD(mgr->listenon4->elts);		     le != NULL;		     le = ISC_LIST_NEXT(le, link))		{			int match;			isc_netaddr_t listen_netaddr;			isc_sockaddr_t listen_sockaddr;			/*			 * Construct a socket address for this IP/port			 * combination.			 */			isc_netaddr_fromin(&listen_netaddr,					   &interface.address.type.in);			isc_sockaddr_fromnetaddr(&listen_sockaddr,						 &listen_netaddr,						 le->port);			/*			 * See if the address matches the listen-on statement;			 * if not, ignore the interface.			 */			result = dns_acl_match(&listen_netaddr, NULL,					       le->acl, &mgr->aclenv,					       &match, NULL);			if (match <= 0)				continue;			ifp = find_matching_interface(mgr, &listen_sockaddr);			if (ifp != NULL) {				ifp->generation = mgr->generation;			} else {				char sabuf[ISC_SOCKADDR_FORMATSIZE];				isc_sockaddr_format(&listen_sockaddr,						    sabuf, sizeof(sabuf));				isc_log_write(IFMGR_COMMON_LOGARGS,					      ISC_LOG_INFO,					      "listening on IPv4 interface "					      "%s, %s", interface.name, sabuf);				result = ns_interface_setup(mgr,							    &listen_sockaddr,							    interface.name,							    &ifp);				if (result != ISC_R_SUCCESS) {					isc_log_write(IFMGR_COMMON_LOGARGS,						 ISC_LOG_ERROR,						 "creating IPv4 interface %s "						 "failed; interface ignored",						 interface.name);				}				/* Continue. */			}		}		continue;	ignore_interface:		isc_log_write(IFMGR_COMMON_LOGARGS,			      ISC_LOG_ERROR,			      "ignoring IPv4 interface %s: %s",			      interface.name, isc_result_totext(result));		continue;	}	if (result != ISC_R_NOMORE)		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "IPv4: interface iteration failed: %s",				 isc_result_totext(result));	else 		result = ISC_R_SUCCESS; cleanup_iter:	isc_interfaceiter_destroy(&iter);	return (result);}static isc_boolean_tlistenon_is_ip6_none(ns_listenelt_t *elt) {	if (elt->acl->length == 0)		return (ISC_TRUE); /* listen-on-v6 { } */	if (elt->acl->length > 1)		return (ISC_FALSE);  /* listen-on-v6 { ...; ...; } */	if (elt->acl->elements[0].negative == ISC_TRUE &&	    elt->acl->elements[0].type == dns_aclelementtype_any)		return (ISC_TRUE);  /* listen-on-v6 { none; } */	return (ISC_FALSE); /* All others */}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_tdo_ipv6(ns_interfacemgr_t *mgr) {	isc_result_t result;	ns_interface_t *ifp;	isc_sockaddr_t listen_addr;	struct in6_addr in6a;	ns_listenelt_t *le;	for (le = ISC_LIST_HEAD(mgr->listenon6->elts);	     le != NULL;	     le = ISC_LIST_NEXT(le, link))	{		if (listenon_is_ip6_none(le))			continue;		if (! listenon_is_ip6_any(le)) {			isc_log_write(IFMGR_COMMON_LOGARGS,				      ISC_LOG_ERROR,				      "bad IPv6 listen-on list: "				      "must be 'any' or 'none'");			return (ISC_R_FAILURE);		}		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);			if (result != ISC_R_SUCCESS) {				isc_log_write(IFMGR_COMMON_LOGARGS,					      ISC_LOG_ERROR,					      "listening on IPv6 interfaces "					      "failed");				/* Continue. */			}		}	}	return (ISC_R_SUCCESS);}voidns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) {	isc_boolean_t purge = ISC_TRUE;	REQUIRE(NS_INTERFACEMGR_VALID(mgr));	mgr->generation++;	/* Increment the generation count. */	if (isc_net_probeipv6() == ISC_R_SUCCESS) {		if (do_ipv6(mgr) != ISC_R_SUCCESS)			purge = ISC_FALSE;	}#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) {		if (do_ipv4(mgr) != ISC_R_SUCCESS)			purge = ISC_FALSE;	} else		isc_log_write(IFMGR_COMMON_LOGARGS,			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),			      "no IPv4 interfaces found");	/*	 * 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 (ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly)		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING,			      "not listening on any interfaces");}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);}

⌨️ 快捷键说明

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