📄 server.c
字号:
CHECK(dns_zone_create(&zone, ns_g_mctx)); CHECK(dns_zone_setorigin(zone, &origin)); dns_zone_settype(zone, dns_zone_master); dns_zone_setclass(zone, dns_rdataclass_ch); /* Transfers don't work so deny them. */ CHECK(dns_acl_none(ns_g_mctx, &acl)); dns_zone_setxfracl(zone, acl); dns_acl_detach(&acl); dns_zone_setview(zone, view); CHECK(dns_zonemgr_managezone(zmgr, zone)); CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, dns_dbtype_zone, dns_rdataclass_ch, 0, NULL, &db)); CHECK(dns_db_newversion(db, &dbver)); CHECK(dns_difftuple_create(ns_g_mctx, DNS_DIFFOP_ADD, &origin, 0, &rdata, &tuple)); dns_diff_append(&diff, &tuple); CHECK(dns_diff_apply(&diff, db, dbver)); dns_db_closeversion(db, &dbver, ISC_TRUE); CHECK(dns_zone_replacedb(zone, db, ISC_FALSE)); CHECK(dns_view_addzone(view, zone)); result = ISC_R_SUCCESS; cleanup: if (zone != NULL) dns_zone_detach(&zone); if (dbver != NULL) dns_db_closeversion(db, &dbver, ISC_FALSE); if (db != NULL) dns_db_detach(&db); dns_diff_clear(&diff); return (result);}/* * Create the special zone that handles queries for "authors.bind. CH". * The strings returned list the BIND 9 authors. */static isc_result_tcreate_authors_zone(cfg_obj_t *options, dns_zonemgr_t *zmgr, dns_view_t *view){ isc_result_t result; dns_db_t *db = NULL; dns_zone_t *zone = NULL; dns_dbversion_t *dbver = NULL; dns_difftuple_t *tuple; dns_diff_t diff; isc_constregion_t r; isc_constregion_t cr; dns_rdata_t rdata = DNS_RDATA_INIT; static const char origindata[] = "\007authors\004bind"; dns_name_t origin; int i; static const char *authors[] = { "\014Mark Andrews", "\015James Brister", "\014Ben Cottrell", "\015Michael Graff", "\022Andreas Gustafsson", "\012Bob Halley", "\016David Lawrence", "\013Danny Mayer", "\013Damien Neil", "\013Matt Nelson", "\016Michael Sawyer", "\020Brian Wellington", NULL, }; cfg_obj_t *obj = NULL; dns_acl_t *acl = NULL; /* * If a version string is specified, disable the authors.bind zone. */ if (options != NULL && cfg_map_get(options, "version", &obj) == ISC_R_SUCCESS) return (ISC_R_SUCCESS); dns_diff_init(ns_g_mctx, &diff); dns_name_init(&origin, NULL); r.base = origindata; r.length = sizeof(origindata); dns_name_fromregion(&origin, (isc_region_t *)&r); CHECK(dns_zone_create(&zone, ns_g_mctx)); CHECK(dns_zone_setorigin(zone, &origin)); dns_zone_settype(zone, dns_zone_master); dns_zone_setclass(zone, dns_rdataclass_ch); /* Transfers don't work so deny them. */ CHECK(dns_acl_none(ns_g_mctx, &acl)); dns_zone_setxfracl(zone, acl); dns_acl_detach(&acl); dns_zone_setview(zone, view); CHECK(dns_zonemgr_managezone(zmgr, zone)); CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, dns_dbtype_zone, dns_rdataclass_ch, 0, NULL, &db)); CHECK(dns_db_newversion(db, &dbver)); for (i = 0; authors[i] != NULL; i++) { cr.base = authors[i]; cr.length = strlen(authors[i]); INSIST(cr.length == ((const unsigned char *)cr.base)[0] + 1U); dns_rdata_fromregion(&rdata, dns_rdataclass_ch, dns_rdatatype_txt, (isc_region_t *)&cr); tuple = NULL; CHECK(dns_difftuple_create(ns_g_mctx, DNS_DIFFOP_ADD, &origin, 0, &rdata, &tuple)); dns_diff_append(&diff, &tuple); dns_rdata_reset(&rdata); } CHECK(dns_diff_apply(&diff, db, dbver)); dns_db_closeversion(db, &dbver, ISC_TRUE); CHECK(dns_zone_replacedb(zone, db, ISC_FALSE)); CHECK(dns_view_addzone(view, zone)); result = ISC_R_SUCCESS; cleanup: if (zone != NULL) dns_zone_detach(&zone); if (dbver != NULL) dns_db_closeversion(db, &dbver, ISC_FALSE); if (db != NULL) dns_db_detach(&db); dns_diff_clear(&diff); return (result);}static isc_result_tconfigure_hints(dns_view_t *view, const char *filename) { isc_result_t result; dns_db_t *db; db = NULL; result = dns_rootns_create(view->mctx, view->rdclass, filename, &db); if (result == ISC_R_SUCCESS) { dns_view_sethints(view, db); dns_db_detach(&db); } return (result);}static isc_result_tconfigure_forward(cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, cfg_obj_t *forwarders, cfg_obj_t *forwardtype){ cfg_obj_t *portobj; cfg_obj_t *faddresses; cfg_listelt_t *element; dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none; isc_sockaddrlist_t addresses; isc_sockaddr_t *sa; isc_result_t result; in_port_t port; /* * Determine which port to send forwarded requests to. */ if (ns_g_lwresdonly && ns_g_port != 0) port = ns_g_port; else CHECKM(ns_config_getport(config, &port), "port"); if (forwarders != NULL) { portobj = cfg_tuple_get(forwarders, "port"); if (cfg_obj_isuint32(portobj)) { isc_uint32_t val = cfg_obj_asuint32(portobj); if (val > ISC_UINT16_MAX) { cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, "port '%u' out of range", val); return (ISC_R_RANGE); } port = (in_port_t) val; } } faddresses = NULL; if (forwarders != NULL) faddresses = cfg_tuple_get(forwarders, "addresses"); ISC_LIST_INIT(addresses); for (element = cfg_list_first(faddresses); element != NULL; element = cfg_list_next(element)) { cfg_obj_t *forwarder = cfg_listelt_value(element); sa = isc_mem_get(view->mctx, sizeof(isc_sockaddr_t)); if (sa == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } *sa = *cfg_obj_assockaddr(forwarder); if (isc_sockaddr_getport(sa) == 0) isc_sockaddr_setport(sa, port); ISC_LINK_INIT(sa, link); ISC_LIST_APPEND(addresses, sa, link); } if (ISC_LIST_EMPTY(addresses)) { if (forwardtype != NULL) cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, "no forwarders seen; disabling " "forwarding"); fwdpolicy = dns_fwdpolicy_none; } else { if (forwardtype == NULL) fwdpolicy = dns_fwdpolicy_first; else { char *forwardstr = cfg_obj_asstring(forwardtype); if (strcasecmp(forwardstr, "first") == 0) fwdpolicy = dns_fwdpolicy_first; else if (strcasecmp(forwardstr, "only") == 0) fwdpolicy = dns_fwdpolicy_only; else INSIST(0); } } result = dns_fwdtable_add(view->fwdtable, origin, &addresses, fwdpolicy); if (result != ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(origin, namebuf, sizeof(namebuf)); cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, "could not set up forwarding for domain '%s': %s", namebuf, isc_result_totext(result)); goto cleanup; } result = ISC_R_SUCCESS; cleanup: while (!ISC_LIST_EMPTY(addresses)) { sa = ISC_LIST_HEAD(addresses); ISC_LIST_UNLINK(addresses, sa, link); isc_mem_put(view->mctx, sa, sizeof(isc_sockaddr_t)); } return (result);}/* * Create a new view and add it to the list. * * If 'vconfig' is NULL, create the default view. * * The view created is attached to '*viewp'. */static isc_result_tcreate_view(cfg_obj_t *vconfig, dns_viewlist_t *viewlist, dns_view_t **viewp) { isc_result_t result; const char *viewname; dns_rdataclass_t viewclass; dns_view_t *view = NULL; if (vconfig != NULL) { cfg_obj_t *classobj = NULL; viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); classobj = cfg_tuple_get(vconfig, "class"); result = ns_config_getclass(classobj, dns_rdataclass_in, &viewclass); } else { viewname = "_default"; viewclass = dns_rdataclass_in; } result = dns_viewlist_find(viewlist, viewname, viewclass, &view); if (result == ISC_R_SUCCESS) return (ISC_R_EXISTS); if (result != ISC_R_NOTFOUND) return (result); INSIST(view == NULL); result = dns_view_create(ns_g_mctx, viewclass, viewname, &view); if (result != ISC_R_SUCCESS) return (result); ISC_LIST_APPEND(*viewlist, view, link); dns_view_attach(view, viewp); return (ISC_R_SUCCESS);}/* * Configure or reconfigure a zone. */static isc_result_tconfigure_zone(cfg_obj_t *config, cfg_obj_t *zconfig, cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view, ns_aclconfctx_t *aclconf){ dns_view_t *pview = NULL; /* Production view */ dns_zone_t *zone = NULL; /* New or reused zone */ dns_zone_t *dupzone = NULL; cfg_obj_t *options = NULL; cfg_obj_t *zoptions = NULL; cfg_obj_t *typeobj = NULL; cfg_obj_t *forwarders = NULL; cfg_obj_t *forwardtype = NULL; cfg_obj_t *only = NULL; isc_result_t result; isc_result_t tresult; isc_buffer_t buffer; dns_fixedname_t fixorigin; dns_name_t *origin; const char *zname; dns_rdataclass_t zclass; const char *ztypestr; options = NULL; (void)cfg_map_get(config, "options", &options); zoptions = cfg_tuple_get(zconfig, "options"); /* * Get the zone origin as a dns_name_t. */ zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); isc_buffer_init(&buffer, zname, strlen(zname)); isc_buffer_add(&buffer, strlen(zname)); dns_fixedname_init(&fixorigin); CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), &buffer, dns_rootname, ISC_FALSE, NULL)); origin = dns_fixedname_name(&fixorigin); CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"), view->rdclass, &zclass)); if (zclass != view->rdclass) { const char *vname = NULL; if (vconfig != NULL) vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); else vname = "<default view>"; isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "zone '%s': wrong class for view '%s'", zname, vname); result = ISC_R_FAILURE; goto cleanup; } (void)cfg_map_get(zoptions, "type", &typeobj); if (typeobj == NULL) { cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, "zone '%s' 'type' not specified", zname); return (ISC_R_FAILURE); } ztypestr = cfg_obj_asstring(typeobj); /* * "hints zones" aren't zones. If we've got one, * configure it and return. */ if (strcasecmp(ztypestr, "hint") == 0) { cfg_obj_t *fileobj = NULL; if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "zone '%s': 'file' not specified", zname); result = ISC_R_FAILURE; goto cleanup; } if (dns_name_equal(origin, dns_rootname)) { char *hintsfile = cfg_obj_asstring(fileobj); result = configure_hints(view, hintsfile); if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "could not configure root hints " "from '%s': %s", hintsfile, isc_result_totext(result)); goto cleanup; } /* * Hint zones may also refer to delegation only points. */ only = NULL; tresult = cfg_map_get(zoptions, "delegation-only", &only); if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) CHECK(dns_view_adddelegationonly(view, origin)); } else { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, "ignoring non-root hint zone '%s'", zname); result = ISC_R_SUCCESS; } /* Skip ordinary zone processing. */ goto cleanup; } /* * "forward zones" aren't zones either. Translate this syntax into * the appropriate selective forwarding configuration and return. */ if (strcasecmp(ztypestr, "forward") == 0) { forwardtype = NULL; forwarders = NULL; (void)cfg_map_get(zoptions, "forward", &forwardtype); (void)cfg_map_get(zoptions, "forwarders", &forwarders); result = configure_forward(config, view, origin, forwarders, forwardtype); goto cleanup; } /* * "delegation-only zones" aren't zones either. */ if (strcasecmp(ztypestr, "delegation-only") == 0) { result = dns_view_adddelegationonly(view, origin); goto cleanup; } /* * Check for duplicates in the new zone table. */ result = dns_view_findzone(view, origin, &dupzone); if (result == ISC_R_SUCCESS) { /* * We already have this zone! */ dns_zone_detach(&dupzone); result = ISC_R_EXISTS; goto cleanup; } INSIST(dupzone == NULL); /* * See if we can reuse an existing zone. This is * only possible if all of these are true: * - The zone's view exists * - A zone with the right name exists in the view * - The zone is compatible with the config * options (e.g., an existing master zone cannot * be reused if the options specify a slave zone) */ result = dns_viewlist_find(&ns_g_server->viewlist, view->name, view->rdclass, &pview); if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) goto cleanup; if (pview != NULL) result = dns_view_findzone(pview, origin, &zone); if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) goto cleanup; if (zone != NULL) { if (! ns_zone_reusable(zone, zconfig)) dns_zone_detach(&zone); } if (zone != NULL) { /* * We found a reusable zone. Make it use the * new view. */ dns_zone_setview(zone, view); } else { /* * We cannot reuse an existing zone, we have * to create a new one. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -