diff --git a/CHANGES b/CHANGES index 4707ce2043..da4690002a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +1032. [func] hostname.bind/txt/chaos now returns the name of + the machine hosting the nameserver. This is useful + in diagnosing problems with anycast servers. + 1031. [bug] libbind.a: isc__gettimeofday() infinite recursion. [RT #1858] diff --git a/bin/named/server.c b/bin/named/server.c index c6426cf87f..5789a713a2 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.348 2001/09/28 18:19:34 gson Exp $ */ +/* $Id: server.c,v 1.349 2001/10/08 07:46:06 marka Exp $ */ #include @@ -966,6 +966,95 @@ create_version_zone(cfg_obj_t **maps, dns_zonemgr_t *zmgr, dns_view_t *view) { return (result); } +/* + * Create the zone that handles queries for "hostname.bind. CH". The + * hostname string is returned either from the "hostname" configuration + * option or the the result of gethostbyname(). + */ +static isc_result_t +create_hostname_zone(cfg_obj_t **maps, 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 = NULL; + dns_diff_t diff; + char *hostnametext; + unsigned char buf[256]; + isc_region_t r; + size_t len; + dns_rdata_t rdata = DNS_RDATA_INIT; + static unsigned char origindata[] = "\010hostname\004bind"; + dns_name_t origin; + cfg_obj_t *obj = NULL; + + dns_name_init(&origin, NULL); + r.base = origindata; + r.length = sizeof(origindata); + dns_name_fromregion(&origin, &r); + + result = ns_config_get(maps, "hostname", &obj); + if (result == ISC_R_SUCCESS) { + hostnametext = cfg_obj_asstring(obj); + len = strlen(hostnametext); + if (len == 0) + return (ISC_R_SUCCESS); + if (len > 255) + len = 255; /* Silently truncate. */ + buf[0] = len; + memcpy(buf + 1, hostnametext, len); + } else { + result = ns_os_gethostname(buf + 1, sizeof(buf) - 1); + if (result != ISC_R_SUCCESS) + return (ISC_R_SUCCESS); /* Silent failure */ + len = strlen(buf + 1); + buf[0] = len; + } + + r.base = buf; + r.length = 1 + len; + dns_rdata_fromregion(&rdata, dns_rdataclass_ch, dns_rdatatype_txt, &r); + + dns_diff_init(ns_g_mctx, &diff); + + 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); + 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. @@ -1903,6 +1992,7 @@ load_configuration(const char *filename, ns_server_t *server, ISC_LIST_APPEND(viewlist, view, link); CHECK(create_version_zone(maps, server->zonemgr, view)); CHECK(create_authors_zone(options, server->zonemgr, view)); + CHECK(create_hostname_zone(maps, server->zonemgr, view)); dns_view_freeze(view); view = NULL; diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h index 0373f6bd4f..b52e7ccd89 100644 --- a/bin/named/unix/include/named/os.h +++ b/bin/named/unix/include/named/os.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: os.h,v 1.16 2001/09/07 00:36:59 marka Exp $ */ +/* $Id: os.h,v 1.17 2001/10/08 07:46:08 marka Exp $ */ #ifndef NS_OS_H #define NS_OS_H 1 @@ -46,4 +46,7 @@ ns_os_writepidfile(const char *filename); void ns_os_shutdown(void); +isc_result_t +ns_os_gethostname(char *buf, size_t len); + #endif /* NS_OS_H */ diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c index 9652afc208..a42415807c 100644 --- a/bin/named/unix/os.c +++ b/bin/named/unix/os.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: os.c,v 1.50 2001/09/19 23:08:24 gson Exp $ */ +/* $Id: os.c,v 1.51 2001/10/08 07:46:07 marka Exp $ */ #include #include @@ -520,3 +520,12 @@ ns_os_shutdown(void) { closelog(); cleanup_pidfile(); } + +isc_result_t +ns_os_gethostname(char *buf, size_t len) { + int n; + + n = gethostname(buf, len); + return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); +} + diff --git a/bin/named/win32/include/named/os.h b/bin/named/win32/include/named/os.h index a042c2386f..a134118928 100644 --- a/bin/named/win32/include/named/os.h +++ b/bin/named/win32/include/named/os.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: os.h,v 1.3 2001/09/07 00:37:02 marka Exp $ */ +/* $Id: os.h,v 1.4 2001/10/08 07:46:11 marka Exp $ */ #ifndef NS_OS_H #define NS_OS_H 1 @@ -46,4 +46,7 @@ ns_os_writepidfile(const char *filename); void ns_os_shutdown(void); +isc_result_t +ns_os_gethostname(char *buf, size_t len); + #endif /* NS_OS_H */ diff --git a/bin/named/win32/os.c b/bin/named/win32/os.c index f1c66a07da..8742121c3b 100644 --- a/bin/named/win32/os.c +++ b/bin/named/win32/os.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: os.c,v 1.7 2001/09/07 00:37:00 marka Exp $ */ +/* $Id: os.c,v 1.8 2001/10/08 07:46:10 marka Exp $ */ #include #include @@ -204,3 +204,10 @@ ns_os_shutdown(void) { cleanup_pidfile(); ntservice_shutdown(); /* This MUST be the last thing done */ } + +isc_result_t +ns_os_gethostname(char *buf, size_t len) { + UNUSED(buf); + UNUSED(len); + return (ISC_R_NOTIMPLEMENTED); +} diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 2deda043f8..1ae907a46b 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -2,7 +2,7 @@ - + BIND 9 Administrator Reference Manual @@ -2736,6 +2736,7 @@ exact match lookup before search path elements are appended. statement in the named.conf file: options { + hostname hostname_string; version version_string; directory path_name; named-xfer path_name; @@ -2836,6 +2837,18 @@ be used. +hostname +This defaults to the hostname of the machine hosting +the nameserver as found by gethostname(). +Its prime purpose is to be able to identify which of a +number of anycast servers is actually answering your queries by sending a +TXT query for hostname.bind in +class CHAOS to the anycast server and getting back a +unique name. +Setting the hostname to a empty string ("") will +disable processing of the queries. + + version The version the server should report via a query of name version.bind in diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 5491c3439f..7a85f7e08e 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: parser.c,v 1.77 2001/09/08 00:21:40 gson Exp $ */ +/* $Id: parser.c,v 1.78 2001/10/08 07:46:04 marka Exp $ */ #include @@ -819,6 +819,7 @@ options_clauses[] = { { "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "heartbeat-interval", &cfg_type_uint32, 0 }, { "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP }, + { "hostname", &cfg_type_qstring, 0 }, { "interface-interval", &cfg_type_uint32, 0 }, { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },