aboutsummaryrefslogtreecommitdiff
path: root/common/dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/dns.c')
-rw-r--r--common/dns.c149
1 files changed, 98 insertions, 51 deletions
diff --git a/common/dns.c b/common/dns.c
index 5ecae67..3992b6c 100644
--- a/common/dns.c
+++ b/common/dns.c
@@ -64,6 +64,11 @@
* support update forwarding, AFAIK). If no TSIG key is listed, the update
* is attempted without TSIG.
*
+ * You can also include IPv6 addresses via the primary6 and secondary6
+ * options. The search order for the addresses is primary, primary6,
+ * secondary and lastly secondary6, with a limit on the number of
+ * addresses used. Currently this limit is 3.
+ *
* The DHCP server tries to find an existing zone for any given name by
* trying to look up a local zone structure for each domain containing
* that name, all the way up to '.'. If it finds one cached, it tries
@@ -602,44 +607,48 @@ int dns_zone_dereference (ptr, file, line)
{
struct dns_zone *dns_zone;
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
+ if ((ptr == NULL) || (*ptr == NULL)) {
+ log_error("%s(%d): null pointer", file, line);
#if defined (POINTER_DEBUG)
- abort ();
+ abort();
#else
- return 0;
+ return (0);
#endif
}
dns_zone = *ptr;
- *ptr = (struct dns_zone *)0;
- --dns_zone -> refcnt;
- rc_register (file, line, ptr, dns_zone, dns_zone -> refcnt, 1, RC_MISC);
- if (dns_zone -> refcnt > 0)
- return 1;
-
- if (dns_zone -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
+ *ptr = NULL;
+ --dns_zone->refcnt;
+ rc_register(file, line, ptr, dns_zone, dns_zone->refcnt, 1, RC_MISC);
+ if (dns_zone->refcnt > 0)
+ return (1);
+
+ if (dns_zone->refcnt < 0) {
+ log_error("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
- dump_rc_history (dns_zone);
+ dump_rc_history(dns_zone);
#endif
#if defined (POINTER_DEBUG)
- abort ();
+ abort();
#else
- return 0;
+ return (0);
#endif
}
- if (dns_zone -> name)
- dfree (dns_zone -> name, file, line);
- if (dns_zone -> key)
- omapi_auth_key_dereference (&dns_zone -> key, file, line);
- if (dns_zone -> primary)
- option_cache_dereference (&dns_zone -> primary, file, line);
- if (dns_zone -> secondary)
- option_cache_dereference (&dns_zone -> secondary, file, line);
- dfree (dns_zone, file, line);
- return 1;
+ if (dns_zone->name)
+ dfree(dns_zone->name, file, line);
+ if (dns_zone->key)
+ omapi_auth_key_dereference(&dns_zone->key, file, line);
+ if (dns_zone->primary)
+ option_cache_dereference(&dns_zone->primary, file, line);
+ if (dns_zone->secondary)
+ option_cache_dereference(&dns_zone->secondary, file, line);
+ if (dns_zone->primary6)
+ option_cache_dereference(&dns_zone->primary6, file, line);
+ if (dns_zone->secondary6)
+ option_cache_dereference(&dns_zone->secondary6, file, line);
+ dfree(dns_zone, file, line);
+ return (1);
}
#if defined (NSUPDATE)
@@ -648,9 +657,10 @@ find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
{
isc_result_t status = ISC_R_NOTFOUND;
const char *np;
- struct dns_zone *zone = (struct dns_zone *)0;
+ struct dns_zone *zone = NULL;
struct data_string nsaddrs;
struct in_addr zone_addr;
+ struct in6_addr zone_addr6;
int ix;
if (direction == FIND_FORWARD) {
@@ -661,14 +671,14 @@ find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
/* We can't look up a null zone. */
if ((np == NULL) || (*np == '\0')) {
- return DHCP_R_INVALIDARG;
+ return (DHCP_R_INVALIDARG);
}
/*
* For each subzone, try to find a cached zone.
*/
for (;;) {
- status = dns_zone_lookup (&zone, np);
+ status = dns_zone_lookup(&zone, np);
if (status == ISC_R_SUCCESS)
break;
@@ -679,32 +689,28 @@ find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
}
if (status != ISC_R_SUCCESS)
- return status;
+ return (status);
/* Make sure the zone is valid. */
- if (zone -> timeout && zone -> timeout < cur_time) {
- dns_zone_dereference (&zone, MDL);
- return ISC_R_CANCELED;
+ if (zone->timeout && zone->timeout < cur_time) {
+ dns_zone_dereference(&zone, MDL);
+ return (ISC_R_CANCELED);
}
/* Make sure the zone name will fit. */
if (strlen(zone->name) > sizeof(ddns_cb->zone_name)) {
- dns_zone_dereference (&zone, MDL);
- return ISC_R_NOSPACE;
+ dns_zone_dereference(&zone, MDL);
+ return (ISC_R_NOSPACE);
}
strcpy((char *)&ddns_cb->zone_name[0], zone->name);
memset (&nsaddrs, 0, sizeof nsaddrs);
ix = 0;
- if (zone -> primary) {
- if (evaluate_option_cache (&nsaddrs, (struct packet *)0,
- (struct lease *)0,
- (struct client_state *)0,
- (struct option_state *)0,
- (struct option_state *)0,
- &global_scope,
- zone -> primary, MDL)) {
+ if (zone->primary) {
+ if (evaluate_option_cache(&nsaddrs, NULL, NULL, NULL,
+ NULL, NULL, &global_scope,
+ zone->primary, MDL)) {
int ip = 0;
while (ix < DHCP_MAXNS) {
if (ip + 4 > nsaddrs.len)
@@ -719,17 +725,36 @@ find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
ip += 4;
ix++;
}
- data_string_forget (&nsaddrs, MDL);
+ data_string_forget(&nsaddrs, MDL);
+ }
+ }
+
+ if (zone->primary6) {
+ if (evaluate_option_cache(&nsaddrs, NULL, NULL, NULL,
+ NULL, NULL, &global_scope,
+ zone->primary6, MDL)) {
+ int ip = 0;
+ while (ix < DHCP_MAXNS) {
+ if (ip + 16 > nsaddrs.len)
+ break;
+ memcpy(&zone_addr6, &nsaddrs.data[ip], 16);
+ isc_sockaddr_fromin6(&ddns_cb->zone_addrs[ix],
+ &zone_addr6,
+ NS_DEFAULTPORT);
+ ISC_LIST_APPEND(ddns_cb->zone_server_list,
+ &ddns_cb->zone_addrs[ix],
+ link);
+ ip += 16;
+ ix++;
+ }
+ data_string_forget(&nsaddrs, MDL);
}
}
- if (zone -> secondary) {
- if (evaluate_option_cache (&nsaddrs, (struct packet *)0,
- (struct lease *)0,
- (struct client_state *)0,
- (struct option_state *)0,
- (struct option_state *)0,
- &global_scope,
- zone -> secondary, MDL)) {
+
+ if (zone->secondary) {
+ if (evaluate_option_cache(&nsaddrs, NULL, NULL, NULL,
+ NULL, NULL, &global_scope,
+ zone->secondary, MDL)) {
int ip = 0;
while (ix < DHCP_MAXNS) {
if (ip + 4 > nsaddrs.len)
@@ -748,6 +773,28 @@ find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
}
}
+ if (zone->secondary6) {
+ if (evaluate_option_cache(&nsaddrs, NULL, NULL, NULL,
+ NULL, NULL, &global_scope,
+ zone->secondary6, MDL)) {
+ int ip = 0;
+ while (ix < DHCP_MAXNS) {
+ if (ip + 16 > nsaddrs.len)
+ break;
+ memcpy(&zone_addr6, &nsaddrs.data[ip], 16);
+ isc_sockaddr_fromin6(&ddns_cb->zone_addrs[ix],
+ &zone_addr6,
+ NS_DEFAULTPORT);
+ ISC_LIST_APPEND(ddns_cb->zone_server_list,
+ &ddns_cb->zone_addrs[ix],
+ link);
+ ip += 16;
+ ix++;
+ }
+ data_string_forget (&nsaddrs, MDL);
+ }
+ }
+
dns_zone_reference(&ddns_cb->zone, zone, MDL);
dns_zone_dereference (&zone, MDL);
return ISC_R_SUCCESS;