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

📄 lwdgabn.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2000, 2001  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: lwdgabn.c,v 1.13 2001/01/22 22:12:16 bwelling Exp $ */#include <config.h>#include <stdlib.h>#include <isc/netaddr.h>#include <isc/sockaddr.h>#include <isc/socket.h>#include <isc/string.h>		/* Required for HP/UX (and others?) */#include <isc/util.h>#include <dns/adb.h>#include <dns/events.h>#include <dns/result.h>#include <named/types.h>#include <named/lwaddr.h>#include <named/lwdclient.h>#include <named/lwresd.h>#include <named/lwsearch.h>#include <named/sortlist.h>#define NEED_V4(c)	((((c)->find_wanted & LWRES_ADDRTYPE_V4) != 0) \			 && ((c)->v4find == NULL))#define NEED_V6(c)	((((c)->find_wanted & LWRES_ADDRTYPE_V6) != 0) \			 && ((c)->v6find == NULL))static isc_result_t start_find(ns_lwdclient_t *);static void restart_find(ns_lwdclient_t *);static void init_gabn(ns_lwdclient_t *);/* * Destroy any finds.  This can be used to "start over from scratch" and * should only be called when events are _not_ being generated by the finds. */static voidcleanup_gabn(ns_lwdclient_t *client) {	ns_lwdclient_log(50, "cleaning up client %p", client);	if (client->v6find != NULL) {		if (client->v6find == client->v4find)			client->v6find = NULL;		else			dns_adb_destroyfind(&client->v6find);	}	if (client->v4find != NULL)		dns_adb_destroyfind(&client->v4find);}static voidsetup_addresses(ns_lwdclient_t *client, dns_adbfind_t *find, unsigned int at) {	dns_adbaddrinfo_t *ai;	lwres_addr_t *addr;	int af;	const struct sockaddr *sa;	isc_result_t result;	if (at == DNS_ADBFIND_INET)		af = AF_INET;	else		af = AF_INET6;	ai = ISC_LIST_HEAD(find->list);	while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) {		sa = &ai->sockaddr.type.sa;		if (sa->sa_family != af)			goto next;		addr = &client->addrs[client->gabn.naddrs];		result = lwaddr_lwresaddr_fromsockaddr(addr, &ai->sockaddr);		if (result != ISC_R_SUCCESS)			goto next;		ns_lwdclient_log(50, "adding address %p, family %d, length %d",				 addr->address, addr->family, addr->length);		client->gabn.naddrs++;		REQUIRE(!LWRES_LINK_LINKED(addr, link));		LWRES_LIST_APPEND(client->gabn.addrs, addr, link);	next:		ai = ISC_LIST_NEXT(ai, publink);	}}typedef struct {	isc_netaddr_t address;	int rank;} rankedaddress;static intaddr_compare(const void *av, const void *bv) {	const rankedaddress *a = (const rankedaddress *) av;	const rankedaddress *b = (const rankedaddress *) bv;	return (a->rank - b->rank);}static voidsort_addresses(ns_lwdclient_t *client) {	unsigned int naddrs;	rankedaddress *addrs;	isc_netaddr_t remote;	dns_addressorderfunc_t order;	void *arg;	ns_lwresd_t *lwresd = client->clientmgr->listener->manager;	unsigned int i;	isc_result_t result;	naddrs = client->gabn.naddrs;	if (naddrs <= 1 || lwresd->view->sortlist == NULL)		return;	addrs = isc_mem_get(lwresd->mctx, sizeof(rankedaddress) * naddrs);	if (addrs == NULL)		return;	isc_netaddr_fromsockaddr(&remote, &client->address);	ns_sortlist_byaddrsetup(lwresd->view->sortlist,				&remote, &order, &arg);	if (order == NULL) {		isc_mem_put(lwresd->mctx, addrs,			    sizeof(rankedaddress) * naddrs);		return;	}	for (i = 0; i < naddrs; i++) {		result = lwaddr_netaddr_fromlwresaddr(&addrs[i].address,						      &client->addrs[i]);		INSIST(result == ISC_R_SUCCESS);		addrs[i].rank = (*order)(&addrs[i].address, arg);	}	qsort(addrs, naddrs, sizeof(rankedaddress), addr_compare);	for (i = 0; i < naddrs; i++) {		result = lwaddr_lwresaddr_fromnetaddr(&client->addrs[i],						      &addrs[i].address);		INSIST(result == ISC_R_SUCCESS);	}	isc_mem_put(lwresd->mctx, addrs, sizeof(rankedaddress) * naddrs);}static voidgenerate_reply(ns_lwdclient_t *client) {	isc_result_t result;	int lwres;	isc_region_t r;	lwres_buffer_t lwb;	ns_lwdclientmgr_t *cm;	cm = client->clientmgr;	lwb.base = NULL;	ns_lwdclient_log(50, "generating gabn reply for client %p", client);	/*	 * We must make certain the client->find is not still active.	 * If it is either the v4 or v6 answer, just set it to NULL and	 * let the cleanup code destroy it.  Otherwise, destroy it now.	 */	if (client->find == client->v4find || client->find == client->v6find)		client->find = NULL;	else		if (client->find != NULL)			dns_adb_destroyfind(&client->find);	/*	 * perhaps there are some here?	 */	if (NEED_V6(client) && client->v4find != NULL)		client->v6find = client->v4find;	/*	 * Run through the finds we have and wire them up to the gabn	 * structure.	 */	LWRES_LIST_INIT(client->gabn.addrs);	if (client->v4find != NULL)		setup_addresses(client, client->v4find, DNS_ADBFIND_INET);	if (client->v6find != NULL)		setup_addresses(client, client->v6find, DNS_ADBFIND_INET6);	/*	 * If there are no addresses, try the next element in the search	 * path, if there are any more.  Otherwise, fall through into	 * the error handling code below.	 */	if (client->gabn.naddrs == 0) {		do {			result = ns_lwsearchctx_next(&client->searchctx);			if (result == ISC_R_SUCCESS) {				cleanup_gabn(client);				result = start_find(client);				if (result == ISC_R_SUCCESS)					return;			}		} while (result == ISC_R_SUCCESS);	}	/*	 * Render the packet.	 */	client->pkt.recvlength = LWRES_RECVLENGTH;	client->pkt.authtype = 0; /* XXXMLG */	client->pkt.authlength = 0;	/*	 * If there are no addresses, return failure.	 */	if (client->gabn.naddrs != 0)		client->pkt.result = LWRES_R_SUCCESS;	else		client->pkt.result = LWRES_R_NOTFOUND;	sort_addresses(client);	lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn,					  &client->pkt, &lwb);	if (lwres != LWRES_R_SUCCESS)		goto out;	r.base = lwb.base;	r.length = lwb.used;	client->sendbuf = r.base;	client->sendlength = r.length;	result = ns_lwdclient_sendreply(client, &r);	if (result != ISC_R_SUCCESS)		goto out;	NS_LWDCLIENT_SETSEND(client);	/*	 * All done!	 */	cleanup_gabn(client);	return; out:	cleanup_gabn(client);	if (lwb.base != NULL)		lwres_context_freemem(client->clientmgr->lwctx,				      lwb.base, lwb.length);	ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);}/* * Take the current real name, move it to an alias slot (if any are * open) then put this new name in as the real name for the target. * * Return success if it can be rendered, otherwise failure.  Note that * not having enough alias slots open is NOT a failure. */static isc_result_tadd_alias(ns_lwdclient_t *client) {	isc_buffer_t b;	isc_result_t result;	isc_uint16_t naliases;	b = client->recv_buffer;	/*	 * Render the new name to the buffer.	 */	result = dns_name_totext(dns_fixedname_name(&client->target_name),				 ISC_TRUE, &client->recv_buffer);	if (result != ISC_R_SUCCESS)		return (result);	/*	 * Are there any open slots?	 */	naliases = client->gabn.naliases;	if (naliases < LWRES_MAX_ALIASES) {		client->gabn.aliases[naliases] = client->gabn.realname;		client->gabn.aliaslen[naliases] = client->gabn.realnamelen;		client->gabn.naliases++;	}	/*	 * Save this name away as the current real name.	 */	client->gabn.realname = (char *)(b.base) + b.used;	client->gabn.realnamelen = client->recv_buffer.used - b.used;	return (ISC_R_SUCCESS);}static isc_result_tstore_realname(ns_lwdclient_t *client) {	isc_buffer_t b;	isc_result_t result;	dns_name_t *tname;	b = client->recv_buffer;	tname = dns_fixedname_name(&client->target_name);	result = ns_lwsearchctx_current(&client->searchctx, tname);	if (result != ISC_R_SUCCESS)		return (result);	/*	 * Render the new name to the buffer.	 */	result = dns_name_totext(tname, ISC_TRUE, &client->recv_buffer);	if (result != ISC_R_SUCCESS)		return (result);

⌨️ 快捷键说明

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