📄 lwresd.c
字号:
/* * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 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: lwresd.c,v 1.37.2.2.2.5 2004/03/08 04:04:19 marka Exp $ *//* * Main program for the Lightweight Resolver Daemon. * * To paraphrase the old saying about X11, "It's not a lightweight deamon * for resolvers, it's a deamon for lightweight resolvers". */#include <config.h>#include <stdlib.h>#include <string.h>#include <isc/list.h>#include <isc/magic.h>#include <isc/mem.h>#include <isc/once.h>#include <isc/print.h>#include <isc/socket.h>#include <isc/task.h>#include <isc/util.h>#include <isccfg/namedconf.h>#include <dns/log.h>#include <dns/result.h>#include <dns/view.h>#include <named/config.h>#include <named/globals.h>#include <named/log.h>#include <named/lwaddr.h>#include <named/lwresd.h>#include <named/lwdclient.h>#include <named/lwsearch.h>#include <named/server.h>#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D')#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC)#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L')#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC)/* * The total number of clients we can handle will be NTASKS * NRECVS. */#define NTASKS 2 /* tasks to create to handle lwres queries */#define NRECVS 2 /* max clients per task */typedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t;static ns_lwreslistenerlist_t listeners;static isc_mutex_t listeners_lock;static isc_once_t once = ISC_ONCE_INIT;static voidinitialize_mutex(void) { RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS);}/* * Wrappers around our memory management stuff, for the lwres functions. */void *ns__lwresd_memalloc(void *arg, size_t size) { return (isc_mem_get(arg, size));}voidns__lwresd_memfree(void *arg, void *mem, size_t size) { isc_mem_put(arg, mem, size);}#define CHECK(op) \ do { result = (op); \ if (result != ISC_R_SUCCESS) goto cleanup; \ } while (0)static isc_result_tbuffer_putstr(isc_buffer_t *b, const char *s) { unsigned int len = strlen(s); if (isc_buffer_availablelength(b) <= len) return (ISC_R_NOSPACE); isc_buffer_putmem(b, (const unsigned char *)s, len); return (ISC_R_SUCCESS);}/* * Convert a resolv.conf file into a config structure. */isc_result_tns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, cfg_obj_t **configp){ char text[4096]; char str[16]; isc_buffer_t b; lwres_context_t *lwctx = NULL; lwres_conf_t *lwc = NULL; isc_sockaddr_t sa; isc_netaddr_t na; int i; isc_result_t result; lwres_result_t lwresult; lwctx = NULL; lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, ns__lwresd_memfree, LWRES_CONTEXT_SERVERMODE); if (lwresult != LWRES_R_SUCCESS) { result = ISC_R_NOMEMORY; goto cleanup; } lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); if (lwresult != LWRES_R_SUCCESS) { result = DNS_R_SYNTAX; goto cleanup; } lwc = lwres_conf_get(lwctx); INSIST(lwc != NULL); isc_buffer_init(&b, text, sizeof(text)); CHECK(buffer_putstr(&b, "options {\n")); /* * Build the list of forwarders. */ if (lwc->nsnext > 0) { CHECK(buffer_putstr(&b, "\tforwarders {\n")); for (i = 0; i < lwc->nsnext; i++) { CHECK(lwaddr_sockaddr_fromlwresaddr( &sa, &lwc->nameservers[i], ns_g_port)); isc_netaddr_fromsockaddr(&na, &sa); CHECK(buffer_putstr(&b, "\t\t")); CHECK(isc_netaddr_totext(&na, &b)); CHECK(buffer_putstr(&b, ";\n")); } CHECK(buffer_putstr(&b, "\t};\n")); } /* * Build the sortlist */ if (lwc->sortlistnxt > 0) { CHECK(buffer_putstr(&b, "\tsortlist {\n")); CHECK(buffer_putstr(&b, "\t\t{\n")); CHECK(buffer_putstr(&b, "\t\t\tany;\n")); CHECK(buffer_putstr(&b, "\t\t\t{\n")); for (i = 0; i < lwc->sortlistnxt; i++) { lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; lwres_addr_t *lwmask = &lwc->sortlist[i].mask; unsigned int mask; CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); isc_netaddr_fromsockaddr(&na, &sa); result = isc_netaddr_masktoprefixlen(&na, &mask); if (result != ISC_R_SUCCESS) { char addrtext[ISC_NETADDR_FORMATSIZE]; isc_netaddr_format(&na, addrtext, sizeof(addrtext)); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, "processing sortlist: '%s' is " "not a valid netmask", addrtext); goto cleanup; } CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); isc_netaddr_fromsockaddr(&na, &sa); CHECK(buffer_putstr(&b, "\t\t\t\t")); CHECK(isc_netaddr_totext(&na, &b)); snprintf(str, sizeof(str), "%u", mask); CHECK(buffer_putstr(&b, "/")); CHECK(buffer_putstr(&b, str)); CHECK(buffer_putstr(&b, ";\n")); } CHECK(buffer_putstr(&b, "\t\t\t};\n")); CHECK(buffer_putstr(&b, "\t\t};\n")); CHECK(buffer_putstr(&b, "\t};\n")); } CHECK(buffer_putstr(&b, "};\n\n")); CHECK(buffer_putstr(&b, "lwres {\n")); /* * Build the search path */ if (lwc->searchnxt > 0) { if (lwc->searchnxt > 0) { CHECK(buffer_putstr(&b, "\tsearch {\n")); for (i = 0; i < lwc->searchnxt; i++) { CHECK(buffer_putstr(&b, "\t\t\"")); CHECK(buffer_putstr(&b, lwc->search[i])); CHECK(buffer_putstr(&b, "\";\n")); } CHECK(buffer_putstr(&b, "\t};\n")); } } /* * Build the ndots line */ if (lwc->ndots != 1) { CHECK(buffer_putstr(&b, "\tndots ")); snprintf(str, sizeof(str), "%u", lwc->ndots); CHECK(buffer_putstr(&b, str)); CHECK(buffer_putstr(&b, ";\n")); } /* * Build the listen-on line */ if (lwc->lwnext > 0) { CHECK(buffer_putstr(&b, "\tlisten-on {\n")); for (i = 0; i < lwc->lwnext; i++) { CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, &lwc->lwservers[i], 0)); isc_netaddr_fromsockaddr(&na, &sa); CHECK(buffer_putstr(&b, "\t\t")); CHECK(isc_netaddr_totext(&na, &b)); CHECK(buffer_putstr(&b, ";\n")); } CHECK(buffer_putstr(&b, "\t};\n")); } CHECK(buffer_putstr(&b, "};\n"));#if 0 printf("%.*s\n", (int)isc_buffer_usedlength(&b), (char *)isc_buffer_base(&b));#endif lwres_conf_clear(lwctx); lwres_context_destroy(&lwctx); return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); cleanup: if (lwctx != NULL) { lwres_conf_clear(lwctx); lwres_context_destroy(&lwctx); } return (result);}/* * Handle lwresd manager objects */isc_result_tns_lwdmanager_create(isc_mem_t *mctx, cfg_obj_t *lwres, ns_lwresd_t **lwresdp){ ns_lwresd_t *lwresd; const char *vname; dns_rdataclass_t vclass; cfg_obj_t *obj, *viewobj, *searchobj; cfg_listelt_t *element; isc_result_t result; INSIST(lwresdp != NULL && *lwresdp == NULL); lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t)); if (lwresd == NULL) return (ISC_R_NOMEMORY); lwresd->mctx = NULL; isc_mem_attach(mctx, &lwresd->mctx); lwresd->view = NULL; lwresd->search = NULL; lwresd->refs = 1; obj = NULL; (void)cfg_map_get(lwres, "ndots", &obj); if (obj != NULL) lwresd->ndots = cfg_obj_asuint32(obj); else lwresd->ndots = 1; RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS); lwresd->shutting_down = ISC_FALSE; viewobj = NULL; (void)cfg_map_get(lwres, "view", &viewobj); if (viewobj != NULL) { vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name")); obj = cfg_tuple_get(viewobj, "class"); result = ns_config_getclass(obj, dns_rdataclass_in, &vclass); if (result != ISC_R_SUCCESS) goto fail; } else { vname = "_default"; vclass = dns_rdataclass_in; } result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass, &lwresd->view); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, "couldn't find view %s", vname); goto fail; } searchobj = NULL; (void)cfg_map_get(lwres, "search", &searchobj); if (searchobj != NULL) { lwresd->search = NULL; result = ns_lwsearchlist_create(lwresd->mctx, &lwresd->search); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, "couldn't create searchlist"); goto fail; } for (element = cfg_list_first(searchobj); element != NULL; element = cfg_list_next(element)) { cfg_obj_t *search; char *searchstr; isc_buffer_t namebuf; dns_fixedname_t fname; dns_name_t *name; search = cfg_listelt_value(element); searchstr = cfg_obj_asstring(search); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&namebuf, searchstr, strlen(searchstr)); isc_buffer_add(&namebuf, strlen(searchstr)); result = dns_name_fromtext(name, &namebuf, dns_rootname, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, "invalid name %s in searchlist", searchstr); continue; } result = ns_lwsearchlist_append(lwresd->search, name); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, "couldn't update searchlist"); goto fail; } } } lwresd->magic = LWRESD_MAGIC; *lwresdp = lwresd; return (ISC_R_SUCCESS); fail: if (lwresd->view != NULL) dns_view_detach(&lwresd->view); if (lwresd->search != NULL) ns_lwsearchlist_detach(&lwresd->search); if (lwresd->mctx != NULL) isc_mem_detach(&lwresd->mctx); return (result);}voidns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) { INSIST(VALID_LWRESD(source)); INSIST(targetp != NULL && *targetp == NULL); LOCK(&source->lock); source->refs++; UNLOCK(&source->lock); *targetp = source;}voidns_lwdmanager_detach(ns_lwresd_t **lwresdp) { ns_lwresd_t *lwresd; isc_mem_t *mctx; isc_boolean_t done = ISC_FALSE; INSIST(lwresdp != NULL && *lwresdp != NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -