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

📄 interfacemgr.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM 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 2002/02/08 03:57:10 marka 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;	}	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, 3);	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;	}	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_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;	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 return 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);}

⌨️ 快捷键说明

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