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

📄 interfacemgr.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002  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. *//* $Id: interfacemgr.c,v 1.59.2.5.8.15 2004/08/10 04:56:23 jinmei Exp $ */#include <config.h>#include <isc/interfaceiter.h>#include <isc/string.h>#include <isc/task.h>#include <isc/util.h>#include <dns/acl.h>#include <dns/dispatch.h>#include <named/client.h>#include <named/log.h>#include <named/interfacemgr.h>#define IFMGR_MAGIC			ISC_MAGIC('I', 'F', 'M', 'G')#define NS_INTERFACEMGR_VALID(t)	ISC_MAGIC_VALID(t, IFMGR_MAGIC)#define IFMGR_COMMON_LOGARGS \	ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGRstruct ns_interfacemgr {	unsigned int		magic;		/* Magic number. */	int			references;	isc_mutex_t		lock;	isc_mem_t *		mctx;		/* Memory context. */	isc_taskmgr_t *		taskmgr;	/* Task manager. */	isc_socketmgr_t *	socketmgr;	/* Socket manager. */	dns_dispatchmgr_t *	dispatchmgr;	unsigned int		generation;	/* Current generation no. */	ns_listenlist_t *	listenon4;	ns_listenlist_t *	listenon6;	dns_aclenv_t		aclenv;		/* Localhost/localnets ACLs */	ISC_LIST(ns_interface_t) interfaces;	/* List of interfaces. */};static voidpurge_old_interfaces(ns_interfacemgr_t *mgr);isc_result_tns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,		       isc_socketmgr_t *socketmgr,		       dns_dispatchmgr_t *dispatchmgr,		       ns_interfacemgr_t **mgrp){	isc_result_t result;	ns_interfacemgr_t *mgr;	REQUIRE(mctx != NULL);	REQUIRE(mgrp != NULL);	REQUIRE(*mgrp == NULL);	mgr = isc_mem_get(mctx, sizeof(*mgr));	if (mgr == NULL)		return (ISC_R_NOMEMORY);	result = isc_mutex_init(&mgr->lock);	if (result != ISC_R_SUCCESS)		goto cleanup_mem;	mgr->mctx = mctx;	mgr->taskmgr = taskmgr;	mgr->socketmgr = socketmgr;	mgr->dispatchmgr = dispatchmgr;	mgr->generation = 1;	mgr->listenon4 = NULL;	mgr->listenon6 = NULL;		ISC_LIST_INIT(mgr->interfaces);	/*	 * The listen-on lists are initially empty.	 */	result = ns_listenlist_create(mctx, &mgr->listenon4);	if (result != ISC_R_SUCCESS)		goto cleanup_mem;	ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);	result = dns_aclenv_init(mctx, &mgr->aclenv);	if (result != ISC_R_SUCCESS)		goto cleanup_listenon;	mgr->references = 1;	mgr->magic = IFMGR_MAGIC;	*mgrp = mgr;	return (ISC_R_SUCCESS); cleanup_listenon:	ns_listenlist_detach(&mgr->listenon4);	ns_listenlist_detach(&mgr->listenon6); cleanup_mem:	isc_mem_put(mctx, mgr, sizeof(*mgr));	return (result);}static voidns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {	REQUIRE(NS_INTERFACEMGR_VALID(mgr));	dns_aclenv_destroy(&mgr->aclenv);	ns_listenlist_detach(&mgr->listenon4);	ns_listenlist_detach(&mgr->listenon6);	DESTROYLOCK(&mgr->lock);	mgr->magic = 0;	isc_mem_put(mgr->mctx, mgr, sizeof(*mgr));}dns_aclenv_t *ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {	return (&mgr->aclenv);}voidns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) {	REQUIRE(NS_INTERFACEMGR_VALID(source));	LOCK(&source->lock);	INSIST(source->references > 0);	source->references++;	UNLOCK(&source->lock);	*target = source;}voidns_interfacemgr_detach(ns_interfacemgr_t **targetp) {	isc_result_t need_destroy = ISC_FALSE;	ns_interfacemgr_t *target = *targetp;	REQUIRE(target != NULL);	REQUIRE(NS_INTERFACEMGR_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_interfacemgr_destroy(target);	*targetp = NULL;}voidns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {	REQUIRE(NS_INTERFACEMGR_VALID(mgr));	/*	 * Shut down and detach all interfaces.	 * By incrementing the generation count, we make purge_old_interfaces()	 * consider all interfaces "old".	 */	mgr->generation++;	purge_old_interfaces(mgr);}static isc_result_tns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,		    const char *name, ns_interface_t **ifpret){	ns_interface_t *ifp;	isc_result_t result;	REQUIRE(NS_INTERFACEMGR_VALID(mgr));	ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));	if (ifp == NULL)		return (ISC_R_NOMEMORY);	ifp->mgr = NULL;	ifp->generation = mgr->generation;	ifp->addr = *addr;	strncpy(ifp->name, name, sizeof(ifp->name));	ifp->name[sizeof(ifp->name)-1] = '\0';	ifp->clientmgr = NULL;	result = isc_mutex_init(&ifp->lock);	if (result != ISC_R_SUCCESS)		goto lock_create_failure;	result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr,				     ns_g_timermgr,				     &ifp->clientmgr);	if (result != ISC_R_SUCCESS) {		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,			      "ns_clientmgr_create() failed: %s",			      isc_result_totext(result));		goto clientmgr_create_failure;	}	ifp->udpdispatch = NULL;	ifp->tcpsocket = NULL;	/*	 * Create a single TCP client object.  It will replace itself	 * with a new one as soon as it gets a connection, so the actual	 * connections will be handled in parallel even though there is	 * only one client initially.	 */	ifp->ntcptarget = 1;	ifp->ntcpcurrent = 0;	ISC_LINK_INIT(ifp, link);	ns_interfacemgr_attach(mgr, &ifp->mgr);	ISC_LIST_APPEND(mgr->interfaces, ifp, link);	ifp->references = 1;	ifp->magic = IFACE_MAGIC;	*ifpret = ifp;	return (ISC_R_SUCCESS); clientmgr_create_failure:	DESTROYLOCK(&ifp->lock); lock_create_failure:	ifp->magic = 0;	isc_mem_put(mgr->mctx, ifp, sizeof(*ifp));	return (ISC_R_UNEXPECTED);}static isc_result_tns_interface_listenudp(ns_interface_t *ifp) {	isc_result_t result;	unsigned int attrs;	unsigned int attrmask;	attrs = 0;	attrs |= DNS_DISPATCHATTR_UDP;	if (isc_sockaddr_pf(&ifp->addr) == AF_INET)		attrs |= DNS_DISPATCHATTR_IPV4;	else		attrs |= DNS_DISPATCHATTR_IPV6;	attrs |= DNS_DISPATCHATTR_NOLISTEN;	attrmask = 0;	attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;	attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;	result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr,				     ns_g_taskmgr, &ifp->addr,				     4096, 1000, 32768, 8219, 8237,				     attrs, attrmask, &ifp->udpdispatch);	if (result != ISC_R_SUCCESS) {		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,			      "could not listen on UDP socket: %s",			      isc_result_totext(result));		goto udp_dispatch_failure;	}	result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus,					    ifp, ISC_FALSE);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "UDP ns_clientmgr_createclients(): %s",				 isc_result_totext(result));		goto addtodispatch_failure;	}	return (ISC_R_SUCCESS); addtodispatch_failure:	dns_dispatch_changeattributes(ifp->udpdispatch, 0,				      DNS_DISPATCHATTR_NOLISTEN);	dns_dispatch_detach(&ifp->udpdispatch); udp_dispatch_failure:	return (result);}static isc_result_tns_interface_accepttcp(ns_interface_t *ifp) {	isc_result_t result;	/*	 * Open a TCP socket.	 */	result = isc_socket_create(ifp->mgr->socketmgr,				   isc_sockaddr_pf(&ifp->addr),				   isc_sockettype_tcp,				   &ifp->tcpsocket);	if (result != ISC_R_SUCCESS) {		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,				 "creating TCP socket: %s",				 isc_result_totext(result));		goto tcp_socket_failure;	}#ifndef ISC_ALLOW_MAPPED	isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE);#endif	result = isc_socket_bind(ifp->tcpsocket, &ifp->addr);	if (result != ISC_R_SUCCESS) {		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,				 "binding TCP socket: %s",				 isc_result_totext(result));		goto tcp_bind_failure;	}	result = isc_socket_listen(ifp->tcpsocket, ns_g_listen);	if (result != ISC_R_SUCCESS) {		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,				 "listening on TCP socket: %s",				 isc_result_totext(result));		goto tcp_listen_failure;	}	/* 	 * If/when there a multiple filters listen to the	 * result.	 */	(void)isc_socket_filter(ifp->tcpsocket, "dataready");	result = ns_clientmgr_createclients(ifp->clientmgr,					    ifp->ntcptarget, ifp,					    ISC_TRUE);	if (result != ISC_R_SUCCESS) {		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "TCP ns_clientmgr_createclients(): %s",				 isc_result_totext(result));		goto accepttcp_failure;	}	return (ISC_R_SUCCESS); accepttcp_failure: tcp_listen_failure: tcp_bind_failure:	isc_socket_detach(&ifp->tcpsocket); tcp_socket_failure:	return (ISC_R_SUCCESS);}static isc_result_tns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,		   const char *name, ns_interface_t **ifpret,		   isc_boolean_t accept_tcp){	isc_result_t result;	ns_interface_t *ifp = NULL;	REQUIRE(ifpret != NULL && *ifpret == NULL);	result = ns_interface_create(mgr, addr, name, &ifp);	if (result != ISC_R_SUCCESS)		return (result);	result = ns_interface_listenudp(ifp);	if (result != ISC_R_SUCCESS)		goto cleanup_interface;	if (accept_tcp == ISC_TRUE) {		result = ns_interface_accepttcp(ifp);		if (result != ISC_R_SUCCESS) {			/*			 * XXXRTH We don't currently have a way to easily stop			 * dispatch service, so we currently return			 * ISC_R_SUCCESS (the UDP stuff will work even if TCP			 * creation failed).  This will be fixed later.			 */			result = ISC_R_SUCCESS;		}	}	*ifpret = ifp;	return (ISC_R_SUCCESS); cleanup_interface:	ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);	ns_interface_detach(&ifp);	return (result);}voidns_interface_shutdown(ns_interface_t *ifp) {	if (ifp->clientmgr != NULL)		ns_clientmgr_destroy(&ifp->clientmgr);}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));

⌨️ 快捷键说明

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